Commit graph

6 commits

Author SHA1 Message Date
Danny
9f146d60fa feat: last-session recall when starting an exercise
When you start an exercise, the Mini App now fetches the most
recent time you logged it and shows a hint line in the sets card
("Last time: 8×60, 6×60, 5×60 · 3 days ago"), plus pre-fills the
weight input with the last set's weight.

- db.get_last_exercise(user_id, name): most recent non-deleted
  entry, case-insensitive name match, sets_detail parsed.
- GET /api/exercises/last?name=<name>.
- webapp: loadLastSession() on startExercise + draft restore;
  hint cleared on editExercise (the set rows are the reference
  there). Pre-fill only when the weight field is empty and no
  sets logged yet, so it never clobbers user input.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:52:37 +02:00
Danny
6d1de53b2e feat: profile/settings (rest timer toggle)
Settings infrastructure + one working preference:

- New user_settings table (JSON blob per user, so adding
  future keys needs no migration).
- db.get_settings / update_settings helpers (merge semantics).
- GET/PUT /api/settings endpoints.
- New Settings tab in the Mini App with a rest-timer on/off
  toggle. Setting is loaded on init and written through on
  change; the rest-timer display now respects it.

Units (kg/lb) and language are intentionally left unwired for
now — each needs end-to-end display/input changes and deserve
focused passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 15:36:06 +02:00
Danny
52277e99de feat: interaction / event logging
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>
2026-04-19 14:03:42 +02:00
Danny
0e4bf65d5b feat: global exercise-name autocomplete
Autocomplete now draws from every user's logged exercises, not
just the requesting user's history. New users get suggestions from
day one.

- db.get_all_exercise_names(): case-insensitive grouping, ordered
  by usage count desc, alphabetical tiebreak, excludes names that
  only appear in soft-deleted workouts.
- server.api_get_exercise_names simplified to a one-liner.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 13:56:53 +02:00
Danny
bc1d44b556 feat: per-user workout numbering (#7)
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>
2026-04-18 22:32:24 +02:00
Danny
e7ac2b174f feat(tg-fitness-bot): add test suite with pre-commit hook
pytest + pytest-asyncio in flake.nix. 53 tests covering parser
(all formats, error cases) and db (CRUD, soft delete, update,
stats, pagination). Pre-commit hook runs tests when fitness bot
files are staged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 20:41:03 +02:00