Реальный контракт AURORA-1540/1751 не дал единой POST .../allocations: решение по строке разбито на PUT/DELETE .../vgo-assignments/rule (привязка/снятие правила) и PUT .../vgo-assignments/exclude (КФО), ответ — список VgoAssignmentOut, а не вся таблица. allocate() маршрутизирует по action и перечитывает таблицу сама — вызывающий код (CorrectionContent, CorrectionEditorModal) не менялся. Фейк контракта (CORRECTIONS_MOCK) убран — API уже есть. mockData/mockCalc остаются тестовыми фикстурами (R-27). Проверено на реальном стенде (Русский Бисквит — 2025 К1): загрузка таблицы, EXCLUDE/INCLUDE, ASSIGN, снятие правила, сохранение корректировки, экспорт — без ошибок в консоли.
79 lines
8.7 KiB
Markdown
79 lines
8.7 KiB
Markdown
# Архитектура фронта arm-core/web
|
||
|
||
SPA поверх API arm-core (`/api/v1`). Своих данных и бизнес-вычислений нет: всё производное (чек-лист, сводная ОСВ,
|
||
статусы) считает сервер, фронт показывает и отправляет действия пользователя. До 21.10.2026 фронт вёлся в отдельном
|
||
репозитории `RSHB/arm-web` и переносился сюда синхронизацией; теперь — только здесь.
|
||
|
||
## Модули
|
||
|
||
| Модуль | Ответственность | Зависит от |
|
||
|---|---|---|
|
||
| `src/api/` | HTTP-клиент, токен, разбор ошибок | `conf/`, `auth/token` |
|
||
| `src/auth/` | профиль `/me`, dev-вход, права для меню | `api/` |
|
||
| `src/services/api/` | вызовы ресурсов arm-core | `api/`, `types/` |
|
||
| `src/store/` | состояние экранов (Redux Toolkit) | `services/api/` |
|
||
| `src/utils/` | чистые функции: деньги, подписи, скачивание, правила консолидаций | `types/` |
|
||
| `src/hooks/` | общие React-хуки (виртуальный список, предупреждение `beforeunload`) | React |
|
||
| `src/types/` | DTO API (повторяют `../api/src/schemas/`) | — |
|
||
| `src/components/` | примитивы UI (таблица, теги, заголовок) | antd |
|
||
| `src/widgets/` | блоки экранов (`DocumentReview` — проверка документа со сканом, `ConsolidatedOsv` — сводная ОСВ, `FilesDrawer`; консолидации — см. ниже) | `components/`, `store/`, `services/api/`, `utils/` |
|
||
| `src/layouts/` | страницы-маршруты | `widgets/` |
|
||
|
||
### Виджеты экранов консолидаций
|
||
|
||
Требования — `../openspec/changes/consolidations-ui/` (после архивации — `../openspec/specs/consolidations-ui/`),
|
||
`consolidation-setup`, `consolidated-osv-ui`.
|
||
|
||
| Виджет | Экран | Что делает |
|
||
|---|---|---|
|
||
| `ConsoleTable/ConsoleTable.tsx` | [34] | список консолидаций ГК: дерево версий, «Только в работе» (`in_work_only`), действия строки, меню «⋯» |
|
||
| `ConsoleTable/LockModal.tsx` | [35] | «Взять в работу» (`POST …/lock`) и перехват с причиной (`takeover_reason`) |
|
||
| `../utils/consolidations.ts` | — | правила без React: подписи и пояснения статусов версии, ручные переходы (`MANUAL_TRANSITIONS` — зеркало бэка), своя блокировка, «Версия», `in_work_only`, причина ≤ 1000 |
|
||
| `ConsoleTable/consts.ts` | — | цвета бейджей статусов версии |
|
||
| `ConsolidatedOsv/OsvTabs.tsx` | [30] | вкладки шагов отчёта и модалка «Проверьте встречные записи участников» при уходе с «ОСВ» (список пар — `counter_pairs` сводки) |
|
||
| `ConsolidatedOsv/CounterPairsView.tsx` | [30] | режим «Встречные записи» вкладки «ОСВ»: пары, строки держателя, строки Б без ИНН с «Указать» |
|
||
| `ConsolidatedOsv/counterPairs.ts` | — | правила без React: подпись пары, параметры адреса режима (`?view=pairs&holder=&missing=`) |
|
||
| `ConsolidatedOsv/useNumberDisplay.tsx` | [30] | «Единицы» и «Знаков после запятой» сводной ОСВ (`formatScaledAmount` из `utils/money.ts`) |
|
||
| `../hooks/useBeforeUnload.ts` | — | предупреждение браузера о несохранённых правках в открытой модалке |
|
||
| `ConsoleLegalEntities/` | [34] | панель «Организации» выбранной версии и чек-лист |
|
||
| `NewConsoleModal/` (`CompanyOptionRow.tsx`) | [42] | «Новая консолидация»; строка ЮЛ с ИНН отдельной колонкой |
|
||
| `StatusChangeModal/ChangeStatusModal.tsx` | [33-01] | «Изменить статус» (`POST …/status`); открывается из шапки `layouts/ConsolidationReportPage.tsx` |
|
||
|
||
### Виджет «Таблица корректировки» (`widgets/CorrectionTable/`)
|
||
|
||
Требования — `../openspec/changes/corrections-table-ui/` (спека `corrections-table-ui`, решения — `design.md`). Контракт —
|
||
`../../docs/dev/api-contract-corrections.md`, типы — `src/types/corrections.ts`, вызовы — `src/services/api/corrections.ts`.
|
||
|
||
Поток данных: страница отчёта → `CorrectionContent` (вкладка: загрузка, ошибка с «Повторить», экспорт, полный экран)
|
||
→ хук `useCorrectionTable` (запрос; применяется только ответ последнего запроса, `latestOnly`) → таблица целиком хранится в
|
||
родителе; `CorrectionTable` только рисует, фильтры/раскрытие/колонки — состояние родителя. Решение по строке (флажок
|
||
нераспределённой, меню) → `allocate` — на сервере (arm-core #208) это две отдельные ручки (`vgo-assignments/rule`
|
||
привязка/снятие, `vgo-assignments/exclude` включение/исключение из КФО), `allocate` сама выбирает нужную по
|
||
`action` и перечитывает таблицу целиком; «Корректировать» → `CorrectionEditorModal` → `saveCorrection`
|
||
(`PUT`, `expected_version_no`, сервер сразу применяет) → подмена одного агрегата; отзыва корректировки нет. Черновик окна —
|
||
`localStorage` (`draftStorage`).
|
||
|
||
| Файл | Тип | Что делает |
|
||
|---|---|---|
|
||
| `tableModel.ts` | чистый | строки таблицы (агрегат, его строки ОСВ, нераспределённые), фильтры, пресет правила, итоги |
|
||
| `editorModel.ts` | чистый | состояние окна: исходное из агрегата, проверки ввода, контроль баланса, кандидаты в picker, пересборка |
|
||
| `editorView.ts` | чистый | тексты окна: ошибки сохранения, плашка черновика, строка контроля, подпись «Выбрать» |
|
||
| `readOnly.ts` | чистый | подсказки «только чтение», меню строки (`allocationMenu`), тело запроса разнесения |
|
||
| `draftStorage.ts` | чистый | черновик окна в `localStorage` (ключ: пользователь + версия + агрегат) |
|
||
| `columns.ts` | чистый | ключи и группы колонок для «Настройки таблицы» |
|
||
| `useCorrectionTable.ts` | хук | загрузка, `reload`/`replace`/`replaceAggregate` |
|
||
| `CorrectionContent.tsx`, `CorrectionToolbar.tsx`, `CorrectionTable.tsx`, `HeaderFilter.tsx` | компоненты | вкладка, панель, таблица с группами колонок, воронки в заголовках |
|
||
| `CorrectionEditorModal.tsx`, `EditorSide.tsx`, `AllocationPicker.tsx` | компоненты | окно «Корректировка операции», сторона окна, выбор нераспределённой строки |
|
||
| `mockData.ts`, `mockCalc.ts` | фикстуры | данные дизайна и пересчёт агрегата; остаются как тестовые фикстуры (R-27); фейк контракта `services/api/correctionsFake.ts` удаляется в Task 8 |
|
||
| `../../utils/money.ts` | чистый | деньги копейками (`toCents`, `percentOfSmaller`, порог 5 %) |
|
||
|
||
Чистые модули покрыты vitest (`*.test.ts`); компоненты тестов не имеют (нет DOM-библиотеки), их проверяют в браузере.
|
||
|
||
## Границы
|
||
- Сетевые запросы — только через `src/api/client.ts`; `fetch` напрямую не вызывается.
|
||
- `components/` не знают про store и API; `types/` ни от чего не зависят.
|
||
- `utils/` не импортирует React, store и API.
|
||
|
||
## Сборка
|
||
`npm run build` → `web/dist`, Dockerfile ядра кладёт его в `api/web/` и FastAPI отдаёт SPA (`../README.md`).
|