All checks were successful
check / check (push) Successful in 1m51s
Backend: - Session/client UUID model: sessions table (uuid, nick, signing_key), clients table (uuid, session_id, token) with per-client message queues - MOTD delivery as IRC numeric messages (375/372/376) on connect - EnqueueToSession fans out to all clients of a session - EnqueueToClient for targeted delivery (MOTD) - All queries updated for session/client model SPA client: - Long-poll loop (15s timeout) instead of setInterval - IRC message envelope parsing (command/from/to/body) - Display JOIN/PART/NICK/TOPIC/QUIT system messages - Nick change via /nick command - Topic display in header bar - Unread count badges on inactive tabs - Auto-rejoin channels on reconnect (localStorage) - Connection status indicator - Message deduplication by UUID - Channel history loaded on join - /topic command support Closes #9
68 lines
2.6 KiB
SQL
68 lines
2.6 KiB
SQL
-- Chat server schema (pre-1.0 consolidated)
|
|
PRAGMA foreign_keys = ON;
|
|
|
|
-- Sessions: IRC-style sessions (no passwords, nick + optional signing key)
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
uuid TEXT NOT NULL UNIQUE,
|
|
nick TEXT NOT NULL UNIQUE,
|
|
signing_key TEXT NOT NULL DEFAULT '',
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
last_seen DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_uuid ON sessions(uuid);
|
|
|
|
-- Clients: each session can have multiple connected clients
|
|
CREATE TABLE IF NOT EXISTS clients (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
uuid TEXT NOT NULL UNIQUE,
|
|
session_id INTEGER NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
token TEXT NOT NULL UNIQUE,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
last_seen DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_clients_token ON clients(token);
|
|
CREATE INDEX IF NOT EXISTS idx_clients_session ON clients(session_id);
|
|
|
|
-- Channels
|
|
CREATE TABLE IF NOT EXISTS channels (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL UNIQUE,
|
|
topic TEXT NOT NULL DEFAULT '',
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Channel members
|
|
CREATE TABLE IF NOT EXISTS channel_members (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
channel_id INTEGER NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
session_id INTEGER NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
joined_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(channel_id, session_id)
|
|
);
|
|
|
|
-- Messages: IRC envelope format
|
|
CREATE TABLE IF NOT EXISTS messages (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
uuid TEXT NOT NULL UNIQUE,
|
|
command TEXT NOT NULL DEFAULT 'PRIVMSG',
|
|
msg_from TEXT NOT NULL DEFAULT '',
|
|
msg_to TEXT NOT NULL DEFAULT '',
|
|
body TEXT NOT NULL DEFAULT '[]',
|
|
meta TEXT NOT NULL DEFAULT '{}',
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_messages_to_id ON messages(msg_to, id);
|
|
CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at);
|
|
|
|
-- Per-client message queues for fan-out delivery
|
|
CREATE TABLE IF NOT EXISTS client_queues (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
client_id INTEGER NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
|
|
message_id INTEGER NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(client_id, message_id)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_client_queues_client ON client_queues(client_id, id);
|