При отсутствии флешки по умолчанию выбирался режим «Сформировать на новой
флешке», и после «Перепроверить флешку» экран прыгал туда. Теперь по умолчанию
всегда «Подключить флешку» (пустое состояние внутри с кнопкой перепроверки).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
- В режиме флешки — кнопка «↻ Перепроверить флешку» (и когда флешка есть, и когда нет)
с индикатором «Ищу флешку…».
- Пустое состояние поясняет: на виртуальной машине USB нужно пробросить в гостя.
- listFlashDrives ловит и съёмный диск с ФС без таблицы разделов (type=disk).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
Свёрнутый блок «Что должно быть на флешке» в шаге «Ключ подписи»: ключ *.vdk
(обязательно), папка spr<N> с local.gdbm+local.pse (обязательно), *.crl/key.reg/
vdkeys необязательны; раскладка любая — bj ищет *.vdk и spr<N>/local.gdbm в любой
папке (как в bj-keymedia-install stage-media).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
- quikDetectAccounts: Export не имеет колонки QuikFirm (ошибка 207 Invalid column
name) — запросы по Actions/Export выполняются по отдельности, источник без нужной
колонки пропускается.
- «Полный ответ сервера (последняя проверка)» свёрнут в details, чтобы не прятать
настройки ниже.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
Кнопка была submit внутри формы режима, у которой обработчик submit делает
preventDefault — клик ничего не отправлял. Теперь type=button + fetch на
/admin/setup/quik/detect-account (X-BJ-Ajax), результат в строке статуса,
найденный счёт подставляется в поле.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
Кнопка «Определить из QUIK» у поля «Торговый счёт для поручений» (режим
чтение+запись). bj читает distinct Account из Actions/Export по коду фирмы
(QuikFirm/FirmID = код участника): один счёт — подставляет, несколько —
показывает на выбор, нет истории — просит ввести вручную. Только чтение.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
Причина «нет процедур» при успешной установке: проверка идёт логином bj_user, а
OBJECT_ID под ним возвращает NULL для объектов без прав — FTV_M2M_JOB виден (ему
выдан EXECUTE), 4 FTV_M2M_PROCESS_* нет. Процедуры установлены и работают (JOB
вызывает их по цепочке владения dbo), но проверка их не видела.
Теперь установка и скачиваемый скрипт выдают GRANT EXECUTE на все 5 процедур.
Убрана ложная блокировка установки по отсутствию пользователя SYSDBA (CREATE
проходит и без него; строка EXECUTE AS проверяется в рантайме).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
Процедуры FTV_M2M_PROCESS_* содержат EXECUTE AS USER=SYSDBA; SQL Server требует
этого пользователя при CREATE (FTV_M2M_JOB без EXECUTE AS создаётся, а 4 PROCESS_* — нет).
- «Проверить возможности» проверяет наличие пользователя EXECUTE AS (из текста процедур)
и блокирует установку с понятным сообщением, если его нет.
- Ошибка установки сохраняется в статус (не мелькает флешем) с подсказкой про SYSDBA.
- Подсказка добавлена и в мастере при «Подготовить».
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
- «Подготовить» в мастере (step 3, режим «дать логин администратора») теперь ставит
и процедуры обработки bj2depo (CREATE OR ALTER) + GRANT, не только логин/таблицы/джобу.
- Скачиваемый скрипт мастера включает процедуры.
- Тексты процедур редактируются под клиента (Настройка → Обмен DEPO → Процедуры):
сохранённый вариант используется при установке и при «Подготовить». Пусто/совпадение
со встроенным — исходная версия.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
Процедуры FTV_M2M_PROCESS_* и FTV_M2M_JOB встроены в bj (depoprocs/*.sql).
В разделе «Учёт DEPO» карточка «Процедуры обработки bj2depo»:
- «Проверить возможности» — подключение, это ли база DEPO, какие процедуры
установлены, есть ли право CREATE PROCEDURE и логин bj в базе (ничего не меняет);
- «Установить» — логином администратора SQL (разово, не сохраняется) выполняет
CREATE OR ALTER в порядке WIRING→OPERATION→EVENTS→CREATE→JOB и GRANT EXECUTE
на FTV_M2M_JOB логину bj; без прав — отказ без изменений;
- скачивание единого скрипта для ручной установки в SSMS.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
Новый шаг 14 «Обновление» в отдельной первой главе мастера. Секция
«Обновления» вынесена из admin_setup.html в {{define "updateSection"}}
(part_fancy.html) и переиспользуется и в настройках, и в шаге мастера —
один источник правды. В мастере рендерится обычным блоком (без
settings-section/active), заголовок h1 скрыт (есть свой h2 шага).
Шаг необязательный (не блокирует путь), зелёный пока нет версии новее;
при наличии обновления — предупреждающая точка. Добавлена пятая глава,
поэтому wizChaptersLine расширен до «Пять глав».
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
Шаг «Время и сеть»:
- Кнопка «Синхронизировать»: bj сам пробует российские серверы точного
времени ВНИИФТРИ (мини-SNTP зонд по UDP/123), и только если из сети они
недоступны — просит указать свой сервер (контроллер домена/маршрутизатор).
Статус времени берётся из timedatectl (timeSynced), а не из флага шага.
- Поле «Доменное имя сервера»: имена вписываются в самоподписанный сертификат
(SAN), чтобы интерфейс открывался по имени без предупреждения браузера.
Сертификат перевыпускается на лету; A-запись заводит админ сети на DNS.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
Требование: в тест анкету не слать, подача только в бою. send_igw теперь
пропускается лишь при боевом канале ИШ (Channel=PROD, профиль prod-*);
в тестовом/гостевом контуре отправка через шлюз заблокирована (кнопка
disabled + явный статус, серверная проверка isProdIGW как defense-in-depth).
Скачивание XML и письмо на M2MOST@nsd.ru остаются доступны везде.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
НРД открыл приём анкеты (M2MTransferParticipantForm) в пром-контуре.
По формату НРД анкета — отдельный тип ЭД M2MPF: тег <package> = "#" +
первые 5 символов имени типа ЭД → "#M2MPF", businessLine=MOST (как и
остальные M2M-сообщения; на ИШ <107.0.0.904 businessLine опускается).
Подпись — боевым ГОСТ-контейнером на стороне ИШ.
- nsdadapter/router.go: тип PackageM2MParticipantForm "#M2MPF";
KindParticipantForm теперь маппится на него (был ошибочно
Assets_investment).
- lkgateway/participant_form.go: действие send_igw — упаковка анкеты
через igw.PackXML(..., "#M2MPF") и отправка igwClient.SendPackage в
канал профиля (в боевом контуре — prod-gost). Кнопка «Отправить через
шлюз (боевой ИШ)»; письмо на M2MOST@nsd.ru оставлено запасным каналом.
Статус готовности ИШ на странице.
- lkgateway/server.go: проброс igwClient/igwChannel в registerParticipantForm.
Образец — sendHandbookRequest (#M2MHR) через тот же ИШ.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
Страница /admin/setup/client-profile: скачать эталон текущей конфигурации (секреты
затёрты) и — для стенда — применить профиль клиента вручную. На боевом профиль
приходит с сервера лицензий (поле config_profile в ответе активации/продления) и
предзаполняет ещё НЕ настроенные разделы мастера, ничего не перетирая. Локальный
фолбэк — файл client-profile.json рядом с setup.json. Администратор правит профиль
под клиента на lic (отличия от стандарта).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
Требование НРД при подключении к сервису M2M (МОСТ): зарегистрировать организацию
в справочнике участников анкетой M2MTransferParticipantForm, иначе сервис отбивает
запросы кодом M2M14. Регистрация идёт ОБЫЧНЫМ каналом (письмом на M2MOST@nsd.ru с
вложением), не через M2M-шлюз.
- Новая страница /admin/setup/participant-form (participant_form.go):
предзаполнение из автоопределения DEPO (ИНН, наименования, код депозитария),
правка оператором, валидация (формат ИНН/кодов + m2m.HandbookParticipant.Validate),
предпросмотр анкеты, «Скачать» (windows-1251) и «Отправить в НРД» письмом с
вложением-анкетой.
- Генерация XML строкой-шаблоном по образцу НРД (namespace participant/form,
CreationTimestamp по МСК, блоки Eng/BrokerPlace — опциональны), кодировка
windows-1251 через nsdxml.EncodeWindows1251; экранирование текста только & < >.
- Почта: выделен транспорт smtpDeliver из sendSMTP; добавлены buildMIMEAttach
(multipart/mixed + base64-вложение) и sendSMTPAttach.
- Тесты: валидация, генерация XML (Eng/BrokerPlace), cp1251 round-trip, MIME-вложение.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
- Карточка заявки: операторский «Путь заявки» (claimTimelineOperator) короткими
понятными вехами + сворачиваемый технический журнал (buildClaimTimeline);
QUIK показан пошагово (register/sign/deny/deposit) с верными временами, отказ
регистрации больше не выглядит успехом (quikActionFailTitles).
- Баннеры: «в НРД не отправлено», когда пакет сформирован, но не ушёл (нет
submitted_to_nsd и не Fail); заголовок карточки и бейдж учитывают это; красный
баннер QUIK при отказе, строгий «нет бумаг» только при реальном шорт/недостатке.
- НРД-ответ «Поручение с исходящим номером … уже существует» теперь REG_DUP
(предупреждение-дубль, не красный «Отказ в регистрации»); не влияет на od.Rejected.
- Idempotency: submitguard.go (inflightSubmit) + защита точек подачи от
двойного срабатывания (manual + auto-loop, двойной клик): submitOutgoingFor,
submitIncomingOrderFor, QuikOutRegister (ранний возврат при registered/signed).
- DEPO-алерты: водяной знак depoFailAlertedID засеивается текущим MAX(ID) на
старте процесса (Hlth03) — после рестарта bj больше не поднимает повторно
алерты про уже известные ошибки обработки событий BJ_*.
- Тесты: claimnotsent_render_test.go (хелперы + рендер карточки).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
Форма «Загрузка справочника из файла» на /admin/handbook принимает
подлинный формат НРД (hk:M2MTransferHandbook, windows-1251 — тот же,
что приходит пакетом #M2MTH и который отдаёт кнопка «XML»). Разбор и
сохранение идут тем же путём, что у поллера при ответе НРД:
nsdxml.Unmarshal → writeHandbookRawXML (сырой XML для байт-в-байт
выгрузки) → saveHandbookEx (плоский JSON) → перезапись FTV_M2M_HANDBOOK
в DEPO → синхронизация получателей в МНП. На сервер лицензий ручной файл
НЕ рассылается (saveHandbookEx push=false): справочник одного стенда не
должен становиться облачным для всех клиентов. Нужно для закрытого
контура и когда шлюз к НРД недоступен.
- handbook_import.go: обработчик importHandbook (POST /admin/handbook/import)
- nsdpoller.go: saveHandbook → saveHandbookEx(hb, push)
- admin.go: маршрут import, поле Flash, renderHandbook читает ?flash=
- admin_handbook.html: карточка загрузки + вывод flash
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
1) XML-выгрузка справочника (/admin/handbook → XML) теперь в формате НРД
(hk:M2MTransferHandbook: SettlementPlaces/Participants, Rus/Eng,
Depository/BrokerPlace). Поллер сохраняет подлинный XML от НРД
(writeHandbookRawXML → m2m-handbook.xml) и выгрузка отдаёт его как есть
(windows-1251, байт в байт). Для установок без своего шлюза — реконструкция
того же формата из плоского JSON (reconstructHandbookXML), проверено
парсером НРД.
2) findDealForResponse: ответ сервиса МОСТ с конкретным GUID, которого нет
среди ИСХОДЯЩИХ сделок (например M2M31 на наше решение по ВХОДЯЩЕМУ
переводу), больше НЕ пришивается по эвристике FIFO к чужой исходящей
заявке и не отклоняет её ошибочно. FIFO остаётся только для ответа с
нулевым/пустым GUID (поведение НРД при M2M14).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Поллер строк в работе (/admin/journal/live, tick в layout.html) обновлял
только нижнюю live-строку, а верхний бейдж статуса оставался тем, что
отрисовал сервер при загрузке — после отправки показывал «не отправлено»,
пока страницу не обновишь. LiveStatus получил поля badge/badgeText/outcome
(заполняются в liveOutgoing/liveIncoming из тех же источников, что и строка
журнала), tick синхронизирует верхний бейдж и бейдж исхода. Касается
журнала обмена, «Исходящих» и «Входящих» — у всех общий поллер.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
manualSend выбирал отправителя грубо: при любой включённой эмуляции (и
imitate, и substitute) уходил на внутренний имитатор. Теперь логика как в
lkemulate.go: imitate — имитатор (в НРД ничего); substitute — реальная
отправка в НРД, клиент из списка RealNSDTest.Docs идёт с заменой блока
инвестора на тест-инвестора (realTestPut для журнала «кто под кем»),
остальные — с настоящими данными; off — реально с настоящими данными.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
На странице /admin/handbook добавлены кнопки «JSON» и «XML» — скачивание
сохранённого справочника участников (readHandbook: от НРД #M2MTH, копия с
сервера лицензий или встроенный снимок) файлом. JSON отдаётся как есть с
отступами, XML формируется из плоских записей. Маршруты /admin/handbook/
export.json и export.xml под админ-авторизацией.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bj на старте сам пишет пустое сигнальное событие HANDBOOK; чтобы оно не
перекрывало последний результат джобы Fancy, QEv11 берёт свежайшее событие
HANDBOOK, у которого заполнен COMMENT или STATE.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
На странице «Справочник участников M2M» теперь выводится итог обработки
справочника джобой bj2depo — STATE/COMMENT последнего события HANDBOOK
из FTV_M2M_EVENTS (поле COMMENT пишет Fancy). Расхождения/предупреждения
выделяются цветом и значком: КРИТИЧ/ОШИБКА — красным, ПРЕДУПРЕЖДЕНИЕ —
жёлтым, «изменений нет» — зелёным, чтобы оператор видел, что проверить.
Только чтение (fsql.QEv11, TOP 1 по EVENT_DATE), короткий таймаут 4с,
страница не висит если DEPO недоступна.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Правильная обработка входящих переводов на ИИС вместо прежнего сплошного отказа.
Настройка AcceptIIS (карточка «Кто отвечает на переводы M2M»):
- выкл (по умолчанию) — поведение не меняется: перевод на ИИС отклоняется целиком (M2M06);
- вкл — ИИС принимается ТОЛЬКО целиком: все бумаги зачисляются на ИИС-счёт клиента;
если хоть одной бумаги нет в учёте / не проходит сверку — отказ по ВСЕМУ переводу.
Изменения:
- iisDecisions: «всё или ничего» (при выкл — отказ всем; при вкл — либо все принять,
либо все отклонить, сохраняя реальные коды отказа по проблемным бумагам);
- depo_check: при вкл приёме ИИС убран искусственный отказ «Перевод не на ИИС»,
добавлена проверка «Счёт зачисления — ИИС» (partyChecks получил флаг wantIIS);
- настройка AcceptIIS в Settings + геттер/сеттер + обработчик /admin/setup/accept-iis
+ тумблер в part_nsd.html; тесты обновлены.
Жёсткий запрет частичного ИИС в answerIncoming (коммит dc8b785) остаётся как страховка.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Перевод по договору ИИС принимается только целиком: если в одном решении
есть и подтверждённые, и отклонённые бумаги — answerIncoming отказывается
отправлять такое решение. Частичный приём ИИС привёл бы к неполному переводу
и двум ИИС у клиента с потерей льгот. Запрет не обойти ручным решением
оператора и переживёт смягчение политики приёма ИИС (iisDecisions).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1) Страница «Настройка» висела до 10 с, когда ЛК ЕСИА Финанс медленный/недоступен: setupData
синхронно тянул список пользователей из ЛК (lkUsersForSetup, таймаут 10 с). Теперь список
берётся из кэша мгновенно, обновляется в фоне с коротким таймаутом (3 с); при недоступном ЛК
показывается сохранённый список с пометкой. Страница больше не ждёт ЛК.
2) Морфинг карточки: добавлена якорная привязка — запоминаем верхний видимый блок и после
обновления корректируем прокрутку, чтобы при изменении высоты карточек выше обзора вид не
подпрыгивал (устраняет «прыгнула чуть выше»).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Вместо location.reload при смене подписи карточка теперь обновляется рекурсивным морфингом
<main>: догружаем ту же страницу и сливаем только изменившиеся узлы, одинаковые поддеревья не
трогаем. Прокрутка окна и боковых блоков («Путь заявки» .claim-tl / .in-tl) не сбивается,
выделение в неизменном тексте сохраняется, нет прыжков и мигания. Морфинг пропускается, если
правится форма (dirty) или идёт выделение. Копи-кнопки переинициализируются (bjInitCopyBars).
Плюс .badge { white-space:nowrap } — в журнале стрелка «↗ Исходящий» больше не переносится над словом.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
В режиме эмуляции «Подмена личности» XML в карточке — это наша запись с РЕАЛЬНЫМИ данными
клиента, а в НРД ушла копия с подменённым блоком инвестора (тест-инвестор). Над XML теперь
выводится предупреждение «В НРД отправлены ПОДМЕНЁННЫЕ данные, не эти» с указанием, под чьими
данными ушло (realTestGet по GUID → claimData.SubstAs). Без подмены — текст как раньше.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Пока пользователь выделяет текст мышью (например, копирует M2M GUID), автообновление
пропускает такт: live-опрос и перезагрузка карточки по смене подписи, а также подстановка
новых строк в журнале не выполняются, пока выделение активно (window.bjSelecting). Как только
выделение снято — обновление продолжается на следующем такте.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Было: правило «боевой ЛК + тестовый профиль → принудительно имитатор» не давало выключить
эмуляцию, а подмена личности жила отдельным тумблером на другой странице — пользователь не мог
понять состояние и выключить.
Стало — явная модель (контур НРД и режим эмуляции независимы):
- «Выключена» — заявки идут в выбранный контур (NSD.Profile) с реальными данными клиента;
- «Подмена личности» — уходят в контур, но у клиентов из списка блок инвестора заменяется на
тест-инвестора (Бубликов/Баранкин); DEPO и QUIK — по реальному клиенту;
- «Полная имитация» — в НРД ничего не уходит, bj сам отвечает (внутренний имитатор).
Режимы взаимоисключающие (ведутся флагами EmulateNSD/RealNSDTest.Enabled), принудительное
правило убрано. Единый 3-радио на /admin/emulators (как у QUIK), с показом контура, тест-инвестора
и списка паспортов; карточка на /admin/m2m-testing — статус + ссылка на «Эмуляторы».
Тесты обновлены под новую модель.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Было: на «Эмуляторы» баннер «Эмулятор НРД включён ... переключатель не выключает», и ни слова,
что для клиентов из real_nsd_test заявки идут МИМО имитатора в реальный TEST3 с подменой — и
выключить это оттуда нельзя (переключатель на другой странице). Пользователь не находил, как снять.
Теперь:
- /admin/emulators: при включённой подмене — заметный блок «Подмена личности в НРД включена»:
по каким паспортам, в какой контур (TEST3) и от чьего имени (тест-инвестор) уходит запрос,
плюс кнопка «Выключить подмену личности» прямо здесь.
- /admin/m2m-testing: карточка real-nsd показывает «Сейчас подменяет: паспорт X → как Y» и
отдельную кнопку «Выключить подмену» (одним кликом), помимо чекбокса включения/списка.
- обработчик /admin/setup/lk-real-nsd honor-ит поле back и возвращает на страницу-источник,
список паспортов при выключении сохраняется (docs передаётся скрытым полем).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Скролл: автообновление карточки (bjReloadKeepScroll) раньше сохраняло только прокрутку окна,
а боковой «Путь заявки» (.claim-tl — position:fixed, свой overflow) и другие прокручиваемые
блоки (.settings-nav, .doc-toc) отбрасывало наверх. Теперь сохраняется и восстанавливается и
их scrollTop (JSON в sessionStorage, восстановление на rAF/timeout/load).
DEPO: на «Обмен с DEPO» рядом с «Вернуть в очередь» добавлена «Снять с очереди» — помечает
застрявшие записи STATE=SKIPPED (QHl04-06, depoDismissFailures), обработчик их больше не берёт
и они уходят из списка ошибок. Для устаревших/ненужных записей (напр. старые тестовые).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Журнал: новый эндпоинт /admin/journal/rows (строки новее since, рендер тем же шаблоном
journalrow) + JS раз в 8 с подставляет новые заявки сверху с мягкой подсветкой (row-new),
без перезагрузки и без дёрганья; счётчик обновляется, плашка «нет переводов» убирается.
Таблица теперь рендерится всегда (tbody#journal-body), строка вынесена в {{define journalrow}}.
Карточка заявки: автообновление по смене подписи раньше делало location.reload() и сбрасывало
прокрутку наверх — мешало читать. Теперь bjReloadKeepScroll() сохраняет позицию прокрутки
(sessionStorage) и восстанавливает после перезагрузки; автообновление сохранено.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
После полной перезаписи FTV_M2M_HANDBOOK (при получении нового справочника от НРД и при
периодической перезаписи раз в 6 ч) bj вставляет в FTV_M2M_EVENTS строку-сигнал
(EVENT_TYPE=HANDBOOK, EVENT_DATE=GETDATE()) — в той же транзакции, что и перезапись.
По ней джоба bj2depo узнаёт, что справочник обновился, и может перечитать его. QEv10.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Раньше вход по AD бил в один контроллер (adDial → один DialURL) одной попыткой: любой
кратковременный сбой TLS/сети к DC выглядел для пользователя как неверный пароль, вход
был нестабилен. Теперь:
- ad_server может перечислять несколько контроллеров (запятая/пробел/перенос строки) —
перебираются по порядку как резерв;
- единственный контроллер пробуется дважды, чтобы одиночный сетевой сбой не ронял вход;
- повтор только на временных сбоях (сеть/TLS/контроллер недоступен). Неверный пароль,
блокировка/отключение учётки, истёкший пароль, нет пользователя/группы — окончательны
(adFinalError/adNoGroupError/errADNotFound), повтора нет и домен-недоступен не маскирует их.
adDial (проверки/мастер) тоже получил перебор резерва. Тесты: adServerURLs, adErrTransient.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
disableEmulatorsIfDevOff сбрасывал только LK.EmulateNSD / Quik.Emulate /
Quik.RealWrite, но не LK.RealNSDTest.Enabled (тест «боевой ЛК → TEST3»).
Из-за этого после истечения dev-режима подмена инвестора оставалась включённой,
а клиент без доступа к dev-вкладкам не мог вернуть стандартный режим.
Теперь сброс LK объединён в одно обновление и гасит и подмену (список паспортов
сохраняется). + тест TestDisableEmulatorsIfDevOffRealNSD.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Третий режим МНП (между «внутренняя имитация» и «боевая запись»): в bj цикл
идёт по обычному пользователю, а поручение в QUIK МНП уходит РЕАЛЬНО, но с
кодом другого, реально существующего в QUIK клиента (обобщение ручного теста
realtest «боевой ЛК → TEST3»).
- QuikMNPSettings: RealWrite + RealClientCode (валидация формата кода).
- Подмена кода — единая точка quikClientCodeFromPort (после ClientCodeMap);
портфель не трогаем. quikActive: RealWrite только при devMode и непустом
коде; Emulate (внутренняя имитация) в приоритете.
- Шаги боевого пути помечаются «[на подставного клиента <код>]» — видно в
«Поручениях QUIK».
- Карточка МНП на /admin/emulators — три взаимоисключающих режима
(выключено / имитация / реальная запись), поле кода, крупное предупреждение;
отдельный красный баннер «Реальные поручения в МНП на клиента <код> (режим
разработки)» — не смешиваем с баннером эмуляции НРД.
- disableEmulatorsIfDevOff сбрасывает и RealWrite (код остаётся, инертен),
новость явно фиксирует прекращение реальных поручений.
Если оператор временно получил dev-режим, включил эмулятор и забыл — при
окончании dev-режима флаги LK.EmulateNSD и QuikMNP.Emulate сбрасываются
насовсем (а не просто перестают действовать): при следующей выдаче dev-режима
эмуляторы молча не оживут.
Проверка disableEmulatorsIfDevOff вызывается при старте сервера (после
продления лицензии) и на каждом проходе цикла продления — ловит истечение
dev и по времени, без продления. При сбросе — запись в ленту событий:
«Эмуляторы отключены: режим разработки закончился» с перечнем выключенного;
если был включён эмулятор МНП при WritesEnabled=false — предупреждение, что
цикл МНП остановлен и для боевой работы нужно включить запись.
В режиме разработки новая страница /admin/emulators с двумя клавишами:
- «Эмулятор НРД» (флаг LK.EmulateNSD): заявки ЛК и ручного ввода идут через
внутренний имитатор, в НРД ничего не отправляется. Настройки: задержка
решения (0–300 с), исход (подтвердить/отклонить/не отвечать), код отказа
M2M01–M2M09/18. Сендер перенастраивается в рантайме через потокобезопасный
mock.Sender.Reconfigure — без перезапуска.
- «Эмулятор МНП QUIK» (флаг QuikMNP.Emulate): шаги цикла без записи в боевую
БД МНП. Настройки: задержка шага (0–60 с), точечные отказы по шагам
(регистрация/подпись/отказ/зачисление) — эмулированный отказ ведёт себя как
боевой: шаг OK=false, состояние не продвигается, повтор на следующем проходе.
Настройки хранятся в setup.json (nsd_emu/mnp_emu), обратная совместимость —
дефолты. Баннер «Режим эмуляции» показывается и при ручном включении
эмуляторов (раньше зависел только от отсутствия ИШ). Пункт меню «Эмуляторы»
и две плитки на дашборде — только в dev. Пути занесены в devOnlyPath.
Попутно: исправлен race в TestLicenseActivateAndRenew (cleanup восстанавливал
DefaultLicensePublicKey без moduleEnforceMu — падал под -race и на чистом HEAD).
- QUIK: подключение к модулю (сервер, база, логин, проверено), как bj работает с QUIK (и отклонения из расширенных), торговый счёт, поручения из терминала, справочник получателей; формы и проверка МНП — под «Перенастроить».
- Криптография: «Подпись работает / ключ скоро закончится / ключ не подключён» с кнопкой установки; ключ организации (срок, заменить), СКЗИ, bj-crypto, сертификаты НРД в справочнике шлюза; остальное — под «Перенастроить» (без повтора плашки «ключ не подключён»).
- НРД: организация, реквизиты, кто отвечает на переводы, шлюз (версия, активный контур, канал, ключ) и папки по сети — из тех же запросов, что блок шлюза (события bj-igate-status / bj-igate-share, без лишних обращений к root-обработчику); формы — под «Перенастроить».
- «Перенастроить» раскрыто само, если что-то не настроено.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
- Сверху — «Обмен с DEPO работает / настроен не до конца / не подключён» и сведения: база DEPO, сервер и СУБД, логин bj, начало номера торговых счетов, признак ИИС (отказ M2M06), трансферные таблицы, кто запускает обработку и итог последней проверки (✓/✗ и когда).
- Все прежние формы — под «Перенастроить»; раскрыто само, если что-то не проверено.
- Общий стиль сведений «название — значение» (.kv) — в оформлении для настроек.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
- Место под полосу прокрутки зарезервировано всегда (scrollbar-gutter: stable): короткий раздел без прокрутки и длинный с ней больше не сдвигают страницу и меню вбок.
- Меню разделов — на месте при прокрутке и целиком на экране (своя прокрутка, если не помещается по высоте).
- Выбор другого раздела — страница с его начала, а не с той высоты, где листали прежний (после сохранения формы — как раньше, к месту формы).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
- Имена папок: тестовый контур — igate_exchange_test, боевой — igate_exchange (было igate_exchange и igate_exchange_prod); bj переименовывает открытые по прежней схеме сам — при сверке, в первый раз через 30 с после запуска.
- После сохранения — все открытые папки с контуром: \\IP\igate_exchange_test (тестовый TEST3), \\IP\igate_exchange (боевой).
- Закрыть папки — Samba выключается (сервер не отвечает по SMB, пока папок нет).
- Установщик (bj-installer, preseed Debian, слой пакетов образа Ubuntu): samba, winbind, libnss-winbind — заранее, чтобы в закрытом контуре папки открывались без интернета; необязательной частью (нет на диске и нет сети — установка bj продолжается); службы выключены до открытия папок.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- «Через домен»: сервер bj подключается к домену AD (winbind, один раз — учётной записью администратора домена, bj её не сохраняет); папки igate_exchange(_prod) открыты группам с ролью в bj и доменным сотрудникам bj — своим входом в Windows; краткое имя домена bj берёт из AD (crossRef nETBIOSName).
- Список доступа bj сверяет сам: после изменения групп, сотрудников и настроек входа (через несколько секунд) и раз в 15 минут.
- «Простой»: как было — один логин и пароль Samba; переход с домена выключает вход через домен (учётная запись компьютера в домене остаётся).
- bj-igate-admin share: режимы simple/domain, join (realm, workgroup, admin), проверка списка доступа на недопустимые символы, состояние — mode/joined/realm.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
- bj-igate-admin share: при открытии — «map to guest = never»: с «bad user» Samba пускала текущую учётную запись Windows гостем, гостю в папку нельзя, и Windows сразу писала «нет доступа» без окна логина и пароля.
- Блок «Папки шлюза по сети» — не под раскрытием, со своим заголовком; поле пароля — скрытое (было открытым текстом).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi