-- ============================================================ -- Map Layers & Pins: persistent map data for department map module -- ============================================================ -- 1. Map Layers (each department can have multiple map layers) CREATE TABLE map_layers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), department_id UUID NOT NULL REFERENCES event_departments(id) ON DELETE CASCADE, name TEXT NOT NULL DEFAULT 'Map', layer_type TEXT NOT NULL DEFAULT 'osm' CHECK (layer_type IN ('osm', 'image')), image_url TEXT, image_width INT, image_height INT, center_lat DOUBLE PRECISION DEFAULT 0, center_lng DOUBLE PRECISION DEFAULT 0, zoom_level INT DEFAULT 13, sort_order INT NOT NULL DEFAULT 0, created_by UUID REFERENCES auth.users(id) ON DELETE SET NULL, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now() ); CREATE INDEX idx_map_layers_dept ON map_layers(department_id); -- 2. Map Pins (belong to a layer) CREATE TABLE map_pins ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), layer_id UUID NOT NULL REFERENCES map_layers(id) ON DELETE CASCADE, label TEXT NOT NULL, description TEXT DEFAULT '', color TEXT NOT NULL DEFAULT '#EF4444', lat DOUBLE PRECISION NOT NULL, lng DOUBLE PRECISION NOT NULL, bounds_north DOUBLE PRECISION, bounds_south DOUBLE PRECISION, bounds_east DOUBLE PRECISION, bounds_west DOUBLE PRECISION, sort_order INT NOT NULL DEFAULT 0, created_by UUID REFERENCES auth.users(id) ON DELETE SET NULL, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now() ); CREATE INDEX idx_map_pins_layer ON map_pins(layer_id); -- 3. RLS ALTER TABLE map_layers ENABLE ROW LEVEL SECURITY; ALTER TABLE map_pins ENABLE ROW LEVEL SECURITY; -- Map Layers: org members can view CREATE POLICY "Org members can view map layers" ON map_layers FOR SELECT USING (EXISTS ( SELECT 1 FROM event_departments ed JOIN events e ON ed.event_id = e.id JOIN org_members om ON e.org_id = om.org_id WHERE ed.id = map_layers.department_id AND om.user_id = auth.uid() )); -- Map Layers: dept members + editors can manage CREATE POLICY "Dept members and editors can manage map layers" ON map_layers FOR ALL USING (EXISTS ( SELECT 1 FROM event_departments ed JOIN events e ON ed.event_id = e.id JOIN org_members om ON e.org_id = om.org_id WHERE ed.id = map_layers.department_id AND om.user_id = auth.uid() AND ( om.role IN ('owner', 'admin', 'editor') OR EXISTS ( SELECT 1 FROM event_member_departments emd JOIN event_members em ON emd.event_member_id = em.id WHERE emd.department_id = ed.id AND em.user_id = auth.uid() ) ) )); -- Map Pins: org members can view CREATE POLICY "Org members can view map pins" ON map_pins FOR SELECT USING (EXISTS ( SELECT 1 FROM map_layers ml JOIN event_departments ed ON ml.department_id = ed.id JOIN events e ON ed.event_id = e.id JOIN org_members om ON e.org_id = om.org_id WHERE ml.id = map_pins.layer_id AND om.user_id = auth.uid() )); -- Map Pins: dept members + editors can manage CREATE POLICY "Dept members and editors can manage map pins" ON map_pins FOR ALL USING (EXISTS ( SELECT 1 FROM map_layers ml JOIN event_departments ed ON ml.department_id = ed.id JOIN events e ON ed.event_id = e.id JOIN org_members om ON e.org_id = om.org_id WHERE ml.id = map_pins.layer_id AND om.user_id = auth.uid() AND ( om.role IN ('owner', 'admin', 'editor') OR EXISTS ( SELECT 1 FROM event_member_departments emd JOIN event_members em ON emd.event_member_id = em.id WHERE emd.department_id = ed.id AND em.user_id = auth.uid() ) ) )); -- 4. Realtime ALTER PUBLICATION supabase_realtime ADD TABLE map_layers; ALTER PUBLICATION supabase_realtime ADD TABLE map_pins;