mirror of
https://github.com/gromlab-ru/slm-design.git
synced 2026-08-22 07:30:16 +03:00
sync
This commit is contained in:
206
DRAFT/level-3/domains/domain.md
Normal file
206
DRAFT/level-3/domains/domain.md
Normal file
@@ -0,0 +1,206 @@
|
||||
# Domain
|
||||
|
||||
> Рабочая заметка. Не является нормативным разделом спецификации.
|
||||
|
||||
## Определение
|
||||
|
||||
### DOM-N003: Domain является границей владения предметной областью
|
||||
|
||||
Domain группирует business-контракт, concrete integrations, готовые presets и framework-specific bindings одной предметной области.
|
||||
|
||||
Примеры Domain:
|
||||
|
||||
- `auth`;
|
||||
- `user`;
|
||||
- `catalog`;
|
||||
- `orders`;
|
||||
- `checkout`.
|
||||
|
||||
Domain не является одним большим module. Он является границей, внутри которой могут находиться modules и logical groups с заданным направлением зависимостей.
|
||||
|
||||
```text
|
||||
Domain
|
||||
├── business module
|
||||
├── presets group
|
||||
│ └── preset modules
|
||||
├── framework binding module или group
|
||||
└── optional reusable adapters group
|
||||
└── adapter modules
|
||||
```
|
||||
|
||||
## Предварительная структура
|
||||
|
||||
```text
|
||||
domains/auth/
|
||||
├── business/
|
||||
│ ├── auth.factory.ts
|
||||
│ ├── errors/
|
||||
│ ├── lib/
|
||||
│ ├── services/
|
||||
│ ├── tests/
|
||||
│ ├── types/
|
||||
│ └── index.ts
|
||||
├── presets/
|
||||
│ └── {preset-name}/
|
||||
│ ├── adapters/
|
||||
│ ├── create-auth.ts
|
||||
│ ├── create-auth.test.ts
|
||||
│ └── index.ts
|
||||
└── {framework-binding}/
|
||||
├── hooks/
|
||||
├── providers/
|
||||
├── tests/
|
||||
├── ui/
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
`{preset-name}` и `{framework-binding}` являются placeholders, а не обязательными именами папок. Preset называется по своему scope или назначению. Framework binding может быть оформлен как `react`, `bindings/react`, `framework/react` или по другому локальному соглашению.
|
||||
|
||||
Environment-specific preset, включая server-only вариант, может быть добавлен отдельным preset module. SLM не требует заранее делить `presets` или `adapters` на `browser`, `server` и другие технические категории.
|
||||
|
||||
## Возможные ветки Domain
|
||||
|
||||
### DOM-N007: Domain не имеет фиксированного набора верхних папок
|
||||
|
||||
| Роль | Типичная форма | Статус |
|
||||
|---|---|---|
|
||||
| Business | Один business module | Основная гипотеза Domain |
|
||||
| Presets | Logical group с preset modules | По наличию повторяемых assemblies |
|
||||
| Framework bindings | Module или logical group | По наличию framework integration |
|
||||
| Reusable adapters | Logical group с adapter modules | Только после promotion из владельца |
|
||||
| Tests | Segment конкретного module | Не создаётся в корне Domain |
|
||||
|
||||
`model`, `types`, `errors`, `lib`, `ui`, `client` и `server` не становятся верхними Domain-разделами автоматически. Они размещаются внутри module-владельца либо появляются как локальное соглашение с отдельным обоснованием.
|
||||
|
||||
## Иерархия сущностей
|
||||
|
||||
### DOM-N004: Роль и структурный вид являются независимыми характеристиками
|
||||
|
||||
Архитектурная роль отвечает на вопрос «какую ответственность выполняет код»:
|
||||
|
||||
- business;
|
||||
- preset;
|
||||
- framework binding;
|
||||
- adapter.
|
||||
|
||||
Структурный вид отвечает на вопрос «как оформлена граница кода»:
|
||||
|
||||
- Domain;
|
||||
- module;
|
||||
- group;
|
||||
- segment;
|
||||
- file.
|
||||
|
||||
```text
|
||||
Domain
|
||||
├── Module
|
||||
│ ├── Segment
|
||||
│ │ └── File
|
||||
│ └── File
|
||||
└── Group
|
||||
├── Module
|
||||
└── Group
|
||||
└── Module
|
||||
```
|
||||
|
||||
Правила структурных видов:
|
||||
|
||||
- Module владеет самостоятельной ответственностью и public API.
|
||||
- Group является logical directory для навигации, не имеет `index.ts`, runtime и собственных файлов реализации.
|
||||
- Segment существует внутри module, группирует его файлы по назначению и не имеет отдельного внешнего API.
|
||||
- Имя папки само по себе не доказывает её структурный вид.
|
||||
|
||||
Пример классификации:
|
||||
|
||||
| Путь | Роль | Структурный вид |
|
||||
|---|---|---|
|
||||
| `domains/auth` | Предметная область Auth | Domain |
|
||||
| `domains/auth/business` | Business | Module |
|
||||
| `domains/auth/business/services` | Business scenarios | Segment |
|
||||
| `domains/auth/business/tests` | Business tests | Segment |
|
||||
| `domains/auth/presets` | Навигация presets | Group |
|
||||
| `domains/auth/presets/{preset-name}` | Preset | Module |
|
||||
| `domains/auth/presets/{preset-name}/adapters` | Private adapters preset | Segment |
|
||||
| `domains/auth/{framework-binding}` | Framework binding | Module или Group по фактической границе |
|
||||
| `domains/auth/adapters` | Навигация promoted adapters | Optional group |
|
||||
| `domains/auth/adapters/{adapter-name}` | Reusable adapter | Module |
|
||||
|
||||
## Публичные границы
|
||||
|
||||
### DOM-N005: Domain предоставляет отдельные public submodules
|
||||
|
||||
Предварительно Domain не имеет обязательного общего facade. Каждый public module предоставляет собственный entrypoint:
|
||||
|
||||
```ts
|
||||
import { authFactory, validateAuthPhone } from '@/domains/auth/business'
|
||||
import { createApplicationAuth } from '@/domains/auth/presets/application'
|
||||
import { AuthProvider, useAuth } from '@/domains/auth/react'
|
||||
```
|
||||
|
||||
`application` и `react` здесь являются только примерами пользовательских имён. Отдельные entrypoints не смешивают business, concrete assembly и framework code в одном import graph.
|
||||
|
||||
Возможные public entrypoints:
|
||||
|
||||
```text
|
||||
@/domains/auth/business
|
||||
@/domains/auth/presets/{preset-name}
|
||||
@/domains/auth/{framework-binding}
|
||||
@/domains/auth/adapters/{adapter-name} # только для promoted adapter module
|
||||
```
|
||||
|
||||
Private adapters внутри preset не получают собственного внешнего entrypoint.
|
||||
|
||||
### DOM-N006: Omnibus barrel для всего Domain опасен
|
||||
|
||||
Такой entrypoint может связать изоморфный, client-only и server-only graphs:
|
||||
|
||||
```ts
|
||||
// Не использовать как default-подход.
|
||||
export * from './business'
|
||||
export * from './presets/application'
|
||||
export * from './react'
|
||||
```
|
||||
|
||||
Tree shaking не считается security boundary. Server-only submodule не должен быть достижим из изоморфного или client entrypoint даже через re-export.
|
||||
|
||||
## Предварительное направление зависимостей
|
||||
|
||||
```text
|
||||
business
|
||||
↑
|
||||
preset + private adapters
|
||||
|
||||
готовый business API instance
|
||||
↑
|
||||
framework bindings / compositions
|
||||
```
|
||||
|
||||
Более точная схема импортов:
|
||||
|
||||
```text
|
||||
business -/→ adapters | presets | framework | infra concrete runtime
|
||||
preset-private adapters → business contracts + concrete runtime
|
||||
promoted adapter module → business contracts + concrete runtime
|
||||
presets → business factory + private or promoted adapters
|
||||
framework → business contracts + ready API or preset
|
||||
compositions → ready business API + framework bindings
|
||||
```
|
||||
|
||||
Framework module может одновременно быть assembly site, если он явно владеет lifecycle API instance. Наличие папки `presets/` не даёт ей монополию на вызов factory.
|
||||
|
||||
## Domain и compositions
|
||||
|
||||
Domain владеет повторяемой доменной ответственностью. Composition по-прежнему владеет страницей, route tree, экраном и конкретным пользовательским outcome.
|
||||
|
||||
Предварительная граница:
|
||||
|
||||
| Ответственность | Владелец |
|
||||
|---|---|
|
||||
| Auth scenarios и contracts | `domains/auth/business` |
|
||||
| Private auth adapters одной assembly | Segment внутри соответствующего preset module |
|
||||
| Reusable auth adapter | Optional adapter module после promotion |
|
||||
| Повторяемая сборка AuthApi | Конкретный preset module или другой assembly site |
|
||||
| Auth React provider/access hook | Выбранный framework binding module |
|
||||
| Текст ошибки, redirect, экран и route outcome | Consumer composition |
|
||||
|
||||
Граница domain-specific UI пока остаётся открытым вопросом.
|
||||
Reference in New Issue
Block a user