Andrey Epifancev c8a89d4c63 docs(openspec): consolidations-ui — расхождения закрыты, дельта consolidated-osv-ui «Единицы» (AURORA-1589, PR #166)
Решение владельца 23.10.2026: PR доводим сами, 71ef633 остаётся. design.md: Known issues
1–14 закрыты, открыты 15 (lucide-react в Nexus), 16 (предупреждение вне модалок), 17
(красное поле поиска в [42]); решения без обсуждения (л)–(х), пересмотр (е) и (к).
Спека: несохранённые правки в модалках, ошибки [35], [31-00] при неактивных вкладках.
tasks.md, web/ARCHITECTURE.md, web/CLAUDE.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 01:15:55 +04:00

159 lines
23 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.

## Context
PR RSHB/arm-core#166 (ветка `AURORA-1589`, автор — Степанов, задача AURORA-1589) доводит до макета экраны консолидаций:
список консолидаций ГК [34] (`widgets/ConsoleTable/`), модалку «Взять в работу» и перехват [35]
(`widgets/ConsoleTable/LockModal.tsx`), панель «Организации» (`widgets/ConsoleLegalEntities/`), модалку «Новая
консолидация» [42] (`widgets/NewConsoleModal/`, строка ЮЛ — `CompanyOptionRow.tsx`), кнопку «Изменить статус» в шапке
карточки версии [30] (`layouts/ConsolidatedOsvPage.tsx`) и модалку [33-01] (`widgets/StatusChangeModal/ChangeStatusModal.tsx`).
Бэкенд — спека `consolidations-api` (список с `in_work_only`, «Взять в работу, перехват, снятие», «Статусы Среза 4»); API не
меняется. В ветку добавлена вторая библиотека иконок `lucide-react` (иконки макета: меню «⋯», «Взять в работу», «К
отчётности», боковое меню).
Спеку, документацию и тесты ведёт ревьюер коммитами в ветку автора (правило владельца для чужих PR). Спека описывает
**целевое** поведение; расхождения кода ветки (коммит 71ef633) с ней — раздел «Known issues». Решение владельца
23.10.2026 после ревью раунда 1: продуктовый код ревьюер исправляет сам в этой же ветке (ручной код автора
не переписывается сверх нужного), коммит 71ef633 («Единицы» сводной ОСВ) остаётся в PR и тоже исправляется, его
поведение описано дельтой `consolidated-osv-ui`. Известные расхождения 1–14 закрыты (раздел «Known issues»).
Источники: макет [34], [35], [42], [30], [33-01], [33], [31-00] (`docs/mockup/INDEX.md`), описание AURORA-1589, ТЗ
«Статусная модель» (`docs/source/tz/…08_4. Статусная модель.md`), гайд фронта по API §5.7.
## Decisions
- **D-1. Ручные переходы — зеркало `MANUAL_TRANSITIONS` во фронте.** API не отдаёт допустимые переходы (в `VersionCard`
нет `allowed_transitions`, заметка AURORA-1589 от 12.10.2026). Фронт держит одну константу «статус → допустимые ручные
переходы», совпадающую с `api/src/services/consolidation_status.py`: `INITIATED → {CANCELLED}`,
`DOCUMENTS_PROCESSING → {CANCELLED, INITIATED}`, `DATA_CORRECTION → {CANCELLED, INITIATED}`. С маршрутом согласования
(Срез 7) константа заменяется ответом API без переделки модалки. Расхождение константы с бэком сервер ловит 409
`TRANSITION_NOT_ALLOWED`; заметка о зеркале — в гайде фронта §5.7 (PR в RSHB/arm-ka-docs).
- **D-2. Комментарий обязателен для обоих ручных переходов** (AURORA-1589): для `CANCELLED` его требует и сервер (422
`COMMENT_REQUIRED`), для возврата в `INITIATED` — только фронт.
- **D-3. «Изменить статус» доступна по `lock` карточки и `/me`**: активна, если `lock.locked_by` = текущий пользователь и в
D-1 есть переходы из текущего статуса. Подсказка «Возьмите консолидацию в работу» (текст задачи AURORA-1589).
- **D-4. После смены статуса экран берёт карточку из ответа** `POST …/status` (`VersionCard`), без повторного
`GET`: бейдж, пояснение и кнопка обновляются сразу; после `CANCELLED` сервер снимает блокировку, кнопка становится
неактивной.
- **D-5. По умолчанию в «Новом этапе» ничего не выбрано** (ревью раунда 1): в макете [33-01] предложен следующий этап, но
сейчас один из двух вариантов — необратимая «Отменена», и случайная отправка по умолчанию недопустима.
- **D-6. «Только в работе» — серверный фильтр `in_work_only`**, по умолчанию выключен (макет [34], значение API по
умолчанию `false`). Фронт не фильтрует по статусу сам: множество «в работе» для списка определяет сервер.
- **D-7. Модалка [35] читает свежую карточку версии** перед показом: данные `lock` строки списка могут устареть. Перехват —
в той же модалке: при известной чужой блокировке сразу поле причины, при 409 `LOCKED_BY_OTHER` (гонка) — предупреждение
и поле причины.
- **D-8. ГСК в API нет (решение владельца П-3)**: колонка «ГСК» — «—», в тексте модалки [35] вместо ГСК макета — ГК
(`company_group.name` карточки).
- **D-9. Подпись `CANCELLED` — «Отменена»** (AURORA-1589, ревью): в ТЗ «Статусная модель» — «Отменен», в словаре UI
`10-user-journey.md` — «Отмена КФО»; выбран вариант задачи (согласование с «консолидацией»). «Корректировка данных» —
как в ТЗ (было «Коррекция данных»).
- **D-10. Кнопку «Взять в работу» блокирует код статуса `CANCELLED`, а не подпись** — подпись меняется (D-9), условие по
подписи ломается молча.
## Known issues
Расхождения кода ветки `AURORA-1589` (71ef633) с целевой спекой по ревью раунда 1. По решению владельца (23.10.2026)
1–14 исправлены ревьюером в этой же ветке; открытыми остаются 15 и часть 16.
1. ~~404 при смене статуса~~ — закрыто: `updateStatus` шлёт `POST /consolidations/versions/{id}/status` (была опечатка
`/consolidation/…`; эндпоинт в main есть, на стенде отвечает 409 `TRANSITION_NOT_ALLOWED` на недопустимый переход).
2. ~~Переходы — заглушка `mockStatusMappingFetch()`~~ — закрыто: синхронная константа `MANUAL_TRANSITIONS` в
`web/src/utils/consolidations.ts` (зеркало бэка, D-1) и `manualTransitions(status)` — пустой список без переходов.
3. ~~«Новый этап» предвыбран~~ — закрыто: по умолчанию пусто, плейсхолдер «Выберите этап» (D-5).
4. ~~Кнопка «Изменить статус»~~ — закрыто: активность — `canChangeStatus` (своя блокировка и есть ручные переходы),
подсказка «Возьмите консолидацию в работу» без своей блокировки (D-3).
5. ~~Колонка «Версия» инвертирована~~ — закрыто: `versionLabel` (1 → пусто, 2+ → номер).
6. ~~«Только в работе» включён по умолчанию~~ — закрыто: `parseInWorkOnly` (включён только `?in_work_only=true`),
параметр запроса — boolean через `api.get(path, params)` (D-6).
7. ~~Пункты «⋯» не `disabled`~~ — закрыто: `disabled: true`, подсказка «Будет позже», переход в журнал и
`message.info` убраны, пустой элемент `{}` убран, клик по меню не выбирает строку таблицы.
8. ~~«Отменён»~~ — закрыто: «Отменена»; «Взять в работу» блокирует `canTakeInWork(status_code)` — у строки списка есть код
статуса (`ConsRow.status_code`), подпись только для показа и фильтра (D-9, D-10).
9. ~~Перехват [35]~~ — закрыто: плейсхолдер «Укажите причину замены», счётчик 0/1000, `isValidReason` (≤ 1000 после
обрезки), «К3» через `quarterShortLabel`, опечатки исправлены, ФИО с инициалами без второй точки (`endSentence`).
10. ~~Пояснение под заголовком~~ — закрыто: `CONS_STATUS_DESCRIPTION` / `consStatusDescription` (тексты спеки; нет текста —
пусто, название статуса не повторяется).
11. ~~Модалка [31-00]~~ — закрыто: `UnmappedInnModal` и проверка в `OsvTabs` (`needsUnmappedWarning`). Вкладки шагов
пока неактивны, поэтому на стенде модалка проверена на временной копии с активной «Шахматкой» (решение (м)).
12. ~~«+ Создать» при одном ЮЛ~~ — закрыто: `MIN_PERIMETER = 2`, кнопка неактивна, у поля — «Выберите не меньше двух ЮЛ».
13. ~~Модалка «Изменить статус»: загрузка без обработки ошибок, `comment.trim()` на `undefined`~~ — закрыто: модалка
карточку не грузит, получает её со страницы (`card`), после 200 страница берёт карточку из ответа (D-4);
`canSubmitStatusChange` принимает `undefined`; ошибки — текст сервера, модалка открыта.
14. ~~Тестов нет~~ — закрыто: `web/src/utils/consolidations.test.ts`, `formatScaledAmount` в `web/src/utils/money.test.ts`.
15. **`lucide-react@0.263.1` в зеркале npm банка не проверен** (открыто). Пакет в `dependencies`, снимок контура его
оставляет (`docs/dev/contour-transfer-guide.md` §3.2); если версии нет в Nexus, сборка в контуре упадёт. Вопрос автору
PR / платформе.
16. **Предупреждение браузера о несохранённых правках** — частично: сделано для трёх модалок экранов консолидаций
(требование «Предупреждение о несохранённых правках в модалках консолидаций», решение (л)). Открыто: нужно ли оно в
остальных формах приложения (справочники, проверка документов) и при переходе по меню вне модалок (у `BrowserRouter`
нет `useBlocker`, нужен переход на data router) — вопрос владельцу.
17. **Поле поиска в блоке «ЮЛ консолидации» [42] подсвечивается красным**, когда у поля ошибка «Выберите не меньше двух
ЮЛ» (antd передаёт статус `Form.Item` вложенному `Input`); так было и с прежним правилом `required`. Косметика, открыто.
## Decisions made without discussion
- **2026-10-23 (а). Новая capability `consolidations-ui`; `consolidation-setup` и `consolidated-osv-ui` не правятся.** Вид
модалки [42], шапка карточки версии и модалка [31-00] описаны в новой спеке; состав модалки [42], создание и «К
отчётности» остаются в `consolidation-setup`, сводная ОСВ — в `consolidated-osv-ui`. Обоснование: не смешивать дельты
трёх спек в одном PR фронта. Цена ошибки: при архивации модалку [42] и страницу отчёта описывают по две спеки; сведение —
MODIFIED-дельтой позже.
- **2026-10-23 (б). Временные пояснения статусов первой очереди и `CANCELLED` — дословные фрагменты ТЗ «Статусная
модель»** (колонка «Описание»), пока аналитик не дал тексты (AURORA-1589: «тексты для статусов первой очереди — у
аналитика»); для `VERIFIED` и `CONSOLIDATION_RF` — тексты макета вместо текстов автора. Обоснование: подзаголовок не
должен повторять название статуса, а придумывать формулировки нельзя. Цена ошибки: замена строк в одном месте.
- **2026-10-23 (в). Порядок версий в дереве — как в ответе API** (сверху последняя версия периода, под ней предыдущие), как
в `main`. В макете [34] версия 1 стоит сверху, версия 2 — под ней. Цена ошибки: правка `flatten.ts` / `groupAdjacent.ts`
и MODIFIED требования «Список консолидаций ГК».
- **2026-10-23 (г). Минимум два ЮЛ для «+ Создать»** — из описания [42] в `docs/mockup/INDEX.md` («минимум 2») и 422
`PERIMETER_TOO_SMALL`; фронт блокирует раньше сервера. Цена ошибки: одно условие.
- **2026-10-23 (д). Модалка [31-00] — только при переходе на другую вкладку отчёта**, не при «Назад» и переходах по меню.
Открытые вопросы владельцу: (1) нужно ли предупреждать и при уходе со страницы отчёта; (2) AURORA-1589: «на реальных
данных в счётчик попадают строки, которые не являются организациями… до нуля он не доводится» — поведение согласовать с
задачей «Блокировка шага до сопоставления контрагентов без ИНН»; до решения модалка не блокирует переход. Цена ошибки:
расширение триггера — MODIFIED требования.
- **2026-10-23 (е). Предупреждение браузера о несохранённых правках не включено в спеку**: пункт задачи касается всех форм
и модалок приложения, а не экранов консолидаций; остаётся задачей автора в `tasks.md`. Цена ошибки: требование появится
отдельной спекой (или дельтой) позже. **Пересмотрено 23.10.2026:** для модалок экранов консолидаций — решение (л).
- **2026-10-23 (ж). Подпись `DOCUMENTS_PROCESSING` оставлена «Обработка документов»** (как в `main`); в ТЗ — «Загрузка,
распознавание и корректировка документов», в словаре UI — «Загрузка и распознавание документов». Вопрос аналитику.
Цена ошибки: замена одной подписи.
- **2026-10-23 (з). Тексты сообщений об ошибках 409/422 в модалке «Изменить статус» не фиксируются дословно**: спека
требует сообщение и открытую модалку. Цена ошибки: низкая.
- **2026-10-23 (и). В ветку влит `origin/main`** (шахматка «пара без встречной стороны» PR #165 и архивы OpenSpec
PR #160, #167, #168) — без конфликтов; файлы `web/` ветки слиянием не затронуты. Цена ошибки: низкая, PR и так
сливается в этот `main`.
- **2026-10-23 (к). «Единицы» и «Знаков после запятой» сводной ОСВ (коммит 71ef633, AURORA-1539) в спеку не включены** —
автору предложено вынести их в отдельный PR. Цена ошибки: если коммит останется в PR, его поведение будет без спеки.
**Пересмотрено 23.10.2026 решением владельца:** коммит остаётся в PR, поведение описано дельтой `consolidated-osv-ui`
(«Единицы и знаки после запятой»).
- **2026-10-23 (л). Предупреждение о несохранённых правках — `beforeunload` в трёх модалках экранов консолидаций**
(перехват с причиной, «Изменить статус», «Новая консолидация»; хук `web/src/hooks/useBeforeUnload.ts`), требование —
в спеке `consolidations-ui`. Пересматривает (е) в части этих экранов. Обоснование: в задаче — «в открытой форме или
модалке»; модалки этого PR — понятное место, маска модалки и так закрывает меню; формы других экранов и переход по
меню вне модалок требуют решения владельца (Known issues 16). Цена ошибки: если предупреждение нужно и в других формах —
подключить тот же хук; если не нужно вовсе — убрать три вызова.
- **2026-10-23 (м). Модалка [31-00] — в `OsvTabs` с параметрами `onNavigate` / `enabledTabs`**; пока шагов нет, вкладки
неактивны и модалка не вызывается, на стенде она проверена на временной копии с активной «Шахматкой». Обоснование: PR
шахматки (#158) только передаёт переход, модалку не пишет. Цена ошибки: подключение вкладки — две строки.
- **2026-10-23 (н). Ошибки в модалках — текст сервера** (`ApiError.message`, по-русски) вместо карты фронтовых текстов;
исключение — 409 `VERSION_NOT_EDITABLE` в [35] (текст спеки). Обоснование: незнакомые коды и 403 раньше проходили молча
или «Что-то пошло не так». Цена ошибки: замена строк.
- **2026-10-23 (о). Пояснения статусов без текстов** (`ADJUSTMENT`, `ARCHIVED`, `REJECTED`) — пусто под заголовком;
`CONSOLIDATION_GO`, `VERIFICATION_RF`, `VERIFICATION_GO` — тексты автора PR, с ТЗ не сверены. Цена ошибки: строки в
`CONS_STATUS_DESCRIPTION`.
- **2026-10-23 (п). Единицы: «млн руб.», «млрд руб.» без точки** (сокращения «млн», «млрд» пишутся без точки; у автора —
«млн. руб.»); по умолчанию «руб.» и 2 знака, хотя в макете [30] выбрано «тыс. руб.»: контрольные цифры спеки
`consolidated-osv-ui` и гайда тестировщика — в рублях. Цена ошибки: одна строка умолчания.
- **2026-10-23 (р). Масштаб сумм — на строке и BigInt, округление половины от нуля** (`formatScaledAmount`, как в
Excel); ноль — «—» по исходной сумме, ненулевая сумма, округлённая до нуля, — «0,00» без минуса. Обоснование: правило
«суммы — строками» (`utils/money.ts`), у автора был `Number()` и потерян `zeroDash`. Цена ошибки: одна функция и тест.
- **2026-10-23 (с). После создания консолидации боковое меню перечитывает список с `in_work_only: false`**: переход
открывает список без `?in_work_only` (флажок выключен). Цена ошибки: низкая.
- **2026-10-23 (т). Строка ЮЛ модалки [42] — сам флажок antd (`<label>` на всю строку)** вместо `div role="checkbox"`
(замечание biome `useSemanticElements`); клик по наименованию или ИНН переключает, клавиатура — как у флажка. Цена
ошибки: низкая.
- **2026-10-23 (у). «Ответственный» после «Взять в работу» — перечитывание панели «Организации»** через `reloadKey`
страницы (`ConsoleTableWidget onVersionLocked`); список перечитывается только после успеха или 409
`VERSION_NOT_EDITABLE`, не после каждой ошибки. Цена ошибки: низкая.
- **2026-10-23 (ф). Чистые правила — `web/src/utils/consolidations.ts`**, подписи и пояснения статусов перенесены туда
из `widgets/ConsoleTable/consts.ts` (там остались цвета бейджей). Цена ошибки: низкая.
- **2026-10-23 (х). Отступ секций бокового меню — `padding: 12px 0`** (у автора закомментирован `12px`): по вертикали —
как в макете [34], по горизонтали пункты остаются на одной линии с кнопкой «Новая консолидация». Цена ошибки: CSS.