Files
agenciapsilmno/database-novo
Leonardo 881fa16c27 Fluxo de reativação de canal WhatsApp + alerta toast sticky + notify owner
Cadeia de fixes descoberta ao testar o heartbeat 6.1 num tenant que migrou
de Evolution → Twilio e precisava voltar pro Evolution.

1. RLS notification_channels (migration 20260423000003)
   - Policy antiga tinha `deleted_at IS NULL` como primeira condição AND,
     bloqueando leitura de soft-deleted até pro próprio owner/saas_admin.
   - Isso fazia o chooser nunca detectar "canal antigo pra reativar".
   - Relaxada: owner/membro/saas_admin leem inclusive soft-deleted.
   - Filtro de deleted_at fica no código aplicativo (todos os queries já
     filtram explicitamente quando querem apenas ativos).

2. Edge function reactivate-notification-channel (nova)
   - Espelho da deactivate existente; service_role bypass RLS.
   - Aceita {channel_id} OU {tenant_id + provider}.
   - Autoriza saas_admin OU membro ativo do tenant.
   - Garante exclusividade: soft-deleta qualquer OUTRO canal ativo do
     mesmo tenant+channel.
   - Reseta metadata.first_unhealthy_at + connection_status=disconnected
     (heartbeat começa do zero).

3. SaasWhatsappPage (/saas/whatsapp)
   - loadChannel busca soft-deleted como fallback quando não tem ativo.
   - saveCredentials detecta soft-deleted e chama reactivate edge,
     depois atualiza credentials+display_name.
   - Banner âmbar "Canal configurado anteriormente" + botão vira
     "Reativar e salvar".

4. ConfiguracoesWhatsappPage tenant (/configuracoes/whatsapp-pessoal)
   - loadCredentials busca soft-deleted como fallback.
   - Card âmbar "WhatsApp Pessoal foi usado anteriormente" com botão
     "Reativar WhatsApp Pessoal" em vez de mostrar apenas "chame o suporte".

5. ChooserPage (/configuracoes/whatsapp)
   - Fix bug lateral: comparava activeProvider === 'evolution' (template)
     com 'evolution_api' (DB) — card nunca mostrava estado ativo. Agora
     normaliza via computed activeProviderKey.
   - softDeletedByProvider map carregado no mount; cards que têm row
     soft-deleted mostram "Reativar" em vez de "Ativar".
   - handleChoose chama reactivate edge antes de goSetup se detecta
     soft-deleted do provider escolhido.

6. whatsapp-heartbeat-check: notifica owner do channel + admins
   - notifyChannelStakeholders substitui notifyTenantAdmins.
   - Set dedupa o owner_id do channel + clinic_admin + tenant_admin.
   - Em tenant solo: 1 notificação; em clínica com canal de terapeuta
     específico: terapeuta (owner) + admin recebem; em clínica com canal
     do próprio admin: 1 (owner=admin).

7. Toast frontend para system_alert
   - notificationStore.subscribeRealtime aceita callback onInsert.
   - useNotifications registra callback que dispara toast PrimeVue
     (severity error, life 24h, closable) para type='system_alert'.
   - Usuário precisa fechar manualmente — alerta crítico de infra
     não pode sumir sozinho.

Cron heartbeat ativado em runtime local via cron.schedule()
(não vai neste commit — é config de ambiente, não migration).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 09:21:29 -03:00
..

database-novo

Banco de dados do AgenciaPsi — organizado, documentado e com CLI para gerenciamento.

Quick Start

cd database-novo

# Instalação do zero (schema + fixes + seeds + backup)
node db.cjs setup

# Ver estado do banco
node db.cjs status

# Backup
node db.cjs backup

# Restaurar (perdi o banco!)
node db.cjs restore

Para o guia completo, veja docs/setup_guide.md.

Comandos do CLI

Comando O que faz
node db.cjs setup Instala do zero (schema + fixes + seeds)
node db.cjs backup Exporta backup com data para backups/
node db.cjs restore [data] Restaura de um backup
node db.cjs migrate Aplica migrations pendentes
node db.cjs seed [grupo] Roda seeds (all, users, system, test_data)
node db.cjs status Estado do banco, backups, migrations
node db.cjs diff Compara schema atual vs último backup
node db.cjs reset Reseta e reinstala tudo
node db.cjs verify Verifica integridade dos dados

