go-htmx-gsd #1

Merged
arthur merged 558 commits from go-htmx-gsd into main 2026-05-23 15:16:44 +00:00
8 changed files with 373 additions and 20 deletions
Showing only changes of commit fcffb57df4 - Show all commits

33
.planning/MILESTONES.md Normal file
View file

@ -0,0 +1,33 @@
# Project Milestones: Xtablo
Entries are listed newest first.
## v2.0 Collaboration, Planning, and Social Sign-in (Shipped: 2026-05-16)
**Delivered:** Google sign-in, one-level etapes, tablo-owned events, personal planning, and native realtime tablo discussions on the Go + HTMX stack.
**Phases completed:** 8-12 (18 plans total)
**Key accomplishments:**
- Added Google social sign-in while preserving Xtablo-owned users and sessions.
- Added one-level etapes for task organization without breaking the kanban model.
- Added tablo-owned events and an authenticated personal planning agenda.
- Added native persisted realtime discussions using Postgres and Go-owned SSE.
- Kept collaboration and scheduling features inside the single Go + HTMX product architecture.
**Stats:**
- 148 files changed across the v2.0 git range
- 17,704 insertions and 527 deletions across the v2.0 git range
- 5 phases, 18 plans, approximately 39 implementation/verification tasks
- 2 days from milestone start to close (2026-05-15 -> 2026-05-16)
- Current backend source footprint: 29,101 lines across Go, templ, SQL, and CSS files
**Git range:** `0d23d94` -> `58a9ce0`
**Known deferred items at close:** 7 acknowledged open artifact items. See `.planning/STATE.md` Deferred Items and `.planning/milestones/v2.0-MILESTONE-AUDIT.md`.
**What's next:** v3.0 Design System & Visual Polish is already planned in `.planning/ROADMAP.md`.
---

View file

