Migrations
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
-- Live position tracking for whereabouts map
|
||||
CREATE TABLE IF NOT EXISTS live_positions (
|
||||
user_id uuid PRIMARY KEY REFERENCES auth.users(id),
|
||||
lat double precision NOT NULL,
|
||||
lng double precision NOT NULL,
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
in_premise boolean NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
-- Enable realtime
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE live_positions;
|
||||
|
||||
-- RLS
|
||||
ALTER TABLE live_positions ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- All authenticated users can read live positions
|
||||
CREATE POLICY "live_positions_select" ON live_positions FOR SELECT TO authenticated
|
||||
USING (true);
|
||||
|
||||
-- Users can only upsert their own position
|
||||
CREATE POLICY "live_positions_insert" ON live_positions FOR INSERT TO authenticated
|
||||
WITH CHECK (user_id = auth.uid());
|
||||
|
||||
CREATE POLICY "live_positions_update" ON live_positions FOR UPDATE TO authenticated
|
||||
USING (user_id = auth.uid());
|
||||
|
||||
-- RPC: update_live_position — upserts position, computes in_premise via geofence
|
||||
CREATE OR REPLACE FUNCTION public.update_live_position(
|
||||
p_lat double precision,
|
||||
p_lng double precision
|
||||
) RETURNS boolean
|
||||
LANGUAGE plpgsql SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
v_geofence jsonb;
|
||||
v_in_premise boolean := false;
|
||||
v_polygon jsonb;
|
||||
v_point_count int;
|
||||
v_i int;
|
||||
v_j int;
|
||||
v_xi double precision;
|
||||
v_yi double precision;
|
||||
v_xj double precision;
|
||||
v_yj double precision;
|
||||
v_inside boolean := false;
|
||||
BEGIN
|
||||
-- Fetch geofence config
|
||||
SELECT value INTO v_geofence FROM app_settings WHERE key = 'geofence';
|
||||
|
||||
IF v_geofence IS NOT NULL THEN
|
||||
v_polygon := COALESCE(v_geofence->'polygon', v_geofence->'points');
|
||||
IF v_polygon IS NOT NULL AND jsonb_array_length(v_polygon) > 2 THEN
|
||||
-- Ray-casting point-in-polygon
|
||||
v_point_count := jsonb_array_length(v_polygon);
|
||||
v_j := v_point_count - 1;
|
||||
FOR v_i IN 0..(v_point_count - 1) LOOP
|
||||
v_xi := (v_polygon->v_i->>'lng')::double precision;
|
||||
v_yi := (v_polygon->v_i->>'lat')::double precision;
|
||||
v_xj := (v_polygon->v_j->>'lng')::double precision;
|
||||
v_yj := (v_polygon->v_j->>'lat')::double precision;
|
||||
|
||||
IF ((v_yi > p_lat) != (v_yj > p_lat)) AND
|
||||
(p_lng < (v_xj - v_xi) * (p_lat - v_yi) / (v_yj - v_yi) + v_xi) THEN
|
||||
v_inside := NOT v_inside;
|
||||
END IF;
|
||||
v_j := v_i;
|
||||
END LOOP;
|
||||
v_in_premise := v_inside;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
INSERT INTO live_positions (user_id, lat, lng, updated_at, in_premise)
|
||||
VALUES (auth.uid(), p_lat, p_lng, now(), v_in_premise)
|
||||
ON CONFLICT (user_id)
|
||||
DO UPDATE SET lat = p_lat, lng = p_lng, updated_at = now(), in_premise = v_in_premise;
|
||||
|
||||
RETURN v_in_premise;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- Update the duty_schedules RLS to allow all authenticated users to SELECT
|
||||
-- (previously only admin/dispatcher could see all; now all roles can see all schedules)
|
||||
DROP POLICY IF EXISTS "duty_schedules_select" ON duty_schedules;
|
||||
CREATE POLICY "duty_schedules_select" ON duty_schedules FOR SELECT TO authenticated
|
||||
USING (true);
|
||||
Reference in New Issue
Block a user