Topic-based communication system with liveblog-style stories that accumulate updates over time — so a single story like "FAA Shutdown 2026" lives on one page with a running timeline instead of fragmenting across disconnected posts. Click any tile to view.
Branch: feature/updates-system-mockups · See docs/architecture/decisions/001-updates-system.md for the full spec.
Topic-filtered feed showing stories as cards with update counts, live indicators, and latest-update previews. The main browse experience at /updates.
Stable story headline + editor-maintained summary + pinned key points + chronological stream of timestamped updates. Think news liveblog. Reached via /updates/[slug].
Configurable card on the Hub landing page. Members pick which topics appear. Urgent posts always pin first.
Per-topic email subscription toggles. Clearly separated from Hub display filters.
Quick-find interface for admins. Search stories, filter by status/topic/author, click "+ Post Update" to append to an existing story instead of starting a new one.
Markdown editor for creating a new story + first update. Topic selector, urgent flag, story status, publish controls. Gated by grants.
Dedicated #updates forum channel. Each story is a forum post, each update is a reply. Topic tags map directly to Discord's built-in forum tags. Browse grid, tag filtering, follow-post tracking — all Discord-native.
Existing text channels (#national-updates, etc.). First update posts in the channel with a rich embed; a thread auto-attaches and all subsequent updates post inside it. Works with your current channel layout.
How a single story (one update, never updated) looks as a standalone embed. Reference for simple announcements.
Urgent message shown with role @mention, action buttons, and red border. Works in text channel, forum post, or thread.
This is Phase 0 of the Updates system — a visual spec before we write any functional code. The goal is to lock down the UI and interaction patterns so we can build the real Vue components (Phase 2) and Platform API (Phase 1) against a clear target.
Single announcements (like "Registration open for CFS conference") are just stories with one update. The data model is uniform.
/updates page always shows everything.Urgent flag is orthogonal: pins to top of Hub regardless of filter, always posts to Discord, (future) always emails the full active-member list.
Authors use a Tiptap-based WYSIWYG editor — no markdown syntax required. Images drag-drop into Supabase Storage. Under the hood we store three formats per update: body_json (Tiptap canonical), body_md (derived, for Discord + portability), body_html (derived cache). See the author mockup for the toolbar and rich content area.
Every published update gets an OpenAI embedding stored in Supabase's pgvector. Members can eventually ask natural-language questions like "What's the latest on H.R. 4412?" and get synthesized answers with citations back to the source stories. Data starts accumulating from day 1; the search UI lands in Phase 5. See ADR 001 for the RAG flow.
The current fragmented approach creates multiple disconnected posts about the same topic (e.g., three separate emails about the same shutdown negotiation). Members can't find the latest state of a story, and older context is lost. A liveblog model — like MS.now, Guardian rolling coverage, or NYT live updates — keeps everything about a story on one page, so members always land on the canonical, up-to-date view.
New topics can be added by inserting a row in updates.topics. The schema is fully extensible.