KoderKoder.ai
ЦеныДля бизнесаОбразованиеДля инвесторов
ВойтиНачать

Продукт

ЦеныДля бизнесаДля инвесторов

Ресурсы

Связаться с намиПоддержкаОбразованиеБлог

Правовая информация

Политика конфиденциальностиУсловия использованияБезопасностьПолитика допустимого использованияСообщить о нарушении

Соцсети

LinkedInTwitter
Koder.ai
Язык

© 2026 Koder.ai. Все права защищены.

Главная›Блог›Claude Code для корректности импорта/экспорта данных: практические шаги
27 дек. 2025 г.·7 мин

Claude Code для корректности импорта/экспорта данных: практические шаги

Claude Code для корректности импорта/экспорта данных: определите правила валидации, единые форматы ошибок и fuzz‑тесты для CSV/JSON, чтобы сократить тикеты по краевым случаям.

Claude Code для корректности импорта/экспорта данных: практические шаги

Что идёт не так при импорте CSV и JSON

Импорты редко ломаются потому, что код «неправильный». Они ломаются потому, что реальные данные грязные, непоследовательные и созданы людьми, которые не видели ваших предположений.

Проблемы с CSV обычно связаны с формой и форматированием. Проблемы с JSON чаще относятся к смыслу и типам. Оба могут ломаться так, что кажется мелочью, но это даёт запутанные результаты.

Эти случаи часто появляются в тикетах поддержки:

  • Отсутствуют обязательные поля (email, id, country) или колонки переименованы кем‑то, кто «очищал» файл
  • Странные даты (01/02/03, 2024-13-01, серийные номера Excel, смешанные часовые пояса)
  • Дополнительные колонки или неожиданные вложенные объекты JSON, добавленные другим инструментом
  • Дрейф типов ("00123" превращается в 123, true/false становится "yes"/"no")
  • Дубликаты и почти‑дубликаты (тот же id дважды, или один и тот же человек с разным регистром)

Корректность — это не только «импортировалось ли». Нужно решить, какие исходы допустимы, потому что пользователи замечают молчаливые ошибки чаще, чем громкие падения.

Большинство команд сходятся на трёх исходах:

  • Accepted: все строки или записи валидны и импортированы
  • Rejected: ничего не импортируется, потому что файл ненадёжен (неверные заголовки, плохая кодировка, нечитаемый JSON)
  • Partially accepted: валидные записи импортируются, невалидные пропускаются с понятными причинами

Крайние случаи превращаются в переработку, когда люди не понимают, что пошло не так и как быстро это исправить. Типичный сценарий: клиент загружает CSV из 5000 строк, импортёр пишет «Invalid format», и он пробует три раза с случайными правками. В итоге — несколько тикетов и кто‑то из вашей команды пытается воспроизвести файл локально.

Поставьте цели, которые сокращают цикл: меньше повторных попыток, быстрее исправления, предсказуемые результаты. До написания правил решите, что значит «частичный» (и разрешаете ли вы его), как вы будете сообщать построчные проблемы и что пользователю делать дальше (править файл, сопоставить поля или экспортировать исправленную версию). Если вы используете платформу вроде Koder.ai (koder.ai) для быстрой генерации валидаторов и тестов, контракт импорта всё равно остаётся тем, что удерживает поведение согласованным по мере развития продукта.

Решите контракт импорта прежде чем писать правила

До того как вы напишете хоть одно правило валидации, договоритесь, что значит «валидный ввод» для вашего продукта. Большинство багов при импорте — это несоответствие ожиданий между тем, что пользователи загружают, и тем, что ваша система молча предполагает.

Начните с форматов и будьте предельно явными. «CSV» может означать запятую или точку‑с запятой, строку заголовка или её отсутствие, UTF-8 или «то, что выдал Excel». Для JSON решите, принимаете ли вы один объект, массив записей или JSON Lines (один объект JSON на строку). Если принимаете вложенный JSON — опишите, какие пути вы читаете, а какие игнорируете.

