- 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>
15 KiB
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 eMAPA-FUNCIONAL-COMPLETO.md. Estado verificado: produçãov1.0.18· DEVdev. 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
- 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). - 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. - A clínica é apenas um workspace? Sim, há evidência explícita:
clinicas.tipopode serpessoal | consultorio | clinica, comowner_id. A clínica é hoje um tipo de workspace dentro da própria tabelaclinicas(que virou, de fato, a tabela de workspaces). - Módulos que favorecem Pessoa→Vínculo→Workspace: login/identidade,
vinculos+RBAC (funcoes/setores),me/workspaces,usuario_plugins,usuario_areas, Salas (workspacetipo='sala'), Marketplace de Profissionais, Tutoria. - 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. - 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 quedentistasjá 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 (tabelasusuarios,vinculos,clinicas,pacientes,dentistas,salas,protese_*,propostas_profissional) e doMAPA-FUNCIONAL-COMPLETO.md. Onde o código tinha ambiguidade (ex.: dois INSERTs depacientes, 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.