docs: auditoria funcional + auditoria estratégica de modelagem

- documentação/MAPA-FUNCIONAL-COMPLETO.md: inventário de rotas/telas/botões/fluxos,
  matriz de módulos, mapa de conexões (mermaid) e notas — baseado em evidências do código.
- documentação/AUDITORIA-ESTRATEGICA-MODELAGEM.md: análise Pessoa→Vínculo→Workspace,
  entidades mal classificadas e riscos arquiteturais.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
VPS 4 Builder
2026-06-19 18:23:54 +02:00
parent 06674563d5
commit 5b99292b2d
2 changed files with 642 additions and 0 deletions
@@ -0,0 +1,157 @@
# AUDITORIA ESTRATÉGICA DE MODELAGEM — ScoreOdonto
> **Análise crítica da modelagem e da visão de negócio.** Não altera código, banco, documentação ou migrations.
> Baseada exclusivamente em evidências reais: `backend/server.js`, schema real (tabelas), fluxos existentes e
> `MAPA-FUNCIONAL-COMPLETO.md`. Estado verificado: produção `v1.0.18` · DEV `dev`. Data: 19/jun/2026.
---
## Evidências-âncora (o que o código realmente diz)
| Camada | Evidência no código | Tabela/linha |
|---|---|---|
| **Identidade (Pessoa)** | `usuarios` é o ponto único de login; perfil multi-área (`usuario_areas`), capacidades por pessoa (`usuario_plugins`), `is_tutor` | `usuarios`, `me/areas`, `me/plugins` |
| **Vínculo (join)** | `vinculos(usuario_id, clinica_id, role, setor_id, funcao_id)` + `CHECK role IN (paciente, dentista, biomedico, protetico, funcionario, donoclinica, donoconsultorio, donosala, admin)` | `server.js:4851` |
| **Workspace** | `clinicas` ganhou `tipo ∈ {pessoal, consultorio, clinica}` + `owner_id`; comentário literal **"Clinicas → workspaces (Fase 1)"** | `server.js:4822-4824` |
| **Workspace pessoal automático** | No registro, cria `clinicas(tipo='pessoal', owner_id=usuario)`**toda pessoa nasce com um workspace** | `server.js:537,550` |
| **Agregação** | `me/workspaces``listarWorkspaces(userId)` reúne clínicas (via vínculo) + salas | `server.js:5680` |
| **Marketplace = pessoa** | `propostas_profissional.profissional_id``JOIN usuarios u` | `server.js:6307` |
| **Legado clínica-cêntrico** | `pacientes` tem `clinica_id` e **não tem `usuario_id`**; `dentistas` é tabela à parte com `usuario_id` opcional; tudo passa por `tenantGuard`+`clinica_id` | `pacientes`, `dentistas:1542` |
**Leitura imediata:** a *espinha de identidade e acesso* **já é** Pessoa → Vínculo → Workspace (e isso está em migração ativa, declarada como "Fase 1"). Os *dados clínicos/operacionais* **ainda são** Clínica → Pessoa. O sistema é **híbrido, com a direção já apontada pelo próprio código**.
---
## ANÁLISE 1 — Pessoa × Workspace
1. **Centrado em clínica ou pessoa?** Híbrido. **Autenticação/autorização/workspaces:** centrado em **pessoa**. **Operação clínica e financeira:** centrado em **clínica** (`tenantGuard` + `clinica_id`).
2. **A pessoa é entidade principal?** **Sim, há evidência forte:** `usuarios` é a âncora; áreas, plugins e tutor são da pessoa; o profissional do marketplace é a pessoa; e cada pessoa recebe um **workspace pessoal** ao se cadastrar.
3. **A clínica é apenas um workspace?** **Sim, há evidência explícita:** `clinicas.tipo` pode ser `pessoal | consultorio | clinica`, com `owner_id`. A clínica é hoje **um tipo de workspace** dentro da própria tabela `clinicas` (que virou, de fato, a tabela de workspaces).
4. **Módulos que favorecem Pessoa→Vínculo→Workspace:** login/identidade, `vinculos`+RBAC (`funcoes`/`setores`), `me/workspaces`, `usuario_plugins`, `usuario_areas`, Salas (workspace `tipo='sala'`), Marketplace de Profissionais, Tutoria.
5. **Módulos que favorecem Clínica→Pessoa:** Pacientes, Dentistas (tabela-recurso), Agenda, Financeiro/Comissão/Repasse, Orçamentos/Contratos, Glosas — **toda a operação** ainda é escopada por `clinica_id`.
6. **Mais sustentável em 5 anos:** **Pessoa → Vínculo → Workspace.** Justificativa técnica: a tabela `vinculos` é N:N (uma pessoa, vários workspaces, papéis distintos por workspace) — é o único modelo que comporta dentista em várias clínicas, locação de salas, tutoria e marketplace **sem duplicar a pessoa**. O modelo clínica-cêntrico exige duplicar o humano por clínica (é o que `dentistas` já faz, e é exatamente o gargalo).
---
## ANÁLISE 2 — Consultório
**Hoje é simultaneamente (A) Papel e (C) Workspace:** existe a *role* `donoconsultorio` em `vinculos` **e** o `tipo='consultorio'` em `clinicas` (`server.js:590` decide o `tipoWs` a partir da role do dono).
**Classificação ideal:** **(C) Workspace** — um `tipo` de workspace, sendo `donoconsultorio` apenas o *papel do dono* dentro dele. O sistema já está ~80% nesse modelo.
**Impactos:** baixo do ponto de vista de dados (já existe `tipo='consultorio'`). O resíduo é **semântico**: a role codifica o tipo do workspace (acoplamento role↔tipo). Enquanto persistir, decisões de UI/permissão ramificam em dois lugares ("é consultório?" pode ser perguntado pela role *ou* pelo tipo), gerando divergência.
---
## ANÁLISE 3 — Protéticos
**Hoje o protético é:** **Usuário/Profissional.** É `usuarios` com role `protetico` em `vinculos`, recebe workspace pessoal, e produz trabalho via `protese_os`/`protese_produtos`.
**Existe conflito conceitual? Sim.** O protético-pessoa está modelado como **profissional do ecossistema**, mas o **laboratório** (onde o trabalho/custo realmente reside, `protese_laboratorios` + custo lab que abate comissão) é um **cadastro interno separado**. Ou seja, a faceta "fornecedor" está **descolada** da pessoa: a pessoa é profissional, o fornecedor é um cadastro à parte.
**Modelo que faz mais sentido: (B) Protético = profissional do ecossistema** — e o **laboratório** é que ocupa o papel de *fornecedor*. Justificativa: o protético, como humano, se encaixa perfeitamente em Pessoa→Vínculo→Workspace (igual a dentista/biomédico); empurrá-lo para "fornecedor" o trataria como entidade não-humana e quebraria o login/marketplace/áreas que já funcionam para ele. A natureza "fornecimento" pertence ao **laboratório**, não ao indivíduo (ver Análise 4). (C) só seria verdade se um protético autônomo *fosse* o próprio laboratório — caso que o modelo atual não distingue.
---
## ANÁLISE 4 — Laboratórios
**Hoje aparecem como:** **(A) Cadastro interno** — `protese_laboratorios` escopado por clínica, alimentando OS e custo lab. Não há identidade própria nem login; não cruzam clínicas.
| Classificação | Vantagens | Desvantagens |
|---|---|---|
| **A) Cadastro auxiliar** (estado atual) | Simples; isolado por clínica; zero atrito | Cada clínica recadastra o mesmo laboratório; sem visão consolidada; sem relação direta com a pessoa protético |
| **B) Participante do ecossistema** (entidade própria) | Laboratório único reaproveitável; liga custo lab à entidade real; base para reputação/histórico | Exige resolver identidade/duplicidade e governança de dados entre clínicas |
| **C) Workspace independente** | Coerente com a linha Pessoa/Workspace; laboratório operaria como ator (recebe OS de várias clínicas) | Maior complexidade de tenancy; só se justifica se o laboratório for *operar dentro* da plataforma |
**Análise (sem assumir locação):** hoje é **A**, e isso é consistente com o legado clínica-cêntrico. A tensão é que o laboratório é a **única entidade "fornecedor" real** do sistema e está modelada como simples lookup — o que limita qualquer evolução para histórico/qualidade/integração entre clínicas. **B** é o ponto de equilíbrio entre o estado atual e a direção arquitetural; **C** só se sustenta se o laboratório virar *operador* na plataforma.
---
## ANÁLISE 5 — Pacientes
**Hoje o paciente pertence à CLÍNICA.** Evidências: `pacientes.clinica_id`, **ausência de `usuario_id`**, e até **dois variantes de INSERT** (um com `clinica_id`, outro sem — resíduo legado). Não há identidade de paciente no ecossistema; o mesmo CPF em duas clínicas vira **dois registros**.
- **Compartilhamento entre clínicas:** inexistente (duplicação por clínica).
- **Histórico:** preso à clínica; não há prontuário único da pessoa.
- **Multiempresa:** o isolamento é forte (bom para tenancy), mas impede portabilidade.
- **Privacidade/LGPD:** o modelo atual é, na verdade, **mais seguro por isolamento** (cada clínica é controladora dos seus dados). Um paciente "do ecossistema" exigiria base legal/consentimento para compartilhar histórico entre controladores distintos — não trivial.
**Abordagem mais coerente com a arquitetura ATUAL:** **o paciente pertence à clínica.** É o que o código faz e o que o LGPD-por-isolamento favorece. **Porém** isso é a **maior contradição** com a direção Pessoa→Workspace: o paciente é a única "pessoa" do sistema que **não** é tratada como pessoa. É coerente com o presente e **incoerente com o futuro declarado**.
---
## ANÁLISE 6 — Marketplace
| Módulo | Encaixa em | Evidência |
|---|---|---|
| Salas | **Modelo B** | workspace `tipo='sala'`, reservas cross-clínica |
| Profissionais | **Modelo B** | `profissional_id``usuarios`; cruza clínicas |
| Tutoria | **Modelo B** | candidatura/pagamento ligados à pessoa (`is_tutor`, MercadoPago) |
| Próteses | **Modelo A** (hoje) | `protese_os` por `clinica_id` |
| Laboratórios | **Modelo A** (hoje) | cadastro interno por clínica |
**Conclusão:** o marketplace **só faz sentido no Modelo B (Pessoa→Vínculo→Workspace→Marketplace)**. Salas, Profissionais e Tutoria já estão lá porque dependem da **pessoa cruzando fronteiras de clínica** — algo que o Modelo A (Clínica→Tudo) torna impossível sem duplicação. Próteses/Laboratórios são os **retardatários** ainda presos ao Modelo A; são a fronteira onde os dois modelos colidem.
---
## ANÁLISE 7 — Escalabilidade (horizonte 5 anos)
| Cenário | Suporta hoje? | Gargalo |
|---|---|---|
| Dentista em múltiplas clínicas | **Parcial** | `vinculos` suporta a identidade, mas `dentistas` **duplica a pessoa por clínica** (agenda/horários presos a `dentistas.id`); não há visão unificada do profissional |
| Biomédico em vários locais | Parcial | mesma duplicação via tabela-recurso |
| Profissionais temporários (Delivery) | **Não** | marketplace só tem proposta-mensagem; sem contrato/pagamento/vínculo temporário |
| Locação de salas | **Sim (estrutura)** | falta captura de pagamento (fluxo financeiro aberto) |
| Tutoria | **Sim** | escala de oferta de tutores |
| Marketplace | Parcial | só Tutoria fatura |
| Protéticos independentes | Parcial | pessoa ok, mas laboratório-fornecedor é cadastro preso à clínica |
| Redes de clínicas | **Não** | **não existe entidade "rede/grupo" acima da clínica**; workspaces são planos, sem hierarquia |
**O modelo escala?** A **camada de identidade sim**; a **camada operacional não**. Gargalos críticos: (1) **duplicação da pessoa** em `dentistas`/recursos; (2) **paciente não-portável**; (3) **ausência de hierarquia** (rede→clínica); (4) **tenancy de `clinica_id` único** impede consolidação cross-clínica (uma pessoa ver tudo o que é seu em todas as clínicas).
---
## ANÁLISE 8 — Contradições (por gravidade)
| Gravidade | Contradição | Evidência |
|---|---|---|
| **ALTA** | `dentistas` é entidade paralela a `usuarios` (mesmo humano duplicado por clínica, com `usuario_id` *opcional*) → identidade fragmentada | `dentistas:1542`, `:328` |
| **ALTA** | `pacientes` é entidade clínica-presa sem identidade de pessoa, com **dois INSERTs** (com/sem `clinica_id`) → ambiguidade legada + bloqueio de portabilidade | INSERTs de `pacientes` |
| **MÉDIA** | O "workspace" está **dividido em duas tabelas**: `clinicas` (pessoal/consultorio/clinica) **e** `salas` — conceito único, dois lugares | `clinicas:4823`, `salas` |
| **MÉDIA** | Acoplamento **role ↔ tipo de workspace** (`donoconsultorio``tipo='consultorio'`) | `server.js:590` |
| **MÉDIA** | Estado de capacidades em **dois lugares**: `usuario_plugins` (servidor) vs `localStorage` (cliente) → divergência entre dispositivos | `pluginRegistry.ts`, `me/plugins` |
| **BAIXA** | Protético-pessoa (profissional) × laboratório (fornecedor) descolados | `protese_laboratorios` |
| **BAIXA** | `superadmin` fora de `vinculos``usuarios.role`) → plano de auth separado (aceitável, mas assimétrico) | `me/workspaces:5682` |
---
## RESULTADO FINAL
**1. Resumo executivo.** O ScoreOdonto é um ERP odontológico multiempresa em **transição arquitetural declarada no próprio código** ("Fase 1: Clinicas → workspaces"). A **identidade, o acesso e os workspaces já operam no modelo Pessoa→Vínculo→Workspace**; a **operação clínica/financeira permanece clínica-cêntrica**. As três frentes de marketplace já vivem no modelo novo; pacientes, dentistas-recurso e laboratórios são o legado que ainda não migrou. As contradições graves são todas de **identidade duplicada** (a mesma pessoa existindo como `usuarios` + `dentistas`, e o paciente sem identidade de pessoa).
**2. Modelo que melhor representa o sistema HOJE:** **híbrido**`Pessoa → Vínculo → Workspace` na espinha; `Clínica → Pacientes/Dentistas/Financeiro` na operação.
**3. Modelo que melhor representa o sistema NO FUTURO:** `Pessoa → Vínculo → Workspace → Serviços → Marketplace → Financeiro` — e o código já está pavimentado para ele.
**4. Entidades CORRETAMENTE classificadas:** `usuarios` (Pessoa), `vinculos` (Vínculo+RBAC), Clínica/Consultório/Sala como **workspaces**, Dentista/Biomédico/Protético/Tutor como **papéis da pessoa**, Profissional do marketplace e capacidades (`areas`/`plugins`) como atributos da pessoa.
**5. Entidades MAL classificadas:**
- **`dentistas`** — modelada como entidade própria; é, na verdade, uma **projeção da pessoa por workspace** (duplica o humano).
- **`pacientes`** — entidade presa à clínica; é a única "pessoa" do sistema **não tratada como pessoa**.
- **Laboratórios** — cadastro auxiliar; é o **único fornecedor real** e está subdimensionado.
- **Consultório** — vive como role **e** tipo (redundância).
**6. Riscos arquiteturais:** identidade fragmentada (dentistas); paciente não-portável e com resíduo de schema; conceito de workspace partido em duas tabelas; ausência de hierarquia "rede→clínica"; tenancy de `clinica_id` único barrando visão consolidada da pessoa; estado de plugins divergente cliente/servidor.
**7. Oportunidades arquiteturais:** a "Fase 1" **já entregou o mais difícil** (identidade + vínculo + workspace + workspace pessoal automático). O ecossistema (marketplace, salas, tutoria) **só existe** porque essa base existe. Unificar as entidades-recurso (dentista) e a entidade-paciente sob a pessoa **destravaria de uma vez** multi-clínica, portabilidade de histórico, redes e o marketplace — sem reescrever o que já está certo.
**8. Recomendação estratégica única:** **assumir e consolidar a PESSOA como âncora única do sistema, reconhecendo que a clínica já é — no código — apenas um tipo de workspace.** A decisão estratégica de fundo não é "se" migrar para Pessoa→Vínculo→Workspace (o sistema já escolheu isso na Fase 1), e sim **parar de manter o legado clínica-cêntrico em paralelo** nas duas entidades que ainda o sustentam (paciente e dentista-recurso) — pois é a coexistência dos dois modelos, não a escolha de um, que gera todas as contradições de gravidade ALTA.
---
> *Nota de método: tudo acima decorre de leitura de `backend/server.js`, do schema real (tabelas `usuarios`,
> `vinculos`, `clinicas`, `pacientes`, `dentistas`, `salas`, `protese_*`, `propostas_profissional`) e do
> `MAPA-FUNCIONAL-COMPLETO.md`. Onde o código tinha ambiguidade (ex.: dois INSERTs de `pacientes`, role↔tipo),
> descreveu-se o fato observado, sem inferir intenção. Conforme solicitado, não há propostas de implementação,
> migrations, código ou tarefas.*
</content>
+485
View File
@@ -0,0 +1,485 @@
# MAPA FUNCIONAL COMPLETO — ScoreOdonto
> **Auditoria funcional baseada SOMENTE em evidências do código.** Nada aqui foi assumido.
> Fonte: `frontend/` (React 19 + Vite, roteador próprio em `App.tsx`) e `backend/server.js`
> (Express monolítico, ~516 KB, **277 rotas**, ~70 tabelas Postgres acessadas por SQL direto).
> Estado verificado: produção `v1.0.18` · DEV `dev` (banco isolado `pgdev`). Data: 19/jun/2026.
---
## Sumário executivo (o que o sistema É, na prática)
O ScoreOdonto é um **ERP odontológico multiempresa** (SaaS) cujo núcleo é o ciclo
**Lead → Paciente → Agenda → Procedimento → Financeiro → Comissão → Repasse**, com módulos
clínicos (Ortodontia, Próteses/GTO, RX), administrativos (Equipe/RBAC, Planos, Procedimentos)
e três frentes de marketplace (**Locação de Salas**, **Diretório/Propostas de Profissionais**,
**Tutoria de Ortodontia** — esta última a única com cobrança automatizada via MercadoPago).
A arquitetura é **multi-tenant real**: quase toda rota passa por `tenantGuard` e filtra por
`clinica_id`. O "workspace" ativo (clínica **ou** sala) governa menu, permissões e dados visíveis.
**Evidências estruturais:**
- Frontend sem `react-router`: roteamento próprio (`ROUTE_MAP` / `VIEW_TO_ROUTE` em `App.tsx`).
- 44 views (`frontend/views/*.tsx`), 16 componentes, 3 plugins.
- Backend num único `server.js` (516 KB) — sem camada de serviços/controllers separada.
- Prisma quase não usado (4 modelos legados de GTO); o banco real é SQL puro via `pg`.
---
# ETAPA 1 — INVENTÁRIO DE ROTAS
Roteamento definido em `frontend/App.tsx` (`ROUTE_MAP`, `VIEW_TO_ROUTE`, `renderView`, `isViewAllowed`).
**Papéis (roles):** `superadmin`, `admin`, `donoclinica`, `donoconsultorio`, `funcionario`,
`dentista`, `biomedico`, `protetico`, `paciente`, `donosala`.
**Tipos de workspace:** `clínica` (padrão) e `sala` (isola o contexto). **Plugins:** `rx-scoreodonto`,
`locacao-salas` (sempre ON), `profissionais-marketplace`.
| URL | View | Componente / Arquivo | Acesso (papéis) | Origem | Destino |
|---|---|---|---|---|---|
| `/` | landing | `LandingPage.tsx` | Público | — | login / área |
| `/login` | login | `LoginView.tsx` | Público | landing | dashboard por papel |
| `/contato` | public | `PublicContactForm.tsx` | Público | landing | cria interesse/lead |
| `/dashboard` | dashboard | `Dashboard.tsx` | admin/donos/func/dentista/bio/prot | login, menu | agenda, pacientes |
| `/leads` | leads | `LeadsView.tsx` | admin/donos/funcionário | menu | converter→paciente+agenda |
| `/pacientes` | pacientes | `PatientsView.tsx` | admin/donos/funcionário | menu, dashboard | agenda, orçamento, procedimento, ortodontia, RX |
| `/agenda` | agenda | `AgendaView.tsx` | quase todos os papéis clínicos | menu, dashboard | paciente, avaliação, procedimento |
| `/ortodontia` | ortodontia | `OrthoView.tsx` | dentista (odonto) | menu, paciente | evolução, fotos, tutoria |
| `/financeiro` | financeiro | `FinanceiroView.tsx` | admin/donos/funcionário | menu | comissão, glosa |
| `/comissoes` | comissoes | `ComissoesView.tsx` | admin/donos | **menu apenas** ⚠️ | repasse |
| `/glosas` | glosas | `GlosasView.tsx` | admin/donos/funcionário | **menu apenas** ⚠️ | recebíveis convênio |
| `/proteses` | proteses | `ProteseView.tsx` | dentista/protético/func | menu | OS de laboratório, GTO |
| `/orcamentos` | orcamentos | `OrcamentosView.tsx` | admin/donos/funcionário | menu, paciente | contrato |
| `/contratos` | contratos | `ContratosView.tsx` | admin/donos/funcionário | menu, orçamento | cobrança/financeiro |
| `/relatorios` | relatorios | `ReportsView.tsx` | admin/donos/funcionário | menu | — |
| `/tratamentos` | tratamentos | `MeusTratamentos.tsx` | paciente + clínicos | menu | — |
| `/lancar-gto` | lancar-gto | `LancarGTO.tsx` | biomédico/protético/func | menu | guias odontológicas |
| `/notificacoes` | notificacoes | `NotificationsView.tsx` | todos | menu | — |
| `/clinicas` | clinicas | `ClinicasView.tsx` | membros | menu, seletor de workspace | criar-clinica |
| `/gestao-equipe` | gestao-equipe | `GestaoEquipeView.tsx` | admin/donos | menu | membros, cargos (RBAC) |
| `/admin/dentistas` | dentistas | `AdminViews.tsx` | admin/donos | menu | horários |
| `/admin/especialidades` | especialidades | `AdminViews.tsx` | admin/donos/biomédico | menu | procedimentos |
| `/admin/procedimentos` | procedimentos | `AdminViews.tsx` | admin/donos/biomédico | menu | valores por plano |
| `/admin/planos` | planos | `AdminViews.tsx` | admin/donos | menu | — |
| `/admin/sync` | sync | `AdminViews.tsx` (`SyncView`) | **NINGUÉM (bloqueado)** ⚠️ | — | — |
| `/plugins` | plugins | `PluginsView.tsx` | **superadmin apenas** | menu (superadmin) | ativa plugins |
| `/rx-radiografias` | rx-radiografias | `plugins/RXPlugin.tsx` | dentista/donos/func (plugin RX) | menu | dispositivos RX |
| `/rx-config` | rx-config | `RxConfigView.tsx` | admin/donos/superadmin | menu | dispositivos RX |
| `/salas` `/minhas-salas` `/alugar-salas` | salas | `plugins/SalasPlugin.tsx` | todos (plugin `locacao-salas`, sempre ON) | menu | reservas |
| `/sala-home` | sala-home | `SalaHomeView.tsx` | workspace tipo `sala` | seletor de workspace | reservas da sala |
| `/marketplace-profissionais` | marketplace-profissionais | `plugins/ProfissionaisPlugin.tsx` | clínicos exceto paciente (plugin) | menu | propostas |
| `/diretorio-profissionais` | diretorio-profissionais | `DiretorioProfissionaisView.tsx` (absorvido pelo plugin) | clínicos | menu | — |
| `/candidatura-tutor` | candidatura-tutor | `TutorCandidaturaView.tsx` | dentista | menu | pagamento MercadoPago |
| `/tutoria-painel` | tutoria-painel | `TutorPainelView.tsx` | **tutores aprovados** (`is_tutor`) | menu | solicitações |
| `/admin-gestao-tutores` | admin-gestao-tutores | `AdminGestaoTutoresView.tsx` | **superadmin** | menu | confirma pagamentos/repasses |
| `/criar-clinica` | criar-clinica | `CreateClinicView.tsx` | admin/donos sem workspace | pós-cadastro | dashboard |
| `/cadastro-dentista` | cadastro-dentista | `DentistRegisterView.tsx` | standalone (magic-link) | **menu apenas** ⚠️ | aguardando-convite |
| `/aguardando-convite` | aguardando-convite | `WaitingInviteView.tsx` | dentista/bio/prot sem vínculo | pós-cadastro | — |
| `/superadmin/*` | superadmin-* | `SuperAdminView.tsx` (tabs) | **superadmin** | menu | usuários, clínicas, logs, financeiro, notificações |
| `/update` | update | `UpdateDbView.tsx` | técnica (URL direta, sempre liberada) | **fora do menu** | migração de banco |
**⚠️ Inconsistências de roteamento encontradas (evidência: `ROUTE_MAP` vs `VIEW_TO_ROUTE` em `App.tsx`):**
- `/comissoes`, `/glosas` e `/cadastro-dentista` **existem em `VIEW_TO_ROUTE`** (a navegação por menu empurra a URL),
mas **NÃO existem em `ROUTE_MAP`**. Consequência: abrir essas URLs direto (deep-link / refresh) cai em `dashboard`.
**Deep-link quebrado** para 3 telas reais.
- `/admin/sync` está mapeada, mas `isViewAllowed` retorna `false` **sempre** (substituída por "backup por clínica").
A tela e a rota existem, porém são **inacessíveis** (código morto navegável).
---
# ETAPA 2 — INVENTÁRIO DE TELAS
(Resumo por tela — objetivo / usuário-alvo / valor / dependências / impacto. Apenas telas reais.)
### Dashboard
- **Objetivo:** visão consolidada (KPIs via `GET /api/dashboard/stats`). **Usuário:** gestores/clínicos.
- **Valor:** ponto de entrada operacional. **Depende de:** agenda, pacientes, financeiro. **Impacta:** navegação.
### Leads / Gestão de Leads
- **Objetivo:** captar e **converter** interessados em pacientes. **Usuário:** funcionário/donos.
- **Valor:** topo do funil comercial. **Depende de:** `interesses`/contato público. **Impacta:** Pacientes + Agenda
(a conversão cria ambos — `POST /api/leads/:id/converter`).
### Pacientes
- **Objetivo:** prontuário e cadastro (dados, família, score, faltas). **Usuário:** funcionário/donos.
- **Valor:** entidade central do negócio. **Depende de:** clínica ativa. **Impacta:** Agenda, Orçamento,
Procedimento realizado, Ortodontia, RX, Receita/Exame. É o hub clínico (view de 92 KB).
### Agenda
- **Objetivo:** agendar/confirmar/remarcar; controle de presença e anti-overbooking. **Usuário:** todos clínicos.
- **Valor:** coração operacional. **Depende de:** Pacientes, Dentistas+horários. **Impacta:** Avaliação,
Procedimento, Financeiro (presença libera lançamento).
### Ortodontia
- **Objetivo:** tratamento orto completo (triagem, diagnóstico, plano, evoluções, fotos, contenção). **Usuário:** dentista.
- **Valor:** vertical clínica de alto valor recorrente. **Depende de:** Paciente. **Impacta:** Tutoria, fotos.
### Próteses / GTO
- **Objetivo:** OS de laboratório (`protese_os`), produtos, custo lab, entrega. **Usuário:** protético/dentista.
- **Valor:** controle do laboratório e do custo que abate comissão. **Depende de:** Procedimentos, Laboratórios.
**Impacta:** Comissão (custo lab entra no cálculo).
### Financeiro
- **Objetivo:** contas a receber/pagar (`financeiro`: RECEITA/DESPESA), formas, centro de custo, fornecedor. **Usuário:** gestores.
- **Valor:** caixa da clínica. **Depende de:** Procedimentos realizados, Contratos, Repasses. **Impacta:** Comissão, Glosa.
### Comissões
- **Objetivo:** definir % (padrão da clínica, por procedimento, override por profissional) e ver produção/comissão.
- **Usuário:** donos. **Depende de:** Procedimentos realizados + Próteses (custo lab). **Impacta:** Repasses.
### Glosas
- **Objetivo:** registrar glosa sobre recebíveis (convênio), recorrer, recuperar. **Usuário:** gestores.
- **Valor:** recupera receita negada por convênio. **Depende de:** Financeiro (recebíveis). **Impacta:** caixa.
### Orçamentos → Contratos
- **Objetivo:** propor tratamento (itens/valores) e formalizar em contrato (modelos com variáveis, assinatura, cobrança).
- **Usuário:** funcionário/donos. **Depende de:** Paciente, Procedimentos. **Impacta:** Financeiro (`gerar-cobranca`).
### Equipe / Usuários (RBAC)
- **Objetivo:** membros, cargos (`funcoes`), setores e permissões por workspace. **Usuário:** donos.
- **Valor:** governa quem vê o quê. **Impacta:** menu e `isViewAllowed` de todos os membros.
### Salas (Locação) / Painel da Sala
- **Objetivo:** cadastrar salas, publicar no marketplace, receber/aceitar reservas. **Usuário:** qualquer conta.
- **Valor:** receita de locação P2P. **Depende de:** conta/sala. **Impacta:** `sala_reservas`.
### Marketplace de Profissionais / Diretório
- **Objetivo:** profissional publica perfil; clínica envia proposta (`propostas_profissional`). **Usuário:** clínicas e profissionais.
- **Valor:** conexão oferta/demanda de mão de obra. **Impacta:** mensagens/propostas (sem cobrança hoje).
### Tutoria de Ortodontia (Candidatura / Painel / Gestão)
- **Objetivo:** dentista vira tutor (pagando inscrição via MercadoPago); resolve solicitações orto.
- **Usuário:** dentistas + superadmin (gestão). **Valor:** **única receita de plataforma automatizada**.
### SuperAdmin (overview/users/clínicas/logs/financeiro/notificações)
- **Objetivo:** administração global da plataforma (preços/assinaturas, broadcast, auditoria de acesso).
- **Usuário:** superadmin. **Valor:** operação do SaaS.
### Configurações / Notificações / Minhas Clínicas
- Conta, integrações (Google), backup por clínica; notificações; seletor/gestão de workspaces.
---
# ETAPA 3 — INVENTÁRIO DE BOTÕES (telas transacionais)
Rótulos extraídos das views; ações mapeadas para as rotas/tabelas do backend.
### Agenda (`AgendaView.tsx`)
- **Novo Agendamento** → `POST /api/agendamentos` → tabela `agendamentos`. Fluxo: Paciente ↓ Procedimento ↓ Financeiro.
- **Confirmar / Confirmar Presença** → `POST /api/agendamentos/:id/confirmar` + `/api/agenda/presenca``agendamentos`, `agenda_presenca`. **Libera lançamento financeiro.**
- **Reagendar / Remarcar** → `POST /api/agendamentos/:id/remarcar``agendamentos`.
- **Registrar Falta** → `POST /api/agendamentos/:id/falta``agendamentos` (impacta score do paciente).
- **Solicitar Avaliação** → `POST /api/agendamentos/:id/solicitar-avaliacao``avaliacoes`.
### Pacientes (`PatientsView.tsx`)
- **Editar/Cadastrar Paciente** → `POST|PUT /api/pacientes``pacientes`.
- **Agendar** → abre fluxo da Agenda. **Lançar Procedimento** (`LancarProcedimentoModal`) → `POST /api/procedimentos-realizados``procedimentos_realizados` (+ gera `financeiro`).
- **Orçamento** (`OrcamentoModal`) → `orcamentos`. **Receita** (`ReceitaModal`) → `modelos_receita`/`items_receita`. **Pedido de Exame** (`PedidoExameModal`) → `pedidos_exame`.
### Financeiro (`FinanceiroView.tsx`)
- **Novo lançamento** (RECEITA/DESPESA, forma, vencimento, centro de custo, fornecedor) → `POST /api/financeiro``financeiro`.
- **Marcar Pago / Alterar / Excluir** → `PUT|DELETE /api/financeiro/:id``financeiro`.
### Comissões (`ComissoesView.tsx`)
- **Salvar % padrão / por procedimento / override por profissional** → `PUT /api/comissoes/regras``comissao_regras`.
- **Base de cálculo** (produção × recebido) e **Custo lab** abatido. Próximo fluxo: **Fechar repasse**.
### Repasses (em Financeiro/Comissões)
- **Fechar Repasse** → `POST /api/repasses/fechar``repasses` (status `fechado`).
- **Pagar** → `POST /api/repasses/:id/pagar` → cria DESPESA em `financeiro` (origem `repasse`, centro de custo `COMISSÕES`).
- **Anexar Comprovante** → `POST /api/repasses/:id/comprovante`. **Cancelar** → estorna a despesa.
### Glosas (`GlosasView.tsx`)
- **Registrar Glosa** (total/livre, motivo, valor) → `POST /api/glosas``glosas`.
- **Recorrer** → `POST /api/glosas/:id/recorrer`. **Recuperar**`POST /api/glosas/:id/recuperar`.
### Orçamentos / Contratos
- **Novo Orçamento** (itens, valor, entrada, parcelas) → `POST /api/orcamentos``orcamentos`/`orcamento_itens`.
- **Gerar Contrato** (modelo + variáveis + prévia) → `POST /api/contratos/instancias``contratos`.
- **Enviar / Assinar / Gerar Cobrança / Cancelar** → `POST /api/contratos/instancias/:id/{enviar,assinar,gerar-cobranca,cancelar}` → liga ao `financeiro`.
### Próteses (`ProteseView.tsx`)
- **Nova OS** (produto, dentes, material, custo lab, preço, prazo) → `POST /api/protese/os``protese_os`.
- **Marcar Entregue / Mudar Status** → `POST /api/protese/os/:id/status``protese_os_evento`.
### Leads (`LeadsView.tsx`)
- **Cadastrar Lead** → `POST /api/leads``leads`.
- **Cadastrar o Paciente / Converter** (com data, hora, dentista) → `POST /api/leads/:id/converter` → cria `pacientes` **+** `agendamentos` (anti-overbooking).
---
# ETAPA 4 — FLUXOS DE NEGÓCIO
## Fluxo principal (núcleo do produto) — COMPLETO
```
Lead/Interesse ──converter──▶ Paciente ──▶ Agenda ──confirmar/presença──▶ Atendimento
(leads) (pacientes) (agendamentos) │
Procedimento Realizado
(procedimentos_realizados)
│ valor>0
Financeiro RECEITA (origem='procedimento')
(financeiro, flag sem_comissao)
computeComissoes = (base custo_lab) × %
Repasse FECHADO (repasses) ──pagar──▶
Financeiro DESPESA (origem='repasse',
centro_custo='COMISSÕES')
```
- **Onde começa:** Lead/Interesse (ou cadastro direto de Paciente).
- **Onde termina:** pagamento do repasse ao profissional (DESPESA conciliada no caixa) — ciclo fechado.
- **Onde quebra / desvio:**
- **Geração de RECEITA é opcional** (`gerarLancamento !== false` e `valor>0`): um procedimento sem valor
**não** entra no financeiro — possível receita não registrada (depende do operador).
- **Glosa** é um ramo paralelo sobre recebíveis de convênio (recupera receita), não integrado ao repasse.
- **Garantia/Reabertura** marcam `sem_comissao` (regra: garantia sempre; reabertura só se mesmo profissional)
— corretamente excluídas do repasse.
- **Duplicidade:** não há dupla geração de comissão — o repasse pago entra como DESPESA com `sem_comissao=true`
(evita recomissionar). Bom controle.
## Fluxo comercial paralelo
```
Orçamento (orcamentos) ──▶ Contrato (contratos) ──gerar-cobranca──▶ Financeiro (a receber)
```
## Fluxos de marketplace (ver Etapas 7 e 8)
```
Sala (salas) ──publica──▶ Marketplace ──reserva──▶ sala_reservas (valor, status) [pagamento MANUAL]
Profissional ──perfil──▶ Diretório ──proposta──▶ propostas_profissional (mensagem) [sem cobrança]
Dentista ──candidatura──▶ MercadoPago (pago) ──webhook──▶ Tutor ativo ──▶ Solicitações de tutoria
```
---
# ETAPA 5 — MATRIZ DE MÓDULOS
| Módulo | Existe? | Acessível? | Funcional? | Completo? | Em uso? | Classificação |
|---|---|---|---|---|---|---|
| Autenticação / Workspaces / RBAC | Sim | Sim | Sim | Sim | Sim | **Maduro** |
| Pacientes | Sim | Sim | Sim | Sim | Sim | **Maduro** |
| Agenda (+presença/anti-overbooking) | Sim | Sim | Sim | Sim | Sim | **Maduro** |
| Financeiro (receita/despesa) | Sim | Sim | Sim | Sim | Sim | **Maduro** |
| Comissão + Repasse | Sim | Sim | Sim | Sim | Sim | **Operacional** |
| Glosas | Sim | menu apenas (deep-link quebrado) | Sim | Parcial | Sim | **Operacional** |
| Orçamentos → Contratos | Sim | Sim | Sim | Sim | Sim | **Operacional** |
| Ortodontia | Sim | Sim | Sim | Sim | Sim | **Maduro** |
| Próteses / GTO | Sim | Sim | Sim | Parcial | Sim | **Operacional** |
| Leads | Sim | Sim | Sim | Sim | Sim | **Operacional** |
| Plano/Procedimentos/Especialidades | Sim | Sim | Sim | Sim | Sim | **Operacional** |
| RX / Radiografias (plugin) | Sim | por plugin/papel | Sim | Parcial | depende clínica | **Parcial** |
| Locação de Salas (marketplace) | Sim | Sim (sempre ON) | Sim | Parcial (sem gateway) | baixo | **Parcial** |
| Marketplace Profissionais | Sim | por plugin | Sim | Parcial (só mensagem) | baixo | **MVP** |
| Tutoria de Ortodontia (MercadoPago) | Sim | Sim | Sim | Sim | baixo | **Operacional** |
| SuperAdmin | Sim | superadmin | Sim | Sim | Sim | **Operacional** |
| Sync Google/legado (global) | Sim | **bloqueado** | parcial | — | **não** | **Abandonado** |
| Relatórios | Sim | Sim | Sim | Parcial | Sim | **Parcial** |
---
# ETAPA 6 — MULTIEMPRESA
**Evidência:** quase todas as 277 rotas usam `tenantGuard` e filtram por `req.clinicaId`/`clinica_id`.
O workspace ativo é resolvido por `GET /api/me/workspaces` (tabela `vinculos` = usuário↔clínica) + salas próprias.
| Entidade | Como é modelada | Multiempresa respeitado? |
|---|---|---|
| Workspaces | `vinculos` (clínica) + `salas` (tipo `sala`); seletor no Sidebar | ✅ Sim |
| Clínicas | `clinicas` + `clinica_id` em todas as tabelas operacionais | ✅ Sim |
| Consultórios | papel `donoconsultorio` (variação de dono, mesmo modelo de clínica) | ✅ Sim |
| Dentistas / Biomédicos / Protéticos | papéis distintos com menus próprios; vínculo por clínica | ✅ Sim |
| Salas | `salas` + workspace `tipo='sala'` **isola** o contexto (menu reduzido) | ✅ Sim |
| Laboratórios | `protese_laboratorios` por clínica | ✅ Sim |
- **Acoplamento indevido:** **não** encontrado acoplamento a "clínica única" — o `clinica_id` é onipresente.
- **Ponto de atenção:** o contexto é **cacheado no `localStorage`** (`SCOREODONTO_USER_DATA`, plugins) e
reconciliado via `hydrateMyPlugins()`. Plugins ativos vivem em `localStorage` (cliente), não só no servidor —
risco de divergência entre dispositivos (mitigado por `me/plugins`, mas é o elo mais frágil do multiempresa).
- O **marketplace de salas é cross-tenant** por desenho (uma clínica aluga sala de outra) — acoplamento *intencional*.
**Veredito:** conceito multiempresa **bem respeitado** no backend; a fragilidade é o estado de UI/plugins no cliente.
---
# ETAPA 7 — MARKETPLACE
```
Salas (salas) ─┬─ Locação (sala_reservas: valor, modelo, status pendente/aceita)
└─ Profissionais (perfil) ─ Propostas (propostas_profissional: mensagem)
└─ Protéticos/Laboratórios (protese_*)
```
| Frente | O que existe hoje | O que falta | Gera receita? | Pode gerar |
|---|---|---|---|---|
| **Locação de salas** | CRUD de salas, publicação no marketplace, reserva com `valor` e workflow de status (`pendente``aceita`), painel da sala | **Gateway de pagamento** e taxa da plataforma (hoje o `valor` é registrado, mas o pagamento é **manual/externo**) | **Não diretamente** | **Sim** — comissão sobre locação |
| **Profissionais** | Perfil público + envio de proposta (mensagem) clínica→profissional | Negociação, contrato, e qualquer cobrança | **Não** | Sim — taxa de match/assinatura premium |
| **Protéticos / Laboratórios** | OS, produtos, custo lab integrados ao financeiro/comissão | Marketplace aberto de laboratórios (hoje é interno por clínica) | Indireto (operacional) | Sim — rede de laboratórios |
| **Tutoria de Ortodontia** | Candidatura **paga via MercadoPago** (`preferences` + `mp-webhook`), `comissao_pct`, solicitações/mensagens | Escala (oferta de tutores), avaliação | ✅ **Sim (a única automatizada)** | Já gera |
**Conclusão:** a infraestrutura de marketplace existe, mas **só a Tutoria tem captura de pagamento real**.
Salas é a frente mais próxima de monetizar (já tem `valor` e reservas) — falta o gateway + a taxa.
---
# ETAPA 8 — FINANCEIRO
```
ORIGEM DO DINHEIRO → DESTINO → RESPONSÁVEL
Procedimento realizado (RECEITA) → financeiro (a receber) → Clínica
Contrato (gerar-cobranca) → financeiro (a receber) → Clínica
Convênio (recebíveis) Glosa → financeiro / recupera → Clínica
Comissão (base custo lab × %) → repasses (fechado) → Profissional
Repasse pago → financeiro DESPESA (COMISSÕES) → Clínica paga Profissional
Locação de sala (valor reserva) → sala_reservas (status) → Locador [pagamento manual]
Tutoria (inscrição) → MercadoPago → ativa tutor → Plataforma (comissao_pct)
```
| Item | Tabela | Estado |
|---|---|---|
| Orçamentos | `orcamentos`/`orcamento_itens` | ✅ completo |
| Contratos | `contratos`/`contrato_*` | ✅ completo (modelos, variáveis, assinatura, cobrança) |
| Convênios/Planos | `planos`, `procedimentos_valores_planos` | ✅ |
| Produção | `procedimentos_realizados``financeiro` | ✅ (RECEITA opcional por valor) |
| Comissão | `comissao_regras` + `computeComissoes` | ✅ (3 níveis de regra; abate custo lab) |
| Repasse | `repasses` (fechar/pagar/cancelar/comprovante) | ✅ ciclo fechado, com estorno |
| Glosas | `glosas` (recorrer/recuperar) | ✅ funcional, isolado do repasse |
| Locação | `sala_reservas.valor` | ⚠️ registra valor, **sem captura de pagamento** |
**Pontos fortes:** rastreabilidade (cada DESPESA de repasse referencia o período/profissional; `audit_log` em tudo),
e não-duplicação de comissão (`sem_comissao` propagado). **Lacuna:** receita de procedimento depende de ação manual.
---
# ETAPA 9 — MAPA DE CONEXÕES (Mermaid)
```mermaid
flowchart TD
U[Usuário] --> WS{Workspace ativo}
WS -->|clínica| CL[Clínica / RBAC]
WS -->|sala| SH[Painel da Sala]
CL --> LEAD[Leads]
LEAD -->|converter| PAC[Pacientes]
PAC --> AG[Agenda]
AG --> AV[Avaliação]
AG --> PR[Procedimento Realizado]
PAC --> ORTO[Ortodontia]
PAC --> RX[RX / Radiografias]
PAC --> ORC[Orçamento]
ORC --> CON[Contrato]
CON -->|gerar-cobranca| FIN[Financeiro]
PR -->|RECEITA| FIN
PR --> COM[Comissão]
PROT[Próteses / Custo Lab] --> COM
COM --> REP[Repasse]
REP -->|pagar DESPESA| FIN
FIN --> GLO[Glosas]
FIN --> REL[Relatórios]
SH --> RES[Reservas de Sala]
CL --> SAL[Salas Marketplace]
SAL --> RES
CL --> MKP[Marketplace Profissionais]
MKP --> PROP[Propostas]
ORTO --> TUT[Tutoria Orto]
TUT -->|MercadoPago| MP[(Pagamento)]
SUPER[SuperAdmin] --> CL
SUPER --> PLUG[Plugins]
```
```mermaid
flowchart LR
subgraph Núcleo financeiro
PR[procedimentos_realizados] --> FINr[financeiro RECEITA]
FINr --> CR[comissao_regras]
CR --> RP[repasses]
RP --> FINd[financeiro DESPESA]
FINr --> GL[glosas]
end
```
---
# ETAPA 10 — OPORTUNIDADES
## Funcionalidades órfãs (existem no código, ninguém usa)
- **`views/OrthoReports.tsx`** — não é roteada em `App.tsx` **nem** importada por nenhuma view. Órfã real
(importa `OrthoPhotoWorkspace`, mas nada importa `OrthoReports`). Relatórios de ortodontia prontos e desligados.
- **`SyncView` (`/admin/sync`)** — tela e rota existem, mas `isViewAllowed` retorna `false` sempre. Código morto navegável.
## Funcionalidades escondidas (existem mas não aparecem no menu)
- **`/update` (`UpdateDbView`)** — migração de banco; acessível por URL direta, fora do menu (ferramenta técnica).
- **`/cadastro-dentista`** — só alcançável por fluxo/magic-link; sem entrada no menu e com deep-link quebrado.
- **Comissões deep-link** — visível no menu (admin/donos) mas `/comissoes` direto cai em dashboard.
## Funcionalidades incompletas (começam mas não terminam o fluxo)
- **Locação de salas** — reserva com `valor` e status, mas **sem captura de pagamento** (fluxo financeiro não fecha).
- **Marketplace de profissionais** — proposta é só mensagem; **não** evolui para contratação/cobrança.
- **RECEITA de procedimento opcional** — pode não gerar lançamento (receita potencialmente não registrada).
- **Glosas isoladas** — recuperam receita, mas não reconciliam com o repasse correspondente.
## Funcionalidades de alto potencial (podem gerar receita)
1. **Gateway na Locação de Salas** (já existe `valor`+reserva): cobrança + taxa da plataforma → receita recorrente.
2. **Assinatura/planos da plataforma** (`superadmin/pricing`, `assinaturas` já existem): monetizar o SaaS por clínica.
3. **Marketplace de Profissionais premium**: taxa de match / destaque de perfil.
4. **Tutoria de Ortodontia em escala** (único pago hoje): aumentar oferta de tutores e volume.
---
# RESULTADO FINAL
## Notas (0100) — com base nas evidências
| Eixo | Nota | Justificativa (evidência) |
|---|---:|---|
| **Arquitetura funcional** | 72 | Roteamento+RBAC robustos, mas `server.js` monolítico (516 KB), roteador próprio e 3 deep-links quebrados. |
| **Integração dos módulos** | 78 | Cadeia Lead→…→Repasse bem costurada, com auditoria e não-duplicação de comissão. |
| **Fluxos de negócio** | 70 | Núcleo clínico+financeiro completo; ramos de marketplace incompletos; receita às vezes manual. |
| **Multiempresa** | 82 | `tenantGuard`+`clinica_id` onipresentes; isolamento de sala; fragilidade no estado de plugins no cliente. |
| **Marketplace** | 45 | Infra existe; só Tutoria captura pagamento; Salas e Profissionais sem fechar fluxo financeiro. |
| **Financeiro** | 80 | Receita/despesa, comissão (3 níveis), repasse com estorno, glosas, contratos com cobrança. |
| **Experiência do usuário** | 70 | Menus por papel, nav mobile, "visualizar como"; prejudicada por deep-links quebrados e estado em localStorage. |
| **Potencial de monetização** | 65 | Tutoria já fatura; Salas e Assinatura SaaS são alavancas prontas e subutilizadas. |
## 1. O que remover
- `views/OrthoReports.tsx` (órfã) — ou religar ao menu de Ortodontia se desejado.
- `SyncView` / rota `/admin/sync` e telas de sync global desativadas (já substituídas por backup por clínica).
- `server.js.bak` e scripts de transformação legados (`transform.js`, `pg-convert.js`) do diretório de produção.
## 2. O que corrigir
- **Adicionar `/comissoes`, `/glosas`, `/cadastro-dentista` ao `ROUTE_MAP`** (deep-link/refresh quebrado).
- Reconciliação de **plugins ativos**: tratar o servidor como fonte da verdade (reduzir dependência de `localStorage`).
- Tornar a **geração de RECEITA do procedimento** o padrão claro (evitar receita não registrada).
## 3. O que finalizar
- **Locação de Salas**: captura de pagamento + taxa da plataforma (fecha o fluxo financeiro do marketplace).
- **Marketplace de Profissionais**: evoluir proposta → contratação → cobrança.
- **Relatórios**: consolidar (há `reports/productivity` + telas parciais).
## 4. O que priorizar
1. Corrigir deep-links e estado de plugins (baixo esforço, destrava UX e confiabilidade).
2. Gateway de pagamento na Locação de Salas (alavanca de receita mais próxima).
3. Cobrança por assinatura da plataforma (`superadmin/pricing`+`assinaturas` já existem).
## 5. O que gera receita mais rapidamente
- **Locação de Salas com pagamento** — o `valor` e o fluxo de reserva já existem; falta só a captura + taxa.
- **Assinatura SaaS por clínica** — a base multiempresa e o `pricing` já estão prontos no superadmin.
## 6. Próximo módulo mais estratégico
- **Monetização da plataforma (Billing/Assinaturas + taxa de marketplace de salas).** É o que converte uma base
técnica madura (ERP odontológico multiempresa funcional) em **receita recorrente da plataforma** — hoje só a
Tutoria cobra. Tudo o mais já está construído; falta o módulo que **fatura**.
---
> **Nota de método:** este mapa reflete exclusivamente o que foi encontrado no código em 19/jun/2026
> (`frontend/App.tsx`, `frontend/views/*`, `frontend/components/Sidebar.tsx`, `backend/server.js`).
> Onde havia ambiguidade (ex.: receita opcional, pagamento manual de salas), o fato foi descrito como está,
> sem inferir intenção. Nenhuma funcionalidade foi inventada.
</content>
</invoke>