---
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*
