Files
slm-design/DRAFT/level-2/domains.md

118 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Домены 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`, даже если сегодня используется одной композицией.