ADR-UI-006. Маршрутизация

ADR Версия: 1.0 accepted

Приложение содержит несколько фич-страниц (ввод, очередь обработки, карты, документы, администрирование). Нужно зафиксировать, как декларируются маршруты, где живёт реестр имён сегментов (чтобы не было литералов URL в коде) и какова URL-структура. Механику защиты доступа (гарды) выносим в отдельный ADR — роли и доступ пока не определены.

⟨/⟩ Исходник

1. Контекст и постановка задачи

Фич-страниц несколько, и число будет расти. Нужно зафиксировать:

Защита маршрутов гардами (аутентификация, права) зависит от ролей и доступа, которые пока не заданы (см. IcdVision), — выносится в отдельный ADR.

2. Драйверы решения

  1. Lazy loading — фичи подгружаются по требованию; стартовый bundle небольшой.
  2. Единый источник имён сегментов — нет литералов вроде '/input' в коде; переименование URL — одна точка правки.
  3. Плоская структура (ADR-UI-003) — URL не повторяет навигационную группировку меню.
  4. Декларативность — маршрут фичи объявляет сама фича.

3. Рассмотренные варианты

4. Решение

Выбран Вариант B: корневой app.routes.ts + per-feature маршруты, lazy-loaded.

4.1. Оболочка и стартовая страница

Оболочка приложения (шапка + рабочая область) — это корневой компонент App (ADR-UI-005), не маршрут-обёртка: все страницы рендерятся в его router-outlet. Стартовый '' ведёт на главную (HomePage) напрямую. Когда появится режим «без оболочки» (экраны входа) и защита доступа — layout вынесется в маршрут-обёртку отдельным ADR.

4.2. Корневой src/app/app.routes.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 },
];

4.3. Per-feature <feature>.routes.ts

Объявляет внутреннюю структуру фичи (список / создание / карточка). Внутренние сегменты — в реестре фичи, если их больше двух-трёх.

4.4. Реестр сегментов — src/app/services/router/

Единый источник имён; классы без префикса (ADR-UI-002):

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' }), когда их несколько.

4.5. URL-структура

4.6. Правила использования

  1. Никаких литералов URL в коде. Сборка пути — через BaseRoutes / RouteParam (routerLink, router.navigate).
  2. Внутренние сегменты фичи — в реестре фичи, не дублируются между маршрутами и компонентами.
  3. Lazy load обязателен для фич (несколько страниц или свои services/models); одностраничные — через loadComponent.

5. Положительные следствия

6. Отрицательные следствия и компромиссы

7. Проверка

8. Открытые вопросы / отложено

Связанные артефакты

Документы