mirror of
https://github.com/gromlab-ru/slm-design.git
synced 2026-08-22 07:30:16 +03:00
feat: уточнить архитектурные границы SLM
This commit is contained in:
@@ -56,12 +56,10 @@ SLM-L{level}-{group}-{class}{number}
|
||||
| `ERROR` | Ошибки домена |
|
||||
| `PORT` | Порты бизнес-логики |
|
||||
| `ADAPTER` | Адаптеры |
|
||||
| `PRESET` | Типовые сборки |
|
||||
| `ASSEMBLY` | Сборка и экземпляры API |
|
||||
| `ASSEMBLY` | Сборка API и жизненный цикл |
|
||||
| `ENVIRONMENT` | Границы сред выполнения |
|
||||
| `FRAMEWORK` | Модули фреймворков |
|
||||
| `TEST` | Тестирование |
|
||||
| `MIGRATION` | Переход между архитектурными формами |
|
||||
|
||||
Код раздела записывается полным английским именем в `UPPER_SNAKE_CASE`. Новый код добавляется в таблицу до первого использования.
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
|
||||
> **Направление зависимостей**
|
||||
>
|
||||
> Внутри одного SLM root код каждого слоя может зависеть только от кода этого же или любого нижнего слоя в нормативном порядке слоёв выбранного уровня SLM.
|
||||
> Внутри одного SLM root код каждого слоя может зависеть только от кода целевых слоёв, разрешённых для него нормативной матрицей слоёв.
|
||||
|
||||
### SLM-L1-LAYER-R003
|
||||
|
||||
> **Граница слоя `app`**
|
||||
>
|
||||
> В `app` размещаются только точки входа фреймворка для запуска, маршрутов, преобразования входных данных и подключения публичных API нижних модулей или ресурсов `shared`; ответственности нижних слоёв остаются за пределами `app`.
|
||||
> В `app` размещаются только точки входа фреймворка для запуска, маршрутов, преобразования входных данных и подключения публичных API модулей разрешённых слоёв или ресурсов `shared`; ответственности этих модулей остаются за пределами `app`.
|
||||
|
||||
## Границы модулей
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Правила SLM второго уровня
|
||||
|
||||
Проект Level 2 соблюдает правила Level 1 и дополнительные правила этого реестра. `SLM-L1-DOMAIN-R015` заменяется правилами доменного пакета. `SLM-L1-GROUP-R007` сохраняется для Groups внутри пакета и вне слоя `domains`, а для навигационных Groups слоя `domains` заменяется `SLM-L2-GROUP-R004`. Для модуля `business` правило `SLM-L1-MODULE-A004` уточняется правилом `SLM-L2-BUSINESS-A019`: три объявленных фасета вместе образуют один логический публичный API и не считаются deep imports. Ранее использовавшийся номер `SLM-L2-DOMAIN-R001` не переиспользуется после изменения модели уровней.
|
||||
Доменный пакет Level 2 соблюдает правила Level 1 и дополнительные правила этого реестра. Для предметной области в пакетной форме `SLM-L1-DOMAIN-R015` заменяется правилами доменного пакета; остальные предметные области того же SLM root могут сохранять форму доменного модуля Level 1. `SLM-L1-GROUP-R007` сохраняется для Groups внутри пакета и вне слоя `domains`, а для навигационных Groups слоя `domains` заменяется `SLM-L2-GROUP-R004`. Для модуля `business` правило `SLM-L1-MODULE-A004` уточняется правилом `SLM-L2-BUSINESS-A019`: объявленные фасеты вместе образуют один логический публичный API и не считаются deep imports. Ранее использовавшиеся номера `SLM-L2-DOMAIN-R001` и `SLM-L2-MIGRATION-A017` не переиспользуются после изменения модели уровней и перехода к постоянному совместному применению форм.
|
||||
|
||||
## Граница доменного пакета
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
> **Предметная граница пакета**
|
||||
>
|
||||
> Каждая самостоятельная предметная область слоя `domains` представлена ровно одним доменным пакетом; все его модули относятся только к этой предметной области.
|
||||
> Каждая предметная область, использующая пакетную форму Level 2, представлена ровно одним доменным пакетом; все его модули относятся только к этой предметной области.
|
||||
|
||||
### SLM-L2-DOMAIN-A003
|
||||
|
||||
@@ -20,21 +20,21 @@
|
||||
|
||||
> **Навигационная Group доменов**
|
||||
>
|
||||
> Group, расположенная непосредственно в слое `domains` или другой такой Group, содержит только доменные пакеты и навигационные Groups и не владеет реализацией, состоянием, жизненным циклом или публичным API.
|
||||
> Group, расположенная непосредственно в слое `domains` или другой такой Group, содержит только доменные модули Level 1, доменные пакеты Level 2 и навигационные Groups и не владеет реализацией, состоянием, жизненным циклом или публичным API.
|
||||
|
||||
## Business и DomainApi
|
||||
## Business и Domain API
|
||||
|
||||
### SLM-L2-BUSINESS-R005
|
||||
|
||||
> **Модуль business**
|
||||
>
|
||||
> Каждый доменный пакет содержит ровно один модуль `business`, который владеет публичными предметными сценариями и контрактом `DomainApi` этой предметной области.
|
||||
> Каждый доменный пакет содержит ровно один модуль `business`, который владеет публичными предметными сценариями и объявляет один или несколько именованных Domain API этой предметной области.
|
||||
|
||||
### SLM-L2-BUSINESS-R006
|
||||
|
||||
> **Единственный runtime-источник домена**
|
||||
> **Предметная власть business**
|
||||
>
|
||||
> Приложение получает доменные данные, состояние и результаты предметных сценариев только через экземпляр `DomainApi`; adapters, presets и framework binding modules не предоставляют параллельный runtime-источник этих данных или результатов.
|
||||
> Adapters, assemblies и framework binding modules транспортируют, кэшируют или проецируют доменные данные только в форме, произведённой или проверенной публичным API либо детерминированным runtime модуля `business`, и не определяют независимую предметную модель, переход или результат сценария.
|
||||
|
||||
### SLM-L2-BUSINESS-A007
|
||||
|
||||
@@ -44,9 +44,9 @@
|
||||
|
||||
### SLM-L2-FACTORY-R008
|
||||
|
||||
> **Единая фабрика DomainApi**
|
||||
> **Фабрики Domain API**
|
||||
>
|
||||
> Модуль `business` предоставляет ровно одну публичную фабрику, которая получает явные runtime-зависимости, создаёт `DomainApi` одного контракта независимо от preset и среды выполнения и является единственным runtime-экспортом фасета `business/factory`.
|
||||
> Каждому публичному Domain API соответствует ровно одна именованная фабрика фасета `business/factory`; фабрика получает явные runtime-зависимости, создаёт только этот API и не выбирает assembly или среду выполнения.
|
||||
|
||||
## Ошибки домена
|
||||
|
||||
@@ -54,27 +54,27 @@
|
||||
|
||||
> **Публичный контракт ошибок**
|
||||
>
|
||||
> Модуль `business` экспортирует через type-only barrel именованные readonly-типы DomainError и DomainErrorCode, а через `business/error` только устойчивые runtime-коды и guards безопасной публичной формы независимо от выбранного способа передачи ошибки.
|
||||
> Каждый ожидаемый сбой публичного предметного сценария представлен именованным readonly-типом собственной доменной ошибки с устойчивым кодом; тип экспортируется через type-only barrel, а необходимые внешним потребителям runtime-коды и guards только через `business/runtime`.
|
||||
|
||||
### SLM-L2-ERROR-R010
|
||||
|
||||
> **Изоляция исходных ошибок**
|
||||
>
|
||||
> Сбой adapter, SDK, транспорта, storage или другого домена, доступный приложению через `DomainApi`, представлен только безопасной ошибкой собственного доменного контракта и не раскрывает исходный объект, тип, message, status, payload или cause.
|
||||
> Сбой adapter, SDK, транспорта, storage или другого домена, доступный приложению через Domain API, представлен только безопасной ошибкой собственного доменного контракта и не раскрывает исходный объект, тип, message, status, payload или cause.
|
||||
|
||||
## Presets и зависимости
|
||||
## Assemblies и зависимости
|
||||
|
||||
### SLM-L2-PRESET-R011
|
||||
### SLM-L2-ASSEMBLY-R011
|
||||
|
||||
> **Роль preset**
|
||||
> **Роль assembly**
|
||||
>
|
||||
> Каждый preset является SLM-модулем одного именованного контекста выполнения, при наличии технических зависимостей выбирает их adapter-модули, вызывает единственную business-фабрику и не добавляет предметные сценарии, методы `DomainApi` или собственные доменные ошибки.
|
||||
> Каждая assembly является SLM-модулем одного именованного контекста выполнения, выбирает необходимые adapter-модули, вызывает одну или несколько business-фабрик и возвращает явный именованный граф их API, не добавляя предметные сценарии, методы API или собственные доменные ошибки.
|
||||
|
||||
### SLM-L2-DEPENDENCY-A012
|
||||
|
||||
> **Междоменные импорты**
|
||||
> **Междоменные импорты Level 2**
|
||||
>
|
||||
> Модуль одного доменного пакета не импортирует runtime-экспорты другого пакета, включая функции, состояние, hooks, contexts, Providers и components; разрешён только type-only импорт публичного business-контракта, который остаётся ребром общего ацикличного графа.
|
||||
> Статическая связь между разными доменными границами, хотя бы одна из которых является пакетом Level 2, допускает только type-only импорт публичного API доменного модуля Level 1 или корневого `business` пакета Level 2 либо runtime-импорт `business/runtime` пакета Level 2; все такие связи входят в общий ацикличный граф, а остальные runtime-экспорты другого домена не импортируются.
|
||||
|
||||
### SLM-L2-ENVIRONMENT-A013
|
||||
|
||||
@@ -94,21 +94,21 @@
|
||||
|
||||
> **Framework binding module**
|
||||
>
|
||||
> Модуль внутри Framework Group владеет одной domain-specific framework-ответственностью, получает готовый `DomainApi` и не выполняет business-сборку, не выбирает adapters и не владеет страницей, маршрутом или multi-domain композицией.
|
||||
> Модуль внутри Framework Group владеет одной domain-specific framework-ответственностью, получает готовые Domain API и не выполняет business-сборку, не выбирает adapters и не владеет страницей, маршрутом или multi-domain композицией.
|
||||
|
||||
### SLM-L2-TEST-R016
|
||||
|
||||
> **Проверка владельцев Level 2**
|
||||
>
|
||||
> Каждый публичный предметный сценарий проверяется через business-фабрику, а основные тесты adapter, preset и framework binding module проверяют только собственные публичные границы и не повторяют полный набор предметных сценариев.
|
||||
> Каждый публичный предметный сценарий проверяется через фабрику владеющего им Domain API, а основные тесты adapter, assembly и framework binding module проверяют только собственные публичные границы и не повторяют полный набор предметных сценариев.
|
||||
|
||||
## Миграция
|
||||
## Совместное применение форм
|
||||
|
||||
### SLM-L2-MIGRATION-A017
|
||||
### SLM-L2-DOMAIN-A026
|
||||
|
||||
> **Изоляция форм во время миграции**
|
||||
> **Однозначная форма домена**
|
||||
>
|
||||
> Пока SLM root содержит одновременно доменные модули Level 1 и доменные пакеты Level 2, модули этих двух форм не создают между собой runtime- или type-only импортов.
|
||||
> Каждая предметная область объявлена ровно в одной форме: как доменный модуль Level 1 либо как доменный пакет Level 2; один SLM root может одновременно содержать разные предметные области обеих форм.
|
||||
|
||||
## Внешние библиотеки business
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
|
||||
> **Business-safe внешний пакет**
|
||||
>
|
||||
> Внешний пакет объявляется business-safe только если он детерминирован, не выполняет ввод-вывод, не владеет изменяемым состоянием или runtime capability и не является SDK, generated client, storage, state manager, framework или другой технической интеграцией.
|
||||
> Внешний пакет объявляется business-safe только если он детерминирован, не выполняет ввод-вывод, не владеет изменяемым состоянием или runtime capability и не является SDK, generated client, storage, state/query manager, framework или другой технической интеграцией.
|
||||
|
||||
## Публичные фасеты business
|
||||
|
||||
@@ -124,24 +124,48 @@
|
||||
|
||||
> **Публичные фасеты business**
|
||||
>
|
||||
> Публичный API `business` состоит ровно из трёх entry points: корневой barrel содержит только type exports, а `business/factory` и `business/error` содержат только runtime exports; другие публичные пути и deep imports запрещены.
|
||||
> Публичный API `business` имеет обязательные entry points `business` только с type exports и `business/factory` только с именованными runtime-фабриками, может иметь `business/runtime` только с runtime exports и не имеет других публичных путей или deep imports.
|
||||
|
||||
## Обязательные роли сборки
|
||||
|
||||
### SLM-L2-PRESET-A020
|
||||
### SLM-L2-ASSEMBLY-A020
|
||||
|
||||
> **Обязательная Group presets**
|
||||
> **Обязательная Group assemblies**
|
||||
>
|
||||
> Корень каждого доменного пакета содержит ровно одну непустую Group `presets`, каждый прямой дочерний элемент которой является объявленной границей SLM-модуля.
|
||||
> Корень каждого доменного пакета содержит ровно одну непустую Group `assemblies`, каждый прямой дочерний элемент которой является объявленной границей SLM-модуля.
|
||||
|
||||
### SLM-L2-ADAPTER-R021
|
||||
|
||||
> **Модули production adapters**
|
||||
>
|
||||
> Если business-фабрика имеет хотя бы одну техническую зависимость, корень доменного пакета содержит непустую Group `adapters`, а каждая production-реализация такой зависимости является отдельным adapter-модулем этой Group и не определяется в другом месте production-графа.
|
||||
> Если хотя бы одна business-фабрика имеет техническую зависимость, корень доменного пакета содержит непустую Group `adapters`, а каждая связная production-реализация одной или нескольких таких зависимостей принадлежит ровно одному adapter-модулю этой Group и не определяется в другом месте production-графа.
|
||||
|
||||
### SLM-L2-BUSINESS-A022
|
||||
|
||||
> **Потребители фасетов business**
|
||||
>
|
||||
> Корневой `business` импортируется извне только через `import type`; `business/factory` импортируют только presets своего домена, `app`, `compositions` и тесты, а `business/error` импортируют только framework binding modules своего домена, `app`, `compositions` и тесты.
|
||||
> Корневой `business` импортируется извне только через `import type`; `business/factory` импортируют только assemblies своего домена, `app`, `compositions` и тесты, а `business/runtime` импортируется только через объявленный публичный путь с соблюдением правил слоёв и междоменных зависимостей.
|
||||
|
||||
## Жизненный цикл assembly
|
||||
|
||||
### SLM-L2-ASSEMBLY-R023
|
||||
|
||||
> **Cleanup ресурса assembly**
|
||||
>
|
||||
> Создание Domain API фабрикой или assembly не запускает скрытый ресурс жизненного цикла; ресурс запускается явной операцией с cleanup, а технический ресурс, который assembly обязана создать для графа, сопровождается публичным cleanup handle, вызываемым не позже завершения области жизни графа.
|
||||
|
||||
## Недетерминизм business
|
||||
|
||||
### SLM-L2-BUSINESS-R024
|
||||
|
||||
> **Явные источники недетерминизма**
|
||||
>
|
||||
> Business-сценарий получает текущее время, timer, random, ID generator, environment и другие источники недетерминизма только через явные зависимости фабрики и не читает их из скрытого runtime-окружения.
|
||||
|
||||
## Публичный runtime business
|
||||
|
||||
### SLM-L2-BUSINESS-R025
|
||||
|
||||
> **Детерминированный runtime business**
|
||||
>
|
||||
> Фасет `business/runtime` экспортирует только необходимые реальным внешним потребителям детерминированные значения и функции без ввода-вывода, изменяемого состояния, runtime capability или environment-specific поведения.
|
||||
|
||||
Reference in New Issue
Block a user