Затем зафиксируйте контракт по полям. Для каждого поля решите: обязательно, опционально или опционально со значением по умолчанию. Значения по умолчанию — часть контракта, а не техническая деталь. Если country отсутствует, вы подставляете пустое, выбираете конкретную страну или отклоняете строку?

Поведение парсинга — это место, где «терпимые» импорты создают долгосрочные проблемы. Решите заранее, насколько строги вы в вопросах обрезки пробелов, нормализации регистра и приёме вариантов вроде "yes"/"true"/"1". Терпимость допустима, если она предсказуема и задокументирована.

Дубликаты — ещё одно контрактное решение, влияющее на корректность и доверие. Определите, что считается дубликатом (тот же email, тот же external_id, или комбинация полей), где вы его обнаруживаете (внутри файла, относительно существующих данных или и там, и там) и что при этом делаете (оставляете первый, последний, объединяете или отклоняете).

Чеклист контракта, который можно вставить в спецификацию:

  • Допустимые форматы и кодировка (разделитель CSV, JSON vs JSON Lines, поддержка вложенности)
  • Правила по полям (обязательное/опциональное/значения по умолчанию, допустимые значения)
  • Правила нормализации (trim, регистр, форматы дат/чисел)
  • Определение дубликата и обработка (область обнаружения, выбранное поведение)
  • Место валидации (клиент, сервер или оба)

Пример: импорт «customers». Если email — уникальный ключ, решите, равны ли " [email protected] " и "[email protected]", разрешено ли отсутствие email если есть external_id, и нужно ли отклонять дубликаты внутри файла даже если в базе совпадений нет. Как только контракт зафиксирован, согласованное поведение в UI и API становится гораздо проще, независимо от того, реализуете вы это с помощью Koder.ai или иначе.

Правила валидации, которые остаются читабельными и тестируемыми

Грязные импорты часто начинаются с одного огромного validate()‑функции. Более чистый подход — слоистые правила с понятными именами и маленькими функциями. Это упрощает ревью изменений и написание тестов.

Начните с правил на уровне поля: проверка одного значения, которая может пройти или провалиться сама по себе (тип, диапазон, длина, допустимые значения, regex). Держите их скучными и предсказуемыми. Примеры: email соответствует базовому шаблону email, age — целое от 0 до 120, status — одно из active|paused|deleted.

Добавляйте кросс‑полевые правила только там, где это важно. Такие проверки зависят от нескольких полей, и именно там прячутся ошибки. Классические примеры: startDate должен быть раньше endDate, или total равен subtotal + tax - discount. Пишите такие правила так, чтобы они ссылались на конкретные поля, а не просто помечали «запись невалидна».

Отделяйте правила уровня записи от правил уровня файла. Правило уровня записи проверяет одну строку (CSV) или один объект (JSON). Правило уровня файла проверяет весь загрузочный файл: обязательные заголовки присутствуют, уникальный ключ не повторяется, число колонок совпадает с ожиданием, или файл объявляет поддерживаемую версию.

Нормализация должна быть явной, а не «магической». Решите, что нормализуется до валидации, и задокументируйте это. Обычно это обрезка пробелов, нормализация Unicode (чтобы визуально одинаковые символы сравнивались одинаково) и форматирование телефонов в единый формат хранения.

Структура, которая остаётся читабельной:

  • Normalize: привести сырой ввод к канонической форме.
  • Validate fields: маленькие, переиспользуемые проверки по полям.
  • Validate relationships: кросс‑полевые проверки с явными целями.
  • Validate file rules: заголовки, дубликаты и поддерживаемые версии.
  • Test each layer: модульные тесты для каждого правила и несколько end‑to‑end‑фикстур.

Версионируйте правила. Положите schemaVersion (или профиль импорта) в файл или API‑запрос. Когда вы меняете определение «валидного», у вас остаётся возможность реимпортировать старые выгрузки по старой версии. Это одно решение, которое предотвращает множество тикетов «вчера работало».

Спроектируйте формат отчётов об ошибках, с которым люди смогут работать

