Files
Bridge-and-Join-s/internal/lkgateway/types.go
T
zuevav 9737c787f9 feat: живой цикл M2M с НРД + мастер установки ключа на флешку
Инфраструктура M2M (живой обмен с НРД через ИШ):
- обработка M2MTransferResponse: ERROR(M2Mxx) → заявка Отклонена, сохранение
  ответа; INFO → ждём Decision; идемпотентность поллера
- fallback-корреляция ответов с нулевым GUID (M2M14/M2M17) по FIFO
- сырой XML ответа НРД в карточке заявки (для пересылки в ТП)
- тестовый пакет роботу приведён к эталону m2m_robot_samples (CostInfo=Yes,
  4 бумаги, IsolationStatus, DocumentSeries=сценарий); override паспорта
- редирект из теста сразу в карточку заявки

Мастер установки ключа Валидаты на флешку (admin/setup/keywizard):
- пошаговый: загрузка .7z+пароль → выбор флешки → запись → справочник
  сертификатов (CRL) → перезапуск+проверка ИШ → готово
- привилегированный воркер (bj-keymedia) в host-namespace через файл-обмен,
  bj-server остаётся в песочнице
- сохранение структуры профиля архива (spr<N>), перечисление съёмных USB

Прочее:
- пакет-доказательство для ТП НРД + форма регистрации участника M2M
- эталонные образцы робота (DOC/m2m_robot_samples)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 00:03:21 +03:00

222 lines
8.6 KiB
Go

