01Contexto
Uma plataforma multi-tenant de gestão de imóveis construída por uma startup americana. Proprietários mantêm um registro vivo da casa: documentos, garantias, um guia para imprimir e um planejador de manutenção que avisa o que precisa de cuidado e quando. Parceiros recebem links de indicação com a própria marca, e o time de operações administra tudo por painéis internos.
Minha parte cobriu as duas pontas do produto. No backend, desenhei e fui dono dos fluxos orientados a eventos que fazem tudo parecer simples: um enriquecimento no estilo ETL que busca registros brutos de imóveis numa API externa, normaliza tudo num formato único e grava no PostgreSQL; a renderização de guias grandes em PDF no Chromium headless; o agendamento dos alertas de garantia e manutenção; e os links curtos que ligam tudo isso. No frontend, desenhei muitas das telas e construí em React, junto com os endpoints NestJS por trás delas, então a mesma pessoa que deu forma aos dados também deu forma a como proprietários e parceiros os veem.
02Restrições
Infraestrutura
Totalmente serverless na AWS, com todos os recursos definidos em Terraform.
Perfil de carga
Relatórios em PDF e enriquecimento de dados são trabalhos lentos e irregulares. Precisavam absorver picos sem nunca segurar uma requisição da API aberta.
Time
Três engenheiros entregando features de produto e infraestrutura juntos, então tudo que construíamos precisava ser barato de rodar e fácil de passar adiante.
03Arquitetura
Guias
Alertas de garantia
Enriquecimento
Links curtos
Downloads grandes
04Decisões
D-01
Renderizar os guias atrás de uma fila
Por quê
Renderizar um PDF no Chromium headless é lento e chega em rajadas. A API confirma na hora e os workers escalam sozinhos.
Custo
A entrega vira assíncrona, então o guia chega por e-mail em vez de ser um download instantâneo.
D-02
Agendar os alertas de garantia com EventBridge
Por quê
Os alertas são disparados por agendamentos e eventos, em vez de um cron varrendo todas as garantias.
Custo
Os agendamentos vivem fora do código da aplicação, então são mais difíceis de testar localmente e de rastrear quando um alerta não dispara.
D-03
Links curtos com DynamoDB e Lambda
Por quê
Cada consulta é uma leitura por chave. Paga por requisição, nada para manter rodando.
Custo
Cold start em links pouco visitados.
D-04
Zipar downloads em lote no navegador, com um worker para arquivos grandes
Por quê
Abaixo de um limite de tamanho, os arquivos saem direto do S3 para um zip montado no cliente, sem job no servidor para rodar ou pagar. Acima dele, um worker monta o zip, guarda no S3 e envia um link de download por e-mail, então um arquivo grande nunca depende do navegador ou da memória do usuário.
Custo
Dois caminhos de código para uma feature e um limite para calibrar. Downloads grandes também deixam de ser instantâneos, porque o link chega por e-mail.
05O que eu mudaria
Eu colocaria tracing de ponta a ponta nas filas desde o primeiro dia. Com o trabalho dividido entre API, EventBridge, SQS e várias Lambdas, seguir um único guia do pedido até a caixa de entrada significava juntar logs na mão.