# Дизайн: экран «Таблица корректировки» (AURORA-1541, arm-core #206) ## Зачем Кредитный аналитик на шаге консолидации видит, где внутригрупповые обороты двух компаний не сошлись, разбирается, из каких строк ОСВ сложилась каждая сторона, переносит строки между правилами и вносит корректировку — сколько и из каких статей ББ исключить. Без экрана корректировки ВГО делаются только вне системы, и тестирование корректировок (AURORA-1542, с 03.11) начать нельзя. ## Что считается готовым (слова владельца, 28.10.2026) - К сроку 02.11 — **рабочий экран на настоящем API**, не демо на моках. Если бэкенд (AURORA-1540) или аналитика не успевают — мы сами помогаем ребятам доделать. - Моки нужны, чтобы фронт не стоял, пока нет API, а не как результат. **Объём плана — только `web/`.** Бэкенд (DBML, `vgo_assignment`, разнесение, эндпоинты, аудит) — AURORA-1540 Цыганкова; помогаем ему на ревью его PR, а не задачами этого плана. Последняя задача плана — подключение к настоящему API, когда 1540 слит: флаг `REACT_APP_CORRECTIONS_MOCK` выключается, если эндпоинты есть в `main`, вкладка открывается на стенде на реальной версии и проходит сценарии спеки; расхождения ответа с контрактом правятся в той ветке, где ошибка (фейк или бэкенд). Сверяем фейк с реальным ответом мы (владелец / этот агент) при подключении. ## Источники и их вес 1. Аналитика Лысенко — DOC-272613, ответы 1–7 (AURORA-1395, 27.10), DOC-274230. **Приоритетна над нашими правилами и черновиками** (решение владельца 28.10). 2. Дизайн от 23.10.2026 — `ДКБ_таблица_корректировок_23_10_26_1.html` (вложение к DOC-272613; в корне workspace). Как лежат строки в дизайне — визуализация; логика — по аналитике. 3. ТЗ 6.8 / Прил. 9 — ниже аналитики, иногда игнорируется. 4. Контракт API — `../docs/dev/api-contract-corrections.md` и `.openapi.yaml` (docs #183, вложение в AURORA-1540). Открытые вопросы аналитику (комментарий `[design-23-10-check]` в AURORA-1395, п. 1–12 + 3 по ТЗ; в AURORA-1396 — ОФР) не блокируют работу: зависящие места сделаны так, чтобы ответ менял поведение точечно. ## Цели - Вкладка «Таблица корректировки» страницы отчёта версии, по виду — как дизайн 23.10. - Таблица агрегатов с раскрытием до строк ОСВ, нераспределённые строки, итоги, фильтры, пресеты по правилам, единицы, настройка колонок, экспорт, полный экран. - Окно «Корректировка операции» агрегата: строки сторон, распределение по статьям, контроль, комментарий, сохранение. - Решения по строкам: флажок «Учитывать в КФО» у нераспределённых, отнести / перенести / убрать / вернуть к автоматике. - Только чтение, когда сервер так говорит (`editable = false`). ## Не цели - Бэкенд и DBML (AURORA-1540), правила §8 в `05-domain-rules.md`. - ОФР (нет в дизайне; AURORA-1396), импорт xlsx (ТЗ 6.8, ждёт ответа). - Корректировка строки ОСВ и нераспределённой строки (аналитика: только агрегат; ждёт п. 2). - Переход из шахматки с фокусом на паре (AURORA-1653), учёт корректировок в шахматке (AURORA-1643). ## Анти-цели (провал, даже если «работает») - Фронт сам считает разнесение строк, отклонения, порог 5 % или статусы агрегата — это делает сервер; фронт только показывает, форматирует и суммирует видимые строки для «Итого». - Деньги через `number`/`float` с потерей копеек. Суммы — строки контракта, сложение — точное десятичное. - Экран, в котором можно что-то нажать и молча потерять изменения окна корректировки. - Кнопки правки у версии, которую сервер считает нередактируемой. ## Ограничения - `web/` arm-core: React 18 + TS strict, antd 6, react-router 7, biome (140, одинарные кавычки), vitest. - Деньги в API — рубли строками с двумя знаками; показ в руб. / тыс. руб. и 0–2 знака — как в шахматке. - Состояние экрана — локальные хуки (стор Redux пуст по соглашению шаблона). - Пользователь слаб во фронте — решения в PR объясняются простыми словами. - Каждый экран сверяется с дизайном в Playwright и проходится руками до сдачи. ## Как устроено ### Данные - `GET …/corrections?statement_type=balance` — одна загрузка всей таблицы; фильтры, сортировка, «Итого» — на клиенте. - Правки: `PUT …/aggregates/{rule}/{c1}/{c2}` (сохранить, сразу `APPLIED`), `POST …/allocations` (решение по строке, ответ — вся таблица), `GET …/export`. - Клиент — `web/src/services/api/corrections.ts` поверх `api/client.ts`. При `REACT_APP_CORRECTIONS_MOCK=true` те же функции отвечают из фейка контракта в памяти (данные — из дизайна 23.10, с проверками контракта: обязательный комментарий, `expected_version_no`, применимость правила). Флаг по умолчанию выключен; фейк включается только переменной окружения, но код фейка остаётся в бандле (R-21, R-26). ### Таблица Колонки как в дизайне: «Учитывать в КФО»; Дебет — ЮЛ, Строка баланса, Счёт, Сумма; Кредит — то же; Контроль — Отклонение %, Отклонение сумма; Корректировка — Строка баланса, Сумма (Дт), Строка баланса, Сумма (Кт), Комментарий; колонка действий. - **Строка агрегата.** Суммы сторон, счета (`accounts`), отклонение. Процент и сумма отклонения красные при `exceeds_threshold`. Корректировка — статьи и суммы `correction.debit` / `credit` (несколько статей стороны — по строке на статью в ячейке), комментарий. Действие — «Корректировать» (окно); отзыва корректировки нет, её меняют в окне (R-29). `composition_changed` — подсветка строки и значок с подсказкой «Состав изменился после корректировки». `correction.status = DRAFT` — пометка «черновик» у корректировки. - **Раскрытие.** Под агрегатом — его строки ОСВ (`side_1.entries`, затем `side_2.entries`): строка стороны 1 заполняет блок «Дебет», стороны 2 — «Кредит», остальные ячейки пустые (DOC-272613 п. 3.4; пары строк из дизайна не строим, ответ п. 3). Флажка у строки нет; меню: «Перенести в правило…» (правила — `candidate_rule_ids` строки; фронт сам не сверяет счета с правилами), «Убрать из правила» (строка уходит в нераспределённые), «Вернуть к автоматике» (если `decision = ASSIGN`). - **Флажок агрегата** «Учитывать в КФО» — отмечен и закреплён: агрегат учитывается целиком, лишнюю строку убирают из правила (ответ Лысенко 29.10, п. 4; R-31). - **Нераспределённые строки** — после агрегатов, фон приглушён. Владелец — на своей стороне (дебетовая строка — в «Дебет», кредитовая — в «Кредит»), на другой стороне — только ЮЛ контрагента. Строка баланса владельца — `line_code` на его стороне (ответ п. 11, R-33). Флажок «Учитывать в КФО» (только здесь), меню «Отнести к правилу…» (список — `candidate_rule_ids`), «Вернуть к автоматике» для `reason = UNASSIGNED`. Кнопки «Корректировать» нет (ответ п. 2). - **«Итого»** — суммы сторон, отклонения и корректировок по видимым агрегатам, точным сложением строк; процент «Итого» не показываем (смысл не задан). - Подписи «Отнести/Перенести в правило…» показывают правила как пресеты: «Правило N: <статья 1> — <статья 2>». ### Панель - «Отображение»: «Общий» / «По пресету»; при «По пресету» — выбор правила (подпись с номером — снимает одинаковые подписи правил 5 и 8 из дизайна, п. 12); в таблице только агрегаты этого правила и те нераспределённые строки, у которых это правило есть в `candidate_rule_ids` (их можно отнести к нему). - «Тип записи»: «Все» / «Пары счетов» (агрегаты) / «Нераспределенные записи». - Фильтры «ЮЛ» и «Счёт» действуют и на нераспределённые строки; «Строка баланса» и «Отклонение» — только на агрегаты, при заданном одном из них нераспределённые строки скрываются (у них нет статьи и отклонения). - Составная статья правила (`"1450/1550"`, `"1310/1350"`, правила 1 и 2) показывается как «1450 / 1550»; в фильтре «Строка баланса» это два кода; в окне корректировки подставляется первый код, аналитик может выбрать второй. - Единицы и знаки — тот же компонент, что в шахматке. - Фильтры в заголовках: ЮЛ (подстрока, обе стороны), Строка баланса (список), Счёт (начало кода), Отклонение % («Все» / «≥ 5 %» / «< 5 %», по `exceeds_threshold`); «Сбросить фильтры» — когда что-то задано. - «Настройка таблицы» — `GenericTable/ColumnSettings` (видимость групп и колонок); «Экспорт» — файл сервера; «На весь экран» — как в шахматке. ### Окно «Корректировка операции» По дизайну: шапка сторон (компания, статья правила), блоки «Исходные данные ОСВ» и «Распределение корректировки» для каждой стороны, итоги, комментарий, «Отменить» / «Сохранить корректировки». - **Исходные данные ОСВ** — строки стороны агрегата. «×» у строки — «Убрать из правила» (`UNASSIGN`), «Добавить строку ОСВ» — выбор из нераспределённых строк, которые подходят под эту сторону: та же пара компаний (владелец и контрагент), сторона строки = сторона правила, правило агрегата есть в `candidate_rule_ids` (ответ 3(а)). Обе операции идут на сервер сразу (`POST …/allocations`), окно перечитывает агрегат. - **Распределение** — статьи стороны: строка баланса (код статьи) и сумма; «Добавить строку» — дочерняя статья. Без корректировки окно предлагает по стороне одну статью правила с суммой стороны (как в дизайне). - **Контроль** — суммы исходных строк сторон и суммы распределения сторон, разница и процент к меньшему (как в таблице; 79,77 % из дизайна — ошибка дизайна, п. 7). Расхождение не запрещает сохранение (ждёт п. 8). - **Сохранить** — `PUT` с `status = APPLIED`, `expected_version_no` из ответа; ошибки сервера показываются в окне по коду (`COMMENT_REQUIRED` — у поля комментария, `INVALID_LINE_CODE` — у статьи, `CORRECTION_VERSION_CONFLICT` — «Корректировку уже изменили, данные обновлены», окно перечитывает данные). - **Черновик окна в `localStorage`** (решение владельца 28.10.2026 вместо блокировки переходов): статьи распределения и комментарий сохраняются при каждой правке; ключ — пользователь + версия + агрегат (`rule_id`, компании), в записи — время и `version_no` корректировки, от которой начаты правки. Переход «Назад», закрытие вкладки, переход по ссылке правки не теряют. При открытии окна этого агрегата черновик подставляется с плашкой «Восстановлены несохранённые правки от ЧЧ:ММ» и кнопкой «Сбросить»; если `version_no` на сервере уже другой — плашка «Корректировку изменили после ваших правок» (аналитик решает: оставить или сбросить). Черновик удаляется после успешного сохранения и после «Отменить» с подтверждением «Есть несохранённые изменения. Закрыть без сохранения?». Действия со строками в черновик не входят (они уже на сервере). Доступ к хранилищу — в `try/catch`: недоступно (приватный режим) — работаем без черновика. ### Только чтение `editable = false` — «Корректировать», флажки и меню решений неактивны; подсказка по `read_only_reason`: `VERSION_NOT_EDITABLE` — «Версия закрыта для изменений», `LOCK_REQUIRED` — «Возьмите консолидацию в работу», `LOCKED_BY_OTHER` — «Консолидацию редактирует другой пользователь». Окно корректировки открывается на просмотр. ### Состояния Загрузка — индикатор на месте таблицы; ошибка — уведомление с текстом сервера и «Повторить»; пусто — «Внутригрупповых остатков между компаниями периметра нет»; фильтры ничего не нашли — «Нет записей для выбранных фильтров» (текст дизайна). ## Что оставлено исполнителю Разбиение на компоненты и хуки, имена файлов внутри `widgets/CorrectionTable/`, способ раскрытия (antd `expandable` или собственные строки), вид меню действий, точная раскладка окна в пределах дизайна, состав данных фейка. ## Decisions made without discussion | Дата | Решение | Почему | Цена ошибки | |---|---|---|---| | 28.10.2026 | Контракт API пишем сами (docs #183), markdown + OpenAPI; корректировка в контракте — только на агрегат | API ещё нет; аналитика приоритетна | при ответе «можно на строку» (п. 2) — новый эндпоинт и кнопки на строках | | 28.10.2026 | Раскрытие агрегата — строки ОСВ под своей стороной, не пары из дизайна | DOC-272613 п. 3.4; пары нигде не хранятся | ответ по п. 3 «пары нужны» — доработка раскрытия и контракта | | 28.10.2026 | «Учитывать в КФО» ставится на строке; у агрегата — производное «Да / Частично / Нет» | DOC-272613 (EXCLUDE на `osv_entry`) | ответ по п. 4 «на агрегат» — поменять флажок агрегата на действие | | 28.10.2026 | Действия со строками в окне корректировки идут на сервер сразу, статьи и комментарий — по «Сохранить» | разнесение и корректировка — разные записи (`vgo_assignment` / `correction`); аналитик видит новые суммы до ввода корректировки | отмена окна не откатывает перенос строк — аналитику нужно вернуть строку вручную | | 28.10.2026 | Сохранение сразу применяет (`APPLIED`), черновик не показываем | в дизайне одна кнопка | ответ по п. 9 «нужен черновик» — вторая кнопка | | 28.10.2026 | «Отменить корректировку» — в меню агрегата, с комментарием | `REVOKED` в аналитике есть, в дизайне нет места | ответ по п. 9 — перенести кнопку | | 28.10.2026 | Процент в окне — к меньшему, как в таблице | аналитика; в дизайне две формулы | — | | 28.10.2026 | Без корректировки окно предлагает суммы сторон целиком | так в дизайне; в аналитике подсказка не описана | ответ по п. 8 — поменять подсказку на min | | 28.10.2026 | Фильтр «Отклонение» — по `exceeds_threshold` (≥ 5 % / < 5 %), а не диапазон чисел | порог — главный вопрос аналитика; диапазон в дизайне не описан | доработка фильтра | | 28.10.2026 | «Итого» без процента | смысл процента по итогам не задан | добавить колонку | | 28.10.2026 | Фейк контракта под флагом `REACT_APP_CORRECTIONS_MOCK`, данные из дизайна | фронт не ждёт бэкенд; тот же код ходит в настоящий API | фейк расходится с бэкендом — ловится при подключении API и ревью AURORA-1540 | | 28.10.2026 | Только `statement_type = balance`, переключателя ББ/ОФР нет | в дизайне его нет; ОФР ждёт AURORA-1396 | добавить переключатель | | 28.10.2026 | Ключ черновика — пользователь + версия + агрегат; черновик без срока жизни, удаляется сохранением или «Отменить» | на общем компьютере у разных пользователей разные черновики | старые черновики копятся в `localStorage` — объём мал | | 28.10.2026 | План — только `web/`, бэкенду помогаем на ревью 1540; последняя задача — подключение к API и снятие флага | слова владельца «поможем ребятам на ревью» | если 1540 не успеет к 02.11, экран сдаётся на фейке | | 28.10.2026 | В контракт добавлен `candidate_rule_ids` у строки агрегата | иначе фронту пришлось бы сверять счета с правилами — это разнесение, анти-цель | правка контракта до начала 1540 — дёшево | | 28.10.2026 | `expected_version_no = null`, когда действующей корректировки нет (и после отзыва) | иначе после отзыва фронту неоткуда взять номер | — | | 28.10.2026 | Составная статья правил 1 и 2 — в окне первый код, можно выбрать второй | `line_code` — один код; особый расчёт правил 1 и 2 (DOC-274230) — на сервере | при ответе «нужно распределение по обеим» — аналитик добавляет вторую статью руками | | 28.10.2026 | «По пресету» показывает и подходящие нераспределённые строки; «Строка баланса» и «Отклонение» скрывают нераспределённые | пресет — рабочее место по правилу, строки для отнесения нужны рядом | поменять функцию фильтров | | 28.10.2026 | R-1: список правил в плане — ориентир; при расхождении с api/seed/core/elimination_rules_v1.yaml (в плане статья 1230/1510 встречается дважды) номера и статьи берутся из yaml, тесты плана про правила 1, 3, 6, 7 остаются верными | seed — источник истины | поправка mockData и тестов | | 28.10.2026 | R-2: в фейк добавлен `widgets/CorrectionTable/mockCalc.ts` (пересчёт агрегата и итогов через BigInt-копейки) — общий для `mockData` и `correctionsFake`, иначе циклический импорт | план не называл файл; без него циклический импорт | перенос функций, без поведения | | 28.10.2026 | R-3: в `mockData` сверх дизайна добавлены агрегат правила 6 «ООО "БСК"» — «ПМП ООО» (310000.00 / 300000.00) и агрегат правила 4 «Агро-Холдинг» без второй стороны (ONE_SIDED); `status` в фейке — ONE_SIDED / DISCREPANCY / AUTO, MANUAL не выдаётся | тест фильтра `ооо "бск"` из плана требует агрегат с таким ЮЛ; ONE_SIDED нужен для проверки отображения | поправка данных фейка, на прод не влияет | | 28.10.2026 | R-4: в окне корректировки сумма с пробелами («1 000 000,5») отклоняется с ошибкой «Сумма без пробелов», хотя `parseAmountInput` пробелы принимает | Review Focus плана прямо требует ошибку для этого ввода | если заказчик хочет пробелы — снять одну проверку в `validateLines` | | 28.10.2026 | R-5: `percentOfSmaller`, `toCents`, `fromCents` и порог 5 % (`THRESHOLD_PERCENT_HUNDREDTHS`) вынесены в `utils/money.ts`; `editorModel` и `mockCalc` импортируют оттуда, зависимости `editorModel` → `mockCalc` нет | фейк `mockCalc` вырезается при подключении API, экран не должен от него зависеть (ревью Task 3, T3.1) | поведение то же; тесты перенесены в `utils/money.test.ts` | | 28.10.2026 | R-6: тексты ошибок валидации окна и ключ ошибки `lines` для «Добавьте статью» выбраны исполнителем | бриф их не задаёт; тексты в spec не указаны | правка строк | | 28.10.2026 | R-7: флажки «Учитывать в КФО» и меню строк неактивны всегда (`actionsEnabled=false`) до Task 5–6, подсказка «только чтение» подключена | бриф Task 4: решения по строкам — в Task 5 | забыть включить флаг в Task 5 | | 28.10.2026 | R-8: ошибка загрузки показывается уведомлением с «Повторить» (по спеке) и кнопкой на месте таблицы | после закрытия уведомления аналитик не остаётся без выхода | две кнопки повтора | | 28.10.2026 | R-9: «Итого» показывается только при наличии видимых агрегатов (при «Нераспределенные записи» его нет) | сценарий спеки | показать «Итого» с пустыми значениями | | 28.10.2026 | R-10: `ROW_ACTIONS_READY`/`actionsEnabled` удалены; контролы строк неактивны при `!editable` (с подсказкой `readOnlyHint`) и на время запроса (`busy`, без подсказки) | включение R-7 в Task 5; блокировка на время запроса не даёт отправить два решения подряд | аналитик не видит, почему контрол замер, пока идёт запрос (виден спиннер таблицы) | | 28.10.2026 | R-11: любая ошибка 409 при решении/отмене — уведомление с текстом сервера и `reload()` (`needsReload`) | 409 = версия закрылась, блокировку забрали, корректировку уже изменили/отозвали: локальная таблица устарела | лишний запрос при 409 без смысла для таблицы; комментарий окна отмены теряется при 409 и перезагрузке — допустимо, корректировка уже изменена; перечитывание и при 404 (`needsReload`) | | 28.10.2026 | R-12: после `allocate` таблица заменяется ответом целиком (`replace`), после `revoke` подменяется один агрегат (`replaceAggregate`); окно отмены при не-409 ошибке остаётся открытым, при 409 закрывается | `allocate` меняет и нераспределённые, `revoke` отдаёт агрегат; при сетевой ошибке комментарий не должен пропасть | после revoke нераспределённые не обновляются (по контракту revoke их не трогает) | | 28.10.2026 | R-13: меню строки вынесено в чистую `allocationMenu` (ключ `MOVE` — «выбрать правило», уходит как `ASSIGN`); правило-кандидат, которого нет в `rules`, пункт «в правило» не включает | тестируемость без React; фронт не выдумывает правил | при рассинхроне справочника правил пункт неактивен | | 28.10.2026 | R-14: окно получило пропс `onReload` сверх сигнатуры плана и рендерится только пока открыто (`key` = ключ агрегата) | при `CORRECTION_VERSION_CONFLICT`/409/404 окну нужно перечитать таблицу; черновик читается один раз при открытии | окно без `onReload` не обновит таблицу при конфликте | | 28.10.2026 | R-15: черновик пишется только при `editable` и если состояние отличается от исходного (суммы — копейками); вернули к исходному — черновик удаляется; при конфликте редакций правки остаются в окне, черновик сохраняется с прежним `baseVersionNo`, плашка «Корректировку изменили после ваших правок» | в режиме чтения черновик бессмыслен; совпавший с исходным — мусор в `localStorage` | при ручном возврате к исходному плашка восстановления пропадает | | 28.10.2026 | R-16: ключ строки статьи в окне — устойчивый числовой `id` из счётчика компонента (в `EditorState` ids нет); наружу (черновик, PUT) уходит `EditorState` без id | ключ-индекс при удалении строки переносил бы введённый текст на соседнюю | id не попадают в черновик, после перезагрузки выдаются заново | | 28.10.2026 | R-17: после `UNASSIGN`/`ASSIGN` в окне суммы статей без своих правок (не dirty) пересобираются из нового агрегата (`initialEditorState`), при правках — остаются как есть | у агрегата без корректировки статья предлагается с суммой стороны, она изменилась; затирать ввод аналитика нельзя | при правках статьи не подстраиваются под новые суммы сторон — их видно по строке контроля | | 28.10.2026 | R-18: суммы в окне показываются в рублях (`1 000 000,00`) независимо от единиц панели, а в полях ввода — как есть (`1000000.00`, пробелы запрещены R-4); у строки контроля без процента (`percent = null`, одна сторона 0) процент не пишется, у равенства — «= 0,00» | единицы панели — про таблицу; дизайн показывает «(100%)» там, где процент к меньшей стороне не определён, фронт его не выдумывает | расхождение с дизайном в тексте контроля | | 28.10.2026 | R-19: агрегат исчез из ответа — окно открыто, стороны «—», «Сохранить» неактивна, пояснение в плашке; ключ PUT берётся из ответа, поэтому без агрегата сохранить нельзя | Review Focus плана | — | | 28.10.2026 | R-20: в окне нет названий статей рядом с кодом («дт 1230 Дебиторская задолженность» в дизайне) | в ответе API названий статей нет, а фронт их не выдумывает | добавить поле `article_name` в контракт и показать | | 28.10.2026 | R-21: код фейка (`correctionsFake`, `mockData`, `mockCalc`, ~20 КБ исходников) остаётся в прод-бандле при сборке без флага; сам не вырезал | `Config.CORRECTIONS_MOCK` — обычное чтение `process.env.REACT_APP_CORRECTIONS_MOCK`, импорты статические: `npm run build` без флага даёт строку «Требуется сверка» в `index_script`; вырезание требует динамического импорта фейка или `define`-константы в rsbuild — не мелкая правка; Task 8 фейк всё равно удаляет | лишние ~8 КБ gzip в бандле до Task 8; вопрос владельцу: делать ли вырезание сейчас | | 28.10.2026 | R-22: Prettier и ESLint применены к файлам задачи (`npm run lint` падал на форматировании 17 файлов, на вложенных тернарниках окна и BOM-литерале в фейке); BOM — `\uFEFF`, поведение то же | `npm run lint` — шаг проверки Task 7 | — | | 28.10.2026 | R-23: «Вернуть к автоматике» на нераспределённой строке в фейке только снимает «исключена» и не возвращает строку в правило | фейк не знает, какое правило было автоматическим; настоящее поведение — на бэкенде (1540) | аналитик на демо на фейке не увидит возврата; проверить при подключении API | | 28.10.2026 | R-24: у агрегата флажок «Учитывать в КФО» — серый неактивный индикатор «Да / Частично / Нет», а в дизайне зелёный | решение 28.10 (флажок ставится на строках, у агрегата производное) | ответ по п. 4 «на агрегат» | | 28.10.2026 | R-25: отдельное ревью Task 7 (стиль, два мелких фикса, документация) не делалось, оно покрыто финальным ревью ветки | дифф механический, финальное ревью читает всю ветку | мелкая ошибка в Task 7 всплывёт на финальном ревью | | 28.10.2026 | R-26: фейк (R-21) остаётся в бандле до Task 8, который его удаляет | вырезание требует динамического импорта или `define` в rsbuild, и всё равно временное | ~20 КБ в бандле до подключения API | | 28.10.2026 | R-27: `mockData` и `mockCalc` остаются как тестовые фикстуры (их импортируют тесты `tableModel`, `editorModel`, `readOnly`, `draftStorage`); Task 8 удаляет только `correctionsFake.ts` (+ его тест) и ветку флага в `corrections.ts`. Уточняет R-5, R-21, R-26: «вырезается» относится только к фейку контракта `correctionsFake` | иначе при подключении API пришлось бы переписывать тесты моделей | если фикстуры устареют относительно контракта — тесты моделей перестанут ловить расхождения; сверять при Task 8 | | 28.10.2026 | R-28: окно выбора нераспределённой строки (picker) не показывает исключённые (`excluded`) — исключённую сначала возвращают в учёт флажком в таблице | исключённая строка сознательно убрана из КФО; разнесение её в правило молча вернуло бы её в расчёт | аналитику нужен лишний шаг; если захотят выбирать исключённые — снять условие `!u.excluded` в `pickerCandidates` | | 29.10.2026 | R-29: отзыв корректировки убран целиком (`RevokeModal`, пункт меню агрегата, `revokeCorrection`, фейк); меню «…» у агрегата больше нет | Лысенко 29.10, п. 9: «REVOKED не нужен, корректировку просто меняют через модалку»; в API 1540 (#208) отзыва нет | понадобится отзыв — вернуть по истории ветки (коммит до правки) | | 29.10.2026 | R-30: `status` из тела `PUT` убран, сервер сразу применяет (`APPLIED`); пометка «черновик» у `DRAFT` оставлена; кнопка — «Сохранить корректировки» (как в дизайне), не «Подтвердить корректировку» | п. 9 Лысенко про DRAFT для > 5 % и «Подтвердить» сформулирован как предположение («как будто», «наверное»); API 1540 всегда пишет `APPLIED` | если введут подтверждение — новая кнопка и поле в контракте; переименование кнопки — одна строка | | 29.10.2026 | R-31: флажок «Учитывать в КФО» — у агрегата отмечен и неактивен всегда, у строк агрегата его нет, у нераспределённых — `EXCLUDE` / `INCLUDE`; поле `excluded` у строки агрегата убрано из типов; «Да / Частично / Нет» (R-24) больше нет | Лысенко 29.10, п. 4: «залочить на агрегате галочку… в агрегате на строках так же убрать… функционал нужен для нераспределённых строк» | если захотят исключать строку внутри агрегата — вернуть флажок строки и производное состояние агрегата | | 29.10.2026 | R-32: меню строки в раскрытии агрегата («Перенести в правило…», «Убрать из правила», «Вернуть к автоматике») оставлено | п. 4 разрешает убирать строки из агрегата «при корректировках»; меню таблицы делает то же, что «×» в окне, и перенос, о котором Лысенко не писал | если перенос из таблицы не нужен — убрать меню строки, оставить «×» в окне | | 29.10.2026 | R-33: у нераспределённой строки — `line_code` (строка баланса владельца) в контракте и на экране; фильтр «Строка баланса» теперь действует и на нераспределённые по `line_code` (без строки — скрыта), их коды есть в выборе | Лысенко 29.10, п. 11: «можно оставить у нераспределённых эту строку»; раньше фильтр прятал нераспределённые, потому что строки у них не было | при `line_code = null` строка пропадает из фильтра по коду | | 29.10.2026 | R-34: граница 5 % на фронте — как в контракте (≥ 5 % — на проверку: фейк и красная разница в окне); в API 1540 ровно 5 % — в допуске | DOC-272613 «от 5 % включительно»; Лысенко на это не отвечал, вопрос не задан | при ровно 5,00 % окно покажет красным, а сервер — в допуске; таблица берёт `exceeds_threshold` из ответа и расходиться не будет | | 02.11.2026 | R-35 (Task 8): граница 5 % в живом контроле окна (`editorModel.diffOf`) и подпись фильтра «Отклонение, %» приведены к фактическому поведению API 1540 (`domain/corrections.py`, `exceeds = percent > 5`, строго больше) — `>`, не `≥`; R-34 снимается как источник расхождения | API 1540 уже в main, фронт без Task 8 не существовал в проде — совпадение с реальным сервером важнее совпадения с неоднозначным текстом контракта («от 5 % включительно», на который Лысенко не ответил); сама таблица и так брала `exceeds_threshold` из ответа и не расходилась | ровно 5,00 % теперь не красное и в окне, и в фильтре, как у сервера; если Лысенко подтвердит «включительно» — одна правка оператора в `editorModel.ts`/`CorrectionTable.tsx`, вопрос не снят, просто фронт временно синхронен с текущим сервером |