Хороший импортёр заваливается полезно. Неоднозначные ошибки приводят к случайным повторным заливкам и лишней работе поддержки. Чёткий формат ошибок помогает пользователям быстро исправить файл и даёт вам возможность улучшать валидацию, не ломая клиентов.

Начните со стабильной формы объекта ошибки и держите её одинаковой для CSV и JSON. Можно использовать Claude Code, чтобы предложить схему и примеры, а затем зафиксировать её как часть контракта импорта.

Стабильный объект ошибки

Рассматривайте каждую ошибку как маленькую запись с неизменяемыми полями. Текст сообщения может эволюционировать, но код и местоположение должны оставаться стабильными.

  • code: короткий стабильный идентификатор, например REQUIRED_MISSING или INVALID_DATE
  • message: удобочитаемое предложение для UI
  • path: где проблема (JSON‑pointer вроде /customer/email или имя колонки email)
  • row или line: для CSV указывайте 1‑основанный номер строки (и опционально оригинальную строку)
  • severity: хотя бы error и warning

Делайте ошибки действующими: включайте, что ожидалось и что было фактически, и по возможности приводите пример, который пройдёт. Например: ожидалось YYYY-MM-DD, получили 03/12/24.

Группировка для UI и отладки

Даже если вы возвращаете плоский список, включите данных достаточно для группировки по строкам и полям. Многие UI хотят «Строка 12 имеет 3 проблемы» и подсвечивают соответствующие колонки. Команды поддержки любят группировку — шаблоны становятся очевидными (например, все строки лишены country).

Компактный ответ может выглядеть так:

{
  "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"
    }
  ]
}

Планируйте локализацию, не меняя коды ошибок. Держите code нейтральным к языку и долговечным, а message — заменяемым. Позже вы можете добавить messageKey или переводы, но старые клиенты всё равно будут полагаться на те же коды для фильтрации, группировки и аналитики.

Что API импорта должен возвращать при успехе и при ошибке

Bring others onto the project
Invite teammates or peers with a referral link and build your importer together in Koder.ai.
Refer Friends

Чтобы избежать «загадочных» импортов, ответ API должен отвечать на два вопроса: что произошло и что пользователь должен сделать дальше.

Возвращайте ясное резюме импорта (всегда)

Даже при наличии ошибок возвращайте согласованное резюме, чтобы UI и инструменты поддержки могли одинаково обрабатывать все импорты.

Включайте:

  • created, updated, skipped, failed — счётчики
  • totalRows (или totalRecords для JSON)
  • mode (например: createOnly, upsert или updateOnly)
  • startedAt и finishedAt — временные метки
  • correlationId, который поддержка может запросить

Этот correlationId стоит внедрить — когда кто‑то пишет «не импортировалось», вы можете найти конкретный прогон и отчёт об ошибках без догадок.

Включайте действующие ошибки и способ получить полный отчёт

Не высыпайте 10 000 ошибок строк в ответ. Возвращайте небольшой сэмпл (например, 20), который показывает шаблон, и предоставляйте отдельный способ получить полный отчёт при необходимости.

Делайте каждую ошибку специфичной и стабильной:

  • местоположение: номер строки (CSV) или путь в стиле JSON‑pointer (JSON)
  • имя поля
  • код ошибки (машиночитаемый)
  • сообщение (для человека)
  • отклонённое значение (осторожно с чувствительными данными)

Пример формы ответа (успех с некоторыми проваленными строками):

{
  "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"
  }
}

Обратите внимание на поле next. Даже минимальный успешный ответ должен помогать продукту двигаться дальше: показать экран обзора, предложить повторную загрузку или открыть импортированную коллекцию.

Определите идемпотентность, чтобы повторные загрузки не создавали дублей

Люди повторяют попытки. Сети падают. Если тот же файл загружен дважды, вы хотите предсказуемое поведение.

