-- Knowledge base joins the cross-device mirror; tombstones get a retention job. -- -- 1. knowledge_documents deletions leave a tombstone like the other synced -- tables, and a (user_id, updated_at, id) cursor index backs keyset pulls. -- Chunks are re-read with their document, so they need neither. -- 2. pg_cron prunes tombstones daily with the 180-day default of -- prune_sync_tombstones_v1 (a device offline longer than that resyncs fully). BEGIN; -- 1) knowledge_documents --------------------------------------------------------- ALTER TABLE public.sync_tombstones DROP CONSTRAINT IF EXISTS sync_tombstones_table_name_check; ALTER TABLE public.sync_tombstones ADD CONSTRAINT sync_tombstones_table_name_check CHECK (table_name IN ( 'history', 'dictionary', 'meetings', 'meeting_memos', 'meeting_documents', 'memo_tags', 'custom_instructions', 'user_templates', 'knowledge_documents' )); DROP TRIGGER IF EXISTS record_sync_tombstone_v1 ON public.knowledge_documents; CREATE TRIGGER record_sync_tombstone_v1 AFTER DELETE ON public.knowledge_documents FOR EACH ROW EXECUTE FUNCTION public.record_sync_tombstone_v1(); CREATE INDEX IF NOT EXISTS idx_knowledge_documents_sync_cursor ON public.knowledge_documents(user_id, updated_at, id); DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_publication_tables WHERE pubname = 'supabase_realtime' AND schemaname = 'public' AND tablename = 'knowledge_documents' ) THEN ALTER PUBLICATION supabase_realtime ADD TABLE public.knowledge_documents; END IF; END $$; COMMIT; -- 2) Tombstone retention --------------------------------------------------------- -- Outside the transaction: extension creation and cron scheduling are -- idempotent, and cron.schedule with an existing job name replaces it. CREATE EXTENSION IF NOT EXISTS pg_cron WITH SCHEMA pg_catalog; SELECT cron.schedule( 'prune-sync-tombstones', '17 3 * * *', $$SELECT public.prune_sync_tombstones_v1()$$ );