8 min

Claude Code para correção de importação/exportação de dados: passos práticos

Claude Code para correção de importação/exportação de dados: defina regras de validação, formatos de erro consistentes e testes de fuzz para importações CSV/JSON e reduza tickets por casos de borda.

Claude Code para correção de importação/exportação de dados: passos práticos

O que dá errado com importações CSV e JSON

As importações raramente falham porque o código está “errado”. Elas falham porque os dados reais são bagunçados, inconsistentes e produzidos por pessoas que nunca viram suas suposições.

Problemas com CSV costumam ser sobre formato e estrutura. Problemas com JSON costumam ser sobre significado e tipos. Ambos podem quebrar de formas que parecem pequenas, mas geram resultados confusos.

Essas questões aparecem repetidamente em tickets de suporte:

  • Campos obrigatórios ausentes (email, id, country) ou colunas renomeadas por alguém “limpando” o arquivo
  • Datas estranhas (01/02/03, 2024-13-01, números seriais do Excel, fusos horários mistos)
  • Colunas extras ou objetos JSON aninhados inesperados adicionados por outra ferramenta
  • Deriva de tipo ("00123" vira 123, true/false vira "yes"/"no")
  • Duplicatas e quase-duplicatas (mesmo id duas vezes, ou a mesma pessoa com caixa diferente)

Correção não é só “foi importado”. Você precisa decidir quais resultados são permitidos, porque os usuários reparam mais em erros silenciosos do que em falhas barulhentas.

A maioria das equipes pode concordar em três desfechos:

  • Accepted: todas as linhas ou registros são válidos e importados
  • Rejected: nada é importado porque o arquivo não é confiável (cabeçalhos errados, codificação ruim, JSON ilegível)
  • Partially accepted: registros válidos são importados, os inválidos são pulados com motivos claros

Casos de borda viram retrabalho quando as pessoas não conseguem dizer o que deu errado ou como corrigir rapidamente. Um cenário comum: um cliente envia um CSV de 5.000 linhas, o importador diz “Invalid format”, e ele tenta de novo três vezes com edições aleatórias. Isso vira vários tickets além de alguém do seu time tentando reproduzir o arquivo localmente.

Defina metas que reduzam o ciclo: menos reenvios, correções mais rápidas, resultados previsíveis. Antes de escrever regras, decida o que “parcial” significa (e se você permite isso), como reportará problemas por linha, e o que os usuários devem fazer em seguida (editar o arquivo, mapear campos ou exportar uma versão corrigida). Se você está usando uma plataforma de geração como Koder.ai (koder.ai) para gerar validadores e testes rapidamente, o contrato de importação ainda é o que mantém esse comportamento consistente conforme o produto evolui.

Decida o contrato de importação antes de escrever regras

Antes de escrever uma única regra de validação, decida o que “entrada válida” significa para seu produto. A maioria dos bugs de importação é um descompasso entre o que os usuários enviam e o que seu sistema assume silenciosamente.

Comece pelos formatos e seja explícito. “CSV” pode significar vírgula ou ponto-e-vírgula, uma linha de cabeçalho ou não, UTF-8 ou “o que o Excel gerou”. Para JSON, decida se aceita um único objeto, um array de registros ou JSON Lines (um objeto JSON por linha). Se aceitar JSON aninhado, defina quais caminhos você lê e quais ignora.

Depois trave o contrato de campos. Para cada campo, decida se é obrigatório, opcional ou opcional com padrão. Padrões fazem parte do contrato, não um detalhe de implementação. Se country faltar, você deixa vazio, escolhe um país específico ou rejeita a linha?

O comportamento de parsing é onde importações “tolerantes” criam dor no longo prazo. Decida desde o início quão estrito você é sobre remover espaços, normalizar caixa e aceitar variantes como "yes"/"true"/"1". Tolerância é aceitável se for previsível e documentada.

Duplicatas são outra decisão de contrato que afeta correção e confiança. Defina o que conta como duplicata (mesmo email, mesmo external_id, ou a combinação de campos), onde você detecta (dentro do arquivo, contra dados existentes, ou ambos) e o que faz quando acontece (manter primeiro, manter último, mesclar ou rejeitar).

