79 lines
3.4 KiB
PL/PgSQL
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;
|
|
$$;
|