13 KiB
| phase | verified | status | score | overrides_applied | human_verification | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 16-tablo-detail | 2026-05-16T23:00:00Z | human_needed | 14/15 must-haves verified | 0 |
|
Phase 16: Tablo Detail Verification Report
Phase Goal: Restyle the tablo detail view — header, task kanban, etapes, and files — using design system components. Verified: 2026-05-16T23:00:00Z Status: human_needed Re-verification: No — initial verification
Goal Achievement
Observable Truths
| # | Truth | Status | Evidence |
|---|---|---|---|
| 1 | Tablo detail header uses project-card-top layout with title, avatar, and action controls | VERIFIED | tablos.templ line 245: <div class="project-card-top"> inside TabloDetailPage; color avatar with tablo.Color.Valid guard; @TabloTitleDisplay inside project-card-title-row; chat/invite/trash action controls on right |
| 2 | Tab nav uses .tab-nav / .tab-nav-item / .tab-nav-item.is-active classes — no hardcoded hex | VERIFIED | tablos.templ lines 327/342/357/372/387: all 5 tabs use conditional class="tab-nav-item is-active" / class="tab-nav-item"; grep -c "#804EEC" tablos.templ returns 0 |
| 3 | Metadata row uses .tablo-metadata-row with created date, Badge status pill, and progress track/bar | VERIFIED | tablos.templ line 304: class="tablo-metadata-row"; line 310: @ui.Badge(BadgeVariantPrimary) "In progress"; lines 311-312: .project-progress-track / .project-progress-bar |
| 4 | Description zone renders inside TabloOverviewTabFragment (not in the persistent header) | VERIFIED | tablos.templ line 421: @TabloDescDisplay(tablo, csrfToken) inside TabloOverviewTabFragment body; no TabloDescDisplay call found above the tab nav |
| 5 | EtapeStrip is not called from TasksTabFragment or tasks.templ | VERIFIED | grep "EtapeStrip" tablos.templ returns 0; grep "EtapeStrip" tasks.templ returns 0 |
| 6 | Task kanban uses tasks-section design: section header with add button, task rows with checkbox and meta | VERIFIED | tasks.templ lines 174-205: .kanban-column > .tasks-section > .tasks-section-header with h3 + badge + @AddTaskTrigger; .task-list sortable-column; TaskCard uses .task-row task-card with .task-check + .task-body + trash IconButton |
| 7 | KanbanBoard and KanbanColumn accept etapes []sqlc.Etape as 5th/6th parameter | VERIFIED | tasks.templ line 173: templ KanbanColumn(tabloID, status, tasks, csrfToken, filter EtapeFilter, etapes []sqlc.Etape); KanbanBoard signature confirmed extended |
| 8 | All three KanbanBoard call sites pass etapes as 5th argument | VERIFIED | handlers_tasks.go lines 594 and 645: KanbanBoard(..., etapes); tablos.templ line 431: @KanbanBoard(..., etapes) |
| 9 | groupTasksByEtape helper groups tasks by etape in declaration order with unassigned last | VERIFIED | tasks.templ line 30: func groupTasksByEtape(tasks []sqlc.Task, etapes []sqlc.Etape) []EtapeGroup; EtapeGroup type at line 21; EtapeGroupHeader at line 73; called in KanbanColumn at line 196 |
| 10 | Files section uses @ui.Table with .overview-section-heading header | VERIFIED | files.templ line 13: class="overview-section-heading"; line 35: @ui.Table(ui.TableProps{Head: fileTableHead(), Body: fileTableBody(...)}) |
| 11 | FileListRow renders as tr.file-row-zone with Download and Delete IconButtons | VERIFIED | files.templ line 104: <tr class="file-row-zone" id={...}> with download IconButton (Icon: "download") at line 119 and trash IconButton for delete |
| 12 | FileDeleteConfirmFragment outer element is tr.file-row-zone with td colspan="4" | VERIFIED | files.templ line 145: <tr class="file-row-zone" id={...}>; line 146: <td colspan="4"> |
| 13 | Empty state uses @ui.EmptyState when no files | VERIFIED | files.templ line 30: @ui.EmptyState(ui.EmptyStateProps{Title: "No files yet", Description: "Upload your first file to get started."}) |
| 14 | All CSS sections 19-25 in app.css use design tokens — no hardcoded hex | VERIFIED | grep -c "#[0-9a-fA-F]{3,6}" app.css returns 0; .tasks-section, .tab-nav-item.is-active (with var(--color-brand-primary)), .kanban-column (width: 18rem), .etape-group-header (background: var(--color-surface-muted)), .task-list-empty (font-style: italic) all confirmed |
| 15 | All existing task, etape, and file handler tests pass unchanged | VERIFIED | go test ./internal/web/... -count=1 exits 0; go build ./... exits 0; 2 test packages pass |
Score: 15/15 truths technically verified
Known Stubs (Intentional — per Plan 02 and UI-SPEC)
These are documented stubs, not gaps. The plans explicitly authorized them as out of scope for Phase 16:
| Stub | Location | Reason |
|---|---|---|
style="width: 0%;" on .project-progress-bar |
tablos.templ line 312 |
Task completion percentage calculation is out of scope for v1 tablo detail header |
Label: "In progress" hardcoded in Badge |
tablos.templ line 310 |
Dynamic status from DB is out of scope for this plan |
| Invite Member button has no action wired | tablos.templ |
Member invitation feature is out of scope for v1 |
EtapeGroup.EtapeColor always "" |
tasks.templ |
sqlc.Etape struct has no Color field in DB schema; color dot will render when field is added |
Required Artifacts
| Artifact | Expected | Status | Details |
|---|---|---|---|
backend/internal/web/ui/icon_button.templ |
download and chat icon cases in UIIcon switch | VERIFIED | Lines 71 and 77: case "download": and case "chat": |
backend/internal/web/ui/app.css |
CSS Sections 19-25 (tasks-section through task-list-empty) | VERIFIED | All 7 sections confirmed; 0 hardcoded hex values |
backend/templates/tablos.templ |
Restyled TabloDetailPage with project-card-top, tab-nav, metadata row | VERIFIED | Lines 245-412: all target patterns present; 0 #804EEC occurrences |
backend/templates/tasks.templ |
groupTasksByEtape, EtapeGroupHeader, restyled KanbanBoard/Column/TaskCard | VERIFIED | All patterns present; 0 EtapeStrip calls |
backend/internal/web/handlers_tasks.go |
Both KanbanBoard call sites pass etapes | VERIFIED | Lines 594 and 645 confirmed |
backend/templates/files.templ |
@ui.Table, @ui.EmptyState, tr-based file rows | VERIFIED | All patterns present |
Key Link Verification
| From | To | Via | Status | Details |
|---|---|---|---|---|
icon_button.templ UIIcon switch |
browser render | case "download": and case "chat": before default |
VERIFIED | Both cases at lines 71, 77; go build ./... exits 0 means generated file is current |
app.css |
browser render | static asset embed | VERIFIED | All 7 new CSS sections present; no hex values |
tablos.templ TabloDetailPage |
app.css .project-card-top |
CSS class on div | VERIFIED | class="project-card-top" at line 245 |
tablos.templ TabloOverviewTabFragment |
TabloDescDisplay |
@TabloDescDisplay(tablo, csrfToken) call inside overview tab |
VERIFIED | Line 421 inside TabloOverviewTabFragment |
tablos.templ TasksTabFragment |
tasks.templ KanbanBoard |
@KanbanBoard(tablo.ID, csrfToken, tasks, filter, etapes) |
VERIFIED | Line 431 |
tasks.templ groupTasksByEtape |
tasks.templ KanbanColumn |
groups := groupTasksByEtape(tasks, etapes) |
VERIFIED | Line 196 inside KanbanColumn body |
handlers_tasks.go |
tasks.templ KanbanBoard |
KanbanBoard(..., etapes) at both handler call sites |
VERIFIED | Lines 594, 645 confirmed |
files.templ FileListRow |
files.templ FileDeleteConfirmFragment |
hx-target="closest .file-row-zone" / both are <tr> |
VERIFIED | Both use <tr class="file-row-zone"> — outerHTML swap is type-safe |
files.templ FilesTabFragment |
backend/internal/web/ui/table.templ @ui.Table |
@ui.Table(ui.TableProps{Head: fileTableHead(), Body: fileTableBody(...)}) |
VERIFIED | Line 35 |
Requirements Coverage
| Requirement | Source Plan | Description | Status | Evidence |
|---|---|---|---|---|
| DETAIL-01 | 16-02 | Tablo detail header area matches the project-card-top design | SATISFIED | project-card-top layout, avatar, tab-nav with token classes, desc in overview tab — all verified in tablos.templ |
| DETAIL-02 | 16-03 | Task kanban board uses the tasks-section design | SATISFIED | .kanban-column > .tasks-section > .tasks-section-header + .task-list + .task-row task-card in tasks.templ |
| DETAIL-03 | 16-03 | Etapes section is visually consistent with the task section | SATISFIED | groupTasksByEtape helper + EtapeGroupHeader component in tasks.templ; EtapeStrip removed from all call sites; tasks grouped by etape in column |
| DETAIL-04 | 16-04 | Files section uses the table component | SATISFIED | @ui.Table + @ui.EmptyState + <tr class="file-row-zone"> rows with Download/Delete IconButtons in files.templ |
Anti-Patterns Found
| File | Line | Pattern | Severity | Impact |
|---|---|---|---|---|
tasks.templ |
458, 467 | TODO: remove etapes and counts params after Phase 16 cleanup |
WARNING | Unreferenced TODO (no issue/PR number), but the retention was explicitly planned in 16-03 Plan Task 1 as a safe default to avoid handler signature changes. These params are kept intentionally. Not a functional blocker. |
Note on TODOs: The two TODO markers in tasks.templ (lines 458, 467) are in TaskCardGone and TaskCardOOB. The plan explicitly instructed: "Add // TODO: remove etapes and counts params after Phase 16 cleanup comment." They indicate cleanup work deferred to after Phase 16, but lack a formal issue reference. Classified as WARNING (not blocker) because: (1) the retention is intentional and functionally correct — the parameters are kept to avoid breaking handler signatures; (2) the TODO references the current phase cleanup as context; (3) they do not prevent any goal truth from being true.
Human Verification Required
1. Browser checkpoint for Phase 16 visual result
Test: Start the dev server (cd backend && just dev or air). Navigate to a tablo detail page (e.g., http://localhost:3000/tablos/{some-id}). Walk through the 24 visual and interaction items from Plan 04's checkpoint task:
- Header (DETAIL-01): Colored circle avatar with first letter of tablo title; inline-editable title; Discussion/Invite/Delete action controls; no visible hardcoded purple hex artifacts
- Metadata row: Created date with calendar icon; "In progress" badge; progress bar track
- Tab nav: 5 tabs in horizontal row; active tab has purple underline + bold; inactive tabs muted; clicking loads content via HTMX
- Overview tab: Description zone appears inside the tab (not above tab nav); click-to-edit works
- Tasks tab (DETAIL-02 + DETAIL-03): 3 kanban columns side by side; section header with status label + badge + "Add task" button; task rows with round checkbox + title + trash icon; if etapes defined, tasks grouped by etape with colored dot sub-heading; no EtapeStrip filter pills; drag-and-drop between columns works
- Files tab (DETAIL-04): "Files" heading + "Upload file" button; clicking Upload reveals form inline; file rows in table (Filename / Size / Uploaded / Actions); download and trash icons per row; trash click → delete confirm replaces row; empty state "No files yet" when no files
Expected: All 24 items pass.
Why human: The Plan 04 blocking checkpoint was marked "auto-approved (AUTO mode active)" in the SUMMARY — it was not approved by an actual human. This is a checkpoint:human-verify gate task that the plan designated as gate="blocking". Visual layout, icon rendering, HTMX swap behavior, drag-and-drop continuity, and the confirm/cancel flow cannot be verified programmatically.
Gaps Summary
No functional gaps found. All 15 must-have truths are verified in the codebase. The phase is blocked on human verification only — the browser checkpoint was auto-approved by the agent rather than reviewed by a human developer.
Verified: 2026-05-16T23:00:00Z Verifier: Claude (gsd-verifier)