@ -72,7 +72,7 @@ If everything else fails, this must work end-to-end on a single Go binary backed
- Visuals will also change — no requirement to mirror the existing UI; Tailwind + HTMX patterns drive the new look.
- `go-backend/` already contains real scaffolding (router, sqlc, air, tailwind input). It is *not* the foundation — a fresh `backend/` package will be created.
- Developer is comfortable in Go and wants a low-dependency, server-rendered stack going forward.
- v2 UI can stay functional and plain; the user will provide a more polished visual design later. The milestone should focus on working behavior and clean integration points.
- v2 shipped functional and plain UI for collaboration and planning. v3 is the visual pass that ports the richer design system and applies it across product surfaces.
## Constraints
@ -90,17 +90,17 @@ If everything else fails, this must work end-to-end on a single Go binary backed
| Decision | Rationale | Outcome |
|----------|-----------|---------|
| Rewrite in Go + HTMX (no SPA) | Simpler stack, developer preference, product pivot | — Pending |
| Built-in sessions, no 3rd-party auth | Avoid vendor coupling; sessions are well-trodden ground | — Pending |
| Drop Supabase (keep Postgres) | Owning the auth + RLS story in Go is simpler than maintaining the boundary | — Pending |
| Fresh `backend/` Go package, set `go-backend/` aside | Existing scaffold has decisions to revisit; cleaner to start over | — Pending |
| v1 = Tablos workflow only (Tasks + Files), defer chat/billing/booking/portal/admin | Focus the rewrite around the load-bearing user loop first | — Pending |
| Single binary + background worker, single VPS deploy | Matches the "simpler stack" thesis; avoid orchestration cost early | — Pending |
| Rewrite in Go + HTMX (no SPA) | Simpler stack, developer preference, product pivot | ✓ Validated through v1-v2 |
| Built-in sessions, no 3rd-party auth | Avoid vendor coupling; sessions are well-trodden ground | ✓ Validated through email/password and Google sign-in |
| Drop Supabase (keep Postgres) | Owning the auth + RLS story in Go is simpler than maintaining the boundary | ✓ Validated through owned authz queries |
| Fresh `backend/` Go package, set `go-backend/` aside | Existing scaffold has decisions to revisit; cleaner to start over | ✓ Validated |
| v1 = Tablos workflow only (Tasks + Files), defer chat/billing/booking/portal/admin | Focus the rewrite around the load-bearing user loop first | ✓ Completed |
| Single binary + background worker, single VPS deploy | Matches the "simpler stack" thesis; avoid orchestration cost early | ✓ Validated for current deploy target |
| User-in-the-loop on Postgres schema for each domain | Schema is changing from JS version; explicit review before sqlc generation | — Pending |
| v2 chat is native, not vendor-backed | User explicitly does not want third-party chat; Postgres + Go should be enough for the first real-time version | — Pending |
| Google/Apple are identity providers only | Preserve server-owned users/sessions while allowing social sign-in | — Pending |
| Etapes are one-level wrappers around tasks | Matches the requested mental model and avoids recursive planning complexity | — Pending |
| Planning is individual, events remain tablo-scoped | Lets users see their schedule while preserving tablos as the source of work context | — Pending |
| v2 chat is native, not vendor-backed | User explicitly does not want third-party chat; Postgres + Go should be enough for the first real-time version | ✓ Validated with SSE receive + HTMX POST send |
| Google/Apple are identity providers only | Preserve server-owned users/sessions while allowing social sign-in | ✓ Google validated; Apple disabled for now |
| Etapes are one-level wrappers around tasks | Matches the requested mental model and avoids recursive planning complexity | ✓ Validated |
| Planning is individual, events remain tablo-scoped | Lets users see their schedule while preserving tablos as the source of work context | ✓ Validated |
## Evolution
@ -124,6 +124,7 @@ This document evolves at phase transitions and milestone boundaries.
- **Phase 1: Foundation** — Completed 2026-05-14. Fresh `backend/` Go package boots a web server, renders an HTMX-driven base layout, connects to local Postgres with goose migrations. FOUND-01..FOUND-05 satisfied; user-approved manual walkthrough. Two inline justfile/tailwind fixes during UAT (commit `fix(01): guard sqlc on empty queries and correct tailwind paths`).
- **Phase 7: deploy-v1** — Completed 2026-05-15. Multi-stage Dockerfile (assets→builder→distroless nonroot), docker-compose.prod.yaml with 4 services (postgres/web/worker/caddy), Caddyfile with `{$DOMAIN}` TLS, README runbook covering first-deploy/rollback/incident. DEPLOY-01..DEPLOY-05 satisfied. 3 UAT items (Docker build, compose config, live smoke test) pending on a Docker-equipped machine.
- **Milestone v2.0 started: Collaboration, planning, and social sign-in** — Started 2026-05-15. Scope: native per-tablo chat, one-level etapes, Google/Apple sign-in, and individual planning with tablo events.
- **Milestone v2.0 shipped: Collaboration, planning, and social sign-in** — Shipped 2026-05-16. Delivered Google sign-in, etapes, events, individual planning, and native SSE-backed tablo discussions. Closed with 7 acknowledged deferred artifact items; see `.planning/milestones/v2.0-MILESTONE-AUDIT.md`.
---
*Last updated: 2026-05-16 after starting milestone v3.0*
*Last updated: 2026-05-16 after archiving milestone v2.0*

View file

