Стримить прогресс пакетной переклассификации

CardReclassifier отдаёт IProgress-отчёты, эндпоинт публикует SSE cards_reclassified {progress:true,...} каждые 5 карточек и финальное событие; фронт показывает done/total и перечитывает доску только по финалу. Закрывает BL-RECLASS-SSE.
This commit is contained in:
Rustam Khalimov
2026-09-11 17:57:47 +03:00
parent ea21dc54c6
commit e62dbfafba
13 changed files with 209 additions and 16 deletions
@@ -30,7 +30,7 @@
| `new_card` | объект **Card** (см. ниже) | создана карточка (пайплайн, демо, тик) |
| `reminder_due` | `{ "id", "title", "containerId" }` | наступило напоминание |
| `toast` | `{ "text", "icon" }` | статистика тика / служебное уведомление |
| `cards_reclassified` | `{ "reclassified", "moved" }` | завершена переклассификация карточки/«Неразобранного» |
| `cards_reclassified` | промежуточный — `{ "progress": true, "done", "total", "moved", "kept", "trashed", "skipped" }`; финал — `{ "progress": false, "reclassified", "moved" }` | прогресс/завершение переклассификации «Неразобранного» |
`new_lead` больше не публикуется (переименован в `new_card`).
@@ -216,9 +216,10 @@
сервиса — детерминированный локальный разбор (без кредов сервис не падает). `usedAi` показывает путь.
- Одна переклассификация за раз (single-flight): при занятом проходе `{ "started": false, "busy": true }`.
- Аудит — событие `card_reclassified` (только при `reclassified > 0`).
- После успешного прохода (`started = true` и `reclassified > 0`) в канал тенанта публикуется SSE
`cards_reclassified` с минимальной нагрузкой `{ "reclassified", "moved" }`; фронт перечитывает доску.
Пустой inbox/всё пропущено не меняют доску — событие не шлётся. Без подписчиков — no-op.
- Во время пакетного прохода публикуются промежуточные SSE `cards_reclassified` с `{ "progress": true,
"done", "total", "moved", "kept", "trashed", "skipped" }` (каждые 5 карточек и на последней); по завершении —
финальное `{ "progress": false, "reclassified", "moved" }`; фронт показывает `done/total` и перечитывает
доску только по финальному событию.
```json
{