Files
fontvielle c5695bf0b6 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>
2026-05-14 11:17:11 +03:00

71 lines
3.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.