-- ═══════════════════════════════════════════════════════════════════════════ -- AAMOS Admin v2 — Chat Schema -- ═══════════════════════════════════════════════════════════════════════════ -- ── Chat Channels ────────────────────────────────────────────────────────── CREATE TABLE IF NOT EXISTS chat_channels ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, description TEXT, type TEXT NOT NULL DEFAULT 'general', -- 'general'|'support'|'hr'|'direct'|'ticket' related_entity_type TEXT, -- 'ticket'|'customer'|'employee' related_entity_id UUID, created_by TEXT, is_active BOOLEAN NOT NULL DEFAULT TRUE, last_activity TIMESTAMPTZ, metadata JSONB NOT NULL DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_chat_channels_type ON chat_channels (type); CREATE INDEX IF NOT EXISTS idx_chat_channels_entity ON chat_channels (related_entity_type, related_entity_id); CREATE INDEX IF NOT EXISTS idx_chat_channels_active ON chat_channels (is_active); -- ── Chat Messages ────────────────────────────────────────────────────────── CREATE TABLE IF NOT EXISTS chat_messages ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), channel_id UUID NOT NULL REFERENCES chat_channels(id) ON DELETE CASCADE, body TEXT NOT NULL, author_id TEXT, message_type TEXT NOT NULL DEFAULT 'text', -- 'text'|'ticket_share'|'system'|'file' attachments JSONB NOT NULL DEFAULT '[]', metadata JSONB NOT NULL DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_chat_messages_channel ON chat_messages (channel_id); CREATE INDEX IF NOT EXISTS idx_chat_messages_created ON chat_messages (created_at); -- ── Chat Message Reads ───────────────────────────────────────────────────── CREATE TABLE IF NOT EXISTS chat_message_reads ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), message_id UUID NOT NULL REFERENCES chat_messages(id) ON DELETE CASCADE, user_id TEXT NOT NULL, read_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (message_id, user_id) ); CREATE INDEX IF NOT EXISTS idx_chat_message_reads_user ON chat_message_reads (user_id); -- ── Chat Channel Reads ───────────────────────────────────────────────────── CREATE TABLE IF NOT EXISTS chat_channel_reads ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), channel_id UUID NOT NULL REFERENCES chat_channels(id) ON DELETE CASCADE, user_id TEXT NOT NULL, last_read_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (channel_id, user_id) ); CREATE INDEX IF NOT EXISTS idx_chat_channel_reads_user ON chat_channel_reads (user_id); -- ── Chat Presence ────────────────────────────────────────────────────────── CREATE TABLE IF NOT EXISTS chat_presence ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id TEXT NOT NULL UNIQUE, status TEXT NOT NULL DEFAULT 'offline', -- 'online'|'away'|'busy'|'offline' last_seen TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_chat_presence_status ON chat_presence (status); -- ── Ticket Shares ────────────────────────────────────────────────────────── CREATE TABLE IF NOT EXISTS ticket_shares ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), ticket_id UUID NOT NULL REFERENCES support_tickets(id), shared_by TEXT NOT NULL, target_channel_id UUID NOT NULL REFERENCES chat_channels(id), note TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_ticket_shares_ticket ON ticket_shares (ticket_id); CREATE INDEX IF NOT EXISTS idx_ticket_shares_channel ON ticket_shares (target_channel_id); -- Insert default channels INSERT INTO chat_channels (name, description, type) VALUES ('General', 'Allmän diskussion', 'general'), ('Support', 'Supportärenden och eskalering', 'support'), ('HR', 'Personalfrågor', 'hr'), ('Försäljning', 'Sälj och leads', 'sales'), ('Teknik', 'Teknisk diskussion', 'tech') ON CONFLICT DO NOTHING;