Telegram-бот для тренировки устного счёта на aiogram 3. Семь типов задач, три уровня сложности, серии дней и общий челлендж дня; пользователи и статистика в PostgreSQL, FSM-состояние активной тренировки в Redis с AOF, поэтому сессия переживает рестарт контейнера. Ежесуточные pg_dump-бэкапы и админ-панель с выгрузкой дампа по паролю.
- 7 типов задач: сложение, вычитание, умножение, деление, деление с остатком, степени, квадратные корни.
- 3 уровня сложности: easy / medium / hard, разные диапазоны чисел.
- Челлендж дня: общий для всех набор из 10 задач на календарный день (Europe/Moscow), один зачёт на пользователя, лидерборд.
- Серии и профиль: streak, max-streak, счётчики верных/неверных, топ с опцией скрыть имя.
- Быстрый старт: «любимый запуск» (сложность + режим) одной кнопкой из главного меню.
- Перерешивание ошибок: новая сессия из задач, в которых ошиблись или пропустили; правильные ответы во время сессии не показываются.
- Напоминания: пресеты и кастомные времена (APScheduler,
Europe/Moscow). - Локализация RU/EN, переключение в настройках.
- 5 таблиц:
users,training_sessions,problems,daily_challenges,daily_challenge_attempts.
Всё в Docker (postgres + redis + bot) - рекомендуемый вариант:
cp .env.example .env
# заполните: BOT_TOKEN, ADMIN_IDS, ADMIN_BACKUP_PASSWORD, POSTGRES_PASSWORD
docker compose up -d --build
docker compose logs -f botAlembic-миграции применяются автоматически при старте bot (init_db → upgrade head). FSM хранится в Redis с AOF - активные тренировки переживают рестарт. Бэкапы пишутся в ./app/data/backups на хосте.
cp .env.example .env # укажите REDIS_URL=redis://localhost:6379/0
docker compose up -d postgres redis
pip install -r requirements.txt
python -m app.mainБез REDIS_URL бот использует MemoryStorage - подходит для локальной разработки, но активные сессии теряются при рестарте.
| Команда | Назначение |
|---|---|
docker compose up -d --build |
Поднять postgres + redis + bot |
docker compose logs -f bot |
Логи бота |
python -m app.main |
Запуск бота на хосте |
alembic upgrade head |
Применить миграции вручную |
pytest tests/ -v |
Тесты (testcontainers Postgres) |
pytest tests/ --cov=app --cov-report=term-missing |
Тесты с покрытием |
Slash-команды бота: /start, /train, /profile, /top, /tips, /settings, /help.
Тесты поднимают временный Postgres через testcontainers на сессию - Docker должен быть доступен. В CI (без DinD) Postgres даётся сервисом, адрес передаётся через DOTMATH_TEST_DB_URL.
pytest tests/ -v
pytest tests/ --cov=app --cov-report=term-missing
DOTMATH_TEST_DB_URL=postgresql+asyncpg://user:pass@host:5432/dotmath_test pytest tests/BackupService запускает pg_dump --format=custom --no-owner --no-acl каждые 12 часов в app/data/backups/bot_backup_YYYYMMDD_HHMMSS.dump, хранятся последние 20. pg_dump должен быть в PATH (в образе ставится postgresql-client). Админ скачивает свежий дамп из чата по ADMIN_BACKUP_PASSWORD. Восстановление:
pg_restore --clean --if-exists -d "postgresql://user:pass@host:5432/db" app/data/backups/bot_backup_20260513_120000.dumpОдин процесс python -m app.main. bootstrap.setup_app собирает Bot/Dispatcher, выбирает FSM-хранилище (Redis или Memory), стартует NotificationService и BackupService (оба на APScheduler) и регистрирует роутеры. Сервисы прокидываются в хендлеры через dispatcher workflow data. Данные - PostgreSQL через async SQLAlchemy + asyncpg; схема версионируется Alembic и накатывается при старте.
app/
├── main.py # точка входа: setup_logging → setup_app → run_app
├── bootstrap.py # сборка Bot/Dispatcher/сервисов, выбор FSM-хранилища
├── config.py # .env → константы, fail-fast на отсутствие секретов
├── database/
│ ├── db.py # async-движок, init_db (alembic upgrade), CRUD
│ └── models.py # User, TrainingSession, Problem, DailyChallenge*
├── handlers/ # aiogram-роутеры: start, training, daily, profile,
│ # notifications, settings, admin
├── services/ # problem_generator, notification_*, backup, stats, hint
├── keyboards/ # inline-клавиатуры и callback-data
├── middlewares/ # error_middleware
├── locales/ # ru / en
└── utils/ # logger, set_commands, pagination, ui, helpers
migrations/ # Alembic (async), versions 0001-0004
tests/ # pytest + testcontainers Postgres
- fail-fast конфиг:
config.pyпадает на старте безBOT_TOKEN/DATABASE_URL/ADMIN_BACKUP_PASSWORD. - FSM-персистентность:
REDIS_URLзадан →RedisStorage, иначеMemoryStorage(dev). - Миграции при старте:
init_dbзовётalembic upgrade head, ручной шаг не нужен. - Челлендж дня идемпотентен:
UNIQUE(challenge_date)+ON CONFLICT DO NOTHINGделают первый клик безопасным при гонке. - Время -
Europe/Moscow: напоминания, бэкапы и граница календарного дня челленджа.
© 2026 DotCore. Все права защищены.
Проприетарный код. Использование, копирование, изменение и распространение запрещены без письменного разрешения автора. Исходный код открыт только для ознакомления. См. LICENSE.