O problema
Um SaaS de delivery que precisava atender restaurantes, entregadores e clientes finais sem virar um monolito que faz deploy toda sexta às 2h. Os donos queriam escalar cada superfície independentemente — tráfego de pedido pico no almoço, tracking de entrega constante, pagamento explosivo no fechamento — e separação limpa entre domínios pra o time conseguir shipar features sem pisar no calo um do outro.
Arquitetura
Sete serviços NestJS 11, cada um dono dos próprios dados e contrato, compartilhando padrões mas nunca banco:
pedeja-delivery-{auth, user, catalog, order, payment, notification, delivery}-api
───────────────────────────────────────────────────────────────────────────────
auth sessões · refresh · rotação de token
user perfis · endereços · roles
catalog restaurantes · cardápios · itens · preços
order criação · máquina de estado do lifecycle
payment providers · liquidação · estornos
notification email · push · in-app dispatch
delivery atribuição de entregador · ETA · comprovante
Cada serviço expõe REST versionada documentada via Swagger. Comunicação entre serviços é HTTP pra reads síncronos e filas Redis pra efeitos colaterais assíncronos (notificações, liquidação, atualizações de ETA). Auth centralizada — um único JWT atravessa todos os serviços, validado por request.
Backoffice web
React 19 + Vite 7 com TanStack Router (file-based, code splitting automático) e TanStack Query v5 pro server state. Primitivos UI são shadcn/ui sobre Radix, estilizados com tokens Tailwind v4 customizados. Formulários em React Hook Form + Zod com schemas espelhando os contratos da API. Client state em stores Zustand (auth, UI, theme).
Pra dev local, plantei mocks MSW contra cada serviço — o backoffice boota e exercita toda a UI sem nenhum backend rodando.
Mobile
App do cliente final é Expo / React Native, compartilhando tipos de domínio via cliente gerado — mudança num schema order no backend propaga type-safe pras duas surfaces.
Resultado
Cada serviço deploya independentemente. Adicionar novo método de pagamento toca um serviço e zero outros. Escalar pico de almoço significa escalar só order e payment — resto fica em baseline. Backoffice web shipa features no próprio cadenciamento, desacoplado do release train mobile.