Skip to content

Hipóteses Técnicas e Alternativas

Para chegar à arquitetura atual, avaliamos diversas hipóteses e caminhos técnicos. Nesta página, detalhamos os "Porquês" por trás de cada escolha, comparando nossa solução com abordagens convencionais e alternativas descartadas.


1. Gestão de Estado: Redux vs. Context API

Hipótese A: Apenas React Context

  • A Ideia: Usar o Context API nativo do React para gerenciar o estado global de cada domínio.
  • Vantagem: Menor boilerplate, sem dependências externas, curva de aprendizado baixa.
  • O Problema (Escala 100M): O Context API causa re-renderizações em massa quando o estado é atualizado, a menos que seja quebrado em centenas de pequenos contextos. Em uma tela de telemedicina com vídeo, chat e prontuário (dados mudando a cada milissegundo), a performance degradaria rapidamente. Além disso, falta o suporte a middlewares complexos e ferramentas de debug (DevTools) robustas.
  • Veredito: Descartado para lógica de negócio complexa. Mantido apenas para dados estáticos (Tema, Autenticação básica).

Hipótese B: Redux Toolkit + Redux-Saga (Nossa Escolha)

  • A Ideia: Centralizar a lógica assíncrona e o estado imutável.
  • Vantagem: Previsibilidade total, ferramentas de depuração de nível industrial, e a capacidade de tratar efeitos colaterais (como WebSockets e Timers) de forma isolada da UI.
  • Por que Saga?: Diferente do Thunk, o Saga permite lidar com fluxos de "corrida" (race conditions) e cancelamentos de forma elegante, o que é vital quando um médico clica rápido demais ou a internet oscila.

2. Isolamento: Monólito Convencional vs. Domínios Isolados

Hipótese C: Arquitetura "Flat" (Tudo em um lugar só)

  • A Ideia: Colocar todos os Reducers em um rootReducer e todos os componentes em /components.
  • Vantagem: Muito rápido para começar o projeto.
  • O Problema: Conforme o sistema cresce para atender 26 estados e dezenas de especialidades, o bundle (arquivo JS final) torna-se gigantesco. Um erro em "Agendamento" pode impedir o carregamento da "Agenda". O acoplamento é inevitável.
  • Veredito: Descartado. Inviável para 100 milhões de usuários com internet limitada.

Hipótese D: Domínios com Injeção Dinâmica (Nossa Escolha)

  • A Ideia: Cada domínio (Consultation, Chat, Users) é um "mini-app" que só entra na memória quando solicitado.
  • Vantagem: O navegador só processa o código necessário. Se o usuário é um Paciente, ele nunca baixa o código do módulo de "Prescrição Médica". Isso economiza bateria, memória e dados.

3. Fluxo de Processo: Booleans vs. State Machines

Hipótese E: Controle via Flags (isLoading, isFinished)

  • A Ideia: Usar variáveis booleanas no Redux para controlar o que aparece na tela.
  • Vantagem: Simples de entender inicialmente.
  • O Problema: Gera "Estados Impossíveis". Como impedir que isStarted e isFinished sejam true ao mesmo tempo por um erro de lógica? Em saúde, isso pode levar a salvar dados em momentos errados.
  • Veredito: Descartado para fluxos críticos.

Hipótese F: XState (Máquinas de Estado - Nossa Escolha)

  • A Ideia: Definir estados fixos e transições permitidas.
  • Vantagem: O sistema é matematicamente seguro. Se não existe uma seta ligando "Agendado" a "Finalizado" sem passar por "Em Atendimento", o erro humano é bloqueado pelo próprio código.

4. Comunicação: Importação Direta vs. Event-Driven

Hipótese G: Importação Lateral (import { action } from '../other-domain')

  • A Ideia: Um domínio chama funções de outro diretamente.
  • Vantagem: Fácil de seguir o fluxo com "Go to Definition".
  • O Problema: Cria um emaranhado de dependências. Para testar o "Chat", você acaba tendo que carregar o "Prontuário", porque um depende do outro. Se quiser remover o "Chat" no futuro, o sistema inteiro quebra.
  • Veredito: Proibido.

Hipótese H: Domain Events (Nossa Escolha)

  • A Ideia: Domínios emitem eventos ("Consulta Finalizada") e outros reagem se quiserem.
  • Vantagem: Desacoplamento total. O módulo de Agendamento pode ser adicionado meses depois sem que o módulo de Consulta precise ser alterado.

5. Estrutura de Repositório: Multi-repo vs. Monorepo

Hipótese I: Multi-repo (Um projeto para cada app/package)

  • A Ideia: Ter repositórios Git separados para app-medical, app-patient, ui-library, etc.
  • Vantagem: Isolamento total de código e histórico de commits. Permite deploys e versões completamente independentes por time.
  • O Problema (Escala 100M): Gerenciar versões de dependências compartilhadas vira um "inferno de atualizações". Se mudarmos a interface de um contrato de saúde em packages/contracts, precisaríamos abrir 10 Pull Requests em repositórios diferentes e garantir que todos façam deploy na ordem certa. O "Type Safety" de ponta a ponta é perdido ou fica muito difícil de manter.
  • Veredito: Descartado para o estágio atual de desenvolvimento acelerado.

