-- ============================================================================ -- Phase V2-M: Knowledge Base — RAG 기초 (텍스트 청크 + 단순 검색) -- V1 RAGService의 Supabase 버전. pgvector 임베딩은 V2-M+1에서 추가 예정. -- ============================================================================ -- pgvector extension (미래 임베딩 검색용, 현재는 미사용) -- CREATE EXTENSION IF NOT EXISTS vector; -- 지식 문서 메타데이터 CREATE TABLE public.knowledge_documents ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, team_id uuid REFERENCES public.teams(id) ON DELETE SET NULL, title text NOT NULL, file_name text, file_type text CHECK (file_type IN ('txt', 'md', 'pdf', 'docx', 'html', 'url')), source_url text, storage_key text, -- Supabase Storage의 경로 (업로드된 경우) chunk_count integer NOT NULL DEFAULT 0, indexed boolean NOT NULL DEFAULT false, indexed_at timestamptz, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX idx_knowledge_documents_user_id ON public.knowledge_documents(user_id); CREATE INDEX idx_knowledge_documents_team_id ON public.knowledge_documents(team_id); CREATE INDEX idx_knowledge_documents_created ON public.knowledge_documents(user_id, created_at DESC); -- 청크 — 원문을 분할한 단위. 임베딩은 추후 vector 컬럼 추가. CREATE TABLE public.knowledge_chunks ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), document_id uuid NOT NULL REFERENCES public.knowledge_documents(id) ON DELETE CASCADE, chunk_index integer NOT NULL, content text NOT NULL, -- embedding vector(768), -- V2-M+1에서 pgvector 활성화 created_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX idx_knowledge_chunks_document ON public.knowledge_chunks(document_id); CREATE UNIQUE INDEX idx_knowledge_chunks_uniq ON public.knowledge_chunks(document_id, chunk_index); -- 임시: 전문 검색을 위한 tsvector (pgvector 적용 전 대체재) ALTER TABLE public.knowledge_chunks ADD COLUMN tsv tsvector GENERATED ALWAYS AS (to_tsvector('simple', content)) STORED; CREATE INDEX idx_knowledge_chunks_tsv ON public.knowledge_chunks USING gin(tsv); -- RLS ------------------------------------------------------------------------ ALTER TABLE public.knowledge_documents ENABLE ROW LEVEL SECURITY; ALTER TABLE public.knowledge_chunks ENABLE ROW LEVEL SECURITY; CREATE POLICY "knowledge_documents_read" ON public.knowledge_documents FOR SELECT USING ( user_id = auth.uid() OR (team_id IS NOT NULL AND team_id IN ( SELECT team_id FROM public.team_members WHERE user_id = auth.uid() )) ); CREATE POLICY "knowledge_documents_insert" ON public.knowledge_documents FOR INSERT WITH CHECK (user_id = auth.uid()); CREATE POLICY "knowledge_documents_update" ON public.knowledge_documents FOR UPDATE USING (user_id = auth.uid()); CREATE POLICY "knowledge_documents_delete" ON public.knowledge_documents FOR DELETE USING (user_id = auth.uid()); -- 청크는 부모 문서 권한 경유 CREATE POLICY "knowledge_chunks_read" ON public.knowledge_chunks FOR SELECT USING ( document_id IN (SELECT id FROM public.knowledge_documents) ); CREATE POLICY "knowledge_chunks_insert" ON public.knowledge_chunks FOR INSERT WITH CHECK ( document_id IN (SELECT id FROM public.knowledge_documents WHERE user_id = auth.uid()) ); CREATE POLICY "knowledge_chunks_delete" ON public.knowledge_chunks FOR DELETE USING ( document_id IN (SELECT id FROM public.knowledge_documents WHERE user_id = auth.uid()) ); -- updated_at trigger CREATE TRIGGER set_updated_at_knowledge_documents BEFORE UPDATE ON public.knowledge_documents FOR EACH ROW EXECUTE FUNCTION public.moddatetime();