Будьте явными по части идемпотентности: принимайте idempotencyKey (или вычисляйте хэш файла) и возвращайте существующий importId, если запрос повторён. Если режим — upsert, определите правило сопоставления (например, «email — уникальный ключ»). Если это create‑only, возвращайте «skipped» для дубликатов, а не «created" снова.

Используйте правильный статус при ошибках, но держите форму ответа стабильной

Если весь запрос недействителен (плохая аутентификация, неверный content type, нечитаемый файл), быстро отклоняйте с status: "rejected" и коротким списком ошибок. Если файл валиден, но есть проблемные строки, рассматривайте задачу как завершённую с failed > 0, чтобы пользователи могли исправить и повторно загрузить без потери резюме.

Как использовать Claude Code для генерации правил и примеров

Полезная привычка: заставьте модель писать контракт в структурированном формате, а не в виде абзацев. «Полезные параграфы» часто пропускают детали вроде правил обрезки, значений по умолчанию и того, означает ли пустая ячейка «отсутствует» или «пусто».

Используйте промпт, который вынуждает вывести таблицу, удобную для быстрого просмотра человеком и пригодную для конвертации в код. Просите для каждого поля правила, примеры pass/fail и явную заметку по неоднозначным ситуациям (например, пустая строка 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).

После первого варианта ужесточите требования, попросив по одному положительному и одному отрицательному примеру для каждого правила. Это расширит покрытие трюковых углов: пустые строки, строки только из пробелов, отсутствующие колонки, null vs "null", очень большие целые, научная нотация, дублирующиеся ID и дополнительные поля JSON.

Для конкретного сценария: импорт «customers» из CSV: email обязателен, phone опционален, signup_date по умолчанию — сегодня при отсутствии. Модель должна указать противоречие, если вы одновременно утверждаете «signup_date обязателен». Она должна предложить тесты вроде import_customers_missing_email_returns_row_error и указать код ошибки и форму сообщения, которую вы возвращаете.

Сделайте ещё один проход перед реализацией: попросите модель восстановить правила в виде чеклиста и указать, где значения по умолчанию, обязательность и нормализация могут конфликтовать. Этот шаг часто ловит поведение, которое потом выльется в тикеты поддержки.

Пошагово: fuzz‑тесты для CSV и JSON импорта

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

Fuzz‑тестирование предотвращает превращение «странных файлов» в тикеты поддержки. Начните с небольшого набора корректных файлов, затем генератором создайте тысячи слегка «ломаных» вариантов и убедитесь, что импортёр реагирует безопасно и понятно.

Постройте набор образцов, затем мутируйте

Начните с минимального набора валидных примеров, которые представляют реальное использование: самый маленький валидный файл, типичный файл и большой файл. Для JSON включите один объект, много объектов и вложенные структуры, если вы их поддерживаете.

Далее добавьте автоматический мутатор, который меняет по одному параметру. Держите мутации воспроизводимыми, логируя случайное зерно, чтобы воспроизвести ошибки.

Измерения фазаф‑мутаций, которые ловят большинство проблем:

  • Проблемы кодировки: UTF-8 с BOM, недопустимые байтовые последовательности, смешанная нормализация
  • Проблемы структуры: отсутствующие заголовки, лишние колонки/поля, неверный разделитель, завершающие запятые
  • Кавычки и переносы строк: незакрытые кавычки, встроенные переводы строк, CRLF vs LF, непоследовательное экранирование
  • Типовые края: огромные целые, NaN/Infinity (JSON), пустые строки vs null, пробельные паддинги
  • Размер и лимиты: очень длинные поля, много строк, повторяющиеся ключи, глубоко вложенные массивы

Не останавливайтесь на синтаксисе. Добавьте семантический fuzz: поменяйте похожие поля местами (email vs username), экстремальные даты, дублированные ID, отрицательные количества или значения, нарушающие enum.

Определите, что значит «прошёл», и зафиксируйте это

Fuzz‑тесты помогают только при жёстких критериях прохождения. Ваш импортёр никогда не должен падать или зависать, а ошибки должны быть последовательными и полезными.

