AAMLabs (atual Forge Labs) · Engenheiro full-stack, lead de backend

FortCred Financial

Gestão de contratos de empréstimo para uma factory financeira — 394+ clientes, 1.100+ contratos, ~20 mil faturas, R$1M+ transacionados em produção.

Cliente
AAMLabs (atual Forge Labs)
Papel
Engenheiro full-stack, lead de backend
Período
2024 – 2025

O problema

Uma factory financeira rodava a operação de empréstimos em planilhas e ferramentas improvisadas. O volume já era expressivo — centenas de tomadores, milhares de contratos, ciclos mensais de fatura, conciliação manual de mora e dunning — e cada passo manual era um lugar onde dinheiro escapava ou compliance quebrava.

O sistema precisava cobrir o ciclo completo: onboarding de cliente, fluxo de aprovação de pedido, geração automática de parcelas, acumulação de juros e mora diária, dunning via WhatsApp, fluxos de renegociação, e trilha de auditoria CRM-like por tomador.

Arquitetura

Monorepo com API em NestJS 11 e frontend em Next.js 15, compartilhando banco PostgreSQL via Prisma 6. Trabalho de background em BullMQ + Redis; mensagens WhatsApp via Evolution API.

   ┌─ Next.js 15 + React 19 ─────────────────────────┐
   │  TanStack Query · Radix UI · Tailwind 4         │
   │  JWT em cookies HTTP-only (withCredentials)     │
   └──────────────────┬──────────────────────────────┘
                      │ axios (tipado via Zod)
   ┌─ API NestJS 11 ──┴──────────────────────────────┐
   │  Auth · Clientes · Pedidos · Faturas · Pagtos   │
   │  Renegociações · Comunicação · Dashboard        │
   └──────┬───────────────────────────────┬──────────┘
          │                               │
     PostgreSQL                  BullMQ + Redis ─→ Evolution API
     (Prisma 6)                  (fila whatsapp-messages)
                                  ├─ delay random 5–15s
                                  ├─ 3 retries, backoff exp.
                                  └─ CommunicationLog

Jobs diários (timezone Brasil)

O scheduler roda três jobs em America/Sao_Paulo, em ordem:

  • 05:00 — processamento de inadimplência: faturas com dueDate < hoje recebem o lateFee% configurado, status vira UNPAID, totais do pedido atualizam.
  • 05:01 — acumulação de mora: (lateFeeMora% / 30) × valor_original × dias_em_atraso somado diariamente. Renegociações sempre compõem sobre o valor do pedido original, não o renegociado — regra financeira não-óbvia que importa pra compliance.
  • 06:00 (somente dias úteis) — mensagens de cobrança: agrupa faturas em atraso e vencendo hoje por pedido, enfileira lembretes WhatsApp via Evolution API.

Cada um dos três tem entrypoint manual de recovery pra replays sem disparar efeitos colaterais acidentais.

Modelagem de domínio

A máquina de estados financeira mapeia pra um enum tipado do Prisma: OPEN → APPROVED → ACTIVE → PAID / RENEGOTIATED / UNAPPROVED / LOST. O dashboard lê agregados cacheados (cachedTotalValuePaid, cachedTotalValueToBreakeven, metricsLastUpdated) — views de portfólio ficam sub-100ms mesmo com milhares de contratos ativos.

Controle de acesso por departamento — LOAN_MANAGEMENT, STREET_SUPERVISOR, RENEGOTIATION_ANALYST, com SUPER_ADMIN override. Roles passam por AuthGuard + RolesGuard em cada controller.

Resultado

Em produção. A factory opera inteiramente dentro do sistema — sem planilhas — e as filas dão conta do ciclo diário sem intervenção humana. Os números acima são contagens vivas.

Números

  • R$1M+

    Transacionado

  • ~20 mil

    Faturas geradas

  • 1.100+

    Contratos cadastrados

  • 394+

    Clientes onboardados

Stack

  • NestJS 11
  • Next.js 15
  • React 19
  • Prisma 6
  • PostgreSQL
  • BullMQ
  • Redis
  • Evolution API (WhatsApp)
  • JWT + cookies HTTP-only
  • TanStack Query
  • Radix UI
  • Tailwind 4