Files
agenciapsilmno/src/sql-arquivos/patient_lifecycle.sql

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;