Практический набор правил прохождения:

  • Никаких падений, таймаутов или всплесков памяти сверх лимита
  • Понятные ошибки с указанием строки/поля (CSV) или JSON‑пути
  • Стабильные коды ошибок между запусками для одинаковой ошибки
  • Никаких частичных записей, если вы явно этого не поддерживаете
  • Успешные импорты дают одинаковый результат независимо от безобидного форматирования (например, пробелы)

Запускайте эти тесты в CI при каждом изменении. Когда вы находите сбой, сохраните точный файл как фикстуру и добавьте регрессионный тест, чтобы он больше не возвращался.

Если вы используете Claude Code для этого, попросите модель сгенерироватьseed‑фикстуры, план мутаций и ожидаемые выходы ошибок. Вы всё ещё решаете правила, но быстро покрываете большую поверхность тестов, особенно для кавычек в CSV и краёв JSON.

Частые ловушки, вызывающие повторяющиеся тикеты поддержки

Большинство тикетов по импорту происходит из‑за неясных правил и неинформативных сообщений.

Одна распространённая ловушка — «best effort» парсинг, который не задокументирован. Если импортёр тихо обрезает пробелы, принимает запятые и точки‑с‑запятыми или угадывает форматы дат, пользователи выстраивают рабочие процессы вокруг этих догадок. Малое изменение или другой генератор файлов ломают всё. Выберите поведение, задокументируйте и протестируйте его.

Другой частый виновник — общее сообщение об ошибке. «Invalid CSV» или «Bad request» заставляет пользователей гадать. Они загружают тот же файл пять раз, а поддержке приходится просить файл. Ошибки должны указывать строку, поле, конкретную причину и стабильный код.

Отклонение всего файла из‑за одной плохой строки тоже обычная боль. Иногда это правильно (финансовые импорты, где частичный успех опасен). Многие бизнес‑импорты могут продолжать и выдавать сводку, если вы явно предлагаете режим strict vs partial.

Проблемы с кодировкой текста создают упорные тикеты. UTF-8 — правильный дефолт, но реальные CSV часто содержат BOM, фигурные кавычки или неразрывные пробелы, скопированные из таблиц. Обрабатывайте это последовательно и указывайте, что вы обнаружили, чтобы пользователь мог изменить настройки экспорта.

Наконец, изменение кодов ошибок между релизами ломает клиентов и автоматизации. Улучшайте формулировки, если нужно, но держите коды и их смысл стабильными. Версионируйте только когда действительно необходимо.

Стоит защититься от следующих ловушек заранее:

  • Незаписанная «best effort» логика парсинга, которая со временем меняется
  • Ошибки без указания строки/поля и без стабильного кода
  • Полное отклонение вместо выбора strict vs partial
  • Непоследовательная обработка UTF-8, BOM и невидимых символов
  • Изменение кодов ошибок, ломающее клиентскую логику

Пример: клиент экспортирует CSV из Excel, который добавляет BOM и форматирует даты как 03/04/2026. Ваш импортёр угадывает MM/DD, а клиент ожидал DD/MM. Если в отчёте ошибок вы укажете обнаруженный формат, точное поле и предложенное исправление, пользователь сможет поправить экспорт без лишних кругов.

Быстрый чеклист перед выпуском импортёра

Own the importer code
Keep full control by exporting the generated source code and adapting it to your stack.
Export Code

Большинство проблем импорта — небольшие расхождения между тем, что пользователи думают про файл, и тем, что система принимает. Рассматривайте это как релизный критерий.

  • Заголовки и имена полей: подтвердите наличие обязательных колонок, совпадение имён с правилами и отклоняйте дубликаты. Решите, что делать с лишними колонками (игнорировать, предупреждать, отклонять) и придерживайтесь этого.
  • Типы данных и форматы: зафиксируйте парсинг целых vs десятичных, булевых (true/false, 0/1, yes/no), дат и временных меток (правила по часовым поясам). Предпочитайте один принятый формат на поле.
  • Null и отсутствующие значения: определите, что значит пустая строка для каждого поля. Разграничьте отсутствующее поле, явный null и пустой текст.
  • Лимиты по размерам и безопасности: задайте лимиты для размера файла, максимального числа строк и длины поля. Отклоняйте заранее с понятным сообщением.
  • Детерминированные ошибки: один и тот же плохой ввод должен давать одинаковый код ошибки и форму сообщения каждый раз.