Hipótese J: Monorepo Modular (Nossa Escolha)

  • A Ideia: Um único repositório com apps/ e packages/ bem definidos.
  • Vantagem: Refatoração Atômica. Se eu mudar um tipo no contrato, o compilador me avisa instantaneamente em todos os apps que usam aquele tipo. O compartilhamento de código (DRY) é natural e a governança é centralizada em um único pipeline de CI/CD.

6. Renderização: Server-Side (SSR) vs. Client-Side (CSR)

Hipótese K: Server-Side Rendering (Next.js / Remix)

  • A Ideia: Gerar o HTML no servidor para cada requisição.
  • Vantagem: Melhor SEO (não crítico para apps logados) e percepção de carregamento inicial mais rápida em alguns casos.
  • O Problema: Em sistemas de saúde com 100M de usuários, o custo de infraestrutura para processar milhões de renderizações no servidor é altíssimo. Além disso, telas de telemedicina são extremamente interativas e dependem de APIs de navegador (WebRTC, Bluetooth), que não existem no servidor, gerando complexidade de "hidratação" e erros de window is not defined.
  • Veredito: Descartado para as áreas logadas.

Hipótese L: Client-Side Rendering (CSR) com SPA (Nossa Escolha)

  • A Ideia: O servidor entrega arquivos estáticos (HTML/JS/CSS) e o navegador faz o trabalho pesado.
  • Vantagem: Escalabilidade horizontal barata (arquivos estáticos em CDNs). Uma vez carregado, o app é instantâneo.
  • Otimização para 100M: Usamos Lazy Loading agressivo para mitigar o problema do carregamento inicial do SPA, garantindo que o usuário só baixe o que precisa para sua região e seu papel (Médico/Paciente).

7. Estilização: CSS-in-JS vs. Utility-First (Tailwind)

Hipótese M: Styled-components / Emotion (Runtime CSS)

  • A Ideia: Escrever CSS dentro do JavaScript.
  • Vantagem: Escopo automático, facilidade para usar props do React no estilo.
  • O Problema: Performance de Runtime. Em telas com centenas de campos de prontuário, o custo de processar estilos no JavaScript em cada renderização pode causar lentidão (lag) em celulares mais simples de usuários em regiões remotas do Brasil.
  • Veredito: Descartado para componentes de alta performance.

Hipótese N: Tailwind CSS / CSS Modules (Nossa Escolha)

  • A Ideia: CSS pré-processado ou classes utilitárias.
  • Vantagem: Zero custo de runtime. O CSS é gerado no build. O Tailwind, especificamente, garante um bundle final minúsculo, pois as classes são reutilizadas exaustivamente, o que é perfeito para usuários com internet 3G instável nos 26 estados.

8. Estratégia de Micro-Frontends (MFE)

Hipótese O: Micro-Frontends desde o Dia 1 (Module Federation)

  • A Ideia: Separar cada domínio em uma URL diferente e juntar tudo em runtime.
  • O Problema: Complexidade prematura. Debugging difícil, orquestração de versões complexa e perda de performance no carregamento inicial (múltiplos requests de infraestrutura).
  • Veredito: Mantido como "Norte" (Roadmap), mas não implementado agora.

Hipótese P: Modular Monolith (Nossa Escolha Atual)

  • A Ideia: Código isolado logicamente, mas compilado em conjunto.
  • Vantagem: Melhor equilíbrio entre isolamento e facilidade de desenvolvimento. Como nossos domínios já seguem o padrão de MFE (Injeção Dinâmica, Eventos), a migração para Module Federation no futuro será apenas uma mudança de configuração de build, e não uma reescrita de código.

Resumo Comparativo Atualizado

RecursoAbordagem ConvencionalNossa Abordagem (Escala 100M)Motivo da Escolha
EstadoContext / Redux GlobalRedux c/ Injeção DinâmicaPerformance e Memória
Lógica AssíncronauseEffect / ThunksRedux-SagasControle de Race Conditions
OrganizaçãoPor Tipo (folders)Por Domínio (Bounded Contexts)Escalabilidade de Times
ProcessosVariáveis de Status (booleanas)State Machines (XState)Segurança Clínica
DependênciasImportações LivresMonorepo + Boundaries + EventosManutenibilidade e Segurança
RenderizaçãoSSR (Next.js)CSR (SPA) + Lazy LoadingEscala Nacional (Custo/Offline)
EstilizaçãoCSS-in-JS (Runtime)Tailwind/CSS Modules (Zero Runtime)Performance em Celulares
EvoluçãoMicro-Frontends PrematurosModular Monolith (MFE Ready)Simplicidade e Velocidade