Files
slm-design/docs/reference/validation.md
S. Gromov 691069af8e sync
2026-08-10 09:12:22 +03:00

7.9 KiB
Raw Blame History

Проверка архитектуры

Проверка SLM подтверждает две разные стороны решения:

  • смысловая проверка устанавливает ответственность, владельца и корректность границ;
  • структурная проверка подтверждает, что решение правильно выражено путями, публичными фасетами и зависимостями.

Успешная сборка или корректно отображаемый интерфейс не доказывают архитектурную корректность.

Карточка решения

Перед изменением структуры нужно ответить:

Вопрос Что зафиксировать
Ответственность Какой результат или поведение изменяется как единое целое
Владелец Какой модуль определяет контракт и внутреннюю реализацию
Слой Какой архитектурной роли соответствует ответственность
Потребители Кому действительно нужен публичный API
Зависимости Какие другие владельцы и возможности необходимы
Состояние Кто определяет смысл и допустимые изменения данных
Жизненный цикл Кто создаёт ресурсы, какова их область жизни и очистка
Физическая форма Какими путями и фасетами представлено принятое решение

Если ответственность или владелец не определены, проверка путей откладывается: одинаковая файловая структура может представлять разные архитектурные решения.

Архитектурное ревью

На ревью проверяется смысл кода, который нельзя надёжно вывести из файловой системы:

  • одна ли связная ответственность находится внутри модуля;
  • есть ли у каждой самостоятельной ответственности ровно один владелец;
  • соответствует ли ответственность роли выбранного слоя;
  • не стали ли группа, сегмент или компонент скрытыми владельцами;
  • нужен ли каждый экспорт реальному внешнему потребителю;
  • не раскрывает ли публичный API изменяемые внутренние механизмы;
  • определены ли владелец, область жизни, число экземпляров и очистка каждого ресурса;
  • не переносится ли владение из-за места вызова, провайдера фреймворка или точки маршрута.

Окончательные смысловые требования имеют класс R в реестре правил.

Автоматическая проверка

Проект сопоставляет физические пути с SLM root, слоями, группами, модулями, вложенными модулями, сегментами, фасетами, точками входа app и ресурсами shared. Сопоставление задаётся локальной конфигурацией и не меняет смысл сущностей.

Наличие index.ts само по себе не объявляет модуль. Проверка отличает объявленные корни модулей и их публичные фасеты от локальных точек входа компонентов и других внутренних единиц.

Автоматически проверяются:

  • допустимое направление импортов по матрице слоёв;
  • отдельная папка каждого модуля;
  • доступ к чужому модулю только через объявленные фасеты;
  • отсутствие циклов между модулями;
  • отсутствие прямого внешнего доступа к вложенным модулям;
  • допустимый транзитивный граф исполняемых импортов каждого фасета среды выполнения;
  • динамическое подключение browser-фасета с отключённым SSR.

Каждое правило класса A должно полностью блокировать проверку при нарушении. SLM не требует конкретного lint-инструмента.

Проверка зависимостей

Для каждого внешнего импорта определяется:

  1. Модуль-владелец исходного файла.
  2. Модуль-владелец целевого файла.
  3. Слои исходного и целевого владельцев.
  4. Публичный фасет, через который выполнен импорт.
  5. Отсутствие цикла после добавления связи.

Импорты типов (import type) и реэкспорты проверяются как архитектурные связи. Относительные импорты внутри одного модуля не пересекают модульную границу.

Проверка фасетов

Совместимость фасета определяется всем достижимым исполняемым кодом, а не только его собственным файлом.

Проверка подтверждает:

  • index не достигает client, browser или server;
  • client не достигает browser или server;
  • browser и server не достигают друг друга;
  • browser доступен только через поддерживаемую динамическую границу без SSR;
  • специализированный фасет существует ради реального потребителя;
  • один исполняемый экспорт не дублируется между фасетами.

Импорт типа остаётся архитектурной зависимостью, но не добавляет исполняемый код в среду фасета.

Критерий завершения

Изменение соответствует SLM, когда одновременно выполнены условия:

  • ответственность и единственный владелец определены;
  • роль слоя соответствует ответственности;
  • публичный API минимален и используется всеми внешними потребителями;
  • зависимости разрешены и не образуют циклов;
  • группа и сегменты не подменяют модульную границу;
  • состояние и ресурсы имеют владельца и корректную область жизни;
  • физическая структура однозначно выражает принятое решение;
  • применимые автоматические проверки и архитектурное ревью пройдены.