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 зелёные.
3.6 KiB
3.6 KiB
Task 6: Воркер Discovery (поиск → оценка → авто-вступление)
Files:
- Create:
backend/app/services/discovery_worker.py - Modify:
backend/app/main.py(фоновый цикл_discovery_loop, каждые 5 c)
Interfaces:
- Consumes:
discovery(Task 3),tg.discovery_*(Task 4),discovery_eval(Task 5),ban_guard(Task 2). - Produces:
async def tick() -> dict— выполняет ОДНО действие и возвращает{"action": ..., "taskId": ...}(или{"action": "none"}).
Логика tick (по одной задаче за вызов, начиная с самой старой running):
- Если задача
search_done=False: взять ключkeywords[search_idx], вызватьtg.discovery_search; для каждого результатаdiscovery.add_candidate;discovery.advance_search(task_id); еслиsearch_doneстал True — логsearch«поиск завершён: N кандидатов». Возврат. - Иначе взять первого кандидата статуса
newзадачи:info = tg.discovery_info;participants,kind(forum еслиis_forum); при заданномmin_subscribersи participants НЕ None и меньше минимума —set_candidate_status(...)нет: простоdiscovery.delete_candidate+ логskip; если participants None — метка «участники не подтверждены» (идём дальше).read = tg.discovery_read(dialog_id, sample_size).- Если
read.ok=False(история недоступна без членства): kind==channel →reviewс меткой «канал: история недоступна»; группа/форум →reviewс меткой «закрытая группа (история скрыта) — вступите сами»; оценка контента не производится, неподтверждённые фильтры помечаются.
- Если
- Язык: если прочитано и
task.lang=='ru':lang_ru=detect_lang_ru(...); False → удалить кандидата, логskip«язык не русский»; None → метка «язык не подтверждён». - Оценка:
evaluate_sample;passed→ метки topics/fit →review+ логreview; иначе удалить кандидата, логskip«мало подходящих (X из N)».
- Авто-вступление (отдельный проход tick, приоритет ниже оценки): если у running-задачи
auto_joinи есть кандидатreviewиban_guard.can_auto_join():- повторная проверка «мы не состоим» (
dialogs/blacklist) → если вступили уже →mark_rejectedс логом; await ban_guard.wait_join_delay()(рандом 50–70 с — спейсинг авто-вступлений; ручные join из API паузу не делают);tg.discovery_join(username)→discovery.mark_joined(dialog_id, auto=True)→tg.add_dialog_monitored(...); при FloodWaitError →ban_guard.note_flood()+ логflood.
- повторная проверка «мы не состоим» (
- Если
task.joined >= task.plan_joins→ статусdone, логdone.
- Step 1: Реализовать
discovery_worker.pyи цикл вmain.py. - Step 2: Проверить компиляцию и запуск без падений (воркер с пустыми таблицами делает
none). Полный прогон — Task 10 вручную.