go-htmx-gsd #1

Merged
arthur merged 558 commits from go-htmx-gsd into main 2026-05-23 15:16:44 +00:00

558 commits

Author SHA1 Message Date
Arthur Belleville
eaaec7a89d
style(planning): implement Month/Week/Day calendar views from sketch 005
Some checks are pending
xtablo-ci / Checks (pull_request) Waiting to run
go-backend-ci / Check go-backend (pull_request) Waiting to run
- Replace 14-day agenda list with three-view calendar (month/week/day)
- Add PlanningCalendar, CalendarDay, CalendarTimeEvent, MiniCalDay data structs
- Add BuildMonthCalendar, BuildWeekCalendar, BuildDayCalendar builder helpers
- Add MondayOf, PlanningMonthURL, PlanningWeekURL, PlanningDayURL URL helpers
- Handler now parses ?view=month|week|day with matching date params
- Month view: 7-col grid with event chips using tablo color via color-mix()
- Week/Day view: split layout with mini-month panel and hour timeline (07-20)
- Timeline events positioned via TopPx/HeightPx from start_time microseconds
- Append all calendar CSS to app.css (view-toggle, cal-grid, tl-* classes)
2026-05-18 16:56:44 +02:00
Arthur Belleville
63e7d65290
feat(phase-20): port tablo detail restyle to backend/
Phase 20 work was executed against go-backend/ (prototype) instead of
backend/ (production). This commit ports the Figma-aligned restyle to
the correct codebase.

Changes:
- tablos.templ: replace project-card-top header with tablo-detail-header,
  tablo-detail-avatar, tablo-detail-title; update tab bar to tablo-tab-bar;
  localise tab labels to French (Vue d'ensemble, Tâches, Fichiers,
  Discussion, Événements)
- tasks.templ: update KanbanBoard to tablo-kanban-board; KanbanColumn to
  tablo-kanban-column with new header/count/empty classes; TaskCard to
  card-style layout (task-card-top-row, task-card-title, task-card-delete)
- app.css: add sections 25–27 — tablo detail page, kanban board/columns,
  and task card (card appearance, hover states)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 16:31:05 +02:00
Arthur Belleville
efa9a85dd7
test(20): UAT diagnosed — Phase 20 work in wrong directory (go-backend vs backend) 2026-05-18 16:18:51 +02:00
Arthur Belleville
35a8a5051e
docs(phase-20): complete phase execution 2026-05-18 16:04:22 +02:00
Arthur Belleville
2e670b0346
test(20): persist human verification items as UAT 2026-05-18 16:04:09 +02:00
Arthur Belleville
efc8dc4c01
docs(20): add code review report 2026-05-18 16:00:57 +02:00
Arthur Belleville
77b9f8473b
docs(phase-20): update tracking after wave 2 2026-05-18 15:56:01 +02:00
Arthur Belleville
8970b91994
docs(20-03): complete tablo detail CSS restyle plan summary 2026-05-18 15:55:16 +02:00
Arthur Belleville
910c3b605d
feat(20-03): kanban board, task card, etapes section, files table CSS + task-list gap
- .tablo-kanban-board flex container with overflow-x auto
- .tablo-kanban-column 18rem wide with border-radius 0.75rem
- .tablo-kanban-column-header muted surface background
- .tablo-kanban-column-title, -task-count, -add-link, -empty rules
- .task-card column-flex with hover shadow and border-color transition
- .task-drag-handle opacity 0 at rest, opacity 1 on .task-card:hover
- .task-card-delete opacity 0 at rest, opacity 1 on .task-card:hover
- .task-card-top-row, .task-card-title helpers
- .task-list updated with gap 8px and padding 8px
- .tablo-etapes-section, .tablo-etape-row, .tablo-etape-name, .tablo-etape-count
- .tablo-files-table-wrapper with border-radius 12px and table header styles
- .task-row and .tasks-section unchanged (no CSS cascade regression)
2026-05-18 15:54:30 +02:00
Arthur Belleville
58710d6eba
feat(20-03): tablo detail header, metadata row, and tab bar CSS
- .tablo-detail-page outer container with 24px 32px padding
- .tablo-detail-header flex column with border-bottom
- .tablo-detail-title-row flex row for avatar + h1
- .tablo-detail-avatar 48x48 colored circle with border-radius 12px
- .tablo-detail-title at 1.75rem weight 600
- .tablo-metadata-row horizontal flex with gap 24px
- .tablo-meta-segment and .tablo-meta-progress helper rules
- .tablo-progress-bar with background var(--color-brand-primary) — NOT project-color
- .tablo-tab-bar and .tablo-tab-bar .tab-nav-item override
2026-05-18 15:53:51 +02:00
Arthur Belleville
b05f280089
docs(20-02): complete tablo detail templ components plan summary
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 15:52:04 +02:00
Arthur Belleville
a60de1fc7a
feat(20-02): replace TabloDetailPage stub with templ component + register tab route
- Remove stub templ.ComponentFunc from tablo_detail_view.go; real TabloDetailPage now comes from tablo_detail_templ.go
- Remove context/io/templ imports that were only used by the stub
- Register GET /tablos/{tabloID}/{tab} route in router.go after /tablos/{tabloID}
- All handler tests pass: TestGetTabloDetailPage_*, TestTabloDetailKanbanColumns, TestComputeTabloProgress, TestNewTabloDetailViewModel_*
2026-05-18 15:51:23 +02:00
Arthur Belleville
4ae19faac9
feat(20-02): TabloDetailPage templ component + GetTabloDetailTab handler
- Create tablo_detail.templ with 8 templ components: TabloDetailPage, TabloDetailHeader, TabloDetailTabBar, TabloDetailKanbanBoard, TabloDetailKanbanColumn, TabloDetailTaskCard, TabloDetailEtapesSection, TabloDetailSortableScript
- Tab links use hx-get + hx-target="#tab-content" + hx-push-url="true" per UI-SPEC interaction contract
- Each kanban column has hidden reorder form id="reorder-form-{status}" for Sortable.js onEnd
- Create tablo_detail_tab.go with GetTabloDetailTab handler for HTMX tab content swaps
- Tasks tab returns kanban board fragment; other tabs return "coming soon" placeholder
2026-05-18 15:51:17 +02:00
Arthur Belleville
27326f57d6
docs(20-01): complete tablo detail handler + view model plan summary
- TabloDetailViewModel, TabloDetailColumnView, TabloDetailEtapeView exported
- computeTabloProgress excludes etape tasks
- GetTabloDetailPage handler with IDOR mitigation
- GET /tablos/{tabloID} route registered
- Full test suite green (13 packages)
2026-05-18 15:47:28 +02:00
Arthur Belleville
3fc8aae7a0
feat(20-01): GetTabloDetailPage handler + GET /tablos/{tabloID} route registration
- tabloDetailRepository interface with ListTasksByTablo
- GetTabloDetailPage: auth check, UUID parse, ownership-scoped tablo lookup, task fetch, vm build, render
- router.go: mux.Get('/tablos/{tabloID}') registered before /edit route
- activePath='/tablos' so sidebar Tablos item stays highlighted
- Threat T-20-01 mitigated: findTabloByID filters by OwnerID from session
2026-05-18 15:46:30 +02:00
Arthur Belleville
9713cbd168
feat(20-01): add TabloDetailViewModel + computeTabloProgress + TabloDetailPage stub
- TabloDetailViewModel with Columns, Etapes, Progress fields
- TabloDetailColumnView, TabloDetailTaskView, TabloDetailEtapeView structs
- computeTabloProgress excludes etape tasks from computation
- NewTabloDetailViewModel builds 4 columns + etapes with child task counts
- TabloDetailPage stub emits tablo name + column status IDs + initTabloDetailSortable
2026-05-18 15:45:30 +02:00
Arthur Belleville
f24e1c4d35
test(20-01): add failing tests for TabloDetailViewModel + GetTabloDetailPage handler
- TestComputeTabloProgress_{Empty,AllDone,Half,EtapesIgnored}
- TestNewTabloDetailViewModel_{GroupsTasksByStatus,EtapesExcludedFromColumns,EtapesPopulated}
- TestGetTabloDetailPage_{Returns200,Returns404,Returns400,Unauthenticated}
- TestTabloDetailKanbanColumns
- TestGetTabloDetailPage_ContainsSortableScript
2026-05-18 15:44:53 +02:00
Arthur Belleville
20e0a02edc
docs(20): create phase 20 plan — tablo detail page + kanban restyle
3 plans in 2 waves: handler+viewmodel (wave 1), templ components + CSS
restyle in parallel (wave 2). Covers DETAIL-01 and TASK-01.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 15:29:41 +02:00
Arthur Belleville
e18bf66dbf
docs(20): research phase — tablo detail page + kanban restyle
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 15:21:53 +02:00
Arthur Belleville
e37b8c5855
docs(20): UI design contract 2026-05-18 15:16:38 +02:00
Arthur Belleville
9312a65ed9
docs(20): UI design contract for tablo detail & kanban restyle
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 15:08:48 +02:00
Arthur Belleville
4fdcc32ebe
fix(19): increase tablo card vertical spacing gap-3 → gap-5
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:36:19 +02:00
Arthur Belleville
53ea451d1c
fix(19): use pure Tailwind for grid progress bar — remove custom CSS classes causing empty bar
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:34:59 +02:00
Arthur Belleville
6b73c78d9d
fix(19): update stale dashboard tests — new view/filter/status class names
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:29:06 +02:00
Arthur Belleville
a575ab93c6
feat(19): list view as proper table — Projet/Statut/Créé le/Progression/Actions
- Two separate containers: #tablos-grid (card grid) and #tablos-table (table), toggled via .hidden
- TabloListRow: new templ for <tr> with icon+title, Actif/Archivé badge, date, progress bar, trash
- JS: setTablosView toggles hidden on both containers; filterTablos targets both article and tr elements
- Remove old .tablo-list-row / #tablos-list[data-view] CSS (no longer needed)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:24:45 +02:00
Arthur Belleville
90d43f98bc
fix(19): move edit+trash to same line as status pill
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:21:49 +02:00
Arthur Belleville
7864c39872
feat(19): tablo card — icon+title+status pill, date, progress, edit+trash
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:20:53 +02:00
Arthur Belleville
af8b4fa38f
fix(19): status badge and edit/trash on same line
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:18:52 +02:00
Arthur Belleville
f506ceeda6
feat(19): restructure tablo card — icon+title, status badge, edit+trash
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:18:05 +02:00
Arthur Belleville
6b0b4be670
fix(19): filter tabs use DB status (all/active/archived)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:13:54 +02:00
Arthur Belleville
3a864aa84e
feat(19): revamp tablos page — filter tabs, view toggle, card click nav
- Dashboard: French header "Mes Projets", underline-tab view toggle (grid/list), filter tabs (Tous/Pas commencé/En cours/Terminé) with JS client-side filtering
- Cards: display status derived from progress (À faire/En cours/Terminé), rounded-xl p-6, w-8 h-8 avatar, green-500 progress bar, dashed "Créé le" footer
- Click on card/row navigates to /tablos/{uuid} via event delegation (delete zone stops propagation)
- List view: single-column grid, rows show status + title + date + task count
- CSS: .view-tab and .filter-tab with .is-active state

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:11:31 +02:00
Arthur Belleville
e699129064
feat(19): show 'X/Y completed tasks' label on tablo cards
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 17:01:45 +02:00
Arthur Belleville
7388418aed
feat(19): restyle tablo cards to production design with X/Y task count
- TabloCardView gains DoneTasks/TotalTasks int fields; handler stores raw counts alongside Progress %
- TabloProjectCard: rounded-2xl card, border-[#EAECF0], purple-50 status badge, colored avatar initial (12x12 rounded-xl), calendar date row, Progression label + X/Y task count + purple-500 progress bar
- List row: matching pill badge + X/Y count
- All 7 TestTablosDashboard_* tests pass

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 17:00:51 +02:00
Arthur Belleville
2a835f52e9
docs(19-03): complete tablo list revamp plan 03 — toggle button and tests
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 16:34:09 +02:00
Arthur Belleville
161437828e
test(19-03): add LIST-01/02/03 test coverage for dashboard
- TestTablosDashboard_ProgressBar: asserts "Progression:" label and project-card-progress-row class
- TestTablosDashboard_ViewToggle: asserts view-toggle-btn class and data-view="grid" attribute
- TestTablosDashboard_StatusBadge: asserts "Active" badge and tablo-list-row dual-element structure
- All tests use unique email addresses; go build ./... exits 0
2026-05-17 16:33:36 +02:00
Arthur Belleville
3deb4f9595
feat(19-03): add view toggle button to TablosDashboard
- Add plain <button class="view-toggle-btn"> with inline SVG list icon and onclick JS
- data-view="grid" static attribute added to #tablos-list container
- .view-toggle-btn CSS block added to app.css (Section 20c)
- Tailwind CSS rebuilt to include view-toggle-btn class
- templ generate + go build exit 0
2026-05-17 16:33:02 +02:00
Arthur Belleville
4a0b42052d
docs(19-02): complete card visual revamp plan summary
- TabloProjectCard rebuilt with status badge, avatar initial, progress bar
- CSS Section 20b added: progress-row, list-row, data-view toggle rules
- Tailwind regenerated
2026-05-17 16:31:28 +02:00
Arthur Belleville
2b786e2014
feat(19-02): add progress-row and list-row CSS, rebuild Tailwind
- Added Section 20b to app.css: .project-card-progress-row, .project-card-progress-label
- Added .project-card-progress-bar (uses var(--color-accent) instead of --project-color)
- Added .tablo-card-wrapper (display:contents) for transparent grid wrapper
- Added .tablo-list-row (hidden by default), .tablo-list-row-title, .tablo-list-row-meta
- Added [data-view="list"] toggle rules for #tablos-list container
- Rebuilt static/tailwind.css with tailwindcss CLI
2026-05-17 16:30:56 +02:00
Arthur Belleville
4b254e9527
feat(19-02): rebuild TabloProjectCard with dual card+row structure
- Rewrote TabloProjectCard with outer article.tablo-card-wrapper (display:contents)
- Added .project-card child: status badge top-left, delete button top-right
- Avatar circle now shows initial letter from card.Tablo.Title
- Added calendar icon + formatted date in .project-date-row
- Added .project-card-progress-row with "Progression: X%" label and .project-card-progress-bar
- Added .tablo-list-row sibling (hidden by default) for list view toggle
- Added strconv and strings imports for Itoa and title-casing Status
2026-05-17 16:30:32 +02:00
Arthur Belleville
ae1798062e
docs(19-01): complete tablo list revamp data layer plan
- Add 19-01-SUMMARY.md with task commits, decisions, and next phase readiness
2026-05-17 16:28:53 +02:00
Arthur Belleville
47ba2f1797
feat(19-01): enrich TabloCardView with Progress field and wire batch progress query
- Add Progress int field to TabloCardView (D-05)
- Map row.Status into Tablo struct in TabloCardsFromUnreadRows
- Wire ListTabloProgressByIDs batch query in TablosListHandler (no N+1)
- Non-fatal error handling: progress defaults to 0 on query failure
2026-05-17 16:28:15 +02:00
Arthur Belleville
c1928e312f
feat(19-01): add tablo status column, batch progress query, and sqlc regen
- Add migration 0010_tablo_status.sql with reversible goose Up/Down
- Update all tablo SQL queries to include status column in SELECT/RETURNING/GROUP BY
- Add ListTabloProgressByIDs batch aggregation query (D-06)
- sqlc regenerated locally (files gitignored — regen via sqlc generate)
2026-05-17 16:27:30 +02:00
Arthur Belleville
c3b470a1a7
docs(19): create phase 19 tablo list revamp plans (3 plans, 3 waves)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 16:22:30 +02:00
Arthur Belleville
28e05b5fc1
docs(19): research tablo list revamp phase 2026-05-17 16:16:27 +02:00
Arthur Belleville
3542f3b105
docs(phase-18): complete phase execution — sidebar + header restyle approved
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 16:04:09 +02:00
Arthur Belleville
9ba650b345
feat(18): restyle sidebar and header to match production design
- Sidebar: Tailwind utilities, French labels (Aperçu/Tâches/Projets/Planning/Discussions/Fichiers), hr separators, collapse button on group hover, tablo list with circle icons, org footer with avatar + "1 membre"
- Header: 75px height, border-b #EAECF0, search input left, bell + avatar-dropdown right (no breadcrumb visible — retained sr-only for a11y + tests)
- Layout: flex instead of grid, dashboard-main no padding, dashboard-main-content wrapper at 2rem
- Tests updated for new search-input assertion

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 16:00:26 +02:00
Arthur Belleville
1952b95405
docs(18-03): complete PageHeader and avatar dropdown plan summary
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 15:35:29 +02:00
Arthur Belleville
9a70553cb0
feat(18-03): add page-header CSS, /settings stub route, and header tests
- Add page-header, breadcrumb, header-search-placeholder, header-icon-button, header-avatar-menu, header-avatar-dropdown CSS rules to app.css
- Regenerate tailwind.css with new page-header and avatar dropdown classes
- Add GET /settings stub route returning 200 with "Coming soon" content (D-06)
- Add page-header and breadcrumb assertions to TestTablosDashboard_Sidebar
- Add new TestTablosDashboard_Header test asserting page-header, header-avatar-menu, Dashboard breadcrumb, header-search-placeholder
2026-05-17 15:34:58 +02:00
Arthur Belleville
c190723538
feat(18-03): add PageHeader component and wire into AppLayout
- Add PageHeader templ component with three-zone layout (breadcrumb left, search placeholder center, bell/inbox/avatar right)
- Avatar dropdown uses native details/summary HTML (D-06, no Alpine.js)
- Logout form inside dropdown with CSRF token (T-18-03-01 mitigated)
- Remove Plan 01 breadcrumb/headerActions stubs from AppLayout body
- Wire @PageHeader call inside dashboard-main before children
- Add inline JS for avatar dropdown outside-click close behavior
2026-05-17 15:33:17 +02:00
Arthur Belleville
5dc21340b0
docs(18-02): complete sidebar rebuild plan summary
- Rebuilt DashboardSidebar with GENERAL/PROJECTS sections and collapse button
- Updated sidebarPrimaryNavItems to Figma-spec 5 items
- Added sidebar-is-collapsed CSS rules and regenerated tailwind.css
2026-05-17 15:31:26 +02:00
Arthur Belleville
8a91183639
feat(18-02): add sidebar collapsed-state CSS rules and regenerate tailwind.css
- Add .dashboard-shell.sidebar-is-collapsed grid-template-columns: 4rem 1fr
- Hide sidebar-brand-title, section labels, nav labels, project labels when collapsed
- Center icons in collapsed state via justify-content: center on sidebar-nav-link-inner
- Hide sidebar-project-list in collapsed state (no icons for project entries)
- Flip collapse button chevron with rotate(180deg) when collapsed
- Regenerate static/tailwind.css via bin/tailwindcss --minify
2026-05-17 15:30:42 +02:00
Arthur Belleville
b592a02bef
feat(18-02): rebuild DashboardSidebar with GENERAL/PROJECTS sections and collapse button
- Add GENERAL section label above primary nav items list
- Add PROJECTS section label and tablo list inlined directly in DashboardSidebar
- Wire collapse button with inline JS toggling sidebar-is-collapsed on .dashboard-shell
- Remove SidebarOrganizationFooter call (moves to avatar dropdown in Plan 03)
- Remove DividerAfter rendering branch (section labels replace dividers)
2026-05-17 15:30:13 +02:00
Arthur Belleville
2763fc195e
feat(18-02): update sidebarPrimaryNavItems and add team icon to SidebarNavIcon
- Replace Dashboard/Tasks/Planning/Chat/Files with Home/My Tasks/Projects/Events/Team Members
- Remove DividerAfter from all items (section labels replace dividers per D-08)
- Add "team" case to SidebarNavIcon switch using Lucide users SVG paths
2026-05-17 15:29:38 +02:00
Arthur Belleville
8cd460e8f0
docs(18-01): complete plan 01 summary - AppLayout signature extension 2026-05-17 15:28:01 +02:00
Arthur Belleville
59f143aecb
feat(18-01): update all handler call sites with per-page breadcrumbs
- handlers_tablos.go: TablosListHandler, renderTabloCreateError, TabloDetailHandler, TabloUpdateHandler
- handlers_planning.go: PlanningPageHandler
- handlers_account.go: AccountProvidersHandler
- handlers_discussion.go: TabloDiscussionTabHandler
- handlers_files.go: TabloFilesTabHandler, TabloTasksTabHandler
- handlers_events.go: TabloEventsTabHandler
- go build ./... succeeds, go test ./... passes
2026-05-17 15:27:38 +02:00
Arthur Belleville
eff62b0fd9
feat(18-01): update templ wrapper signatures to forward pageTitle and breadcrumb
- TablosDashboard: add pageTitle, breadcrumb params; pass through to AppLayout
- TabloDetailPage: add pageTitle, breadcrumb params; pass through to AppLayout
- TabloNotFoundPage: pass hardcoded 'Not found' values to AppLayout
- PlanningPage: add pageTitle, breadcrumb params; pass through to AppLayout
- AccountProvidersPage: add pageTitle, breadcrumb params; pass through to AppLayout
2026-05-17 15:26:28 +02:00
Arthur Belleville
3e2c86904b
feat(18-01): extend AppLayout signature with pageTitle, breadcrumb, headerActions
- Add BreadcrumbItem struct to app_layout_helpers.go
- Update AppLayout to accept 8 parameters (was 5)
- Add minimal breadcrumb/headerActions stubs in layout body
2026-05-17 15:25:46 +02:00
Arthur Belleville
bc2cde8fa3
docs(18): research phase domain 2026-05-17 15:10:00 +02:00
Arthur Belleville
4b8149028d
docs(18): capture phase context 2026-05-17 15:05:13 +02:00
Arthur Belleville
dfd61528d4
docs: create milestone v4.0 roadmap (5 phases) 2026-05-17 14:27:29 +02:00
Arthur Belleville
586321e8ef
docs: define milestone v4.0 requirements 2026-05-17 14:24:49 +02:00
Arthur Belleville
e91aa5d15d
docs: start milestone v4.0 Figma Design Parity 2026-05-17 14:22:10 +02:00
Arthur Belleville
dc0d3dec42
chore: archive v3.0 phase directories to milestones/v3.0-phases/
Phases 13-17 (design-system-foundation, auth-pages, dashboard-tablos,
tablo-detail, chat-planning) moved from .planning/phases/ to
.planning/milestones/v3.0-phases/ as execution history archive.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 14:14:32 +02:00
Arthur Belleville
a57827dde3
chore: remove REQUIREMENTS.md for v3.0 milestone
Fresh REQUIREMENTS.md will be created for v4.0 via /gsd-new-milestone.
History preserved — see .planning/milestones/v3.0-REQUIREMENTS.md.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 14:12:56 +02:00
Arthur Belleville
c2d191bd4b
chore: archive v3.0 milestone files 2026-05-17 14:12:49 +02:00
Arthur Belleville
fa48d81ffd
docs(phase-17): evolve PROJECT.md after phase completion 2026-05-17 13:04:53 +02:00
Arthur Belleville
f5563ec6aa
docs(phase-17): complete phase execution 2026-05-17 13:04:32 +02:00
Arthur Belleville
5624ca59ca
feat(17): add day-separator headers to planning event list
- PlanningShowDaySeparator in planning_forms.go — returns true when date
  changes between consecutive events
- PlanningDaySeparator templ: slate-50 header row with date label and
  data-day-separator attribute
- PlanningEventListItem: remove redundant DateLabel column (now in separator)
- Loop uses index to call PlanningShowDaySeparator before each event row

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 13:03:30 +02:00
Arthur Belleville
3d5d9a05ea
feat(17): cap discussion height at 32rem with auto-scroll to latest message
- #discussion-messages: max-height 32rem, overflow-y auto, smooth scroll
- Auto-scroll to bottom on initial load, on own message sent (htmx:afterRequest),
  and on SSE message received from other users

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 12:58:26 +02:00
Arthur Belleville
2e8c9de24e
chore(dev): watch static JS files in air — rebuild on discussion-sse.js changes
Remove static/ from exclude_dir, add js to include_ext.
Exclude static/tailwind.css via regex to prevent rebuild loop from
the Tailwind output file triggering its own regeneration.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 12:55:14 +02:00
Arthur Belleville
681c094b0c
fix(17): skip own-user SSE messages in JS to eliminate left-then-right flash
The server-side flush didn't eliminate the race because browser HTMX and SSE
event processing are inherently async.

Real fix: embed data-current-user-id on #discussion-tab (from DiscussionTabData.
CurrentUserID). The SSE handler now skips any event whose authorUserId matches
the current user — those messages are always delivered via HTMX (IsOwn=true,
right-aligned). SSE only appends messages from other users.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 12:47:21 +02:00
Arthur Belleville
96a58ef0ea
fix(17): flush HTTP response before SSE publish to fix own-message alignment race
The server was publishing to the SSE broker before writing the HTMX response,
causing a race: if the SSE event (IsOwn=false, left-aligned) arrived at the
browser before HTMX appended the response (IsOwn=true, right-aligned), the
SSE path won and messageExists() then blocked the correct HTMX append.

