@aneuhold/core-ts-db-lib 4.1.14 → 5.0.0

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 (29) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/lib/ctos/workout/WorkoutExerciseCTO.d.ts +2 -2
  3. package/lib/ctos/workout/WorkoutExerciseCTO.d.ts.map +1 -1
  4. package/lib/ctos/workout/WorkoutExerciseCTO.js +5 -6
  5. package/lib/ctos/workout/WorkoutExerciseCTO.js.map +1 -1
  6. package/lib/ctos/workout/WorkoutExerciseCTO.ts +5 -6
  7. package/lib/documents/workout/WorkoutSet.d.ts +9 -6
  8. package/lib/documents/workout/WorkoutSet.d.ts.map +1 -1
  9. package/lib/documents/workout/WorkoutSet.ts +9 -6
  10. package/lib/services/workout/Exercise/WorkoutExerciseService.d.ts +27 -23
  11. package/lib/services/workout/Exercise/WorkoutExerciseService.d.ts.map +1 -1
  12. package/lib/services/workout/Exercise/WorkoutExerciseService.js +82 -93
  13. package/lib/services/workout/Exercise/WorkoutExerciseService.js.map +1 -1
  14. package/lib/services/workout/Exercise/WorkoutExerciseService.ts +93 -120
  15. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.d.ts.map +1 -1
  16. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.js +6 -8
  17. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.js.map +1 -1
  18. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.ts +7 -17
  19. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.d.ts +13 -8
  20. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.d.ts.map +1 -1
  21. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.js +30 -9
  22. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.js.map +1 -1
  23. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.ts +42 -14
  24. package/lib/services/workout/Set/WorkoutSetService.d.ts +4 -3
  25. package/lib/services/workout/Set/WorkoutSetService.d.ts.map +1 -1
  26. package/lib/services/workout/Set/WorkoutSetService.js +25 -20
  27. package/lib/services/workout/Set/WorkoutSetService.js.map +1 -1
  28. package/lib/services/workout/Set/WorkoutSetService.ts +26 -21
  29. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 🔖 [5.0.0] (2026-03-13)
9
+
10
+ ### 🏗️ Changed
11
+
12
+ - _Breaking Change:_ `WorkoutExerciseCTO.lastFirstSet` (nullable `WorkoutSet`) replaced by `lastSessionSets` (array of `WorkoutSet`).
13
+ - _Breaking Change:_ `WorkoutExerciseService.calculateTargetRepsAndWeightForFirstSet` parameter `previousFirstSet?: WorkoutSet` replaced by `previousSets: WorkoutSet[]`.
14
+ - Autoregulation now averages surplus across all sets in a session exercise instead of using only the first set, providing a more representative performance signal.
15
+ - `WorkoutSessionExerciseService.calculateSetSurplus` is now private; the new public `calculateAverageSurplus(sets)` method handles multi-set aggregation.
16
+ - `WorkoutMesocycleService` performance-drop detection now averages surplus across all sets rather than using only the first set.
17
+ - `WorkoutSetService` now retrieves all sets from the previous microcycle for autoregulation instead of only the first set.
18
+ - Rep progression severe underperformance (average surplus < -3) now also reduces weight by one equipment increment.
19
+
20
+ ## 🔖 [4.1.15] (2026-03-12)
21
+
22
+ ### 🏗️ Changed
23
+
24
+ - `CompletedWorkoutSet` type refined to only require planned and actual performance fields (`plannedReps`, `plannedWeight`, `plannedRir`, `actualReps`, `actualWeight`, `rir`) to be non-nullable, rather than all fields.
25
+ - `WorkoutExerciseService.calculateTargetRepsAndWeightForFirstSet` no longer accepts a `microcycleIndex` parameter; all microcycle-to-microcycle progression is now handled by autoregulation/forecasting from the previous set.
26
+ - Replaced `hasCompleteAutoRegulationData` with `toCompletedSet`, which converts a `WorkoutSet` to a `CompletedWorkoutSet` and forecasts planned-only sets (surplus = 0) so progression continues smoothly even without actual performance data.
27
+ - `calculateCalibrationBasedTargets` now computes initial targets only (no microcycle loops); it is used exclusively when no previous set exists.
28
+ - `WorkoutSetService` no longer passes `microcycleIndex` to `calculateTargetRepsAndWeightForFirstSet`.
29
+
8
30
  ## 🔖 [4.1.14] (2026-03-07)
9
31
 
