9e6e95f431
- internal/m2mcore/fsm.go: конечный автомат с переходами Draft → Validated → SubmittedToNSD → AwaitingDecision → Confirmed → AwaitingSUB16 → Done, ветки Rejected/TimedOut/ManualApproval - internal/m2mcore/deal.go: доменная модель Deal с методами Validate/Submit/ReceiveDecision/Timeout/SendToManualApproval/ApproveManually/RejectManually/CompleteSUB16, журнал событий - internal/m2mcore/uuid.go: генератор UUID v4 без внешних зависимостей (crypto/rand) - internal/m2mcore/repo.go: порт Repository + MemoryRepository с идемпотентным Create по GUID - internal/m2mcore/ports.go: порты NSDSender/LKCallbackClient/CryptoVerifier/FansyStore с no-op заглушками для M1 - internal/m2mcore/enrich.go: EnrichRequest — сборка M2MTransferRequest из ClaimInput + Fansy, генерация ReferenceID по каждой ЦБ - internal/m2mcore/metrics.go: порт Recorder + MemoryRecorder в Prometheus-text формате - cmd/m2m-core/main.go: HTTP-сервер с /healthz и /metrics, graceful shutdown - migrations/m2m-core/001__deals.sql: схема для PostgreSQL-Repository (для M2) Покрытие: 63.1%. make ci зелёный. Без внешних Go-зависимостей (pgx и prometheus подключим в M2, когда прокси zetit откроет Go-модули). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
50 lines
2.7 KiB
Markdown
50 lines
2.7 KiB
Markdown
# internal/m2mcore — ядро бизнес-логики M2M
|
||
|
||
Конечный автомат сделки, репозиторий, идемпотентность по GUID,
|
||
сборка `M2MTransferRequest` из заявки ЛК + данных Fansy, метрики SLA.
|
||
|
||
## Состав
|
||
|
||
- `fsm.go` — состояния FSM и матрица разрешённых переходов
|
||
(`Draft → Validated → SubmittedToNSD → AwaitingDecision → Confirmed →
|
||
AwaitingSUB16 → Done`, ветки `Rejected`, `TimedOut`,
|
||
`ManualApproval`).
|
||
- `deal.go` — доменная модель `Deal` с явными методами переходов
|
||
(`Validate`, `Submit`, `ReceiveDecision`, `Timeout`,
|
||
`SendToManualApproval`, `ApproveManually`, `RejectManually`,
|
||
`CompleteSUB16`). Каждый переход проверяет текущее состояние,
|
||
пишет историю в `Stages` и фиксирует событие в журнале.
|
||
- `uuid.go` — генератор UUID v4 без внешних зависимостей.
|
||
- `repo.go` — порт `Repository` + in-memory реализация
|
||
`MemoryRepository` с идемпотентным `Create` (по GUID возвращает
|
||
существующую сделку). PostgreSQL-реализация — задача M2 (миграция
|
||
лежит в `migrations/m2m-core/001__deals.sql`).
|
||
- `ports.go` — порты к внешним системам (`NSDSender`,
|
||
`LKCallbackClient`, `CryptoVerifier`, `FansyStore`) с no-op
|
||
заглушками для M1.
|
||
- `enrich.go` — функция `EnrichRequest`: из `ClaimInput` (заявка ЛК)
|
||
+ данных Fansy собирает валидный `M2MTransferRequest`, генерирует
|
||
`GUID` и `ReferenceID` по каждой ЦБ.
|
||
- `metrics.go` — порт `Recorder` + `MemoryRecorder`, отдающий
|
||
Prometheus text-format. В M2 заменим на `prometheus/client_golang`,
|
||
когда прокси откроет Go-модули.
|
||
|
||
## Зависимости
|
||
|
||
Только stdlib и собственные пакеты `internal/m2m`, `internal/nsdxml`.
|
||
Никаких внешних модулей.
|
||
|
||
## Тесты
|
||
|
||
- `fsm_test.go` — переходы и терминальные состояния.
|
||
- `repo_test.go` — идемпотентность по GUID, фильтры в `List`.
|
||
- `uuid_test.go` — формат UUID v4 и `ReferenceID`.
|
||
- `metrics_test.go` — Prometheus-текст.
|
||
|
||
## Сервис cmd/m2m-core
|
||
|
||
`cmd/m2m-core/main.go` — HTTP-сервер с `/healthz` и `/metrics`,
|
||
in-memory репозиторий, no-op порты. Адрес из `BJ_HTTP_ADDR`
|
||
(по умолчанию `:8081`). В M2 будет заменено на реальные клиенты НРД
|
||
и crypto-service.
|