-- Schema RAG do projeto G-ART (fcp-mcp-server). -- Idempotente: seguro rodar múltiplas vezes (CREATE ... IF NOT EXISTS). -- Segue o padrão dos bancos irmãos (rag_doza, rag_tigre, jhonny-rag): um -- banco por sistema dentro do container compartilhado rag-hub-db, schema -- próprio. Banco: rag_gart. Schema: gart. -- -- Colunas e tabelas espelham exatamente o que admin/update_rag.py grava -- (code_chunks, file_index, indexed_files) e o que rag/search.py lê. CREATE EXTENSION IF NOT EXISTS vector; CREATE EXTENSION IF NOT EXISTS pg_trgm; CREATE SCHEMA IF NOT EXISTS gart; CREATE TABLE IF NOT EXISTS gart.code_chunks ( id bigserial PRIMARY KEY, file_path text NOT NULL, content text NOT NULL, chunk_index int, embedding vector(768), content_hash text, file_mtime double precision, -- Faixa de linhas do trecho no arquivo original. É o que permite ao -- agente ler só a janela relevante em vez do arquivo inteiro. start_line int, end_line int, -- Nomes declarados no trecho (class/def/func...), separados por vírgula — -- o lado lexical (pg_trgm) da busca híbrida casa contra isto. symbols text, -- Módulo derivado do caminho relativo (primeiro segmento, ex: code/fcpxml -> code). module text, -- 'window': admin/update_rag.py corta por janela de linhas, não por -- declaração (o projeto é majoritariamente Python/Swift/Markdown/shell). kind text, updated_at timestamp DEFAULT now() ); -- HNSW, não ivfflat: com poucas centenas/milhares de chunks o ivfflat -- particiona o espaço em listas quase vazias e a busca com probes baixo -- varre quase nada (ver rag/README.md para os números de referência). CREATE INDEX IF NOT EXISTS code_chunks_embedding_hnsw_idx ON gart.code_chunks USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64); -- Acelera a reindexação incremental (busca por file_path) e a limpeza de -- chunks de um arquivo antes de reinserir. CREATE INDEX IF NOT EXISTS idx_code_chunks_file_path ON gart.code_chunks (file_path); -- Lado lexical da busca híbrida. CREATE INDEX IF NOT EXISTS code_chunks_file_path_trgm_idx ON gart.code_chunks USING gin (file_path gin_trgm_ops); CREATE INDEX IF NOT EXISTS code_chunks_symbols_trgm_idx ON gart.code_chunks USING gin (symbols gin_trgm_ops); CREATE INDEX IF NOT EXISTS code_chunks_module_idx ON gart.code_chunks (module); -- Hash de conteúdo por arquivo, usado pelo indexador para pular arquivos -- que não mudaram desde a última rodada (reindexação incremental). CREATE TABLE IF NOT EXISTS gart.indexed_files ( file_path text PRIMARY KEY, content_hash text NOT NULL, updated_at timestamp DEFAULT now() ); -- Mapa de arquivos: 1 linha por arquivo. Responde "onde fica X" e "o que -- tem no módulo Y" sem trazer nenhum corpo de código. CREATE TABLE IF NOT EXISTS gart.file_index ( file_path text PRIMARY KEY, module text, main_type text, public_symbols text[], summary text, n_lines int, content_hash text, summary_embedding vector(768), updated_at timestamp DEFAULT now() ); CREATE INDEX IF NOT EXISTS file_index_module_idx ON gart.file_index (module); CREATE INDEX IF NOT EXISTS file_index_path_trgm_idx ON gart.file_index USING gin (file_path gin_trgm_ops); CREATE INDEX IF NOT EXISTS file_index_summary_hnsw_idx ON gart.file_index USING hnsw (summary_embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);