86 lines
2.8 KiB
PL/PgSQL
86 lines
2.8 KiB
PL/PgSQL
-- ============================================================
|
|
-- 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;
|