Telegram Mini App that watches flight routes and notifies you when fares drop into your budget.
You subscribe to a route — origin, destination, date range, budget and currency. A background worker polls fare data on a schedule, and as soon as a fare matches an active subscription, the bot sends a notification in Telegram.
The bot itself is only an entry point: /start opens the Mini App, and the rest
of the experience — creating, editing, pausing and deleting subscriptions — lives
in the web interface that runs inside Telegram.
| Service | Entry point | Responsibility |
|---|---|---|
api |
app/main.py |
FastAPI backend for the Mini App; also serves the built frontend |
bot |
bot/main.py |
aiogram bot: opens the Mini App, delivers notifications |
worker |
bot/worker.py |
polls fares for active subscriptions on a loop |
edge-monitor |
ops/edge_monitor.py |
external availability and TLS certificate checks |
migrate |
Alembic | one-shot schema migration, runs under the tools profile |
Fare data comes from the Aviasales API. Prices are cached in Redis, so repeated checks across overlapping subscriptions do not re-query the upstream API.
- Backend — Python 3.11, aiogram 3.22, FastAPI 0.115, SQLAlchemy 2.0 (async, asyncpg), Alembic
- Storage — PostgreSQL 16, Redis 7
- Frontend — React 18, TypeScript 5.7, Vite 5
- Localization — Fluent, Russian and English
- Infrastructure — Docker Compose, GitHub Actions
app/ FastAPI backend: routes, Telegram initData auth, price and location services
bot/ aiogram bot, background worker, settings, database layer, locales
frontend/ React Mini App (Vite), built into frontend/dist and served by the API
migrations/ Alembic migration history
ops/ operational scripts: edge monitor, smoke checks, nginx config
tests/ pytest suite
Requires Docker and a bot/.env file — copy bot/.env.example and fill it in.
docker compose up -d db redis docker compose --profile tools run --rm --no-deps migrate docker compose up -d api bot worker edge-monitor
The API listens on 127.0.0.1:8093 by default and answers a health check at
GET /api/healthz. Postgres and Redis are published on 127.0.0.1 only.
All settings are read through pydantic-settings in bot/settings.py; there are
no direct environment reads scattered through the code. Required variables:
| Variable | Purpose |
|---|---|
TG_TOKEN |
Telegram bot token |
AVIASALES_API_TOKEN |
access to the fare data API |
POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, POSTGRES_HOST |
database connection |
REDIS_HOST |
cache connection |
Optional variables cover the Mini App URL, cache and worker timings, logging,
incident alerts and the edge monitor. See bot/.env.example for the full list.
python -m pytest --cov=app --cov=bot.db --cov=bot.main --cov=bot.worker --cov-fail-under=70 cd frontend && npm test
The Python suite fails below 70% coverage. The frontend uses Vitest and Testing Library.
GitHub Actions runs three jobs on every push and pull request: the Python suite
with coverage and flake8, the frontend test and build, and a Docker image build
that exercises the test stage. Deployment runs only after CI passes on main.