-- Foodlinkk 2nd brain: emails, agenda, LLM memory CREATE TABLE IF NOT EXISTS emails ( id SERIAL PRIMARY KEY, message_id TEXT UNIQUE NOT NULL, thread_id TEXT, client_id INT REFERENCES clients(id) ON DELETE SET NULL, deal_id INT REFERENCES deals(id) ON DELETE SET NULL, direction VARCHAR(8) NOT NULL CHECK (direction IN ('in', 'out')), from_addr TEXT, to_addrs TEXT[] DEFAULT '{}', cc_addrs TEXT[] DEFAULT '{}', subject TEXT, body_text TEXT, body_html TEXT, received_at TIMESTAMPTZ, sent_at TIMESTAMPTZ, is_read BOOLEAN DEFAULT FALSE, labels TEXT[] DEFAULT '{}', raw_headers JSONB DEFAULT '{}', created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_emails_received ON emails(received_at DESC); CREATE INDEX IF NOT EXISTS idx_emails_client ON emails(client_id); CREATE INDEX IF NOT EXISTS idx_emails_from ON emails(from_addr); CREATE TABLE IF NOT EXISTS calendar_events ( id SERIAL PRIMARY KEY, title TEXT NOT NULL, description TEXT, starts_at TIMESTAMPTZ NOT NULL, ends_at TIMESTAMPTZ, client_id INT REFERENCES clients(id) ON DELETE SET NULL, deal_id INT REFERENCES deals(id) ON DELETE SET NULL, location TEXT, source VARCHAR(32) DEFAULT 'manual', external_id TEXT, all_day BOOLEAN DEFAULT FALSE, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_calendar_starts ON calendar_events(starts_at); CREATE TABLE IF NOT EXISTS llm_memory ( id SERIAL PRIMARY KEY, category VARCHAR(64) NOT NULL DEFAULT 'fact', subject TEXT, content TEXT NOT NULL, client_id INT REFERENCES clients(id) ON DELETE SET NULL, deal_id INT REFERENCES deals(id) ON DELETE SET NULL, source VARCHAR(64) DEFAULT 'herman', metadata JSONB DEFAULT '{}', created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_llm_memory_category ON llm_memory(category); CREATE INDEX IF NOT EXISTS idx_llm_memory_updated ON llm_memory(updated_at DESC); -- Seed: deal deadlines als agenda-items (zichtbaar in ochtendbericht) INSERT INTO calendar_events (title, starts_at, ends_at, deal_id, source, description) SELECT 'Deadline: ' || d.title, d.deadline::timestamptz, d.deadline::timestamptz + INTERVAL '1 hour', d.id, 'deal_deadline', COALESCE(d.next_action, '') FROM deals d WHERE d.deadline IS NOT NULL AND d.stage NOT IN ('won', 'lost') AND NOT EXISTS ( SELECT 1 FROM calendar_events ce WHERE ce.deal_id = d.id AND ce.source = 'deal_deadline' );