12 KiB
title, description
| title | description |
|---|---|
| Архитектурная проверка | Блокирующие проверки SLM перед завершением создания, рефакторинга и архитектурного ревью |
Архитектурная проверка
Не считай задачу завершённой только потому, что код компилируется или UI отображается. Проверь архитектурное решение, runtime-цепочку и обязательные тестовые границы.
Проверка владельца
- У каждой ответственности один явный владелец.
- Product state и сценарии принадлежат business-домену.
- Page/route UI-state принадлежит соответствующему composition module.
- Concrete technical service принадлежит infra-модулю.
- Concrete business dependency adapter принадлежит
compositions/business/{domain}. - Provider находится у владельца scope, а не в generic infra-модуле.
- Код не поднят в общий слой или package без реального consumer.
Проверка runtime-цепочки
Для каждого {Domain}Api проследи цепочку сборки:
graph owner
→ per-domain builder
→ dependency adapters + business factory
→ {Domain}Api
→ provider/entry
И отдельно цепочку вызова:
consumer
→ {Domain}Api
→ business scenario
→ {Domain}Deps
→ dependency adapter
→ source/runtime
Если отсутствует хотя бы одно необходимое звено, домен не подключён. Тип будущего API, пустой provider или неиспользуемый builder не заменяет runtime-сборку.
Для каждого route/page entry проверь, что он достигает готового composition module. app не должен реализовывать screen/layout/product wiring самостоятельно.
Проверка business imports
В production-коде business/** не должно быть прямых runtime или type-only imports из concrete runtimes:
infra,compositions,app;- SDK/generated clients;
- SWR/TanStack Query/Apollo;
- Zustand/Redux/MobX/RxJS store runtime;
- React state/effect runtime;
- storage/browser API;
- env/event bus/clock/random implementations.
Разрешены собственные файлы, type-only business contracts, shared без runtime-capabilities и чистые детерминированные библиотеки.
Проверь не только import paths, но и re-export/barrel/helper, который может скрывать запрещённую зависимость.
Проверка deps
- Каждая runtime-capability присутствует в
{Domain}Deps. - Контракт принадлежит business и назван доменным языком.
- В
Depsнет client/SDK/generated operation/StoreApi/query-library types. - Dependency hook возвращает business-owned source result.
- State dependency использует business-owned state port.
- External result имеет
unknown, если требует runtime validation. - Subscription возвращает cleanup.
- Cross-domain API сужен до реально используемых методов.
Проверка adapters
- Для каждой runtime-capability есть явный adapter.
- Adapter находится в
compositions/business/{domain}. - Builder не содержит inline integration logic.
- Adapter не формирует domain error.
- Adapter не выполняет domain normalization.
- Adapter не выбирает business fallback.
- Private adapters отсутствуют в public
index.ts. - Concrete transport imports не протекают в обычные consumer compositions.
Проверка product data
- Page/layout/screen/widget получает product data через
{Domain}Api. - Нет прямого вызова SDK/client/generated operation из потребительской composition.
- Нет product storage access в UI/component/composition service.
- DTO не используется как domain/view contract без business normalization.
- Один источник не имеет параллельного прямого и business-пути.
Проверка ошибок
Для каждого public runtime operation проверь:
- rejected dependency;
- synchronous throw dependency;
undefined/null/empty body;- объект неправильной формы;
- source hook error;
- invalid state/storage value;
- неизвестную runtime-ошибку.
Во всех случаях наружу выходит только domain error со стабильным code. Source error сохраняется в cause, но не становится consumer contract. Technical failure и malformed response нельзя превращать в fallback; fallback разрешён только для валидного доменного исхода.
Не оставляй формулировку «domain error, если контракт это обещает». Business public contract всегда обещает только domain errors.
Проверка state и hooks
- Business владеет domain state model, но не concrete state manager.
- Zustand/Redux/MobX store создаётся adapter-ом, не factory.
- SWR/Query hook создаётся adapter-ом, не business-модулем.
- Dependency hook является non-throwing/non-Suspense и передаёт technical error через business-owned result.
- Business wrapper вызывает dependency hook и возвращает собственный result type.
- Business wrapper преобразует error result и ошибки callbacks в domain errors.
- Store/query library types отсутствуют в public API и
Deps. - Определены creator, scope, количество instances и cleanup.
- Module singleton используется только при явно доказанном application/process lifetime.
- Provider не создаёт ложное впечатление владения instance, созданным на module scope.
Проверка graph
- Per-domain builders собирают только свои фабрики.
- Graph owner назван и соответствует lifecycle.
- Домены создаются в топологическом порядке.
- Runtime-циклы отсутствуют.
- Один и тот же graph не копируется по нескольким providers без обоснования scope.
- Screen/widget не собирает graph самостоятельно.
- Provider value имеет точный тип.
- Нет
Partial<Graph>с unchecked cast к полному graph. - Subscription, timer, socket и другие resources имеют cleanup/dispose.
- Pending operation не может записать stale state после invalidation/unmount без явно принятой политики.
Проверка public API
- Межмодульные импорты идут через реальный public entrypoint.
- Import alias/package export существует физически.
- Group не имеет
index.ts. - Business
index.tsэкспортирует runtime только factory, остальное черезexport type. - Integration module экспортирует builder и необходимые type-only integration input contracts.
- Raw context, raw store, mutable singleton, adapter, generated operation и persistence key закрыты.
- Каждый export имеет реального внешнего consumer.
- Deep imports отсутствуют, включая tests уровня public contract.
Проверка тестов
Business-модуль не завершён без factory-level tests.
Обязательный минимум:
- Форма public API фабрики.
- Happy path каждого runtime method/hook.
- Invalid dependency response.
- Rejected dependency.
- Synchronous throw каждого обычного method/callback/state/lifecycle dependency. Dependency hooks проверяются отдельным non-throwing contract.
- Domain error
codeиcause. - Порядок side effects и остановка после ошибки.
- State transitions и concurrent calls.
compositions/business/{domain} не завершён без assembly tests:
- Factory получает правильные adapters.
- Каждый adapter вызывает нужный runtime source с правильным payload.
- Builder не делает I/O при создании API.
- Cross-domain API передан в правильном виде.
- Private adapters не раскрыты public API.
- Adapter пробрасывает source error без создания domain error.
- Dependency hook не бросает и не использует Suspense/throw-on-error mode.
- Lifecycle cleanup проверен, если есть subscriptions/resources.
Colocated tests обязательны для mappers, normalizers, type guards, domain errors и другой внутренней runtime-safe логики. Они дополняют, но не заменяют factory-level tests. Подробная матрица находится в Тестировании business-модулей.
Проверь наличие исполняемого test script и test runner именно в изменяемом workspace. Root task без локального script не является выполненной тестовой инфраструктурой.
Проверка целостности репозитория
- Все imports разрешаются.
- Все упомянутые modules и public entrypoints существуют.
- Direct runtime packages объявлены в package текущего workspace.
- Старый provider/store/source path удалён после миграции, если больше не используется.
- Нет speculative scaffold с пустым graph, несуществующими доменами или placeholder contracts.
- Template исправлен, если именно он системно создаёт нарушение.
- Выполнены доступные typecheck, tests, lint/build и
git diff --check.
Формат архитектурного ревью
Для каждого нарушения укажи:
- Путь и строку.
- Нарушенный invariant.
- Runtime или maintenance риск.
- Минимальную корректную границу.
- Необходимые tests.
Отделяй обязательное нарушение от необязательного улучшения. Не предлагай большую миграцию, если нарушение можно устранить локально без создания второй архитектуры.
Финальный gate
Перед завершением ответь «да» на все вопросы:
- Архитектурная роль изменения определена?
- Владелец ответственности и state определён?
- Все runtime-capabilities проходят через правильную границу?
- Product data проходит через business API?
- Business вызывает только переданные deps и собственную детерминированную логику?
- Наружу выходят только domain errors?
- Adapters существуют и закрыты?
- Graph и lifecycle определены?
- Public API минимален и разрешим?
- Обязательные tests созданы и запущены?
- Изменение не оставило старый параллельный путь?
Если хотя бы один ответ «нет», задача не завершена.