# CHANGELOG — Banco de Dados AgênciaPsi

Registro histórico de todas as migrations aplicadas no banco.
Formato: data | arquivo | o que mudou | por quê

---

## [001] — 2026-03-03
**Arquivo:** `migration_001.sql`
**Seed:** `seed_001.sql`

### Contexto
O schema original foi construído de forma incremental e acumulou
inconsistências no modelo de identidade. Usuários não tinham um
tipo de conta definido formalmente, tenants não distinguiam
terapeuta de clínica, e não existia suporte a paciente como
tipo de conta de plataforma.

### O que mudou

#### `profiles`
- ✅ Adicionada coluna `account_type text NOT NULL DEFAULT 'free'`
  - Valores: `free | patient | therapist | clinic`
  - Imutável após sair de `free` (trigger `trg_account_type_immutable`)
  - Usuários com role=`patient` migrados para `account_type='patient'`
  - Usuários com tenant `saas` ativo migrados para `account_type='therapist'`

#### `tenants`
- ✅ Novos valores aceitos em `kind`:
  - `therapist` → terapeuta individual (substitui `saas`)
  - `clinic_coworking` → clínica tipo 1: gestão de salas
  - `clinic_reception` → clínica tipo 2: secretaria + múltiplas agendas
  - `clinic_full` → clínica tipo 3: coworking + secretaria
- ✅ `kind` agora é imutável após criação (trigger `trg_tenant_kind_immutable`)
- ✅ 10 tenants `saas` órfãos (sem admin, sem subscriptions) deletados
- ✅ Tenants `saas` com admin ativo migrados para `kind='therapist'`
- ⚠️ `saas` e `clinic` (legados) mantidos no CHECK por compatibilidade.
  Não criar novos tenants com esses kinds.

#### `plans`
- ✅ Adicionado `patient` como valor válido em `target`
- ✅ Inserido plano `patient_free` (gratuito, target=patient)

#### Novas funções
| Função | Descrição |
|--------|-----------|
| `provision_account_tenant(user_id, kind, name?)` | Cria tenant + membership + atualiza account_type. Chamar no onboarding. |
| `is_therapist_tenant(tenant_id)` | Retorna true se tenant é do tipo therapist |
| `is_clinic_tenant(tenant_id)` | Atualizada: inclui todos os subtipos de clínica |
| `guard_tenant_kind_immutable()` | Trigger: bloqueia alteração de tenants.kind |
| `guard_account_type_immutable()` | Trigger: bloqueia alteração de account_type após escolha |
| `guard_patient_cannot_own_tenant()` | Trigger: bloqueia paciente de ser tenant_admin/therapist |

#### Funções atualizadas
| Função | O que mudou |
|--------|-------------|
| `handle_new_user()` | Agora insere `account_type='free'` |
| `handle_new_user_create_personal_tenant()` | Desabilitada — tenant criado no onboarding |
| `ensure_personal_tenant()` | Busca por `kind IN ('therapist','saas')` e delega para `provision_account_tenant` |

### Regras de negócio agora garantidas no banco
1. **Paciente é para sempre paciente** — `account_type` imutável após escolha
2. **Terapeuta nunca vira clínica e vice-versa** — `tenants.kind` imutável
3. **Paciente não pode ter tenant** — trigger bloqueia na inserção
4. **Cada tipo de conta tem seu tipo de tenant** — `provision_account_tenant` garante

### Usuários de seed (apenas dev/staging)
| Email | Tipo | Tenant |
|-------|------|--------|
| paciente@agenciapsi.com.br | patient | nenhum |
| terapeuta@agenciapsi.com.br | therapist | tenant próprio (therapist) + vinculado à Clínica 3 |
| clinica1@agenciapsi.com.br | clinic | clinic_coworking |
| clinica2@agenciapsi.com.br | clinic | clinic_reception |
| clinica3@agenciapsi.com.br | clinic | clinic_full |
| saas@agenciapsi.com.br | saas_admin | nenhum |
> Senha de todos: `Teste@123`

---

## [002] — seed_002.sql

**Arquivo:** `Novo-DB/seed_002.sql`

### O que cria

#### Migration embutida
- ✅ `profiles.platform_roles text[] NOT NULL DEFAULT '{}'` — adicionada via `ADD COLUMN IF NOT EXISTS` (idempotente)

#### Usuários de teste
| Email | Senha | Papel | Tenant |
|-------|-------|-------|--------|
| `supervisor@agenciapsi.com.br` | `Teste@123` | `supervisor` em `tenant_members` | Clínica Bem Estar (Full) |
| `editor@agenciapsi.com.br` | `Teste@123` | `therapist` em `tenant_members` + `platform_roles = '{editor}'` | Clínica Bem Estar (Full) |

UUIDs reservados:
- Supervisor: `aaaaaaaa-0007-0007-0007-000000000007`
- Editor: `aaaaaaaa-0008-0008-0008-000000000008`

---

## [PENDENTE] — Migration necessária: `platform_roles` em `profiles`

**Contexto:**
Implementação das áreas de **Supervisor** (papel de tenant) e **Editor** (papel de plataforma).
O papel de Editor é atribuído pelo `saas_admin` e armazenado diretamente no perfil do usuário,
independente de qual tenant ele pertence.

### O que precisa ser aplicado no banco

#### `profiles`
- ⚠️ **Adicionar coluna** `platform_roles text[] NOT NULL DEFAULT '{}'`
  - Armazena papéis globais de plataforma. Ex.: `'{editor}'`
  - Quem pode escrever: somente `saas_admin` (via RLS ou função privilegiada)
  - Quem pode ter: qualquer usuário autenticado, **exceto** `account_type = 'patient'`
  - Valores previstos: `editor` (mais podem ser adicionados futuramente)

#### SQL sugerido
```sql
ALTER TABLE public.profiles
  ADD COLUMN IF NOT EXISTS platform_roles text[] NOT NULL DEFAULT '{}';

-- Comentário descritivo
COMMENT ON COLUMN public.profiles.platform_roles IS
  'Papéis globais de plataforma, independentes de tenant. Ex: editor de microlearning. Atribuído pelo saas_admin.';

-- RLS: somente saas_admin pode atualizar platform_roles (exemplo)
-- CREATE POLICY "saas_admin pode atualizar platform_roles"
--   ON public.profiles FOR UPDATE
--   USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'saas_admin'))
--   WITH CHECK (true);
```

#### `tenant_members` (sem alteração necessária)
- O papel `supervisor` já é suportado como valor text em `tenant_members.role`.
- Nenhuma alteração de schema é necessária — basta inserir memberships com `role = 'supervisor'`.

### Impacto se não aplicado
- Área do Editor (`/editor`) fica inacessível a todos (coluna ausente → `platform_roles` vem `null` → acesso negado).
- Área do Supervisor (`/supervisor`) funciona normalmente — não depende desta migration.

---

## Futuro — registrado mas não implementado

### Vínculo Terapeuta ↔ Clínica (a implementar)
- Terapeuta autoriza explicitamente que secretaria gerencie suas sessões
- Permissão só válida se clínica tiver `kind IN ('clinic_reception', 'clinic_full')`
- Secretaria acessa apenas sessões — não prontuário nem anotações
- Dissociação bloqueada se houver `agenda_eventos` futuros (`inicio_em > now()`)
- Após dissociação: cada parte fica com seus próprios pacientes
- Requer: coluna de permissão no vínculo + função de dissociação com validação

---

*Última atualização: 2026-03-03*
