MVP: IRC envelope format, long-polling, per-client queues, SPA rewrite
Major changes: - Consolidated schema into single migration with IRC envelope format - Messages table stores command/from/to/body(JSON)/meta(JSON) per spec - Per-client delivery queues (client_queues table) with fan-out - In-memory broker for long-poll notifications (no busy polling) - GET /messages supports ?after=<queue_id>&timeout=15 long-polling - All commands (JOIN/PART/NICK/TOPIC/QUIT/PING) broadcast events - Channels are ephemeral (deleted when last member leaves) - PRIVMSG to nicks (DMs) fan out to both sender and recipient - SPA rewritten in vanilla JS (no build step needed): - Long-poll via recursive fetch (not setInterval) - IRC envelope parsing with system message display - /nick, /join, /part, /msg, /quit commands - Unread indicators on inactive tabs - DM tabs from user list clicks - Removed unused models package (was for UUID-based schema) - Removed conflicting UUID-based db methods - Increased HTTP write timeout to 60s for long-poll support
This commit is contained in:
@@ -1,4 +1,54 @@
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version INTEGER PRIMARY KEY,
|
||||
applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
-- Chat server schema (pre-1.0 consolidated)
|
||||
PRAGMA foreign_keys = ON;
|
||||
|
||||
-- Users: IRC-style sessions (no passwords, just nick + token)
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
nick TEXT NOT NULL UNIQUE,
|
||||
token TEXT NOT NULL UNIQUE,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
last_seen DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_token ON users(token);
|
||||
|
||||
-- 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,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
joined_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(channel_id, user_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,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
message_id INTEGER NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(user_id, message_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_client_queues_user ON client_queues(user_id, id);
|
||||
|
||||
Reference in New Issue
Block a user