Задача и мой вклад
У работающего сообщества уже есть правила, накопленные данные и привычные сценарии. Полная перепись с одним большим переключением делает любую потерянную деталь проблемой пользователей.
Мой вклад. Я создал KOM17 как собственный продукт: первая версия была монолитом, затем я разделил систему на модули. Отвечаю за логику сообщества и экономики, архитектуру обеих версий и требования к переходу: какие сценарии должны сохраниться, как разделить ответственность модулей и по каким признакам можно отказаться от старого пути.
Новые обработчики постепенно появлялись за совместимым входом. На этапе перехода необработанные события уходили старому боту. Тесты совместимости закрепляли существующее поведение, включая неочевидные правила. После покрытия нужных сценариев мост был удалён.
Что получилось
26 мая 2026 завершён переход на единый путь FastAPI → aiogram 3. Исторический мост больше не является рабочим fallback. Регрессионный тест не позволяет вернуть старую точку входа, а монолит остаётся источником для тестов совместимости.
Инженерные решения
Перенести поведение, а не только код
Правила экономики и модерации фиксируются в тестах до замены. Иначе более чистая реализация может незаметно изменить продукт.
Завершить переход
Временный мост полезен, пока нужен откат. После переключения его удаление закреплено тестом — временная архитектура не остаётся навсегда.
Миграции по владельцам данных
Пять SQLite-баз имеют отдельные линии Alembic. Обновление схемы выполняется для каждой явно через wrapper.
Архитектура
| Слой | Технологии и назначение |
|---|---|
| Frontend | Telegram; публичные web-страницы и администрирование |
| Backend | Python, aiogram 3, FastAPI, dishka |
| Данные | SQLAlchemy 2 async, пять SQLite-баз, Alembic |
| Инфраструктура / AI | Docker / systemd; метрики, Sentry; провайдеры текста и речи |
Компромиссы и выводы
Постепенный переход требует больше совместимого кода и тестов, чем перепись с нуля. Взамен изменения можно проверять небольшими частями. Отдельные базы разграничивают данные, но усложняют миграции и согласованность операций между ними.
Что показала практика
В коде задокументирован важный урок эксплуатации: проверка БД внутри liveness могла превращать временную блокировку SQLite в перезапуск процесса. Теперь /healthz проверяет живость, а /readyz — готовность баз. Вывод: временная недоступность зависимости не всегда означает, что процесс нужно убить.
Что бы я улучшил сейчас
Сейчас я бы раньше выделил контракты между экономикой, активностью и модерацией и сделал сценарии повторной доставки и восстановления после перезапуска частью обязательного набора проверок.
Эксплуатация и данные
Webhook принимает события Telegram, проверяет секретный заголовок и передаёт обработчику. /healthz, /readyz и /metrics дают отдельные сигналы о процессе, базах и работе приложения. Платёжные интеграции имеют собственные проверки и учёт повторов.
Данные и миграции
users, economy, activity, moderation и message_stats имеют независимые версии схемы. scripts.alembic_run выбирает нужную линию миграций. Это важно: обычная команда Alembic без выбора базы не заменяет миграцию всех пяти хранилищ.
| База | Область ответственности |
|---|---|
| users | Пользователи и профили |
| economy | Баланс и экономические операции |
| activity | Активность сообщества |
| moderation | Действия модерации |
| message_stats | Статистика сообщений |
Ограничения
Публичный репозиторий — снимок, а не вся история рабочей разработки. Для локального запуска нужен отдельный бот и конфигурация. Сквозной exactly-once для всех обработчиков не заявляется: повторная доставка требует защиты на уровне конкретной операции.
Проверяемые источники
Проверено 24.09.2026: 3 регрессионные проверки завершённого cutover. Это целевая проверка описанных решений, не аудит всего приложения.
Утверждения выше связаны с публичным кодом и документацией. Ссылки закреплены за проверенной версией; статус CI по ссылке может меняться.
