tasq/supabase/migrations/20260322150000_pass_slip_start_and_expired_notifs.sql
Marc Rejohn Castillano 049ab2c794 Added My Schedule tab in attendance screen
Allow 1 Day, Whole Week and Date Range swapping
2026-03-22 11:52:25 +08:00

79 lines
3.4 KiB
PL/PgSQL

-- Migration: Pass slip requested_start column + expired pass slip notifications
--
-- 1. Add optional requested_start column to pass_slips
-- 2. Create enqueue_pass_slip_expired_notifications() for recurring reminders
-- every 15 minutes after a pass slip exceeds its 1-hour limit
-- 3. Update enqueue_all_notifications() master dispatcher
-- ============================================================================
-- 1. SCHEMA: Add requested_start column
-- ============================================================================
ALTER TABLE public.pass_slips
ADD COLUMN IF NOT EXISTS requested_start timestamptz;
-- ============================================================================
-- 2. ENQUEUE FUNCTION: Expired pass slip reminders (every 15 min after 1 hour)
-- ============================================================================
-- Follows the end_hourly pattern: uses epoch for unique rows, checks latest
-- scheduled notification to enforce a minimum gap between reminders.
-- Caps at 24 hours to avoid processing ancient slips.
CREATE OR REPLACE FUNCTION public.enqueue_pass_slip_expired_notifications()
RETURNS void LANGUAGE plpgsql AS $$
DECLARE
rec RECORD;
v_intervals_since_expiry int;
v_latest_expired timestamptz;
BEGIN
FOR rec IN
SELECT ps.id AS pass_slip_id, ps.user_id, ps.slip_start
FROM public.pass_slips ps
WHERE ps.status = 'approved'
AND ps.slip_end IS NULL
AND ps.slip_start IS NOT NULL
-- Expired: past the 1-hour mark
AND ps.slip_start + interval '1 hour' <= now()
-- Cap at 24 hours to avoid processing ancient slips
AND ps.slip_start + interval '24 hours' > now()
LOOP
-- Calculate how many 15-min intervals since expiry (for unique epoch)
v_intervals_since_expiry := GREATEST(1,
EXTRACT(EPOCH FROM (now() - (rec.slip_start + interval '1 hour')))::int / 900
);
-- Check latest expired notification for this pass slip
SELECT MAX(scheduled_for) INTO v_latest_expired
FROM public.scheduled_notifications
WHERE pass_slip_id = rec.pass_slip_id
AND user_id = rec.user_id
AND notify_type = 'pass_slip_expired_15';
-- Only enqueue if no prior expired reminder, or last one was >14 min ago
IF v_latest_expired IS NULL OR v_latest_expired < now() - interval '14 minutes' THEN
INSERT INTO public.scheduled_notifications
(pass_slip_id, user_id, notify_type, scheduled_for, epoch)
VALUES
(rec.pass_slip_id, rec.user_id, 'pass_slip_expired_15', now(), v_intervals_since_expiry)
ON CONFLICT DO NOTHING;
END IF;
END LOOP;
END;
$$;
-- ============================================================================
-- 3. MASTER DISPATCHER: Add new function
-- ============================================================================
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();
END;
$$;