261 lines
11 KiB
SQL
261 lines
11 KiB
SQL
-- ==========================================================================
|
|
-- 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
|
|
-- ==========================================================================
|