Uma checklist de contrato que você pode colar numa especificação:

  • Formatos e codificação aceitos (delimitador CSV, JSON vs JSON Lines, suporte a aninhamento)
  • Regras de campo (obrigatório/opcional/padrões, valores permitidos)
  • Regras de normalização (trim, caixa, formatos de data/número)
  • Definição e tratamento de duplicatas (escopo de detecção, comportamento escolhido)
  • Local de validação (cliente, servidor ou ambos)

Exemplo: importando “customers.” Se email é a chave única, decida se " [email protected] " é igual a "[email protected]", se email ausente é permitido quando external_id existe, e se duplicatas dentro do arquivo devem ser rejeitadas mesmo que o banco não tenha correspondência. Uma vez que esse contrato esteja fixo, comportamento consistente entre UI e API fica muito mais fácil, seja implementado em Koder.ai ou em outro lugar.

Regras de validação que permanecem legíveis e testáveis

Importações bagunçadas frequentemente começam com uma única função gigante validate(). Uma abordagem mais limpa é usar camadas de regras com nomes claros e funções pequenas. Isso torna mudanças mais fáceis de revisar e testes mais fáceis de escrever.

Comece com regras por campo: checam um único valor que pode passar ou falhar sozinho (tipo, intervalo, comprimento, valores permitidos, regex). Mantenha-as simples e previsíveis. Exemplos: email corresponde a um padrão básico, age é um inteiro entre 0 e 120, status é um de active|paused|deleted.

Adicione regras cruzadas apenas onde importam. Essas verificações dependem de múltiplos campos, e bugs se escondem aqui. Exemplos clássicos: startDate deve ser antes de endDate, ou total é igual a subtotal + tax - discount. Escreva essas regras para que possam apontar campos específicos, não apenas “registro inválido”.

Separe regras de nível de registro das de nível de arquivo. Uma regra de nível de registro checa uma linha (CSV) ou um objeto (JSON). Uma regra de nível de arquivo checa o upload inteiro: cabeçalhos necessários existem, uma chave única não se repete entre linhas, contagem de colunas bate com a expectativa, ou o arquivo declara uma versão suportada.

Normalização deve ser explícita, não “mágica”. Decida o que você normaliza antes de validar e documente isso. Exemplos comuns incluem remover espaços, normalização Unicode (para que caracteres visualmente idênticos comparem igual) e formatar telefones em um formato consistente de armazenamento.

Uma estrutura que se mantém legível:

  • Normalize: transforme a entrada bruta em uma forma canônica.
  • Validate fields: checagens pequenas e reutilizáveis por campo.
  • Validate relationships: checagens cruzadas com alvos claros.
  • Validate file rules: cabeçalhos, duplicatas e suporte de versão.
  • Test each layer: testes unitários para cada regra, mais alguns fixtures end-to-end.

Versione suas regras. Coloque um schemaVersion (ou perfil de importação) no arquivo ou na requisição da API. Quando você mudar o que “válido” significa, ainda poderá reimportar exports antigos usando a versão anterior. Essa escolha previne muitos tickets “funcionava ontem”.

Desenhe um formato de erro que as pessoas possam agir sobre

Um bom importador falha de forma útil. Erros vagos levam a reenvios aleatórios e trabalho de suporte evitável. Um formato de erro claro ajuda usuários a corrigir o arquivo rapidamente e ajuda você a melhorar validações sem quebrar clientes.

Comece com um shape de objeto de erro estável e mantenha-o consistente entre CSV e JSON. Você pode usar Claude Code para propor um esquema e alguns exemplos realistas, depois consolidá-lo como parte do contrato de importação.

Um objeto de erro estável

Trate cada erro como um pequeno registro com campos que não mudam. A mensagem pode evoluir, mas o código e a localização devem permanecer estáveis.

  • code: um identificador curto e estável como REQUIRED_MISSING ou INVALID_DATE
  • message: uma frase amigável para a UI
  • path: onde está o problema (ponteiro JSON como /customer/email, ou nome da coluna como email)
  • row ou line: para CSV, inclua número de linha 1-based (e opcionalmente a linha original)
  • severity: pelo menos error e warning

Torne os erros acionáveis. Inclua o que você esperava e o que você realmente viu, e quando possível mostre um exemplo que passaria. Por exemplo: esperado YYYY-MM-DD, recebido 03/12/24.

