Files
Deal/.superpowers/sdd/channel-discovery/task-9-report.md
T
Rustam Khalimov 27c7831910
ci / build-test (push) Canceled after 0s
Deal — единая кодовая база
SaaS-мониторинг Telegram: ядро (модули Cards/Kanban/Pipeline/Tenants/Settings/
Discovery, Api, Infrastructure), сервисы telegram/ai/ml/storage, фронт Vue,
контракты и grpc-hosting, деплой-конфиги (dev/prod/observability/CI-раннер),
Gitea Actions CI, документация (ТЗ, техдок, api-map, код-стайл, планы, бэклог).

Текущее состояние: все этапы роадмапа 0–12 закрыты, сборка 5 sln 0/0,
тесты 1340/130/52/38/9 зелёные.
2026-09-11 23:56:47 +03:00

7.0 KiB
Raw Blame History

Task 9 — Отчёт: Фронтенд — кандидаты, действия, чёрный список, история

Статус

Выполнено. cd /c/telbase/frontend && npm run build — без ошибок (✓ built, 42 modules transformed). python -m py_compile backend/app/routers/settings_routes.py — OK.

Файлы

  • Изменён: frontend/src/views/DiscoveryView.vue — табы кандидатов/истории/чёрного списка, карточки кандидатов, квоты.
  • Изменён: frontend/src/store.jsstate.discCounts + loadDiscCounts(taskId); loadDiscCandidates обновляет счётчик текущего статуса.
  • Изменён: frontend/src/components/Icon.vue — новые иконки users, megaphone, list (чипы вида источника, участники, темы).
  • Изменён: backend/app/routers/settings_routes.pydiscPaused добавлен в _PUBLIC_BOOL (одной строкой).

Что сделано

Табы панели задачи (DiscoveryView, правая колонка)

  • Под «мастером» и действиями задачи — панель с табами: «В обработке» (new), «На рассмотрении» (review), «Вступили» (joined), «Отклонены» (rejected), «История» (лог), «Чёрный список».
  • Бейджи-счётчики (state.discCounts) скрыты при 0; переключение таба вызывает loadDiscCandidates(taskId, status) / loadDiscLog(taskId) / loadDiscBlacklist(); смена активной задачи и повторный клик по ней — авто-загрузка панели (loadPanel).
  • Счётчики всех четырёх статусов обновляет loadDiscCounts (4 параллельных GET по статусам). Защита от гонок при быстром переключении табов/задач — panelSeq (stale-ответ перезагружает актуальный таб).
  • Пока задача running — список кандидатов/счётчики тихо обновляются каждый второй тик опроса (~9 c).

Карточка кандидата

  • Аватар по hue (как в ChannelsView), название, @username, чип вида (канал megaphone/brand, группа users/online, форум list/warn), участники (N участник/а/ов, «—» при None), метки marks чипами (важные — закрытая группа/история недоступна — подсвечиваются warn).
  • Соответствие: для канала/группы — «подходит N%» (по fitRatio); для форума — «подходит тем: N из M» и раскрывающийся список тем «тема „{title}" — подходит {fitCount} из {total}» с passed-подсветкой (pass — online, нет — приглушённый).
  • Кнопки «Вступить и мониторить» и «Отклонить» — только для status === 'review'; join без подтверждения, reject через askConfirm (уходит в чёрный список). Для new кнопок нет — подпись «воркер оценит источник». После join/reject счётчики перечитываются.
  • Раскрытие тем форума — локальный Set expanded (chevron).

Чёрный список

  • Выбран отдельный таб «Чёрный список» в той же панели (читабельно и не спорит с макетом). Строка: иконка, имя, причина/дата, кнопка «Снять» (removeDiscBlacklist, guard от двойного клика unbanId).

Квоты авто-вступлений

  • Маленькая кнопка «Квоты» в шапке левой панели (рядом со списком задач) → inline-блок: суточный лимит discJoinLimit, паузы мин/макс discJoinDelayMin/Max (сек), стоп-кран-переключатель discPaused.
  • Дефолты не хардкодятся: при первом открытии блока — GET /api/settings (локальная загрузка), сохранение чисел — PATCH /api/settings одним объектом (клампы 1–200 и 5–600 как на бэке, min ≤ max), стоп-кран патчится сразу при переключении.
  • На бэке discPaused добавлен в _PUBLIC_BOOL — теперь принимается PATCH и отдаётся в GET.

store.js

  • state.discCounts = { new:0, review:0, joined:0, rejected:0 }.
  • loadDiscCandidates дополнительно пишет discCounts[status].
  • loadDiscCounts(taskId) — Promise.all по 4 статусам, заполняет discCounts (не трогает discCandidates).

Вывод проверок

  1. cd /c/telbase/frontend && npm run build✓ built in 1.24s, 42 modules transformed, ошибок нет.
  2. diagnostics по DiscoveryView.vue, store.js, Icon.vue — ошибок/предупреждений нет.
  3. python -m py_compile backend/app/routers/settings_routes.py → OK.

Concerns

  1. Живой API/UI не гонялся (нет запущенного бэкенда/дев-сервера в этой сессии); поведение опирается на контракт Task 7. Визуальная проверка сценариев — за Task 10.
  2. Кнопка «Квоты» дергает GET/PATCH /api/settings напрямую из вью (в store нет state-полей под диск-квоты, по брифу разрешена локальная загрузка/сохранение через api.patch). Это единственное место, где вью импортирует api напрямую — если захочется строгой «только через store», квоты стоит перевести в store-функции.
  3. Счётчики табов получаются отдельными запросами по каждому статусу (у бэкенда нет эндпоинта counts); при активном воркере это ~4 лёгких GET каждые ~9 c — приемлемо для текущих объёмов, но при росте числа кандидатов можно добавить серверный counts.
  4. «На рассмотрении» — таб по умолчанию для активной задачи (в state.discCandidateStatus изначально review); таб «История»/«Чёрный список» сохраняется при переключении задач.
  5. progress.md не трогался.