padronizacao: foundation Fase 0+0.5 — blueprints + auditoria + clinical_notes
Pre-MVP: 3 blueprints canonicos (repository, composable, quick-create overlay), AUDIT_BASELINE com 51 divergencias em 6 modulos, estrategia PADRONIZACAO de 4 fases, DESIGN_BILLING_ORCHESTRATOR. Schema clinical notes pronto pra Fase B (4 migrations + seed templates). AgendaEvent Dialog.vue.bak deletado (lixo de refator anterior). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
-- ============================================================================
|
||||
-- Trigger de versionamento automático de clinical_notes
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- A cada INSERT ou UPDATE relevante em clinical_notes, cria snapshot completo
|
||||
-- em clinical_note_versions. Função é SECURITY DEFINER pra bypassar a RLS
|
||||
-- (que bloqueia INSERT direto em clinical_note_versions).
|
||||
--
|
||||
-- Versionamento dispara em:
|
||||
-- • INSERT — registra criação (version_number = 1)
|
||||
-- • UPDATE em content_text, content_structured ou title — registra edição
|
||||
--
|
||||
-- Mudanças em pinned/is_draft NÃO disparam versionamento (mudança de UI/state,
|
||||
-- não de conteúdo).
|
||||
-- ============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.fn_clinical_note_version()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $$
|
||||
DECLARE
|
||||
next_version integer;
|
||||
reason text;
|
||||
BEGIN
|
||||
SELECT COALESCE(MAX(version_number), 0) + 1
|
||||
INTO next_version
|
||||
FROM public.clinical_note_versions
|
||||
WHERE note_id = NEW.id;
|
||||
|
||||
IF TG_OP = 'INSERT' THEN
|
||||
reason := 'criacao';
|
||||
ELSIF TG_OP = 'UPDATE' THEN
|
||||
IF NEW.deleted_at IS NOT NULL AND OLD.deleted_at IS NULL THEN
|
||||
reason := 'soft_delete';
|
||||
ELSIF NEW.deleted_at IS NULL AND OLD.deleted_at IS NOT NULL THEN
|
||||
reason := 'restore';
|
||||
ELSE
|
||||
reason := 'edicao';
|
||||
END IF;
|
||||
ELSE
|
||||
reason := 'desconhecido';
|
||||
END IF;
|
||||
|
||||
INSERT INTO public.clinical_note_versions (
|
||||
note_id,
|
||||
tenant_id,
|
||||
version_number,
|
||||
title,
|
||||
content_text,
|
||||
content_structured,
|
||||
change_reason,
|
||||
created_at,
|
||||
created_by
|
||||
) VALUES (
|
||||
NEW.id,
|
||||
NEW.tenant_id,
|
||||
next_version,
|
||||
NEW.title,
|
||||
NEW.content_text,
|
||||
NEW.content_structured,
|
||||
reason,
|
||||
now(),
|
||||
COALESCE(NEW.updated_by, NEW.created_by)
|
||||
);
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
COMMENT ON FUNCTION public.fn_clinical_note_version() IS
|
||||
'Snapshot completo de clinical_notes a cada INSERT/UPDATE relevante. SECURITY DEFINER bypassa RLS pra escrever em clinical_note_versions (que bloqueia INSERT direto).';
|
||||
|
||||
CREATE TRIGGER trg_clinical_notes_version_insert
|
||||
AFTER INSERT ON public.clinical_notes
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION public.fn_clinical_note_version();
|
||||
|
||||
CREATE TRIGGER trg_clinical_notes_version_update
|
||||
AFTER UPDATE OF content_text, content_structured, title, deleted_at
|
||||
ON public.clinical_notes
|
||||
FOR EACH ROW
|
||||
WHEN (
|
||||
OLD.content_text IS DISTINCT FROM NEW.content_text
|
||||
OR OLD.content_structured IS DISTINCT FROM NEW.content_structured
|
||||
OR OLD.title IS DISTINCT FROM NEW.title
|
||||
OR OLD.deleted_at IS DISTINCT FROM NEW.deleted_at
|
||||
)
|
||||
EXECUTE FUNCTION public.fn_clinical_note_version();
|
||||
|
||||
-- ──────────────────────────────────────────────────────────────────────────
|
||||
-- Trigger para updated_at automático
|
||||
-- ──────────────────────────────────────────────────────────────────────────
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.fn_clinical_notes_updated_at()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.updated_at := now();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE TRIGGER trg_clinical_notes_updated_at
|
||||
BEFORE UPDATE ON public.clinical_notes
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION public.fn_clinical_notes_updated_at();
|
||||
|
||||
CREATE TRIGGER trg_clinical_note_templates_updated_at
|
||||
BEFORE UPDATE ON public.clinical_note_templates
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION public.fn_clinical_notes_updated_at();
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user