From a5adcaccaa3628aba1f9299a732d23705112c0c3 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Tue, 6 Oct 2026 21:19:34 +0400 Subject: [PATCH] =?UTF-8?q?docs(2b):=20qa-guide=20=C2=A76.7=20=E2=80=94=20?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D0=BC=D1=8B=20=D0=91=D0=91/=D0=9E=D0=A4?= =?UTF-8?q?=D0=A0,=20=D0=98=D0=9D=D0=9D=20=D0=B2=20=D1=82=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D1=82=D0=B5=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #26 Co-Authored-By: Claude Sonnet 5.5 Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b --- dev/qa-guide.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/dev/qa-guide.md b/dev/qa-guide.md index 28ece19..5b0f70f 100644 --- a/dev/qa-guide.md +++ b/dev/qa-guide.md @@ -17,7 +17,7 @@ Node 24, uv 0.10): от пустого каталога до экрана адм - Журнал аудита в БД (`dkb.audit_event`). - Загрузка файлов ОСВ через API (`POST /legal-entities/{id}/files`), распознавание реальным `tabular-parser`, разбор результата в документы и строки ОСВ, статусы файла и документа, автозамена версий, подтверждение документа, удаление - файла (раздел 6.6); проверка парсера на произвольных форматах ОСВ — раздел 6.7. Всё — через Swagger/curl, UI «Первичные документы» — подсрез 2d. + файла (раздел 6.6); проверка парсера на произвольных форматах ОСВ и формах ББ/ОФР — раздел 6.7 (маппинг форм в ядре — Срез 3). Всё — через Swagger/curl, UI «Первичные документы» — подсрез 2d. - Консолидация через API (Срез 4): версии за период, периметр, блокировка «взять в работу», статусы, привязка подтверждённых документов, чек-лист, сводная ОСВ, ручное сопоставление контрагента, экспорт xlsx (раздел 7; полный прогон на данных РБ и контрольные цифры — 7.1–7.3). UI консолидации — другой исполнитель. @@ -335,7 +335,7 @@ ENV_FILE=.env.test .venv/bin/python -m src.parser.cli "/путь/к/файлу.x | № | Что | Ожидание | |---|---|---| -| P1 | Лист | найден каждый лист с текстом «Оборотно-сальдовая ведомость» (один `documents[]` на лист, `locator = sheet:<имя>`); листы без ОСВ (справки, формы ББ/ОФР) пропущены с `warnings` `skipped: …`, а не ошибка | +| P1 | Лист | найден каждый лист с текстом «Оборотно-сальдовая ведомость» (один `documents[]` на лист, `locator = sheet:<имя>`); листы без ОСВ (справки) пропущены с `warnings` `skipped: …`, а не ошибка; листы форм ББ/ОФР — отдельные документы, см. «Формы ББ/ОФР» ниже | | P2 | Шапка | `organization_name`, `organization_inn` (если есть в шапке), `account_code_raw`, `period_text` → `period_year`, `period_quarter`, `is_cumulative` соответствуют тексту над таблицей. Поле не найдено → `null` + предупреждение, не ошибка | | P3 | Период | «1 квартал» → `Q1`, нарастающий; «2 квартал» → `Q2`, квартальный; «полугодие», «6 месяцев», «январь – июнь» → `Q2`, нарастающий; «9 месяцев», «3 квартал» → `Q3`; «2024 г.», «12 месяцев» → `Q4`, нарастающий; римские кварталы («I кв.») тоже | | P4 | Колонки сумм | шесть сумм разнесены верно: сальдо на начало Дт/Кт, обороты Дт/Кт, сальдо на конец Дт/Кт. Проверьте 2–3 строки с ненулевыми значениями во всех шести колонках и строку «Итого» | @@ -348,12 +348,23 @@ ENV_FILE=.env.test .venv/bin/python -m src.parser.cli "/путь/к/файлу.x **Реальные нестандартные файлы** — `../fixtures/osv-dkb/` (пакет ДКБ 06.10.2026: шесть организаций, многолистовые книги, вариант 2 «сумма», скользящий период, 50 тыс. строк; ожидаемые статусы и находки — `osv-dkb/README.md`) и -`../fixtures/analysis-reports/` («Анализ счета», ожидается `INVALID_DOCUMENT`). **Готовые кейсы синтетики** — синтетика `../fixtures/osv/synthetic/s01…s16` с описанием каждого файла и +`../fixtures/analysis-reports/` («Анализ счета», ожидается `INVALID_DOCUMENT`). **Готовые кейсы синтетики** — синтетика `../fixtures/osv/synthetic/s01…s19` с описанием каждого файла и ожиданием в `../fixtures/osv/synthetic/README.md`: шапка варианта 2 («Период: …», «Субконто»), уровни без outline (только отступами, только по кодам счетов), строки валюты и количества, числа текстом, два листа ОСВ и посторонний лист, нет сальдо на начало и свёрнутое сальдо на конец, колонка КПП, названия субсчетов, сломанная сумма (`needs_check`), повтор заголовка внутри таблицы, лист ББ рядом с ОСВ, xlsb, синонимы заголовков. Прогоните их способом Б и сверьте с README. +**Формы ББ/ОФР (Срез 2b).** Та же команда CLI (способ Б) разбирает и формы: в `documents[]` лист формы — отдельный документ +(`document_type` = `BALANCE` / `INCOME` / `DISCLOSURE`, ОСВ идут первыми), с `header`, `columns[]`, `lines[]`, `checks`. +Что смотреть: `document_type` соответствует форме на листе; `columns[].period_date` — даты колонок слева направо (для ОФР — +конец периода); `checks.relations_failed` (жёсткие соотношения §7 с `expected`/`actual` по колонкам — причина `needs_check`), +`checks.soft_relations_failed` и `duplicate_line_codes`; в `metrics.warnings` — предупреждение об единицах («N значений с +дробной частью при единице тыс. руб.»: значения как в файле, не нормализованы, OQ-137), «колонка кодов не найдена», +«страница-продолжение без шапки». Ожидания по реальным файлам — `../tabular-parser/api/tests/statements_manifest.yaml` и +таблица «файл → статус» в README `tabular-parser`; файлы — `../fixtures/statements-xlsx/` (синтетика `st01…st06`). +Постраничные xls из 1С (страница 2 отдельным файлом, ББ только актив) и формы в рублях при шапке «тыс. руб.» дают +`needs_check` — это штатно (OQ-137, OQ-139), не баг; `done` ожидается только у форм, где §7 сходится (Межениновская). + **Как делать свои файлы.** Возьмите любую реальную ОСВ и меняйте по одному признаку, после каждого — прогон и чек-лист: - сдвинуть таблицу: вставить 5–10 пустых строк и 2–3 колонки слева/сверху; перенести шапку организации ниже или выше; @@ -373,8 +384,8 @@ ENV_FILE=.env.test .venv/bin/python -m src.parser.cli "/путь/к/файлу.x только «Сальдо на начало». - Заголовок с незнакомым синонимом («Нач. остаток») даёт `needs_check`, суммы уходят в `extra`. Это не ошибка кода, а словарь: присылайте файл, синоним добавляется строкой в `rules/osv_headers.yaml`. -- ИНН внутри текста контрагента («Полиграф, 3528315710») и ИНН в ячейке над названием сейчас не извлекаются — задача - RSHB/arm-tabular-parser#9 (OQ-100, OQ-130). До неё строка уходит в ядро с именем целиком, `counterparty_inn` пуст. +- ИНН внутри текста контрагента («Полиграф, 3528315710»), в ячейке над названием и склеенный «ИНН/КПП» парсер извлекает + (OQ-100, OQ-130, arm-tabular-parser#9): `counterparty_inn` заполнен, `counterparty_name` без ИНН, исходный текст — в `row_value`. - xlsb читается без outline level и форматирования: уровни только по отступам пробелами и кодам счетов. Настоящего xlsb из Excel в фикстурах нет (OQ-102) — если у вас есть Excel, сохраните `s02_no_outline_indent.xlsx` как xlsb и прогоните. - Строка «Итого» нужна: без неё `needs_check`.