-- Cross-device face verification sessions. -- Created when web cannot access a camera and generates a QR code. -- Mobile scans the QR, performs liveness detection, and completes the session. CREATE TABLE IF NOT EXISTS verification_sessions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, type TEXT NOT NULL CHECK (type IN ('enrollment', 'verification')), context_id TEXT, -- e.g. attendance_log_id for verification type status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'completed', 'expired')), image_url TEXT, -- filled when mobile completes the session created_at TIMESTAMPTZ NOT NULL DEFAULT now(), expires_at TIMESTAMPTZ NOT NULL DEFAULT (now() + interval '5 minutes') ); -- Index for quick lookup by user + status CREATE INDEX idx_verification_sessions_user_status ON verification_sessions (user_id, status); -- Enable realtime for this table ALTER PUBLICATION supabase_realtime ADD TABLE verification_sessions; -- RLS policies ALTER TABLE verification_sessions ENABLE ROW LEVEL SECURITY; -- Users can read their own sessions CREATE POLICY "Users can read own verification sessions" ON verification_sessions FOR SELECT USING (auth.uid() = user_id); -- Users can create their own sessions CREATE POLICY "Users can create own verification sessions" ON verification_sessions FOR INSERT WITH CHECK (auth.uid() = user_id); -- Users can update their own sessions (complete from mobile) CREATE POLICY "Users can update own verification sessions" ON verification_sessions FOR UPDATE USING (auth.uid() = user_id); -- Users can delete their own sessions (cleanup) CREATE POLICY "Users can delete own verification sessions" ON verification_sessions FOR DELETE USING (auth.uid() = user_id);