@aneuhold/core-ts-db-lib 4.1.12 → 4.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/lib/browser.d.ts +11 -8
  3. package/lib/browser.d.ts.map +1 -1
  4. package/lib/browser.js +6 -4
  5. package/lib/browser.js.map +1 -1
  6. package/lib/browser.ts +23 -9
  7. package/lib/ctos/workout/WorkoutMuscleGroupVolumeCTO.d.ts +14 -0
  8. package/lib/ctos/workout/WorkoutMuscleGroupVolumeCTO.d.ts.map +1 -1
  9. package/lib/ctos/workout/WorkoutMuscleGroupVolumeCTO.ts +18 -0
  10. package/lib/documents/workout/WorkoutSet.d.ts +8 -0
  11. package/lib/documents/workout/WorkoutSet.d.ts.map +1 -1
  12. package/lib/documents/workout/WorkoutSet.ts +9 -0
  13. package/lib/services/workout/Exercise/WorkoutExerciseService.d.ts +40 -0
  14. package/lib/services/workout/Exercise/WorkoutExerciseService.d.ts.map +1 -1
  15. package/lib/services/workout/Exercise/WorkoutExerciseService.js +134 -1
  16. package/lib/services/workout/Exercise/WorkoutExerciseService.js.map +1 -1
  17. package/lib/services/workout/Exercise/WorkoutExerciseService.ts +204 -1
  18. package/lib/services/workout/ExerciseCalibration/WorkoutExerciseCalibrationService.d.ts +15 -0
  19. package/lib/services/workout/ExerciseCalibration/WorkoutExerciseCalibrationService.d.ts.map +1 -1
  20. package/lib/services/workout/ExerciseCalibration/WorkoutExerciseCalibrationService.js +18 -1
  21. package/lib/services/workout/ExerciseCalibration/WorkoutExerciseCalibrationService.js.map +1 -1
  22. package/lib/services/workout/ExerciseCalibration/WorkoutExerciseCalibrationService.ts +19 -1
  23. package/lib/services/workout/Mesocycle/WorkoutMesocyclePlanContext.d.ts +26 -4
  24. package/lib/services/workout/Mesocycle/WorkoutMesocyclePlanContext.d.ts.map +1 -1
  25. package/lib/services/workout/Mesocycle/WorkoutMesocyclePlanContext.js +51 -4
  26. package/lib/services/workout/Mesocycle/WorkoutMesocyclePlanContext.js.map +1 -1
  27. package/lib/services/workout/Mesocycle/WorkoutMesocyclePlanContext.ts +58 -3
  28. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.d.ts +45 -1
  29. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.d.ts.map +1 -1
  30. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.js +201 -11
  31. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.js.map +1 -1
  32. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.ts +285 -9
  33. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.types.d.ts +33 -0
  34. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.types.d.ts.map +1 -0
  35. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.types.js +24 -0
  36. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.types.js.map +1 -0
  37. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.types.ts +36 -0
  38. package/lib/services/workout/Session/WorkoutSessionService.d.ts.map +1 -1
  39. package/lib/services/workout/Session/WorkoutSessionService.js +1 -11
  40. package/lib/services/workout/Session/WorkoutSessionService.js.map +1 -1
  41. package/lib/services/workout/Session/WorkoutSessionService.ts +1 -17
  42. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.d.ts +14 -2
  43. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.d.ts.map +1 -1
  44. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.js +17 -3
  45. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.js.map +1 -1
  46. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.ts +28 -3
  47. package/lib/services/workout/Set/WorkoutSetService.d.ts +17 -5
  48. package/lib/services/workout/Set/WorkoutSetService.d.ts.map +1 -1
  49. package/lib/services/workout/Set/WorkoutSetService.js +83 -16
  50. package/lib/services/workout/Set/WorkoutSetService.js.map +1 -1
  51. package/lib/services/workout/Set/WorkoutSetService.ts +107 -24
  52. package/lib/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.d.ts +72 -2
  53. package/lib/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.d.ts.map +1 -1
  54. package/lib/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.js +202 -15
  55. package/lib/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.js.map +1 -1
  56. package/lib/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.ts +268 -18
  57. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutSessionExerciseService.js","sourceRoot":"","sources":["../../../../src/services/workout/SessionExercise/WorkoutSessionExerciseService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkoutSessionExerciseService.js","sourceRoot":"","sources":["../../../../src/services/workout/SessionExercise/WorkoutSessionExerciseService.ts"],"names":[],"mappings":"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"}
