6.8 KiB
6.8 KiB
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 12-native-tablo-chat | 03 | discussion |
|
|
|
|
|
|
|
|
|
~45min | 2026-05-16 |
Phase 12 Plan 03: Discussion Realtime Summary
Native realtime discussion delivery is implemented with Go-owned SSE receive and HTMX POST send.
Performance
- Duration: ~45 min
- Started: 2026-05-16T08:16:00Z
- Completed: 2026-05-16T08:33:05Z
- Tasks: 4
- Files modified: 9
Accomplishments
- Added RED tests for stream authentication, owner-only access, SSE headers, broker publishing, broker cancellation cleanup, and browser script behavior.
- Added
DiscussionBrokerwith per-tablo subscriptions, non-blocking publish, and unregister-on-cancel behavior. - Added protected
GET /tablos/{id}/discussion/streamwith SSE headers, initial flush, keepalives, and request-context cancellation. - Wired discussion POST to broadcast newly inserted messages after DB persistence and read-state update.
- Added local
/static/discussion-sse.jsEventSource integration with duplicate suppression. - Added form-level HTMX reset behavior so successful sends clear the composer reliably.
- Completed browser UAT: one visible row per sent message, composer clears, second tab receives messages without manual refresh, and no external realtime provider is used.
Task Commits
- Task 1: Add RED SSE handler and broker tests -
c6dcb68 - Task 2: Implement SSE broker, stream route, and local browser glue -
d15c374 - Realtime UAT fixes: duplicate suppression and composer reset -
6f17c30,426d89c,1034efc,409245e
Files Created/Modified
backend/internal/web/discussion_broker.go- Adds in-process discussion pub/sub.backend/internal/web/handlers_discussion.go- Adds stream handler and publish-after-insert behavior.backend/internal/web/handlers_discussion_test.go- Adds SSE, broker, and browser-script regression coverage.backend/internal/web/router.go- Adds discussion stream route and default broker wiring.backend/cmd/web/main.go- Wires production discussion broker.backend/templates/discussion.templ- Adds stream URL hook and form-level reset behavior.backend/templates/discussion_forms.go- Adds stream URL helper.backend/templates/layout.templ- Loads local discussion SSE script.backend/static/discussion-sse.js- Adds EventSource append and duplicate suppression.
Decisions Made
- The broker broadcasts persisted messages only after the database insert succeeds.
- The browser script does not surface connection state; EventSource handles silent reconnect.
- Sender duplicate prevention stays client-side because the same user may legitimately have a second tab that should receive the SSE event.
- Composer reset is attached to the HTMX form instead of a delegated script handler after HTMX v2 event detail differences made delegated source lookup brittle.
Deviations from Plan
- UAT found two UI regressions in the initial SSE implementation: sender-visible duplicate rows and composer text not clearing. Both were fixed before close-out.
Issues Encountered
- HTMX v2 event details did not expose the source form where the initial delegated reset handler expected it.
- Canceling duplicate swaps meant
detail.successfulwas not reliable for reset behavior, so reset moved onto the form withhx-on::after-request.
User Setup Required
None.
Verification
- RED command failed before implementation because SSE types/routes did not exist:
TEST_DATABASE_URL='postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable' go test ./internal/web -run 'TestDiscussionStream|TestDiscussionBroker|TestDiscussionPostBroadcasts' -count=1 cd backend && just generatepassed.cd backend && TEST_DATABASE_URL='postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable' go test ./internal/web -run 'TestDiscussionStream|TestDiscussionBroker|TestDiscussionPostBroadcasts|TestDiscussion' -count=1passed.cd backend && TEST_DATABASE_URL='postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable' go test ./... -count=1passed.git diff --checkpassed.- Browser UAT approved by user on 2026-05-16 after duplicate-row and composer-reset fixes.
Self-Check: PASSED
- CHAT-04 is covered by SSE implementation and browser UAT.
- CHAT-05 is satisfied with only Xtablo-owned Go/Postgres/static infrastructure.
- No WebSocket, managed chat, external realtime runtime, or runtime CDN script was added.
- Stream auth, ownership, headers, broker publish, and cancellation cleanup have automated coverage.
Phase 12 Readiness
Phase 12 is ready for final phase verification and close-out.
Phase: 12-native-tablo-chat Completed: 2026-05-16