-- 014_notes.sql — Notes table with full-text search
--
-- Notes are user-scoped persistent documents. The LLM can create, search,
-- and update them via built-in tools (note_create, note_search, etc.).
-- Full-text search uses PostgreSQL tsvector — zero additional infrastructure.
--
-- DROP first: if a previous deployment created an incomplete version of
-- this table (e.g. missing search_vector), IF NOT EXISTS would skip and
-- the indexes/trigger would fail. Safe because 014 was never recorded
-- in schema_migrations — any existing data is from a failed attempt.

DROP TABLE IF EXISTS notes CASCADE;

CREATE TABLE notes (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id         UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    title           VARCHAR(500) NOT NULL,
    content         TEXT DEFAULT '',
    folder_path     TEXT DEFAULT '/',
    tags            TEXT[] DEFAULT '{}',
    metadata        JSONB DEFAULT '{}',
    source_channel_id UUID REFERENCES channels(id) ON DELETE SET NULL,
    search_vector   TSVECTOR,
    created_at      TIMESTAMP DEFAULT NOW(),
    updated_at      TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_notes_user ON notes(user_id);
CREATE INDEX idx_notes_search ON notes USING GIN(search_vector);
CREATE INDEX idx_notes_folder ON notes(user_id, folder_path);
CREATE INDEX idx_notes_tags ON notes USING GIN(tags);
CREATE INDEX idx_notes_updated ON notes(user_id, updated_at DESC);

-- Auto-update search vector from title + content
CREATE OR REPLACE FUNCTION notes_search_update_fn()
RETURNS TRIGGER AS $$
BEGIN
    NEW.search_vector :=
        setweight(to_tsvector('pg_catalog.english', COALESCE(NEW.title, '')), 'A') ||
        setweight(to_tsvector('pg_catalog.english', COALESCE(NEW.content, '')), 'B');
    NEW.updated_at := NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Drop first to allow re-run
DROP TRIGGER IF EXISTS notes_search_update ON notes;
CREATE TRIGGER notes_search_update
    BEFORE INSERT OR UPDATE OF title, content ON notes
    FOR EACH ROW EXECUTE FUNCTION notes_search_update_fn();