@ -0,0 +1,68 @@
# Project Retrospective
A living document updated after each milestone. Lessons feed forward into future planning.
## Milestone: v2.0 — Collaboration, Planning, and Social Sign-in
**Shipped:** 2026-05-16
**Phases:** 5 | **Plans:** 18 | **Sessions:** multiple GSD sessions
### What Was Built
- Google sign-in with Xtablo-owned user/session issuance and Apple sign-in disabled for the shipped scope.
- One-level etapes for organizing tasks while preserving existing kanban behavior.
- Tablo-owned scheduled events plus an authenticated personal planning agenda.
- Native per-tablo discussion history, posting, unread state, and realtime SSE delivery.
### What Worked
- The Go + HTMX stack handled new auth, planning, and realtime surfaces without introducing a JS framework or managed chat provider.
- DB-backed handler tests gave strong coverage for ownership, validation, and cross-tablo aggregation.
- UAT feedback during Phase 12 caught real browser behavior around duplicate rows and composer reset.
### What Was Inefficient
- Milestone close happened after v3.0 was already initialized, so archival had to preserve current v3 planning files instead of using the standard current-milestone deletion path.
- Some verification artifacts lagged behind shipped behavior, which made milestone audit status noisier than implementation state.
- Earlier v1 UAT/verification records still carry human-needed or partial statuses and should be cleaned separately if strict historical reporting matters.
### Patterns Established
- Use owned Postgres queries plus handler tests as the primary guardrail for cross-user isolation.
- Keep social identity providers as login inputs only; Xtablo sessions remain authoritative.
- For v2 realtime, SSE receive plus HTMX POST send is sufficient and keeps infrastructure local.
- Validation files should be closed immediately after phase execution to avoid stale milestone audits.
### Key Lessons
1. Archive a milestone before starting the next one, or make the close workflow explicitly support archival from a historical commit.
2. Treat `*-VERIFICATION.md` as a required phase exit artifact, not a later audit cleanup.
3. Browser UAT remains necessary for HTMX swap/reset behavior even when handler tests are green.
### Cost Observations
- Model mix: not tracked.
- Sessions: multiple interactive GSD sessions.
- Notable: most rework came from artifact hygiene and UAT-discovered browser behavior, not from core backend design.
---
## Cross-Milestone Trends
### Process Evolution
| Milestone | Sessions | Phases | Key Change |
|-----------|----------|--------|------------|
| v2.0 | multiple | 5 | Collaboration, scheduling, and realtime work stayed inside Go + HTMX; artifact hygiene needs tighter close discipline. |
### Cumulative Quality
| Milestone | Tests | Coverage | Zero-Dep Additions |
|-----------|-------|----------|-------------------|
| v2.0 | Go handler/DB suites plus browser UAT | Strong behavior coverage; some archive artifacts deferred | Native SSE chat, server-owned sessions, Postgres-backed planning |
### Top Lessons
1. Close phase validation and verification artifacts before running milestone audit.
2. Keep milestone archival before next-milestone initialization when possible.
3. Preserve browser UAT for HTMX interaction behavior.

View file

@ -8,6 +8,12 @@
---
## Previous Milestones
- [x] **v2.0 Collaboration, Planning, and Social Sign-in** — Phases 8-12, shipped 2026-05-16. Archive: [`milestones/v2.0-ROADMAP.md`](milestones/v2.0-ROADMAP.md)
---
## Phase Summary
| # | Phase | Goal | Requirements |

View file

@ -3,8 +3,8 @@ gsd_state_version: 1.0
milestone: v3.0
milestone_name: Design System & Visual Polish
status: planning
last_updated: "2026-05-16T08:52:04.598Z"
last_activity: 2026-05-16
last_updated: "2026-05-16T11:01:00+02:00"
last_activity: 2026-05-16 -- v2.0 milestone archived; v3.0 remains active
progress:
total_phases: 0
completed_phases: 0
@ -16,29 +16,29 @@ progress:
# STATE
**Project:** Xtablo Go+HTMX Product
**Milestone:** v2.0 — Collaboration, planning, and social sign-in
**Milestone:** v3.0 — Design System & Visual Polish
**Created:** 2026-05-14
## Project Reference
See: `.planning/PROJECT.md` (updated 2026-05-15)
See: `.planning/PROJECT.md` (updated 2026-05-16)
**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:** v2.0 milestone verification
**Current focus:** v3.0 design system and visual polish planning
## Current Position
Phase: Not started (defining requirements)
Plan: —
Status: Defining requirements
Last activity: 2026-05-16 — Milestone v3.0 started
Last activity: 2026-05-16 — v2.0 milestone archived; v3.0 remains active
## Phase Status
## Previous Milestone Status
| # | Phase | Status |
|---|-------|--------|
| 8 | Social Sign-in | ✓ Complete |
| 9 | Etapes | ◆ UAT passed; security pending |
| 9 | Etapes | ✓ Complete |
| 10 | Events | ✓ Complete |
| 11 | Individual Planning | ✓ Complete |
| 12 | Native Tablo Chat | ✓ Complete |
@ -49,6 +49,21 @@ Last activity: 2026-05-16 — Milestone v3.0 started
- 2026-05-15: Phase 9 UAT complete. Five browser checkpoints passed after fixing the selected-etape create gap; backend verification passed with `TEST_DATABASE_URL='postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable' go test ./... -count=1`.
- 2026-05-16: Phase 10 execution complete. Events UAT approved; backend verification passed with `TEST_DATABASE_URL='postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable' go test ./... -count=1`.
- 2026-05-16: Phase 12 execution complete. Discussion realtime UAT approved after duplicate-row and composer-reset fixes; backend verification passed with `just generate` and `TEST_DATABASE_URL='postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable' go test ./... -count=1`.
- 2026-05-16: Milestone v2.0 archived after acknowledging 7 legacy/open artifact items as deferred.
## Deferred Items
Items acknowledged and deferred at milestone close on 2026-05-16:
| Category | Item | Status |
|----------|------|--------|
| uat_gap | Phase 01: 01-HUMAN-UAT.md | resolved; 0 pending scenarios |
| uat_gap | Phase 05: 05-HUMAN-UAT.md | partial; 6 pending scenarios |
| uat_gap | Phase 07: 07-HUMAN-UAT.md | partial; 3 pending scenarios |
| verification_gap | Phase 03: 03-VERIFICATION.md | human_needed |
| verification_gap | Phase 04: 04-VERIFICATION.md | human_needed |
| verification_gap | Phase 05: 05-VERIFICATION.md | human_needed |
| verification_gap | Phase 07: 07-VERIFICATION.md | human_needed |
## Decisions

