Backward-compatible reorder: env var wins, then file. This lets
multiple instances on the same host (prod + shipyard staging)
each load a distinct token via systemd EnvironmentFile, instead
of fighting over the single ~/.secrets/bigbiggerbiggestbot file.
Also documents the new two-environment workflow in README.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New `events` table with (user_id, kind, created_at, data JSON).
Instruments:
Bot:
- cmd.start, cmd.history, cmd.stats, cmd.delete, cmd.export, cmd.feedback
- workout.save (source=text), workout.delete (source=bot)
Server:
- workout.save (source=webapp), workout.update, workout.delete (source=webapp)
- POST /api/events for Mini App client-side events
Mini App:
- miniapp.open on init()
- set.add on addSet(), with exercise name / reps / weight
(per-set timestamps unlock the rest-timer feature later)
log_event swallows failures so it can never break a caller.
get_events supports user_id / kind filtering for inspection.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Display workouts as "#N" based on each user's own ordered list of
non-deleted workouts (rank by timestamp ascending). Global auto-
increment id stays the primary key, used only internally and in
exports. User-visible surfaces now all use the per-user number:
- /history listing
- /delete now accepts the per-user number
- Save confirmations (bot text and Mini App toast)
Deleting a workout renumbers the later ones downward, as expected
for a pure display transform.
New db helpers: get_user_workout_number, resolve_user_number, and
get_workouts now includes user_number per row via SQLite window
function.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Users can send /feedback <text> to record feedback. Stored in a new
feedback table with user_id, text, created_at. Updated /start help text.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Parser now supports per-set notation (8x25, 5x35, 6x40),
bodyweight exercises (3x10), and asterisk separators.
Failed parse lines get user-facing error feedback instead of
being silently ignored.
Added /delete <id> and /export commands. Stats computed in SQL
instead of loading all workouts into memory. API gains DELETE,
CSV and JSON export endpoints.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- server.py: aiohttp API serving webapp/ and REST endpoints using existing db.py
- start.py: orchestrator that loads token, starts server + localtunnel + bot
- webapp/: Mini App frontend (Log, History, Stats) with Telegram-native theming
- bot.py: added Mini App menu button and inline button on /start
- flake.nix: added aiohttp + localtunnel, nix run now uses start.py
Python bot that parses workout messages (Exercise: SetsxRepsxWeight),
detects supersets from consecutive lines, extracts machine IDs, stores
both raw message text and parsed data in SQLite, and reads original
timestamps from forwarded Saved Messages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>