- toggleTreeCheck (utils/treeChecks): родитель отмечен, только если отмечены все потомки, на всех уровнях; скрытые поиском отметки берутся из состояния выпадашки — снятые подряд отметки больше не возвращаются; тесты. - Правило тегов из App.css → ConsolidationChessTableFilter.css (App.css пустой, как в main); класс с формы ЮЛ снят. - Спека: Known issues — остаток (одна сторона Дт/Кт) в техдолг AURORA-1799, решение (п), tasks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
14 KiB
Context
Экран «Шахматка» [31-01] добавлен в arm-core/web PR #158 (ветка feat/chessTable, AURORA-1538) как вторая вкладка страницы
отчёта по версии. Страница layouts/ConsolidatedOsvPage.tsx разделена: общую шапку и вкладки держит
layouts/ConsolidationReportPage.tsx, содержимое вкладок — widgets/ConsolidatedOsvContent (прежняя сводная ОСВ без изменений
поведения) и widgets/ConsolidatedChessContent (матрица ConsolidationChessTable и результирующая таблица
ConsolidationChessResTable). Бэкенд — change 2026-10-16-intercompany-matrix (матрица, результирующая таблица) и
2026-10-22-intercompany-result-table-export (выгрузка результирующей таблицы); расчёт — чистая функция версии, ничего не
хранится.
Decisions
- D-1. Маршрут
:tab.OsvTabsберёт активную вкладку изuseParams().tab(по умолчаниюosv) и по выбору заменяет последний сегмент адреса. Неизвестныйtabзаменяется наosv(navigate(…, {replace: true})). - D-2. Ключ версии. Страница отчёта разделена на обёртку с
key={version_id}и содержимое: при смене версии карточка, фильтры и данные создаются заново (как было вConsolidatedOsvPage). - D-3. Режим расчёта из выбора счетов:
manual— при непустых Дт и Кт,all— при пустых обоих; при одной выбранной стороне запроса нет (бэкенд ответил бы 422 наmanual, аallпоказал бы не то, что выбрано). Тот же признак выбирает маршрут экспорта. - D-4. Единицы, знаки и фильтр компаний — на клиенте. Запрос повторяется только при смене выбора счетов или версии.
Единицы — сдвиг запятой в десятичной строке (
utils/chessTableCellFormatValue.ts),Intl.NumberFormatполучает строку и форматирует её как точное десятичное (без float). - D-5. План счетов —
GET /directories/accountsцеликом, деревья Дт и Кт строятся на клиенте поparent_id. - D-6.
apiFetchBlob(path, init)принимаетRequestInit, чтобы выгружать POST-ом с телом; безinitповедение прежнее. - D-7. Полноэкранный режим — Fullscreen API на контейнере блока, состояние следует за
fullscreenchange; выпадающие окна antd рендерятся вdocument.fullscreenElement(ConfigProvider getPopupContainer). - D-8. Итоги — задача бэкенда. Решение владельца 22.10.2026: агрегаты (строки «Итого») должен отдавать API. Перенос —
технический долг: AURORA-1756 (итоги и правило суммирования в API, ждёт аналитику AURORA-1373) и AURORA-1757 (вывод итогов из
API). До этого строки «Итого» остаются клиентскими (решение владельца: «особо не мешает»): точное сложение строк через
sumAmounts, под матрицей —amount_aпо колонке, под результирующей таблицей — все статьи по колонке; колонка «Итого» результирующей таблицы —group_totalиз ответа. - D-9.
useNotificationApiмемоизирован (useMemoпоnotificationизApp.useApp(), который antd сам мемоизирует): объект уведомлений стабилен между рендерами, поэтомуloadData/loadResData—useCallback([notification]), а эффекты загрузки зависят от них без лишних перезапросов.
Known issues
Открытая проблема на момент слияния (решение владельца 23.10.2026 — сливать, остаток в техдолг AURORA-1799):
- Выбрана одна сторона Дт/Кт: «Экспорт» недоступен, но таблица показывает прежние данные, подсказка — всплывающее уведомление и постоянный текст внутри выпадающего окна, текста у таблицы и у фильтров нет. Целевое поведение — решение (ж).
Пункты раунда 3 про поиск в дереве счетов и стили закрыты ревьюером (решение (п)).
Decisions made without discussion
- 2026-10-21 (а). Спеку пишет ревьюер в ветке автора — по решению владельца (разрешено явно); альтернатива — оставить автору. Цена ошибки: автор может не согласиться с формулировками; правится одним коммитом в этом же change.
- 2026-10-21 (б). Спека описывает фактическое поведение, дефекты вынесены в «Known issues». Отменено 22.10.2026 (е). Обоснование: спека — единственный
источник истины при рулингах, а закреплять баги требованиями нельзя; иначе их закрытие превратится в «нарушение спеки». Цена
ошибки: отдельные требования (например, режим
allпри выборе одной стороны, «Итого» из расхождений) описаны как есть и после исправления потребуют MODIFIED. - 2026-10-21 (в). При восстановлении затёртого фронта (коммит
175343b) изorigin/mainвзяты целиком все файлы без шахматочных изменений, а вApp.tsx,layouts/index.ts,api/client.ts(параметрinit),OsvTabs.tsx,ConsolidatedOsvContent.tsxоставлены изменения шахматки. Возвращёнkey={version_id}(разделением страницы на обёртку и содержимое — поведение как в main). Обоснование: изменения PR в этих файлах относятся к шахматке; цена ошибки — незамеченная откатившаяся правка main в этих пяти файлах (построчно сверено сorigin/main, расхождений кроме шахматочных нет). - 2026-10-21 (г). Механические правки biome без смены поведения (коммит
e19291c): типIntercompanyMatrixResponseуlet res,Number.isNaN,keyуspanвOsvTabs,?? nullвместо пустого фрагмента. Предупреждения eslint (8 новых в коде шахматки:any, deps хуков,console) не исправлялись — они входят в Known issues. Цена ошибки:keyнаspanвнутриTooltipбезвреден, но избыточен. - 2026-10-21 (д). Дельта к
consolidated-osv-uiне делается: вкладки описаны в новой спеке, текстconsolidated-osv-uiне правился, чтобы не смешивать UI-половины. Цена ошибки: при архивации две спеки частично описывают один компонент (OsvTabs). - 2026-10-22 (е). Спека переписана на целевое поведение (раунд 3 ревью): владелец решил, что спеки и тесты чужих PR ведём мы, а автор правит продуктовый код; целевая спека даёт автору однозначный ориентир, расхождения кода — в «Known issues». Цена ошибки: до исправлений спека и код ветки расходятся; PR не сливается, пока «Known issues» не закрыты.
- 2026-10-22 (ж). Выбрана одна сторона Дт/Кт — пустая таблица с текстом «Для расчёта по счетам выберите счета и в Дт, и в Кт» у таблицы и у фильтров, «Экспорт» матрицы недоступен. Альтернатива — оставить прежние данные с подсказкой; отвергнута: на экране были бы данные, не соответствующие фильтру. Цена ошибки: правка текста и одного условия.
- 2026-10-22 (з). Правило отметок дерева по полному плану счетов (родитель отмечен ⇔ отмечены все потомки), в том числе при поиске. Обоснование: бэкенд разворачивает выбранный счёт в потомков, лишняя отметка родителя меняет расчёт. Цена ошибки: если аналитик захочет «родитель + выбранные субсчета» как отдельный режим — MODIFIED требования.
- 2026-10-22 (и). Запасные имена файлов
Шахматка_<ГК>_<год>_<квартал>.xlsxиРезультирующая_таблица_ВГО_<ГК>_<год>_<квартал>.xlsx. Цена ошибки: низкая, имя изContent-Dispositionприоритетнее. - 2026-10-22 (к). Тесты форматтера
utils/chessTableCellFormatValue.test.tsнаписаны ревьюером: сдвиг единиц, точное округление, большие суммы, «-0,00», пустые и нечисловые значения при любых единицах. - 2026-10-22 (л). В ветку влит
main(PR #159), чтобы выгрузка результирующей таблицы работала на стенде из ветки. - 2026-10-22 (м). Желательные пункты ревью закрыты ревьюером (решение владельца): форматтер (проверка числа до сдвига
запятой,
Intl.StringNumericLiteralчерезES2023.Intlвlibtsconfig вместоas any, без мёртвого разбора скобок), запасные имена (utils/download.xlsxFilename), отдельные флаги выгрузки, зависимости эффектов (D-9), «—» вместо выдуманного нуля, ячейки по макету, «Год»/«Период» версии только для чтения, сервисservices/api/intercompanyMatrix.tsсwithJsonBody, типы шахматки вtypes/api.ts,Account.kind: 'A' | 'P' | 'AP' | null. Цена ошибки: конфликты слияния у автора вConsolidatedChessContent.tsxиConsolidationChessTableFilter.tsx— он правит те же файлы по «Known issues»; автору сказано начать сgit pull. - 2026-10-22 (н). «-0,00» убирается проверкой готовой строки, а не опцией
signDisplay: 'negative'. Обоснование: на движке без Intl.NumberFormat v3 неизвестное значениеsignDisplayбросаетRangeErrorи ломает весь экран, а проверка строки безопасна везде. Цена ошибки: нет. - 2026-10-22 (о). Расхождение в скобках всегда, в том числе нулевое —
(0,00): в APIvariance_amount— модуль разности (неотрицательный), скобки в макете 31-01 — способ показа третьей строки, а не знак. Значок пропущенных строк ОСВ — оранжевыйWarningOutlinedу первого числа. Подпись «Период» (не «Квартал») — как в макете. Цена ошибки: правка вида ячейки. - 2026-10-23 (п). Остаток раунда 3 закрыт ревьюером, пункт про одну сторону Дт/Кт — в техдолг (решение владельца: «доправим
сами, потом сольём»). Отметки дерева — чистая функция
utils/treeChecks.toggleTreeCheck(правило (з) снизу вверх по полному дереву на всех уровнях; скрытые поиском отметки берутся из состояния выпадашки, а не из применённого фильтра — иначе снятые отметки возвращались), тестыutils/treeChecks.test.ts. Правило тегов изApp.cssперенесено вConsolidationChessTableFilter.css, класс с формы ЮЛ снят. Пустая таблица с подсказкой при одной стороне — AURORA-1799. Цена ошибки: при одной стороне до AURORA-1799 на экране прежние данные, выгрузка недоступна.