-- ========================================== -- Chat Switchboard — 006 Multi-User: DMs + Channels -- ========================================== -- Extends channels with 'dm' and 'channel' types, ai_mode, and topic. -- Adds presence tracking table. -- ICD §3 (Channels & Conversations) — v0.23.1 -- ========================================== -- ── Channel type extension ─────────────────────────────────────────── -- Add 'dm' (human-to-human, AI silent unless @mentioned) -- Add 'channel' (named persistent space, configurable ai_mode) -- Existing 'direct', 'group', 'workflow' are unchanged. ALTER TABLE channels DROP CONSTRAINT IF EXISTS channels_type_check; ALTER TABLE channels ADD CONSTRAINT channels_type_check CHECK (type IN ('direct', 'dm', 'group', 'channel', 'workflow')); -- ── ai_mode ────────────────────────────────────────────────────────── -- auto : AI responds to every message (existing behavior for 'direct') -- mention_only : AI silent unless @mentioned (default for 'dm') -- off : AI disabled entirely ALTER TABLE channels ADD COLUMN IF NOT EXISTS ai_mode VARCHAR(20) NOT NULL DEFAULT 'auto' CHECK (ai_mode IN ('auto', 'mention_only', 'off')); -- Back-fill: DM channels should be mention_only -- (No existing rows should have type='dm' yet, but be safe) UPDATE channels SET ai_mode = 'mention_only' WHERE type = 'dm' AND ai_mode = 'auto'; -- ── topic ───────────────────────────────────────────────────────────── ALTER TABLE channels ADD COLUMN IF NOT EXISTS topic TEXT; -- ── Presence (in-memory heartbeat, DB stores last_seen for persistence) ── -- Not queried at high frequency — updated by heartbeat (30s), read on load. CREATE TABLE IF NOT EXISTS user_presence ( user_id UUID PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE, last_seen TIMESTAMPTZ NOT NULL DEFAULT NOW(), status VARCHAR(20) NOT NULL DEFAULT 'online' CHECK (status IN ('online', 'away', 'offline')) ); CREATE INDEX IF NOT EXISTS idx_user_presence_last_seen ON user_presence(last_seen DESC); COMMENT ON TABLE user_presence IS 'Heartbeat-driven presence. Rows upserted every 30s by active clients.'; COMMENT ON COLUMN channels.ai_mode IS 'auto=respond always, mention_only=@mention required, off=AI disabled'; COMMENT ON COLUMN channels.topic IS 'Short channel description shown in header';