Sessoes 1-6 acumuladas: hardening B2, defesa em camadas, +192 testes

Repositorio estava ha ~5 sessoes sem commit. Consolida tudo desde d088a89.

Ver commit.md na raiz para descricao completa por sessao.

# Numeros
- A# auditoria abertos: 0/30
- V# verificacoes abertos: 5/52 (todos adiados com plano)
- T# testes escritos: 10/10
- Vitest: 192/192
- SQL integration: 33/33
- E2E (Playwright, novo): 5/5
- Migrations: 17 (10 novas Sessao 6)
- Areas auditadas: 7 (+documentos com 10 V#)

# Highlights Sessao 6 (hoje)
- V#34/V#41 Opcao B2: tenant_features com plano + override (RPC SECURITY DEFINER, tela /saas/tenant-features)
- A#20 rev2 self-hosted: defesa em 5 camadas (honeypot + rate limit + math captcha condicional + paranoid mode + dashboard /saas/security)
- Documentos hardening (V#43-V#49): tenant scoping em storage policies (vazamento entre clinicas eliminado), RPC validate_share_token, signatures policy granular
- SaaS Twilio Config (/saas/twilio-config): UI editavel para SID/webhook/cotacao; AUTH_TOKEN permanece em env var
- T#9 + T#10: useAgendaEvents.spec.js + Playwright E2E (descobriu bug no front que foi corrigido)

# Sessoes anteriores (1-5) consolidadas
- Sessao 1: auth/router/session, normalizeRole extraido
- Sessao 2: agenda - composables/services consolidados
- Sessao 3: pacientes - tenant_id em todas queries
- Sessao 4: security review pagina publica - 14/15 vulnerabilidades corrigidas
- Sessao 5: SaaS - P0 (A#30: 7 tabelas com RLS off corrigidas)

# .gitignore ajustado
- supabase/* + !supabase/functions/ (mantem 10 edge functions, ignora .temp/migrations gerados pelo CLI)
- database-novo/backups/ (regeneravel via db.cjs backup)
- test-results/ + playwright-report/
- .claude/settings.local.json (config local com senha de dev removida do tracking)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leonardo
2026-04-19 15:42:46 -03:00
parent d088a89fb7
commit 7c20b518d4
175 changed files with 37325 additions and 37968 deletions
+223
View File
@@ -0,0 +1,223 @@
# AgenciaPsi — Estrutura Atual
> Snapshot do que já está construído no sistema hoje (2026-04-17).
> Inventário extraído dos menus de cada perfil de usuário.
**Legenda:** `[ok]` pronto · `[~]` parcial (estrutura existe, refinar) · `[--]` placeholder/vazio
---
```
AgenciaPsi (v5.0.0)
├── SaaS Admin (operação da plataforma)
│ │
│ ├── Início
│ │ └── Dashboard [ok] /saas
│ │
│ ├── Planos
│ │ ├── Planos e Preços [ok] /saas/plans
│ │ ├── Vitrine Pública [ok] /saas/plans-public
│ │ ├── Recursos (features) [ok] /saas/features
│ │ ├── Controle de Recursos [ok] /saas/plan-features
│ │ └── Limites por Plano [ok] /saas/plan-limits
│ │
│ ├── Assinaturas
│ │ ├── Listagem [ok] /saas/subscriptions
│ │ ├── Intenções [ok] /saas/subscription-intents
│ │ ├── Histórico (eventos) [ok] /saas/subscription-events
│ │ └── Saúde das Assinaturas [ok] /saas/subscription-health
│ │
│ ├── Operações
│ │ ├── Clínicas (Tenants) [ok] /saas/tenants
│ │ ├── Feriados [ok] /saas/feriados
│ │ └── Suporte Técnico [ok] /saas/support
│ │
│ ├── Canais de Comunicação
│ │ ├── WhatsApp (Evolution API) [ok] /saas/whatsapp
│ │ ├── WhatsApp Twilio (Subcontas) [ok] /saas/twilio-whatsapp
│ │ ├── Templates WhatsApp/SMS [ok] /saas/notification-templates
│ │ └── Add-ons / Créditos SMS [ok] /saas/addons
│ │
│ └── Conteúdo
│ ├── Documentação [ok] /saas/docs
│ ├── FAQ [ok] /saas/faq
│ ├── Carrossel de Login [ok] /saas/login-carousel
│ ├── Avisos Globais [ok] /saas/global-notices
│ ├── Templates de E-mail [ok] /saas/email-templates
│ └── Templates de Documentos [ok] /saas/document-templates
├── Clínica Admin (gestão da clínica)
│ │
│ ├── Início
│ │ ├── Dashboard da Clínica [ok] /admin
│ │ ├── Agenda da Clínica [ok] /admin/agenda/clinica
│ │ ├── Recorrências [ok] /admin/agenda/recorrencias
│ │ └── Compromissos [ok] /admin/agenda/compromissos
│ │
│ ├── Pacientes
│ │ ├── Lista de Pacientes [ok] /admin/pacientes
│ │ ├── Grupos [ok] /admin/pacientes/grupos
│ │ ├── Tags [ok] /admin/pacientes/tags
│ │ ├── Médicos & Referências [ok] /admin/pacientes/medicos
│ │ ├── Link Externo (cadastro) [ok] /admin/pacientes/link-externo
│ │ ├── Cadastros Recebidos [ok] /admin/pacientes/cadastro/recebidos
│ │ └── Templates de Documentos [ok] /admin/documents/templates
│ │
│ ├── Gestão
│ │ ├── Profissionais [ok] /admin/clinic/professionals
│ │ ├── Tipos de Clínicas (features ativas) [ok] /admin/clinic/features
│ │ └── Meu Plano [ok] /admin/meu-plano
│ │
│ ├── Financeiro
│ │ └── Cobranças [ok] /admin/financeiro
│ │
│ └── Sistema
│ ├── Meu Perfil [ok] /account/profile
│ ├── Meu Negócio [ok] /account/negocio
│ ├── Segurança [ok] /admin/settings/security
│ ├── Agendamento Online (PRO) [ok] /admin/online-scheduling
│ └── Agendamentos Recebidos [ok] /admin/agendamentos-recebidos
├── Terapeuta (dia-a-dia do profissional)
│ │
│ ├── Início
│ │ └── Dashboard [ok] /therapist
│ │
│ ├── Agenda
│ │ ├── Agenda [ok] /therapist/agenda
│ │ ├── Recorrências [ok] /therapist/agenda/recorrencias
│ │ └── Compromissos [ok] /therapist/agenda/compromissos
│ │
│ ├── Pacientes
│ │ ├── Meus Pacientes [ok] /therapist/patients
│ │ ├── Grupos de Pacientes [ok] /therapist/patients/grupos
│ │ ├── Tags [ok] /therapist/patients/tags
│ │ ├── Médicos & Referências [ok] /therapist/patients/medicos
│ │ ├── Documentos [ok] /therapist/documents
│ │ ├── Templates de Documentos [ok] /therapist/documents/templates
│ │ ├── Meu Link de Cadastro [ok] /therapist/patients/link-externo
│ │ └── Cadastros Recebidos [ok] /therapist/patients/cadastro/recebidos
│ │
│ ├── Agendamento Online
│ │ ├── Configurar Página Pública [ok] /therapist/online-scheduling
│ │ └── Agendamentos Recebidos [ok] /therapist/agendamentos-recebidos
│ │
│ ├── Financeiro
│ │ ├── Cobranças [ok] /therapist/financeiro
│ │ └── Lançamentos [ok] /therapist/financeiro/lancamentos
│ │
│ ├── Relatórios
│ │ └── Relatórios [~] /therapist/relatorios (export PDF/Excel a validar)
│ │
│ └── Conta
│ ├── Meu Plano [ok] /therapist/meu-plano
│ ├── Meu Perfil [ok] /account/profile
│ ├── Meu Negócio [ok] /account/negocio
│ └── Segurança [ok] /account/security
├── Supervisor (supervisão de casos)
│ │
│ ├── Início
│ │ └── Dashboard [ok] /supervisor
│ │
│ ├── Supervisão
│ │ └── Sala de Supervisão [~] /supervisor/sala (features avançadas a confirmar)
│ │
│ └── Conta
│ ├── Meu Plano [ok] /supervisor/meu-plano
│ ├── Meu Perfil [ok] /account/profile
│ └── Segurança [ok] /account/security
├── Portal do Paciente (portal web para o paciente)
│ │
│ ├── Início
│ │ └── Dashboard [ok] /portal
│ │
│ ├── Minhas Sessões
│ │ └── Sessões [ok] /portal/sessoes
│ │
│ └── Conta
│ ├── Meu Plano [ok] /portal/meu-plano
│ ├── Minha Conta [ok] /account/profile
│ └── Segurança [ok] /account/security
└── Editor de Conteúdo (criação de cursos — roadmap futuro)
├── Início
│ └── Dashboard [ok] /editor
├── Conteúdo
│ ├── Cursos [--] /editor/cursos (placeholder)
│ ├── Módulos [--] /editor/modulos (placeholder)
│ └── Publicados [--] /editor/publicados (placeholder)
└── Conta
├── Meu Plano [ok] /editor/meu-plano
├── Meu Perfil [ok] /account/profile
└── Segurança [ok] /account/security
```
---
## Stack / Infraestrutura (suporte)
```
Infraestrutura
├── Banco & Backend
│ ├── Supabase (Postgres + Auth + Storage + Realtime + Edge Functions) [ok]
│ ├── PostgreSQL 15 (container Docker local + cloud) [ok]
│ └── Docker Compose (supabase + evolution-api) [ok]
├── Comunicação
│ ├── Evolution API (WhatsApp) [ok]
│ ├── Twilio (SMS / Voz / WhatsApp Business) [ok]
│ ├── Mailpit (SMTP dev local) [ok]
│ └── SMTP produção (envio real de e-mails) [--] pendente
├── Geração de Documentos
│ ├── pdfmake + html2pdf + jsPDF [ok]
│ ├── Jodit (editor rico) [ok]
│ └── html2canvas-pro [ok]
├── Frontend
│ ├── Vue 3 + Composition API [ok]
│ ├── Vite 5 + Brotli/Gzip [ok]
│ ├── PrimeVue 4 (tema Sakai) [ok]
│ ├── Tailwind v4 [ok]
│ ├── Vue Router (guards por role/tenant) [ok]
│ ├── Pinia (state) [ok]
│ ├── FullCalendar 6 (agenda) [ok]
│ └── Chart.js 3 (dashboards) [ok]
└── Dev / Tooling
├── Supabase CLI [ok]
├── db.cjs (setup/backup/restore/migrate/verify) [ok]
├── generate-dashboard.cjs (mapa do banco) [ok]
├── Vitest 4 [~] base pronta, cobertura a expandir
└── ESLint + Prettier [ok]
```
---
## Resumo numérico
- **6 perfis** (roles)
- **27 grupos** de navegação
- **79 features** ativas no menu
- **73** `[ok]` prontas
- **2** `[~]` parciais
- **4** `[--]` placeholders
- **97 tabelas** no banco (11 domínios)
- **27 views**
- **165 funções SQL**
---
## Próximos passos (a definir nesta manhã)
- [ ] Mapear módulos que **deveriam existir** mas ainda não estão (comparando com Psicomanager / SimplePractice / iClinic)
- [ ] Organizar o roadmap em **fases** (MVP → v2 → v3)
- [ ] Identificar dependências entre módulos (ex: pagamento integrado antes de faturamento automático)
- [ ] Decidir cortes (o que fica pra pós-MVP)
Binary file not shown.
@@ -0,0 +1,741 @@
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mapa do Sistema · AgenciaPsi</title>
<link rel="stylesheet" href="https://unpkg.com/primeicons@7.0.0/primeicons.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&family=Space+Grotesk:wght@300;400;500;600;700&display=swap');
:root {
--bg: #0b0d12;
--bg2: #111520;
--bg3: #181e2d;
--bg4: #1e2740;
--border: #1e2740;
--border2: #2a3552;
--text: #e2e8f8;
--text2: #94a3b8;
--text3: #5a6782;
--accent: #6366f1;
--ok: #22c55e;
--warn: #eab308;
--pend: #f87171;
/* role colors */
--saas: #4f8cff;
--clinic: #38bdf8;
--therapist: #6366f1;
--supervisor: #a78bfa;
--portal: #ec4899;
--editor: #fb923c;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: var(--bg);
color: var(--text);
font-family: 'Space Grotesk', system-ui, sans-serif;
min-height: 100vh;
overflow-x: hidden;
}
/* ============ TOPBAR ============ */
.topbar {
position: sticky; top: 0; z-index: 50;
display: flex; align-items: center; gap: 20px;
padding: 0 28px; height: 60px;
background: rgba(11,13,18,.92);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border);
}
.brand { font-weight: 700; font-size: 16px; letter-spacing: -.3px; }
.brand span { color: var(--accent); }
.brand small { display: block; font-size: 10px; font-weight: 400; color: var(--text3); font-family: 'IBM Plex Mono', monospace; margin-top: -2px; }
.search {
flex: 1; max-width: 360px;
background: var(--bg3); border: 1px solid var(--border);
border-radius: 8px; padding: 7px 14px;
color: var(--text); font-size: 13px; outline: none;
transition: border-color .15s;
}
.search:focus { border-color: var(--accent); }
.search::placeholder { color: var(--text3); }
.legend { display: flex; align-items: center; gap: 14px; margin-left: auto; font-size: 12px; color: var(--text2); }
.legend .dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 5px; vertical-align: middle; }
.dot-done { background: var(--ok); }
.dot-partial { background: var(--warn); }
.dot-missing { background: var(--pend); }
.stats-pill { display: flex; gap: 10px; }
.stats-pill .p {
display: flex; align-items: center; gap: 6px;
font-size: 12px; color: var(--text2);
background: var(--bg3); border: 1px solid var(--border);
border-radius: 20px; padding: 4px 12px;
}
.stats-pill .p strong { color: var(--text); font-size: 13px; }
/* ============ HERO ============ */
.hero {
padding: 40px 28px 20px;
text-align: center;
background: radial-gradient(ellipse at center top, rgba(99,102,241,.12), transparent 60%);
border-bottom: 1px solid var(--border);
}
.hero h1 { font-size: 28px; font-weight: 700; letter-spacing: -.5px; margin-bottom: 8px; }
.hero h1 span { color: var(--accent); }
.hero p { font-size: 14px; color: var(--text2); max-width: 640px; margin: 0 auto; line-height: 1.55; }
.hub {
display: inline-block; margin: 24px auto 8px;
padding: 18px 32px;
background: linear-gradient(135deg, var(--accent), #8b5cf6);
border-radius: 14px;
box-shadow: 0 10px 40px rgba(99,102,241,.35), 0 0 0 4px rgba(99,102,241,.15);
font-size: 17px; font-weight: 700; letter-spacing: -.2px;
}
.hub .tag {
display: inline-block; margin-right: 10px;
font-size: 10px; text-transform: uppercase; letter-spacing: 1px;
background: rgba(255,255,255,.2); padding: 3px 8px; border-radius: 4px;
vertical-align: middle;
}
.hero-totals {
display: flex; justify-content: center; gap: 20px;
margin-top: 20px;
font-size: 13px; color: var(--text2);
}
.hero-totals b { color: var(--text); }
/* ============ GRID ============ */
.map {
padding: 30px 28px 60px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(440px, 1fr));
gap: 22px;
max-width: 1900px;
margin: 0 auto;
}
/* ============ ROLE CARD ============ */
.role {
background: var(--bg2);
border: 1px solid var(--border);
border-radius: 14px;
overflow: hidden;
transition: border-color .2s;
position: relative;
}
.role::before {
content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px;
background: var(--rc);
}
.role:hover { border-color: var(--border2); }
.role-head {
display: flex; align-items: center; gap: 14px;
padding: 18px 20px 14px;
cursor: pointer; user-select: none;
}
.role-icon {
width: 42px; height: 42px; border-radius: 10px;
display: grid; place-items: center;
background: color-mix(in srgb, var(--rc) 18%, transparent);
color: var(--rc);
font-size: 20px;
flex-shrink: 0;
}
.role-meta { flex: 1; min-width: 0; }
.role-name { font-size: 15px; font-weight: 700; letter-spacing: -.2px; }
.role-sub { font-size: 11px; color: var(--text3); font-family: 'IBM Plex Mono', monospace; margin-top: 2px; }
.role-counter {
display: flex; gap: 6px; font-size: 10px; font-weight: 600;
font-family: 'IBM Plex Mono', monospace;
}
.role-counter span {
padding: 3px 7px; border-radius: 10px;
background: var(--bg4); color: var(--text2);
}
.role-counter span.done { background: rgba(34,197,94,.15); color: var(--ok); }
.role-counter span.partial { background: rgba(234,179,8,.15); color: var(--warn); }
.role-counter span.missing { background: rgba(248,113,113,.15); color: var(--pend); }
.role-tg {
color: var(--text3); font-size: 11px;
transition: transform .2s;
margin-left: 6px;
}
.role-tg.open { transform: rotate(180deg); }
.role-body {
display: none;
padding: 0 20px 18px;
border-top: 1px solid var(--border);
}
.role-body.open { display: block; }
/* ============ GROUPS ============ */
.group {
margin-top: 16px;
position: relative;
padding-left: 18px;
border-left: 2px dashed color-mix(in srgb, var(--rc) 40%, transparent);
}
.group::before {
content: ''; position: absolute; left: -6px; top: 6px;
width: 10px; height: 10px; border-radius: 50%;
background: var(--rc);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--rc) 15%, var(--bg2));
}
.group-head {
display: flex; align-items: center; gap: 10px;
font-size: 12px; font-weight: 700; letter-spacing: 1px;
color: color-mix(in srgb, var(--rc) 70%, var(--text));
text-transform: uppercase;
margin-bottom: 8px;
}
.group-head i { font-size: 13px; }
.items {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 6px;
}
.item {
display: flex; align-items: center; gap: 9px;
padding: 8px 11px;
background: var(--bg3);
border: 1px solid var(--border);
border-radius: 7px;
font-size: 12px;
cursor: pointer;
transition: all .15s;
position: relative;
user-select: none;
}
.item:hover {
background: var(--bg4);
border-color: var(--border2);
transform: translateX(1px);
}
.item.hl {
background: color-mix(in srgb, var(--accent) 15%, var(--bg3));
border-color: var(--accent);
}
.item.dim { opacity: .25; }
.item i.pi { font-size: 12px; color: var(--text3); flex-shrink: 0; }
.item .lbl { flex: 1; min-width: 0; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.item .status-dot {
width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
/* ============ PANEL (detail) ============ */
.panel {
position: fixed; top: 60px; right: 0; bottom: 0;
width: 380px; max-width: 92vw;
background: var(--bg2);
border-left: 1px solid var(--border);
padding: 24px 22px;
transform: translateX(100%);
transition: transform .2s ease-out;
overflow-y: auto;
z-index: 40;
}
.panel.open { transform: translateX(0); }
.panel-close {
position: absolute; top: 14px; right: 16px;
background: none; border: none; cursor: pointer;
color: var(--text2); font-size: 18px;
width: 32px; height: 32px; border-radius: 6px;
transition: background .15s;
}
.panel-close:hover { background: var(--bg4); color: var(--text); }
.panel-role {
display: inline-block;
font-size: 10px; text-transform: uppercase; letter-spacing: 1px;
color: var(--rc); background: color-mix(in srgb, var(--rc) 15%, transparent);
padding: 3px 9px; border-radius: 4px;
margin-bottom: 12px;
}
.panel-title {
display: flex; align-items: center; gap: 12px;
font-size: 18px; font-weight: 700; letter-spacing: -.2px;
margin-bottom: 4px;
}
.panel-title i {
width: 36px; height: 36px; border-radius: 8px;
display: grid; place-items: center;
background: color-mix(in srgb, var(--rc) 18%, transparent);
color: var(--rc); font-size: 16px;
}
.panel-group {
font-size: 12px; color: var(--text2); margin-bottom: 20px;
font-family: 'IBM Plex Mono', monospace;
}
.panel-section { margin-top: 18px; }
.panel-label { font-size: 10px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--text3); margin-bottom: 6px; }
.panel-value { font-size: 13px; color: var(--text); line-height: 1.55; }
.panel-route {
font-family: 'IBM Plex Mono', monospace;
background: var(--bg3); border: 1px solid var(--border);
padding: 8px 11px; border-radius: 6px;
font-size: 12px; word-break: break-all;
}
.panel-status {
display: inline-flex; align-items: center; gap: 7px;
padding: 4px 10px; border-radius: 10px;
font-size: 11px; font-weight: 600; letter-spacing: .3px;
text-transform: uppercase;
}
.panel-status.done { background: rgba(34,197,94,.15); color: var(--ok); }
.panel-status.partial { background: rgba(234,179,8,.15); color: var(--warn); }
.panel-status.missing { background: rgba(248,113,113,.15); color: var(--pend); }
.panel-btn {
display: inline-flex; align-items: center; gap: 7px;
background: var(--accent); color: white;
padding: 9px 16px; border-radius: 7px;
font-size: 12px; font-weight: 600; text-decoration: none;
transition: opacity .15s;
margin-top: 8px;
}
.panel-btn:hover { opacity: .9; }
/* ============ SEARCH no results ============ */
.empty { text-align: center; padding: 40px; color: var(--text3); font-size: 13px; }
/* ============ RESPONSIVE ============ */
@media (max-width: 860px) {
.hero h1 { font-size: 22px; }
.hub { font-size: 14px; padding: 14px 22px; }
.legend { display: none; }
.stats-pill { display: none; }
.map { grid-template-columns: 1fr; padding: 20px 16px 40px; }
.panel { width: 100%; }
}
</style>
</head>
<body>
<header class="topbar">
<div class="brand">Mapa do Sistema<small>AgenciaPsi · v5.0.0</small></div>
<input type="search" class="search" id="search" placeholder="Buscar feature, rota ou grupo..." autocomplete="off">
<div class="stats-pill" id="stats"></div>
<div class="legend">
<span><i class="dot dot-done"></i>Pronto</span>
<span><i class="dot dot-partial"></i>Parcial</span>
<span><i class="dot dot-missing"></i>Faltando</span>
</div>
</header>
<section class="hero">
<h1>Mapa do <span>Sistema</span></h1>
<p>Tudo que o AgenciaPsi entrega hoje, agrupado por perfil de usuário. Clique em qualquer feature pra ver detalhes — rota, status e notas. Use a busca no topo pra filtrar.</p>
<div class="hub"><span class="tag">SaaS</span>AgenciaPsi</div>
<div class="hero-totals" id="heroTotals"></div>
</section>
<main class="map" id="map"></main>
<aside class="panel" id="panel">
<button class="panel-close" onclick="closePanel()" aria-label="Fechar"></button>
<div id="panelContent"></div>
</aside>
<script>
// ======================================================================
// DADOS - inventário extraído dos menus de cada role
// ======================================================================
const DATA = {
"roles": {
"saas": {
"label": "SaaS Admin",
"icon": "pi-shield",
"color": "#4f8cff",
"description": "Operação da plataforma — planos, assinaturas, clínicas, canais, conteúdo",
"groups": [
{ "label": "Início", "icon": "pi-chart-bar", "items": [
{ "label": "Dashboard", "icon": "pi-chart-bar", "route": "/saas", "status": "done" }
]},
{ "label": "Planos", "icon": "pi-list", "items": [
{ "label": "Planos e Preços", "icon": "pi-list", "route": "/saas/plans", "status": "done" },
{ "label": "Vitrine Pública", "icon": "pi-megaphone", "route": "/saas/plans-public", "status": "done" },
{ "label": "Recursos", "icon": "pi-bolt", "route": "/saas/features", "status": "done" },
{ "label": "Controle de Recursos", "icon": "pi-th-large", "route": "/saas/plan-features", "status": "done" },
{ "label": "Limites por Plano", "icon": "pi-sliders-h", "route": "/saas/plan-limits", "status": "done" }
]},
{ "label": "Assinaturas", "icon": "pi-credit-card", "items": [
{ "label": "Listagem", "icon": "pi-list", "route": "/saas/subscriptions", "status": "done" },
{ "label": "Intenções", "icon": "pi-inbox", "route": "/saas/subscription-intents", "status": "done" },
{ "label": "Histórico", "icon": "pi-history", "route": "/saas/subscription-events", "status": "done" },
{ "label": "Saúde das Assinaturas", "icon": "pi-shield", "route": "/saas/subscription-health", "status": "done" }
]},
{ "label": "Operações", "icon": "pi-users", "items": [
{ "label": "Clínicas (Tenants)", "icon": "pi-users", "route": "/saas/tenants", "status": "done" },
{ "label": "Feriados", "icon": "pi-star", "route": "/saas/feriados", "status": "done" },
{ "label": "Suporte Técnico", "icon": "pi-headphones", "route": "/saas/support", "status": "done" }
]},
{ "label": "Canais de Comunicação", "icon": "pi-whatsapp", "items": [
{ "label": "WhatsApp (Evolution)", "icon": "pi-whatsapp", "route": "/saas/whatsapp", "status": "done" },
{ "label": "WhatsApp Twilio", "icon": "pi-whatsapp", "route": "/saas/twilio-whatsapp", "status": "done" },
{ "label": "Templates WA/SMS", "icon": "pi-comment", "route": "/saas/notification-templates", "status": "done" },
{ "label": "Add-ons / Créditos", "icon": "pi-box", "route": "/saas/addons", "status": "done" }
]},
{ "label": "Conteúdo", "icon": "pi-book", "items": [
{ "label": "Documentação", "icon": "pi-question-circle", "route": "/saas/docs", "status": "done" },
{ "label": "FAQ", "icon": "pi-comments", "route": "/saas/faq", "status": "done" },
{ "label": "Carrossel Login", "icon": "pi-images", "route": "/saas/login-carousel", "status": "done" },
{ "label": "Avisos Globais", "icon": "pi-megaphone", "route": "/saas/global-notices", "status": "done" },
{ "label": "Templates E-mail", "icon": "pi-envelope", "route": "/saas/email-templates", "status": "done" },
{ "label": "Templates Documentos", "icon": "pi-file-edit", "route": "/saas/document-templates", "status": "done" }
]}
]
},
"clinic": {
"label": "Clínica Admin",
"icon": "pi-building",
"color": "#38bdf8",
"description": "Gestão da clínica — agenda, pacientes, profissionais, financeiro",
"groups": [
{ "label": "Início", "icon": "pi-home", "items": [
{ "label": "Dashboard", "icon": "pi-home", "route": "/admin", "status": "done" },
{ "label": "Agenda da Clínica", "icon": "pi-calendar", "route": "/admin/agenda/clinica", "status": "done" },
{ "label": "Recorrências", "icon": "pi-refresh", "route": "/admin/agenda/recorrencias", "status": "done" },
{ "label": "Compromissos", "icon": "pi-clock", "route": "/admin/agenda/compromissos", "status": "done" }
]},
{ "label": "Pacientes", "icon": "pi-users", "items": [
{ "label": "Lista de Pacientes", "icon": "pi-users", "route": "/admin/pacientes", "status": "done" },
{ "label": "Grupos", "icon": "pi-sitemap", "route": "/admin/pacientes/grupos", "status": "done" },
{ "label": "Tags", "icon": "pi-tags", "route": "/admin/pacientes/tags", "status": "done" },
{ "label": "Médicos & Referências", "icon": "pi-heart", "route": "/admin/pacientes/medicos", "status": "done" },
{ "label": "Link Externo", "icon": "pi-link", "route": "/admin/pacientes/link-externo", "status": "done" },
{ "label": "Cadastros recebidos", "icon": "pi-inbox", "route": "/admin/pacientes/cadastro/recebidos", "status": "done" },
{ "label": "Templates Documentos", "icon": "pi-file-edit", "route": "/admin/documents/templates", "status": "done" }
]},
{ "label": "Gestão", "icon": "pi-id-card", "items": [
{ "label": "Profissionais", "icon": "pi-id-card", "route": "/admin/clinic/professionals", "status": "done" },
{ "label": "Tipos de Clínicas", "icon": "pi-sliders-h", "route": "/admin/clinic/features", "status": "done" },
{ "label": "Meu plano", "icon": "pi-credit-card", "route": "/admin/meu-plano", "status": "done" }
]},
{ "label": "Financeiro", "icon": "pi-wallet", "items": [
{ "label": "Cobranças", "icon": "pi-wallet", "route": "/admin/financeiro", "status": "done" }
]},
{ "label": "Sistema", "icon": "pi-cog", "items": [
{ "label": "Meu Perfil", "icon": "pi-user", "route": "/account/profile", "status": "done" },
{ "label": "Meu Negócio", "icon": "pi-building", "route": "/account/negocio", "status": "done" },
{ "label": "Segurança", "icon": "pi-shield", "route": "/admin/settings/security", "status": "done" },
{ "label": "Agendamento Online (PRO)", "icon": "pi-calendar-plus", "route": "/admin/online-scheduling", "status": "done" },
{ "label": "Agendamentos Recebidos", "icon": "pi-inbox", "route": "/admin/agendamentos-recebidos", "status": "done" }
]}
]
},
"therapist": {
"label": "Terapeuta",
"icon": "pi-user",
"color": "#6366f1",
"description": "Dia-a-dia do profissional — agenda, prontuários, documentos, cobrança",
"groups": [
{ "label": "Início", "icon": "pi-home", "items": [
{ "label": "Dashboard", "icon": "pi-home", "route": "/therapist", "status": "done" }
]},
{ "label": "Agenda", "icon": "pi-calendar", "items": [
{ "label": "Agenda", "icon": "pi-calendar", "route": "/therapist/agenda", "status": "done" },
{ "label": "Recorrências", "icon": "pi-refresh", "route": "/therapist/agenda/recorrencias", "status": "done" },
{ "label": "Compromissos", "icon": "pi-clock", "route": "/therapist/agenda/compromissos", "status": "done" }
]},
{ "label": "Pacientes", "icon": "pi-list", "items": [
{ "label": "Meus pacientes", "icon": "pi-list", "route": "/therapist/patients", "status": "done" },
{ "label": "Grupos de pacientes", "icon": "pi-users", "route": "/therapist/patients/grupos", "status": "done" },
{ "label": "Tags", "icon": "pi-tags", "route": "/therapist/patients/tags", "status": "done" },
{ "label": "Médicos & Referências", "icon": "pi-heart", "route": "/therapist/patients/medicos", "status": "done" },
{ "label": "Documentos", "icon": "pi-file", "route": "/therapist/documents", "status": "done" },
{ "label": "Templates Documentos", "icon": "pi-file-edit", "route": "/therapist/documents/templates", "status": "done" },
{ "label": "Meu link de cadastro", "icon": "pi-link", "route": "/therapist/patients/link-externo", "status": "done" },
{ "label": "Cadastros recebidos", "icon": "pi-inbox", "route": "/therapist/patients/cadastro/recebidos", "status": "done" }
]},
{ "label": "Agendamento Online", "icon": "pi-globe", "items": [
{ "label": "Configurar página", "icon": "pi-globe", "route": "/therapist/online-scheduling", "status": "done" },
{ "label": "Agendamentos Recebidos", "icon": "pi-inbox", "route": "/therapist/agendamentos-recebidos", "status": "done" }
]},
{ "label": "Financeiro", "icon": "pi-wallet", "items": [
{ "label": "Cobranças", "icon": "pi-wallet", "route": "/therapist/financeiro", "status": "done" },
{ "label": "Lançamentos", "icon": "pi-list", "route": "/therapist/financeiro/lancamentos", "status": "done" }
]},
{ "label": "Relatórios", "icon": "pi-chart-bar", "items": [
{ "label": "Relatórios", "icon": "pi-chart-bar", "route": "/therapist/relatorios", "status": "partial", "notes": "Página existe, mas export PDF/Excel pode não estar 100% — validar." }
]},
{ "label": "Conta", "icon": "pi-user", "items": [
{ "label": "Meu plano", "icon": "pi-credit-card", "route": "/therapist/meu-plano", "status": "done" },
{ "label": "Meu Perfil", "icon": "pi-user", "route": "/account/profile", "status": "done" },
{ "label": "Meu Negócio", "icon": "pi-building", "route": "/account/negocio", "status": "done" },
{ "label": "Segurança", "icon": "pi-shield", "route": "/account/security", "status": "done" }
]}
]
},
"supervisor": {
"label": "Supervisor",
"icon": "pi-users",
"color": "#a78bfa",
"description": "Supervisão de casos e grupos",
"groups": [
{ "label": "Início", "icon": "pi-home", "items": [
{ "label": "Dashboard", "icon": "pi-home", "route": "/supervisor", "status": "done" }
]},
{ "label": "Supervisão", "icon": "pi-users", "items": [
{ "label": "Sala de Supervisão", "icon": "pi-users", "route": "/supervisor/sala", "status": "partial", "notes": "Estrutura base pronta — features avançadas (gravação, anotações colaborativas) a confirmar." }
]},
{ "label": "Conta", "icon": "pi-user", "items": [
{ "label": "Meu plano", "icon": "pi-credit-card", "route": "/supervisor/meu-plano", "status": "done" },
{ "label": "Meu Perfil", "icon": "pi-user", "route": "/account/profile", "status": "done" },
{ "label": "Segurança", "icon": "pi-shield", "route": "/account/security", "status": "done" }
]}
]
},
"portal": {
"label": "Portal do Paciente",
"icon": "pi-heart",
"color": "#ec4899",
"description": "Portal web pro paciente — ver sessões, histórico, dados",
"groups": [
{ "label": "Início", "icon": "pi-home", "items": [
{ "label": "Dashboard", "icon": "pi-home", "route": "/portal", "status": "done" }
]},
{ "label": "Minhas sessões", "icon": "pi-calendar", "items": [
{ "label": "Sessões", "icon": "pi-calendar", "route": "/portal/sessoes", "status": "done" }
]},
{ "label": "Conta", "icon": "pi-user", "items": [
{ "label": "Meu plano", "icon": "pi-credit-card", "route": "/portal/meu-plano", "status": "done" },
{ "label": "Minha Conta", "icon": "pi-user", "route": "/account/profile", "status": "done" },
{ "label": "Segurança", "icon": "pi-shield", "route": "/account/security", "status": "done" }
]}
]
},
"editor": {
"label": "Editor de Conteúdo",
"icon": "pi-book",
"color": "#fb923c",
"description": "Criação de cursos e conteúdo (roadmap futuro)",
"groups": [
{ "label": "Início", "icon": "pi-home", "items": [
{ "label": "Dashboard", "icon": "pi-home", "route": "/editor", "status": "done" }
]},
{ "label": "Conteúdo", "icon": "pi-book", "items": [
{ "label": "Cursos", "icon": "pi-book", "route": "/editor/cursos", "status": "partial", "notes": "Placeholder / estrutura inicial — biblioteca de cursos ainda não está plena." },
{ "label": "Módulos", "icon": "pi-th-large", "route": "/editor/modulos", "status": "partial", "notes": "Placeholder / estrutura inicial." },
{ "label": "Publicados", "icon": "pi-check-circle", "route": "/editor/publicados", "status": "partial", "notes": "Placeholder / estrutura inicial." }
]},
{ "label": "Conta", "icon": "pi-user", "items": [
{ "label": "Meu plano", "icon": "pi-credit-card", "route": "/editor/meu-plano", "status": "done" },
{ "label": "Meu Perfil", "icon": "pi-user", "route": "/account/profile", "status": "done" },
{ "label": "Segurança", "icon": "pi-shield", "route": "/account/security", "status": "done" }
]}
]
}
}
};
// ======================================================================
// RENDER
// ======================================================================
const STATUS_LABEL = { done: 'Pronto', partial: 'Parcial', missing: 'Faltando' };
let currentQuery = '';
function countItems(role) {
const total = role.groups.reduce((s, g) => s + g.items.length, 0);
const done = role.groups.reduce((s, g) => s + g.items.filter(i => i.status === 'done').length, 0);
const partial = role.groups.reduce((s, g) => s + g.items.filter(i => i.status === 'partial').length, 0);
const missing = role.groups.reduce((s, g) => s + g.items.filter(i => i.status === 'missing').length, 0);
return { total, done, partial, missing };
}
function matchesQuery(item, group, role) {
if (!currentQuery) return true;
const q = currentQuery.toLowerCase();
return (
item.label.toLowerCase().includes(q) ||
(item.route || '').toLowerCase().includes(q) ||
group.label.toLowerCase().includes(q) ||
role.label.toLowerCase().includes(q)
);
}
function renderMap() {
const map = document.getElementById('map');
let html = '';
let totalMatch = 0;
for (const [key, role] of Object.entries(DATA.roles)) {
const counts = countItems(role);
let visibleGroups = '';
let groupsWithMatches = 0;
for (const group of role.groups) {
const itemsHtml = group.items.map(item => {
const match = matchesQuery(item, group, role);
if (match) totalMatch++;
const dim = currentQuery && !match ? ' dim' : '';
const hl = currentQuery && match ? ' hl' : '';
const statusColor = { done: 'var(--ok)', partial: 'var(--warn)', missing: 'var(--pend)' }[item.status] || 'var(--text3)';
return `<div class="item${dim}${hl}" onclick="openPanel('${key}','${escapeAttr(group.label)}','${escapeAttr(item.label)}')">
<i class="pi ${item.icon}"></i>
<span class="lbl">${escapeHtml(item.label)}</span>
<span class="status-dot" style="background:${statusColor}"></span>
</div>`;
}).join('');
const groupMatched = group.items.some(i => matchesQuery(i, group, role)) || matchesQuery({label:'',route:''}, group, role);
if (groupMatched) groupsWithMatches++;
visibleGroups += `
<div class="group">
<div class="group-head"><i class="pi ${group.icon}"></i>${escapeHtml(group.label)}</div>
<div class="items">${itemsHtml}</div>
</div>`;
}
// Decide expansion default: expanded if no search (so user sees all), expanded if search matches any
const expanded = !currentQuery || groupsWithMatches > 0;
html += `
<section class="role" style="--rc:${role.color}">
<div class="role-head" onclick="toggleRole('${key}')">
<div class="role-icon"><i class="pi ${role.icon}"></i></div>
<div class="role-meta">
<div class="role-name">${escapeHtml(role.label)}</div>
<div class="role-sub">${escapeHtml(role.description)}</div>
</div>
<div class="role-counter">
<span class="done">${counts.done}</span>
${counts.partial ? `<span class="partial">${counts.partial}</span>` : ''}
${counts.missing ? `<span class="missing">${counts.missing}</span>` : ''}
</div>
<span class="role-tg ${expanded ? 'open' : ''}" id="tg-${key}">▼</span>
</div>
<div class="role-body ${expanded ? 'open' : ''}" id="body-${key}">
${visibleGroups}
</div>
</section>`;
}
map.innerHTML = html;
renderStats(totalMatch);
}
function renderStats(visibleCount) {
let totalItems = 0, totalDone = 0, totalPartial = 0, totalMissing = 0;
for (const role of Object.values(DATA.roles)) {
const c = countItems(role);
totalItems += c.total; totalDone += c.done; totalPartial += c.partial; totalMissing += c.missing;
}
const totalRoles = Object.keys(DATA.roles).length;
const totalGroups = Object.values(DATA.roles).reduce((s, r) => s + r.groups.length, 0);
document.getElementById('stats').innerHTML = `
<div class="p"><strong>${totalRoles}</strong> perfis</div>
<div class="p"><strong>${totalGroups}</strong> grupos</div>
<div class="p"><strong>${totalItems}</strong> features</div>`;
document.getElementById('heroTotals').innerHTML = `
<span><b>${totalRoles}</b> perfis</span>
<span>·</span>
<span><b>${totalGroups}</b> grupos</span>
<span>·</span>
<span><b>${totalItems}</b> features</span>
<span>·</span>
<span style="color:var(--ok)"><b>${totalDone}</b> prontas</span>
${totalPartial ? `<span>·</span><span style="color:var(--warn)"><b>${totalPartial}</b> parciais</span>` : ''}
${totalMissing ? `<span>·</span><span style="color:var(--pend)"><b>${totalMissing}</b> faltando</span>` : ''}`;
}
function escapeHtml(s) {
return String(s || '').replace(/[&<>"']/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m]));
}
function escapeAttr(s) {
return String(s || '').replace(/'/g, "\\'");
}
// ======================================================================
// INTERACTIONS
// ======================================================================
function toggleRole(key) {
const body = document.getElementById('body-' + key);
const tg = document.getElementById('tg-' + key);
body.classList.toggle('open');
tg.classList.toggle('open');
}
function openPanel(roleKey, groupLabel, itemLabel) {
const role = DATA.roles[roleKey];
const group = role.groups.find(g => g.label === groupLabel);
const item = group.items.find(i => i.label === itemLabel);
const statusLabel = STATUS_LABEL[item.status];
const panel = document.getElementById('panel');
const content = document.getElementById('panelContent');
content.innerHTML = `
<div class="panel-role" style="--rc:${role.color};color:${role.color};background:color-mix(in srgb, ${role.color} 15%, transparent)">${escapeHtml(role.label)}</div>
<div class="panel-title">
<i class="pi ${item.icon}" style="--rc:${role.color};background:color-mix(in srgb, ${role.color} 18%, transparent);color:${role.color}"></i>
<span>${escapeHtml(item.label)}</span>
</div>
<div class="panel-group">${escapeHtml(group.label)}</div>
<div class="panel-section">
<div class="panel-label">Status</div>
<div class="panel-status ${item.status}">
<span class="status-dot" style="width:8px;height:8px;border-radius:50%;background:currentColor"></span>
${statusLabel}
</div>
</div>
<div class="panel-section">
<div class="panel-label">Rota</div>
<div class="panel-route">${escapeHtml(item.route || '-')}</div>
</div>
${item.notes ? `
<div class="panel-section">
<div class="panel-label">Notas</div>
<div class="panel-value">${escapeHtml(item.notes)}</div>
</div>` : ''}
${item.route ? `<a class="panel-btn" href="http://localhost:5173${item.route}" target="_blank" rel="noopener">
<i class="pi pi-external-link"></i> Abrir no dev server
</a>` : ''}
`;
panel.classList.add('open');
}
function closePanel() {
document.getElementById('panel').classList.remove('open');
}
// ======================================================================
// SEARCH
// ======================================================================
let searchTimer;
document.getElementById('search').addEventListener('input', (e) => {
clearTimeout(searchTimer);
searchTimer = setTimeout(() => {
currentQuery = e.target.value.trim();
renderMap();
}, 150);
});
// Close panel on ESC
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') closePanel();
});
// ======================================================================
// INIT
// ======================================================================
renderMap();
</script>
</body>
</html>
+274
View File
@@ -0,0 +1,274 @@
# Auditoria Técnica — AgenciaPsi MVP
**Data:** 2026-03-11
**Stack:** Vue 3 · PrimeVue · Supabase · PostgreSQL · FullCalendar
**Modelo:** claude-sonnet-4-6
---
## 1. Visão Geral Arquitetural
**Pontos fortes:**
- Estrutura feature-based bem definida (`features/agenda`, `features/patients`)
- Separação correta: repository → composable → page
- Multi-tenancy é first-class: `tenant_id` em todos os queries críticos
- Sistema de guards robusto: RBAC + entitlements + tenantFeatures + session race-condition handling
- `useRecurrence` é bem arquitetado: virtual occurrences no frontend + exceções no banco (sem N linhas futuras)
---
## 2. Bugs Críticos
### ✅ [RESOLVIDO] `useRecurrence.js` — variável `occurrenceCount` não declarada
**Bug original:** branches `custom_weekdays`, `monthly` e `yearly` usavam `occurrenceCount` sem declará-la → `ReferenceError` em runtime. Nenhum dos três contava ocorrências anteriores ao range, então `max_occurrences` nunca funcionava corretamente.
**Correção (Sessão 2):** Cada branch ganhou `let occurrenceCount = 0` + fase de pré-contagem de `ruleStart` até `effStart`.
**Resolvido em:** Sessão 2 — 2026-03-11
---
### ✅ [RESOLVIDO] Exceção de remarcação fora do range não aparece
**Bug original:** `loadExceptions` só buscava `original_date` no range. Se `original_date` estivesse fora mas `new_date` caísse dentro, a sessão remarcada não aparecia.
**Correção (Sessão 3):**
- `loadExceptions`: duas queries paralelas — `q1` (original_date no range) + `q2` (reschedule com new_date no range). Mescladas e deduplicadas por `id`.
- `expandRules` post-pass: itera exceções não consumidas (`handledExIds`), injeta inbound reschedules com `buildOccurrence(rule, newDate, ex.original_date, ex)`.
**Resolvido em:** Sessão 3 — 2026-03-11
---
## 3. Segurança
### ✅ [RESOLVIDO] SQL dumps no repositório
**Arquivos:** `schema.sql`, `backup.sql`, `data_dump.sql`, `full_dump.sql`
Verificado via `git log --all --full-history` — arquivos **nunca foram commitados**. Movidos para pasta externa ao repositório. Nenhuma purga de histórico necessária.
**Resolvido em:** Sessão 3 — 2026-03-11
---
### ✅ [RESOLVIDO] `useAgendaEvents` — sem `tenant_id` em nenhuma operação
**Correção (Sessão 2):** `tenant_id` injetado em `create()`, `loadMyRange()`, `update()`, `remove()`, `removeSeriesFrom()`, `removeAllSeries()`. Helpers `assertTenantId()` e `getUid()` adicionados.
**Resolvido em:** Sessão 2 — 2026-03-11
---
### ✅ [RESOLVIDO] `loadRules` em `useRecurrence` sem filtro `tenant_id`
**Correção (Sessão 2):** `loadRules` e `loadAndExpand` aceitam `tenantId` opcional e aplicam `.eq('tenant_id', tenantId)`. Call site em `AgendaTerapeutaPage._reloadRange` passa `tenantStore.activeTenantId`.
**Resolvido em:** Sessão 2 — 2026-03-11
---
### ✅ [RESOLVIDO] `console.log` expõe dados de pacientes no browser
**Correção (Sessão 2):** Todos os `console.*` substituídos pelo `supportLogger`. Logs só aparecem quando modo suporte está ativo (token válido no banco).
**Resolvido em:** Sessão 2 — 2026-03-11
**Arquivos criados:** `src/support/supportLogger.js`, `src/support/supportDebugStore.js`
---
### 🟡 [ABERTO] `window.__guardsBound` / `window.__supabaseAuthListenerBound`
Usar `window.*` para controle de listeners é frágil em hot-reload.
**Solução:** Gerenciar via módulo singleton ou `app.config.globalProperties`.
---
### ✅ [RESOLVIDO] `globalRole` do `profiles` sem cache no guard
Adicionados `globalRoleCacheUid` + `globalRoleCache` no `guards.js`.
Cache invalida em: uid change, SIGNED_OUT, SIGNED_IN com user diferente.
Query ao banco ocorre apenas na primeira navegação por sessão.
**Resolvido em:** Sessão 4 — 2026-03-11
---
## 4. Duplicações e Inconsistências
### ✅ [RESOLVIDO] Dois composables para a mesma entidade
`src/composables/useAgendaEvents.js` era código morto (sem imports). Deletado.
O autoritativo `src/features/agenda/composables/useAgendaEvents.js` permanece.
**Resolvido em:** Sessão 3 — 2026-03-11
---
### ✅ [RESOLVIDO] Dois mappers para agenda
`src/features/agenda/domain/agenda.mappers.js` estava vazio e sem imports. Deletado.
`src/features/agenda/domain/agenda.types.js` também sem imports. Deletado. Diretório `domain/` removido.
O autoritativo `src/features/agenda/services/agendaMappers.js` permanece.
**Resolvido em:** Sessão 4 — 2026-03-11
---
### ✅ [RESOLVIDO] N+1 Query — migração `paciente_id` → `patient_id`
**Resolvido em:** Sessão 3 — 2026-03-11
**Migration executada:** `migrations/unify_patient_id.sql`
- UPDATE copiou `paciente_id``patient_id` onde null (resultado: 0 órfãos — todos já tinham `patient_id`)
- `ALTER TABLE agenda_eventos DROP COLUMN paciente_id` executado com sucesso
**Código atualizado:**
- `useAgendaEvents.js`: `paciente_id` removido do `BASE_SELECT`; `create()`/`update()` stripam `paciente_id` do payload
- `agendaRepository.js`: workaround N+1 de orphan ids removido
- `agendaMappers.js`: `paciente_id` agora é alias de `patient_id` (UI only)
- `AgendaTerapeutaPage.vue` + `AgendaClinicaPage.vue`: `pickDbFields` usa `patient_id`
- `AgendamentosRecebidosPage.vue`: `dbFields` removeu `paciente_id`
- `PatientsListPage.vue` + `AgendaEventDialog.vue`: `.or()``.eq('patient_id', id)`
---
## 5. Limpeza Necessária
### ✅ [RESOLVIDO] Template Sakai removido — bundle de produção
**Resolvido em:** Sessão 3 — 2026-03-11
**Removidos:** `src/views/uikit/` (15 arquivos), `src/views/utilities/Blocks.vue`, `src/components/BlockViewer.vue`, `src/components/FloatingConfigurator.vue`, `src/views/pages/Documentation.vue`, `src/assets/demo/`, `src/navigation/menus/sakai.demo.menu.js`, `src/router/routes.demo.js`, `src/assets/styles.scss` (@use demo removido)
**Referências limpas:** `package.json` renomeado para `agenciapsi`, demoRoutes e sakaiDemoMenu removidos dos index files, `FloatingConfigurator` removido de Login, NotFound, Access, Error, ResetPasswordPage.
---
### 🟡 [PARCIAL] Arquivos obsoletos no projeto
**Deletados (Sessão 4):**
- `src/layout/ConfiguracoesPage-old.vue`
- `src/features/agenda/domain/` (diretório inteiro — 2 arquivos não usados)
**Ainda presentes:**
- `src/layout/ConfiguracoesPage - Copia.vue` — verificar se está no git (staged como D)
- `src/views/pages/public/Landingpage-v1 - bkp.vue`
- `comandos.txt` (na raiz)
---
### ✅ [RESOLVIDO] Logs excessivos em produção
`console.time/timeLog/timeEnd/warn/error` em `guards.js` substituídos por `logGuard()`, `logError()`, `logPerf()`.
**Resolvido em:** Sessão 2 — 2026-03-11
---
## 6. Status das Features do MVP
| Feature | Status | Observação |
|---|---|---|
| Agenda de sessões | ✅ Implementado | FullCalendar + composables |
| Cadastro de pacientes | ✅ Implementado | CRUD completo |
| Recorrência de sessões | ✅ Corrigido | Bugs de occurrenceCount e cross-range resolvidos |
| Sessões presenciais/online | ✅ Implementado | campo `modalidade` |
| Controle de faltas | ✅ Implementado | `exception_type = 'patient_missed'` |
| Remarcação | ✅ Corrigido | Bug cross-range resolvido (Sessão 3) |
| Bloqueio de agenda | ✅ Implementado | `BloqueioDialog.vue` |
| Agendamento online | ✅ Implementado | `AgendadorPublicoPage.vue` |
| Prontuário | ✅ Integrado | Seção "Sessões" adicionada ao `PatientProntuario.vue` |
| Notificações/lembretes | ❌ Não implementado | Sem trigger/edge function |
| Financeiro/faturamento | ⚠️ Parcial | Páginas de plano mas sem sessão→pagamento |
| Relatórios | ✅ Implementado | `RelatoriosPage.vue` — terapeuta — sessões, faltas, taxa, gráfico |
---
## 7. Backlog Técnico
- [ ] Cache de `globalRole` no guard (reduzir queries por navegação)
- [ ] Implementar notificações: WhatsApp/Email via Supabase Edge Functions
- [ ] Integração prontuário ↔ sessões
- [ ] Integração sessão ↔ pagamento (financeiro)
- [ ] Relatórios básicos: sessões realizadas, faltas, receita
- [ ] Migrar domínio de recorrência para TypeScript
- [ ] Consolidar dois mappers de agenda (`agendaMappers.js` vs `domain/agenda.mappers.js`)
- [ ] Remover arquivos obsoletos (ConfiguracoesPage-old, Landingpage-v1 bkp, etc.)
---
## 8. Prioridades de Ação
### ✅ Fazer AGORA — todos concluídos
1. `[x]` ~~Remover dumps SQL~~ → nunca commitados, movidos para fora do repo
2. `[x]` ~~Corrigir bug `occurrenceCount`~~ → pré-contagem em todos os branches
3. `[x]` ~~Adicionar `tenant_id` ao `useAgendaEvents` e `loadRules`~~ → injetado em todas as operações
4. `[x]` ~~Remover `console.log` com dados de pacientes~~`supportLogger`
### ✅ Fazer em seguida — todos concluídos
5. `[x]` ~~Corrigir bug remarcação cross-range~~ → 2 queries + post-pass em `expandRules`
6. `[x]` ~~Consolidar dois `useAgendaEvents`~~ → legado deletado
7. `[x]` ~~Unificar `paciente_id` + `patient_id`~~ → migration executada + código limpo
8. `[x]` ~~Remover Sakai de demo~~ → removido + menu SaaS limpo
### Backlog
9. `[x]` Cache de `globalRole` no guard — `globalRoleCacheUid/globalRoleCache` em guards.js
10. `[ ]` Notificações (WhatsApp/Email via Edge Functions) ← próximo
11. `[x]` Integração prontuário ↔ sessões — seção "Sessões" em `PatientProntuario.vue`
12. `[x]` Relatórios básicos — `RelatoriosPage.vue` em /therapist/relatorios
13. `[x]` Consolidar mappers de agenda — `domain/` deletado, `agendaMappers.js` é único
---
## 9. Sistema de Suporte Técnico SaaS
Sistema seguro para admins SaaS acessarem a agenda de terapeutas em modo debug.
| Arquivo | Responsabilidade |
|---|---|
| `migrations/support_sessions.sql` | Tabela, índices, RLS, RPCs (token gerado via `gen_random_uuid()` duplo — sem pgcrypto) |
| `src/support/supportLogger.js` | Logger centralizado — silencioso fora do modo suporte |
| `src/support/supportDebugStore.js` | Store Pinia — valida token via RPC `validate_support_session` |
| `src/support/supportSessionService.js` | CRUD de sessões de suporte (criar/listar/revogar) |
| `src/support/components/SupportDebugBanner.vue` | Banner fixo na agenda com painel de logs filtráveis |
| `src/views/pages/saas/SaasSupportPage.vue` | Painel SaaS para gerenciar sessões de suporte |
**RPCs no banco:**
- `create_support_session(p_tenant_id, p_ttl_minutes)``{ token, expires_at, session_id }`
- `validate_support_session(p_token)``{ valid, tenant_id }`
- `revoke_support_session(p_token)``boolean`
---
## 10. Histórico de Sessões
### Sessão 1 — 2026-03-11
- Auditoria técnica completa gerada
- Nenhum item resolvido
### Sessão 2 — 2026-03-11
- Sistema de suporte técnico SaaS implementado (migration + 5 arquivos criados)
- Bug `occurrenceCount` corrigido (itens 2 e 4)
- `tenant_id` adicionado ao `useAgendaEvents` e `loadRules` (item 3)
- `console.*` substituídos por `supportLogger`
### Sessão 4 — 2026-03-11
- Cache `globalRole` adicionado ao guard (item 9) — sem query ao banco por navegação
- Integração prontuário ↔ sessões (item 11) — painel "Sessões" em `PatientProntuario.vue`
- `RelatoriosPage.vue` criada em `/therapist/relatorios` (item 12) — cards, gráfico Chart.js, tabela DataTable
- Consolidação mappers (item 13) — `domain/agenda.mappers.js` vazio deletado + `agenda.types.js` + dir `domain/`
- `ConfiguracoesPage-old.vue` deletado (limpeza)
### Sessão 3 — 2026-03-11
- Bug remarcação cross-range resolvido (item 5)
- `logPerf is not defined` em guards.js corrigido
- `pgcrypto` → substituído por `gen_random_uuid()` duplo no support_sessions
- Sakai demo removido completamente (item 8) + `styles.scss` corrigido
- `useAgendaEvents` legado deletado (item 6)
- `paciente_id` unificado em `patient_id` — migration executada (item 7)
- SQL dumps confirmados como nunca commitados (item 1 encerrado)
---
*Para retomar: devolva este arquivo ao início da conversa e indique qual item quer atacar.*
+740
View File
@@ -0,0 +1,740 @@
# Concorrentes — Análise Comparativa
> Benchmark de referência pro **AgenciaPsi**. Objetivo: mapear features dos principais players, confrontar com o que já temos e identificar gaps de roadmap.
## Como usar este documento
Cada produto tem sua seção com módulos organizados por domínio. Tags de fonte:
- `[observação 2026-04-17]` — observado direto pelo usuário navegando no produto
- `[fetched 2026-04-17]` — extraído via WebFetch das páginas oficiais
- `[público]` — inferido de conhecimento público (marketing/demos/reviews)
- `[?]` — ainda não verificado
## Legenda de status (vs AgenciaPsi)
- `[tem]` — AgenciaPsi já tem esta feature
- `[parcial]` — tem estrutura mas não está completo
- `[gap]` — AgenciaPsi **não** tem → candidato a roadmap
- `[?]` — a investigar (no concorrente ou no AgenciaPsi)
---
## 1. SimplePractice (EUA)
### Resumo executivo
- **País:** EUA · **Idioma:** inglês (+ Client Portal em espanhol) `[fetched 2026-04-17]`
- **Escala:** **20M+ clientes** e **250k+ practitioners** na plataforma `[fetched: /pricing/]`
- **Pricing:** USD ~2999/mês por profissional (Essential, Plus, e um terceiro tier) · **30-day** ou **7-day trial** `[fetched: /pricing/]`
- **Público-alvo:** terapeutas, psicólogos, counselors, psiquiatras — solo e pequenas clínicas (até ~10 profissionais) `[público]`
- **Diferencial:** maturidade em telehealth HIPAA, claims de seguro (insurance billing), consent forms assinados eletronicamente, biblioteca de instrumentos de avaliação `[público]`
- **Compliance:** HIPAA + HITRUST + PCI + BAA `[fetched: /features/]`
- **Posicionamento:** "o Salesforce da saúde mental" no mercado americano `[público]`
### Categorias top-level confirmadas `[fetched: /features/]`
- **Admin & Practice Management** — Reports Access, AutoPay Enrollment, Practitioner Profiles, Permissions Management
- **Client Care & Documentation** — Secure Messaging, Client Scoring/Assessment Tools, Prescription/Medication Renewal Requests
- **Client-Facing Services** — Client Portal, Telehealth
- **Compliance & Security** — HIPAA, HITRUST, PCI, BAA
- **Additional Services** — Credentialing Services (grátis, ofertado), Switching Assistance (ajuda na migração de outra plataforma)
### Navegação principal observada
`[observação 2026-04-17]`
Menus top-level vistos no app:
- **Clients** (Clientes)
- **Billing / Payments** (Pagamentos)
- **Insurance** (Convênios EUA)
- **Analytics**
- **Activities** (Atividades)
- **Supervision**
- **Settings**
- **Reminders**
- **Requests**
- **Marketing**
- **Recently Viewed** — atalho pros últimos clientes acessados
- **Busca global** no topbar por clientes
### Módulos
#### 1.1 Clientes (Clients)
- Cadastro completo do paciente — `[tem]`
- **Recently Viewed** (últimos clientes acessados) — `[gap]`
- **Busca global** no topbar — `[?]` investigar no AgenciaPsi
- Insurance info no perfil — `[parcial]` (temos convênios cadastrados, mas não ligados ao perfil do paciente desse jeito)
- Emergency contacts — `[?]`
- Tags / grupos — `[tem]`
- Merge de clientes duplicados — `[gap]`
#### 1.2 Settings → Clinical Info
`[observação 2026-04-17]`
> Estou vendo a tela de Clinical Info. Para os EUA, tem NPI Number, Taxonomy Code e Specialty. Nós já temos um cadastro de clínica completo para o Brasil. Acho que poderíamos colocar o campo **Especialidades** também, listar um monte e, se o usuário não encontrar, cadastrar o seu.
**Propostas derivadas:**
- Campo **Especialidades** da clínica/profissional com lista pré-definida + "outro" — `[gap]`
- Equivalente BR do NPI/Taxonomy seria: **número de registro** (CRP, CRM, etc) e **área de atuação** — talvez já exista em user_settings/profile, a confirmar — `[?]`
`[observação 2026-04-17]`
> Tem um campo **Licenses Type** onde o usuário seleciona se é Médico, PhD, etc. (Não sei se isso seria aqui.)
**Proposta derivada:** campo **Tipo de registro profissional** (CRP, CRM, CRFa, RMS, etc) no cadastro do terapeuta — útil pra aparecer em recibos/laudos — `[gap]`
#### 1.3 Settings → Practice Details
`[observação 2026-04-17]`
> Cadastra a localização da clínica e digamos filiais (no caso de gestão de clínicas). É possível definir qual é o **Main Office**.
**Proposta derivada:** **multi-unidade/filiais** com marcação de "unidade principal" — `[gap]`
- Ao criar consulta, escolher em qual unidade ocorre
- Faturamento pode ser consolidado ou por unidade
- Cada unidade tem endereço, telefone, papel timbrado próprio (opcional)
#### 1.4 Client Care → Template Library
`[observação 2026-04-17]`
> Variados tipos de arquivos prontos pra personalizar. Ex: **GAD-7** (Generalized Anxiety Disorder), **PHQ-9** (Patient Health Questionnaire), **COVID-19 Pre-Appointment Screening Questionnaire**.
**Proposta derivada (alto valor):** **Biblioteca de instrumentos de avaliação psicológica** com scoring automático — `[gap]`
- GAD-7 (ansiedade generalizada)
- PHQ-9 (depressão)
- BDI (Inventário Beck)
- BAI (Beck ansiedade)
- PCL-5 (PTSD)
- AUDIT (uso de álcool)
- DASS-21 (depressão/ansiedade/estresse)
- SRQ-20 (MS/BR)
- Escala de qualidade de vida (WHOQOL)
> **Diferencial possível pro BR:** curar uma biblioteca com instrumentos validados em português (muitos psicólogos ainda aplicam em papel).
#### 1.5 Client Care → Shareable Documents
`[observação 2026-04-17]`
> Manage default intake documents and upload files.
**Interpretação:** documentos que vão com o paciente durante onboarding/intake (antes da 1ª sessão).
- AgenciaPsi já tem módulo de Documentos — `[tem]`
- Mas "enviar pacote de intake" estruturado antes da 1ª sessão — `[parcial / ?]`
- Upload de arquivo pelo paciente (anexos, exames) — `[?]`
#### 1.6 Consent Forms
`[observação 2026-04-17]`
> Read and signed by clients via the client portal. Legal disclaimer: consent forms are for reference only. It's your responsibility to customize them and ensure they meet the legal requirements of your state.
>
> Formulários default observados:
> - Consent for Telehealth Consultation
> - Credit Card Authorization
> - Notice of Privacy Practices
> - Informed Consent for Psychotherapy
> - Practice Policies
> - Release Forms
> - Consent to Record Audio
> - (+ New Consent Form)
>
> O usuário consegue adicionar, editar um novo e visualizar.
**Proposta derivada:** **biblioteca de termos de consentimento** editáveis + assinatura eletrônica no portal — `[gap]`
Equivalentes BR a disponibilizar:
- **TCLE** — Termo de Consentimento Livre e Esclarecido (CFP exige)
- **Termo de Atendimento Online** — atendimento remoto (Resolução CFP 11/2018)
- **Política de Privacidade LGPD** — tratamento de dados sensíveis de saúde
- **Autorização de Cobrança** (cartão recorrente)
- **Termo de Gravação** (se for gravar sessão)
- **Termo de Sigilo** em caso de supervisão/atendimento em grupo
- **Autorização de uso de imagem** (se aplicável)
- **+ Novo termo personalizado** (botão)
#### 1.7 Papel Timbrado
`[observação 2026-04-17]`
> Precisa criar a parte de papel timbrado, assim como fizemos no outro projeto. Quando chegar a hora, pode me perguntar.
**Status:** `[gap]` — reaproveitar a implementação do outro projeto (UniaoApp). Quando chegar a hora, me pergunta pra eu buscar lá e portar.
#### 1.8 Outros módulos públicos do SimplePractice `[público]`
> Essas features são conhecidas publicamente (pricing pages / demos). A confirmar navegando.
##### Client Portal (Portal do Paciente) `[fetched: /features/client-portal/]`
Portal do cliente completo, HIPAA-compliant. Extraído da página oficial:
- **Self-scheduling** — cliente solicita / cancela / reagenda consultas — `[tem parcial]` (agendador público existe mas não é portal autenticado)
- **Paperless intake forms** — cliente preenche formulários antes da 1ª sessão — `[gap]`
- **Questionnaires** — instrumentos de medição/progresso (GAD-7, PHQ-9 etc) — `[gap]`
- **Secure messaging** — chat seguro terapeuta ↔ cliente — `[gap]`
- **Invoice payment** — paciente paga direto pelo portal — `[gap]`
- **Push notifications** — notif antes da consulta — `[gap]` (temos email/SMS/WhatsApp, push seria diferencial)
- **Appointment reminders** — lembretes programados — `[tem]`
- **Portal em espanhol** — multi-idioma — `[gap]` (pensar se vale traduzir pra ES pro LATAM)
- **Administrative controls** — clínica decide quais features o paciente enxerga — `[parcial]`
- **HIPAA-compliant** — `[parcial]` (LGPD equivalente no BR)
##### Telehealth `[fetched: /features/telehealth/]`
SP tem um **módulo de telehealth próprio**, totalmente integrado ao EHR. Confirmado na página oficial:
- **Vídeo nativo** — "launch sessions directly from your calendar — no extra login required" — `[gap]`
- **Sala de espera virtual** — "admit clients when you're ready" — `[gap]`
- **Screen sharing** embutido — `[gap]`
- **Chat seguro** durante a sessão — `[gap]`
- **Digital whiteboard** (quadro branco digital) — `[gap]` · bom pra sessões com crianças / TCC visual
- **Video em grupo** — até 15 clientes por sessão — `[gap]` · suporta terapia de grupo
- **Timer de sessão** embutido + **fundos desfocados (blurred backgrounds)**`[gap]`
- **Lembretes automáticos** SMS/email — `[tem parcial]` (temos lembretes; falta o link da sala)
- **HIPAA + HITRUST + PCI** compliance — `[tem parcial]` (temos LGPD compliance mas não certificação formal)
- **Integração nativa com o EHR** — notas da sessão + billing automáticos — `[gap]`
- **Apps iOS / Android** — `[gap]` (AgenciaPsi é só web)
##### Documentation / Notes de sessão
- Templates de notas pré-prontos (**SOAP**, **BIRP**, **DAP**) — `[?]`
- Progress notes com versionamento — `[parcial]` (temos Prontuário, validar versionamento)
- Co-assinatura de supervisor em notas de supervisionando — `[gap]`
##### Billing
- **Credit card on file** (cartão salvo) — `[gap]`
- **Auto-billing** / cobrança recorrente automática — `[parcial]` (temos recorrências de consulta, não de cobrança)
- **Superbill** (recibo detalhado com CID, CPT codes equivalente) — `[gap]`
- **AR reports** (contas a receber, aging) — `[?]`
##### Insurance (EUA) — equivalente BR: **Convênios**
- Eligibility check automático — `[gap]` (BR seria checagem TISS mas raramente integra)
- Claims submission eletrônico (837) — `[gap]`
- ERA (Electronic Remittance Advice) — `[gap]`
##### Reminders (Lembretes)
- Email / SMS / Voice — `[tem]` (temos Email + SMS + WhatsApp)
- Confirmação pelo paciente (responder "SIM") — `[?]`
- Configuração de quanto tempo antes — `[tem]`
- Templates customizáveis — `[tem]`
##### Marketing
- Perfil público / diretório — `[gap]` (similar a Doctoralia)
- Website/landing de divulgação — `[gap]`
- SEO básico — `[gap]`
##### Analytics / Relatórios
- Receita (MRR, por período, por profissional) — `[parcial]` (dashboard tem alguns KPIs, não sei se tudo)
- Sessões realizadas (por tipo, por profissional, por convênio) — `[?]`
- Clientes ativos / novos / churn — `[?]`
- Export PDF/Excel — `[parcial]`
##### Supervisão
- Compartilhar notas com supervisor — `[parcial]` (Sala de Supervisão existe, features a confirmar)
- Co-assinar antes de fechar nota — `[gap]`
##### Sync & Integrações
- **Google Calendar** 2-way sync — `[gap]` (já listado no assessment como pós-MVP)
- **Apple Calendar** — `[gap]`
- **Stripe** / gateway de pagamento — `[gap]` (crítico)
##### Tasks / To-do
- Lista de tarefas por cliente — `[?]`
- Task follow-ups (ex: "ligar em 30 dias") — `[gap]`
---
## 2. Psicomanager (Brasil)
### Resumo executivo `[público]`
- **País:** Brasil · **Pricing:** R$ ~50150/mês por profissional (varia por plano e módulos contratados) — **confirmar**
- **Público-alvo:** psicólogos solo e clínicas no BR
- **Diferencial:** nicho-específico em psicologia no BR, familiaridade com CFP/LGPD, integração com WhatsApp/PIX
- **Posicionamento:** o "padrão" do mercado brasileiro pra psicólogos
### Módulos conhecidos publicamente `[público / ?]`
> **Tentativa de WebFetch em 2026-04-17:** `psicomanager.com.br/`, `/planos/`, `/funcionalidades/`, `/blog/`, `/agenda-online/`, `/prontuario-eletronico/` — **todas retornaram SPA vazia ou 404**. O site do Psicomanager é single-page app renderizado via JS, o que torna scraping impossível sem browser headless.
>
> **Caminhos alternativos pra validar:**
> 1. Você abrir o site logado e me mandar screenshots/texto das principais telas
> 2. Criar um trial e navegar junto comigo
> 3. Buscar reviews detalhados em sites tipo **B2BStack**, **Reclame Aqui**, **SoftwareSuggest BR**
> 4. Buscar por posts do blog deles via Google (`site:psicomanager.com.br`)
>
> A lista abaixo é conhecimento de mercado. Priorizar validação antes de tomar decisões de roadmap baseadas nela.
- **Agenda** — online, presencial, bloqueios, recorrências
- **Prontuário Eletrônico** — anamnese, evolução, sessões
- **Cadastro de Pacientes** — multi-paciente, anamnese inicial
- **Financeiro** — cobranças, PIX, cartão (Asaas? Iugu? a confirmar)
- **Lembretes** — Email/SMS/WhatsApp
- **Recibo / NFSe** — emissão de nota fiscal de serviço
- **Teleconsulta** — integrada ao sistema (próprio ou externo? a confirmar)
- **Anamnese e Evolução** — templates customizáveis
- **Portal do Paciente** — visão do paciente das sessões/faturas
- **Documentos** — atestados, laudos, declarações
- **Relatórios** — produção, financeiro, agenda
- **LGPD** — compliance, consentimento de dados
- **Multi-profissional** — gestão de clínica com múltiplos psicólogos
- **Assinatura eletrônica** — documentos assinados pelo paciente `[?]`
- **App mobile** pro paciente/profissional `[?]`
### Observações durante exploração
> *Em branco — preencher navegando no Psicomanager.*
---
## 3. PsicoPlanner (Brasil) — concorrente direto `[fetched 2026-04-17]`
### Resumo executivo
- **País:** Brasil · **Nicho:** psicologia-first
- **Preços (publicados):**
- **Individual:** R$ 59/mês (1 acesso)
- **Plus:** R$ 79/mês (1 profissional + 1 recepcionista)
- **Duo:** R$ 99/mês (2 logins independentes)
- **Clínicas:** R$ 395/mês (até 5 profissionais)
- **Posicionamento:** "psicólogo que odeia planilha" — simples, WhatsApp-first, IA
### Features confirmadas
- **Lembretes WhatsApp** ilimitados e personalizáveis (confirmações, lembretes, avisos de pagamento)
- **Sala de vídeo integrada** (teleconsulta com confidencialidade dentro do app)
- **Prontuários e anamnese customizáveis** por profissional
- **Autoagendamento** via link compartilhável (paciente escolhe horário)
- **Agenda diária por WhatsApp às 7h** (push automático do cronograma do dia) — `[gap]` diferencial forte
- **Gestão financeira** visual (pagamentos, recebidos, pendentes)
- **PsiAssist AI** — gera relatórios, documentos, resumos e conteúdo com **compliance CFP**
- **Rastreamento de engajamento em tempo real** — ver se paciente recebeu, leu e respondeu
### Destaques comparativos
| Feature | PsicoPlanner | AgenciaPsi |
|---|---|---|
| WhatsApp nativo com dashboard engajamento | ✅ | `[parcial]` (enviamos, mas tracking?) |
| Agenda diária automática 7AM via WA | ✅ | `[gap]` |
| IA com compliance CFP | ✅ (PsiAssist) | `[gap]` |
| Preço entrada baixo | R$ 59 solo | (definir pricing) |
---
## 4. iClinic (Brasil) — multispecialidade popular `[fetched 2026-04-17]`
### Resumo executivo
- **País:** Brasil · **Nicho:** multispecialidade (psicólogos usam bastante apesar de não ser foco)
- **Posicionamento:** "o EHR completo pro consultório/clínica médica no BR"
### Módulos confirmados
#### Prontuário Eletrônico
- Histórico de valores em tabela/gráfico
- Campos personalizados por especialidade
- Anexo de arquivos centralizado
- **Assinatura Digital** com validade jurídica
- Consulta CID-10 integrada
- Compartilhamento de prontuário entre profissionais
- **Controle de vacinas** (rastreamento por idade) — menos relevante pra psico
- Tags de lembrete
- Comparação de imagens (evolução do tratamento)
#### Prescrição Eletrônica
- Base de medicamentos atualizada
- Modelos personalizados
- **Envio por WhatsApp** direto ao paciente
#### Emissão de Documentos
- Modelos com campos automáticos
- Preenchimento automático de dados do paciente
#### Ferramentas Clínicas
- Calculadoras: IMC, curva de crescimento, IG, DPP
- Integração com Glic (diabetes)
#### Outros módulos mencionados
- Agenda Médica · Teleconsulta · Agendamento Online · Marketing Médico (email campaigns) · Gestão Financeira · Recepcionista
### Destaques comparativos
| Feature | iClinic | AgenciaPsi |
|---|---|---|
| Assinatura digital com validade jurídica | ✅ | `[gap]` |
| CID-10 integrado | ✅ | `[?]` |
| Prescrição eletrônica com WhatsApp | ✅ | `[gap]` |
| Email campaigns (marketing) | ✅ | `[gap]` |
| Histórico em gráfico/tabela evolutiva | ✅ | `[?]` |
---
## 5. Amplimed (Brasil) — AI-first `[fetched 2026-04-17]`
### Resumo executivo
- **País:** Brasil · **Nicho:** multispecialidade com **forte aposta em IA**
- **Posicionamento:** "IA que trabalha pela sua clínica"
### Módulos confirmados
#### 🤖 Amélia (IA proprietária — 3 produtos)
- **Amélia Agendamento** — bot virtual que atende e responde pacientes via WhatsApp **24/7** com sincronização automática da agenda
- **Amélia Transcrição** — converte áudio em texto e preenche prontuário automaticamente
- **Amélia Copilot** — localiza, resume e organiza info do paciente + pesquisas médicas
#### Gestão
- Gestão Clínica com redução de até **38% de ausências** via agenda inteligente
- Prontuário Eletrônico estruturado + compartilhamento seguro
- Agenda de Procedimentos (cirurgias, exames) com controle de conflitos
#### Agendamento & Comunicação
- Agendamento Online 24/7 com integração a prontuário + pagamento
- SMS (redução de faltas)
- **WhatsApp Connect** — mensagens personalizadas + lembretes
#### Financeiro
- **Faturamento TISS** — "99% menos glosas" via padrão automático — `[gap]` (psico usa pouco TISS, mas é diferencial enorme pra clínica grande)
- **NFS-e** emissão simplificada integrada
- Dashboards de indicadores
#### Outros
- Teleconsulta com criptografia E2E + prescrição digital
- Estoque com alertas de validade
- **Painel de chamados** com TV na recepção
- **Certificado Digital ICP-Brasil** embutido
### Destaques comparativos (e FORTES alertas)
| Feature | Amplimed | AgenciaPsi |
|---|---|---|
| Bot WhatsApp 24/7 que agenda sozinho | ✅ Amélia | `[gap]` 🔥 |
| Transcrição de sessão via áudio | ✅ Amélia | `[gap]` 🔥 |
| Copilot de IA no prontuário | ✅ Amélia | `[gap]` 🔥 |
| NFS-e integrado | ✅ | `[gap]` |
| Faturamento TISS com validação automática | ✅ | `[gap]` |
| Certificado digital ICP-Brasil | ✅ | `[gap]` |
> **Nota:** AI-heavy é a principal tendência BR em 2026. Amplimed e Psicomanager (prov.) vão nessa direção. Pode ser **o diferencial** do AgenciaPsi se investir.
---
## 6. Ninsaúde (Brasil) — ERP clínico `[fetched 2026-04-17]`
### Resumo executivo
- **País:** Brasil · **Nicho:** ERP clínico completo (várias especialidades) — menos focado em psico
- **Posicionamento:** "ERP da clínica" — mais robusto, mais caro
### Módulos confirmados
- Prontuário Eletrônico
- Sistema de Atendimento (fluxo)
- Gerenciamento Financeiro
- **Faturamento de Convênios**
- Controle de Estoque
- Engajamento dos Pacientes (retenção)
- Engajamento da Equipe (motivação interna)
- Análise Inteligente (BI)
- Retenção de Pacientes
### Produtos satélites
- **Ninsaúde CRM** — gestão de relacionamento
- **Ninsaúde Safe** — segurança de dados
- **Ninsaúde Sign** — assinatura digital
- Integração QR Code
- **Nome Social** — respeita identidade de gênero no cadastro
### Destaques comparativos
| Feature | Ninsaúde | AgenciaPsi |
|---|---|---|
| CRM interno (leads, funil) | ✅ | `[gap]` |
| Nome social | ✅ | `[?]` (validar se temos) |
| Retenção automatizada (CRM) | ✅ | `[gap]` |
| BI avançado | ✅ | `[parcial]` |
---
## 7. Jane App (Canadá) — referência internacional de UX `[fetched 2026-04-17]`
### Resumo executivo
- **País:** Canadá · **Idioma:** inglês · **Mercados:** CA, US, UK
- **Posicionamento:** "o app mais amado pelos profissionais de saúde" — UX premium
### Módulos confirmados
#### Cliente & Agendamento
- **Online Booking** com branding customizável da clínica + 24/7
- **Staff & Appointment Scheduling** multi-location (sala, recurso, waitlist, pagamento — tudo na mesma visão)
#### Documentação
- **Charting & Documentation** — biblioteca de templates, SOAP notes, forms, surveys
- **AI Scribe** — grava ou dicta a sessão e gera nota em minutos (integrado)
#### Comunicação
- **Telehealth** HIPAA-compliant — até **12 clientes** por sessão (solo + grupo/family)
#### Financeiro
- **Jane Payments** — online + terminal físico, PCI-compliant
- Billing & Insurance multi-região (CA, US, UK)
- Invoicing de serviços, memberships e produtos
#### BI
- Real-time dashboards de saúde do negócio
- Relatórios customizáveis
#### Infra & Support
- Compliance: HIPAA + PIPEDA + GDPR + SOC-2 + 256-bit encryption
- Integrações com apps third-party
- **Website Builder com IA** — cria site da clínica auto-sincronizado com staff/branding
- Suporte ilimitado (phone/email/chat)
- **Migração de dados grátis**
### Destaques comparativos
| Feature | Jane App | AgenciaPsi |
|---|---|---|
| AI Scribe (grava e gera nota) | ✅ | `[gap]` 🔥 |
| Terminal físico de pagamento | ✅ | `[gap]` (POS integrado) |
| Multi-location + resources (sala/equipamento) | ✅ | `[parcial]` |
| Website builder integrado | ✅ | `[gap]` |
| Cert SOC-2 | ✅ | `[gap]` |
| Migração grátis de outra plataforma | ✅ | `[gap]` |
---
## 8. Comparação rápida (quadro)
> Linhas com `*` têm fonte `[fetched]` confirmada do SimplePractice. Demais são `[público]`/`[?]`.
| Domínio | AgenciaPsi | SimplePractice | Psicomanager |
|---|---|---|---|
| Cadastro de pacientes | `[tem]` | `[tem]` | `[tem]` |
| Grupos / Tags | `[tem]` | `[tem]` | `[?]` |
| **Busca global topbar** | `[?]` | `[tem]` | `[?]` |
| **Recently viewed** | `[gap]` | `[tem]` | `[?]` |
| **Merge de duplicatas** | `[gap]` | `[tem]` | `[?]` |
| Agenda | `[tem]` | `[tem]` | `[tem]` |
| Agendamento online público | `[tem]` | `[tem]` | `[?]` |
| Recorrências | `[tem]` | `[tem]` | `[?]` |
| **Teleconsulta integrada** | `[gap]` | `[tem]` * | `[?]` |
| **Sala de espera virtual** | `[gap]` | `[tem]` * | `[gap]` |
| **Screen sharing na sessão** | `[gap]` | `[tem]` * | `[?]` |
| **Digital whiteboard** | `[gap]` | `[tem]` * | `[?]` |
| **Video em grupo (até 15)** | `[gap]` | `[tem]` * | `[?]` |
| **Blurred background (vídeo)** | `[gap]` | `[tem]` * | `[?]` |
| Prontuário / Notas | `[tem]` | `[tem]` | `[tem]` |
| **Templates de nota (SOAP/BIRP/DAP)** | `[?]` | `[tem]` | `[?]` |
| **Versionamento de nota** | `[?]` | `[tem]` | `[?]` |
| **Biblioteca de avaliações (GAD-7/PHQ-9)** | `[gap]` | `[tem]` | `[?]` |
| **Consent forms assinados** | `[gap]` | `[tem]` | `[?]` |
| **Assinatura eletrônica paciente** | `[?]` | `[tem]` | `[?]` |
| **Papel timbrado** | `[gap]` | `[tem]` | `[tem]` |
| **Intake / pacote onboarding** | `[parcial]` | `[tem]` | `[?]` |
| **Upload de arquivo pelo paciente** | `[?]` | `[tem]` | `[?]` |
| Cobrança / financeiro | `[tem]` | `[tem]` | `[tem]` |
| **Gateway de pagamento (Stripe/PIX)** | `[gap]` | `[tem]` | `[tem]` |
| **Cartão on file** | `[gap]` | `[tem]` | `[?]` |
| **Auto-billing recorrente** | `[parcial]` | `[tem]` | `[?]` |
| **Superbill / recibo detalhado** | `[parcial]` | `[tem]` | `[?]` |
| **NFSe emissão** | `[?]` | N/A (EUA) | `[tem]` |
| Convênios / Insurance | `[parcial]` | `[tem]` | `[?]` |
| **Claims eletrônico (TISS/837)** | `[gap]` | `[tem]` | `[gap]` |
| Lembretes Email/SMS/WA | `[tem]` | `[tem]` | `[tem]` |
| **Confirmação pelo paciente** | `[?]` | `[tem]` | `[?]` |
| Portal do paciente | `[parcial]` | `[tem]` * | `[tem]` |
| **Push notifications (portal)** | `[gap]` | `[tem]` * | `[?]` |
| **Portal multi-idioma (ES)** | `[gap]` | `[tem]` * | `[?]` |
| **Paciente paga fatura no portal** | `[gap]` | `[tem]` * | `[?]` |
| **App mobile paciente** | `[gap]` | `[tem]` * | `[?]` |
| Analytics / Relatórios | `[parcial]` | `[tem]` | `[tem]` |
| **Export PDF/Excel** | `[parcial]` | `[tem]` | `[?]` |
| Supervisão | `[parcial]` | `[tem]` | `[?]` |
| **Co-assinatura supervisor** | `[gap]` | `[tem]` | `[?]` |
| **Marketing / perfil público** | `[gap]` | `[tem]` | `[?]` |
| **Google Calendar sync** | `[gap]` | `[tem]` | `[?]` |
| **Multi-unidade / filiais** | `[gap]` | `[tem]` | `[?]` |
| **Especialidades (cadastro)** | `[gap]` | `[tem]` | `[?]` |
| **Tipo de registro (CRP/CRM)** | `[?]` | `[tem]` | `[tem]` |
| **Tasks / To-do por cliente** | `[gap]` | `[?]` | `[?]` |
| **E-prescribing** | N/A | `[tem]` | N/A |
| Multi-tenant SaaS | `[tem]` | `[tem]` | `[?]` |
| RLS por tenant | `[tem]` | N/A | `[?]` |
| **Credentialing grátis** (EUA) | N/A | `[tem]` * | N/A |
| **Migração assistida de outra plataforma** | `[gap]` | `[tem]` * | `[?]` |
| **HITRUST cert** | `[gap]` | `[tem]` * | `[?]` |
| **Compliance HIPAA/PCI** | N/A (LGPD) | `[tem]` * | N/A |
---
## 9. Quem faz melhor — diferenciais por player
Resumo punchy: cada concorrente tem um ponto onde está **claramente na frente** do que AgenciaPsi entrega hoje. Mapa pra você pensar em "copiar o melhor de cada um":
### 🤖 Inteligência Artificial
- **Amplimed — Amélia Agendamento** 🥇 · bot 24/7 que agenda pelo WhatsApp sozinho
- **Amplimed — Amélia Transcrição** · áudio→texto no prontuário
- **Amplimed — Amélia Copilot** · resumo/pesquisa inteligente no prontuário
- **Jane App — AI Scribe** · grava sessão e gera nota em minutos
- **PsicoPlanner — PsiAssist** · gera relatórios/documentos com **compliance CFP** (diferencial BR)
> Conclusão: IA é **a tendência dominante em 2026**. AgenciaPsi tem `[gap]` nos 3 casos (agendador, transcrição, resumo). Virar IA-first pode ser o **diferencial de posicionamento**.
### 💬 WhatsApp / Engajamento
- **PsicoPlanner** 🥇 · agenda diária às 7h automática, rastreamento de leitura/resposta em tempo real
- **Amplimed** · WhatsApp Connect + Amélia como bot de atendimento
- **iClinic** · envio de prescrição direto pelo WhatsApp
### 💰 Faturamento / Fiscal BR
- **Amplimed** 🥇 · "99% menos glosas" no TISS + NFS-e integrada + ICP-Brasil
- **iClinic** · assinatura digital com validade jurídica embutida
- **Ninsaúde Sign** · assinatura digital como produto satélite
### 🎥 Teleconsulta
- **SimplePractice** 🥇 · vídeo grupo (15 pessoas), whiteboard digital, blurred BG, screen share
- **Jane App** · telehealth multi-cliente (até 12)
- **PsicoPlanner** · sala de vídeo integrada (solo, mas nativa)
- **Amplimed** · teleconsulta E2E + prescrição digital
### 📋 Prontuário / Documentação
- **SimplePractice** 🥇 · biblioteca GAD-7/PHQ-9/BDI + consent forms assinados + Spanish portal
- **Jane App** · template library + SOAP/notes + AI Scribe
- **iClinic** · histórico em gráfico/tabela + CID-10 + vacinação
### 💳 Pagamentos
- **Jane App** 🥇 · Jane Payments online + **terminal físico POS**
- **SimplePractice** · AutoPay + Superbills
- **Amplimed** · integrado ao prontuário
### 🌐 Portal Paciente
- **SimplePractice** 🥇 · portal em EN+ES, self-scheduling, intake, questionnaires, invoice payment, messaging seguro
- **Jane App** · online booking + website builder com IA
### 🏢 Multi-unidade / Rede
- **Jane App** 🥇 · multi-location + sala/equipamento como resources
- **SimplePractice** · Practice Details com Main Office definido
### 🔒 Compliance & Segurança
- **Jane App** 🥇 · HIPAA + PIPEDA + GDPR + SOC-2 + 256-bit
- **SimplePractice** · HIPAA + HITRUST + PCI + BAA
- **Ninsaúde Safe** · produto de segurança dedicado
### 🎁 Onboarding / Migração
- **Jane App** 🥇 · migração de dados **grátis**
- **SimplePractice** · "Switching Assistance" + Credentialing grátis
### 🎯 Retenção / CRM
- **Ninsaúde CRM** 🥇 · produto dedicado
- **Amplimed** · redução 38% ausências via agenda inteligente
- **iClinic** · marketing médico (email campaigns)
---
## 10. Gaps priorizados (primeira leitura)
Agrupando os `[gap]` acima por tema e impacto-no-usuário:
### 🔴 Críticos pro MVP (quick wins, dependência fraca)
1. **Especialidades** (lista + "outro") no cadastro da clínica/profissional
2. **Tipo de registro** (CRP/CRM) no cadastro do profissional
3. **Busca global de clientes** no topbar
4. **Recently viewed** (últimos pacientes acessados)
5. **Papel timbrado** (portar do UniaoApp quando chegar a hora)
### 🟡 Alto valor, esforço médio
6. **Biblioteca de instrumentos de avaliação** (GAD-7, PHQ-9, BDI, BAI, DASS-21) com scoring automático — **diferencial forte no BR**
7. **Biblioteca de termos de consentimento** (TCLE, Telehealth, LGPD) — editáveis
8. **Assinatura eletrônica** no portal do paciente
9. **Templates de nota de sessão** (SOAP, DAP, BIRP ou equivalente BR)
10. **Auto-billing recorrente** (cobrança automática baseada em agenda)
### 🔵 Grandes (esforço alto, dependências)
11. **Gateway de pagamento integrado** (Stripe/Asaas/Iugu) — destrava cartão on file, auto-billing, superbill
12. **Multi-unidade / filiais** com unidade principal
13. **Teleconsulta integrada** (video próprio ou Daily/Jitsi)
14. **Google Calendar 2-way sync**
15. **Co-assinatura de supervisor**
16. **Claims eletrônico TISS** (convênios BR — mercado nichado mas alto valor pra clínicas grandes)
### ⚪ Diferenciação / marketing
17. **Perfil público / diretório de profissionais**
18. **App mobile** (PWA talvez seja suficiente)
19. **NFSe automatizada** (se for posicionar contra Amplimed/iClinic)
20. **Website builder** pra clínica (Jane App faz com IA)
21. **Terminal POS físico** pra pagamento presencial
### 🤖 IA (novo balde — tendência forte 2026)
22. **Bot WhatsApp que agenda sozinho** — equivalente Amélia Agendamento da Amplimed (ROI claro: 24/7 sem recepcionista)
23. **Transcrição de sessão áudio→texto** — equivalente Amélia Transcrição ou AI Scribe do Jane
24. **Copilot no prontuário** — resumo da história clínica do paciente + busca semântica
25. **Gerador de documentos** (relatórios, laudos) com **compliance CFP** — equivalente PsiAssist do PsicoPlanner
### 🧾 Fiscal / Jurídico BR (diferencial local)
26. **Assinatura digital ICP-Brasil** (Amplimed, iClinic têm)
27. **NFS-e integrada** com dados da consulta
28. **Faturamento TISS automatizado** (nichado mas essencial pra clínicas grandes)
29. **Nome social** no cadastro do paciente (Ninsaúde tem) — LGPD + CFP
---
## 11. Próximos passos
### Feito em 2026-04-17
- [x] Estrutura do doc criada e notas do usuário organizadas
- [x] **Primeira rodada de WebFetch** (SP + Psicomanager)
- ✅ SP `/features/` — categorias top-level + compliance
- ✅ SP `/features/telehealth/` — módulo completo extraído
- ✅ SP `/features/client-portal/` — módulo completo extraído
- ✅ SP `/pricing/` — escala (20M clientes, 250k practitioners) + trials
- ❌ SP `/features/scheduling|billing|documentation/` — 404 (URLs mudaram)
- ❌ Psicomanager — site é SPA JS, scraping não retorna conteúdo
- [x] **Segunda rodada — varredura de concorrentes BR + internacional**
-**iClinic** (`/funcionalidades/` + `/`) — Prontuário + Prescrição + Documentos + Ferramentas
-**Amplimed** (`/`) — **AI-first** (Amélia Agendamento/Transcrição/Copilot) + TISS + NFS-e + ICP
-**PsicoPlanner** (`/`) — concorrente direto: WhatsApp + PsiAssist (IA com CFP) + preços
-**Jane App** (`/features`) — referência internacional de UX + AI Scribe + Jane Payments
-**Ninsaúde** (`/`) — ERP clínico + CRM + Safe + Sign + Nome Social
- ❌ Feegow — SSL handshake falhou
- ❌ Mapps (mapps.com.br, mappsbr.com.br) — DNS não resolve
- ❌ TheraNest (`/features/`) — SSL handshake falhou
- ❌ Doctoralia (`/empresa/produtos`) — 404
- [x] Seções 3-7 adicionadas ao doc com features extraídas
- [x] Seção 9 "Quem faz melhor" criada — diferenciais por player
- [x] Gaps priorizados expandidos (+12 itens novos, com balde 🤖 IA e 🧾 Fiscal BR)
### Pendente
- [ ] **Validar este doc** — você lê e marca o que está certo/errado/incompleto
- [ ] **SimplePractice restante** (alta prioridade): Documentation/Notes, Billing & Insurance, Analytics, Supervision
- Estratégia: você navega logado/trial e me manda prints — eu transcrevo pro doc
- [ ] **Psicomanager completo** — impossível via WebFetch, precisa de:
- Prints das telas principais, ou
- Reviews em B2BStack / Capterra BR / SoftwareSuggest, ou
- Trial pra navegar junto
- [ ] **Decidir fases** — transformar a lista de gaps em roadmap v1/v2/v3
- [ ] **Atualizar `mapa-sistema.html`** marcando os itens `missing` conforme formos confirmando gaps
---
## Rascunho original do usuário (17/04/2026)
> *Preservado aqui pra não perder nenhuma observação. Tudo acima foi organizado a partir destas notas.*
```
SIMPLE PRATICTICE
CLIENTES
PAGAMENTOS
INSURENCE
ANALYTICS
ATIVIDADES
SUPERVISION
SETTINGS
REMINDERS
REQUESTS
MARKETING
RECENTLY VIEWS
BUSCA NO TOPBAR POR CLIENTES
ESTOU VENDO A TELA DE CLINICAL INFO. PARA OS EUA, TEM NPI NUMBER, TAXONOMY CODE E SPECIALITY,
NOS JA TEMOS UM CADASTRO DE CLINICA COMPLETO PARA O BRASIL. ACHO QUE PODERIAMOS COLOCAR O CAMPO
ESPECIALIDADES TBM, LISTAR UM MONTE E SE O USUARIO NAO ENCONTRAR, CADASTRAR O SEU.
TBM TEM UM CAMPO LICENSES TYPE, ONDE O USUARIO SELECIONA SE É MEDICO, PHD, ...
(NÃO SEI SE ISSO SERIA AKI).
AI TEM UMA SESSAO CHAMADA PRACTICE DETAILS ONDE CADASTRA A LOCALIZACAO DA CLINICA
E DIGAMOS FILIAIS (NO CASO DE GESTAO DE CLINICAS). É POSSIVEL DEFINIR QUAL É O MAIN OFFICE.
EM OUTRA ABA ACHAMADA CLIENT CARE, TEM O TEMPLATE LIBRARY, QUE TEM VARIADOS TIPOS
DE ARQUIVOS PRONTOS PARA PERSONALIZAR. E INLUSIVE MONTAR O TEMPLATE.
EX. GAD-7 (GENERALIZED ANXIETY DISORDER), PHQ-9 (PATIENT HEALTH QUESTIONAIRE),
COVID-19 PRE-APPOINTMENT SCREENING QUESTIONAIRE.
TBM TEM UMA OUTRA SESSAO CHAMADA SHARABLE DOCUMENTS: A SESSAO DIZ
MANAGE DEFAULT INTAKE DOCUMENTS AND UPLOADS FILES.
CONSENT FORMS: READ AN SIGNED BY CLIENTS VIA THA CLIENT PORTAL
LEGAL DISCLAIMER: CONSENT FORMS ARE FOR REFERENCE ONLY.
ITS YOUR RESPONSIBILITY TO CUSTOMIZE THEM AND ENSURE THEY MEET
THE LEGAL REQUERIMENTS OF YOUR STATE.
- CONSENT FOR TELEHEALTH CONSULTATION
- CREDIT CARD AUTORIZATION
- NOTICE OF PRIVACY PRATICES
- INFORMED CONSENT FOR PSYCOTHERAPY
- PRACTICE POLICIES
- RELEASE FORMS
- CONSENT TO RECORD AUDIO
- + NEW CONSENT FORM
O USUARIO CONSEGUE ADICIONAR, EDITAR UM NOVO E VISUALIZAR.
PRECISA CRIAR A PARTE DE PAPEL TIMBRADO, ASSIM COMO FIZEMOS NO OUTRO PROJETO,
QUANDO CHEGAR A HORA VC PODE ME PERGUNTAR.
```
+278
View File
@@ -0,0 +1,278 @@
# AgenciaPsi — Roadmap em Fases
> Proposta derivada de `ESTRUTURA.md` (o que já existe) + `concorrentes.md` (o que o mercado tem).
> Data: 2026-04-17
> **Decisões estratégicas** abertas pra validação estão marcadas com ⚠️
---
## Posicionamento recomendado (proposta)
Olhando o estado atual e o terreno competitivo, recomendo:
> **"Psicomanager moderno + IA"** — competir diretamente no nicho de psicologia BR (onde já temos 75-80% pronto), ganhar por **UX moderna** (Vue 3 / PrimeVue / dark mode) e **IA nativa** (onde Psicomanager/PsicoPlanner ainda estão correndo atrás). Pricing entry baixo (tipo PsicoPlanner R$59-79/mês solo) + tier clínica pra monetizar rede.
**Por quê esse corte:**
- 🎯 **Foco:** psico-first (e não generalista como iClinic/Amplimed) — o diferencial é conhecer profundamente o fluxo CFP
- 🎯 **Competitividade:** IA é o campo aberto — Amplimed (Amélia) e Jane (AI Scribe) já estão lá; ainda dá pra chegar
- 🎯 **Custo:** solo-dev → priorizar features de **alto ROI por esforço**; deixar TISS/hospital-grade pra depois
- 🎯 **UX:** PrimeVue/Tailwind dá dignidade visual que Psicomanager ainda não tem
⚠️ **Decisão aberta:** se você quer competir por preço-baixo (PsicoPlanner) ou por valor-alto (Jane App), o roadmap muda. Supus mid-market aqui.
---
## Legenda de esforço
- **S** — <1 semana (quick win)
- **M** — 1-3 semanas
- **L** — 3-8 semanas
- **XL** — 2+ meses (feature grande, múltiplas deps)
## Legenda de prioridade
- 🔴 **Bloqueador** — sem isso, não rola lançar a fase
- 🟠 **Alta** — cria valor imediato pro usuário, reduz churn
- 🟡 **Média** — completa a paridade, não é urgente
- 🔵 **Diferencial** — aposta de posicionamento
---
# 🚀 FASE 1 — MVP Launch
**Objetivo:** ter um produto cobrável, confiável, completo o suficiente pra um terapeuta solo trocar Psicomanager/PsicoPlanner pelo AgenciaPsi.
**Timeline sugerida:** 4-6 semanas
**Critério de saída:** 5 usuários pagantes em produção sem churn por "falta de feature básica".
## 1.1 Monetização (bloqueador total) 🔴
Você **não consegue cobrar** os próprios clientes nem as assinaturas SaaS sem isso.
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 1 | **Integração com gateway de pagamento** (Asaas ou Iugu recomendado pro BR — PIX + cartão + boleto nativos) | L | Asaas é o mais barato pra começar; Iugu tem API melhor. Escolha 1. Stripe só se for internacional. |
| 2 | **Cartão on file** (tokenização via gateway) | M | Desdobra de #1 |
| 3 | **Auto-billing recorrente** (baseado na agenda) | M | Trigger: sessão realizada → gera fatura → cobra automaticamente |
| 4 | **Cobrança das próprias assinaturas SaaS** (tenants pagam pelo plano) | M | Aproveita estrutura de `subscriptions` que já existe |
## 1.2 Compliance básico BR 🔴
Não dá pra lançar sem isso ou você pega processo em 6 meses.
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 5 | **Tipo de registro profissional** (CRP, CRM, CRFa, RMS…) — campo obrigatório no cadastro | S | Aparece em recibos/laudos |
| 6 | **Biblioteca de consent forms editáveis** (TCLE, Telehealth, LGPD, Gravação, TCLE menores) | M | Templates pré-prontos; profissional customiza |
| 7 | **Assinatura eletrônica pelo paciente no portal** (simples, com IP+timestamp) | M | Não precisa ICP-Brasil nessa fase |
| 8 | **Nome social** no cadastro (além do nome de registro) — CFP exige | S | Campo adicional; aparece em todas as telas voltadas ao paciente |
| 9 | **Especialidades** no cadastro do profissional (lista + "outra") | S | DB: tabela `specialties` + FK em `profiles` |
## 1.3 UX mínima esperada 🟠
Todo concorrente tem — usuário novo estranha se não tiver.
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 10 | **Busca global no topbar** (paciente, email, telefone) | S | Autocomplete com debounce + highlight |
| 11 | **Recently viewed** (últimos 5 pacientes acessados, por usuário) | S | localStorage ou tabela `user_recent_access` |
| 12 | **Papel timbrado** (portar do UniaoApp como você mencionou) | M | Já existe noutro projeto — só adaptar |
| 13 | **Relatórios com export PDF/Excel** (já tem estrutura, fechar) | M | Fechar os gaps que o MVP assessment apontou |
## 1.4 Fiscal mínimo 🟠
Pra o terapeuta conseguir operar.
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 14 | **Recibo profissional** (PDF gerado, com dados CFP) | S | Já tem base de documentos — só formalizar template |
| 15 | **NFS-e emissão** (integração Focus NF-e ou NFS-e direto da prefeitura) | L | Pode ficar pra 1.5 se apertar prazo; faz diferença pro profissional se diferenciar |
## 1.5 Qualidade pra lançar 🟠
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 16 | **Testes E2E dos fluxos críticos** (cadastro, login, agendamento, cobrança, prontuário) | L | Playwright ou Cypress; prioridade: compra + agendamento |
| 17 | **Responsividade mobile validada** (terapeuta consulta agenda no celular) | M | Auditoria + fix de breakpoints |
| 18 | **Monitoramento de produção** (Sentry + Supabase dashboards) | S | Detectar bugs antes do usuário reclamar |
### 📦 Entregas da Fase 1
- **Produto cobrável** (gateway integrado)
- **Legal safe** (consent forms, nome social, especialidades)
- **UX polida** (busca, papel timbrado, relatórios)
- **Testado** (E2E crítico + mobile)
### ⚠️ Decisões abertas
- **Gateway:** Asaas (barato) vs Iugu (melhor DX) vs Stripe (internacional depois) — recomendo **Asaas** pra começar rápido
- **NFS-e:** incluir na 1.4 ou empurrar pra 2? Recomendo **incluir** — é quick win e diferencia de Psicomanager
- **Pricing:** qual é o seu valor? (R$59 solo como PsicoPlanner? R$99? R$149?) — afeta quanto time você tem pra chegar nas próximas fases
---
# 🏗️ FASE 2 — Paridade Competitiva
**Objetivo:** qualquer usuário avaliando AgenciaPsi × Psicomanager × PsicoPlanner deve ver **paridade ou mais** de features. Nenhum "ah, mas lá tem X" válido.
**Timeline sugerida:** 2-3 meses após Fase 1
**Critério de saída:** feature checklist empatada com top-3 concorrentes nichados.
## 2.1 Comunicação / Engajamento (onde PsicoPlanner ganha hoje) 🟠
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 19 | **Agenda diária automática 7h via WhatsApp** | S | Cron job + template; feature signature do PsicoPlanner |
| 20 | **Confirmação de presença pelo paciente** ("responder SIM") | M | Parser de resposta WhatsApp/SMS → atualiza status |
| 21 | **Rastreamento de engajamento em tempo real** (recebeu/leu/respondeu) | M | Webhooks da Evolution API + dashboard no topbar |
| 22 | **Envio de prescrição/documento via WhatsApp direto** | S | Botão "Enviar via WA" já gerando link temporário |
## 2.2 Prontuário (onde iClinic ganha hoje) 🟠
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 23 | **Templates de nota** (SOAP / DAP / BIRP / evolução livre CFP-style) | M | Biblioteca com templates selecionáveis |
| 24 | **Biblioteca de instrumentos de avaliação** (GAD-7, PHQ-9, BDI, BAI, DASS-21, SRQ-20) com scoring automático | L | Cada escala tem perguntas + score calculado + gráfico de evolução |
| 25 | **Histórico em gráfico/tabela** (evolução de escalas ao longo do tempo) | M | Chart.js já no projeto |
| 26 | **Versionamento de notas** (auditoria de alterações) | M | Log de alterações + diff visual |
## 2.3 Intake / Onboarding do paciente 🟡
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 27 | **Pacote de intake** (formulários + anamnese + consent forms enviados pré-1ª-sessão) | M | Fluxo: terapeuta monta pacote → paciente recebe link → preenche → assina → terapeuta vê tudo |
| 28 | **Upload de arquivo pelo paciente** (exames, relatórios externos) | S | Storage bucket já configurado |
## 2.4 Agenda / Integrações 🟡
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 29 | **Google Calendar 2-way sync** | L | API OAuth + conflict resolution |
| 30 | **iCal feed** (leitura por Apple Calendar / Outlook) | S | Endpoint que serve .ics |
## 2.5 Fiscal avançado BR (onde Amplimed/iClinic ganham) 🟡
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 31 | **Assinatura digital ICP-Brasil** (laudos com validade jurídica) | L | Integração com ValidCertificadora ou similar |
| 32 | **Faturamento TISS básico** (pra clínicas que têm convênio) | XL | Nichado — só se você quiser ir pra tier clínica/rede |
## 2.6 Marketing / Presença 🟡
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 33 | **Perfil público do terapeuta** (página /p/<slug> com bio, horários, agendamento) | M | Já tem agendador público — só enriquecer |
| 34 | **SEO básico** (schema.org/MedicalBusiness + meta tags) | S | Melhora descoberta orgânica |
### 📦 Entregas da Fase 2
- Paridade completa com Psicomanager/PsicoPlanner/iClinic
- **Sem furo comparativo** em review de feature
- Começo de presença pública (perfil + SEO)
### ⚠️ Decisões abertas
- **TISS (item 32):** grande esforço por nichado — só faz sentido se você for atrás de mercado de clínica com convênio. **Recomendo não fazer** nesta fase.
- **ICP-Brasil (item 31):** pesa? Depende do público. Terapeuta solo raramente precisa. Clínica com laudo pericial, sim. **Recomendo empurrar pra Fase 3** se o MVP foi pra solo.
---
# 🧠 FASE 3 — Diferenciação (IA-first)
**Objetivo:** ter 2-3 features que **nenhum concorrente BR tem em paridade**. Vira marketing: "o sistema com IA pra psicólogos".
**Timeline sugerida:** 3-6 meses após Fase 2
**Critério de saída:** você consegue justificar um **tier premium 2x mais caro** que o básico.
## 3.1 IA — Onde compensa correr 🔵
O time de IA geral (Claude, GPT) tá commoditizado — vantagem vai pra quem **integra bem** ao workflow do usuário.
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 35 | **Bot WhatsApp que agenda sozinho** (equivalente Amélia Agendamento) | XL | Stack: Evolution API + LLM + RAG na disponibilidade da agenda. ROI claro: **24/7 sem recepcionista** |
| 36 | **Transcrição de sessão áudio→texto** (equivalente AI Scribe do Jane + Amélia Transcrição) | L | Whisper API local ou Deepgram; paciente consente; transcrição vira rascunho de nota |
| 37 | **Copilot no prontuário** (resumir histórico, sugerir diagnóstico diferencial baseado em notas anteriores, buscar semântica) | L | RAG em cima das notas do paciente |
| 38 | **Gerador de documentos com compliance CFP** (equivalente PsiAssist) | M | LLM com system prompt de CFP + templates |
## 3.2 Teleconsulta nativa 🔵
Se o público-alvo inclui teleatendimento (grande chance pós-pandemia), isso é essencial.
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 39 | **Vídeo nativo integrado** (Daily.co ou Jitsi Meet) | L | Sala gerada por consulta + link no lembrete |
| 40 | **Sala de espera virtual** | M | Profissional admite paciente |
| 41 | **Whiteboard digital + screen share** | M | Daily.co tem nativo |
## 3.3 Rede / Multi-unidade (se posicionar pra clínicas) 🔵
Só fazer se posicionar pra tier **enterprise**. Solo-therapist não precisa.
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 42 | **Multi-unidade / filiais** com Main Office | L | Tabela `clinic_units` + FK em consultas/profissionais |
| 43 | **Salas e equipamentos como recursos** (estilo Jane App) | M | Evita double-booking |
| 44 | **CRM de leads** (captura de landing → funil → matching com terapeuta) | L | Aproveita o perfil público da Fase 2 |
| 45 | **BI avançado** (MRR, cohort retention, LTV por terapeuta) | M | Dashboards dedicados |
## 3.4 UX premium / diferenciação fina 🔵
| # | Feature | Esforço | Notas |
|---|---|---|---|
| 46 | **Website builder pra clínica** (estilo Jane) — sem precisar de Wix/WordPress | XL | Grande mas ROI de marketing enorme |
| 47 | **App mobile (PWA otimizado)** — paciente instala no celular | M | Vue já dá PWA grátis, só polir |
| 48 | **Migração assistida de Psicomanager** (importador de CSV/API) | M | Feature de venda: "deixa o outro, a gente migra" |
### 📦 Entregas da Fase 3
- **IA-nativa** posicionamento (bot WhatsApp, transcrição, copilot) — Amplimed/Jane nível
- **Teleconsulta própria** (se optar)
- Opcional: tier **enterprise** com multi-unidade
- **Website builder** como moat de marketing
### ⚠️ Decisões abertas
- **Foco único ou múltiplas apostas?** Recomendo: **só IA (3.1)** no primeiro semestre da Fase 3. Teleconsulta e Multi-unidade podem esperar Fase 4.
- **Custo de IA:** transcrição (Whisper) + LLM (Claude/GPT) tem custo por uso — precisa embutir no pricing ou cobrar add-on
---
# ❌ O que ficou FORA do roadmap (propositalmente)
Decisões de "não fazer" são tão importantes quanto as de fazer:
- **Prescrição eletrônica de medicamentos** — só psiquiatras usam; mercado nichado demais
- **Marketplace de terapeutas público** (tipo Doctoralia) — é um negócio completamente diferente; seu negócio é gestão, não captação
- **E-prescribing com farmácia integrada** — idem, só pra psiquiatra
- **Controle de estoque** (Ninsaúde/iClinic têm) — irrelevante pra psicólogo
- **Integração com laboratórios** — irrelevante
- **Controle de vacinas** (iClinic tem) — irrelevante
- **Multi-idioma** (SimplePractice tem espanhol) — empurrar pra Fase 4+ quando for pensar LATAM
- **Certificação HIPAA/HITRUST** — caríssima; LGPD suficiente pra BR
- **App iOS/Android nativo** — PWA resolve 90% do caso; nativo só se houver demanda explícita
---
# 📊 Resumo em tabela
| Fase | Foco | Duração | Features | Esforço total |
|---|---|---|---|---|
| **1 — MVP** | Cobrável + legal safe + UX básica | 4-6 semanas | 18 itens | ~3M de backlog |
| **2 — Paridade** | Empatar com competição BR | 2-3 meses | 16 itens | ~4L de backlog |
| **3 — Diferenciação IA** | Virar "o SaaS com IA pra psico" | 3-6 meses | 14 itens | ~5XL de backlog |
---
# 🎯 Decisões estratégicas pendentes (pra você)
Antes de começar, definir:
1. **Pricing** — R$59, R$99 ou R$149 solo? Afeta quanto tempo você tem pra chegar na Fase 2.
2. **Tier clínica** — vai existir desde o MVP ou só na Fase 3? Afeta item 32 (TISS) e 42 (multi-unidade).
3. **Gateway de pagamento** — Asaas (barato) vs Iugu (melhor DX)? Escolher agora.
4. **IA própria ou terceirizada?** — chamar API da Anthropic/OpenAI (rápido, custo variável) ou rodar modelos open-source localmente (lento, custo fixo)? **Recomendo API** pra começar.
5. **Foco na Fase 3** — IA-first, teleconsulta-first, enterprise-first? Você só tem tempo pra **uma** dessas apostas no primeiro semestre.
6. **Data de lançamento do MVP** — se a meta é 2026-06-01, Fase 1 tem que terminar mid-maio. Planejar capacity.
---
# 📎 Referências cruzadas
- **`ESTRUTURA.md`** — o que já existe no sistema (79 features construídas)
- **`concorrentes.md`** — benchmark de 7 players (SP, Psicomanager, iClinic, Amplimed, PsicoPlanner, Ninsaúde, Jane)
- **`mapa-sistema.html`** — visualização interativa do que está feito
- **`memory/project_mvp_assessment.md`** (25/03/2026) — gaps críticos MVP-assessment original
---
**Próximo passo sugerido:** você lê, contesta o que discorda, responde as 6 decisões pendentes lá em cima, e a gente passa pra **backlog executável** da Fase 1 (breakdown task-por-task do que você vai fazer esta semana / próxima).
+33
View File
@@ -0,0 +1,33 @@
# Database — ferramentas
As ferramentas de banco vivem em [`../../database-novo/`](../../database-novo/) na raiz do projeto. Esta pasta existe apenas como **index** de referência pra navegação.
## Scripts principais
### `database-novo/db.cjs`
CLI completa do banco. Comandos:
- `setup` — instalação do zero (schema + fixes + seeds + migrations) + auto-backup + verify
- `backup` — exporta `schema.sql`, `data.sql`, `full_dump.sql`, `supabase_restore.sql` (restauração completa)
- `restore [data]` — restaura do backup mais recente (ou de uma data específica)
- `migrate` — aplica migrations pendentes com auto-backup antes
- `seed [grupo]` — roda seeds (`all` / `users` / `system` / `test_data`)
- `status` — estado do banco + contagens em tabelas-chave
- `diff` — compara schema atual vs último backup
- `reset` — dropa schema public e reinstala tudo (com safety backup)
- `verify` — checa integridade (tabelas e views definidas em `db.config.json`)
- `schema-export` — gera `schema/00_full``10_grants/` granulares
- `dashboard` — gera `agenciapsi-db-dashboard.html` interativo
### `database-novo/generate-dashboard.cjs`
Gera dashboard HTML do banco lendo schema do backup mais recente. Lê config de `db.config.json` (domínios, cores, infraestrutura).
## Config
`database-novo/db.config.json` — domínios (11), cores, infraestrutura (6 grupos × 23 itens), contagens esperadas pra verify.
## Na UI
A página `/saas/desenvolvimento > Banco de Dados` vai:
- Exibir os comandos com botão "copiar" (executar no terminal)
- Mostrar status dos últimos runs (lido de `dev_generation_log`)
- Link pro dashboard HTML gerado (abre em nova aba)
+170
View File
@@ -0,0 +1,170 @@
# Development — Pendências
> Registro vivo do que ficou pra próximas etapas da área de desenvolvimento.
> **Nada aqui pode se perder** — cada item vira task quando for tratado.
**Última atualização:** 2026-04-17
**Responsável:** Leonardo (user) · **Implementação:** Claude (dev sessions)
---
## ✅ Entregue até agora
### Parte A — Banco + estrutura (2026-04-17)
- [x] Pasta `development/` criada com estrutura hierárquica (`01-visao-geral``05-database`)
- [x] 6 arquivos `.md`/`.txt`/`.html` movidos da raiz pra subpastas temáticas
- [x] `development/README.md` de navegação
- [x] Migration `20260417000001_dev_tables.sql` aplicada com 8 tabelas (`dev_*`) + RLS via `is_saas_admin()`
- [x] 3 seeds executados:
- `seed_030_dev_phases_items.sql` → 3 fases + 48 items
- `seed_031_dev_auditoria.sql` → 14 bugs/débitos (12 resolvidos + 2 abertos)
- `seed_032_dev_competitors.sql` → 7 concorrentes + 74 features + 60 linhas de matriz
### Parte B — UI read-only (2026-04-17)
- [x] Rota `/saas/desenvolvimento` registrada em `routes.saas.js`
- [x] Item de menu "Desenvolvimento > Área de Dev" em `saas.menu.js`
- [x] `SaasDevelopmentPage.vue` com TabView de 7 abas
- [x] 7 sub-componentes (read-only):
- `DevOverviewTab.vue` — stats + progresso das fases + últimas gerações
- `DevRoadmapTab.vue` — fases, items, filtros por status/prioridade/bloco
- `DevEstruturaTab.vue` — ESTRUTURA.md embutido + iframe do mapa-sistema.html
- `DevAuditoriaTab.vue` — bugs/débitos expansíveis, filtros por status/severidade
- `DevCompetitorsTab.vue` — concorrentes + features agrupadas por categoria + matriz de gaps
- `DevDatabaseTab.vue` — comandos do db.cjs com copy-to-clipboard + log de execuções
- `DevExportTab.vue` — stubs de "Gerar ROADMAP.md/AUDITORIA.md/concorrentes.md/ESTRUTURA.md" (desabilitados, mensagem "Pendente — Parte C")
---
## 🔨 Parte C — Edição + integração CLI
### C.1 Edição inline na UI ✅ **CONCLUÍDA (2026-04-17)**
Banco agora é source-of-truth. Implementado:
**Infra reutilizável:**
- [x] `components/DevDrawer.vue` — drawer lateral com footer (save/cancel/delete)
- [x] `components/DevField.vue` — wrapper de label/input padronizado
- [x] `composables/useDraggableList.js` — drag-drop HTML5 nativo (sem deps)
- [x] Migration `20260417000002_dev_tables_ordem.sql` — coluna `ordem` em `dev_auditoria_items` e `dev_competitor_features`
**Roadmap (`DevRoadmapTab.vue`)**
- [x] Drawer pra editar item (todos os campos)
- [x] Drag & drop pra reordenar items dentro de um bloco (via `BlocoItems.vue`)
- [x] Mover item entre fases (via select no drawer)
- [x] Criar novo item
- [x] Excluir item (com confirm)
- [x] Criar nova fase (botão "+" no seletor)
- [x] Editar fase (nome, objetivo, timeline, status, datas)
- [x] Excluir fase (cascade nos items)
**Auditoria (`DevAuditoriaTab.vue`)**
- [x] Drawer com todos os campos (título, categoria, severidade, status, problema, solução, arquivo, tags, datas)
- [x] Criar/editar/excluir
- [x] Drag-reorder (desativado quando filtro ativo)
**Concorrentes (`DevCompetitorsTab.vue`)**
- [x] CRUD de concorrente (slug, nome, país, foco, pricing, posicionamento, url, notas, ativo)
- [x] CRUD de feature por concorrente (categoria, nome, descrição, fonte, url, destaque)
- [x] CRUD de linha da matriz (domínio, feature, status, nota, importância)
- [x] **Edição inline de status na matriz** (dropdown colorido)
**Pendências menores que ficaram:**
- [ ] Drag-reorder no overview das fases
- [ ] Drag-reorder na matriz de comparação
- [ ] Drag-reorder nas features dentro de um concorrente
- [ ] Drag-reorder do topo da lista de concorrentes
- [ ] Autosave nos drawers (hoje é "clique em Salvar")
- [ ] Undo recente
- [ ] Keyboard shortcuts (`/` busca, `n` novo, `Esc` fecha)
- [ ] Mudança rápida de status direto no badge do card (sem abrir drawer)
- [ ] Marcar fase como concluída automaticamente quando 100% items concluídos
- [ ] Quick filters no overview (só bloqueadores, só Fase 1, etc.)
### C.2 Integração CLI local (opcional — usuário disse "copy-to-clipboard por ora")
Hoje todos os comandos do `DevDatabaseTab.vue` são copy-to-clipboard. Na próxima onda (se for quiser):
- [ ] Pequeno server Node em `development/cli-server/server.cjs`
- Escuta em `127.0.0.1:3456` (localhost-only)
- Whitelist de comandos: `backup`, `dashboard`, `schema-export`, `status`, `verify`, `migrate`, `seed`, `diff`
- Endpoints: `POST /run/:cmd` com SSE pra streaming do stdout
- Escreve em `dev_generation_log` o resultado
- [ ] Script `npm run dev:cli` pra iniciar o server
- [ ] Indicador na UI (verde/vermelho) mostrando se server está online
- [ ] Botões "Executar agora" ao lado de cada comando (alternativo ao copy)
### C.3 Export banco → .md (botões da aba "Exportar")
- [ ] Edge Function `generate-roadmap-md` que lê `dev_roadmap_phases` + `dev_roadmap_items` e retorna markdown
- [ ] Edge Function `generate-auditoria-md` análogo
- [ ] Edge Function `generate-concorrentes-md` análogo
- [ ] Na UI: botão clica → fetch da edge function → `<a download>` do resultado
- [ ] OU: endpoint no CLI server escreve direto em `development/04-roadmap/ROADMAP.md` (se CLI server existir)
- [ ] Versionar os arquivos gerados no git (script "publish": gera tudo + `git add development/`)
### C.4 Pesquisa automática de concorrentes
O usuário **disse "não sei"** sobre essa feature. Quando for decidir:
- [ ] Edge Function `fetch-competitor-page` — recebe URL, faz `fetch()` do HTML, retorna raw
- [ ] UI: botão "Pesquisar este concorrente" abre modal com:
- Input de URL
- Preview do HTML capturado
- Campo de texto livre pra colar observações
- Opção: "extrair com IA" (chama Anthropic API com system prompt pra listar features)
- [ ] Features extraídas entram numa fila de revisão (usuário aprova → salva em `dev_competitor_features`)
- [ ] Histórico: `dev_competitor_features` ganha campos `aprovado_em`, `aprovado_por`, `revisao_status`
### C.5 Melhorias secundárias
- [ ] **Autosave** nos drawers de edição (debounce 1s)
- [ ] **Toast de feedback** em toda mutação
- [ ] **Undo recente** (Ctrl+Z nos últimos 5 minutos via revision log)
- [ ] **Keyboard shortcuts**`/` foca busca, `n` novo item, `Esc` fecha drawer
- [ ] **Dark mode** — se o app tem, garantir compatibilidade (surface tokens estão OK mas validar)
- [ ] **Responsividade mobile** — tabs scroll horizontal já tratado, mas drawers precisam virar modals full-screen em mobile
- [ ] **Paginação/virtualização** nas listas grandes (quando matriz passar de 100 linhas)
---
## 📋 Itens órfãos / decisões estratégicas
### Decisões **abertas** (do `ROADMAP.md`)
Repetidas aqui pra não perder:
1. **Pricing** — R$ 59, R$ 99 ou R$ 149 solo? Afeta quanto tempo você tem pra Fase 2.
2. **Tier clínica** — existe desde o MVP ou só na Fase 3? Afeta TISS (item 32) e multi-unidade (42).
3. **Gateway de pagamento** — Asaas (barato) vs Iugu (melhor DX)? Escolher agora.
4. **IA própria ou terceirizada?** — Claude/OpenAI via API (rápido, custo variável) vs open-source local (lento, custo fixo)? Recomendo API pra começar.
5. **Foco da Fase 3** — IA-first, teleconsulta-first ou enterprise-first? Capacity só dá pra uma aposta no primeiro semestre.
6. **Data de lançamento MVP** — se meta é 2026-06-01, Fase 1 termina mid-maio.
### Itens técnicos **abertos** do `AUDITORIA.md`
Ainda não resolvidos (já no banco como `dev_auditoria_items` com status `aberto` / `em_analise`):
- `window.__guardsBound / window.__supabaseAuthListenerBound` — flags globais no window (anti-pattern)
- Arquivos obsoletos no projeto (cleanup parcial — a finalizar)
---
## 🎯 Ordem sugerida pra Parte C
Se quiser atacar **agora**:
1. **C.1 roadmap** — drawer de edição (mais valor imediato — marcar items concluídos)
2. **C.1 auditoria** — mesmo padrão do roadmap
3. **C.3 export** — ROADMAP.md e AUDITORIA.md (para versionar o que você editou)
4. **C.1 concorrentes** — edição completa
5. **C.2 CLI server** — quando cansar de copy-paste
6. **C.4 pesquisa auto** — se decidir que vale
---
## 📁 Referências
- Migração: `database-novo/migrations/20260417000001_dev_tables.sql`
- Seeds: `database-novo/seeds/seed_030_dev_phases_items.sql`, `seed_031_dev_auditoria.sql`, `seed_032_dev_competitors.sql`
- Frontend: `src/views/pages/saas/development/`
- Rota: `src/router/routes.saas.js` (path `desenvolvimento`)
- Menu: `src/navigation/menus/saas.menu.js` (grupo "Desenvolvimento")
- Docs fonte: `development/04-roadmap/ROADMAP.md` · `development/02-auditoria/AUDITORIA.md` · `development/03-concorrentes/concorrentes.md`
+53
View File
@@ -0,0 +1,53 @@
# Development — AgenciaPsi
> Área de trabalho de desenvolvimento. Centraliza documentação interna, análise competitiva, roadmap e ferramentas de banco de dados.
>
> Este diretório é a **contraparte em arquivos** da página `/saas/desenvolvimento` no sistema. Dados estruturados (roadmap, auditoria, concorrentes) ficam no banco (`dev_*` tables); os `.md` aqui são **snapshots exportáveis** a partir do banco ou leitura humana da situação atual.
## Navegação
### [`01-visao-geral/`](./01-visao-geral/)
Snapshot do sistema hoje.
- [`ESTRUTURA.md`](./01-visao-geral/ESTRUTURA.md) — tree-view dos 6 perfis × ~79 features ativas
- [`mapa-sistema.html`](./01-visao-geral/mapa-sistema.html) — visualização interativa (abrir no navegador)
- [`estrutura.txt`](./01-visao-geral/estrutura.txt) — snapshot antigo da árvore de arquivos (histórico)
### [`02-auditoria/`](./02-auditoria/)
Bugs, dívidas técnicas e decisões arquiteturais.
- [`AUDITORIA.md`](./02-auditoria/AUDITORIA.md) — auditoria técnica com status `[RESOLVIDO]` / `[ABERTO]`
### [`03-concorrentes/`](./03-concorrentes/)
Benchmark competitivo.
- [`concorrentes.md`](./03-concorrentes/concorrentes.md) — 7 players analisados (SimplePractice, Psicomanager, PsicoPlanner, iClinic, Amplimed, Ninsaúde, Jane App) + tabela comparativa + diferenciais por player
### [`04-roadmap/`](./04-roadmap/)
Fases de evolução do produto.
- [`ROADMAP.md`](./04-roadmap/ROADMAP.md) — Fase 1 (MVP Launch) · Fase 2 (Paridade) · Fase 3 (Diferenciação IA) · decisões estratégicas abertas
### [`05-database/`](./05-database/)
Ferramentas de banco (read-only aqui — os scripts vivem em `database-novo/` na raiz do projeto).
## Fluxo de trabalho
1. **Edição primária na UI** — a página `/saas/desenvolvimento` lê/escreve diretamente nas tabelas `dev_*`
2. **Export pra git** — botões "Gerar {ROADMAP, concorrentes, ESTRUTURA}.md" serializam o banco pros arquivos aqui (pra versionar)
3. **Import inicial** (uma vez) — seeds em `database-novo/seeds/seed_030_*_dev.sql` populam o banco a partir dos `.md` atuais
## Tabelas no banco (schema `public`, prefixo `dev_`)
Criadas pela migration `20260417000001_dev_tables.sql`. Todas com RLS restrita a `saas_admins`.
| Tabela | Pra quê |
|---|---|
| `dev_roadmap_phases` | Fases (1/2/3) com status, datas, objetivo |
| `dev_roadmap_items` | Itens das fases (prioridade, esforço, status, notas) |
| `dev_auditoria_items` | Bugs/débitos técnicos (severidade, status, solução) |
| `dev_competitors` | Concorrentes (pricing, URL, última pesquisa) |
| `dev_competitor_features` | Features deles (categoria, nome, fonte) |
| `dev_comparison_matrix` | AgenciaPsi × feature-de-concorrente (nosso status) |
| `dev_generation_log` | Histórico de execuções (backup/dashboard/export) |
## Relacionados (fora de `development/`)
- [`database-novo/`](../database-novo/) — CLI do banco (db.cjs, generate-dashboard.cjs) e schema/migrations/seeds
- [`diagrama-visualizacao-dados.webp`](../diagrama-visualizacao-dados.webp) — referência visual (fica na raiz)