From dd4134b1ce7016bf2908076867799554073019d5 Mon Sep 17 00:00:00 2001 From: Fizzlepoof Date: Thu, 28 May 2026 20:55:22 +0000 Subject: [PATCH] Default routine log reps from targets --- home/doris-barbell/app/routes/ui.py | 12 +++++- .../app/templates/routine_log.html | 1 + home/doris-barbell/tests/test_app.py | 41 +++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/home/doris-barbell/app/routes/ui.py b/home/doris-barbell/app/routes/ui.py index cc1852d..ab065d5 100644 --- a/home/doris-barbell/app/routes/ui.py +++ b/home/doris-barbell/app/routes/ui.py @@ -159,7 +159,7 @@ async def log_seeded_routine_workout( 'performed_at': performed_at, 'routine_name': routine_name.strip(), 'notes': notes.strip() or None, - 'exercises': await _parse_structured_routine_form(request, exercise_count), + 'exercises': await _parse_structured_routine_form(request, routine, exercise_count), } request.app.state.store.add_workout(payload) return RedirectResponse(url='/', status_code=status.HTTP_303_SEE_OTHER) @@ -272,6 +272,7 @@ def _build_routine_log_sheet(routine: dict) -> list[dict]: 'exercise_name': exercise['exercise_name'], 'target_sets': target_sets, 'target_reps': exercise.get('target_reps'), + 'default_reps': default_reps, 'notes': exercise.get('notes'), 'sets': [ { @@ -328,8 +329,9 @@ def _routine_action_label(routine_name: str) -> str: return day_aliases.get(label, label) -async def _parse_structured_routine_form(request: Request, exercise_count: int) -> list[dict]: +async def _parse_structured_routine_form(request: Request, routine: dict, exercise_count: int) -> list[dict]: form = await request.form() + routine_exercises = routine.get('exercises', []) exercises = [] for exercise_index in range(exercise_count): exercise_name = str(form.get(f'exercise_{exercise_index}_name', '')).strip() @@ -339,12 +341,18 @@ async def _parse_structured_routine_form(request: Request, exercise_count: int) set_count = int(str(form.get(f'exercise_{exercise_index}_set_count', '0')).strip()) except ValueError as exc: raise HTTPException(status_code=400, detail='Invalid set count in routine log form.') from exc + target_reps = None + if exercise_index < len(routine_exercises): + target_reps = routine_exercises[exercise_index].get('target_reps') + default_reps_raw = _default_reps_value(target_reps) sets = [] for set_index in range(set_count): reps_raw = str(form.get(f'exercise_{exercise_index}_set_{set_index}_reps', '')).strip() weight_raw = str(form.get(f'exercise_{exercise_index}_set_{set_index}_weight_lbs', '')).strip() if not reps_raw and not weight_raw: continue + if not reps_raw and weight_raw and default_reps_raw.isdigit(): + reps_raw = default_reps_raw if not reps_raw or not weight_raw: raise HTTPException( status_code=400, diff --git a/home/doris-barbell/app/templates/routine_log.html b/home/doris-barbell/app/templates/routine_log.html index 1ae21c4..f106e9f 100644 --- a/home/doris-barbell/app/templates/routine_log.html +++ b/home/doris-barbell/app/templates/routine_log.html @@ -53,6 +53,7 @@ {% for exercise in routine_sheet %}
+
{{ exercise.target_sets }} sets diff --git a/home/doris-barbell/tests/test_app.py b/home/doris-barbell/tests/test_app.py index b21dedd..80d87f7 100644 --- a/home/doris-barbell/tests/test_app.py +++ b/home/doris-barbell/tests/test_app.py @@ -464,6 +464,47 @@ def test_seeded_routine_log_submission_creates_structured_workout(tmp_path: Path assert payload[0]['exercises'][1]['exercise_name'] == 'Upright Row' +def test_seeded_routine_log_uses_numeric_target_reps_when_reps_left_blank(tmp_path: Path) -> None: + client = make_client(tmp_path) + + summary = client.get('/api/dashboard/summary').json() + shoulders = next(routine for routine in summary['routines'] if routine['name'] == 'Thursday: Shoulders') + + response = client.post( + '/workouts/routine-log', + data={ + 'user_id': 'john', + 'routine_id': shoulders['id'], + 'performed_at': '2026-05-28T12:00:00', + 'routine_name': shoulders['name'], + 'notes': 'Use default target reps when left blank.', + 'exercise_count': '1', + 'exercise_0_name': 'Shoulder Press', + 'exercise_0_set_count': '3', + 'exercise_0_set_0_reps': '', + 'exercise_0_set_0_weight_lbs': '45', + 'exercise_0_set_1_reps': '', + 'exercise_0_set_1_weight_lbs': '45', + 'exercise_0_set_2_reps': '', + 'exercise_0_set_2_weight_lbs': '45', + }, + follow_redirects=False, + ) + + assert response.status_code == 303 + assert response.headers['location'] == '/' + + workout_history = client.get('/api/history/john/workouts') + assert workout_history.status_code == 200 + payload = workout_history.json() + assert payload[0]['routine_name'] == 'Thursday: Shoulders' + assert payload[0]['exercises'][0]['sets'] == [ + {'reps': 10, 'weight_lbs': 45.0}, + {'reps': 10, 'weight_lbs': 45.0}, + {'reps': 10, 'weight_lbs': 45.0}, + ] + + def test_existing_state_gets_seeded_routine_backfill(tmp_path: Path) -> None: state_path = tmp_path / 'state.json' state_path.write_text(