// server/supabase/functions/embed-chunks/supabase-knowledge-store.ts // KnowledgeIndexStore adapter over the service-role Supabase client. import type { createClient } from '@supabase/supabase-js' import { type KnowledgeChunkRow, type KnowledgeIndexStore, KnowledgeStorageError } from './handler.ts' type SupabaseClient = ReturnType export function createSupabaseKnowledgeStore(client: SupabaseClient): KnowledgeIndexStore { return { async documentOwner(documentId) { const { data, error } = await client .from('knowledge_documents') .select('id,user_id') .eq('id', documentId) .maybeSingle() if (error) throw new KnowledgeStorageError() const row = data as { user_id?: unknown } | null return row && typeof row.user_id === 'string' ? row.user_id : null }, async countChunks(documentId, pendingOnly) { let query = client .from('knowledge_chunks') .select('id', { count: 'exact', head: true }) .eq('document_id', documentId) if (pendingOnly) query = query.is('embedding', null) const { count, error } = await query if (error) throw new KnowledgeStorageError() return count }, async listPendingChunks(documentId, limit) { const { data, error } = await client .from('knowledge_chunks') .select('id,content') .eq('document_id', documentId) .is('embedding', null) .order('chunk_index', { ascending: true }) .limit(limit) if (error) throw new KnowledgeStorageError() return (data ?? []) as KnowledgeChunkRow[] }, async saveEmbedding(documentId, chunkId, embedding) { const { error } = await client .from('knowledge_chunks') .update({ embedding }) .eq('id', chunkId) .eq('document_id', documentId) return !error }, async clearIndexed(documentId, userId) { let query = client .from('knowledge_documents') .update({ indexed: false, indexed_at: null }) .eq('id', documentId) if (userId !== null) query = query.eq('user_id', userId) const { error } = await query return !error }, async markIndexed(documentId, userId) { const { data, error } = await client .from('knowledge_documents') .update({ indexed: true, indexed_at: new Date().toISOString() }) .eq('id', documentId) .eq('user_id', userId) .select('id') .maybeSingle() return !error && Boolean(data) }, } }