Fix: write and flush the HTMX response first, then publish to SSE. This ensures
the sender's own message lands in the DOM right-aligned before the SSE event fires.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 12:26:13 +02:00
Arthur Belleville
30256895b2
fix(17): address all code review findings
- CR-01: add id="discussion-message-list" to .divide-y; change hx-target
  to #discussion-message-list so HTMX appends inside the list, not after it.
  Always render the list div so the target exists even when messages is empty.
- WR-01: SSE broadcast now renders IsOwn=false for all recipients so other
  users don't receive the sender's right-aligned bubble
- WR-02: add HX-Retarget/HX-Reswap headers on 422 and 500 error responses
  so validation errors reach the composer form in the DOM
- WR-03: replace hardcoded rgba(128,78,236,0.10) with color-mix() using
  the --color-brand-primary token
- WR-04: remove hardcoded "1 participant" subtitle (no participant count in data)
- IN-02: DiscussionMessageFromRow now accepts currentUserID uuid.UUID (matching
  DiscussionMessagesFromRows) instead of a pre-computed bool

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 12:23:21 +02:00
Arthur Belleville
bb2001f3ce
docs(17): add code review report 2026-05-17 10:41:32 +02:00
Arthur Belleville
ab756c64ce
docs(17-02): complete planning page restyle plan execution
- 17-02-SUMMARY.md: TDD RED/GREEN cycle documented, all verification criteria met
- STATE.md: plan 2 of 2 complete, phase 17 ready for verification
- ROADMAP.md: phase 17 marked Complete (2/2 plans)
- REQUIREMENTS.md: PLAN-UI-01 marked complete
2026-05-17 10:36:43 +02:00
Arthur Belleville
9fe6c897e3
feat(17-02): wire PlanningMainContent with real planning view (GREEN)
- dashboard_components.templ: PlanningMainContent(data PlanningTabData) — overview-section heading (h1), day separators with data-day-separator attribute, event rows, empty state via ui.EmptyState
- handlers/auth.go: GetPlanningPage passes views.NewPlanningTabData()
- dashboard_components_templ.go: regenerated by templ generate
- go test ./... -count=1 exits 0
2026-05-17 10:35:30 +02:00
Arthur Belleville
1afc39e70a
test(17-02): add failing render test + view model + CSS h1 selector fix (RED)
- go-backend/internal/web/ui/app.css: prepend .overview-section-heading h1 to heading selector
- go-backend/internal/web/views/planning_view.go: PlanningEventRow, PlanningTabData, NewPlanningTabData (5 demo events / 2 dates), PlanningShowDaySeparator
- go-backend/internal/web/views/planning_view_test.go: TestPlanningShowDaySeparator (logic tests), TestPlanningMainContentRendersOverviewSection (render test — RED until Task 2)
2026-05-17 10:34:49 +02:00
Arthur Belleville
78785d1851
docs(17-01): update SUMMARY with checkpoint approval and backend/ deviations
- Expand SUMMARY to reflect 3 additional commits made during checkpoint:
  56194cf (backend/ restyle), d8e52f6 (IsOwn wiring + divide-y), bc3d8e6 (HTMX tab fix)
- Document Rule 1 deviations: real app restyle, IsOwn user-comparison, overview tab fix
- Add IsOwn threading decision to STATE.md
- Checkpoint approved by user ("approved")

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 10:32:48 +02:00
Arthur Belleville
bc3d8e6355
fix(17): return TabloOverviewTabFragment on HX-Request for overview tab
TabloDetailHandler was always rendering the full page regardless of
HX-Request, causing HTMX to swap the entire layout (sidebar, header)
into #tab-content instead of just the overview fragment.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 10:24:39 +02:00
Arthur Belleville
d8e52f695b
fix(17): own messages right-aligned; restore .divide-y for SSE compatibility
- Add IsOwn bool to DiscussionMessageView; set via user.ID comparison in
  DiscussionMessagesFromRows and DiscussionMessageFromRow
- Thread currentUserID through loadDiscussionTabData and all call sites
- discussion.templ: branch message-own vs message-other on message.IsOwn
- Restore .divide-y wrapper inside #discussion-messages (discussion-sse.js
  depends on it to locate the message list before appending SSE events)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 10:22:23 +02:00
Arthur Belleville
56194cfdb5
feat(17): restyle discussion view and planning page in backend/
- discussion.templ: #discussion-messages uses .ui-card; DiscussionMessageRow
  uses .message-row/.message-other/.message-bubble/.message-meta classes;
  day separator gets data-day-separator attribute
- planning.templ: wraps content in .overview-section; heading uses
  .overview-section-heading with h1; empty state uses .ui-card
