Learn session forecasts from training blocks and clarify progress UI

This commit is contained in:
Peter Stockings
2026-09-06 16:20:15 +10:00
parent 499d859478
commit 86fade54f1
13 changed files with 1008 additions and 343 deletions
+23 -8
View File
@@ -380,7 +380,7 @@ class DataBase():
else:
return (topset.get('repetitions'), topset.get('weight'), topset['exercise_name'])
def get_recent_topsets_for_exercise(self, person_id, exercise_id, limit=5, offset=0):
def get_recent_topsets_for_exercise(self, person_id, exercise_id, limit=5, offset=0, min_date=None, max_date=None):
topsets = self.execute("""
SELECT
t.topset_id,
@@ -394,11 +394,13 @@ class DataBase():
JOIN topset t ON e.exercise_id = t.exercise_id
JOIN workout w ON t.workout_id = w.workout_id
WHERE
e.exercise_id = %s AND w.person_id = %s
e.exercise_id = %s AND w.person_id = %s
AND (%s::date IS NULL OR w.start_date >= %s::date)
AND (%s::date IS NULL OR w.start_date <= %s::date)
ORDER BY
w.start_date DESC, t.topset_id DESC
LIMIT %s OFFSET %s;
""", [exercise_id, person_id, limit, offset])
""", [exercise_id, person_id, min_date, min_date, max_date, max_date, limit, offset])
return topsets
@@ -419,7 +421,7 @@ class DataBase():
SELECT
T.topset_id, E.name AS exercise_name, W.person_id, T.workout_id,
T.repetitions, T.weight,
ROUND((100 * T.weight::NUMERIC::INTEGER) / (101.3 - 2.67123 * T.repetitions), 0)::NUMERIC::INTEGER AS estimated_1rm,
ROUND((100 * T.weight::NUMERIC) / (101.3 - 2.67123 * T.repetitions), 1) AS estimated_1rm,
W.start_date
FROM
topset T
@@ -433,7 +435,7 @@ class DataBase():
(%s::date IS NULL OR W.start_date >= %s::date) AND
(%s::date IS NULL OR W.start_date <= %s::date)
ORDER BY
W.start_date;
W.start_date, T.topset_id;
""", [person_id, exercise_id, min_date, min_date, max_date, max_date])
# Return None if no topsets found
@@ -442,7 +444,7 @@ class DataBase():
# Extracting values and calculating value ranges for SVG dimensions
exercise_name = topsets[0]['exercise_name']
estimated_1rm = [t['estimated_1rm'] for t in topsets]
estimated_1rm = [float(t['estimated_1rm']) for t in topsets]
repetitions = [t['repetitions'] for t in topsets]
weight = [t['weight'] for t in topsets]
start_dates = [t['start_date'] for t in topsets]
@@ -453,7 +455,19 @@ class DataBase():
latest_topset_id = latest_topset['topset_id']
latest_workout_id = latest_topset['workout_id']
exercise_progress = get_exercise_graph_model(
# View controls affect the chart/rep map, not training. Respect the
# visible cutoff so custom historical views never train on later sets.
forecast_training_rows = None
if forecast_enabled:
forecast_training_rows = self.execute("""
SELECT w.start_date, t.weight, t.repetitions
FROM topset t JOIN workout w USING(workout_id)
WHERE w.person_id = %s AND t.exercise_id = %s
AND w.start_date <= %s
ORDER BY w.start_date, t.topset_id
""", [person_id, exercise_id, max(start_dates)])
exercise_progress = get_exercise_graph_model(
exercise_name,
estimated_1rm,
repetitions,
@@ -468,7 +482,8 @@ class DataBase():
degree,
forecast_enabled,
forecast_weeks,
forecast_target_reps)
forecast_target_reps,
forecast_training_rows=forecast_training_rows)
exercise_progress['latest_topset_id'] = latest_topset_id
exercise_progress['latest_workout_id'] = latest_workout_id