@aneuhold/core-ts-db-lib 4.1.2 → 4.1.4

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 (40) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/lib/documents/workout/WorkoutEquipmentType.d.ts +1 -0
  3. package/lib/documents/workout/WorkoutEquipmentType.d.ts.map +1 -1
  4. package/lib/documents/workout/WorkoutEquipmentType.js +4 -0
  5. package/lib/documents/workout/WorkoutEquipmentType.js.map +1 -1
  6. package/lib/documents/workout/WorkoutEquipmentType.ts +4 -0
  7. package/lib/documents/workout/WorkoutMesocycle.d.ts +1 -0
  8. package/lib/documents/workout/WorkoutMesocycle.d.ts.map +1 -1
  9. package/lib/documents/workout/WorkoutMesocycle.js +8 -0
  10. package/lib/documents/workout/WorkoutMesocycle.js.map +1 -1
  11. package/lib/documents/workout/WorkoutMesocycle.ts +8 -0
  12. package/lib/documents/workout/WorkoutMicrocycle.d.ts +1 -0
  13. package/lib/documents/workout/WorkoutMicrocycle.d.ts.map +1 -1
  14. package/lib/documents/workout/WorkoutMicrocycle.js +8 -1
  15. package/lib/documents/workout/WorkoutMicrocycle.js.map +1 -1
  16. package/lib/documents/workout/WorkoutMicrocycle.ts +8 -1
  17. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.d.ts +3 -1
  18. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.d.ts.map +1 -1
  19. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.js +8 -4
  20. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.js.map +1 -1
  21. package/lib/services/workout/Mesocycle/WorkoutMesocycleService.ts +9 -4
  22. package/lib/services/workout/Microcycle/WorkoutMicrocycleService.d.ts +1 -1
  23. package/lib/services/workout/Microcycle/WorkoutMicrocycleService.d.ts.map +1 -1
  24. package/lib/services/workout/Microcycle/WorkoutMicrocycleService.ts +1 -1
  25. package/lib/services/workout/Session/WorkoutSessionService.d.ts +24 -1
  26. package/lib/services/workout/Session/WorkoutSessionService.d.ts.map +1 -1
  27. package/lib/services/workout/Session/WorkoutSessionService.js +48 -0
  28. package/lib/services/workout/Session/WorkoutSessionService.js.map +1 -1
  29. package/lib/services/workout/Session/WorkoutSessionService.ts +57 -1
  30. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.d.ts +10 -0
  31. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.d.ts.map +1 -1
  32. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.js +17 -0
  33. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.js.map +1 -1
  34. package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.ts +21 -0
  35. package/lib/services/workout/Set/WorkoutSetService.d.ts +8 -1
  36. package/lib/services/workout/Set/WorkoutSetService.d.ts.map +1 -1
  37. package/lib/services/workout/Set/WorkoutSetService.js +10 -0
  38. package/lib/services/workout/Set/WorkoutSetService.js.map +1 -1
  39. package/lib/services/workout/Set/WorkoutSetService.ts +14 -1
  40. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@ 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
+ ## 🔖 [4.1.4] (2026-02-20)
9
+
10
+ ### ✅ Added
11
+
12
+ - Added optional `description` field to `WorkoutEquipmentType` for additional equipment details.
13
+ - Added `startDate` field to `WorkoutMesocycle` to track when a user explicitly begins training.
14
+ - Added `completedDate` field to `WorkoutMicrocycle` to mark completion and indicate regeneration state.
15
+
16
+ ### 🏗️ Changed
17
+
18
+ - Updated `WorkoutMesocycleService` to preserve microcycles with `completedDate` set during mesocycle regeneration, even when sessions are incomplete.
19
+
20
+ ## 🔖 [4.1.3] (2026-02-17)
21
+
22
+ ### ✅ Added
23
+
24
+ - Added `getActiveAndNextSessions()` method to `WorkoutSessionService` for efficiently finding in-progress and next-up sessions.
25
+ - Added `isDeloadExercise()` method to `WorkoutSessionExerciseService` to identify deload exercises.
26
+ - Added `needsReview()` method to `WorkoutSessionExerciseService` to check if late session fields are missing.
27
+ - Added `isCompleted()` method to `WorkoutSetService` to verify if a set has been fully logged.
28
+ - Added comprehensive unit tests for workout session, exercise, and set services.
29
+
30
+ ### 🏗️ Changed
31
+
32
+ - Updated deload microcycle handling: `targetRir` is now `null` for deload microcycles instead of using a numeric value.
33
+ - Refactored method signatures to support `targetRir: number | null` across workout services.
34
+
8
35
  ## 🔖 [4.1.2] (2026-02-15)
9
36
 
10
37
  ### ✅ Added
@@ -225,6 +252,8 @@ Updated dependency: now requires `@aneuhold/core-ts-lib@^2.3.11`.
225
252
 
226
253
  <!-- Link References -->
227
254
 
255
+ [4.1.4]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.3...core-ts-db-lib-v4.1.4
256
+ [4.1.3]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.2...core-ts-db-lib-v4.1.3
228
257
  [4.1.2]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.1...core-ts-db-lib-v4.1.2
229
258
  [4.1.1]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.0...core-ts-db-lib-v4.1.1
230
259
  [4.1.0]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.0.4...core-ts-db-lib-v4.1.0
