Appearance
Arquitetura Multi-Persona (Superapp)
Estrutura que prepara o app mobile para servir duas experiências dentro de um único binário Expo (Metro, sem microfrontend remoto): a experiência de Contrato (prestador por contrato, hoje funcional) e a experiência de Tomador (borrower, em construção).
Eixo da arquitetura
| Experiência | Papel (UserRole) | Escopo |
|---|---|---|
| Contrato | provider | Entrada por contrato (/me/provider-contracts). Abas Horas, Compliance, Notas Fiscais, Histórico, Documentos. |
| Tomador | borrower | Área completa de gestão (Dashboard, Contratos, Templates, Monitoramento, Prestadores, Equipe, Relatórios). |
PF/PJ não é eixo de arquitetura. Dentro da experiência de Contrato, a natureza da parte (
legal_entity/natural_person) é um discriminador de domínio derivado decontract_parts(XORcompanyId/userId), nunca uma rota ou módulo separado. Ver../../business/contratos.md.
Rotas (app/)
app/
├── _layout.tsx # Providers + <RootGate/> + Stack[(auth),(access),(main)]
├── (auth)/
│ ├── _layout.tsx
│ └── login.tsx # usa useAuth().login
├── (access)/
│ ├── _layout.tsx
│ └── index.tsx # picker estilo Vue: "Meus contratos" / "Minhas empresas"
└── (main)/
├── _layout.tsx # Stack[contract, borrower]
├── contract/ # experiência atual (URLs /contract/*)
│ ├── _layout.tsx
│ ├── (tabs)/...
│ └── HoursEntry | HoursDetail | InvoiceDetail | InvoiceEmit
│ | ComplianceDetail | Notifications | Settings
└── borrower/ # NOVO scaffold
├── _layout.tsx
└── (tabs)/index.tsxcontract e borrower são segmentos reais (não route groups) para evitar colisão de (tabs) e ambiguidade de rota inicial. URLs: /contract/... e /borrower/....
Gate de navegação (RootGate)
modules/app/components/RootGate decide o redirect a partir do useAuth():
- não autenticado →
/(auth)/login - autenticado sem experiência escolhida →
/(access) - autenticado com experiência →
/contractou/borrower
O AuthContext deixou de renderizar LoginScreen diretamente; ele só expõe estado (isAuthenticated, experience, login, selectExperience, clearExperience). A escolha de experiência é persistida em SecureStore (EXPERIENCE_KEY) e limpa no logout.
Módulos
| Módulo | Responsabilidade |
|---|---|
modules/contract | Experiência de Contrato (refactor de modules/provider). |
modules/borrower | Experiência de Tomador scaffold (stores/services/hooks/components/contexts/screens). |
modules/access | Picker de experiência. Reutiliza getProviderContractsService; tab de empresas é placeholder até o módulo borrower evoluir. |
modules/auth modules/notification | Infra de dominio (auth, push). |
components/ui/ | UI compartilhada entre modulos (shell, layout, primitivos). |
modules/app | Legado — migrar UI para components/ui/ e escopo para modulos donos. |
Pendências do módulo borrower
- Listagem de empresas em
(access)hoje usa a empresa única já persistida noAuthContext; deve ser substituída por uma listagem real quando o móduloborrowerfor implementado. domain/authganhouAppExperience(contract|borrower) eEXPERIENCE_KEY.