View file

@ -0,0 +1,101 @@
# Requirements Archive: Xtablo v2.0 Collaboration, Planning, and Social Sign-in
**Archived:** 2026-05-16
**Source commit:** `58a9ce0`
**Outcome:** Shipped with acknowledged audit debt
## 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.
## Completed Requirements
### Authentication
- [x] **AUTH-08**: User can start a Google sign-in flow from the login/signup page
- [x] **AUTH-09**: Google callback validates state, exchanges the authorization code, verifies the ID token, and creates or links a local Xtablo user
- [x] **AUTH-10**: Apple sign-in is disabled and hidden from the login/signup page
- [x] **AUTH-11**: Direct Apple sign-in routes are unavailable while Apple sign-in is disabled
- [x] **AUTH-12**: Social sign-in issues the same server-managed Xtablo session cookie used by email/password login
- [x] **AUTH-13**: Existing email/password login, signup, logout, CSRF, and rate limiting continue to work after social sign-in is added
### Chat
- [x] **CHAT-01**: Each tablo has a discussion view where authenticated authorized users can see persisted message history
- [x] **CHAT-02**: User can post a text message to a tablo discussion with validation and CSRF protection
- [x] **CHAT-03**: Messages are stored in Postgres with tablo, author, body, created timestamp, and deletion/edit metadata
- [x] **CHAT-04**: Open tablo discussion views receive new messages in real time without a manual refresh
- [x] **CHAT-05**: Real-time delivery uses Xtablo-owned infrastructure only; no managed chat or realtime provider is introduced
- [x] **CHAT-06**: Message rendering escapes user content and enforces a server-side maximum body length
### Etapes
- [x] **ETAPE-01**: User can create an etape inside a tablo with a title and optional description
- [x] **ETAPE-02**: User can edit, delete, and reorder etapes inside a tablo
- [x] **ETAPE-03**: User can assign a task to zero or one etape
- [x] **ETAPE-04**: Deleting an etape unassigns its tasks by default rather than deleting the tasks
- [x] **ETAPE-05**: The task UI can show or filter tasks by etape while preserving existing kanban status and ordering behavior
- [x] **ETAPE-06**: The data model prevents nested etapes; an etape cannot have a parent etape
### Events
- [x] **EVENT-01**: User can create a scheduled event attached to a tablo with title, start time, optional end time, optional description, and optional location
- [x] **EVENT-02**: User can edit and delete tablo events
- [x] **EVENT-03**: Tablo detail page includes an events view listing that tablo's scheduled events
- [x] **EVENT-04**: Event validation requires an end time to be empty or after the start time
- [x] **EVENT-05**: Event authorization follows tablo access rules so users cannot read or mutate events for inaccessible tablos
### Planning
- [x] **PLAN-01**: Each authenticated user can open an individual planning page
- [x] **PLAN-02**: Planning page lists the user's scheduled events across tablos in chronological order
- [x] **PLAN-03**: Planning page links each event back to its tablo context
- [x] **PLAN-04**: Planning page supports a functional empty state and date navigation/filtering suitable for the first working version
## Traceability
| Requirement | Phase | Final Status | Notes |
|-------------|-------|--------------|-------|
| AUTH-08..13 | Phase 8 | Complete with audit artifact debt | Implementation and validation passed; strict milestone audit wanted `08-VERIFICATION.md`. |
| ETAPE-01..06 | Phase 9 | Complete with archive correction | Source requirements were stale; `09-VALIDATION.md` and UAT evidence confirm completion. |
| EVENT-01..05 | Phase 10 | Complete | `10-VERIFICATION.md` and `10-VALIDATION.md` passed. |
| PLAN-01..04 | Phase 11 | Complete with validation draft debt | `11-VERIFICATION.md` passed; `11-VALIDATION.md` remained draft. |
| CHAT-01..06 | Phase 12 | Complete with audit artifact debt | Implementation, validation, and UAT passed; strict milestone audit wanted `12-VERIFICATION.md`. |
## Future Requirements
### Chat
- **CHAT-FUT-01**: Typing indicators
- **CHAT-FUT-02**: Read receipts
- **CHAT-FUT-03**: Message reactions
- **CHAT-FUT-04**: Threads or replies
- **CHAT-FUT-05**: File previews in chat messages
### Planning
- **PLAN-FUT-01**: Recurring events
- **PLAN-FUT-02**: Reminder notifications
- **PLAN-FUT-03**: ICS import/export
- **PLAN-FUT-04**: External calendar sync
### Etapes
- **ETAPE-FUT-01**: Etape progress rollups
- **ETAPE-FUT-02**: Etape templates
- **ETAPE-FUT-03**: Etape dependencies
## Out of Scope
| Feature | Reason |
|---------|--------|
| Managed chat/realtime providers | User explicitly does not want third-party chat. |
| Managed auth platforms | Google is an identity provider only; Xtablo owns users and sessions. Apple sign-in is disabled for now. |
| WebSocket-first chat protocol | SSE receive + HTMX POST send shipped for v2. |
| Nested etapes or arbitrary task hierarchy | User requested one parent per task and no parent-of-parent. |
| Notes / rich documents | Not part of the requested v2 feature set. |
| Billing / Stripe | Still deferred until product loop is validated. |
| Public booking widget | Separate product surface, not part of this milestone. |
| Client portal | Separate product surface, not part of this milestone. |
| Admin tooling | Separate product surface, not part of this milestone. |
| Mobile / Expo app | Web rewrite remains the current product surface. |