Практический тест: возьмите преднамеренно «мусорный» файл. Например: заголовок повторяется дважды (две колонки email), булево поле использует Y, а дата в виде 03/04/05. Ваш импортёр не должен угадывать. Он либо применит задокументированное правило маппинга, либо отклонит с конкретной ошибкой.

Два проверки, которые команды часто пропускают:

Во‑первых, убедитесь, что импортёр сообщает ошибки с достаточной детализацией местоположения, чтобы исправить исходный файл. «Invalid date» неинформативно. «Строка 42, колонка start_date: ожидалось YYYY-MM-DD, получили 03/04/05» — уже можно исправить.

Во‑вторых, прогоните один и тот же неверный файл дважды и сравните результаты. Если порядок ошибок меняется, коды меняются или номера строк сдвигаются — пользователи теряют доверие. Детерминированность — это скучно, и в этом её сила.

Реалистичный пример сценария и дальнейшие шаги

Обычный реальный импорт — заказы клиентов из экспортированной таблицы. Кто‑то экспортирует CSV из старой системы, правит в Excel, затем загружает. Большинство тикетов возникает, когда импортёр молча «исправляет» данные, или сообщение об ошибке не говорит, что менять.

Представьте файл orders.csv со столбцами: order_id,customer_email,order_date,currency,total_amount.

Вот три реалистичных ошибочных строки (как их увидит пользователь):

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

В строке 2 — неверный email и неоднозначный формат даты. В строке 3 — отсутствует order_id, неподдерживаемый код валюты (US вместо USD) и отрицательная сумма.

Если API возвращает ошибки, держите форму ответа согласованной и конкретной. Пример ответа, поддерживающего частичный успех:

{
  "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]
  }
}

Частичный успех важен, ведь пользователям не нужно заново загружать весь файл. Простой поток повторной попытки: исправить только проваленные строки, экспортировать маленький CSV со строками 2 и 3 и повторно загрузить. Импортёр должен обрабатывать это идемпотентно, если order_id присутствует, чтобы «повтор» обновлял те же записи, а не создавал дубликаты.

Для поддержки correlation_id — самый быстрый путь к диагностике. Агент поддержки просит единственное значение, находит прогон в логах и подтверждает, видел ли парсер лишние колонки, неверный разделитель или неожиданную кодировку.

Дальнейшие шаги, которые делают процесс повторяемым:

  • Используйте Claude Code для генерации правил валидации, примеров ошибочных строк и стандартных кодов/сообщений.
  • Превратите эти примеры в автоматические тесты (включая fuzz‑тесты), чтобы новые крайние случаи становились падающими тестами, а не новыми тикетами.
  • Если вы строите на Koder.ai, используйте режим планирования для черновика контракта импорта, генерации валидатора и тестов, затем итеративно доводите выход ошибок до согласованной формы между CSV и JSON.

FAQ

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

Большинство сбоев происходят из-за «грязных» данных, а не из-за «плохого кода». Проблемы с CSV чаще связаны с формой (заголовки, разделитель, кавычки, кодировка), тогда как с JSON — с смыслом (типы, null vs пустая строка, неожиданная вложенность). Рассматривайте оба формата как недоверенный ввод и валидируйте по явному контракту.

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

Определите три возможных исхода заранее:

  • Accepted: всё импортировано.
  • Rejected: ничего не импортируется — файл нельзя считать надёжным (неверные заголовки, нечитаемый JSON, плохая кодировка).
  • Partially accepted: валидные записи импортируются, невалидные пропускаются с понятной причиной.

