ci / build-test (push) Canceled after 0s
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 зелёные.
7.0 KiB
7.0 KiB
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.js—state.discCounts+loadDiscCounts(taskId);loadDiscCandidatesобновляет счётчик текущего статуса. - Изменён:
frontend/src/components/Icon.vue— новые иконкиusers,megaphone,list(чипы вида источника, участники, темы). - Изменён:
backend/app/routers/settings_routes.py—discPausedдобавлен в_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 счётчики перечитываются. - Раскрытие тем форума — локальный
Setexpanded(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).
Вывод проверок
cd /c/telbase/frontend && npm run build→✓ built in 1.24s,42 modules transformed, ошибок нет.diagnosticsпоDiscoveryView.vue,store.js,Icon.vue— ошибок/предупреждений нет.python -m py_compile backend/app/routers/settings_routes.py→ OK.
Concerns
- Живой API/UI не гонялся (нет запущенного бэкенда/дев-сервера в этой сессии); поведение опирается на контракт Task 7. Визуальная проверка сценариев — за Task 10.
- Кнопка «Квоты» дергает
GET/PATCH /api/settingsнапрямую из вью (в store нет state-полей под диск-квоты, по брифу разрешена локальная загрузка/сохранение черезapi.patch). Это единственное место, где вью импортируетapiнапрямую — если захочется строгой «только через store», квоты стоит перевести в store-функции. - Счётчики табов получаются отдельными запросами по каждому статусу (у бэкенда нет эндпоинта counts); при активном воркере это ~4 лёгких GET каждые ~9 c — приемлемо для текущих объёмов, но при росте числа кандидатов можно добавить серверный
counts. - «На рассмотрении» — таб по умолчанию для активной задачи (в
state.discCandidateStatusизначальноreview); таб «История»/«Чёрный список» сохраняется при переключении задач. progress.mdне трогался.