# Regras de Negócio — Banco de Dados AgenciaPsi ## 1. Planos e Targets | Target | Planos | Escopo da Subscription | |--------|--------|----------------------| | `patient` | patient_free | `user_id` (sem tenant_id) | | `therapist` | therapist_free, therapist_pro | `user_id` (sem tenant_id) | | `clinic` | clinic_free, clinic_pro | `tenant_id` (sem user_id) | | `supervisor` | supervisor_free, supervisor_pro | `user_id` (sem tenant_id) | **Constraint `subscriptions_owner_xor`**: Uma subscription DEVE ter `tenant_id` XOR `user_id`, nunca ambos. **Trigger `subscriptions_validate_scope`**: Valida que o target do plano casa com o escopo: - `clinic` → exige `tenant_id`, rejeita `user_id` - `therapist`, `supervisor`, `patient` → exige `user_id`, rejeita `tenant_id` ## 2. Planos Core (protegidos) Os planos `clinic_free`, `clinic_pro`, `therapist_free`, `therapist_pro` são **core**: - **Não podem ter `key` alterada** (trigger `trg_no_change_core_plan_key`) - **Não podem ter `target` alterado** (trigger `trg_no_change_plan_target`) - **Não podem ser deletados** (trigger `trg_no_delete_core_plans`) Para bypass (migração): `SET LOCAL app.plan_migration_bypass = '1'` ## 3. Entitlements (Features) ### Resolução de features para TENANTS (clínicas) ``` tenant_has_feature(tenant_id, feature_key) = EXISTS em v_tenant_entitlements (via plano) OR EXISTS em tenant_features (override direto) ``` ### Resolução de features para USERS (terapeutas, supervisores) ``` user_has_feature(user_id, feature_key) = EXISTS em v_user_entitlements (via plano pessoal) ``` ### Cadeia de resolução ``` subscription → plan → plan_features → features ↓ plan_features.limits (jsonb) → limites quantitativos ``` ### Views de entitlements - `v_tenant_active_subscription` → subscription ativa do tenant - `v_user_active_subscription` → subscription ativa do user - `v_tenant_entitlements` → feature_key + allowed - `v_tenant_entitlements_full` → + limits + plan_id + plan_key - `v_user_entitlements` → feature_key + allowed (para planos pessoais) ## 4. Tipos de Tenant | kind | Descrição | Criação | |------|-----------|---------| | `therapist` | Terapeuta solo | Automático ao criar conta de terapeuta | | `clinic_coworking` | Clínica coworking | Manual | | `clinic_reception` | Clínica com recepção | Manual | | `clinic_full` | Clínica completa | Manual | | `supervisor` | Supervisor | Automático | | `saas` | Sistema (legado) | — | | `clinic` | Legado | — | **O `kind` é imutável após criação** (trigger `trg_tenant_kind_immutable`). ## 5. Roles e Permissões ### Profile roles | Role | Descrição | |------|-----------| | `saas_admin` | Administrador da plataforma | | `tenant_member` | Membro de um ou mais tenants | | `portal_user` | Paciente (acesso ao portal) | | `patient` | Paciente (legado) | ### Tenant member roles | Role | Descrição | |------|-----------| | `tenant_admin` | Admin do tenant (dono) | | `therapist` | Terapeuta membro | | `clinic_admin` | Admin da clínica (secretária com poderes) | | `secretary` | Secretária | | `supervisor` | Supervisor | | `patient` | Paciente do tenant | ### Platform roles (array em profiles) | Role | Descrição | |------|-----------| | `editor` | Editor de conteúdo da plataforma | ## 6. Compromissos Determinados A função `seed_determined_commitments(tenant_id)` cria 5 tipos nativos: | native_key | Nome | locked | active | |------------|------|--------|--------| | `session` | Sessão | true | true | | `reading` | Leitura | false | true | | `supervision` | Supervisão | false | true | | `class` | Aula | false | **false** | | `analysis` | Análise Pessoal | false | true | - `session` é **locked** (não pode ser editado/deletado) - O `native_key = 'session'` é usado pelo agendador online para identificar o compromisso padrão ## 7. Grupos de Pacientes Padrão A função `seed_default_patient_groups(tenant_id)` cria 3 grupos sistema: | Nome | Cor | is_system | |------|-----|-----------| | Crianças | #60a5fa | true | | Adolescentes | #a78bfa | true | | Idosos | #34d399 | true | Grupos sistema não podem ser editados/deletados (trigger `prevent_system_group_changes`). ## 8. Subscriptions — Status | Status | Descrição | |--------|-----------| | `pending` | Aguardando ativação | | `active` | Ativa | | `past_due` | Pagamento atrasado | | `suspended` | Suspensa | | `cancelled` | Cancelada | | `expired` | Expirada | ## 9. Templates de Email **Globais** (`email_templates_global`): templates padrão da plataforma, gerenciados pelo saas_admin. **Tenant** (`email_templates_tenant`): overrides por tenant. Se existir, usa o do tenant; se não, usa o global. ### Keys de template | Domínio | Templates | |---------|-----------| | session | reminder, confirmation, cancellation, rescheduled | | intake | received, approved, rejected | | scheduler | request_accepted, request_rejected | | system | welcome, password_reset | Canais: `email`, `whatsapp`, `sms` ## 10. Notificações — Sistema | Canal | Tipos | |-------|-------| | WhatsApp | lembrete_sessao, confirmacao_sessao, cancelamento_sessao | | SMS | lembrete_sessao | ### Schedule keys | Key | Descrição | |-----|-----------| | `lembrete_24h` | 24 horas antes | | `lembrete_2h` | 2 horas antes | | `lembrete_30min` | 30 minutos antes | | `confirmacao_imediata` | Imediato após confirmar | | `cancelamento_imediato` | Imediato após cancelar | ## 11. RLS (Row Level Security) Todas as tabelas do schema `public` têm RLS habilitado. As policies usam: - `auth.uid()` — ID do usuário autenticado - `is_saas_admin()` — verifica se é admin da plataforma - `is_tenant_member(tenant_id)` — verifica se pertence ao tenant - `is_tenant_admin(tenant_id)` — verifica se é admin do tenant - `current_member_role(tenant_id)` — role do membro no tenant - `tenant_has_feature(tenant_id, feature_key)` — verifica feature **Se as features/plan_features não existirem no banco, as policies de RLS bloqueiam o acesso.**