Agrupamento para UI e depuração

Mesmo que você retorne uma lista plana, inclua dados suficientes para agrupar erros por linha e por campo. Muitas UIs querem “Linha 12 tem 3 problemas” e então destacar cada coluna. Equipes de suporte gostam de agrupar porque padrões ficam óbvios (por exemplo, toda linha está sem country).

Uma resposta compacta pode ficar assim:

{
  "importId": "imp_123",
  "status": "failed",
  "errors": [
    {
      "code": "INVALID_DATE",
      "message": "Signup date must be in YYYY-MM-DD.",
      "path": "signup_date",
      "row": 12,
      "severity": "error",
      "expected": "YYYY-MM-DD",
      "actual": "03/12/24"
    },
    {
      "code": "UNKNOWN_FIELD",
      "message": "Column 'fav_colour' is not recognized.",
      "path": "fav_colour",
      "row": 1,
      "severity": "warning"
    }
  ]
}

Planeje localização sem mudar os códigos de erro. Mantenha code neutro em idioma e durável, e trate message como texto substituível. Se depois você adicionar messageKey ou mensagens traduzidas, clientes antigos ainda podem confiar nos mesmos códigos para filtro, agrupamento e análise.

O que a API de importação deve retornar no sucesso e na falha

Harden your CSV importer
Build parsing, normalization, and header checks for real-world CSV exports without guesswork.

Para evitar “importações misteriosas”, sua resposta de API deve responder duas perguntas: o que aconteceu e o que o usuário deve fazer em seguida.

Retorne um sumário claro da importação (sempre)

Mesmo quando há erros, retorne um resumo consistente para que a UI e as ferramentas de suporte lidem com qualquer importação do mesmo jeito.

Inclua:

  • contagens: created, updated, skipped, failed
  • totalRows (ou totalRecords para JSON)
  • mode (por exemplo: "createOnly", "upsert" ou "updateOnly")
  • timestamps startedAt e finishedAt
  • um correlationId que o suporte possa pedir

Esse correlationId vale muito. Quando alguém relata “não importou”, você encontra a execução exata e o relatório de erros sem adivinhar.

Inclua erros acionáveis, mais uma forma de buscar o relatório completo

Não despeje 10.000 erros de linha na resposta. Retorne uma amostra pequena (por exemplo 20) que mostre o padrão, e forneça um meio separado para recuperar o relatório completo se necessário.

Faça cada erro específico e estável:

  • localização: número da linha (CSV) ou caminho tipo ponteiro JSON (JSON)
  • nome do campo
  • código de erro (legível por máquina)
  • mensagem (legível por humanos)
  • valor rejeitado (cuidado com dados sensíveis)

Exemplo de shape de resposta (sucesso com algumas falhas por linha):

{
  "importId": "imp_01HZY...",
  "correlationId": "c_9f1f2c2a",
  "status": "completed_with_errors",
  "summary": {
    "totalRows": 1200,
    "created": 950,
    "updated": 200,
    "skipped": 10,
    "failed": 40
  },
  "errorsSample": [
    {
      "row": 17,
      "field": "email",
      "code": "invalid_format",
      "message": "Email must contain '@'.",
      "value": "maria.example.com"
    }
  ],
  "report": {
    "hasMore": true,
    "nextPageToken": "p_002"
  },
  "next": {
    "suggestedAction": "review_errors"
  }
}

Note o campo next. Mesmo um payload mínimo de sucesso deve ajudar o produto a avançar: mostrar uma tela de revisão, oferecer uma nova tentativa ou abrir a coleção importada.

Defina idempotência para que reenvios não criem duplicatas

Pessoas reenviam. Redes falham. Se o mesmo arquivo for importado duas vezes, você quer resultados previsíveis.

Seja explícito sobre idempotência: aceite um idempotencyKey (ou calcule um hash do arquivo) e retorne o importId existente se a requisição for repetida. Se seu modo for upsert, defina a regra de correspondência (por exemplo, “email é a chave única”). Se for apenas create, retorne “skipped” para duplicatas, não “created again”.

Use o status certo para falhas, mas mantenha o formato estável

