diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 350b2f3..d67a2cc 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -18,12 +18,12 @@ Requirements for milestone v2.0. Each requirement must map to exactly one roadma ### Chat -- [ ] **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 +- [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 - [ ] **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 +- [x] **CHAT-06**: Message rendering escapes user content and enforces a server-side maximum body length ### Etapes diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 9b15065..4ba1040 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -16,7 +16,7 @@ | 9 | Etapes | Tasks can be grouped under one-level etapes without breaking the kanban model | ETAPE-01..06 | | 10 | 4/4 | Complete | 2026-05-16 | | 11 | 2/2 | Complete | 2026-05-16 | -| 12 | Native Tablo Chat | Each tablo has persisted discussion with real-time delivery and no managed chat provider | CHAT-01..06 | +| 12 | 1/3 | In Progress| | --- diff --git a/.planning/STATE.md b/.planning/STATE.md index 5504b63..1a5eb52 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v2.0 milestone_name: Collaboration, planning, and social sign-in status: executing -last_updated: "2026-05-16T08:03:11.927Z" +last_updated: "2026-05-16T08:11:52.739Z" last_activity: 2026-05-16 -- Phase 12 planning complete progress: total_phases: 5 completed_phases: 4 total_plans: 18 - completed_plans: 15 - percent: 83 + completed_plans: 16 + percent: 89 --- # STATE @@ -121,6 +121,7 @@ Resume file: .planning/phases/12-native-tablo-chat/12-01-PLAN.md | Phase 08 P05 | 20min | 2 tasks | 7 files | | Phase 11 P01 | ~15min | 2 tasks | 15 files | | Phase 11 P02 | ~20min | 2 tasks | 4 files | +| Phase 12 P01 | ~25min | 3 tasks | 22 files | ## Notes diff --git a/.planning/phases/12-native-tablo-chat/12-01-SUMMARY.md b/.planning/phases/12-native-tablo-chat/12-01-SUMMARY.md new file mode 100644 index 0000000..5d6962d --- /dev/null +++ b/.planning/phases/12-native-tablo-chat/12-01-SUMMARY.md @@ -0,0 +1,130 @@ +--- +phase: 12-native-tablo-chat +plan: 01 +subsystem: discussion +tags: [chat, discussion, postgres, sqlc, htmx, templ] + +requires: + - phase: 03-tablos-crud + provides: protected tablo detail page and owner-only `loadOwnedTablo` + - phase: 10-events + provides: recent child-tab routing and full-page fallback pattern +provides: + - Discussion message schema and sqlc queries + - Protected Discussion tab with full-page fallback + - CSRF-protected message POST with server validation + - Escaped server-rendered message history and composer UI +affects: [discussion, tablos, router, templates, tests] + +tech-stack: + added: [] + patterns: + - "Discussion sends remain normal CSRF-protected POST requests." + - "Message history renders through templ escaped expressions with whitespace-preserving text." + +key-files: + created: + - backend/migrations/0009_discussion.sql + - backend/internal/db/queries/discussion.sql + - backend/internal/web/handlers_discussion.go + - backend/internal/web/handlers_discussion_test.go + - backend/templates/discussion.templ + - backend/templates/discussion_forms.go + modified: + - backend/internal/web/router.go + - backend/cmd/web/main.go + - backend/templates/tablos.templ + +key-decisions: + - "Use email fallback for Phase 12 author labels; no user display-name schema added." + - "Use 10000 characters as the first server-side maximum message body length." + - "Keep read-state schema in the initial migration so later unread work has durable storage." + +patterns-established: + - "Tablo detail now accepts Discussion tab data alongside task/file/event tab data." + - "Discussion POST renders the sender's message fragment immediately for HTMX." + +requirements-completed: [CHAT-01, CHAT-02, CHAT-03, CHAT-06] + +duration: ~25min +completed: 2026-05-16 +--- + +# Phase 12 Plan 01: Persisted Discussion Tab Summary + +**Native per-tablo discussion history and posting are implemented in the Go/HTMX backend.** + +## Performance + +- **Duration:** ~25 min +- **Started:** 2026-05-16T08:05:00Z +- **Completed:** 2026-05-16T08:30:00Z +- **Tasks:** 3 +- **Files modified:** 22 + +## Accomplishments + +- Added `discussion_messages` and `discussion_read_states` schema with lifecycle metadata for future edit/delete support. +- Added sqlc queries for discussion history, message creation, message lookup with author email, and read-state upsert. +- Added DB-backed RED tests covering history rendering, full-page fallback, POST send, validation, ownership, CSRF, escaping, ordering, and out-of-scope controls. +- Added `DiscussionDeps`, protected discussion routes, and production/test router wiring. +- Added restrained templ UI for Discussion heading, participant count, day separators, message rows, empty state, and textarea composer. + +## Task Commits + +1. **Task 1: Add discussion schema and sqlc queries** - `68884da` +2. **Task 2: Add RED discussion handler tests** - `39e21be` +3. **Task 3: Implement discussion tab, templates, and POST send** - `c5477e4` + +## Files Created/Modified + +- `backend/migrations/0009_discussion.sql` - Adds message and read-state tables. +- `backend/internal/db/queries/discussion.sql` - Adds typed discussion queries. +- `backend/internal/web/handlers_discussion.go` - Adds tab and POST handlers. +- `backend/internal/web/handlers_discussion_test.go` - Adds DB-backed discussion coverage. +- `backend/templates/discussion.templ` - Adds Discussion UI. +- `backend/templates/discussion_forms.go` - Adds view models and helpers. +- Router/main/test call sites - Wire `DiscussionDeps`. +- `backend/templates/tablos.templ` - Adds Discussion tab link and active tab branch. + +## Decisions Made + +- Author display uses `users.email` for Phase 12; no account profile/display-name expansion was needed. +- Body length is enforced at 10000 characters in both schema and handler validation. +- GET `/tablos/{id}/discussion` marks the latest loaded message as read when messages exist, preparing Plan 12-02 unread behavior. + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None. + +## User Setup Required + +None. + +## Verification + +- RED command with local DB failed before implementation with missing discussion routes: + `TEST_DATABASE_URL='postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable' go test ./internal/web -run 'TestDiscussion' -count=1` +- `cd backend && just generate` passed. +- `cd backend && TEST_DATABASE_URL='postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable' go test ./internal/web -run 'TestDiscussion' -count=1` passed. +- `cd backend && go test ./internal/web -count=1` passed. +- `git diff --check` passed. + +## Self-Check: PASSED + +- Created files exist on disk. +- Task commits exist for `12-01`. +- CHAT-01, CHAT-02, CHAT-03, and CHAT-06 are covered by tests and implementation. +- No open deviations. + +## Next Phase Readiness + +Ready for Plan 12-02: persistent unread badge and read-state integration. + +--- +*Phase: 12-native-tablo-chat* +*Completed: 2026-05-16*