diff --git a/docs/agent/FRONTEND_CODE_STANDARD_REVIEW_PLAN.md b/docs/agent/FRONTEND_CODE_STANDARD_REVIEW_PLAN.md new file mode 100644 index 0000000..262cb18 --- /dev/null +++ b/docs/agent/FRONTEND_CODE_STANDARD_REVIEW_PLAN.md @@ -0,0 +1,126 @@ +# План приведения фронтенда к стандарту кода + +Дата аудита: 2026-10-03 +Репозиторий: `evening_detective_frontend` + +## Результат проверки + +- `npm run type-check` — успешно. +- `npx eslint .` — успешно. +- `npx stylelint 'src/**/*.{css,scss,vue}'` — успешно. +- Проверки запускались без `--fix`, исходный код аудитом не изменён. +- `src/api/generated/**` и `dist/**` в план исправлений не включены. + +Автоматические проверки подтверждают синтаксическую и базовую lint-корректность, +но не проверяют все обязательные правила `docs/FRONTEND_CODE_STANDARD.md`. + +## Приоритетный план + +### 1. Ошибки, загрузка и повторные действия — P0 + +Цель: ни один API-вызов не должен терять ошибку или оставлять UI в неясном +состоянии. + +- Обработать `getPermissions()` в `src/components/HeaderMenu.vue:24` и + `src/components/OfficePage.vue:17`: показать русское сообщение через + `useMessage()` и добавить состояние загрузки/ошибки, если оно влияет на UI. +- Обернуть начальные вызовы `getStory()` и `getAnswers()` в + `src/components/TeamStoryPage.vue:115` в единый flow с отображением ошибки. +- Проверить мутации `src/components/GamePage.vue:287-655` и + `src/components/ScenariosEditorPage.vue:85-529`: для каждого действия оставить + `try/catch/finally`, пользовательское сообщение и блокировку повторной отправки. +- Проверить `src/components/LoginPage.vue:40-76`: во время всех операций формы + кнопки должны быть недоступны, а ошибка должна обрабатываться в том же flow. +- Для каждого экрана явно сохранить состояния loading, empty и error в template. + +Готово, когда ручной API-ошибкой можно проверить, что пользователь получает +сообщение, кнопка разблокируется после `finally`, а частично изменённые данные не +перезаписываются фоновым обновлением. + +### 2. Доступность интерактивных элементов и изображений — P0 + +- Заменить кликабельные `div`/`span` или дать им полноценную клавиатурную + семантику в `src/components/HeaderMenu.vue`, `GamePage.vue`, + `PlaceBlock.vue`, `IntroBlock.vue` и `ScenariosPage.vue`. +- Восстановить видимый focus: в частности, не оставлять + `outline: none` в `src/components/GameInputForm.vue:186-189` без равноценной + замены. +- Добавить осмысленные `alt` к изображениям в `src/components/PlaceBlock.vue` + (строки 268, 298, 345, 355, 368, 453, 504), а также проверить остальные + `` через поиск по `src`. +- Для модальных окон в `OfficePage.vue:261` и `UsersPage.vue:114` добавить + `n-card` с `role="dialog"` и `aria-modal="true"` либо эквивалентную + доступную структуру; проверить остальные модальные окна на единообразие. +- Добавить доступные названия/`title` там, где действие выражено только иконкой + или символом `x`. + +Готово, когда все действия доступны Tab/Enter/Space, focus виден, изображения +озвучиваются понятно, а модальные окна имеют корректную семантику. + +### 3. Границы компонентов и типизация — P1 + +- Оставить `*View.vue` маршрутными прокси. Перенести содержимое и стили + `src/views/HomeView.vue` в `src/components/HomePage.vue`; стиль сделать + `scoped`. Вьюхи документов с `DocsPage` и `HeaderMenu` отдельно проверить на + соответствие этому правилу. +- Перевести runtime-описания props на typed `defineProps` там, где нет причины + сохранять `PropType`: `HeaderMenu.vue`, `PlaceBlock.vue`, + `GameInputForm.vue`, `IntroBlock.vue`, `QuestionBlock.vue`. +- В `PlaceBlock.vue` и `TeamStoryPage.vue` проверить типы режимов и callback-ов: + заменить широкие `string`/необязательные утверждения на существующие типы, + не дублируя generated API. +- Не выделять новые composable или универсальные обёртки: выносить только + реально повторяющийся flow после исправления конкретных callers. + +Готово, когда маршрутные страницы не содержат экранной логики, props/emits +типизированы, а `any` и необоснованные `as` отсутствуют. + +### 4. Формы и единообразие UI — P1 + +- Проверить обязательные поля и сообщения ошибок в формах + `LoginPage.vue`, `GameInputForm.vue`, `TeamStoryPage.vue` и + `ScenariosEditorPage.vue`. +- Использовать Naive UI для обычных UI-контролов. Нативные контролы в + `GameInputForm.vue:96-117` и `TeamStoryPage.vue:272,321` оставлять только + там, где они нужны бумажному визуальному стилю; в таком случае сохранить + доступную семантику и focus. +- Проверить, что кнопки с мутациями имеют `loading`/`disabled`, а пустые и + ошибочные ответы явно видны пользователю. + +### 5. CSS-токены и локальность стилей — P2 + +- Сгруппировать повторяющиеся цвета из компонентов в уже существующую палитру + `src/assets/base.css`; новые токены добавлять только с семантическими именами. +- Не расширять глобальные стили. После переноса `HomeView.vue` проверить, + что одноразовые классы не попали в `main.css`. +- Сохранять алфавитный порядок CSS-свойств и существующие mobile-first + брейкпоинты. + +## Порядок выполнения + +1. Исправить ошибки/loading и доступность в общих и часто используемых + компонентах (`HeaderMenu`, `PlaceBlock`, `GameInputForm`). +2. Исправить `GamePage`, `TeamStoryPage`, `ScenariosEditorPage` по месту, + не расширяя diff несвязанным рефакторингом. +3. Перенести `HomeView` в page-компонент и типизировать props. +4. Выполнить точечную миграцию цветов и стилей только затронутых файлов. +5. Запустить обязательные проверки: + + ```bash + npm run type-check + npm run lint + npm run lint:css + npm run build + ``` + +6. Выполнить ручной smoke-check: вход/регистрация, меню с клавиатуры, загрузка + и ошибка API, создание/редактирование сценария, игровой ход, модальные окна, + просмотр изображений и мобильная ширина. + +## Не входит в исправление + +- Переписывание всего существующего кода только ради косметического соответствия. +- Изменение `src/api/generated/**`, protobuf-контрактов и продуктового поведения. +- Новые зависимости, новый state manager, общие абстракции «на будущее». +- Редизайн и массовая замена бумажного визуального языка. +