Frontend (src-ui) — карта кода
Навигатор по реализации frontend в src-ui: на чём построен фронт, как разложен проект, где физически лежит каждый тип артефакта и как запускать dev-сервер. Frontend в ранней стадии: собственный набор ui-компонентов, страница «Ввод данных» (per-page service + маппинг), потребление backend через генерируемый API-клиент. Прочитать ПЕРЕД реализацией UI — заменяет разведку по коду.
1. Фреймворк и окружение
- Angular 22 — standalone-компоненты, signals, zoneless, OnPush по умолчанию, нативный control flow (
@if/@for), новый формат файлов без суффикса.component. - Свой набор ui-компонентов (
src/app/ui/) на@angular/cdk— вместо готового UI-kit; формы на Signal Forms (@angular/forms/signals). Стили — SCSS + токены дизайна--icd-*(см. ADR-UI-001/004/009). Среди прочих:ui/tabs(горизонтальные вкладки),ui/image-viewer(полноэкранный просмотрщик с перелистыванием и вариантами «оригинал/обработано»),ui/camera(захват кадра с камеры через getUserMedia → File; secure context/localhost). Экспериментальныйui/confirm-popover(подтверждение в поповере, CDK overlay) — паттерн пробный, ADR-UI-020 его не ратифицирует, возможна замена. - Пакет —
ban-icd-ui, живёт вsrc-ui/. Имена файлов и артефактов — kebab-case (конвенция Angular), не C#-стиль. - Алиасы путей:
@app/*→src/app,@ui/*→src/app/ui,@api/*→src/app/services/api-clients. - Node современнее системного требуется CLI-версией Angular; ведётся через nvm. Конкретные версии — деталь машины разработчика.
- UI-реализация ссылается на спеку, не наоборот (методология): имена файлов Angular могут отличаться от имён артефактов спеки.
2. Раскладка проекта (src-ui)
| Что | Путь |
|---|---|
| Точка входа (bootstrap) | src/main.ts |
| Корневой компонент | src/app/app.ts (+ app.html, app.scss) |
| Конфигурация приложения (провайдеры) | src/app/app.config.ts (локаль ru, HttpClient, рантайм-конфиг, BASE_PATH, api-сервисы) |
| Рантайм-конфиг (адрес API) | src/app/services/runtime-config/runtime-config.service.ts + public/config.json (ADR-UI-014) |
| Маршруты | src/app/app.routes.ts (+ services/router/base-routes.ts) |
| Оболочка (шапка, меню) | src/app/layout/app-header/ |
| Свой набор ui-компонентов | src/app/ui/<component>/ + ui/tokens, ui/styles, ui/pipes, ui/layout |
| Фичи (страницы) | src/app/modules/<feature>/ — pages/, services/ (per-page), models/ (+ mapper), <feature>.routes.ts |
| Dev-витрина ui | src/app/modules/ui-kit/ (только по URL /ui-kit, не в меню) |
| Генерируемый API-клиент | src/app/services/api-clients/icd/ (импорт @api/icd) |
| Тулинг генерации клиента | src-ui/swagger-codegen/ (generate.py) |
| Глобальные стили | src/styles.scss |
| Статика (favicon и пр.) | public/ |
Примеры фич: modules/input/ — страница «Ввод данных» (pages/data-input/, per-page service; свободная съёмка кадров, ui/camera); modules/queue/ — страница «Обработка очереди» (мастер-деталь: список пакетов + состав выбранного, models/ + UI-модели).
3. Соответствие spec → code
Раскладка спеки (sdaid) и кода (src-ui) различаются — целевой маппинг:
| sdaid (спека) | src-ui (код) |
|---|---|
65_Ui/Pages/<Area>/<Name> (спека страницы) |
modules/<feature>/pages/<name>/ + per-page service |
65_Ui/Components/, Layout/ |
src/app/ui/<component>/, src/app/layout/ |
контракт данных (endpoint из 45_Api) |
сгенерированный клиент @api/icd (services/api-clients/icd/) |
| маппинг API-модели → UI-модель | modules/<feature>/models/<name>.mapper.ts (per-page service / mapper, ADR-UI-012) |
Каждый код-файл реализации несёт ссылку на артефакт спеки sdaid (правило в CLAUDE.md).
API-клиент генерируется, не пишется руками и правится только через перегенерацию из OpenAPI backend
(src-ui/swagger-codegen/generate.py); сгенерированный ApiModule не используем — api-сервисы
регистрируются в app.config.ts, шаблоны работают только с UI-моделями (не с @api/*).
4. Сборка и запуск
cd src-ui
npm install # при первом запуске
npm start # dev-сервер, http://localhost:4200
npm run build # production-сборка в dist/
Требуется версия Node, поддерживаемая Angular CLI; на машине разработчика она активируется до вызова npm/ng.
5. Связь с backend
Фронт обращается к backend через сгенерированный клиент (@api/icd): per-page service
инжектирует api-сервис, дёргает эндпоинт, маппит API-модель в UI-модель (изоляция, ADR-UI-012).
Базовый URL — токен BASE_PATH из рантайм-конфига (config.json → RuntimeConfigService,
ADR-UI-014): одна сборка на все среды, деплой подменяет только config.json.
Генерация клиента (src-ui/swagger-codegen/): python3 generate.py тянет /openapi/v1.json
с запущенного backend и генерирует services/api-clients/icd. Локальная разработка: backend отдаёт
dev-CORS (фронт :4200 ↔ backend :5080).
Потребители:
- «Ввод данных»: свободная съёмка кадров (камера/диск/ссылка, без плана — ADR-007) с накопителем
в пределах лимита (по умолчанию 5); по кадру — просмотр (
ui/image-viewer), пересъёмка (замена файла), удаление, порядок. Сохранение пакета («Сохранить и перейти к следующей») — multipartPOST /api/InputPacketчерез сгенерированныйInputPacketService.apiInputPacketPostForm(payload, files); «сдано за смену» — из ответа сервера. Справочников ввода больше нет. - «Обработка очереди»: список пакетов
GET /api/InputPacket, содержимое кадра для превью/просмотрщикаGET …/frames/{order}/content(variant=normalized— обработанное), обработка кадраPOST …/frames/{order}/normalize, удалениеDELETE …/{id}(мягкое) и.../force(жёсткое) — черезHttpClient(типы — свои UI-модели вmodules/queue/models/).