mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
93 lines
2.9 KiB
PL/PgSQL
93 lines
2.9 KiB
PL/PgSQL
-- Add match notification digest system
|
|
-- Coalesces multiple match events into a single push notification.
|
|
--
|
|
-- Design goals:
|
|
-- - Reduce push spam when many matches occur quickly
|
|
-- - Keep delivery latency bounded (<= ~2 minutes)
|
|
-- - Keep match creation real-time; only push notifications are delayed
|
|
|
|
-- Create pending match notifications table
|
|
CREATE TABLE pending_match_notifications (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
couple_id UUID NOT NULL REFERENCES couples(id) ON DELETE CASCADE,
|
|
match_count INTEGER NOT NULL DEFAULT 1,
|
|
latest_match_id UUID REFERENCES matches(id) ON DELETE SET NULL,
|
|
notify_at TIMESTAMPTZ NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT now(),
|
|
updated_at TIMESTAMPTZ DEFAULT now(),
|
|
UNIQUE(couple_id) -- One pending notification per couple (UPSERT timer reset)
|
|
);
|
|
|
|
-- Index for efficient cron queries
|
|
CREATE INDEX idx_pending_match_notifications_notify_at
|
|
ON pending_match_notifications(notify_at);
|
|
|
|
-- Enable RLS
|
|
ALTER TABLE pending_match_notifications ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- RLS policies
|
|
CREATE POLICY "Users can view their couple's pending match notifications"
|
|
ON pending_match_notifications FOR SELECT
|
|
USING (couple_id = get_auth_user_couple_id());
|
|
|
|
CREATE POLICY "Super admins can view all pending match notifications"
|
|
ON pending_match_notifications FOR SELECT
|
|
USING (is_super_admin());
|
|
|
|
-- Updated_at trigger
|
|
CREATE TRIGGER update_pending_match_notifications_updated_at
|
|
BEFORE UPDATE ON pending_match_notifications
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
|
|
|
-- Function to queue match notifications
|
|
-- Runs whenever a new match row is inserted.
|
|
-- The notify_at value is aligned to minute boundaries so that a once-per-minute cron
|
|
-- can deliver notifications within ~1-2 minutes.
|
|
CREATE OR REPLACE FUNCTION queue_match_notification()
|
|
RETURNS TRIGGER
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
SET search_path = 'public'
|
|
AS $$
|
|
BEGIN
|
|
INSERT INTO pending_match_notifications (
|
|
couple_id,
|
|
match_count,
|
|
latest_match_id,
|
|
notify_at
|
|
)
|
|
VALUES (
|
|
NEW.couple_id,
|
|
1,
|
|
NEW.id,
|
|
date_trunc('minute', now()) + interval '2 minutes'
|
|
)
|
|
ON CONFLICT (couple_id) DO UPDATE SET
|
|
match_count = pending_match_notifications.match_count + 1,
|
|
latest_match_id = NEW.id,
|
|
notify_at = date_trunc('minute', now()) + interval '2 minutes',
|
|
updated_at = now();
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$$;
|
|
|
|
-- Trigger on matches table
|
|
CREATE TRIGGER on_match_created
|
|
AFTER INSERT ON matches
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION queue_match_notification();
|
|
|
|
-- Schedule cron job (runs every minute)
|
|
SELECT cron.schedule(
|
|
'send-match-notification-digests',
|
|
'* * * * *',
|
|
$$
|
|
SELECT net.http_post(
|
|
url := 'https://ckjcrkjpmhqhiucifukx.supabase.co/functions/v1/send-match-notification-digest',
|
|
headers := jsonb_build_object('Content-Type', 'application/json'),
|
|
body := '{}'::jsonb
|
|
)
|
|
$$
|
|
);
|