-- ============================================================ -- CICLO DE VIDA DE PACIENTES — patient_lifecycle.sql -- Rodar no Supabase SQL Editor (idempotente) -- ============================================================ -- ------------------------------------------------------------ -- 1.1 Expandir CHECK de status para incluir 'Arquivado' -- ------------------------------------------------------------ ALTER TABLE public.patients DROP CONSTRAINT IF EXISTS patients_status_check; ALTER TABLE public.patients ADD CONSTRAINT patients_status_check CHECK (status = ANY(ARRAY[ 'Ativo'::text, 'Inativo'::text, 'Alta'::text, 'Encaminhado'::text, 'Arquivado'::text ])); -- ------------------------------------------------------------ -- 1.2 can_delete_patient(uuid) → boolean -- Retorna false se existir histórico clínico ou financeiro -- ------------------------------------------------------------ CREATE OR REPLACE FUNCTION public.can_delete_patient(p_patient_id uuid) RETURNS boolean LANGUAGE sql STABLE SECURITY DEFINER AS $$ SELECT NOT EXISTS ( SELECT 1 FROM public.agenda_eventos WHERE patient_id = p_patient_id UNION ALL SELECT 1 FROM public.recurrence_rules WHERE patient_id = p_patient_id UNION ALL SELECT 1 FROM public.billing_contracts WHERE patient_id = p_patient_id ); $$; GRANT EXECUTE ON FUNCTION public.can_delete_patient(uuid) TO postgres, anon, authenticated, service_role; -- ------------------------------------------------------------ -- 1.3 safe_delete_patient(uuid) → jsonb -- Verifica histórico antes de deletar fisicamente -- ------------------------------------------------------------ CREATE OR REPLACE FUNCTION public.safe_delete_patient(p_patient_id uuid) RETURNS jsonb LANGUAGE plpgsql SECURITY DEFINER AS $$ BEGIN -- Bloqueia se houver histórico IF NOT public.can_delete_patient(p_patient_id) THEN RETURN jsonb_build_object( 'ok', false, 'error', 'has_history', 'message', 'Este paciente possui histórico clínico ou financeiro e não pode ser removido. Você pode desativar ou arquivar o paciente.' ); END IF; -- Verifica ownership via RLS (owner_id ou responsible_member_id) IF NOT EXISTS ( SELECT 1 FROM public.patients WHERE id = p_patient_id AND ( owner_id = auth.uid() OR responsible_member_id IN ( SELECT id FROM public.tenant_members WHERE user_id = auth.uid() ) ) ) THEN RETURN jsonb_build_object( 'ok', false, 'error', 'forbidden', 'message', 'Sem permissão para excluir este paciente.' ); END IF; DELETE FROM public.patients WHERE id = p_patient_id; RETURN jsonb_build_object('ok', true); END; $$; GRANT EXECUTE ON FUNCTION public.safe_delete_patient(uuid) TO postgres, anon, authenticated, service_role;