--- description: Унифицированные стандарты разработки для репозиториев воркспейса dnd_project alwaysApply: true --- # Унифицированные стандарты разработки ## Область применения - Разделы про **React / renderer UI / формы / модалки** относятся к репозиториям с пользовательским интерфейсом (**`dnd_player`**, **`project-converter`** и т.п.). Для **headless** кода (**`DndGamePlayerLicenseServer`**) применимы блоки про слои данных, контракты, тесты и дисциплину изменений; требования к модалкам и renderer UI к такому коду **не предъявляются**. - **i18n** (ключи пользовательских строк и т.д.) — **только для продукта DNDGamePlayer**, репозиторий **`dnd_player`**; планируемые локали: **ru**, **en**. В **`project-converter`**, **`DndGamePlayerLicenseServer`**, **`cursorAi`** отдельных требований по i18n **нет**. - Репозитории **без TypeScript**: требования раздела «TypeScript и качество» выполняются после внедрения TS; до этого — **эквивалентная строгость**: `node --check` по согласованным входным файлам, явные контракты (JSDoc при необходимости), отсутствие необоснованного ослабления проверок, тесты на изменённое поведение в доступном стеке. ## Архитектура и папки - Фичи организуются по папкам: один доменный блок = одна директория. - Публичный вход фичи обычно размещается в `index.tsx` (или в согласованном с репозиторием входном файле). - Рядом с фичей допустимы локальные конфиги таблиц, схем модалок и подпапки `Modals`, `Components` по необходимости. - Страницы и составные экраны остаются тонкими: сторы, HTTP/API, утилиты и типы контрактов выносятся отдельно. - Типы API и DTO держатся в выделенной зоне (`interfaces`, `api-types` и т.п.). - Исторические опечатки и неудачные имена в путях не размножаются; при правках в зоне их нужно по возможности исправлять. ## Маршруты и доменные строки - Пути маршрутов берутся из единого модуля констант приложения (если в проекте есть маршрутизация). - Строковые литералы не дублируются в `Route`, `Link`, `navigate`. - Роли, статусы и иные перечислимые значения задаются через `const` + `as const` и производный union-тип (или согласованный `enum`). - Магические строки в доменных значениях не допускаются. ## Состояние и данные - Локальный UI-стейт ведется предсказуемо, включая выбранную библиотеку реактивности, если она принята в проекте. - Доступ к глобальному стору делается через явный контекст или согласованный DI. - Скрытые синглтоны в компонентах не используются. - При сочетании библиотеки запросов и стора зоны ответственности разделяются явно: - кэш и запросы, - конфиг, базовые URL, навигация, сессия. - HTTP работает через общий слой (клиент, перехватчики, обработка ошибок). - Базовые URL и окружение берутся из конфигурации, а не из JSX. ## Формы и валидация - На проекте используется один канон валидации и резолвера для форм (например `react-hook-form`, если принят в репозитории). - Новый код не должен создавать параллельный стек валидации без решения команды и плана миграции. - Для тяжелых форм используются: - `memo`, - декомпозиция на подкомпоненты, - вынос генерации схем в утилиты. - Дублирование правил валидации в разметке не допускается. - Создание и редактирование одной и той же сущности реализуются **одной общей формой** (один компонент/модуль формы, общая схема по возможности). Отдельные «форма создания» и «форма редактирования» как копии друг друга не допускаются. - Если поведение полей отличается между режимами создания и редактирования, различия задаются условно: условный рендеринг блоков полей, условная обязательность и правила в схеме валидации, различие дефолтов и `defaultValues`, флаги режима (`mode`, `isEdit` и т.п.) — без дублирования разметки и правил там, где достаточно параметризации. ## UI и стили - **Единый источник** визуальных примитивов и отступов — **существующие общие компоненты и соглашения этого репозитория** (не внешняя «дизайн-система из правил»). Перед добавлением нового примитива ищи аналог в кодовой базе; дубли без причины не вводятся. - Новый UI создаётся по **канону репозитория** (например CSS Modules или другой зафиксированный способ). - Токены темы хранятся в согласованном месте проекта (если принято). - Устаревший подход стилизации допускается только в наследуемых зонах; новые экраны на нем не строятся без решения команды. ## Модальные окна и подтверждения действий - Любые модальные окна и запросы подтверждения в **renderer** реализуются **только** через **внутренние** компоненты приложения и паттерны **этого** репозитория (не нативные блокирующие диалоги ОС в зоне UI продукта). - Использование **`alert` / `confirm` / `prompt`** в новом и изменяемом коде **renderer** запрещено (исключения — только явно зафиксированные в самом репозитории, например отдельный отладочный путь). - **Продукт DNDGamePlayer** (`dnd_player`): после внедрения i18n (план: **ru**, **en**) подписи модалок и UI — через **ключи**; до внедрения — литералы в стиле репо. - Повторяющаяся разметка и логика модалок выносится в переиспользуемые обёртки/конфиги, а не копируется между фичами. ## Переиспользование кода и дублирование - Новый код проектируется с максимальным переиспользованием: общие компоненты, хуки, утилиты, схемы валидации и типы — единственный источник правды для повторяющегося поведения. - Необоснованное дублирование блоков UI и бизнес-логики в новом коде не допускается: при появлении второго такого же фрагмента выносится общий модуль; при правках смежных дублей по возможности консолидируют реализацию. - Наследуемый дублирующийся код при точечных задачах не обязан переписываться целиком, но расширять дубли вместо выноса общего решения не следует без явной причины (объём/риск миграции фиксируется в задаче или ревью). ## TypeScript и качество - В репозиториях на TypeScript обязателен **`strict`**; новые `any` и `@ts-ignore` не добавляются. - Ослабления возможны только точечно, с комментарием причины и ссылкой на задачу. - Границы модулей (роутинг, внешние библиотеки) типизируются осмысленно. - Практика «везде any» как норма запрещена. ## Локализация (только **`dnd_player`**) и комментарии - **Продукт DNDGamePlayer** (`dnd_player`): планируется отдельная задача на **мультиязычность** — языки **русский (ru)** и **английский (en)**. После внедрения i18n пользовательские строки интерфейса выносятся в **ключи**; префиксы и соглашения по ключам — единые для приложения; новые строки без ключей не добавляются. До внедрения стека i18n действуют литералы в текущем стиле репозитория. - **Вне `dnd_player`:** отдельных требований к i18n нет; строки — в принятом для репозитория виде. - Над нетривиальными функциями, эффектами и публичными сущностями добавляется краткий смысловой комментарий там, где это принято в репозитории. - Стиль комментариев и кодировка файлов соответствуют стандарту репозитория (UTF-8, читаемый язык команды). ## Инженерная дисциплина - Изменения должны быть минимальными и сфокусированными (`minimal diff`). - Предсказуемость решения приоритетнее «хитрости». - Изменения контрактов модульной федерации и shared-зависимостей проходят с повышенным вниманием на ревью. - Линтер, форматтер, pre-commit и политика компилятора (включая React Compiler, если включен) соблюдаются как в репозитории; если скрипта ещё нет — не ослаблять дисциплину «отмазкой репозитория», а фиксировать проверки в задаче (**одинаковая жёсткость** ожиданий по всем проектам воркспейса). - Запрещено ослаблять правила только ради быстрого прохождения проверок.