From f9d3a0c2d4d7b2638a46e549b3b2f236a4163aa6 Mon Sep 17 00:00:00 2001 From: ulfrxdev Date: Fri, 24 Apr 2026 18:24:24 +0200 Subject: [PATCH] docs(01-06): add SUMMARY for dev-ergonomics plan --- .../01-06-SUMMARY.md | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 .planning/phases/01-project-infrastructure-module-wiring/01-06-SUMMARY.md diff --git a/.planning/phases/01-project-infrastructure-module-wiring/01-06-SUMMARY.md b/.planning/phases/01-project-infrastructure-module-wiring/01-06-SUMMARY.md new file mode 100644 index 0000000..99abe7b --- /dev/null +++ b/.planning/phases/01-project-infrastructure-module-wiring/01-06-SUMMARY.md @@ -0,0 +1,155 @@ +--- +phase: 01-project-infrastructure-module-wiring +plan: 06 +subsystem: dev-ergonomics +tags: [docker-compose, postgres, readme, local-dev, infra] +dependency_graph: + requires: [] + provides: + - "Local Postgres 16 dev instance matching application.conf HOCON defaults (recipe/recipe/recipe)" + - "Named volume recipe-pgdata for persistence across container restarts" + - "pg_isready healthcheck enabling docker compose up --wait usage" + - "README 'Local development' section documenting the two-command dev loop" + affects: + - "server/src/main/resources/application.conf (Plan 05 — credentials match contract)" + - "Phase 3 (Households + DB migrations) — depends on a working local Postgres" + - "Phase 11 (homelab deployment) — separate compose config will diverge from this dev-local one" +tech_stack: + added: + - "postgres:16 (Docker image, pinned major version)" + patterns: + - "Dev-local compose file committed to repo (non-secret literal creds)" + - "Healthcheck via pg_isready gating sequencing" + - "Named Docker volume for data persistence" +key_files: + created: + - "docker-compose.yml" + modified: + - "README.md" +decisions: + - "Kept it single-service: postgres only. Authentik stays on homelab (CONTEXT.md D-17); Ktor server runs via Gradle on the dev host for fast iteration." + - "Pinned postgres:16 (not :latest, not :15) matching D-17 scope statement." + - "No version: key in compose file — modern docker compose v2 treats it as legacy and emits warnings." + - "No .env file in this plan — inline POSTGRES_* is fine for single-dev + matching application.conf defaults (D-17 / PATTERNS.md recommendation)." + - "Port binding 5432:5432 is dev-local; README calls it out. Phase 11 homelab compose will use a different approach." +metrics: + duration_seconds: 92 + duration_human: "1m32s" + tasks_completed: 2 + files_created: 1 + files_modified: 1 + completed_at: "2026-04-24T16:22:48Z" +--- + +# Phase 01 Plan 06: Dev ergonomics — docker-compose + README Local development summary + +Shipped `docker-compose.yml` (single postgres:16 service, named volume, healthcheck — credentials matching Plan 05's `application.conf` HOCON defaults exactly) and a "Local development" README section documenting the `docker compose up -d postgres && ./gradlew :server:run && curl /health` dev loop, while dropping the legacy `js` target docs per D-01. + +## What was built + +### docker-compose.yml (20 lines) + +- `services.postgres`: + - `image: postgres:16` (pinned major version) + - `container_name: recipe-postgres` + - `environment`: `POSTGRES_DB / POSTGRES_USER / POSTGRES_PASSWORD` all literal `recipe` + - `ports: "5432:5432"` (dev-local loopback via host Docker) + - `volumes: recipe-pgdata:/var/lib/postgresql/data` (persistence) + - `healthcheck`: `pg_isready -U recipe -d recipe` every 5s, timeout 5s, 5 retries +- Top-level `volumes.recipe-pgdata:` (named volume declaration) +- No `version:` key (modern compose v2) +- No additional services (no Authentik — lives on user's homelab per D-17) + +### README.md edits + +**Edit A — dropped js target block** (lines 77-85 of previous README): the "- for the JS target (slower, supports older browsers)" paragraph and its two command blocks were deleted. The `wasmJs` paragraph is preserved intact. + +**Edit B — inserted new "Local development" section** (after the iOS subsection, before the trailing `---` horizontal rule): + +- Two-command boot: `docker compose up -d postgres` + `./gradlew :server:run` +- Smoke test: `curl http://localhost:8080/health` with expected `{"status":"ok"}` response +- Documented env-var overrides: `DATABASE_URL`, `DATABASE_USER`, `DATABASE_PASSWORD`, `PORT` +- Pre-commit formatter hint: `./gradlew spotlessApply` (D-10) +- Full-suite: `./gradlew check` +- DB reset: `docker compose down -v` (destroys `recipe-pgdata`) + +All other existing headings (Android, Desktop/JVM, Server, iOS, web `wasmJs`) and the top introduction (lines 1-20) are unchanged. The trailing `---` + learn-more links paragraph is unchanged. + +## Credential-match contract with Plan 05 + +The three compose env-vars are byte-identical to the literals in `server/src/main/resources/application.conf`: + +| compose env | application.conf | +|-------------|------------------| +| `POSTGRES_DB: recipe` | JDBC URL path `/recipe` | +| `POSTGRES_USER: recipe` | `user = "recipe"` | +| `POSTGRES_PASSWORD: recipe` | `password = "recipe"` | + +Verified via `grep -c '^\s*POSTGRES_\(DB\|USER\|PASSWORD\): recipe$' docker-compose.yml` → `3`. + +## Requirements addressed + +- **INFRA-02** — local development environment via `docker-compose.yml` and README dev loop documentation. + +## Tasks executed + +| Task | Name | Commit | Files | +|------|------|--------|-------| +| 1 | Create docker-compose.yml at repo root | `af4428f` | docker-compose.yml (new) | +| 2 | Add "Local development" section to README.md and drop js target docs | `f691400` | README.md (modified) | + +## Deviations from Plan + +None — plan executed exactly as written. No Rule 1-3 auto-fixes, no checkpoints, no auth gates. Both `` verify blocks and every acceptance criterion passed on first attempt. + +## Threat surface scan + +No new network endpoints, auth paths, file access patterns, or schema changes at trust boundaries were introduced beyond what the plan's `` already covers (T-01-06-01..04). The `5432:5432` host binding and literal `recipe/recipe/recipe` credentials are the exact surface the plan's STRIDE register dispositions (`mitigate`/`accept`) already cover. No new flags. + +## Known stubs + +None. Both deliverables are complete — no placeholders, no TODOs, no empty data paths. + +## Verification + +**Task 1 automated check:** +``` +test -f docker-compose.yml && grep -q 'image: postgres:16' ... && grep -q 'pg_isready -U recipe -d recipe' ... && grep -q '^volumes:$' ... +→ VERIFY PASS +grep -c '^\s*POSTGRES_\(DB\|USER\|PASSWORD\): recipe$' docker-compose.yml → 3 +``` + +**Task 2 automated check:** +``` +grep -q 'Local development' && grep -q 'docker compose up -d postgres' && grep -q 'curl http://localhost:8080/health' && grep -q 'DATABASE_URL' && grep -q 'gradlew spotlessApply' && grep -q 'docker compose down -v' && ! grep -q 'jsBrowserDevelopmentRun' && grep -q 'wasmJsBrowserDevelopmentRun' +→ VERIFY PASS +``` + +**Acceptance criteria — Task 2 individually confirmed:** +- `Local development` appears exactly once (section heading) +- All 4 env-vars listed: `DATABASE_URL`, `DATABASE_USER`, `DATABASE_PASSWORD`, `PORT` +- `gradlew check` present +- Existing section headings (Android / Desktop (JVM) / Server / iOS) all preserved (grep `-c` → `1` each) +- `jsBrowserDevelopmentRun` absent; `wasmJsBrowserDevelopmentRun` present +- Top introduction (lines 1-20) unchanged + +## Manual sanity checks (optional, not blocking) + +Skipped per plan ``: +- `docker compose config` YAML parse — not blocking per plan; docker may not be running in this worktree sandbox. +- `docker compose up -d postgres && pg_isready` live test — not required; will be validated in Phase 3 when migrations land. + +## Notes for downstream plans + +- **Plan 05** (this wave) — credential contract lives in both files; any future change to the `recipe/recipe/recipe` triple MUST update both `application.conf` AND `docker-compose.yml` in the same commit. +- **Phase 3** (Households + DB migrations) — can add `depends_on: { postgres: { condition: service_healthy } }` to a future `server` service in compose if we ever run the Ktor server in Docker; the healthcheck is already wired for it. +- **Phase 11** (homelab deployment) — will ship a separate compose file (not editing this one) because homelab creds are secret and this file's creds are deliberately non-secret literals. + +## Self-Check: PASSED + +- `docker-compose.yml` exists at repo root: FOUND +- `README.md` contains "Local development" section: FOUND +- Commit `af4428f` (Task 1): FOUND in `git log` +- Commit `f691400` (Task 2): FOUND in `git log` +- All acceptance criteria from both tasks verified via grep +- No file deletions in either commit