feat: уточнить архитектурные границы SLM

This commit is contained in:
2026-07-30 21:44:47 +03:00
parent 4ce6bae61c
commit 15805e28df
28 changed files with 1006 additions and 553 deletions

View File

@@ -9,17 +9,17 @@ Level 1 задаёт полную структурную основу SLM: сл
| Уровень | Назначение |
|---|---|
| Level 1 | Слои, доменные модули, зависимости, структурные сущности и жизненный цикл ресурсов |
| Level 2 | Доменные пакеты, единый `DomainApi`, сборки и явные границы сред выполнения |
| Level 2 | Опциональная пакетная форма отдельных доменов, именованные API, assemblies и явные границы сред выполнения |
Повышение уровня может требовать рефакторинга, но базовые понятия Level 1 сохраняются.
Переход отдельного домена на Level 2 может требовать рефакторинга, но базовые понятия Level 1 сохраняются. Остальные домены того же SLM root могут оставаться модулями Level 1.
## Область Level 1
Level 1 описывает слои, доменные модули, группы, сегменты, компоненты, публичный API, граф зависимостей и владение жизненным циклом ресурсов.
Level 1 не задаёт обязательную внутреннюю форму доменного модуля, фабрики, порты, адаптеры, presets, обязательный поток данных, монорепозитории, соглашения об именовании и файловый стайлгайд.
Level 1 не задаёт обязательную внутреннюю форму доменного модуля, фабрики, порты, адаптеры, assemblies, обязательный поток данных, монорепозитории, соглашения об именовании и файловый стайлгайд.
Появление нескольких сред выполнения, устойчивого `DomainApi` или необходимости разделить бизнес-логику и технические сборки является сигналом рассмотреть [Level 2](../level-2/).
Появление нескольких сред выполнения, нескольких независимо собираемых API или необходимости разделить бизнес-логику и технические сборки является сигналом перевести конкретный домен на [Level 2](../level-2/).
## Виды утверждений

View File

@@ -2,7 +2,7 @@
> Пояснение нормативной модели зависимостей Level 1.
Слои задают допустимое направление связей, а модули образуют граф зависимостей.
Матрица слоёв задаёт допустимые связи, а модули образуют граф зависимостей.
## Что считается зависимостью
@@ -16,11 +16,12 @@
Ресурс `shared` также не является модулем. Его прямой импорт участвует в проверке направления слоёв, но не нарушает требование о публичном API модуля.
## Направление
## Допустимые связи
- Модуль может импортировать модули своего или любого нижнего слоя.
- Модуль может импортировать модули своего слоя и слоёв, разрешённых нормативной матрицей.
- Модули одного слоя могут импортировать друг друга.
- Промежуточный слой не является обязательным посредником.
- `infra` и `ui` не импортируют друг друга; их связывает владелец из `domains`, `compositions` или `app`.
Доменный модуль Level 1 может импортировать публичный API другого доменного модуля. Runtime- и type-only импорты одинаково создают ребро графа, поэтому общий граф обязан оставаться ацикличным.
@@ -31,7 +32,7 @@ import type { Product } from '@/domains/catalog'
Level 1 не требует отдельного механизма междоменной инъекции. Более строгая модель cross-domain зависимостей задаётся Level 2.
Направление слоёв определено в [Слоях](./layers.md).
Матрица слоёв определена в [Слоях](./layers.md).
## Связанные правила

View File

