using System;
using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd;
namespace Ban.Sdaid.Icd.Arch.Tech.Angular
{
/// <summary>
/// ADR-UI-001: Технологический стек фронтенда ICD. Фиксирует фреймворк, подход к
/// компонентам (собственный набор вместо готового UI-kit), вспомогательные пакеты и
/// явный список того, что сознательно не используется.
/// </summary>
public class ADR_UI_001_Stack : IAdrDocument, IFolder<ArchAngularFolder>
{
public string Name => "ADR-UI-001. Технологический стек фронтенда";
public string Description =>
@"Запускается фронтенд ICD (`src-ui`). Нужно зафиксировать **базовый стек** UI: фреймворк,
подход к компонентной базе, вспомогательные пакеты — и явно обозначить, что используется, а что
сознательно **не** включается. Ключевая особенность: компонентную базу строим **свою**, а не берём
готовый UI-kit, с прицелом на переиспользование набора в других проектах.";
public string Version => "1.0";
public string Status => "accepted";
public string[] Comments => new[]
{
"2026-08-11. Принято при разворачивании каркаса фронтенда ICD.",
};
public Type? Supersedes => null;
public static string S1_Context = """
## Контекст и постановка задачи
Фронтенд ICD — тонкий клиент (браузерное веб-приложение), запускается с нуля, наследия нет.
Нужно зафиксировать базовый стек, чтобы дальнейшие решения принимались осознанно, а не по
инерции.
Дополнительное требование, определяющее выбор: компонентную базу (от элементарных кнопок и
полей до крупных таблиц с сортировкой и редактированием ячеек) хотим сделать **своей** и
переиспользуемой в других проектах. Это прямой довод против готового UI-kit как фундамента —
иначе каждый проект-потребитель тянул бы за собой стороннюю библиотеку и её визуальный язык.
""";
public static string S2_DecisionDrivers = """
## Драйверы решения
1. **Актуальность** — новый проект стартует на самой свежей стабильной версии Angular.
2. **Переносимость своего UI-набора** — компоненты должны безболезненно выноситься в другой
проект (целиком или по одному), без завязки на доменный код и без чужой темы.
3. **Контроль над визуалом и API** — свой дизайн-язык и свой контракт компонентов, а не
адаптация под чужую тему.
4. **Минимум зависимостей** — каждая внешняя библиотека несёт цену поддержки; подключаем
только то, что дорого и рискованно писать самим.
5. **Покрытие официальной документацией** — стек опирается на Angular и его CDK, без редких
пакетов.
""";
public static string S3_ConsideredOptions = """
## Рассмотренные варианты
- **A. Готовый UI-kit** (ng-zorro / Angular Material / PrimeNG). Быстрый старт, но навязывает
сторонний визуальный язык и делает будущую библиотеку компонентов обёрткой над чужой
зависимостью — против цели переносимости.
- **B. Собственный набор компонентов на headless-фундаменте `@angular/cdk`.** Свой визуал и
API; CDK закрывает дорогую механику (overlay, a11y, sticky-таблица, virtual-scroll,
drag-drop) без навязывания внешнего вида.
- **C. Собственный набор полностью без зависимостей** (даже без CDK). Максимальная
независимость, но overlay-позиционирование, focus-trap и a11y легко реализовать
некорректно — высокий риск при небольшой выгоде.
""";
public static string S4_DecisionOutcome = """
## Решение
Выбран **Вариант B**: Angular (последний стабильный) + собственный набор компонентов на
`@angular/cdk`, без готового UI-kit.
### Базовые зависимости
| Пакет | Версия | Назначение |
|---|---|---|
| `@angular/*` | `22.x` | Фреймворк. |
| `@angular/cdk` | `22.x` | Headless-примитивы (overlay, a11y/focus-trap, sticky-таблица, virtual-scroll, drag-drop) — фундамент собственных компонентов, без навязанного визуала. |
| `rxjs` | `7.x` | Реактивные потоки: HTTP, мост в сигналы (`toSignal`). |
| `date-fns` | `4.x` | Работа с датами, локаль `ru` (при работе с таймзонами добавляется `date-fns-tz`). |
| `sass` (SCSS) | — | Препроцессор стилей. Дизайн-токены — на CSS custom properties (тема задаётся переменными снаружи, что и делает набор переносимым). |
### Формы
Формы — на **Signal Forms** (`@angular/forms/signals`), а не на Reactive Forms. Фронт строится
signals-first: значения и валидность формы — сигналы, без моста к реактивным потокам. В
актуальной версии Angular это **стабильный публичный API**, так что выбор не противоречит
драйверу стабильности.
### Собственный набор компонентов — принципы переносимости
Компоненты живут в `src-ui/src/app/ui/` (пока **не** отдельная npm-библиотека), но
проектируются так, чтобы выноситься в другой проект без переписывания:
1. Зависимости только «вниз»: Angular, `@angular/cdk`, свои ui-примитивы, дизайн-токены. Ни
одного импорта из доменного/прикладного кода проекта.
2. Ноль доменных знаний: данные — через `input()`/generics, поведение — через
`output()`/колбэки.
3. Стили на дизайн-токенах (CSS custom properties), без хардкода цветов; тема — снаружи.
4. Гранулярность и слабая связность: компонент — своя папка со своим barrel; один компонент не
тянет весь набор.
5. Единый alias и barrel-экспорты (`@ui/*`) — набор перемещается одним движением.
6. Минимум внешних зависимостей, standalone-компоненты.
### Что не используем
- **Готовый UI-kit** (ng-zorro / Angular Material / PrimeNG) как компонентную базу — по
причинам выше.
- **Глобальный store** (NgRx / `@ngneat/elf`). Состояние компонента — через сигналы;
разделяемое — через `@Injectable({providedIn:'root'})`-сервисы с сигналами. Store вводим
только при кейсе, который сервисом не решается.
- **`@ngneat/until-destroy`** — эквивалент нативного `takeUntilDestroyed()` + `DestroyRef`,
внешняя зависимость избыточна.
- **Глобальный event bus** — взаимодействие через сервисы и роутер. Понадобится широковещание
— заведём отдельный ADR.
- **Провайдер анимаций** (`@angular/animations` / `provideAnimations`). Анимации — нативными
CSS-механизмами (`animate.enter` / `animate.leave`) по мере надобности; deprecated-провайдер
в фундамент не тянем.
""";
public static string S5_PositiveConsequences = """
## Положительные следствия
- Полный контроль над визуалом и API компонентов; набор переносим между проектами.
- Сигналы и `takeUntilDestroyed` — нативно, без сторонних пакетов; меньше зависимостей —
дешевле апгрейд Angular.
- CDK снимает самое дорогое и рискованное (overlay, a11y), не навязывая внешний вид.
""";
public static string S6_NegativeConsequences = """
## Отрицательные следствия и компромиссы
- Свой набор компонентов — долгосрочное обязательство: поддержка, a11y, кросс-браузерность,
документация. Окупается при переиспользовании в нескольких проектах; на одном — дороже
готового kit.
- Крупные компоненты (таблица с сортировкой/редактированием, date-picker) пишем сами поверх
CDK — заметный объём разовой работы.
- Без глобального store сложные shared-кейсы (если появятся) пишутся руками через сигналы в
сервисе.
""";
public static string S7_Validation = """
## Проверка
- Каркас `src-ui` собирается и запускается на Angular 22 (standalone, страница-приветствие),
без обращения к глобальному store и без готового UI-kit.
- Первый крупный компонент (таблица) собирается на `@angular/cdk` с сортировкой и режимом
редактирования ячеек, оставаясь независимым от доменного кода.
""";
public static string S8_OpenQuestions = """
## Открытые вопросы / отложено
- **Тестирование** — фреймворк и пакеты не зафиксированы; вероятно `vitest` (идёт с `ng new`).
Решение отдельным пунктом позже.
- **Zoneless** — режим change detection Angular 22; свериться с текущим каркасом и
зафиксировать явно.
- **Вынос набора в отдельную библиотеку** (npm-пакет / registry) — возможная будущая веха;
сейчас набор живёт в `ui/`, но проектируется переносимым.
- **Событийная шина** — вернёмся, если рост числа фич потребует широковещания.
""";
public static string S99_Related = $"""
## Связанные артефакты
- {nameof(Ban.Sdaid.Icd.Vision.IcdVision)} — Видение (тонкий клиент, браузерное веб-приложение).
""";
}
}