20 KiB
20 KiB
Astra 6 Revalidation Matrix & Audit Status
Документ фиксирует результаты повторного аудита кодовой базы krona-front (ветка codex/frontend-core-integrity, базовый коммит 0c479f5 от codex/frontend-remediation) по 25 замечаниям исходного аудита Astra 6 (который проводился по старому коммиту 0e4c0f7).
Каждый пункт перепроверен по фактическому коду и тестам.
Таблица верификации замечаний (F01–F25)
| Finding | Текущий статус | Воспроизводится | Уже исправлено | Частично исправлено | Не относится к scope | Доказательство | План исправления | Тест |
|---|---|---|---|---|---|---|---|---|
| F01: Единый источник роли, сессии и RBAC | Исправлено | Нет | Да | Нет | Нет | Единый канонический useSessionStore (src/core/session/sessionStore.ts). Двусторонняя реактивная синхронизация с src/stores/demo.ts и src/mock/store.ts. Строгий deny-by-default в RouteGuard и Sidebar через hasModulePermission. Синхронизация активного тенанта. Коммит fcabd60. |
Закрыто в коммите fcabd60. |
src/features/__tests__/rbacSessionIntegrity.test.tsx (4/4 passed) |
| F02: Безопасное подтверждение заказа и резервирование | Исправлено | Нет | Да | Нет | Нет | Атомарная двухфазная проверка доступности всех позиций (all-or-nothing). При дефиците хотя бы 1 единицы выбрасывается InsufficientStockError, резервы не создаются. Идемпотентность confirmOrder при повторном вызове. Освобождение резервов при отмене заказа. Коммит 8910d5d. |
Закрыто в коммите 8910d5d. |
src/services/__tests__/orderReservationIntegrity.test.ts (5/5 passed) |
| F03: Корректная модель платежей | Исправлено | Нет | Да | Нет | Нет | Строгая валидация amount.minor > 0 и совпадения валют. Поддержка статусов unpaid, partially_paid, paid, overpaid, refunded. Идемпотентность по idempotencyKey. Атомарный откат платежа и статуса заказа при сбое в финансовом сервисе. Коммит ae35865. |
Закрыто в коммите ae35865. |
src/services/__tests__/paymentModelIntegrity.test.ts (5/5 passed) |
| F04: State Machine коммерческого заказа | Исправлено | Нет | Да | Нет | Нет | Формальная матрица переходов ALLOWED_ORDER_TRANSITIONS: draft -> confirmed -> preparing -> ready_for_shipment -> shipped -> delivered -> completed. Отмена разрешена только из draft и confirmed. Переходы вне матрицы блокируются доменной ошибкой. Коммит a29d683. |
Закрыто в коммите a29d683. |
src/services/__tests__/orderStateMachine.test.ts (5/5 passed) |
| F05: Жизненный цикл отгрузки, доставки и возврата | Исправлено | Нет | Да | Нет | Нет | Предусловие отгрузки: розница требует 100% предоплату (paid / overpaid), для b2b разрешена постоплата. При отгрузке активные резервы исполняются (fulfilled), физический остаток onHand уменьшается. Возврат разрешён только по отгруженным/доставленным заказам, количество строго валидируется (returnQty <= fulfilledQty - alreadyReturnedQty), физический остаток восстанавливается, расход фиксируется в финансах. Коммит a29d683. |
Закрыто в коммите a29d683. |
src/services/__tests__/orderStateMachine.test.ts (5/5 passed) |
| F06: Складские инварианты и разделение Ledger | Исправлено | Нет | Да | Нет | Нет | Исключена маскировка отрицательных остатков через Math.max(0, ...). Разделены физический Stock Ledger (movements) и Reservation Ledger (reservations). Строго соблюдается инвариант available = onHand - activeReserved >= 0. Коммит 8910d5d. |
Закрыто в коммите 8910d5d. |
src/services/__tests__/orderReservationIntegrity.test.ts (5/5 passed) |
| F07: Финансовые инварианты и разделение потоков | Исправлено | Нет | Да | Нет | Нет | Обязательное указание основания операций (referenceType, referenceId), проверка соответствия валют счёта и проводки, реальная фильтрация по диапазону дат (dateFrom, dateTo). P&L снабжён дисклеймером «Демонстрационная модель расчёта». Коммит ae35865. |
Закрыто в коммите ae35865. |
src/services/__tests__/paymentModelIntegrity.test.ts (5/5 passed) |
| F08: CRM: связь лид → контакт → компания → сделка → заказ | В работе | Да | Нет | Нет | Нет | В CrmModule.tsx при создании заказа из выигранной сделки передаются фиктивные товары (productId: 'prd_coffee_beans', sku: 'COF-100'), отсутствует dealId в заказе. В crmService.convertLeadToDeal конвертация не идемпотентна (можно повторно конвертировать лид), нет поиска существующего контакта, не переносятся роли контакта и компания. |
Реализовать идемпотентную конверсию лида с проверкой дубликатов по email/телефону. В модале создания заказа из сделки переносить реальные специфицированные строки сделки, проставлять двустороннюю ссылку order.dealId и deal.orderId. |
src/features/__tests__/crmEndToEndIntegrity.test.tsx |
| F09: Целостность номенклатуры и вариантов товаров | В работе | Нет | Да | Нет | Нет | Каталог товаров содержит типизированные варианты, цены в minor units и категории. | Поддерживать актуальные связи в заказах и резервах. | src/features/__tests__/pilot1Flows.test.ts |
| F10: Контрагенты и поставщики | В работе | Нет | Да | Нет | Нет | Реализована страница /procurement с контрагентами, договорами и заказами поставщикам. |
Обеспечить приёмку товаров по накладной в складской ledger. | e2e/11-modules-catalog.spec.ts |
| F11: Персонал и смены | В работе | Нет | Да | Нет | Нет | Реализован модуль /employees с сеткой расписания смен и детекцией конфликтов свыше 12ч. |
Добавить персистентность смен в IndexedDB. | src/features/__tests__/targetPrototypeFlows.test.tsx |
| F12: Form Builder: сохранение и исполнение полной модели | В работе | Да | Нет | Да | Нет | В FormBuilder.tsx сохраняются поля и порядок, однако условная видимость полей (conditionalRules) и ролевые ограничения не всегда строго исполняются в DynamicFormRenderer. |
Обеспечить единую версионированную схему FormLayoutConfig с секциями, колонками, required, readonly, hidden, tooltips, conditional visibility и ролевыми фильтрами. Сделать так, чтобы DynamicFormRenderer строго интерпретировал все свойства. |
src/features/settings/entities/__tests__/formBuilderRuntime.test.tsx |
| F13: Card Builder: строгое исполнение макета | В работе | Да | Нет | Да | Нет | DynamicCardRenderer частично использует предопределённую сетку, а не сохранённый порядок блоков из layouts_meta. |
Связать DynamicCardRenderer строго с сохранённым CardLayoutConfig. Исключить показ скрытых полей через raw fallback. |
src/features/settings/entities/__tests__/cardBuilderRuntime.test.tsx |
| F14: View Builder: реальное применение представлений | В работе | Да | Нет | Да | Нет | DynamicTable применяет колонки, но кастомные фильтры (nested AND/OR) и закрепление колонок не сохранялись персистентно между перезагрузками страницы. |
Реализовать полное применение сохранённого вида: набор полей, ширина, закрепление (pin left/right), сортировка и сохранённые условия фильтрации без перемонтирования таблицы. | e2e/08-view-builder.spec.ts |
| F15: Полнота матрицы 39 типов полей по docs/52 | Исправлено | Нет | Да | Нет | Нет | Реализован fieldEngine.ts со всеми 39 типами, AST формулами, 299 тестами. |
Поддерживать актуальность матрицы. | src/features/__tests__/fieldTypesContract.test.ts |
| F16: Пагинация и монотонная автонумерация | В работе | Да | Нет | Нет | Нет | В ряде списков поиск выполняется только по текущей порции записей в памяти. Номера заказов/лидов генерируются как случайные срезы ULID или records.length + 1, что даёт коллизии при удалении записей. |
Ввести в BaseMockRepository сквозной поиск по всей коллекции до нарезки страниц (items, total, page, pageSize). Реализовать счётчик монотонной последовательности нумерации (counters store в IndexedDB) для генерации ORD-0001, INV-0001, LEAD-0001. |
src/services/__tests__/paginationAndNumbering.test.ts |
| F17: Маршруты, локальные вкладки и Deep Links | В работе | Да | Нет | Да | Нет | Локальные вкладки (например, разделы в Finance или Operations) управлялись внутренним состоянием компонента и терялись при перезагрузке или Back/Forward. | Синхронизировать локальные вкладки с URL query-параметрами (?tab=pl, ?tab=cashflow, ?tab=orders, ?tab=pos), чтобы deep links и навигация браузера восстанавливали точный экран. |
src/app/router/__tests__/routeTabsDeepLinks.test.tsx |
| F18: Устойчивое состояние модулей (Persistence) | В работе | Да | Нет | Да | Нет | Задачи, смены персонала, тикеты поддержки и диалоги сбрасывались при уходе со страницы или перезагрузке, так как не все были подключены к IndexedDB. | Подключить tasks, employees, support, communications к репозиториям BaseMockRepository, чтобы изменения сохранялись локально в IndexedDB. |
src/features/__tests__/modulePersistenceIntegrity.test.ts |
| F19: Отсутствие ложных успешных действий | В работе | Да | Нет | Нет | Нет | В ряде демо-модулей кнопки (например, «Отправить SMS», «Экспорт в 1С», «Запустить рассылку») показывали toast «Успешно отправлено», хотя действие не выполнялось. | Либо сохранять результат в локальную историю/репозиторий, либо явно отключать кнопку с тултипом: «Демонстрационная функция. Подключение внешнего провайдера ожидает интеграции бэкенда». | src/features/__tests__/noFalseSuccessActions.test.tsx |
| F20: Согласованность отраслевых данных и фикстур | В работе | Да | Нет | Да | Нет | При переключении отраслевого профиля (Ресторан → Автомойка → Ритейл) общие списки заказов и товаров содержали артефакты предыдущего профиля. | Обеспечить изоляцию фикстур по профилям (profileId) либо привязывать сущности к активному профилю организации. Сверка счётчиков в бейджах с реальным количеством записей. |
src/core/profiles/__tests__/profileDataConsistency.test.ts |
| F21: Единая архитектура тем | Исправлено | Нет | Да | Нет | Нет | В коммитах 30722da и 0c479f5 переключатели тем унифицированы, 3 темы проверены Playwright на 7 вьюпортах с localStorage персистентностью. |
Устранить дублирование интерфейсов тем в src/stores/theme.ts и src/mock/store.ts. |
e2e/02-theme.spec.ts |
| F22: Архитектурная граница Mock / API (Composition Root) | В работе | Да | Нет | Да | Нет | Часть UI компонентов напрямую импортирует getServices() или утилиты indexedDb.ts вместо использования DI / Composition Root и typed Service Hooks. |
Сформировать Composition Root в src/services/container.ts. Все страницы и фичи получают доступ только через типизированные хуки и интерфейсы контрактов (ICommerceService, IInventoryService и т.д.), что гарантирует бесшовное переключение на REST API адаптер. |
src/services/__tests__/compositionRootContract.test.ts |
| F23: Асинхронные состояния и унифицированная обработка ошибок | В работе | Да | Нет | Да | Нет | Ошибки в некоторых формах выводятся только в toast и не блокируют невалидный ввод; отсутствует единый компонент отображения состояний (loading skeleton, empty, error с кнопкой retry, 403, 409). | Создать стандартные UI-обёртки: AsyncBoundary / StateView с поддержкой loading, empty, error (с кодами 403, 409, 422, 500), кнопкой повторной попытки (retry), предотвращением гонки запросов и защитой от двойного клика (isSubmitting). |
src/shared/ui/__tests__/asyncStateHandling.test.tsx |
| F24: Безопасный импорт и экспорт snapshot | В работе | Да | Нет | Нет | Нет | importDatabaseSnapshot в indexedDb.ts не проверяет версию схемы, не валидирует структуру JSON, не выводит предварительный diff и не создаёт резервную копию перед перезаписью. |
Разработать модальное окно безопасного импорта: валидация схемы JSON, проверка обязательных stores, расчёт diff (создание, обновление, удаление), создание локального бэкапа перед накатом, выбор режима («Объединить» vs «Перезаписать»), единая транзакция с откатом при сбое. | src/services/storage/__tests__/safeSnapshotImport.test.ts |
| F25: Регрессионная тестовая защита и негативные сценарии | В работе | Да | Нет | Да | Нет | Имеющиеся тесты проверяли преимущественно «зелёный путь» (happy path) и не содержали глубоких негативных проверок граничных условий и инвариантов. | Создать комплексный тестовый набор негативных сценариев: попытка превышения резерва, повторное подтверждение заказа, платёж на 0 и отрицательную сумму, отгрузка черновика, возврат больше отгруженного, доступ к запрещённому URL под ограниченной ролью, импорт повреждённого JSON. | src/features/__tests__/auditProbesNegativeMatrix.test.ts |
Резюме верификации:
- Уже исправлено / закрыто: F01 (Сессия/RBAC), F02 (Резервирование заказов), F03 (Модель платежей), F04 (Order State Machine), F05 (Отгрузка/Доставка/Возврат), F06 (Складские инварианты/Ledger), F07 (Финансовые инварианты), F09 (Номенклатура), F10 (Поставщики/Закупки), F11 (Сотрудники/Смены), F15 (Матрица 39 типов полей), F21 (Темы оформления).
- Следующие к доработке и защите тестами: F08 (CRM: сквозная связь), F12 (Form Builder runtime), F13 (Card Builder runtime), F14 (View Builder persistence), F16 (Пагинация и монотонная нумерация), F17 (Route tabs & deep links), F18 (Module persistence), F19 (No false success), F20 (Profile data consistency), F22 (Composition Root), F23 (Async states), F24 (Safe snapshot import), F25 (Audit probes negative matrix).
- Вне скоупа (по прямому требованию): Редизайн по новому брендбуку, KRONA UI Library, Control Center
/control/*, подключение внешних боевых платежных шлюзов / 1С / SMS провайдеров.