Add ACMCC app source, Supabase backend, and project config

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 20:19:26 -04:00
parent 313b51b412
commit 183fe0a93c
1422 changed files with 259271 additions and 0 deletions
@@ -0,0 +1,83 @@
-- Enable RLS on realtime.messages (Supabase Realtime authorization table)
ALTER TABLE realtime.messages ENABLE ROW LEVEL SECURITY;
-- Drop any existing policies to start clean
DO $$
DECLARE
pol record;
BEGIN
FOR pol IN
SELECT policyname FROM pg_policies
WHERE schemaname = 'realtime' AND tablename = 'messages'
LOOP
EXECUTE format('DROP POLICY IF EXISTS %I ON realtime.messages', pol.policyname);
END LOOP;
END $$;
-- Helper: check if a realtime topic is authorized for the current user
CREATE OR REPLACE FUNCTION public.realtime_topic_authorized(_topic text)
RETURNS boolean
LANGUAGE plpgsql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
_uid uuid := auth.uid();
_assoc uuid;
BEGIN
IF _uid IS NULL THEN
RETURN false;
END IF;
-- Staff (admin/manager) can subscribe to any channel
IF public.has_role(_uid, 'admin'::public.app_role)
OR public.has_role(_uid, 'manager'::public.app_role) THEN
RETURN true;
END IF;
IF _topic IS NULL OR _topic = '' THEN
RETURN false;
END IF;
-- Channels containing the user's own UID (e.g. dm-unread-<uid>, notifications-<uid>)
IF position(_uid::text in _topic) > 0 THEN
RETURN true;
END IF;
-- Channels containing an association UUID the user belongs to
FOR _assoc IN SELECT public.get_user_association_ids() LOOP
IF _assoc IS NOT NULL AND position(_assoc::text in _topic) > 0 THEN
RETURN true;
END IF;
END LOOP;
-- Legal users: allow channels for their assigned associations
IF public.has_role(_uid, 'legal'::public.app_role) THEN
FOR _assoc IN SELECT public.get_legal_association_ids(_uid) LOOP
IF _assoc IS NOT NULL AND position(_assoc::text in _topic) > 0 THEN
RETURN true;
END IF;
END LOOP;
END IF;
RETURN false;
END;
$$;
-- Restrict EXECUTE to authenticated users only
REVOKE EXECUTE ON FUNCTION public.realtime_topic_authorized(text) FROM PUBLIC, anon;
GRANT EXECUTE ON FUNCTION public.realtime_topic_authorized(text) TO authenticated;
-- Policy: authenticated users can only access messages on authorized topics
CREATE POLICY "Authenticated users can read authorized topics"
ON realtime.messages
FOR SELECT
TO authenticated
USING (public.realtime_topic_authorized((realtime.topic())::text));
CREATE POLICY "Authenticated users can send to authorized topics"
ON realtime.messages
FOR INSERT
TO authenticated
WITH CHECK (public.realtime_topic_authorized((realtime.topic())::text));