Se a requisição inteira for inválida (auth ruim, content-type errado, arquivo ilegível), falhe rápido e retorne status: "rejected" com uma lista curta de erros. Se o arquivo é válido mas tem problemas por linha, trate como um job completo com failed > 0 para que os usuários possam consertar e reenviar sem perder o resumo.

Como usar Claude Code para gerar regras e exemplos

Um hábito útil: faça o modelo escrever o contrato em formato estruturado, não em prosa. “Parágrafos úteis” muitas vezes pulam detalhes como regras de trim, valores padrão e se célula vazia significa “ausente” ou “vazia”.

Use um prompt que force uma tabela que um humano revise rapidamente e que um desenvolvedor possa transformar em código. Peça a regra de cada campo, exemplos de passe/falha e uma nota explícita para qualquer ambiguidade (por exemplo, string vazia vs null).

You are helping design an importer for CSV and JSON.
Output a Markdown table with columns:
Field | Type | Required? | Normalization | Validation rules | Default | Pass examples | Fail examples
Rules must be testable (no vague wording).
Then output:
1) A list of edge cases to test (CSV + JSON).
2) Proposed test names with expected result (pass/fail + error code).
Finally, list any contradictions you notice (required vs default, min/max vs examples).

Depois do rascunho inicial, aperfeiçoe pedindo um exemplo positivo e um negativo por regra. Isso força cobertura de cantos complicados como strings vazias, valores só com espaço, colunas faltando, null vs "null", inteiros muito grandes, notação científica, IDs duplicados e campos JSON extras.

Para um cenário concreto, imagine importar “customers” de CSV: email é obrigatório, phone é opcional, e signup_date tem padrão hoje se faltar. O modelo deve apontar contradição se você também marcar signup_date como obrigatório. Deve propor testes como import_customers_missing_email_returns_row_error e especificar o código de erro e o formato da mensagem que você retorna.

Faça mais uma revisão antes da implementação: peça ao modelo para reformular as regras como um checklist e apontar onde padrões, campos obrigatórios e normalização podem conflitar. Essa checagem captura muitos comportamentos que virariam tickets.

Passo a passo: testes de fuzz para importações CSV e JSON

Add fuzz testing fast
Generate seed fixtures and fuzz test mutations so weird files become repeatable tests.

Fuzz testing impede que “arquivos estranhos” virem tickets de suporte. Comece com um pequeno conjunto de arquivos válidos, depois gere milhares de variações levemente quebradas e garanta que seu importador reaja de forma segura e clara.

Construa um conjunto seed e depois muteie

Comece com um pequeno corpus seed de exemplos válidos que representem uso real: o menor arquivo válido, um arquivo típico e um arquivo grande. Para JSON, inclua um objeto, muitos objetos e estruturas aninhadas se você as suporta.

Depois adicione um mutador automatizado que mexa em uma coisa por vez. Mantenha as mutações reprodutíveis registrando a seed aleatória para poder reproduzir falhas.

Dimensões de fuzz que pegam a maioria dos problemas reais:

  • Problemas de codificação: UTF-8 com BOM, sequências de bytes inválidas, normalização mista
  • Problemas de estrutura: cabeçalhos ausentes, colunas/fields extras, delimitador errado, vírgulas finais
  • Citação e novas linhas: aspas não fechadas, novas linhas embutidas, CRLF vs LF, escape inconsistente
  • Arestas de tipo: inteiros enormes, NaN/Infinity (JSON), strings vazias vs null, padding de espaço
  • Tamanho e limites: campos muito longos, muitas linhas, chaves repetidas, arrays profundamente aninhados

Não pare na sintaxe. Adicione fuzz semântico também: troque campos semelhantes (email vs username), datas extremas, IDs duplicados, quantidades negativas ou valores que violem enums.

Defina o que “passa” significa, então trave isso

Testes de fuzz só ajudam se critérios de passe forem rígidos. Seu importador nunca deve travar ou ficar pendente, e erros devem ser consistentes e acionáveis.

Um conjunto prático de regras de passe:

  • Sem crashes, timeouts ou picos de memória além do limite
  • Erros claros com ponteiros de linha/campo (CSV) ou caminhos JSON
  • Códigos de erro estáveis entre execuções para a mesma falha
  • Sem escritas parciais a menos que você suporte sucesso parcial explicitamente
  • Importações bem-sucedidas produzem resultados idênticos independentemente de formatações inofensivas (como espaços)

