11 KiB
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 документ
OSV60 —CONFIRMED,confirmed_byNULL,confirmed_atзаполнен; естьaudit_event(DOCUMENT_CONFIRM)сuser_idNULL и описанием «автоподтверждение: без замечаний»
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 документ
INCOMECONFIRMED,reviewed_byNULL,reviewed_atзаполнен
Scenario: Форма OCR не подтверждается сама
- WHEN смаплен эталон
ocr/expected_normalize/БО 1 кв 2025(уверенность значений < 100, дата отчёта не разобрана) - THEN документы
BALANCEиINCOME—NEEDS_CHECK, неCONFIRMED
Scenario: Файл без загрузившего
- WHEN версия в
INITIATED, ЮЛ в периметре; смаплен чистый результат файла сuploaded_byNULL - THEN документ
CONFIRMEDи привязан к версии; версия осталасьINITIATED; в логе — строка о пропуске перехода
Scenario: Автозамена чистой версией файла
- WHEN документ ОСВ 60 РБ за 2025 Q1 из файла A привязан к версии 2025 Q1; загружен и смаплен файл B того же ключа (чистый), A заменён автозаменой
- THEN привязка документа A снята, документ B
CONFIRMEDи привязан к версии
Scenario: Факт автоподтверждения
- WHEN документ автоподтверждён
- THEN есть
quality_outcome_factAUTO_CONFIRMEDдля этого документа