Estrutura

database-novo/
│
├── db.cjs                              # CLI de gerenciamento do banco
├── db.config.json                      # Configuração (container, seeds, fixes)
│
├── schema/                             # Schema SQL separado por seção
│   ├── 00_full/schema.sql              # Schema completo (referência)
│   ├── 01_extensions/                  # Schemas + extensões PostgreSQL
│   ├── 02_types/                       # Enums (auth, public, infra)
│   ├── 03_functions/                   # 11 arquivos por domínio
│   ├── 04_tables/                      # 10 arquivos por domínio
│   ├── 05_views/                       # 24 views
│   ├── 06_indexes/                     # Índices
│   ├── 07_foreign_keys/               # PKs, FKs, constraints
│   ├── 08_triggers/                    # Triggers
│   ├── 09_policies/                    # 217 RLS policies
│   └── 10_grants/                      # Grants
│
├── seeds/                              # Seeds de dados
│   ├── seed_001_fixed.sql              # 6 usuários base + tenants
│   ├── seed_002.sql                    # Supervisor + Editor
│   ├── seed_003.sql                    # Therapist2, Therapist3, Secretary
│   ├── seed_010_plans.sql              # 7 planos + 4 preços
│   ├── seed_011_features.sql           # 26 features
│   ├── seed_012_plan_features.sql      # 85 vínculos plano↔feature
│   ├── seed_013_subscriptions.sql      # 9 subscriptions + compromissos
│   ├── seed_014_global_data.sql        # 11 email + 16 notif templates + 3 slides
│   ├── seed_020_test_data.sql          # Dados de teste (50 pacientes, eventos, etc.)
│   ├── seed_020_test_data_cleanup.sql  # Limpeza dos dados de teste
│   └── run_all_seeds.sh               # Script bash alternativo
│
├── migrations/                         # Migrations incrementais
│
├── fixes/                              # 7 correções aplicadas
│
├── backups/                            # Backups com data (auto-gerenciados)
│   └── 2026-03-23/                     # schema.sql + data.sql + full_dump.sql
│
└── docs/                               # Documentação
    ├── setup_guide.md                  # Guia completo de instalação e uso
    ├── schema_map.md                   # Mapa das 84 tabelas
    ├── business_rules.md               # Regras de negócio
    └── users_test.md                   # 11 usuários de teste (UUIDs + vínculos)

Planos

Key Target Preço Limites
patient_free patient R$0
therapist_free therapist R$0 40 agendamentos/mês, 50 lembretes/mês
therapist_pro therapist R$49/mês · R$490/ano Ilimitado
clinic_free clinic R$0 30 pacientes, 5 terapeutas, 40 agend/mês
clinic_pro clinic R$149/mês · R$1490/ano Ilimitado
supervisor_free supervisor R$0 Até 3 supervisionados
supervisor_pro supervisor R$0 Até 20 supervisionados

Usuários de Teste

Senha de todos: Teste@123

Email Plano Tipo
paciente@agenciapsi.com.br patient_free Paciente
terapeuta@agenciapsi.com.br therapist_free Terapeuta solo + Clínica 3
clinica1@agenciapsi.com.br clinic_free Clínica coworking
clinica2@agenciapsi.com.br clinic_free Clínica recepção
clinica3@agenciapsi.com.br clinic_free Clínica full
saas@agenciapsi.com.br Admin plataforma
supervisor@agenciapsi.com.br supervisor_free Supervisor
editor@agenciapsi.com.br therapist_free Editor
therapist2@agenciapsi.com.br therapist_free Terapeuta
therapist3@agenciapsi.com.br therapist_free Terapeuta
secretary@agenciapsi.com.br Secretária (Clínica 2)

Idempotência

Todos os seeds são idempotentes (ON CONFLICT DO UPDATE ou DELETE + INSERT). Podem ser re-executados quantas vezes necessário.