Changeset 0.7.2 (#40)
This commit is contained in:
50
server/database/migrations/014_notes.sql
Normal file
50
server/database/migrations/014_notes.sql
Normal file
@@ -0,0 +1,50 @@
|
||||
-- 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();
|
||||
Reference in New Issue
Block a user