Andrey Epifancev a2b0a58fd0 docs(openspec): спеки экранов из arm-web@de4e477 перенесены в arm-core (#148)
Спеки 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>
2026-10-21 09:58:02 +04:00

82 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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, а ошибка сервера показывается текстом, а не скачивается