Execute esses testes no CI a cada mudança. Quando encontrar uma falha, salve o arquivo exato como fixture e adicione um teste de regressão para que nunca mais retorne.

Se usar Claude Code para esse trabalho, peça que gere fixtures seed que batam com seu contrato, um plano de mutações e os outputs de erro esperados. Você ainda escolhe as regras, mas obtém uma superfície de testes ampla rapidamente, especialmente para citações em CSV e cantos do JSON.

Armadilhas comuns que causam tickets repetidos

A maioria dos tickets de importação vem de regras pouco claras e feedback não útil.

Uma armadilha comum é parsing “best effort” que não está documentado. Se seu importador remove espaços silenciosamente, aceita vírgula e ponto-e-vírgula, ou adivinha formatos de data, usuários criam fluxos dependentes dessas suposições. Depois uma pequena mudança, ou um gerador de arquivos diferente, quebra tudo. Escolha o comportamento, documente e teste.

Outro causador frequente é mensagem genérica de erro. “Invalid CSV” ou “Bad request” força o usuário a adivinhar. Eles reenviam o mesmo arquivo cinco vezes e o suporte acaba pedindo o arquivo. Erros devem apontar linha, campo, motivo claro e um código estável.

Rejeitar todo o arquivo por uma linha ruim também é ponto de dor. Às vezes isso é correto (imports financeiros onde parcial é perigoso). Muitos imports de negócios podem continuar e reportar um sumário, desde que você ofereça uma escolha explícita como modo estrito vs importação parcial.

Problemas de codificação de texto geram tickets persistentes. UTF-8 é o padrão certo, mas CSVs reais frequentemente incluem BOM, aspas curvas ou espaços sem quebra copiados de planilhas. Trate isso de forma consistente e reporte o que foi detectado para que usuários ajustem suas configurações de exportação.

Por fim, mudar códigos de erro entre versões quebra clientes e automações. Melhore a redação se quiser, mas mantenha códigos e significados estáveis. Só versione quando realmente necessário.

Armadilhas a proteger desde o início:

  • Parsing “best effort” não documentado que muda ao longo do tempo
  • Erros sem ponteiros de linha/campo e sem código de erro estável
  • Importações tudo-ou-nada sem opção estrita vs parcial
  • UTF-8, BOM e caracteres invisíveis não tratados de forma consistente
  • Mudança de códigos de erro que quebram clientes

Exemplo: um cliente exporta um CSV do Excel, que adiciona um BOM e formata datas como 03/04/2026. Seu importador adivinha MM/DD, mas o cliente esperava DD/MM. Se seu relatório de erro inclui o formato detectado, o campo exato e uma sugestão de correção, o usuário corrige sem ida-e-volta.

Checklist rápido antes de liberar um importador

Deploy your import pipeline
Move from prototype to deployment and hosting when your importer is ready to ship.

A maioria dos problemas de importação são pequenos descompassos entre o que os usuários pensam que o arquivo significa e o que seu sistema aceita. Trate isso como um gate de release.

  • Headers e nomes de campo: confirme que colunas obrigatórias estão presentes, nomes batem com suas regras e duplicatas são rejeitadas. Decida o que fazer com colunas extras (ignorar, avisar, falhar) e mantenha consistente.
  • Tipos e formatos de dados: trave como parsear inteiros vs decimais, booleanos (true/false, 0/1, yes/no), datas e timestamps (regras de fuso). Prefira um formato aceito por campo.
  • Null e valores faltantes: defina o que string vazia significa por campo. Separe campo ausente, null explícito e texto em branco.
  • Limites de tamanho e segurança: defina limites de tamanho de arquivo, máximo de linhas e comprimento máximo de campo. Falhe cedo com mensagem clara.
  • Erros determinísticos: a mesma entrada ruim deve produzir o mesmo código de erro e formato de mensagem sempre.

Um teste prático: use um arquivo intencionalmente bagunçado. Exemplo: um CSV onde o cabeçalho aparece duas vezes (dois “email”), um campo booleano usa “Y” e uma data é “03/04/05”. Seu importador não deve adivinhar. Deve aplicar uma regra de mapeamento documentada ou rejeitar com um erro específico.

