Files
agenciapsilmno/database-novo/migrations/20260328000001_create_medicos.sql

148 lines
6.7 KiB
PL/PgSQL

-- ==========================================================================
-- Agência PSI — Migração: tabela `medicos`
-- ==========================================================================
-- Criado por: Leonardo Nohama
-- Data: 2026 · São Carlos/SP — Brasil
--
-- Propósito:
-- Armazena médicos e profissionais de referência (psiquiatras, neurologistas,
-- clínicos gerais, etc.) que encaminham pacientes ou fazem parte da rede de
-- suporte clínico do terapeuta.
--
-- Usado em:
-- - PatientsCadastroPage: campo "Encaminhado por" (FK medico_id)
-- - CadastroRapidoMedico.vue: cadastro rápido dentro do formulário
-- - MedicosCadastroPage.vue: página completa de gestão de médicos
--
-- Relacionamentos:
-- medicos.owner_id → auth.users(id)
-- medicos.tenant_id → tenants(id)
-- patients.medico_encaminhador_id → medicos(id) (opcional, ver abaixo)
--
-- RLS: owner_id = auth.uid() — cada profissional vê apenas seus médicos.
-- ==========================================================================
-- --------------------------------------------------------------------------
-- 1. Tabela principal
-- --------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS public.medicos (
id uuid DEFAULT gen_random_uuid() NOT NULL,
-- Contexto de acesso
owner_id uuid NOT NULL,
tenant_id uuid NOT NULL,
-- Identidade profissional
nome text NOT NULL,
crm text, -- Ex: "123456/SP"
especialidade text, -- Ex: "Psiquiatria"
-- Contatos — telefone_pessoal é sensível (exibido com ícone de olho)
telefone_profissional text, -- Consultório / clínica
telefone_pessoal text, -- WhatsApp / pessoal
email text,
-- Local de atuação
clinica text, -- Nome da clínica/hospital
cidade text,
estado text DEFAULT 'SP',
-- Notas internas do terapeuta
observacoes text,
-- Controle
ativo boolean DEFAULT true NOT NULL,
created_at timestamptz DEFAULT now(),
updated_at timestamptz DEFAULT now(),
CONSTRAINT medicos_pkey PRIMARY KEY (id),
-- CRM único por owner (mesmo terapeuta não cadastra o mesmo CRM duas vezes)
CONSTRAINT medicos_crm_owner_unique UNIQUE NULLS NOT DISTINCT (owner_id, crm)
);
-- --------------------------------------------------------------------------
-- 2. Índices de performance
-- --------------------------------------------------------------------------
CREATE INDEX IF NOT EXISTS medicos_owner_idx
ON public.medicos USING btree (owner_id);
CREATE INDEX IF NOT EXISTS medicos_tenant_idx
ON public.medicos USING btree (tenant_id);
CREATE INDEX IF NOT EXISTS medicos_nome_idx
ON public.medicos USING btree (nome);
CREATE INDEX IF NOT EXISTS medicos_especialidade_idx
ON public.medicos USING btree (especialidade);
-- Busca textual por nome e especialidade
CREATE INDEX IF NOT EXISTS medicos_nome_trgm_idx
ON public.medicos USING gin (nome gin_trgm_ops);
-- --------------------------------------------------------------------------
-- 3. Trigger de updated_at
-- --------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION public.set_medicos_updated_at()
RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$;
CREATE TRIGGER trg_medicos_updated_at
BEFORE UPDATE ON public.medicos
FOR EACH ROW
EXECUTE FUNCTION public.set_medicos_updated_at();
-- --------------------------------------------------------------------------
-- 4. Row Level Security
-- --------------------------------------------------------------------------
ALTER TABLE public.medicos ENABLE ROW LEVEL SECURITY;
-- Owner tem acesso total aos seus próprios médicos
CREATE POLICY "medicos: owner full access"
ON public.medicos
USING (owner_id = auth.uid())
WITH CHECK (owner_id = auth.uid());
-- --------------------------------------------------------------------------
-- 5. Comentários de documentação
-- --------------------------------------------------------------------------
COMMENT ON TABLE public.medicos IS 'Médicos e profissionais de referência cadastrados pelo terapeuta.';
COMMENT ON COLUMN public.medicos.owner_id IS 'Terapeuta dono do cadastro (auth.uid()).';
COMMENT ON COLUMN public.medicos.tenant_id IS 'Tenant do terapeuta.';
COMMENT ON COLUMN public.medicos.nome IS 'Nome completo do médico/profissional.';
COMMENT ON COLUMN public.medicos.crm IS 'CRM com UF. Ex: 123456/SP. Único por owner_id.';
COMMENT ON COLUMN public.medicos.especialidade IS 'Especialidade médica. Ex: Psiquiatria, Neurologia.';
COMMENT ON COLUMN public.medicos.telefone_profissional IS 'Telefone do consultório ou clínica.';
COMMENT ON COLUMN public.medicos.telefone_pessoal IS 'Telefone pessoal / WhatsApp. Campo sensível.';
COMMENT ON COLUMN public.medicos.email IS 'E-mail profissional.';
COMMENT ON COLUMN public.medicos.clinica IS 'Nome da clínica ou hospital onde atua.';
COMMENT ON COLUMN public.medicos.cidade IS 'Cidade de atuação.';
COMMENT ON COLUMN public.medicos.estado IS 'UF de atuação. Default SP.';
COMMENT ON COLUMN public.medicos.observacoes IS 'Notas internas do terapeuta sobre o médico.';
COMMENT ON COLUMN public.medicos.ativo IS 'Soft delete: false oculta da listagem.';
-- --------------------------------------------------------------------------
-- 6. Coluna FK opcional em patients
-- (Conecta "Encaminhado por" ao cadastro de médico)
-- Execute apenas se quiser a FK estruturada; caso contrário,
-- o campo encaminhado_por (text) no PatientsCadastroPage já funciona.
-- --------------------------------------------------------------------------
-- ALTER TABLE public.patients
-- ADD COLUMN IF NOT EXISTS medico_encaminhador_id uuid
-- REFERENCES public.medicos(id) ON DELETE SET NULL;
-- CREATE INDEX IF NOT EXISTS patients_medico_encaminhador_idx
-- ON public.patients USING btree (medico_encaminhador_id);
-- COMMENT ON COLUMN public.patients.medico_encaminhador_id
-- IS 'FK para medicos.id — quem encaminhou o paciente.';
-- ==========================================================================
-- FIM DA MIGRAÇÃO
-- ==========================================================================