@@ -11,7 +11,7 @@
## Один домен, один модуль
Связная предметная область получает один доменный модуль. Level 1 не требует выделять business, adapters, presets или framework bindings в самостоятельные соседние модули.
Связная предметная область получает один доменный модуль. Level 1 не требует выделять business, adapters, assemblies или framework bindings в самостоятельные соседние модули.
```text
domains/auth/
@@ -56,6 +56,6 @@ Group не имеет `index.ts`, реализации, состояния ил
## Переход на Level 2
Доменный модуль переводится в доменный пакет Level 2, когда ему нужны устойчивый `DomainApi`, одна фабрика, несколько сред выполнения или независимые SLM-модули сборок и framework-интеграции.
Доменный модуль переводится в доменный пакет Level 2, когда ему нужны устойчивые API, несколько фабрик, разные среды выполнения или независимые SLM-модули сборок и framework-интеграции.
Такой переход изменяет структурную границу: корневой доменный модуль исчезает, а его предметная ответственность переходит обязательному модулю `business` внутри доменного пакета.
Такой переход изменяет только форму выбранного домена: корневой доменный модуль исчезает, а его предметная ответственность переходит обязательному модулю `business` внутри доменного пакета. Другие предметные области SLM root не обязаны переходить вместе с ним.

View File

@@ -22,9 +22,9 @@ src/
### App
`app` связывает приложение с фреймворком: запускает его, объявляет маршруты, преобразует входные данные и подключает публичные API нижних модулей или ресурсы `shared`. Файлы `app` являются точками входа фреймворка, а не модулями SLM.
`app` связывает приложение с фреймворком: запускает его, объявляет маршруты, преобразует входные данные и подключает публичные API модулей разрешённых слоёв или ресурсы `shared`. Файлы `app` являются точками входа фреймворка, а не модулями SLM.
Точка входа может напрямую использовать `compositions`, `infra`, `ui` или `shared`, если зависимость разрешена общим порядком слоёв. Такое использование не переносит ответственность нижнего модуля в `app`.
Точка входа может напрямую использовать `compositions`, `domains`, `infra`, `ui` или `shared`, если зависимость разрешена матрицей слоёв. Такое использование не переносит ответственность импортируемого модуля в `app`.
### Compositions
@@ -52,32 +52,32 @@ src/
Если ресурсу нужны самостоятельная ответственность, собственные архитектурные зависимости, несколько файлов реализации, изменяемое состояние, ввод-вывод или область жизни, он оформляется как модуль. Каталог ресурсов не реэкспортирует модули и не используется для обхода их публичных API.
## Порядок слоёв
## Матрица зависимостей
```text
app
|
compositions
|
domains
infra
ui
/ \
infra ui
\ /
shared
```
Код слоя может импортировать модули своего или любого нижнего слоя. Промежуточные слои можно пропускать.
Код слоя может импортировать модули своего слоя и слоёв, разрешённых строкой матрицы. Разрешённая зависимость может пропускать промежуточные роли.
| Слой | Может импортировать нижние слои |
| Слой | Может импортировать |
|---|---|
| `app` | `compositions`, `domains`, `infra`, `ui`, `shared` |
| `compositions` | `domains`, `infra`, `ui`, `shared` |
| `domains` | `infra`, `ui`, `shared` |
| `infra` | `ui`, `shared` |
| `ui` | `shared` |
| `shared` | Нет |
| `app` | `app`, `compositions`, `domains`, `infra`, `ui`, `shared` |
| `compositions` | `compositions`, `domains`, `infra`, `ui`, `shared` |
| `domains` | `domains`, `infra`, `ui`, `shared` |
| `infra` | `infra`, `shared` |
| `ui` | `ui`, `shared` |
| `shared` | `shared` |
`infra` и `ui` не импортируют друг друга. Универсальный UI получает локализованный текст, тему, callbacks аналитики и другие возможности через входной контракт либо связывается с ними в `domains` или `compositions`. Если UI-модулю необходимо напрямую знать конкретный технический сервис приложения, такой код не является универсальным UI.
Импорты внутри слоя, публичный API и циклы описаны отдельно в [Зависимостях](./dependencies.md).

View File

@@ -28,4 +28,4 @@
Одиночный экземпляр на всё приложение допустим только тогда, когда модуль действительно владеет областью жизни приложения или процесса. Размещение экземпляра на уровне файла само по себе этого не доказывает.
Точка входа `app` может запускать или подключать ресурс через публичный API нижнего модуля, но не становится его владельцем.
Точка входа `app` может запускать или подключать ресурс через публичный API импортируемого модуля, но не становится его владельцем.

View File

@@ -42,11 +42,11 @@
## Структурные сущности
### Нормативный порядок слоёв
### Нормативная матрица слоёв
Полный линейный порядок слоёв выбранного уровня SLM. Он определяет, какой слой является нижним для проверки зависимостей.
Отношение допустимой зависимости между слоями одного SLM root. Матрица определяет, код каких слоёв может импортировать исходный слой; она не обязана образовывать линейный порядок.
Для Level 1 нормативным является порядок `app → compositions → domains → infra ui → shared`. Level 2 сохраняет этот порядок и уточняет внутреннюю форму слоя `domains`.
Для Level 1 нормативно отношение `app → compositions → domains → { infra, ui } → shared`. `infra` и `ui` являются независимыми ветвями: они не импортируют друг друга. Промежуточный слой не является обязательным посредником.
### Слой
@@ -61,7 +61,16 @@
| `ui` | Универсальные модули интерфейса без зависимости от конкретной продуктовой композиции |
| `shared` | Независимый детерминированный фундамент без знания о продукте, изменяемого состояния и ввода-вывода |
Слои образуют линейный порядок `app → compositions → domains → infra → ui → shared`. Нижним считается любой слой справа от исходного; промежуточный слой не является обязательным посредником.
Полная матрица допустимых зависимостей:
| Исходный слой | Допустимые целевые слои |
|---|---|
| `app` | `app`, `compositions`, `domains`, `infra`, `ui`, `shared` |
| `compositions` | `compositions`, `domains`, `infra`, `ui`, `shared` |
| `domains` | `domains`, `infra`, `ui`, `shared` |
| `infra` | `infra`, `shared` |
| `ui` | `ui`, `shared` |
| `shared` | `shared` |
### Модуль