diff --git a/.vitepress/config.ts b/.vitepress/config.ts index e2cf104..faa6d40 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -10,7 +10,16 @@ const ruSidebar = [ items: [ { text: 'Технологии и библиотеки', link: '/basics/tech-stack' }, { text: 'Именование', link: '/basics/naming' }, - { text: 'Архитектура', link: '/basics/architecture' }, + { + text: 'Архитектура', + link: '/basics/architecture/', + collapsed: false, + items: [ + { text: 'Слои', link: '/basics/architecture/reference/layers' }, + { text: 'Модули', link: '/basics/architecture/reference/modules' }, + { text: 'Сегменты', link: '/basics/architecture/reference/segments' }, + ], + }, { text: 'Стиль кода', link: '/basics/code-style' }, { text: 'Документирование', link: '/basics/documentation' }, { text: 'Типизация', link: '/basics/typing' }, diff --git a/concat-md.js b/concat-md.js index b1f89e9..ce18594 100644 --- a/concat-md.js +++ b/concat-md.js @@ -10,7 +10,10 @@ const fileOrder = [ // basics "basics/tech-stack.md", "basics/naming.md", - "basics/architecture.md", + "basics/architecture/index.md", + "basics/architecture/reference/layers.md", + "basics/architecture/reference/modules.md", + "basics/architecture/reference/segments.md", "basics/code-style.md", "basics/documentation.md", "basics/typing.md", diff --git a/docs/ru/applied/components.md b/docs/ru/applied/components.md index 5ea67fd..5782d43 100644 --- a/docs/ru/applied/components.md +++ b/docs/ru/applied/components.md @@ -6,7 +6,7 @@ title: Компоненты Правила написания React-компонентов: файловая структура модуля, типизация пропсов, документирование и реализация. Раздел охватывает компоненты всех слоёв — от `shared/ui` до `screens`. -Архитектурные слои и их назначение описаны в разделе [Архитектура](/basics/architecture). +Архитектурные слои и их назначение описаны в разделе [Архитектура](/basics/architecture/). ## Правила организации diff --git a/docs/ru/applied/project-structure.md b/docs/ru/applied/project-structure.md index 64463b8..423d7b8 100644 --- a/docs/ru/applied/project-structure.md +++ b/docs/ru/applied/project-structure.md @@ -50,7 +50,7 @@ src/ └── shared/ # Общие ресурсы (утилиты, типы, стили) ``` -Принципы организации слоёв описаны в разделе [Архитектура](../basics/architecture). +Принципы организации слоёв описаны в разделе [Архитектура](../basics/architecture/). ### Папка `app/` diff --git a/docs/ru/basics/architecture.md b/docs/ru/basics/architecture.md deleted file mode 100644 index 40b4ca9..0000000 --- a/docs/ru/basics/architecture.md +++ /dev/null @@ -1,659 +0,0 @@ ---- -title: Архитектура -description: "Раздел описывает архитектуру проекта: из каких слоёв состоит приложение, как организован код внутри слоёв и какие правила управляют зависимостями." ---- - -# SLM Design -Scoped Layered Module Design — модульная архитектура фронтенд-приложений. Код организован по слоям ответственности, а модуль содержит всё, что ему нужно: компоненты, хуки, сторы, типы, стили. - -## Преимущества - -### Вертикальная организация домена - -Бизнес-домен не разбивается по техническим слоям — сценарии, сущности, типы и UI живут в одном модуле. Это сокращает время навигации и упрощает сопровождение: все изменения домена локализованы. - -### Разделение ответственности без перегрузки слоёв - -Сервисы приложения (`infrastructure/`), UI-кит (`ui/`) и общие ресурсы (`shared/`) — три разных слоя с разной природой. Ни один слой не превращается в свалку разнородного кода. - -### Горизонтальная инкапсуляция - -Вложенные модули (`parts/`) и направление зависимостей позволяют нескольким разработчикам работать над одной областью приложения параллельно, не затрагивая код друг друга. - -### Колокация по умолчанию - -Код начинает жизнь рядом с местом использования и поднимается в общие слои только при реальной потребности. Глобальные слои не засоряются преждевременными абстракциями. - -### Явное разделение каркаса и контента - -Каркас группы маршрутов (`layouts/`) и контент конкретной страницы (`screens/`) — независимые слои с собственной ответственностью. - -### Масштабирование через группировку - -При росте проекта слои не теряют структуру — модули группируются по естественным признакам: бизнес-домены по субдоменам, страницы по разделам, UI-компоненты по уровню абстракции (примитивы и композиции). - -### Dependency Injection без фреймворков - -Cross-domain зависимости в бизнес-слое реализуются через фабрики — модуль декларирует что ему нужно, а точка использования предоставляет зависимости. Домены изолированы без DI-контейнеров, провайдеров и шин событий. - -## Происхождение - -SLM Design вырос на основе: - -- **Feature-Sliced Design** — слоистая структура, публичный API модуля, направление зависимостей -- **Vertical Slice Architecture** — модуль как вертикальный срез, содержащий всё необходимое -- **Screaming Architecture** — структура проекта «кричит» о назначении: открыл `business/auth` — видишь авторизацию -- **Colocation Principle** — код живёт рядом с местом использования - -## Пример структуры проекта - -```text -src/ -├── app/ -│ -├── layouts/ -│ ├── main/ -│ └── dashboard/ -│ -├── screens/ -│ ├── home/ -│ ├── products/ -│ ├── product-detail/ -│ └── about/ -│ -├── widgets/ -│ ├── page-heading/ -│ ├── hero-section/ -│ └── promo-banner/ -│ -├── business/ -│ ├── auth/ -│ ├── catalog/ -│ ├── orders/ -│ └── chat/ -│ -├── infrastructure/ -│ ├── theme/ -│ ├── i18n/ -│ ├── backend-api/ -│ └── logger/ -│ -├── ui/ -│ ├── button/ -│ ├── input/ -│ ├── modal/ -│ ├── toast/ -│ └── dropdown/ -│ -└── shared/ - ├── lib/ - ├── types/ - └── styles/ -``` - -## Принципы - -- **Домен — единое целое.** Всё, что относится к домену, живёт в одном модуле. -- **Колокация.** Код рождается рядом с местом использования и поднимается только при необходимости. -- **Зависимости однонаправлены.** Импорты только сверху вниз, только через публичный API. -- **Архитектура — каркас, не клетка.** Правила фиксируют направление зависимостей и структуру модуля, остальное определяет команда. - -## Слои - -Раздел описывает слои SLM: что такое слой, какие бывают, как между ними направлены зависимости и какие правила действуют на каждом. - -### Определение - -**Слой — уровень организации кода внутри `src/`. Каждый слой отвечает за свою область (каркас страницы, бизнес-логика, UI-кит) и задаёт правила для кода внутри: направление импортов, именование, допустимые связи между модулями.** - -### Группы слоёв - -Слои делятся на три группы: - -| Группа | Слои | Описание | -|--------|------|----------| -| Композиция | `app`, `layouts`, `screens`, `widgets` | Собирают интерфейс из готовых блоков: маршруты, каркасы, страницы | -| Ядро | `business`, `infrastructure`, `ui` | Реализация продукта: бизнес-домены, техсервисы, UI-кит | -| Фундамент | `shared` | Общие ресурсы: утилиты, хелперы, стили, конфиги | - -### Направление зависимостей - -Любой импорт между модулями — только через публичный API. - -``` -app → [ layouts | screens ] → widgets → business → infrastructure → ui → shared -``` - -- `layouts` и `screens` — параллельные слои, не импортируют друг друга -- Модули одного слоя в группе «Композиция» изолированы друг от друга -- Модули одного слоя `infrastructure` и `ui` могут импортировать друг друга через публичный API -- Модули `business` — cross-domain зависимости по коду через фабрику, `import type` напрямую -- Импорт типов (`import type`) в «Ядре» разрешён в обоих направлениях - - -### Слой App - -Точка входа приложения. Отвечает за запуск, роутинг и композицию маршрутов из layout и screen. - -В отличие от остальных слоёв, `app/` не содержит модулей SLM. Здесь живут только инфраструктурные файлы, которые не могут быть никаким другим слоем: файлы фреймворка роутинга, точка запуска и код инициализации. - -#### Требования - -- Не содержит модулей SLM — только файлы фреймворка, роутинг, инициализация -- Содержит: файлы маршрутов, bootstrap, обработку ошибок верхнего уровня (404, error boundary), подключение глобальных стилей и ассетов -- Провайдеры и гарды — только подключает готовые из нижних слоёв, не реализует -- Не содержит бизнес-логику, UI-компоненты, хуки, сторы, сервисы -- Никем не импортируется - -### Слой Layouts - -Каркас страницы: общие элементы, одинаковые для группы маршрутов (header, footer, sidebar). - -```text -src/layouts/ -├── main/ -├── dashboard/ -└── auth/ -``` - -#### Требования - -- Содержит только модули -- Не содержит бизнес-логику -- Контекстно-зависимые блоки принимает через пропсы от `app`, не импортирует напрямую - -### Слой Screens - -Контент конкретной страницы: собирает её из модулей нижних слоёв. - -```text -src/screens/ -├── home/ -├── products/ -├── product-detail/ -├── about/ -└── contacts/ -``` - -Когда количество страниц затрудняет навигацию — вводится группировка по разделам. Группа — папка для организации, не модуль (без `index.ts`). - -```text -src/screens/ -├── shop/ -│ ├── home/ -│ ├── products/ -│ ├── product-detail/ -│ └── cart/ -├── account/ -│ ├── profile/ -│ ├── settings/ -│ └── order-history/ -└── info/ - ├── about/ - ├── contacts/ - └── faq/ -``` - -#### Требования - -- Содержит только модули -- Не содержит бизнес-логику -- Локальные одноразовые секции живут внутри screen-модуля, не выносятся в `widgets`/`business` - -### Слой Widgets - -Составной блок интерфейса, который компонует модули ядра, но не принадлежит конкретному бизнес-домену. Widget появляется когда блок используется в нескольких screens или layouts. - -Если блок принадлежит домену — он живёт в `business/{area}/`, даже если переиспользуется. Если блок нужен только в одном месте — это `screens/{name}/parts/` или `layouts/{name}/parts/`, а не widget. - -```text -src/widgets/ -├── page-heading/ -├── hero-section/ -├── onboarding-checklist/ -├── promo-banner/ -└── error-boundary/ -``` - -#### Требования - -- Не принадлежит конкретному бизнес-домену. Если блок доменный — он живёт в `business/` -- Используется в нескольких screens или layouts - -### Слой Business - -Бизнес-домены приложения: auth, catalog, orders, checkout, chat. Каждый домен — отдельный модуль со своими типами, логикой, UI и сервисами. - -Слой входит в группу «Ядро». Импортирует `infrastructure/`, `ui/`, `shared/`. Cross-domain зависимости по коду реализуются через фабрику. `import type` между доменами разрешён напрямую. - -Business объединяет то, что в FSD разделено на `features` и `entities`: пользовательские сценарии и бизнес-сущности живут вместе, внутри одного домена. Внутри домена сегменты разделяют ответственность: `types/` — доменная модель, `hooks/` и `services/` — сценарии и логика, `mappers/` — трансформация данных, `parts/` — составные блоки. - -```text -src/business/ -├── auth/ -├── catalog/ -├── orders/ -├── checkout/ -└── chat/ -``` - -Когда количество доменов затрудняет навигацию — вводится группировка по субдоменам. Группа — папка для организации, не модуль (без `index.ts`). - -```text -src/business/ -├── commerce/ -│ ├── catalog/ -│ ├── cart/ -│ ├── orders/ -│ └── checkout/ -└── communication/ - ├── chat/ - └── notifications/ -``` - -#### Требования - -- Один модуль = один бизнес-домен -- Циклические зависимости между доменами запрещены -- Импорт кода между доменами — через фабрику. `import type` — напрямую -- Доменные типы (`User`, `Product`) живут здесь, не в `shared/` - -### Слой Infrastructure - -Техсервисы приложения: theme, i18n, API-адаптеры, logger, realtime. Каждый сервис — отдельный модуль. - -Слой входит в группу «Ядро». Импортирует `infrastructure/`, `ui/`, `shared/`. - -Отличие от `shared/`: infrastructure — инфраструктура приложения (сервисы, темы, адаптеры к API), `shared/` — общие ресурсы (утилиты, хелперы, стили, конфиги). - -```text -src/infrastructure/ -├── theme/ -├── i18n/ -├── backend-api/ -├── maps-api/ -├── logger/ -├── feature-flags/ -└── realtime/ -``` - -#### Требования - -- Один модуль = один техсервис -- Импортирует `infrastructure/`, `ui/`, `shared/` - -### Слой UI - -UI-кит без бизнес-логики: button, carousel, toast, modal. - -Слой входит в группу «Ядро». Импортирует `ui/` и `shared/`. - -Компоненты строятся друг на друге: `button` использует `icon`, `carousel` использует `button`. - -```text -src/ui/ -├── button/ -├── input/ -├── icon/ -├── carousel/ -├── modal/ -├── toast/ -├── dropdown/ -├── tabs/ -└── tooltip/ -``` - -Когда количество компонентов затрудняет навигацию — вводится группировка на примитивы и композиции. Примитивы (`button`, `icon`, `input`) не импортируют композиции. Композиции (`carousel`, `modal`, `dropdown`) строятся на примитивах. - -```text -src/ui/ -├── primitives/ -│ ├── button/ -│ ├── input/ -│ ├── icon/ -│ └── badge/ -└── composites/ - ├── carousel/ - ├── modal/ - ├── dropdown/ - ├── tabs/ - └── tooltip/ -``` - -#### Требования - -- Не содержит бизнес-логику -- Импортирует только `ui/` и `shared/` - -### Слой Shared - -Общие ресурсы: утилиты, хелперы, стили, конфиги. Не знает о бизнес-домене. - -Слой входит в группу «Фундамент» — ни о ком не знает, никого не импортирует. - -Отличие от `infrastructure/`: infrastructure — инфраструктура приложения (сервисы, темы, адаптеры к API), `shared/` — общие ресурсы (утилиты, хелперы, стили, конфиги). - -Отличие от `ui/`: UI-компоненты (button, carousel, modal) живут в слое `ui/`, а не здесь. - -```text -src/shared/ -├── lib/ -├── types/ -├── styles/ -└── sprites/ -``` - -#### Требования - -- Не имеет runtime-состояния - -## Модули - -Раздел описывает модули SLM: что такое модуль, из чего он состоит и как взаимодействует с остальным кодом. - -### Определение - -**Модуль — универсальный строительный блок архитектуры. Живёт на слое и содержит всё необходимое для своей работы: компоненты, хуки, сторы, сервисы, типы, стили. Набор содержимого не фиксирован — включаются только нужные части.** - -### Модуль vs компонент - -**Компонент** — один `.tsx` файл. Не имеет своих сегментов, использует сегменты родительского модуля. Живёт в корне или `ui/` сегменте модуля. - -**Модуль** — папка, которая может содержать корневой компонент, сегменты (`hooks/`, `types/`, `styles/`, `ui/`, `parts/` и т.д.) и публичный API (`index.ts`). - -```text -auth/ -├── ui/ -│ ├── auth-guard.tsx -│ └── logout-button.tsx -├── parts/ -│ ├── login-form/ -│ ├── registration-form/ -│ └── restore-form/ -├── hooks/ -├── stores/ -├── types/ -├── auth.tsx # корневой компонент (опционален) -└── index.ts -``` - -### Структура - -Модуль состоит из сегментов. Ни один сегмент не обязателен — модуль может состоять даже из одного `index.ts` с реэкспортом типов. - -```text -{module-name}/ -├── {module-name}.tsx # корневой компонент (опционален) -├── ui/ # компоненты модуля (только .tsx) -├── parts/ # вложенные модули (со своими сегментами) -├── hooks/ # хуки -├── stores/ # сторы состояния -├── services/ # внешние источники данных -├── mappers/ # трансформация данных между форматами -├── types/ # типы -├── styles/ # стили -├── lib/ # утилиты модуля -├── config/ # константы -└── index.ts # публичный API -``` - -Подробное описание каждого сегмента — в разделе [Сегменты](/reference/segments). - -### Публичный API - -Модуль экспортирует наружу только то, что нужно другим. Всё остальное — внутреннее. - -```ts -// business/auth/index.ts -export type { User, Session } from './types/user.types' -export { useAuth } from './hooks/use-auth.hook' -export { AuthGuard } from './ui/auth-guard' -``` - -Импорт в обход `index.ts` запрещён: - -```ts -// Плохо -import { validateToken } from '@/business/auth/lib/tokens' - -// Хорошо -import { useAuth } from '@/business/auth' -``` - -### Фабрика - -Если модуль зависит от кода другого бизнес-домена — он экспортирует фабрику. Фабрика декларирует необходимые зависимости и возвращает API модуля. Точка использования (screen, widget, layout) предоставляет зависимости при вызове. - -Модуль без cross-domain зависимостей экспортирует API напрямую. Типы всегда экспортируются напрямую — `import type` не является runtime-зависимостью. - -#### Модуль без зависимостей — прямой экспорт: - -```ts -// business/auth/index.ts -export { useAuth } from './hooks/use-auth' -export { useCurrentUser } from './hooks/use-current-user' -export type { User, Session } from './types' -``` - -#### Модуль с зависимостями — фабрика: - -```ts -// business/chat/types/deps.ts -import type { User } from '@/business/auth' - -export interface ChatDeps { - useCurrentUser: () => User | null -} -``` - -```ts -// business/chat/index.ts -import type { ChatDeps } from './types/deps' - -export function chatFactory(deps: ChatDeps) { - return { - useMessages: (roomId: string) => { - const user = deps.useCurrentUser() - // ... - }, - useSendMessage: (roomId: string) => { - const user = deps.useCurrentUser() - return (text: string) => { /* ... */ } - }, - useChatRooms: () => { - const user = deps.useCurrentUser() - // ... - }, - ChatBadge: ({ count }: { count: number }) => { /* ... */ }, - } -} - -export type { Message, ChatRoom } from './types' -export type { ChatDeps } from './types/deps' -``` - -#### Использование на странице: - -```tsx -// screens/support/support.tsx -import { useCurrentUser } from '@/business/auth' -import { chatFactory } from '@/business/chat' - -const chat = chatFactory({ useCurrentUser }) - -export function SupportScreen() { - const { useMessages, useSendMessage, ChatBadge } = chat - const messages = useMessages('support') - const sendMessage = useSendMessage('support') - - return ( -
- - {messages.map(m => )} - -
- ) -} -``` - -### Жизненный цикл - -Модуль рождается на самом низком уровне использования и поднимается выше только при реальной потребности. - -- Нужен на одной странице → `screens/{name}/parts/` -- Появился в 2+ местах → поднимается по природе: - - абстрактный UI → `ui/` - - блок с данными/логикой → `widgets/` - - представление бизнес-домена → `business/{area}/parts/` - -Подъём — обычный рефакторинг в рамках задачи, а не отдельная активность. - -## Сегменты - -Раздел описывает сегменты SLM: что такое сегмент, какие бывают и что в каждом из них лежит. - -### Определение - -**Сегмент — папка внутри модуля, которая группирует файлы по назначению. Набор сегментов не фиксирован — модуль включает только те, которые ему нужны. Команда сама определяет какие сегменты используются в проекте — архитектура даёт рекомендацию.** - -### Обзор - -| Сегмент | Содержимое | -|---------|------------| -| `ui/` | Компоненты модуля — только `.tsx` файлы | -| `parts/` | Вложенные модули со своими сегментами | -| `hooks/` | React-хуки | -| `stores/` | Сторы состояния | -| `services/` | Работа с внешними источниками данных | -| `mappers/` | Трансформация данных между форматами | -| `types/` | TypeScript-типы и интерфейсы | -| `styles/` | Стили | -| `lib/` | Утилиты и хелперы модуля | -| `config/` | Константы и конфигурация | - -### Сегмент ui/ - -Компоненты, принадлежащие модулю. Содержит только `.tsx` файлы — без своих сегментов, стилей, типов, хуков. Использует сегменты родительского модуля. - -```text -auth/ -├── ui/ -│ ├── auth-provider.tsx -│ ├── auth-guard.tsx -│ └── logout-button.tsx -├── types/ -├── hooks/ -└── index.ts -``` - -Если компоненту нужны собственные сегменты — это уже не `ui/`, а `parts/`. - -### Сегмент parts/ - -Вложенные модули со своими сегментами. Каждый элемент `parts/` — полноценный модуль: папка с компонентом, хуками, стилями, типами и т.д. - -```text -home/ -├── parts/ -│ ├── hero-section/ -│ │ ├── hero-section.tsx -│ │ ├── styles/ -│ │ └── parts/ -│ │ └── top-banner/ -│ │ └── top-banner.tsx -│ └── features-section/ -│ ├── features-section.tsx -│ └── hooks/ -├── home.screen.tsx -└── index.ts -``` - -Отличие от `ui/`: элемент `parts/` — модуль со своими сегментами. Элемент `ui/` — компонент, один `.tsx` файл. - -Вложенность `parts/` инкапсулирует область разработки горизонтально: каждый разработчик работает в своём `parts/`-модуле, не затрагивая чужие. Это снижает конфликты при параллельной разработке. - -Если вложенный модуль обрастает своими `parts/` — это сигнал, что он достаточно самостоятельный для подъёма на уровень выше. - -### Сегмент hooks/ - -React-хуки модуля. Инкапсулируют логику, состояние, подписки, побочные эффекты. - -```text -hooks/ -├── use-auth.hook.ts -├── use-session.hook.ts -└── use-permissions.hook.ts -``` - -### Сегмент stores/ - -Сторы состояния модуля. Конкретная реализация зависит от выбранного стейт-менеджера (Zustand, MobX, Redux и т.д.). - -```text -stores/ -├── auth.store.ts -└── session.store.ts -``` - -### Сегмент services/ - -Работа с внешними источниками данных: API-вызовы, запросы, подписки. - -```text -services/ -├── auth.service.ts -└── token.service.ts -``` - -### Сегмент mappers/ - -Функции трансформации данных из одного формата в другой: DTO в доменный тип, доменный тип в DTO, доменный тип в ViewModel. - -```text -mappers/ -├── map-user.ts -├── map-product.ts -└── map-order-to-dto.ts -``` - -### Сегмент types/ - -TypeScript-типы и интерфейсы модуля. Доменные типы, DTO, пропсы компонентов. - -```text -types/ -├── user.type.ts -└── session.type.ts -``` - -### Сегмент styles/ - -Стили модуля. Формат зависит от выбранного подхода (CSS Modules, SCSS, CSS-in-JS и т.д.). - -```text -styles/ -├── auth.module.css -└── login-form.module.css -``` - -### Сегмент lib/ - -Утилиты и хелперы, специфичные для модуля. Чистые функции без побочных эффектов. - -```text -lib/ -├── validate-email.ts -└── format-phone.ts -``` - -Отличие от `shared/lib/`: здесь лежат утилиты, нужные только этому модулю. Общие утилиты — в `shared/lib/`. - -### Сегмент config/ - -Константы и конфигурация модуля: маршруты, лимиты, дефолтные значения. - -```text -config/ -├── routes.ts -└── constants.ts -``` diff --git a/docs/ru/basics/architecture/index.md b/docs/ru/basics/architecture/index.md new file mode 100644 index 0000000..742d600 --- /dev/null +++ b/docs/ru/basics/architecture/index.md @@ -0,0 +1,99 @@ +--- +title: Архитектура +description: "Раздел описывает архитектуру проекта: из каких слоёв состоит приложение, как организован код внутри слоёв и какие правила управляют зависимостями." +--- + +# SLM Design +Scoped Layered Module Design — модульная архитектура фронтенд-приложений. Код организован по слоям ответственности, а модуль содержит всё, что ему нужно: компоненты, хуки, сторы, типы, стили. + +## Преимущества + +### Вертикальная организация домена + +Бизнес-домен не разбивается по техническим слоям — сценарии, сущности, типы и UI живут в одном модуле. Это сокращает время навигации и упрощает сопровождение: все изменения домена локализованы. + +### Dependency Injection без фреймворков + +Cross-domain зависимости в бизнес-слое реализуются через фабрики — модуль декларирует что ему нужно, а точка использования предоставляет зависимости. Домены изолированы без DI-контейнеров, провайдеров и шин событий. + +### Разделение ответственности без перегрузки слоёв + +Сервисы приложения (`infrastructure/`), UI-кит (`ui/`) и общие ресурсы (`shared/`) — три разных слоя с разной природой. Ни один слой не превращается в свалку разнородного кода. + +### Горизонтальная инкапсуляция + +Вложенные модули (`parts/`) и направление зависимостей позволяют нескольким разработчикам работать над одной областью приложения параллельно, не затрагивая код друг друга. + +### Колокация по умолчанию + +Код начинает жизнь рядом с местом использования и поднимается в общие слои только при реальной потребности. Глобальные слои не засоряются преждевременными абстракциями. + +### Явное разделение каркаса и контента + +Каркас группы маршрутов (`layouts/`) и контент конкретной страницы (`screens/`) — независимые слои с собственной ответственностью. + +### Масштабирование через группировку + +При росте проекта слои не теряют структуру — модули группируются по естественным признакам: бизнес-домены по субдоменам, страницы по разделам, UI-компоненты по уровню абстракции (примитивы и композиции). + +## Происхождение + +SLM Design вырос на основе: + +- **Feature-Sliced Design** — слоистая структура, публичный API модуля, направление зависимостей +- **Vertical Slice Architecture** — модуль как вертикальный срез, содержащий всё необходимое +- **Screaming Architecture** — структура проекта «кричит» о назначении: открыл `business/auth` — видишь авторизацию +- **Colocation Principle** — код живёт рядом с местом использования + +## Пример структуры проекта + +```text +src/ +├── app/ +│ +├── layouts/ +│ ├── main/ +│ └── dashboard/ +│ +├── screens/ +│ ├── home/ +│ ├── products/ +│ ├── product-detail/ +│ └── about/ +│ +├── widgets/ +│ ├── page-heading/ +│ ├── hero-section/ +│ └── promo-banner/ +│ +├── business/ +│ ├── auth/ +│ ├── catalog/ +│ ├── orders/ +│ └── chat/ +│ +├── infrastructure/ +│ ├── theme/ +│ ├── i18n/ +│ ├── backend-api/ +│ └── logger/ +│ +├── ui/ +│ ├── button/ +│ ├── input/ +│ ├── modal/ +│ ├── toast/ +│ └── dropdown/ +│ +└── shared/ + ├── lib/ + ├── types/ + └── styles/ +``` + +## Принципы + +- **Домен — единое целое.** Всё, что относится к домену, живёт в одном модуле. +- **Колокация.** Код рождается рядом с местом использования и поднимается только при необходимости. +- **Зависимости однонаправлены.** Импорты только сверху вниз, только через публичный API. +- **Архитектура — каркас, не клетка.** Правила фиксируют направление зависимостей и структуру модуля, остальное определяет команда. diff --git a/docs/ru/basics/architecture/reference/layers.md b/docs/ru/basics/architecture/reference/layers.md new file mode 100644 index 0000000..c313273 --- /dev/null +++ b/docs/ru/basics/architecture/reference/layers.md @@ -0,0 +1,252 @@ +--- +title: Слои +--- + +# Слои + +Раздел описывает слои SLM: что такое слой, какие бывают, как между ними направлены зависимости и какие правила действуют на каждом. + +## Определение + +**Слой — уровень организации кода внутри `src/`. Каждый слой отвечает за свою область (каркас страницы, бизнес-логика, UI-кит) и задаёт правила для кода внутри: направление импортов, именование, допустимые связи между модулями.** + +## Группы слоёв + +Слои делятся на три группы: + +| Группа | Слои | Описание | +|--------|------|----------| +| Композиция | `app`, `layouts`, `screens`, `widgets` | Собирают интерфейс из готовых блоков: маршруты, каркасы, страницы | +| Ядро | `business`, `infrastructure`, `ui` | Реализация продукта: бизнес-домены, техсервисы, UI-кит | +| Фундамент | `shared` | Общие ресурсы: утилиты, хелперы, стили, конфиги | + +## Направление зависимостей + +Любой импорт между модулями — только через публичный API. + +``` +app → [ layouts | screens ] → widgets → business → infrastructure → ui → shared +``` + +- `layouts` и `screens` — параллельные слои, не импортируют друг друга +- Модули одного слоя в группе «Композиция» изолированы друг от друга +- Модули одного слоя `infrastructure` и `ui` могут импортировать друг друга через публичный API +- Модули `business` — cross-domain зависимости по коду через фабрику, `import type` напрямую +- Импорт типов (`import type`) в «Ядре» разрешён в обоих направлениях + + +## Слой App + +Точка входа приложения. Отвечает за запуск, роутинг и композицию маршрутов из layout и screen. + +В отличие от остальных слоёв, `app/` не содержит модулей SLM. Здесь живут только инфраструктурные файлы, которые не могут быть никаким другим слоем: файлы фреймворка роутинга, точка запуска и код инициализации. + +### Требования + +- Не содержит модулей SLM — только файлы фреймворка, роутинг, инициализация +- Содержит: файлы маршрутов, bootstrap, обработку ошибок верхнего уровня (404, error boundary), подключение глобальных стилей и ассетов +- Провайдеры и гарды — только подключает готовые из нижних слоёв, не реализует +- Не содержит бизнес-логику, UI-компоненты, хуки, сторы, сервисы +- Никем не импортируется + +## Слой Layouts + +Каркас страницы: общие элементы, одинаковые для группы маршрутов (header, footer, sidebar). + +```text +src/layouts/ +├── main/ +├── dashboard/ +└── auth/ +``` + +### Требования + +- Содержит только модули +- Не содержит бизнес-логику +- Контекстно-зависимые блоки принимает через пропсы от `app`, не импортирует напрямую + +## Слой Screens + +Контент конкретной страницы: собирает её из модулей нижних слоёв. + +```text +src/screens/ +├── home/ +├── products/ +├── product-detail/ +├── about/ +└── contacts/ +``` + +Когда количество страниц затрудняет навигацию — вводится группировка по разделам. Группа — папка для организации, не модуль (без `index.ts`). + +```text +src/screens/ +├── shop/ +│ ├── home/ +│ ├── products/ +│ ├── product-detail/ +│ └── cart/ +├── account/ +│ ├── profile/ +│ ├── settings/ +│ └── order-history/ +└── info/ + ├── about/ + ├── contacts/ + └── faq/ +``` + +### Требования + +- Содержит только модули +- Не содержит бизнес-логику +- Локальные одноразовые секции живут внутри screen-модуля, не выносятся в `widgets`/`business` + +## Слой Widgets + +Составной блок интерфейса, который компонует модули ядра, но не принадлежит конкретному бизнес-домену. Widget появляется когда блок используется в нескольких screens или layouts. + +Если блок принадлежит домену — он живёт в `business/{area}/`, даже если переиспользуется. Если блок нужен только в одном месте — это `screens/{name}/parts/` или `layouts/{name}/parts/`, а не widget. + +```text +src/widgets/ +├── page-heading/ +├── hero-section/ +├── onboarding-checklist/ +├── promo-banner/ +└── error-boundary/ +``` + +### Требования + +- Не принадлежит конкретному бизнес-домену. Если блок доменный — он живёт в `business/` +- Используется в нескольких screens или layouts + +## Слой Business + +Бизнес-домены приложения: auth, catalog, orders, checkout, chat. Каждый домен — отдельный модуль со своими типами, логикой, UI и сервисами. + +Слой входит в группу «Ядро». Импортирует `infrastructure/`, `ui/`, `shared/`. Cross-domain зависимости по коду реализуются через фабрику. `import type` между доменами разрешён напрямую. + +Business объединяет то, что в FSD разделено на `features` и `entities`: пользовательские сценарии и бизнес-сущности живут вместе, внутри одного домена. Внутри домена сегменты разделяют ответственность: `types/` — доменная модель, `hooks/` и `services/` — сценарии и логика, `mappers/` — трансформация данных, `parts/` — составные блоки. + +```text +src/business/ +├── auth/ +├── catalog/ +├── orders/ +├── checkout/ +└── chat/ +``` + +Когда количество доменов затрудняет навигацию — вводится группировка по субдоменам. Группа — папка для организации, не модуль (без `index.ts`). + +```text +src/business/ +├── commerce/ +│ ├── catalog/ +│ ├── cart/ +│ ├── orders/ +│ └── checkout/ +└── communication/ + ├── chat/ + └── notifications/ +``` + +### Требования + +- Один модуль = один бизнес-домен +- Циклические зависимости между доменами запрещены +- Импорт кода между доменами — через фабрику. `import type` — напрямую +- Доменные типы (`User`, `Product`) живут здесь, не в `shared/` + +## Слой Infrastructure + +Техсервисы приложения: theme, i18n, API-адаптеры, logger, realtime. Каждый сервис — отдельный модуль. + +Слой входит в группу «Ядро». Импортирует `infrastructure/`, `ui/`, `shared/`. + +Отличие от `shared/`: infrastructure — инфраструктура приложения (сервисы, темы, адаптеры к API), `shared/` — общие ресурсы (утилиты, хелперы, стили, конфиги). + +```text +src/infrastructure/ +├── theme/ +├── i18n/ +├── backend-api/ +├── maps-api/ +├── logger/ +├── feature-flags/ +└── realtime/ +``` + +### Требования + +- Один модуль = один техсервис +- Импортирует `infrastructure/`, `ui/`, `shared/` + +## Слой UI + +UI-кит без бизнес-логики: button, carousel, toast, modal. + +Слой входит в группу «Ядро». Импортирует `ui/` и `shared/`. + +Компоненты строятся друг на друге: `button` использует `icon`, `carousel` использует `button`. + +```text +src/ui/ +├── button/ +├── input/ +├── icon/ +├── carousel/ +├── modal/ +├── toast/ +├── dropdown/ +├── tabs/ +└── tooltip/ +``` + +Когда количество компонентов затрудняет навигацию — вводится группировка на примитивы и композиции. Примитивы (`button`, `icon`, `input`) не импортируют композиции. Композиции (`carousel`, `modal`, `dropdown`) строятся на примитивах. + +```text +src/ui/ +├── primitives/ +│ ├── button/ +│ ├── input/ +│ ├── icon/ +│ └── badge/ +└── composites/ + ├── carousel/ + ├── modal/ + ├── dropdown/ + ├── tabs/ + └── tooltip/ +``` + +### Требования + +- Не содержит бизнес-логику +- Импортирует только `ui/` и `shared/` + +## Слой Shared + +Общие ресурсы: утилиты, хелперы, стили, конфиги. Не знает о бизнес-домене. + +Слой входит в группу «Фундамент» — ни о ком не знает, никого не импортирует. + +Отличие от `infrastructure/`: infrastructure — инфраструктура приложения (сервисы, темы, адаптеры к API), `shared/` — общие ресурсы (утилиты, хелперы, стили, конфиги). + +Отличие от `ui/`: UI-компоненты (button, carousel, modal) живут в слое `ui/`, а не здесь. + +```text +src/shared/ +├── lib/ +├── types/ +├── styles/ +└── sprites/ +``` + +### Требования + +- Не имеет runtime-состояния diff --git a/docs/ru/basics/architecture/reference/modules.md b/docs/ru/basics/architecture/reference/modules.md new file mode 100644 index 0000000..5a245ee --- /dev/null +++ b/docs/ru/basics/architecture/reference/modules.md @@ -0,0 +1,164 @@ +--- +title: Модули +--- + +# Модули + +Раздел описывает модули SLM: что такое модуль, из чего он состоит и как взаимодействует с остальным кодом. + +## Определение + +**Модуль — универсальный строительный блок архитектуры. Живёт на слое и содержит всё необходимое для своей работы: компоненты, хуки, сторы, сервисы, типы, стили. Набор содержимого не фиксирован — включаются только нужные части.** + +## Модуль vs компонент + +**Компонент** — один `.tsx` файл. Не имеет своих сегментов, использует сегменты родительского модуля. Живёт в корне или `ui/` сегменте модуля. + +**Модуль** — папка, которая может содержать корневой компонент, сегменты (`hooks/`, `types/`, `styles/`, `ui/`, `parts/` и т.д.) и публичный API (`index.ts`). + +```text +auth/ +├── ui/ +│ ├── auth-guard.tsx +│ └── logout-button.tsx +├── parts/ +│ ├── login-form/ +│ ├── registration-form/ +│ └── restore-form/ +├── hooks/ +├── stores/ +├── types/ +├── auth.tsx # корневой компонент (опционален) +└── index.ts +``` + +## Структура + +Модуль состоит из сегментов. Ни один сегмент не обязателен — модуль может состоять даже из одного `index.ts` с реэкспортом типов. + +```text +{module-name}/ +├── {module-name}.tsx # корневой компонент (опционален) +├── ui/ # компоненты модуля (только .tsx) +├── parts/ # вложенные модули (со своими сегментами) +├── hooks/ # хуки +├── stores/ # сторы состояния +├── services/ # внешние источники данных +├── mappers/ # трансформация данных между форматами +├── types/ # типы +├── styles/ # стили +├── lib/ # утилиты модуля +├── config/ # константы +└── index.ts # публичный API +``` + +Подробное описание каждого сегмента — в разделе [Сегменты](/basics/architecture/reference/segments). + +## Публичный API + +Модуль экспортирует наружу только то, что нужно другим. Всё остальное — внутреннее. + +```ts +// business/auth/index.ts +export type { User, Session } from './types/user.types' +export { useAuth } from './hooks/use-auth.hook' +export { AuthGuard } from './ui/auth-guard' +``` + +Импорт в обход `index.ts` запрещён: + +```ts +// Плохо +import { validateToken } from '@/business/auth/lib/tokens' + +// Хорошо +import { useAuth } from '@/business/auth' +``` + +## Фабрика + +Если модуль зависит от кода другого бизнес-домена — он экспортирует фабрику. Фабрика декларирует необходимые зависимости и возвращает API модуля. Точка использования (screen, widget, layout) предоставляет зависимости при вызове. + +Модуль без cross-domain зависимостей экспортирует API напрямую. Типы всегда экспортируются напрямую — `import type` не является runtime-зависимостью. + +### Модуль без зависимостей — прямой экспорт: + +```ts +// business/auth/index.ts +export { useAuth } from './hooks/use-auth' +export { useCurrentUser } from './hooks/use-current-user' +export type { User, Session } from './types' +``` + +### Модуль с зависимостями — фабрика: + +```ts +// business/chat/types/deps.ts +import type { User } from '@/business/auth' + +export interface ChatDeps { + useCurrentUser: () => User | null +} +``` + +```ts +// business/chat/index.ts +import type { ChatDeps } from './types/deps' + +export function chatFactory(deps: ChatDeps) { + return { + useMessages: (roomId: string) => { + const user = deps.useCurrentUser() + // ... + }, + useSendMessage: (roomId: string) => { + const user = deps.useCurrentUser() + return (text: string) => { /* ... */ } + }, + useChatRooms: () => { + const user = deps.useCurrentUser() + // ... + }, + ChatBadge: ({ count }: { count: number }) => { /* ... */ }, + } +} + +export type { Message, ChatRoom } from './types' +export type { ChatDeps } from './types/deps' +``` + +### Использование на странице: + +```tsx +// screens/support/support.tsx +import { useCurrentUser } from '@/business/auth' +import { chatFactory } from '@/business/chat' + +const chat = chatFactory({ useCurrentUser }) + +export function SupportScreen() { + const { useMessages, useSendMessage, ChatBadge } = chat + const messages = useMessages('support') + const sendMessage = useSendMessage('support') + + return ( +
+ + {messages.map(m => )} + +
+ ) +} +``` + +## Жизненный цикл + +Модуль рождается на самом низком уровне использования и поднимается выше только при реальной потребности. + +- Нужен на одной странице → `screens/{name}/parts/` +- Появился в 2+ местах → поднимается по природе: + - абстрактный UI → `ui/` + - блок с данными/логикой → `widgets/` + - представление бизнес-домена → `business/{area}/parts/` + +Подъём — обычный рефакторинг в рамках задачи, а не отдельная активность. diff --git a/docs/ru/basics/architecture/reference/segments.md b/docs/ru/basics/architecture/reference/segments.md new file mode 100644 index 0000000..f68240d --- /dev/null +++ b/docs/ru/basics/architecture/reference/segments.md @@ -0,0 +1,153 @@ +--- +title: Сегменты +--- + +# Сегменты + +Раздел описывает сегменты SLM: что такое сегмент, какие бывают и что в каждом из них лежит. + +## Определение + +**Сегмент — папка внутри модуля, которая группирует файлы по назначению. Набор сегментов не фиксирован — модуль включает только те, которые ему нужны. Команда сама определяет какие сегменты используются в проекте — архитектура даёт рекомендацию.** + +## Обзор + +| Сегмент | Содержимое | +|---------|------------| +| `ui/` | Компоненты модуля — только `.tsx` файлы | +| `parts/` | Вложенные модули со своими сегментами | +| `hooks/` | React-хуки | +| `stores/` | Сторы состояния | +| `services/` | Работа с внешними источниками данных | +| `mappers/` | Трансформация данных между форматами | +| `types/` | TypeScript-типы и интерфейсы | +| `styles/` | Стили | +| `lib/` | Утилиты и хелперы модуля | +| `config/` | Константы и конфигурация | + +## Сегмент ui/ + +Компоненты, принадлежащие модулю. Содержит только `.tsx` файлы — без своих сегментов, стилей, типов, хуков. Использует сегменты родительского модуля. + +```text +auth/ +├── ui/ +│ ├── auth-provider.tsx +│ ├── auth-guard.tsx +│ └── logout-button.tsx +├── types/ +├── hooks/ +└── index.ts +``` + +Если компоненту нужны собственные сегменты — это уже не `ui/`, а `parts/`. + +## Сегмент parts/ + +Вложенные модули со своими сегментами. Каждый элемент `parts/` — полноценный модуль: папка с компонентом, хуками, стилями, типами и т.д. + +```text +home/ +├── parts/ +│ ├── hero-section/ +│ │ ├── hero-section.tsx +│ │ ├── styles/ +│ │ └── parts/ +│ │ └── top-banner/ +│ │ └── top-banner.tsx +│ └── features-section/ +│ ├── features-section.tsx +│ └── hooks/ +├── home.screen.tsx +└── index.ts +``` + +Отличие от `ui/`: элемент `parts/` — модуль со своими сегментами. Элемент `ui/` — компонент, один `.tsx` файл. + +Вложенность `parts/` инкапсулирует область разработки горизонтально: каждый разработчик работает в своём `parts/`-модуле, не затрагивая чужие. Это снижает конфликты при параллельной разработке. + +Если вложенный модуль обрастает своими `parts/` — это сигнал, что он достаточно самостоятельный для подъёма на уровень выше. + +## Сегмент hooks/ + +React-хуки модуля. Инкапсулируют логику, состояние, подписки, побочные эффекты. + +```text +hooks/ +├── use-auth.hook.ts +├── use-session.hook.ts +└── use-permissions.hook.ts +``` + +## Сегмент stores/ + +Сторы состояния модуля. Конкретная реализация зависит от выбранного стейт-менеджера (Zustand, MobX, Redux и т.д.). + +```text +stores/ +├── auth.store.ts +└── session.store.ts +``` + +## Сегмент services/ + +Работа с внешними источниками данных: API-вызовы, запросы, подписки. + +```text +services/ +├── auth.service.ts +└── token.service.ts +``` + +## Сегмент mappers/ + +Функции трансформации данных из одного формата в другой: DTO в доменный тип, доменный тип в DTO, доменный тип в ViewModel. + +```text +mappers/ +├── map-user.ts +├── map-product.ts +└── map-order-to-dto.ts +``` + +## Сегмент types/ + +TypeScript-типы и интерфейсы модуля. Доменные типы, DTO, пропсы компонентов. + +```text +types/ +├── user.type.ts +└── session.type.ts +``` + +## Сегмент styles/ + +Стили модуля. Формат зависит от выбранного подхода (CSS Modules, SCSS, CSS-in-JS и т.д.). + +```text +styles/ +├── auth.module.css +└── login-form.module.css +``` + +## Сегмент lib/ + +Утилиты и хелперы, специфичные для модуля. Чистые функции без побочных эффектов. + +```text +lib/ +├── validate-email.ts +└── format-phone.ts +``` + +Отличие от `shared/lib/`: здесь лежат утилиты, нужные только этому модулю. Общие утилиты — в `shared/lib/`. + +## Сегмент config/ + +Константы и конфигурация модуля: маршруты, лимиты, дефолтные значения. + +```text +config/ +├── routes.ts +└── constants.ts +``` diff --git a/docs/ru/basics/tech-stack.md b/docs/ru/basics/tech-stack.md index 40e8d8c..2c20d71 100644 --- a/docs/ru/basics/tech-stack.md +++ b/docs/ru/basics/tech-stack.md @@ -13,7 +13,7 @@ title: Технологии и библиотеки - `Next.js` — для продуктовых сайтов. ### Архитектура -- `SLM Design` — собственная модульная архитектура проекта. Подробнее в разделе [Архитектура](/basics/architecture). +- `SLM Design` — собственная модульная архитектура проекта. Подробнее в разделе [Архитектура](/basics/architecture/). ### UI компоненты - `Mantine UI` — базовые UI-компоненты. diff --git a/generated/en/RULES.md b/generated/en/RULES.md index af892fd..d342838 100644 --- a/generated/en/RULES.md +++ b/generated/en/RULES.md @@ -67,11 +67,6 @@ Base technology stack and libraries used in projects. Naming should be predictable, concise, and reflect the meaning of the entity. - -## Architecture - -Architecture based on FSD (Feature-Sliced Design) and strict module boundaries. - ## Code Style diff --git a/generated/ru/RULES.md b/generated/ru/RULES.md index 201e645..bf10628 100644 --- a/generated/ru/RULES.md +++ b/generated/ru/RULES.md @@ -155,7 +155,7 @@ - `Next.js` — для продуктовых сайтов. #### Архитектура -- `SLM Design` — собственная модульная архитектура проекта. Подробнее в разделе [Архитектура](/basics/architecture). +- `SLM Design` — собственная модульная архитектура проекта. Подробнее в разделе [Архитектура](/basics/architecture/). #### UI компоненты - `Mantine UI` — базовые UI-компоненты. @@ -319,7 +319,7 @@ const usersMap = []; const users = {} as Record; ``` - + ## SLM Design Scoped Layered Module Design — модульная архитектура фронтенд-приложений. Код организован по слоям ответственности, а модуль содержит всё, что ему нужно: компоненты, хуки, сторы, типы, стили. @@ -329,6 +329,10 @@ Scoped Layered Module Design — модульная архитектура фр Бизнес-домен не разбивается по техническим слоям — сценарии, сущности, типы и UI живут в одном модуле. Это сокращает время навигации и упрощает сопровождение: все изменения домена локализованы. +#### Dependency Injection без фреймворков + +Cross-domain зависимости в бизнес-слое реализуются через фабрики — модуль декларирует что ему нужно, а точка использования предоставляет зависимости. Домены изолированы без DI-контейнеров, провайдеров и шин событий. + #### Разделение ответственности без перегрузки слоёв Сервисы приложения (`infrastructure/`), UI-кит (`ui/`) и общие ресурсы (`shared/`) — три разных слоя с разной природой. Ни один слой не превращается в свалку разнородного кода. @@ -349,10 +353,6 @@ Scoped Layered Module Design — модульная архитектура фр При росте проекта слои не теряют структуру — модули группируются по естественным признакам: бизнес-домены по субдоменам, страницы по разделам, UI-компоненты по уровню абстракции (примитивы и композиции). -#### Dependency Injection без фреймворков - -Cross-domain зависимости в бизнес-слое реализуются через фабрики — модуль декларирует что ему нужно, а точка использования предоставляет зависимости. Домены изолированы без DI-контейнеров, провайдеров и шин событий. - ### Происхождение SLM Design вырос на основе: @@ -415,15 +415,16 @@ src/ - **Зависимости однонаправлены.** Импорты только сверху вниз, только через публичный API. - **Архитектура — каркас, не клетка.** Правила фиксируют направление зависимостей и структуру модуля, остальное определяет команда. -### Слои + +## Слои Раздел описывает слои SLM: что такое слой, какие бывают, как между ними направлены зависимости и какие правила действуют на каждом. -#### Определение +### Определение **Слой — уровень организации кода внутри `src/`. Каждый слой отвечает за свою область (каркас страницы, бизнес-логика, UI-кит) и задаёт правила для кода внутри: направление импортов, именование, допустимые связи между модулями.** -#### Группы слоёв +### Группы слоёв Слои делятся на три группы: @@ -433,7 +434,7 @@ src/ | Ядро | `business`, `infrastructure`, `ui` | Реализация продукта: бизнес-домены, техсервисы, UI-кит | | Фундамент | `shared` | Общие ресурсы: утилиты, хелперы, стили, конфиги | -#### Направление зависимостей +### Направление зависимостей Любой импорт между модулями — только через публичный API. @@ -448,13 +449,13 @@ app → [ layouts | screens ] → widgets → business → infrastructure → ui - Импорт типов (`import type`) в «Ядре» разрешён в обоих направлениях -#### Слой App +### Слой App Точка входа приложения. Отвечает за запуск, роутинг и композицию маршрутов из layout и screen. В отличие от остальных слоёв, `app/` не содержит модулей SLM. Здесь живут только инфраструктурные файлы, которые не могут быть никаким другим слоем: файлы фреймворка роутинга, точка запуска и код инициализации. -##### Требования +#### Требования - Не содержит модулей SLM — только файлы фреймворка, роутинг, инициализация - Содержит: файлы маршрутов, bootstrap, обработку ошибок верхнего уровня (404, error boundary), подключение глобальных стилей и ассетов @@ -462,7 +463,7 @@ app → [ layouts | screens ] → widgets → business → infrastructure → ui - Не содержит бизнес-логику, UI-компоненты, хуки, сторы, сервисы - Никем не импортируется -#### Слой Layouts +### Слой Layouts Каркас страницы: общие элементы, одинаковые для группы маршрутов (header, footer, sidebar). @@ -473,13 +474,13 @@ src/layouts/ └── auth/ ``` -##### Требования +#### Требования - Содержит только модули - Не содержит бизнес-логику - Контекстно-зависимые блоки принимает через пропсы от `app`, не импортирует напрямую -#### Слой Screens +### Слой Screens Контент конкретной страницы: собирает её из модулей нижних слоёв. @@ -511,13 +512,13 @@ src/screens/ └── faq/ ``` -##### Требования +#### Требования - Содержит только модули - Не содержит бизнес-логику - Локальные одноразовые секции живут внутри screen-модуля, не выносятся в `widgets`/`business` -#### Слой Widgets +### Слой Widgets Составной блок интерфейса, который компонует модули ядра, но не принадлежит конкретному бизнес-домену. Widget появляется когда блок используется в нескольких screens или layouts. @@ -532,12 +533,12 @@ src/widgets/ └── error-boundary/ ``` -##### Требования +#### Требования - Не принадлежит конкретному бизнес-домену. Если блок доменный — он живёт в `business/` - Используется в нескольких screens или layouts -#### Слой Business +### Слой Business Бизнес-домены приложения: auth, catalog, orders, checkout, chat. Каждый домен — отдельный модуль со своими типами, логикой, UI и сервисами. @@ -568,14 +569,14 @@ src/business/ └── notifications/ ``` -##### Требования +#### Требования - Один модуль = один бизнес-домен - Циклические зависимости между доменами запрещены - Импорт кода между доменами — через фабрику. `import type` — напрямую - Доменные типы (`User`, `Product`) живут здесь, не в `shared/` -#### Слой Infrastructure +### Слой Infrastructure Техсервисы приложения: theme, i18n, API-адаптеры, logger, realtime. Каждый сервис — отдельный модуль. @@ -594,12 +595,12 @@ src/infrastructure/ └── realtime/ ``` -##### Требования +#### Требования - Один модуль = один техсервис - Импортирует `infrastructure/`, `ui/`, `shared/` -#### Слой UI +### Слой UI UI-кит без бизнес-логики: button, carousel, toast, modal. @@ -637,12 +638,12 @@ src/ui/ └── tooltip/ ``` -##### Требования +#### Требования - Не содержит бизнес-логику - Импортирует только `ui/` и `shared/` -#### Слой Shared +### Слой Shared Общие ресурсы: утилиты, хелперы, стили, конфиги. Не знает о бизнес-домене. @@ -660,19 +661,20 @@ src/shared/ └── sprites/ ``` -##### Требования +#### Требования - Не имеет runtime-состояния -### Модули + +## Модули Раздел описывает модули SLM: что такое модуль, из чего он состоит и как взаимодействует с остальным кодом. -#### Определение +### Определение **Модуль — универсальный строительный блок архитектуры. Живёт на слое и содержит всё необходимое для своей работы: компоненты, хуки, сторы, сервисы, типы, стили. Набор содержимого не фиксирован — включаются только нужные части.** -#### Модуль vs компонент +### Модуль vs компонент **Компонент** — один `.tsx` файл. Не имеет своих сегментов, использует сегменты родительского модуля. Живёт в корне или `ui/` сегменте модуля. @@ -694,7 +696,7 @@ auth/ └── index.ts ``` -#### Структура +### Структура Модуль состоит из сегментов. Ни один сегмент не обязателен — модуль может состоять даже из одного `index.ts` с реэкспортом типов. @@ -714,9 +716,9 @@ auth/ └── index.ts # публичный API ``` -Подробное описание каждого сегмента — в разделе [Сегменты](/reference/segments). +Подробное описание каждого сегмента — в разделе [Сегменты](/basics/architecture/reference/segments). -#### Публичный API +### Публичный API Модуль экспортирует наружу только то, что нужно другим. Всё остальное — внутреннее. @@ -737,13 +739,13 @@ import { validateToken } from '@/business/auth/lib/tokens' import { useAuth } from '@/business/auth' ``` -#### Фабрика +### Фабрика Если модуль зависит от кода другого бизнес-домена — он экспортирует фабрику. Фабрика декларирует необходимые зависимости и возвращает API модуля. Точка использования (screen, widget, layout) предоставляет зависимости при вызове. Модуль без cross-domain зависимостей экспортирует API напрямую. Типы всегда экспортируются напрямую — `import type` не является runtime-зависимостью. -##### Модуль без зависимостей — прямой экспорт: +#### Модуль без зависимостей — прямой экспорт: ```ts // business/auth/index.ts @@ -752,7 +754,7 @@ export { useCurrentUser } from './hooks/use-current-user' export type { User, Session } from './types' ``` -##### Модуль с зависимостями — фабрика: +#### Модуль с зависимостями — фабрика: ```ts // business/chat/types/deps.ts @@ -789,7 +791,7 @@ export type { Message, ChatRoom } from './types' export type { ChatDeps } from './types/deps' ``` -##### Использование на странице: +#### Использование на странице: ```tsx // screens/support/support.tsx @@ -813,7 +815,7 @@ export function SupportScreen() { } ``` -#### Жизненный цикл +### Жизненный цикл Модуль рождается на самом низком уровне использования и поднимается выше только при реальной потребности. @@ -825,15 +827,16 @@ export function SupportScreen() { Подъём — обычный рефакторинг в рамках задачи, а не отдельная активность. -### Сегменты + +## Сегменты Раздел описывает сегменты SLM: что такое сегмент, какие бывают и что в каждом из них лежит. -#### Определение +### Определение **Сегмент — папка внутри модуля, которая группирует файлы по назначению. Набор сегментов не фиксирован — модуль включает только те, которые ему нужны. Команда сама определяет какие сегменты используются в проекте — архитектура даёт рекомендацию.** -#### Обзор +### Обзор | Сегмент | Содержимое | |---------|------------| @@ -848,7 +851,7 @@ export function SupportScreen() { | `lib/` | Утилиты и хелперы модуля | | `config/` | Константы и конфигурация | -#### Сегмент ui/ +### Сегмент ui/ Компоненты, принадлежащие модулю. Содержит только `.tsx` файлы — без своих сегментов, стилей, типов, хуков. Использует сегменты родительского модуля. @@ -865,7 +868,7 @@ auth/ Если компоненту нужны собственные сегменты — это уже не `ui/`, а `parts/`. -#### Сегмент parts/ +### Сегмент parts/ Вложенные модули со своими сегментами. Каждый элемент `parts/` — полноценный модуль: папка с компонентом, хуками, стилями, типами и т.д. @@ -891,7 +894,7 @@ home/ Если вложенный модуль обрастает своими `parts/` — это сигнал, что он достаточно самостоятельный для подъёма на уровень выше. -#### Сегмент hooks/ +### Сегмент hooks/ React-хуки модуля. Инкапсулируют логику, состояние, подписки, побочные эффекты. @@ -902,7 +905,7 @@ hooks/ └── use-permissions.hook.ts ``` -#### Сегмент stores/ +### Сегмент stores/ Сторы состояния модуля. Конкретная реализация зависит от выбранного стейт-менеджера (Zustand, MobX, Redux и т.д.). @@ -912,7 +915,7 @@ stores/ └── session.store.ts ``` -#### Сегмент services/ +### Сегмент services/ Работа с внешними источниками данных: API-вызовы, запросы, подписки. @@ -922,7 +925,7 @@ services/ └── token.service.ts ``` -#### Сегмент mappers/ +### Сегмент mappers/ Функции трансформации данных из одного формата в другой: DTO в доменный тип, доменный тип в DTO, доменный тип в ViewModel. @@ -933,7 +936,7 @@ mappers/ └── map-order-to-dto.ts ``` -#### Сегмент types/ +### Сегмент types/ TypeScript-типы и интерфейсы модуля. Доменные типы, DTO, пропсы компонентов. @@ -943,7 +946,7 @@ types/ └── session.type.ts ``` -#### Сегмент styles/ +### Сегмент styles/ Стили модуля. Формат зависит от выбранного подхода (CSS Modules, SCSS, CSS-in-JS и т.д.). @@ -953,7 +956,7 @@ styles/ └── login-form.module.css ``` -#### Сегмент lib/ +### Сегмент lib/ Утилиты и хелперы, специфичные для модуля. Чистые функции без побочных эффектов. @@ -965,7 +968,7 @@ lib/ Отличие от `shared/lib/`: здесь лежат утилиты, нужные только этому модулю. Общие утилиты — в `shared/lib/`. -#### Сегмент config/ +### Сегмент config/ Константы и конфигурация модуля: маршруты, лимиты, дефолтные значения. @@ -1360,7 +1363,7 @@ src/ └── shared/ # Общие ресурсы (утилиты, типы, стили) ``` -Принципы организации слоёв описаны в разделе [Архитектура](../basics/architecture). +Принципы организации слоёв описаны в разделе [Архитектура](../basics/architecture/). #### Папка `app/` @@ -1413,7 +1416,7 @@ src/app/ Правила написания React-компонентов: файловая структура модуля, типизация пропсов, документирование и реализация. Раздел охватывает компоненты всех слоёв — от `shared/ui` до `screens`. -Архитектурные слои и их назначение описаны в разделе [Архитектура](/basics/architecture). +Архитектурные слои и их назначение описаны в разделе [Архитектура](/basics/architecture/). ### Правила организации