feat(m2m): сквозной поток с веб-интерфейсами — lk-gateway BFF + admin UI + lk-emulator + mock NSD
Реализован M2-шаг-1: первый рабочий сквозной поток M2M-заявки от ЛК
через нашу систему и обратно, с двумя видимыми веб-интерфейсами.
internal/nsdadapter/mock/:
- mock NSDSender с реалистичным синтетическим Response и асинхронной
эмиссией Decision через настраиваемую задержку (Confirm/Reject/Timeout)
- использует собственный жизненный цикл, чтобы HTTP-контексты вызывающего
не прерывали эмиссию Decision до истечения DecisionDelay
internal/lkgateway/:
- REST по контракту ESIA Finance V1 (POST/GET/PATCH/list claims)
- admin web UI (/admin/, /admin/claims, /admin/claims/{id}, /admin/status):
- дашборд со статусом подсистем (postgres, crypto-service UDS,
nsd-adapter, lk-emulator callback) и счётчиками сделок
- журнал и карточка заявки с историей FSM, ответом НРД, решением
принимающей стороны и последним callback'ом
- in-memory SeedStore с 5 тестовыми клиентами и счетами депо
- фоновый consumeDecisions: подписан на mock.Sender.Decisions(),
применяет ApplyDecision и отправляет PATCH callback в ЛК
internal/lkemulator/:
- имитация ЛК клиента (порт 8083)
- веб-формы: журнал, форма «новая заявка», карточка заявки
- HTTP-клиент к lk-gateway (создание заявки + регистрация callback URL)
- приёмник PATCH callback'ов, локальное хранилище заявок,
автообновление страницы каждые 3 сек
cmd/lk-gateway/main.go и cmd/lk-emulator/main.go — заглушки заменены
на полные сервисы с graceful shutdown.
Сквозной поток проверен smoke-test'ом: подача заявки через форму
эмулятора → создание сделки в lk-gateway → Send в mock NSD →
эмиссия Decision через 3 сек → ApplyDecision → PATCH callback в ЛК →
эмулятор показывает confirmed. Дашборд lk-gateway: Total=1, Подтверждено=1.
make ci зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# internal/lkgateway — BFF слой ЛК + admin web UI
|
||||
|
||||
Реализует REST-контракт ESIA Finance V1
|
||||
(`docs/lk-contract/v1/openapi.yaml`) на стороне Bridge-and-Join-s и
|
||||
admin-веб для оператора.
|
||||
|
||||
## REST API
|
||||
|
||||
- `POST /api/v1/back_office/claims/` — приём заявки от ЛК.
|
||||
Валидирует, собирает `M2MTransferRequest` через
|
||||
`m2mcore.EnrichRequest`, создаёт `m2mcore.Deal`, отправляет в НРД
|
||||
через `m2mcore.NSDSender` (на M2 — mock).
|
||||
- `GET /api/v1/back_office/claims/{id}` — карточка заявки.
|
||||
- `GET /api/v1/back_office/claims` — список с фильтрами
|
||||
(status/investor_id/created_from/created_to/limit/offset).
|
||||
- `PATCH /api/v1/back_office/claims/{id}` — placeholder для callback
|
||||
от внешней системы.
|
||||
- `/healthz` — health.
|
||||
|
||||
## Admin web UI
|
||||
|
||||
- `/admin/` — дашборд: статус системы, счётчики (Total/Confirmed/
|
||||
InProgress/Failed), последние 10 заявок.
|
||||
- `/admin/claims` — журнал всех заявок.
|
||||
- `/admin/claims/{id}` — детальная карточка: история FSM, ответ НРД
|
||||
(`M2MTransferResponse`), решение принимающей стороны
|
||||
(`M2MTransferDecision`), последний callback.
|
||||
- `/admin/status` — детальные проверки: postgres, crypto-service (UDS),
|
||||
nsd-adapter (REST), lk-emulator callback URL.
|
||||
|
||||
## Состав пакета
|
||||
|
||||
- `server.go` — `Server` обвязка: HTTP mux + сервис + фоновый
|
||||
consumeDecisions (читает из `mock.Sender.Decisions()` и обновляет
|
||||
сделки + шлёт callback в ЛК).
|
||||
- `service.go` — бизнес-логика: DTO ↔ доменные сущности m2mcore,
|
||||
оркестрация FSM, отправка callback'ов.
|
||||
- `api.go` — REST endpoints.
|
||||
- `admin.go` — HTML endpoints с шаблонами в `web/templates/`.
|
||||
- `checks.go` — проверки готовности подсистем (postgres, crypto-service,
|
||||
nsd-adapter, callback URL).
|
||||
- `seedstore.go` — in-memory `m2mcore.FansyStore` с 5 тестовыми
|
||||
клиентами и счетами депо (соответствует
|
||||
`docs/fansy-contract/v1/examples/seed-data.sql`).
|
||||
- `types.go` — DTO под OpenAPI.
|
||||
- `http_util.go` — JSON-хелперы.
|
||||
|
||||
## Конфигурация (cmd/lk-gateway/main.go, ENV)
|
||||
|
||||
| Переменная | По умолчанию | Назначение |
|
||||
|---|---|---|
|
||||
| `BJ_HTTP_ADDR` | `:8080` | Адрес HTTP |
|
||||
| `BJ_M2M_SENDER` | `MC0079200000` | DeponentCode отправителя в M2M Header |
|
||||
| `BJ_M2M_RECEIVER` | `MC0010300000` | DeponentCode получателя |
|
||||
| `BJ_DSN` | — | PostgreSQL DSN (M2-шаг-3, пока пусто = in-memory) |
|
||||
| `BJ_CRYPTO_SOCKET` | `/run/bj/crypto.sock` | UDS для crypto-service |
|
||||
| `BJ_NSD_ADAPTER_URL` | — | URL nsd-adapter HTTP (пусто = mock) |
|
||||
| `BJ_LK_CALLBACK_URL` | — | URL ЛК для PATCH callback'ов (пусто = эмулятор регистрирует свой) |
|
||||
| `BJ_NSD_PROFILE` | `demo (mock NSD)` | Имя профиля (отображается в admin) |
|
||||
| `BJ_CRYPTO_PROVIDER` | `stub` | Провайдер криптографии в admin-статусе |
|
||||
|
||||
## Что подключается в следующих шагах
|
||||
|
||||
- **M2-шаг-3**: pgx-репозиторий → миграция
|
||||
`migrations/m2m-core/001__deals.sql` уже готова.
|
||||
- **M3**: реальный `nsd-adapter` вместо mock — выставить
|
||||
`BJ_NSD_ADAPTER_URL` и реализовать в nsd-adapter поллер,
|
||||
отправляющий Decision не через канал mock, а через шину.
|
||||
- **M4**: `admin-ui` v2 на React + раздел «Сертификаты КриптоПро»
|
||||
для обновления публичных сертификатов через UI.
|
||||
Reference in New Issue
Block a user