diff --git a/.planning/phases/17-chat-planning/17-01-PLAN.md b/.planning/phases/17-chat-planning/17-01-PLAN.md index 72331cf..2cfa06a 100644 --- a/.planning/phases/17-chat-planning/17-01-PLAN.md +++ b/.planning/phases/17-chat-planning/17-01-PLAN.md @@ -51,6 +51,23 @@ Purpose: CHAT-UI-01 requires a card/surface design with visually differentiated Output: discussion_view.go (view model), discussion_view_test.go (render tests), CSS additions to app.css, ChatMainContent() replacement in dashboard_components.templ, handler call-site update in auth.go. + +## Deferred Decisions — D-D01, D-D02, D-D03, D-D04 (User-Authoritative) + +Phase 17 is a **restyle-only** phase. The following decisions from CONTEXT.md are explicitly deferred to a future phase when the real chat backend is built: + +- **D-D01** — `DiscussionMessageView` gaining `IsOwn bool` set via `DiscussionMessagesFromRows(rows, currentUserID)`: deferred. The go-backend/ codebase does not yet have `DiscussionMessagesFromRows`. `IsOwn` is present as a plain field on `DiscussionMessageView` (used for demo rendering only) — no `currentUserID` threading required in this phase. +- **D-D02** — `loadDiscussionTabData` receiving `currentUserID` and passing it to `DiscussionMessagesFromRows`: deferred. go-backend/ has no `loadDiscussionTabData` function or equivalent yet. +- **D-D03** — HTMX POST path setting `IsOwn = true` vs. SSE broadcast setting `IsOwn = false`: deferred. go-backend/ has no SSE handler or HTMX POST route for message creation yet. +- **D-D04** — `DiscussionMessageFromRow` struct-mutation approach for the SSE/HTMX paths: deferred. There is no `DiscussionMessageFromRow` function in go-backend/ yet. + +**SPEC Req 2** (SSE path `IsOwn` via `DiscussionMessageFromRow`) is similarly deferred — it depends on the same missing backend infrastructure. + +**What IS correct for this phase:** `NewDiscussionTabData()` returns hardcoded demo data with alternating `IsOwn` values. This is intentional. The demo data drives visual verification of the CSS bubble classes without requiring a real data layer. + +Executors: do not attempt to implement D-D01 through D-D04 in this phase. Implement only what is described in the tasks below. + + @/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 diff --git a/.planning/phases/17-chat-planning/17-02-PLAN.md b/.planning/phases/17-chat-planning/17-02-PLAN.md index f346d99..f6674f2 100644 --- a/.planning/phases/17-chat-planning/17-02-PLAN.md +++ b/.planning/phases/17-chat-planning/17-02-PLAN.md @@ -138,7 +138,7 @@ From go-backend/internal/web/views/tablos.templ (EmptyState usage pattern): - Logic test: PlanningShowDaySeparator(events, 2) returns true when events[2].DateLabel != events[1].DateLabel - Render test: renderViewToString(PlanningMainContent(data)) with 3 events spanning 2 dates → HTML contains "overview-section" - Render test: same render → HTML contains "overview-section-heading" - - Render test: same render → HTML contains "bg-slate-50" (day separator element) + - Render test: same render → HTML contains attribute data-day-separator (day separator element — see action note on separator markup) - Note: These tests will fail (RED) until PlanningMainContent is replaced in Task 2 @@ -166,10 +166,12 @@ From go-backend/internal/web/views/tablos.templ (EmptyState usage pattern): return events[index].DateLabel != events[index-1].DateLabel No imports needed — all fields are plain string and bool. + Note on file location (D-P02 path adaptation): D-P02 in CONTEXT.md names `planning_forms.go` as the target for PlanningShowDaySeparator. That file does not exist in go-backend/. The go-backend/ equivalent is `planning_view.go` — this is a path adaptation, not a decision override. PlanningShowDaySeparator lives in planning_view.go as specified above. + Step 3 — Create go-backend/internal/web/views/planning_view_test.go with package views: Import bytes, context, strings, testing. Do NOT redeclare renderViewToString. Write TestPlanningShowDaySeparator covering 3 cases (index 0 = always true, same date = false, date change = true). Use a table-driven test with t.Run subtests. - Write TestPlanningMainContentRendersOverviewSection: construct PlanningTabData with 3 events spanning 2 dates, call renderViewToString(PlanningMainContent(data)), assert all three strings present: "overview-section", "overview-section-heading", "bg-slate-50". Use t.Fatalf with the missing-string pattern (see PATTERNS.md render assertion template). + Write TestPlanningMainContentRendersOverviewSection: construct PlanningTabData with 3 events spanning 2 dates, call renderViewToString(PlanningMainContent(data)), assert all three strings present: "overview-section", "overview-section-heading", "data-day-separator". Use t.Fatalf with the missing-string pattern (see PATTERNS.md render assertion template). The TestPlanningMainContentRendersOverviewSection test will compile-fail or test-fail (RED) until PlanningMainContent is updated in Task 2. TestPlanningShowDaySeparator is pure logic and must go GREEN immediately. @@ -185,6 +187,7 @@ From go-backend/internal/web/views/tablos.templ (EmptyState usage pattern): - planning_view_test.go does NOT declare renderViewToString (grep for "func renderViewToString" in planning_view_test.go returns 0 matches) - `go test ./internal/web/views/ -run TestPlanningShowDaySeparator -count=1` exits 0 with output "PASS" — logic tests are GREEN immediately - `go test ./internal/web/views/ -run TestPlanningMainContentRendersOverviewSection -count=1` exits non-zero (RED — PlanningMainContent still has old stub signature) + - The day separator div in the templ component includes the attribute data-day-separator="true" so that the render test can assert its presence without coupling to a Tailwind class name CSS selector extended; view model + helper created; logic tests GREEN; render test written and RED (expected) @@ -233,7 +236,7 @@ From go-backend/internal/web/views/tablos.templ (EmptyState usage pattern): If events exist: render a