1f44c1a5bb
Поверх ручного бронирования — информационный слой (достаточность судит оператор). M1 покрытие: coverage.ts (растровое Monte-Carlo % покрытия заявки, чистые функции + coverage.test.ts), CoveragePanel (живой % + бар), слой coverage на карте (drawCoverage, union контуров, клип по заявке). M2 эргономика: сортировка списка по вкладу в покрытие (жадный маргинальный прирост), по крену; колонка «Вклад» (+N%). M3 конфликты: бейдж держателя BUSY-слота (заявка + важность) из holders в SlotDTO. Выбор полосами (TASK_slot-strip-selection it.1): slotStrips.ts (groupStrips — same-roll цепочки по-КА, ε=0.01 с якорным креном, тотальный порядок) + slotStrips.test.ts; toggleStripSelection в slotSelection.ts; чип «полоса ×N» в строке, рельс по StripId в сортировке «время», подсветка полосы при наведении. Физику выполнимости не дублируем на фронте — это backend validate (it.2). Смежный баг: anchorIndexRef (якорь Shift-выбора) сбрасывается при смене видимого набора (фильтры/окно суток), не только сортировки.
pcp-tgu-ui-service
Фронтенд «ТГУ — Операции». Сервис собран с нуля на чистой базе исходного
pcp-tgu-ops-ui (React + Vite, своя тёмная тема), в которую добавлены только две
вещи с платформы NStart:
- Авторизация — headless-ядро
@nstart/auth(New Start ID / Keycloak): токен, login, logout, refresh. Без@nstart/ui— UI-компоненты библиотеки (ProfilePage/UserPanel) намеренно не подключены, экраны ТГУ остаются на своём UI. - Сборка и деплой — платформенный контракт: hardened
Dockerfile(non-root, healthcheck), runtime-config (config.jsизAPP_*),docker-bake.hcl,.gitlab-ci.yml(build → trivy/semgrep → push в registry),nginx.conf.
В отличие от pcp-tgu-ops-ui-template, здесь нет демо-страниц шаблона, @nstart/ui,
Tailwind, i18n и борьбы тем — только рабочий ТГУ + auth + контур сборки/деплоя.
Авторизация (headless)
- Режим выбирается переменной
authMode(anonymous|new-start-id). anonymous(дефолт): приложение открывается сразу, токена нет, заголовокAuthorizationне добавляется — поведение как у исходного сервиса.new-start-id: вход редиректом на New Start ID; токен подставляется в каждый запросsrc/api/*через мостapiFetch+AuthTokenBridge. В шапке появляется кнопка «Выйти».- Конфиг входа берётся из
src/config/env.ts(runtimeAPP_*имеют приоритет над buildVITE_*).
Конфигурация окружения
| Назначение | DEV (npm run dev) |
PROD (Docker) |
|---|---|---|
| источник | .env (VITE_*) |
APP_* контейнера → config.js |
| api | VITE_API_URL |
APP_API_URL |
| режим auth | VITE_AUTH_MODE |
APP_AUTH_MODE |
| New Start ID | VITE_NEW_START_ID_* |
APP_NEW_START_ID_* |
Доступ к приватному реестру @nstart/*: scope @nstart:registry=... должен быть в
~/.npmrc (или в конфиге CI-раннера). Проектный .npmrc задаёт только
min-release-age=7.
Запуск
cp .env.example .env # режим anonymous, открывается сразу
npm install # нужен доступ к repo.nstart.cloud (scope @nstart)
npm run dev # http://localhost:5174
npm run build # tsc -b + vite build
npm run test # vitest
Прод-прокси (осталось настроить)
В nginx.conf активный /api/ — заглушка (127.0.0.1:8000), а
блоки pcp-* закомментированы (зеркало server.proxy из vite.config.ts).
Подставьте реальные UPSTREAM_* кластера и раскомментируйте, либо вынесите
маршрутизацию на gateway/ingress.