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:
@@ -8,6 +8,9 @@
|
||||
- [`SLM-L2-FACTORY-R008`](../../rules/level-2.md#slm-l2-factory-r008)
|
||||
- [`SLM-L2-ERROR-R010`](../../rules/level-2.md#slm-l2-error-r010)
|
||||
- [`SLM-L2-DEPENDENCY-A012`](../../rules/level-2.md#slm-l2-dependency-a012)
|
||||
- [`SLM-L2-BUSINESS-A019`](../../rules/level-2.md#slm-l2-business-a019)
|
||||
- [`SLM-L2-ADAPTER-R021`](../../rules/level-2.md#slm-l2-adapter-r021)
|
||||
- [`SLM-L2-BUSINESS-A022`](../../rules/level-2.md#slm-l2-business-a022)
|
||||
|
||||
## Одна фабрика
|
||||
|
||||
@@ -18,9 +21,17 @@
|
||||
Модуль `business` предоставляет одну публичную фабрику. Она получает все runtime-возможности явными аргументами и создаёт API одного контракта независимо от выбранного preset.
|
||||
|
||||
```ts
|
||||
import type { AuthApi, AuthDeps } from '@/domains/auth/business'
|
||||
|
||||
export type AuthFactory = (deps: AuthDeps) => AuthApi
|
||||
```
|
||||
|
||||
Runtime-фабрика импортируется только через отдельный entry point:
|
||||
|
||||
```ts
|
||||
import { authFactory } from '@/domains/auth/business/factory'
|
||||
```
|
||||
|
||||
Рекомендуется сохранять сам вызов фабрики чистым: он создаёт объекты и closures, но не читает скрытое окружение и не выбирает конкретную техническую реализацию. Детальный lifecycle ресурсов будет нормирован позже.
|
||||
|
||||
## Технические зависимости
|
||||
@@ -50,11 +61,11 @@ export type UserDeps = {
|
||||
}
|
||||
```
|
||||
|
||||
Runtime-значение передаёт место сборки графа через preset. `user/business` не импортирует executable API, factory или preset Auth.
|
||||
Runtime-значение место сборки графа передаёт через preset либо напрямую зависимой business-фабрике. `user/business` не импортирует executable API, factory или preset Auth.
|
||||
|
||||
## Adapter
|
||||
## Adapter module
|
||||
|
||||
Adapter соединяет явную зависимость фабрики с технической системой:
|
||||
Adapter module соединяет явную техническую зависимость фабрики с конкретной системой:
|
||||
|
||||
```text
|
||||
business dependency ← adapter → SDK / storage / platform / request data
|
||||
@@ -64,23 +75,40 @@ Adapter преобразует аргументы и технический ре
|
||||
|
||||
Ожидаемый исходный сбой возвращается `business`, который выбирает собственный error code. Поэтому приложение никогда не строит поведение по HTTP status, SDK error class или storage exception.
|
||||
|
||||
## Размещение adapter
|
||||
## Размещение adapters
|
||||
|
||||
Одноразовый adapter остаётся закрытым сегментом preset-модуля:
|
||||
|
||||
```text
|
||||
auth/presets/browser/
|
||||
├── adapters/
|
||||
│ └── phone.adapter.ts
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
Adapter становится самостоятельным SLM-модулем, когда нужен нескольким presets или имеет отдельную integration responsibility:
|
||||
Каждая production-реализация является отдельным SLM-модулем в Group `adapters`, даже если пока используется одним preset:
|
||||
|
||||
```text
|
||||
auth/adapters/
|
||||
└── identity-provider/
|
||||
├── phone-http/
|
||||
│ └── index.ts
|
||||
└── browser-session/
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
Самостоятельный adapter сохраняет минимальный публичный API и не становится альтернативным источником доменных данных для приложения.
|
||||
Adapter module имеет собственные ответственность, публичный API, environment label и тестовую границу. Group `adapters` не имеет `index.ts` и не реэкспортирует дочерние модули.
|
||||
|
||||
Production adapter запрещено определять:
|
||||
|
||||
- закрытым сегментом preset;
|
||||
- inline-функцией в `composition` или `app`;
|
||||
- частью framework binding module;
|
||||
- скрытой реализацией внутри `business`.
|
||||
|
||||
Preset и одноразовое место сборки импортируют конкретные adapter-модули через их публичные API:
|
||||
|
||||
```ts
|
||||
import { authFactory } from '@/domains/auth/business/factory'
|
||||
import { createPhoneHttpAdapter } from '@/domains/auth/adapters/phone-http'
|
||||
import { createBrowserSessionAdapter } from '@/domains/auth/adapters/browser-session'
|
||||
|
||||
const authApi = authFactory({
|
||||
phone: createPhoneHttpAdapter(),
|
||||
session: createBrowserSessionAdapter(),
|
||||
})
|
||||
```
|
||||
|
||||
Если фабрика не имеет технических зависимостей, Group `adapters` не обязательна. Cross-domain API dependency не считается adapter и передаётся отдельно.
|
||||
|
||||
Локальные fake implementations в business-тестах не являются production adapters и не требуют SLM-модулей. Они существуют только внутри тестовой границы и не экспортируются в рабочий код.
|
||||
|
||||
Reference in New Issue
Block a user