diff --git a/openspec/changes/consolidations-ui/design.md b/openspec/changes/consolidations-ui/design.md index e3f3f0f..e2f6986 100644 --- a/openspec/changes/consolidations-ui/design.md +++ b/openspec/changes/consolidations-ui/design.md @@ -9,8 +9,11 @@ PR RSHB/arm-core#166 (ветка `AURORA-1589`, автор — Степанов, меняется. В ветку добавлена вторая библиотека иконок `lucide-react` (иконки макета: меню «⋯», «Взять в работу», «К отчётности», боковое меню). -Спеку, документацию и тесты ведёт ревьюер коммитами в ветку автора (правило владельца для чужих PR); продуктовый код -правит автор. Спека описывает **целевое** поведение; расхождения кода ветки (коммит 71ef633) — раздел «Known issues». +Спеку, документацию и тесты ведёт ревьюер коммитами в ветку автора (правило владельца для чужих 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. @@ -46,40 +49,43 @@ PR RSHB/arm-core#166 (ветка `AURORA-1589`, автор — Степанов, ## Known issues -Расхождения кода ветки `AURORA-1589` (71ef633) с целевой спекой — по пунктам ревью раунда 1; исправляет автор PR. +Расхождения кода ветки `AURORA-1589` (71ef633) с целевой спекой по ревью раунда 1. По решению владельца (23.10.2026) +1–14 исправлены ревьюером в этой же ветке; открытыми остаются 15 и часть 16. -1. **404 при смене статуса.** `services/api/consolidations.ts` `updateStatus` шлёт `POST /consolidation/versions/{id}/status` - (нет «s»); нужен `/consolidations/versions/{id}/status`. -2. **Переходы — заглушка `mockStatusMappingFetch()` внутри модалки** (`ChangeStatusModal.tsx`). Нужна одна константа (D-1) - рядом с подписями статусов. Для статусов без переходов сейчас `nextStatusOptions = undefined`: форма скрыта, кнопка - «Изменить статус» в шапке при этом активна. -3. **«Новый этап» предвыбран** (`initialValues.to_status = nextStatusOptions[0]`, на стенде — «Отменён»); нужно пусто (D-5). -4. **Кнопка «Изменить статус»**: подсказка «Сначала возьмите версию в работу» вместо «Возьмите консолидацию в работу»; - отсутствие ручных переходов не учитывается (при своей блокировке `VERIFIED` кнопка активна, модалка пустая). -5. **Колонка «Версия» инвертирована** (`ConsoleTable/config.tsx`): показывает «1» и скрывает 2+; нужно наоборот. -6. **«Только в работе» включён по умолчанию** (`ConsoleTable.tsx`: `searchParams.get('in_work_only') || true`, флажок - отмечен, пока параметр не `'false'`); нужно выключен (D-6). -7. **Пункты «⋯» не `disabled`**: у них только класс `ant-dropdown-menu-item-disabled`, клик обрабатывается - («История изменений» ведёт в пустой «Журнал действий», остальные — `message.info('Будет позже')`); в `ITEMS` лишний - пустой элемент `{}`. -8. **Подпись `CANCELLED` — «Отменён»** (нужно «Отменена», D-9); «Взять в работу» блокируется сравнением - `row.status === 'Отменён'` — после переименования условие перестанет срабатывать (D-10). -9. **Перехват [35]**: плейсхолдер поля причины «Type message»; проверка длины `< 1000` вместо `≤ 1000`; квартал в тексте — - `Q3` вместо «К3»; опечатки «обнаржуена», «нформацию». -10. **Пояснение под заголовком**: для `INITIATED`, `DOCUMENTS_PROCESSING`, `DATA_CORRECTION` повторяется название статуса; - тексты `VERIFIED` и `CONSOLIDATION_RF` в `consStatusDescriptionMapping` расходятся с макетом [30], [33-01]. -11. **Модалка [31-00] «Остались неуказанные ИНН»** не реализована. Другие вкладки отчёта в ветке пока неактивны - (`OsvTabs`), поэтому сценарий проверяется после появления вкладки «Шахматка» (PR #158) или в нём же. -12. **«+ Создать» активна при одном отмеченном ЮЛ** (`NewConsoleModal.tsx`, `!legEntIds?.length`); нужно не меньше двух - (сервер отвечает 422 `PERIMETER_TOO_SMALL`). -13. **Модалка «Изменить статус», замечено при написании спеки** (в комментарий ревью раунда 1 не вошло): ошибка - `getVersionCard` не обрабатывается — модалка остаётся в загрузке; `comment.trim()` вызывается на значении - `Form.useWatch`, которое до монтирования формы `undefined`. -14. **Тестов нет.** Чистые правила (подпись версии, переходы, активность кнопок, параметр `in_work_only`) зашиты в - компоненты; тесты vitest — после их выноса в чистые функции (`tasks.md`). -15. **`lucide-react@0.263.1` в зеркале npm банка не проверен.** Пакет в `dependencies`, снимок контура его оставляет - (`docs/dev/contour-transfer-guide.md` §3.2); если версии нет в Nexus, сборка в контуре упадёт. -16. **Предупреждение браузера о несохранённых правках** (пункт AURORA-1589) не реализовано; в спеку не входит (решение (е)). +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 @@ -104,7 +110,7 @@ PR RSHB/arm-core#166 (ветка `AURORA-1589`, автор — Степанов, расширение триггера — MODIFIED требования. - **2026-10-23 (е). Предупреждение браузера о несохранённых правках не включено в спеку**: пункт задачи касается всех форм и модалок приложения, а не экранов консолидаций; остаётся задачей автора в `tasks.md`. Цена ошибки: требование появится - отдельной спекой (или дельтой) позже. + отдельной спекой (или дельтой) позже. **Пересмотрено 23.10.2026:** для модалок экранов консолидаций — решение (л). - **2026-10-23 (ж). Подпись `DOCUMENTS_PROCESSING` оставлена «Обработка документов»** (как в `main`); в ТЗ — «Загрузка, распознавание и корректировка документов», в словаре UI — «Загрузка и распознавание документов». Вопрос аналитику. Цена ошибки: замена одной подписи. @@ -115,3 +121,38 @@ PR RSHB/arm-core#166 (ветка `AURORA-1589`, автор — Степанов, сливается в этот `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 (`