Канал ИШ: необязательные параметры — NULL (иначе ИШ молча выкидывал канал); мастер: шаг «Учётные записи», HTTPS сразу, DEPO без процедур — не блокирует

- bj-igate-admin: пустые строки в числовых/интервальных параметрах канала ИШ разбирал с ошибкой и не
  загружал канал («There are no active channels», API 500 «more than one Channel…»); теперь NULL, как пишет
  интерфейс ИШ; старые каналы чинятся при «Создать канал»; папка архивов 1042S — по имени
- проверка «Шлюз НРД»: канал контура действительно загружен и включён (api/admin/channels/wsl)
- «Учёт DEPO»: нет процедур bj2depo — жёлтое «не забудьте доустановить», не блокирует
- HTTPS: перенаправление с http:// включено по умолчанию, только когда HTTPS реально слушает порт
- мастер: шаг «Учётные записи» (роли, создание, «Придумать пароль») перед проверкой; письма с проверки убраны;
  форма «создать» не меняет существующую запись с тем же логином

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-10-06 23:19:01 +03:00
parent b3f3454e4a
commit 44f00a006a
12 changed files with 264 additions and 47 deletions
+32 -4
View File
@@ -14,11 +14,14 @@ import (
"os"
"os/exec"
"sort"
"strconv"
"strings"
"sync"
"time"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/release"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdadapter"
)
// cryptoJarPath — модуль проверки ключа подписи bj-crypto (компонент crypto-service.jar).
@@ -177,6 +180,20 @@ func readinessChecks(ctx context.Context, rc *RuntimeConfig) []ReadyCheck {
c.State, c.Detail = "err", "шлюз отвечает, но контур НРД в bj не выбран"
default:
c.State, c.Detail = "ok", msg+"; контур "+s.NSD.Profile
if prof, err := nsdadapter.LookupProfile(s.NSD.Profile); err == nil && orgCode(s) != "" {
code := prof.Channel + orgCode(s)
switch found, enabled, err := igateChannelState(ctx, s.NSD.IGWBaseURL, code); {
case err != nil:
case !found:
c.State, c.Detail = "err", "движок шлюза работает, но канала "+code+" в нём нет — шлюз не загрузил канал: пересоздайте его на шаге «Шлюз НРД» (кнопка «Создать канал»)"
return c
case !enabled:
c.State, c.Detail = "err", "канал "+code+" в шлюзе выключен — он включается, когда установлен ключ подписи этого контура (шаг «Ключ подписи»)"
return c
default:
c.Detail += "; канал " + code + " работает"
}
}
nsdWatch.Lock()
okAt := nsdWatch.LastPollOK
nsdWatch.Unlock()
@@ -239,8 +256,10 @@ func readinessChecks(ctx context.Context, rc *RuntimeConfig) []ReadyCheck {
c.State, c.Detail = "warn", "сертификат HTTPS: "+err.Error()
case certDaysLeft(until) < 14:
c.State, c.Detail = "warn", fmt.Sprintf("сертификат «%s» истекает %s — замените", cn, until.Format("02.01.2006"))
case !s.HTTPS.Redirect:
c.State, c.Detail = "warn", "вход в bj по http:// не перенаправляется на https:// — пароли могут идти по сети открытым текстом"
case !httpsUp.Load():
c.State, c.Detail = "warn", "HTTPS не запущен (порт "+strconv.Itoa(s.HTTPS.port())+" занят или нет сертификата) — вход только по http://, пароли идут по сети открытым текстом; см. журнал bj-server"
case !s.HTTPS.RedirectOn():
c.State, c.Detail = "warn", "перенаправление с http:// на https:// выключено в настройках — пароли могут идти по сети открытым текстом"
default:
c.State, c.Detail = "ok", fmt.Sprintf("вход только по HTTPS, сертификат «%s» до %s", cn, until.Format("02.01.2006"))
}
@@ -386,17 +405,26 @@ func readyDepo(ctx context.Context, rc *RuntimeConfig) ReadyCheck {
c.State = "err"
notes = append(notes, "таблицы обмена FTV_M2M: "+pickStr(f.DepoTablesCheck, "не проверены"))
}
if msg := depoObjectsMissing(cctx, db, f); msg != "" {
procsPending := false
if msg := depoTablesMissing(cctx, db, f); msg != "" {
c.State = "err"
notes = append(notes, msg)
} else if msg := depoProcsMissing(cctx, db, f); msg != "" {
// процедуры bj2depo ещё не установлены — не блокирует: формат обмена с учётной системой готовится, их
// доустанавливают отдельно; пока их нет, события bj в DEPO копятся необработанными
procsPending = true
notes = append(notes, "процедуры обработки bj2depo ещё не установлены — не забудьте их доустановить. Пока их нет, события bj в базе DEPO ждут обработки")
} else if !f.DepoProcCheckOK && f.DepoProcCheck != "" {
c.State = "err"
notes = append(notes, "обработка событий: "+f.DepoProcCheck)
}
if jmsg, jok := depoJobCheck(cctx, rc); !jok {
if jmsg, jok := depoJobCheck(cctx, rc); !jok && !procsPending {
c.State = "err"
notes = append(notes, "запуск обработки: "+jmsg)
}
if procsPending && c.State == "ok" {
c.State = "warn"
}
if n, _, err := depoAccPrefixInfo(cctx, f); err == nil && n == 0 && !f.IsPostgres() {
c.State = "err"
notes = append(notes, "открытых торговых счетов «"+depoAccPrefix()+"…» в учёте нет — проверьте префикс счёта")