# 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.**
