-- Schedule/Timeline + Contacts/Vendor Directory for department dashboards -- These are self-contained modules that can be added to any department dashboard -- ============================================================ -- 1. Schedule Stages (rooms/areas where things happen) -- ============================================================ CREATE TABLE schedule_stages ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), department_id UUID NOT NULL REFERENCES event_departments(id) ON DELETE CASCADE, name TEXT NOT NULL, color TEXT DEFAULT '#6366f1', sort_order INT NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); -- ============================================================ -- 2. Schedule Blocks (time blocks in the program) -- ============================================================ CREATE TABLE schedule_blocks ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), department_id UUID NOT NULL REFERENCES event_departments(id) ON DELETE CASCADE, stage_id UUID REFERENCES schedule_stages(id) ON DELETE SET NULL, title TEXT NOT NULL, description TEXT, start_time TIMESTAMPTZ NOT NULL, end_time TIMESTAMPTZ NOT NULL, color TEXT DEFAULT '#6366f1', speaker TEXT, sort_order INT NOT NULL DEFAULT 0, 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() ); -- ============================================================ -- 3. Contacts / Vendor Directory -- ============================================================ CREATE TABLE department_contacts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), department_id UUID NOT NULL REFERENCES event_departments(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() ); -- ============================================================ -- 4. Indexes -- ============================================================ CREATE INDEX idx_schedule_stages_dept ON schedule_stages(department_id); CREATE INDEX idx_schedule_blocks_dept ON schedule_blocks(department_id); CREATE INDEX idx_schedule_blocks_stage ON schedule_blocks(stage_id); CREATE INDEX idx_schedule_blocks_time ON schedule_blocks(start_time, end_time); CREATE INDEX idx_department_contacts_dept ON department_contacts(department_id); CREATE INDEX idx_department_contacts_category ON department_contacts(category); -- ============================================================ -- 5. RLS Policies -- ============================================================ ALTER TABLE schedule_stages ENABLE ROW LEVEL SECURITY; ALTER TABLE schedule_blocks ENABLE ROW LEVEL SECURITY; ALTER TABLE department_contacts ENABLE ROW LEVEL SECURITY; -- Schedule stages: org members can read, editors can write CREATE POLICY "schedule_stages_select" ON schedule_stages 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 = schedule_stages.department_id AND om.user_id = auth.uid() ) ); CREATE POLICY "schedule_stages_insert" ON schedule_stages 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 = schedule_stages.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "schedule_stages_update" ON schedule_stages 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 = schedule_stages.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "schedule_stages_delete" ON schedule_stages 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 = schedule_stages.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); -- Schedule blocks: same pattern CREATE POLICY "schedule_blocks_select" ON schedule_blocks 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 = schedule_blocks.department_id AND om.user_id = auth.uid() ) ); CREATE POLICY "schedule_blocks_insert" ON schedule_blocks 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 = schedule_blocks.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "schedule_blocks_update" ON schedule_blocks 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 = schedule_blocks.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "schedule_blocks_delete" ON schedule_blocks 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 = schedule_blocks.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); -- Contacts: same pattern CREATE POLICY "department_contacts_select" ON department_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_contacts.department_id AND om.user_id = auth.uid() ) ); CREATE POLICY "department_contacts_insert" ON department_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_contacts.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "department_contacts_update" ON department_contacts 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 = department_contacts.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) ); CREATE POLICY "department_contacts_delete" ON department_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_contacts.department_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor') ) );