@@ -36,8 +36,8 @@ export default class WorkoutSessionExerciseService {
36
36
  /**
37
37
  * Calculates the performance score (0-3) for an exercise based on its sets.
38
38
  *
39
- * For each set with complete data, a surplus is computed as
40
- * `(actualReps - plannedReps) + (rir - plannedRir)`. The per-set score is:
39
+ * For each set with complete data, a surplus is computed via
40
+ * {@link calculateSetSurplus}. The per-set score is:
41
41
  * - 0: surplus >= 2 (exceeded expectations)
42
42
  * - 1: surplus 0-1 (on target)
43
43
  * - 2: surplus < 0 but hit target reps (declining)
@@ -64,7 +64,12 @@ export default class WorkoutSessionExerciseService {
64
64
  continue;
65
65
  }
66
66
 
67
- const surplus = set.actualReps - set.plannedReps + (set.rir - set.plannedRir);
67
+ const surplus = this.calculateSetSurplus(
68
+ set.actualReps,
69
+ set.plannedReps,
70
+ set.rir,
71
+ set.plannedRir
72
+ );
68
73
 
69
74
  if (surplus >= 2) {
70
75
  setScores.push(0);
@@ -83,6 +88,26 @@ export default class WorkoutSessionExerciseService {
83
88
  return Math.round(average);
84
89
  }
85
90
 
91
+ /**
92
+ * Calculates the surplus for a single set: how much the user exceeded or
93
+ * fell short of the plan. Positive means exceeded, negative means fell short.
94
+ *
95
+ * Formula: `(actualReps - plannedReps) + (rir - plannedRir)`
96
+ *
97
+ * @param actualReps The actual reps performed.
98
+ * @param plannedReps The planned reps.
99
+ * @param rir The actual RIR (reps in reserve).
100
+ * @param plannedRir The planned RIR.
101
+ */
102
+ static calculateSetSurplus(
103
+ actualReps: number,
104
+ plannedReps: number,
105
+ rir: number,
106
+ plannedRir: number
107
+ ): number {
108
+ return actualReps - plannedReps + (rir - plannedRir);
109
+ }
110
+
86
111
  /**
87
112
  * Uses the soreness/performance table from the workout model notes to recommend whether to add
88
113
  * sets next microcycle or employ recovery sessions.
@@ -1,5 +1,4 @@
1
- import type { WorkoutExercise } from '../../../documents/workout/WorkoutExercise.js';
2
- import type { WorkoutExerciseCalibration } from '../../../documents/workout/WorkoutExerciseCalibration.js';
1
+ import type { WorkoutExerciseCTO } from '../../../ctos/workout/WorkoutExerciseCTO.js';
3
2
  import type { WorkoutSession } from '../../../documents/workout/WorkoutSession.js';
4
3
  import type { WorkoutSessionExercise } from '../../../documents/workout/WorkoutSessionExercise.js';
5
4
  import { type WorkoutSet } from '../../../documents/workout/WorkoutSet.js';
@@ -12,11 +11,11 @@ export default class WorkoutSetService {
12
11
  * - Calculating the initial target weight/reps based on microcycle progression.
13
12
  * - Handling intra-session fatigue (dropping reps/weight across sets).
14
13
  * - Applying Deload phase modifications (cutting volume/intensity).
14
+ * - Using previous performance data to adjust progression via autoregulation.
15
15
  */
16
- static generateSetsForSessionExercise({ context, exercise, calibration, session, sessionExercise, microcycleIndex, sessionIndex, setCount, targetRir, isDeloadMicrocycle }: {
16
+ static generateSetsForSessionExercise({ context, exerciseCTO, session, sessionExercise, microcycleIndex, sessionIndex, setCount, targetRir, isDeloadMicrocycle }: {
17
17
  context: WorkoutMesocyclePlanContext;
18
- exercise: WorkoutExercise;
19
- calibration: WorkoutExerciseCalibration;
18
+ exerciseCTO: WorkoutExerciseCTO;
20
19
  session: WorkoutSession;
21
20
  sessionExercise: WorkoutSessionExercise;
22
21
  microcycleIndex: number;
@@ -31,6 +30,19 @@ export default class WorkoutSetService {
31
30
  * and either rir is recorded or no plannedRir was expected (deload sets).
32
31
  */
33
32
  static isCompleted(set: WorkoutSet): boolean;
33
+ /**
34
+ * Finds the previous microcycle's first set for an exercise to use for autoregulation.
35
+ *
36
+ * Uses the mesocycle's fixed exercise-to-session mapping to go directly to the
37
+ * correct session and exercise position rather than iterating all sessions.
38
+ *
39
+ * Returns undefined if the previous microcycle doesn't exist or has no sessions
40
+ * (the context may not have full history). Throws if the structure is present but
41
+ * inconsistent with the mesocycle plan.
42
+ *
43
+ * @throws {Error} If the session/exercise structure doesn't match the plan.
44
+ */
45
+ private static findPreviousFirstSet;
34
46
  /**
35
47
  * Generates the planned reps and weight for a specific set within a session exercise, only
36
48
  * taking into account simple -2 reps drop per set logic, and deload modifications.
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutSetService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Set/WorkoutSetService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,eAAe,EAChB,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AAC3G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AACnF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sDAAsD,CAAC;AACnG,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAG7F,OAAO,KAAK,2BAA2B,MAAM,6CAA6C,CAAC;AAE3F,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC;;;;;;;OAOG;IACH,MAAM,CAAC,8BAA8B,CAAC,EACpC,OAAO,EACP,QAAQ,EACR,WAAW,EACX,OAAO,EACP,eAAe,EACf,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,kBAAkB,EACnB,EAAE;QACD,OAAO,EAAE,2BAA2B,CAAC;QACrC,QAAQ,EAAE,eAAe,CAAC;QAC1B,WAAW,EAAE,0BAA0B,CAAC;QACxC,OAAO,EAAE,cAAc,CAAC;QACxB,eAAe,EAAE,sBAAsB,CAAC;QACxC,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,kBAAkB,EAAE,OAAO,CAAC;KAC7B,GAAG,IAAI;IAsDR;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAQ5C;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAuDxC"}
1
+ {"version":3,"file":"WorkoutSetService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Set/WorkoutSetService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAGtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AACnF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sDAAsD,CAAC;AACnG,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAG7F,OAAO,KAAK,2BAA2B,MAAM,6CAA6C,CAAC;AAE3F,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC;;;;;;;;OAQG;IACH,MAAM,CAAC,8BAA8B,CAAC,EACpC,OAAO,EACP,WAAW,EACX,OAAO,EACP,eAAe,EACf,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,kBAAkB,EACnB,EAAE;QACD,OAAO,EAAE,2BAA2B,CAAC;QACrC,WAAW,EAAE,kBAAkB,CAAC;QAChC,OAAO,EAAE,cAAc,CAAC;QACxB,eAAe,EAAE,sBAAsB,CAAC;QACxC,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,kBAAkB,EAAE,OAAO,CAAC;KAC7B,GAAG,IAAI;IA6DR;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAQ5C;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAmEnC;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAuDxC"}
@@ -9,44 +9,49 @@ export default class WorkoutSetService {
9
9
  * - Calculating the initial target weight/reps based on microcycle progression.
10
10
  * - Handling intra-session fatigue (dropping reps/weight across sets).
11
11
  * - Applying Deload phase modifications (cutting volume/intensity).
12
+ * - Using previous performance data to adjust progression via autoregulation.
12
13
  */
13
- static generateSetsForSessionExercise({ context, exercise, calibration, session, sessionExercise, microcycleIndex, sessionIndex, setCount, targetRir, isDeloadMicrocycle }) {
14
- const equipment = context.equipmentMap.get(exercise.workoutEquipmentTypeId);
15
- if (!equipment) {
16
- throw new Error(`Equipment type not found for exercise ${exercise._id}, ${exercise.exerciseName}`);
14
+ static generateSetsForSessionExercise({ context, exerciseCTO, session, sessionExercise, microcycleIndex, sessionIndex, setCount, targetRir, isDeloadMicrocycle }) {
15
+ const { equipmentType, bestCalibration } = exerciseCTO;
16
+ if (!bestCalibration) {
17
+ throw new Error(`No calibration found for exercise ${exerciseCTO._id}, ${exerciseCTO.exerciseName}`);
17
18
  }
18
19
  const sets = [];
20
+ // For the first microcycle, use the CTO's previous performance data.
21
+ // For subsequent microcycles, look up the previous microcycle's first set from the context.
22
+ const previousFirstSet = microcycleIndex === 0
23
+ ? (exerciseCTO.lastFirstSet ?? undefined)
24
+ : this.findPreviousFirstSet(context, exerciseCTO._id, microcycleIndex);
19
25
  // Calculate progressed targets for the first set.
20
26
  // For deload microcycles, use the previous microcycle's index so we base
21
27
  // the deload on the last accumulation weight rather than progressing further.
22
- const { targetWeight: firstSetWeight, targetReps: firstSetReps } = WorkoutExerciseService.calculateTargetRepsAndWeightForFirstSet({
23
- exercise,
24
- calibration,
25
- equipment,
28
+ const { targetReps: firstSetReps, targetWeight: firstSetWeight } = WorkoutExerciseService.calculateTargetRepsAndWeightForFirstSet({
29
+ exercise: exerciseCTO,
30
+ calibration: bestCalibration,
31
+ equipment: equipmentType,
26
32
  microcycleIndex: isDeloadMicrocycle ? microcycleIndex - 1 : microcycleIndex,
27
- firstMicrocycleRir: context.FIRST_MICROCYCLE_RIR
33
+ firstMicrocycleRir: context.firstMicrocycleRir,
34
+ previousFirstSet
28
35
  });
29
36
  for (let setIndex = 0; setIndex < setCount; setIndex++) {
30
- const { plannedReps, plannedWeight } = this.generateSetRepsAndWeight(
31
- // If there is a previous set, base off that, otherwise use first set targets
32
- sets[setIndex - 1]?.plannedReps || firstSetReps, sets[setIndex - 1]?.plannedWeight || firstSetWeight, setIndex, exercise.repRange, equipment, {
37
+ const { plannedReps, plannedWeight } = this.generateSetRepsAndWeight(sets[setIndex - 1]?.plannedReps || firstSetReps, sets[setIndex - 1]?.plannedWeight || firstSetWeight, setIndex, exerciseCTO.repRange, equipmentType, {
33
38
  isDeloadMicrocycle,
34
39
  sessionIndex,
35
40
  plannedSessionCountPerMicrocycle: context.mesocycle.plannedSessionCountPerMicrocycle
36
41
  });
37
42
  const workoutSet = WorkoutSetSchema.parse({
38
- userId: exercise.userId,
39
- workoutExerciseId: exercise._id,
43
+ userId: exerciseCTO.userId,
44
+ workoutExerciseId: exerciseCTO._id,
40
45
  workoutSessionId: session._id,
41
46
  workoutSessionExerciseId: sessionExercise._id,
42
47
  plannedReps,
43
48
  plannedWeight,
44
49
  plannedRir: targetRir,
45
- exerciseProperties: calibration.exerciseProperties
50
+ exerciseProperties: bestCalibration.exerciseProperties
46
51
  });
47
52
  sets.push(workoutSet);
48
53
  }
49
- context.setsToCreate.push(...sets);
54
+ context.addSets(sets);
50
55
  }
51
56
  /**
52
57
  * Returns true if the set has been logged (has actual performance data).
@@ -58,6 +63,68 @@ export default class WorkoutSetService {
58
63
  set.actualWeight != null &&
59
64
  (set.rir != null || set.plannedRir == null));
60
65
  }
66
+ /**
67
+ * Finds the previous microcycle's first set for an exercise to use for autoregulation.
68
+ *
69
+ * Uses the mesocycle's fixed exercise-to-session mapping to go directly to the
70
+ * correct session and exercise position rather than iterating all sessions.
71
+ *
72
+ * Returns undefined if the previous microcycle doesn't exist or has no sessions
73
+ * (the context may not have full history). Throws if the structure is present but
74
+ * inconsistent with the mesocycle plan.
75
+ *
76
+ * @throws {Error} If the session/exercise structure doesn't match the plan.
77
+ */
78
+ static findPreviousFirstSet(context, exerciseId, microcycleIndex) {
79
+ if (microcycleIndex <= 0) {
80
+ return undefined;
81
+ }
82
+ const previousMicrocycle = context.microcyclesInOrder[microcycleIndex - 1];
83
+ if (!previousMicrocycle || previousMicrocycle.sessionOrder.length === 0) {
84
+ return undefined;
85
+ }
86
+ // Exercise-to-session mapping is fixed for the mesocycle — look up directly
87
+ const sessionIndex = context.exerciseIdToSessionIndex?.get(exerciseId);
88
+ if (sessionIndex == null) {
89
+ throw new Error(`Exercise ${exerciseId} has no session mapping in the mesocycle plan`);
90
+ }
91
+ const sessionId = previousMicrocycle.sessionOrder[sessionIndex];
92
+ if (!sessionId) {
93
+ // The previous microcycle may have fewer sessions than the plan (e.g. pruned
94
+ // during early deload). Treat as missing history rather than a structural error.
95
+ return undefined;
96
+ }
97
+ const session = context.sessionMap.get(sessionId);
98
+ if (!session) {
99
+ throw new Error(`Session ${sessionId} not found in context`);
100
+ }
101
+ // Exercise order within a session is consistent — find the index from the plan
102
+ const plannedCTOs = context.plannedSessionExerciseCTOs?.[sessionIndex];
103
+ if (!plannedCTOs) {
104
+ throw new Error(`No planned CTOs for session index ${sessionIndex}`);
105
+ }
106
+ const exerciseIndex = plannedCTOs.findIndex((cto) => cto._id === exerciseId);
107
+ if (exerciseIndex === -1) {
108
+ throw new Error(`Exercise ${exerciseId} not found in planned CTOs for session ${sessionIndex}`);
109
+ }
110
+ const seId = session.sessionExerciseOrder[exerciseIndex];
111
+ if (!seId) {
112
+ throw new Error(`No session exercise at index ${exerciseIndex} in session ${sessionId}`);
113
+ }
114
+ const sessionExercise = context.sessionExerciseMap.get(seId);
115
+ if (!sessionExercise) {
116
+ throw new Error(`Session exercise ${seId} not found in context`);
117
+ }
118
+ const firstSetId = sessionExercise.setOrder[0];
119
+ if (!firstSetId) {
120
+ throw new Error(`Session exercise ${seId} for exercise ${exerciseId} has no sets`);
121
+ }
122
+ const set = context.setMap.get(firstSetId);
123
+ if (!set) {
124
+ throw new Error(`Set ${firstSetId} not found in context`);
125
+ }
126
+ return set;
127
+ }
61
128
  /**
62
129
  * Generates the planned reps and weight for a specific set within a session exercise, only
63
130
  * taking into account simple -2 reps drop per set logic, and deload modifications.
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutSetService.js","sourceRoot":"","sources":["../../../../src/services/workout/Set/WorkoutSetService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkoutSetService.js","sourceRoot":"","sources":["../../../../src/services/workout/Set/WorkoutSetService.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,7 @@
1
+ import type { UUID } from 'crypto';
2
+ import type { WorkoutExerciseCTO } from '../../../ctos/workout/WorkoutExerciseCTO.js';
1
3
  import type { WorkoutEquipmentType } from '../../../documents/workout/WorkoutEquipmentType.js';
2
- import type {
3
- ExerciseRepRange,
4
- WorkoutExercise
5
- } from '../../../documents/workout/WorkoutExercise.js';
6
- import type { WorkoutExerciseCalibration } from '../../../documents/workout/WorkoutExerciseCalibration.js';
4
+ import type { ExerciseRepRange } from '../../../documents/workout/WorkoutExercise.js';
7
5
  import type { WorkoutSession } from '../../../documents/workout/WorkoutSession.js';
8
6
  import type { WorkoutSessionExercise } from '../../../documents/workout/WorkoutSessionExercise.js';
9
7
  import { WorkoutSetSchema, type WorkoutSet } from '../../../documents/workout/WorkoutSet.js';
@@ -19,11 +17,11 @@ export default class WorkoutSetService {
19
17
  * - Calculating the initial target weight/reps based on microcycle progression.
20
18
  * - Handling intra-session fatigue (dropping reps/weight across sets).
21
19
  * - Applying Deload phase modifications (cutting volume/intensity).
20
+ * - Using previous performance data to adjust progression via autoregulation.
22
21
  */
23
22
  static generateSetsForSessionExercise({
24
23
  context,
25
- exercise,
26
- calibration,
24
+ exerciseCTO,
27
25
  session,
28
26
  sessionExercise,
29
27
  microcycleIndex,
@@ -33,8 +31,7 @@ export default class WorkoutSetService {
33
31
  isDeloadMicrocycle
34
32
  }: {
35
33
  context: WorkoutMesocyclePlanContext;
36
- exercise: WorkoutExercise;
37
- calibration: WorkoutExerciseCalibration;
34
+ exerciseCTO: WorkoutExerciseCTO;
38
35
  session: WorkoutSession;
39
36
  sessionExercise: WorkoutSessionExercise;
40
37
  microcycleIndex: number;
@@ -43,35 +40,42 @@ export default class WorkoutSetService {
43
40
  targetRir: number | null;
44
41
  isDeloadMicrocycle: boolean;
45
42
  }): void {
46
- const equipment = context.equipmentMap.get(exercise.workoutEquipmentTypeId);
47
- if (!equipment) {
43
+ const { equipmentType, bestCalibration } = exerciseCTO;
44
+ if (!bestCalibration) {
48
45
  throw new Error(
49
- `Equipment type not found for exercise ${exercise._id}, ${exercise.exerciseName}`
46
+ `No calibration found for exercise ${exerciseCTO._id}, ${exerciseCTO.exerciseName}`
50
47
  );
51
48
  }
52
49
 
53
50
  const sets: WorkoutSet[] = [];
54
51
 
52
+ // For the first microcycle, use the CTO's previous performance data.
53
+ // For subsequent microcycles, look up the previous microcycle's first set from the context.
54
+ const previousFirstSet =
55
+ microcycleIndex === 0
56
+ ? (exerciseCTO.lastFirstSet ?? undefined)
57
+ : this.findPreviousFirstSet(context, exerciseCTO._id, microcycleIndex);
58
+
55
59
  // Calculate progressed targets for the first set.
56
60
  // For deload microcycles, use the previous microcycle's index so we base
57
61
  // the deload on the last accumulation weight rather than progressing further.
58
- const { targetWeight: firstSetWeight, targetReps: firstSetReps } =
62
+ const { targetReps: firstSetReps, targetWeight: firstSetWeight } =
59
63
  WorkoutExerciseService.calculateTargetRepsAndWeightForFirstSet({
60
- exercise,
61
- calibration,
62
- equipment,
64
+ exercise: exerciseCTO,
65
+ calibration: bestCalibration,
66
+ equipment: equipmentType,
63
67
  microcycleIndex: isDeloadMicrocycle ? microcycleIndex - 1 : microcycleIndex,
64
- firstMicrocycleRir: context.FIRST_MICROCYCLE_RIR
68
+ firstMicrocycleRir: context.firstMicrocycleRir,
69
+ previousFirstSet
65
70
  });
66
71
 
67
72
  for (let setIndex = 0; setIndex < setCount; setIndex++) {
68
73
  const { plannedReps, plannedWeight } = this.generateSetRepsAndWeight(
69
- // If there is a previous set, base off that, otherwise use first set targets
70
74
  sets[setIndex - 1]?.plannedReps || firstSetReps,
71
75
  sets[setIndex - 1]?.plannedWeight || firstSetWeight,
72
76
  setIndex,
73
- exercise.repRange,
74
- equipment,
77
+ exerciseCTO.repRange,
78
+ equipmentType,
75
79
  {
76
80
  isDeloadMicrocycle,
77
81
  sessionIndex,
@@ -80,20 +84,20 @@ export default class WorkoutSetService {
80
84
  );
81
85
 
82
86
  const workoutSet = WorkoutSetSchema.parse({
83
- userId: exercise.userId,
84
- workoutExerciseId: exercise._id,
87
+ userId: exerciseCTO.userId,
88
+ workoutExerciseId: exerciseCTO._id,
85
89
  workoutSessionId: session._id,
86
90
  workoutSessionExerciseId: sessionExercise._id,
87
91
  plannedReps,
88
92
  plannedWeight,
89
93
  plannedRir: targetRir,
90
- exerciseProperties: calibration.exerciseProperties
94
+ exerciseProperties: bestCalibration.exerciseProperties
91
95
  });
92
96
 
93
97
  sets.push(workoutSet);
94
98
  }
95
99
 
96
- context.setsToCreate.push(...sets);
100
+ context.addSets(sets);
97
101
  }
98
102
 
99
103
  /**
@@ -109,6 +113,85 @@ export default class WorkoutSetService {
109
113
  );
110
114
  }
111
115
 
116
+ /**
117
+ * Finds the previous microcycle's first set for an exercise to use for autoregulation.
118
+ *
119
+ * Uses the mesocycle's fixed exercise-to-session mapping to go directly to the
120
+ * correct session and exercise position rather than iterating all sessions.
121
+ *
122
+ * Returns undefined if the previous microcycle doesn't exist or has no sessions
123
+ * (the context may not have full history). Throws if the structure is present but
124
+ * inconsistent with the mesocycle plan.
125
+ *
126
+ * @throws {Error} If the session/exercise structure doesn't match the plan.
127
+ */
128
+ private static findPreviousFirstSet(
129
+ context: WorkoutMesocyclePlanContext,
130
+ exerciseId: UUID,
131
+ microcycleIndex: number
132
+ ): WorkoutSet | undefined {
133
+ if (microcycleIndex <= 0) {
134
+ return undefined;
135
+ }
136
+
137
+ const previousMicrocycle = context.microcyclesInOrder[microcycleIndex - 1];
138
+ if (!previousMicrocycle || previousMicrocycle.sessionOrder.length === 0) {
139
+ return undefined;
140
+ }
141
+
142
+ // Exercise-to-session mapping is fixed for the mesocycle — look up directly
143
+ const sessionIndex = context.exerciseIdToSessionIndex?.get(exerciseId);
144
+ if (sessionIndex == null) {
145
+ throw new Error(`Exercise ${exerciseId} has no session mapping in the mesocycle plan`);
146
+ }
147
+
148
+ const sessionId = previousMicrocycle.sessionOrder[sessionIndex];
149
+ if (!sessionId) {
150
+ // The previous microcycle may have fewer sessions than the plan (e.g. pruned
151
+ // during early deload). Treat as missing history rather than a structural error.
152
+ return undefined;
153
+ }
154
+
155
+ const session = context.sessionMap.get(sessionId);
156
+ if (!session) {
157
+ throw new Error(`Session ${sessionId} not found in context`);
158
+ }
159
+
160
+ // Exercise order within a session is consistent — find the index from the plan
161
+ const plannedCTOs = context.plannedSessionExerciseCTOs?.[sessionIndex];
162
+ if (!plannedCTOs) {
163
+ throw new Error(`No planned CTOs for session index ${sessionIndex}`);
164
+ }
165
+
166
+ const exerciseIndex = plannedCTOs.findIndex((cto) => cto._id === exerciseId);
167
+ if (exerciseIndex === -1) {
168
+ throw new Error(
169
+ `Exercise ${exerciseId} not found in planned CTOs for session ${sessionIndex}`
170
+ );
171
+ }
172
+
173
+ const seId = session.sessionExerciseOrder[exerciseIndex];
174
+ if (!seId) {
175
+ throw new Error(`No session exercise at index ${exerciseIndex} in session ${sessionId}`);
176
+ }
177
+
178
+ const sessionExercise = context.sessionExerciseMap.get(seId);
179
+ if (!sessionExercise) {
180
+ throw new Error(`Session exercise ${seId} not found in context`);
181
+ }
182
+
183
+ const firstSetId = sessionExercise.setOrder[0];
184
+ if (!firstSetId) {
185
+ throw new Error(`Session exercise ${seId} for exercise ${exerciseId} has no sets`);
186
+ }
187
+
188
+ const set = context.setMap.get(firstSetId);
189
+ if (!set) {
190
+ throw new Error(`Set ${firstSetId} not found in context`);
191
+ }
192
+ return set;
193
+ }
194
+
112
195
  /**
113
196
  * Generates the planned reps and weight for a specific set within a session exercise, only
114
197
  * taking into account simple -2 reps drop per set logic, and deload modifications.
@@ -1,4 +1,5 @@
1
1
  import type { UUID } from 'crypto';
2
+ import type { WorkoutMuscleGroupVolumeCTO, WorkoutVolumeLandmarkEstimate } from '../../../../ctos/workout/WorkoutMuscleGroupVolumeCTO.js';
2
3
  import type WorkoutMesocyclePlanContext from '../../Mesocycle/WorkoutMesocyclePlanContext.js';
3
4
  /**
4
5
  * A service for handling volume planning operations across microcycles.
@@ -19,6 +20,28 @@ import type WorkoutMesocyclePlanContext from '../../Mesocycle/WorkoutMesocyclePl
19
20
  export default class WorkoutVolumePlanningService {
20
21
  private static readonly MAX_SETS_PER_EXERCISE;
21
22
  private static readonly MAX_SETS_PER_MUSCLE_GROUP_PER_SESSION;
23
+ /** Minimum average RSM required for a mesocycle to count toward MEV estimation. */
24
+ private static readonly MEV_RSM_THRESHOLD;
25
+ /** Default estimated MEV when no qualifying mesocycle history exists. */
26
+ private static readonly DEFAULT_MEV;
27
+ /** Minimum average performance score (or recovery presence) to count a mesocycle toward MRV estimation. */
28
+ private static readonly MRV_PERFORMANCE_THRESHOLD;
29
+ /** Extra sets added above the historical peak when no stressed mesocycles exist, to estimate MRV. */
30
+ private static readonly MRV_HEADROOM;
31
+ /** Default estimated MRV when no mesocycle history exists at all. */
32
+ private static readonly DEFAULT_MRV;
33
+ /** RSM bracket upper bound for "below MEV" proximity (0 to this value inclusive). */
34
+ private static readonly MEV_PROXIMITY_BELOW_THRESHOLD;
35
+ /** RSM bracket upper bound for "at MEV" proximity (above BELOW threshold up to this value inclusive). */
36
+ private static readonly MEV_PROXIMITY_AT_THRESHOLD;
37
+ /** Recommended set adjustment when volume is below MEV. */
38
+ private static readonly MEV_BELOW_SET_ADJUSTMENT;
39
+ /** Recommended set adjustment when volume is above MEV. */
40
+ private static readonly MEV_ABOVE_SET_ADJUSTMENT;
41
+ /** Maximum sets that can be added to a single exercise in one progression step. */
42
+ private static readonly MAX_SET_ADDITION_PER_EXERCISE;
43
+ /** Maximum total sets to distribute across a muscle group in one progression step. */
44
+ private static readonly MAX_TOTAL_SET_ADDITIONS;
22
45
  /**
23
46
  * Calculates the set plan for an entire microcycle.
24
47
  */
@@ -26,6 +49,42 @@ export default class WorkoutVolumePlanningService {
26
49
  exerciseIdToSetCount: Map<UUID, number>;
27
50
  recoveryExerciseIds: Set<UUID>;
28
51
  };
52
+ /**
53
+ * Estimates MEV, MRV, and MAV for a muscle group based on historical data
54
+ * across completed mesocycles.
55
+ *
56
+ * @param volumeCTO The WorkoutMuscleGroupVolumeCTO containing mesocycle
57
+ * history for this muscle group.
58
+ */
59
+ static estimateVolumeLandmarks(volumeCTO: WorkoutMuscleGroupVolumeCTO): WorkoutVolumeLandmarkEstimate;
60
+ /**
61
+ * Evaluates MEV (Minimum Effective Volume) proximity for a muscle group based on
62
+ * RSM scores from the first microcycle. Called when generating the second microcycle to adjust
63
+ * the volume baseline.
64
+ *
65
+ * Returns `null` when the first microcycle is incomplete or has no RSM data for the muscle group.
66
+ *
67
+ * @param context The mesocycle planning context containing microcycle/session/exercise data.
68
+ * @param muscleGroupId The muscle group to evaluate.
69
+ */
70
+ static evaluateMevProximity(context: WorkoutMesocyclePlanContext, muscleGroupId: UUID): {
71
+ /** 'below' = RSM 0-3, 'at' = RSM 4-6, 'above' = RSM 7-9 */
72
+ proximity: 'below' | 'at' | 'above';
73
+ /**
74
+ * Recommended total set adjustment for this muscle group.
75
+ * Positive = add sets, negative = remove sets, 0 = no change.
76
+ * Range: -2 to +3
77
+ */
78
+ recommendedSetAdjustment: number;
79
+ /** The average RSM across session exercises targeting this muscle group. */
80
+ averageRsm: number;
81
+ } | null;
82
+ /**
83
+ * Applies MEV proximity adjustments based on RSM data from the first microcycle.
84
+ * Adjusts set counts per muscle group when the first microcycle indicates volume
85
+ * was below or above MEV.
86
+ */
87
+ private static applyMevProximityAdjustments;
29
88
  /**
30
89
  * Calculates the set count for each exercise in a particular muscle group for this microcycle.
31
90
  *
@@ -40,8 +99,19 @@ export default class WorkoutVolumePlanningService {
40
99
  * for the entire microcycle, regardless of which session those exercises are in.
41
100
  *
42
101
  * Baseline: 2 sets per exercise in the muscle group.
43
- * Progression: add 1 total set per microcycle per muscle group (distributed to earlier exercises
44
- * in the muscle-group-wide ordering).
102
+ * Progression: add 1 set per muscle group every `progressionInterval` microcycles.
103
+ * - MuscleGain (interval 1): every microcycle
104
+ * - Cut (interval 2): every other microcycle
105
+ * - Resensitization (interval 0): no progression (flat 2 sets per exercise)
106
+ *
107
+ * @param microcycleIndex The index of the current microcycle.
108
+ * @param totalExercisesInMuscleGroupForMicrocycle Total exercises in the muscle group for
109
+ * this microcycle.
110
+ * @param exerciseIndexInMuscleGroupForMicrocycle Index of the current exercise within the
111
+ * muscle group.
112
+ * @param isDeloadMicrocycle Whether this is a deload microcycle.
113
+ * @param progressionInterval Number of microcycles between each set addition. 0 means no
114
+ * progression.
45
115
  */
46
116
  private static calculateBaselineSetCount;
47
117
  }
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutVolumePlanningService.d.ts","sourceRoot":"","sources":["../../../../../src/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC,OAAO,KAAK,2BAA2B,MAAM,gDAAgD,CAAC;AAG9F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,4BAA4B;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAK;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qCAAqC,CAAM;IAEnE;;OAEG;IACH,MAAM,CAAC,6BAA6B,CAClC,OAAO,EAAE,2BAA2B,EACpC,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,OAAO,GAC1B;QAAE,oBAAoB,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;KAAE;IA4B9E;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,6CAA6C;IAoP5D;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,yBAAyB;CA6BzC"}
1
+ {"version":3,"file":"WorkoutVolumePlanningService.d.ts","sourceRoot":"","sources":["../../../../../src/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,OAAO,KAAK,EACV,2BAA2B,EAC3B,6BAA6B,EAC9B,MAAM,yDAAyD,CAAC;AAEjE,OAAO,KAAK,2BAA2B,MAAM,gDAAgD,CAAC;AAI9F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,4BAA4B;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAK;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qCAAqC,CAAM;IAEnE,mFAAmF;IACnF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAK;IAE9C,yEAAyE;IACzE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAK;IAExC,2GAA2G;IAC3G,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAO;IAExD,qGAAqG;IACrG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAK;IAEzC,qEAAqE;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAK;IAExC,qFAAqF;IACrF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,6BAA6B,CAAK;IAE1D,yGAAyG;IACzG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAK;IAEvD,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAK;IAErD,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAM;IAEtD,mFAAmF;IACnF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,6BAA6B,CAAK;IAE1D,sFAAsF;IACtF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAK;IAEpD;;OAEG;IACH,MAAM,CAAC,6BAA6B,CAClC,OAAO,EAAE,2BAA2B,EACpC,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,OAAO,GAC1B;QAAE,oBAAoB,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;KAAE;IAuC9E;;;;;;OAMG;IACH,MAAM,CAAC,uBAAuB,CAC5B,SAAS,EAAE,2BAA2B,GACrC,6BAA6B;IAkDhC;;;;;;;;;OASG;IACH,MAAM,CAAC,oBAAoB,CACzB,OAAO,EAAE,2BAA2B,EACpC,aAAa,EAAE,IAAI,GAClB;QACD,2DAA2D;QAC3D,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC;QAEpC;;;;WAIG;QACH,wBAAwB,EAAE,MAAM,CAAC;QAEjC,4EAA4E;QAC5E,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI;IA+CR;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA4B3C;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,6CAA6C;IA0Q5D;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,MAAM,CAAC,yBAAyB;CAgCzC"}