- docs/architecture/plan.md — полный план проекта (архитектура, стек, SLA, регуляторика, Реестр ПО, roadmap M1–M5, открытые вопросы и решения). - docs/tasks/README.md — индекс задач и инструкция запуска для Claude Code на dev-ВМ. - docs/tasks/PR-1-go-models-m2m.md — Go-модели M2M, парсер windows-1251, NSDDateTime, round-trip тесты на эталонах. - docs/tasks/PR-2-fansy-ddl.md — DDL принимающей БД для команды Fansy (контракт данных, ETL-требования, словарь полей, тестовые данные). - docs/tasks/PR-3-lk-openapi.md — OpenAPI контракт lk-gateway по ESIA Finance API V1, для синхронизации с командой ЛК. - docs/tasks/PR-4-m2m-core-skeleton.md — FSM сделки, репозиторий, идемпотентность по GUID, метрики SLA. - docs/tasks/PR-5-nsd-adapter-skeleton.md — REST-клиент ИШ НРД, маршрутизация типов пакетов (M2MTR/M2MTD/M2MER/SUBBR/SUBER/SUB16). - docs/tasks/PR-6-crypto-service-skeleton.md — gRPC-каркас Java-сервиса криптографии (КриптоПро JCP, UDS, Provider-абстракция). С этого коммита дальнейшая разработка идёт на dev-ВМ через запущенный там Claude Code. Промпты PR-1..PR-3 готовы к параллельному запуску; PR-4 после PR-1; PR-5 и PR-6 ждут поставку артефактов (ИШ НРД, сертификаты, КриптоПро JCP). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
95 KiB
План: Сервис M2M (НРД) — связующий модуль брокера, Реестр российского ПО
Краткий итог на одной странице
┌──────────────────────────────────────────────────────────────────────────────┐
│ ЧТО ДЕЛАЕМ: Внутренний модуль брокера для M2M-перевода ЦБ через НРД (MOST) │
│ КОМУ: сначала — нашему заказчику; потом — тиражируется другим брокерам │
│ СТЕК: Go (ядро) + Java (crypto-service на КриптоПро JCP) + React (admin-ui) │
│ ОС/СУБД: РЕД ОС 7.3 (целевая) + PostgreSQL Pro Certified │
│ ДЕПЛОЙ: одна ВМ внутри контура, docker-compose (без k8s) │
│ КАНАЛ К НРД: Интеграционный шлюз (REST) — основной; ONYX — резерв │
│ ВНЕШНИЕ: ЛК ESIA Finance (через эмулятор сейчас); Fansy → fansy-store │
│ КРИПТО: КриптоПро CSP/JCP, класс СКЗИ КС1; подпись операторов — серверная │
│ SLA: 5 мин/этап (старт) → 2 мин/этап (цель); таймаут MOST: 10→5 мин │
│ ДЕДЛАЙН ПРОДА: 01.09.2026 (124-ФЗ + Указание ЦБ) │
│ РЕЕСТР ПО: ПП-1236, заявка на M5; стек и архитектура — соответствуют │
└──────────────────────────────────────────────────────────────────────────────┘
Архитектура одной картинкой
ВМ внутри контура брокера (Astra Linux SE)
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ ┌──────────────┐ REST (ESIA Finance API V1) ┌────────────────────┐ │
│ │ lk-emulator │ ─────────────────────────────► │ lk-gateway │ │
│ │ (Go + HTMX) │ ◄─ callback статусов ────────── │ (Go) │ │
│ └──────────────┘ └─────────┬──────────┘ │
│ (заглушка ЛК клиента, пока ЛК ESIA Finance не готов) │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ admin-ui ◄─── WebSocket / REST ───────────────│ m2m-core │ │
│ (React) │ FSM + SLA-метрики │ │
│ • журнал │ идемпотентность │ │
│ • ручное согласование │ по GUID │ │
│ • сертификаты └────┬─────────┬──────┘ │
│ • уведомления │ │ │
│ • SLA-дашборд ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ fansy- │ │ notify │ │
│ │ store │ │ (Go) │ │
│ │ (PG Pro) │ │ plugins: │ │
│ │ ◄─ ETL │ │ smtp, │ │
│ │ команда │ │ ya360, │ │
│ │ Fansy │ │ webhook, │ │
│ └──────────┘ │ ws-push │ │
│ └──────────┘ │
│ ▲ │
│ gRPC по UDS │ │
│ ┌──────────────────────┐ ┌──────────┴──────────┐ │
│ │ crypto-service │ ◄────────────────│ nsd-adapter │ │
│ │ Java + КриптоПро JCP │ │ (Go) │ │
│ │ • XMLDSig подпись │ │ ┌──────────────────┐ │ │
│ │ • проверка входящих │ │ │ ИШ REST основ. │ │ │
│ │ • подпись операторов │ │ │ WS ONYX резерв │ │ │
│ │ (КС1) │ │ │ ФШ fallback│ │ │
│ └──────────────────────┘ │ └────────┬─────────┘ │ │
│ └──────────┼───────────┘ │
│ │ │
└───────────────────────────────────────────────────────┼────────────────────┘
│ HTTPS / mTLS
▼
┌────────────────────────┐
│ ИШ НРД (на нашей ВМ) │
│ REST: /api/package/… │
└───────────┬────────────┘
│ ЭДО НРД (подпись делает ИШ)
▼
┌────────────────────────┐
│ Сервис MOEX MOST / │
│ WS ONYX gost-*.nsd.ru │
└────────────────────────┘
Хранилища на ВМ: PostgreSQL Pro Certified (m2m-core, fansy-store, аудит, конфиги), MinIO (эталоны подписанных XML).
Поток одной заявки end-to-end (донор)
ИНВЕСТОР ЛК (ESIA lk-gateway m2m-core fansy-store crypto-svc nsd-adapter ИШ НРД → MOST → Брокер 2
Finance/
эмулятор)
│ │ │ │ │ │ │ │ │ │
│ заявление │ │ │ │ │ │ │ │ │
├──подпись──►│ │ │ │ │ │ │ │ │
│ │ POST /claims │ │ │ │ │ │ │ │
│ ├─────────────►│ │ │ │ │ │ │ │
│ │ │ verify sig │ │ │ │ │ │ │
│ │ ├───────────────────────────────────────►│ │ │ │ │
│ │ │ enqueue │ │ │ │ │ │ │
│ │ ├───────────►│ │ │ │ │ │ │
│ │ │ │ enrich │ │ │ │ │ │
│ │ │ ├────────────►│ │ │ │ │ │
│ │ │ │ build XML │ │ │ │ │ │
│ │ │ │ M2MTransferRequest │ │ │ │ │
│ │ │ ├──── send via ИШ ─────────────────────►│ │ │ │
│ │ │ │ (ИШ сам подписывает пакет ЭДО) │ │ │
│ │ │ │ │ │ ├──#M2MTR──►│ │ │
│ │ │ │ │ │ │ квитанция ЭДО │ │
│ │ │ │ │ │ │◄──────────┤ │ │
│ │ │ │ WAIT (≤10→5 min) │ │ │ → Брокер 2 │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ │ │ #M2MTD (подтверждение от Брокера 2) │
│ │ │ │ │ │ │◄──────────┤◄───────┤◄────────┤
│ │ │ │ verify sig +│ │ │ │ │ │
│ │ │ │ apply Decision │ │ │ │ │
│ │ │ ├ → notify (e-mail + Yandex Messenger + WS) │ │ │
│ │ callback │ │ │ │ │ │ │ │
│ │◄─────────────┤ │ │ │ │ │ │ │
│ статус ОК │ │ │ │ │ │ │ │ │
│◄───────────┤ │ │ │ │ │ │ │ │
│ │ │ │ ждём SUB16 (черновики 16-х поручений) для депозитария │ │
│ │ │ │ │ │ │◄── #SUB16 ─────────────────── │
│ │ │ │ → передать в депозитарную систему / показать в admin-ui │ │
Ветка TIMEOUT: если Decision не пришёл за 10→5 мин — MOST сам шлёт Transfer_reject (#SUBER) → FSM в Rejected.
Roadmap M1–M5 (визуально)
2026
нед: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
├───────────────┤
M1: │ Каркас+стенды│
│ • моно-репо │
│ • XSD→Go │
│ • ИШ на ВМ │
│ • crypto-svc │
│ • контракт ЛК │
│ • DDL fansy │
├───────────────────────┤
M2: │ Сквозной донор TEST3 │
│ • lk-emulator v1 │
│ • FSM донор │
│ • #M2MTR/#M2MTD │
│ • метрики SLA │
├───────────────────────┤
M3: │ Реципиент+admin-ui v1 │
│ • Decision исх │
│ • Handbook+Participant│
│ • SUB16, SUBBR/SUBER │
│ • Справка о расходах │
│ • роли, сертификаты │
├───────────────┤
M4: │ Ручное+notify │
│ • manual-appr │
│ • smtp+ya360 │
│ • plug-ins │
│ • совм.с Fansy│
├───────────────────────┤
M5: │ ИБ+нагруз+Реестр+ПРОД │
│ • 57580 аудит │
│ • k6 SLA 2 мин │
│ • заявка в Реестр ПО │
│ • ПСИ на промконтуре │
└───── 01.09.2026 ──────┘
ДЕДЛАЙН (124-ФЗ)
Маппинг сообщений и каналов (одна таблица)
| Этап | Тип пакета НРД | Кто формирует | Кто подписывает | Канал |
|---|---|---|---|---|
| Заявление от инвестора | (внутренний JSON ESIA Finance) | ЛК клиента / эмулятор | ЛК | REST → lk-gateway |
| Запрос на перевод M2M | #M2MTR (M2MTransferRequest) |
m2m-core |
ИШ НРД | ИШ REST |
| Тех.ответ НРД на запрос | #M2MER (M2MTransferResponse) |
НРД | НРД | ИШ → nsd-adapter |
| Решение принимающего | #M2MTD (M2MTransferDecision) |
Брокер 2 / мы (если реципиент) | ИШ | ИШ |
| Авто-отказ по таймауту | #SUBER (Transfer_reject) |
MOST автоматически | НРД | ИШ → нам |
| Черновики 16-х поручений | #SUB16 |
НРД | НРД | ИШ → нам → депозитарий |
| Справка о расходах | Assets_investment_account_transfer_details |
Брокер 1 | ИШ | ИШ |
| Статус справки | Assets_investment_details_status |
Брокер 2 | ИШ | ИШ |
| Действие оператора в admin-ui | внутр. подпись | оператор | crypto-service серверной ЭП |
внутри ВМ |
Готовность по Реестру российского ПО (ПП-1236) — матрица
Критерий ПП-1236 Статус
───────────────────────────────────────────────────── ──────────────────
1. Российский правообладатель, инокапитал ≤ 50% ⚠ проверить ЕГРЮЛ
2. Исключительное право — у правообладателя ⚠ договоры с разрабами на M1
3. Свободная гражданская реализация в РФ ✓ ОК
4. Выплаты за рубеж < 30% выручки ✓ нет иностр. лицензий
5. Не содержит гостайны ✓ ОК
6. Класс ПО (02.13 СЭД + 02.09 финсектор) ⚠ уточнить на M5
7. Исходники и сборки в РФ ✓ git.zetit.ru
8. Техподдержка в РФ ✓ M5
9. Документация на русском ✓ закладываем с M1
10. Совместимость с реестровой ОС (Astra/РЕД) ✓ M2 (CI на Astra)
СТЕК (всё в Реестре или open-source upstream):
ОС: РЕД ОС 7.3 (целевая) ✓
СУБД: PostgreSQL Pro Certified ✓
JDK: Liberica / Axiom JDK ✓
СКЗИ: КриптоПро CSP/JCP, КС1 ✓
Уведомления: Yandex 360 + smtp + WS ✓
Прочее: Go, MinIO, NATS — open-source ✓
Старт работ — первая неделя M1
Репозиторий: https://git.zetit.ru/zuevav/Bridge-and-Join-s (РФ-хостинг, основной).
Среда разработки — выделенная ВМ заказчика (dev-стенд) на целевой ОС (Astra Linux SE 1.7+ или РЕД ОС 7.3). Решение: разрабатываем сразу на «живой» машине, чтобы не было разрыва между dev и прод-средой, и чтобы КриптоПро/ИШ/тестовые сертификаты НРД жили в одном защищённом контуре. На эту ВМ ставится Claude Code CLI, разработка идёт там же.
Подготовка dev-ВМ (день 1–2, до старта Трека А)
| Что | Зачем |
|---|---|
| ОС: РЕД ОС 7.3 | Целевая ОС. На dev-этапе — бесплатная редакция РЕД ОС («Свободная»), без сертификата ФСТЭК; одну сертифицированную лицензию закупаем к M3-M4 для целевого stage-стенда |
Учётные записи: dev (без sudo по умолчанию), admin (sudo) |
Минимизация прав; разработка под dev, обслуживание — под admin |
| Сетевая сегментация: dev-ВМ в отдельном VLAN с доступом наружу только к whitelist (git.zetit.ru, gost-.nsd.ru, rsa-.nsd.ru, registry.npmjs.org/proxy, proxy.golang.org/proxy, anthropic.com для Claude Code) | Ограничение поверхности, контроль исходящего трафика |
| Прокси / NAT с журналированием | Аудит исходящих соединений (требование 57580) |
| Установлено: Go 1.23+, JDK 21 (Liberica), Docker/Podman, docker-compose, Git, Make, jq, xmlstarlet | Базовый dev-набор |
| Установлено: КриптоПро CSP + JCP (когда лицензия будет получена) | Для crypto-service |
| Установлено: ИШ НРД (когда дистрибутив получим) | Для интеграционного канала |
| Установлено: Claude Code CLI | Разработка в репо, доступ к gpu/контурам не требуется |
Доступ: git.zetit.ru — SSH-ключ dev пользователя; push в основной репо |
Чтобы коммиты шли напрямую |
| Доступ: тестовые сертификаты GUEST/TEST3 | Работа со стендами НРД |
Бэкап: БД и /etc ежедневно на отдельный том |
Безопасность работы |
| Ресурсы dev-ВМ: 8 vCPU / 16 GB RAM / 200 GB SSD | Запас на полный стек: Go-сервисы, Postgres, MinIO, JVM (crypto-service + ИШ НРД), admin-ui dev-server, Claude Code, CI-раннер на той же ВМ, e2e-тесты с Playwright (Chromium), параллельная сборка/линтер, место под логи и эталонные XML в MinIO. Прод-ВМ — отдельно, конфигурируется к M3-M4. |
Безопасность работы Claude Code на «живой» машине
- Запуск Claude Code только под
dev(без sudo). Если нужно sudo (установка пакетов) — отдельная сессияadminвручную, не через Claude Code. - Ограничения файловой системы: рабочая директория = клон репо в
/srv/dev/Bridge-and-Join-s. Нет доступа к/home/admin,/etc/cryptopro, контейнерам ключей. - Закрытые ключи КриптоПро и сертификаты хранятся в отдельной директории
/var/cryptopro/keys/, владелецcrypto:crypto, mode0700, доступ только изcrypto-serviceчерез JCP. Claude Code и dev-пользователь туда не ходят. .claude/settings.jsonв репо: разрешённые директории — только корень репо; запрет командrm -rf,dd, доступ к/etc/,/var/cryptopro/,/etc/ipsec.d/.- CI и сборки — отдельный раннер, не на dev-ВМ. Прод-сборки и подпись релизов — на изолированной build-ВМ.
- Журналирование действий: shell history
devпользователя пишется с timestamp; журнал работы Claude Code сохраняется в~/.claude/logs/и регулярно архивируется. - Сетевой трафик Claude Code наружу (anthropic.com) согласован с ИБ заказчика; если сегмент закрытый — Claude Code запускается только в момент когда нужен (не всегда), либо через корпоративный исходящий прокси с логированием.
- Никаких ПДн в репо (пример заявления для эмулятора — синтетические данные).
Параллельно три трека:
Трек А — Код (наша команда, день 1–5)
- Проинициализировать структуру моно-репо:
cmd/,internal/{m2m-core,nsd-adapter,lk-gateway,lk-emulator,notify,fansy-store}/,services/crypto-service/(Java),web/admin-ui/,docs/,deploy/docker-compose/,migrations/. go.mod,Makefile,.golangci.yml, базовый CI наgit.zetit.ru(lint + test, раннеры — на ВМ заказчика).- Сгенерировать Go-модели из XSD (
DOC/M2MSchemas_260408/) с (de)serializer windows-1251, кастомнымNSDDateTimeTypeи валидатором pattern (ReferenceIdM2M[A-Z0-9]{13}, ISIN, ИНН, DeponentCode, IIAContractTypeT12|T03). - Round-trip тесты на эталонах
DOC/Эталонные сообщения/*.xmlиDOC/Примеры/*.xml. - README на русском.
Трек Б — Контракты для смежных команд (день 1–7)
- DDL
fansy-storev0 вdocs/fansy-contract/v1/ddl/+data-dictionary.md+etl-requirements.md→ отправить команде Fansy на согласование. Это разблокирует их ETL. - OpenAPI
lk-gatewayv0 по контракту ESIA Finance API V1 (/api/v1/back_office/claims/...) → отправить команде ЛК как точку синхронизации.
Трек В — Заказчик, фоном 2–4 недели
- Запросить у НРД дистрибутив Интеграционного шлюза + ставить на тестовую ВМ.
- Инициировать выпуск тестовых сертификатов GUEST и TEST3 (ГОСТ + RSA).
- Получить лицензию и дистрибутив КриптоПро CSP + JCP под РЕД ОС 7.3 (целевая).
- Юр-проверки для Реестра ПО: ЕГРЮЛ правообладателя (доля иноучастия ≤ 50%), договоры с разработчиками на отчуждение исключительного права.
Definition of Done первой недели
- Структура репо в
git.zetit.ru/zuevav/Bridge-and-Join-sинициализирована, CI зелёный. - Все 6 типов M2M-сообщений десериализуются/сериализуются в windows-1251 без потерь, эталоны проходят.
- DDL
fansy-storev0 отправлен команде Fansy. - OpenAPI-контракт
lk-gatewayотправлен команде ЛК ESIA Finance. - Заявки заказчика поданы: ИШ, сертификаты GUEST/TEST3, КриптоПро, юр-аудит.
Контекст
Репозиторий — green-field (только документация в DOC/). Задача — построить внутренний связующий модуль брокера для обмена с НРД сообщениями о переводе ценных бумаг (M2M, ЭДО НРД).
Существующий ландшафт у заказчика:
- ЛК клиента — уже есть. Инвестор сам формирует и подписывает заявление через внутреннюю подсистему ЛК. Наш сервис получает уже подписанное заявление через API ЛК клиента. Свой фронт инвестора не делаем.
- Fansy (учётная система депозитария) — система-источник по счетам, реквизитам, остаткам. Сам ETL Fansy → БД делает ДРУГАЯ команда разработки в автоматизированном режиме. Наша зона: спроектировать принимающую БД (схема, индексы, миграции, исходя из требований документации НРД к данным M2M), согласовать контракт с командой Fansy и передать им перечень и структуру наших таблиц, читать и анализировать эти данные. Сам процесс выгрузки в наш скоуп не входит.
- Договор ЭДО с НРД подписан, лицензии КриптоПро / VipNet есть.
- Стек: Go (бэкенд) + Java-sidecar для XMLDSig по ГОСТ (см. ниже).
- Развёртывание: одна ВМ внутри контура компании (не k8s; docker-compose или systemd-юниты).
- Цель — Реестр российского ПО (ПП РФ № 1236).
Поток (Схема M2M от НРД.pdf): инвестор инициирует и подписывает в ЛК → ЛК передаёт заявление в наш сервис → мы валидируем, обогащаем из Fansy, формируем M2MTransferRequest, подписываем и шлём в НРД → принимаем M2MTransferResponse (тех. ответ) → ждём M2MTransferDecision от встречного брокера (или сами формируем, если мы сторона-реципиент) → закрываем сделку, сообщаем ЛК и депозитарию.
SLA и регуляторные сроки
- Стартовое SLA: ≤ 5 минут на каждый этап (приём от ЛК, обогащение из
fansy-store, отправка в НРД, обработка ответа, обработка Decision, передача в ЛК/депозитарий). - Целевое SLA: ≤ 2 минуты на этап без переписывания архитектуры — за счёт прогрева кэшей справочников, тёплого пула SOAP/HTTP-соединений, event-driven обработки, индексов БД.
- Регуляторный таймаут MOST «нет ответа от Брокера 2»: на старте — 10 минут, целевой — 5 минут. По истечении сервис MOST формирует автоматический
Transfer_reject.xml(тип пакетаSUBER) — это делает MOST, мы только отслеживаем тайминг и обрабатываем входящий отказ как штатную ветку FSM. - Регуляторный дедлайн прод-релиза — 01.09.2026. Вступают в силу Федеральный закон № 124-ФЗ от 23.05.2025 и Указание Банка России о проведении операций по зачислению ЦБ на счёт депо без поручения депонента (изменения п.5 ст.7 39-ФЗ «О рынке ценных бумаг»). На этот срок закладываем M5.
Проектные следствия:
- Очередь на каждый этап (in-memory worker pool на старте → внешняя шина при росте) с метриками длительности этапа (Prometheus histograms
m2m_stage_duration_seconds). - SLA-budget alerting: при > 80% бюджета — нотификация оператору.
- Идемпотентность по GUID на всех точках, чтобы повторы (ретраи в SLA-окне) не порождали дубли.
- Сначала синхронная in-process архитектура (быстрее всего и проще держит 2 минуты), внешняя шина — только если этапы выйдут на разные ВМ.
Криптография: Go + ГОСТ — пересмотренный план
В Go нет зрелой реализации XMLDSig по ГОСТ Р 34.10-2012 / 34.11-2012, поэтому криптография изолирована в отдельный сервис crypto-service на Java + Apache Santuario с ГОСТ-патчем. gRPC через Unix Domain Socket (минимальная задержка — критично для SLA).
Уточнение по результатам ре-аудита. Основной канал отправки — ИШ через REST API, и ИШ сам подписывает пакет ЭДО на стороне НРД-шного софта. Поэтому для основного потока внешний XMLDSig нам не нужен. crypto-service остаётся обязательным для:
- проверки подписи входящих квитанций ЭДО, ответов НРД, сообщений от брокеров;
- подписи действий оператора в ручном согласовании (серверная подпись от имени оператора);
- резервного канала через WS ONYX напрямую — там подпись/упаковка пакета целиком на нашей стороне;
- криптографических проверок целостности эталонных архивов в MinIO.
Решено: используем КриптоПро. В crypto-service — КриптоПро JCP на JVM, КриптоПро CSP на ВМ. Архитектурно сохраняем Provider-абстракцию (Валидата / VipNet / иное), чтобы при тиражировании другой компании можно было подключить иной провайдер без правки бизнес-логики, но реализация на M1 — только КриптоПро. Для проверки совместимости с эндпоинтами НРД (исторически ГОСТ-контуры МосБиржи — Валидата) — отдельная задача проверки на стенде GUEST/TEST3 в M1.
Целевая архитектура (один моно-репозиторий, одна ВМ)
| # | Модуль | Стек | Назначение |
|---|---|---|---|
| 1 | lk-gateway |
Go (chi) | REST-интеграция с ЛК клиента на платформе ESIA Finance (/api/v1/back_office/...): получение заявок на M2M-перевод (/claims/), реквизитов (/requisites), пользователей (/users), сообщений (/messages), сертификатов (/control_certificates), Депо-счетов (/depo_accounts); проверка подписи заявления через crypto-service; callback статусов обратно в ЛК. Basic HTTP, кодировка UTF-8 — по контракту ESIA Finance API V1. |
| 1a | lk-emulator |
Go + минимальный HTML/HTMX | Эмулятор ЛК клиента (временная заглушка). Веб-форма «загрузить заявление» с моделированием контракта ESIA Finance API V1 (POST /claims/, статусные апдейты): оператор тестирования «как будто загрузил» заявление и нажимает «Отправить» — это запускает в нашей системе полный путь обработки документа. Используется на стендах GUEST/TEST3 и в регресс-сьюите. Когда реальный ЛК будет готов — эмулятор остаётся как тестовый инструмент в QA-окружении. |
| 2 | m2m-core |
Go | FSM сделки, идемпотентность по GUID, валидация против XSD, ручное согласование как параллельная ветка автомата, метрики SLA |
| 3 | fansy-store |
PostgreSQL Pro + Go-репозиторий | Только принимающая БД под выгрузку Fansy (схема и миграции — наши). Сам ETL делает другая команда. Внутри нашей системы — Go-репозиторий с типизированным API «получи реквизиты по ИНН/коду депонента», локальный кэш в памяти |
| 4 | nsd-adapter |
Go | Три транспорта к НРД (см. раздел «Транспорт к НРД»): (1) ИШ REST API — основной, (2) WS ONYX напрямую — резерв, (3) обменные папки ИШ — fallback. Сериализация/парсинг XML в windows-1251; кастомный NSDDateTimeType; маршрутизация по типам пакетов (#M2MTR/#M2MTD/#M2MER/SUBBR/SUBER/SUB16/Справки/квитанции ЭДО) |
| 5 | crypto-service |
Java 21 (Liberica JDK) + КриптоПро JCP (CSP на ВМ) | XMLDSig подпись/проверка (ГОСТ и RSA), gRPC по UDS. Для основного канала ИШ REST подпись пакета делает сам ИШ; здесь — проверка входящих, подпись действий оператора, резервный канал WS ONYX. Архитектурно сохранена Provider-абстракция (на случай добавления Валидата CSP / VipNet в будущем) |
| 6 | notify |
Go | E-mail (SMTP внутренний) + Yandex Messenger (Yandex 360 для бизнеса, до-интеграция готового бота заказчика) + WS-push в admin-ui. Архитектура — провайдеры-плагины: единый интерфейс Notifier, реализации (smtp, yandex360, telegram, mattermost, webhook…), подключение и переключение через конфиг и UI без правки кода |
| 7 | admin-ui |
React (SPA) + Go BFF в lk-gateway |
Веб-интерфейс администратора и сотрудника депозитария: журнал приходов/уходов, статусы, ручное согласование, SLA-дашборд, управление сертификатами для подписи (загрузка/обновление/отзыв серверных ключей и сертификатов оператора и системного ключа НРД) |
| 8 | Хранилища | PostgreSQL Pro Certified (на той же ВМ), MinIO (локальный, для эталонных подписанных XML) | Состояние сделок, аудит, копия выгрузки Fansy |
Шина сообщений на старте — встроенная in-process (Go channels + worker pool); если выйдем за пределы одной ВМ или разнесём этапы — добавляем NATS JetStream (легче Kafka, в реестре через Tarantool/NATS-форки нет, но как open source ставится).
Поток обработки одного заявления (целевой ≤ 2 мин)
- Приём от ЛК (
lk-gateway): REST POST с подписанным XML заявления → проверка подписи (crypto-service) → записьincoming_requestв БД, ack ЛК. - Валидация и обогащение (
m2m-core+fansy-connector): валидация по XSD, разрешение ИНН и кодов депонента из локальной копии Fansy. - Формирование
M2MTransferRequest(m2m-core): сборка по схеме, GUID = идемпотентный ключ. - Подпись (
crypto-service): XMLDSig по ГОСТ или RSA в зависимости от профиля. - Отправка в НРД (
nsd-adapter): SOAP к ONYX, разборM2MTransferResponse(INFO/ERROR). - Ожидание
Decision(если мы — донор): входящий poll или callback от НРД, разбор Confirmation/Rejection. - Формирование
Decision(если мы — реципиент): получение подтверждения сотрудника депозитария (авто или ручное согласование) → подпись → отправка. - Финализация: запись результата, callback в ЛК клиента, событие в
notify, обновление статуса вadmin-ui.
Каждый этап измеряется: stage_started_at, stage_finished_at → метрика m2m_stage_duration_seconds{stage="..."}. Алерт при превышении 80% SLA-бюджета.
Ручное согласование
В FSM сделки добавлена ветка manual-approval на каждом критичном этапе (AwaitingFansyEnrichment, AwaitingDecision, AwaitingNSDSend):
- В
admin-uiсотрудник депозитария видит сделку «на ручном согласовании» с кнопкамиПодтвердить/Отклонить с кодом/Доработать(с комментарием). - Триггеры ручного режима:
- явный флаг в заявлении из ЛК (для теста/спецсценариев),
- правила (сумма, ISIN из white-list, нерезидент и т.п.) — конфигурируемые,
- таймаут авто-обработки (защитный fallback).
- Подпись действий оператора — серверная, от имени оператора (через
crypto-serviceна серверном ГОСТ-ключе, выделенном на оператора). Решение принято ради SLA: подпись на рабочей станции через КриптоПро CSP добавляет 10–30 секунд на каждое действие плюс зависимость от состояния АРМ — это съедает бюджет 2 минут. Серверная подпись даёт стабильные миллисекунды. - Требования к серверной подписи оператора (документируем в формуляре СКЗИ и регламенте):
- Двухфакторная авторизация оператора в
admin-uiперед любым действием подписи (пароль + TOTP/корпоративный SSO). - Контейнер ключа оператора на сервере защищён, доступ через HSM или закрытый раздел КриптоПро; ключ не извлекаем.
- Каждая операция подписи сопровождается аудит-записью: оператор, действие, IP/браузер, GUID сделки, timestamp, хэш подписанного XML — неизменяемая (append-only таблица + периодический хэш-сцепленный snapshot).
- Регламент отзыва ключа оператора при увольнении/смене роли.
- Двухфакторная авторизация оператора в
- Документ «ОП личного кабинета оператора» (правила использования, ответственность) подключим к проекту позже, как только заказчик его передаст.
Управление сертификатами через admin-ui
В веб-интерфейсе администратор имеет раздел «Сертификаты», в котором происходит только обновление сертификатов для подписи (без управления самими ключами на низком уровне). Закрытые ключи остаются в защищённом серверном хранилище (КриптоПро, HSM) и через UI не выгружаются и не вводятся вручную — UI работает только с открытой частью / привязкой.
Что делает раздел:
- Просмотр текущих сертификатов: системный (для подписи M2M в НРД, профили GUEST/TEST3/PROD ГОСТ и RSA), серверные сертификаты операторов.
- Срок действия, серийный номер, отпечаток, издатель, fingerprint — отображаются для контроля.
- Загрузка нового сертификата (
.cer/.crt) для существующего ключевого контейнера — кнопка «Обновить сертификат», файл валидируется (срок действия, цепочка доверия, соответствие открытому ключу контейнера) и подменяет старый без рестарта сервиса. - Привязка сертификата к роли (системный/оператор
<имя>/конкретный профиль НРД). - Алерты об истечении срока (за 30/14/7/1 день) — в
notify(e-mail + Yandex Messenger) и в шапкеadmin-ui. - Полный аудит-лог операций с сертификатами (кто, когда, какой fingerprint обновил).
Ограничения и безопасность:
- Доступ к разделу — только для роли
Администратор СКЗИ(отдельная роль, не равна обычному админу). - Все операции — под двухфакторной авторизацией.
- Регламент обновления оформляется как часть документа «Эксплуатация СКЗИ».
Уведомления для депозитария (для соблюдения SLA)
Уведомления по двум каналам параллельно (notify):
- E-mail — обязательный (внутренний SMTP).
- Yandex Messenger (Yandex 360 для бизнеса) — мгновенная доставка в корпоративный мессенджер. У заказчика уже есть готовый бот, мы его до-интегрируем: передаём API-токен / webhook / список chat-id и user-id через конфиг и UI настроек. Российский сервис — важно для Реестра ПО.
- Push в
admin-uiчерез WebSocket — мгновенно, если оператор открыл вкладку (бесплатно, без внешних сервисов).
Расширяемость провайдеров (важное требование тиражирования)
Сейчас сервис делается под заказчика (Yandex 360 + e-mail). Но другая компания, разворачивающая систему у себя, должна иметь возможность легко переключиться на свои каналы без правок кода. Поэтому:
- В коде — единый интерфейс
Notifier { Send(ctx, recipient, template, data) }. - Провайдеры — отдельные пакеты-плагины:
smtp,yandex360,telegram,mattermost,rocketchat,webhook(универсальный POST по URL заказчика). - Список активных провайдеров и их параметры — в конфиге (YAML/ENV) и в
admin-uiв разделе «Уведомления»: можно включить/выключить, ввести токены, тестово отправить сообщение, настроить роутинг по ролям и типам событий. - Шаблоны сообщений — версионируемые, на русском, с подстановками (
{{guid}},{{stage}},{{deadline}}). - Документация для интегратора: «как подключить новый канал» — описание интерфейса и пример провайдера.
Логика роутинга: критичный этап (ручное согласование, > 80% SLA, отказ НРД) → параллельно e-mail + Yandex Messenger + WS-push. Обычные события — только e-mail. Маршрутизация по ролям (администратор, сотрудник депозитария, оператор) — настраивается в admin-ui.
Соответствие схемам НРД (привязка к XSD)
Из DOC/M2MSchemas_260408/ (namespace http://nsd.ru/schemas/m2m/..., version 2026-04-08):
- Сообщения:
M2MTransferRequest,M2MTransferResponse(StatusCode ∈ {INFO, ERROR}),M2MTransferDecision,M2MTransferHandbook(+Request),M2MTransferParticipantForm. - Кодировка XML — windows-1251, обязательный учёт в (de)serializer.
NSDDateTimeType— pattern[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\(МСК([+-][0-9]{1,2})?\)— только зона МСК с опциональным сдвигом (например,2026-03-02T14:30:45(МСК+2)).IsM2Mфиксированоtrue.- Choice-типы:
CostInfo (Yes{Code} | No),Quantity (Whole | Fractional),SecurityDetails (ISIN | SecurityInfo),SecurityInfo.IdentificationDetails (RegNumber | FundShares),DecisionTransfer (Confirmation | Rejection). - Точные ограничения (использовать в валидаторе):
ReferenceIdType: длина 16, patternM2M[A-Z0-9]{13}.DeponentCodeType: до 12 символов,[A-Z0-9]*.ISINtype: длина 12,[A-Z]{2}[A-Z0-9]{9}[0-9].OrganizationINNType: ровно 10 цифр (юрлицо).UUIDType: стандартный UUID-pattern.Decimal16: до 38 цифр всего, до 16 после запятой.IsolationStatus: единственное значениеSGDN.SecurityClassificationEnum:BOND | SHAR | MFUN.SecurityCategoryEnum:ORDN | PREF | UKWN.IIAContractTypeEnum:T12 | T03(T12 — обмен ИИС-1 ↔ ИИС-2, T03 — ИИС-3). Не путать с T01/T02.IdentityDocumentCodeEnum: 01–14, 21–27, 91 (полный список см. вM2MTypesNSD.xsd).StatusCodeEnum:INFO | ERROR.
- Эталоны из
DOC/Эталонные сообщения/— fixtures для приёмочных тестов черезxml-exc-c14n.
Транспорт к НРД (три канала, рекомендация — ИШ REST)
Из DOC/Ссылки для доступа в тестовые контуры.pdf, DOC/Инструкция по передаче эталонного запроса на перевод M2M 08.04 (1).pdf, DOC/Инструккия M2M.pdf, DOC/Презентация MOEX MOST.pdf, DOC/Презентация тестирование систем НРД.pdf:
- Контуры: GUEST (текущая прод-версия для тестов с клиентами), TEST3 (перспективная, для ОЭ), PROD (по «Анкете НРД»).
- Эндпоинты ГОСТ (
gost-*.nsd.ru) и RSA (rsa-*.nsd.ru) — раздельно.
Каналы взаимодействия
- Интеграционный шлюз НРД (ИШ) с REST API — ОСНОВНОЙ КАНАЛ.
- НРД-шный софт, ставится локально на наш сервер, имеет REST API:
POST /api/package/{channel}/file(отправка пакета как ZIP в base64),GET /api/package/status/{id}(статус),GET /api/package?channel=&date=&type=...(входящие). - ИШ сам формирует пакет ЭДО, подписывает его и шифрует по Правилам ЭДО НРД. Это резко уменьшает наш скоуп: для основного пути нам не нужен XMLDSig.
- Альтернативный режим ИШ — обменные папки (OUTBOX/INBOX/
#M2MTR/#M2MTD/#M2MER), как fallback при недоступности REST.
- НРД-шный софт, ставится локально на наш сервер, имеет REST API:
- Web-сервис ONYX (WSL) — резервный/прямой канал.
- URL:
https://gost-t3.nsd.ru/onyx-ms/OnyxEdoWSService/OnyxEdo(TEST3, ГОСТ), аналогично для GUEST/RSA. - WSDL:
.../OnyxEdo/OnyxEdo.wsdl. - Подпись и упаковка пакета — на нашей стороне (через
crypto-service). - Используем для диагностики, при отказе ИШ, и в сценариях, где ИШ не подходит.
- URL:
- Файловый шлюз НРД (ФШ).
- Файловый обмен по тем же папкам, что и ИШ-обменные. Поддерживается «на всякий случай», в основном потоке не используем.
В admin-ui — переключатель «канал отправки» для теста и эксплуатационных сценариев. Для каждого сценария фиксируется фактический канал в журнале.
Типы пакетов ЭДО (важно для маршрутизации в ИШ)
| Тип пакета | Содержимое | Сценарий |
|---|---|---|
#M2MTR |
M2MTransferRequest | Запрос на перевод M2M |
#M2MTD |
M2MTransferDecision | Решение принимающей стороны |
#M2MER |
M2MTransferResponse (ошибки сервиса MOST) | Тех. ошибка / отказ форматно-логического контроля |
SUBBR |
Transfer_out_request.xml / Transfer_in_request.xml / Transfer_in_consent.xml |
Старый сценарий «брокер→брокер» (поддержка для совместимости) |
SUBER |
Transfer_reject.xml |
Отказ в старом сценарии и автоматический отказ MOST по таймауту |
SUB16 |
Черновики 16-х/16-1 поручений (по одной ЦБ в одном сообщении) | Подготавливаются НРД после согласования M2M, отправляются обоим брокерам |
| Справка о расходах | Assets_investment_account_transfer_details.xml + Assets_investment_details_status.xml (статус) |
Передача справки о расходах, связанных с приобретением и хранением ЦБ, между брокерами через MOST |
| Стандартная квитанция ЭДО | служебное | Подтверждение доставки от НРД на каждый отправленный пакет |
Конфиг — профили guest-gost|guest-rsa|test3-gost|test3-rsa|prod-gost|prod-rsa. Тёплый пул HTTP-соединений (Transport.MaxIdleConnsPerHost) для SLA.
Тиражируемость продукта (внутренний MVP → другие компании)
Сейчас разрабатываем «для себя», но в архитектуру с самого начала закладываем возможность лёгкой передачи системы другим брокерам. Принципы:
- Никаких хардкодов заказчика в коде. ИНН, коды депонента, имена брокера, цвета бренда, тексты писем, шаблоны уведомлений — только через конфиг или БД настроек, доступных в
admin-ui. - Конфигурация одной командой. При первом запуске в новой компании — мастер-«первоначальная настройка»: реквизиты юрлица, профиль ЭДО НРД (контур, тип ключей), путь к ИШ, провайдеры уведомлений, контракты ESIA Finance ЛК (URL, basic-auth-токен), путь к контейнерам ключей КриптоПро.
- Лёгкое обновление версий у клиентов. Артефакт поставки — собранные docker-образы + один скрипт
install.sh/update.sh(поднимает docker-compose на ВМ, накатывает миграции БД, перезапускает только изменённые сервисы). Версии семантические (semver), changelog обязателен. Откат — на предыдущий тег образа одной командой. - СКЗИ-абстракция. На M1 реализация — только КриптоПро. Но интерфейс
Providerостаётся, чтобы другая компания со своим СКЗИ (Валидата CSP, VipNet) подключила свой провайдер, не трогая бизнес-логику. - Уведомления — провайдеры-плагины (см. соответствующий раздел). Сейчас smtp + Yandex 360 + webhook; другая компания может включить Mattermost/Telegram/SMS-провайдер через UI.
- Канал ЛК клиента — конфигурируемый (см. ниже про ESIA Finance). Если у другой компании ЛК на иной платформе — реализуется отдельный адаптер и подменяется через конфиг.
- Документация поставки: руководство администратора (установка, настройка, обновление), руководство оператора, формуляр СКЗИ. На русском.
- Лицензионная модель: код — собственность правообладателя (наша компания), поставка — лицензия + поддержка. В реестр ПО заявка от нашего юрлица.
Разделение «продуктовой части» (ядро, переиспользуется) и «настроек заказчика» (БД конфигов, шаблоны, реквизиты) — обязательно с самого первого спринта, иначе позже разбирать дороже.
Контракт с командой Fansy — что мы передаём
Команда Fansy реализует ETL на нашу БД. Чтобы они могли начать, мы передаём им следующий пакет (готовится в M1, согласуется в начале M2):
- DDL-скрипты PostgreSQL для всех таблиц
fansy-store. Минимально нужны (по требованиям документации НРД к данным M2M):- Депоненты / клиенты (ИНН, ФИО/наименование, тип, привязка к учётной записи в ESIA Finance).
- Документы инвестора, удостоверяющие личность (тип
IdentityDocumentCodeEnum01–14/21–27/91, серия, номер). - ИИС-договоры (
IIAContractTypeEnum ∈ {T12, T03}, номер, дата, ИНН брокера) — для ветки ИИС. - Депо-счета и разделы (
AccountId,SectionId,DeponentCode, привязка к клиенту, статус, признак торгового раздела). - Реквизиты расчётов (ИНН депозитария, код депонента, банковские реквизиты при необходимости).
- Портфели и остатки ЦБ (счёт + раздел + ISIN/
SecurityCode+IsolationStatus = SGDN+ кол-воWhole/Fractional) — для проверки достаточности на момент инициации перевода. - Справочник ЦБ (
SecurityCode,ISIN,SecurityClassification ∈ {BOND, SHAR, MFUN},SecurityCategory, для ПИФ —RegNumber/Class). - Контрагенты-участники сервиса MOST (
Справочник пользователей: БКС/Ренессанс/Альфа-банк, ИНН, ОГРН, статус «доступен для M2M»). - Audit/staging-таблицы для каждой основной (
*_staging,*_history) — чтобы команда Fansy писала в staging, а наш сервис читал готовое.
- Контракт данных на каждую таблицу: семантика поля, источник в Fansy (если известен), nullable, единицы, примеры.
- Тип load: предпочтительно инкрементный UPSERT по бизнес-ключу в staging-таблицу + хвост-триггер в основную; вариант полной перезаливки оговаривается отдельно (только для справочников).
- Окна обновления и SLA на свежесть данных: например, портфели/остатки — не позднее 1 минуты после изменения в Fansy; справочники ЦБ и контрагентов — раз в сутки или по событию.
- Технические требования: способ подключения (отдельная роль PostgreSQL
fansy_etlс правом INSERT/UPDATE на staging-схему, без DDL-прав), формат timestamp (UTC + явная зона), способ передачи ошибок (отдельная таблицаetl_errors). - Пример заявки M2M «end-to-end»: какие поля из Fansy потребуются
m2m-coreдля одной заявки и какой запрос будет выполнен — чтобы команда Fansy убедилась, что все нужные данные у них есть. - Тестовые данные: 5–10 тестовых клиентов, портфелей и заявок — для совместного приёмочного теста на стенде.
- График интеграции: даты передачи DDL, даты первой выгрузки в
fansy-store, дата начала совместного тестирования (в M4).
Документ оформляется как docs/fansy-contract/v1/... в моно-репо: ddl/, data-dictionary.md, etl-requirements.md, examples/. Версионируется отдельно (v1, v2).
Российское ПО — встроенные требования (Реестр ПП РФ № 1236)
Что требуется по ПП-1236 для включения в Реестр
Постановление Правительства РФ от 16.11.2015 № 1236 (с поправками) и Приказ Минцифры № 486 определяют условия включения ПО в Единый реестр российских программ. Ключевые критерии и наша готовность:
| № | Требование ПП-1236 | Реализация в проекте | Статус |
|---|---|---|---|
| 1 | Правообладатель — российское лицо: РФ, субъект РФ, муниципалитет, российская НКО (без преобладающего иностранного контроля) или гражданин РФ. Доля иностранного участия в УК ≤ 50% | Юрлицо заказчика — российское ООО/АО, проверяем долю иностранного капитала, готовим выписку из ЕГРЮЛ для заявки | К проверке у заказчика |
| 2 | Исключительное право на ПО принадлежит правообладателю на территории всего мира и на весь срок действия | Все договоры с разработчиками (штат + подряд) содержат пункты об отчуждении исключительного права; для open-source-зависимостей — лицензии совместимы (MIT/Apache 2.0/BSD/MPL/LGPL); GPL-копилефт исключаем | Закладываем в шаблоны договоров с M1 |
| 3 | Свободная гражданская реализация на территории РФ | Лицензионные договоры, ценник в рублях, оплата на расчётный счёт в РФ | Стандартная коммерческая модель — ОК |
| 4 | Сумма выплат за рубеж < 30% годовой выручки от реализации (роялти, лицензии иностранцам и т.п.) | Не используем платные иностранные SaaS/библиотеки; все облачные сервисы — российские | ОК (см. стек ниже) |
| 5 | Сведения о ПО не составляют гостайну | Не работаем с гостайной | ОК |
| 6 | Класс ПО по классификатору Минцифры | Заявляем как «02.13 Системы электронного документооборота» + «02.09 Прикладное ПО для финансового сектора» (уточнить с патентным поверенным при подаче) | На M5 |
| 7 | Размещение исходного кода и сборок на территории РФ | Git-репозиторий в РФ-хостинге: https://git.zetit.ru/zuevav/Bridge-and-Join-s (заказчиковый Gitea/GitLab on-prem). CI на РФ-инфраструктуре (раннеры этого же сервера или собственная ВМ заказчика) |
ОК — репо уже есть |
| 8 | Техподдержка на территории РФ | Договор поддержки с юрлицом-правообладателем, контактные данные на сайте, телефон РФ, поддержка на русском, SLA в часовом поясе MSK | На M5 |
| 9 | Документация на русском | Все артефакты (руководства администратора, оператора, формуляр СКЗИ, описание архитектуры, OpenAPI/AsyncAPI, тексты UI) — на русском с самого начала | Закладываем с M1 |
| 10 | Совместимость с реестровой ОС или независимость от ОС | Сборки и приёмочные тесты на Astra Linux SE 1.7+ и РЕД ОС 7.3 (минимум одна из реестровых ОС обязательна) | M2 — добавить в CI |
Стек — все компоненты соответствуют импортозамещению
| Слой | Выбор | Реестр ПО / российское |
|---|---|---|
| ОС | Astra Linux SE 1.7+ (целевая) или РЕД ОС 7.3 (альтернатива) | Да, в Реестре |
| СУБД | PostgreSQL Pro Certified (Postgres Professional) | Да, в Реестре |
JDK для crypto-service |
Liberica JDK (BellSoft) или Axiom JDK (BellSoft / Axiom) | Да, в Реестре |
| СКЗИ | КриптоПро CSP/JCP, класс КС1 | Сертифицировано ФСБ, в Реестре |
| Среда исполнения Go | Open-source upstream — допустимо, ограничений нет | Open-source — ОК |
| Сборка / контейнеризация | Docker / Podman + docker-compose / systemd | Open-source — ОК; при k8s — Deckhouse в Реестре |
| Корпоративная почта/мессенджер интеграция | Внутренний SMTP заказчика + Yandex 360 для бизнеса | Yandex — российский сервис |
| Объектное хранилище | MinIO (open source, локально на ВМ) | Open-source — ОК |
| Шина (если выйдем за in-process) | NATS JetStream или Apache Kafka | Open-source — ОК |
| Хостинг репозитория и CI | git.zetit.ru (РФ-хостинг заказчика) |
Российская инфраструктура |
| Фронтенд | React + Vite (open-source upstream); UI-kit — Yandex Cloud UI Kit или собственный | Open-source — ОК |
| Артефакт-репозиторий | Nexus on-prem или собственный реестр Docker | Self-hosted — ОК |
Что НЕ используем (и почему)
- GitHub / GitLab.com / Atlassian Bitbucket как первичный репозиторий — для подачи в Реестр требуется размещение в РФ. На GitHub допустимо «зеркало» в режиме read-only.
- JetBrains Space, Confluence Cloud, Slack, Notion — иностранные SaaS, заменяем российскими аналогами (Yandex 360, Mattermost on-prem, YouTrack on-prem допустим как self-hosted).
- Microsoft .NET, MS SQL Server, Oracle DB, Windows Server — не в Реестре, импортозамещаем (см. стек).
- AWS / GCP / Azure / Cloudflare — облака недружественной юрисдикции; всё on-prem или РФ-облака (Yandex Cloud, VK Cloud, MTS Cloud).
- GPL/AGPL-зависимости в основном коде — несовместимы с проприетарной поставкой; в SBOM ведём контроль лицензий, GPL разрешаем только для отдельно стоящих утилит, не линкующихся к ядру.
Что уже учтено в архитектуре
- Локализация: UI и документы на русском, MSK timezone, формат даты ISO 8601 с явной зоной как требует
NSDDateTimeType. - Тиражируемость (см. отдельный раздел): отсутствие хардкодов заказчика, конфигурируемый
ProviderСКЗИ, провайдеры уведомлений плагинами — это и для других компаний, и для аккуратной заявки в Реестр (один артефакт ПО, разные настройки, без копий продукта на каждого заказчика). - СКЗИ КС1 на сертифицированной ОС.
- 57580.1/.2 (защита информации в финансовых организациях): сегментация ВМ, журналирование, контроль доступа, шифрование «в покое» (PostgreSQL Pro TDE).
- 152-ФЗ + ПП-1119: УЗ-2 (ПДн категории «иные»), DPIA, согласие инвестора, журнал доступа к ПДн, маскирование в логах.
- Документация поставки (руководство администратора, оператора, формуляр СКЗИ) — на русском, в скоупе M5.
Что нужно сделать дополнительно для подачи в Реестр
Эти задачи добавлены в M5, но подготовка идёт с M1:
- Юридический пакет (готовится к моменту подачи):
- Выписка из ЕГРЮЛ правообладателя.
- Документы об отчуждении исключительного права (от каждого разработчика — трудовой договор + служебное задание / договор подряда).
- Договоры на технологии в составе (open-source — указать лицензии в SBOM; коммерческие — КриптоПро, Postgres Pro, Liberica, Astra/РЕД ОС — приложить копии).
- Анкета и формы Минцифры (заполняются через ЕСИА руководителя на портале reestr.digital.gov.ru).
- Технический пакет:
- Описание процессов разработки и поддержки.
- SBOM (CycloneDX) — для контроля происхождения и лицензий.
- Инструкции по установке и эксплуатации на русском.
- Сборка-демонстратор для проверки экспертами Минцифры (типовая инсталляция на Astra/РЕД ОС, доступ предоставляется по запросу).
- Интеллектуальная собственность:
- Регистрация ПО в Роспатенте (необязательно, но повышает доказательность исключительного права при споре).
- Свидетельство Роспатента — приложение к заявке в Минцифры.
- Соответствие классу ПО: пройти классификатор и подать с правильным классом (02.13 / 02.09 / 02.04 «средства защиты информации» — уточнить с патентным поверенным).
- Сертификация ФСТЭК / ФСБ (не для Реестра, но для применимости в финансовых организациях):
- Сертификат ФСТЭК на встроенные средства защиты (если потребуется по аттестации сегмента у заказчика) — обычно не нужен, если заказчик аттестует свой сегмент сам.
- Сертификат ФСБ на криптомодуль — у нас не нужен, мы используем сертифицированный КриптоПро (его сертификат прикладываем).
Открытые проверки у заказчика
- Доля иностранного участия в УК правообладателя ≤ 50% (выписка из ЕГРЮЛ).
- Все разработчики — резиденты РФ или работают по договорам с правильными формулировками о передаче ИС.
- Расчёт суммы выплат за рубеж < 30% выручки от реализации (актуально, если есть лицензии иностранным правообладателям).
- Согласие правообладателя подавать заявку (решение собственников, протокол).
Вердикт
С точки зрения архитектуры и стека — всё закладывается корректно, ни одно из выбранных технических решений не противоречит требованиям Реестра. Основные риски — юридические/корпоративные (правообладатель, ИС, выплаты за рубеж) и процессные (правильно выбранный класс ПО, грамотно оформленный пакет документов). Эти риски решаются на M5 при участии юриста и патентного поверенного, но проверки у заказчика стоит начать уже на M1, потому что несоответствие в составе УК или в договорах с разработчиками невозможно «дописать» позже.
Roadmap (полный MVP)
M1 — Каркас, контракты, стенды (4 нед)
- Моно-репо, CI, линтеры, конвенции.
- Go-модели из XSD + (de)serializer windows-1251 +
NSDDateTimeType+ строгий валидатор по pattern (ReferenceId, ISIN, ИНН, DeponentCode). - gRPC-контракт
crypto-serviceс реализацией КриптоПро JCP (плюс сохранённаяProvider-абстракция для тиражирования), установка КриптоПро CSP на ВМ. - docker-compose: PostgreSQL Pro, MinIO, заглушки сервисов.
- Установка и настройка Интеграционного шлюза НРД на тестовой ВМ, проверка REST API (
POST /api/package/{channel}/file). - Инициировать выпуск тестовых сертификатов GUEST/TEST3 (ГОСТ + RSA), снять противоречие СКЗИ (Валидата vs КриптоПро/VipNet) с НРД и заказчиком.
- Версионированный контракт
lk-gateway↔lk-emulator, совместимый с ESIA Finance API V1 (/api/v1/back_office/claims); тот же контракт предлагаем команде реального ЛК.
M2 — Сквозной сценарий «донор» через стенд (6 нед)
lk-emulatorv1: веб-форма «загрузить заявление» (готовый XML или сборка из полей), эмуляция вызоваPOST /api/v1/back_office/claims/, кнопка «Подписать и отправить», просмотр статусов и callback-ответов отlk-gateway.lk-gatewayпринимает заявление от эмулятора, валидирует подпись.fansy-storev0: схема БД и миграции под принимаемые от Fansy данные; передача командe Fansy перечня таблиц + DDL как контракт; стартовое наполнение фикстурами.m2m-coreFSMDraft → Validated → SubmittedToNSD → AwaitingDecision → Confirmed/Rejected/TimedOut → Done, с веткойTimedOutпо регуляторному таймауту (10→5 мин).crypto-service: проверка подписи входящих квитанций ЭДО и ответов НРД, подпись действий оператора.nsd-adapterv1: ИШ через REST API как основной канал, прохождение эталонного запроса изDOC/Инструкция по передаче эталонного запроса на перевод M2M 08.04 (1).pdfна TEST3 с типом пакета#M2MTR, ожидание#M2MTD.- Метрики SLA по этапам, дашборд в
admin-ui.
M3 — Сценарий «реципиент», справочники, admin-ui v1 (6 нед)
- Приём входящих от НРД через ИШ REST (
GET /api/package?channel=&type=M2MTD|M2MER|...), формированиеM2MTransferDecision. M2MTransferHandbookRequest/Handbook/ParticipantForm+ кэш в локальной БД, плюс загрузкаСправочник пользователей(БКС, Ренессанс Брокер, Альфа-банк).- Поддержка дополнительных типов пакетов:
SUB16(черновики 16-х/16-1 поручений) — приём, парсинг, отображение в журнале и передача депозитарию. - Поддержка
SUBBR/SUBER(старый сценарий перевода) для совместимости иAssets_investment_account_transfer_details+Assets_investment_details_status(Справка о расходах). - Стандартная квитанция ЭДО — обязательная проверка для каждого исходящего пакета.
admin-ui: журнал входящих/уходящих, фильтры (GUID/инвестор/статус/период/тип пакета), просмотр эталонов, переключатель канала (ИШ/ONYX/ФШ).admin-ui: раздел «Сертификаты» — обновление сертификатов, сроки, алерты.- Роли: администратор, администратор СКЗИ, сотрудник депозитария, оператор, аудитор.
M4 — Ручное согласование, уведомления (4 нед)
- Ветка manual-approval в FSM, UI кнопок согласования.
notify: e-mail + Yandex Messenger (до-интеграция готового бота заказчика) + WS-push вadmin-ui.- Архитектура провайдеров-плагинов для notify (smtp, yandex360, webhook, telegram, mattermost) — реализуем минимум smtp + yandex360 + webhook, остальные — заглушками с примером.
- Раздел «Уведомления» в
admin-ui: включение/выключение провайдеров, ввод токенов, тестовая отправка, маршрутизация. - Конфигурируемые правила «отправить на ручное согласование».
- Совместное тестирование с командой Fansy-ETL: проверка наполнения
fansy-storeбоевым потоком.
M5 — ИБ, нагрузочное, оптимизация на SLA 2 мин, прод (6 нед, до 01.09.2026)
- Аудит ГОСТ Р 57580, моделирование угроз, документы для ФСТЭК.
- Нагрузочное (k6) с целевым TPS, верификация SLA 2 мин и регуляторного таймаута 5 мин.
- Подача в Реестр ПО (заявка готовится параллельно с M3-M4).
- Подключение резервного канала через WS ONYX напрямую для ситуации недоступности ИШ.
- Подключение промконтура НРД, ПСИ.
- Жёсткий дедлайн: вступление 124-ФЗ + Указания Банка России 01.09.2026.
Критичные файлы и активы
DOC/M2MSchemas_260408/*.xsd— единственный источник правды для моделей.DOC/Примеры/*.xml— fixtures unit-тестов.DOC/Эталонные сообщения/*.xml— приёмочные fixtures.DOC/Ссылки для доступа в тестовые контуры.pdf— конфиги стендов.DOC/Инструкция по передаче эталонного запроса на перевод M2M 08.04 (1).pdf— сценарий приёмки M2.DOC/instr_podkl_stend_v3.pdf— подключение к стендам.DOC/Справочник пользователей.pdf— перечень организаций-участников сервиса (БКС ИНН 5406121446, Ренессанс Брокер 7709258228, Альфа-банк 7728168971 — последний на пилоте). Загружается вfansy-store/локальный справочник как white-list контрагентов и индикатор «доступен ли участник для M2M-перевода». Модель ролей операторов нашей системы — отдельная, проектируется вadmin-ui.DOC/so_cher_por.pdf— схема обмена для получения черновиков поручений (типы пакетовSUBBR,SUBER,SUB16— черновики 16-х поручений на каждую ЦБ).DOC/so_spravki.pdf— схема обмена Справки о расходах (Assets_investment_account_transfer_details.xml+Assets_investment_details_status.xml) между Брокером 1 и Брокером 2 через MOST.DOC/Презентация MOEX MOST.pdf— целевая архитектура M2M, регуляторика (124-ФЗ, дедлайн 01.09.2026), таймауты 5/2 минуты, таймаут отсутствия ответа 10/5 минут.DOC/Презентация тестирование систем НРД.pdf— окружение тестирования: СКЗИ «Валидата CSP», Криптосервис НРД (порты 48737/48200), требования к рабочему месту оператора для веб-кабинетов.DOC/API ЛК ЕСИА.pdf— это НЕ ЕСИА Госуслуг, а API бэк-офиса платформы «ESIA Finance» (/api/v1/back_office/..., Basic HTTP, JSON, UTF-8). Это и есть контракт ЛК клиента, через который работает наша интеграция; релевантные разделы: Заявки (/claims), Реквизиты (/requisites), Депо-счета (/depo_accounts), Сообщения (/messages), Сертификаты (/control_certificates), Пользователи (/users).
Верификация
- Unit: round-trip сериализация всех 6 типов сообщений против эталонов (
xml-exc-c14nсравнение). - Crypto: подпись эталона
crypto-serviceГОСТ-ключом → проверка штатным верификатором СКЗИ (Валидата/КриптоПро) → green. - Контрактные тесты: WireMock-стенд ИШ REST API (методы
/api/package/...) и WS ONYX в CI; ночные прогоны на GUEST/TEST3. - Регуляторный таймаут: интеграционный тест «отправили
#M2MTRна стенде, не получили#M2MTDза 10 мин» → проверка, что MOST прислалTransfer_reject.xml (SUBER)и наша FSM перешла вTimedOut. - SLA: синтетический тест каждого этапа в CI, fail при > 5 мин (старт) и > 2 мин (целевой).
- E2E: docker-compose, Playwright прокликивает сценарии через
lk-emulator(загрузка заявления → подпись → отправка) и далее поadmin-ui(приход → авто-обработка, приход → ручное согласование, приход → таймаут SLA → нотификация). Эмулятор — основной инструмент E2E на всём протяжении, пока реальный ЛК не подключён. - Fansy: контрактный тест выгрузки против тестовой схемы Fansy.
- Приёмка НРД: эталонный сценарий 08.04 без ручных правок, GUID совпадает в Request/Response/Decision.
Открытые вопросы (нужно уточнить перед M1)
- API ЛК клиента: подтверждено — концепция взаимодействия реального ЛК соответствует
API ЛК ЕСИА.pdf(платформа ESIA Finance,/api/v1/back_office/...). Сами формы документа на стороне ЛК ещё не реализованы, поэтому вlk-emulatorмы пишем «как-будто-ЛК», который вызывает нашlk-gatewayточно по этому контракту; реальный ЛК подключится через тот же контракт без правок на нашей стороне. - СКЗИ — решено: КриптоПро. В
crypto-serviceподнимаем КриптоПро JCP (на JVM) и КриптоПро CSP на ВМ, согласуем версию и лицензию. Поддержку других провайдеров не убираем (Provider-абстракция остаётся), но в реализации — только КриптоПро. - Установка ИШ: дистрибутив ИШ НРД получает заказчик (как участник ЭДО), наша сторона ставит ИШ на целевую ВМ и сопровождает.
- Fansy-store: ETL делает команда Fansy в автоматизированном режиме. Наша ответственность — спроектировать таблицы согласно требованиям документации НРД к данным M2M (поля
Header,Data, реквизиты сторон, счета/разделы, остатки) и передать команде Fansy перечень таблиц + DDL как контракт. Согласуем тип load, частоту, окно простоя. - Подпись действий оператора: решено — серверная, от имени оператора (через
crypto-service) ради SLA 2 мин. Клиентская подпись отклонена. - Yandex Messenger: используется Yandex 360 для бизнеса, на стороне заказчика уже есть готовый бот — мы его до-интегрируем (передаём токен/webhook/ID чатов через конфиг).
- Класс СКЗИ — решено: КС1. Программная защита без аппаратного ДСЧ/HSM. Используем сертифицированное исполнение КриптоПро CSP/JCP на сертифицированной ОС (РЕД ОС 7.3 (целевая)). На M5 — сборка формуляра и эксплуатационной документации СКЗИ под требования КС1.
- Аутентификация в
admin-ui: внутренний SSO компании (LDAP/Keycloak) или собственная учётка?
Что добавлено по результатам повторного аудита документации
Ниже — сводно, чтобы было видно, что план учёл все обнаруженные при ре-аудите факты:
- Три транспортных канала к НРД (ИШ REST — основной, WS ONYX — резерв, ФШ — fallback) и таблица типов пакетов ЭДО (
#M2MTR/#M2MTD/#M2MER/SUBBR/SUBER/SUB16/Справки/квитанции). - ИШ сам подписывает пакеты — пересмотрена роль
crypto-service(он теперь нужен в первую очередь для проверки входящих, подписи действий оператора и резерва через WS ONYX). - СКЗИ Валидата CSP добавлено как поддерживаемый провайдер; противоречие с лицензиями заказчика вынесено в открытые вопросы; в
crypto-service— абстракцияProvider. API ЛК ЕСИА.pdfидентифицирован как API ESIA Finance (не госЕСИА). Контрактlk-gateway/lk-emulatorприводится к этому API (/claims,/requisites,/depo_accounts,/messages,/control_certificates,/users).- Регуляторика: 124-ФЗ от 23.05.2025, Указание ЦБ, дедлайн прода 01.09.2026, таймаут MOST 10→5 мин — учтены в SLA и M5.
Справочник пользователейпереинтерпретирован: это перечень контрагентов (БКС, Ренессанс Брокер, Альфа-банк), не модель ролей операторов.- Дополнительные сценарии: справка о расходах (
Assets_investment_account_transfer_details+ статус), черновики порученийSUB16, старый сценарийSUBBR/SUBER— добавлены в скоуп M3. - XSD-уточнения: исправлен
IIAContractTypeEnum(T12 | T03, неT01/T02/T03); зафиксированы pattern дляReferenceId,ISIN,DeponentCode, ИНН,NSDDateTimeType(только зона МСК); полный списокIdentityDocumentCodeEnum. - Установка ИШ НРД включена в M1 как обязательный шаг подключения к стенду.
- Регуляторный таймаут MOST оформлен как ветка FSM
TimedOutс интеграционным тестом на стенде.