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 зелёные.
2.9 KiB
2.9 KiB
Task 3: Хранилище Discovery (задачи/кандидаты/чёрный список/лог)
Files:
- Create:
backend/app/services/discovery.py
Interfaces:
-
Consumes:
store(таблицы Task 1). -
Produces (все синхронные):
list_tasks() -> list[dict],get_task(id) -> dict | None(keywords — список)create_task(payload: dict) -> dict— валидация: name непустое;plan_joins1..limit; правило бюджета:sum(plan_joins задач, где status NOT IN ('done','failed')) + plan_joins <= discJoinLimit, иначеraise ValueError(...).patch_task(id, patch: dict) -> dict(name/description/keywords/min_subscribers/lang/threshold/sample_size/plan_joins/auto_join; увеличение plan_joins — с той же проверкой)delete_task(id) -> None(удалить задачу и её кандидатов)start_task(id) -> dict— требует непустой keywords; status=running;pause_task(id) -> dict— pausedlist_candidates(task_id, status: str | None) -> list[dict](декод marks/topics)add_candidate(task_id, dialog_id, name, username, kind, hue) -> dict | None—None, если: вdialogs, вdisc_blacklist, либо уже естьdisc_candidatesсо статусом new/review/joined. Логskipс причиной.bump_counter(task_id, field: str, n: int = 1)— found/evaluated/joined/rejectedset_candidate(task_id, dialog_id, patch: dict)— обновление полей кандидатаset_candidate_status(dialog_id, status)+ логdelete_candidate(dialog_id) -> None— удалить кандидата (skip-ветки)advance_search(task_id) -> None—search_idx += 1; когда индекс >= len(keywords) →search_done=Truemark_joined(dialog_id, auto: bool)— статус joined +bump_counter('joined')+ логjoin_auto/join_manualmark_rejected(dialog_id, reason="")— статус rejected +bump_counter('rejected')+ логreject+add_blacklistadd_blacklist(dialog_id, name, reason) / remove_blacklist(dialog_id) / list_blacklist() -> list[dict]add_log(task_id, event, text="");task_log(task_id, limit=100) -> list[dict]
-
Step 1: Реализовать модуль (json-поля по конвенции проекта; все
store.execute/queryс параметрами). -
Step 2: Проверить на временной БД (сценарий): создать задачу plan=25 → ок; создать вторую plan=30 →
ValueError; кандидат, совпадающий сdialogs→add_candidateвернул None + лог skip;mark_rejected→ в чёрном списке; повторныйadd_candidateтого же источника → None.