Показ
Замер от: 2026-08-14 · чем проверено: ZAMER-KARTY-BLOKOV-2026-08-14.md, прогон
php vendor/phpunit/phpunit/phpunit tests/Feature/FilamentДля кого: кто добавляет страницу в/newили чинит «страница не появляется / отдаёт 403».
Что делает
Блок рисует интерфейс mp.hyp.ru/new на Filament 3. Отчётные данные площадок
приходят через Data API; административные ресурсы пользователей, прав и настроек
живут в хранилище Laravel, а запись отгрузки остаётся отдельным неприкосновенным
обходом. Живые числа на 14.08: 145 страниц (описаний PageSpec), 42 описания
отчётов, 49 их вариантов. По дереву — 69 страниц в
app/Filament/Pages/ и 11 ресурсов в app/Filament/Resources/.
⚠️ Два счёта путать нельзя: «147 файлов упоминают PageSpec» — про файлы, а не про описания; прежнее «22 ресурса» неверно — их 11.
Точка входа в код
app/Providers/Filament/AdminPanelProvider.php — метод panel(). Здесь решается,
какие страницы и ресурсы зарегистрированы в /new (список задан явно, не
автообнаружением) и как строится меню.
Чем задаётся
specs/pages/*.yaml— 145 описаний страниц;specs/grids/*.yaml— их колонки. Общий маршрутUniversalReportPageотрисовывает PageSpec по коду описания.BrandPage— другой общий маршрут для отдельных описаний бренд-менеджеров; к PageSpec его относить нельзя.app/Services/SpecPlatform/PrimaryNavigationCatalog.php— единый источник меню: его читают и Filament, и порождаемый каталог интерфейса; совпадение двух потребителей проверяетPrimaryNavigationTreeTest.config/access-control.php+app/Services/Access/AccessManager.php— бизнес-доступ: возможности (access.reports.view…) × площадки (marketplace.wildberries…).config/filament-shield.php— роли и разрешения Shield (view_any_*,page_*).
Какие правила обязан соблюдать
- Поверхность страницы объявляется в трёх местах — панель
(
AdminPanelProvider::panel), меню (PrimaryNavigationCatalog) и Shield (разрешениеpage_*или политика ресурса). Для PageSpec маршрут панели общий —UniversalReportPage, а конкретныйpage_codeдобавляет каталог. Пропуск любого слоя молчалив: пункта нет либо прямой переход получает 403. Это самая частая ловушка блока. - Shield даёт ресурсу 403 только при наличии политики. Без политики его ворота
не принимают решение, и запрет часто выглядит как отсутствующая страница или
пункт. Это не отменяет отдельный 403 от
EnforceBusinessAccess. Политики лежат вapp/Policies/; обычная проверка начинается с$user->can('view_any_…'). - Проверка прав идёт на прямые переходы, а не только на меню. Мидлварь
app/Http/Middleware/EnforceBusinessAccess.phpстоит на всех маршрутах/newи отвечает 403 «Эта роль не имеет доступа к разделу или маркетплейсу». - Отгрузку показывать можно, менять нельзя (
RULES.md, «НЕПРИКОСНОВЕННОЕ»).
Чем проверяется
APP_BASE_PATH="$PWD" php vendor/phpunit/phpunit/phpunit tests/Feature/Filament
Набор включает проверки значений в ячейках (не только факта отрисовки), дерева
меню и прямого доступа. APP_BASE_PATH удерживает Laravel в текущем worktree,
даже когда vendor/ подключён ссылкой из основного checkout. Сверка ссылок —
python3 scripts/docs/check_doc_links.py.
Поимённое соответствие «описание PageSpec → пункт меню» проверяет
PrimaryNavigationTreeTest::test_every_pagespec_page_is_reachable_from_the_tree
(tests/Feature/Filament/PrimaryNavigationTreeTest.php:355-381): тест собирает
из настоящего меню адреса с page_code= и сверяет их с
PageSpecRegistry::pages(). Выпавшая страница делает прогон красным.
Чего делать нельзя
- Не регистрировать страницу в одном месте из трёх и не надеяться на
автообнаружение: в целевом режиме
/newсписок страниц и ресурсов задан явно (автообнаружение осталось только у прежнего/admin), и неупомянутый класс не существует как маршрут. - Не менять меню в обход
PrimaryNavigationCatalog. У каталога два потребителя, и расхождение между ними — это мёртвые пункты, которые сервер отдаёт с кодом 200, а браузер дорисовывает надписью «Страница не найдена». - Не удалять страницы-дубли из прежних экранов ради «чистоты»: добавление вместо перестройки — решение владельца 07.08.2026.
- Не ослаблять проверку прав ради «страница хотя бы открылась»: ложный успех хуже молчания.
Что НЕ установлено
- Какие именно роли несут какие
page_*-разрешения в боевой базе — базы нет, не замерено. Поэтому поимённая цепочка «описание → пункт меню → назначенное роли разрешение» доказана только до пункта меню.
Куда за подробностью
- docs/ui/README.md — каталог страниц и как устроен интерфейс.
- docs/ui/TWO-STACKS.md — два контура, маршруты, вход.
- docs/domain/ACCESS-CONTROL.md — модель бизнес-доступа.
- docs/guards/app-guards.md — сторожа A1 (бизнес-доступ) и A2 (токен API).
specs/pages/,specs/grids/— описания страниц;app/Filament/Pages/UniversalReportPage.php— как описание становится экраном.