// Package lkgateway реализует REST API контракта ESIA Finance V1
// (docs/lk-contract/v1/openapi.yaml) и admin web-интерфейс.
package lkgateway
import (
"time"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/m2m"
)
// CreateClaimRequest — DTO входа POST /api/v1/back_office/claims/.
type CreateClaimRequest struct {
Investor Investor `json:"investor"`
TransferringDepositoryINN string `json:"transferring_depository_inn"`
ReceivingDepositoryINN string `json:"receiving_depository_inn"`
CostInfo CostInfo `json:"cost_info"`
IIAAgreement *IIAAgreement `json:"iia_agreement,omitempty"`
Securities []ClaimSec `json:"securities"`
SignedDocument string `json:"signed_document"`
SignatureFormat string `json:"signature_format"`
// ReceiverCodeOverride — если задан, переопределяет код получателя
// (Header.ReceiverCode). Используется для тестовых пакетов роботу НРД
// (MC0012500000). Пусто = берётся defaultReceiver.
ReceiverCodeOverride string `json:"receiver_code_override,omitempty"`
// InvestorDocumentOverride — если задан, переопределяет документ инвестора
// из анкеты. Используется тестом с роботом НРД (серия ДУЛ = код сценария).
InvestorDocumentOverride *Document `json:"investor_document_override,omitempty"`
}
// Investor — анкета.
type Investor struct {
ID string `json:"id,omitempty"`
LastName string `json:"last_name"`
FirstName string `json:"first_name"`
MiddleName string `json:"middle_name,omitempty"`
Document Document `json:"document"`
}
// Document — удостоверение личности.
type Document struct {
DocumentType string `json:"document_type"`
Series string `json:"series,omitempty"`
Number string `json:"number"`
}
// CostInfo — choice yes|no.
type CostInfo struct {
Yes *CostInfoYes `json:"yes,omitempty"`
No *struct{} `json:"no,omitempty"`
}
// CostInfoYes — учёт ведётся, с кодом депонента-источника.
type CostInfoYes struct {
Code string `json:"code"`
}
// IIAAgreement — реквизиты договора ИИС.
type IIAAgreement struct {
AgreementType string `json:"agreement_type"`
AgreementNumber string `json:"agreement_number"`
AgreementDate string `json:"agreement_date"`
BrokerINN string `json:"broker_inn"`
}
// ClaimSec — одна ЦБ в заявке.
type ClaimSec struct {
SecurityCode string `json:"security_code"`
SecurityDetails SecurityDetails `json:"security_details"`
Quantity Quantity `json:"quantity"`
SettlementAccounts []SettlementAccount `json:"settlement_accounts"`
}
// SecurityDetails — choice isin|security_info.
type SecurityDetails struct {
ISIN string `json:"isin,omitempty"`
SecurityInfo *SecurityInfo `json:"security_info,omitempty"`
}
// SecurityInfo — описание ЦБ без ISIN.
type SecurityInfo struct {
Classification string `json:"classification"`
Category string `json:"category"`
SecurityType string `json:"security_type,omitempty"`
SecuritySeries string `json:"security_series,omitempty"`
IdentificationDetails IdentificationDetails `json:"identification_details"`
}
// IdentificationDetails — choice reg_number|fund_shares.
type IdentificationDetails struct {
RegNumber string `json:"reg_number,omitempty"`
FundShares *FundShares `json:"fund_shares,omitempty"`
}
// FundShares — ПИФ.
type FundShares struct {
RegNumber string `json:"reg_number"`
Class string `json:"class,omitempty"`
}
// Quantity — choice whole|fractional.
type Quantity struct {
Whole uint64 `json:"whole,omitempty"`
Fractional string `json:"fractional,omitempty"`
}
// SettlementAccount — реквизиты счёта.
type SettlementAccount struct {
SettlementRequisitesINN string `json:"settlement_requisites_inn"`
SettlementLocation SettlementLocation `json:"settlement_location"`
}
// SettlementLocation — место хранения.
type SettlementLocation struct {
DeponentCode string `json:"deponent_code"`
AccountID string `json:"account_id"`
SectionID string `json:"section_id"`
}
// CreateClaimResponse — DTO ответа POST.
type CreateClaimResponse struct {
ID string `json:"id"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
Success bool `json:"success"`
}
// ClaimView — полная заявка с историей (GET и admin).
type ClaimView struct {
ID string `json:"id"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Investor Investor `json:"investor"`
TransferringDepositoryINN string `json:"transferring_depository_inn"`
ReceivingDepositoryINN string `json:"receiving_depository_inn"`
CostInfo CostInfo `json:"cost_info"`
IIAAgreement *IIAAgreement `json:"iia_agreement,omitempty"`
Securities []ClaimSec `json:"securities"`
LastCallback *StatusCallback `json:"last_callback,omitempty"`
Stages []StageView `json:"stages,omitempty"`
M2MGUID m2m.UUID `json:"m2m_guid,omitempty"`
M2MResponse *NSDResponseView `json:"m2m_response,omitempty"`
M2MDecision *NSDDecisionView `json:"m2m_decision,omitempty"`
}
// StageView — точка истории FSM для UI.
type StageView struct {
State string `json:"state"`
EnteredAt time.Time `json:"entered_at"`
LeftAt *time.Time `json:"left_at,omitempty"`
Reason string `json:"reason,omitempty"`
}
// StatusCallback — callback статуса от lk-gateway к ЛК.
type StatusCallback struct {
ClaimID string `json:"claim_id"`
NewStatus string `json:"new_status"`
ReasonCode string `json:"reason_code,omitempty"`
ReasonText string `json:"reason_text,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
NSDResponse *NSDResponseView `json:"nsd_response,omitempty"`
}
// NSDResponseView — сжатое представление M2MTransferResponse для UI/callback.
type NSDResponseView struct {
GUID string `json:"guid"`
StatusCode string `json:"status_code"`
Responses []NSDResponseEntry `json:"responses"`
// RawXML — точные байты ответа МОСТ от НРД (декодированные в UTF-8 для
// показа). Для дословной пересылки в техподдержку НРД.
RawXML string `json:"raw_xml,omitempty"`
}
// NSDResponseEntry — одна запись Response.
type NSDResponseEntry struct {
ReferenceID string `json:"reference_id,omitempty"`
Code string `json:"code"`
Text string `json:"text,omitempty"`
}
// NSDDecisionView — сжатое представление M2MTransferDecision для UI.
type NSDDecisionView struct {
GUID string `json:"guid"`
Securities []NSDDecisionSecurity `json:"securities"`
}
// NSDDecisionSecurity — решение по одной ЦБ.
type NSDDecisionSecurity struct {
ReferenceID string `json:"reference_id"`
Outcome string `json:"outcome"` // "confirmed" | "rejected"
RejectCodes []string `json:"reject_codes,omitempty"`
}
// ErrorResponse — формат ошибки, идентичный ESIA Finance.
type ErrorResponse struct {
Error bool `json:"error"`
Status int `json:"status"`
Code string `json:"code"`
Title string `json:"title"`
Meta *ErrorMeta `json:"meta,omitempty"`
}
// ErrorMeta — детали ошибки.
type ErrorMeta struct {
Message string `json:"message,omitempty"`
Errors []FieldErrorDetail `json:"errors,omitempty"`
}
// FieldErrorDetail — ошибка по конкретному полю.
type FieldErrorDetail struct {
Field string `json:"field"`
Message string `json:"message"`
}
// ClaimsPage — постраничная выдача.
type ClaimsPage struct {
Items []ClaimView `json:"items"`
Total int `json:"total"`
Limit int `json:"limit"`
Offset int `json:"offset"`
}