- app.css: add Section 26 .message-* bubble classes; extend
  .overview-section-heading selector to include h1

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 10:01:24 +02:00
Arthur Belleville
e3596ff753
docs(17-01): complete plan execution — chat bubble restyle summary
- Create 17-01-SUMMARY.md with TDD gate compliance docs
- Advance plan counter to 2/2
- Mark CHAT-UI-01 complete in REQUIREMENTS.md
- Update ROADMAP.md phase 17 progress (1/2 plans complete)
2026-05-17 09:39:37 +02:00
Arthur Belleville
81ccaeb107
feat(17-01): wire ChatMainContent with real discussion view (GREEN)
- Replace ChatMainContent() stub with ChatMainContent(data DiscussionTabData)
- Renders .ui-card container with .message-own/.message-other rows and .message-bubble
- Update GetChatPage handler to pass views.NewDiscussionTabData()
- Run templ generate; TestChatMainContentRendersBubbleClasses passes
- Full go test ./... -count=1 exits 0
2026-05-17 09:38:43 +02:00
Arthur Belleville
dd1133d7cc
test(17-01): add failing test + view model + message bubble CSS (RED)
- Append .message-row/.message-own/.message-other/.message-bubble/.message-meta CSS classes to app.css
- Create discussion_view.go with DiscussionMessageView, DiscussionTabData, NewDiscussionTabData
- Create discussion_view_test.go with TestChatMainContentRendersBubbleClasses (RED: compile error expected)
2026-05-17 09:38:10 +02:00
Arthur Belleville
ba48c2c74f
docs(17): create phase plan 2026-05-17 09:36:36 +02:00
Arthur Belleville
664f826052
fix(17): revise plans based on checker feedback
- Add <scope_note> to Plan 01 documenting D-D01–D-D04 and SPEC Req 2 deferral (restyle-only phase, no SSE/HTMX backend yet)
- Plan 02 Task 1: replace fragile bg-slate-50 render assertion with data-day-separator semantic attribute; add D-P02 path-adaptation note (planning_forms.go → planning_view.go)
- VALIDATION.md: set nyquist_compliant/wave_0_complete true, update Wave 0 section, check off sign-off items, set approval 2026-05-17

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 09:33:59 +02:00
Arthur Belleville
7e3b3af1e3
docs(17): create phase 17 plans — discussion view and planning page restyle
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 09:26:26 +02:00
Arthur Belleville
f45f7c6010
docs(17): research phase domain 2026-05-17 06:37:06 +02:00
Arthur Belleville
b84503a54a
docs(17): add UI design contract for chat & planning phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 06:30:40 +02:00
Arthur Belleville
08e8fc1976
docs(17): capture phase context 2026-05-17 00:15:15 +02:00
Arthur Belleville
8fa490978b
spec(phase-17): add SPEC.md for Chat & Planning — 6 requirements (#2213) 2026-05-17 00:06:24 +02:00
Arthur Belleville
d40909ac9b
docs(phase-16): evolve PROJECT.md after phase completion 2026-05-17 00:00:02 +02:00
Arthur Belleville
3d3fcc9c2b
docs(phase-16): complete phase execution 2026-05-16 23:59:52 +02:00
Arthur Belleville
18a705c812
fix(16): restore task-drag-handle for Sortable.js drag-and-drop
Phase 16 executor removed the .task-drag-handle div from TaskCard
during restyling. Sortable.js handle: '.task-drag-handle' had no
matching element → dragging completely non-functional.

Restores the grip element with CSS-token styling (no Tailwind).
2026-05-16 23:58:51 +02:00
Arthur Belleville
a10fa46ae2
test(16): persist human verification items as UAT 2026-05-16 23:55:44 +02:00
Arthur Belleville
b48fe9ae89
docs(16): add code review report 2026-05-16 23:51:32 +02:00
Arthur Belleville
03d9bad0ae
docs(16-04): complete files section restyle plan summary
- DETAIL-04 delivered: @ui.Table, @ui.EmptyState, tr-based file rows
- All file handler tests pass; browser checkpoint auto-approved
2026-05-16 23:46:52 +02:00
Arthur Belleville
ca693f1683
feat(16-04): restyle files section with @ui.Table, EmptyState, and tr rows
- Replace <ul>/<li> layout with @ui.Table using fileTableHead/fileTableBody helpers
- Add .overview-section-heading header with "Files" h3 and Upload file button
- Convert FileListRow outer element from <li> to <tr class="file-row-zone">
- Convert FileDeleteConfirmFragment outer element from <div> to <tr class="file-row-zone"> with <td colspan="4">
- Add Download and Delete @ui.IconButton in FileListRow actions column
- Replace FileListEmpty with @ui.EmptyState in FilesTabFragment and UploadErrorFragment
- Convert FileRowGone from <div> to <tr> for DOM consistency
- All 9 file handler tests pass; go build ./... exits 0
2026-05-16 23:46:12 +02:00
Arthur Belleville
3a5a26c5c8
docs(16-03): complete kanban restyle + etape grouping plan summary
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 23:43:44 +02:00
Arthur Belleville
e2ee4349f8
feat(16-03): update all three KanbanBoard call sites to pass etapes
- tablos.templ TasksTabFragment: add etapes as 5th argument to @KanbanBoard
- handlers_tasks.go reorder (single): capture etapes from loadTasksTabData; pass to KanbanBoard
- handlers_tasks.go reorder (batch): capture etapes from loadTasksTabData; pass to KanbanBoard
- go build ./backend/... exits 0; go test ./backend/internal/web/... -count=1 passes
2026-05-16 23:42:46 +02:00
Arthur Belleville
084fc0ebba
feat(16-03): restyle kanban board with etape grouping (tasks.templ)
- Add EtapeGroup type and groupTasksByEtape helper (etape declaration order, unassigned last)
- Add EtapeGroupHeader templ component with color dot and muted label for unassigned
- Update KanbanBoard and KanbanColumn signatures to accept etapes []sqlc.Etape (5th param)
- Restyle KanbanColumn: kanban-column > tasks-section > tasks-section-header/task-list layout
- Restyle TaskCard: task-row task-card with task-check + task-body + @ui.IconButton(trash)
- Restyle AddTaskTrigger: tasks-add-button class (replaces ui-button compound classes)
- Remove @EtapeStrip OOB calls from TaskCardGone and TaskCardOOB; keep params with TODO
2026-05-16 23:42:40 +02:00
Arthur Belleville
f39971bd0a
docs(16-02): add SUMMARY.md for tablo detail header restyling plan 2026-05-16 23:38:05 +02:00
Arthur Belleville
443a38dfc8
feat(16-02): restyle TabloDetailPage header, tab nav, metadata row; remove EtapeStrip
- Replace header with project-card-top layout: color avatar with first char, tablo-title-zone
- Replace Discussion link/Invite button/Delete button with @ui.IconButton and @ui.Button using design token variants
- Add inline tablo-delete-zone with trash @ui.IconButton (does not use TabloDeleteButtonFragment)
- Replace metadata row hardcoded flex/hex classes with tablo-metadata-row, @ui.Badge(BadgeVariantPrimary), project-progress-track/bar
- Replace 5 tab nav <a> elements from long inline Tailwind hex classes to tab-nav-item / tab-nav-item is-active
- Wrap tab nav in class="tab-nav" replacing raw flex container
- Move @TabloDescDisplay call from persistent header into TabloOverviewTabFragment
- Remove @EtapeStrip call from TasksTabFragment (D-E01; KanbanBoard call site update deferred to Plan 03)
- Remove last #804EEC hex value from TabloTitleDisplay hover class
- Regenerated tablos_templ.go via templ generate
2026-05-16 23:37:16 +02:00
Arthur Belleville
4e0336c950
docs(16-01): complete icon-cases and CSS-foundations plan
- add download + chat icon SVG cases to UIIcon switch
- append CSS Sections 19-25 to app.css (tasks-section through task-list-empty)
- all tests pass; zero hardcoded hex values in new CSS
2026-05-16 23:33:38 +02:00
Arthur Belleville
44209b9db2
feat(16-01): append CSS Sections 19-25 to app.css
- Section 19: tasks-section block (task-row, task-check, task-body, task-meta, tasks-add-button)
- Section 20: project-progress-track and project-progress-bar
- Section 21: tab-nav, tab-nav-item, tab-nav-item.is-active, tab-nav-item:hover
- Section 22: tablo-metadata-row, tablo-metadata-date
- Section 23: kanban-column wrapper (width: 18rem) + scoped h3 override (1rem)
- Section 24: etape-group-header, etape-group-color-dot, etape-group-label
- Section 25: task-list-empty placeholder
- all values use var(--...) tokens; zero hardcoded hex values
2026-05-16 23:32:57 +02:00
Arthur Belleville
a1a3ea8239
feat(16-01): add download and chat icon cases to UIIcon switch
- insert case "download" with arrow-down SVG (path + polyline + line) before default case
- insert case "chat" with speech-bubble SVG (path) before default case
- icon_button_templ.go regenerated via templ generate (gitignored, regenerated at build time)
2026-05-16 23:31:58 +02:00
Arthur Belleville
337c380d6b
docs(16): create phase plan 2026-05-16 23:30:34 +02:00
Arthur Belleville
5060e4bb96
fix(16): revise plans based on checker feedback
- RESEARCH.md: mark Open Questions as RESOLVED; resolve A2 (ButtonVariantGhost does not exist as ButtonTone; use ButtonToneSoft+ButtonVariantDefault for Invite button); confirm TaskCardGone/OOB keep params; confirm FileDeleteConfirmFragment <tr> is safe
- VALIDATION.md: fix automated command paths to match actual plan verify commands (go test ./backend/internal/web/... not cd go-backend); set nyquist_compliant: true and wave_0_complete: true
- 16-02 Task 2: remove KanbanBoard call site update (was causing accepted compile error); Task 2 now only deletes EtapeStrip call and requires clean go build ./backend/... exit 0
- 16-02 Task 1: clarify Discussion link as <a> wrapping @ui.IconButton (not ambiguous OR); fix Invite button to ButtonToneSoft+ButtonVariantDefault
- 16-03 Task 2: add tablos.templ as modified file; update action to include all three KanbanBoard call sites atomically

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 23:27:59 +02:00
Arthur Belleville
965ec5e5ce
docs(16): create phase 16 tablo detail plan — 4 plans, 4 waves
Phase 16 delivers DETAIL-01/02/03/04: header restyling, kanban
tasks-section layout with server-side etape grouping, and files
table component. Ends with a browser verify checkpoint.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 23:20:49 +02:00
Arthur Belleville
36011fc8a3
docs(phase-16): add validation strategy 2026-05-16 23:08:43 +02:00
Arthur Belleville
73780323d2
docs(16): research phase domain 2026-05-16 23:07:57 +02:00
Arthur Belleville
30c446fc0e
docs(16): UI design contract 2026-05-16 23:02:25 +02:00
Arthur Belleville
dcb99fb19a
docs(16): add UI design contract for tablo detail phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 22:51:58 +02:00
Arthur Belleville
a6eace8364
docs(state): record phase 16 context session 2026-05-16 22:47:02 +02:00
Arthur Belleville
7f01453ca2
docs(16): capture phase context 2026-05-16 22:46:57 +02:00
Arthur Belleville
5708156dcf
docs(15): mark VALIDATION.md compliant after audit
All 3 DASH tests green with TEST_DATABASE_URL:
- TestTablosDashboard_Sidebar (DASH-01)
- TestTablosDashboard_ProjectCards (DASH-02)
- TestTablosDashboard_EmptyState (DASH-03)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 22:32:04 +02:00
Arthur Belleville
d5ce65a003
docs(15): add code review report 2026-05-16 22:28:50 +02:00
Arthur Belleville
716678cddd
docs(phase-15): update tracking after wave 2 2026-05-16 22:25:13 +02:00
Arthur Belleville
64ba8abbb0
fix(15-03): apply tablo detail restyle with correct AppLayout signatures
Merge conflict resolution had taken the old template signatures (pre-AppLayout).
Restored HEAD~1 signatures then applied the header/tab-nav restyle:
- Title row: md:text-3xl font-bold, Discussion + Invite action buttons
- Metadata row: created date, status badge, 0% progress bar
- Sticky purple-accent tab bar (Overview, Tasks, Files, Discussion, Events)
- All HTMX wiring and AppLayout wrapping preserved
2026-05-16 22:24:52 +02:00
Arthur Belleville
79039721c6
chore: merge executor worktree (worktree-agent-adcff3bb3254fb8c6) 2026-05-16 22:19:11 +02:00
Arthur Belleville
7d8036777e
docs(15-03): complete tablo detail restyle plan summary 2026-05-16 22:17:40 +02:00
Arthur Belleville
6953536dd8
feat(15-03): restyle tablo detail page header and tab nav to match reference design
- Replace plain back-link + title with structured header: title row + metadata row
- Title uses larger md:text-3xl font-bold style with inline-edit preserved
- Add Discussion and Invite action buttons in header (purple brand colors)
- Add metadata row: created date, hardcoded En cours status badge, 0% progress bar
- Replace plain slate tab nav with purple-accent tab bar (icon + label per tab)
- Tab active state: text-[#804EEC] border-[#804EEC]; inactive: text-[#667085]
- Tab bar is sticky (top-0 z-40) with horizontal scroll and hidden scrollbar
- Keep all HTMX attributes, hx-push-url, hx-target="#tab-content" logic unchanged
- tablo-title-zone, tablo-desc-zone, tablo-delete-zone elements retained
2026-05-16 22:15:49 +02:00
Arthur Belleville
50bd9a0133
docs(15-03): complete plan 03 summary — AppLayout wired to all authenticated pages
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 21:50:15 +02:00
Arthur Belleville
c7a16dbcae
feat(15-03): wire AppLayout into all authenticated handlers and templates
- TablosListHandler: derives sidebarTablos from cardViews, calls TablosDashboard with activePath="/"
- TabloDetailHandler: fetches ListTablosByUser for sidebar, calls TabloDetailPage with activePath=""
- TabloUpdateHandler: fetches ListTablosByUser for non-HTMX error path
- renderTabloCreateError: derives errorSidebarTablos from errorCardViews
- TabloDiscussionTabHandler, TabloEventsTabHandler, TabloFilesTabHandler, TabloTasksTabHandler: fetch ListTablosByUser for non-HTMX full-page renders
- PlanningPageHandler: fetches ListTablosByUser, calls PlanningPage with activePath="/planning"
- AccountProvidersHandler: fetches ListTablosByUser, calls AccountProvidersPage with activePath="/"
- planning.templ: updated signature + switched to @AppLayout
- account_providers.templ: updated signature + switched to @AppLayout
2026-05-16 21:49:23 +02:00
Arthur Belleville
9c7b080f67
feat(15-03): restyle tablos.templ with AppLayout, TabloProjectCard, and EmptyState
- Updated TablosDashboard signature to accept activePath and tablos for AppLayout
- Replaced old @Layout call with @AppLayout (sidebar-based shell)
- Added TabloProjectCard component with project-card grid, colored avatar, tablo-title-zone, edit/delete icon buttons
- Replaced TablosEmptyState raw HTML with @ui.EmptyState component (ui-empty-state class)
- Updated TabloDetailPage signature with activePath and sidebarTablos params
- Updated TabloNotFoundPage signature with activePath and sidebarTablos params
- Both detail pages switch from @Layout to @AppLayout
2026-05-16 21:49:10 +02:00
Arthur Belleville
ae0ab0ca5b
docs(phase-15): update tracking after wave 1 2026-05-16 21:44:18 +02:00
Arthur Belleville
41cf96ae66
docs(15-02): complete AppLayout CSS foundation + sidebar components plan 2026-05-16 21:43:44 +02:00
Arthur Belleville
9b0d335329
feat(15-02): create app_layout.templ and app_layout_helpers.go with sidebar sub-components
- Create backend/templates/app_layout_helpers.go: sidebarNavItem struct, sidebarNavItemClass, isActivePath, sidebarNavItemID, sidebarPrimaryNavItems
- Create backend/templates/app_layout.templ: SidebarNavIcon, SidebarNavItemRow, SidebarProjectsSection, SidebarOrganizationFooter, DashboardSidebar, AppLayout
- templ generate and go build exit 0; all existing tests pass
2026-05-16 21:43:15 +02:00
Arthur Belleville
f533d53c74
feat(15-02): port sidebar + project-card CSS into app.css and register in tailwind
- Create backend/internal/web/ui/app.css with dashboard shell, sidebar, and project-card CSS ported verbatim from go-backend
- All color values use var(--...) design tokens — no hex colors
- Add @import "./internal/web/ui/app.css" to backend/tailwind.input.css
2026-05-16 21:41:58 +02:00
Arthur Belleville
140f400e10
docs(phase-15): update tracking after wave 0 2026-05-16 21:39:58 +02:00
Arthur Belleville
459892f31f
docs(15-01): complete Wave 0 test stubs plan — DASH-01/02/03 RED baseline 2026-05-16 21:39:11 +02:00
Arthur Belleville
7bea525c1b
test(15-01): add Wave 0 RED test stubs for DASH-01, DASH-02, DASH-03
- TestTablosDashboard_Sidebar: asserts dashboard-sidebar + sidebar-nav-shell in GET / body
- TestTablosDashboard_ProjectCards: asserts project-card in GET / body with a pre-inserted tablo
- TestTablosDashboard_EmptyState: asserts ui-empty-state in GET / body with zero tablos
- All three skip without TEST_DATABASE_URL; compile cleanly; existing TestTablos* tests unaffected
2026-05-16 21:38:50 +02:00
Arthur Belleville
13b6f525de
docs(15): create phase plan 2026-05-16 21:35:53 +02:00
Arthur Belleville
431096e4de
docs(15): resolve open questions and fix 15-03 edit-title wiring
- RESEARCH.md: rename '## Open Questions' to '## Open Questions (RESOLVED)';
  add [RESOLVED] markers to all three questions with verified answers.
  Q2 resolved: edit-title route confirmed via codebase, no single /edit route.
- 15-03-PLAN.md Task 1: add handlers_tablos.go to read_first; make edit
  icon button definitively use hx-get=/tablos/{id}/edit-title with
  hx-target="closest .tablo-title-zone"; remove open-ended href fallback
  discretion; add edit-title grep to acceptance criteria.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 21:33:16 +02:00
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
Arthur Belleville
8422d82fc8
docs(15): research phase domain 2026-05-16 21:17:03 +02:00
Arthur Belleville
65c17561ae
docs(15): capture phase context 2026-05-16 21:08:44 +02:00
Arthur Belleville
8a34e5c79a
docs(14): add VALIDATION.md — phase is Nyquist-compliant
14 automated tests covering AUTH-UI-01/02/03. 3 manual-only items
(animated CSS, Roboto font render, HTMX browser swap) verified at
human checkpoint on 2026-05-16.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 20:44:04 +02:00
Arthur Belleville
dcbc05b642
test(14): add Nyquist validation tests for AUTH-UI-01/02/03
auth_login_test.go: LoginPage renders AuthLayout structure (login-screen,
auth-card-shell, brand-logo, h1, auth-body, divider-pill), HTMX form
attributes, password not echoed.

auth_components_test.go: AnimatedBackground exactly 35 elements,
GoogleButton configured/unconfigured variants, AuthDivider or-pill.

handlers_auth_test.go: extend configured provider tests to assert
class="gsi-material-button" on the anchor element (AUTH-UI-03).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 20:43:31 +02:00
Arthur Belleville
9f0c92fc89
docs(14-02): complete plan summary and update state
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 19:29:10 +02:00
Arthur Belleville
6e64cfb3ed
chore(dev): watch CSS files in air and include Tailwind in rebuild cmd
Add css to air's include_ext so edits to internal/web/ui/*.css trigger a
rebuild. Add Tailwind build step to the air cmd so static/tailwind.css is
always up to date on reload. static/ remains excluded so the generated
output file doesn't cause a loop.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 19:25:55 +02:00
Arthur Belleville
70fe3848fb
fix(14-02): shrink Google button to content width
width: auto on a block element still fills the parent. Use width: max-content
so the button wraps its icon + label + padding only. Remove flex-grow: 1 on
the label span so it doesn't stretch within the now-natural-width button.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 19:24:10 +02:00
Arthur Belleville
6a58b2970a
fix(14-02): shrink Google button to natural width per Google spec
Google's gsi-material-button uses width: auto, not 100%. Replace width: 100%
/ max-width: 400px with width: auto + margin: 0 auto so the button sizes to
its content (icon + label + padding) and stays centered in the card.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 19:21:41 +02:00
Arthur Belleville
4624fb305a
fix(14-02): load Roboto font and fix Google button SVG icon sizing
Per Google's branding guidelines, the gsi-material-button requires Roboto
Medium. Add Google Fonts preconnect + stylesheet link to AuthLayout head.
Also add display:block + 100% dimensions to the SVG inside the icon
container to prevent inline baseline gaps.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 19:18:58 +02:00
Arthur Belleville
65e3dbfd03
feat(14-02): migrate auth_signup.templ to AuthLayout with ui.FormField inputs
- Replace Layout+Card pattern with AuthLayout("Create your account", csrfToken)
- Wire GoogleButton and AuthDivider into SignupPage body
- Replace raw <input> elements with @ui.FormField/@ui.Input design system components
- Password placeholder "12 characters minimum", autocomplete="new-password"
- Add signup-copy nav link ("Already have an account? Sign in") pointing to /login
- Preserve HTMX swap: hx-post="/signup" hx-target="#signup-form" hx-swap="outerHTML"
- Remove signupCardBody helper
2026-05-16 19:10:12 +02:00
Arthur Belleville
808eaecc85
feat(14-02): migrate auth_login.templ to AuthLayout with ui.FormField inputs
- Replace Layout+Card pattern with AuthLayout("Sign in to Xtablo", csrfToken)
- Wire GoogleButton and AuthDivider into LoginPage body
- Replace raw <input> elements with @ui.FormField/@ui.Input design system components
- Add signup-copy nav link ("Don't have an account? Sign up")
- Preserve HTMX swap: hx-post="/login" hx-target="#login-form" hx-swap="outerHTML"
- Remove loginCardBody, AuthProviderButtonsBlock, AuthProviderButtonControl helpers
- Update test assertions for new GoogleButton labels ("Sign in with Google" / disabled attr)
2026-05-16 19:10:08 +02:00
Arthur Belleville
51cb9bd895
docs(14-01): complete auth assets and components plan 2026-05-16 19:07:39 +02:00
Arthur Belleville
e4d5f96571
feat(14-01): create auth_components.templ and auth_layout.templ
- auth_components.templ: AnimatedBackground (35 elements, /static/logo_dark.png, no light/dark pairs), GoogleButton (a/button variant, English label 'Sign in with Google'), AuthDivider ('or' divider)
- auth_layout.templ: standalone HTML shell with .login-screen, @AnimatedBackground(), .card-wrap/.card-glow/.auth-card-shell, htmx.min.js only (no sortable/sse scripts)
- No auth.User param on AuthLayout (auth pages always unauthenticated)
- just generate exits 0, all Go tests pass
2026-05-16 19:06:07 +02:00
Arthur Belleville
cf116ff696
feat(14-01): copy logo assets and replace auth.css with full auth card + animation CSS
- Copy logo_dark.png and logo_white.png from go-backend/static into backend/static
- Replace minimal 62-line auth.css with 828-line extraction from go-backend/static/styles.css
- Sections: login-screen shell, animated background (bg-01..35, size/opacity utilities), card wrapper, card internals, gsi-material-button, legacy auth-provider controls, 66 keyframe definitions, animate-* utility classes
- Added display:block and text-decoration:none to .gsi-material-button for the anchor variant
- Does NOT include .app-shell or .dashboard-shell rules
2026-05-16 19:04:44 +02:00
Arthur Belleville
522c071550
docs(14): create phase plan
Plan 14-01: Auth foundation (logo assets, auth.css, auth_components.templ, auth_layout.templ)
Plan 14-02: Page migration (auth_login.templ, auth_signup.templ → AuthLayout + ui.FormField + nav links)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 19:00:57 +02:00
Arthur Belleville
5ed9291d76
docs(14): create phase plan for auth pages restyle
Two-wave plan: Plan 01 creates foundation (logo assets, full auth.css
replacement with animations, auth_components.templ, auth_layout.templ);
Plan 02 migrates auth_login.templ and auth_signup.templ to AuthLayout
with @ui.FormField inputs and cross-page nav links, closing AUTH-UI-01..03.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 18:58:59 +02:00
Arthur Belleville
848f7480a8
docs(14): UI design contract 2026-05-16 18:48:32 +02:00
Arthur Belleville
0d49c20e42
docs(14): add UI design contract for auth-pages restyle
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 18:40:46 +02:00
Arthur Belleville
d4a44631b7
docs(state): record phase 14 context session 2026-05-16 18:35:16 +02:00
Arthur Belleville
ba19e40482
docs(14): capture phase context 2026-05-16 18:35:11 +02:00
Arthur Belleville
0dac33b784
docs(phase-13): complete phase execution 2026-05-16 18:24:23 +02:00
Arthur Belleville
be84d1f803
test(13): add phase verification report 2026-05-16 18:18:26 +02:00
Arthur Belleville
9dcf628322
docs(13): add code review report 2026-05-16 18:10:17 +02:00
Arthur Belleville
9d17acbe2b
fix(13-05): catalog air config watches css and rebuilds tailwind on change 2026-05-16 18:05:15 +02:00
Arthur Belleville
caba6c15ee
fix(13-05): icon-button hover changes icon color only, no background fill 2026-05-16 18:02:37 +02:00
Arthur Belleville
7ecc063fce
fix(13-05): run catalog via air for live-reload (-tags catalog) 2026-05-16 18:00:40 +02:00
Arthur Belleville
d2c5a0cc07
fix(13-05): add tone-aware hover colors to icon-button (danger/warning/success/neutral) 2026-05-16 17:59:17 +02:00
Arthur Belleville
cae5e7c785
fix(13-05): wire /static/tailwind.css into catalog page head 2026-05-16 14:17:46 +02:00
Arthur Belleville
ae4bb876c1
docs(13-05): complete catalog plan summary
- Create 13-05-SUMMARY.md with catalog package documentation
- Self-check passed: all files and commits verified
2026-05-16 14:14:29 +02:00
Arthur Belleville
4046783fd4
feat(13-05): create catalog package with route files and router wiring
- Add backend/internal/web/ui/catalog/catalog.templ: single-page layout
  with 240px sidebar nav (11 anchor links) and 11 component sections with
  section headings matching DS-XX requirement IDs
- Add backend/internal/web/ui/catalog/examples.go: Example struct + typed
  example functions for all 11 component types (badge/button/card/empty-state/
  form-field/icon-button/input/modal/select/table/textarea); modal renders
  panel-only (no backdrop wrapper, Pitfall 7)
- Add backend/internal/web/catalog_route_catalog.go (//go:build catalog):
  RegisterCatalogRoute mounts GET /ui-catalog via catalogPageHandler()
- Add backend/internal/web/catalog_route_stub.go (//go:build !catalog):
  no-op RegisterCatalogRoute for production builds
- Wire RegisterCatalogRoute(r) unconditionally in NewRouter after protected routes
- Add justfile catalog target: just generate + go run -tags catalog ./cmd/web
- go build ./... and go build -tags catalog ./... both pass; go test ./... green
2026-05-16 14:13:30 +02:00
Arthur Belleville
f57952b6fb
chore: merge executor worktree (worktree-agent-a80aab8b5919843d3) 2026-05-16 14:09:40 +02:00
Arthur Belleville
a8d2942c4d
docs(13-04): complete remaining components plan summary
- Modal, EmptyState, Table, IconButton, UIIcon, Space components ported
- UIIcon wired into button.templ; tailwind.input.css updated to 14 imports
- All 13 new tests pass; full go test ./... green
2026-05-16 14:08:17 +02:00
Arthur Belleville
c80ebcb9b1
feat(13-04): port icon-button/space components; wire UIIcon into button.templ; update tailwind.input.css (GREEN)
- icon-button.css + icon_button.templ: UIIcon switch (plus/grid3x3/list/filter/search/calendar/pencil/trash + fallback span)
- spacing.css + space.templ: SpaceX/SpaceY with SpacingStep classes
- button.templ: wire @UIIcon(props.Icon) replacing Plan 02 placeholder comment
- tailwind.input.css: add modal, empty-state, table, icon-button, form-field, spacing imports (14 total)
- All 7 new tests pass; full go test ./... green
2026-05-16 14:07:07 +02:00
Arthur Belleville
fa2405938a
test(13-04): add failing tests for IconButton, UIIcon, Space, and Button icon wiring (RED) 2026-05-16 14:05:44 +02:00
Arthur Belleville
fbdf188f5f
feat(13-04): port modal, empty-state, table components with CSS and templ (GREEN)
- modal.css + modal.templ: backdrop/panel structure, Title/Body/Actions props
- empty-state.css + empty_state.templ: dashed border, nil-guarded Icon/Action
- table.css + table.templ: ui-table-shell wrapper, Head/Body typed props
- All 6 TestModal/TestEmptyState/TestTable tests pass; full suite green
2026-05-16 14:05:11 +02:00
Arthur Belleville
4bdb78debf
test(13-04): add failing tests for Modal, EmptyState, Table components (RED) 2026-05-16 14:04:19 +02:00
Arthur Belleville
569c6c7853
docs(13-03): complete form input components plan summary
- Input, Textarea, Select, FormField components ported from go-backend
- TDD gates: 4 RED/GREEN commits, all 13 new tests passing
- Full go test ./... is green (all packages)
2026-05-16 14:01:53 +02:00
Arthur Belleville
52fb77d4f8
feat(13-03): port select + form-field components with CSS and helpers (GREEN)
- select_helpers.go: 9 helper functions verbatim from go-backend
- select.templ: SelectProps/SelectOption structs, inline JS with __uiSelectInitAll
  and htmx:afterSwap re-init listener (Pitfall 6)
- select.css: .ui-select-control (min-height 44px), .ui-select-menu (max-height 16rem)
- form_field.templ: FormFieldProps with Label/For/Field/Error/Hint; conditional regions
- form-field.css: .ui-form-field/.ui-form-label/.ui-form-hint/.ui-form-error
- tailwind.input.css: add @import for select.css and form-field.css
- All 6 TestSelect/TestFormField tests passing; full go test ./... is green
2026-05-16 14:00:51 +02:00
Arthur Belleville
50e3fb0021
test(13-03): add failing tests for Select and FormField components (RED)
- TestSelect_RendersControl: expects ui-select-control in output
- TestSelect_HasInlineScript: expects __uiSelectInitAll in script block
- TestSelect_HasHtmxListener: expects htmx:afterSwap re-init listener
- TestFormField_RendersLabel: expects ui-form-field and ui-form-label
- TestFormField_RendersError: expects ui-form-error when Error is set
- TestFormField_NoErrorWhenEmpty: expects no ui-form-error when Error is empty
2026-05-16 13:59:21 +02:00
Arthur Belleville
9556b20ade
feat(13-03): port input.templ/input.css and textarea.templ/textarea.css (GREEN)
- input.css: .ui-input with min-height 44px, border-radius 0.75rem, focus ring
- input.templ: InputProps with ID/Name/Type/Placeholder/Value/Disabled/Required/Attrs
- textarea.css: .ui-textarea with min-height 7rem, resize vertical, focus ring
- textarea.templ: TextareaProps with ID/Name/Value/Placeholder/Rows/Disabled/Required/Attrs
- tailwind.input.css: add @import for input.css and textarea.css
- All 7 TestInput/TestTextarea tests passing
2026-05-16 13:59:03 +02:00
Arthur Belleville
ace9f5bdc4
test(13-03): add failing tests for Input and Textarea components (RED)
- TestInput_DefaultType: expects type="text" for empty Type
- TestInput_EmailType: expects type="email" for explicit Type
- TestInput_IDFallback: expects id from Name when no ID set
- TestInput_ExplicitID: expects explicit ID to take precedence
- TestTextarea_RendersClass: expects class="ui-textarea"
- TestTextarea_DefaultRows: expects rows="4" for zero Rows
- TestTextarea_ExplicitRows: expects rows="6" for explicit Rows
2026-05-16 13:58:19 +02:00
Arthur Belleville
43ffdae07f
docs(13-02): complete component API migration plan summary 2026-05-16 13:56:20 +02:00
Arthur Belleville
a30a6f9088
feat(13-02): replace CSS files, migrate card.templ to typed API, update all template hardcodes
- button.css: replaced with go-backend multi-class selector version + ghost variant rules
- badge.css: replaced with go-backend pill-shape version + primary variant
- card.css: replaced with go-backend token-based header/body/footer version
- card.templ: migrated from children passthrough to typed CardProps{Header/Body/Footer}
- ui_test.go: rewrote TestCard_RendersChildren -> TestCard_RendersTypedRegions; added TestBadge_PrimaryVariant; added textComponent helper + io import
- auth_login.templ, auth_signup.templ: migrated Card usage to typed CardProps API
- tablos.templ: migrated TabloCard to typed CardProps API with extracted tabloCardBody
- planning.templ, tasks.templ, events.templ, etapes.templ: all compound button class strings updated to multi-class pattern
- go test ./... passes (all packages green)
- just generate succeeds
2026-05-16 13:55:30 +02:00
Arthur Belleville
66f23bba77
feat(13-02): multi-class ButtonClass() + Icon field + buttonType helper in button.templ
- ButtonClass() now emits "ui-button ui-button-solid ui-button-default ui-button-md"
- Ghost variant special case: "ui-button ui-button-ghost ui-button-md" (tone omitted)
- button.templ: added Icon string field to ButtonProps, replaced inline btnType with buttonType() helper
- ui_test.go: updated TestButton_DefaultSolidMD to multi-class slice assertions
- ui_test.go: updated TestButtonClass_String and TestButtonClass_GhostVariant expectations
- All 18 ui package tests pass
2026-05-16 13:52:01 +02:00
Arthur Belleville
ab030dbe71
chore: merge executor worktree (worktree-agent-a3f5fac8dd5e3bd34) 2026-05-16 13:49:39 +02:00
Arthur Belleville
555d41f247
docs(13-01): complete design system foundation plan 01 summary
- Full CSS token vocabulary (223-line base.css) and auth.css extraction
- Ghost/Primary variant enums, IconButton/SpacingStep types, and helper functions
- All 18 tests green; TDD RED/GREEN gates documented
2026-05-16 13:48:44 +02:00
Arthur Belleville
d1499659bf
feat(13-01): extend variants.go with new enums and helpers.go with helper functions (GREEN)
- Add ButtonVariantGhost to ButtonVariant enum and NormalizedButtonVariant switch
- Add BadgeVariantPrimary to BadgeVariant enum and NormalizedBadgeVariant switch
- Add IconButtonVariant type (Neutral/Warning/Success/Danger) with normalizer
- Add IconButtonTone type (Solid/Ghost) with normalizer
- Add SpacingStep type (XS/SM/MD/LG/XL) with normalizer
- Add IconButtonClass(), SpaceXClass(), SpaceYClass() exported class functions
- Add buttonType(), inputType(), inputID(), textareaRows() helper functions to helpers.go
- Fix TestButtonClass_GhostVariant assertion to match compound class format preserved for Plan 02
2026-05-16 13:46:30 +02:00
Arthur Belleville
8602eb10a1
test(13-01): add failing tests for new variant enums and class functions (RED)
- TestButtonVariantGhost_Normalizer, TestButtonClass_GhostVariant
- TestBadgeVariantPrimary_Normalizer, TestBadgeClass_PrimaryVariant
- TestIconButtonClass_GhostNeutral, TestIconButtonClass_SolidNeutral
- TestSpaceXClass_MD, TestSpaceYClass_LG
2026-05-16 13:44:36 +02:00
Arthur Belleville
59e39fe538
feat(13-01): replace base.css with 223-line token vocabulary and extract auth.css
- Replace 28-line backend/internal/web/ui/base.css stub with full go-backend token vocabulary (223 lines, --color-brand-primary: #804eec)
- Create backend/internal/web/ui/auth.css with auth-provider button styles extracted from button.css Phase 8 block
- Update backend/tailwind.input.css to import auth.css after base.css
2026-05-16 13:43:56 +02:00
Arthur Belleville
45a914f4ea
docs(13): create phase plan 2026-05-16 13:28:09 +02:00
Arthur Belleville
593bb5bf20
fix(13): apply checker revisions to plans 04 and 05
- 13-04: add 13-03 to depends_on, bump wave 3→4 (form-field.css must exist before tailwind.input.css manifest is written)
- 13-05: bump wave 4→5 to follow 13-04; clear overclaimed requirements (DS-01–DS-09 → []); extend Task 1 automated verify with grep checks for RegisterCatalogRoute, build tag, and catalog page heading

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 13:24:46 +02:00
Arthur Belleville
9e954a40e7
docs(13): create phase 13 design system foundation plan (5 plans, 4 waves)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 13:20:43 +02:00
Arthur Belleville
a25421e2cf
docs(13): add validation strategy 2026-05-16 13:08:31 +02:00
Arthur Belleville
5bb2636577
docs(13): research design system foundation phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 13:07:59 +02:00
Arthur Belleville
e867b735d9
docs(13): UI design contract 2026-05-16 12:58:32 +02:00
Arthur Belleville
bab59fb220
fix(13): collapse typography to 2 weights, fix CTA copy, add focal point
- Heading weight 700 → 600 (resolves checker BLOCK on Dim 4 — max 2 weights)
- Modal header and empty-state title font-weight updated to match
- Empty state CTA "Add item" → "Create item" (verb + noun, Dim 1 flag)
- Catalog page focal point declaration added (Dim 2 flag)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 12:53:13 +02:00
Arthur Belleville
a0c21b0582
docs(13): UI design contract for design system foundation phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 12:48:52 +02:00
Arthur Belleville
ab64a73b1d
docs(state): record phase 13 context session 2026-05-16 12:41:32 +02:00
Arthur Belleville
3b9bd62a24
docs(13): capture phase context 2026-05-16 12:41:28 +02:00
Arthur Belleville
fcffb57df4
chore: archive v2.0 milestone 2026-05-16 11:01:12 +02:00
Arthur Belleville
7a1eaa7b0f
docs: create milestone v3.0 roadmap (5 phases) 2026-05-16 10:57:13 +02:00
Arthur Belleville
88d0187c84
docs: define milestone v3.0 requirements 2026-05-16 10:53:38 +02:00
Arthur Belleville
7b4f50f953
docs: start milestone v3.0 Design System & Visual Polish 2026-05-16 10:52:10 +02:00
Arthur Belleville
58a9ce0b03
docs(phase-10): update validation strategy 2026-05-16 10:49:50 +02:00
Arthur Belleville
207f5fd089
docs(phase-09): update validation strategy 2026-05-16 10:46:19 +02:00
Arthur Belleville
a0f62c261e
test(phase-09): add etape schema validation 2026-05-16 10:45:29 +02:00
Arthur Belleville
163be5bb32
docs: audit v2.0 milestone 2026-05-16 10:41:23 +02:00
Arthur Belleville
fa208a5bf7
docs(phase-12): update validation strategy 2026-05-16 10:38:26 +02:00
Arthur Belleville
deab7a9aa2
test(phase-12): add discussion schema validation 2026-05-16 10:37:29 +02:00
Arthur Belleville
81538bb780
docs(12-03): complete discussion realtime plan 2026-05-16 10:34:41 +02:00
Arthur Belleville
409245eac0
fix(12-03): reset discussion composer from htmx form 2026-05-16 10:32:28 +02:00
Arthur Belleville
1034efcec4
fix(12-03): clear discussion composer after suppressed swap 2026-05-16 10:29:38 +02:00
Arthur Belleville
426d89c43b
fix(12-03): use htmx request source for discussion posts 2026-05-16 10:27:56 +02:00
Arthur Belleville
6f17c3016f
fix(12-03): suppress sender duplicate discussion rows 2026-05-16 10:24:34 +02:00
Arthur Belleville
d15c3748e4
feat(12-03): add discussion SSE stream 2026-05-16 10:18:33 +02:00
Arthur Belleville
c6dcb680bd
test(12-03): add discussion SSE coverage 2026-05-16 10:17:23 +02:00
Arthur Belleville
0fa34cebf0
docs(12-02): complete discussion unread plan 2026-05-16 10:16:24 +02:00
Arthur Belleville
3111b6e011
feat(12-02): implement discussion unread badges 2026-05-16 10:15:38 +02:00
Arthur Belleville
e3c8d51782
test(12-02): add discussion unread coverage 2026-05-16 10:12:56 +02:00
Arthur Belleville
6af4d70d51
docs(12-01): complete discussion foundation plan 2026-05-16 10:12:06 +02:00
Arthur Belleville
c5477e4ceb
feat(12-01): implement discussion tab and posting 2026-05-16 10:11:14 +02:00
Arthur Belleville
39e21be126
test(12-01): add discussion handler coverage 2026-05-16 10:08:34 +02:00
Arthur Belleville
68884daf11
feat(12-01): add discussion schema and queries 2026-05-16 10:07:12 +02:00
Arthur Belleville
f848c42e54
docs(12): create phase plan 2026-05-16 10:04:06 +02:00
Arthur Belleville
164fa1133c
docs(state): record phase 12 UI session 2026-05-16 09:55:44 +02:00
Arthur Belleville
50a3f255fc
docs(12): UI design contract 2026-05-16 09:55:43 +02:00
Arthur Belleville
7ffa3600a0
docs(state): record phase 12 context session 2026-05-16 09:33:06 +02:00
Arthur Belleville
bfd1468bc4
docs(12): capture phase context 2026-05-16 09:32:55 +02:00
Arthur Belleville
74a5f17d09
docs(11): verify phase completion 2026-05-16 09:07:50 +02:00
Arthur Belleville
abc587b4a5
docs(11): add code review report 2026-05-16 09:06:45 +02:00
Arthur Belleville
9a8cdf097f
docs(11-02): complete verification plan 2026-05-16 09:05:59 +02:00
Arthur Belleville
bb84d70569
fix(11-02): show planning event dates 2026-05-16 08:39:10 +02:00
Arthur Belleville
404b545a5d
docs(11-01): complete planning agenda plan 2026-05-16 07:28:12 +02:00
Arthur Belleville
2989c0b917
feat(11-01): implement planning agenda page 2026-05-16 07:26:49 +02:00
Arthur Belleville
c5c3bbe2d0
test(11-01): add planning agenda red coverage 2026-05-16 07:24:23 +02:00
Arthur Belleville
66e3846614
docs(11): begin execution 2026-05-16 07:23:12 +02:00
Arthur Belleville
9de18b00a2
docs(11): mark planning ready to execute 2026-05-16 07:22:00 +02:00
Arthur Belleville
29b1e904c0
docs(11): create phase plan 2026-05-16 07:21:34 +02:00
Arthur Belleville
aa897b1fab
docs(state): record phase 11 UI-SPEC session 2026-05-16 07:16:37 +02:00
Arthur Belleville
3c5622b101
docs(11): UI design contract 2026-05-16 07:16:28 +02:00
Arthur Belleville
01f2a073a2
docs(state): record phase 11 context session 2026-05-16 07:11:52 +02:00
Arthur Belleville
9b32ef9378
docs(11): capture phase context 2026-05-16 07:11:43 +02:00
Arthur Belleville
34d2c23e20
docs(phase-10): complete phase execution 2026-05-16 06:46:15 +02:00
Arthur Belleville
1d760d5540
test(10-04): add final events regression coverage 2026-05-16 00:36:40 +02:00
Arthur Belleville
a94550e72b
docs(10-03): complete event navigation plan 2026-05-16 00:35:41 +02:00
Arthur Belleville
ebd31b5645
feat(10-03): add event navigation and user range query 2026-05-16 00:35:09 +02:00
Arthur Belleville
0692dd2d4f
test(10-03): add failing event navigation query tests 2026-05-16 00:34:31 +02:00
Arthur Belleville
0dc0e8978f
docs(10-02): complete event mutation plan 2026-05-16 00:33:33 +02:00
Arthur Belleville
614003f165
feat(10-02): add event edit and delete flows 2026-05-16 00:32:55 +02:00
Arthur Belleville
e5f083d2a8
test(10-02): add failing event mutation tests 2026-05-16 00:30:52 +02:00
Arthur Belleville
c45e96d610
docs(10-01): complete events creation plan 2026-05-16 00:29:27 +02:00
Arthur Belleville
0bfe8cfbb4
feat(10-01): add events calendar creation slice 2026-05-16 00:27:58 +02:00
Arthur Belleville
4fbd960621
test(10-01): add failing events create calendar tests 2026-05-16 00:24:33 +02:00
Arthur Belleville
a15596cd09
docs(10): create phase plan 2026-05-16 00:19:03 +02:00
Arthur Belleville
0b894f494d
docs(10): map event implementation patterns 2026-05-16 00:15:20 +02:00
Arthur Belleville
a569cffd41
docs(state): record phase 10 UI spec 2026-05-16 00:12:29 +02:00
Arthur Belleville
29ae0aefe5
docs(10): UI design contract 2026-05-16 00:12:17 +02:00
Arthur Belleville
0148d71d06
docs(10): add validation strategy 2026-05-16 00:09:55 +02:00
Arthur Belleville
9bab2801d8
docs(10): research events phase 2026-05-16 00:09:52 +02:00
Arthur Belleville
3aeace89fb
docs(state): record phase 10 context session 2026-05-16 00:04:48 +02:00
Arthur Belleville
c896b26f47
docs(10): capture phase context 2026-05-16 00:04:26 +02:00
Arthur Belleville
ec6bb7d11c
docs(09): close etape UAT and summary 2026-05-15 23:48:15 +02:00
Arthur Belleville
f9fc7a1e34
fix(09): honor selected etape on task create 2026-05-15 23:46:32 +02:00
Arthur Belleville
c5513df987
test(09): complete UAT - 4 passed, 1 issue 2026-05-15 23:44:44 +02:00
Arthur Belleville
ee62ff9f9b
fix(09): refresh etape counts on task delete 2026-05-15 23:02:05 +02:00
Arthur Belleville
0c95049447
fix(09): refresh etape counts on task create 2026-05-15 22:59:01 +02:00
Arthur Belleville
cf07c29ae5
test(09-04): harden db-backed regressions 2026-05-15 22:54:46 +02:00
Arthur Belleville
3a3ecf5803
fix(09-04): preserve etape filter on reorder 2026-05-15 22:49:40 +02:00
Arthur Belleville
55263e4a52
test(09-04): add etape reorder regressions 2026-05-15 22:49:09 +02:00
Arthur Belleville
be86eb7d80
docs(09-03): complete task assignment plan 2026-05-15 22:48:12 +02:00
Arthur Belleville
b22d79d972
feat(09-03): add task etape selector 2026-05-15 22:47:56 +02:00
Arthur Belleville
9f6c7eb044
test(09-03): add task etape assignment tests 2026-05-15 22:46:14 +02:00
Arthur Belleville
3ce7c8ea4f
docs(09-02): complete etape management plan 2026-05-15 22:45:10 +02:00
Arthur Belleville
4af623a57b
feat(09-02): manage etapes 2026-05-15 22:44:50 +02:00
Arthur Belleville
9b89282692
test(09-02): add etape management tests 2026-05-15 22:42:39 +02:00
Arthur Belleville
c1c20c4158
docs(09-01): complete etape slice plan 2026-05-15 22:41:23 +02:00
Arthur Belleville
565bb88df5
feat(09-01): add etape task slice 2026-05-15 22:40:25 +02:00
Arthur Belleville
a8a3e5f596
test(09-01): add failing etape slice tests 2026-05-15 22:33:40 +02:00
Arthur Belleville
0e6347ef26
docs(09): create phase plan 2026-05-15 22:30:18 +02:00
Arthur Belleville
29691e82a3
docs(state): record phase 9 UI-SPEC session 2026-05-15 22:26:04 +02:00
Arthur Belleville
1e0821915f
docs(09): UI design contract 2026-05-15 22:25:43 +02:00
Arthur Belleville
df741e43ee
docs(09): research etapes implementation 2026-05-15 22:21:27 +02:00
Arthur Belleville
a7d77c607c
docs(state): set phase 9 ready for planning 2026-05-15 22:06:24 +02:00
Arthur Belleville
37016cfd7b
docs(state): record phase 9 context session 2026-05-15 22:05:50 +02:00
Arthur Belleville
ebc209ebd9
docs(09): capture phase context 2026-05-15 22:05:46 +02:00
Arthur Belleville
981d2a0174
docs(08): verify Nyquist validation coverage 2026-05-15 21:52:33 +02:00
Arthur Belleville
4101138f15
docs(08): verify social sign-in threat mitigations 2026-05-15 21:49:09 +02:00
Arthur Belleville
bc617f4632
test(08): complete UAT - 7 passed, 0 issues 2026-05-15 21:46:30 +02:00
Arthur Belleville
90af9bdaef
feat(08): disable apple sign-in 2026-05-15 21:41:22 +02:00
Arthur Belleville
85b8c7bce1
chore(dev): load backend env in just recipes 2026-05-15 21:26:55 +02:00
Arthur Belleville
f9f528544d
docs(08): complete social sign-in execution 2026-05-15 21:13:59 +02:00
Arthur Belleville
6e6583636f
feat(08-05): add linked providers view and provider docs 2026-05-15 21:10:45 +02:00
Arthur Belleville
59fd6b15b5
feat(08-04): show social sign-in controls on auth pages 2026-05-15 21:09:14 +02:00
Arthur Belleville
a8b6a03eac
feat(08-03): add apple social sign-in flow 2026-05-15 21:06:08 +02:00
Arthur Belleville
6779663c8a
feat(08-02): add google social sign-in flow 2026-05-15 21:03:30 +02:00
Arthur Belleville
2d004cd251
feat(08-01): add social identity schema foundation 2026-05-15 20:59:34 +02:00
Arthur Belleville
2f4a4f9ebb
docs(08): create social sign-in phase plans 2026-05-15 20:50:59 +02:00
Arthur Belleville
25e07a7f44
docs(state): record phase 8 UI-SPEC session 2026-05-15 20:45:47 +02:00
Arthur Belleville
3dfe054fcc
docs(08): UI design contract 2026-05-15 20:45:27 +02:00
Arthur Belleville
6ac1dbd8fc
docs(phase-8): add validation strategy 2026-05-15 20:41:58 +02:00
Arthur Belleville
23a69272b9
docs(state): record phase 8 context session 2026-05-15 20:36:24 +02:00
Arthur Belleville
40fa25fd5f
docs(08): capture phase context 2026-05-15 20:35:41 +02:00
Arthur Belleville
cd8034f33b
docs: create milestone v2.0 roadmap (5 phases) 2026-05-15 20:16:20 +02:00
Arthur Belleville
39a1e4d21d
docs: define milestone v2.0 requirements 2026-05-15 20:15:26 +02:00
Arthur Belleville
367364e9f8
docs: research milestone v2.0 collaboration planning social sign-in 2026-05-15 20:11:23 +02:00
Arthur Belleville
0d23d94700
docs: start milestone v2.0 collaboration planning social sign-in 2026-05-15 20:09:23 +02:00
Arthur Belleville
6e49771788
Add pattern file to background worker 2026-05-15 19:58:05 +02:00
Arthur Belleville
3998a5ab92
Made various improvements to the file management 2026-05-15 19:57:46 +02:00
Arthur Belleville
03387ed6a7
docs(05): fix UI-SPEC typography and copywriting per checker block
- Collapse 5-size type scale to 4 by removing 12px from page scale;
  annotate text-xs as badge-system token scoped to .ui-badge only
- Metadata (file size, date) stays at 14px, differentiated by slate-500
- Update CTAs to verb+noun: Upload File, Delete File, Download File

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 19:30:36 +02:00
Arthur Belleville
e939563a49
docs(05): UI design contract for files phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 19:27:53 +02:00
Arthur Belleville
7d65cb4d94
docs(07): mark review findings fixed
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 18:57:05 +02:00
Arthur Belleville
4ea4d28e6e
fix(07): WR-05 sanitize upload filename with filepath.Base and length cap
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 18:56:11 +02:00
Arthur Belleville
e7a66c44cf
fix(07): WR-03 add SetMaxOpenConns(2) on migration sql.DB pool
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 18:55:40 +02:00
Arthur Belleville
ab12bf0962
fix(07): WR-02 move rate limit check before validation in LoginPostHandler
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 18:55:27 +02:00
Arthur Belleville
b61f36f17e
fix(07): WR-01 NewRouter returns error instead of panicking on bad static FS
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 18:54:49 +02:00
Arthur Belleville
fbda7cbe5e
fix(07): CR-02 call cancel() explicitly after S3 Delete, not via defer
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 18:53:04 +02:00
Arthur Belleville
62edbca44e
docs(phase-07): evolve PROJECT.md after phase completion 2026-05-15 18:48:20 +02:00
Arthur Belleville
2a73bba4e1
docs(phase-07): complete phase execution 2026-05-15 18:47:58 +02:00
Arthur Belleville
5fc4705bd3
fix(07): replace minioadmin placeholder creds and add worker->web migration gate 2026-05-15 18:46:30 +02:00
Arthur Belleville
c8bce7669f
test(07): persist human verification items as UAT 2026-05-15 18:33:14 +02:00
Arthur Belleville
087a933fe7
test(07): add phase verification report 2026-05-15 18:33:02 +02:00
Arthur Belleville
9ff40ac821
docs(07): add code review report 2026-05-15 18:29:46 +02:00
Arthur Belleville
7bca961bb0
docs(07-03): complete production compose stack and runbook plan
- SUMMARY for 07-03: docker-compose.prod.yaml, deploy/Caddyfile, README runbook
2026-05-15 18:26:01 +02:00
Arthur Belleville
f261fb39b8
docs(07-03): extend README with Deploy, Rollback, and Incident Runbook sections
- Deploy section: prerequisites, first-time setup, deploying new versions (DEPLOY-05)
- First-time setup documents DATABASE_URL internal URL, SESSION_SECRET generation,
  full S3/R2 var list, chmod 600 .env.prod reminder (T-07-10), TLS staging note
- Rollback section: image tag redeployment + break-glass schema rollback via goose CLI
- Incident Runbook: /readyz 503, Caddy TLS rate limits, log viewing, distroless debug
  (ephemeral busybox container technique for shell-less runtime image, RESEARCH Pitfall 7)
2026-05-15 18:25:03 +02:00
Arthur Belleville
273f0632be
feat(07-03): add docker-compose.prod.yaml and deploy/Caddyfile
- Production compose stack with postgres, web, worker, caddy services (D-01..D-04, D-08)
- postgres service has no host ports binding (internal network only, T-07-09 mitigated)
- web and worker use same image with different command: values (/app/web, /app/worker)
- Both web and worker depend_on postgres with service_healthy condition (T-07-12 mitigated)
- Caddy handles TLS via Let's Encrypt with persistent caddy_data and caddy_config volumes (D-04)
- Caddyfile uses {$DOMAIN} env var interpolation for the site block (RESEARCH Pattern 6)
- Caddyfile includes Let's Encrypt staging note to avoid rate limits (RESEARCH Pitfall 4)
2026-05-15 18:23:13 +02:00
Arthur Belleville
45701bf8aa
chore: merge executor worktree (worktree-agent-ad2dff45f7520558c) 2026-05-15 18:20:51 +02:00
Arthur Belleville
2329e19e75
docs(07-02): complete plan summary — Dockerfile and .env.example S3/R2 vars 2026-05-15 18:20:38 +02:00
Arthur Belleville
0781403f5c
feat(07-02): add S3/R2, DOMAIN, and MAX_UPLOAD_SIZE_MB vars to .env.example
- Add S3_ENDPOINT, S3_BUCKET, S3_REGION, S3_ACCESS_KEY, S3_SECRET_KEY with MinIO dev defaults
- Add S3_USE_PATH_STYLE (true for MinIO, false for R2 virtual-hosted)
- Add MAX_UPLOAD_SIZE_MB=25 with default note
- Add commented DOMAIN=app.yourdomain.com for Caddy TLS in docker-compose.prod.yaml (D-04)
- Clarify TEST_DATABASE_URL is dev/test only and must not appear in .env.prod
- All original vars (DATABASE_URL, SESSION_SECRET, PORT, ENV) preserved
2026-05-15 18:19:58 +02:00
Arthur Belleville
f29bf0c765
feat(07-02): multi-stage Dockerfile for web + worker binaries
- Stage 1 (assets): downloads Tailwind v4.0.0 CLI, HTMX@2, Sortable.js 1.15.7; compiles minified CSS
- Stage 2 (builder): runs templ generate @v0.3.1020; CGO_ENABLED=0 go build for /app/web and /app/worker
- Stage 3 (runtime): gcr.io/distroless/static-debian12:nonroot; no CMD per D-08
- No .env files COPY'd into any layer (T-07-05 mitigated)
2026-05-15 18:19:32 +02:00
Arthur Belleville
5550befffc
chore: merge executor worktree (worktree-agent-a1df44c5ba4be47de) 2026-05-15 18:17:11 +02:00
Arthur Belleville
735106f797
docs(07-01): complete plan summary — embed anchor, RunMigrations, health endpoint split
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 18:16:05 +02:00
Arthur Belleville
bdd3cba314
feat(07-01): wire embed.FS into NewRouter and RunMigrations into cmd/web/main.go
- backend/internal/web/router.go: staticDir string -> staticFS fs.FS; /healthz uses HealthzHandler(); /readyz registered with ReadyzHandler(pinger); embedded FS served via fs.Sub()
- backend/cmd/web/main.go: import assets "backend"; db.RunMigrations(ctx, pool, assets.Migrations) before router; web.NewRouter now receives assets.Static
- All *_test.go NewRouter call sites updated from "./static" to os.DirFS("./static"); "os" import added where missing
2026-05-15 18:14:33 +02:00
Arthur Belleville
77e37cb21b
feat(07-01): embed.go + RunMigrations + HealthzHandler()/ReadyzHandler() split
- backend/embed.go: package assets with //go:embed all:static and //go:embed migrations
- backend/internal/db/migrate.go: RunMigrations using pgx/v5/stdlib bridge to goose.Up()
- backend/internal/web/handlers.go: HealthzHandler() no-arg liveness + ReadyzHandler(pinger) readiness
- backend/internal/web/handlers_test.go: TestHealthz_OK (no pinger), TestReadyz_OK, TestReadyz_Down added; TestHealthz_Down deleted
2026-05-15 18:14:26 +02:00
Arthur Belleville
aa3429717f
test(07-01): add failing tests for HealthzHandler (no-arg) and ReadyzHandler split
- TestHealthz_OK now calls HealthzHandler() with no args (liveness, no db field)
- TestHealthz_Down deleted (new HealthzHandler has no failure mode)
- TestReadyz_OK added: ReadyzHandler(stubPinger{err: nil}) -> 200 + db:ok
- TestReadyz_Down added: ReadyzHandler(stubPinger{err: ...}) -> 503 + degraded
2026-05-15 18:08:16 +02:00
Arthur Belleville
8ae83f6c50
docs(07): create phase plan 2026-05-15 18:06:08 +02:00
Arthur Belleville
dbe9d493be
docs(07): create phase 7 plan — deploy v1 (3 plans, 3 waves)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 17:57:46 +02:00
Arthur Belleville
8fbe87295a
docs(07): add validation strategy 2026-05-15 17:47:42 +02:00
Arthur Belleville
588c03dae2
docs(07): research phase domain 2026-05-15 17:46:37 +02:00
Arthur Belleville
e14fd36fdc
docs(07): capture phase context 2026-05-15 17:35:43 +02:00
Arthur Belleville
eec691442a
docs(06): resolve SC-3/SC-4 conflict — accept D-03/D-06 deferrals
ROADMAP SC-3 (list-failed-jobs CLI) and SC-4 (web binary enqueue) struck
through as deferred per CONTEXT.md decisions D-03 and D-06. VERIFICATION.md
status updated to complete (3/3 active success criteria).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 17:21:25 +02:00
Arthur Belleville
8b64b48490
docs(06): create gap-closure plan 04 — list-failed-jobs CLI and web enqueue wiring
Closes SC-3 (WORK-04) with a list-failed-jobs subcommand in cmd/worker and
SC-4 (WORK-01) by wiring a river insert-only client into cmd/web with a
/debug/enqueue-test handler that proves the web→worker enqueue path.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 17:12:25 +02:00
Arthur Belleville
7a54755618
docs(06): add phase verification report — gaps found
SC-3 (failed-job CLI surface) and SC-4 (web binary enqueue) not yet implemented.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 16:49:20 +02:00
Arthur Belleville
5e8dd4e4e4
docs(06): add code review report 2026-05-15 16:46:28 +02:00
Arthur Belleville
a81e112527
docs(06-03): human verification checkpoint passed
All WORK-01 through WORK-04 requirements verified live against Postgres + MinIO.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 16:43:48 +02:00
Arthur Belleville
9e07407484
docs(06-02): complete cmd/worker river wiring plan
- 06-02-SUMMARY.md: river wiring summary with commits, decisions, threat flag review
- STATE.md: decisions, metrics, notes, SUMMARY reference added for Plan 02
- ROADMAP.md: 06-02 marked complete (2/3 plans executed)
2026-05-15 16:39:54 +02:00
Arthur Belleville
e202ad3a9e
feat(06-02): add just worker target and document worker in README
- justfile: worker target depends on db-up, passes MinIO dev defaults
  (DATABASE_URL, S3_ENDPOINT/BUCKET/REGION/ACCESS_KEY/SECRET_KEY/USE_PATH_STYLE)
- README: replace skeleton section with full "Running the Worker" docs
  (just worker command, expected logs, single-worker constraint, graceful shutdown,
   failed job retry observation)
2026-05-15 16:38:01 +02:00
Arthur Belleville
6e70478417
feat(06-02): replace cmd/worker skeleton with full river wiring
- rivermigrate at startup (idempotent, before client construction)
- S3 store init from env vars (S3_ENDPOINT/S3_BUCKET/S3_ACCESS_KEY/S3_SECRET_KEY/S3_REGION/S3_USE_PATH_STYLE)
- signal.NotifyContext created AFTER all startup I/O (PATTERNS.md critical ordering)
- HeartbeatWorker + OrphanCleanupWorker registered via river.AddWorker
- river.Client with slog.Default() Logger, SlogErrorHandler, MaxWorkers:10
- HeartbeatArgs periodic every 1 min (RunOnStart:true), OrphanCleanupArgs every 1 hr
- StopAndCancel(10s timeout) on shutdown; pool.Close after StopAndCancel
2026-05-15 16:37:20 +02:00
Arthur Belleville
94ac095dee
docs(06-01): complete jobs foundation plan 2026-05-15 16:35:31 +02:00
Arthur Belleville
a1c2828dc4
feat(06-01): implement internal/jobs package with workers and error handler
- HeartbeatArgs + HeartbeatWorker (logs slog.Info on each tick)
- OrphanCleanupArgs + OrphanCleanupWorker (S3 delete then DB delete loop)
- NewOrphanCleanupWorker constructor with pool + FileStorer injection
- SlogErrorHandler implementing river.ErrorHandler (HandleError + HandlePanic)
- fileQuerier interface for test injection without real DB
- Unit tests: 7 tests pass (pure mock-based, no DB required)
- go build ./... exits 0
2026-05-15 16:34:08 +02:00
Arthur Belleville
62e5e3eb60
feat(06-01): add river dependency and ListOrphanFiles sqlc query
- go get github.com/riverqueue/river@v0.37.0 + riverpgxv5@v0.37.0
- append ListOrphanFiles :many query to files.sql (orphan tablo_files rows)
- regenerate sqlc: ListOrphanFilesRow{ID, TabloID, S3Key} exported
- go build ./... exits 0
2026-05-15 16:32:48 +02:00
Arthur Belleville
71d9c32e85
docs(06): create phase plan 2026-05-15 16:30:23 +02:00
Arthur Belleville
f242b7184f
docs(06): create phase 6 background worker plans
Three plans: Wave 1 adds river dependency + internal/jobs package with unit
tests; Wave 2 wires cmd/worker/main.go with full river runtime + justfile
target + README; Wave 3 is human-verify checkpoint.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 16:20:11 +02:00
Arthur Belleville
58cfac4955
docs(phase-6): add validation strategy 2026-05-15 16:12:51 +02:00
Arthur Belleville
27cecc6701
docs(06): research phase background-worker 2026-05-15 16:12:11 +02:00
Arthur Belleville
d8a130cd01
docs(state): record phase 6 context session 2026-05-15 15:13:11 +02:00
Arthur Belleville
9d1e24fc7e
docs(06): capture phase context 2026-05-15 15:13:06 +02:00
Arthur Belleville
8215f53356
docs(05-files): mark validation nyquist_compliant true, fill gap map
- Set nyquist_compliant: true and wave_0_complete: true in frontmatter
- Update Per-Task Verification Map: FILE-01..06 integration tests marked ⚠️
  (clean skip without TEST_DATABASE_URL); new unit tests marked  green
- Check all Wave 0 requirements as complete
- Fill in Validation Sign-Off checklist

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 13:29:13 +02:00
Arthur Belleville
cb7d5d1dd1
test(05-files): add pure unit tests for formatBytes, byteCountReader, and content-type sniff
Gap fill: three no-infrastructure unit tests that run without TEST_DATABASE_URL or S3_ENDPOINT:
- backend/templates/files_helpers_test.go — formatBytes boundary cases (B/KB/MB/GB)
- backend/internal/files/store_unit_test.go — byteCountReader accumulation, io.ErrUnexpectedEOF
  guard for small files, and MultiReader body reconstruction after 512-byte sniff

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 13:29:08 +02:00
Arthur Belleville
7fed6d1049
docs(phase-5): add security threat verification 2026-05-15 12:54:45 +02:00
Arthur Belleville
3a7726e6ed
docs(05): add code review fix report 2026-05-15 12:51:29 +02:00
Arthur Belleville
49e84c8176
fix(05-WR-01): raise ReadTimeout/WriteTimeout to 120s for large uploads
15s was too short for 25MB uploads on slow connections (~256KB/s takes
~100s). Both timeouts are raised to 120s to accommodate MAX_UPLOAD_SIZE_MB
at worst-case bandwidth with headroom.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 12:50:25 +02:00
Arthur Belleville
690ea2ddaf
fix(05): CR-01/WR-02/WR-03/WR-04 handlers_files.go fixes
- CR-01: add S3 cleanup before 500 when InsertTabloFile fails
- WR-02: validate empty filename, return 400 before S3 upload
- WR-03: remove dead errMsg variable (was silenced with _ = errMsg)
- WR-04: delete itoa/formatMBError helpers, inline strconv.Itoa

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 12:50:07 +02:00
Arthur Belleville
ab30db4a2f
docs(phase-5): complete phase execution 2026-05-15 12:46:25 +02:00
Arthur Belleville
1876ad0956
test(05): persist human verification items as UAT 2026-05-15 12:46:16 +02:00
Arthur Belleville
7fb3156638
test(05): add phase verification report 2026-05-15 12:46:02 +02:00
Arthur Belleville
f93ef972ad
docs(05): add code review report 2026-05-15 12:42:20 +02:00
Arthur Belleville
aab336fa36
docs(phase-05): update tracking after wave 4 2026-05-15 12:38:20 +02:00
Arthur Belleville
facd2846f2
docs(05-04): complete Phase 5 verification checkpoint
- Pre-flight automation passed: go test ./... exits 0, go build exits 0
- Human-verify checkpoint auto-approved (AUTO_MODE=true)
- All FILE-01..06 requirements confirmed implemented in Plans 01-03
2026-05-15 12:37:48 +02:00
Arthur Belleville
fe4f166ce3
docs(phase-05): update tracking after wave 3 2026-05-15 12:36:06 +02:00
Arthur Belleville
e30d3c3d7f
docs(05-03): complete file download + delete plan SUMMARY
- All six FILE requirements (FILE-01..06) implemented across Plans 01-03
- TDD gates documented (RED 98a5a02, GREEN 9d4dd4f)
- Self-check passed
2026-05-15 12:35:13 +02:00
Arthur Belleville
9d4dd4f3e2
feat(05-03): implement FileDownloadHandler, FileDeleteConfirmHandler, FileDeleteHandler
- FileDownloadHandler: nil guard → loadOwnedTabloForFile → PresignDownload → 302 redirect (FILE-04)
- FileDeleteConfirmHandler: nil guard → loadOwnedTabloForFile → render FileDeleteConfirmFragment
- FileDeleteHandler: nil guard → loadOwnedTabloForFile → S3 Delete (log+continue) → DeleteTabloFile → FileRowGone HTMX / 303 redirect (FILE-05, FILE-06)
- Add FileDeleteConfirmFragment templ component mirroring TaskDeleteConfirmFragment pattern (T-05-03-05)
2026-05-15 12:34:07 +02:00
Arthur Belleville
98a5a02b93
test(05-03): add RED test scaffold for file download + delete handlers
- Expand stubbedFileStorer with deletedKey tracking and deleteErr injection field
- Implement TestFileDownload (FILE-04): 302 redirect to presigned URL
- Implement TestFileDownload_NonOwner: non-owner gets 404
- Implement TestFileDelete (FILE-05): HTMX delete, S3+DB both deleted
- Implement TestFileDelete_S3Failure: S3 error does not abort DB delete, 200 returned
- Implement TestFileOwnership (FILE-06): non-owner gets 404 on all three routes
2026-05-15 12:32:49 +02:00
Arthur Belleville
072eda1028
docs(phase-05): update tracking after wave 2 2026-05-15 12:30:36 +02:00
Arthur Belleville
99719e6e96
docs(05-02): complete file upload + tab navigation plan SUMMARY
- Tasks: 2 + RED scaffold committed
- Commits: cc0d6cf (RED), f50836f (GREEN handlers), a12c5ab (templates + router + wiring)
- All acceptance criteria met; go build + go test ./... pass
- Known stubs: FileDownloadHandler/DeleteHandler/DeleteConfirmHandler (Plan 03)
2026-05-15 12:29:42 +02:00
Arthur Belleville
a12c5abea6
feat(05-02): 3-tab layout + files templates + router + main.go S3 wiring
- tablos.templ: TabloDetailPage gains files+activeTab params, 3-tab nav with hx-push-url
- tablos.templ: TabloOverviewTabFragment + TasksTabFragment (wraps KanbanBoard) added
- files.templ: FilesTabFragment, FileUploadForm (hx-encoding=multipart/form-data),
  FileListRow, FileListEmpty, FileRowGone, UploadErrorFragment
- files_helpers.go: formatBytes() converts int64 bytes to human-readable string
- router.go: fileDeps FilesDeps param added; TabloTasksTabHandler + file routes wired
- handlers_tablos.go: both TabloDetailPage call sites updated (nil, 'overview')
- main.go: S3_ENDPOINT/S3_BUCKET/S3_REGION env vars read; files.NewStore constructed;
  fileDeps wired; nil filesStore allowed when S3 env unset (503 from handlers)
- All test routers updated to pass FilesDeps{} in new param position
2026-05-15 12:28:33 +02:00
Arthur Belleville
f50836fa31
feat(05-02): implement FilesDeps + FileUploadHandler + TabloFilesTabHandler + TabloTasksTabHandler
- FilesDeps struct with Queries, Files FileStorer, MaxUploadMB
- loadOwnedTabloForFile helper (mirrors loadOwnedTabloForTask)
- TabloFilesTabHandler: nil guard first, loadOwnedTablo, list files, HTMX/full-page dispatch
- TabloTasksTabHandler: loadOwnedTablo, list tasks, HTMX/full-page dispatch
- FileUploadHandler: nil guard, MaxBytesReader before ParseMultipartForm, S3 key files/{uuid}, InsertTabloFile, list + redirect
- FileDownloadHandler/FileDeleteConfirmHandler/FileDeleteHandler: 501 stubs for Plan 03
- Security: D-04 S3 key isolation, T-05-02-02 size guard, T-05-02-04 ownership
2026-05-15 12:28:07 +02:00
Arthur Belleville
cc0d6cfd4e
test(05-02): add RED test scaffold for file upload and tab handlers
- TestFileUpload: POST /tablos/{id}/files → 303 redirect + DB row + S3 key check
- TestFileUploadTooLarge: oversized file → 422 + 'too large' message
- TestFilesList: GET /tablos/{id}/files lists pre-inserted file with filename + size
- TestFilesTab: HTMX fragment vs full-page rendering
- stubbedFileStorer records uploadedKey for assertion
- TestFileDownload/Delete/Ownership remain t.Skip (Plan 03)
2026-05-15 12:24:40 +02:00
Arthur Belleville
74af9d7052
docs(phase-05): update tracking after wave 1 2026-05-15 12:21:26 +02:00
Arthur Belleville
848dca9263
docs(05-01): complete files foundation plan SUMMARY
- Wave 0: aws-sdk-go-v2 modules, 0005_files migration, sqlc queries, files.Store, RED test scaffold, MinIO in compose
- go build ./... passes; all 6 TestFile* stubs SKIP; TestStoreImplementsFileStorer PASS
2026-05-15 12:20:05 +02:00
Arthur Belleville
3327a4286d
test(05-01): add RED test scaffold for FILE-01..06 and MinIO in compose.yaml
- Create handlers_files_test.go: six TestFile* stubs (all t.Skip), stubbedFileStorer no-op implementing files.FileStorer
- Create store_test.go: compile-time interface assertion, TestNewStore_SkipIfNoEndpoint skips when S3_ENDPOINT unset
- Update compose.yaml: add minio (port 9000/9001) and minio-init services; minio-init uses restart: no (Pitfall 7); add minio_data volume
2026-05-15 12:19:23 +02:00
Arthur Belleville
e0d72747e0
feat(05-01): add aws-sdk-go-v2 modules, 0005_files migration, sqlc queries, and files.Store
- Add four aws-sdk-go-v2 modules: core, config, credentials, service/s3
- Write 0005_files.sql migration (tablo_files table with ON DELETE CASCADE)
- Write internal/db/queries/files.sql with InsertTabloFile, ListFilesByTablo, GetTabloFileByID, DeleteTabloFile
- Implement internal/files/store.go: FileStorer interface, Store struct, NewStore (UsePathStyle for MinIO), Upload (sniff+stream+bytecount), Delete, PresignDownload
- sqlc generate produces files.sql.go + TabloFile model (gitignored, regeneratable)
2026-05-15 12:18:16 +02:00
Arthur Belleville
5ce8b70f69
docs(05): create phase plan
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 12:14:48 +02:00
Arthur Belleville
f115082bd5
docs(05): create phase 5 file upload plans (4 plans, 4 waves)
Adds 4 PLAN.md files for Phase 5 — Files. Wave 1 lays the S3
foundation (aws-sdk-go-v2, migration, FileStorer, MinIO compose).
Wave 2 delivers the upload + list vertical slice with 3-tab tablo
layout. Wave 3 closes download + delete. Wave 4 is the browser
verify checkpoint.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 11:58:52 +02:00
Arthur Belleville
261c85ae73
docs(05): research phase files domain 2026-05-15 11:46:09 +02:00
Arthur Belleville
740d367dc4
docs(state): record phase 5 context session 2026-05-15 10:58:24 +02:00
Arthur Belleville
1c02de475e
docs(05): capture phase context 2026-05-15 10:58:19 +02:00
Arthur Belleville
9e6ab6d5aa
docs(04): mark review findings fixed
All 6 in-scope findings (CR-01, CR-02, WR-01, WR-02, WR-03, WR-04)
have been applied and verified. Updated status from issues_found to fixed.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:19:54 +02:00
Arthur Belleville
61e6e778e0
fix(04-WR-04): guard against int32 overflow in TaskCreateHandler position arithmetic
maxPos + 100 could silently overflow to a negative value when maxPos
approached MaxInt32. Added a maxAllowedPosition guard that returns a
validation error before the InsertTask call if the column position space
is exhausted.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:19:48 +02:00
Arthur Belleville
f6ab318f4e
fix(04-WR-03): trim whitespace from description in TaskUpdateHandler
A description of spaces-only was being stored as a valid non-null DB value
because the empty-string check ran before trimming. Now consistent with how
other nullable text fields are handled.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:19:30 +02:00
Arthur Belleville
3dafba72cc
fix(04-WR-02): set HX-Retarget/HX-Reswap on 422 path in TaskCreateHandler
Without these headers, HTMX used the form's own hx-target="#column-{status}"
+ hx-swap="beforeend", appending the error form into the task column and
destroying all visible task cards. The error form now lands back in the
add-task slot where it belongs.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:19:10 +02:00
Arthur Belleville
3d32f2d92f
fix(04-WR-01): check UpdateTask errors in TaskReorderHandler instead of discarding
Both the single-task branch and the main loop were using _, _ = to
discard UpdateTask errors. Now both log the error and return 500 so
the client is never shown a false success when DB writes fail.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:18:53 +02:00
Arthur Belleville
392b5321be
fix(04-CR-02): replace fmt.Fprintf in TaskDeleteHandler with TaskCardGone templ component
The raw fmt.Fprintf bypassed templ's auto-escaping pipeline and was
inconsistent with every other handler. Added TaskCardGone(taskID uuid.UUID)
to tasks.templ and updated TaskDeleteHandler to use it. Ran just generate.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:18:34 +02:00
Arthur Belleville
e97f4988bd
fix(04-CR-01): add r.ParseForm() to TaskCreateHandler and TaskUpdateHandler
Both handlers were missing the mandatory ParseForm call before reading
PostFormValue. This caused gorilla/csrf (which reads the body for CSRF
token validation) to consume the body, leaving PostFormValue to return
empty strings. TaskReorderHandler was used as the correct reference.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:17:49 +02:00
Arthur Belleville
142ca547ea
docs(04): add code review report 2026-05-15 10:10:41 +02:00
Arthur Belleville
879f7b1161
docs(phase-04): complete phase execution — tasks kanban
7/7 TASK requirements verified. Human browser verification done in
plan 04-04 checkpoint (badge count + DnD bugs fixed before approval).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:08:02 +02:00
Arthur Belleville
06bbb49a7f
docs(04-04): human checkpoint approved — phase 4 complete
All 7 TASK requirements verified in browser. Two bugs found and fixed
during verification (badge count, drag-and-drop draggable selector).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:04:21 +02:00
Arthur Belleville
131c9fd6b3
fix(04): draggable:.task-card-zone — move wrapper not inner card
Sortable.js draggable must match direct children of .sortable-column.
Using .task-card (grandchild) caused Sortable to detach it from its
.task-card-zone wrapper, breaking HTMX OOB swap targets and making
drag appear to do nothing. Changed to .task-card-zone so the full
wrapper moves, keeping id= attributes intact for HTMX round-trips.

Also removed redundant form.dispatchEvent() before htmx.trigger()
which could cause a double submit on reorder.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:01:34 +02:00
Arthur Belleville
68f2ccdea3
fix(04): badge count + DnD init — use DOMContentLoaded/htmx:afterSettle
Replace htmx.onLoad (requires htmx at parse time) with native
document.addEventListener('DOMContentLoaded') + 'htmx:afterSettle'
so Sortable.js is guaranteed loaded before init runs.

Add task-count-badge-{status} wrapper IDs and updateBadges() that
recounts .task-card elements on every HTMX settle so badge counts
stay in sync after create, delete, and reorder operations.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 09:56:28 +02:00
Arthur Belleville
8ac0a51969
docs(04-03): complete plan 03 — inline edit + reorder fully implemented
- 04-03-SUMMARY.md created with full execution details
- STATE.md updated: decisions, metrics, notes for plan 03
- ROADMAP.md updated with plan progress (3/4 summaries for phase 4)
2026-05-15 09:40:35 +02:00
Arthur Belleville
f6deb8709b
feat(04-03): remove t.Skip from TestTaskOrderPersists — all 9 TestTask* tests active
- Remove t.Skip("handlers_tasks not yet implemented") from TestTaskOrderPersists
- Full test suite green: go test ./... exits 0, no FAIL lines
- All 9 TestTask* tests active (skip on missing TEST_DATABASE_URL per existing pattern)
2026-05-15 09:38:53 +02:00
Arthur Belleville
5f87d7e0ea
feat(04-03): implement TaskReorderHandler + remove t.Skip from reorder tests
- TaskReorderHandler: POST /tablos/{id}/tasks/reorder updates status+position
- Fetches existing task via GetTaskByID before UpdateTask (T-04-08 mass assignment guard)
- Supports both array form (task_id[]/task_col[]) and single-value form (task_id/status/position)
- Invalid UUIDs silently skipped (D-05); tasks from other tablos skipped (T-04-10)
- Returns updated KanbanBoard outerHTML for HTMX swap
- Remove t.Skip from TestTaskReorderCrossColumn and TestTaskReorderSameColumn
2026-05-15 09:38:28 +02:00
Arthur Belleville
2b299e21f4
feat(04-03): implement TaskEditHandler, TaskUpdateHandler, TaskEditFragment
- TaskEditHandler: GET /tablos/{id}/tasks/{task_id}/edit returns TaskEditFragment pre-filled with existing title+description
- TaskUpdateHandler: POST validates title (required, max 255), updates title+description preserving status+position (T-04-12)
- TaskEditFragment: outer .task-card-zone wrapper with outerHTML round-trip, discard restores via /show
- Sortable.js htmx.onLoad init script added to KanbanBoard (Pitfall 2 protection)
- TaskEditFragment added to tasks.templ; remove t.Skip from TestTaskUpdate
2026-05-15 09:37:46 +02:00
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
Arthur Belleville
92ebb5f5fe
feat(04-02): activate task integration tests (RED stubs to GREEN-ready)
- Remove t.Skip from TestTasksKanbanRenders, TestTaskCreate, TestTaskCreateValidation, TestTaskDelete, TestTaskOwnership
- Fix column header strings: 'To do'/'In progress'/'In review' to match TaskColumnLabels
- Add kanban-board id assertion and non-owner 404 check to TestTasksKanbanRenders
- TestTaskUpdate, TestTaskReorder*, TestTaskOrderPersists remain SKIP for Plan 03
2026-05-15 09:33:19 +02:00
Arthur Belleville
889164b437
feat(04-02): KanbanBoard, TaskCard, TaskDeleteConfirmFragment templates
- Add tasks.templ with KanbanBoard, KanbanColumn, TaskCard, TaskCreateFormFragment, TaskDeleteConfirmFragment, AddTaskTrigger, TaskCardOOB
- Add TaskColumns/TaskColumnLabels to tasks_forms.go (moved from web package to break import cycle)
- Update TabloDetailPage signature to accept tasks []sqlc.Task; embed KanbanBoard below tablo header
- Update handlers_tablos.go TabloDetailHandler to fetch tasks via ListTasksByTablo
- Update layout.templ: add sortable.min.js script tag, update footer to Phase 4 · Tasks
2026-05-15 09:32:06 +02:00
Arthur Belleville
181ae79369
feat(04-02): TasksDeps, task handlers, router task routes
- Add handlers_tasks.go: TasksDeps, TaskNewFormHandler, TaskCancelNewHandler, TaskCreateHandler, TaskShowHandler, TaskDeleteConfirmHandler, TaskDeleteHandler, plus stub Edit/Update/Reorder handlers
- Add task routes to router.go (static before parametric per Pitfall 1)
- Add TasksDeps param to NewRouter; update main.go and all test callers
- Move TaskColumns/TaskColumnLabels to templates package to avoid import cycle
2026-05-15 09:31:59 +02:00
Arthur Belleville
2be4cb6bc9
docs(04-01): complete Wave 0 foundation plan summary and state updates
- 04-01-SUMMARY.md: documents migration, sqlc, RED scaffold, Sortable.js, soft-danger CSS
- STATE.md: Phase 4 in-progress, 3 new decisions recorded, metrics row added
- ROADMAP.md: Phase 4 progress updated (1/4 plans)
- REQUIREMENTS.md: TASK-01..07 marked complete
2026-05-15 09:26:31 +02:00
Arthur Belleville
55fb32f1e1
chore(04-01): Sortable.js bootstrap and soft-danger button CSS
- justfile: add sortable_version := "1.15.7" variable
- justfile: bootstrap downloads sortable.min.js from jsDelivr
- justfile: clean removes static/sortable.min.js
- button.css: add .ui-button-soft-danger-md rule with hover and focus-visible states
- static/sortable.min.js: downloaded at 1.15.7 (45 kB)
2026-05-15 09:24:44 +02:00
Arthur Belleville
8b9543db6f
test(04-01): add RED test scaffold and task form structs
- handlers_tasks_test.go: 9 TestTask* functions (TASK-01..07 + IDOR) all skip
- TasksDeps stub struct declared in test file for Plan 02 wiring
- tasks_forms.go: TaskCreateForm, TaskCreateErrors, TaskUpdateForm, TaskUpdateErrors structs
- go build ./... passes; go test -run TestTask exits 0 with all 9 SKIP
2026-05-15 09:24:05 +02:00
Arthur Belleville
c9c826247a
feat(04-01): add tasks migration and sqlc query source
- CREATE TYPE task_status ENUM (todo, in_progress, in_review, done)
- CREATE TABLE tasks with tablo_id FK, position, status columns
- DROP order: table before type in Down migration (Pitfall 3)
- sqlc queries: ListTasksByTablo, InsertTask, GetTaskByID, UpdateTask, DeleteTask, MaxPositionByTabloAndStatus
- migration applied cleanly, sqlc generate produces TaskStatus type and Task struct
2026-05-15 09:22:18 +02:00
Arthur Belleville
2c6c3bf87e
docs(04): create phase plan — 4 plans for Tasks (Kanban)
Wave 1: migration 0004_tasks + sqlc + RED test scaffold + Sortable.js + CSS
Wave 2: board render + task create + delete (TASK-01, TASK-02, TASK-06)
Wave 3: inline edit + drag reorder/move (TASK-03, TASK-04, TASK-05, TASK-07)
Wave 4: human-verify checkpoint

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 09:19:42 +02:00
Arthur Belleville
7f58588f5a
docs(04): create phase 4 tasks-kanban plan (4 plans, 3 waves)
Wave 1 (Plan 01): DB migration, sqlc queries, RED test scaffold, Sortable.js bootstrap, soft-danger CSS.
Wave 2 (Plan 02): Kanban board render + task create + task delete vertical slice (TASK-01, TASK-02, TASK-06).
Wave 3 (Plan 03): Inline task edit + Sortable.js drag reorder/move (TASK-03, TASK-04, TASK-05, TASK-07).
Wave 4 (Plan 04): Human-verify checkpoint — full browser verification of all 7 TASK requirements.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 09:16:17 +02:00
Arthur Belleville
cfd30eb277
docs(04): UI design contract 2026-05-15 09:05:54 +02:00
Arthur Belleville
cdcb335fec
docs(04): UI design contract for Tasks (Kanban) phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 09:01:17 +02:00
Arthur Belleville
02cf49ac31
docs(04): add validation strategy 2026-05-15 08:52:20 +02:00
Arthur Belleville
1c7b9d632c
docs(04): research phase tasks-kanban domain 2026-05-15 08:51:06 +02:00
Arthur Belleville
338e7e6e92
docs(state): record phase 4 context session 2026-05-15 08:40:41 +02:00
Arthur Belleville
f31951ce1d
docs(04): capture phase context 2026-05-15 08:40:37 +02:00
Arthur Belleville
58c8231af9
docs(03): mark REVIEW.md status fixed after applying CR/WR fixes
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:33 +02:00
Arthur Belleville
79435602c4
fix(03): WR-04 add color field error display to create form template
- TabloCreateErrors: add Color field for server-side hex validation error
- TabloCreateFormFragment: render FieldError for color field and update
  placeholder to hex-only hint (#6366f1) matching the validation constraint

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:27 +02:00
Arthur Belleville
38fe5b3909
fix(03): CR-02 capture user from loadOwnedTablo on update error path
- TabloUpdateHandler: capture user from loadOwnedTablo (was discarded with _)
- Pass captured user to TabloDetailPage on non-HTMX validation error path
  instead of nil, preventing broken layout (no logout button/email shown)
- TabloUpdateHandler: pass tablo.Color to UpdateTablo to preserve color on update (CR-01)
- loadOwnedTablo: pass GetTabloByIDParams{ID, UserID} to DB query (WR-01 call site)
- TabloDeleteHandler: pass DeleteTabloParams{ID, UserID} to DB query (WR-02 call site)
- TabloDeleteHandler: on DB error with HX-Request, render TabloDeleteConfirmFragment
  instead of plain http.Error to avoid broken HTMX DOM state (CR-03)
- renderTabloCreateError: log secondary ListTablosByUser fetch failure (WR-03)
- TablosCreateHandler: validate color with isValidCSSColor (hex only) and surface
  TabloCreateErrors.Color field error to prevent CSS injection (WR-04)
- Add isValidCSSColor helper using ^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$ regex
- Update test call sites for GetTabloByID and DeleteTablo new param types

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:22 +02:00
Arthur Belleville
fc41883b1f
fix(03): CR-01 WR-01 WR-02 add color to UpdateTablo and user_id filters to GetTabloByID/DeleteTablo
- UpdateTablo SQL: add color = \$4 so color is preserved across title/description edits
- GetTabloByID SQL: add AND user_id = \$2 to push ownership enforcement into the DB layer
- DeleteTablo SQL: add AND user_id = \$2 to push authorization into the DB layer
- sqlc bindings regenerated (UpdateTabloParams+Color, GetTabloByIDParams, DeleteTabloParams)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:11 +02:00
Arthur Belleville
7b945652d3
docs(03): add code review report 2026-05-15 08:24:09 +02:00
Arthur Belleville
a420a9c45c
docs(phase-03): complete phase execution — TABLO-01..06 verified 2026-05-15 08:21:38 +02:00
Arthur Belleville
450291a697
docs(03-03): complete Phase 3 — advance state and roadmap
Phase 3 Tablos CRUD fully complete: all 3 plans done, TABLO-01..06
closed, 10/10 TABLO tests green, browser verify passed. Advance active
phase to Phase 4 Tasks (Kanban).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:10:31 +02:00
Arthur Belleville
b5fa3188f4
docs(03-03): mark Task 3 checkpoint approved — plan 03-03 complete
Human verify passed all 13 sub-checks: ownership 404, CSRF forms on
every mutating form, inline edit/discard, inline delete confirm/cancel,
HX-Redirect navigation, and non-JS 303 fallback. Phase 3 fully complete.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:09:24 +02:00
Arthur Belleville
a78221ae1c
docs(03-03): plan 03-03 summary and state 2026-05-15 08:03:58 +02:00
Arthur Belleville
ab6937c1aa
feat(03-03): detail/edit/delete handlers + router wiring; all 10 TABLO tests green
- loadOwnedTablo helper: uuid.Parse, GetTabloByID, ownership check (D-04: 404 not 403)
- TabloDetailHandler: GET /tablos/{id} renders detail page
- TabloEditTitleHandler/ShowTitleHandler: GET /tablos/{id}/edit-title|show-title fragments
- TabloEditDescHandler/ShowDescHandler: GET /tablos/{id}/edit-desc|show-desc fragments
- TabloUpdateHandler: POST /tablos/{id} — validates, updates DB, renders matching zone fragment
- TabloDeleteConfirmHandler/CancelHandler: GET /tablos/{id}/delete-confirm|delete-cancel
- TabloDeleteHandler: POST /tablos/{id}/delete — deletes row, HX-Redirect:/ or 303
- router.go: 9 new routes in RequireAuth group, static-before-parametric order preserved
- Fix [Rule 1 - Bug]: test title "Owner's Tablo" caused HTML entity mismatch — changed to "Owners Detail Tablo"
- go test ./internal/web/... -run TestTablo: 10/10 PASS; full suite: all PASS
2026-05-15 08:02:43 +02:00
Arthur Belleville
6f167e2956
feat(03-03): detail page, edit and delete templ fragments + TabloUpdateErrors
- TabloDetailPage: full detail layout with title/desc/delete zones
- TabloTitleDisplay/EditFragment: outerHTML-swappable title zone with _zone=title hidden field
- TabloDescDisplay/EditFragment: outerHTML-swappable desc zone with _zone=desc hidden field
- TabloDeleteButtonFragment: canonical single-source delete zone (TabloCard now delegates here)
- TabloDeleteConfirmFragment: inline confirm with "Delete tablo?", "Yes, delete", "Keep tablo"
- TabloNotFoundPage: 404 page with UI-SPEC copy
- TabloUpdateErrors struct added to tablos_forms.go
- just generate + go build ./... both exit 0
2026-05-15 07:59:10 +02:00
Arthur Belleville
878ab69602
docs(03-02): complete plan 02 — checkpoint approved, SUMMARY + STATE finalized
- Task 3 human-verify checkpoint approved: dashboard, HTMX create, validation, non-JS fallback all confirmed
- SUMMARY updated: all 3 tasks complete, checkpoint outcome documented
- STATE updated: plan 02 marked complete, commit hashes recorded
- index.templ deletion fix noted as final deviation

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 07:56:44 +02:00
Arthur Belleville
c08da7f5bd
fix(03-02): delete retired index.templ to stop templ generating stale imports 2026-05-15 07:51:50 +02:00
Arthur Belleville
c4406cf16c
docs(03-02): plan 02 SUMMARY + STATE update — checkpoint at Task 3
- 03-02-SUMMARY.md: TablosDeps, handler contracts, template contracts,
  4/10 tests green, 6 RED for Plan 03, known stubs documented
- STATE.md: 2 new decisions, plan 02 metrics row added, notes updated
- ROADMAP.md: phase 3 progress updated (2/3 summaries)
2026-05-15 00:22:16 +02:00
Arthur Belleville
5db9215a73
feat(03-02): tablo handlers + router wiring — list/new/create green
- Implement TablosListHandler, TablosNewHandler, TablosCreateHandler in
  handlers_tablos.go replacing the Plan 01 stub
- TablosCreateHandler: reads via r.PostFormValue, validates title (required,
  <=255), inserts with pgtype.Text nullable params, sends HX-Retarget +
  HX-Reswap on HTMX success, 303 redirect on non-HTMX success
- router.go: replace r.Get("/", IndexHandler()) with TablosListHandler;
  add GET /tablos/new and POST /tablos (static before parametric — Pitfall 1)
- handlers.go: remove IndexHandler + unused auth/csrf imports
- index.templ: reduced to bare package declaration (dashboard moved to tablos.templ)
- index_templ.go: deleted (empty templ file generates broken import)
- TestTabloList, TestTabloList_Empty, TestTabloCreate, TestTabloCreate_Validation: PASS
- TestSignup, TestLogin, TestLogout, TestCSRF: still PASS (no regression)
2026-05-15 00:20:25 +02:00
Arthur Belleville
43ddf25364
feat(03-02): tablos templates — dashboard, empty state, card, create form, OOB-clear
- Create backend/templates/tablos.templ with TablosDashboard, TablosEmptyState,
  TabloCard, TabloCreateFormFragment, TabloCardWithOOBFormClear components
- Create backend/templates/tablos_forms.go declaring TabloCreateForm and
  TabloCreateErrors types (mirrors auth_forms.go pattern)
- Update layout.templ footer: "Phase 2 · Authentication" → "Phase 3 · Tablos"
- TabloCardWithOOBFormClear emits OOB div as top-level sibling (Pitfall 5)
- TabloCard guards description/color rendering with pgtype.Text null checks
- All UI-SPEC copywriting copy strings present; templ generate succeeds
2026-05-15 00:17:56 +02:00
Arthur Belleville
2f22d68776
docs(03-01): complete Plan 01 — migration, test scaffold, button CSS
- 03-01-SUMMARY.md: tablos schema foundation, RED test scaffold, button CSS variants
- STATE.md: decisions + metrics for 03-01; phase 3 status updated
- ROADMAP.md: phase 3 plan progress (1/3 complete)
- REQUIREMENTS.md: TABLO-01..06 marked complete
2026-05-15 00:15:36 +02:00
Arthur Belleville
2c1b186fb7
feat(03-01): add ui-button-solid-danger-md and ui-button-soft-neutral-md CSS variants
- Danger variant: #b91c1c bg, #991b1b hover, min-height 44px (WCAG 2.5.5)
- Neutral-soft variant: #f1f5f9 bg, #e2e8f0 hover, #334155 text, min-height 44px
- All pseudo-class selectors top-level (no CSS nesting per Phase 1 convention)
- static/tailwind.css updated via just generate (Pitfall 4: imported CSS passes through)
2026-05-15 00:13:56 +02:00
Arthur Belleville
c8f44b1ad2
test(03-01): add TablosDeps stub and RED integration test scaffold for TABLO-01..06
- handlers_tablos.go: TablosDeps stub type enabling test compilation
- handlers_tablos_test.go: 10 integration tests (RED baseline) for all TABLO-01..06 paths
  - TestTabloList, TestTabloList_Empty, TestTabloCreate, TestTabloCreate_Validation
  - TestTabloDetail_Owner, TestTabloDetail_NonOwner, TestTabloDetail_InvalidID
  - TestTabloUpdate, TestTabloDeleteConfirm, TestTabloDelete
- router.go: NewRouter accepts TablosDeps as second deps parameter
- handlers_auth_test.go, handlers_test.go, csrf_test.go: update NewRouter call sites
- cmd/web/main.go: construct and pass TablosDeps to NewRouter
2026-05-15 00:13:31 +02:00
Arthur Belleville
f1b8d6e629
feat(03-01): add tablos migration and sqlc queries
- 0003_tablos.sql: tablos table with user_id FK + ON DELETE CASCADE + tablos_user_id_idx
- tablos.sql: 5 named queries (ListTablosByUser, GetTabloByID, InsertTablo, UpdateTablo, DeleteTablo)
- UpdateTablo sets updated_at = now() explicitly (Pitfall 7)
- color not editable in UpdateTablo per Phase 3 scope
- sqlc generates Tablo struct with pgtype.Text for description/color (not committed per .gitignore convention)
2026-05-15 00:10:40 +02:00
Arthur Belleville
f53b54637b
docs(03): plan phase 3 — Tablos CRUD (3 plans, 3 waves)
Plans cover TABLO-01..06 via MVP vertical slices: foundation (migration
+ sqlc + test scaffold + button CSS), list+create (dashboard, inline
form, OOB swap), and detail+edit+delete (ownership 404, inline edit
fragments, inline confirm delete). Includes Nyquist VALIDATION.md and
PATTERNS.md with real analog excerpts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 00:08:08 +02:00
Arthur Belleville
dc7f5ac4e2
docs(03): research phase domain 2026-05-14 23:51:35 +02:00
Arthur Belleville
65cdfbc00f
docs(03): fix UI-SPEC checker blocks — copywriting labels and typography weight
- Replace generic "Save"/"Cancel" with specific labels: "Save changes",
  "Discard changes", "Keep tablo" throughout spec, component inventory,
  interaction contracts, and HTMX reference table
- Remove 500 (medium) weight; form labels now use font-semibold (600),
  consistent with Button convention — 2 declared weights total

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-14 23:42:53 +02:00
Arthur Belleville
c779d2aee1
docs(03): UI design contract for Tablos CRUD phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-14 23:39:48 +02:00
Arthur Belleville
ab5b58cd06
docs(state): record phase 3 context session 2026-05-14 23:36:00 +02:00
Arthur Belleville
5fe692aa93
docs(03): capture phase 3 context 2026-05-14 23:35:55 +02:00
Arthur Belleville
df78ed2832
docs(02): phase 2 verification PASSED — AUTH-01..07 complete
All 7 plans executed and verified against the phase boundary.
2026-05-14 23:06:31 +02:00
Arthur Belleville
efb3df51da
docs(02-07): complete gorilla/csrf integration plan (AUTH-06 closed)
- SUMMARY.md: gorilla/csrf middleware, ui.CSRFField, env-driven key, all CSRF tests
- STATE.md: Phase 2 complete (7/7), decisions, commits, metrics recorded
- ROADMAP.md: Phase 2 Authentication marked complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 23:01:36 +02:00
Arthur Belleville
389e1bc8b4
feat(02-07): gorilla/csrf integration — mount middleware, wire all forms, env-driven key
- auth.Mount(env, key) wraps csrf.Protect with locked D-14/D-24 options
- auth.LoadKeyFromEnv() reads SESSION_SECRET, hex-decodes, validates 32 bytes; fails fast on error
- ui.CSRFField(token) templ component renders hidden _csrf input
- Layout, LoginPage/Fragment, SignupPage/Fragment, Index all embed @ui.CSRFField(csrfToken)
- Handlers thread csrf.Token(r) into every page/fragment render call
- NewRouter mounts auth.Mount after ResolveSession, before all route groups (D-24)
- main.go calls auth.LoadKeyFromEnv(); logs.Fatalf on missing/invalid SESSION_SECRET
- SESSION_SECRET documented in .env.example with openssl rand -hex 32 instruction
- go.mod: gorilla/csrf v1.7.3 (direct); prior tests updated with getCSRFToken helper
- All Plan 04/05/06 tests updated to acquire and submit valid _csrf tokens
2026-05-14 22:59:06 +02:00
Arthur Belleville
ae2d356f87
test(02-07): add failing CSRF tests (RED gate)
- TestLoadCSRFKey_* in internal/auth for env key loading
- TestCSRF_*MissingToken / TestCSRF_*ValidToken for all three POST routes
- TestForms_ContainCSRFField for hidden _csrf input in rendered HTML
- TestRouter_CSRFMountedAfterResolveSession for middleware order (D-24)
- TestCSRF_HeaderFallback for X-CSRF-Token header support
- Add gorilla/csrf v1.7.3 dependency
2026-05-14 22:45:36 +02:00
Arthur Belleville
00a9388c32
docs(02-06): complete logout + protected routes + layout plan
- Create 02-06-SUMMARY.md with TDD gate compliance, router middleware snapshot
- Update STATE.md: plans 01-06 complete, plan 07 (CSRF) next
- Update ROADMAP.md: Phase 2 at 6/7 plans, 02-06 checked
- Mark AUTH-04 complete in REQUIREMENTS.md (AUTH-05 was already checked)
2026-05-14 22:42:23 +02:00
Arthur Belleville
8b54ff4bec
feat(02-06): implement logout, protect GET /, and update layout with auth state
- Add LogoutHandler: deletes session row (D-06), clears cookie, redirects to /login
- Protect GET / inside RequireAuth group; remove old top-level registration
- Add POST /logout inside same RequireAuth group (D-22: POST-only logout)
- Update Layout signature to accept *auth.User; render logout form + email when authed
- Update Index template to accept *auth.User and show "Signed in as {email}"
- Update SignupPage/LoginPage to pass nil to Layout (auth pages are unauthed)
- Update IndexHandler to pull user from auth.Authed(ctx) and pass to template
- Update TestIndex_RendersHxGet -> TestIndex_UnauthRedirects (GET / now protected)
- AUTH-04 (logout) and AUTH-05 (protected /) are now closed
2026-05-14 22:40:10 +02:00
Arthur Belleville
b5c3fc4d48
test(02-06): add failing tests for logout, protected routes, and layout auth
- TestLogout_Success: POST /logout with valid cookie -> 303, cookie cleared, session deleted
- TestLogout_UnauthRedirectsToLogin: POST /logout without cookie -> 303 from RequireAuth
- TestLogout_HXRedirect: HTMX logout -> 200 + HX-Redirect: /login
- TestLogout_AfterLogoutSubsequentRequestUnauth: stale cookie blocked after logout
- TestProtected_HomeUnauthRedirects: GET / without session -> 303 /login
- TestProtected_HomeUnauthHXRedirect: HTMX GET / without session -> 200 + HX-Redirect
- TestProtected_HomeAuthRendersUserEmail: authed GET / -> 200 with user email
- TestLayout_LogoutFormVisibleWhenAuthed: Layout with user shows logout form
- TestLayout_LogoutFormHiddenWhenUnauthed: Layout with nil user hides logout form
2026-05-14 22:32:33 +02:00
Arthur Belleville
977dafa31d
docs(02-05): complete login + rate limit plan
- SUMMARY.md: login vertical slice, rate limiter design decisions, 12 test results
- STATE.md: advance to 5/7 plans, add decisions, metrics row
- ROADMAP.md: mark 02-05 complete (5/7 plans)
- REQUIREMENTS.md: mark AUTH-07 complete (rate limit delivered)
2026-05-14 22:30:00 +02:00
Arthur Belleville
7d8c498980
feat(02-05): login vertical slice with rate limiting
- auth_login.templ: LoginPage + LoginFormFragment (mirrors signup shape)
- LoginForm + LoginErrors types added to templates/auth_forms.go
- LoginPageHandler + LoginPostHandler in handlers_auth.go
  - Rate-limit check before user lookup (D-16, T-2-14)
  - Single errInvalidCreds constant for D-20 enumeration defense
  - Session rotation via Store.Rotate on success (D-10, T-2-04)
  - HTMX-aware redirect and fragment responses (D-19, D-21)
- AuthDeps extended with Limiter *auth.LimiterStore field
- router.go: GET /login in RedirectIfAuthed group (D-23)
- main.go: LimiterStore created with janitor goroutine (D-16)
- Export NewLimiterStoreWithClock + SetLimiterClock for cross-package tests
- 12 TestLogin_* integration tests all pass with real DB
2026-05-14 22:27:54 +02:00
Arthur Belleville
b5c20c7892
feat(02-05): implement LimiterStore with injectable clock and janitor
- Token-bucket rate limiter keyed per (email+IP) using golang.org/x/time/rate
- rate.Every(12s), burst=5, idleTTL=10min (D-16)
- AllowN(t, 1) with injectable clock for deterministic tests (Pattern 8)
- Janitor goroutine evicts entries idle > 10min via cleanupNow()
- No .Allow() without args (Pitfall 8 avoided)
- Five tests pass with -race: burst, refill, isolation, janitor, concurrent
- golang.org/x/time v0.15.0 added to go.mod
2026-05-14 22:22:24 +02:00
Arthur Belleville
f6a453ff1f
docs(02-04): complete signup vertical slice plan
- Add 02-04-SUMMARY.md: signup form + handler + integration tests
- Update STATE.md: plan 04 complete (4/7 in phase 2), plan 05 next
- Update ROADMAP.md: 02-04 checked off, phase 2 progress 4/7
2026-05-14 22:20:09 +02:00
Arthur Belleville
efdc16babe
feat(02-04): signup handler, router wiring, and integration tests
- Add handlers_auth.go: SignupPageHandler + SignupPostHandler (validate -> hash -> insert -> session -> redirect)
- Add AuthDeps struct; wire argon2id hash, InsertUser, Store.Create, SetSessionCookie
- Update router.go: NewRouter accepts AuthDeps; mount ResolveSession (D-24); wire /signup routes behind RedirectIfAuthed
- Update cmd/web/main.go: build AuthDeps (sqlc.Queries + auth.Store + secure flag) and pass to NewRouter
- Add nil-Store guard to auth.ResolveSession for Phase 1 unit-test compatibility
- Update handlers_test.go: pass AuthDeps{} zero value to NewRouter (Phase 1 routes unaffected)
- Add testdb_test.go: isolated-schema test helper for web package integration tests
- Add handlers_auth_test.go: 8 TestSignup_* integration tests (all pass against real Postgres)
2026-05-14 22:17:50 +02:00
Arthur Belleville
73935ed11c
feat(02-04): signup templates (full page + HTMX fragment) with render tests
- Create auth_form_errors.templ: FieldError and GeneralError primitives
- Create auth_signup.templ: SignupPage (full) and SignupFormFragment (HTMX swap target)
- Define SignupForm and SignupErrors types in templates/auth_forms.go
- Add three smoke tests: renders form, renders errors, does not echo password
2026-05-14 22:14:28 +02:00
Arthur Belleville
38596ac41e
docs(02-03): complete session store + middleware plan
- Create 02-03-SUMMARY.md: SHA-256 token hashing, sliding TTL, HTMX-aware chi middleware
- STATE.md: advance to plan 03 complete, plan 04 (signup) next
- ROADMAP.md: Phase 2 progress 3/7 plans
- REQUIREMENTS.md: mark AUTH-02, AUTH-03, AUTH-05 complete
2026-05-14 22:11:58 +02:00
Arthur Belleville
1d07830954
feat(02-03): ResolveSession + RequireAuth + RedirectIfAuthed middleware
- ResolveSession: reads cookie, SHA-256 lookup, MaybeExtend best-effort, attaches Session+User to ctx
- RequireAuth: 303 /login for plain requests; HX-Redirect: /login for HTMX (D-23, Pattern 5)
- RedirectIfAuthed: bounces authed users to / from login/signup pages
- Authed(ctx): typed context accessor for session + user
- redirect helper centralizes 303 vs HX-Redirect logic (Pitfall 9: no 302)
- 9 tests: 3 real-DB (ResolveSession) + 6 pure ctx/routing (RequireAuth, RedirectIfAuthed)
2026-05-14 22:09:58 +02:00
Arthur Belleville
fd2301decf
feat(02-03): session store + cookie helpers (real-DB TDD)
- Store.Create: 32-byte crypto/rand token, SHA-256 hex as DB id (D-05)
- Store.Lookup: hashes cookie, maps pgx.ErrNoRows to ErrSessionNotFound (D-07)
- Store.Delete: hard-deletes session row (D-06)
- Store.Rotate: deletes old row before creating new one (D-10, T-2-04)
- Store.MaybeExtend: extends only when remaining < 7 days (D-09)
- SetSessionCookie: HttpOnly + Secure (env-gated) + SameSite=Lax (D-12)
- ClearSessionCookie: MaxAge=-1 not 0 (RESEARCH Pattern 3 / D-06)
- 10 tests: 7 real-DB (skip without TEST_DATABASE_URL) + 3 cookie unit tests
2026-05-14 22:08:04 +02:00
Arthur Belleville
648ce143a2
docs(02-02): complete argon2id password TDD plan
- Add 02-02-SUMMARY.md: argon2id Hash+Verify, DefaultParams (OWASP 2024), TestParams, init self-test
- Update STATE.md: plan 02 complete, plan count 7, decision logged
- Update ROADMAP.md: phase 2 now shows 2/7 plans complete
2026-05-14 22:02:25 +02:00
Arthur Belleville
ee36a5c78b
feat(02): GREEN — argon2id Hash + Verify + self-test
- Add Params struct with Memory/Iterations/Parallelism/SaltLength/KeyLength
- DefaultParams: OWASP 2024 baseline (m=64KiB, t=1, p=4, salt=16B, key=32B) — D-08
- TestParams: reduced cost (m=8KiB) so go test stays under 5s — D-26/Pitfall 4
- Hash(): crypto/rand salt per call, argon2.IDKey, PHC format $argon2id$v=19$...
- Verify(): PHC split/parse, ErrInvalidHash on malformed, ErrIncompatibleVersion on v!=19
- subtle.ConstantTimeCompare for timing-attack resistance (T-2-13)
- init() self-test: hash/verify round-trip panics on regression (D-08/T-2-15)
- Add golang.org/x/crypto v0.51.0 as direct dependency
2026-05-14 22:00:55 +02:00
Arthur Belleville
3bb3828cdc
test(02): RED — failing argon2id password tests
- Six tests: HashVerify, VerifyWrong, VerifyMalformed, VerifyVersion, DistinctSaltsPerCall, DefaultParamsShape
- Tests use auth.TestParams for fast wall time (Pitfall 4 guard)
- Guards ErrInvalidHash + ErrIncompatibleVersion sentinel errors
- All tests fail with undefined: auth.Hash / auth.TestParams / auth.Verify (implementation missing)
2026-05-14 21:59:38 +02:00
Arthur Belleville
fb9aac30ba
docs(02-01): complete auth-substrate plan 2026-05-14 21:58:23 +02:00
Arthur Belleville
2c84f4275b
feat(02-01): create internal/auth package skeleton, test DB harness, env docs
- auth/doc.go: package comment explaining consolidated layout (Open Question 3 resolved)
- auth/types.go: User + Session structs, SessionCookieName (D-12), SessionTTL (D-09),
  SessionExtendThreshold (D-09), ErrSessionNotFound, ErrInvalidHash, ErrIncompatibleVersion
- auth/testdb_test.go: setupTestDB creates isolated per-test schema (test_<uuid>),
  runs goose Up with unique version table, drops schema on cleanup (D-26)
  TestSetupTestDB_Roundtrip smoke test verifies users table visible
- go.mod: added github.com/pressly/goose/v3 v3.27.1 as direct dependency
- .env.example: added TEST_DATABASE_URL and SESSION_SECRET with comments (D-14, D-26)
2026-05-14 21:56:45 +02:00
Arthur Belleville
799c26099e
feat(02-01): add sqlc queries + citext/uuid overrides; generate bindings
- sqlc.yaml: overrides citext→string and uuid→uuid.UUID (Pattern 10, Pitfall 3)
- users.sql: InsertUser :one and GetUserByEmail :one
- sessions.sql: InsertSession :exec, GetSessionWithUser :one (expires_at > now() per D-07),
  DeleteSession :exec, DeleteSessionsByUser :exec, ExtendSession :exec
- sqlc generate produces Email string (not pgtype.Text) and uuid.UUID in bindings
- go build ./internal/db/... exits 0
2026-05-14 21:52:48 +02:00
Arthur Belleville
513044de58
feat(02-01): add 0002_auth.sql migration with users + sessions tables
- citext extension + pgcrypto for gen_random_uuid()
- users: id uuid PK, email citext UNIQUE, password_hash, created_at, updated_at (D-01)
- sessions: id text PK (SHA-256 hex), user_id FK ON DELETE CASCADE, created_at, expires_at (D-04)
- indexes on sessions(user_id) and sessions(expires_at)
- no deleted_at, email_verified_at, user_agent, ip_address columns (D-02, D-03, D-04)
- goose Up/Down round-trip verified against compose Postgres
2026-05-14 21:51:37 +02:00
Arthur Belleville
032e020fe3
docs(02): create phase plan (7 plans, 6 waves)
7 vertical-slice plans covering AUTH-01..07: schema+sqlc skeleton →
password (TDD) || session+middleware → signup → login+ratelimit →
logout+protect → CSRF. All 26 CONTEXT.md decisions cited; threat
model covers T-2-01..T-2-10.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 21:44:08 +02:00
Arthur Belleville
194072bd9a
docs(02-authentication): add CSRF integration plan (Plan 07) for AUTH-06 2026-05-14 21:36:06 +02:00
Arthur Belleville
284251083b
docs(02): add phase research 2026-05-14 21:20:13 +02:00
Arthur Belleville
0d62b9988d
docs(phase-2): add validation strategy 2026-05-14 21:19:41 +02:00
Arthur Belleville
d2af5d227b
docs(state): record phase 2 context session 2026-05-14 20:55:27 +02:00
Arthur Belleville
63672731f7
docs(02): capture phase context 2026-05-14 20:55:22 +02:00
Arthur Belleville
8d0f7a5a9c
docs(phase-01): evolve PROJECT.md after phase completion 2026-05-14 20:12:25 +02:00
Arthur Belleville
e1a1169e3e
test(01): user-approved human UAT items; close phase 2026-05-14 20:11:54 +02:00
Arthur Belleville
dd615a0195
fix(01): guard sqlc on empty queries and correct tailwind paths 2026-05-14 20:09:39 +02:00
Arthur Belleville
5eada7f480
test(01): persist human verification items as UAT 2026-05-14 19:35:41 +02:00
Arthur Belleville
d032162cc0
docs(phase-01): update tracking after wave 4 2026-05-14 19:32:14 +02:00
Arthur Belleville
5d17594356
chore: merge executor worktree (worktree-agent-a1c29b6bd03c33a2b) [plan 01-04] 2026-05-14 19:32:12 +02:00
Arthur Belleville
9149399578
docs(01-04): complete README quickstart plan
Adds 01-04-SUMMARY.md documenting the README onboarding doc that closes
FOUND-05 and completes Phase 1 foundation requirements.
2026-05-14 19:31:56 +02:00
Arthur Belleville
88f3706cd5
docs(01-04): add backend/README.md quickstart (closes FOUND-05)
- Five-minute clone-to-page onboarding doc covering prereqs, bootstrap,
  two-terminal dev workflow, common commands, and troubleshooting.
- Documents docker compose fallback for contributors not on podman (D-11).
- Documents two-terminal workflow: just dev + just styles-watch (D-14).
- Every `just <recipe>` referenced is a real recipe in backend/justfile.
- Uses 'bootstrap-downloaded' wording (not 'vendored') for tailwindcss
  and htmx.min.js per Codex review concern #4.
- Clarifies HTMX runtime no-CDN policy; the unpkg URL in justfile is the
  single authoritative version pin (D-10 / Codex concern #5).
- Top 3 pitfalls from RESEARCH surfaced in Troubleshooting.
- 195 lines, no emoji, no marketing voice.
2026-05-14 19:31:19 +02:00
Arthur Belleville
709aa5cff3
docs(phase-01): update tracking after wave 3 2026-05-14 19:28:44 +02:00
Arthur Belleville
cc204463ad
chore: merge executor worktree (worktree-agent-a69c8b0de96868f99) [plan 01-03] 2026-05-14 19:28:34 +02:00
Arthur Belleville
991af880b9
docs(01-03): summary for Walking Skeleton GREEN slice 2026-05-14 19:28:13 +02:00
Arthur Belleville
aa1e1fd415
feat(01-03): cmd/worker Phase 1 skeleton (D-03)
- Opens pgxpool from DATABASE_URL, logs 'worker ready', blocks on
  SIGINT/SIGTERM, closes pool, exits 0
- Reuses web.NewSlogHandler — pure helper, no HTTP coupling
- No job queue libraries (river/asynq/pg_notify) — Phase 6 replaces this
  file in full
- 48 lines (under 80-line budget signals 'we did not implement Phase 6
  by accident')
2026-05-14 19:26:57 +02:00
Arthur Belleville
08a2c3cd96
feat(01-03): cmd/web entrypoint with graceful shutdown
- Reads DATABASE_URL (required), PORT (default 8080), ENV (default
  development) from os.Getenv only — no third-party env loader (D-15:
  .env exported by just dev, prod injects real env)
- slog.SetDefault wired before fatal-on-missing-DSN so even startup errors
  emit structured output; sanitization per T-01-12 (never log DSN)
- pgxpool opened via db.NewPool; chi router mounted with ./static as the
  asset root
- http.Server: ReadTimeout=15s, WriteTimeout=15s, IdleTimeout=60s
  (T-01-10 slow-client mitigation)
- signal.NotifyContext (Go 1.21+) traps SIGINT/SIGTERM, propagates through
  ctx; on signal: srv.Shutdown with 10s timeout, then explicit pool.Close
  (Pitfall 4 — never via defer)
- No /readyz route (Phase 7 scope)
2026-05-14 19:26:22 +02:00
Arthur Belleville
3a12f8f47d
feat(01-03): templ layout/index/fragments + handlers + chi router
- templates/layout.templ: base HTML shell per UI-SPEC §Base Layout Contract
  (max-w-5xl container, slate-50 header, slate-200 borders, footer copy,
  /static/tailwind.css in <head>, /static/htmx.min.js deferred at body end —
  D-10: HTMX never loaded from a CDN)
- templates/index.templ: root page consuming @ui.Card and @ui.Button for the
  canonical HTMX demo (UI-SPEC §Component Library Contract canonical block)
- templates/fragments.templ: TimeFragment renders <span> with RFC3339 UTC
  timestamp; templ auto-escapes interpolation (T-01-13)
- internal/web/handlers.go: HealthzHandler (200 ok / 503 degraded per D-20,
  2s Ping timeout), IndexHandler, DemoTimeHandler with injected clock
- internal/web/router.go: Pinger interface; NewRouter wires
  RequestIDMiddleware → RealIP → SlogLoggerMiddleware → Recoverer (D-08
  + Pitfall 6 — chi middleware.Logger deliberately NOT registered) and
  routes /, /healthz, /demo/time, /static/* via http.FileServer (T-01-08
  path traversal blocked by http.Dir)

All six handler tests + ui package tests are GREEN under default go test.
2026-05-14 19:25:43 +02:00
Arthur Belleville
36e96015f5
feat(01-03): pgxpool wrapper, RequestID/slog middleware, slog handler switch
- Remove //go:build red_gate tag from internal/web/handlers_test.go and
  internal/db/pool_test.go now that consumer symbols are about to exist
- go mod tidy after real importers land (deferred from Plan 01-01 per
  Codex concern #1) — chi/v5, templ, pgx/v5, google/uuid now in require list
- internal/db/pool.go: NewPool(ctx, dsn) builds a pgxpool.Pool with
  MaxConns=10, MinConns=1; no eager Ping (RESEARCH Pitfall 2)
- internal/web/slog.go: NewSlogHandler returns JSON when env='production',
  text otherwise; pure helper, no slog.SetDefault side effect
- internal/web/middleware.go: RequestIDMiddleware (UUIDv4 → ctx +
  X-Request-ID header), LoggerFromContext helper, SlogLoggerMiddleware
  factory using chi WrapResponseWriter; field allowlist per V7/T-01-09
2026-05-14 19:24:16 +02:00
Arthur Belleville
9c829f9783
docs(phase-01): update tracking after wave 2 2026-05-14 18:57:31 +02:00
Arthur Belleville
f2212676c5
1password 2026-05-14 18:55:51 +02:00
Arthur Belleville
3b2efbb8f7
chore: merge executor worktree (worktree-agent-afdaf4b9e5211a350) [plan 01-02] 2026-05-14 18:53:24 +02:00
Arthur Belleville
798271cc77 docs(01-02): summary for ui foundation + RED gate plan 2026-05-14 18:49:22 +02:00
Arthur Belleville
37d19a3314 test(01-02): add red-gated handler and pool tests
- handlers_test.go (//go:build red_gate): TestHealthz_OK, TestHealthz_Down,
  TestIndex_RendersHxGet, TestDemoTime_Fragment, TestRequestID_HeaderSet,
  TestSlog_HandlerSwitch — reference web.HealthzHandler / NewRouter /
  NewSlogHandler / Pinger to be implemented in Plan 01-03
- pool_test.go (//go:build red_gate): TestPool_Connects with t.Skip
  fallback when DATABASE_URL is unset
- Build tag isolates the RED state from default 'go test ./...' (Codex #3)
2026-05-14 18:48:26 +02:00
Arthur Belleville
75cbd29d44 test(01-02): add ui package smoke tests
- TestButton_DefaultSolidMD: asserts root class and label
- TestButton_PassesThroughAttrs: asserts hx-* attribute spread
- TestButton_ExplicitTypeSubmit: type override
- TestCard_RendersChildren: templ.WithChildren child injection
- TestBadge_{Info,Success}Variant + zero-value normalization
- TestButtonClass_String / TestBadgeClass_String: class contract
- TestNormalizers_ZeroValueDefaults: every Normalized* returns safe default
2026-05-14 18:47:31 +02:00
Arthur Belleville
d056b33241 feat(01-02): add Button, Card, Badge templ components + CSS
- button.templ: Button(ButtonProps) renders <button type=...> with class
  from ui.ButtonClass(); Attrs spread for hx-* pass-through
- button.css: .ui-button base + .ui-button-solid-default-md variant
  with non-nested :hover and :focus-visible (Codex concern #7)
- card.templ: Card(attrs) accepts children via templ child syntax
- card.css: slate-50 panel, slate-200 border
- badge.templ: Badge(BadgeProps) renders <span class=...>
- badge.css: info / success / danger variants (warning deferred)
2026-05-14 18:46:42 +02:00
Arthur Belleville
1ff8e681da feat(01-02): add ui package enums, helpers, base CSS
- tokens.go: semantic token constants
- variants.go: Size/ButtonVariant/ButtonTone/BadgeVariant enums + Normalized*
- helpers.go: mergeAttrs for templ.Attributes
- base.css: resets, :focus-visible ring (no nesting)
2026-05-14 18:45:15 +02:00
Arthur Belleville
5b19a8815c
docs(phase-01): update tracking after wave 1 2026-05-14 17:58:25 +02:00
Arthur Belleville
a639fdf502
chore: merge executor worktree (worktree-agent-a98c01ef03e47adfc) [plan 01-01] 2026-05-14 17:57:38 +02:00
Arthur Belleville
586b683131
docs(01-01): complete backend scaffold plan summary
- Documents 5 task commits (aa90008, 4de9685, 2fe5b51, d6085b7, ce22472)
- Records pinned versions actually wired
- Confirms Codex review concerns 1, 2, 3, 4, 6, 10 are addressed
- Logs auto-approved human-verify checkpoint (Task 6 — real bootstrap requires developer-side network)
- Path forward to Plans 01-02 (handler tests + ui/*.css) and 01-03 (cmd/* entrypoints + walking skeleton)
2026-05-14 17:57:09 +02:00
Arthur Belleville
ce224725e2
feat(01-01): justfile with bootstrap, db, migrate, generate, dev, test, lint, build, clean
- bootstrap: installs goose/templ/sqlc/air at pinned versions; downloads Tailwind v4 standalone
  binary via explicit OS/arch case mapping (darwin->macos, x86_64->x64, arm64/aarch64->arm64)
  resolving to one of {tailwindcss-macos-x64,tailwindcss-macos-arm64,tailwindcss-linux-x64,tailwindcss-linux-arm64}
  (Codex concern #2); bootstrap-downloads htmx.min.js from unpkg into static/
- migrate: GOOSE_DRIVER + GOOSE_DBSTRING + GOOSE_MIGRATION_DIR wired
- generate / styles-watch / dev / test / lint / build / clean recipes complete
- 'just --list' enumerates 11 recipes; no pnpm/npm/node references (D-12)
- clean recipe removes bin/, tmp/, generated CSS, bootstrap-downloaded htmx, *_templ.go (Codex #10)
- Tailwind watch is run separately (RESEARCH Open Q2 two-terminal workflow)
- The only CDN URLs in the entire backend are inside this justfile's bootstrap recipe;
  served HTML/CSS/JS reference only /static/* (CONTEXT D-10 clarified)
2026-05-14 17:56:02 +02:00
Arthur Belleville
d6085b7dbb
feat(01-01): sqlc config, tailwind input CSS, air live-reload config
- sqlc.yaml: postgresql engine, schema points at migrations/ (Pitfall 7), pgx/v5 sql_package
- tailwind.input.css: @source globs for templ + internal/web Go files (Pitfall 3), @imports four ui/*.css files per UI-SPEC
- .air.toml: watches .go + .templ, excludes generated *_templ.go (Pitfall 5), runs 'templ generate' pre-build
- Tailwind watch is NOT wired into air pre_cmd (two-terminal workflow per RESEARCH Open Q2)
2026-05-14 17:54:35 +02:00
Arthur Belleville
2fe5b51f80
feat(01-01): compose file, env example, gitignore, bootstrap migration
- compose.yaml: postgres:16-alpine with pg_isready healthcheck (no seed mounts)
- .env.example: DATABASE_URL, PORT, ENV (D-15)
- .gitignore: bin/, tmp/, .env, generated tailwind.css, bootstrap-downloaded htmx.min.js, *_templ.go, sqlc output
- migrations/0001_init.sql: goose no-op bootstrap migration
2026-05-14 17:54:18 +02:00
Arthur Belleville
4de96854b5
feat(01-01): create directory skeleton and per-package doc.go placeholders
- internal/{db,session,tablos,tasks,files}/doc.go (D-02 placeholder packages)
- internal/db/{queries,sqlc}, templates/, migrations/, bin/, static/ via .gitkeep
- 'go build ./internal/...' compiles cleanly
- cmd/web, cmd/worker, internal/web are deliberately deferred to Plans 01-02 / 01-03
2026-05-14 17:53:55 +02:00
Arthur Belleville
aa90008d95
feat(01-01): initialize Go module and pin runtime dependencies
- module: backend (go 1.26.1)
- chi v5.2.5, templ v0.3.1020, pgx/v5 v5.9.2, goose v3.27.1, uuid v1.6.0
- pinned via 'go get'; 'go mod tidy' deferred to Plan 01-03 where consumers exist (Codex concern #1)
2026-05-14 17:53:36 +02:00
Arthur Belleville
c95a64e78e
docs(01): replan with cross-AI review feedback (codex) 2026-05-14 17:50:48 +02:00
Arthur Belleville
a54a10a7fd
docs(01): cross-AI review for phase 1 (codex) 2026-05-14 17:23:11 +02:00
Arthur Belleville
ad3a3d42ef
docs(01): create phase plan (4 plans, MVP walking skeleton) 2026-05-14 17:19:04 +02:00
Arthur Belleville
5f8af63e5e
docs(01): create Phase 1 foundation plans (4 plans, 3 waves) 2026-05-14 17:12:46 +02:00
Arthur Belleville
4d745f82c3
docs(01): add custom templ component library contract to UI-SPEC
Adds a Component Library Contract section locking in a small in-house
templ design-system under backend/internal/web/ui/, modeled on the
reference at go-backend/internal/web/ui/. Phase 1 ships only Button,
Card, and Badge; later phases extend the same package.
2026-05-14 16:58:27 +02:00
Arthur Belleville
5a14166583
docs(01): UI design contract for foundation phase
Lock base layout, spacing/typography/color tokens, and the canonical
HTMX interaction pattern that later phases inherit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:53:08 +02:00
Arthur Belleville
5f63929477
Remove backend folder 2026-05-14 16:50:48 +02:00
Arthur Belleville
b7f7a8964a
docs(01): add validation strategy 2026-05-14 16:50:15 +02:00
Arthur Belleville
74e1c3c126
docs(01): research foundation phase domain
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:49:21 +02:00
Arthur Belleville
6b58230f17
docs(state): record phase 1 context session 2026-05-14 16:42:38 +02:00
Arthur Belleville
6373834b9f
docs(01): capture phase context 2026-05-14 16:42:33 +02:00
Arthur Belleville
f58596e496
docs: create roadmap (7 phases) 2026-05-14 16:28:40 +02:00
Arthur Belleville
b46d314a35
docs: define v1 requirements 2026-05-14 16:27:20 +02:00
Arthur Belleville
39c7608851
chore: add project config 2026-05-14 16:26:25 +02:00
Arthur Belleville
3e3d02e244
docs: initialize project (go+htmx rewrite) 2026-05-14 16:24:26 +02:00
Arthur Belleville
2c23906716
docs: map existing codebase 2026-05-14 16:01:31 +02:00
Arthur Belleville
d9bf94583b
Refactor tasks UI to use reusable button and select components
Replace inline button markup with `ui.Button` component calls for
consistency and maintainability. Add filter menu component with dropdown
functionality. Convert roadmap mode toggle from link-based to select
dropdown. Include filter counter badge and clear filter actions.
2026-05-10 23:38:19 +02:00
Arthur Belleville
c80a8a875e
First pass on tasks frontend 2026-05-10 23:14:47 +02:00
Arthur Belleville
faf3199b71
Rename tasks plan dashboard state types 2026-05-10 22:18:00 +02:00
Arthur Belleville
71a56b72f1
Add tasks multi-view dashboard implementation plan 2026-05-10 22:06:37 +02:00
Arthur Belleville
c148ff9af3
Add select component with single and multi-value support 2026-05-10 22:04:09 +02:00
Arthur Belleville
9a92f358e8
Add task management features with database schema and handlers
Create a new tasks module with full CRUD operations, supporting both
regular tasks and etapes (phases). Implements task hierarchy with
parent-child relationships, assignees, and due dates. Includes database
schema with validation triggers, SQLC query generation, in-memory
repository implementation, HTTP handlers, view templates, and
comprehensive test coverage.
2026-05-10 21:58:48 +02:00
Arthur Belleville
1a00f84364
Add tasks multi-view dashboard design spec 2026-05-10 21:52:39 +02:00
Arthur Belleville
dd6e5b7d64
Update go-backend tasks docs for assignee support 2026-05-10 18:37:44 +02:00
Arthur Belleville
ef7ccd8c6f
Add go-backend tasks and etapes design spec 2026-05-10 18:25:18 +02:00
Arthur Belleville
354785edff
Pass tablo list to dashboard views
Update DashboardPage and DashboardContentSwap to receive the list of
tablos so the sidebar can display real project data. Extract tablo icon
palette logic into a new tabloicons package that maps hex colors to
presentation attributes (icon, background, foreground colors).

Update handlers to load tablos from the repository before rendering
dashboard views. Refactor TabloCardView to use icon presentation instead
of initials when available.
2026-05-10 14:56:46 +02:00
Arthur Belleville
3232309388
Make tablo icon selection dynamic based on color using nearest palette
match

Instead of selecting icons based on tablo name length, compute the
closest matching icon from a predefined palette by comparing hex color
values. This ensures consistent icon-color pairing and better visual
harmony.
2026-05-10 14:18:33 +02:00
Arthur Belleville
c780dd1625
Remove server-side search filtering and implement client-side filtering
This commit moves project search filtering from the server to the
client.
Changes include:

- Remove `Query` field from `ListTablosInput` and related handlers
- Add French date formatting for project cards
- Convert search form to client-side filter with data attributes
- Add empty state message for no search results
- Update button border-radius from 0 to 0.7rem
- Increase air.toml build command to include Tailwind CSS generation
2026-05-10 13:53:23 +02:00
Arthur Belleville
8bcf81a3f1
Add co-located CSS sources and semantic token infrastructure to Go
backend

Create the foundational structure for managing design-system CSS with
co-located sources and semantic tokens:

- Add `cmd/buildstyles` to concatenate ordered CSS sources into a single
  shipped stylesheet
- Define semantic color and effect tokens in `internal/web/ui/base.css`
- Move primitive and catalog CSS sources from `static/css/` to
  co-located locations under `internal/web/ui/`
- Update test contract to verify token presence and proper stylesheet
  generation
- Regenerate `static/styles.css` with new semantic token layer and
  source annotations
2026-05-10 11:47:42 +02:00
Arthur Belleville
0ac8bd0fc9
Update templ 2026-05-10 11:23:48 +02:00
Arthur Belleville
90da6646ea
docs: update css co-location design spec 2026-05-10 11:03:53 +02:00
Arthur Belleville
69a6844324
docs: add css-sources-per-primitive design spec 2026-05-10 10:42:13 +02:00
Arthur Belleville
2e52daa81d
Add space X and space Y to components 2026-05-10 10:38:07 +02:00
Arthur Belleville
b84eff7887
Add spacing, update catalog, and make several improvements to the tablo:
add update
2026-05-10 10:37:47 +02:00
Arthur Belleville
c89f526780
docs: add spacing primitives design spec 2026-05-10 10:04:39 +02:00
Arthur Belleville
cf64404d25
feat: refresh go-backend button variants and tablos styling 2026-05-10 09:22:22 +02:00
Arthur Belleville
a089f35a9b
docs: add go-backend tablo edit color design 2026-05-10 09:21:34 +02:00
Arthur Belleville
c14af76fb2
feat: toggle overview projects with vanilla js 2026-05-09 21:46:56 +02:00
Arthur Belleville
4ac33c77b9
feat: add go-backend design system and tablos UI 2026-05-09 20:18:24 +02:00
Arthur Belleville
bea78ffca7
docs: add go-backend design system design 2026-05-09 15:03:55 +02:00
Arthur Belleville
63882be278
docs: add go-backend tablos index CRUD design 2026-05-08 21:33:51 +02:00
Arthur Belleville
a5ea88b0a6
CI for go-backend on github actions 2026-05-08 16:28:48 +02:00
Arthur Belleville
c4eb878b0e
Split components, add sessions to the DB and make the apercu page 2026-05-08 16:03:54 +02:00
Arthur Belleville
0a38442d88 Build go-backend auth app with Podman dev flow 2026-05-08 12:08:53 +02:00
Arthur Belleville
98952ace6e
Deprecate previous backend 2026-05-07 23:02:29 +02:00
Arthur Belleville
0a647fc7c4
fix: make revenuecat config optional in api 2026-05-06 23:44:02 +02:00
Arthur Belleville
8a99a1a792
Merge pull request #85 from artslidd/in-app-purchases
In app purchases
2026-05-03 09:36:49 +02:00
Arthur Belleville
66fa698e48
feat: add apple billing flow for expo app 2026-05-03 09:28:46 +02:00
Arthur Belleville
5fba42f678
docs: add expo apple iap unified billing design 2026-05-02 16:25:32 +02:00
Arthur Belleville
888bc269ba
Merge pull request #84 from artslidd/work-2
Work 2
2026-05-02 11:21:31 +02:00
Arthur Belleville
eb23d84f8e
Merge branch 'develop' into work-2 2026-05-02 11:21:20 +02:00
Arthur Belleville
e18dd8f017
feat: route client auth through clients app 2026-05-01 11:55:05 +02:00
Arthur Belleville
90d34833e8
Fix config.ts 2026-05-01 10:33:00 +02:00
Arthur Belleville
2cf5eb8789
feat: migrate client portal to magic link auth 2026-05-01 10:11:08 +02:00
Arthur Belleville
06e1114cf8 feat: add client auth helpers and middleware 2026-04-30 18:37:29 +02:00
Arthur Belleville
fda95d9ce4 feat: add client auth tables 2026-04-30 18:33:31 +02:00
Arthur Belleville
f3ea5ac76e
docs: add client magic link auth replacement design 2026-04-30 18:21:38 +02:00
Arthur Belleville
4eaa8731c4
fix(api): remove redundant profile soft-delete
profiles.id has ON DELETE CASCADE from auth.users, so calling
auth.admin.deleteUser already removes the profile row. Only the
org soft-delete needs to happen explicitly.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 18:22:36 +02:00
Arthur Belleville
42d5161ab6
chore(db): add deleted_at to profiles and organizations
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 17:45:40 +02:00