Спеки consolidated-osv-ui, consolidation-setup, document-review-ui, primary-files-ui и архив changes demo-prototype, statements-v2. Каталоги архива statement-template-lines и console-files в arm-core уже заняты другими изменениями и не переносились. Ссылки на ../arm-web/openspec в CLAUDE.md и web/CLAUDE.md заменены на openspec/specs/*-ui. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8.4 KiB
consolidated-osv-ui Specification
Purpose
Аналитик видит сводную ОСВ версии [30]: сводку с несопоставленными строками, пробелы по кварталам, таблицу с фильтрами в заголовках колонок и экспорт в xlsx; сопоставляет контрагента строки с ЮЛ справочника [32].
Requirements
Requirement: Сводка версии
Экран «Сводная ОСВ» [30] SHALL показывать шапку версии (ГК, период, номер, статус) и сводку
GET /consolidations/versions/{id}/osv/summary: строк всего, документов, несопоставленных (unmapped_total — счётчик
«Осталось N» — строки без сопоставленного ЮЛ и без ИНН из файла, arm-core #74; сопоставление — «Указать» в строке),
автоматически сопоставленных.
Scenario: Контрольные цифры РБ 2024 Q3
- WHEN открыт свод версии РБ 2024 Q3 после подтверждения 22 ОСВ из
fixtures/osv/{rb,schastl}/2024-Q{1,2,3} - THEN «строк» = 1385, «документов» = 22, «несопоставленных» = 1260
Requirement: Таблица свода и фильтры
Экран SHALL показывать строки GET /consolidations/versions/{id}/osv постранично (размер страницы ≤ 2000): ЮЛ, счёт,
контрагент, ИНН контрагента, сальдо на начало Дт/Кт, обороты Дт/Кт, сальдо на конец Дт/Кт (суммы — строками с
разделителями разрядов) и последней колонкой «Тип контрагента» — бейдж ГСК (синий) / ГК (зелёный) / Внешний (серый), как
в макете [30]. Фильтры — в заголовках колонок: ЮЛ (legal_entity_id), корень счёта (account_root), поиск по
контрагенту (q, ≤ 500 символов), тип контрагента (counterparty_type, одно значение — на колонке «Тип контрагента»);
только несопоставленные (unmapped) — кнопкой «Показать ЮЛ без ИНН» в баннере и воронкой колонки «ИНН» (подсвечена,
пока фильтр включён, макет [32-osv-no-inn]). «Применить» и «Сбросить» SHALL закрывать окно фильтра.
Смена фильтра SHALL перечитывать первую страницу.
Scenario: Строка из контрольных цифр
- WHEN фильтр ЮЛ «Пекарня Счастливочная» и поиск «бисквит»
- THEN строка
60.01показывает сальдо нач. Кт 4 454 151.93, обороты Дт 128 058 143.65, Кт 125 950 450.77, сальдо кон. Кт 2 346 459.05, признак «ГСК»
Requirement: Ручное сопоставление контрагента
Ячейка ИНН (моноширинный шрифт, по центру) SHALL показывать, как в макете [32-osv-no-inn]:
- ИНН из файла (
counterparty_inn) — просто текстом, сопоставлена строка или нет (строка с ИНН сопоставления не требует, решение владельца 08.10.2026, отмена П-1); - строка сопоставлена, ИНН в файле нет — ИНН ЮЛ справочника (
counterparty_entity_inn) кнопкой-«таблеткой» (osv-inn-mapped-button); нажатие открывает ту же модалку для пересопоставления, у текущего ЮЛ вместо «Связать» — неактивное «Связано»; - нет ни ЮЛ, ни ИНН — подсвеченная ячейка со ссылкой «Указать» (
osv-inn-link-button).
«Указать» и «таблетка» SHALL открывать модалку
«Выбор организации для связи с <имя контрагента из файла>» [32-osv-map-counterparty]: поиск, таблица ИНН / Организация /
ГК / ГСК / ГСЗ / «Связать», рекомендуемые (recommended) — первыми под заголовком «Рекомендуемые» с зелёной подсветкой.
Кандидаты — GET …/counterparty-candidates?scope=&entry_id=&q= с паузой 300 мс после ввода: по умолчанию scope=group
(периметр и ГК); галочка «Искать во всём справочнике» — scope=all, при поиске короче 3 символов запрос не отправляется
и показывается подсказка.
«Связать» SHALL отправлять POST …/osv/entries/{entry_ids.at(-1)}/counterparty {legal_entity_id}, после успеха —
сообщение (с кем связано, сколько записей ОСВ сопоставлено автоприменением, создан или перенесён алиас), закрывать
модалку и перечитывать страницу свода и сводку («Осталось N» на клиенте не вычисляется). Ответы 409:
ALIAS_TAKEN— подтверждение «Имя уже закреплено за <владельцы>. Перенести?» → повтор сmove_alias = true;LOCK_REQUIRED— подтверждение «Взять версию в работу?» →POST …/lock→ повтор; отказ — ничего не меняется;LOCKED_BY_OTHER(от правки или отPOST …/lock) — «Версию держит <имя>» (имя — из ответаPOST …/lockили изlockкарточки версии), без перехвата;VERSION_NOT_EDITABLEи прочие ошибки — текстом сервера.
Scenario: Сопоставление «Пекарня Счастливочная ООО» в ОСВ РБ
- WHEN в своде РБ 2024 Q3 у строки контрагента «Пекарня Счастливочная ООО» без сопоставления нажато «Указать» и у рекомендуемой «Пекарни Счастливочной» — «Связать» (версия не взята в работу → «Взять в работу»)
- THEN строка показывает ЮЛ и тип «ГСК», «Осталось N» уменьшается на число сопоставленных строк, у ЮЛ появляется алиас
Scenario: Алиас занят
- WHEN имя строки уже алиас другого ЮЛ и аналитик выбирает третье ЮЛ
- THEN показан вопрос о переносе с именами владельцев; «Перенести» повторяет запрос с
move_alias = true
Requirement: Пробелы
Экран SHALL показывать gaps[] сводки списком «ЮЛ — счёт — недостающие кварталы» с пояснением, что строки этих пар в
своде отсутствуют.
Scenario: Пробелы РБ 2024 Q3
- WHEN открыт свод версии РБ 2024 Q3
- THEN показано 7 пробелов, у каждого недостающие кварталы «Q1, Q2»
Requirement: Экспорт
Кнопка «Скачать xlsx» SHALL получать GET /consolidations/versions/{id}/osv/export с текущими фильтрами через клиент API
с токеном и сохранять файл; имя — из Content-Disposition, а если заголовок недоступен —
Сводная_ОСВ_<ГК>_<год>_<квартал>.xlsx.
Scenario: Экспорт с фильтром
- WHEN аналитик скачивает свод с фильтром по ЮЛ
- THEN сохраняется xlsx, а ошибка сервера показывается текстом, а не скачивается