mirror of
https://github.com/gromlab-ru/slm-design.git
synced 2026-08-22 07:30:16 +03:00
feat: level-2 документация
This commit is contained in:
117
DRAFT/level-2/domains.md
Normal file
117
DRAFT/level-2/domains.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Домены Level 2
|
||||
|
||||
> Пояснение модели доменных модулей без строгой внутренней архитектуры Level 3.
|
||||
|
||||
Домен Level 2 является обычным SLM-модулем. Новый уровень добавляет доменную роль и место в порядке слоёв, но не вводит отдельную структурную сущность поверх модуля.
|
||||
|
||||
## Связанные правила
|
||||
|
||||
- [`SLM-L2-DOMAIN-R001`](../rules/level-2.md#slm-l2-domain-r001)
|
||||
- [`SLM-L1-MODULE-A004`](../rules/level-1.md#slm-l1-module-a004)
|
||||
- [`SLM-L1-MODULE-A014`](../rules/level-1.md#slm-l1-module-a014)
|
||||
- [`SLM-L1-MODULE-R006`](../rules/level-1.md#slm-l1-module-r006)
|
||||
- [`SLM-L1-MODULE-R011`](../rules/level-1.md#slm-l1-module-r011)
|
||||
- [`SLM-L1-MODULE-R012`](../rules/level-1.md#slm-l1-module-r012)
|
||||
- [`SLM-L1-GROUP-R007`](../rules/level-1.md#slm-l1-group-r007)
|
||||
- [`SLM-L1-NESTED_MODULE-A010`](../rules/level-1.md#slm-l1-nested_module-a010)
|
||||
- [`SLM-L1-LIFECYCLE-R013`](../rules/level-1.md#slm-l1-lifecycle-r013)
|
||||
|
||||
## Один домен, один модуль
|
||||
|
||||
Связная предметная область получает один корневой доменный модуль. Вся логика авторизации может находиться внутри `auth` без обязательного выделения `session`, `phone-login` или каждого сценария в соседний доменный модуль.
|
||||
|
||||
```text
|
||||
domains/auth/
|
||||
├── hooks/
|
||||
├── services/
|
||||
│ ├── session.service.ts
|
||||
│ └── phone-login.service.ts
|
||||
├── stores/
|
||||
├── types/
|
||||
├── ui/
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
Названия и набор сегментов определяет стайлгайд проекта. Level 2 не требует показанный каркас.
|
||||
|
||||
## Внутренняя свобода
|
||||
|
||||
Доменный модуль может содержать всё, что нужно его ответственности:
|
||||
|
||||
- доменные типы, модели, правила и сценарии;
|
||||
- продуктовое состояние и управление его жизненным циклом;
|
||||
- framework hooks и domain-specific компоненты;
|
||||
- вызовы переданных или импортированных технических сервисов;
|
||||
- локальные adapters, mappers и интеграционный код;
|
||||
- сегменты и вложенные модули.
|
||||
|
||||
Если техническая реализация становится самостоятельным сервисом без доменной семантики, она переносится в `infra` по общим правилам назначения слоёв.
|
||||
|
||||
## Когда нужен вложенный модуль
|
||||
|
||||
Часть домена становится вложенным модулем только при появлении самостоятельной ответственности, публичного API внутри родительской границы, собственных зависимостей или области жизни.
|
||||
|
||||
```text
|
||||
domains/auth/
|
||||
├── parts/
|
||||
│ ├── auth-form/
|
||||
│ │ ├── auth-form.tsx
|
||||
│ │ └── index.ts
|
||||
│ └── registration-form/
|
||||
│ ├── registration-form.tsx
|
||||
│ └── index.ts
|
||||
├── auth.ts
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
Внешний код по-прежнему получает `auth-form` и `registration-form` только через публичный API `auth`. Само наличие нескольких файлов или отдельного пользовательского сценария не требует вложенного модуля.
|
||||
|
||||
## Опциональная группировка
|
||||
|
||||
Если количество доменов затрудняет навигацию, Groups внутри `domains` могут классифицировать их по принадлежности к разным бизнес-приложениям или продуктовым областям.
|
||||
|
||||
```text
|
||||
domains/
|
||||
├── shop/ # Group
|
||||
│ ├── auth/ # Доменный модуль Shop Auth
|
||||
│ ├── catalog/ # Доменный модуль
|
||||
│ └── orders/ # Доменный модуль
|
||||
└── cabinet/ # Group
|
||||
├── auth/ # Отдельный доменный модуль Cabinet Auth
|
||||
├── profile/ # Доменный модуль
|
||||
└── documents/ # Доменный модуль
|
||||
```
|
||||
|
||||
`shop` и `cabinet` не имеют `index.ts`, состояния, реализации или публичного API. Они могут содержать только доменные модули и другие Groups.
|
||||
|
||||
Одинаковое имя модуля в разных Groups допустимо, если это разные владельцы и разные предметные области. Если авторизация действительно общая, ей нужен один общий модуль-владелец, а не две копии.
|
||||
|
||||
Group не создаёт dependency boundary. Импорт между модулями разных Groups проверяется так же, как любой импорт внутри слоя `domains`.
|
||||
|
||||
## Публичный API
|
||||
|
||||
Внешний код использует домен через обычный публичный API модуля:
|
||||
|
||||
```ts
|
||||
import { signOut, useSession } from '@/domains/auth'
|
||||
```
|
||||
|
||||
Deep import остаётся нарушением:
|
||||
|
||||
```ts
|
||||
import { useSession } from '@/domains/auth/hooks/use-session'
|
||||
```
|
||||
|
||||
Group не предоставляет агрегирующий API и не реэкспортирует содержащиеся в ней домены.
|
||||
|
||||
## Граница с другими слоями
|
||||
|
||||
| Ответственность | Владелец |
|
||||
|---|---|
|
||||
| Доменная модель, правило, сценарий или продуктовое состояние | Доменный модуль |
|
||||
| Страница, маршрут, экран и конкретный visual outcome | Модуль `compositions` |
|
||||
| Самостоятельный технический сервис без предметной модели | Модуль `infra` |
|
||||
| Универсальный интерфейс без продуктовой семантики | Модуль `ui` |
|
||||
| Независимая детерминированная утилита | `shared` или локальный владелец |
|
||||
|
||||
Число потребителей не является единственным критерием. Самостоятельная доменная ответственность может принадлежать `domains`, даже если сегодня используется одной композицией.
|
||||
Reference in New Issue
Block a user