10
32
  ### 🏗️ Changed
@@ -374,7 +396,8 @@ Updated dependency: now requires `@aneuhold/core-ts-lib@^2.3.11`.
374
396
  - Updated workflow permissions to allow repository write access
375
397
 
376
398
  <!-- Link References -->
377
-
399
+ [5.0.0]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.15...core-ts-db-lib-v5.0.0
400
+ [4.1.15]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.14...core-ts-db-lib-v4.1.15
378
401
  [4.1.14]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.13...core-ts-db-lib-v4.1.14
379
402
  [4.1.13]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.12...core-ts-db-lib-v4.1.13
380
403
  [4.1.12]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.11...core-ts-db-lib-v4.1.12
@@ -71,7 +71,7 @@ export declare const WorkoutExerciseCTOSchema: z.ZodObject<{
71
71
  _id: z.ZodPipe<z.ZodDefault<z.ZodUUID>, z.ZodTransform<`${string}-${string}-${string}-${string}-${string}`, string>>;
72
72
  userId: z.ZodPipe<z.ZodUUID, z.ZodTransform<`${string}-${string}-${string}-${string}-${string}`, string>>;
73
73
  }, z.core.$strip>>;
74
- lastFirstSet: z.ZodNullable<z.ZodObject<{
74
+ lastSessionSets: z.ZodDefault<z.ZodArray<z.ZodObject<{
75
75
  docType: z.ZodDefault<z.ZodLiteral<"workoutSet">>;
76
76
  workoutExerciseId: z.ZodPipe<z.ZodUUID, z.ZodTransform<`${string}-${string}-${string}-${string}-${string}`, string>>;
77
77
  workoutSessionId: z.ZodPipe<z.ZodUUID, z.ZodTransform<`${string}-${string}-${string}-${string}-${string}`, string>>;
@@ -87,7 +87,7 @@ export declare const WorkoutExerciseCTOSchema: z.ZodObject<{
87
87
  lastUpdatedDate: z.ZodDefault<z.ZodDate>;
88
88
  _id: z.ZodPipe<z.ZodDefault<z.ZodUUID>, z.ZodTransform<`${string}-${string}-${string}-${string}-${string}`, string>>;
89
89
  userId: z.ZodPipe<z.ZodUUID, z.ZodTransform<`${string}-${string}-${string}-${string}-${string}`, string>>;
90
- }, z.core.$strip>>;
90
+ }, z.core.$strip>>>;
91
91
  docType: z.ZodDefault<z.ZodLiteral<"workoutExercise">>;
92
92
  exerciseName: z.ZodString;
93
93
  workoutEquipmentTypeId: z.ZodPipe<z.ZodUUID, z.ZodTransform<`${string}-${string}-${string}-${string}-${string}`, string>>;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutExerciseCTO.d.ts","sourceRoot":"","sources":["../../../src/ctos/workout/WorkoutExerciseCTO.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+CnC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
1
+ {"version":3,"file":"WorkoutExerciseCTO.d.ts","sourceRoot":"","sources":["../../../src/ctos/workout/WorkoutExerciseCTO.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8CnC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -46,13 +46,12 @@ export const WorkoutExerciseCTOSchema = z.object({
46
46
  */
47
47
  lastSessionExercise: WorkoutSessionExerciseSchema.nullable(),
48
48
  /**
49
- * The first WorkoutSet from the lastSessionExercise's setOrder.
50
- * This is the "anchor" set that progression calculations use since
51
- * subsequent sets are derived from the first via intra-session fatigue
52
- * drops.
49
+ * All WorkoutSets from the lastSessionExercise's setOrder. Surplus is
50
+ * averaged across all sets for a holistic performance signal during
51
+ * autoregulation (the first set alone can mask poor later-set performance).
53
52
  *
54
- * Null if no previous accumulation performance exists.
53
+ * Empty array if no previous accumulation performance exists.
55
54
  */
56
- lastFirstSet: WorkoutSetSchema.nullable()
55
+ lastSessionSets: z.array(WorkoutSetSchema).default([])
57
56
  });
58
57
  //# sourceMappingURL=WorkoutExerciseCTO.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutExerciseCTO.js","sourceRoot":"","sources":["../../../src/ctos/workout/WorkoutExerciseCTO.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAE,gCAAgC,EAAE,MAAM,uDAAuD,CAAC;AACzG,OAAO,EAAE,4BAA4B,EAAE,MAAM,mDAAmD,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAEzE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,GAAG,qBAAqB,CAAC,KAAK;IAE9B;;;OAGG;IACH,aAAa,EAAE,0BAA0B;IAEzC;;;;OAIG;IACH,eAAe,EAAE,gCAAgC,CAAC,QAAQ,EAAE;IAE5D;;;;;;;OAOG;IACH,OAAO,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IAEpC;;;;;;;;;OASG;IACH,mBAAmB,EAAE,4BAA4B,CAAC,QAAQ,EAAE;IAE5D;;;;;;;OAOG;IACH,YAAY,EAAE,gBAAgB,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC"}
1
+ {"version":3,"file":"WorkoutExerciseCTO.js","sourceRoot":"","sources":["../../../src/ctos/workout/WorkoutExerciseCTO.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAE,gCAAgC,EAAE,MAAM,uDAAuD,CAAC;AACzG,OAAO,EAAE,4BAA4B,EAAE,MAAM,mDAAmD,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAEzE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,GAAG,qBAAqB,CAAC,KAAK;IAE9B;;;OAGG;IACH,aAAa,EAAE,0BAA0B;IAEzC;;;;OAIG;IACH,eAAe,EAAE,gCAAgC,CAAC,QAAQ,EAAE;IAE5D;;;;;;;OAOG;IACH,OAAO,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IAEpC;;;;;;;;;OASG;IACH,mBAAmB,EAAE,4BAA4B,CAAC,QAAQ,EAAE;IAE5D;;;;;;OAMG;IACH,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACvD,CAAC,CAAC"}
@@ -52,14 +52,13 @@ export const WorkoutExerciseCTOSchema = z.object({
52
52
  lastSessionExercise: WorkoutSessionExerciseSchema.nullable(),
53
53
 
54
54
  /**
55
- * The first WorkoutSet from the lastSessionExercise's setOrder.
56
- * This is the "anchor" set that progression calculations use since
57
- * subsequent sets are derived from the first via intra-session fatigue
58
- * drops.
55
+ * All WorkoutSets from the lastSessionExercise's setOrder. Surplus is
56
+ * averaged across all sets for a holistic performance signal during
57
+ * autoregulation (the first set alone can mask poor later-set performance).
59
58
  *
60
- * Null if no previous accumulation performance exists.
59
+ * Empty array if no previous accumulation performance exists.
61
60
  */
62
- lastFirstSet: WorkoutSetSchema.nullable()
61
+ lastSessionSets: z.array(WorkoutSetSchema).default([])
63
62
  });
64
63
 
65
64
  /**
@@ -39,11 +39,14 @@ export declare const WorkoutSetSchema: z.ZodObject<{
39
39
  */
40
40
  export type WorkoutSet = z.infer<typeof WorkoutSetSchema>;
41
41
  /**
42
- * A {@link WorkoutSet} with all nullable fields guaranteed to be defined.
43
- * Zod's `.nullish()` produces `T | null | undefined`, so `Required` alone
44
- * only strips the optional `?` — `NonNullable` is needed to also strip `null`.
42
+ * A {@link WorkoutSet} with all planned and actual performance fields guaranteed non-nullable.
45
43
  */
46
- export type CompletedWorkoutSet = Required<{
47
- [K in keyof WorkoutSet]: NonNullable<WorkoutSet[K]>;
48
- }>;
44
+ export type CompletedWorkoutSet = WorkoutSet & {
45
+ plannedReps: NonNullable<WorkoutSet['plannedReps']>;
46
+ plannedWeight: NonNullable<WorkoutSet['plannedWeight']>;
47
+ plannedRir: NonNullable<WorkoutSet['plannedRir']>;
48
+ actualReps: NonNullable<WorkoutSet['actualReps']>;
49
+ actualWeight: NonNullable<WorkoutSet['actualWeight']>;
50
+ rir: NonNullable<WorkoutSet['rir']>;
51
+ };
49
52
  //# sourceMappingURL=WorkoutSet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutSet.d.ts","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutSet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;iBAyD3B,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;KACxC,CAAC,IAAI,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;CACpD,CAAC,CAAC"}
1
+ {"version":3,"file":"WorkoutSet.d.ts","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutSet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;iBAyD3B,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG;IAC7C,WAAW,EAAE,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC;IACpD,aAAa,EAAE,WAAW,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC;IACxD,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;IAClD,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;IAClD,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;IACtD,GAAG,EAAE,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;CACrC,CAAC"}
@@ -90,10 +90,13 @@ export const WorkoutSetSchema = z.object({
90
90
  export type WorkoutSet = z.infer<typeof WorkoutSetSchema>;
91
91
 
92
92
  /**
93
- * A {@link WorkoutSet} with all nullable fields guaranteed to be defined.
94
- * Zod's `.nullish()` produces `T | null | undefined`, so `Required` alone
95
- * only strips the optional `?` — `NonNullable` is needed to also strip `null`.
93
+ * A {@link WorkoutSet} with all planned and actual performance fields guaranteed non-nullable.
96
94
  */
97
- export type CompletedWorkoutSet = Required<{
98
- [K in keyof WorkoutSet]: NonNullable<WorkoutSet[K]>;
99
- }>;
95
+ export type CompletedWorkoutSet = WorkoutSet & {
96
+ plannedReps: NonNullable<WorkoutSet['plannedReps']>;
97
+ plannedWeight: NonNullable<WorkoutSet['plannedWeight']>;
98
+ plannedRir: NonNullable<WorkoutSet['plannedRir']>;
99
+ actualReps: NonNullable<WorkoutSet['actualReps']>;
100
+ actualWeight: NonNullable<WorkoutSet['actualWeight']>;
101
+ rir: NonNullable<WorkoutSet['rir']>;
102
+ };
@@ -27,48 +27,44 @@ export default class WorkoutExerciseService {
27
27
  */
28
28
  static getFatigueScore(exercise: WorkoutExercise): number;
29
29
  /**
30
- * Calculates the progressed target weight and reps for an exercise based on microcycle progression.
31
- * This returns the target weight and reps for the FIRST set of the exercise in the given microcycle,
32
- * assuming it is an accumulation phase (i.e., not a deload).
30
+ * Calculates the target weight and reps for the FIRST set of an exercise.
33
31
  *
34
- * This method applies either rep-based or load-based progression depending on the exercise's
35
- * preferred progression type, then rounds the weight to available equipment options.
32
+ * When `previousSets` are provided (completed or planned-only), autoregulation
33
+ * computes an average surplus across all sets and applies progression. Planned-only
34
+ * sets are forecasted with surplus = 0 so the plan progresses smoothly without
35
+ * falling back to calibration.
36
36
  *
37
- * When a `previousFirstSet` is provided, autoregulation adjusts progression based on the
38
- * surplus between planned and actual performance. Without it, the calibration-based formula
39
- * is used as a baseline.
40
- *
41
- * Rep progression: The weight is calculated based on reps at microcycle 0, and reps increase
42
- * by 2 per microcycle to reach max reps at the final accumulation microcycle (ideally),
43
- * or drop back down and increase weight by 2%.
44
- *
45
- * Load progression: Increases weight by at least 2% per microcycle.
46
- * If weight can't be increased, adds 2 reps instead.
37
+ * When no previous sets exist (first mesocycle or new exercise), the calibration-based
38
+ * formula computes initial targets from the exercise's 1RM and rep range.
47
39
  */
48
40
  static calculateTargetRepsAndWeightForFirstSet(params: {
49
41
  exercise: WorkoutExercise;
50
42
  calibration: WorkoutExerciseCalibration;
51
43
  equipment: WorkoutEquipmentType;
52
- microcycleIndex: number;
53
44
  firstMicrocycleRir: number;
54
- previousFirstSet?: WorkoutSet;
45
+ previousSets: WorkoutSet[];
55
46
  }): {
56
47
  targetWeight: number;
57
48
  targetReps: number;
58
49
  };
59
50
  /**
60
- * Calculates targets using auto-regulation based on actual performance from a previous set.
51
+ * Calculates targets using auto-regulation based on actual performance from previous sets.
52
+ * Surplus is averaged across all sets for a more representative performance signal.
53
+ * Previously only the first set's surplus was used, which masked poor performance
54
+ * on later sets (e.g., first set hits target but second set falls far short).
61
55
  */
62
56
  private static calculateAutoRegulatedTargets;
63
57
  /**
64
- * Auto-regulated rep progression. Weight stays the same, reps adjust based on surplus.
58
+ * Auto-regulated rep progression. Attempts to increase reps until hitting rep range max,
59
+ * then resets reps and increases weight.
65
60
  *
66
61
  * | Surplus | Action |
67
62
  * |---:|---|
68
63
  * | >= 3 | Accelerate: actualReps + 2 (progress from actual, not planned) |
69
64
  * | 0 to 2 | Normal: plannedReps + 2 |
70
65
  * | -1 to -2 | Hold: plannedReps (don't add reps) |
71
- * | <= -3 | Regress: actualReps (use actual as new baseline) |
66
+ * | -3 | Regress: actualReps (use actual as new baseline) |
67
+ * | < -3 | Severe regress: actualReps + reduce weight (weight is too heavy for rep range) |
72
68
  */
73
69
  private static calculateAutoRegulatedRepTargets;
74
70
  /**
@@ -83,11 +79,19 @@ export default class WorkoutExerciseService {
83
79
  */
84
80
  private static calculateAutoRegulatedLoadTargets;
85
81
  /**
86
- * Checks whether a set has all the data needed for autoregulation calculations.
82
+ * Converts a {@link WorkoutSet} into a {@link CompletedWorkoutSet} for autoregulation.
83
+ *
84
+ * If actual performance data exists, returns the set with those values. Otherwise,
85
+ * forecasts by copying planned values into the actual fields (producing surplus = 0)
86
+ * so that autoregulation applies normal progression from the planned baseline.
87
+ *
88
+ * Returns null if the set lacks the minimum planned data needed.
87
89
  */
88
- private static hasCompleteAutoRegulationData;
90
+ private static toCompletedSet;
89
91
  /**
90
- * Calculates targets using the calibration-based formula (original behavior).
92
+ * Calculates initial targets from calibration data. Used only when no previous
93
+ * set exists (first microcycle of the first mesocycle, or brand-new exercise).
94
+ * All subsequent microcycle progression is handled by autoregulation/forecasting.
91
95
  */
92
96
  private static calculateCalibrationBasedTargets;
93
97
  private static findNextTwoPercentWeight;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutExerciseService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Exercise/WorkoutExerciseService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EAEL,gBAAgB,EACjB,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AAC3G,OAAO,KAAK,EAAuB,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAMhG;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,sBAAsB;IACzC;;;;;;;;OAQG;IACH,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAWlF;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM;IAIzD;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,uCAAuC,CAAC,MAAM,EAAE;QACrD,QAAQ,EAAE,eAAe,CAAC;QAC1B,WAAW,EAAE,0BAA0B,CAAC;QACxC,SAAS,EAAE,oBAAoB,CAAC;QAChC,eAAe,EAAE,MAAM,CAAC;QACxB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,gBAAgB,CAAC,EAAE,UAAU,CAAC;KAC/B,GAAG;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IA2ChD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAsB5C;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,gCAAgC;IA4C/C;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,iCAAiC;IA2ChD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAU5C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gCAAgC;IAgG/C,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAgBxC"}
1
+ {"version":3,"file":"WorkoutExerciseService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Exercise/WorkoutExerciseService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EAEL,gBAAgB,EACjB,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AAC3G,OAAO,KAAK,EAAuB,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAMhG;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,sBAAsB;IACzC;;;;;;;;OAQG;IACH,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAWlF;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM;IAIzD;;;;;;;;;;OAUG;IACH,MAAM,CAAC,uCAAuC,CAAC,MAAM,EAAE;QACrD,QAAQ,EAAE,eAAe,CAAC;QAC1B,WAAW,EAAE,0BAA0B,CAAC;QACxC,SAAS,EAAE,oBAAoB,CAAC;QAChC,kBAAkB,EAAE,MAAM,CAAC;QAC3B,YAAY,EAAE,UAAU,EAAE,CAAC;KAC5B,GAAG;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IA0ChD;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAuB5C;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM,CAAC,gCAAgC;IAyD/C;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,iCAAiC;IA2ChD;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAmB7B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,gCAAgC;IA2C/C,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAgBxC"}
@@ -35,26 +35,18 @@ export default class WorkoutExerciseService {
35
35
  return WorkoutSFRService.getFatigueTotal(exercise.initialFatigueGuess) || 0;
36
36
  }
37
37
  /**
38
- * Calculates the progressed target weight and reps for an exercise based on microcycle progression.
39
- * This returns the target weight and reps for the FIRST set of the exercise in the given microcycle,
40
- * assuming it is an accumulation phase (i.e., not a deload).
38
+ * Calculates the target weight and reps for the FIRST set of an exercise.
41
39
  *
42
- * This method applies either rep-based or load-based progression depending on the exercise's
43
- * preferred progression type, then rounds the weight to available equipment options.
40
+ * When `previousSets` are provided (completed or planned-only), autoregulation
41
+ * computes an average surplus across all sets and applies progression. Planned-only
42
+ * sets are forecasted with surplus = 0 so the plan progresses smoothly without
43
+ * falling back to calibration.
44
44
  *
45
- * When a `previousFirstSet` is provided, autoregulation adjusts progression based on the
46
- * surplus between planned and actual performance. Without it, the calibration-based formula
47
- * is used as a baseline.
48
- *
49
- * Rep progression: The weight is calculated based on reps at microcycle 0, and reps increase
50
- * by 2 per microcycle to reach max reps at the final accumulation microcycle (ideally),
51
- * or drop back down and increase weight by 2%.
52
- *
53
- * Load progression: Increases weight by at least 2% per microcycle.
54
- * If weight can't be increased, adds 2 reps instead.
45
+ * When no previous sets exist (first mesocycle or new exercise), the calibration-based
46
+ * formula computes initial targets from the exercise's 1RM and rep range.
55
47
  */
56
48
  static calculateTargetRepsAndWeightForFirstSet(params) {
57
- const { exercise, calibration, equipment, microcycleIndex, firstMicrocycleRir, previousFirstSet } = params;
49
+ const { exercise, calibration, equipment, firstMicrocycleRir, previousSets } = params;
58
50
  // Validate equipment has weight options
59
51
  if (!equipment.weightOptions || equipment.weightOptions.length === 0) {
60
52
  throw new Error(`No weight options defined for equipment type ${equipment._id}, ${equipment.title}`);
@@ -62,12 +54,18 @@ export default class WorkoutExerciseService {
62
54
  // Get rep range for this exercise
63
55
  const repRange = this.getRepRangeValues(exercise.repRange);
64
56
  const repRangeMidpoint = Math.floor((repRange.min + repRange.max) / 2);
65
- // If we have a previous set with complete data, use autoregulation
66
- if (previousFirstSet && this.hasCompleteAutoRegulationData(previousFirstSet)) {
57
+ // Convert all previous sets to completed sets (forecasting planned actual if needed).
58
+ // toCompletedSet returns the real data when actual performance exists, or
59
+ // forecasts by copying planned values into actuals (surplus = 0) so the
60
+ // plan progresses smoothly from the planned baseline.
61
+ const completedSets = previousSets
62
+ .map((set) => this.toCompletedSet(set))
63
+ .filter((set) => set !== null);
64
+ if (completedSets.length > 0) {
67
65
  return this.calculateAutoRegulatedTargets({
68
66
  exercise,
69
67
  equipment,
70
- previousFirstSet,
68
+ previousSets: completedSets,
71
69
  repRange
72
70
  });
73
71
  }
@@ -76,32 +74,41 @@ export default class WorkoutExerciseService {
76
74
  exercise,
77
75
  calibration,
78
76
  equipment,
79
- microcycleIndex,
80
77
  firstMicrocycleRir,
81
78
  repRange,
82
79
  repRangeMidpoint
83
80
  });
84
81
  }
85
82
  /**
86
- * Calculates targets using auto-regulation based on actual performance from a previous set.
83
+ * Calculates targets using auto-regulation based on actual performance from previous sets.
84
+ * Surplus is averaged across all sets for a more representative performance signal.
85
+ * Previously only the first set's surplus was used, which masked poor performance
86
+ * on later sets (e.g., first set hits target but second set falls far short).
87
87
  */
88
88
  static calculateAutoRegulatedTargets(params) {
89
- const { exercise, equipment, previousFirstSet, repRange } = params;
90
- const surplus = WorkoutSessionExerciseService.calculateSetSurplus(previousFirstSet.actualReps, previousFirstSet.plannedReps, previousFirstSet.rir, previousFirstSet.plannedRir);
89
+ const { exercise, equipment, previousSets, repRange } = params;
90
+ // The first set is the reference for rep/weight targets (subsequent sets are
91
+ // derived from the first via intra-session fatigue drops).
92
+ const previousFirstSet = previousSets[0];
93
+ // Average surplus across all sets for a holistic performance signal.
94
+ // previousSets are CompletedWorkoutSets (all fields non-null), so this always returns a number.
95
+ const surplus = WorkoutSessionExerciseService.calculateAverageSurplus(previousSets) ?? 0;
91
96
  if (exercise.preferredProgressionType === ExerciseProgressionType.Rep) {
92
97
  return this.calculateAutoRegulatedRepTargets(previousFirstSet, surplus, repRange, equipment);
93
98
  }
94
99
  return this.calculateAutoRegulatedLoadTargets(previousFirstSet, surplus, repRange, equipment);
95
100
  }
96
101
  /**
97
- * Auto-regulated rep progression. Weight stays the same, reps adjust based on surplus.
102
+ * Auto-regulated rep progression. Attempts to increase reps until hitting rep range max,
103
+ * then resets reps and increases weight.
98
104
  *
99
105
  * | Surplus | Action |
100
106
  * |---:|---|
101
107
  * | >= 3 | Accelerate: actualReps + 2 (progress from actual, not planned) |
102
108
  * | 0 to 2 | Normal: plannedReps + 2 |
103
109
  * | -1 to -2 | Hold: plannedReps (don't add reps) |
104
- * | <= -3 | Regress: actualReps (use actual as new baseline) |
110
+ * | -3 | Regress: actualReps (use actual as new baseline) |
111
+ * | < -3 | Severe regress: actualReps + reduce weight (weight is too heavy for rep range) |
105
112
  */
106
113
  static calculateAutoRegulatedRepTargets(previousSet, surplus, repRange, equipment) {
107
114
  let targetReps;
@@ -115,14 +122,24 @@ export default class WorkoutExerciseService {
115
122
  else if (surplus >= -2) {
116
123
  targetReps = previousSet.plannedReps;
117
124
  }
125
+ else if (surplus >= -3) {
126
+ targetReps = previousSet.actualReps;
127
+ }
118
128
  else {
129
+ // Severe underperformance: the weight is too heavy for this rep range.
130
+ // Reduce weight by one equipment increment so the user can actually
131
+ // train in the target rep range.
119
132
  targetReps = previousSet.actualReps;
133
+ const reducedWeight = WorkoutEquipmentTypeService.findNearestWeight(equipment, targetWeight - 0.01, 'down');
134
+ if (reducedWeight !== null) {
135
+ targetWeight = reducedWeight;
136
+ }
120
137
  }
121
138
  // Clamp to rep range floor (never target below min, even if actual was 0)
122
139
  targetReps = Math.max(targetReps, repRange.min);
123
140
  // Handle rep range ceiling: if target exceeds max, reset and bump weight
124
141
  if (targetReps > repRange.max) {
125
- targetReps = repRange.max;
142
+ targetReps = Math.floor((repRange.min + repRange.max) / 2);
126
143
  const nextWeight = this.findNextTwoPercentWeight(targetWeight, equipment);
127
144
  if (nextWeight !== null) {
128
145
  targetWeight = nextWeight;
@@ -176,82 +193,54 @@ export default class WorkoutExerciseService {
176
193
  return { targetWeight, targetReps };
177
194
  }
178
195
  /**
179
- * Checks whether a set has all the data needed for autoregulation calculations.
196
+ * Converts a {@link WorkoutSet} into a {@link CompletedWorkoutSet} for autoregulation.
197
+ *
198
+ * If actual performance data exists, returns the set with those values. Otherwise,
199
+ * forecasts by copying planned values into the actual fields (producing surplus = 0)
200
+ * so that autoregulation applies normal progression from the planned baseline.
201
+ *
202
+ * Returns null if the set lacks the minimum planned data needed.
180
203
  */
181
- static hasCompleteAutoRegulationData(set) {
182
- return (set.actualReps != null &&
183
- set.plannedReps != null &&
184
- set.rir != null &&
185
- set.plannedRir != null &&
186
- set.plannedWeight != null);
204
+ static toCompletedSet(set) {
205
+ if (!set) {
206
+ return null;
207
+ }
208
+ const { plannedReps, plannedWeight, plannedRir } = set;
209
+ if (plannedReps == null || plannedWeight == null || plannedRir == null) {
210
+ return null;
211
+ }
212
+ return {
213
+ ...set,
214
+ plannedReps,
215
+ plannedWeight,
216
+ plannedRir,
217
+ actualReps: set.actualReps ?? plannedReps,
218
+ actualWeight: set.actualWeight ?? plannedWeight,
219
+ rir: set.rir ?? plannedRir
220
+ };
187
221
  }
188
222
  /**
189
- * Calculates targets using the calibration-based formula (original behavior).
223
+ * Calculates initial targets from calibration data. Used only when no previous
224
+ * set exists (first microcycle of the first mesocycle, or brand-new exercise).
225
+ * All subsequent microcycle progression is handled by autoregulation/forecasting.
190
226
  */
191
227
  static calculateCalibrationBasedTargets(params) {
192
- const { exercise, calibration, equipment, microcycleIndex, firstMicrocycleRir, repRange, repRangeMidpoint } = params;
193
- // For rep progression, calculate weight based on reps at microcycle 0
228
+ const { exercise, calibration, equipment, firstMicrocycleRir, repRange, repRangeMidpoint } = params;
229
+ // For rep progression, calculate weight based on midpoint + RIR reps
194
230
  // For load progression, use max reps
195
- let baseRepsForWeight;
196
- if (exercise.preferredProgressionType === ExerciseProgressionType.Rep) {
197
- baseRepsForWeight = repRangeMidpoint + firstMicrocycleRir;
198
- }
199
- else {
200
- // Load progression uses max reps for initial weight calculation
201
- baseRepsForWeight = repRange.max;
202
- }
231
+ const baseRepsForWeight = exercise.preferredProgressionType === ExerciseProgressionType.Rep
232
+ ? repRangeMidpoint + firstMicrocycleRir
233
+ : repRange.max;
203
234
  // Calculate base weight
204
- let targetWeight = WorkoutExerciseCalibrationService.getTargetWeight(calibration, baseRepsForWeight);
205
- // Round to nearest available weight, preferring lower
206
- const roundedWeight = WorkoutEquipmentTypeService.findNearestWeight(equipment, targetWeight, 'prefer-down');
207
- if (roundedWeight === null) {
235
+ const rawWeight = WorkoutExerciseCalibrationService.getTargetWeight(calibration, baseRepsForWeight);
236
+ const targetWeight = WorkoutEquipmentTypeService.findNearestWeight(equipment, rawWeight, 'prefer-down');
237
+ if (targetWeight === null) {
208
238
  throw new Error(`No available weight options found for equipment type ${equipment._id}, ${equipment.title}`);
209
239
  }
210
- targetWeight = roundedWeight;
211
- // Calculate target reps based on progression type
212
- let targetReps;
213
- if (exercise.preferredProgressionType === ExerciseProgressionType.Rep) {
214
- // Rep progression: Add up to max reps, then loop back if needed
215
- let currentMicrocycleIndex = 0;
216
- targetReps = repRangeMidpoint;
217
- while (currentMicrocycleIndex < microcycleIndex) {
218
- targetReps += 2;
219
- if (targetReps > repRange.max) {
220
- // Different reset amounts based on the rep range
221
- switch (exercise.repRange) {
222
- case ExerciseRepRange.Heavy:
223
- targetReps = targetReps - 4;
224
- break;
225
- case ExerciseRepRange.Medium:
226
- targetReps = targetReps - 6;
227
- break;
228
- case ExerciseRepRange.Light:
229
- targetReps = targetReps - 8;
230
- break;
231
- }
232
- const nextWeight = this.findNextTwoPercentWeight(targetWeight, equipment);
233
- if (nextWeight !== null) {
234
- targetWeight = nextWeight;
235
- }
236
- }
237
- currentMicrocycleIndex++;
238
- }
239
- }
240
- else {
241
- // Load progression: Start at max reps
242
- targetReps = repRange.max;
243
- }
244
- // Apply load progression if applicable for the weight
245
- if (exercise.preferredProgressionType === ExerciseProgressionType.Load && microcycleIndex > 0) {
246
- const nextWeight = this.findNextTwoPercentWeight(targetWeight, equipment);
247
- if (nextWeight !== null) {
248
- targetWeight = nextWeight;
249
- }
250
- else {
251
- // Increase reps if we can't increase weight
252
- targetReps = targetReps + 2;
253
- }
254
- }
240
+ // Rep progression starts at midpoint; load progression starts at max reps
241
+ const targetReps = exercise.preferredProgressionType === ExerciseProgressionType.Rep
242
+ ? repRangeMidpoint
243
+ : repRange.max;
255
244
  return { targetWeight, targetReps };
256
245
  }
257
246
  static findNextTwoPercentWeight(currentWeight, equipment) {
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutExerciseService.js","sourceRoot":"","sources":["../../../../src/services/workout/Exercise/WorkoutExerciseService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkoutExerciseService.js","sourceRoot":"","sources":["../../../../src/services/workout/Exercise/WorkoutExerciseService.ts"],"names":[],"mappings":"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"}