# Архитектура SLM SLM описывает владение ответственностями внутри одного фронтенд-приложения. Слой определяет роль кода, группа классифицирует модули, модуль владеет ответственностью, а сегмент организует реализацию владельца. ## Владение как основа **Ответственность** — результат или поведение приложения, за которое отвечает один модуль-владелец. Она становится самостоятельной, когда ей нужны собственный публичный контракт, зависимости, состояние или область жизни, а не только внутренняя роль в работе другого модуля. Props, импорты, локальное состояние и lifecycle-код сами по себе этого не доказывают. У каждой самостоятельной ответственности есть ровно один владелец. В SLM владельцем является модуль. Он определяет: - какие возможности доступны внешним потребителям; - от каких других модулей зависит ответственность; - кому принадлежат данные и изменяемое состояние; - когда создаются и уничтожаются долгоживущие ресурсы; - как устроена внутренняя реализация. Каждый файл принадлежит ближайшей модульной границе и реализует ответственность этого модуля. Место выполнения или вид кода не меняют владельца. ## Структурная модель ```text SLM root └── слой ├── модуль │ ├── сегмент │ └── вложенный модуль │ ├── сегмент │ └── вложенный модуль └── группа ├── модуль └── группа └── модуль ``` | Сущность | Назначение | Владеет ответственностью | |---|---|---| | Слой | Классифицирует код по архитектурной роли | Нет | | Группа | Навигационно классифицирует модули внутри слоя | Нет | | Модуль | Владеет одной самостоятельной ответственностью | Да | | Сегмент | Организует внутренности одного модуля | Нет | Вложенный модуль является обычным модулем, размещённым внутри родительского. Он владеет отдельно сформулированной подответственностью и создаёт следующий рекурсивный структурный уровень. Слой и группа находятся снаружи модульной границы. Сегмент находится внутри неё. Framework-компоненты, Providers, Guards, hooks, stores, services и другой внутренний код не являются архитектурными сущностями SLM и принадлежат ближайшему модулю. ## Внутренняя реализация Модуль может содержать любой код, относящийся к его ответственности. SLM ограничивает не набор framework-механизмов, а владение и наблюдаемую структуру: - помимо опционального главного framework-файла в корне, остальные компонентные единицы располагаются на одном внутреннем уровне относительно модуля; - каталог компонентной единицы не содержит другие компонентные единицы или вложенные модули; - рекурсивная структурная вложенность создаётся только вложенными модулями; - помимо публичных фасетов, в корне находится не более одного главного implementation- или assembly-файла; - если главный файл нельзя определить уверенно, реализация размещается в сегментах. Ограничение глубины framework-компонентов относится к файловой организации, а не к runtime-дереву фреймворка. ## Порядок проектирования Архитектурное решение принимается от смысла к структуре: 1. Описать результат, который должен получить пользователь или приложение. 2. Назначить модуль, который отвечает за этот результат. 3. Определить, что модуль делает сам, а что получает от других модулей. 4. Определить, кто использует результат работы модуля. 5. Выбрать [слой](./layers.md) по роли ответственности. 6. Спроектировать публичный API и допустимые [зависимости](./dependencies.md). 7. При необходимости классифицировать модули [группами](./groups.md), организовать внутренний код [сегментами](./segments.md) и выбрать физические пути. Например, Header сам определяет расположение шапки, отображение навигации и состояние мобильного меню. Текущего пользователя он получает от модуля `auth`, а `Button` и `Avatar` — от модулей `ui`. Если удалить Header, авторизация и UI-компоненты останутся нужны приложению, поэтому Header использует их, но не владеет ими. Если ответственность или владелец не определены, файловая структура не может исправить архитектурную неопределённость. ## Логическая и физическая границы Модуль не определяется наличием папки, `index.ts`, framework-компонента или нескольких файлов. Его определяет самостоятельная ответственность и владение её контрактом, зависимостями, состоянием и жизненным циклом. После принятия решения модуль получает отдельную папку и публичные точки входа. Это обязательное физическое представление модульной границы, необходимое потребителям и автоматическим проверкам. Верны обе формулировки: - самостоятельная ответственность требует модульной границы; - отдельная папка сама по себе не доказывает наличие модуля. Пути сопоставляются со слоями, группами, модулями, вложенными модулями и сегментами в стайлгайде или конфигурации конкретного проекта. Имя пути не меняет нормативный смысл сущности. ## Область применения SLM применяется внутри **SLM root** — границы структурной архитектуры одного приложения. Это может быть `src/` или другая область, установленная проектом. Архитектура определяет: - роли слоёв и допустимые межслойные направления; - владельцев самостоятельных ответственностей; - публичные границы модулей; - общий ацикличный граф модулей; - назначение групп и сегментов; - внутреннюю глубину framework-компонентных единиц; - владение состоянием и жизненным циклом ресурсов. SLM не задаёт обязательный поток данных, конкретный framework, фиксированные имена сегментов, правила монорепозиториев или полный файловый стайлгайд. Нормативный смысл терминов находится в [терминологии](../reference/terminology.md). Точные блокирующие требования объявлены только в [реестре правил](../rules/registry.md).