diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index b2906fc..9cc2108 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -36,13 +36,13 @@ Requirements for the initial Go+HTMX milestone. Each maps to exactly one roadmap ### Tasks (Kanban) -- [ ] **TASK-01**: Each tablo has a kanban board with named columns (e.g. To do / Doing / Done; configurable in v1 or fixed — user-in-loop on schema) -- [ ] **TASK-02**: User can create a task inside a column with a title -- [ ] **TASK-03**: User can edit a task's title and description -- [ ] **TASK-04**: User can move a task between columns (HTMX + drag-and-drop or button-based reorder, decided in plan-phase) -- [ ] **TASK-05**: User can reorder tasks within a column -- [ ] **TASK-06**: User can delete a task -- [ ] **TASK-07**: Task ordering persists across refreshes +- [x] **TASK-01**: Each tablo has a kanban board with named columns (e.g. To do / Doing / Done; configurable in v1 or fixed — user-in-loop on schema) +- [x] **TASK-02**: User can create a task inside a column with a title +- [x] **TASK-03**: User can edit a task's title and description +- [x] **TASK-04**: User can move a task between columns (HTMX + drag-and-drop or button-based reorder, decided in plan-phase) +- [x] **TASK-05**: User can reorder tasks within a column +- [x] **TASK-06**: User can delete a task +- [x] **TASK-07**: Task ordering persists across refreshes ### Files diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 0ae12bb..40f270a 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -15,7 +15,7 @@ | 1 | Foundation | Fresh `backend/` Go package boots, renders HTMX, talks to Postgres | FOUND-01..05 | | 2 | Authentication | Complete (7/7) | AUTH-01..07 | | 3 | Tablos CRUD | Complete (3/3) | TABLO-01..06 | -| 4 | Tasks (Kanban) | A user can run a kanban board inside a tablo | TASK-01..07 | +| 4 | 1/4 | In Progress| | | 5 | Files | A user can attach, list, download, delete files on a tablo | FILE-01..06 | | 6 | Background Worker | A second binary runs jobs against the same Postgres | WORK-01..04 | | 7 | Deploy v1 | The product runs in production on a single host | DEPLOY-01..05 | @@ -103,9 +103,9 @@ Plans: **User-in-loop:** Approve the `task_columns` (or fixed-column) schema and the ordering strategy (fractional indices, gaps-of-100, linked list — to be decided with research). Approve whether reorder is drag-and-drop or button-driven. -**Plans:** 4 plans +**Plans:** 1/4 plans executed Plans: -- [ ] 04-01-PLAN.md — Wave 0: migration 0004_tasks + sqlc queries + handlers_tasks_test.go RED scaffold + soft-danger button CSS + Sortable.js bootstrap +- [x] 04-01-PLAN.md — Wave 0: migration 0004_tasks + sqlc queries + handlers_tasks_test.go RED scaffold + soft-danger button CSS + Sortable.js bootstrap - [ ] 04-02-PLAN.md — Vertical slice 1: kanban board render + task create + task delete (TASK-01, TASK-02, TASK-06) - [ ] 04-03-PLAN.md — Vertical slice 2: task inline edit + Sortable.js drag reorder/move (TASK-03, TASK-04, TASK-05, TASK-07) - [ ] 04-04-PLAN.md — Human-verify checkpoint: full kanban board browser verification diff --git a/.planning/STATE.md b/.planning/STATE.md index 4384b1b..5d55a26 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,13 +3,13 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: ready_to_execute -last_updated: "2026-05-15T07:05:59.234Z" +last_updated: "2026-05-15T07:25:45.316Z" progress: total_phases: 7 completed_phases: 3 - total_plans: 14 - completed_plans: 14 - percent: 100 + total_plans: 18 + completed_plans: 15 + percent: 83 --- # STATE @@ -23,7 +23,7 @@ progress: See: `.planning/PROJECT.md` (updated 2026-05-14) **Core value:** A user can sign in and run the Tablos workflow — create tablos, manage their tasks (kanban), and attach files — without a JS framework. -**Current focus:** Phase 04 — tasks-kanban (Phase 03 complete) +**Current focus:** Phase 04 — tasks-kanban ## Phase Status @@ -32,14 +32,14 @@ See: `.planning/PROJECT.md` (updated 2026-05-14) | 1 | Foundation | ✓ Complete | | 2 | Authentication | ✓ Complete — VERIFIED PASS (2026-05-14) | | 3 | Tablos CRUD | ✓ Complete — All 3 plans done, TABLO-01..06 closed, verified 2026-05-15 | -| 4 | Tasks (Kanban) | ◷ Planned (4 plans) | +| 4 | Tasks (Kanban) | ◷ In Progress — Plan 01 done | | 5 | Files | ○ Pending | | 6 | Background Worker | ○ Pending | | 7 | Deploy v1 | ○ Pending | ## Active Phase -**Phase 4: Tasks (Kanban)** — Planned (4 plans, 4 waves). Ready to execute. Plans created 2026-05-15. +**Phase 4: Tasks (Kanban)** — In progress. Plan 01 done (Wave 0 foundation). Plans 02-04 pending. ## Verification Record @@ -73,6 +73,9 @@ See: `.planning/PROJECT.md` (updated 2026-05-14) - **_zone hidden field (title|desc) in edit fragments** — unified POST /tablos/{id} handler reads _zone to select which display fragment to return; misuse only affects response body, not DB state (03-03) - **loadOwnedTablo helper for all parametric handlers** — uuid.Parse + GetTabloByID + ownership check factored into single function; 404 on any failure, 403 never used (D-04) (03-03) - **TabloDeleteButtonFragment canonical delete-zone** — TabloCard delegates to it; single source of truth for zone HTML across card and detail-page contexts (03-03) +- **task_status ENUM order matches visual column order** (todo, in_progress, in_review, done) — ENUM ordinal sorting aligns with kanban column display order per Pitfall 6 (04-01) +- **Down migration drops TABLE before TYPE** — tasks table dropped before task_status type per Pitfall 3; type cannot be dropped while still referenced (04-01) +- **TasksDeps stub in test file** — declared in handlers_tasks_test.go; moved to handlers_tasks.go in Plan 02 to avoid file dependency before handlers exist (04-01) ## Performance Metrics @@ -88,6 +91,7 @@ See: `.planning/PROJECT.md` (updated 2026-05-14) | 03-tablos-crud | 01 | ~15min | 3 | 10 | | 03-tablos-crud | 02 | ~4min | 3 | 8 | | 03-tablos-crud | 03 | ~30min | 3 | 5 | +| 04-tasks-kanban | 01 | ~4min | 3 | 7 | ## Notes @@ -115,6 +119,8 @@ See: `.planning/PROJECT.md` (updated 2026-05-14) - Phase 3 Plan 03 SUMMARY: `.planning/phases/03-tablos-crud/03-03-SUMMARY.md` - Commits (03-03): 6f167e2 (detail/edit/delete templates), ab6937c (handlers + router + all 10 TABLO tests green), b5fa318 (checkpoint approved) - **Phase 3 complete** — All 3 plans done; TABLO-01..06 closed; 10/10 TABLO tests green; full browser verify passed 2026-05-15 +- Phase 4 Plan 01 SUMMARY: `.planning/phases/04-tasks-kanban/04-01-SUMMARY.md` +- Commits (04-01): c9c8262 (migration + sqlc queries), 8b9543d (RED test scaffold + form structs), 55fb32f (Sortable.js + soft-danger CSS) --- -*Last updated: 2026-05-15 after Phase 3 fully complete (Plan 03, Task 3 checkpoint approved)* +*Last updated: 2026-05-15 after Phase 4 Plan 01 complete (Wave 0 foundation)* diff --git a/.planning/phases/04-tasks-kanban/04-01-SUMMARY.md b/.planning/phases/04-tasks-kanban/04-01-SUMMARY.md new file mode 100644 index 0000000..ab0018f --- /dev/null +++ b/.planning/phases/04-tasks-kanban/04-01-SUMMARY.md @@ -0,0 +1,88 @@ +--- +phase: 04-tasks-kanban +plan: "01" +subsystem: backend/tasks +tags: [migration, sqlc, tdd-red, css, sortablejs] +dependency_graph: + requires: [03-tablos-crud/03-03] + provides: [tasks-migration, tasks-sqlc, tasks-test-scaffold, sortablejs-asset, soft-danger-css] + affects: [backend/internal/db/sqlc, backend/migrations, backend/templates, backend/static] +tech_stack: + added: [SortableJS 1.15.7] + patterns: [goose-migration, sqlc-queries, tdd-red-scaffold, css-utility-class] +key_files: + created: + - backend/migrations/0004_tasks.sql + - backend/internal/db/queries/tasks.sql + - backend/templates/tasks_forms.go + - backend/internal/web/handlers_tasks_test.go + - backend/static/sortable.min.js + modified: + - backend/justfile + - backend/internal/web/ui/button.css +decisions: + - "ENUM declaration order matches visual left-to-right column order (todo, in_progress, in_review, done) per Pitfall 6" + - "Down migration drops tasks TABLE before task_status TYPE (Pitfall 3 — type is referenced by column)" + - "All sqlc queries use explicit column lists (no SELECT *)" + - "TasksDeps stub declared in test file — moved to handlers_tasks.go in Plan 02" + - "t.Skip at top of each TestTask* function — all skip without running any DB setup" +metrics: + duration: ~4min + completed: "2026-05-15" + tasks: 3 + files: 7 +--- + +# Phase 4 Plan 01: Tasks Foundation (Wave 0) Summary + +Wave 0 foundation for Tasks (Kanban): DB schema, sqlc query source, RED test scaffold, Sortable.js asset, soft-danger button CSS, and form structs. Nothing user-visible yet — creates preconditions for Plans 02 and 03 to deliver vertical slices. + +## Tasks Completed + +| Task | Name | Commit | Files | +|------|------|--------|-------| +| 1 | Migration 0004_tasks.sql + sqlc queries | c9c8262 | backend/migrations/0004_tasks.sql, backend/internal/db/queries/tasks.sql | +| 2 | RED test scaffold + form structs | 8b9543d | backend/internal/web/handlers_tasks_test.go, backend/templates/tasks_forms.go | +| 3 | Sortable.js bootstrap + soft-danger CSS | 55fb32f | backend/justfile, backend/internal/web/ui/button.css, backend/static/sortable.min.js | + +## Verification Results + +- `just migrate up` applied 0004_tasks.sql cleanly (goose 7.93ms, version 4) +- `just generate` produced TaskStatus type and Task struct in internal/db/sqlc/tasks.sql.go +- `go build ./...` exits 0 +- `go test ./internal/web/ -run TestTask -v` exits 0 with 9 SKIP (TestTasksKanbanRenders, TestTaskCreate, TestTaskCreateValidation, TestTaskUpdate, TestTaskReorderCrossColumn, TestTaskReorderSameColumn, TestTaskDelete, TestTaskOrderPersists, TestTaskOwnership) +- `grep 'ui-button-soft-danger-md' button.css` returns match (3 occurrences — base, hover, focus-visible) +- `ls static/sortable.min.js` succeeds (45,478 bytes at 1.15.7) + +## Decisions Made + +1. **ENUM declaration order** matches visual left-to-right column order (`todo`, `in_progress`, `in_review`, `done`) per RESEARCH Pitfall 6 — ensures ENUM ordinal sorting aligns with kanban column display order. + +2. **Down migration DROP order** — `DROP TABLE IF EXISTS tasks` precedes `DROP TYPE IF EXISTS task_status` per RESEARCH Pitfall 3 — the type cannot be dropped while referenced by a table column. + +3. **TasksDeps stub in test file** — declared in `handlers_tasks_test.go` rather than a separate file so the test file compiles without requiring handlers_tasks.go to exist yet. Plan 02 moves it to handlers_tasks.go. + +4. **t.Skip at top** of each TestTask* function — skips without executing any DB setup, so tests pass cleanly in environments without TEST_DATABASE_URL. + +## Deviations from Plan + +None — plan executed exactly as written. + +## Known Stubs + +None — this plan produces no UI-rendering code; all stubs are test-only t.Skip calls. + +## Threat Flags + +None — this plan adds no network endpoints, auth paths, file access patterns, or schema changes at trust boundaries beyond what is documented in the plan's threat model. + +## Self-Check: PASSED + +- backend/migrations/0004_tasks.sql: FOUND +- backend/internal/db/queries/tasks.sql: FOUND +- backend/templates/tasks_forms.go: FOUND +- backend/internal/web/handlers_tasks_test.go: FOUND +- backend/static/sortable.min.js: FOUND +- backend/justfile (sortable_version): FOUND +- backend/internal/web/ui/button.css (ui-button-soft-danger-md): FOUND +- Commits c9c8262, 8b9543d, 55fb32f: FOUND