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 зелёные.
5.5 KiB
5.5 KiB
Task 1 — Отчёт: Схема БД и настройки по умолчанию (Discovery)
Статус: DONE
Что сделано по шагам
Step 1: Таблицы в _SCHEMA (backend/app/db.py)
Добавлены перед таблицей settings (текст SQL — дословно из брифа):
disc_tasks— задачи поиска каналов (статус, прогресс, план);disc_candidates— найденные кандидаты (оценки, статус);disc_blacklist— чёрный список;disc_log— лог событий по задаче;- индексы
idx_disc_cand_task(candidates: task_id, status) иidx_disc_log_task(log: task_id, created_at).
⚠️ ВАЖНО (поймано при проверке):
_SCHEMAисполняется по фрагментам черезsplit(";"), поэтому в---комментариях над таблицами не должно быть точки с запятой. Первая версия комментария содержала «;» внутри строки комментария — приложение падало на старте (Parser Error: syntax error at or near "столбцы"). Исправлено переформулировкой комментария без;. Inline-комментарии внутри строкCREATE TABLE(из брифа, напр.-- draft|running|...) безопасны — в них;нет.
Step 2: Настройки в DEFAULT_SETTINGS (backend/app/constants.py)
Добавлены в конец словаря (дословно из брифа):
# поиск каналов (Discovery)
"discJoinLimit": 50, # суточный лимит авто-вступлений (общий)
"discJoinDelayMin": 50, # сек, нижняя граница паузы между авто-вступлениями
"discJoinDelayMax": 70, # сек, верхняя граница
"discEvalSample": 10, # размер выборки сообщений при оценке
"discEvalThreshold": 40, # % подходящих сообщений
Step 3: Публичные ключи и клампы (backend/app/routers/settings_routes.py)
- В
_PUBLIC_INTдобавлены:discJoinLimit, discJoinDelayMin, discJoinDelayMax, discEvalSample, discEvalThreshold. - В
patch_settings(по образцу существующих кламповarchiveAfterDays/minLen):discJoinLimit→ 1..200;discJoinDelayMin/discJoinDelayMax→ 5..600;discEvalSample→ 3..30;discEvalThreshold→ 1..100.
Step 4: Проверка
Выполнена (вывод ниже).
Изменённые файлы
backend/app/db.pybackend/app/constants.pybackend/app/routers/settings_routes.py
Вывод проверок
1. py_compile
$ cd /c/telbase && python -m py_compile backend/app/db.py backend/app/constants.py backend/app/routers/settings_routes.py
PY_COMPILE_OK # без ошибок
2. Пересборка и запуск контейнера
$ docker compose build app && docker compose up -d app
[+] build 1/1 ✔ Image telbase-app Built (первый запуск упал — см. Concern/Фикс)
[+] up 3/3
✔ Container leadradar-ml Running
✔ Container leadradar-minio Running
✔ Container leadradar Started
Логи контейнера после фикса:
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Ctrl+C to quit)
3. API
POST /api/auth/login {"login":"admin","password":"admin"} → login status: 200
GET /api/settings →
settings: {"discJoinLimit": 50, "discJoinDelayMin": 50, "discJoinDelayMax": 70,
"discEvalSample": 10, "discEvalThreshold": 40}
Все пять ключей присутствуют и равны значениям по умолчанию. ✔
Дополнительно
- Попытка прямой проверки таблиц в DuckDB вторым процессом
(
duckdb.connect(..., read_only=True)) не удалась ожидаемо: DuckDB — одна запись, лок держит процесс приложения (Conflicting lock is held... PID 1). Косвенное подтверждение:_SCHEMAисполняется вstore.init()при старте и падает loudly (первый запуск упал с Parser Error — это и выявило баг), а финальный старт чистый.
Concerns
;в---комментариях_SCHEMAопасен — пайплайнsplit(";")режет схему посередине комментария. В добавленном блоке таких мест больше нет, но при будущих правках схемы стоит избегать;в комментариях.- Клампы
discJoinDelayMin/discJoinDelayMaxнезависимы (оба 5..600) — нет перекрёстной проверкиmin <= max(в брифе её не требовалось). - Прямой SQL-запрос к таблицам извне невозможен при запущенном приложении (лок
DuckDB); фактическое наличие таблиц подтверждено чистым стартом и прохождением
всей схемы в
store.init().