Duas checagens que times frequentemente pulam:

Primeiro, verifique se seu importador reporta erros com detalhe de localização suficiente para corrigir o arquivo fonte. “Invalid date” não é acionável. “Linha 42, coluna start_date: esperado YYYY-MM-DD, recebeu 03/04/05” é.

Segundo, rode o mesmo arquivo inválido duas vezes e compare resultados. Se a ordem dos erros muda, códigos mudam ou números de linha flutuam, usuários perdem confiança. Comportamento determinístico é chato, e esse é o objetivo.

Um exemplo realista e próximos passos

Um import comum é pedidos de clientes vindo de export de planilha. Alguém exporta um CSV de um sistema antigo, edita no Excel e faz upload. A maioria dos tickets ocorre quando o importador “corrige” dados silenciosamente ou a mensagem de erro não diz o que mudar.

Imagine um arquivo chamado orders.csv com colunas: order_id,customer_email,order_date,currency,total_amount.

Aqui estão três linhas ruins realistas (como o usuário as veria):

order_id,customer_email,order_date,currency,total_amount
A-1001,[email protected],2026-01-05,USD,129.99
A-1002,not-an-email,01/06/2026,USD,49.00
,[email protected],2026-01-07,US, -10

Linha 2 tem email inválido e data ambígua. Linha 3 está sem order_id, tem um código de moeda não suportado (US em vez de USD) e um valor negativo.

Se sua API retorna erros, mantenha o formato consistente e específico. Aqui vai um exemplo de resposta que suporta sucesso parcial:

{
  "correlation_id": "imp_20260109_7f3a9d",
  "import_id": "ord_01HZZ...",
  "status": "partial_success",
  "summary": {
    "total_rows": 3,
    "imported_rows": 1,
    "failed_rows": 2
  },
  "errors": [
    {
      "row_number": 2,
      "field": "customer_email",
      "code": "invalid_email",
      "message": "Email must contain a valid domain.",
      "value": "not-an-email"
    },
    {
      "row_number": 2,
      "field": "order_date",
      "code": "invalid_date_format",
      "message": "Use ISO-8601 (YYYY-MM-DD).",
      "value": "01/06/2026"
    },
    {
      "row_number": 3,
      "field": "order_id",
      "code": "required",
      "message": "order_id is required.",
      "value": ""
    },
    {
      "row_number": 3,
      "field": "currency",
      "code": "unsupported_currency",
      "message": "Allowed values: USD, EUR, GBP.",
      "value": "US"
    },
    {
      "row_number": 3,
      "field": "total_amount",
      "code": "must_be_positive",
      "message": "total_amount must be greater than 0.",
      "value": " -10"
    }
  ],
  "retry": {
    "mode": "upload_failed_only",
    "failed_row_numbers": [2, 3]
  }
}

Sucesso parcial importa porque usuários não devem reenviar o arquivo inteiro. Um fluxo simples de retry é: conserte apenas as linhas com falha, exporte um CSV pequeno contendo as linhas 2 e 3 e reenvie. Seu importador deve tratar isso como idempotente quando order_id estiver presente, assim o “retry” atualiza os mesmos registros em vez de criar duplicatas.

Para suporte, correlation_id é o caminho mais rápido para diagnóstico. Um agente de suporte pode pedir esse único valor, encontrar a execução no log e confirmar se o parser viu colunas extras, delimitador errado ou codificação inesperada.

Próximos passos que tornam isso repetível:

  • Use Claude Code para gerar regras de validação, exemplos de linhas ruins e os códigos/mensagens de erro que deseja padronizar.
  • Transforme esses exemplos em testes automatizados (incluindo testes de fuzz) para que novos cantos virem testes falhos, não novos tickets.
  • Se construir com Koder.ai, use o modo de planejamento para rascunhar o contrato de importação, gerar o validador e os testes, então itere até que o output de erro permaneça consistente entre CSV e JSON.

Perguntas frequentes

Why do CSV and JSON imports fail even when my importer code looks correct?

