chore: каркас моно-репо и скрипт первичной подготовки dev-ВМ
Содержимое первого коммита:
- Структура моно-репо: cmd/{lk-gateway,m2m-core,nsd-adapter,lk-emulator,notify}/,
internal/{m2m,nsdxml,fansystore,notify}/, services/crypto-service/,
web/admin-ui/, deploy/docker-compose/, migrations/, docs/.
- Заглушки main.go во всех cmd/ — make build проходит из коробки.
- Makefile с целями build/test/lint/fmt/vet/tidy/ci/compose-up/compose-down.
- .golangci.yml, .gitignore, README.md (на русском).
- .claude/settings.json — общие ограничения Claude Code для команды
(запрет sudo, rm -rf, доступа к /etc/cryptopro, /var/cryptopro).
- README в каждом каталоге — назначение и стадия (M1..M5).
- docs/architecture/overview.md — выжимка из плана проекта.
- docs/fansy-contract/v1/, docs/lk-contract/v1/ — точки сборки контрактов
с командами Fansy и ЛК клиента.
- deploy/docker-compose/docker-compose.yml — dev-стек (PostgreSQL, MinIO).
- scripts/setup-dev-vm.sh — первичная подготовка dev-ВМ под РЕД ОС 7.x
и Ubuntu 22.04+ (для компаний без бюджета на лицензии); ставит Go 1.23,
Liberica JDK 21, Node.js 20 LTS, Podman, podman-compose, Claude Code CLI;
создаёт пользователя dev, /srv/dev, аудит-history. Идемпотентен.
- scripts/README.md — описание скрипта и ограничений.
Что НЕ коммитим:
- Секреты, ключи, сертификаты — закрыто в .gitignore.
- Локальные настройки Claude Code (settings.local.json) и сессионные
каталоги (.claude/projects/, .claude/worktrees/, .claude/logs/).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(go *)",
|
||||
"Bash(make *)",
|
||||
"Bash(git status)",
|
||||
"Bash(git diff *)",
|
||||
"Bash(git log *)",
|
||||
"Bash(git branch *)",
|
||||
"Bash(git fetch *)",
|
||||
"Bash(git pull *)",
|
||||
"Bash(git remote -v)",
|
||||
"Bash(podman *)",
|
||||
"Bash(podman-compose *)",
|
||||
"Bash(docker *)",
|
||||
"Bash(docker-compose *)",
|
||||
"Bash(xmlstarlet *)",
|
||||
"Bash(jq *)",
|
||||
"Bash(ls *)",
|
||||
"Bash(cat *)",
|
||||
"Bash(grep *)",
|
||||
"Bash(find *)",
|
||||
"Bash(npm run *)",
|
||||
"Bash(npx *)",
|
||||
"Bash(./scripts/*)"
|
||||
],
|
||||
"deny": [
|
||||
"Bash(rm -rf /*)",
|
||||
"Bash(rm -rf ~)",
|
||||
"Bash(rm -rf $HOME)",
|
||||
"Bash(sudo *)",
|
||||
"Bash(dd *)",
|
||||
"Bash(mkfs *)",
|
||||
"Bash(curl * | sh)",
|
||||
"Bash(curl * | bash)",
|
||||
"Bash(wget * | sh)",
|
||||
"Bash(wget * | bash)",
|
||||
"Read(/etc/cryptopro/**)",
|
||||
"Read(/var/cryptopro/**)",
|
||||
"Read(/etc/ipsec.d/**)",
|
||||
"Read(/root/**)",
|
||||
"Read(/home/admin/**)",
|
||||
"Write(/etc/**)",
|
||||
"Write(/var/**)",
|
||||
"Write(/root/**)",
|
||||
"Write(/home/admin/**)"
|
||||
]
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
# Сборки
|
||||
/bin/
|
||||
/dist/
|
||||
*.exe
|
||||
*.test
|
||||
*.out
|
||||
|
||||
# Go
|
||||
vendor/
|
||||
go.sum.lock
|
||||
|
||||
# Java / crypto-service
|
||||
services/crypto-service/build/
|
||||
services/crypto-service/.gradle/
|
||||
services/crypto-service/target/
|
||||
*.jar
|
||||
*.class
|
||||
|
||||
# Node / admin-ui
|
||||
web/admin-ui/node_modules/
|
||||
web/admin-ui/dist/
|
||||
|
||||
# Локальные конфиги и секреты
|
||||
.env
|
||||
.env.local
|
||||
*.local.yaml
|
||||
*.local.yml
|
||||
secrets/
|
||||
certs/private/
|
||||
|
||||
# Контейнеры ключей и сертификаты — никогда не коммитим
|
||||
*.p12
|
||||
*.pfx
|
||||
*.pem
|
||||
*.key
|
||||
*.cer.priv
|
||||
|
||||
# IDE и временные файлы
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
.DS_Store
|
||||
|
||||
# Логи
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# Тестовые артефакты
|
||||
coverage.out
|
||||
coverage.html
|
||||
test-results/
|
||||
|
||||
# Claude Code сессионные логи и локальные настройки
|
||||
.claude/logs/
|
||||
.claude/settings.local.json
|
||||
.claude/projects/
|
||||
.claude/worktrees/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
@@ -0,0 +1,44 @@
|
||||
run:
|
||||
timeout: 3m
|
||||
go: "1.23"
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- unused
|
||||
- gofmt
|
||||
- goimports
|
||||
- misspell
|
||||
- revive
|
||||
- gocritic
|
||||
- bodyclose
|
||||
- errorlint
|
||||
- nilerr
|
||||
- prealloc
|
||||
- unconvert
|
||||
- unparam
|
||||
- whitespace
|
||||
|
||||
linters-settings:
|
||||
goimports:
|
||||
local-prefixes: git.zetit.ru/zuevav/Bridge-and-Join-s
|
||||
misspell:
|
||||
locale: US
|
||||
revive:
|
||||
rules:
|
||||
- name: var-naming
|
||||
disabled: false
|
||||
- name: package-comments
|
||||
disabled: true
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- errcheck
|
||||
- unparam
|
||||
@@ -0,0 +1,52 @@
|
||||
.PHONY: help build test lint fmt vet clean tidy ci compose-up compose-down
|
||||
|
||||
GO ?= go
|
||||
GOLANGCI_LINT ?= golangci-lint
|
||||
COMPOSE ?= podman-compose
|
||||
|
||||
help:
|
||||
@echo "Цели:"
|
||||
@echo " make build - сборка всех бинарников Go"
|
||||
@echo " make test - юнит-тесты"
|
||||
@echo " make lint - golangci-lint"
|
||||
@echo " make fmt - gofmt + goimports"
|
||||
@echo " make vet - go vet"
|
||||
@echo " make tidy - go mod tidy"
|
||||
@echo " make ci - все проверки CI локально"
|
||||
@echo " make compose-up - поднять локальный стек (PostgreSQL, MinIO, заглушки)"
|
||||
@echo " make compose-down - остановить локальный стек"
|
||||
@echo " make clean - удалить артефакты"
|
||||
|
||||
build:
|
||||
@mkdir -p bin
|
||||
$(GO) build -o bin/lk-gateway ./cmd/lk-gateway
|
||||
$(GO) build -o bin/m2m-core ./cmd/m2m-core
|
||||
$(GO) build -o bin/nsd-adapter ./cmd/nsd-adapter
|
||||
$(GO) build -o bin/lk-emulator ./cmd/lk-emulator
|
||||
$(GO) build -o bin/notify ./cmd/notify
|
||||
|
||||
test:
|
||||
$(GO) test ./... -race -count=1
|
||||
|
||||
lint:
|
||||
$(GOLANGCI_LINT) run ./...
|
||||
|
||||
fmt:
|
||||
$(GO) fmt ./...
|
||||
|
||||
vet:
|
||||
$(GO) vet ./...
|
||||
|
||||
tidy:
|
||||
$(GO) mod tidy
|
||||
|
||||
ci: tidy fmt vet lint test build
|
||||
|
||||
compose-up:
|
||||
$(COMPOSE) -f deploy/docker-compose/docker-compose.yml up -d
|
||||
|
||||
compose-down:
|
||||
$(COMPOSE) -f deploy/docker-compose/docker-compose.yml down
|
||||
|
||||
clean:
|
||||
rm -rf bin/ dist/ coverage.out coverage.html
|
||||
@@ -0,0 +1,61 @@
|
||||
# Bridge and Join's — сервис M2M-перевода ценных бумаг через НРД
|
||||
|
||||
Внутренний модуль брокера для обмена с НРД сообщениями о переводе ценных бумаг
|
||||
(M2M, ЭДО НРД, сервис MOEX MOST). Реализация — российское ПО, готовится к
|
||||
включению в Реестр (ПП РФ № 1236).
|
||||
|
||||
## Назначение
|
||||
|
||||
Связующий модуль между:
|
||||
|
||||
- личным кабинетом клиента на платформе ESIA Finance (источник заявлений инвестора);
|
||||
- учётной системой `Fansy` (источник реквизитов и остатков, выгрузка в нашу
|
||||
принимающую БД делает отдельная команда);
|
||||
- НРД через Интеграционный шлюз / Web-сервис ONYX (формат XML по схемам
|
||||
`M2MTransferRequest/Decision/Response/Handbook/ParticipantForm`).
|
||||
|
||||
Подробное описание архитектуры, потока, регуляторных требований, SLA и
|
||||
дорожной карты — см. `docs/architecture/overview.md` и план в репозитории
|
||||
команды.
|
||||
|
||||
## Стек
|
||||
|
||||
- Go 1.23+ — ядро (`cmd/`, `internal/`).
|
||||
- Java 21 (Liberica JDK) + КриптоПро JCP — `services/crypto-service` (XMLDSig
|
||||
по ГОСТ Р 34.10-2012, серверная подпись действий оператора).
|
||||
- React + Vite — `web/admin-ui` (журнал, ручное согласование, сертификаты).
|
||||
- PostgreSQL Pro Certified — основная БД (`m2m-core`, `fansy-store`, аудит).
|
||||
- MinIO — эталоны подписанных XML.
|
||||
- Развёртывание — одна ВМ внутри контура брокера, `podman-compose`.
|
||||
|
||||
## Документация
|
||||
|
||||
- `DOC/` — оригинальная документация НРД (схемы XSD, инструкции, эталоны).
|
||||
- `docs/architecture/overview.md` — обзор архитектуры.
|
||||
- `docs/fansy-contract/v1/` — DDL и контракт данных для команды Fansy.
|
||||
- `docs/lk-contract/v1/` — OpenAPI контракта с ЛК клиента (ESIA Finance).
|
||||
- `scripts/setup-dev-vm.sh` — скрипт первичной подготовки dev-ВМ.
|
||||
|
||||
## Быстрый старт (на dev-ВМ)
|
||||
|
||||
```bash
|
||||
# под admin (один раз на ВМ)
|
||||
sudo bash scripts/setup-dev-vm.sh
|
||||
|
||||
# под dev
|
||||
git clone https://git.zetit.ru/zuevav/Bridge-and-Join-s.git
|
||||
cd Bridge-and-Join-s
|
||||
make build
|
||||
make test
|
||||
```
|
||||
|
||||
## Ветви
|
||||
|
||||
- `main` — стабильная.
|
||||
- `feature/<имя>` — рабочие ветви, в основную через merge request.
|
||||
- `claude/<...>` — служебные ветви автоматизированных правок.
|
||||
|
||||
## Лицензия
|
||||
|
||||
Внутренняя разработка. Лицензионная модель будет определена при подаче
|
||||
в Реестр российского ПО.
|
||||
@@ -0,0 +1,20 @@
|
||||
// Package main — сервис lk-emulator. Эмулятор ЛК клиента (ESIA Finance API V1)
|
||||
// на время, пока реальный ЛК не готов. Позволяет «как будто загрузить»
|
||||
// заявление через веб-форму и запустить полный путь обработки документа.
|
||||
//
|
||||
// Когда реальный ЛК подключится — эмулятор остаётся как тестовый инструмент
|
||||
// в QA-окружении.
|
||||
//
|
||||
// На этапе M1 — заглушка.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
const serviceName = "lk-emulator"
|
||||
|
||||
func main() {
|
||||
fmt.Fprintf(os.Stdout, "%s: запуск (заглушка M1)\n", serviceName)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Package main — сервис lk-gateway. Принимает заявления от ЛК клиента
|
||||
// (платформа ESIA Finance, /api/v1/back_office/...), валидирует их подпись,
|
||||
// передаёт в m2m-core, отдаёт callback-статусы обратно в ЛК.
|
||||
//
|
||||
// На этапе M1 — заглушка. Реализация контракта — M2.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
const serviceName = "lk-gateway"
|
||||
|
||||
func main() {
|
||||
fmt.Fprintf(os.Stdout, "%s: запуск (заглушка M1)\n", serviceName)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Package main — сервис m2m-core. Бизнес-логика и FSM сделки M2M-перевода:
|
||||
// идемпотентность по GUID, валидация по XSD, метрики SLA, ветка ручного
|
||||
// согласования и таймаут-отказа MOST.
|
||||
//
|
||||
// На этапе M1 — заглушка.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
const serviceName = "m2m-core"
|
||||
|
||||
func main() {
|
||||
fmt.Fprintf(os.Stdout, "%s: запуск (заглушка M1)\n", serviceName)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Package main — сервис notify. Отправка уведомлений по нескольким каналам:
|
||||
// e-mail (SMTP), Yandex Messenger (Yandex 360), WebSocket-push в admin-ui,
|
||||
// плюс расширяемая модель провайдеров-плагинов (smtp, yandex360, telegram,
|
||||
// mattermost, webhook) под единый интерфейс Notifier — для тиражирования
|
||||
// продукта другим компаниям.
|
||||
//
|
||||
// На этапе M1 — заглушка.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
const serviceName = "notify"
|
||||
|
||||
func main() {
|
||||
fmt.Fprintf(os.Stdout, "%s: запуск (заглушка M1)\n", serviceName)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Package main — сервис nsd-adapter. Транспорт к НРД:
|
||||
// - Интеграционный шлюз через REST API (основной канал, ИШ сам подписывает);
|
||||
// - Web-сервис ONYX напрямую (резерв);
|
||||
// - Файловый шлюз / обменные папки ИШ (fallback).
|
||||
//
|
||||
// Сериализация и парсинг XML по схемам M2MSchemas в windows-1251,
|
||||
// маршрутизация по типам пакетов (#M2MTR / #M2MTD / #M2MER / SUBBR / SUBER /
|
||||
// SUB16 / Справки / квитанции ЭДО).
|
||||
//
|
||||
// На этапе M1 — заглушка.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
const serviceName = "nsd-adapter"
|
||||
|
||||
func main() {
|
||||
fmt.Fprintf(os.Stdout, "%s: запуск (заглушка M1)\n", serviceName)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
version: "3.9"
|
||||
|
||||
# Локальный стек разработки и тестирования.
|
||||
# В прод-среде сервисы поднимаются через systemd-юниты или podman-compose
|
||||
# с production-overlay. Здесь — dev-конфиг с минимальными настройками
|
||||
# и без секретов.
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16
|
||||
# В проде заменить на postgrespro/std-16 или registry.postgrespro.ru/pgpro/...
|
||||
container_name: bj-postgres
|
||||
environment:
|
||||
POSTGRES_USER: bj
|
||||
POSTGRES_PASSWORD: bj_dev
|
||||
POSTGRES_DB: bj
|
||||
ports:
|
||||
- "127.0.0.1:5432:5432"
|
||||
volumes:
|
||||
- bj-postgres-data:/var/lib/postgresql/data
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
container_name: bj-minio
|
||||
command: server /data --console-address ":9001"
|
||||
environment:
|
||||
MINIO_ROOT_USER: bj
|
||||
MINIO_ROOT_PASSWORD: bj_dev_minio
|
||||
ports:
|
||||
- "127.0.0.1:9000:9000"
|
||||
- "127.0.0.1:9001:9001"
|
||||
volumes:
|
||||
- bj-minio-data:/data
|
||||
|
||||
volumes:
|
||||
bj-postgres-data:
|
||||
bj-minio-data:
|
||||
@@ -0,0 +1,52 @@
|
||||
# Архитектура — обзор
|
||||
|
||||
Краткая выжимка из плана проекта. Полный план хранится у разработки в
|
||||
`/.claude/plans/precious-percolating-axolotl.md` (внешний документ).
|
||||
|
||||
## Что строим
|
||||
|
||||
Внутренний модуль брокера для M2M-перевода ценных бумаг через НРД
|
||||
(сервис MOEX MOST). Сейчас разрабатывается «для себя», но архитектура
|
||||
изначально закладывается под тиражирование другим компаниям.
|
||||
|
||||
## Состав
|
||||
|
||||
- `lk-gateway` — интеграция с ЛК клиента (ESIA Finance API V1).
|
||||
- `lk-emulator` — эмулятор ЛК на время, пока реальный ЛК не готов.
|
||||
- `m2m-core` — бизнес-логика и FSM сделки.
|
||||
- `nsd-adapter` — три транспорта к НРД (ИШ REST — основной, WS ONYX —
|
||||
резерв, ФШ — fallback) и маршрутизация по типам пакетов
|
||||
(`#M2MTR/#M2MTD/#M2MER/SUBBR/SUBER/SUB16/Справки/квитанции ЭДО`).
|
||||
- `crypto-service` — Java + КриптоПро JCP, КС1.
|
||||
- `notify` — уведомления (e-mail, Yandex Messenger 360, WS-push,
|
||||
webhook), архитектура плагинов.
|
||||
- `fansy-store` — принимающая БД для выгрузки от команды Fansy.
|
||||
- `admin-ui` — веб-интерфейс администратора и сотрудника депозитария.
|
||||
|
||||
## Стек
|
||||
|
||||
- Go 1.23, Java 21 (Liberica JDK), React + Vite + TypeScript.
|
||||
- PostgreSQL Pro Certified (на проде), MinIO.
|
||||
- Развёртывание — одна ВМ, podman-compose.
|
||||
- Класс СКЗИ — КС1 (КриптоПро CSP/JCP).
|
||||
|
||||
## Ключевые ограничения
|
||||
|
||||
- SLA: 5 мин/этап на старте, 2 мин/этап в проде. Регуляторный таймаут
|
||||
отсутствия ответа от Брокера 2 — 10 → 5 мин.
|
||||
- Дедлайн прод-релиза — **01.09.2026** (вступление 124-ФЗ + Указания ЦБ).
|
||||
- Реестр российского ПО (ПП-1236) — заявка на M5; стек и архитектура
|
||||
соответствуют.
|
||||
- Кодировка XML — windows-1251; формат `NSDDateTime` — только МСК-зона.
|
||||
|
||||
## Документация интеграций
|
||||
|
||||
- `docs/fansy-contract/v1/` — DDL и контракт данных для команды Fansy
|
||||
(мы передаём, ETL делают они).
|
||||
- `docs/lk-contract/v1/` — OpenAPI контракта с ЛК клиента.
|
||||
|
||||
## Развёртывание
|
||||
|
||||
- `deploy/docker-compose/docker-compose.yml` — dev-стек (PostgreSQL +
|
||||
MinIO).
|
||||
- `scripts/setup-dev-vm.sh` — подготовка dev-ВМ под РЕД ОС или Ubuntu.
|
||||
@@ -0,0 +1,33 @@
|
||||
# docs/fansy-contract/v1 — контракт данных с командой Fansy
|
||||
|
||||
ETL Fansy → принимающая БД (`fansy-store`) реализует **другая команда
|
||||
разработки**. С нашей стороны:
|
||||
|
||||
1. Спроектировать таблицы по требованиям документации НРД к данным M2M.
|
||||
2. Передать команде Fansy DDL и контракт данных.
|
||||
3. Согласовать тип load (UPSERT в staging), окна обновления, SLA на
|
||||
свежесть данных.
|
||||
4. Не давать ETL-роли DDL-прав в принимающей схеме.
|
||||
|
||||
Состав каталога (создаём в M1, отправляем в начале M2):
|
||||
|
||||
- `ddl/` — `*.sql` миграции PostgreSQL для всех таблиц.
|
||||
- `data-dictionary.md` — семантика каждого поля (источник в Fansy,
|
||||
nullable, единицы, примеры).
|
||||
- `etl-requirements.md` — требования к процессу выгрузки: тип load,
|
||||
расписание, способ записи, окна простоя, обработка ошибок,
|
||||
конфиденциальность.
|
||||
- `examples/` — пример заявки M2M «end-to-end», 5–10 тестовых клиентов
|
||||
и заявок для совместного приёмочного теста.
|
||||
|
||||
Минимальный набор таблиц (см. план):
|
||||
|
||||
- Депоненты / клиенты.
|
||||
- Документы инвестора (`IdentityDocumentCodeEnum`).
|
||||
- ИИС-договоры (`IIAContractTypeEnum ∈ {T12, T03}`).
|
||||
- Депо-счета и разделы (`AccountId`, `SectionId`, `DeponentCode`).
|
||||
- Реквизиты расчётов (ИНН депозитария).
|
||||
- Портфели и остатки (Whole / Fractional, `IsolationStatus = SGDN`).
|
||||
- Справочник ЦБ (`SecurityCode`, `ISIN`, `Classification`, `Category`).
|
||||
- Контрагенты-участники сервиса MOST (Справочник пользователей).
|
||||
- Audit / staging-таблицы для каждой основной.
|
||||
@@ -0,0 +1,18 @@
|
||||
# docs/lk-contract/v1 — контракт с ЛК клиента (ESIA Finance)
|
||||
|
||||
ЛК клиента работает на платформе **ESIA Finance**, контракт описан
|
||||
в `DOC/API ЛК ЕСИА.pdf` (`/api/v1/back_office/...`, Basic HTTP, JSON,
|
||||
UTF-8).
|
||||
|
||||
На этапе M1 в `lk-emulator` мы воспроизводим этот контракт для запуска
|
||||
сквозного потока. Реальный ЛК подключится по тому же контракту, без
|
||||
правок на нашей стороне.
|
||||
|
||||
В этом каталоге будут:
|
||||
|
||||
- `openapi.yaml` — наш OpenAPI-контракт `lk-gateway`, согласованный
|
||||
с командой ЛК.
|
||||
- `examples/` — примеры заявлений и ответов.
|
||||
- `changelog.md` — версионирование контракта.
|
||||
|
||||
Реализация — задача M1.
|
||||
@@ -0,0 +1,8 @@
|
||||
# internal/fansystore — Go-репозиторий чтения нашей принимающей БД
|
||||
|
||||
ETL Fansy → принимающая БД делает **отдельная команда**. Здесь только
|
||||
типизированный Go-доступ на чтение/обогащение из `m2m-core`.
|
||||
|
||||
DDL и контракт данных — `docs/fansy-contract/v1/`.
|
||||
|
||||
Реализация — задача M2 (см. план).
|
||||
@@ -0,0 +1,24 @@
|
||||
# internal/m2m — доменные модели сообщений M2M
|
||||
|
||||
Go-модели, генерируемые/выровненные по XSD из `DOC/M2MSchemas_260408/`
|
||||
(namespace `http://nsd.ru/schemas/m2m/...`, version `2026-04-08`).
|
||||
|
||||
Состав:
|
||||
|
||||
- `M2MTransferRequest` — запрос на перевод.
|
||||
- `M2MTransferDecision` — решение принимающей стороны.
|
||||
- `M2MTransferResponse` — тех. ответ НРД (`StatusCode ∈ {INFO, ERROR}`).
|
||||
- `M2MTransferHandbook(+Request)` — справочник участников.
|
||||
- `M2MTransferParticipantForm` — карточка участника.
|
||||
|
||||
Точные ограничения (валидаторы):
|
||||
|
||||
- `ReferenceId` — длина 16, pattern `M2M[A-Z0-9]{13}`.
|
||||
- `DeponentCode` — до 12 символов, `[A-Z0-9]*`.
|
||||
- `ISIN` — длина 12, `[A-Z]{2}[A-Z0-9]{9}[0-9]`.
|
||||
- `OrganizationINN` — ровно 10 цифр.
|
||||
- `IIAContractType` — `T12 | T03`.
|
||||
- `SecurityClassification` — `BOND | SHAR | MFUN`.
|
||||
- `IsolationStatus` — единственное значение `SGDN`.
|
||||
|
||||
Реализация — задача M1 (см. план).
|
||||
@@ -0,0 +1,15 @@
|
||||
# internal/notify — провайдеры уведомлений
|
||||
|
||||
Архитектура — плагины под единый интерфейс `Notifier`. Реализации в
|
||||
конфиге включаются/выключаются без изменений в коде:
|
||||
|
||||
- `smtp` — внутренняя корпоративная почта.
|
||||
- `yandex360` — Yandex Messenger через Yandex 360 для бизнеса
|
||||
(используем готового бота заказчика).
|
||||
- `webhook` — универсальный POST по URL, для лёгкого подключения
|
||||
других систем при тиражировании.
|
||||
- `wspush` — push-уведомления в `admin-ui` через WebSocket.
|
||||
- (опционально) `telegram`, `mattermost`, `rocketchat` — заглушки с
|
||||
примером расширения.
|
||||
|
||||
Реализация — задача M4 (см. план).
|
||||
@@ -0,0 +1,14 @@
|
||||
# internal/nsdxml — сериализация и парсинг XML по правилам НРД
|
||||
|
||||
Особенности, которые этот пакет обязан учитывать:
|
||||
|
||||
- **Кодировка `windows-1251`** на чтение и запись (XML-объявление и тело).
|
||||
Для конвертации — `golang.org/x/text/encoding/charmap.Windows1251`.
|
||||
- **Тип `NSDDateTime`** — формат `YYYY-MM-DDThh:mm:ss(МСК[+/-N])`,
|
||||
pattern из XSD:
|
||||
`[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})?\)`.
|
||||
Только зона МСК, опциональный сдвиг.
|
||||
- **Каноникализация `xml-exc-c14n`** для проверки совпадения с эталоном.
|
||||
- **Round-trip**: `Marshal(Unmarshal(x)) == x` после канонизации.
|
||||
|
||||
Реализация — задача M1 (см. план).
|
||||
@@ -0,0 +1,56 @@
|
||||
# scripts — служебные скрипты
|
||||
|
||||
## setup-dev-vm.sh
|
||||
|
||||
Первичная подготовка dev-ВМ.
|
||||
|
||||
Поддерживаемые ОС:
|
||||
|
||||
- **РЕД ОС 7.x** — целевая прод-ОС.
|
||||
- **Ubuntu 22.04+** / **Debian 12+** — бюджетная альтернатива для
|
||||
разработки и для компаний без лицензий на сертифицированные ОС.
|
||||
- **Astra Linux** (deb-семейство) — поддерживается базовый сценарий.
|
||||
- RHEL-совместимые (Rocky, Alma) — для разработки.
|
||||
|
||||
Что ставит:
|
||||
|
||||
- базовый dev-стек (git, make, jq, xmlstarlet и т. п.),
|
||||
- Podman + podman-compose,
|
||||
- Go 1.23,
|
||||
- Liberica JDK 21 (BellSoft),
|
||||
- Node.js 20 LTS,
|
||||
- Claude Code CLI (`@anthropic-ai/claude-code`).
|
||||
|
||||
Что готовит:
|
||||
|
||||
- пользователя `dev` с домашней директорией, без sudo по умолчанию,
|
||||
- рабочий каталог `/srv/dev`,
|
||||
- bash-историю с timestamp для аудита,
|
||||
- `/etc/profile.d/go.sh` для PATH к Go.
|
||||
|
||||
Запуск:
|
||||
|
||||
```bash
|
||||
sudo bash scripts/setup-dev-vm.sh
|
||||
```
|
||||
|
||||
Тонкая настройка через переменные окружения — см. шапку скрипта.
|
||||
|
||||
Идемпотентен — повторный запуск ничего не ломает.
|
||||
|
||||
### Что НЕ делает скрипт
|
||||
|
||||
Эти шаги — вручную, по мере получения артефактов:
|
||||
|
||||
1. Установка КриптоПро CSP и КриптоПро JCP под целевую ОС.
|
||||
2. Установка дистрибутива Интеграционного шлюза НРД.
|
||||
3. Импорт тестовых сертификатов GUEST/TEST3 (ГОСТ + RSA).
|
||||
4. Настройка исходящего файрвола / прокси (whitelist для НРД,
|
||||
git.zetit.ru, npmjs, golang, anthropic).
|
||||
|
||||
### Прод-ограничения
|
||||
|
||||
Скрипт удобен для разработки на любой из перечисленных ОС, но для
|
||||
прод-стенда в финансовом секторе требуется **сертифицированная РЕД ОС
|
||||
или Astra SE** + лицензированный **КриптоПро КС1**. Ubuntu/Debian/Rocky
|
||||
для прода финсектора не подходят.
|
||||
Executable
+373
@@ -0,0 +1,373 @@
|
||||
#!/usr/bin/env bash
|
||||
# Скрипт первичной подготовки dev-ВМ для проекта Bridge and Join's
|
||||
# (сервис M2M-перевода ЦБ через НРД).
|
||||
#
|
||||
# Поддерживаемые ОС:
|
||||
# - РЕД ОС 7.x — целевая прод-ОС (вариант с бюджетом на лицензии)
|
||||
# - Ubuntu 22.04+ — бюджетная альтернатива для разработки и для
|
||||
# компаний, у которых ещё нет лицензий на РЕД ОС
|
||||
# (для прод-сертификации в финсекторе всё равно
|
||||
# потребуется РЕД ОС / Astra SE с сертификатом ФСТЭК)
|
||||
#
|
||||
# Что делает:
|
||||
# - определяет ОС и пакетный менеджер;
|
||||
# - устанавливает базовый dev-стек (Git, Make, jq, xmlstarlet, ...);
|
||||
# - устанавливает Go 1.23, Liberica JDK 21, Node.js 20 LTS, Podman;
|
||||
# - устанавливает Claude Code CLI;
|
||||
# - создаёт пользователя dev и каталог /srv/dev;
|
||||
# - готовит безопасный shell-history с timestamp.
|
||||
#
|
||||
# Запуск (под root или через sudo):
|
||||
# sudo bash scripts/setup-dev-vm.sh
|
||||
#
|
||||
# Переменные окружения для тонкой настройки:
|
||||
# GO_VERSION — версия Go (по умолчанию 1.23.4)
|
||||
# JDK_VERSION — версия Liberica JDK (по умолчанию 21)
|
||||
# NODE_VERSION — версия Node (по умолчанию 20)
|
||||
# DEV_USER — имя пользователя для разработки (по умолчанию dev)
|
||||
# DEV_HOME — домашняя директория dev (по умолчанию /home/dev)
|
||||
# WORKSPACE_ROOT — корень рабочих репо (по умолчанию /srv/dev)
|
||||
# SKIP_USER — 1, чтобы не создавать пользователя
|
||||
# SKIP_CLAUDE — 1, чтобы не ставить Claude Code CLI
|
||||
#
|
||||
# Скрипт идемпотентен — повторный запуск не ломает то, что уже сделано.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# Параметры
|
||||
# --------------------------------------------------------------------- #
|
||||
GO_VERSION="${GO_VERSION:-1.23.4}"
|
||||
JDK_VERSION="${JDK_VERSION:-21}"
|
||||
NODE_VERSION="${NODE_VERSION:-20}"
|
||||
DEV_USER="${DEV_USER:-dev}"
|
||||
DEV_HOME="${DEV_HOME:-/home/${DEV_USER}}"
|
||||
WORKSPACE_ROOT="${WORKSPACE_ROOT:-/srv/dev}"
|
||||
SKIP_USER="${SKIP_USER:-0}"
|
||||
SKIP_CLAUDE="${SKIP_CLAUDE:-0}"
|
||||
|
||||
REPO_URL="https://git.zetit.ru/zuevav/Bridge-and-Join-s.git"
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# Хелперы
|
||||
# --------------------------------------------------------------------- #
|
||||
log() { printf '[%s] %s\n' "$(date +'%Y-%m-%d %H:%M:%S')" "$*"; }
|
||||
die() { printf '[ОШИБКА] %s\n' "$*" >&2; exit 1; }
|
||||
need_root() { [[ "$EUID" -eq 0 ]] || die "Нужны права root. Запусти через sudo."; }
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# 0. Предусловия — определение ОС и менеджера пакетов
|
||||
# --------------------------------------------------------------------- #
|
||||
need_root
|
||||
|
||||
if [[ ! -f /etc/os-release ]]; then
|
||||
die "Файл /etc/os-release не найден. Проверь, что ОС поддерживает FHS."
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release
|
||||
|
||||
OS_FAMILY="" # rpm | deb
|
||||
OS_HUMAN=""
|
||||
|
||||
case "${ID:-}" in
|
||||
redos)
|
||||
OS_FAMILY="rpm"
|
||||
OS_HUMAN="РЕД ОС ${VERSION_ID:-?}"
|
||||
;;
|
||||
rhel|centos|rocky|almalinux|fedora)
|
||||
OS_FAMILY="rpm"
|
||||
OS_HUMAN="${PRETTY_NAME:-RHEL-совместимая}"
|
||||
log "ВНИМАНИЕ: ОС ${OS_HUMAN} — для разработки подходит, для прод-сертификации в финсекторе нужна РЕД ОС / Astra SE."
|
||||
;;
|
||||
ubuntu|debian)
|
||||
OS_FAMILY="deb"
|
||||
OS_HUMAN="${PRETTY_NAME:-${ID} ${VERSION_ID:-?}}"
|
||||
log "ОС ${OS_HUMAN} — бюджетный вариант для разработки. Для прода в финсекторе нужна РЕД ОС / Astra SE с сертификатом ФСТЭК."
|
||||
;;
|
||||
astra)
|
||||
OS_FAMILY="deb"
|
||||
OS_HUMAN="Astra Linux ${VERSION_ID:-?}"
|
||||
;;
|
||||
*)
|
||||
log "ВНИМАНИЕ: ОС определена как ${ID:-неизвестно} ${VERSION_ID:-?}."
|
||||
if command -v dnf >/dev/null 2>&1 || command -v yum >/dev/null 2>&1; then
|
||||
OS_FAMILY="rpm"
|
||||
elif command -v apt-get >/dev/null 2>&1; then
|
||||
OS_FAMILY="deb"
|
||||
else
|
||||
die "Не удалось определить пакетный менеджер. Поддерживаются dnf/yum (РЕД ОС, RHEL) и apt (Ubuntu, Debian, Astra)."
|
||||
fi
|
||||
log "Пробуем как ${OS_FAMILY}-совместимую."
|
||||
;;
|
||||
esac
|
||||
|
||||
log "ОС: ${OS_HUMAN}, семейство: ${OS_FAMILY}"
|
||||
|
||||
PKG_INSTALL=""
|
||||
PKG_UPDATE=""
|
||||
case "${OS_FAMILY}" in
|
||||
rpm)
|
||||
if command -v dnf >/dev/null 2>&1; then PKG_INSTALL="dnf install -y"; PKG_UPDATE="dnf -y makecache"
|
||||
elif command -v yum >/dev/null 2>&1; then PKG_INSTALL="yum install -y"; PKG_UPDATE="yum -y makecache"
|
||||
else die "Не найден dnf/yum"
|
||||
fi
|
||||
;;
|
||||
deb)
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
PKG_INSTALL="apt-get install -y --no-install-recommends"
|
||||
PKG_UPDATE="apt-get update -y"
|
||||
;;
|
||||
esac
|
||||
|
||||
log "Обновление кэша пакетов"
|
||||
${PKG_UPDATE}
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# 1. Базовый системный стек
|
||||
# --------------------------------------------------------------------- #
|
||||
log "Шаг 1/8: установка базовых пакетов"
|
||||
case "${OS_FAMILY}" in
|
||||
rpm)
|
||||
${PKG_INSTALL} \
|
||||
git make curl wget tar gzip unzip ca-certificates \
|
||||
jq xmlstarlet libxml2 \
|
||||
gcc gcc-c++ binutils \
|
||||
python3 python3-pip \
|
||||
postgresql-libs \
|
||||
openssl-libs
|
||||
;;
|
||||
deb)
|
||||
${PKG_INSTALL} \
|
||||
git make curl wget tar gzip unzip ca-certificates \
|
||||
jq xmlstarlet libxml2-utils \
|
||||
build-essential \
|
||||
python3 python3-pip python3-venv \
|
||||
libpq5 \
|
||||
libssl3 \
|
||||
gnupg lsb-release software-properties-common
|
||||
;;
|
||||
esac
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# 2. Podman + podman-compose
|
||||
# --------------------------------------------------------------------- #
|
||||
log "Шаг 2/8: установка Podman и podman-compose"
|
||||
case "${OS_FAMILY}" in
|
||||
rpm)
|
||||
${PKG_INSTALL} podman podman-docker || true
|
||||
;;
|
||||
deb)
|
||||
${PKG_INSTALL} podman || true
|
||||
# podman-docker может отсутствовать — не критично
|
||||
apt-get install -y --no-install-recommends podman-docker 2>/dev/null || true
|
||||
;;
|
||||
esac
|
||||
|
||||
if ! command -v podman-compose >/dev/null 2>&1; then
|
||||
pip3 install --quiet podman-compose || \
|
||||
log "ВНИМАНИЕ: не удалось установить podman-compose через pip3. Поставь вручную."
|
||||
fi
|
||||
|
||||
# Включаем сокет podman, чтобы клиенты, ожидающие docker.sock, работали без правок
|
||||
systemctl enable --now podman.socket 2>/dev/null || true
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# 3. Go
|
||||
# --------------------------------------------------------------------- #
|
||||
log "Шаг 3/8: установка Go ${GO_VERSION}"
|
||||
GO_TARBALL="go${GO_VERSION}.linux-amd64.tar.gz"
|
||||
GO_URL="https://go.dev/dl/${GO_TARBALL}"
|
||||
|
||||
if [[ -d /usr/local/go && -x /usr/local/go/bin/go ]]; then
|
||||
CURRENT_GO_VER="$(/usr/local/go/bin/go version | awk '{print $3}' | sed 's/go//')"
|
||||
if [[ "${CURRENT_GO_VER}" == "${GO_VERSION}" ]]; then
|
||||
log "Go ${GO_VERSION} уже установлен"
|
||||
else
|
||||
log "Найден Go ${CURRENT_GO_VER}, переустанавливаем на ${GO_VERSION}"
|
||||
rm -rf /usr/local/go
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -d /usr/local/go ]]; then
|
||||
TMP_TAR="/tmp/${GO_TARBALL}"
|
||||
wget -q --show-progress -O "${TMP_TAR}" "${GO_URL}"
|
||||
tar -C /usr/local -xzf "${TMP_TAR}"
|
||||
rm -f "${TMP_TAR}"
|
||||
fi
|
||||
|
||||
cat > /etc/profile.d/go.sh <<'EOF'
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
export GOPATH=$HOME/go
|
||||
export PATH=$PATH:$GOPATH/bin
|
||||
EOF
|
||||
chmod 0644 /etc/profile.d/go.sh
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# 4. Liberica JDK
|
||||
# --------------------------------------------------------------------- #
|
||||
log "Шаг 4/8: установка Liberica JDK ${JDK_VERSION}"
|
||||
case "${OS_FAMILY}" in
|
||||
rpm)
|
||||
if [[ ! -f /etc/yum.repos.d/bellsoft.repo ]]; then
|
||||
cat > /etc/yum.repos.d/bellsoft.repo <<'EOF'
|
||||
[bellsoft]
|
||||
name=BellSoft Repository
|
||||
baseurl=https://yum.bell-sw.com/
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.bell-sw.com/pki/GPG-KEY-bellsoft
|
||||
EOF
|
||||
fi
|
||||
${PKG_INSTALL} "bellsoft-java${JDK_VERSION}" || \
|
||||
log "ВНИМАНИЕ: не удалось установить bellsoft-java${JDK_VERSION}. Альтернатива — скачать tar.gz с https://bell-sw.com/pages/downloads/."
|
||||
;;
|
||||
deb)
|
||||
if [[ ! -f /etc/apt/sources.list.d/bellsoft.list ]]; then
|
||||
curl -fsSL https://download.bell-sw.com/pki/GPG-KEY-bellsoft \
|
||||
| gpg --dearmor -o /usr/share/keyrings/bellsoft.gpg
|
||||
echo "deb [signed-by=/usr/share/keyrings/bellsoft.gpg] https://apt.bell-sw.com/ stable main" \
|
||||
> /etc/apt/sources.list.d/bellsoft.list
|
||||
apt-get update -y
|
||||
fi
|
||||
${PKG_INSTALL} "bellsoft-java${JDK_VERSION}-full" || \
|
||||
${PKG_INSTALL} "bellsoft-java${JDK_VERSION}" || \
|
||||
log "ВНИМАНИЕ: не удалось установить bellsoft-java${JDK_VERSION}. Альтернатива — скачать tar.gz с https://bell-sw.com/pages/downloads/."
|
||||
;;
|
||||
esac
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# 5. Node.js LTS (для admin-ui и Claude Code CLI)
|
||||
# --------------------------------------------------------------------- #
|
||||
log "Шаг 5/8: установка Node.js ${NODE_VERSION} LTS"
|
||||
need_install_node=1
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
CUR_NODE_MAJOR="$(node --version | sed 's/v//;s/\..*//')"
|
||||
if [[ "${CUR_NODE_MAJOR}" == "${NODE_VERSION}" ]]; then
|
||||
log "Node.js ${NODE_VERSION} уже установлен"
|
||||
need_install_node=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${need_install_node}" == "1" ]]; then
|
||||
case "${OS_FAMILY}" in
|
||||
rpm)
|
||||
curl -fsSL "https://rpm.nodesource.com/setup_${NODE_VERSION}.x" | bash -
|
||||
${PKG_INSTALL} nodejs
|
||||
;;
|
||||
deb)
|
||||
curl -fsSL "https://deb.nodesource.com/setup_${NODE_VERSION}.x" | bash -
|
||||
${PKG_INSTALL} nodejs
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# 6. Claude Code CLI
|
||||
# --------------------------------------------------------------------- #
|
||||
if [[ "${SKIP_CLAUDE}" != "1" ]]; then
|
||||
log "Шаг 6/8: установка Claude Code CLI"
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
else
|
||||
log "Шаг 6/8: пропуск установки Claude Code CLI (SKIP_CLAUDE=1)"
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# 7. Пользователь dev и рабочая директория
|
||||
# --------------------------------------------------------------------- #
|
||||
if [[ "${SKIP_USER}" != "1" ]]; then
|
||||
log "Шаг 7/8: подготовка пользователя ${DEV_USER}"
|
||||
if ! id -u "${DEV_USER}" >/dev/null 2>&1; then
|
||||
useradd -m -s /bin/bash -d "${DEV_HOME}" "${DEV_USER}"
|
||||
log "Создан пользователь ${DEV_USER}"
|
||||
else
|
||||
log "Пользователь ${DEV_USER} уже существует"
|
||||
fi
|
||||
|
||||
mkdir -p "${WORKSPACE_ROOT}"
|
||||
chown "${DEV_USER}:${DEV_USER}" "${WORKSPACE_ROOT}"
|
||||
|
||||
HIST_SNIPPET="${DEV_HOME}/.bashrc.d-history"
|
||||
cat > "${HIST_SNIPPET}" <<'EOF'
|
||||
# История с timestamp и общая для всех сессий — для аудита.
|
||||
export HISTTIMEFORMAT="%F %T "
|
||||
export HISTSIZE=10000
|
||||
export HISTFILESIZE=20000
|
||||
shopt -s histappend
|
||||
PROMPT_COMMAND="history -a; ${PROMPT_COMMAND:-}"
|
||||
EOF
|
||||
chown "${DEV_USER}:${DEV_USER}" "${HIST_SNIPPET}"
|
||||
|
||||
if ! grep -q "bashrc.d-history" "${DEV_HOME}/.bashrc" 2>/dev/null; then
|
||||
echo "[ -f ${HIST_SNIPPET} ] && . ${HIST_SNIPPET}" >> "${DEV_HOME}/.bashrc"
|
||||
fi
|
||||
|
||||
if ! grep -q "/usr/local/go/bin" "${DEV_HOME}/.bashrc" 2>/dev/null; then
|
||||
cat >> "${DEV_HOME}/.bashrc" <<'EOF'
|
||||
[ -f /etc/profile.d/go.sh ] && . /etc/profile.d/go.sh
|
||||
EOF
|
||||
fi
|
||||
else
|
||||
log "Шаг 7/8: пропуск подготовки пользователя (SKIP_USER=1)"
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# 8. Финальные проверки
|
||||
# --------------------------------------------------------------------- #
|
||||
log "Шаг 8/8: проверка установленных версий"
|
||||
{
|
||||
printf 'git: '; git --version
|
||||
printf 'make: '; make --version | head -n1
|
||||
printf 'jq: '; jq --version
|
||||
printf 'xmlstarlet: '; xmlstarlet --version | head -n1
|
||||
printf 'podman: '; podman --version 2>/dev/null || echo "(не установлен)"
|
||||
printf 'podman-compose:'; podman-compose --version 2>/dev/null || echo "(не установлен)"
|
||||
printf 'go: '; /usr/local/go/bin/go version
|
||||
printf 'java: '; java -version 2>&1 | head -n1
|
||||
printf 'node: '; node --version 2>/dev/null || echo "(не установлен)"
|
||||
printf 'npm: '; npm --version 2>/dev/null || echo "(не установлен)"
|
||||
if [[ "${SKIP_CLAUDE}" != "1" ]]; then
|
||||
printf 'claude: '; claude --version 2>/dev/null || echo "(не установлен или требует первого запуска)"
|
||||
fi
|
||||
} || true
|
||||
|
||||
cat <<EOF
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
Подготовка dev-ВМ завершена.
|
||||
ОС: ${OS_HUMAN}
|
||||
|
||||
Дальше — под пользователем ${DEV_USER}:
|
||||
|
||||
su - ${DEV_USER}
|
||||
cd ${WORKSPACE_ROOT}
|
||||
|
||||
# Положи свой публичный SSH-ключ в ~/.ssh/id_ed25519.pub
|
||||
# и добавь его в git.zetit.ru → Settings → SSH Keys
|
||||
|
||||
git clone ${REPO_URL}
|
||||
cd Bridge-and-Join-s
|
||||
|
||||
make ci # локальный прогон линтера, тестов и сборки
|
||||
make compose-up # PostgreSQL + MinIO для разработки
|
||||
|
||||
# Запуск Claude Code из корня репо:
|
||||
claude
|
||||
|
||||
Дополнительные шаги, которые НЕ автоматизированы (делаются вручную при
|
||||
получении соответствующих артефактов от заказчика):
|
||||
|
||||
1. Установка КриптоПро CSP и КриптоПро JCP под целевую ОС.
|
||||
2. Установка дистрибутива Интеграционного шлюза НРД.
|
||||
3. Импорт тестовых сертификатов GUEST/TEST3 (ГОСТ + RSA).
|
||||
4. Конфигурирование исходящего прокси/whitelist для git.zetit.ru,
|
||||
gost-*.nsd.ru, rsa-*.nsd.ru, registry.npmjs.org, proxy.golang.org,
|
||||
api.anthropic.com.
|
||||
|
||||
ВАЖНО про прод:
|
||||
Эта ВМ годится для разработки и тестирования. Для прод-стенда в
|
||||
финсекторе обязательны РЕД ОС / Astra SE с сертификатом ФСТЭК и
|
||||
лицензированный КриптоПро класса КС1 — Ubuntu/Debian для прода
|
||||
финсектора не подходят.
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
EOF
|
||||
@@ -0,0 +1,24 @@
|
||||
# services/crypto-service — Java + КриптоПро JCP
|
||||
|
||||
Изолированный сервис для криптографических операций по ГОСТ:
|
||||
|
||||
- проверка подписи входящих квитанций ЭДО, ответов НРД и сообщений
|
||||
от брокеров;
|
||||
- серверная подпись действий оператора в `admin-ui` (ради соблюдения
|
||||
SLA 2 мин — клиентский КриптоПро на АРМ исключён);
|
||||
- резервный канал отправки в НРД через WS ONYX напрямую (когда ИШ не
|
||||
задействован — упаковка и подпись на нашей стороне);
|
||||
- криптографические проверки целостности эталонов в MinIO.
|
||||
|
||||
Стек: Java 21 (Liberica JDK), Apache Santuario с ГОСТ-патчем, КриптоПро
|
||||
JCP. КриптоПро CSP ставится на ВМ. Класс СКЗИ — **КС1** (программная
|
||||
защита, без HSM).
|
||||
|
||||
Канал общения с Go-ядром — gRPC по Unix Domain Socket (без сетевого хопа,
|
||||
минимальная задержка).
|
||||
|
||||
Архитектурно сохранена `Provider`-абстракция (Валидата JCP / VipNet и
|
||||
прочее) — для тиражирования другим компаниям. На M1 реализован только
|
||||
КриптоПро.
|
||||
|
||||
Реализация — задача M1-M2 (заглушка gRPC) и M3-M4 (полный функционал).
|
||||
@@ -0,0 +1,18 @@
|
||||
# web/admin-ui — веб-интерфейс администратора и сотрудника депозитария
|
||||
|
||||
Стек: React + Vite + TypeScript. Реализация — M3.
|
||||
|
||||
Разделы:
|
||||
|
||||
- Журнал входящих и исходящих сообщений (фильтры по GUID / инвестору /
|
||||
статусу / периоду / типу пакета).
|
||||
- Ручное согласование (manual-approval) сделок с подписью оператора
|
||||
серверной ЭП через `crypto-service`.
|
||||
- Раздел «Сертификаты» — обновление сертификатов для подписи (закрытые
|
||||
ключи через UI не выгружаются), сроки, алерты, аудит.
|
||||
- Раздел «Уведомления» — включение и настройка провайдеров плагинов.
|
||||
- SLA-дашборд по этапам.
|
||||
- Переключатель канала отправки (ИШ / ONYX / ФШ) для тестов.
|
||||
|
||||
Роли: Администратор, Администратор СКЗИ, Сотрудник депозитария,
|
||||
Оператор, Аудитор.
|
||||
Reference in New Issue
Block a user