Documentos Pacientes, Template Documentos Pacientes Saas, Documentos prontuários, Documentos Externos, Visualização Externa, Permissão de Visualização, Render Otimização
This commit is contained in:
@@ -0,0 +1,260 @@
|
||||
-- ==========================================================================
|
||||
-- Agencia PSI — Migracao: tabelas de Templates de Documentos
|
||||
-- ==========================================================================
|
||||
-- Criado por: Leonardo Nohama
|
||||
-- Data: 2026-03-29 · Sao Carlos/SP — Brasil
|
||||
--
|
||||
-- Proposito:
|
||||
-- Templates de documentos (declaracao, atestado, recibo, relatorio etc.)
|
||||
-- e registro de cada documento gerado (instancia PDF).
|
||||
--
|
||||
-- Tabelas: document_templates, document_generated.
|
||||
--
|
||||
-- Relacionamentos:
|
||||
-- document_templates.tenant_id → tenants(id)
|
||||
-- document_templates.owner_id → auth.users(id)
|
||||
-- document_generated.template_id → document_templates(id)
|
||||
-- document_generated.patient_id → patients(id)
|
||||
-- document_generated.tenant_id → tenants(id)
|
||||
--
|
||||
-- Templates globais: is_global = true, tenant_id = NULL.
|
||||
-- Templates do tenant: is_global = false, tenant_id preenchido.
|
||||
-- ==========================================================================
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 1. Tabela: document_templates
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS public.document_templates (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
|
||||
-- Contexto
|
||||
tenant_id uuid,
|
||||
owner_id uuid,
|
||||
|
||||
-- Identificacao
|
||||
nome_template text NOT NULL,
|
||||
tipo text NOT NULL DEFAULT 'outro',
|
||||
-- declaracao_comparecimento | atestado_psicologico
|
||||
-- relatorio_acompanhamento | recibo_pagamento
|
||||
-- termo_consentimento | encaminhamento | outro
|
||||
descricao text,
|
||||
|
||||
-- Corpo do template
|
||||
corpo_html text NOT NULL DEFAULT '',
|
||||
cabecalho_html text,
|
||||
rodape_html text,
|
||||
|
||||
-- Variaveis que o template utiliza
|
||||
variaveis text[] DEFAULT '{}',
|
||||
-- Ex: {paciente_nome, paciente_cpf, data_sessao, terapeuta_nome, ...}
|
||||
|
||||
-- Personalizacao visual
|
||||
logo_url text,
|
||||
|
||||
-- Escopo
|
||||
is_global boolean DEFAULT false NOT NULL,
|
||||
-- true = template padrao do sistema (visivel para todos)
|
||||
-- false = template criado pelo tenant/terapeuta
|
||||
|
||||
-- Controle
|
||||
ativo boolean DEFAULT true NOT NULL,
|
||||
created_at timestamptz DEFAULT now(),
|
||||
updated_at timestamptz DEFAULT now(),
|
||||
|
||||
CONSTRAINT document_templates_pkey PRIMARY KEY (id),
|
||||
|
||||
CONSTRAINT dt_tipo_check CHECK (
|
||||
tipo = ANY (ARRAY[
|
||||
'declaracao_comparecimento', 'atestado_psicologico',
|
||||
'relatorio_acompanhamento', 'recibo_pagamento',
|
||||
'termo_consentimento', 'encaminhamento',
|
||||
'contrato_servicos', 'tcle', 'autorizacao_menor',
|
||||
'laudo_psicologico', 'parecer_psicologico',
|
||||
'termo_sigilo', 'declaracao_inicio_tratamento',
|
||||
'termo_alta', 'tcle_online', 'outro'
|
||||
])
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 2. Indices — document_templates
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE INDEX IF NOT EXISTS dt_tenant_idx
|
||||
ON public.document_templates USING btree (tenant_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS dt_owner_idx
|
||||
ON public.document_templates USING btree (owner_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS dt_global_idx
|
||||
ON public.document_templates USING btree (is_global)
|
||||
WHERE is_global = true;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS dt_tipo_idx
|
||||
ON public.document_templates USING btree (tipo);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS dt_nome_trgm_idx
|
||||
ON public.document_templates USING gin (nome_template gin_trgm_ops);
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 3. Trigger updated_at
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE TRIGGER trg_dt_updated_at
|
||||
BEFORE UPDATE ON public.document_templates
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION public.set_updated_at();
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 4. RLS — document_templates
|
||||
-- --------------------------------------------------------------------------
|
||||
ALTER TABLE public.document_templates ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Templates globais: todos podem ler
|
||||
CREATE POLICY "dt: global templates readable by all"
|
||||
ON public.document_templates
|
||||
FOR SELECT
|
||||
USING (is_global = true);
|
||||
|
||||
-- Templates do tenant: membros do tenant podem ler
|
||||
CREATE POLICY "dt: tenant members can select"
|
||||
ON public.document_templates
|
||||
FOR SELECT
|
||||
USING (
|
||||
is_global = false
|
||||
AND tenant_id IN (
|
||||
SELECT tm.tenant_id FROM public.tenant_members tm
|
||||
WHERE tm.user_id = auth.uid() AND tm.status = 'active'
|
||||
)
|
||||
);
|
||||
|
||||
-- Owner pode inserir/atualizar/deletar seus templates
|
||||
CREATE POLICY "dt: owner can insert"
|
||||
ON public.document_templates
|
||||
FOR INSERT
|
||||
WITH CHECK (owner_id = auth.uid() AND is_global = false);
|
||||
|
||||
CREATE POLICY "dt: owner can update"
|
||||
ON public.document_templates
|
||||
FOR UPDATE
|
||||
USING (owner_id = auth.uid() AND is_global = false)
|
||||
WITH CHECK (owner_id = auth.uid() AND is_global = false);
|
||||
|
||||
CREATE POLICY "dt: owner can delete"
|
||||
ON public.document_templates
|
||||
FOR DELETE
|
||||
USING (owner_id = auth.uid() AND is_global = false);
|
||||
|
||||
-- SaaS admin pode gerenciar templates globais (usa funcao public.is_saas_admin())
|
||||
CREATE POLICY "dt: saas admin can insert global"
|
||||
ON public.document_templates
|
||||
FOR INSERT
|
||||
WITH CHECK (is_global = true AND public.is_saas_admin());
|
||||
|
||||
CREATE POLICY "dt: saas admin can update global"
|
||||
ON public.document_templates
|
||||
FOR UPDATE
|
||||
USING (is_global = true AND public.is_saas_admin())
|
||||
WITH CHECK (is_global = true AND public.is_saas_admin());
|
||||
|
||||
CREATE POLICY "dt: saas admin can delete global"
|
||||
ON public.document_templates
|
||||
FOR DELETE
|
||||
USING (is_global = true AND public.is_saas_admin());
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 5. Comentarios — document_templates
|
||||
-- --------------------------------------------------------------------------
|
||||
COMMENT ON TABLE public.document_templates IS 'Templates de documentos para geracao automatica (declaracao, atestado, recibo etc.).';
|
||||
COMMENT ON COLUMN public.document_templates.nome_template IS 'Nome do template. Ex: Declaracao de Comparecimento.';
|
||||
COMMENT ON COLUMN public.document_templates.tipo IS 'declaracao_comparecimento|atestado_psicologico|relatorio_acompanhamento|recibo_pagamento|termo_consentimento|encaminhamento|outro.';
|
||||
COMMENT ON COLUMN public.document_templates.corpo_html IS 'Corpo do template em HTML com variaveis {{nome_variavel}}.';
|
||||
COMMENT ON COLUMN public.document_templates.cabecalho_html IS 'HTML do cabecalho (logo, nome da clinica etc.).';
|
||||
COMMENT ON COLUMN public.document_templates.rodape_html IS 'HTML do rodape (CRP, endereco, contato etc.).';
|
||||
COMMENT ON COLUMN public.document_templates.variaveis IS 'Array com nomes das variaveis usadas no template. Ex: {paciente_nome, data_sessao}.';
|
||||
COMMENT ON COLUMN public.document_templates.is_global IS 'true = template padrao do sistema visivel para todos. false = template do tenant.';
|
||||
COMMENT ON COLUMN public.document_templates.logo_url IS 'URL do logo personalizado para o cabecalho do documento.';
|
||||
|
||||
|
||||
-- ==========================================================================
|
||||
-- 6. Tabela: document_generated (cada PDF gerado)
|
||||
-- ==========================================================================
|
||||
CREATE TABLE IF NOT EXISTS public.document_generated (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
|
||||
-- Origem
|
||||
template_id uuid NOT NULL REFERENCES public.document_templates(id) ON DELETE RESTRICT,
|
||||
patient_id uuid NOT NULL REFERENCES public.patients(id) ON DELETE CASCADE,
|
||||
tenant_id uuid NOT NULL,
|
||||
|
||||
-- Dados usados no preenchimento (snapshot — permite auditoria futura)
|
||||
dados_preenchidos jsonb NOT NULL DEFAULT '{}',
|
||||
|
||||
-- PDF gerado
|
||||
pdf_path text NOT NULL,
|
||||
storage_bucket text NOT NULL DEFAULT 'generated-docs',
|
||||
|
||||
-- Vinculo opcional com documento pai (se o PDF gerado tambem for registrado em documents)
|
||||
documento_id uuid REFERENCES public.documents(id) ON DELETE SET NULL,
|
||||
|
||||
-- Quem gerou
|
||||
gerado_por uuid NOT NULL,
|
||||
gerado_em timestamptz DEFAULT now() NOT NULL,
|
||||
|
||||
CONSTRAINT document_generated_pkey PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 7. Indices — document_generated
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE INDEX IF NOT EXISTS dg_template_idx
|
||||
ON public.document_generated USING btree (template_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS dg_patient_idx
|
||||
ON public.document_generated USING btree (patient_id, gerado_em DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS dg_tenant_idx
|
||||
ON public.document_generated USING btree (tenant_id, gerado_em DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS dg_gerado_por_idx
|
||||
ON public.document_generated USING btree (gerado_por, gerado_em DESC);
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 8. RLS — document_generated
|
||||
-- --------------------------------------------------------------------------
|
||||
ALTER TABLE public.document_generated ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY "dg: generator full access"
|
||||
ON public.document_generated
|
||||
USING (gerado_por = auth.uid())
|
||||
WITH CHECK (gerado_por = auth.uid());
|
||||
|
||||
-- Membros do tenant podem visualizar
|
||||
CREATE POLICY "dg: tenant members can select"
|
||||
ON public.document_generated
|
||||
FOR SELECT
|
||||
USING (tenant_id IN (
|
||||
SELECT tm.tenant_id FROM public.tenant_members tm
|
||||
WHERE tm.user_id = auth.uid() AND tm.status = 'active'
|
||||
));
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 9. Comentarios — document_generated
|
||||
-- --------------------------------------------------------------------------
|
||||
COMMENT ON TABLE public.document_generated IS 'Registro de cada documento PDF gerado a partir de um template.';
|
||||
COMMENT ON COLUMN public.document_generated.template_id IS 'Template usado para gerar o documento.';
|
||||
COMMENT ON COLUMN public.document_generated.dados_preenchidos IS 'Snapshot JSON dos dados usados no preenchimento. Permite auditoria futura.';
|
||||
COMMENT ON COLUMN public.document_generated.pdf_path IS 'Caminho do PDF gerado no Supabase Storage bucket.';
|
||||
COMMENT ON COLUMN public.document_generated.documento_id IS 'FK opcional para documents — se o PDF gerado tambem foi registrado como documento do paciente.';
|
||||
COMMENT ON COLUMN public.document_generated.gerado_por IS 'Usuario que gerou o documento (auth.uid()).';
|
||||
|
||||
|
||||
-- ==========================================================================
|
||||
-- FIM DA MIGRACAO 006
|
||||
-- ==========================================================================
|
||||
Reference in New Issue
Block a user