DEPO: строчные события по депо-поручениям (частичное исполнение пакета)
По ответам программиста Fancy (В. Кокин, 21.09.2026) на 8 вопросов из docs/fancy-events-partial-m2m.md. Одно депо-поручение (MF010) = одна бумага пакета, поэтому подача и исход теперь пишутся в DEPO ПО СТРОКАМ с REFERENCE и сразу по MS010 этой строки, не дожидаясь остальных: пакет может исполниться частично (Сбер — да, Т-Технологии — отказ). События на весь GUID (пустой REFERENCE) больше не пишем — переход одновременно с bj2depo. - BJ_ORDER_SENT / BJ_ORDER_ACCEPTED / BJ_EXECUTED / BJ_ORDER_REJECTED / BJ_ORDER_LATE / BJ_CANCELLED — по строке (depoOnOrderLineSent/Result); contr_d_id кладём в COMMENT (джобе связка не нужна — по REFERENCE найдёт). - OrderWatch.Lines — состояние по строкам (contr_d_id → REFERENCE/ISIN/MS010/ отказ/истечение); объект закрыт, когда MS010 по всем строкам; 30 дней — BJ_CANCELLED по каждой незакрытой строке, QUIK-блок снимается по её ISIN. - Входящий 16/1 хранит ВСЕ contr_d_id (OrderLines) — раньше только первый (дефект «входящие отслеживают только первый contr_d_id»). Исходящий 16: REFERENCE по ISIN из бумаг M2MTR (outgoingLineRefs, кэш по GUID; svc в deps). - Карточка: «исполнено частично: N из M» (StatusRu), бейдж warn — как статус «частично» в DEPO. Backfill и эмуляция — тоже по строкам. - Попутно: EXEC процедуры обработчика DEPO — через execProc с проверкой имени (sqlident.go), чтобы значение из настроек не стало произвольным T-SQL. Тесты: TestOrderWatchLinesPartial, TestIncomingOrderLines, TestOutgoingLineRefsNoRepo; весь пакет зелёный. РАЗВЁРТЫВАНИЕ — только одновременно с bj2depo (п. 8 ответов Fancy). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package lkgateway
|
||||
|
||||
// sqlident.go — имена объектов MSSQL из настроек (процедура обработчика DEPO,
|
||||
// база, логин) параметризовать нельзя, они склеиваются в текст запроса. Чтобы
|
||||
// значение из формы не превратилось в произвольный T-SQL, перед EXEC имя
|
||||
// проверяется по строгому шаблону идентификатора.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// sqlIdentRe — допустимое имя: буквы, цифры, подчёркивание, точка (схема.имя),
|
||||
// квадратные скобки MSSQL. Ни пробелов, ни кавычек, ни точки с запятой.
|
||||
var sqlIdentRe = regexp.MustCompile(`^[A-Za-z0-9_.\[\]]{1,128}$`)
|
||||
|
||||
// sqlIdentOK — строка похожа на имя объекта SQL, а не на код.
|
||||
func sqlIdentOK(s string) bool { return sqlIdentRe.MatchString(s) }
|
||||
|
||||
// execProc — выполнить хранимую процедуру по имени из настроек, предварительно
|
||||
// проверив имя. Сигнатура как у ExecContext, чтобы подставлять на место "exec "+name.
|
||||
func execProc(ctx context.Context, db *sql.DB, proc string) (sql.Result, error) {
|
||||
if !sqlIdentOK(proc) {
|
||||
return nil, fmt.Errorf("недопустимое имя процедуры %q: разрешены буквы, цифры, _ . [ ]", proc)
|
||||
}
|
||||
return db.ExecContext(ctx, "exec "+proc)
|
||||
}
|
||||
Reference in New Issue
Block a user