xtablo-source/.planning/phases/04-tasks-kanban/04-02-SUMMARY.md
Arthur Belleville 5158eb09af
docs(04-02): complete kanban vertical slice plan — handlers, templates, test activation
- Add 04-02-SUMMARY.md with full decisions and deviation documentation
- Update STATE.md: Plans 01-02 done, add decisions, metrics, notes
- Update ROADMAP.md phase 4 progress (2/4 plans complete)
2026-05-15 09:35:03 +02:00

6.7 KiB

phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
04-tasks-kanban 02 backend/tasks
kanban
htmx
handlers
templ
tdd-green
requires provides affects
04-tasks-kanban/04-01
kanban-board-ui
task-create
task-delete
task-handlers
task-routes
backend/internal/web
backend/templates
backend/cmd/web
added patterns
htmx-oob-swap
chi-route-ordering
templ-components
ownership-guard
created modified
backend/internal/web/handlers_tasks.go
backend/templates/tasks.templ
backend/internal/web/router.go
backend/cmd/web/main.go
backend/templates/tablos.templ
backend/templates/layout.templ
backend/templates/tasks_forms.go
backend/internal/web/handlers_tablos.go
backend/internal/web/handlers_tasks_test.go
backend/internal/web/handlers_test.go
backend/internal/web/handlers_tablos_test.go
backend/internal/web/handlers_auth_test.go
backend/internal/web/csrf_test.go
TaskColumns/TaskColumnLabels moved to templates package to avoid web↔templates import cycle
TabloDetailPage updated to accept tasks []sqlc.Task; handlers_tablos.go fetches tasks via ListTasksByTablo before rendering
Non-HTMX validation error in TabloUpdateHandler also fetches tasks for kanban board rendering
AddTaskTrigger and TaskCard use raw CSS class string for soft-danger button (not ui.Button) per plan spec
Column labels match tasks_forms.go TaskColumnLabels; test scaffold updated from incorrect capitalization
duration completed tasks files
~20min 2026-05-15 3 12

Phase 4 Plan 02: Kanban Board Vertical Slice (Wave 1) Summary

Vertical slice 1 of the kanban workflow: renders the kanban board on tablo detail page with 4 columns, implements task creation via inline column form with HTMX, and task deletion with inline confirmation. Users can now open a tablo, see 4 columns (To do, In progress, In review, Done), create tasks, and delete them.

Tasks Completed

Task Name Commit Files
1 handlers_tasks.go + router + main.go 181ae79 backend/internal/web/handlers_tasks.go, router.go, main.go, 5 test files
2 tasks.templ + tablos.templ + layout.templ 889164b backend/templates/tasks.templ, tablos.templ, layout.templ, tasks_forms.go, handlers_tablos.go
3 Activate task integration tests 92ebb5f backend/internal/web/handlers_tasks_test.go

Verification Results

  • go build ./... exits 0
  • go test ./... exits 0 (all tests pass or skip correctly)
  • go test ./internal/web/ -run TestTask -v: 9 SKIP total — 5 skip due to no TEST_DATABASE_URL (activated, awaiting DB), 4 skip with "handlers_tasks not yet implemented" (Plan 03)
  • grep -c 'KanbanBoard' templates/tasks.templ returns 2
  • grep -c 'TaskCreateHandler' internal/web/router.go returns 1
  • grep -c 'sortable.min.js' templates/layout.templ returns 1

Decisions Made

  1. TaskColumns/TaskColumnLabels moved to templates packagehandlers_tasks.go imports templates, and tasks.templ needs the column definitions. Putting them in web package would create a cycle (templatesweb → ... → templates). Moving to templates/tasks_forms.go breaks the cycle cleanly.

  2. TabloDetailPage signature updated — Added tasks []sqlc.Task parameter. All callers updated: TabloDetailHandler fetches tasks via ListTasksByTablo; TabloUpdateHandler non-HTMX error path also fetches tasks for correct rendering.

  3. Task column header strings corrected — The Plan 01 test scaffold used "Todo", "In Progress", "In Review" which didn't match the plan spec "To do", "In progress", "In review". Updated test to use correct labels from TaskColumnLabels.

  4. Integration tests skip on missing TEST_DATABASE_URL — Tests are activated (no t.Skip), but the test helper setupTestDB skips when no database is configured. This is the correct behavior per the existing test pattern.

Deviations from Plan

Auto-fixed Issues

1. [Rule 2 - Import cycle prevention] TaskColumns/TaskColumnLabels moved from web to templates package

  • Found during: Task 2 (templ generation, go build cycle check)
  • Issue: tasks.templ needs web.TaskColumns and web.TaskColumnLabels. But templates package imports web/ui (not web), and web imports templates — adding web as a direct import to templates would create web → templates → web cycle.
  • Fix: Moved TaskColumns and TaskColumnLabels to backend/templates/tasks_forms.go. Handlers reference templates.TaskColumns via the already-existing templates import. No structural change — just a different home for the constants.
  • Files modified: backend/templates/tasks_forms.go, backend/internal/web/handlers_tasks.go
  • Commit: 181ae79

2. [Rule 1 - Bug] Column header test strings corrected

  • Found during: Task 3 (activating tests)
  • Issue: Plan 01 scaffold used "Todo", "In Progress", "In Review" but TaskColumnLabels defines "To do", "In progress", "In review".
  • Fix: Updated TestTasksKanbanRenders to use the correct label strings.
  • Files modified: backend/internal/web/handlers_tasks_test.go
  • Commit: 92ebb5f

3. [Rule 3 - Router update] All NewRouter call sites updated

  • Found during: Task 1 (adding TasksDeps param to NewRouter)
  • Issue: 5 test helper functions across 4 test files called NewRouter without TasksDeps.
  • Fix: Updated all callers: handlers_test.go, handlers_tablos_test.go, handlers_auth_test.go, csrf_test.go.
  • Files modified: 4 test files
  • Commit: 181ae79

Known Stubs

  • TaskEditHandler returns 501 — Plan 03 implements task editing
  • TaskUpdateHandler returns 501 — Plan 03 implements task update
  • TaskReorderHandler returns 501 — Plan 03 implements drag-and-drop reorder

These stubs are intentional per the plan spec; routes are registered so route resolution tests work.

Threat Flags

None — all threat mitigations from the plan's threat register are implemented:

  • T-04-03: loadOwnedTabloForTask uses GetTaskByID(WHERE id=$1 AND tablo_id=$2) with ownership-verified tablo_id
  • T-04-04: title validated non-empty, max 255 chars
  • T-04-05: status validated against validTaskStatuses map before DB insert
  • T-04-07: TabloDetailPage only renders after loadOwnedTablo passes ownership check

Self-Check: PASSED

  • backend/internal/web/handlers_tasks.go: FOUND
  • backend/templates/tasks.templ: FOUND
  • backend/internal/web/router.go (TaskCreateHandler): FOUND
  • backend/templates/layout.templ (sortable.min.js): FOUND
  • backend/templates/tablos.templ (tasks param): FOUND
  • Commits 181ae79, 889164b, 92ebb5f: FOUND