feat: map shapes, image persistence, grab tool, layer rename/delete, i18n, page metadata
This commit is contained in:
108
supabase/migrations/046_map_layers_pins.sql
Normal file
108
supabase/migrations/046_map_layers_pins.sql
Normal file
@@ -0,0 +1,108 @@
|
||||
-- ============================================================
|
||||
-- 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;
|
||||
Reference in New Issue
Block a user