using System;
using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd;
namespace Ban.Sdaid.Icd.Arch.Tech.Angular
{
/// <summary>
/// ADR-UI-006: Маршрутизация. Корневой + per-feature lazy-маршруты, единый реестр
/// сегментов (без литералов URL), плоская URL-структура. Гарды доступа — отдельным ADR.
/// </summary>
public class ADR_UI_006_Routing : IAdrDocument, IFolder<ArchAngularFolder>
{
public string Name => "ADR-UI-006. Маршрутизация";
public string Description =>
@"Приложение содержит несколько фич-страниц (ввод, очередь обработки, карты, документы,
администрирование). Нужно зафиксировать, как декларируются маршруты, где живёт реестр имён сегментов
(чтобы не было литералов URL в коде) и какова URL-структура. Механику защиты доступа (гарды) выносим
в отдельный ADR — роли и доступ пока не определены.";
public string Version => "1.0";
public string Status => "accepted";
public string[] Comments => new[]
{
"2026-08-11. Принято перед реализацией страниц; гарды доступа отложены до определения ролей.",
};
public Type? Supersedes => null;
public static string S1_Context = """
## Контекст и постановка задачи
Фич-страниц несколько, и число будет расти. Нужно зафиксировать:
- как декларируются маршруты (один файл против корневой + per-feature);
- где живёт **реестр имён сегментов**, чтобы избежать литералов URL в коде;
- какова URL-структура.
Защита маршрутов гардами (аутентификация, права) зависит от ролей и доступа, которые пока не
заданы (см. `IcdVision`), — выносится в отдельный ADR.
""";
public static string S2_DecisionDrivers = """
## Драйверы решения
1. **Lazy loading** — фичи подгружаются по требованию; стартовый bundle небольшой.
2. **Единый источник имён сегментов** — нет литералов вроде `'/input'` в коде; переименование
URL — одна точка правки.
3. **Плоская структура** (ADR-UI-003) — URL не повторяет навигационную группировку меню.
4. **Декларативность** — маршрут фичи объявляет сама фича.
""";
public static string S3_ConsideredOptions = """
## Рассмотренные варианты
- **A. Один файл `app.routes.ts`** со всеми маршрутами — просто, но тащит код всех фич в
initial bundle и плохо масштабируется.
- **B. Корневой `app.routes.ts` + per-feature `<feature>.routes.ts`, lazy-loaded** — каждая
фича объявляет свои маршруты.
- **C. Группировка маршрутов по разделам меню** (`/admin/users`) — лишняя вложенность в URL и
файлах.
""";
public static string S4_DecisionOutcome = """
## Решение
Выбран **Вариант B**: корневой `app.routes.ts` + per-feature маршруты, lazy-loaded.
### Оболочка и стартовая страница
Оболочка приложения (шапка + рабочая область) — это корневой компонент `App` (ADR-UI-005),
**не** маршрут-обёртка: все страницы рендерятся в его `router-outlet`. Стартовый `''` ведёт на
**главную** (`HomePage`) напрямую. Когда появится режим «без оболочки» (экраны входа) и защита
доступа — layout вынесется в маршрут-обёртку отдельным ADR.
### Корневой `src/app/app.routes.ts`
```ts
export const routes: Routes = [
{ path: BaseRoutes.home, pathMatch: 'full',
loadComponent: () => import('@app/modules/home/pages/home/home').then((m) => m.Home) },
{ path: BaseRoutes.input,
loadChildren: () => import('@app/modules/input/input.routes').then((m) => m.inputRoutes) },
// ... queue / cards / documents / admin
{ path: '**', redirectTo: BaseRoutes.home },
];
```
### Per-feature `<feature>.routes.ts`
Объявляет внутреннюю структуру фичи (список / создание / карточка). Внутренние сегменты — в
реестре фичи, если их больше двух-трёх.
### Реестр сегментов — `src/app/services/router/`
Единый источник имён; классы без префикса (ADR-UI-002):
```ts
export const BaseRoutes = {
root: '/',
home: '',
input: 'input',
queue: 'queue',
cards: 'cards',
documents: 'documents',
admin: 'admin',
} as const;
export const RouteParam = {
packetId: 'packetId',
cardId: 'cardId',
documentId: 'documentId',
} as const;
```
Внутренние сегменты фичи — в `services/router/<feature>-routes.ts` (например
`InputRouteSegments = { list: 'list', new: 'new' }`), когда их несколько.
### URL-структура
- **Плоская**: `/input`, `/queue`, `/cards`, `/documents`, `/admin`.
- **Без префикса групп** навигации — группировка живёт только в меню (ADR-UI-005).
- **Корневой `''`** → главная.
### Правила использования
1. **Никаких литералов URL в коде.** Сборка пути — через `BaseRoutes` / `RouteParam`
(`routerLink`, `router.navigate`).
2. **Внутренние сегменты фичи** — в реестре фичи, не дублируются между маршрутами и
компонентами.
3. **Lazy load обязателен** для фич (несколько страниц или свои `services`/`models`);
одностраничные — через `loadComponent`.
""";
public static string S5_PositiveConsequences = """
## Положительные следствия
- Initial bundle — только оболочка и общие компоненты; фичи грузятся по требованию.
- Реестр сегментов — единая точка правки при переименовании путей.
- Маршрут фичи объявляет сама фича — структура не расползается.
""";
public static string S6_NegativeConsequences = """
## Отрицательные следствия и компромиссы
- URL не отражает навигационную группировку — при необходимости (deep-links) пересмотрим.
- Реестр `BaseRoutes` нужно держать в синхроне с реальными маршрутами — ревью / линт.
""";
public static string S7_Validation = """
## Проверка
- Новая фича добавляется тремя действиями: сегмент в `BaseRoutes` → `modules/<feature>/
<feature>.routes.ts` → подключение через `loadChildren` в `app.routes.ts`.
- В коде нет литералов вроде `'/input'` — `grep` подтверждает.
""";
public static string S8_OpenQuestions = """
## Открытые вопросы / отложено
- **Гарды доступа** — аутентификация и права на маршрутах (защита оболочки, требуемые права
на фиче, стартовый редирект по правам) — отдельным ADR при определении ролей/доступа.
- **Внутренние сегменты фич** — заводятся по мере появления многостраничных фич.
- **Группировка URL по разделам** — не делаем; при необходимости отдельный ADR.
""";
public static string S99_Related = $"""
## Связанные артефакты
- {nameof(Ban.Sdaid.Icd.Arch.Tech.Angular.ADR_UI_003_ProjectStructure)} — Плоская структура модулей.
- {nameof(Ban.Sdaid.Icd.Arch.Tech.Angular.ADR_UI_005_Layout)} — Оболочка приложения и режимы.
- {nameof(Ban.Sdaid.Icd.Vision.IcdVision)} — Роли и доступ (открытый вопрос).
""";
}
}