← todos os trabalhos

estudo de caso · Serasa Experian · 2025

De uma semana de código a poucas horas de configuração: formulários orientados a schema na Serasa

A Serasa conecta pessoas que estão procurando seguro de carro com seguradoras. Cada seguradora quer as próprias perguntas, e cada novo conjunto de perguntas significava código novo e um deploy novo. Troquei o formulário fixo no código por um formulário orientado a schema. Adicionar uma seguradora deixou de levar no mínimo uma semana de engenharia e passou a levar poucas horas de configuração, feita pelo time de produto.

Papel
Frontend Developer
Parceiros
2 → 10, com mais 2 em onboarding
Onboarding
≥1 semana → poucas horas
Stack
Next.js · React · TypeScript · JSON Schema · REST

Contexto

O produto de seguros da Serasa funciona como um marketplace de leads. A pessoa preenche um pedido de cotação, e a Serasa envia esse lead para as seguradoras que ela escolher. As seguradoras são os parceiros, e as perguntas que elas fazem fazem parte do próprio fluxo de vendas delas. São elas que decidem o que precisam saber antes de fazer uma oferta.

O fluxo tem três etapas:

  1. Sobre você. Um questionário geral sobre o dono do carro e as pessoas que podem dirigi-lo.
  2. Escolha as seguradoras. A pessoa escolhe de quais seguradoras quer receber ofertas.
  3. Perguntas da seguradora. Um questionário específico de cada seguradora escolhida.
  1. step 1Sobre vocêDono e possíveis condutoresigual para todos
  2. step 2Escolha as seguradorasQuem deve enviar ofertaigual para todos
  3. step 3Perguntas da seguradoraDefinidas por cada parceirodiferente por seguradoraSeguradora ASeguradora BSeguradora C…

As etapas 1 e 2 são iguais para todo mundo. A etapa 3 é diferente para cada parceiro.

O formulário estático foi o primeiro passo certo

Começamos com dois parceiros e um formulário escrito à mão. Cada pergunta era um componente no código, com validação e ligação próprias.

Foi a decisão certa. Com dois parceiros, um formulário estático era o jeito mais barato de descobrir se o produto funcionava. Construir uma engine de formulários antes de alguém usar o fluxo seria resolver um problema que ainda não existia.

Onde ele parou de funcionar

O problema apareceu assim que começamos a adicionar parceiros. Cada nova seguradora trazia a própria lista de perguntas. Cada pergunta significava escrever um componente, ligar a validação, mapear a resposta, testar e fazer um deploy. Adicionar um parceiro levava no mínimo uma semana.

O formulário tinha virado o gargalo do negócio. O time comercial conseguia fechar parceiros mais rápido do que a engenharia conseguia integrá-los, e todo pedido de parceiro caía na fila de um dev.

Defendendo a mudança

Ninguém pediu isso. Vi que o formulário estático ia limitar quantos parceiros conseguiríamos receber e continuei levantando o assunto com o time: cada novo parceiro ia custar mais uma semana, e esse custo só ia crescer.

Não foi uma discussão difícil de ganhar, porque o problema estava visível para todo mundo. Faltava alguém dar nome a ele e propor uma saída concreta.

O desenho

A ideia era parar de tratar perguntas como código e começar a tratá-las como dados.

Perguntas como schema

O questionário de cada parceiro é um JSON schema. O front-end lê o schema e renderiza o formulário a partir dele. O time de produto cria e edita schemas por uma página de onboarding, que os salva por uma API de backend em um banco de dados. Um novo parceiro não precisa de deploy no front-end.

// ilustrativo
{
  "id": "garage",
  "type": "radio",
  "label": "O carro fica em garagem à noite?",
  "options": ["sim", "não"],
  "children": {
    "sim": [
      {
        "id": "garage_where",
        "type": "select",
        "label": "Onde?",
        "options": ["casa", "trabalho", "ambos"]
      }
    ]
  }
},
{
  "id": "cep",
  "type": "text",
  "label": "CEP onde o carro fica à noite",
  "mask": "00000-000",
  "validation": { "required": true, "pattern": "^\\d{5}-?\\d{3}$" }
}

Perguntas condicionais como árvore

Questionários de seguro se ramificam o tempo todo. “O carro fica em garagem?” só leva a “Onde?” se a resposta for sim. Então cada pergunta pode ter perguntas filhas ligadas a uma resposta específica, e essas filhas só aparecem quando aquela resposta é escolhida. O formulário é uma árvore, e o renderizador percorre essa árvore.

Validação e máscaras como configuração

Cada pergunta carrega as próprias regras opcionais: uma máscara para coisas como CEP e placa, e validação por regex ou por um dos validadores nativos da biblioteca de formulários. Nada sobre uma pergunta específica fica no código dos componentes.

Uma saída, muitos parceiros

Não importa de qual parceiro são as perguntas, o formulário produz sempre o mesmo formato de saída. Um serviço de backend recebe essa saída e a traduz para o formato de cada parceiro. O front-end nunca precisa saber com qual seguradora está falando.

Produto cria formulários com o formulário

A página de onboarding que o time de produto usa para escrever as perguntas de um parceiro também foi construída com a mesma engine orientada a schema. A ferramenta que cria formulários é um formulário. Isso manteve a engine honesta, porque qualquer limitação aparecia primeiro na nossa própria ferramenta.

formulário orientado a schema · ao vivo

Teste: mude um label, adicione uma opção ou apague uma pergunta.

Formulário renderizado
O carro fica em garagem à noite?
Alguém entre 18 e 25 anos vai dirigir o carro?
Saída enviada ao serviço de integração
{
  "partner": "insurer_c",
  "answers": {
    "garage": "sim",
    "garage_where": "casa",
    "young_driver": "não"
  }
}

Resultados

  • Integrar um parceiro deixou de levar no mínimo uma semana e passou a levar poucas horas.
  • 2 parceiros viraram 10, com mais 2 em onboarding quando saí.
  • Nenhum deploy por parceiro. Um novo questionário é um schema no banco, não uma release.
  • Produto é dono do onboarding. Adicionar um parceiro deixou de ser tarefa de engenharia.

O que aprendi

Olhando para trás, meu primeiro instinto foi pensar “eu teria feito dinâmico desde o começo”. Não acho que isso esteja certo.

O formulário estático validou o negócio gastando pouco. Com dois parceiros, era o desenho correto. A habilidade que importou não foi saber construir uma engine de formulários. Foi perceber o momento em que a solução simples deixou de ser a certa e defender a mudança antes que ela travasse o negócio.

O que eu faria a seguir

Versionamento de schemas. Quando um parceiro muda as perguntas, quem está no meio de uma cotação deveria terminar com a versão em que começou.

Validação antes de publicar. Um schema quebrado deveria ser barrado na página de onboarding, não por um usuário em produção.

Preview ao vivo para produto. O time de produto poderia ver exatamente o formulário que o usuário vai receber enquanto edita o schema, e não só depois de salvar.


Stack: Next.js · React · TypeScript · JSON Schema · REST