# Архитектура проекта Версия: см. [`VERSION`](../VERSION). История изменений: [`docs/CHANGELOG.md`](CHANGELOG.md). ## Назначение Система загружает посты и события из внешних источников, хранит их в MariaDB, публикует анонсы в Telegram-канал и даёт веб-интерфейс для редактирования и управления подписками через responder-бота. Поддерживаются два режима работы (`WORKMODE` в `.env`): | Режим | Источники данных | Публикация | |-------|------------------|------------| | **ZILANT** | VK (`vk_load.py`), JSON Zilant (`zk_load.py`) | `tg_publish.py`, `evtg_publish.py` | | **VOLK** | VOLK API (`volk_load.py`) | `volk_cat_publish.py` | Подробнее о VOLK: [`docs/volk-mode.md`](volk-mode.md). ## Компоненты runtime ``` ┌─────────────────┐ rsync ┌──────────────────┐ │ Woodpecker CI │ ─────────────► │ /opt/testbot-git │ └─────────────────┘ └────────┬─────────┘ │ ┌──────────────────────────────────┼──────────────────────────┐ ▼ ▼ ▼ runner.timer testbot-git.service testedit-git.service → runner.sh gunicorn :5005 gunicorn :5006 vk_load, zk_load, wsgi_bot → tg_mainbot wsgi_edit → db_edit db_update_shortname, tg_publish, evtg_publish ``` ### Responder-бот (подписки) - **`tg_mainbot.py`** — Flask + webhook, обработка `/start`, callback-кнопок подписки. - **`wsgi_bot.py`** — точка входа gunicorn; однократная регистрация webhook с file lock. - **`season_links.py`** — сезонные payload (`zk2026_post_*`, `subscribe_zk2026_*` и т.д.). - Старые ссылки без префикса сезона → сообщение «сезон завершён» + кнопка в канал. ### Poster (публикация в канал) - **`tg_publish.py`** — посты VK → Telegram. - **`evtg_publish.py`** — события → Telegram. - **`volk_cat_publish.py`** — категории VOLK → Telegram (режим VOLK). - Все исходящие вызовы Bot API — через **`telegram_relay.py`** (`RELAY_URL`). ### Веб-интерфейс - **`db_edit.py`** — CRUD постов/событий, кнопки рескана, публикации, «Назвать» (AI shortname). - **`db_update_shortname.py`** — генерация коротких названий через RouterAI. - **`test_tg_poster.py`** — тестовый пост в канал (кнопка «Тест» в UI). - Шаблоны: `templates/`. ### База данных - **`ensure_db.py`** — создание/миграция схемы (вызывается из loader-скриптов). - **`backupdb.sh`** — дамп БД при deploy (`post-deploy.sh`). ## Пайплайн runner.sh (ZILANT) Порядок выполнения (systemd timer `runner.timer`): 1. `vk_load.py` — загрузка постов из VK 2. `zk_load.py` — загрузка событий из JSON 3. `db_update_shortname.py` — AI shortname для новых записей 4. `tg_publish.py` — публикация постов 5. `evtg_publish.py` — публикация событий > **`tools/legacy/evt_prefetch.py`** раньше стоял перед `evtg_publish.py`; с 1.0.0 снят с пайплайна. ## Deploy - **`.woodpecker.yml`** — rsync на сервер, затем `services/post-deploy.sh`. - **`post-deploy.sh`** — venv, pip, backup БД, обновление systemd units, restart сервисов. ## Конфигурация (.env) Шаблон для нового инстанса: [`.env.example`](../.env.example). ```bash cp .env.example .env # заполнить CHANGE_ME_*; секреты: python tools/ops/genkey.py ``` | Переменная | Назначение | |------------|------------| | `WORKMODE` | `ZILANT` или `VOLK` | | `SEASON` | Префикс сезона для deep link (`zk2026`) | | `RELAY_URL` | Internal relay для Bot API | | `WEBHOOK_URL`, `WEBHOOK_SECRET` | Доставка апдейтов боту | | `MDB_*`, `MDBASE` | MariaDB | | `POSTER_BOT_TOKEN`, `RESPONDER_BOT_TOKEN` | Токены ботов | | `PZK_PREFIX`, `EVT_PREFIX`, `DESC_PREFIX` | Ссылки ZILANT | | `VK_NO_REPOST_TAG` | Тег VK, отключающий автопубликацию | | `VK_POST_MIN_LETTERS` | Минимум букв в тексте VK-поста (иначе «пустой пост», не публиковать) | | `VOLK_*` | API VOLK (при `WORKMODE=VOLK`) | | `RA_KEY`, `RA_MODEL` | RouterAI для shortname | ## Карта файлов ### Ядро (runtime) | Файл | Роль | |------|------| | `tg_mainbot.py` | Responder-бот, webhook | | `wsgi_bot.py` | Gunicorn entry (бот) | | `db_edit.py` | Веб-UI | | `wsgi_edit.py` | Gunicorn entry (UI) | | `tg_publish.py` | Публикация постов | | `evtg_publish.py` | Публикация событий | | `vk_load.py` | Загрузка VK | | `zk_load.py` | Загрузка Zilant JSON | | `volk_load.py` | Загрузка VOLK (режим VOLK) | | `volk_cat_publish.py` | Публикация VOLK (режим VOLK) | | `db_update_shortname.py` | AI shortname | | `formatter.py` | Форматирование текста постов/событий | | `ensure_db.py` | Схема БД | | `telegram_relay.py` | Relay для Bot API | | `season_links.py` | Сезонные ссылки и callback | | `test_tg_poster.py` | Тестовая публикация (UI) | | `runner.sh` | Пайплайн по расписанию | | `backupdb.sh` | Бэкап БД | | `gunicorn_bot.conf.py` | Stub-конфиг gunicorn (бот) | ### Инфраструктура | Путь | Роль | |------|------| | `services/testbot-git.service` | systemd: бот :5005 | | `services/testedit-git.service` | systemd: UI :5006 | | `services/runner.service`, `runner.timer` | systemd: hourly runner | | `services/post-deploy.sh` | Post-deploy | | `.woodpecker.yml` | CI deploy | ### Вспомогательные (`tools/`) | Путь | Роль | |------|------| | `tools/ops/genkey.py` | Генерация секретов | | `tools/ops/register_tg_webhook.py` | Ручная регистрация webhook | | `tools/ops/copy_databases.sh` | Клонирование MariaDB | | `tools/dev/send_telegram_example.py` | CLI-пример `/send_message` | | `tools/dev/volk_telegram_testing.py` | Отладка публикации в Telegram | | `tools/dev/volk_category_testing.py` | Отладка загрузки категории VOLK | | `tools/legacy/evt_prefetch.py` | Legacy: prefetch событий | См. [`tools/README.md`](../tools/README.md). ### Документация | Файл | Содержание | |------|------------| | `README.md` | Быстрый старт | | `docs/ARCHITECTURE.md` | Этот файл | | `docs/volk-mode.md` | Режим VOLK | | `docs/telegram-messaging.md` | API `/send_message` | | `docs/runner-setup.md` | Настройка runner timer | | `docs/CHANGELOG.md` | История версий | ## Версионирование - Версия в корне: **`VERSION`** (SemVer: `MAJOR.MINOR.PATCH`). - При каждом значимом изменении обновлять `VERSION` и запись в `docs/CHANGELOG.md`. - Правило для агентов: `.cursor/rules/version-and-docs.mdc`.