mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 14:41:28 -07:00
38 lines
1.8 KiB
SQL
38 lines
1.8 KiB
SQL
-- Chat threads and their membership, owned by the `chat` worker.
|
|
--
|
|
-- A thread is a conversation — a DM pair, a group chat, or a system thread. Membership
|
|
-- in `thread_member` is the authorization gate: a player may read or post to a thread
|
|
-- only if they hold a row here, and the same rows render the `playerIds` array the
|
|
-- client shows. There is deliberately no FK to accounts, here or on
|
|
-- `message.sender_player_id`: that table belongs to the `auth` worker, and a thread
|
|
-- outlives the accounts in it.
|
|
--
|
|
-- `latest_message_id` is denormalized onto the thread so the thread list renders from
|
|
-- one indexed row per thread instead of a per-thread MAX() over `message`; it also
|
|
-- orders that list (message ids being monotonic, newest thread = highest id). Kept in
|
|
-- sync on every insert — see touchThread in src/thread-db.ts.
|
|
--
|
|
-- The per-viewer fields live on the membership row, not the thread: two players in one
|
|
-- DM have independent read positions, snoozes, and favorites. Kept in sync with
|
|
-- THREAD_SCHEMA_DDL in src/thread-db.ts.
|
|
|
|
CREATE TABLE IF NOT EXISTS message_thread (
|
|
chat_thread_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
-- Null for DMs and unnamed groups; the client falls back to rendering the members.
|
|
chat_thread_name TEXT,
|
|
latest_message_id INTEGER,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_message_thread_latest ON message_thread (latest_message_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS thread_member (
|
|
chat_thread_id INTEGER NOT NULL,
|
|
player_id INTEGER NOT NULL,
|
|
last_read_message_id INTEGER,
|
|
snoozed_until TEXT,
|
|
is_favorited INTEGER NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (chat_thread_id, player_id)
|
|
);
|
|
-- The thread-list query is "every thread this player is in", so player_id leads.
|
|
CREATE INDEX IF NOT EXISTS idx_thread_member_player ON thread_member (player_id);
|