A maioria das falhas vem de dados do mundo real bagunçados, não de “código ruim”. Problemas com CSV costumam ser sobre formato (cabeçalhos, delimitador, citação, codificação), enquanto problemas com JSON tendem a ser sobre significado (tipos, null vs vazio, aninhamentos inesperados). Trate ambos como entrada não confiável e valide contra um contrato explícito.

Should my importer reject the whole file or allow partial success?

Defina três resultados desde o início:

  • Accepted: tudo foi importado.
  • Rejected: nada é importado porque o arquivo não é confiável (cabeçalhos errados, JSON ilegível, codificação ruim).
  • Partially accepted: registros válidos são importados; os inválidos são ignorados com razões claras.

Escolha um padrão (muitos produtos optam por parcial) e mantenha isso consistente na UI e na API.

What should an “import contract” include?

Escreva um contrato de importação antes de implementar validações:

  • Formatos aceitos (delimitador CSV, cabeçalho obrigatório, tratamento UTF-8/BOM; JSON array vs objeto vs JSON Lines)
  • Regras de campo (obrigatório/opcional/padrões)
  • Normalização (trim, regras de caixa, formatos de data)
  • Definição e tratamento de duplicados
  • Onde a validação ocorre (cliente, servidor ou ambos)

Isso evita surpresas do tipo “funcionava ontem” quando o comportamento muda.

How do I handle weird dates and type drift ("00123" → 123, yes/no booleans)?

Adote um formato inequívoco por campo (por exemplo, datas como YYYY-MM-DD). Se aceitar variantes, deixe isso explícito e previsível (por exemplo, aceite true/false/1/0, mas não todo palpite de planilha). Evite adivinhar datas ambíguas como 01/02/03; exija ISO ou rejeite com um erro claro.

What’s the best way to deal with duplicates during import?

Decida:

  • O que conta como duplicado (email, external_id ou um composto)
  • Escopo de detecção (dentro do arquivo, contra os registros existentes ou ambos)
  • A ação (manter o primeiro, manter o último, mesclar ou rejeitar)

Combine isso com idempotência quando usuários puderem reenviar importações para evitar duplicações.

How should I structure validation rules so they stay readable and testable?

Use camadas em vez de uma única função gigante validate():

  • Normalize a entrada em uma forma canônica
  • Regras por campo (tipo, intervalo, enum)
  • Regras cruzadas (start < end, totais conferem)
  • Regras de arquivo (cabeçalhos obrigatórios, chaves duplicadas, versão suportada)

Regras pequenas e nomeadas são mais fáceis de testar e de alterar com segurança.

What should my error reporting format look like?

Retorne um formato de erro estável com:

  • code (identificador estável)
  • message (texto amigável)
  • path/field (nome da coluna ou ponteiro JSON)
  • row/line (para CSV)
  • severity (error vs warning)

Torne-o acionável incluindo o que era esperado e o que foi recebido sempre que possível.

What should my import API return on success and on failure?

Sempre retorne um resumo consistente, mesmo quando houver erros:

  • contagens: created, updated, skipped, failed, mais totalRows/totalRecords
  • status (success, rejected, completed_with_errors)
  • timestamps (startedAt, finishedAt)
  • um correlationId para suporte/diagnóstico

Para arquivos grandes, inclua uma pequena errorsSample e um meio de recuperar o relatório completo depois.

How do I make imports idempotent so retries don’t create duplicates?

Suporte reenvios explicitamente:

  • Aceite um idempotencyKey (ou use um hash do arquivo)
  • Retorne o importId existente se a mesma requisição for repetida
  • Defina regras de upsert (por exemplo, email é a chave única)

Sem isso, reenvios normais de usuário podem criar duplicatas.

How do I fuzz test CSV/JSON imports without making the test suite unmanageable?

Comece com alguns arquivos seed conhecidos, depois gere muitas mutações pequenas (uma mudança por vez):

  • codificação (UTF-8 BOM, bytes inválidos)
  • estrutura (cabeçalhos ausentes, colunas extras, delimitador errado)
  • citação/quebras de linha (aspas não fechadas, novas linhas embutidas)
  • arestas de tipo (números enormes, vazio vs null, NaN/Infinity em JSON)
  • limites de tamanho (campos muito longos, aninhamento profundo)

Um teste de fuzz “passa” quando o importador nunca trava/fica pendente e sempre retorna erros determinísticos e acionáveis.

Related posts