feat(admin): вкладка «Инструкции» + русификация статусов в UI

В admin-панели lk-gateway добавлен раздел /admin/help — справка по
основным интеграциям, читается прямо на сервере, без выхода во
внешнюю документацию.

Состав /admin/help:
- /admin/help — hub-страница с 4 карточками-ссылками
- /admin/help/database — подключение PostgreSQL, схемы fansy/fansy_staging/m2m_core,
  что подгружается через ETL Fansy и что пишет сама система, роли,
  миграции, полезные запросы
- /admin/help/lk-api — REST-контракт ESIA Finance V1: аутентификация,
  POST/GET/PATCH/list, формат callback'ов и ошибок, эмулятор для тестов,
  примеры curl
- /admin/help/cryptopro — установка КриптоПро CSP на РЕД ОС и Ubuntu,
  ввод серийного номера лицензии (cpconfig), путь к PKCS#11 модулю
  libcppkcs11.so, подключение Рутокен ЭЦП 2.0 для подписи оператора,
  тестирование подписи через csptest и cryptcp
- /admin/help/systems — Интеграционный шлюз НРД (профили guest/test3/prod),
  команда Fansy (порядок согласования контракта), уведомления
  (SMTP/Yandex Messenger/Telegram), контакты команд

Русификация статусов:
- Добавлены template-функции ruState и ruOutcome (в lkgateway и lkemulator)
- "draft" → "Черновик", "confirmed" → "Подтверждена", "rejected" → "Отклонена" и т.д.
- CSS-классы бейджей сохраняются (по исходному state), меняется только
  отображаемый текст. Технические термины (PostgreSQL, ИНН, GUID, REST)
  остаются как есть — они являются именами программного обеспечения.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
fontvielle
2026-05-14 13:53:37 +03:00
parent 978777ff6a
commit 67e81e5d7f
12 changed files with 574 additions and 13 deletions
+35 -1
View File
@@ -37,10 +37,44 @@ type Server struct {
mux *http.ServeMux
}
// templateFuncs — функции, доступные внутри шаблонов эмулятора
// (русификация статусов).
var templateFuncs = template.FuncMap{
"ruState": ruState,
}
// ruState — те же значения, что и в lkgateway.russianState. Дублирование
// допустимое: lkemulator — отдельный пакет и не зависит от lkgateway.
func ruState(s string) string {
switch s {
case "draft":
return "Черновик"
case "validated":
return "Валидирована"
case "submitted_to_nsd":
return "Отправлена в НРД"
case "awaiting_decision":
return "Ожидает решение"
case "confirmed":
return "Подтверждена"
case "awaiting_sub16":
return "Ожидает SUB16"
case "done":
return "Завершена"
case "rejected":
return "Отклонена"
case "timed_out":
return "Таймаут SLA"
case "manual_approval":
return "На ручном разборе"
}
return s
}
// NewServer собирает Server.
func NewServer(cfg ServerConfig) (*Server, error) {
parse := func(content string) (*template.Template, error) {
return template.ParseFS(tplFS, "web/templates/layout.html", "web/templates/"+content)
return template.New("layout.html").Funcs(templateFuncs).ParseFS(tplFS, "web/templates/layout.html", "web/templates/"+content)
}
home, err := parse("home.html")
if err != nil {
+2 -2
View File
@@ -1,6 +1,6 @@
{{define "content"}}
<div class="card">
<h2>Заявка <code>{{slice .Claim.ID 0 8}}</code> · <span class="badge {{.Claim.Status}}">{{.Claim.Status}}</span></h2>
<h2>Заявка <code>{{slice .Claim.ID 0 8}}</code> · <span class="badge {{.Claim.Status}}">{{ruState .Claim.Status}}</span></h2>
<div class="kv">
<div>Создана</div><div>{{.Claim.CreatedAt.Format "02.01.2006 15:04:05"}}</div>
<div>Обновлена</div><div>{{.Claim.UpdatedAt.Format "02.01.2006 15:04:05"}}</div>
@@ -30,7 +30,7 @@
<div class="card">
<h2>Полученный callback от lk-gateway</h2>
<div class="kv">
<div>Новый статус</div><div><span class="badge {{.Claim.LastCallback.NewStatus}}">{{.Claim.LastCallback.NewStatus}}</span></div>
<div>Новый статус</div><div><span class="badge {{.Claim.LastCallback.NewStatus}}">{{ruState .Claim.LastCallback.NewStatus}}</span></div>
{{if .Claim.LastCallback.ReasonCode}}
<div>Код причины</div><div><code>{{.Claim.LastCallback.ReasonCode}}</code> {{.Claim.LastCallback.ReasonText}}</div>
{{end}}
+1 -1
View File
@@ -17,7 +17,7 @@
<td>{{.SecuritiesCount}}</td>
<td><code>{{.TransferringDepositoryINN}}</code></td>
<td><code>{{.ReceivingDepositoryINN}}</code></td>
<td><span class="badge {{.Status}}">{{.Status}}</span></td>
<td><span class="badge {{.Status}}">{{ruState .Status}}</span></td>
<td><a href="/claims/{{.ID}}">детали →</a></td>
</tr>
{{end}}