Attendance log now record both check in and out photos and allow IT Staffs, Dispatchers and Admins to view for verification
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
-- Split single verification_photo_url into separate check-in and check-out columns.
|
||||
-- Also add check_out_justification for off-site checkout.
|
||||
|
||||
-- Add new columns
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'attendance_logs' AND column_name = 'check_in_verification_photo_url'
|
||||
) THEN
|
||||
ALTER TABLE attendance_logs ADD COLUMN check_in_verification_photo_url TEXT;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'attendance_logs' AND column_name = 'check_out_verification_photo_url'
|
||||
) THEN
|
||||
ALTER TABLE attendance_logs ADD COLUMN check_out_verification_photo_url TEXT;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'attendance_logs' AND column_name = 'check_out_justification'
|
||||
) THEN
|
||||
ALTER TABLE attendance_logs ADD COLUMN check_out_justification TEXT;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Migrate existing data: copy verification_photo_url → check_in_verification_photo_url
|
||||
-- (the old column stored the last verification photo, which was overwritten by checkout;
|
||||
-- for rows that were only checked in, this is the check-in photo)
|
||||
UPDATE attendance_logs
|
||||
SET check_in_verification_photo_url = verification_photo_url
|
||||
WHERE verification_photo_url IS NOT NULL
|
||||
AND check_in_verification_photo_url IS NULL;
|
||||
|
||||
-- Update checkout RPC to accept optional justification
|
||||
CREATE OR REPLACE FUNCTION public.attendance_check_out(
|
||||
p_attendance_id uuid,
|
||||
p_lat double precision,
|
||||
p_lng double precision,
|
||||
p_justification text DEFAULT NULL
|
||||
) RETURNS void
|
||||
LANGUAGE plpgsql SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
v_log attendance_logs%ROWTYPE;
|
||||
BEGIN
|
||||
SELECT * INTO v_log FROM attendance_logs WHERE id = p_attendance_id;
|
||||
IF NOT FOUND THEN
|
||||
RAISE EXCEPTION 'Attendance log not found';
|
||||
END IF;
|
||||
IF v_log.user_id != auth.uid() THEN
|
||||
RAISE EXCEPTION 'Not your attendance log';
|
||||
END IF;
|
||||
IF v_log.check_out_at IS NOT NULL THEN
|
||||
RAISE EXCEPTION 'Already checked out';
|
||||
END IF;
|
||||
|
||||
UPDATE attendance_logs
|
||||
SET check_out_at = now(),
|
||||
check_out_lat = p_lat,
|
||||
check_out_lng = p_lng,
|
||||
check_out_justification = p_justification
|
||||
WHERE id = p_attendance_id;
|
||||
END;
|
||||
$$;
|
||||
@@ -0,0 +1,37 @@
|
||||
-- ───────────────────────────────────────────────────────────
|
||||
-- Fix storage SELECT policies so admin, dispatcher, and it_staff
|
||||
-- can view any user's face-enrollment and attendance-verification photos.
|
||||
-- Regular users can still only view their own.
|
||||
-- ───────────────────────────────────────────────────────────
|
||||
|
||||
-- face-enrollment: owner OR privileged roles can view
|
||||
DROP POLICY IF EXISTS "Users can view own face" ON storage.objects;
|
||||
CREATE POLICY "Users can view own face"
|
||||
ON storage.objects FOR SELECT
|
||||
USING (
|
||||
bucket_id = 'face-enrollment'
|
||||
AND (
|
||||
(storage.foldername(name))[1] = auth.uid()::text
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.profiles
|
||||
WHERE id = auth.uid()
|
||||
AND role IN ('admin', 'dispatcher', 'it_staff')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
-- attendance-verification: owner OR privileged roles can view
|
||||
DROP POLICY IF EXISTS "Users and admins can view verification photos" ON storage.objects;
|
||||
CREATE POLICY "Users and admins can view verification photos"
|
||||
ON storage.objects FOR SELECT
|
||||
USING (
|
||||
bucket_id = 'attendance-verification'
|
||||
AND (
|
||||
(storage.foldername(name))[1] = auth.uid()::text
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.profiles
|
||||
WHERE id = auth.uid()
|
||||
AND role IN ('admin', 'dispatcher', 'it_staff')
|
||||
)
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user