feat(portal): add api contracts for future ui

This commit is contained in:
igor04091968
2026-06-05 08:18:12 +03:00
parent ec9de0e039
commit 5e6bbd47a1
8 changed files with 1163 additions and 65 deletions
+82 -25
View File
@@ -1,13 +1,19 @@
# DPD/Dioxus Pilot Portal
# DPD Parallel Portal
`detmir-dpd-portal` - параллельный DPD-портал DetMir. Основной режим работает
как полный mirror текущего `detmir-portal`, а экспериментальный компактный экран
оставлен отдельно как preview.
`detmir-dpd-portal` - параллельный gateway-портал DetMir. Он не заменяет
текущий `detmir-portal`, а повторяет его функциональность через отдельный
маршрут `/dpd/`.
## Назначение
Портал не заменяет текущий `detmir-portal`. Он работает рядом с ним и
проксирует все функции текущего портала через отдельный маршрут `/dpd/`:
DPD нужен для безопасной эволюции интерфейса:
- основной HTML-портал `/portal/` остаётся стабильным;
- `/dpd/` работает как полный mirror текущего портала;
- будущий React/Tauri UI сможет использовать те же API-контракты;
- новые UI-решения проверяются без cutover и без дублирования бизнес-логики.
DPD проксирует:
- вкладки;
- API;
@@ -17,22 +23,27 @@
- markdown/download endpoints;
- материалы проверки.
Компактный experimental preview доступен отдельно и показывает:
DPD gateway сохраняет операторский контекст для симметрии с основным порталом:
`X-Remote-User`, `X-Gateway-User`, `X-Forwarded-*`, `User-Agent`, `Referer`,
`Origin`, `Cookie` и `Authorization` передаются в upstream, hop-by-hop
заголовки не передаются. Это нужно, чтобы audit/review/case-действия через
`/dpd/` фиксировались так же, как через `/portal/`.
- главный вывод;
- события безопасности;
- полнота данных;
- риски подразделений;
- очередь проверки;
- связь рисков и активности.
## Архитектурное решение
## Почему отдельный бинарник
Выбран зрелый путь:
Dioxus 0.7 fullstack использует разделение client/server и отдельные web/server
feature flags. Для безопасного первого этапа создан параллельный Rust shell,
который не меняет боевой портал, но уже повторяет его функциональность через
mirror-proxy. Это оставляет место для постепенного переноса UI на
Dioxus-компоненты без риска разъезда данных и API.
```text
detmir-portal Rust backend
|
| stable /api/contracts
v
current HTML UI + DPD mirror + future React/Tauri UI
```
Не используется отдельный экспериментальный UI-фреймворк в production path.
Сначала фиксируются API-контракты, тестируется совместимость и только затем
добавляется новый frontend.
## Запуск
@@ -53,11 +64,57 @@ detmir-dpd-portal \
- `/dpd/` - полный параллельный mirror текущего портала.
- `/dpd/_dpd/health` - health самого DPD gateway.
- `/dpd/preview/` - компактный preview-экран для будущего Dioxus-подхода.
- `/dpd/preview/` - компактный read-only preview-экран.
## Ограничения v0.1
## API-контракты
- DPD gateway не добавляет новые бизнес-сущности;
- без замены текущего портала;
- данные берутся из существующего портала/API;
- preview-экран остается read-only.
Контракты публикует основной `detmir-portal`, а DPD зеркалирует их:
- `/api/contracts`;
- `/api/contracts/openapi.json`;
- `/api/contracts/typescript.d.ts`;
- `/dpd/api/contracts`;
- `/dpd/api/contracts/openapi.json`;
- `/dpd/api/contracts/typescript.d.ts`.
Правило совместимости: изменения API должны быть additive. Клиенты React/Tauri
обязаны игнорировать неизвестные поля и корректно обрабатывать отсутствующие
optional-поля.
## Проверка симметрии
Минимальная проверка на сервере:
```bash
systemctl is-active detmir-dpd-portal detmir-portal nginx --no-pager
curl -sS http://127.0.0.1:8722/_dpd/health
curl -sS -o /dev/null -w 'dpd_index=%{http_code}\n' http://127.0.0.1:8722/
curl -sS -o /dev/null -w 'dpd_reports=%{http_code}\n' http://127.0.0.1:8722/api/reports
curl -sS -o /dev/null -w 'dpd_contracts=%{http_code}\n' http://127.0.0.1:8722/api/contracts
```
Браузерная проверка с ноутбука:
```bash
ssh -o ExitOnForwardFailure=yes -o ServerAliveInterval=15 -o ServerAliveCountMax=3 \
-N -L 18720:127.0.0.1:8720 <GATEWAY_HOST>
detmir-dpd-portal \
--bind 127.0.0.1:18722 \
--upstream-base http://127.0.0.1:18720
DETMIR_PORTAL_SMOKE_URL=http://127.0.0.1:18722/ \
DETMIR_PORTAL_SMOKE_TIMEOUT_MS=70000 \
node scripts/detmir-portal-tabs-smoke.mjs
```
Ожидаемый результат: `ok=true`, все вкладки работают, нет JS/API ошибок,
абсолютные `/portal/...` ссылки в HTML/JS переписаны в `/dpd/...`.
## Ограничения
- DPD gateway не добавляет новые бизнес-сущности.
- DPD gateway не заменяет текущий портал.
- Данные берутся из существующего портала/API.
- Новый React/Tauri UI должен появляться поверх контрактов, а не через
копирование backend-логики.