@@ -9,6 +9,7 @@ export declare const WorkoutEquipmentType_docType = "workoutEquipmentType";
9
9
  export declare const WorkoutEquipmentTypeSchema: z.ZodObject<{
10
10
  docType: z.ZodDefault<z.ZodLiteral<"workoutEquipmentType">>;
11
11
  title: z.ZodString;
12
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
12
13
  weightOptions: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodNumber>>>;
13
14
  createdDate: z.ZodDefault<z.ZodDate>;
14
15
  lastUpdatedDate: z.ZodDefault<z.ZodDate>;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutEquipmentType.d.ts","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutEquipmentType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;GAEG;AACH,eAAO,MAAM,4BAA4B,yBAAyB,CAAC;AAEnE;;GAEG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;iBAmBrC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
1
+ {"version":3,"file":"WorkoutEquipmentType.d.ts","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutEquipmentType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;GAEG;AACH,eAAO,MAAM,4BAA4B,yBAAyB,CAAC;AAEnE;;GAEG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;iBAuBrC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
@@ -17,6 +17,10 @@ export const WorkoutEquipmentTypeSchema = z.object({
17
17
  * The title of the equipment type.
18
18
  */
19
19
  title: z.string(),
20
+ /**
21
+ * An optional description of the equipment type.
22
+ */
23
+ description: z.string().nullish(),
20
24
  /**
21
25
  * The available weight options for this equipment type.
22
26
  *
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutEquipmentType.js","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutEquipmentType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EACL,0BAA0B,EAC1B,4CAA4C,EAC7C,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,sBAAsB,CAAC;AAEnE;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,GAAG,0BAA0B,CAAC,KAAK;IACnC,GAAG,oBAAoB,CAAC,KAAK;IAC7B,GAAG,4CAA4C,CAAC,KAAK;IACrD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC,4BAA4B,CAAC;IACtF;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB;;;;;;;;OAQG;IACH,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE;CAC3D,CAAC,CAAC"}
1
+ {"version":3,"file":"WorkoutEquipmentType.js","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutEquipmentType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EACL,0BAA0B,EAC1B,4CAA4C,EAC7C,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,sBAAsB,CAAC;AAEnE;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,GAAG,0BAA0B,CAAC,KAAK;IACnC,GAAG,oBAAoB,CAAC,KAAK;IAC7B,GAAG,4CAA4C,CAAC,KAAK;IACrD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC,4BAA4B,CAAC;IACtF;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB;;OAEG;IACH,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;IACjC;;;;;;;;OAQG;IACH,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE;CAC3D,CAAC,CAAC"}
@@ -22,6 +22,10 @@ export const WorkoutEquipmentTypeSchema = z.object({
22
22
  * The title of the equipment type.
23
23
  */
24
24
  title: z.string(),
25
+ /**
26
+ * An optional description of the equipment type.
27
+ */
28
+ description: z.string().nullish(),
25
29
  /**
26
30
  * The available weight options for this equipment type.
27
31
  *
@@ -29,6 +29,7 @@ export declare const WorkoutMesocycleSchema: z.ZodObject<{
29
29
  plannedMicrocycleLengthInDays: z.ZodInt;
30
30
  plannedMicrocycleRestDays: z.ZodDefault<z.ZodArray<z.ZodInt>>;
31
31
  plannedMicrocycleCount: z.ZodOptional<z.ZodNullable<z.ZodInt>>;
32
+ startDate: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
32
33
  completedDate: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
33
34
  createdDate: z.ZodDefault<z.ZodDate>;
34
35
  lastUpdatedDate: z.ZodDefault<z.ZodDate>;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutMesocycle.d.ts","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutMesocycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;GAOG;AACH,oBAAY,SAAS;IACnB,UAAU,eAAe;IACzB,eAAe,oBAAoB;IACnC,GAAG,QAAQ;IACX,QAAQ,aAAa;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,qBAAqB,CAAC;AAE3D;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;iBAmDjC,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"WorkoutMesocycle.d.ts","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutMesocycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;GAOG;AACH,oBAAY,SAAS;IACnB,UAAU,eAAe;IACzB,eAAe,oBAAoB;IACnC,GAAG,QAAQ;IACX,QAAQ,aAAa;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,qBAAqB,CAAC;AAE3D;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;iBA2DjC,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -66,6 +66,14 @@ export const WorkoutMesocycleSchema = z.object({
66
66
  * Should typically be 5-9 microcycles (4-8 accumulation weeks + 1 deload week).
67
67
  */
68
68
  plannedMicrocycleCount: z.int().min(2).max(20).nullish(),
69
+ /**
70
+ * The date this mesocycle was started by the user.
71
+ *
72
+ * Distinct from `createdDate` — this is set when the user explicitly clicks
73
+ * "Start Mesocycle" to begin training. This is helpful because we need a way to indicate that
74
+ * the final regeneration has been done just before they start.
75
+ */
76
+ startDate: z.date().nullish(),
69
77
  /**
70
78
  * The date this mesocycle was completed.
71
79
  *
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutMesocycle.js","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutMesocycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EACL,0BAA0B,EAC1B,4CAA4C,EAC7C,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,sCAAyB,CAAA;IACzB,gDAAmC,CAAA;IACnC,wBAAW,CAAA;IACX,kCAAqB,CAAA;AACvB,CAAC,EALW,SAAS,KAAT,SAAS,QAKpB;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAE3D;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,GAAG,0BAA0B,CAAC,KAAK;IACnC,GAAG,oBAAoB,CAAC,KAAK;IAC7B,GAAG,4CAA4C,CAAC,KAAK;IACrD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC;IAC9E;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;IAC3B;;;;;OAKG;IACH,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACpF;;OAEG;IACH,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;IAC5B;;OAEG;IACH,gCAAgC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACpD;;;;OAIG;IACH,6BAA6B,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACjD;;;;;OAKG;IACH,yBAAyB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACrE;;;;OAIG;IACH,sBAAsB,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE;IACxD;;;;;;OAMG;IACH,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE;CAClC,CAAC,CAAC"}
1
+ {"version":3,"file":"WorkoutMesocycle.js","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutMesocycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EACL,0BAA0B,EAC1B,4CAA4C,EAC7C,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,sCAAyB,CAAA;IACzB,gDAAmC,CAAA;IACnC,wBAAW,CAAA;IACX,kCAAqB,CAAA;AACvB,CAAC,EALW,SAAS,KAAT,SAAS,QAKpB;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAE3D;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,GAAG,0BAA0B,CAAC,KAAK;IACnC,GAAG,oBAAoB,CAAC,KAAK;IAC7B,GAAG,4CAA4C,CAAC,KAAK;IACrD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC;IAC9E;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;IAC3B;;;;;OAKG;IACH,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACpF;;OAEG;IACH,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;IAC5B;;OAEG;IACH,gCAAgC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACpD;;;;OAIG;IACH,6BAA6B,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACjD;;;;;OAKG;IACH,yBAAyB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACrE;;;;OAIG;IACH,sBAAsB,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE;IACxD;;;;;;OAMG;IACH,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE;IAC7B;;;;;;OAMG;IACH,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE;CAClC,CAAC,CAAC"}
@@ -72,6 +72,14 @@ export const WorkoutMesocycleSchema = z.object({
72
72
  * Should typically be 5-9 microcycles (4-8 accumulation weeks + 1 deload week).
73
73
  */
74
74
  plannedMicrocycleCount: z.int().min(2).max(20).nullish(),
75
+ /**
76
+ * The date this mesocycle was started by the user.
77
+ *
78
+ * Distinct from `createdDate` — this is set when the user explicitly clicks
79
+ * "Start Mesocycle" to begin training. This is helpful because we need a way to indicate that
80
+ * the final regeneration has been done just before they start.
81
+ */
82
+ startDate: z.date().nullish(),
75
83
  /**
76
84
  * The date this mesocycle was completed.
77
85
  *
@@ -12,6 +12,7 @@ export declare const WorkoutMicrocycleSchema: z.ZodObject<{
12
12
  startDate: z.ZodDate;
13
13
  endDate: z.ZodDate;
14
14
  sessionOrder: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodUUID, z.ZodTransform<`${string}-${string}-${string}-${string}-${string}`, string>>>>;
15
+ completedDate: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
15
16
  createdDate: z.ZodDefault<z.ZodDate>;
16
17
  lastUpdatedDate: z.ZodDefault<z.ZodDate>;
17
18
  _id: z.ZodPipe<z.ZodDefault<z.ZodUUID>, z.ZodTransform<`${string}-${string}-${string}-${string}-${string}`, string>>;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutMicrocycle.d.ts","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutMicrocycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;GAEG;AACH,eAAO,MAAM,yBAAyB,sBAAsB,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;iBA8BlC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
1
+ {"version":3,"file":"WorkoutMicrocycle.d.ts","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutMicrocycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;GAEG;AACH,eAAO,MAAM,yBAAyB,sBAAsB,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;iBAqClC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
@@ -37,6 +37,13 @@ export const WorkoutMicrocycleSchema = z.object({
37
37
  * This makes it easier to reason about the order of sessions before dates
38
38
  * are assigned.
39
39
  */
40
- sessionOrder: z.array(z.uuidv7().transform((val) => val)).default([])
40
+ sessionOrder: z.array(z.uuidv7().transform((val) => val)).default([]),
41
+ /**
42
+ * The date this microcycle was marked as completed by the user.
43
+ *
44
+ * This helps for performance reasons, but also acts as our indicator that the mesocycle has been
45
+ * regenerated after the microcycle was completed.
46
+ */
47
+ completedDate: z.date().nullish()
41
48
  });
42
49
  //# sourceMappingURL=WorkoutMicrocycle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutMicrocycle.js","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutMicrocycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EACL,0BAA0B,EAC1B,4CAA4C,EAC7C,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,GAAG,0BAA0B,CAAC,KAAK;IACnC,GAAG,oBAAoB,CAAC,KAAK;IAC7B,GAAG,4CAA4C,CAAC,KAAK;IACrD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC;IAChF;;;;OAIG;IACH,kBAAkB,EAAE,CAAC;SAClB,MAAM,EAAE;SACR,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAW,CAAC;SAC/B,OAAO,EAAE;IACZ;;OAEG;IACH,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE;IACnB;;OAEG;IACH,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE;IACjB;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC9E,CAAC,CAAC"}
1
+ {"version":3,"file":"WorkoutMicrocycle.js","sourceRoot":"","sources":["../../../src/documents/workout/WorkoutMicrocycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EACL,0BAA0B,EAC1B,4CAA4C,EAC7C,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,GAAG,0BAA0B,CAAC,KAAK;IACnC,GAAG,oBAAoB,CAAC,KAAK;IAC7B,GAAG,4CAA4C,CAAC,KAAK;IACrD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC;IAChF;;;;OAIG;IACH,kBAAkB,EAAE,CAAC;SAClB,MAAM,EAAE;SACR,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAW,CAAC;SAC/B,OAAO,EAAE;IACZ;;OAEG;IACH,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE;IACnB;;OAEG;IACH,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE;IACjB;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7E;;;;;OAKG;IACH,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE;CAClC,CAAC,CAAC"}
@@ -43,7 +43,14 @@ export const WorkoutMicrocycleSchema = z.object({
43
43
  * This makes it easier to reason about the order of sessions before dates
44
44
  * are assigned.
45
45
  */
46
- sessionOrder: z.array(z.uuidv7().transform((val) => val as UUID)).default([])
46
+ sessionOrder: z.array(z.uuidv7().transform((val) => val as UUID)).default([]),
47
+ /**
48
+ * The date this microcycle was marked as completed by the user.
49
+ *
50
+ * This helps for performance reasons, but also acts as our indicator that the mesocycle has been
51
+ * regenerated after the microcycle was completed.
52
+ */
53
+ completedDate: z.date().nullish()
47
54
  });
48
55
 
49
56
  /**
@@ -32,8 +32,10 @@ export default class WorkoutMesocycleService {
32
32
  * @param existingSessions Existing session documents.
33
33
  * @param existingSessionExercises Existing session exercise documents.
34
34
  * @param existingSets Existing set documents.
35
+ * @param startDate Optional start date for the first microcycle. Defaults to
36
+ * the current date when not provided.
35
37
  */
36
- static generateOrUpdateMesocycle(mesocycle: WorkoutMesocycle, calibrations: WorkoutExerciseCalibration[], exercises: WorkoutExercise[], equipmentTypes: WorkoutEquipmentType[], existingMicrocycles?: WorkoutMicrocycle[], existingSessions?: WorkoutSession[], existingSessionExercises?: WorkoutSessionExercise[], existingSets?: WorkoutSet[]): {
38
+ static generateOrUpdateMesocycle(mesocycle: WorkoutMesocycle, calibrations: WorkoutExerciseCalibration[], exercises: WorkoutExercise[], equipmentTypes: WorkoutEquipmentType[], existingMicrocycles?: WorkoutMicrocycle[], existingSessions?: WorkoutSession[], existingSessionExercises?: WorkoutSessionExercise[], existingSets?: WorkoutSet[], startDate?: Date): {
37
39
  mesocycleUpdate?: Partial<WorkoutMesocycle>;
38
40
  microcycles?: DocumentOperations<WorkoutMicrocycle>;
39
41
  sessions?: DocumentOperations<WorkoutSession>;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutMesocycleService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Mesocycle/WorkoutMesocycleService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AAC3G,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AAEzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AACnF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sDAAsD,CAAC;AACnG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAC1C;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,MAAM,CAAC,yBAAyB,CAC9B,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EAAE,0BAA0B,EAAE,EAC1C,SAAS,EAAE,eAAe,EAAE,EAC5B,cAAc,EAAE,oBAAoB,EAAE,EACtC,mBAAmB,GAAE,iBAAiB,EAAO,EAC7C,gBAAgB,GAAE,cAAc,EAAO,EACvC,wBAAwB,GAAE,sBAAsB,EAAO,EACvD,YAAY,GAAE,UAAU,EAAO,GAC9B;QACD,eAAe,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC5C,WAAW,CAAC,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QACpD,QAAQ,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;QAC9C,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;QAC9D,IAAI,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;KACvC;IAyHD;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;CAyF5C"}
1
+ {"version":3,"file":"WorkoutMesocycleService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Mesocycle/WorkoutMesocycleService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AAC3G,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AAEzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AACnF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sDAAsD,CAAC;AACnG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAC1C;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,yBAAyB,CAC9B,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EAAE,0BAA0B,EAAE,EAC1C,SAAS,EAAE,eAAe,EAAE,EAC5B,cAAc,EAAE,oBAAoB,EAAE,EACtC,mBAAmB,GAAE,iBAAiB,EAAO,EAC7C,gBAAgB,GAAE,cAAc,EAAO,EACvC,wBAAwB,GAAE,sBAAsB,EAAO,EACvD,YAAY,GAAE,UAAU,EAAO,EAC/B,SAAS,CAAC,EAAE,IAAI,GACf;QACD,eAAe,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC5C,WAAW,CAAC,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QACpD,QAAQ,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;QAC9C,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;QAC9D,IAAI,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;KACvC;IAwHD;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;CA4F5C"}
@@ -28,8 +28,10 @@ export default class WorkoutMesocycleService {
28
28
  * @param existingSessions Existing session documents.
29
29
  * @param existingSessionExercises Existing session exercise documents.
30
30
  * @param existingSets Existing set documents.
31
+ * @param startDate Optional start date for the first microcycle. Defaults to
32
+ * the current date when not provided.
31
33
  */
32
- static generateOrUpdateMesocycle(mesocycle, calibrations, exercises, equipmentTypes, existingMicrocycles = [], existingSessions = [], existingSessionExercises = [], existingSets = []) {
34
+ static generateOrUpdateMesocycle(mesocycle, calibrations, exercises, equipmentTypes, existingMicrocycles = [], existingSessions = [], existingSessionExercises = [], existingSets = [], startDate) {
33
35
  // Free-form mesocycles are intentionally not auto-planned. The user can still log workouts,
34
36
  // but we avoid generating microcycles/sessions/sets because recommendations wouldn't be able
35
37
  // to be done / make any sense.
@@ -55,8 +57,7 @@ export default class WorkoutMesocycleService {
55
57
  const startMicrocycleIndex = context.microcyclesInOrder.length;
56
58
  let currentDate;
57
59
  if (startMicrocycleIndex === 0) {
58
- // No existing microcycles, start from current date
59
- currentDate = new Date();
60
+ currentDate = startDate ? new Date(startDate) : new Date();
60
61
  }
61
62
  else {
62
63
  // Continue from where the last existing microcycle ended
@@ -68,7 +69,7 @@ export default class WorkoutMesocycleService {
68
69
  const isDeloadMicrocycle = microcycleIndex === deloadMicrocycleIndex;
69
70
  // Calculate RIR for this microcycle (4 -> 3 -> 2 -> 1 -> 0, capped at microcycle 5)
70
71
  const rirForMicrocycle = Math.min(microcycleIndex, 4);
71
- const targetRir = 4 - rirForMicrocycle;
72
+ const targetRir = isDeloadMicrocycle ? null : 4 - rirForMicrocycle;
72
73
  // Create microcycle
73
74
  const microcycle = WorkoutMicrocycleSchema.parse({
74
75
  userId: mesocycle.userId,
@@ -124,6 +125,9 @@ export default class WorkoutMesocycleService {
124
125
  let firstIncompleteMicrocycleIndex = -1;
125
126
  for (let i = 0; i < microcyclesForMesocycle.length; i++) {
126
127
  const microcycle = microcyclesForMesocycle[i];
128
+ if (microcycle.completedDate) {
129
+ continue;
130
+ }
127
131
  if (microcycle.sessionOrder.length === 0) {
128
132
  // Microcycle has no sessions, it's incomplete
129
133
  firstIncompleteMicrocycleIndex = i;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutMesocycleService.js","sourceRoot":"","sources":["../../../../src/services/workout/Mesocycle/WorkoutMesocycleService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkoutMesocycleService.js","sourceRoot":"","sources":["../../../../src/services/workout/Mesocycle/WorkoutMesocycleService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,OAAO,EAAE,SAAS,EAAyB,MAAM,gDAAgD,CAAC;AAElG,OAAO,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAK1F,OAAO,wBAAwB,MAAM,2CAA2C,CAAC;AACjF,OAAO,2BAA2B,MAAM,kCAAkC,CAAC;AAE3E;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAC1C;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,yBAAyB,CAC9B,SAA2B,EAC3B,YAA0C,EAC1C,SAA4B,EAC5B,cAAsC,EACtC,sBAA2C,EAAE,EAC7C,mBAAqC,EAAE,EACvC,2BAAqD,EAAE,EACvD,eAA6B,EAAE,EAC/B,SAAgB;QAQhB,4FAA4F;QAC5F,6FAA6F;QAC7F,+BAA+B;QAC/B,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS,CAAC,QAAQ,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,0DAA0D;QAC1D,MAAM,aAAa,GAAG,IAAI,CAAC,4BAA4B,CACrD,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,YAAY,CACb,CAAC;QAEF,4CAA4C;QAC5C,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,MAAM,CACjD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAC1D,CAAC;QACF,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CACvD,CAAC;QACF,MAAM,qBAAqB,GAAG,wBAAwB,CAAC,MAAM,CAC3D,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CACjE,CAAC;QACF,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAE1F,0CAA0C;QAC1C,MAAM,OAAO,GAAG,IAAI,2BAA2B,CAC7C,SAAS,EACT,YAAY,EACZ,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,SAAS,CACV,CAAC;QAEF,2EAA2E;QAC3E,mEAAmE;QACnE,OAAO,CAAC,8BAA8B,CACpC,wBAAwB,CAAC,iCAAiC,CACxD,SAAS,CAAC,gCAAgC,EAC1C,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,WAAW,CACpB,CACF,CAAC;QAEF,6FAA6F;QAC7F,MAAM,gBAAgB,GAAG,SAAS,CAAC,sBAAsB,IAAI,CAAC,CAAC;QAC/D,MAAM,qBAAqB,GAAG,gBAAgB,GAAG,CAAC,CAAC;QAEnD,0CAA0C;QAC1C,MAAM,oBAAoB,GAAG,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC;QAC/D,IAAI,WAAiB,CAAC;QAEtB,IAAI,oBAAoB,KAAK,CAAC,EAAE,CAAC;YAC/B,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,yDAAyD;YACzD,MAAM,sBAAsB,GAAG,OAAO,CAAC,kBAAkB,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;YACpF,WAAW,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACzD,CAAC;QAED,iCAAiC;QACjC,KACE,IAAI,eAAe,GAAG,oBAAoB,EAC1C,eAAe,GAAG,gBAAgB,EAClC,eAAe,EAAE,EACjB,CAAC;YACD,MAAM,kBAAkB,GAAG,eAAe,KAAK,qBAAqB,CAAC;YAErE,oFAAoF;YACpF,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC;YAEnE,oBAAoB;YACpB,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,CAAC;gBAC/C,MAAM,EAAE,SAAS,CAAC,MAAM;gBACxB,kBAAkB,EAAE,SAAS,CAAC,GAAG;gBACjC,SAAS,EAAE,IAAI,IAAI,CAAC,WAAW,CAAC;gBAChC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,6BAA6B,CAAC;aACnF,CAAC,CAAC;YACH,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YAElC,wBAAwB,CAAC,6BAA6B,CAAC;gBACrD,OAAO;gBACP,eAAe;gBACf,SAAS;gBACT,kBAAkB;aACnB,CAAC,CAAC;YAEH,0BAA0B;YAC1B,WAAW,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO;YACL,eAAe,EAAE,SAAS;YAC1B,WAAW,EAAE;gBACX,MAAM,EAAE,OAAO,CAAC,mBAAmB;gBACnC,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,aAAa,CAAC,mBAAmB;aAC1C;YACD,QAAQ,EAAE;gBACR,MAAM,EAAE,OAAO,CAAC,gBAAgB;gBAChC,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,aAAa,CAAC,gBAAgB;aACvC;YACD,gBAAgB,EAAE;gBAChB,MAAM,EAAE,OAAO,CAAC,wBAAwB;gBACxC,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,aAAa,CAAC,wBAAwB;aAC/C;YACD,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,YAAY,EAAE;SACvF,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACK,MAAM,CAAC,4BAA4B,CACzC,SAA2B,EAC3B,mBAAwC,EACxC,gBAAkC,EAClC,wBAAkD,EAClD,YAA0B;QAO1B,MAAM,mBAAmB,GAAW,EAAE,CAAC;QACvC,MAAM,gBAAgB,GAAW,EAAE,CAAC;QACpC,MAAM,wBAAwB,GAAW,EAAE,CAAC;QAC5C,MAAM,YAAY,GAAW,EAAE,CAAC;QAEhC,sCAAsC;QACtC,MAAM,uBAAuB,GAAG,mBAAmB,CAAC,IAAI,CACtD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CACxD,CAAC;QAEF,mCAAmC;QACnC,IAAI,8BAA8B,GAAG,CAAC,CAAC,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxD,MAAM,UAAU,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC;YAC9C,IAAI,UAAU,CAAC,aAAa,EAAE,CAAC;gBAC7B,SAAS;YACX,CAAC;YACD,IAAI,UAAU,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzC,8CAA8C;gBAC9C,8BAA8B,GAAG,CAAC,CAAC;gBACnC,MAAM;YACR,CAAC;YAED,oCAAoC;YACpC,MAAM,aAAa,GAAG,UAAU,CAAC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAClF,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC;YAC1E,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,CAAC;gBAC3B,8BAA8B,GAAG,CAAC,CAAC;gBACnC,MAAM;YACR,CAAC;QACH,CAAC;QAED,uDAAuD;QACvD,IAAI,8BAA8B,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1C,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,YAAY,EAAE,CAAC;QAC3F,CAAC;QAED,MAAM,yBAAyB,GAAG,uBAAuB,CAAC,8BAA8B,CAAC,CAAC;QAE1F,0EAA0E;QAC1E,IAAI,yBAAyB,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtD,MAAM,cAAc,GAAG,yBAAyB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjE,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,cAAc,CAAC,CAAC;YAC5E,IAAI,YAAY,EAAE,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACb,iDAAiD,SAAS,CAAC,GAAG,IAAI;oBAChE,uBAAuB,8BAA8B,oCAAoC;oBACzF,6FAA6F,CAChG,CAAC;YACJ,CAAC;QACH,CAAC;QAED,qFAAqF;QACrF,MAAM,qBAAqB,GAAG,uBAAuB,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC5F,mBAAmB,CAAC,IAAI,CAAC,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAErE,2FAA2F;QAC3F,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACjF,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;YACvC,IAAI,OAAO,CAAC,mBAAmB,IAAI,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAC5F,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACrD,KAAK,MAAM,eAAe,IAAI,wBAAwB,EAAE,CAAC;YACvD,IAAI,kBAAkB,CAAC,GAAG,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC7D,wBAAwB,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QAED,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACrE,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;YAC/B,IAAI,0BAA0B,CAAC,GAAG,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,CAAC;gBACjE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,YAAY,EAAE,CAAC;IAC3F,CAAC;CACF"}
@@ -38,6 +38,8 @@ export default class WorkoutMesocycleService {
38
38
  * @param existingSessions Existing session documents.
39
39
  * @param existingSessionExercises Existing session exercise documents.
40
40
  * @param existingSets Existing set documents.
41
+ * @param startDate Optional start date for the first microcycle. Defaults to
42
+ * the current date when not provided.
41
43
  */
42
44
  static generateOrUpdateMesocycle(
43
45
  mesocycle: WorkoutMesocycle,
@@ -47,7 +49,8 @@ export default class WorkoutMesocycleService {
47
49
  existingMicrocycles: WorkoutMicrocycle[] = [],
48
50
  existingSessions: WorkoutSession[] = [],
49
51
  existingSessionExercises: WorkoutSessionExercise[] = [],
50
- existingSets: WorkoutSet[] = []
52
+ existingSets: WorkoutSet[] = [],
53
+ startDate?: Date
51
54
  ): {
52
55
  mesocycleUpdate?: Partial<WorkoutMesocycle>;
53
56
  microcycles?: DocumentOperations<WorkoutMicrocycle>;
@@ -114,8 +117,7 @@ export default class WorkoutMesocycleService {
114
117
  let currentDate: Date;
115
118
 
116
119
  if (startMicrocycleIndex === 0) {
117
- // No existing microcycles, start from current date
118
- currentDate = new Date();
120
+ currentDate = startDate ? new Date(startDate) : new Date();
119
121
  } else {
120
122
  // Continue from where the last existing microcycle ended
121
123
  const lastExistingMicrocycle = context.microcyclesInOrder[startMicrocycleIndex - 1];
@@ -132,7 +134,7 @@ export default class WorkoutMesocycleService {
132
134
 
133
135
  // Calculate RIR for this microcycle (4 -> 3 -> 2 -> 1 -> 0, capped at microcycle 5)
134
136
  const rirForMicrocycle = Math.min(microcycleIndex, 4);
135
- const targetRir = 4 - rirForMicrocycle;
137
+ const targetRir = isDeloadMicrocycle ? null : 4 - rirForMicrocycle;
136
138
 
137
139
  // Create microcycle
138
140
  const microcycle = WorkoutMicrocycleSchema.parse({
@@ -208,6 +210,9 @@ export default class WorkoutMesocycleService {
208
210
  let firstIncompleteMicrocycleIndex = -1;
209
211
  for (let i = 0; i < microcyclesForMesocycle.length; i++) {
210
212
  const microcycle = microcyclesForMesocycle[i];
213
+ if (microcycle.completedDate) {
214
+ continue;
215
+ }
211
216
  if (microcycle.sessionOrder.length === 0) {
212
217
  // Microcycle has no sessions, it's incomplete
213
218
  firstIncompleteMicrocycleIndex = i;
@@ -12,7 +12,7 @@ export default class WorkoutMicrocycleService {
12
12
  static generateSessionsForMicrocycle({ context, microcycleIndex, targetRir, isDeloadMicrocycle }: {
13
13
  context: WorkoutMesocyclePlanContext;
14
14
  microcycleIndex: number;
15
- targetRir: number;
15
+ targetRir: number | null;
16
16
  isDeloadMicrocycle: boolean;
17
17
  }): void;
18
18
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutMicrocycleService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Microcycle/WorkoutMicrocycleService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EACV,uBAAuB,EACvB,0BAA0B,EAC3B,MAAM,0DAA0D,CAAC;AAElE,OAAO,KAAK,2BAA2B,MAAM,6CAA6C,CAAC;AAI3F;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,wBAAwB;IAC3C;;OAEG;IACH,MAAM,CAAC,6BAA6B,CAAC,EACnC,OAAO,EACP,eAAe,EACf,SAAS,EACT,kBAAkB,EACnB,EAAE;QACD,OAAO,EAAE,2BAA2B,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,kBAAkB,EAAE,OAAO,CAAC;KAC7B,GAAG,IAAI;IA8DR;;;;;;;OAOG;IACH,MAAM,CAAC,iCAAiC,CACtC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,GAAG,CAAC,IAAI,EAAE,0BAA0B,CAAC,EACrD,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,GACtC,uBAAuB,EAAE,EAAE;CAuI/B"}
1
+ {"version":3,"file":"WorkoutMicrocycleService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Microcycle/WorkoutMicrocycleService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EACV,uBAAuB,EACvB,0BAA0B,EAC3B,MAAM,0DAA0D,CAAC;AAElE,OAAO,KAAK,2BAA2B,MAAM,6CAA6C,CAAC;AAI3F;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,wBAAwB;IAC3C;;OAEG;IACH,MAAM,CAAC,6BAA6B,CAAC,EACnC,OAAO,EACP,eAAe,EACf,SAAS,EACT,kBAAkB,EACnB,EAAE;QACD,OAAO,EAAE,2BAA2B,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,kBAAkB,EAAE,OAAO,CAAC;KAC7B,GAAG,IAAI;IA8DR;;;;;;;OAOG;IACH,MAAM,CAAC,iCAAiC,CACtC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,GAAG,CAAC,IAAI,EAAE,0BAA0B,CAAC,EACrD,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,GACtC,uBAAuB,EAAE,EAAE;CAuI/B"}
@@ -28,7 +28,7 @@ export default class WorkoutMicrocycleService {
28
28
  }: {
29
29
  context: WorkoutMesocyclePlanContext;
30
30
  microcycleIndex: number;
31
- targetRir: number;
31
+ targetRir: number | null;
32
32
  isDeloadMicrocycle: boolean;
33
33
  }): void {
34
34
  const mesocycle = context.mesocycle;
@@ -1,6 +1,8 @@
1
1
  import type { UUID } from 'crypto';
2
2
  import type { CalibrationExercisePair } from '../../../documents/workout/WorkoutExerciseCalibration.js';
3
3
  import type { WorkoutSession } from '../../../documents/workout/WorkoutSession.js';
4
+ import type { WorkoutSessionExercise } from '../../../documents/workout/WorkoutSessionExercise.js';
5
+ import type { WorkoutSet } from '../../../documents/workout/WorkoutSet.js';
4
6
  import type WorkoutMesocyclePlanContext from '../Mesocycle/WorkoutMesocyclePlanContext.js';
5
7
  /**
6
8
  * A service for handling operations related to {@link WorkoutSession}s.
@@ -29,6 +31,27 @@ export default class WorkoutSessionService {
29
31
  * Calculates the Stimulus to Fatigue Ratio (SFR) for a session.
30
32
  */
31
33
  static getSFR(session: WorkoutSession): number | null;
34
+ /**
35
+ * Finds the in-progress session and the next-up session in a single pass.
36
+ * - In-progress: complete === false, at least one set has actualReps != null
37
+ * - Next-up: first complete === false session with no logged sets (after any in-progress)
38
+ *
39
+ * Sessions should be in microcycle order (as returned by getAssociatedDocsForMesocycle).
40
+ * Only checks sets for incomplete sessions, skipping completed ones entirely.
41
+ *
42
+ * @param sessions Ordered sessions for the mesocycle.
43
+ * @param sessionExerciseMap Map of session exercise ID to WorkoutSessionExercise.
44
+ * @param setMap Map of set ID to WorkoutSet.
45
+ */
46
+ static getActiveAndNextSessions(sessions: WorkoutSession[], sessionExerciseMap: Map<UUID, WorkoutSessionExercise>, setMap: Map<UUID, WorkoutSet>): {
47
+ inProgressSession: WorkoutSession | null;
48
+ nextUpSession: WorkoutSession | null;
49
+ };
50
+ /**
51
+ * Returns true if any set in the session has actualReps != null.
52
+ * Traverses session → sessionExercises → sets via order arrays and map lookups.
53
+ */
54
+ private static sessionHasLoggedSets;
32
55
  /**
33
56
  * Generates a session and its associated exercises and sets.
34
57
  */
@@ -38,7 +61,7 @@ export default class WorkoutSessionService {
38
61
  sessionIndex: number;
39
62
  sessionStartDate: Date;
40
63
  sessionExerciseList: CalibrationExercisePair[];
41
- targetRir: number;
64
+ targetRir: number | null;
42
65
  isDeloadMicrocycle: boolean;
43
66
  setPlan: {
44
67
  exerciseIdToSetCount: Map<UUID, number>;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutSessionService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Session/WorkoutSessionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0DAA0D,CAAC;AACxG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAGnF,OAAO,KAAK,2BAA2B,MAAM,6CAA6C,CAAC;AAI3F;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACxC;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAI1D;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAI9D;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAIrD;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,EACrB,OAAO,EACP,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,kBAAkB,EAClB,OAAO,EACR,EAAE;QACD,OAAO,EAAE,2BAA2B,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,IAAI,CAAC;QACvB,mBAAmB,EAAE,uBAAuB,EAAE,CAAC;QAC/C,SAAS,EAAE,MAAM,CAAC;QAClB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,OAAO,EAAE;YAAE,oBAAoB,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;SAAE,CAAC;KACtF,GAAG,IAAI;CAqET"}
1
+ {"version":3,"file":"WorkoutSessionService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Session/WorkoutSessionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0DAA0D,CAAC;AACxG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAGnF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sDAAsD,CAAC;AACnG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,2BAA2B,MAAM,6CAA6C,CAAC;AAI3F;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACxC;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAI1D;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAI9D;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAIrD;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,wBAAwB,CAC7B,QAAQ,EAAE,cAAc,EAAE,EAC1B,kBAAkB,EAAE,GAAG,CAAC,IAAI,EAAE,sBAAsB,CAAC,EACrD,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,GAC5B;QAAE,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAAC;QAAC,aAAa,EAAE,cAAc,GAAG,IAAI,CAAA;KAAE;IAkBrF;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAgBnC;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,EACrB,OAAO,EACP,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,kBAAkB,EAClB,OAAO,EACR,EAAE;QACD,OAAO,EAAE,2BAA2B,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,IAAI,CAAC;QACvB,mBAAmB,EAAE,uBAAuB,EAAE,CAAC;QAC/C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,OAAO,EAAE;YAAE,oBAAoB,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;SAAE,CAAC;KACtF,GAAG,IAAI;CAqET"}
@@ -35,6 +35,54 @@ export default class WorkoutSessionService {
35
35
  static getSFR(session) {
36
36
  return WorkoutSFRService.getSFR(session.rsm, session.fatigue);
37
37
  }
38
+ /**
39
+ * Finds the in-progress session and the next-up session in a single pass.
40
+ * - In-progress: complete === false, at least one set has actualReps != null
41
+ * - Next-up: first complete === false session with no logged sets (after any in-progress)
42
+ *
43
+ * Sessions should be in microcycle order (as returned by getAssociatedDocsForMesocycle).
44
+ * Only checks sets for incomplete sessions, skipping completed ones entirely.
45
+ *
46
+ * @param sessions Ordered sessions for the mesocycle.
47
+ * @param sessionExerciseMap Map of session exercise ID to WorkoutSessionExercise.
48
+ * @param setMap Map of set ID to WorkoutSet.
49
+ */
50
+ static getActiveAndNextSessions(sessions, sessionExerciseMap, setMap) {
51
+ let inProgressSession = null;
52
+ let nextUpSession = null;
53
+ for (const session of sessions) {
54
+ if (session.complete)
55
+ continue;
56
+ if (this.sessionHasLoggedSets(session, sessionExerciseMap, setMap)) {
57
+ if (!inProgressSession)
58
+ inProgressSession = session;
59
+ }
60
+ else {
61
+ if (!nextUpSession)
62
+ nextUpSession = session;
63
+ }
64
+ if (inProgressSession && nextUpSession)
65
+ break;
66
+ }
67
+ return { inProgressSession, nextUpSession };
68
+ }
69
+ /**
70
+ * Returns true if any set in the session has actualReps != null.
71
+ * Traverses session → sessionExercises → sets via order arrays and map lookups.
72
+ */
73
+ static sessionHasLoggedSets(session, sessionExerciseMap, setMap) {
74
+ for (const seId of session.sessionExerciseOrder) {
75
+ const se = sessionExerciseMap.get(seId);
76
+ if (!se)
77
+ continue;
78
+ for (const setId of se.setOrder) {
79
+ const set = setMap.get(setId);
80
+ if (set?.actualReps != null)
81
+ return true;
82
+ }
83
+ }
84
+ return false;
85
+ }
38
86
  /**
39
87
  * Generates a session and its associated exercises and sets.
40
88
  */
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutSessionService.js","sourceRoot":"","sources":["../../../../src/services/workout/Session/WorkoutSessionService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkoutSessionService.js","sourceRoot":"","sources":["../../../../src/services/workout/Session/WorkoutSessionService.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ import type { CalibrationExercisePair } from '../../../documents/workout/Workout
3
3
  import type { WorkoutSession } from '../../../documents/workout/WorkoutSession.js';
4
4
  import { WorkoutSessionSchema } from '../../../documents/workout/WorkoutSession.js';
5
5
  import { WorkoutSessionExerciseSchema } from '../../../documents/workout/WorkoutSessionExercise.js';
6
+ import type { WorkoutSessionExercise } from '../../../documents/workout/WorkoutSessionExercise.js';
7
+ import type { WorkoutSet } from '../../../documents/workout/WorkoutSet.js';
6
8
  import type WorkoutMesocyclePlanContext from '../Mesocycle/WorkoutMesocyclePlanContext.js';
7
9
  import WorkoutSetService from '../Set/WorkoutSetService.js';
8
10
  import WorkoutSFRService from '../util/SFR/WorkoutSFRService.js';
@@ -43,6 +45,60 @@ export default class WorkoutSessionService {
43
45
  return WorkoutSFRService.getSFR(session.rsm, session.fatigue);
44
46
  }
45
47
 
48
+ /**
49
+ * Finds the in-progress session and the next-up session in a single pass.
50
+ * - In-progress: complete === false, at least one set has actualReps != null
51
+ * - Next-up: first complete === false session with no logged sets (after any in-progress)
52
+ *
53
+ * Sessions should be in microcycle order (as returned by getAssociatedDocsForMesocycle).
54
+ * Only checks sets for incomplete sessions, skipping completed ones entirely.
55
+ *
56
+ * @param sessions Ordered sessions for the mesocycle.
57
+ * @param sessionExerciseMap Map of session exercise ID to WorkoutSessionExercise.
58
+ * @param setMap Map of set ID to WorkoutSet.
59
+ */
60
+ static getActiveAndNextSessions(
61
+ sessions: WorkoutSession[],
62
+ sessionExerciseMap: Map<UUID, WorkoutSessionExercise>,
63
+ setMap: Map<UUID, WorkoutSet>
64
+ ): { inProgressSession: WorkoutSession | null; nextUpSession: WorkoutSession | null } {
65
+ let inProgressSession: WorkoutSession | null = null;
66
+ let nextUpSession: WorkoutSession | null = null;
67
+
68
+ for (const session of sessions) {
69
+ if (session.complete) continue;
70
+
71
+ if (this.sessionHasLoggedSets(session, sessionExerciseMap, setMap)) {
72
+ if (!inProgressSession) inProgressSession = session;
73
+ } else {
74
+ if (!nextUpSession) nextUpSession = session;
75
+ }
76
+ if (inProgressSession && nextUpSession) break;
77
+ }
78
+
79
+ return { inProgressSession, nextUpSession };
80
+ }
81
+
82
+ /**
83
+ * Returns true if any set in the session has actualReps != null.
84
+ * Traverses session → sessionExercises → sets via order arrays and map lookups.
85
+ */
86
+ private static sessionHasLoggedSets(
87
+ session: WorkoutSession,
88
+ sessionExerciseMap: Map<UUID, WorkoutSessionExercise>,
89
+ setMap: Map<UUID, WorkoutSet>
90
+ ): boolean {
91
+ for (const seId of session.sessionExerciseOrder) {
92
+ const se = sessionExerciseMap.get(seId);
93
+ if (!se) continue;
94
+ for (const setId of se.setOrder) {
95
+ const set = setMap.get(setId);
96
+ if (set?.actualReps != null) return true;
97
+ }
98
+ }
99
+ return false;
100
+ }
101
+
46
102
  /**
47
103
  * Generates a session and its associated exercises and sets.
48
104
  */
@@ -61,7 +117,7 @@ export default class WorkoutSessionService {
61
117
  sessionIndex: number;
62
118
  sessionStartDate: Date;
63
119
  sessionExerciseList: CalibrationExercisePair[];
64
- targetRir: number;
120
+ targetRir: number | null;
65
121
  isDeloadMicrocycle: boolean;
66
122
  setPlan: { exerciseIdToSetCount: Map<UUID, number>; recoveryExerciseIds: Set<UUID> };
67
123
  }): void {
@@ -1,4 +1,5 @@
1
1
  import type { WorkoutSessionExercise } from '../../../documents/workout/WorkoutSessionExercise.js';
2
+ import type { WorkoutSet } from '../../../documents/workout/WorkoutSet.js';
2
3
  /**
3
4
  * A service for handling operations related to {@link WorkoutSessionExercise}s.
4
5
  */
@@ -41,5 +42,14 @@ export default class WorkoutSessionExerciseService {
41
42
  | **3** | Do not add sets | Do not add sets | Do not add sets | Employ recovery sessions (see Fatigue Management) |
42
43
  */
43
44
  static getRecommendedSetAdditionsOrRecovery(workoutSessionExercise: WorkoutSessionExercise): number | null;
45
+ /**
46
+ * Returns true if the exercise is a deload exercise (all sets have plannedRir == null).
47
+ */
48
+ static isDeloadExercise(exerciseSets: WorkoutSet[]): boolean;
49
+ /**
50
+ * Returns true if the session exercise needs review (complete session but missing late fields).
51
+ * Deload exercises never need review.
52
+ */
53
+ static needsReview(sessionExercise: WorkoutSessionExercise, exerciseSets: WorkoutSet[]): boolean;
44
54
  }
45
55
  //# sourceMappingURL=WorkoutSessionExerciseService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutSessionExerciseService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/SessionExercise/WorkoutSessionExerciseService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sDAAsD,CAAC;AAGnG;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,6BAA6B;IAChD;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,eAAe,EAAE,sBAAsB,GAAG,MAAM,GAAG,IAAI;IAI1E;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,eAAe,EAAE,sBAAsB,GAAG,MAAM,GAAG,IAAI;IAI9E;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,sBAAsB,GAAG,MAAM,GAAG,IAAI;IAIrE;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,oCAAoC,CACzC,sBAAsB,EAAE,sBAAsB,GAC7C,MAAM,GAAG,IAAI;CAqBjB"}
1
+ {"version":3,"file":"WorkoutSessionExerciseService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/SessionExercise/WorkoutSessionExerciseService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sDAAsD,CAAC;AACnG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAG3E;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,6BAA6B;IAChD;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,eAAe,EAAE,sBAAsB,GAAG,MAAM,GAAG,IAAI;IAI1E;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,eAAe,EAAE,sBAAsB,GAAG,MAAM,GAAG,IAAI;IAI9E;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,sBAAsB,GAAG,MAAM,GAAG,IAAI;IAIrE;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,oCAAoC,CACzC,sBAAsB,EAAE,sBAAsB,GAC7C,MAAM,GAAG,IAAI;IAsBhB;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,OAAO;IAI5D;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,eAAe,EAAE,sBAAsB,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,OAAO;CAQjG"}
@@ -65,5 +65,22 @@ export default class WorkoutSessionExerciseService {
65
65
  ];
66
66
  return table[sorenessScore]?.[performanceScore] ?? null;
67
67
  }
68
+ /**
69
+ * Returns true if the exercise is a deload exercise (all sets have plannedRir == null).
70
+ */
71
+ static isDeloadExercise(exerciseSets) {
72
+ return exerciseSets.length > 0 && exerciseSets.every((s) => s.plannedRir == null);
73
+ }
74
+ /**
75
+ * Returns true if the session exercise needs review (complete session but missing late fields).
76
+ * Deload exercises never need review.
77
+ */
78
+ static needsReview(sessionExercise, exerciseSets) {
79
+ if (WorkoutSessionExerciseService.isDeloadExercise(exerciseSets))
80
+ return false;
81
+ return (sessionExercise.rsm?.disruption == null ||
82
+ sessionExercise.fatigue?.unusedMusclePerformance == null ||
83
+ sessionExercise.sorenessScore == null);
84
+ }
68
85
  }
69
86
  //# sourceMappingURL=WorkoutSessionExerciseService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutSessionExerciseService.js","sourceRoot":"","sources":["../../../../src/services/workout/SessionExercise/WorkoutSessionExerciseService.ts"],"names":[],"mappings":"AACA,OAAO,iBAAiB,MAAM,kCAAkC,CAAC;AAEjE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,6BAA6B;IAChD;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,eAAuC;QACxD,OAAO,iBAAiB,CAAC,WAAW,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,eAAuC;QAC5D,OAAO,iBAAiB,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,eAAuC;QACnD,OAAO,iBAAiB,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAChF,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,oCAAoC,CACzC,sBAA8C;QAE9C,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,GAAG,sBAAsB,CAAC;QACnE,IAAI,aAAa,IAAI,IAAI,IAAI,gBAAgB,IAAI,IAAI,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,gEAAgE;QAChE,0FAA0F;QAC1F,MAAM,KAAK,GAAe;YACxB,uDAAuD;YACvD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACb,uDAAuD;YACvD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACb,6DAA6D;YAC7D,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACb,6DAA6D;YAC7D,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SACd,CAAC;QAEF,OAAO,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC;IAC1D,CAAC;CACF"}
1
+ {"version":3,"file":"WorkoutSessionExerciseService.js","sourceRoot":"","sources":["../../../../src/services/workout/SessionExercise/WorkoutSessionExerciseService.ts"],"names":[],"mappings":"AAEA,OAAO,iBAAiB,MAAM,kCAAkC,CAAC;AAEjE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,6BAA6B;IAChD;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,eAAuC;QACxD,OAAO,iBAAiB,CAAC,WAAW,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,eAAuC;QAC5D,OAAO,iBAAiB,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,eAAuC;QACnD,OAAO,iBAAiB,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAChF,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,oCAAoC,CACzC,sBAA8C;QAE9C,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,GAAG,sBAAsB,CAAC;QACnE,IAAI,aAAa,IAAI,IAAI,IAAI,gBAAgB,IAAI,IAAI,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,gEAAgE;QAChE,0FAA0F;QAC1F,MAAM,KAAK,GAAe;YACxB,uDAAuD;YACvD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACb,uDAAuD;YACvD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACb,6DAA6D;YAC7D,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACb,6DAA6D;YAC7D,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SACd,CAAC;QAEF,OAAO,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,YAA0B;QAChD,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC;IACpF,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,eAAuC,EAAE,YAA0B;QACpF,IAAI,6BAA6B,CAAC,gBAAgB,CAAC,YAAY,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/E,OAAO,CACL,eAAe,CAAC,GAAG,EAAE,UAAU,IAAI,IAAI;YACvC,eAAe,CAAC,OAAO,EAAE,uBAAuB,IAAI,IAAI;YACxD,eAAe,CAAC,aAAa,IAAI,IAAI,CACtC,CAAC;IACJ,CAAC;CACF"}
@@ -1,4 +1,5 @@
1
1
  import type { WorkoutSessionExercise } from '../../../documents/workout/WorkoutSessionExercise.js';
2
+ import type { WorkoutSet } from '../../../documents/workout/WorkoutSet.js';
2
3
  import WorkoutSFRService from '../util/SFR/WorkoutSFRService.js';
3
4
 
4
5
  /**
@@ -74,4 +75,24 @@ export default class WorkoutSessionExerciseService {
74
75
 
75
76
  return table[sorenessScore]?.[performanceScore] ?? null;
76
77
  }
78
+
79
+ /**
80
+ * Returns true if the exercise is a deload exercise (all sets have plannedRir == null).
81
+ */
82
+ static isDeloadExercise(exerciseSets: WorkoutSet[]): boolean {
83
+ return exerciseSets.length > 0 && exerciseSets.every((s) => s.plannedRir == null);
84
+ }
85
+
86
+ /**
87
+ * Returns true if the session exercise needs review (complete session but missing late fields).
88
+ * Deload exercises never need review.
89
+ */
90
+ static needsReview(sessionExercise: WorkoutSessionExercise, exerciseSets: WorkoutSet[]): boolean {
91
+ if (WorkoutSessionExerciseService.isDeloadExercise(exerciseSets)) return false;
92
+ return (
93
+ sessionExercise.rsm?.disruption == null ||
94
+ sessionExercise.fatigue?.unusedMusclePerformance == null ||
95
+ sessionExercise.sorenessScore == null
96
+ );
97
+ }
77
98
  }
@@ -2,6 +2,7 @@ import type { WorkoutExercise } from '../../../documents/workout/WorkoutExercise
2
2
  import type { WorkoutExerciseCalibration } from '../../../documents/workout/WorkoutExerciseCalibration.js';
3
3
  import type { WorkoutSession } from '../../../documents/workout/WorkoutSession.js';
4
4
  import type { WorkoutSessionExercise } from '../../../documents/workout/WorkoutSessionExercise.js';
5
+ import { type WorkoutSet } from '../../../documents/workout/WorkoutSet.js';
5
6
  import type WorkoutMesocyclePlanContext from '../Mesocycle/WorkoutMesocyclePlanContext.js';
6
7
  export default class WorkoutSetService {
7
8
  /**
@@ -21,9 +22,15 @@ export default class WorkoutSetService {
21
22
  microcycleIndex: number;
22
23
  sessionIndex: number;
23
24
  setCount: number;
24
- targetRir: number;
25
+ targetRir: number | null;
25
26
  isDeloadMicrocycle: boolean;
26
27
  }): void;
28
+ /**
29
+ * Returns true if the set has been logged (has actual performance data).
30
+ * A set is considered completed when actualReps and actualWeight are recorded,
31
+ * and either rir is recorded or no plannedRir was expected (deload sets).
32
+ */
33
+ static isCompleted(set: WorkoutSet): boolean;
27
34
  /**
28
35
  * Generates the planned reps and weight for a specific set within a session exercise, only
29
36
  * 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;AAInG,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,CAAC;QAClB,kBAAkB,EAAE,OAAO,CAAC;KAC7B,GAAG,IAAI;IAoDR;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAiDxC"}
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;IAoDR;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO;IAQ5C;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAiDxC"}
@@ -46,6 +46,16 @@ export default class WorkoutSetService {
46
46
  }
47
47
  context.setsToCreate.push(...sets);
48
48
  }
49
+ /**
50
+ * Returns true if the set has been logged (has actual performance data).
51
+ * A set is considered completed when actualReps and actualWeight are recorded,
52
+ * and either rir is recorded or no plannedRir was expected (deload sets).
53
+ */
54
+ static isCompleted(set) {
55
+ return (set.actualReps != null &&
56
+ set.actualWeight != null &&
57
+ (set.rir != null || set.plannedRir == null));
58
+ }
49
59
  /**
50
60
  * Generates the planned reps and weight for a specific set within a session exercise, only
51
61
  * 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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"}
@@ -40,7 +40,7 @@ export default class WorkoutSetService {
40
40
  microcycleIndex: number;
41
41
  sessionIndex: number;
42
42
  setCount: number;
43
- targetRir: number;
43
+ targetRir: number | null;
44
44
  isDeloadMicrocycle: boolean;
45
45
  }): void {
46
46
  const equipment = context.equipmentMap.get(exercise.workoutEquipmentTypeId);
@@ -94,6 +94,19 @@ export default class WorkoutSetService {
94
94
  context.setsToCreate.push(...sets);
95
95
  }
96
96
 
97
+ /**
98
+ * Returns true if the set has been logged (has actual performance data).
99
+ * A set is considered completed when actualReps and actualWeight are recorded,
100
+ * and either rir is recorded or no plannedRir was expected (deload sets).
101
+ */
102
+ static isCompleted(set: WorkoutSet): boolean {
103
+ return (
104
+ set.actualReps != null &&
105
+ set.actualWeight != null &&
106
+ (set.rir != null || set.plannedRir == null)
107
+ );
108
+ }
109
+
97
110
  /**
98
111
  * Generates the planned reps and weight for a specific set within a session exercise, only
99
112
  * taking into account simple -2 reps drop per set logic, and deload modifications.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@aneuhold/core-ts-db-lib",
3
3
  "author": "Anton G. Neuhold Jr.",
4
4
  "license": "MIT",
5
- "version": "4.1.2",
5
+ "version": "4.1.4",
6
6
  "description": "A core database library used for personal projects",
7
7
  "packageManager": "pnpm@10.25.0",
8
8
  "type": "module",