12 KiB
12 KiB
| gsd_state_version | milestone | milestone_name | status | last_updated | last_activity | progress | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1.0 | v2.0 | Collaboration, planning, and social sign-in | planning | 2026-05-15T20:25:48.078Z | 2026-05-15 -- Phase 09 UI-SPEC approved |
|
STATE
Project: Xtablo Go+HTMX Product Milestone: v2.0 — Collaboration, planning, and social sign-in Created: 2026-05-14
Project Reference
See: .planning/PROJECT.md (updated 2026-05-15)
Core value: A user can sign in and run the Tablos workflow — organize work, attach files, discuss, and plan scheduled events — without a JS framework or managed chat provider. Current focus: Phase 9 — Etapes
Current Position
Phase: 9 — Etapes Plan: — Status: Ready for planning Last activity: 2026-05-15 -- Phase 09 UI-SPEC approved Resume file: .planning/phases/09-etapes/09-UI-SPEC.md
Phase Status
| # | Phase | Status |
|---|---|---|
| 8 | Social Sign-in | ✓ Complete |
| 9 | Etapes | ◐ UI-SPEC approved |
| 10 | Events | ○ Pending |
| 11 | Individual Planning | ○ Pending |
| 12 | Native Tablo Chat | ○ Pending |
Verification Record
- 2026-05-15: Phase 8 execution complete. Local verification passed with
go test ./... -count=1; database-backed integration coverage skips unlessTEST_DATABASE_URLis configured.
Decisions
- Consolidated internal/auth package (not split with internal/session) — RESEARCH Open Question 3
- compose Postgres + schema isolation for tests (not testcontainers-go) — RESEARCH Open Question 1
- goose.SetTableName per test-schema prevents public goose_db_version table collision
- argon2id over bcrypt for password hashing — D-08, confirmed by user
- Hand-rolled PHC encode/decode (Pattern 1 verbatim) — no alexedwards/argon2id wrapper dep; keeps code lean and self-tested
- Store.now injectable field (not method/interface) — simpler for single-test-clock use case in MaybeExtend threshold tests
- sha256.Sum256 inlined at Create + Lookup (not in helper) — satisfies >= 2 grep acceptance criterion; makes D-05 hashing visible at usage sites
- SignupForm/SignupErrors in templates package (not handlers or separate forms pkg) — avoids import cycle between templates and internal/web
- setupTestDB duplicated into web package test file — Go prohibits importing _test.go files across packages; duplication chosen over non-test shared infra
- nil-Store guard in auth.ResolveSession — enables Phase 1 unit tests to pass AuthDeps{} zero value without panic
- errInvalidCreds const (not inline string) — satisfies D-20 single-source-of-truth grep gate; both credential failure paths use the constant
- NewLimiterStoreWithClock exported — cross-package integration tests inject a frozen clock without a test-helper shim
- Status 401 for non-HTMX credential failures — consistent with HTTP semantics; HTMX path returns 200+fragment
- *Layout takes auth.User explicitly (not thread-through-ctx) — easier to test templates in isolation; no magic context values
- TestIndex_RendersHxGet rewritten to TestIndex_UnauthRedirects — GET / is now protected; Phase 1 test was a false positive after this plan
- csrf.PlaintextHTTPRequest(r) in dev mode — skips TLS Referer check in plain-HTTP local dev/httptest; production unaffected
- trustedOrigins variadic arg in auth.Mount + NewRouter — test routers pass "localhost"; production passes none
- sqlc-generated files not committed — backend/.gitignore excludes internal/db/sqlc/*.go; just generate reproduces them (03-01)
- NewRouter extended with TablosDeps parameter — second explicit deps param before csrfKey; all call sites updated (03-01)
- index_templ.go deleted manually after emptying index.templ — templ generates broken import when .templ has no components (03-02)
- Non-HTMX validation error re-fetches tablos and renders full dashboard — no form state threading; simpler than threading form through full page (03-02)
- _zone hidden field (title|desc) in edit fragments — unified POST /tablos/{id} handler reads _zone to select which display fragment to return; misuse only affects response body, not DB state (03-03)
- loadOwnedTablo helper for all parametric handlers — uuid.Parse + GetTabloByID + ownership check factored into single function; 404 on any failure, 403 never used (D-04) (03-03)
- TabloDeleteButtonFragment canonical delete-zone — TabloCard delegates to it; single source of truth for zone HTML across card and detail-page contexts (03-03)
- task_status ENUM order matches visual column order (todo, in_progress, in_review, done) — ENUM ordinal sorting aligns with kanban column display order per Pitfall 6 (04-01)
- Down migration drops TABLE before TYPE — tasks table dropped before task_status type per Pitfall 3; type cannot be dropped while still referenced (04-01)
- TasksDeps stub in test file — declared in handlers_tasks_test.go; moved to handlers_tasks.go in Plan 02 to avoid file dependency before handlers exist (04-01)
- TaskColumns/TaskColumnLabels in templates package — moved from web package to templates to avoid web↔templates import cycle; handlers reference via templates.TaskColumns (04-02)
- TabloDetailPage accepts tasks []sqlc.Task — kanban board embedded below tablo header; TabloDetailHandler fetches tasks via ListTasksByTablo before rendering (04-02)
- Dual reorder payload — TaskReorderHandler supports array form (task_id[]/task_col[]) and single-value form (task_id/status/position) for test scaffold + Sortable.js compatibility (04-03)
- GetTaskByID before UpdateTask in reorder — preserves title+description (T-04-08), validates task-to-tablo ownership at fetch time (T-04-10) (04-03)
- fileQuerier interface in OrphanCleanupWorker — enables mock injection for pure unit tests without real DB; pool field retained for production (06-01)
- river deps as // indirect until Plan 02 — cmd/worker wiring in Plan 02 will promote river to direct dependency; expected Go module behavior (06-01)
- signal.NotifyContext after rivermigrate and S3 init — startup I/O uses context.Background(); signal context created after all I/O succeeds; prevents river.Client.Start receiving a pre-cancelled context (RESEARCH Pitfall 2) (06-02)
- pool.Close() explicit after StopAndCancel, not via defer — StopAndCancel fully returns before pool is closed; matches PATTERNS.md pool close ordering (06-02)
- Social-only users use NULL password_hash — email/password login rejects them through the generic invalid-credentials path while provider sign-in owns the session path (08-01)
- Verified provider identity links by provider subject first, then verified email — prevents duplicate local users while keeping provider subject as the strongest identity key (08-02)
- Apple callback uses GET/query response mode for the first working version — keeps the callback inside existing CSRF middleware boundaries; Apple dashboard configuration must match (08-03)
- Provider buttons degrade to disabled controls when config is missing — auth pages remain deployable without provider credentials (08-04)
- Account providers page is read-only in Phase 8 — linked identity visibility shipped before unlink/add-password account management (08-05)
- Apple sign-in disabled after UAT scope change — Apple controls are hidden, Apple auth routes are not mounted, and provider docs only cover Google for now (08-UAT)
Performance Metrics
| Phase | Plan | Duration | Tasks | Files |
|---|---|---|---|---|
| 02-authentication | 01 | ~10min | 3 | 9 |
| 02-authentication | 02 | ~8min | 2 | 4 |
| 02-authentication | 03 | ~15min | 2 | 5 |
| 02-authentication | 04 | ~25min | 2 | 11 |
| 02-authentication | 05 | ~7min | 2 | 9 |
| 02-authentication | 06 | ~12min | 1 | 9 |
| 02-authentication | 07 | ~25min | 1 | 18 |
| 03-tablos-crud | 01 | ~15min | 3 | 10 |
| 03-tablos-crud | 02 | ~4min | 3 | 8 |
| 03-tablos-crud | 03 | ~30min | 3 | 5 |
| 04-tasks-kanban | 01 | ~4min | 3 | 7 |
| 04-tasks-kanban | 02 | ~20min | 3 | 12 |
| Phase 04-tasks-kanban P03 | ~15min | 3 tasks | 3 files | |
| 06-background-worker | 01 | ~15min | 2 | 9 |
| Phase 06-background-worker P01 | ~15min | 2 tasks | 9 files | |
| 06-background-worker | 02 | ~10min | 2 | 3 |
| Phase 08 P01 | 25min | 2 tasks | 8 files | |
| Phase 08 P02 | 35min | 2 tasks | 9 files | |
| Phase 08 P03 | 30min | 2 tasks | 7 files | |
| Phase 08 P04 | 20min | 2 tasks | 8 files | |
| Phase 08 P05 | 20min | 2 tasks | 7 files |
Notes
- Existing
go-backend/is set aside; new code lives in a freshbackend/Go package. - DB schema is changing from the JS/Supabase version — user is in the loop on every schema decision (Phases 2–5).
- Phase 2 Plan 01 SUMMARY:
.planning/phases/02-authentication/02-01-SUMMARY.md - Phase 2 Plan 02 SUMMARY:
.planning/phases/02-authentication/02-02-SUMMARY.md - Phase 2 Plan 03 SUMMARY:
.planning/phases/02-authentication/02-03-SUMMARY.md - Commits (02-01):
513044d(migration),799c260(sqlc),2c84f42(auth package + test harness) - Commits (02-02):
3bb3828(RED tests),ee36a5c(GREEN implementation) - Commits (02-03):
fd2301d(session store + cookie helpers),1d07830(middleware) - Commits (02-04):
73935ed(signup templates + smoke tests),efdc16b(handler + router + integration tests) - Phase 2 Plan 04 SUMMARY:
.planning/phases/02-authentication/02-04-SUMMARY.md - Commits (02-05):
b5c20c7(LimiterStore + tests),7d8c498(login handler + integration tests) - Phase 2 Plan 05 SUMMARY:
.planning/phases/02-authentication/02-05-SUMMARY.md - Commits (02-06):
b5c3fc4(RED tests),8b54ff4(logout + protected routes + layout) - Phase 2 Plan 06 SUMMARY:
.planning/phases/02-authentication/02-06-SUMMARY.md - Commits (02-07):
ae2d356(RED tests),389e1bc(GREEN csrf implementation) - Phase 2 Plan 07 SUMMARY:
.planning/phases/02-authentication/02-07-SUMMARY.md - Phase 3 Plan 01 SUMMARY:
.planning/phases/03-tablos-crud/03-01-SUMMARY.md - Commits (03-01):
f1b8d6e(migration + queries),c8f44b1(TablosDeps stub + test scaffold),2c1b186(button CSS variants) - Phase 3 Plan 02 SUMMARY:
.planning/phases/03-tablos-crud/03-02-SUMMARY.md - Commits (03-02):
43ddf25(tablos templates + layout footer),5db9215(tablo handlers + router wiring),c08da7f(delete retired index.templ) - 03-02 complete — all 3 tasks done including human-verify checkpoint approval
- Phase 3 Plan 03 SUMMARY:
.planning/phases/03-tablos-crud/03-03-SUMMARY.md - Commits (03-03):
6f167e2(detail/edit/delete templates),ab6937c(handlers + router + all 10 TABLO tests green),b5fa318(checkpoint approved) - Phase 3 complete — All 3 plans done; TABLO-01..06 closed; 10/10 TABLO tests green; full browser verify passed 2026-05-15
- Phase 4 Plan 01 SUMMARY:
.planning/phases/04-tasks-kanban/04-01-SUMMARY.md - Commits (04-01):
c9c8262(migration + sqlc queries),8b9543d(RED test scaffold + form structs),55fb32f(Sortable.js + soft-danger CSS) - Phase 4 Plan 02 SUMMARY:
.planning/phases/04-tasks-kanban/04-02-SUMMARY.md - Commits (04-02):
181ae79(handlers + router + main.go),889164b(templates + tablos.templ + layout.templ),92ebb5f(activate task tests) - Phase 4 Plan 03 SUMMARY:
.planning/phases/04-tasks-kanban/04-03-SUMMARY.md - Commits (04-03):
2b299e2(TaskEditHandler + TaskUpdateHandler + TaskEditFragment + Sortable.js init),5f87d7e(TaskReorderHandler + reorder test skips removed),f6deb87(TestTaskOrderPersists active — full suite green) - Phase 6 Plan 01 SUMMARY:
.planning/phases/06-background-worker/06-01-SUMMARY.md - Commits (06-01):
62e5e3e(river dep + ListOrphanFiles sqlc query),a1c2828(internal/jobs package + unit tests) - Phase 6 Plan 02 SUMMARY:
.planning/phases/06-background-worker/06-02-SUMMARY.md - Commits (06-02):
6e70478(cmd/worker full river wiring),e202ad3(just worker target + README docs) - Phase 8 Plan 01 SUMMARY:
.planning/phases/08-social-sign-in/08-01-SUMMARY.md - Phase 8 Plan 02 SUMMARY:
.planning/phases/08-social-sign-in/08-02-SUMMARY.md - Phase 8 Plan 03 SUMMARY:
.planning/phases/08-social-sign-in/08-03-SUMMARY.md - Phase 8 Plan 04 SUMMARY:
.planning/phases/08-social-sign-in/08-04-SUMMARY.md - Phase 8 Plan 05 SUMMARY:
.planning/phases/08-social-sign-in/08-05-SUMMARY.md - Commits (08):
2d004cd(social identity schema foundation),6779663(Google sign-in),a8b6a03(Apple implementation later disabled),59fd6b1(auth page provider controls),6e65836(account providers view + docs)
Last updated: 2026-05-15 after Phase 8 execution complete