cd67f7e9f5
ROADMAP Fase 1.2 (Compliance basico BR). Item #5: profiles ganha 3 colunas (professional_registration_type/number/uf) com CHECK constraint dos conselhos comuns (CRP, CRM, CRFa, CREFITO, CRESS, CRN, RMS, outro). Item #9: catalogo public.specialties + join M:N profile_specialties + RLS. Seed seed_050 popula 33 especialidades is_system=true (clinica, jurídica, neuropsicologia, ABA, TCC, psicanalise etc). Service specialtiesService.js no src/services pra consumo na UI. Item #8 (nome social) ja estava integrado. #6 (consent forms UI) e #7 (assinatura no portal) adiados — schemas document_templates e document_signatures existem, falta workflow UI dedicado. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
80 lines
3.5 KiB
PL/PgSQL
80 lines
3.5 KiB
PL/PgSQL
-- ============================================================================
|
|
-- Compliance CFP — Especialidades do profissional (ROADMAP item #9)
|
|
-- ----------------------------------------------------------------------------
|
|
-- Catálogo de especialidades/abordagens + join many-to-many com profiles.
|
|
-- Profissional pode ter múltiplas especialidades (clínica + jurídica, etc).
|
|
-- ============================================================================
|
|
|
|
BEGIN;
|
|
|
|
CREATE TABLE IF NOT EXISTS public.specialties (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
key text UNIQUE NOT NULL,
|
|
name text NOT NULL,
|
|
category text,
|
|
is_system boolean DEFAULT false NOT NULL,
|
|
active boolean DEFAULT true NOT NULL,
|
|
created_at timestamptz DEFAULT now() NOT NULL
|
|
);
|
|
|
|
COMMENT ON TABLE public.specialties IS
|
|
'Catálogo global de especialidades/abordagens psicológicas (ROADMAP item #9). is_system=true pra entries seedadas.';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_specialties_active ON public.specialties (active, category, name);
|
|
|
|
CREATE TABLE IF NOT EXISTS public.profile_specialties (
|
|
profile_id uuid NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
|
|
specialty_id uuid NOT NULL REFERENCES public.specialties(id) ON DELETE RESTRICT,
|
|
other_label text,
|
|
created_at timestamptz DEFAULT now() NOT NULL,
|
|
PRIMARY KEY (profile_id, specialty_id)
|
|
);
|
|
|
|
COMMENT ON TABLE public.profile_specialties IS
|
|
'M:N entre profile e specialty. other_label preenchido só quando specialty.key=outra (custom user-defined).';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_profile_specialties_profile ON public.profile_specialties (profile_id);
|
|
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
-- RLS
|
|
-- ──────────────────────────────────────────────────────────────────────────
|
|
|
|
ALTER TABLE public.specialties ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.profile_specialties ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- specialties: read-only pra todos authenticated (catálogo público); só saas_admin escreve
|
|
CREATE POLICY specialties_authenticated_read
|
|
ON public.specialties FOR SELECT TO authenticated
|
|
USING (active = true);
|
|
|
|
CREATE POLICY specialties_saas_admin_write
|
|
ON public.specialties TO authenticated
|
|
USING (public.is_saas_admin())
|
|
WITH CHECK (public.is_saas_admin());
|
|
|
|
-- profile_specialties: cada user gerencia o próprio
|
|
CREATE POLICY profile_specialties_owner_select
|
|
ON public.profile_specialties FOR SELECT TO authenticated
|
|
USING (profile_id = auth.uid());
|
|
|
|
CREATE POLICY profile_specialties_owner_insert
|
|
ON public.profile_specialties FOR INSERT TO authenticated
|
|
WITH CHECK (profile_id = auth.uid());
|
|
|
|
CREATE POLICY profile_specialties_owner_delete
|
|
ON public.profile_specialties FOR DELETE TO authenticated
|
|
USING (profile_id = auth.uid());
|
|
|
|
-- Tenant_admin pode VER specialties dos membros (pra cards públicos / perfil clínica)
|
|
CREATE POLICY profile_specialties_tenant_admin_read
|
|
ON public.profile_specialties FOR SELECT TO authenticated
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM public.tenant_members tm
|
|
WHERE tm.user_id = profile_specialties.profile_id
|
|
AND public.is_tenant_admin(tm.tenant_id)
|
|
)
|
|
);
|
|
|
|
COMMIT;
|