Krok 1 planu docs/kb/modules/05-faza2-plan.md §3/§6 (chunk-level embeddings, 1:N do envelope). Addytywna — 001_envelope.sql nietknięta (zweryfikowane \d envelope po migracji: identyczny schemat + FK jako "Referenced by"). Schemat wg rekomendacji recon (§2 decyzja 1+2): osobna tabela (nie kolumna w envelope, bo N-wartościowy chunking jest obowiązkowy przy dokumentach >8k tokenów), embedding VECTOR(1024) pod bge-m3 (dense), HNSW cosine index, kolumna `model` do trywialnego re-indexu przy zmianie modelu (kb-00 zasada #1: indeks odtwarzalny). Idempotentna (CREATE TABLE/INDEX IF NOT EXISTS, zweryfikowane podwójnym uruchomieniem na kb-postgres@PIHA — drugi run same NOTICE "already exists, skipping"). Zastosowana na żywej bazie: ssh piha docker exec kb-postgres psql, po potwierdzeniu SQL przez Oskara. \dt + \d document_chunk + \d envelope zweryfikowane po migracji. Testy: dopisane sanity-testy 002 do packages/kb-mail/tests/test_migration.py (wzorzec 001 — statyczne assercje na treści SQL, bez DB), 13/13 zielone. Co NIE jest częścią tego kroku (§3 planu, odłożone): entity/entity_link (graf encji) — szkic na przyszłość, nie blokuje domknięcia modułu 5. Co dalej (plan §6, poza zakresem tego kroku): ollama pull bge-m3 na SOLARII, token API Paperless, jobs/gmail-header-backfill/, adapter Paperless→koperta, chunking+embed job. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
19 lines
996 B
SQL
19 lines
996 B
SQL
-- KB spine: document_chunk — chunk-level embeddings, 1:N against envelope
|
|
-- Additive: does not modify 001_envelope.sql. envelope stays untouched.
|
|
-- Version: 002 — chunks (bge-m3 dense embeddings, dim=1024)
|
|
|
|
CREATE TABLE IF NOT EXISTS document_chunk (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
envelope_id TEXT NOT NULL REFERENCES envelope(id) ON DELETE CASCADE,
|
|
chunk_index INT NOT NULL, -- order within envelope, 0-based
|
|
text TEXT NOT NULL,
|
|
embedding VECTOR(1024), -- bge-m3 dense; NULL until embedded
|
|
model TEXT NOT NULL, -- e.g. 'bge-m3' — tracks re-index on model change
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE (envelope_id, chunk_index)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS document_chunk_envelope_idx ON document_chunk (envelope_id);
|
|
CREATE INDEX IF NOT EXISTS document_chunk_embedding_hnsw_idx
|
|
ON document_chunk USING hnsw (embedding vector_cosine_ops);
|