View file

@ -0,0 +1,129 @@
# Milestone v2.0: Collaboration, Planning, and Social Sign-in
**Status:** SHIPPED 2026-05-16
**Phases:** 8-12
**Total Plans:** 18
**Source commit:** `58a9ce0`
## Overview
v2.0 added the collaboration and scheduling layer around tablos while keeping the Go + HTMX architecture: Google sign-in, one-level etapes for task organization, tablo-owned events, a personal planning agenda, and native persisted realtime discussions.
The milestone was closed after acknowledging 7 legacy/open artifact items from earlier phase UAT and verification records. Runtime v2.0 flows were kept as shipped; the acknowledged items are tracked in `STATE.md` and the archived audit.
## Phases
### Phase 8: Social Sign-in
**Goal:** Users can sign in with Google while Xtablo keeps owning user accounts and sessions; Apple sign-in is disabled and hidden for now.
**Plans:** 5
**Requirements:** AUTH-08, AUTH-09, AUTH-10, AUTH-11, AUTH-12, AUTH-13
Plans:
- [x] 08-01: Social identity schema foundation
- [x] 08-02: Google OAuth/OIDC sign-in flow
- [x] 08-03: Apple sign-in implementation, later disabled by UAT scope change
- [x] 08-04: Social sign-in controls and missing-config states
- [x] 08-05: Account provider visibility and final docs/regression coverage
Outcome:
- Google social sign-in starts from auth pages, validates callback state, links by provider subject or verified email, and issues existing Xtablo sessions.
- Apple sign-in was intentionally disabled after UAT; routes are not mounted and controls are hidden.
- Provider configuration is documented without committing secrets.
### Phase 9: Etapes
**Goal:** A user can organize tasks under one-level etapes inside a tablo while preserving existing task status and ordering behavior.
**Plans:** 4
**Requirements:** ETAPE-01, ETAPE-02, ETAPE-03, ETAPE-04, ETAPE-05, ETAPE-06
Plans:
- [x] 09-01: Etape create/filter/assigned-task slice
- [x] 09-02: Etape edit, delete-unassign, and reorder management
- [x] 09-03: Task assignment and filter-aware task loading
- [x] 09-04: Reorder preservation, count refresh fixes, and UAT closure
Outcome:
- Etapes are tablo-owned one-level wrappers; tasks can belong to zero or one etape.
- Deleting an etape unassigns its tasks instead of deleting them.
- Task assignment, filtering, and reorder behavior remain compatible with the existing kanban model.
### Phase 10: Events
**Goal:** A user can schedule events that belong to tablos, with the same authorization expectations as tasks and files.
**Plans:** 4
**Requirements:** EVENT-01, EVENT-02, EVENT-03, EVENT-04, EVENT-05
Plans:
- [x] 10-01: Event creation and month calendar listing
- [x] 10-02: Inline edit, update validation, and hard delete
- [x] 10-03: Month navigation, day prefill, overflow display, and planning query
- [x] 10-04: Final regression coverage, full backend verification, and browser UAT
Outcome:
- Tablo events support title, date, start time, optional end time, location, and description.
- Invalid end times are rejected by handler validation and database constraint.
- Event access follows tablo ownership; inaccessible events cannot be read or mutated.
### Phase 11: Individual Planning
**Goal:** Each authenticated user can open a personal planning view that aggregates their scheduled events across tablos.
**Plans:** 2
**Requirements:** PLAN-01, PLAN-02, PLAN-03, PLAN-04
Plans:
- [x] 11-01: Protected planning agenda with owned cross-tablo event aggregation
- [x] 11-02: Full verification and UAT-approved 14-day planning agenda
Outcome:
- `/planning` is authenticated and lists the user's owned events chronologically.
- Event rows link back to their source tablo event context.
- Empty state, invalid-date fallback, and 14-day navigation were verified.
### Phase 12: Native Tablo Chat
**Goal:** Each tablo has a native persisted discussion stream with real-time updates and no managed chat/realtime provider.
**Plans:** 3
**Requirements:** CHAT-01, CHAT-02, CHAT-03, CHAT-04, CHAT-05, CHAT-06
Plans:
- [x] 12-01: Discussion schema, history, posting, validation, and templates
- [x] 12-02: Persistent unread state and dashboard/discussion read paths
- [x] 12-03: Native realtime discussion delivery with Go-owned SSE receive and HTMX POST send
Outcome:
- Discussion history and sends are persisted in Postgres with ownership, CSRF, escaping, and body length validation.
- Realtime receive uses local Go SSE infrastructure; no managed chat or realtime provider was added.
- Duplicate sender rows and composer reset behavior were fixed during UAT.
## Milestone Summary
**Key accomplishments:**
- Added Google social sign-in while preserving Xtablo-owned sessions and disabling Apple sign-in for the shipped scope.
- Added one-level etapes for organizing tasks without changing the kanban status model.
- Added tablo-owned events and a personal planning agenda that aggregates owned events across tablos.
- Added native persisted realtime discussions using Postgres and Go-owned SSE.
- Kept the milestone inside the low-dependency Go + HTMX architecture.
**Known deferred items at close:** 7 acknowledged open artifact items. See `STATE.md` Deferred Items and `v2.0-MILESTONE-AUDIT.md`.
**Technical debt carried forward:**
- Phase 8, 9, and 12 lacked strict `*-VERIFICATION.md` aggregation artifacts in the archived milestone audit.
- Phase 11 validation remained draft even though `11-VERIFICATION.md` passed.
- Earlier v1 UAT/verification records still contain acknowledged human-needed or partial statuses.
---
For current project status, see `.planning/ROADMAP.md`.