Architecture Overview
Standalone mode (default)
When SCHEDULE_DB_URL is not set, each bot fetches from DTEK independently:
┌─────────────────┐ HTTP ┌──────────┐
│ dtek-telegram │ ─────────────────▶ │ DTEK │
│ -bot │ ◀───────────────── │ website │
└─────────────────┘ └──────────┘
│ cache (in-memory)
▼
serve users
┌─────────────────┐ HTTP ┌──────────┐
│ dtek-discord │ ─────────────────▶ │ DTEK │
│ -bot │ ◀───────────────── │ website │
└─────────────────┘ └──────────┘
│ cache (in-memory)
▼
serve users
Each bot maintains its own in-memory cache with a TTL of CACHE_DURATION_MINUTES.
On a cache miss or expiry the bot makes a fresh HTTP request to DTEK.
Shared DB mode
When SCHEDULE_DB_URL is set, a single dtek-schedule-service process owns
all DTEK traffic. Bots become read-only consumers of the shared SQLite:
┌──────────────────────┐ HTTP ┌──────────┐
│ dtek-schedule │ ─────────────────▶ │ DTEK │
│ -service │ ◀───────────────── │ website │
└──────────────────────┘ └──────────┘
│ writes every 30 min
▼
┌──────────┐ (schedules table)
│ shared │
│ .db │
└──────────┘
│ │
▼ ▼
┌─────────┐ ┌─────────┐
│ TG │ │ DS │
│ bot │ │ bot │
│(reads) │ │(reads) │
└─────────┘ └─────────┘
│ │
▼ ▼
own local.db own local.db
(subscriptions) (user_groups)
The in-memory cache is kept in both bots — the shared DB is only consulted on a cache miss, so bots still serve most requests from RAM.
Caching layers
User request
│
▼
In-memory cache (RwLock)
│ HIT → return immediately
│ MISS ↓
▼
SCHEDULE_DB_URL set?
│ YES → read from SQLite shared DB
│ NO → spawn_blocking → DTEKParser → HTTP
▼
Update in-memory cache
│
▼
Return to user