feat: Phase 1 - Events entity (migration, API, list page, detail layout with module sidebar, overview page)
This commit is contained in:
84
supabase/migrations/022_events.sql
Normal file
84
supabase/migrations/022_events.sql
Normal file
@@ -0,0 +1,84 @@
|
||||
-- Events: the core project entity within an organization
|
||||
-- Each event represents a project (conference, festival, meetup, etc.)
|
||||
|
||||
CREATE TABLE events (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
slug TEXT NOT NULL,
|
||||
description TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'planning' CHECK (status IN ('planning', 'active', 'completed', 'archived')),
|
||||
start_date DATE,
|
||||
end_date DATE,
|
||||
venue_name TEXT,
|
||||
venue_address TEXT,
|
||||
cover_image_url TEXT,
|
||||
color TEXT,
|
||||
created_by UUID REFERENCES auth.users(id),
|
||||
created_at TIMESTAMPTZ DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ DEFAULT now(),
|
||||
UNIQUE(org_id, slug)
|
||||
);
|
||||
|
||||
-- Event members: subset of org members assigned to an event
|
||||
CREATE TABLE event_members (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
||||
role TEXT NOT NULL DEFAULT 'member' CHECK (role IN ('lead', 'manager', 'member')),
|
||||
assigned_at TIMESTAMPTZ DEFAULT now(),
|
||||
UNIQUE(event_id, user_id)
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_events_org ON events(org_id);
|
||||
CREATE INDEX idx_events_status ON events(org_id, status);
|
||||
CREATE INDEX idx_events_dates ON events(start_date, end_date);
|
||||
CREATE INDEX idx_event_members_event ON event_members(event_id);
|
||||
CREATE INDEX idx_event_members_user ON event_members(user_id);
|
||||
|
||||
-- RLS
|
||||
ALTER TABLE events ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE event_members ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Events: org members can view, editors+ can manage
|
||||
CREATE POLICY "Org members can view events" ON events FOR SELECT
|
||||
USING (EXISTS (SELECT 1 FROM org_members WHERE org_id = events.org_id AND user_id = auth.uid()));
|
||||
|
||||
CREATE POLICY "Editors can manage events" ON events FOR ALL
|
||||
USING (EXISTS (SELECT 1 FROM org_members WHERE org_id = events.org_id AND user_id = auth.uid() AND role IN ('owner', 'admin', 'editor')));
|
||||
|
||||
-- Event members: org members can view, editors+ can manage
|
||||
CREATE POLICY "Org members can view event members" ON event_members FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM events e
|
||||
JOIN org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_members.event_id AND om.user_id = auth.uid()
|
||||
));
|
||||
|
||||
CREATE POLICY "Editors can manage event members" ON event_members FOR ALL
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM events e
|
||||
JOIN org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_members.event_id AND om.user_id = auth.uid() AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- Enable realtime
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE events;
|
||||
|
||||
-- Auto-add creator as event lead
|
||||
CREATE OR REPLACE FUNCTION public.handle_new_event()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
IF NEW.created_by IS NOT NULL THEN
|
||||
INSERT INTO public.event_members (event_id, user_id, role)
|
||||
VALUES (NEW.id, NEW.created_by, 'lead')
|
||||
ON CONFLICT (event_id, user_id) DO NOTHING;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||
|
||||
CREATE TRIGGER on_event_created
|
||||
AFTER INSERT ON events
|
||||
FOR EACH ROW EXECUTE FUNCTION public.handle_new_event();
|
||||
Reference in New Issue
Block a user