From 39a1e4d21da17d27a3fe80a60597cd95e6db49e4 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Fri, 15 May 2026 20:15:26 +0200 Subject: [PATCH] docs: define milestone v2.0 requirements --- .planning/REQUIREMENTS.md | 170 +++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 96 deletions(-) diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 6461b8f..0c3f3b2 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -1,133 +1,111 @@ -# Requirements: Xtablo Go+HTMX Rewrite +# Requirements: Xtablo v2.0 Collaboration, Planning, and Social Sign-in -**Defined:** 2026-05-14 -**Core Value:** A user can sign in and run the Tablos workflow — create tablos, manage their tasks (kanban), and attach files — without a JS framework. +**Defined:** 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. -## v1 Requirements +## v2.0 Requirements -Requirements for the initial Go+HTMX milestone. Each maps to exactly one roadmap phase. - -### Foundation - -- [ ] **FOUND-01**: Fresh `backend/` Go package with module init, `cmd/web` and `cmd/worker` entrypoints, and a runnable HTTP server returning `/healthz` -- [ ] **FOUND-02**: Postgres connection pool with env-driven config and a versioned migration tool (e.g. `goose` or `migrate`) wired into a `justfile`/`Makefile` -- [ ] **FOUND-03**: HTMX + Tailwind + templ rendering pipeline producing a base layout with a working dev loop (template hot-reload, CSS rebuild) -- [ ] **FOUND-04**: Structured logging, request ID middleware, and graceful shutdown on the web server -- [ ] **FOUND-05**: `.env.example`, local Postgres via `compose.yaml`, and a `justfile` documenting `dev`, `migrate`, `test`, `lint` +Requirements for milestone v2.0. Each requirement must map to exactly one roadmap phase. ### Authentication -- [x] **AUTH-01**: User can sign up with email and password (server-side validation, bcrypt/argon2 hash) -- [x] **AUTH-02**: User can log in with email and password and receives a server-managed session -- [x] **AUTH-03**: Sessions persist via HTTP-only, signed cookies (Secure + SameSite=Lax) and survive browser refresh -- [x] **AUTH-04**: User can log out from any authenticated page (server invalidates session) -- [x] **AUTH-05**: Protected routes redirect unauthenticated requests to the login page; authenticated users on auth pages are sent to the dashboard -- [x] **AUTH-06**: CSRF protection on all state-changing requests -- [x] **AUTH-07**: Rate-limited login attempts per email + IP to discourage credential stuffing +- [ ] **AUTH-08**: User can start a Google sign-in flow from the login/signup page +- [ ] **AUTH-09**: Google callback validates state, exchanges the authorization code, verifies the ID token, and creates or links a local Xtablo user +- [ ] **AUTH-10**: User can start an Apple sign-in flow from the login/signup page +- [ ] **AUTH-11**: Apple callback validates state/nonce, exchanges the authorization code, verifies the ID token, and creates or links a local Xtablo user +- [ ] **AUTH-12**: Social sign-in issues the same server-managed Xtablo session cookie used by email/password login +- [ ] **AUTH-13**: Existing email/password login, signup, logout, CSRF, and rate limiting continue to work after social sign-in is added -### Tablos +### Chat -- [x] **TABLO-01**: Authenticated user can list their tablos on the dashboard (newest first) -- [x] **TABLO-02**: User can create a tablo with at minimum a title (and optional description) -- [x] **TABLO-03**: User can view a single tablo's detail page (only owners can view in v1) -- [x] **TABLO-04**: User can edit a tablo's title and description -- [x] **TABLO-05**: User can delete a tablo (soft delete or hard delete; user-in-loop on schema decision) -- [x] **TABLO-06**: All tablo mutations are HTMX-driven (no full page reloads for CRUD actions) +- [ ] **CHAT-01**: Each tablo has a discussion view where authenticated authorized users can see persisted message history +- [ ] **CHAT-02**: User can post a text message to a tablo discussion with validation and CSRF protection +- [ ] **CHAT-03**: Messages are stored in Postgres with tablo, author, body, created timestamp, and deletion/edit metadata +- [ ] **CHAT-04**: Open tablo discussion views receive new messages in real time without a manual refresh +- [ ] **CHAT-05**: Real-time delivery uses Xtablo-owned infrastructure only; no managed chat or realtime provider is introduced +- [ ] **CHAT-06**: Message rendering escapes user content and enforces a server-side maximum body length -### Tasks (Kanban) +### Etapes -- [x] **TASK-01**: Each tablo has a kanban board with named columns (e.g. To do / Doing / Done; configurable in v1 or fixed — user-in-loop on schema) -- [x] **TASK-02**: User can create a task inside a column with a title -- [x] **TASK-03**: User can edit a task's title and description -- [x] **TASK-04**: User can move a task between columns (HTMX + drag-and-drop or button-based reorder, decided in plan-phase) -- [x] **TASK-05**: User can reorder tasks within a column -- [x] **TASK-06**: User can delete a task -- [x] **TASK-07**: Task ordering persists across refreshes +- [ ] **ETAPE-01**: User can create an etape inside a tablo with a title and optional description +- [ ] **ETAPE-02**: User can edit, delete, and reorder etapes inside a tablo +- [ ] **ETAPE-03**: User can assign a task to zero or one etape +- [ ] **ETAPE-04**: Deleting an etape unassigns its tasks by default rather than deleting the tasks +- [ ] **ETAPE-05**: The task UI can show or filter tasks by etape while preserving existing kanban status and ordering behavior +- [ ] **ETAPE-06**: The data model prevents nested etapes; an etape cannot have a parent etape -### Files +### Events -- [x] **FILE-01**: User can upload a file (with size limit) to a tablo; metadata stored in Postgres, bytes stored in S3-compatible storage (R2) -- [x] **FILE-02**: Uploads use direct-to-S3 presigned PUT URLs OR server-proxied upload (decided in plan-phase) -- [x] **FILE-03**: User can list files attached to a tablo with original filename and size -- [x] **FILE-04**: User can download a file via a signed time-limited URL -- [x] **FILE-05**: User can delete an attached file (removes both DB row and S3 object) -- [x] **FILE-06**: Authorization checks ensure only the tablo owner can upload/list/download/delete +- [ ] **EVENT-01**: User can create a scheduled event attached to a tablo with title, start time, optional end time, optional description, and optional location +- [ ] **EVENT-02**: User can edit and delete tablo events +- [ ] **EVENT-03**: Tablo detail page includes an events view listing that tablo's scheduled events +- [ ] **EVENT-04**: Event validation requires an end time to be empty or after the start time +- [ ] **EVENT-05**: Event authorization follows tablo access rules so users cannot read or mutate events for inaccessible tablos -### Worker +### Planning -- [x] **WORK-01**: `cmd/worker` binary connects to the same Postgres and runs a job queue (e.g. `river`, `asynq`, or a hand-rolled `pg_notify` queue — decided in plan-phase) -- [x] **WORK-02**: At least one real job runs end-to-end (e.g. periodic signed-URL prewarm OR scheduled file-orphan cleanup) to prove the wiring -- [x] **WORK-03**: Worker has structured logging and graceful shutdown matching the web binary -- [x] **WORK-04**: Failed jobs are retried with backoff and visible in a simple admin/CLI surface +- [ ] **PLAN-01**: Each authenticated user can open an individual planning page +- [ ] **PLAN-02**: Planning page lists the user's scheduled events across tablos in chronological order +- [ ] **PLAN-03**: Planning page links each event back to its tablo context +- [ ] **PLAN-04**: Planning page supports a functional empty state and date navigation/filtering suitable for the first working version -### Deploy +## Future Requirements -- [ ] **DEPLOY-01**: Both binaries build into a single multi-stage Docker image (or two stages from one Dockerfile) -- [ ] **DEPLOY-02**: Image runs on a single VPS / Cloud Run-style host with env-injected config (no Supabase, no GCP Secret Manager required for v1) -- [ ] **DEPLOY-03**: Migrations run on deploy (entrypoint or pre-deploy step) without manual intervention -- [ ] **DEPLOY-04**: Health checks (`/healthz`, `/readyz`) and structured logs that a basic uptime monitor can consume -- [ ] **DEPLOY-05**: A documented runbook in `backend/README.md` covers local dev, deploy, and rollback +Deferred beyond v2.0. -## v2 Requirements +### Chat -Acknowledged, not in current roadmap. +- **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 -### Booking +### Planning -- **BOOK-01**: Public embeddable booking widget (port of `apps/external`) -- **BOOK-02**: Event types + availabilities backend +- **PLAN-FUT-01**: Recurring events +- **PLAN-FUT-02**: Reminder notifications +- **PLAN-FUT-03**: ICS import/export +- **PLAN-FUT-04**: External calendar sync -### Client Portal +### Etapes -- **CLIENT-01**: Magic-link client portal (port of `apps/clients`) - -### Admin - -- **ADMIN-01**: Internal admin tooling (port of `apps/admin`) - -### Tablo Sub-features - -- **TABLO-NOTES**: Rich notes inside a tablo -- **TABLO-ETAPES**: Etapes / roadmap sections inside a tablo -- **TABLO-EVENTS**: Calendar events tied to a tablo - -### Communication & Billing - -- **CHAT-01**: Real-time discussion inside a tablo (replacement for Stream Chat) -- **BILL-01**: Stripe subscriptions + entitlement gating +- **ETAPE-FUT-01**: Etape progress rollups +- **ETAPE-FUT-02**: Etape templates +- **ETAPE-FUT-03**: Etape dependencies ## Out of Scope | Feature | Reason | |---------|--------| -| Third-party auth (Clerk, Auth0, Lucia) | Explicit "no 3rd party" decision — built-in sessions only | -| Supabase as runtime dependency | Drop the BaaS; Postgres only | -| React / SPA frontend | Whole point of the rewrite is HTMX + server templates | -| Stream Chat / Durable Object chat | Complexity not justified for v1; possibly revisited as a Go-native version | -| Mobile / Expo app | Web rewrite first; mobile not in scope | -| Existing `go-backend/` directory as foundation | Set aside; fresh `backend/` package | -| Full feature parity with JS app before cutover | Leaner-by-design — v2 milestones add back what's worth keeping | -| Kubernetes / multi-node deployment | Single VPS/container target only | +| Managed chat/realtime providers | User explicitly does not want third-party chat | +| Managed auth platforms | Google/Apple are identity providers only; Xtablo owns users and sessions | +| WebSocket-first chat protocol | SSE receive + HTMX POST send is the recommended v2 path unless plan-phase proves WebSockets are needed | +| 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 | ## Traceability -Populated during roadmap creation in Step 8. +Populated during roadmap creation. | Requirement | Phase | Status | |-------------|-------|--------| -| FOUND-01..05 | Phase 1 | Pending | -| AUTH-01..07 | Phase 2 | Complete — verified 2026-05-14 | -| TABLO-01..06 | Phase 3 | Pending | -| TASK-01..07 | Phase 4 | Pending | -| FILE-01..06 | Phase 5 | Pending | -| WORK-01..04 | Phase 6 | Pending | -| DEPLOY-01..05 | Phase 7 | Pending | +| AUTH-08..13 | TBD | Pending | +| ETAPE-01..06 | TBD | Pending | +| EVENT-01..05 | TBD | Pending | +| PLAN-01..04 | TBD | Pending | +| CHAT-01..06 | TBD | Pending | **Coverage:** -- v1 requirements: 40 total -- Mapped to phases: 40 -- Unmapped: 0 ✓ +- v2.0 requirements: 27 total +- Mapped to phases: 0 +- Unmapped: 27 --- -*Requirements defined: 2026-05-14* -*Last updated: 2026-05-14 — AUTH-06 checkbox corrected to [x] after phase 2 verification* +*Requirements defined: 2026-05-15* +*Last updated: 2026-05-15 after v2.0 requirements draft*