Выберите поведение по умолчанию (многие продукты выбирают partial) и сделайте его единообразным в UI и API.

What should an “import contract” include?

Пропишите import contract до написания правил валидации:

  • Допустимые форматы (CSV: разделитель, обязательность заголовка, BOM/UTF-8; JSON: массив vs объект vs JSON Lines)
  • Правила по полям (обязательное/опциональное/значение по умолчанию)
  • Нормализация (trim, правила регистра, форматы дат)
  • Обработка дубликатов
  • Где выполняется валидация (клиент, сервер или оба)

Это предотвращает сюрпризы «вчера работало, сегодня нет».

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

Предпочитайте один однозначный формат на поле (например, даты в YYYY-MM-DD). Если вы принимаете варианты, оговорите их явно и предсказуемо (например, true/false/1/0, но не все «угадайки» из таблиц). Избегайте интерпретации неоднозначных дат вроде 01/02/03 — либо требуйте ISO, либо возвращайте понятную ошибку.

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

Решите заранее:

  • Что считать дубликатом (email, external_id или композитный ключ)
  • Область обнаружения (внутри файла, относительно базы данных или обе)
  • Действие (оставить первый, оставить последний, объединить, отклонить)

Комбинируйте это с идемпотентностью — тогда повторная загрузка не создаст дубликатов.

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

Разбейте валидацию на слои вместо одного большого validate():

  • Normalize: привести сырые данные к канонической форме
  • Field-level rules: тип, диапазон, enum
  • Cross-field rules: зависимости между полями
  • File-level rules: заголовки, дубликаты, версия схемы
What should my error reporting format look like?

Возвращайте стабильную форму ошибки с полями:

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

Всегда возвращайте согласованное резюме, даже при ошибках:

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

Поддерживайте повторные попытки явно:

  • Принимайте idempotencyKey (или используйте хэш файла)
  • Возвращайте существующий importId для повторного запроса
  • Определите правила upsert (например, email как уникальный ключ)

Иначе обычные повторные загрузки могут создать дубликаты.

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

Начните с небольшого набора валидных файлов-образцов, затем генерируйте мутации по одной в каждом тесте:

  • кодировка (UTF-8 BOM, битовые ошибки)
  • структура (отсутствующие заголовки, лишние колонки, неверный разделитель)
  • кавычки/переносы строк (незакрытые кавычки, встроенные переводы строки)
  • краевые типы (очень большие числа, пустое vs null, NaN/Infinity в JSON)
  • ограничения размера (длинные поля, глубокая вложенность)

Тест считается пройденным, если парсер не падает/не зависает и возвращает детерминированные, понятные ошибки.

Содержание
Что идёт не так при импорте CSV и JSONРешите контракт импорта прежде чем писать правилаПравила валидации, которые остаются читабельными и тестируемымиСпроектируйте формат отчётов об ошибках, с которым люди смогут работатьЧто API импорта должен возвращать при успехе и при ошибкеКак использовать Claude Code для генерации правил и примеровПошагово: fuzz‑тесты для CSV и JSON импортаЧастые ловушки, вызывающие повторяющиеся тикеты поддержкиБыстрый чеклист перед выпуском импортёраРеалистичный пример сценария и дальнейшие шагиFAQ
Поделиться
Koder.ai
Создайте свое приложение с Koder сегодня!

Лучший способ понять возможности Koder — попробовать самому.

Начать бесплатноЗаказать демо

Малые именованные правила легче тестировать и безопаснее менять.

  • code (стабильный идентификатор)
  • message (для человека)
  • path/field (имя колонки или JSON-путь)
  • row/line (для CSV)
  • severity (error vs warning)
  • Делайте ошибки действующими: где возможно, указывайте что ожидалось и что получили.

  • счётчики: created, updated, skipped, failed, плюс totalRows/totalRecords
  • status (success, rejected, completed_with_errors)
  • временные метки (startedAt, finishedAt)
  • correlationId для поддержки
  • Для больших файлов возвращайте маленькую errorsSample и способ получить весь отчёт позже.