Добавить этрн.md

This commit is contained in:
2026-10-07 12:29:29 +00:00
parent 5bf6c5bb9f
commit 5ca3dbb947
+251
View File
@@ -0,0 +1,251 @@
# ТЗ на доработку: оптимизация создания и обработки ЭТрН
**Дата:** 07.10.2026
**Конфигурация:** ВесоваяАК (`ves2020`)
**Версия конфигурации (на момент анализа):** 0.0.3.21
**Область:** контур электронных транспортных накладных (ЭТрН / ЭПД, API Санадор)
**Тип работ:** оптимизация производительности без изменения бизнес-смысла процесса
Документ сформирован по результатам анализа исходников. Правки в конфигурацию этим документом не вносятся.
---
## 1. Цель и критерии успеха
### 1.1. Цель
Сократить время и нагрузку на СУБД/сеть при регламентной обработке очереди ЭТрН и при сборке payload титулов Т1/Т3, сохранив текущую модель:
- проведение документов **не** обращается к внешнему API;
- создание/отправка ЭТрН выполняется роботом `ак_ЭТрНРобот` по очереди в регистре `ак_СтатусыДокументовЭПД`;
- опросы статусов остаются пакетными по организации.
### 1.2. Критерии приёмки
| № | Критерий | Как проверить |
|---|----------|---------------|
| К1 | Один проход РЗ с той же порцией новых документов укладывается в бюджет времени стабильнее (меньше срабатываний «Исчерпан бюджет времени») | Журнал регистрации события робота до/после на сопоставимой нагрузке |
| К2 | Запросы выборки очереди (`ДобавитьНовые` / `ДобавитьОпросы` / подсчёт неудач) не сканируют лишнюю историю без необходимости | План запроса / замер времени на тестовой ИБ с наполненным регистром |
| К3 | На одну отправку Т1 уменьшено число точечных запросов к ИБ (адреса, телефоны, КИ, ТС и т.п.) | Сравнение числа запросов на документ в отладке / технологическом журнале |
| К4 | Повторные чтения параметров авторизации ЭПД и создание нового HTTP-соединения на каждый вызов устранены или сведены к минимуму в рамках порции | Код-ревью + замер latency порции |
| К5 | Поиск перевозки для Т3 без uuid не выполняет отдельный HTTP-запрос на каждый документ при одинаковых ключах поиска | Код-ревью сценария «только Т3» |
| К6 | Поведение статусов, идемпотентность перепроведения и запрет повторной отправки Т1 при наличии uuid **не нарушены** | Регрессионные сценарии §6 |
Нефункционально: изменения обратимы, без «тихих» смен контракта API Санадора.
---
## 2. Текущая архитектура (as-is)
### 2.1. Поток
```text
Проведение (5 видов документов)
↓
ак_ЭТрНРобот.ЗарегистрироватьПриПроведении
↓
РС ак_СтатусыДокументовЭПД («К отправке» / «Не требуется»)
↓
РЗ ак_ОбработкаОчередиЭТрН → ак_ЭТрНРобот.ОбработатьОчередь
↓
ак_ЭТрНОтправка (Т1 / Т3) ← ак_ЭТрНФормированиеТитулов ← ак_ЭТрНДанные
↓
ак_ПолучениеДанныхЭПД (синхронный HTTPS к Санадору)
```
### 2.2. Ключевые объекты
| Объект | Назначение |
|--------|------------|
| `ОбщийМодуль.ак_ЭТрНРобот` | Регистрация при проведении, очередь, регламент |
| `ОбщийМодуль.ак_ЭТрНОтправка` | Сборка + отправка Т1/Т3, запись статусов |
| `ОбщийМодуль.ак_ЭТрНФормированиеТитулов` | Payload титулов для API |
| `ОбщийМодуль.ак_ЭТрНДанные` | Запросы к ИБ, `КешДанных` |
| `ОбщийМодуль.ак_ЭТрНКлиентСервер` / `ак_ЭТрНПовтИсп` | Контекст, статусы, константы |
| `ОбщийМодуль.ак_ПолучениеДанныхЭПД` | HTTP к API ЭПД |
| `РС.ак_СтатусыДокументовЭПД` | Очередь и история статусов (период — секунда) |
| `РС.ак_УчетныеЗаписиЭПД`, `ак_АбонентыЭПД` | Учётные записи / абоненты |
| `РЗ.ак_ОбработкаОчередиЭТрН` | Метод: `ак_ЭТрНРобот.ОбработатьОчередь` |
| `Обработка.ак_ВыбывшиеДокументыЭТрН` | РМ по застрявшим документам |
Документы-основания: `РасходнаяНакладная`, `РасходПоСкладу`, `ПеремещениеСПоляНаЭлеватор`, `ПриходПоВесовой`, `ПриходПоСкладу`.
Отдельного документа «Электронная транспортная накладная» в конфигурации нет: ЭТрН создаётся во внешнем сервисе.
### 2.3. Что уже сделано удачно (не ломать)
- Проведение не ходит в сеть.
- Разделение очередей «новые» / «опросы» по наличию `ИдентификаторСанадор` (защита от повторного Т1).
- Пакетный опрос статусов по организации (порции uuid).
- Раздельные лимиты порций новых и опросов, мягкий бюджет времени.
- `КешДанных` на порцию (часть идентификаторов / auth / организация по контрагенту).
- Ключ регламентного задания против параллельного запуска.
---
## 3. Проблемы (на основании анализа кода)
| ID | Проблема | Где | Влияние |
|----|----------|-----|---------|
| P1 | Синхронный HTTP в цикле по документам порции; каждое соединение создаётся заново | `ОбработатьОчередь` → отправка → `ак_ПолучениеДанныхЭПД.ОтправитьHTTPЗапрос` | Основной риск исчерпания бюджета 300 с |
| P2 | Auth (`ак_УчетныеЗаписиЭПД`) читается на каждый HTTP; кэш робота HTTP-слоем не используется | `ВызватьHTTPМетод` | Лишние обращения к РС на каждый вызов |
| P3 | `СрезПоследних` без отбора по измерениям; итоги среза последних выключены; `ВТ_Неудачи` сканирует историю по регистру | `ДобавитьНовые`, `ДобавитьОпросы`, `ТекстВременнойТаблицыНеудач` | Рост стоимости РЗ с объёмом истории |
| P4 | Фильтрация статусов по `.Наименование` (строка) | Запросы робота | Хуже для индексации/планов, хрупкость |
| P5 | Много точечных запросов на сборку одного Т1 | `ак_ЭТрНДанные` + `ак_ЭТрНФормированиеТитулов` | Нагрузка на СУБД пропорционально порции × полям |
| P6 | Поиск Т3 без uuid: HTTP-список АРМ на каждый документ | `ак_ЭТрНОтправка.ПеревозкаВСервисе` | Лишние сетевые вызовы при сценарии «только Т3» |
| P7 | Мелкие накладные: ИНН через точечные чтения; `Метаданные.НайтиПоТипу` в цикле РМ | `ПеревозкаСторонняя`, `ДокументыСОшибками` | Вторичный эффект |
---
## 4. Объём доработки (to-be)
Работы разбиты на этапы. Этапы можно сдавать отдельно при сохранении критериев §1.2 для затронутой части.
### Этап A — очередь и регистр статусов (P3, P4) — приоритет 1
**Задачи**
1. Оценить и при положительном результате **включить итоги среза последних** у `ак_СтатусыДокументовЭПД` (сейчас `EnableTotalsSliceLast = false`). Зафиксировать влияние на запись статусов и объём ИБ.
2. Переработать выборку кандидатов очереди:
- не строить полный срез «всего регистра», если достаточно отбора по активным статусам / отдельной структуре очереди;
- подсчёт неудач (`ВТ_Неудачи`) ограничить документами-кандидатами текущей выборки, а не всей историей ошибок.
3. По возможности заменить отбор по `Статус.Наименование` на отбор по ссылкам справочника `ак_СтатусыЭТРН` (предопределённые / кэшированные ссылки).
4. (Опционально, при росте объёма) ввести узкий регистр/механизм «активная очередь» (документ + вид очереди: новый/опрос), историю статусов оставить в текущем РС.
**Ограничения**
- Сохранить семантику: условие в параметрах `СрезПоследних` по статусу **нельзя** ставить так, чтобы возвращалась «последняя запись с таким статусом», а не последняя запись документа (это уже осознанно зафиксировано в комментариях модуля).
- Не менять смысл границы «новый / опрос» по `ИдентификаторСанадор`.
**Результат этапа:** ускорение `ДобавитьНовые` / `ДобавитьОпросы` / протокола ошибок на наполненном регистре.
### Этап B — HTTP и авторизация в рамках порции (P1, P2) — приоритет 1
**Задачи**
1. Переиспользовать `HTTPСоединение` (и при возможности параметры авторизации) **в рамках одной порции / одной организации**.
2. Пробросить/использовать кэш параметров авторизации (`КешДанных.ПараметрыАвторизации` или аналог) в `ак_ПолучениеДанныхЭПД.ВызватьHTTPМетод`, чтобы не читать `ак_УчетныеЗаписиЭПД` на каждый вызов.
3. Настроить/зафиксировать рекомендуемые параметры РЗ: меньшая порция новых (ориентир 10–20) при отдельном/более частом запуске опросов — без изменения кода бизнес-логики титулов, если достаточно настроек расписания и параметров метода.
**Ограничения**
- Параллельный запуск нескольких экземпляров робота по-прежнему не допускается без отдельного архитектурного решения (ключ РЗ).
- Контракт API (URL, заголовки Bearer / `counterparty-uuid`, тела Т1/Т3) не менять.
**Результат этапа:** снижение latency порции отправки при том же числе документов.
### Этап C — пакетная подготовка данных титула Т1 (P5) — приоритет 2
**Задачи**
1. Расширить prefetch на порцию: один или несколько пакетных запросов по массиву документов вместо серии точечных вызовов (`РабочийТелефонВодителя`, `АдресВесовой`, адреса/телефоны сторон, координаты, `ДокументЗакрепленияТС`, даты прибытия/убытия и т.п. — по фактическому использованию в `ПараметрыОтправкиТ1`).
2. Расширить `КешДанных` ключами по ссылкам (адреса КИ, телефоны, коды регионов, закрепления ТС), с заполнением из prefetch.
3. По возможности дополнить уже существующий `ДанныеПоДокументам` (UNION по видам документов) полями, которые сейчас читаются повторно при сборке payload.
**Ограничения**
- Состав и смысл полей JSON payload Т1/Т3 не менять (кроме явно согласованных дефектов данных).
- Ошибки заполнения полей по-прежнему фиксируются в результате формирования / статусах.
**Результат этапа:** меньше запросов к ИБ на документ при отправке Т1.
### Этап D — батч поиска перевозки для Т3 (P6) — приоритет 2
**Задачи**
1. Группировать вызовы `ПолучитьСписокДокументовДляАРМ` по ключу (организация, водитель, номер ТС, окно дат) внутри порции.
2. Разбирать общую таблицу ответа локально для нескольких документов группы.
3. Где в данных есть uuid связанной перевозки / ранее сохранённый идентификатор — использовать его и не вызывать поиск АРМ.
**Ограничения**
- Правила различения нескольких перевозок «Груз в пути» (входящий номер / номер документа) сохранить.
- Состояния ожидания Т2 по-прежнему блокируют отправку Т3.
**Результат этапа:** меньше HTTP при сценарии документов только с Т3 без uuid.
### Этап E — мелкие оптимизации (P7) — приоритет 3
**Задачи**
1. Пакетное/кэшируемое чтение ИНН сторон в `ПеревозкаСторонняя`.
2. В `ДокументыСОшибками` — соответствие тип → синоним вместо `Метаданные.НайтиПоТипу` на каждую строку.
3. Оценить необходимость двух записей статуса после успешного Т1 («Черновик…» + «Ожидается Т2…»); менять только при согласовании с пользователями РМ/отчётами по истории.
---
## 5. Вне объёма
- Изменение формата обмена с Санадором / новых титулов ЭПД.
- Перенос создания ЭТрН в интерактивный режим «по кнопке» вместо робота.
- Оптимизация бумажных макетов `ПФ_MXL_ТранспортнаяНакладная*`.
- Параллельная обработка очереди несколькими рабочими процессами (требует отдельного ТЗ по блокировкам и идемпотентности API).
- Рефакторинг модулей `сндОбменДаннымиСанадор*` вне контура ЭТрН.
---
## 6. Регрессионные сценарии
| № | Сценарий | Ожидание |
|---|----------|----------|
| R1 | Проведение документа со сторонней перевозкой и включённой настройкой Т1/Т3 | Статус «К отправке», сеть не вызывается |
| R2 | Проведение при внутренней перевозке / выключенных настройках | «Не требуется» или отсутствие постановки по текущим правилам |
| R3 | Повторное проведение документа уже в процессе | Статус/очередь не дублируют отправку |
| R4 | РЗ: новый документ → Т1 | Черновик в сервисе, заполнен `ИдентификаторСанадор`, статус ожидания Т2 |
| R5 | РЗ: опрос при готовности к Т3 | Отправка Т3, корректный статус |
| R6 | РЗ: документ с ошибкой первой отправки, неудач < максимума | Повторная попытка как «новый» |
| R7 | Документ с uuid и ошибкой Т3 | Не уходит в очередь «новых», не создаётся второй Т1 |
| R8 | РМ «Выбывшие документы ЭТрН» → вернуть в очередь | Счётчик неудач сбрасывается логикой `ВернутьВОчередь`, история сохраняется |
| R9 | Исчерпание бюджета времени | Текущий документ дорабатывается, остальные подхватываются следующим запуском |
---
## 7. Порядок внедрения и оценка
Рекомендуемый порядок: **A → B → C → D → E**.
| Этап | Ориентир трудозатрат | Зависимости |
|------|----------------------|-------------|
| A | 2–5 чел·дн (без нового РС); +2–4 при введении узкой очереди | Решение по итогам среза / метаданным РС |
| B | 1–3 чел·дн | Согласование сигнатур HTTP-обёрток |
| C | 3–6 чел·дн | Этап B желателен, не обязателен |
| D | 1–3 чел·дн | — |
| E | 0,5–1,5 чел·дн | — |
Оценки ориентировочные; уточняются после замера текущего времени `ДобавитьНовые`/`ДобавитьОпросы` и средней длительности HTTP на тестовой/боевой статистике.
---
## 8. Риски
| Риск | Митигация |
|------|-----------|
| Включение итогов среза увеличит стоимость каждой записи статуса | Замер записи до/после; при неприемлемости — узкая очередь без итогов |
| Кэш auth устареет при смене токена в середине порции | Инвалидация кэша по организации при 401/ошибке авторизации и один повтор |
| Prefetch полей титула разъедется с ветвлениями по видам документов | Покрыть R4–R5 на всех 5 видах документов |
| Батч поиска Т3 склеит чужие перевозки | Сохранить текущие правила уточнения по номерам; не укрупнять ключ сверх (орг+водитель+ТС+даты) |
---
## 9. Поставка
1. Описание изменений по модулям/метаданным.
2. Результаты замеров до/после (хотя бы время порции РЗ и число запросов/HTTP на документ).
3. Протокол прохождения сценариев §6.
4. При изменении метаданных РС — инструкция обновления ИБ и оценка времени пересчёта итогов (если применимо).
---
## 10. Источники анализа
- `ves2020/CommonModules/ак_ЭТрНРобот/Ext/Module.bsl`
- `ves2020/CommonModules/ак_ЭТрНОтправка/Ext/Module.bsl`
- `ves2020/CommonModules/ак_ЭТрНФормированиеТитулов/Ext/Module.bsl`
- `ves2020/CommonModules/ак_ЭТрНДанные/Ext/Module.bsl`
- `ves2020/CommonModules/ак_ПолучениеДанныхЭПД/Ext/Module.bsl`
- `ves2020/InformationRegisters/ак_СтатусыДокументовЭПД.xml`
- `ves2020/ScheduledJobs/ак_ОбработкаОчередиЭТрН.xml`
**Memory:** локальный `memory.md` (постоянных записей по ЭТрН нет).
**Template:** проверка шаблонов MCP в сессии недоступна — «no fitting template».
**Docs / Metadata tooling:** разбор по исходникам выгрузки; live MCP user-1c при анализе был частично недоступен.