2026-11-07 04:01:45 +04:00

11 KiB
Raw Blame History

Spec Delta

Purpose

Дельта change quality-metrics (метрики качества первички).

MODIFIED Requirements

Requirement: Цикл маппинга отделён от inbox

Фоновая задача ядра SHALL с периодом MAPPING_POLL_SECONDS (5) выбирать одно задание со status ∈ {done, needs_check}, чей файл имеет status = PROCESSING и current_recognition_job_id = это задание (FOR UPDATE SKIP LOCKED), проверять, что result_s3_object относится к бакету хранилища и его ключ начинается с results/{file_id}/{job_id}/ (OQ-70), читать объект из S3 вне транзакции, валидировать RecognitionResult v1.x и в одной транзакции создать документы и строки (листы ОСВ и формы ББ/ОФР), записать recognition_job.group_schema, перевести файл в PROCESSED и выполнить автозамену. Результат без документов SHALL давать неповторяемую ошибку маппинга «в результате нет документов»; результат с формами, но без ОСВ, ошибкой MUST NOT быть. Inbox MUST NOT читать файл результата и MUST NOT создавать документы. После map_file и до автоподтверждения транзакция маппинга SHALL писать факты приёма quality_intake_fact по документам BALANCE / INCOME / OSV; неповторяемая ошибка маппинга (файл → ERROR) SHALL писать quality_failure_fact (failure_kind = MAPPING, error_code = MAPPING_FAILED).

Scenario: Результат смапплен

  • WHEN в S3 лежит результат парсера для rb/2024-FY/ОСВ_66 за 2024.xls, задание done, файл PROCESSING
  • THEN не позднее чем через MAPPING_POLL_SECONDS + время маппинга файл — PROCESSED, создан один document (OSV, osv_account_code = "66", period_year = 2024, period_quarter = Q4, is_cumulative = true, locator = sheet:Лист_1), osv_entry — все строки результата кроме TOTAL, group_schema задания содержит [{"locator": "sheet:Лист_1", "groups": [...]}]

Scenario: Ключ результата вне папки задания

  • WHEN result_s3_object.key = results/<другой file_id>/.../result.json
  • THEN файл — ERROR с ошибкой маппинга, документы не созданы, повтор не выполняется

Scenario: Сбой маппинга с повтором

  • WHEN вставка строк падает по ошибке БД
  • THEN транзакция откачена, metrics.mapping_attempts = 1, файл остаётся PROCESSING; на третьей неудаче — ERROR с metrics.mapping_error

Scenario: Повторный маппинг идемпотентен

  • WHEN маппинг прерван после частичной вставки (имитация) и выполнен снова
  • THEN у файла ровно один набор документов и строк, дублей по (document_id, row_number) нет

Scenario: Файл только с формами

  • WHEN смаплен golden-снимок mezheninovskaya/2025-Q3/1_Форма1_бух_09 (одна форма BALANCE, ОСВ нет)
  • THEN файл PROCESSED, создан документ BALANCE, ошибки «нет документов ОСВ» нет

Scenario: Пустой результат

  • WHEN результат без документов (documents = []): контракт v1.x такого результата не допускает — его останавливает проверка схемы, а прямой вызов map_file даёт MappingFatal
  • THEN файл ERROR, причина в metrics.mapping_error (при проверке схемы — ошибка схемы, в map_file — «в результате нет документов»), повтор не выполняется

Scenario: Факт приёма в транзакции маппинга

  • WHEN результат смаплен и создан документ ОСВ
  • THEN в той же транзакции записан quality_intake_fact документа до перехода в CONFIRMED

Scenario: Неповторяемая ошибка маппинга

  • WHEN маппинг завершился неповторяемой ошибкой
  • THEN файл ERROR и записан quality_failure_fact с failure_kind = MAPPING

Requirement: Автоподтверждение чистого документа

В транзакции маппинга после автозамены прежних версий файла и до перехода версий по NEEDS_CHECK цикл маппинга SHALL перевести каждый документ файла, получивший при маппинге статус RECOGNIZED, в CONFIRMED (ТЗ 03_9 п. 4, 10_10; решение владельца 08.10.2026, OQ-157): confirmed_by = NULL, confirmed_at = now; у формы BALANCE/INCOME — financial_statement_meta.reviewed_by = NULL, reviewed_at = now; audit_event(DOCUMENT_CONFIRM, PRIMARY_DOCUMENTS, object_type = document) с user_id = NULL, before_value.status = RECOGNIZED, after_value.status = CONFIRMED и description = «автоподтверждение: без замечаний». Форма BALANCE/INCOME с шапкой SHALL подтверждаться автоматически, только если выполнены условия ручного подтверждения (period_year и period_quarter определены, нет непройденных неакцептованных жёстких проверок §7); иначе она MUST оставаться RECOGNIZED без ошибки. Документы NEEDS_CHECK MUST NOT подтверждаться автоматически.

Автоподтверждённый документ SHALL привязываться к версиям так же, как при ручном подтверждении (documents-api «Подтверждение документа»: все подходящие версии «в работе», замена привязки того же ключа R-1), и каждая версия, получившая привязку, из INITIATED или DOCUMENTS_PROCESSING SHALL переходить в DATA_CORRECTION с changed_by = stored_file.uploaded_by и comment = «автоподтверждение документа <document_type> <osv_account_code>» (счёт — только у ОСВ). Если uploaded_by NULL, привязка SHALL создаваться, а переход — пропускаться с записью в лог. Пересчёт статуса формы после правки или акцепта MUST NOT подтверждать документ автоматически. Для каждого автоподтверждённого документа BALANCE / INCOME / OSV SHALL записываться quality_outcome_fact (AUTO_CONFIRMED, primary_cause = WITHOUT_PARTICIPATION, confirmed_by пуст); автозамена прежних версий SHALL писать SUPERSEDED / SUPERSEDED_AFTER_CONFIRM по вытесненным документам.

Scenario: Чистая ОСВ сразу «Загружен»

  • WHEN смаплен результат fixtures/osv/rb/2025-Q1/ОСВ сч 60 за 1 кв 2025 год.xlsx для ЮЛ АО «Русский бисквит» (задание done, шапка совпадает с владельцем, нарушений и предупреждений нет)
  • THEN документ OSV 60 — CONFIRMED, confirmed_by NULL, confirmed_at заполнен; есть audit_event(DOCUMENT_CONFIRM) с user_id NULL и описанием «автоподтверждение: без замечаний»

Scenario: Привязка и переход версии

  • WHEN версия ГК «Русский Бисквит» 2025 Q1 в INITIATED, РБ в периметре; смаплен чистый результат ОСВ 60 РБ за 2025 Q1, файл загрузил ka_go
  • THEN consolidation_document(version, document) создан; версия в DATA_CORRECTION; запись истории INITIATED → DATA_CORRECTION с changed_by = ka_go и комментарием «автоподтверждение документа OSV 60»

Scenario: Документ с замечанием ждёт аналитика

  • WHEN файл ОСВ загружен для ЮЛ «Пекарня Счастливочная», а в шапке АО "Русский бисквит"
  • THEN документ NEEDS_CHECK, confirmed_at пуст, события DOCUMENT_CONFIRM нет, привязки нет

Scenario: Чистая форма Excel

  • WHEN смаплен statements-xlsx/mezheninovskaya/2025-Q3/1_Форма2_бух_09 (ОФР, done, соотношения сходятся, период определён)
  • THEN документ INCOME CONFIRMED, reviewed_by NULL, reviewed_at заполнен

Scenario: Форма OCR не подтверждается сама

  • WHEN смаплен эталон ocr/expected_normalize/БО 1 кв 2025 (уверенность значений < 100, дата отчёта не разобрана)
  • THEN документы BALANCE и INCOME — NEEDS_CHECK, не CONFIRMED

Scenario: Файл без загрузившего

  • WHEN версия в INITIATED, ЮЛ в периметре; смаплен чистый результат файла с uploaded_by NULL
  • THEN документ CONFIRMED и привязан к версии; версия осталась INITIATED; в логе — строка о пропуске перехода

Scenario: Автозамена чистой версией файла

  • WHEN документ ОСВ 60 РБ за 2025 Q1 из файла A привязан к версии 2025 Q1; загружен и смаплен файл B того же ключа (чистый), A заменён автозаменой
  • THEN привязка документа A снята, документ B CONFIRMED и привязан к версии

Scenario: Факт автоподтверждения

  • WHEN документ автоподтверждён
  • THEN есть quality_outcome_fact AUTO_CONFIRMED для этого документа