.счёт
DotMath
Решил пример, и один и тот же результат уже разложен на четыре места в рейтинге.
суть
Двуязычный Telegram-тренажёр устного счёта, построенный вокруг удержания: серии дней, напоминания и рейтинг, который читает один и тот же результат сразу с четырёх сторон: стрик, решено, точность и взвешенные очки, где сложное стоит дороже. Общий челлендж дня сравнивает всех на одном наборе задач, а работа над ошибками собирает отдельную сессию из того, что не далось.
Платформа изнутри
Интерактивный разбор ключевых механик. Выбери домен, увидишь как всё работает изнутри.
Выбери, что тренировать.
Настройка
что тренируемРеши
пример 1 из 7посчитай в уме и выбери ответ
промахи копятся: «перерешать ошибки» собрал бы новый набор только из них
Табло
один результат: четыре срезасамая длинная серия без пропусков
- Аня 0
- Борис 0
- Вера 0
- ты ты 0
Серия дней
последние 7 дней- день с верным ответом
- пропуск обнуляет серию
- второй подход за день ничего не меняет
текущая серия: 4 дн.
ProblemGenerator · DIFFICULTY_CONFIG · StatsService: 4 среза · веса 1·2·3 · челлендж дня · aiogram 3 · PostgreSQL + asyncpg · Redis FSM · APScheduler · ~9k строк · RU/EN
масштаб
размер и срок: что стоит за продуктом.
архитектура
Источник апдейтов; бот опрашивает через long polling
- DotMath bot polling
APScheduler-cron шлёт напоминания (Europe/Moscow)
- Telegram API cron
Dispatcher: роутеры-хендлеры, FSM, DI сервисов
- Problem gen
- Scoring · top
- PostgreSQL 16
- Redis · FSM
7 операций × 3 уровня; seed-RNG для челленджа дня
Рейтинг в 4 среза, очки с весом по сложности
- PostgreSQL 16
pg_dump каждые 12ч, последние дампы лежат на хосте
- PostgreSQL 16 pg_dump
FSM активной тренировки; AOF переживает рестарт
Пользователи, сессии, задачи и челлендж дня
стек
- Язык 1
- Фреймворк 4
- Данные 3
- Инфраструктура 5
- Клиент 1
Язык
- Python 3.12
Фреймворк
- aiogram 3.15
- SQLAlchemy 2.0
- Pydantic 2
- APScheduler 3.10
Данные
- PostgreSQL 16
- Redis
- asyncpg
Инфраструктура
- Alembic 1.14
- Docker
- GitHub Actions
- pg_dump backups
- testcontainers
Клиент
- Telegram Bot API
что умеет
ключевые возможности продукта прямо сейчас.
Тренировки
Семь типов операций, от сложения до степеней и квадратных корней, на трёх уровнях сложности. Можно выбирать ответ из вариантов или писать его сам.
Уровень меняет и диапазон чисел, и размер набора: у лёгкого 5 примеров и 2 варианта, у среднего 7 и 3, у сложного 10 и 4. Неверные варианты подбираются как правдоподобные соседи (гауссов разброс вокруг ответа), а в режиме «Напиши ответ сам» ответ вводится с клавиатуры.
Челлендж дня
Общий для всех набор из 10 задач на календарный день, один зачёт на человека и отдельный дневной рейтинг по верным ответам и времени.
Набор детерминирован seed-ом, поэтому у всех он одинаковый. UNIQUE по дате и ON CONFLICT DO NOTHING делают первый клик безопасным при гонке, а UNIQUE по паре «пользователь + дата» гарантирует ровно одну попытку. Сутки считаются по Europe/Moscow.
Рейтинг в четыре среза
Один и тот же результат читается с четырёх сторон: серия, всего решено, точность и взвешенные очки, где сложное стоит дороже.
Взвешенные очки: лёгкое × 1, среднее × 2, сложное × 3 по верным ответам, поэтому в каждом срезе может лидировать свой человек. Имя в топе можно скрыть, список листается постранично.
Привычка и удержание
Серия дней держится, пока не пропустишь день; настраиваемые напоминания возвращают к тренировке, а быстрый старт запускает любимый режим одной кнопкой.
День с хотя бы одним верным ответом продлевает серию; пропуск её обнуляет, а второй подход за день ничего не меняет. Напоминания бывают пресетами (утро, обед, вечер или три раза в день) и своим временем на APScheduler в том же процессе.
Работа над ошибками
Отдельная сессия собирается только из задач, в которых ты ошибся или пропустил: правильные ответы во время неё не показываются.
Каждая задача сохраняется со своим форматом и метаданными (остаток, показатель степени, подкоренное число), поэтому перерешивание восстанавливает её точь-в-точь, а не как «144 √ 0».
RU + EN и стойкость к рестарту
Полная локализация с переключением языка на лету, состояние активной тренировки в Redis и ежесуточные бэкапы базы.
FSM активной тренировки лежит в Redis с AOF, поэтому сессия переживает рестарт контейнера; без Redis используется MemoryStorage для локальной разработки. pg_dump пишет дамп каждые 12 часов и хранит последние 20.
хронология
как продукт рос от первой версии.
-
14 Feb 2026
Старт .счёта
MVP за день: 7 операций × 3 уровня, режим «Напиши ответ сам», рейтинг с сортировкой и напоминания на APScheduler (пресеты + своё время).
-
4 Mar 2026
Админ-панель и приватность рейтинга
Панель администратора, скрытие имени в топе и pagination, выгрузка бэкапа из чата по паролю.
-
13 May 2026
SQLite → PostgreSQL
Полный переезд на PostgreSQL, pg_dump-бэкапы каждые 12 часов и рефактор интерфейса.
-
30 May 2026
Челлендж дня, работа над ошибками, прод-обвязка
Общий челлендж дня и перерешивание ошибок, быстрый старт с любимым режимом, anchor-message UX на CallbackData; Redis FSM, Docker и CI.
-
16 Jun 2026
Закрытая сеть, Postgres-only
Docker-образ хардится на tini и непривилегированном пользователе, Postgres и Redis лишаются последнего открытого порта наружу, CI получает сборку образа. Следом полностью выброшен SQLite-тулинг: в проекте остаётся только Postgres.
-
Jun 2026
Сейчас: секреты и права под замком
Ужесточаются права контейнера и CI, пароль бэкапа получает timing-safe проверку; следом pg_dump уходит со строки подключения в логах на переменную окружения, healthcheck бота работает по heartbeat-файлу, GitHub Actions запинены на коммит, а SECURITY.md открывает приватный канал раскрытия уязвимостей через GitHub Security Advisories.