refactor: remove obsolete member management API module
Some checks failed
Workflow / ʦ TypeScript (pull_request) Failing after 5m57s
Workflow / ⚫️ Test (pull_request) Has been skipped

This commit is contained in:
T. Zehetbauer
2026-04-03 14:08:31 +02:00
parent 124c6a632a
commit 5c5aaabae5
132 changed files with 10107 additions and 3442 deletions

View File

@@ -0,0 +1,140 @@
-- =====================================================
-- Atomic Event Registration
--
-- Problem: Registering for an event requires multiple
-- queries (check capacity, validate age, count registrations,
-- insert). Race conditions can over-register an event.
--
-- Fix:
-- A) Ensure member_id FK column exists on event_registrations
-- (idempotent — may already exist from 20260416000006).
-- B) Single transactional PG function that locks the event
-- row, validates capacity/age, and inserts with the
-- correct status (confirmed vs waitlisted).
-- =====================================================
-- A) Add member_id column if not already present
ALTER TABLE public.event_registrations
ADD COLUMN IF NOT EXISTS member_id uuid
REFERENCES public.members(id) ON DELETE SET NULL;
-- Ensure index exists (idempotent)
CREATE INDEX IF NOT EXISTS ix_event_registrations_member
ON public.event_registrations(member_id)
WHERE member_id IS NOT NULL;
-- The status CHECK constraint already includes 'waitlisted' in the
-- original schema: check (status in ('pending','confirmed','waitlisted','cancelled'))
-- No constraint modification needed.
-- B) Atomic registration function
CREATE OR REPLACE FUNCTION public.register_for_event(
p_event_id uuid,
p_member_id uuid DEFAULT NULL,
p_first_name text DEFAULT NULL,
p_last_name text DEFAULT NULL,
p_email text DEFAULT NULL,
p_phone text DEFAULT NULL,
p_date_of_birth date DEFAULT NULL,
p_parent_name text DEFAULT NULL,
p_parent_phone text DEFAULT NULL
)
RETURNS jsonb
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = ''
AS $$
DECLARE
v_event record;
v_reg_count bigint;
v_status text;
v_age integer;
v_registration_id uuid;
BEGIN
-- 1. Lock the event row to prevent concurrent registration races
SELECT * INTO v_event
FROM public.events
WHERE id = p_event_id
FOR UPDATE;
IF v_event IS NULL THEN
RAISE EXCEPTION 'Event % not found', p_event_id
USING ERRCODE = 'P0002';
END IF;
-- 2. Validate event status is open for registration
IF v_event.status != 'open' THEN
RAISE EXCEPTION 'Event is not open for registration (current status: %)', v_event.status
USING ERRCODE = 'P0001';
END IF;
-- 3. Check registration deadline hasn't passed
IF v_event.registration_deadline IS NOT NULL AND v_event.registration_deadline < current_date THEN
RAISE EXCEPTION 'Registration deadline (%) has passed', v_event.registration_deadline
USING ERRCODE = 'P0001';
END IF;
-- 4. Age validation: calculate age at event_date if date_of_birth provided
IF p_date_of_birth IS NOT NULL THEN
v_age := extract(year FROM age(v_event.event_date, p_date_of_birth))::integer;
IF v_event.min_age IS NOT NULL AND v_age < v_event.min_age THEN
RAISE EXCEPTION 'Participant age (%) is below the minimum age (%) for this event', v_age, v_event.min_age
USING ERRCODE = 'P0001';
END IF;
IF v_event.max_age IS NOT NULL AND v_age > v_event.max_age THEN
RAISE EXCEPTION 'Participant age (%) exceeds the maximum age (%) for this event', v_age, v_event.max_age
USING ERRCODE = 'P0001';
END IF;
END IF;
-- 5. Count confirmed + pending registrations
SELECT count(*) INTO v_reg_count
FROM public.event_registrations
WHERE event_id = p_event_id
AND status IN ('confirmed', 'pending');
-- 6. Determine status based on capacity
IF v_event.capacity IS NOT NULL AND v_reg_count >= v_event.capacity THEN
v_status := 'waitlisted';
ELSE
v_status := 'confirmed';
END IF;
-- 7. Insert the registration
INSERT INTO public.event_registrations (
event_id,
member_id,
first_name,
last_name,
email,
phone,
date_of_birth,
parent_name,
parent_phone,
status
) VALUES (
p_event_id,
p_member_id,
p_first_name,
p_last_name,
p_email,
p_phone,
p_date_of_birth,
p_parent_name,
p_parent_phone,
v_status
)
RETURNING id INTO v_registration_id;
-- 8. Return result
RETURN jsonb_build_object(
'registration_id', v_registration_id,
'status', v_status
);
END;
$$;
GRANT EXECUTE ON FUNCTION public.register_for_event(uuid, uuid, text, text, text, text, date, text, text) TO authenticated;
GRANT EXECUTE ON FUNCTION public.register_for_event(uuid, uuid, text, text, text, text, date, text, text) TO service_role;