# PR-5: Каркас `nsd-adapter` — клиент к ИШ НРД (REST), резерв через WS ONYX ## Цель Реализовать транспорт к НРД. Основной канал — Интеграционный шлюз НРД через REST API (ИШ сам подписывает и упаковывает пакеты ЭДО, нам XMLDSig не нужен). Резерв — WS ONYX (с подписью на нашей стороне через `crypto-service`, реализуется когда КриптоПро JCP будет доступен). ## Зависимости - PR-1 (Go-модели). - PR-4 (`m2m-core` — туда инжектим `NSDSender`). - Внешние: установленный ИШ НРД на ВМ, тестовые сертификаты GUEST/TEST3. ## Состояние блокеров Этот PR можно начать **только после**: - НРД выдал тестовые сертификаты GUEST/TEST3 (ГОСТ или RSA); - получен и установлен дистрибутив Интеграционного шлюза; - доступен REST-эндпоинт ИШ (обычно `http://localhost:8080/api/...`). До этого — оставить PR-5 в очереди, не блокировать другие PR. ## Источники - `DOC/Инструкция по передаче эталонного запроса на перевод M2M 08.04 (1).pdf` - `DOC/Презентация MOEX MOST.pdf` - `DOC/instr_podkl_stend_v3.pdf` - `DOC/Ссылки для доступа в тестовые контуры.pdf` ## Состав PR ### 1. REST-клиент ИШ `internal/nsdadapter/igw/client.go`: Методы: - `SendPackage(ctx, channel, packageType, body []byte) (packageID string, err error)` → `POST /api/package/{channel}/file`, тело: ZIP в base64 в JSON. - `GetStatus(ctx, packageID) (Status, err error)` → `GET /api/package/status/{id}`. - `ListIncoming(ctx, channel, since time.Time, packageType string) ([]Package, error)` → `GET /api/package?channel=&date=&type=...`. Поддержка типов пакетов: `#M2MTR`, `#M2MTD`, `#M2MER`, `SUBBR`, `SUBER`, `SUB16`, Assets_investment_*, стандартные квитанции ЭДО. ### 2. Маршрутизация и пакетирование `internal/nsdadapter/router.go`: Функция «доменное сообщение → тип пакета ЭДО + содержимое ZIP». Каждое сообщение M2M упаковывается в ZIP вместе с `config.xml` по Правилам ЭДО — но если ИШ работает в режиме «принимаю XML, сам формирую пакет», достаточно отправить чистый XML и тип пакета. ### 3. Реализация `NSDSender` из PR-4 `internal/nsdadapter/sender.go`: Реализует интерфейс `m2mcore.NSDSender`, использует REST-клиент ИШ. ### 4. Конфигурация `internal/nsdadapter/config.go`: Профили: `guest-gost`, `guest-rsa`, `test3-gost`, `test3-rsa`, `prod-gost`, `prod-rsa`. Каждый профиль: URL ИШ, путь к ключевому контейнеру (на стороне ИШ), таймауты, retry-политика. ### 5. Резервный канал WS ONYX (опц., если время позволяет) `internal/nsdadapter/onyx/`: SOAP-клиент к `OnyxEdoWSService`. Подпись пакета через `crypto-service` (gRPC). Реализуется когда `crypto-service` будет готов (PR-6). В PR-5 — структуры и заглушка с TODO. ### 6. Опрос входящих `cmd/nsd-adapter/main.go`: Минимальный сервис: каждые N секунд (конфиг) делает `ListIncoming` для актуальных типов пакетов, скачивает новые, сохраняет в БД (`incoming_packages` таблица), эмитит событие в `m2m-core` через шину или прямой вызов. ### 7. Интеграционный тест на стенде `internal/nsdadapter/igw/integration_test.go`: - Помечен `//go:build integration`. - Запускает эталонный запрос из `DOC/Инструкция по передаче эталонного запроса на перевод M2M 08.04 (1).pdf` на TEST3. - Проверяет, что приходит `#M2MTD` (от тестового брокера 2) или `#M2MER` (тех. ошибка). - Поднимается только когда `BJ_INTEGRATION_TEST_NSD=1`. ## Требования - Логировать каждое обращение к ИШ (метод, URL, HTTP-статус, package_id, длительность). **Не логировать содержимое пакета** (там могут быть ПДн). - Маскировать ПДн (ФИО, документы) в любых логах. - Без эмодзи. ## Коммит ``` feat(nsd-adapter): REST-клиент ИШ НРД + маршрутизация типов пакетов - internal/nsdadapter/igw/: REST-клиент ИШ (SendPackage, GetStatus, ListIncoming) - internal/nsdadapter/router.go: маршрутизация по типам пакетов ЭДО - internal/nsdadapter/sender.go: реализация m2mcore.NSDSender - internal/nsdadapter/config.go: профили GUEST/TEST3/PROD x ГОСТ/RSA - internal/nsdadapter/onyx/: каркас резервного канала WS ONYX - cmd/nsd-adapter/main.go: опрос входящих пакетов Co-Authored-By: Claude Opus 4.7 (1M context) ``` ## После коммита Обновить `docs/tasks/README.md`: PR-5 — «выполнено».