xtablo-source/.planning/phases/15-dashboard-tablos/15-01-PLAN.md
Arthur Belleville 8baf8a430f
docs(15): create phase plan — sidebar + project-card dashboard
3 plans across 3 waves:
- 15-01 (Wave 0): RED test stubs for DASH-01/02/03
- 15-02 (Wave 1): app.css CSS foundation + AppLayout templ component
- 15-03 (Wave 2): tablos.templ restyled + handler wiring + visual checkpoint

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 21:28:25 +02:00

7.4 KiB

phase plan type wave depends_on files_modified autonomous requirements must_haves
15-dashboard-tablos 01 execute 0
backend/internal/web/handlers_tablos_test.go
true
DASH-01
DASH-02
DASH-03
truths artifacts key_links
TestTablosDashboard_Sidebar fails RED until AppLayout is implemented
TestTablosDashboard_ProjectCards fails RED until project-card template is implemented
TestTablosDashboard_EmptyState fails RED until empty state is wired to ui.EmptyState
path provides contains
backend/internal/web/handlers_tablos_test.go Wave 0 test stubs for DASH-01/02/03 TestTablosDashboard_Sidebar
from to via pattern
TestTablosDashboard_Sidebar GET / handler response body httptest.ResponseRecorder strings.Contains.*dashboard-sidebar

Phase Goal

As a signed-in user, I want to see a sidebar-based dashboard with project cards for my tablos, so that the app matches the go-backend visual design and I can navigate my work efficiently.

Create failing integration test stubs for DASH-01, DASH-02, and DASH-03 in the existing handlers_tablos_test.go file. These tests define the acceptance target for Plans 02 and 03 — they MUST fail (RED) when this plan is complete.

Purpose: Nyquist compliance requires automated tests for every requirement ID before implementation begins. Wave 0 plants the tests that Plans 02 and 03 will turn green.

Output: Three new test functions added to handlers_tablos_test.go, all failing at runtime until the AppLayout and project-card templates are implemented.

<execution_context> @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.claude/get-shit-done/workflows/execute-plan.md @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.claude/get-shit-done/templates/summary.md </execution_context>

@/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.planning/ROADMAP.md @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.planning/phases/15-dashboard-tablos/15-VALIDATION.md Task 1: Add Wave 0 RED test stubs for DASH-01, DASH-02, DASH-03 backend/internal/web/handlers_tablos_test.go

<read_first> - backend/internal/web/handlers_tablos_test.go — read the full file to understand: package name, existing test helper signatures (loginUser, newTabloTestRouter, getCSRFToken), how existing tests issue GET / and check response body via strings.Contains, and how tablos are pre-inserted (look for helper that inserts a tablo row). - backend/internal/web/handlers_auth_test.go — read to understand setupTestDB, preInsertUser, and the newTestRouter pattern used across test files. </read_first>

- TestTablosDashboard_Sidebar: authenticated GET / must contain "dashboard-sidebar" in the response body. Fails RED until AppLayout renders the sidebar. - TestTablosDashboard_ProjectCards: authenticated GET / with at least one pre-inserted tablo must contain "project-card" in the response body. Fails RED until TabloProjectCard is implemented. - TestTablosDashboard_EmptyState: authenticated GET / with zero tablos must contain "ui-empty-state" in the response body. Fails RED until TablosEmptyState uses @ui.EmptyState. Append three new test functions at the end of handlers_tablos_test.go. Each follows the exact same httptest pattern already used by the file's existing tests: call loginUser to get session cookies, issue GET / with those cookies, check rec.Code == 200, call strings.Contains on rec.Body.String() for the target string.
TestTablosDashboard_Sidebar: after login (no tablo pre-insert needed), GET /, assert strings.Contains(body, "dashboard-sidebar"). The test should also assert strings.Contains(body, "sidebar-nav-shell") as a secondary structural check.

TestTablosDashboard_ProjectCards: pre-insert one tablo for the user (use whatever helper function the file already uses for tablo insertion, or insert directly via deps.Queries.CreateTablo if available), then GET /, assert strings.Contains(body, "project-card"). If no tablo-insert helper exists yet, use a direct sqlc query call matching the CreateTablo pattern visible elsewhere in the test file.

TestTablosDashboard_EmptyState: after login with zero tablos, GET /, assert strings.Contains(body, "ui-empty-state").

All three functions must be inside a TEST_DATABASE_URL guard (same pattern used by the existing integration tests in the file — check how they skip when no DB is configured). Follow the package-level skip pattern exactly as seen in handlers_tablos_test.go.

Do NOT implement: any template changes, any CSS, any handler changes. This task is test-only.
cd /Users/arthur.belleville/Documents/perso/projects/xtablo-source/backend && go build ./internal/web/... 2>&1

<acceptance_criteria> - handlers_tablos_test.go compiles without error: go build ./internal/web/... exits 0 - File contains func TestTablosDashboard_Sidebar: grep -c "func TestTablosDashboard_Sidebar" backend/internal/web/handlers_tablos_test.go returns 1 - File contains func TestTablosDashboard_ProjectCards: grep -c "func TestTablosDashboard_ProjectCards" backend/internal/web/handlers_tablos_test.go returns 1 - File contains func TestTablosDashboard_EmptyState: grep -c "func TestTablosDashboard_EmptyState" backend/internal/web/handlers_tablos_test.go returns 1 - Each test asserts "dashboard-sidebar", "project-card", and "ui-empty-state" respectively via strings.Contains - Without TEST_DATABASE_URL set, go test ./internal/web/... -run "TestTablosDashboard_Sidebar|TestTablosDashboard_ProjectCards|TestTablosDashboard_EmptyState" -count=1 exits 0 (tests skip rather than fail) - The existing TestTablos* tests still pass: go test ./internal/web/... -run TestTablos -count=1 exits 0 (skips count as pass when no DB configured) </acceptance_criteria>

Three test stubs exist, compile cleanly, and skip when TEST_DATABASE_URL is absent. They will turn RED when a DB is wired and AppLayout is not yet implemented — that is the expected Wave 0 state.

<threat_model>

Trust Boundaries

Boundary Description
test harness → handler httptest requests carry session cookies issued by the test login helper

STRIDE Threat Register

Threat ID Category Component Disposition Mitigation Plan
T-15-01-01 Information Disclosure test DB accept Tests skip without TEST_DATABASE_URL; no production secrets in test code
</threat_model>
`cd /Users/arthur.belleville/Documents/perso/projects/xtablo-source/backend && go build ./internal/web/... && go test ./internal/web/... -run TestTablos -count=1`

All existing Tablos tests pass (skip without DB). Three new stubs compile and skip without DB.

<success_criteria>

  • handlers_tablos_test.go contains TestTablosDashboard_Sidebar, TestTablosDashboard_ProjectCards, TestTablosDashboard_EmptyState
  • go build ./internal/web/... exits 0
  • No existing tests broken </success_criteria>
After completion, create `.planning/phases/15-dashboard-tablos/15-01-SUMMARY.md`