O problema
A plataforma acumulou três anos de casts com any, tipos parciais e validadores caseiros que divergiam do schema do banco a cada migração. Erro de runtime em produção não era anomalia, era evento programado.
A abordagem
Em vez de remendar a camada de tipos existente, nós a substituímos. A arquitetura passou a usar o schema do banco como fonte única de verdade, com a inferência se propagando para fora até a camada de aplicação.
const ArticleSchema = z.object({
id: z.string().uuid(),
title: z.string().min(1).max(280),
body: z.string(),
publishedAt: z.date().nullable(),
authorId: z.string().uuid(),
});
type Article = z.infer<typeof ArticleSchema>;
A restrição central era simples: nenhuma definição manual de tipo para entidades de domínio. Toda forma é inferida. O compilador vira o validador.
Resultados
- Zero erros de tipo em runtime nos seis meses após o deploy
- Tempo de onboarding para novos engenheiros caiu de duas semanas para três dias
- Divergência entre schema e migração eliminada