Files
slm-design/DRAFT/level-3/domains/auth-example.md

97 lines
3.6 KiB
Markdown
Raw Normal View History

2026-07-30 13:22:45 +03:00
# Auth как пример миграции
2026-07-30 13:22:45 +03:00
> Проверочный пример Level 3. Он показывает направление декомпозиции, а не обязательный scaffold.
2026-07-30 13:22:45 +03:00
## Исходная проблема
2026-07-30 13:22:45 +03:00
В более ранней форме SLM business contract Auth и concrete assembly могли находиться отдельно:
```text
business/auth/
├── auth.factory.ts
├── errors/
├── hooks/
├── services/
├── types/
└── index.ts
2026-07-30 13:22:45 +03:00
compositions/business/auth/
├── adapters/
2026-07-30 13:22:45 +03:00
├── create-auth-business.ts
└── index.ts
```
2026-07-30 13:22:45 +03:00
Такая форма отделяет pure business от concrete runtime, но разносит одну предметную область по разным архитектурным местам. Level 3 колоцирует их внутри Domain, не смешивая роли.
## Целевая форма
```text
domains/auth/
├── business/
2026-07-30 13:22:45 +03:00
│ ├── auth.factory.ts
│ ├── errors/
│ ├── lib/
│ ├── ports/
│ ├── services/
│ ├── types/
│ └── index.ts
├── presets/
2026-07-30 13:22:45 +03:00
│ ├── application/
│ │ ├── adapters/
│ │ └── index.ts
│ └── request/
│ └── index.ts
└── react/
├── hooks/
├── providers/
└── index.ts
```
2026-07-30 13:22:45 +03:00
## Разделение обязанностей
2026-07-30 13:22:45 +03:00
| Исходная часть | Назначение в Level 3 |
|---|---|
| `auth.factory.ts`, scenarios, validators, domain errors | `domains/auth/business` |
| SDK, storage и state manager integration | Private adapters выбранного preset |
| Повторяемый browser builder | `domains/auth/presets/application` |
| Request-specific cookies, headers и client | `domains/auth/presets/request` |
| React hooks, provider и domain UI | `domains/auth/react` |
| Page text, redirect и screen outcome | Consumer composition |
2026-07-30 13:22:45 +03:00
## Проверка границ
2026-07-30 13:22:45 +03:00
`authFactory` не импортирует `useAuth`, `'use client'`, SDK или storage. React hook строится поверх готового `AuthApi`, например через framework-neutral `getSnapshot` и `subscribe`.
2026-07-30 13:22:45 +03:00
Нормализация номера телефона может быть public pure business function:
```ts
import {
normalizeAuthPhone,
validateAuthPhone,
} from '@/domains/auth/business'
```
2026-07-30 13:22:45 +03:00
UI использует её для feedback, но `requestPhoneOtp` повторно валидирует значение внутри business scenario.
## Error contract
2026-07-30 13:22:45 +03:00
`AuthBusinessError` остаётся private implementation. Consumer получает только stable contract:
```ts
2026-07-30 13:22:45 +03:00
import {
AUTH_ERROR_CODES,
isAuthError,
} from '@/domains/auth/business'
```
2026-07-30 13:22:45 +03:00
Так React composition может выбрать сообщение или retry behavior по `code`, не зная SDK error, HTTP status или constructor private ошибки.
2026-07-30 13:22:45 +03:00
## Migration order
2026-07-30 13:22:45 +03:00
1. Выделить `business` entrypoint и убедиться, что его transitive graph isomorphic.
2. Перенести concrete runtime в adapters выбранного preset.
3. Оформить повторяемую assembly как `presets/application`.
4. Перенести hooks и Provider в `react`, передавая им готовый API.
5. Сохранить page-specific UI и graph ownership в `compositions`.
6. Добавить factory, adapter, preset и React boundary tests до удаления старого пути.