tasq/supabase/migrations/20260307090000_fix_check_in_location_geography.sql

99 lines
2.7 KiB
PL/PgSQL

-- Fix check_in_location to use PostGIS geography instead of JSONB
-- Update attendance_check_in RPC to use geography point
CREATE OR REPLACE FUNCTION public.attendance_check_in(
p_duty_id uuid,
p_lat double precision,
p_lng double precision
) RETURNS uuid
LANGUAGE plpgsql SECURITY DEFINER
AS $$
DECLARE
v_schedule duty_schedules%ROWTYPE;
v_geofence jsonb;
v_log_id uuid;
v_now timestamptz := now();
v_status text;
BEGIN
-- Fetch the duty schedule
SELECT * INTO v_schedule FROM duty_schedules WHERE id = p_duty_id;
IF NOT FOUND THEN
RAISE EXCEPTION 'Duty schedule not found';
END IF;
IF v_schedule.user_id != auth.uid() THEN
RAISE EXCEPTION 'Not your duty schedule';
END IF;
-- Check 2-hour window
IF v_now < (v_schedule.start_time - interval '2 hours') THEN
RAISE EXCEPTION 'Too early to check in (2-hour window)';
END IF;
IF v_now > v_schedule.end_time THEN
RAISE EXCEPTION 'Duty has already ended';
END IF;
-- Determine status
IF v_now <= v_schedule.start_time THEN
v_status := 'arrival';
ELSE
v_status := 'late';
END IF;
-- Insert attendance log
INSERT INTO attendance_logs (user_id, duty_schedule_id, check_in_at, check_in_lat, check_in_lng)
VALUES (auth.uid(), p_duty_id, v_now, p_lat, p_lng)
RETURNING id INTO v_log_id;
-- Update duty schedule with geography point (longitude, latitude order)
UPDATE duty_schedules
SET check_in_at = v_now,
check_in_location = ST_SetSRID(ST_MakePoint(p_lng, p_lat), 4326)::geography,
status = v_status::duty_status
WHERE id = p_duty_id;
RETURN v_log_id;
END;
$$;
-- Update duty_check_in RPC to use geography point
CREATE OR REPLACE FUNCTION public.duty_check_in(
p_duty_id uuid,
p_lat double precision,
p_lng double precision
) RETURNS text
LANGUAGE plpgsql SECURITY DEFINER
AS $$
DECLARE
v_schedule duty_schedules%ROWTYPE;
v_now timestamptz := now();
v_status text;
BEGIN
SELECT * INTO v_schedule FROM duty_schedules WHERE id = p_duty_id;
IF NOT FOUND THEN
RAISE EXCEPTION 'Duty schedule not found';
END IF;
IF v_schedule.user_id != auth.uid() THEN
RAISE EXCEPTION 'Not your duty schedule';
END IF;
IF v_now <= v_schedule.start_time THEN
v_status := 'arrival';
ELSE
v_status := 'late';
END IF;
-- Update duty schedule with geography point (longitude, latitude order)
UPDATE duty_schedules
SET check_in_at = v_now,
check_in_location = ST_SetSRID(ST_MakePoint(p_lng, p_lat), 4326)::geography,
status = v_status::duty_status
WHERE id = p_duty_id;
-- Also create an attendance log entry
INSERT INTO attendance_logs (user_id, duty_schedule_id, check_in_at, check_in_lat, check_in_lng)
VALUES (auth.uid(), p_duty_id, v_now, p_lat, p_lng);
RETURN v_status;
END;
$$;