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

7.0 KiB
Raw Blame History

Домены Level 2

Пояснение модели доменных модулей без строгой внутренней архитектуры Level 3.

Домен Level 2 является обычным SLM-модулем. Новый уровень добавляет доменную роль и место в порядке слоёв, но не вводит отдельную структурную сущность поверх модуля.

Связанные правила

Один домен, один модуль

Связная предметная область получает один корневой доменный модуль. Вся логика авторизации может находиться внутри auth без обязательного выделения session, phone-login или каждого сценария в соседний доменный модуль.

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 внутри родительской границы, собственных зависимостей или области жизни.

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 могут классифицировать их по принадлежности к разным бизнес-приложениям или продуктовым областям.

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 модуля:

import { signOut, useSession } from '@/domains/auth'

Deep import остаётся нарушением:

import { useSession } from '@/domains/auth/hooks/use-session'

Group не предоставляет агрегирующий API и не реэкспортирует содержащиеся в ней домены.

Граница с другими слоями

Ответственность Владелец
Доменная модель, правило, сценарий или продуктовое состояние Доменный модуль
Страница, маршрут, экран и конкретный visual outcome Модуль compositions
Самостоятельный технический сервис без предметной модели Модуль infra
Универсальный интерфейс без продуктовой семантики Модуль ui
Независимая детерминированная утилита shared или локальный владелец

Число потребителей не является единственным критерием. Самостоятельная доменная ответственность может принадлежать domains, даже если сегодня используется одной композицией.