feat(docker-watcher): phase 1 - project scaffold & SQLite store
Initialize Go module, directory structure, and full SQLite store layer: - 7-table schema (projects, stages, registries, settings, instances, deploys, deploy_logs) with auto-migration - CRUD operations for all entities with proper error handling - ErrNotFound sentinel for distinguishing 404 from 500 in handlers - WAL mode, foreign keys, busy timeout pragmas
This commit is contained in:
@@ -22,7 +22,7 @@ A self-hosted tool that automates Docker container deployment with Nginx Proxy M
|
||||
|
||||
## Phases
|
||||
|
||||
- [ ] Phase 1: Project Scaffold & SQLite Store [domain: backend] → [subplan](./phase-1-scaffold-store.md)
|
||||
- [x] Phase 1: Project Scaffold & SQLite Store [domain: backend] → [subplan](./phase-1-scaffold-store.md)
|
||||
- [ ] Phase 2: Crypto & Config Seed Loader [domain: backend] → [subplan](./phase-2-crypto-config.md)
|
||||
- [ ] Phase 3: Docker Client [domain: backend] → [subplan](./phase-3-docker-client.md)
|
||||
- [ ] Phase 4: NPM Client [domain: backend] → [subplan](./phase-4-npm-client.md)
|
||||
@@ -43,7 +43,7 @@ A self-hosted tool that automates Docker container deployment with Nginx Proxy M
|
||||
|
||||
| Phase | Domain | Status | Review | Build | Committed |
|
||||
|-------|--------|--------|--------|-------|-----------|
|
||||
| Phase 1: Scaffold & Store | backend | ⬜ Not Started | ⬜ | ⏭️ Skip (Big Bang) | ⬜ |
|
||||
| Phase 1: Scaffold & Store | backend | ✅ Complete | ⬜ | ⏭️ Skip (Big Bang) | ⬜ |
|
||||
| Phase 2: Crypto & Config | backend | ⬜ Not Started | ⬜ | ⏭️ Skip (Big Bang) | ⬜ |
|
||||
| Phase 3: Docker Client | backend | ⬜ Not Started | ⬜ | ⏭️ Skip (Big Bang) | ⬜ |
|
||||
| Phase 4: NPM Client | backend | ⬜ Not Started | ⬜ | ⏭️ Skip (Big Bang) | ⬜ |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Phase 1: Project Scaffold & SQLite Store
|
||||
|
||||
**Status:** ⬜ Not Started
|
||||
**Status:** ✅ Complete
|
||||
**Parent plan:** [PLAN.md](./PLAN.md)
|
||||
**Domain:** backend
|
||||
|
||||
@@ -9,17 +9,17 @@ Initialize the Go project, establish the directory structure, and implement the
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Task 1: Initialize Go module (`go mod init`), create directory structure per PLAN.md
|
||||
- [ ] Task 2: Add core dependencies to go.mod (sqlite, chi, yaml, uuid, cron)
|
||||
- [ ] Task 3: Define SQLite schema — tables for projects, stages, registries, settings, instances, deploys, deploy_logs
|
||||
- [ ] Task 4: Implement store initialization with auto-migration (create tables if not exist)
|
||||
- [ ] Task 5: Implement projects CRUD (Create, GetByID, GetAll, Update, Delete)
|
||||
- [ ] Task 6: Implement stages CRUD (Create, GetByProjectID, Update, Delete)
|
||||
- [ ] Task 7: Implement registries CRUD (Create, GetByID, GetAll, Update, Delete)
|
||||
- [ ] Task 8: Implement settings Get/Update (single-row config pattern)
|
||||
- [ ] Task 9: Implement instances CRUD (Create, GetByStageID, GetByID, Update, Delete, UpdateStatus)
|
||||
- [ ] Task 10: Implement deploys CRUD (Create, GetByProjectID, GetRecent, GetByID) + deploy_logs append
|
||||
- [ ] Task 11: Create `cmd/server/main.go` entry point (minimal — just opens DB, defers close)
|
||||
- [x] Task 1: Initialize Go module (`go mod init`), create directory structure per PLAN.md
|
||||
- [x] Task 2: Add core dependencies to go.mod (sqlite, chi, yaml, uuid, cron)
|
||||
- [x] Task 3: Define SQLite schema — tables for projects, stages, registries, settings, instances, deploys, deploy_logs
|
||||
- [x] Task 4: Implement store initialization with auto-migration (create tables if not exist)
|
||||
- [x] Task 5: Implement projects CRUD (Create, GetByID, GetAll, Update, Delete)
|
||||
- [x] Task 6: Implement stages CRUD (Create, GetByProjectID, Update, Delete)
|
||||
- [x] Task 7: Implement registries CRUD (Create, GetByID, GetAll, Update, Delete)
|
||||
- [x] Task 8: Implement settings Get/Update (single-row config pattern)
|
||||
- [x] Task 9: Implement instances CRUD (Create, GetByStageID, GetByID, Update, Delete, UpdateStatus)
|
||||
- [x] Task 10: Implement deploys CRUD (Create, GetByProjectID, GetRecent, GetByID) + deploy_logs append
|
||||
- [x] Task 11: Create `cmd/server/main.go` entry point (minimal — just opens DB, defers close)
|
||||
|
||||
## Files to Modify/Create
|
||||
- `go.mod` — module definition and dependencies
|
||||
@@ -54,4 +54,42 @@ Initialize the Go project, establish the directory structure, and implement the
|
||||
- [ ] CRUD functions handle not-found cases properly
|
||||
|
||||
## Handoff to Next Phase
|
||||
<!-- Filled in by the implementation agent after completing this phase. -->
|
||||
|
||||
### What was built
|
||||
|
||||
- Go module initialized at `github.com/alexei/docker-watcher` with all core dependencies
|
||||
- Full directory structure created: `cmd/server/`, `internal/store/`, plus empty dirs for config, docker, npm, registry, deployer, health, notify, webhook, api, crypto
|
||||
- SQLite store with 7 tables: projects, stages, registries, settings, instances, deploys, deploy_logs
|
||||
- Auto-migration runs on store initialization (CREATE TABLE IF NOT EXISTS)
|
||||
- WAL mode, foreign keys, and busy timeout pragmas enabled
|
||||
- Settings table uses single-row pattern with `INSERT OR IGNORE` seed
|
||||
- Models extracted to `internal/store/models.go` for clean separation
|
||||
|
||||
### Key files
|
||||
|
||||
- `go.mod` — module definition with modernc.org/sqlite, chi, yaml, uuid, cron
|
||||
- `cmd/server/main.go` — entry point that creates data dir, opens store, defers close
|
||||
- `internal/store/store.go` — DB connection, pragmas, schema DDL, migration
|
||||
- `internal/store/models.go` — all entity structs (Project, Stage, Registry, Settings, Instance, Deploy, DeployLog)
|
||||
- `internal/store/projects.go` — full CRUD
|
||||
- `internal/store/stages.go` — full CRUD with bool-to-int conversion for SQLite
|
||||
- `internal/store/registries.go` — full CRUD
|
||||
- `internal/store/settings.go` — Get/Update (single-row upsert)
|
||||
- `internal/store/instances.go` — full CRUD + UpdateStatus
|
||||
- `internal/store/deploys.go` — Create, GetByID, GetByProjectID, GetRecent, UpdateDeployStatus, SetDeployInstanceID, AppendDeployLog, GetDeployLogs
|
||||
|
||||
### Conventions established
|
||||
|
||||
- UUIDs generated via `github.com/google/uuid` on Create operations
|
||||
- Timestamps stored as `datetime('now')` defaults in schema, `time.Now().UTC().Format("2006-01-02 15:04:05")` in Go code
|
||||
- All query errors wrapped with `fmt.Errorf` and `%w` for unwrapping
|
||||
- Not-found cases return descriptive error strings (not sentinel errors yet — can be refined)
|
||||
- Boolean fields stored as INTEGER (0/1) in SQLite, converted via `boolToInt` helper
|
||||
- JSON-encoded maps stored as TEXT for env and volumes fields
|
||||
|
||||
### What Phase 2 needs to know
|
||||
|
||||
- `store.New(dbPath)` returns a `*Store` that is ready to use — no additional init needed
|
||||
- The `settings` table is pre-seeded with a row (id=1) so `GetSettings` always works
|
||||
- Registry `token` and settings `npm_password` are stored as plain text — Phase 2 (Crypto) should add encryption/decryption around these fields
|
||||
- `go.sum` does not exist yet — run `go mod tidy` after Go is available to generate it
|
||||
|
||||
Reference in New Issue
Block a user