refactor: remove obsolete member management API module
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
-- =====================================================
|
||||
-- Audit Timeline RPCs for Courses, Events, Bookings
|
||||
--
|
||||
-- Paginated, filterable read layer on the audit logs.
|
||||
-- Mirrors get_member_timeline from 20260416000007.
|
||||
-- =====================================================
|
||||
|
||||
-- -------------------------------------------------------
|
||||
-- 1. Course timeline RPC
|
||||
-- -------------------------------------------------------
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_course_timeline(
|
||||
p_course_id uuid,
|
||||
p_page integer DEFAULT 1,
|
||||
p_page_size integer DEFAULT 50,
|
||||
p_action_filter text DEFAULT NULL
|
||||
)
|
||||
RETURNS TABLE (
|
||||
id bigint,
|
||||
action text,
|
||||
changes jsonb,
|
||||
metadata jsonb,
|
||||
user_id uuid,
|
||||
user_email text,
|
||||
created_at timestamptz,
|
||||
total_count bigint
|
||||
)
|
||||
LANGUAGE plpgsql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = ''
|
||||
AS $$
|
||||
DECLARE
|
||||
v_account_id uuid;
|
||||
v_total bigint;
|
||||
v_offset integer;
|
||||
BEGIN
|
||||
-- Get course's account for access check
|
||||
SELECT c.account_id INTO v_account_id
|
||||
FROM public.courses c WHERE c.id = p_course_id;
|
||||
|
||||
IF v_account_id IS NULL THEN
|
||||
RAISE EXCEPTION 'Course not found';
|
||||
END IF;
|
||||
|
||||
IF NOT public.has_role_on_account(v_account_id) THEN
|
||||
RAISE EXCEPTION 'Access denied' USING ERRCODE = '42501';
|
||||
END IF;
|
||||
|
||||
-- Clamp page size to prevent unbounded queries
|
||||
p_page_size := LEAST(GREATEST(p_page_size, 1), 200);
|
||||
v_offset := GREATEST(0, (p_page - 1)) * p_page_size;
|
||||
|
||||
-- Get total count
|
||||
SELECT count(*) INTO v_total
|
||||
FROM public.course_audit_log cal
|
||||
WHERE cal.course_id = p_course_id
|
||||
AND (p_action_filter IS NULL OR cal.action = p_action_filter);
|
||||
|
||||
-- Return paginated results with user email
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
cal.id,
|
||||
cal.action,
|
||||
cal.changes,
|
||||
cal.metadata,
|
||||
cal.user_id,
|
||||
u.email::text AS user_email,
|
||||
cal.created_at,
|
||||
v_total AS total_count
|
||||
FROM public.course_audit_log cal
|
||||
LEFT JOIN auth.users u ON u.id = cal.user_id
|
||||
WHERE cal.course_id = p_course_id
|
||||
AND (p_action_filter IS NULL OR cal.action = p_action_filter)
|
||||
ORDER BY cal.created_at DESC
|
||||
LIMIT p_page_size OFFSET v_offset;
|
||||
END;
|
||||
$$;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION public.get_course_timeline(uuid, integer, integer, text)
|
||||
TO authenticated, service_role;
|
||||
|
||||
-- -------------------------------------------------------
|
||||
-- 2. Event timeline RPC
|
||||
-- -------------------------------------------------------
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_event_timeline(
|
||||
p_event_id uuid,
|
||||
p_page integer DEFAULT 1,
|
||||
p_page_size integer DEFAULT 50,
|
||||
p_action_filter text DEFAULT NULL
|
||||
)
|
||||
RETURNS TABLE (
|
||||
id bigint,
|
||||
action text,
|
||||
changes jsonb,
|
||||
metadata jsonb,
|
||||
user_id uuid,
|
||||
user_email text,
|
||||
created_at timestamptz,
|
||||
total_count bigint
|
||||
)
|
||||
LANGUAGE plpgsql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = ''
|
||||
AS $$
|
||||
DECLARE
|
||||
v_account_id uuid;
|
||||
v_total bigint;
|
||||
v_offset integer;
|
||||
BEGIN
|
||||
-- Get event's account for access check
|
||||
SELECT e.account_id INTO v_account_id
|
||||
FROM public.events e WHERE e.id = p_event_id;
|
||||
|
||||
IF v_account_id IS NULL THEN
|
||||
RAISE EXCEPTION 'Event not found';
|
||||
END IF;
|
||||
|
||||
IF NOT public.has_role_on_account(v_account_id) THEN
|
||||
RAISE EXCEPTION 'Access denied' USING ERRCODE = '42501';
|
||||
END IF;
|
||||
|
||||
-- Clamp page size to prevent unbounded queries
|
||||
p_page_size := LEAST(GREATEST(p_page_size, 1), 200);
|
||||
v_offset := GREATEST(0, (p_page - 1)) * p_page_size;
|
||||
|
||||
-- Get total count
|
||||
SELECT count(*) INTO v_total
|
||||
FROM public.event_audit_log eal
|
||||
WHERE eal.event_id = p_event_id
|
||||
AND (p_action_filter IS NULL OR eal.action = p_action_filter);
|
||||
|
||||
-- Return paginated results with user email
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
eal.id,
|
||||
eal.action,
|
||||
eal.changes,
|
||||
eal.metadata,
|
||||
eal.user_id,
|
||||
u.email::text AS user_email,
|
||||
eal.created_at,
|
||||
v_total AS total_count
|
||||
FROM public.event_audit_log eal
|
||||
LEFT JOIN auth.users u ON u.id = eal.user_id
|
||||
WHERE eal.event_id = p_event_id
|
||||
AND (p_action_filter IS NULL OR eal.action = p_action_filter)
|
||||
ORDER BY eal.created_at DESC
|
||||
LIMIT p_page_size OFFSET v_offset;
|
||||
END;
|
||||
$$;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION public.get_event_timeline(uuid, integer, integer, text)
|
||||
TO authenticated, service_role;
|
||||
|
||||
-- -------------------------------------------------------
|
||||
-- 3. Booking timeline RPC
|
||||
-- -------------------------------------------------------
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_booking_timeline(
|
||||
p_booking_id uuid,
|
||||
p_page integer DEFAULT 1,
|
||||
p_page_size integer DEFAULT 50,
|
||||
p_action_filter text DEFAULT NULL
|
||||
)
|
||||
RETURNS TABLE (
|
||||
id bigint,
|
||||
action text,
|
||||
changes jsonb,
|
||||
metadata jsonb,
|
||||
user_id uuid,
|
||||
user_email text,
|
||||
created_at timestamptz,
|
||||
total_count bigint
|
||||
)
|
||||
LANGUAGE plpgsql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = ''
|
||||
AS $$
|
||||
DECLARE
|
||||
v_account_id uuid;
|
||||
v_total bigint;
|
||||
v_offset integer;
|
||||
BEGIN
|
||||
-- Get booking's account for access check
|
||||
SELECT b.account_id INTO v_account_id
|
||||
FROM public.bookings b WHERE b.id = p_booking_id;
|
||||
|
||||
IF v_account_id IS NULL THEN
|
||||
RAISE EXCEPTION 'Booking not found';
|
||||
END IF;
|
||||
|
||||
IF NOT public.has_role_on_account(v_account_id) THEN
|
||||
RAISE EXCEPTION 'Access denied' USING ERRCODE = '42501';
|
||||
END IF;
|
||||
|
||||
-- Clamp page size to prevent unbounded queries
|
||||
p_page_size := LEAST(GREATEST(p_page_size, 1), 200);
|
||||
v_offset := GREATEST(0, (p_page - 1)) * p_page_size;
|
||||
|
||||
-- Get total count
|
||||
SELECT count(*) INTO v_total
|
||||
FROM public.booking_audit_log bal
|
||||
WHERE bal.booking_id = p_booking_id
|
||||
AND (p_action_filter IS NULL OR bal.action = p_action_filter);
|
||||
|
||||
-- Return paginated results with user email
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
bal.id,
|
||||
bal.action,
|
||||
bal.changes,
|
||||
bal.metadata,
|
||||
bal.user_id,
|
||||
u.email::text AS user_email,
|
||||
bal.created_at,
|
||||
v_total AS total_count
|
||||
FROM public.booking_audit_log bal
|
||||
LEFT JOIN auth.users u ON u.id = bal.user_id
|
||||
WHERE bal.booking_id = p_booking_id
|
||||
AND (p_action_filter IS NULL OR bal.action = p_action_filter)
|
||||
ORDER BY bal.created_at DESC
|
||||
LIMIT p_page_size OFFSET v_offset;
|
||||
END;
|
||||
$$;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION public.get_booking_timeline(uuid, integer, integer, text)
|
||||
TO authenticated, service_role;
|
||||
Reference in New Issue
Block a user