143 lines
5.9 KiB
PL/PgSQL
143 lines
5.9 KiB
PL/PgSQL
-- Event Team Management: departments, roles, and member-department assignments
|
|
-- Supports real-world event teams where members have roles and belong to departments
|
|
|
|
-- ============================================================
|
|
-- 1. Event Roles: customizable per-event position types
|
|
-- ============================================================
|
|
CREATE TABLE event_roles (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '#6366f1',
|
|
sort_order INT NOT NULL DEFAULT 0,
|
|
is_default BOOLEAN NOT NULL DEFAULT false,
|
|
created_at TIMESTAMPTZ DEFAULT now(),
|
|
UNIQUE(event_id, name)
|
|
);
|
|
|
|
CREATE INDEX idx_event_roles_event ON event_roles(event_id);
|
|
|
|
-- ============================================================
|
|
-- 2. Event Departments: teams/areas within an event
|
|
-- ============================================================
|
|
CREATE TABLE event_departments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '#00A3E0',
|
|
description TEXT,
|
|
sort_order INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ DEFAULT now(),
|
|
UNIQUE(event_id, name)
|
|
);
|
|
|
|
CREATE INDEX idx_event_departments_event ON event_departments(event_id);
|
|
|
|
-- ============================================================
|
|
-- 3. Evolve event_members: add role_id FK, keep role text as fallback
|
|
-- ============================================================
|
|
ALTER TABLE event_members
|
|
ADD COLUMN role_id UUID REFERENCES event_roles(id) ON DELETE SET NULL,
|
|
ADD COLUMN notes TEXT;
|
|
|
|
-- ============================================================
|
|
-- 4. Member-Department assignments (many-to-many)
|
|
-- ============================================================
|
|
CREATE TABLE event_member_departments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
event_member_id UUID NOT NULL REFERENCES event_members(id) ON DELETE CASCADE,
|
|
department_id UUID NOT NULL REFERENCES event_departments(id) ON DELETE CASCADE,
|
|
assigned_at TIMESTAMPTZ DEFAULT now(),
|
|
UNIQUE(event_member_id, department_id)
|
|
);
|
|
|
|
CREATE INDEX idx_emd_member ON event_member_departments(event_member_id);
|
|
CREATE INDEX idx_emd_department ON event_member_departments(department_id);
|
|
|
|
-- ============================================================
|
|
-- 5. RLS policies
|
|
-- ============================================================
|
|
ALTER TABLE event_roles ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE event_departments ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE event_member_departments ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Event roles: org members can view, editors+ can manage
|
|
CREATE POLICY "Org members can view event roles" ON event_roles FOR SELECT
|
|
USING (EXISTS (
|
|
SELECT 1 FROM events e
|
|
JOIN org_members om ON e.org_id = om.org_id
|
|
WHERE e.id = event_roles.event_id AND om.user_id = auth.uid()
|
|
));
|
|
|
|
CREATE POLICY "Editors can manage event roles" ON event_roles FOR ALL
|
|
USING (EXISTS (
|
|
SELECT 1 FROM events e
|
|
JOIN org_members om ON e.org_id = om.org_id
|
|
WHERE e.id = event_roles.event_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor')
|
|
));
|
|
|
|
-- Event departments: org members can view, editors+ can manage
|
|
CREATE POLICY "Org members can view event departments" ON event_departments FOR SELECT
|
|
USING (EXISTS (
|
|
SELECT 1 FROM events e
|
|
JOIN org_members om ON e.org_id = om.org_id
|
|
WHERE e.id = event_departments.event_id AND om.user_id = auth.uid()
|
|
));
|
|
|
|
CREATE POLICY "Editors can manage event departments" ON event_departments FOR ALL
|
|
USING (EXISTS (
|
|
SELECT 1 FROM events e
|
|
JOIN org_members om ON e.org_id = om.org_id
|
|
WHERE e.id = event_departments.event_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor')
|
|
));
|
|
|
|
-- Member-department assignments: org members can view, editors+ can manage
|
|
CREATE POLICY "Org members can view member departments" ON event_member_departments FOR SELECT
|
|
USING (EXISTS (
|
|
SELECT 1 FROM event_members em
|
|
JOIN events e ON em.event_id = e.id
|
|
JOIN org_members om ON e.org_id = om.org_id
|
|
WHERE em.id = event_member_departments.event_member_id AND om.user_id = auth.uid()
|
|
));
|
|
|
|
CREATE POLICY "Editors can manage member departments" ON event_member_departments FOR ALL
|
|
USING (EXISTS (
|
|
SELECT 1 FROM event_members em
|
|
JOIN events e ON em.event_id = e.id
|
|
JOIN org_members om ON e.org_id = om.org_id
|
|
WHERE em.id = event_member_departments.event_member_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor')
|
|
));
|
|
|
|
-- ============================================================
|
|
-- 6. Auto-seed default roles when a new event is created
|
|
-- ============================================================
|
|
CREATE OR REPLACE FUNCTION public.seed_event_defaults()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
-- Default roles (generalized from real event data)
|
|
INSERT INTO public.event_roles (event_id, name, color, sort_order, is_default) VALUES
|
|
(NEW.id, 'Head Organizer', '#EF4444', 0, false),
|
|
(NEW.id, 'Team Lead', '#8B5CF6', 1, false),
|
|
(NEW.id, 'Organizer', '#F59E0B', 2, true),
|
|
(NEW.id, 'Volunteer', '#10B981', 3, false),
|
|
(NEW.id, 'Sponsor', '#00A3E0', 4, false);
|
|
|
|
-- Default departments (generalized from real event data)
|
|
INSERT INTO public.event_departments (event_id, name, color, sort_order) VALUES
|
|
(NEW.id, 'Logistics', '#F59E0B', 0),
|
|
(NEW.id, 'IT & Tech', '#6366F1', 1),
|
|
(NEW.id, 'Marketing', '#EC4899', 2),
|
|
(NEW.id, 'Finance', '#10B981', 3),
|
|
(NEW.id, 'Program', '#8B5CF6', 4),
|
|
(NEW.id, 'Sponsorship', '#00A3E0', 5),
|
|
(NEW.id, 'Design', '#F97316', 6),
|
|
(NEW.id, 'Volunteers', '#14B8A6', 7);
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
CREATE TRIGGER on_event_created_seed_defaults
|
|
AFTER INSERT ON events
|
|
FOR EACH ROW EXECUTE FUNCTION public.seed_event_defaults();
|