Учёт DEPO: ход подготовки по шагам, понятный блок «Логин bj», пауза после неудачного входа

- «Подготовить» / «Проверить подключение» показывают ход: подключение логином
  администратора, проверка, что это база DEPO, применение скрипта, вход логином bj,
  таблицы обмена, задание, процедуры, «Готово». Сервер отдаёт шаги строками JSON
  (stream=1), на ошибке — шаг с крестиком и причина, без перехода со страницы.
- Блоки «Администратор SQL — нужен один раз, не сохраняется» и «Логин bj — под ним
  bj будет работать»: bj сохраняет и использует ровно то, что вписано; «другой
  пароль»; на итоге шага — каким логином bj работает.
- Пауза 15 минут после неудачного входа в DEPO (логин/пароль отвергнуты) для
  фоновых служб: с неверным паролем они за минуты блокировали логин на сервере
  (CHECK_POLICY) у всех, кто им пользуется. Действия человека идут без паузы;
  новый пароль — сразу; системное событие в «Новостях».

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 15:46:25 +03:00
parent fbf6a23667
commit a9915bcc82
8 changed files with 395 additions and 53 deletions
+23 -3
View File
@@ -192,19 +192,38 @@ func depoSetupFileName(f FancyMSSQLSettings) string {
return "bj-depo-setup-mssql.sql"
}
// depoStep — ход подготовки для экрана: key — шаг, state — run (начат) | ok | warn, text — что делается или итог.
type depoStep func(key, state, text string)
// depoSetupRun — «bj сделает сам»: тот же скрипт выполняется логином администратора (не сохраняется) в базе
// db, которую назвал клиент; сначала — проверка, что это база DEPO.
func depoSetupRun(ctx context.Context, f FancyMSSQLSettings, db, adminUser, adminPass, login, pass string, agentJob bool) error {
// db, которую назвал клиент; сначала — подключение и проверка, что это база DEPO. step — ход для экрана.
func depoSetupRun(ctx context.Context, f FancyMSSQLSettings, db, adminUser, adminPass, login, pass string, agentJob bool, step depoStep) error {
adm := f
adm.User, adm.Password = strings.TrimSpace(adminUser), adminPass
if !validDBName(db) {
return fmt.Errorf("укажите имя базы DEPO")
}
step("connect", "run", "Подключаюсь к серверу "+f.Server+" логином администратора «"+adm.User+"»")
if _, err := fancyPing(ctx, adm, ""); err != nil {
return fmt.Errorf("к серверу %s логином %s подключиться не удалось — %s", f.Server, adm.User, quikErrorDetail(err))
}
step("connect", "ok", "")
step("isdepo", "run", "Проверяю, что «"+db+"» — база учёта DEPO")
if err := depoCheckIsDepo(ctx, adm, db); err != nil {
return err
}
step("isdepo", "ok", "")
what := "логин bj «" + login + "», таблицы обмена, права"
if agentJob && !f.IsPostgres() {
what += ", задание «" + depoJobName + "»"
}
step("apply", "run", "Применяю скрипт подготовки: "+what)
if f.IsPostgres() {
return depoSetupRunPG(ctx, adm, db, login, pass)
if err := depoSetupRunPG(ctx, adm, db, login, pass); err != nil {
return err
}
step("apply", "ok", "")
return nil
}
conn, err := fancyOpen(adm, "")
if err != nil {
@@ -216,6 +235,7 @@ func depoSetupRun(ctx context.Context, f FancyMSSQLSettings, db, adminUser, admi
if _, err := conn.ExecContext(cctx, depoSetupScript(f, db, login, pass, agentJob)); err != nil {
return fmt.Errorf("подготовка базы %s логином %s: %s%s", db, adm.User, quikErrorDetail(err), depoTablesRightsHint(f, adm.User, err))
}
step("apply", "ok", "")
return nil
}