d3ro-voice/server/supabase/migrations/20260927000037_server_owned_sync_timestamps.sql

68 lines
2.2 KiB
PL/PgSQL

-- Server-owned sync timestamps.
--
-- The desktop mirror (SyncEngine.pullEntity) and the audio sync read every
-- synced table with a (updated_at, id) keyset cursor and rewind it by only a
-- minute. That cursor is only sound when updated_at is a server clock value
-- for every write. moddatetime already owns it on UPDATE, but an INSERT kept
-- whatever updated_at the client sent:
--
-- a) a row recorded offline at T0 and pushed a day later landed behind every
-- other desktop's cursor and was never pulled there;
-- b) a desktop whose clock ran ahead inserted rows in the future, pushed the
-- other desktops' cursors ahead with them, and every server-stamped edit in
-- that window was then skipped for good;
-- c) restore_account_portability re-inserted archived updated_at values, so a
-- desktop that already applied the delete tombstones never got the rows
-- back.
--
-- From here on the server stamps updated_at on INSERT as well. user_templates
-- had no UPDATE stamp at all (only its RPC set it), so it gets one too. The
-- value is now(), the same clock moddatetime uses, so INSERT and UPDATE share
-- one cursor timeline and the existing overlap window still covers late
-- commits.
BEGIN;
CREATE OR REPLACE FUNCTION public.stamp_sync_timestamp_v1()
RETURNS trigger
LANGUAGE plpgsql
SET search_path = ''
AS $$
BEGIN
NEW.updated_at := pg_catalog.now();
RETURN NEW;
END;
$$;
REVOKE ALL ON FUNCTION public.stamp_sync_timestamp_v1() FROM PUBLIC, anon, authenticated;
DO $$
DECLARE
t text;
BEGIN
FOREACH t IN ARRAY ARRAY[
'history',
'dictionary',
'meetings',
'meeting_memos',
'meeting_documents',
'custom_instructions',
'user_templates',
'knowledge_documents'
]
LOOP
EXECUTE format('DROP TRIGGER IF EXISTS stamp_sync_insert_v1 ON public.%I', t);
EXECUTE format(
'CREATE TRIGGER stamp_sync_insert_v1 BEFORE INSERT ON public.%I '
'FOR EACH ROW EXECUTE FUNCTION public.stamp_sync_timestamp_v1()',
t
);
END LOOP;
END $$;
DROP TRIGGER IF EXISTS stamp_sync_update_v1 ON public.user_templates;
CREATE TRIGGER stamp_sync_update_v1
BEFORE UPDATE ON public.user_templates
FOR EACH ROW EXECUTE FUNCTION public.stamp_sync_timestamp_v1();
COMMIT;