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>
This commit is contained in:
Danny 2026-04-18 22:32:24 +02:00
parent 8e22cdb29d
commit bc1d44b556
6 changed files with 129 additions and 19 deletions

View file

@ -17,7 +17,7 @@ from urllib.parse import parse_qs
from aiohttp import web
from db import init_db, get_db, save_workout, get_workouts, get_workout_count, get_stats_sql, delete_workout, update_workout, export_workouts
from db import init_db, get_db, save_workout, get_workouts, get_workout_count, get_stats_sql, delete_workout, update_workout, export_workouts, get_user_workout_number
from parser import parse_workout, format_workout
logging.basicConfig(
@ -227,7 +227,11 @@ async def api_save_workout(request: web.Request):
{"error": "Provide superset_groups or raw_text"}, status=400
)
return web.json_response({"workout_id": workout_id}, status=201)
user_number = get_user_workout_number(request["user_id"], workout_id)
return web.json_response(
{"workout_id": workout_id, "user_number": user_number},
status=201,
)
@require_auth
@ -244,7 +248,8 @@ async def api_update_workout(request: web.Request):
new_id = update_workout(request["user_id"], workout_id, superset_groups, note=note)
if new_id is None:
return web.json_response({"error": "Not found"}, status=404)
return web.json_response({"workout_id": new_id})
user_number = get_user_workout_number(request["user_id"], new_id)
return web.json_response({"workout_id": new_id, "user_number": user_number})
@require_auth