-- Finance enhancements: planned budgets per department, sponsor allocations, -- org-wide contacts, and department contact pinning -- ============================================================ -- 1. Add planned_budget to event_departments -- ============================================================ ALTER TABLE event_departments ADD COLUMN IF NOT EXISTS planned_budget NUMERIC(12,2) NOT NULL DEFAULT 0; -- ============================================================ -- 2. Sponsor Allocations -- Tracks how sponsor money is allocated to departments. -- A sponsor (confirmed/active) has an amount; the finance lead -- distributes portions of that to specific departments. -- ============================================================ CREATE TABLE sponsor_allocations ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), sponsor_id UUID NOT NULL REFERENCES sponsors(id) ON DELETE CASCADE, department_id UUID NOT NULL REFERENCES event_departments(id) ON DELETE CASCADE, allocated_amount NUMERIC(12,2) NOT NULL DEFAULT 0, used_amount NUMERIC(12,2) NOT NULL DEFAULT 0, notes TEXT, created_by UUID REFERENCES auth.users(id) ON DELETE SET NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX idx_sponsor_alloc_sponsor ON sponsor_allocations(sponsor_id); CREATE INDEX idx_sponsor_alloc_dept ON sponsor_allocations(department_id); -- Prevent duplicate allocations of the same sponsor to the same department CREATE UNIQUE INDEX idx_sponsor_alloc_unique ON sponsor_allocations(sponsor_id, department_id); -- ============================================================ -- 3. Org-wide Contacts -- Contacts that belong to the organization, not a department. -- Departments can "pin" contacts from this list. -- ============================================================ CREATE TABLE org_contacts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE, name TEXT NOT NULL, role TEXT, company TEXT, email TEXT, phone TEXT, website TEXT, notes TEXT, category TEXT DEFAULT 'general', color TEXT DEFAULT '#00A3E0', created_by UUID REFERENCES auth.users(id) ON DELETE SET NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX idx_org_contacts_org ON org_contacts(org_id); CREATE INDEX idx_org_contacts_category ON org_contacts(category); -- ============================================================ -- 4. Department pinned contacts (junction table) -- Links org_contacts to departments for quick access -- ============================================================ CREATE TABLE department_pinned_contacts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), department_id UUID NOT NULL REFERENCES event_departments(id) ON DELETE CASCADE, contact_id UUID NOT NULL REFERENCES org_contacts(id) ON DELETE CASCADE, pinned_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE UNIQUE INDEX idx_dept_pinned_unique ON department_pinned_contacts(department_id, contact_id); CREATE INDEX idx_dept_pinned_dept ON department_pinned_contacts(department_id); CREATE INDEX idx_dept_pinned_contact ON department_pinned_contacts(contact_id); -- ============================================================ -- 5. RLS Policies -- ============================================================ -- Sponsor Allocations ALTER TABLE sponsor_allocations ENABLE ROW LEVEL SECURITY; CREATE POLICY "sponsor_allocations_select" ON sponsor_allocations FOR SELECT USING ( EXISTS ( SELECT 1 FROM event_departments ed JOIN events e ON e.id = ed.event_id JOIN org_members om ON om.org_id = e.org_id WHERE ed.id = sponsor_allocations.department_id AND om.user_id = auth.uid() ) ); CREATE POLICY "sponsor_allocations_insert" ON sponsor_allocations FOR INSERT WITH CHECK ( EXISTS ( SELECT 1 FROM event_departments ed JOIN events e ON e.id = ed.event_id JOIN org_members om ON om.org_id = e.org_id WHERE ed.id = sponsor_allocations.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "sponsor_allocations_update" ON sponsor_allocations FOR UPDATE USING ( EXISTS ( SELECT 1 FROM event_departments ed JOIN events e ON e.id = ed.event_id JOIN org_members om ON om.org_id = e.org_id WHERE ed.id = sponsor_allocations.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "sponsor_allocations_delete" ON sponsor_allocations FOR DELETE USING ( EXISTS ( SELECT 1 FROM event_departments ed JOIN events e ON e.id = ed.event_id JOIN org_members om ON om.org_id = e.org_id WHERE ed.id = sponsor_allocations.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); -- Org Contacts ALTER TABLE org_contacts ENABLE ROW LEVEL SECURITY; CREATE POLICY "org_contacts_select" ON org_contacts FOR SELECT USING ( EXISTS ( SELECT 1 FROM org_members om WHERE om.org_id = org_contacts.org_id AND om.user_id = auth.uid() ) ); CREATE POLICY "org_contacts_insert" ON org_contacts FOR INSERT WITH CHECK ( EXISTS ( SELECT 1 FROM org_members om WHERE om.org_id = org_contacts.org_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "org_contacts_update" ON org_contacts FOR UPDATE USING ( EXISTS ( SELECT 1 FROM org_members om WHERE om.org_id = org_contacts.org_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "org_contacts_delete" ON org_contacts FOR DELETE USING ( EXISTS ( SELECT 1 FROM org_members om WHERE om.org_id = org_contacts.org_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); -- Department Pinned Contacts ALTER TABLE department_pinned_contacts ENABLE ROW LEVEL SECURITY; CREATE POLICY "dept_pinned_contacts_select" ON department_pinned_contacts FOR SELECT USING ( EXISTS ( SELECT 1 FROM event_departments ed JOIN events e ON e.id = ed.event_id JOIN org_members om ON om.org_id = e.org_id WHERE ed.id = department_pinned_contacts.department_id AND om.user_id = auth.uid() ) ); CREATE POLICY "dept_pinned_contacts_insert" ON department_pinned_contacts FOR INSERT WITH CHECK ( EXISTS ( SELECT 1 FROM event_departments ed JOIN events e ON e.id = ed.event_id JOIN org_members om ON om.org_id = e.org_id WHERE ed.id = department_pinned_contacts.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "dept_pinned_contacts_delete" ON department_pinned_contacts FOR DELETE USING ( EXISTS ( SELECT 1 FROM event_departments ed JOIN events e ON e.id = ed.event_id JOIN org_members om ON om.org_id = e.org_id WHERE ed.id = department_pinned_contacts.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); -- ============================================================ -- 6. Enable realtime for sponsor allocations -- ============================================================ ALTER PUBLICATION supabase_realtime ADD TABLE sponsor_allocations;