f94a4ae97f
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>
166 lines
8.9 KiB
PL/PgSQL
166 lines
8.9 KiB
PL/PgSQL
-- ============================================================================
|
|
-- Cria tabelas do prontuário clínico
|
|
-- ----------------------------------------------------------------------------
|
|
-- Núcleo do prontuário: notas clínicas (anamnese, evolução, plano), com
|
|
-- versionamento (audit trail) e templates (SOAP/DAP/BIRP/livre).
|
|
--
|
|
-- Decisões (sessão de modelagem 2026-05-20):
|
|
-- • Tabela única `clinical_notes` discriminada por `note_type` (não 1 tabela
|
|
-- por tipo). Templates customizáveis exigem flexibilidade.
|
|
-- • `content_text` (livre) + `content_structured` (jsonb) coexistem na mesma
|
|
-- row — UI prioriza conforme template; busca/edit rápido sempre tem text.
|
|
-- • Versionamento via snapshot completo (não diff) em `clinical_note_versions`
|
|
-- — restore trivial e audit visualization friendly. Trigger de versionamento
|
|
-- criado em migration separada.
|
|
-- • Instrumentos de avaliação (GAD-7, PHQ-9, etc) ficam pra Fase 2.
|
|
-- • RLS: owner-only (terapeuta responsável). Sem clinic-wide read — CFP exige
|
|
-- sigilo entre profissionais. Policies em migration separada.
|
|
-- ============================================================================
|
|
|
|
BEGIN;
|
|
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
-- 1. clinical_notes — núcleo do prontuário
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
|
|
CREATE TABLE IF NOT EXISTS public.clinical_notes (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id uuid NOT NULL,
|
|
owner_id uuid NOT NULL, -- terapeuta responsável
|
|
patient_id uuid NOT NULL REFERENCES public.patients(id) ON DELETE RESTRICT,
|
|
session_event_id uuid REFERENCES public.agenda_eventos(id) ON DELETE SET NULL,
|
|
note_type text NOT NULL,
|
|
template_id uuid, -- FK adicionada após criar templates
|
|
title text,
|
|
content_text text,
|
|
content_structured jsonb,
|
|
pinned boolean DEFAULT false NOT NULL,
|
|
is_draft boolean DEFAULT false NOT NULL,
|
|
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
|
updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
|
created_by uuid NOT NULL,
|
|
updated_by uuid,
|
|
deleted_at timestamp with time zone,
|
|
deleted_by uuid,
|
|
CONSTRAINT clinical_notes_note_type_check CHECK (note_type IN (
|
|
'anamnese',
|
|
'evolucao_sessao',
|
|
'plano_terapeutico',
|
|
'observacao_livre',
|
|
'resumo_caso'
|
|
)),
|
|
CONSTRAINT clinical_notes_content_present_check CHECK (
|
|
content_text IS NOT NULL OR content_structured IS NOT NULL
|
|
)
|
|
);
|
|
|
|
COMMENT ON TABLE public.clinical_notes IS
|
|
'Notas clínicas do prontuário (anamnese, evolução de sessão, plano, observações). Owner-only via RLS — CFP exige sigilo.';
|
|
COMMENT ON COLUMN public.clinical_notes.session_event_id IS
|
|
'Sessão associada (quando aplicável). Anamnese/plano/resumo podem ter NULL.';
|
|
COMMENT ON COLUMN public.clinical_notes.content_text IS
|
|
'Conteúdo em texto livre (sempre disponível pra busca/edit rápido).';
|
|
COMMENT ON COLUMN public.clinical_notes.content_structured IS
|
|
'Conteúdo em formato estruturado quando há template ativo (jsonb dos campos preenchidos).';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_notes_patient_recent
|
|
ON public.clinical_notes (tenant_id, patient_id, created_at DESC)
|
|
WHERE deleted_at IS NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_notes_owner
|
|
ON public.clinical_notes (owner_id)
|
|
WHERE deleted_at IS NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_notes_session
|
|
ON public.clinical_notes (session_event_id)
|
|
WHERE session_event_id IS NOT NULL AND deleted_at IS NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_notes_type
|
|
ON public.clinical_notes (tenant_id, patient_id, note_type)
|
|
WHERE deleted_at IS NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_notes_pinned
|
|
ON public.clinical_notes (tenant_id, patient_id)
|
|
WHERE pinned = true AND deleted_at IS NULL;
|
|
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
-- 2. clinical_note_versions — audit trail (snapshot completo)
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
|
|
CREATE TABLE IF NOT EXISTS public.clinical_note_versions (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
note_id uuid NOT NULL REFERENCES public.clinical_notes(id) ON DELETE CASCADE,
|
|
tenant_id uuid NOT NULL,
|
|
version_number integer NOT NULL,
|
|
title text,
|
|
content_text text,
|
|
content_structured jsonb,
|
|
change_reason text, -- 'criacao' | 'edicao' | livre
|
|
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
|
created_by uuid NOT NULL,
|
|
CONSTRAINT clinical_note_versions_unique UNIQUE (note_id, version_number)
|
|
);
|
|
|
|
COMMENT ON TABLE public.clinical_note_versions IS
|
|
'Snapshot completo de cada versão de clinical_notes. Criado via trigger AFTER INSERT OR UPDATE.';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_note_versions_recent
|
|
ON public.clinical_note_versions (note_id, version_number DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_note_versions_audit
|
|
ON public.clinical_note_versions (created_by, created_at DESC);
|
|
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
-- 3. clinical_note_templates — templates SOAP/DAP/BIRP/anamnese padrão
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
|
|
CREATE TABLE IF NOT EXISTS public.clinical_note_templates (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id uuid, -- NULL = template global do sistema
|
|
owner_id uuid, -- NULL = template do tenant inteiro
|
|
key text NOT NULL, -- 'soap', 'dap', 'birp', 'anamnese_padrao', ...
|
|
name text NOT NULL,
|
|
note_type text NOT NULL,
|
|
description text,
|
|
structure jsonb NOT NULL, -- [{key, label, type, required, hint}]
|
|
is_system boolean DEFAULT false NOT NULL,
|
|
is_global boolean DEFAULT false NOT NULL,
|
|
active boolean DEFAULT true NOT NULL,
|
|
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
|
updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
|
CONSTRAINT clinical_note_templates_note_type_check CHECK (note_type IN (
|
|
'anamnese',
|
|
'evolucao_sessao',
|
|
'plano_terapeutico',
|
|
'observacao_livre',
|
|
'resumo_caso'
|
|
)),
|
|
CONSTRAINT clinical_note_templates_scope_check CHECK (
|
|
-- Sistema: ambos NULL e is_system=true
|
|
-- Tenant-wide: tenant_id presente, owner_id NULL
|
|
-- Owner: ambos presentes
|
|
(is_system = true AND tenant_id IS NULL AND owner_id IS NULL)
|
|
OR (is_system = false AND tenant_id IS NOT NULL)
|
|
)
|
|
);
|
|
|
|
COMMENT ON TABLE public.clinical_note_templates IS
|
|
'Templates de notas clínicas. Escopo: sistema (is_system, sem tenant), tenant-wide (tenant_id sem owner), owner (ambos).';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_note_templates_active
|
|
ON public.clinical_note_templates (note_type)
|
|
WHERE active = true;
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_note_templates_tenant
|
|
ON public.clinical_note_templates (tenant_id, note_type)
|
|
WHERE tenant_id IS NOT NULL AND active = true;
|
|
CREATE INDEX IF NOT EXISTS idx_clinical_note_templates_owner
|
|
ON public.clinical_note_templates (owner_id, note_type)
|
|
WHERE owner_id IS NOT NULL AND active = true;
|
|
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
-- 4. FK de clinical_notes.template_id (criada agora que templates existe)
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
|
|
ALTER TABLE public.clinical_notes
|
|
ADD CONSTRAINT clinical_notes_template_fkey
|
|
FOREIGN KEY (template_id)
|
|
REFERENCES public.clinical_note_templates(id)
|
|
ON DELETE SET NULL;
|
|
|
|
COMMIT;
|