# Сегменты Сегмент организует внутреннее содержимое одного модуля по назначению. Он помогает ориентироваться в реализации владельца, но не создаёт новую ответственность или архитектурную границу. ## Место в модели Сегмент появляется только внутри уже определённого модуля: ```text Слой → [Группа*] → Модуль → [Сегмент*] ``` Группа классифицирует модули внутри слоя. Сегмент классифицирует код одного модуля. Ни группа, ни сегмент не являются владельцами. Все файлы, framework-компоненты, состояние, зависимости и lifecycle-код сегмента принадлежат ближайшему модулю. Исключением является только вложенный модуль, который начинает собственную границу владения. ## Назначение Сегмент используется, когда группировка внутренних файлов по назначению упрощает навигацию. Набор и названия сегментов определяет проект. ```text profile/ ├── index.ts # Публичный фасет ├── profile.tsx # Главная реализация ├── components/ # Возможный сегмент ├── hooks/ # Возможный сегмент ├── services/ # Возможный сегмент ├── stores/ # Возможный сегмент ├── types/ # Возможный сегмент └── styles/ # Возможный сегмент ``` Ни один сегмент не создаётся заранее. Модуль может обойтись без сегментов, если помимо публичных фасетов содержит только один главный implementation- или assembly-файл, однозначно выражающий его ответственность. Любая остальная реализация размещается в подходящих сегментах. Если главный файл нельзя определить уверенно, вся реализация остаётся в сегментах. Сегмент: - не имеет самостоятельной ответственности; - не предоставляет публичный API; - не владеет состоянием или жизненным циклом; - не является узлом графа зависимостей; - не импортируется внешним кодом как отдельная архитектурная сущность. Локальный `index.ts` может использоваться во внутренней единице сегмента. Он не превращает эту единицу или сегмент в модульную границу. ## Framework-компоненты Framework-компоненты являются обычным внутренним кодом модуля. Они могут выполнять визуальные и невизуальные роли, включая Provider, Guard или Error Boundary, если используемый фреймворк считает соответствующую сущность компонентом. Помимо опционального главного framework-файла в корне, остальные компонентные единицы размещаются на одном внутреннем уровне относительно модуля. Каталог такой единицы может содержать локальные `styles`, `types`, `hooks`, `tests` и внутренний `index.ts`, но не содержит другие компонентные единицы или вложенные модули. ```text header/ # Модуль ├── index.ts # Публичный фасет ├── header.tsx # Главная реализация └── components/ # Сегмент ├── button-submit/ │ ├── index.ts # Локальная точка входа │ ├── button-submit.tsx │ ├── styles/ │ ├── types/ │ └── hooks/ └── icon.tsx # Соседняя компонентная единица ``` `ButtonSubmit` может рендерить `Icon`, но их файловые области не вкладываются друг в друга. Ограничение относится к файловой структуре, а не к runtime-дереву. Внешний код не импортирует `components/button-submit`. Если компонент нужен снаружи, модуль-владелец реэкспортирует его через собственный публичный фасет. ## Вложенные модули Сегмент может содержать вложенные модули. В отличие от остальных файлов сегмента, каждый вложенный модуль владеет отдельно сформулированной подответственностью и имеет публичный API и границу зависимостей. ```text landing/ # Родительский модуль └── modules/ # Сегмент └── hero/ # Вложенный модуль ├── index.ts # Публичный фасет вложенного модуля ├── hero.tsx # Главная реализация hero └── modules/ # Допустимая модульная рекурсия └── media/ └── index.ts ``` Компонентный каталог не содержит `components` или `modules`. Рекурсивная структурная вложенность допускается только через вложенные модули. Имена `components` и `modules` являются примерами локального стайлгайда, а не обязательными соглашениями SLM. ## Выбор размещения | Ситуация | Решение | |---|---| | Код относится к существующему владельцу и группируется по назначению | Сегмент | | Вспомогательный код нужен только одной компонентной единице | Колоцировать в её локальном каталоге | | Выделена отдельная framework-компонентная единица | Разместить на общем внутреннем уровне модуля | | Код нужен нескольким внутренним единицам модуля | Поднять в ближайший общий сегмент | | Появилась самостоятельная связная подответственность | Создать вложенный модуль | | Файл однозначно является главной реализацией или сборкой ответственности | Допустимо разместить в корне модуля | | Файл не является главным или его роль неоднозначна | Разместить в подходящем сегменте | Размер каталога и количество файлов не определяют модульную границу. Её создаёт только самостоятельная ответственность и назначение нового владельца. ## Связанные правила - [`SLM-SEGMENT-R008`](../rules/registry.md#slm-segment-r008) - [`SLM-MODULE-A004`](../rules/registry.md#slm-module-a004) - [`SLM-MODULE-R020`](../rules/registry.md#slm-module-r020) - [`SLM-MODULE-R021`](../rules/registry.md#slm-module-r021) - [`SLM-NESTED_MODULE-A010`](../rules/registry.md#slm-nested_module-a010)