77 lines
4.0 KiB
PL/PgSQL
77 lines
4.0 KiB
PL/PgSQL
-- Migration: Definitive enqueue_all_notifications() dispatcher + self-hosted fix
|
|
--
|
|
-- WHY THIS EXISTS:
|
|
-- 1. Sort-order bug: 20260322_finalize_notification_functions.sql has an
|
|
-- underscore at filename position 9, which sorts AFTER all 20260322NNNNNN_*
|
|
-- files (underscore ASCII 95 > digits 48-57). It therefore ran LAST and
|
|
-- overrode enqueue_all_notifications() with a version that omitted:
|
|
-- - enqueue_announcement_banner_notifications() (added in 20260322210000)
|
|
-- - enqueue_pass_slip_expired_notifications() (added in 20260322150000)
|
|
-- This migration (20260323000000) sorts after all 20260322* files and
|
|
-- restores the authoritative 10-type definition.
|
|
--
|
|
-- 2. Self-hosted Docker: process_notification_queue() fires the edge function
|
|
-- via pg_net (HTTP), but on self-hosted the vault secrets and GUC fallbacks
|
|
-- are often not configured, so the function returns early and the edge
|
|
-- function is never triggered. enqueue_all_notifications() therefore never
|
|
-- runs and scheduled_notifications is never populated.
|
|
-- Fix: a dedicated pg_cron job calls enqueue_all_notifications() directly
|
|
-- (pure SQL, no HTTP, no vault required). The edge function is still called
|
|
-- for FCM delivery — only the enqueue step is decoupled.
|
|
|
|
-- ============================================================================
|
|
-- 1. Authoritative master dispatcher (all 10 types)
|
|
-- ============================================================================
|
|
CREATE OR REPLACE FUNCTION public.enqueue_all_notifications()
|
|
RETURNS void LANGUAGE plpgsql AS $$
|
|
BEGIN
|
|
PERFORM public.enqueue_due_shift_notifications();
|
|
PERFORM public.enqueue_overtime_idle_notifications();
|
|
PERFORM public.enqueue_overtime_checkout_notifications();
|
|
PERFORM public.enqueue_isr_event_notifications();
|
|
PERFORM public.enqueue_isr_evidence_notifications();
|
|
PERFORM public.enqueue_paused_task_notifications();
|
|
PERFORM public.enqueue_backlog_notifications();
|
|
PERFORM public.enqueue_pass_slip_expiry_notifications();
|
|
PERFORM public.enqueue_pass_slip_expired_notifications();
|
|
PERFORM public.enqueue_announcement_banner_notifications();
|
|
END;
|
|
$$;
|
|
|
|
-- ============================================================================
|
|
-- 2. Dedicated enqueue cron job (self-hosted compatible)
|
|
-- ============================================================================
|
|
-- This job calls enqueue_all_notifications() directly inside PostgreSQL every
|
|
-- minute. It requires only pg_cron — no pg_net, no vault, no HTTP.
|
|
--
|
|
-- On Supabase cloud: both this job and the edge-function trigger run, which
|
|
-- is safe because every enqueue function is idempotent via
|
|
-- ON CONFLICT DO NOTHING.
|
|
-- On self-hosted Docker: this job ensures scheduled_notifications is populated
|
|
-- even when the pg_net → edge-function path is broken.
|
|
-- For FCM delivery you still need the edge function to
|
|
-- run; use the system crontab as shown below if pg_net
|
|
-- is not configured:
|
|
--
|
|
-- */1 * * * * curl -sS -X POST \
|
|
-- "http://localhost:8000/functions/v1/process_scheduled_notifications" \
|
|
-- -H "Authorization: Bearer <service-role-key>" \
|
|
-- -H "Content-Type: application/json" -d '{}'
|
|
--
|
|
-- Self-hosted vault / GUC setup (run once, required for pg_net path):
|
|
-- SELECT vault.create_secret('http://localhost:8000', 'supabase_url');
|
|
-- SELECT vault.create_secret('<service-role-key>', 'service_role_key');
|
|
-- -- or via GUC (no vault extension required):
|
|
-- ALTER DATABASE postgres SET "app.settings.supabase_url" = 'http://localhost:8000';
|
|
-- ALTER DATABASE postgres SET "app.settings.service_role_key" = '<service-role-key>';
|
|
DO $$
|
|
BEGIN
|
|
PERFORM cron.schedule(
|
|
'notification_enqueue_every_min',
|
|
'*/1 * * * *',
|
|
'SELECT public.enqueue_all_notifications();'
|
|
);
|
|
EXCEPTION WHEN others THEN
|
|
RAISE NOTICE 'pg_cron not available (%). Use the system crontab to call the edge function directly instead.', SQLERRM;
|
|
END $$;
|