Тест «боевой ЛК → TEST3»: заявки выбранных клиентов ЕСИА Финанс — у нас всё по-настоящему (DEPO, QUIK МНП боевая запись только для них), в НРД с подменой инвестора на тест-клиента; «Исполнена» в ЛК по MS010; повтор отправки тоже с подменой; пометка и шаги ЛК в пути заявки; включатель на «Тестирование M2M»

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-09-29 13:10:06 +03:00
parent 340fca7bd7
commit 91d8584a9c
15 changed files with 485 additions and 21 deletions
+37 -4
View File
@@ -21,6 +21,7 @@ import (
"time"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/m2m"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/m2mcore"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdadapter/mock"
)
@@ -94,13 +95,32 @@ func lkProcessEmulated(ctx context.Context, rc *RuntimeConfig, svc *Service, ep
globalLKFlows.step(guid, id, "crane", "Проверка шлюза bj: можно исполнить",
fmt.Sprintf("Сверка с DEPO: %s (инвестор %s, счёт %s).", res.Summary, pick(res.Investor, "—"), pick(res.Account, "—")))
if _, err := svc.SendBuiltRequestVia(ctx, lkEmuSender, req, inv.ID, nil); err != nil {
// Тест «боевой ЛК → TEST3» (realtest.go): клиент из списка — в настоящий НРД с подменой инвестора.
sender := m2mcore.NSDSender(lkEmuSender)
realNSD := realTestMatch(rc, inv.Document.Series, inv.Document.Number) && svc.sender != nil
if realNSD {
asInv, asText := realTestInvestor(rc, req.Data.InvestorInformation.IdentityDocument.DocumentType)
realTestPut(RealTestRec{GUID: guid, ClaimID: id, At: time.Now(), As: asText,
Client: strings.TrimSpace(fmt.Sprintf("%s %s %s, %s %s", inv.LastName, inv.FirstName, inv.MiddleName, inv.Document.Series, inv.Document.Number))})
sender = substituteSender{real: svc.sender, inv: asInv}
globalLKFlows.step(guid, id, "gateway", "Тест: в НРД (TEST3) — с данными тест-инвестора",
"У нас заявка проходит как клиент ("+inv.LastName+"): DEPO, QUIK МНП (боевая запись), статусы в ЛК. В НРД блок инвестора заменён на "+asText+"; GUID и референсы — настоящие.")
log.Printf("lk-gateway: ЛК #%d (%s): тест «боевой ЛК → TEST3» — в НРД как %s", id, shortGUID(guid), asText)
}
if _, err := svc.SendBuiltRequestVia(ctx, sender, req, inv.ID, nil); err != nil {
if strings.Contains(err.Error(), "QUIK") {
reason := "Отказ: не удалось заблокировать бумаги клиента — " + err.Error()
globalLKFlows.step(guid, id, "reject", "Блокировка в QUIK не удалась", err.Error())
lkGatewayReject(ctx, rc, svc, id, inv.ID, req, "QUIK", "Отказ: не удалось заблокировать ценные бумаги", reason)
return "rejected", nil
}
if realNSD {
// НРД не принял пакет — заявка «Не отправлена», повтор автоматически (sendfail.go); в ЛК — «В работе»
globalLKFlows.step(guid, id, "reject", "НРД не принял пакет — повтор автоматически", err.Error())
lkMarkSent(id)
lkLinkGUID(guid, ep, id)
return "sent", nil
}
return "", fmt.Errorf("имитация отправки: %w", err)
}
lkMarkSent(id)
@@ -110,11 +130,18 @@ func lkProcessEmulated(ctx context.Context, rc *RuntimeConfig, svc *Service, ep
if devMode(rc) {
sentTitle = "Бумаги заблокированы, заявка передана имитатору НРД"
}
globalLKFlows.step(guid, id, "gateway", sentTitle,
lkQuikSummary(guid)+fmt.Sprintf(" В НРД не отправлялась; ответ контрагента — через %s.", lkEmuDecisionDelay))
sentDetail := lkQuikSummary(guid) + fmt.Sprintf(" В НРД не отправлялась; ответ контрагента — через %s.", lkEmuDecisionDelay)
if realNSD {
sentTitle, sentDetail = "Бумаги заблокированы, запрос перевода отправлен в НРД (TEST3)", lkQuikSummary(guid)+" Ждём решения контрагента от НРД."
}
globalLKFlows.step(guid, id, "gateway", sentTitle, sentDetail)
if pc, pb := lkPatch(ctx, ep, fmt.Sprintf("/claims/%d", id), []byte(`{"claim":{"status":"in_process"}}`)); pc >= 400 {
log.Printf("lk-gateway: ЛК #%d: PATCH «В работе» не прошёл: HTTP %d %s", id, pc, pb)
}
if realNSD {
log.Printf("lk-gateway: ЛК #%d (%s): сверка пройдена, бумаги заблокированы, отправлено в НРД TEST3 с подменой инвестора", id, shortGUID(guid))
return "sent", nil
}
log.Printf("lk-gateway: ЛК #%d (%s): сверка пройдена, бумаги заблокированы, заявка передана имитатору НРД — решение контрагента через %s", id, shortGUID(guid), lkEmuDecisionDelay)
return "sent", nil
}
@@ -284,7 +311,13 @@ func (s *Server) applyDecisionEffects(ctx context.Context, decision *m2m.M2MTran
log.Printf("lk-gateway: %s: finalize(%s) GUID=%s: %v", source, fancyStatus, decision.Header.GUID, e)
}
_ = note // клиенту в ЛК — только короткий итог, подробности в журнале bj
OnLKOutcome(ctx, s.rc, string(decision.Header.GUID), lkStatus, lkReason)
if realTestGet(string(decision.Header.GUID)) != nil && conf > 0 {
// тест «боевой ЛК → TEST3»: согласие контрагента — ещё не исполнение; «Исполнена» — по MS010 (realtest.go)
globalLKFlows.stepIfExists(string(decision.Header.GUID), "response", "Контрагент согласился — ждём исполнения НРД",
fmt.Sprintf("Принято %d, отклонено %d. Статус в ЛК — «В работе» до отчёта НРД об исполнении (MS010).", conf, rej))
} else {
OnLKOutcome(ctx, s.rc, string(decision.Header.GUID), lkStatus, lkReason)
}
quikOnDecision(ctx, s.rc, s.svc, decision)
go depoOnCounterpartyDecision(s.rc, decision)
}