- добавлена сборка self-contained skill для Claude Code и opencode - добавлен install-ready архив skill в public/slm-design/skill - обновлена карточка SLM Design с меню действий открыть/скачать - добавлен static fallback главной страницы из общего конфига - подключены Mantine Menu и Phosphor Icons для действий карточки
9.2 KiB
9.2 KiB
SLM Design Skill
SLM Design — новая архитектура. Не заменяй её правилами Feature-Sliced Design, Atomic Design, Clean Architecture или другими привычными схемами. Если в проекте нет локальной документации SLM, считай этот файл единственным источником правды.
Определение Контекста
Перед применением правил убедись, что проект использует SLM Design.
- Проверь характерные слои SLM. Сильные сигналы: одновременное наличие
src/screens/иsrc/widgets/(комбинация специфична именно для SLM — в FSD этоpages/, в Atomic и Clean таких слоёв нет); файлы*.factory.tsв business-модулях сindex.ts, экспортирующим только фабрику и type-only. Дополнительные сигналы:src/ui/,src/shared/,src/layouts/как слои. В монорепо проверяй то же внутриapps/{app}/src/. ВАЖНО: отсутствиеsrc/business/НЕ означает, что проект не на SLM. В маленьких или ранних проектах бизнес-доменов может ещё не быть. - Проверь, что business-модули (если они есть) имеют
*.factory.tsв корне иindex.tsэкспортирует только фабрику и type-only экспорты. - Если видишь признаки другой архитектуры —
features/,entities/,pages/(FSD),atoms/,molecules/(Atomic),domain/,useCases/(Clean) — это НЕ SLM. Не применяй правила этого skill. - Если структура неоднозначна или проект новый — спроси пользователя, какая архитектура используется, прежде чем применять правила.
- Если пользователь работает в legacy-коде без SLM и НЕ просит миграцию — не предлагай рефакторинг по SLM. Соблюдай существующие паттерны кода.
Порядок Работы
- Найди границу приложения:
src/илиapps/{app}/src. - Определи ответственность изменения: запуск приложения, layout, screen, widget, business-domain, infra-service, UI-kit или shared resource.
- Размещай код на самом низком подходящем уровне и поднимай выше только при реальной потребности переиспользования.
- Проверяй, является сущность модулем или компонентом. Если сущность получает данные, владеет сценарием, композирует зависимости или имеет внутреннюю архитектуру — это модуль, а не компонент в
ui/. - Все внешние импорты между модулями делай только через публичный API (
index.ts). Deep imports запрещены. - Для
businessruntime-зависимостей между доменами используй фабрики. Не импортируй runtime-код одного business-домена напрямую в другой. - Перед завершением проверь слой, модульную границу, сегменты, публичный API, направление импортов и monorepo-ограничения.
Жёсткие Правила
- Направление зависимостей внутри приложения:
app → [ layouts | screens ] → widgets → business → infra → ui → shared. layoutsиscreensпараллельны и не импортируют друг друга.- Модули одного слоя в группе «Композиция» изолированы друг от друга.
- Runtime-импорты между
business-доменами запрещены. Cross-domain runtime-зависимости передаются только через аргументы фабрики. import typeв группе «Ядро» разрешён в обоих направлениях, потому что не создаёт runtime-зависимость.- Каждый внешний импорт модуля идёт через
index.tsмодуля или публичный API пакета. business/{name}/index.tsэкспортирует только фабрику и type-only экспорты.- Компонент в
ui/родительского модуля не импортирует проектный код за пределами родительского модуля, не получает данные, не вызывает сценарные хуки и не содержит бизнес-логику. parts/содержит только вложенные модули, не произвольные.tsx, стили или хуки.shared/не знает о продукте, бизнес-доменах, UI-kit сущностях и runtime-состоянии.- В monorepo SLM применяется внутри каждого
apps/{app}/src. - В
packages/*можно выносить только общиеui,infraиshared.business,app,layouts,screens,widgetsне выносятся в пакеты.
Выбор Места Для Кода
- Код нужен одной странице или layout: оставь его внутри
screens/{name}/parts/илиlayouts/{name}/parts/. - Абстрактный UI без бизнес-логики и сценариев:
ui/{name}/. - Составной блок интерфейса без принадлежности конкретному домену, используемый в нескольких screens/layouts:
widgets/{name}/. - Код принадлежит бизнес-домену:
business/{domain}/, даже если переиспользуется. - Технический сервис приложения:
infra/{service}/. - Чистая утилита или фундаментальный ресурс без знания о продукте:
shared/. - В monorepo общий UI/infra/shared код, потенциально нужный двум и более frontend-приложениям:
packages/ui/*,packages/infra/*,packages/shared.
Шаблон Business-Модуля
business/{name}/
├── {name}.factory.ts
├── hooks/
├── services/
├── mappers/
├── types/
│ ├── {name}-api.type.ts
│ ├── {name}-deps.type.ts
│ └── {name}-factory.type.ts
├── ui/
└── index.ts
Фабрика лежит в корне business-модуля и возвращает публичный runtime API. Если модулю нужны другие домены, принимай зависимости аргументом фабрики доменными именами.
export { customerFactory } from './customer.factory'
export type { Customer } from './types/customer.type'
export type { CustomerApi } from './types/customer-api.type'
export type { CustomerDeps } from './types/customer-deps.type'
export type { CustomerFactory } from './types/customer-factory.type'
Чеклист Ревью
Проверяй архитектуру в таком порядке:
- Правильно ли выбран слой по ответственности?
- Не вынесен ли код выше, чем нужно для текущего использования?
- Не лежит ли модульная сущность в
ui/как компонент? - Не содержит ли компонент в
ui/данные, сценарии, внешние импорты или вложенную архитектуру? - Есть ли у каждого модуля публичный API и нет ли deep imports?
- Соблюдено ли направление зависимостей?
- Нет ли runtime-импортов между business-доменами?
- Экспортирует ли
business/index.tsтолько фабрику и типы? - Не попали ли продуктовые типы, конфиги или стили в
shared/? - В monorepo не вынесены ли
business,screens,layoutsилиwidgetsвpackages/*?
При ревью сначала перечисляй нарушения с файлами и причиной. Затем предлагай минимальное исправление.
Каноническая Спецификация
Ниже находится полная спецификация SLM Design из канонов проекта. Не сокращай и не переинтерпретируй эти правила.