# ADR-012: Data Consistency and Partial Load Model ## Status Accepted ## Context Система загружает данные из внешних государственных и смежных источников, которые могут: - быть нестабильны - отдавать большие объёмы данных - завершаться по таймауту - менять формат ответа - содержать частично поврежденные записи - быть доступны только частично на момент синхронизации Загрузка может выполняться: - по периоду - по файлам - по внешним реестрам - в инкрементальном режиме На практике возможно частичное успешное выполнение: - часть записей уже сохранена, часть ещё нет - файл обработан наполовину - один источник за период обработался, второй — нет - FZ-248 успешно загружен, а FZ-294 завершился ошибкой - часть данных валидна, часть — нет Без явной модели частичной загрузки система становится трудно восстанавливаемой и операционно непрозрачной. ## Decision Проект принимает модель controlled partial progress. Это означает: - частично выполненная загрузка допустима - частичный прогресс должен быть наблюдаем и восстанавливаем - повторный запуск должен быть безопасен - состояние загрузки должно быть определимо без ручного анализа базы ### Основные правила 1. Единицей согласованности является не "вся система целиком", а отдельная операция загрузки: - период - файл - тип источника - подтип данных - конкретная синхронизационная задача 2. Частичная загрузка допустима только если: - данные записываются идемпотентно - можно безопасно повторить обработку - есть способ определить статус операции 3. Полный rollback всей загрузки не является обязательным требованием. Вместо этого используется повторяемая и безопасная модель дозагрузки/перезапуска. ### Модель фиксации состояния Для каждой операции загрузки система должна уметь определить: - что именно загружалось - за какой период или из какого файла - когда началась обработка - завершилась ли она успешно - была ли частичная ошибка - можно ли безопасно повторить запуск Предпочтительная гранулярность статусов: - pending - running - partial - failed - completed ### Правила работы с частичными данными - уже сохраненные валидные данные не удаляются автоматически только из-за того, что операция завершилась частично - повторный запуск обязан корректно переиспользовать уже записанные сущности - повреждённые или невалидные записи должны логироваться отдельно - ошибка части набора данных не должна молча скрываться как общий успех ### Периодическая синхронизация Для периодических источников (например, месячные загрузки): - период считается завершённым только после явной успешной фиксации - отсутствие новых записей само по себе не всегда считается ошибкой - для "пустых" периодов допустима отдельная бизнес-логика подтверждения отсутствия данных ### Работа с файлами Для file-based ingestion: - файл должен иметь трассируемый жизненный цикл - необходимо различать: - файл получен - файл распознан - файл обработан успешно - файл обработан частично - файл отклонён - перемещение файла в processed или failed является частью операционного контракта ## Consequences ### Positive - система сохраняет управляемость при partial failures - упрощается восстановление после ошибок - уменьшается потребность в ручной чистке данных - повышается наблюдаемость загрузок и синхронизаций - упрощается повторный запуск задач по периоду или файлу ### Negative - модель состояний усложняется - требуется более аккуратный job tracking - появляется необходимость различать "partial" и "failed" - возрастает ответственность сервисного слоя за корректную фиксацию статусов ## Alternatives considered ### 1. Полная транзакционность всей синхронизации Отклонено, так как для больших и внешних ETL-процессов это дорого, хрупко и часто нереализуемо. ### 2. Игнорировать частичный прогресс и считать любую ошибку полным провалом Отклонено, так как приводит к потере уже обработанного полезного результата и затрудняет recovery. ### 3. Append-only ingestion без статусов операции Отклонено, так как делает систему непрозрачной и плохо сопровождаемой. ## Notes Это решение напрямую зависит от: - ADR-011 Idempotency and Retry Strategy - ADR-013 Parser Stability and Source Change Detection