177 lines
5.9 KiB
Markdown
177 lines
5.9 KiB
Markdown
# 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.**
|