@aneuhold/core-ts-db-lib 4.1.8 → 4.1.10
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.
- package/CHANGELOG.md +27 -0
- package/lib/services/workout/Mesocycle/WorkoutMesocycleService.d.ts +48 -0
- package/lib/services/workout/Mesocycle/WorkoutMesocycleService.d.ts.map +1 -1
- package/lib/services/workout/Mesocycle/WorkoutMesocycleService.js +114 -4
- package/lib/services/workout/Mesocycle/WorkoutMesocycleService.js.map +1 -1
- package/lib/services/workout/Mesocycle/WorkoutMesocycleService.ts +147 -4
- package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.d.ts +14 -0
- package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.d.ts.map +1 -1
- package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.js +43 -0
- package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.js.map +1 -1
- package/lib/services/workout/SessionExercise/WorkoutSessionExerciseService.ts +50 -0
- package/lib/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.d.ts.map +1 -1
- package/lib/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.js +13 -2
- package/lib/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.js.map +1 -1
- package/lib/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.ts +16 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ 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.10] (2026-02-23)
|
|
9
|
+
|
|
10
|
+
### ✅ Added
|
|
11
|
+
|
|
12
|
+
- Added `WorkoutMesocycleService.getProjectedStartDate()` to return the projected start date for a mesocycle, falling back to the earliest microcycle start date when `startDate` is not set.
|
|
13
|
+
|
|
14
|
+
### 🏗️ Changed
|
|
15
|
+
|
|
16
|
+
- _Breaking Change:_ Renamed `WorkoutMesocycleService.calculateProjectedEndDate()` to `getProjectedEndDate()`.
|
|
17
|
+
- Updated `WorkoutMesocycleService.detectMesocycleOverlap()` to use `getProjectedStartDate()`, enabling overlap detection for future mesocycles that have no `startDate` but have associated microcycles.
|
|
18
|
+
- Deload microcycles in `WorkoutVolumePlanningService` now halve the previous microcycle's historical set counts (minimum 1) and skip SFR-based set additions entirely.
|
|
19
|
+
|
|
20
|
+
## 🔖 [4.1.9] (2026-02-22)
|
|
21
|
+
|
|
22
|
+
### ✅ Added
|
|
23
|
+
|
|
24
|
+
- Added `WorkoutMesocycleService.calculateProjectedEndDate()` to compute a mesocycle's projected end from its microcycles or planned parameters.
|
|
25
|
+
- Added `WorkoutMesocycleService.shiftMesocycleDates()` to shift all dates of a mesocycle and its child documents in place by a given number of days.
|
|
26
|
+
- Added `WorkoutMesocycleService.detectMesocycleOverlap()` to detect overlapping date ranges across a set of mesocycles.
|
|
27
|
+
- Added `WorkoutMesocycleService.getEarliestAllowedStartDate()` to determine the earliest valid start date for a new mesocycle based on existing ones.
|
|
28
|
+
|
|
29
|
+
### 🏗️ Changed
|
|
30
|
+
|
|
31
|
+
- Refactored internal date handling in `WorkoutMesocycleService` to use existing `Date` references directly instead of wrapping them in `new Date()`.
|
|
32
|
+
|
|
8
33
|
## 🔖 [4.1.8] (2026-02-22)
|
|
9
34
|
|
|
10
35
|
### 🏗️ Changed
|
|
@@ -287,6 +312,8 @@ Updated dependency: now requires `@aneuhold/core-ts-lib@^2.3.11`.
|
|
|
287
312
|
|
|
288
313
|
<!-- Link References -->
|
|
289
314
|
|
|
315
|
+
[4.1.10]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.9...core-ts-db-lib-v4.1.10
|
|
316
|
+
[4.1.9]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.8...core-ts-db-lib-v4.1.9
|
|
290
317
|
[4.1.8]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.7...core-ts-db-lib-v4.1.8
|
|
291
318
|
[4.1.7]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.6...core-ts-db-lib-v4.1.7
|
|
292
319
|
[4.1.6]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.5...core-ts-db-lib-v4.1.6
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UUID } from 'crypto';
|
|
1
2
|
import type { WorkoutEquipmentType } from '../../../documents/workout/WorkoutEquipmentType.js';
|
|
2
3
|
import type { WorkoutExercise } from '../../../documents/workout/WorkoutExercise.js';
|
|
3
4
|
import type { WorkoutExerciseCalibration } from '../../../documents/workout/WorkoutExerciseCalibration.js';
|
|
@@ -42,6 +43,53 @@ export default class WorkoutMesocycleService {
|
|
|
42
43
|
sessionExercises?: DocumentOperations<WorkoutSessionExercise>;
|
|
43
44
|
sets?: DocumentOperations<WorkoutSet>;
|
|
44
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* Returns the projected start date for a mesocycle. Uses
|
|
48
|
+
* `mesocycle.startDate` if set (active/completed), otherwise falls back to
|
|
49
|
+
* the earliest microcycle's start date (future/planned mesocycles).
|
|
50
|
+
*
|
|
51
|
+
* @param mesocycle The mesocycle to get the projected start date for.
|
|
52
|
+
* @param microcycles The microcycles belonging to this mesocycle (pre-filtered).
|
|
53
|
+
*/
|
|
54
|
+
static getProjectedStartDate(mesocycle: WorkoutMesocycle, microcycles: WorkoutMicrocycle[]): Date | null;
|
|
55
|
+
/**
|
|
56
|
+
* Returns the projected end date of a mesocycle based on its microcycles.
|
|
57
|
+
* If microcycles exist, uses the last microcycle's endDate. Otherwise,
|
|
58
|
+
* calculates from the mesocycle's start date and planned parameters.
|
|
59
|
+
*
|
|
60
|
+
* @param mesocycle The mesocycle to calculate the end date for.
|
|
61
|
+
* @param microcycles The microcycles belonging to this mesocycle (pre-filtered).
|
|
62
|
+
*/
|
|
63
|
+
static getProjectedEndDate(mesocycle: WorkoutMesocycle, microcycles: WorkoutMicrocycle[]): Date | null;
|
|
64
|
+
/**
|
|
65
|
+
* Shifts all dates in a mesocycle and its child documents by the given number of days.
|
|
66
|
+
* Mutates the passed-in objects in place.
|
|
67
|
+
*
|
|
68
|
+
* @param mesocycle The mesocycle to shift. Its startDate is mutated directly.
|
|
69
|
+
* @param microcycles The microcycles belonging to this mesocycle (pre-filtered). Mutated in place.
|
|
70
|
+
* @param sessions The sessions belonging to these microcycles (pre-filtered). Mutated in place.
|
|
71
|
+
* @param daysDelta The number of days to shift (positive = forward, negative = backward).
|
|
72
|
+
*/
|
|
73
|
+
static shiftMesocycleDates(mesocycle: WorkoutMesocycle, microcycles: WorkoutMicrocycle[], sessions: WorkoutSession[], daysDelta: number): void;
|
|
74
|
+
/**
|
|
75
|
+
* Detects whether any mesocycles in the provided list have overlapping date ranges.
|
|
76
|
+
* Two mesocycles overlap if their projected date ranges intersect.
|
|
77
|
+
*
|
|
78
|
+
* @param mesocycles The mesocycles to check.
|
|
79
|
+
* @param mesocycleToMicrocyclesMap A map from mesocycle ID to its microcycles.
|
|
80
|
+
*/
|
|
81
|
+
static detectMesocycleOverlap(mesocycles: WorkoutMesocycle[], mesocycleToMicrocyclesMap: Map<UUID, WorkoutMicrocycle[]>): {
|
|
82
|
+
hasOverlap: boolean;
|
|
83
|
+
overlappingPairs: Array<[UUID, UUID]>;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Returns the earliest allowed start date for a new mesocycle. This is the later
|
|
87
|
+
* of: the projected end of the last existing mesocycle, or today.
|
|
88
|
+
*
|
|
89
|
+
* @param existingMesocycles All existing mesocycles.
|
|
90
|
+
* @param mesocycleToMicrocyclesMap A map from mesocycle ID to its microcycles.
|
|
91
|
+
*/
|
|
92
|
+
static getEarliestAllowedStartDate(existingMesocycles: WorkoutMesocycle[], mesocycleToMicrocyclesMap: Map<UUID, WorkoutMicrocycle[]>): Date;
|
|
45
93
|
/**
|
|
46
94
|
* Cleans up incomplete microcycles and their associated documents.
|
|
47
95
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkoutMesocycleService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Mesocycle/WorkoutMesocycleService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WorkoutMesocycleService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Mesocycle/WorkoutMesocycleService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,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;;;;;;;OAOG;IACH,MAAM,CAAC,qBAAqB,CAC1B,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,iBAAiB,EAAE,GAC/B,IAAI,GAAG,IAAI;IAQd;;;;;;;OAOG;IACH,MAAM,CAAC,mBAAmB,CACxB,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,iBAAiB,EAAE,GAC/B,IAAI,GAAG,IAAI;IAiBd;;;;;;;;OAQG;IACH,MAAM,CAAC,mBAAmB,CACxB,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,iBAAiB,EAAE,EAChC,QAAQ,EAAE,cAAc,EAAE,EAC1B,SAAS,EAAE,MAAM,GAChB,IAAI;IAeP;;;;;;OAMG;IACH,MAAM,CAAC,sBAAsB,CAC3B,UAAU,EAAE,gBAAgB,EAAE,EAC9B,yBAAyB,EAAE,GAAG,CAAC,IAAI,EAAE,iBAAiB,EAAE,CAAC,GACxD;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;KAAE;IA8BjE;;;;;;OAMG;IACH,MAAM,CAAC,2BAA2B,CAChC,kBAAkB,EAAE,gBAAgB,EAAE,EACtC,yBAAyB,EAAE,GAAG,CAAC,IAAI,EAAE,iBAAiB,EAAE,CAAC,GACxD,IAAI;IAiBP;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;CA4F5C"}
|
|
@@ -57,12 +57,12 @@ export default class WorkoutMesocycleService {
|
|
|
57
57
|
const startMicrocycleIndex = context.microcyclesInOrder.length;
|
|
58
58
|
let currentDate;
|
|
59
59
|
if (startMicrocycleIndex === 0) {
|
|
60
|
-
currentDate = startDate
|
|
60
|
+
currentDate = startDate ?? new Date();
|
|
61
61
|
}
|
|
62
62
|
else {
|
|
63
63
|
// Continue from where the last existing microcycle ended
|
|
64
64
|
const lastExistingMicrocycle = context.microcyclesInOrder[startMicrocycleIndex - 1];
|
|
65
|
-
currentDate =
|
|
65
|
+
currentDate = lastExistingMicrocycle.endDate;
|
|
66
66
|
}
|
|
67
67
|
// Generate remaining microcycles
|
|
68
68
|
for (let microcycleIndex = startMicrocycleIndex; microcycleIndex < totalMicrocycles; microcycleIndex++) {
|
|
@@ -74,7 +74,7 @@ export default class WorkoutMesocycleService {
|
|
|
74
74
|
const microcycle = WorkoutMicrocycleSchema.parse({
|
|
75
75
|
userId: mesocycle.userId,
|
|
76
76
|
workoutMesocycleId: mesocycle._id,
|
|
77
|
-
startDate:
|
|
77
|
+
startDate: currentDate,
|
|
78
78
|
endDate: DateService.addDays(currentDate, mesocycle.plannedMicrocycleLengthInDays)
|
|
79
79
|
});
|
|
80
80
|
context.addMicrocycle(microcycle);
|
|
@@ -85,7 +85,7 @@ export default class WorkoutMesocycleService {
|
|
|
85
85
|
isDeloadMicrocycle
|
|
86
86
|
});
|
|
87
87
|
// Move to next microcycle
|
|
88
|
-
currentDate =
|
|
88
|
+
currentDate = microcycle.endDate;
|
|
89
89
|
}
|
|
90
90
|
return {
|
|
91
91
|
mesocycleUpdate: undefined,
|
|
@@ -107,6 +107,116 @@ export default class WorkoutMesocycleService {
|
|
|
107
107
|
sets: { create: context.setsToCreate, update: [], delete: cleanupResult.setsToDelete }
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Returns the projected start date for a mesocycle. Uses
|
|
112
|
+
* `mesocycle.startDate` if set (active/completed), otherwise falls back to
|
|
113
|
+
* the earliest microcycle's start date (future/planned mesocycles).
|
|
114
|
+
*
|
|
115
|
+
* @param mesocycle The mesocycle to get the projected start date for.
|
|
116
|
+
* @param microcycles The microcycles belonging to this mesocycle (pre-filtered).
|
|
117
|
+
*/
|
|
118
|
+
static getProjectedStartDate(mesocycle, microcycles) {
|
|
119
|
+
if (mesocycle.startDate != null) {
|
|
120
|
+
return mesocycle.startDate;
|
|
121
|
+
}
|
|
122
|
+
const sorted = [...microcycles].sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
|
|
123
|
+
return sorted.length > 0 ? sorted[0].startDate : null;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Returns the projected end date of a mesocycle based on its microcycles.
|
|
127
|
+
* If microcycles exist, uses the last microcycle's endDate. Otherwise,
|
|
128
|
+
* calculates from the mesocycle's start date and planned parameters.
|
|
129
|
+
*
|
|
130
|
+
* @param mesocycle The mesocycle to calculate the end date for.
|
|
131
|
+
* @param microcycles The microcycles belonging to this mesocycle (pre-filtered).
|
|
132
|
+
*/
|
|
133
|
+
static getProjectedEndDate(mesocycle, microcycles) {
|
|
134
|
+
const sorted = [...microcycles].sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
|
|
135
|
+
if (sorted.length > 0) {
|
|
136
|
+
return sorted[sorted.length - 1].endDate;
|
|
137
|
+
}
|
|
138
|
+
const startDate = this.getProjectedStartDate(mesocycle, microcycles);
|
|
139
|
+
if (startDate == null) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const totalMicrocycles = mesocycle.plannedMicrocycleCount ?? 6;
|
|
143
|
+
const totalDays = totalMicrocycles * mesocycle.plannedMicrocycleLengthInDays;
|
|
144
|
+
return DateService.addDays(startDate, totalDays);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Shifts all dates in a mesocycle and its child documents by the given number of days.
|
|
148
|
+
* Mutates the passed-in objects in place.
|
|
149
|
+
*
|
|
150
|
+
* @param mesocycle The mesocycle to shift. Its startDate is mutated directly.
|
|
151
|
+
* @param microcycles The microcycles belonging to this mesocycle (pre-filtered). Mutated in place.
|
|
152
|
+
* @param sessions The sessions belonging to these microcycles (pre-filtered). Mutated in place.
|
|
153
|
+
* @param daysDelta The number of days to shift (positive = forward, negative = backward).
|
|
154
|
+
*/
|
|
155
|
+
static shiftMesocycleDates(mesocycle, microcycles, sessions, daysDelta) {
|
|
156
|
+
if (mesocycle.startDate != null) {
|
|
157
|
+
mesocycle.startDate = DateService.addDays(mesocycle.startDate, daysDelta);
|
|
158
|
+
}
|
|
159
|
+
for (const microcycle of microcycles) {
|
|
160
|
+
microcycle.startDate = DateService.addDays(microcycle.startDate, daysDelta);
|
|
161
|
+
microcycle.endDate = DateService.addDays(microcycle.endDate, daysDelta);
|
|
162
|
+
}
|
|
163
|
+
for (const session of sessions) {
|
|
164
|
+
session.startTime = DateService.addDays(session.startTime, daysDelta);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Detects whether any mesocycles in the provided list have overlapping date ranges.
|
|
169
|
+
* Two mesocycles overlap if their projected date ranges intersect.
|
|
170
|
+
*
|
|
171
|
+
* @param mesocycles The mesocycles to check.
|
|
172
|
+
* @param mesocycleToMicrocyclesMap A map from mesocycle ID to its microcycles.
|
|
173
|
+
*/
|
|
174
|
+
static detectMesocycleOverlap(mesocycles, mesocycleToMicrocyclesMap) {
|
|
175
|
+
const overlappingPairs = [];
|
|
176
|
+
const ranges = [];
|
|
177
|
+
for (const mesocycle of mesocycles) {
|
|
178
|
+
const microcycles = mesocycleToMicrocyclesMap.get(mesocycle._id) ?? [];
|
|
179
|
+
const start = this.getProjectedStartDate(mesocycle, microcycles);
|
|
180
|
+
if (start == null) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const end = this.getProjectedEndDate(mesocycle, microcycles);
|
|
184
|
+
if (end == null) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
ranges.push({ id: mesocycle._id, start, end });
|
|
188
|
+
}
|
|
189
|
+
ranges.sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
190
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
191
|
+
for (let j = i + 1; j < ranges.length; j++) {
|
|
192
|
+
if (ranges[j].start.getTime() < ranges[i].end.getTime()) {
|
|
193
|
+
overlappingPairs.push([ranges[i].id, ranges[j].id]);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return { hasOverlap: overlappingPairs.length > 0, overlappingPairs };
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Returns the earliest allowed start date for a new mesocycle. This is the later
|
|
201
|
+
* of: the projected end of the last existing mesocycle, or today.
|
|
202
|
+
*
|
|
203
|
+
* @param existingMesocycles All existing mesocycles.
|
|
204
|
+
* @param mesocycleToMicrocyclesMap A map from mesocycle ID to its microcycles.
|
|
205
|
+
*/
|
|
206
|
+
static getEarliestAllowedStartDate(existingMesocycles, mesocycleToMicrocyclesMap) {
|
|
207
|
+
let latestEnd = new Date();
|
|
208
|
+
for (const mesocycle of existingMesocycles) {
|
|
209
|
+
if (mesocycle.completedDate != null) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const microcycles = mesocycleToMicrocyclesMap.get(mesocycle._id) ?? [];
|
|
213
|
+
const projectedEnd = this.getProjectedEndDate(mesocycle, microcycles);
|
|
214
|
+
if (projectedEnd != null && projectedEnd.getTime() > latestEnd.getTime()) {
|
|
215
|
+
latestEnd = projectedEnd;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return latestEnd;
|
|
219
|
+
}
|
|
110
220
|
/**
|
|
111
221
|
* Cleans up incomplete microcycles and their associated documents.
|
|
112
222
|
*
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
1
|
+
{"version":3,"file":"WorkoutMesocycleService.js","sourceRoot":"","sources":["../../../../src/services/workout/Mesocycle/WorkoutMesocycleService.ts"],"names":[],"mappings":"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"}
|
|
@@ -117,11 +117,11 @@ export default class WorkoutMesocycleService {
|
|
|
117
117
|
let currentDate: Date;
|
|
118
118
|
|
|
119
119
|
if (startMicrocycleIndex === 0) {
|
|
120
|
-
currentDate = startDate
|
|
120
|
+
currentDate = startDate ?? new Date();
|
|
121
121
|
} else {
|
|
122
122
|
// Continue from where the last existing microcycle ended
|
|
123
123
|
const lastExistingMicrocycle = context.microcyclesInOrder[startMicrocycleIndex - 1];
|
|
124
|
-
currentDate =
|
|
124
|
+
currentDate = lastExistingMicrocycle.endDate;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
// Generate remaining microcycles
|
|
@@ -140,7 +140,7 @@ export default class WorkoutMesocycleService {
|
|
|
140
140
|
const microcycle = WorkoutMicrocycleSchema.parse({
|
|
141
141
|
userId: mesocycle.userId,
|
|
142
142
|
workoutMesocycleId: mesocycle._id,
|
|
143
|
-
startDate:
|
|
143
|
+
startDate: currentDate,
|
|
144
144
|
endDate: DateService.addDays(currentDate, mesocycle.plannedMicrocycleLengthInDays)
|
|
145
145
|
});
|
|
146
146
|
context.addMicrocycle(microcycle);
|
|
@@ -153,7 +153,7 @@ export default class WorkoutMesocycleService {
|
|
|
153
153
|
});
|
|
154
154
|
|
|
155
155
|
// Move to next microcycle
|
|
156
|
-
currentDate =
|
|
156
|
+
currentDate = microcycle.endDate;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
return {
|
|
@@ -177,6 +177,149 @@ export default class WorkoutMesocycleService {
|
|
|
177
177
|
};
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Returns the projected start date for a mesocycle. Uses
|
|
182
|
+
* `mesocycle.startDate` if set (active/completed), otherwise falls back to
|
|
183
|
+
* the earliest microcycle's start date (future/planned mesocycles).
|
|
184
|
+
*
|
|
185
|
+
* @param mesocycle The mesocycle to get the projected start date for.
|
|
186
|
+
* @param microcycles The microcycles belonging to this mesocycle (pre-filtered).
|
|
187
|
+
*/
|
|
188
|
+
static getProjectedStartDate(
|
|
189
|
+
mesocycle: WorkoutMesocycle,
|
|
190
|
+
microcycles: WorkoutMicrocycle[]
|
|
191
|
+
): Date | null {
|
|
192
|
+
if (mesocycle.startDate != null) {
|
|
193
|
+
return mesocycle.startDate;
|
|
194
|
+
}
|
|
195
|
+
const sorted = [...microcycles].sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
|
|
196
|
+
return sorted.length > 0 ? sorted[0].startDate : null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Returns the projected end date of a mesocycle based on its microcycles.
|
|
201
|
+
* If microcycles exist, uses the last microcycle's endDate. Otherwise,
|
|
202
|
+
* calculates from the mesocycle's start date and planned parameters.
|
|
203
|
+
*
|
|
204
|
+
* @param mesocycle The mesocycle to calculate the end date for.
|
|
205
|
+
* @param microcycles The microcycles belonging to this mesocycle (pre-filtered).
|
|
206
|
+
*/
|
|
207
|
+
static getProjectedEndDate(
|
|
208
|
+
mesocycle: WorkoutMesocycle,
|
|
209
|
+
microcycles: WorkoutMicrocycle[]
|
|
210
|
+
): Date | null {
|
|
211
|
+
const sorted = [...microcycles].sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
|
|
212
|
+
|
|
213
|
+
if (sorted.length > 0) {
|
|
214
|
+
return sorted[sorted.length - 1].endDate;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const startDate = this.getProjectedStartDate(mesocycle, microcycles);
|
|
218
|
+
if (startDate == null) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const totalMicrocycles = mesocycle.plannedMicrocycleCount ?? 6;
|
|
223
|
+
const totalDays = totalMicrocycles * mesocycle.plannedMicrocycleLengthInDays;
|
|
224
|
+
return DateService.addDays(startDate, totalDays);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Shifts all dates in a mesocycle and its child documents by the given number of days.
|
|
229
|
+
* Mutates the passed-in objects in place.
|
|
230
|
+
*
|
|
231
|
+
* @param mesocycle The mesocycle to shift. Its startDate is mutated directly.
|
|
232
|
+
* @param microcycles The microcycles belonging to this mesocycle (pre-filtered). Mutated in place.
|
|
233
|
+
* @param sessions The sessions belonging to these microcycles (pre-filtered). Mutated in place.
|
|
234
|
+
* @param daysDelta The number of days to shift (positive = forward, negative = backward).
|
|
235
|
+
*/
|
|
236
|
+
static shiftMesocycleDates(
|
|
237
|
+
mesocycle: WorkoutMesocycle,
|
|
238
|
+
microcycles: WorkoutMicrocycle[],
|
|
239
|
+
sessions: WorkoutSession[],
|
|
240
|
+
daysDelta: number
|
|
241
|
+
): void {
|
|
242
|
+
if (mesocycle.startDate != null) {
|
|
243
|
+
mesocycle.startDate = DateService.addDays(mesocycle.startDate, daysDelta);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
for (const microcycle of microcycles) {
|
|
247
|
+
microcycle.startDate = DateService.addDays(microcycle.startDate, daysDelta);
|
|
248
|
+
microcycle.endDate = DateService.addDays(microcycle.endDate, daysDelta);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
for (const session of sessions) {
|
|
252
|
+
session.startTime = DateService.addDays(session.startTime, daysDelta);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Detects whether any mesocycles in the provided list have overlapping date ranges.
|
|
258
|
+
* Two mesocycles overlap if their projected date ranges intersect.
|
|
259
|
+
*
|
|
260
|
+
* @param mesocycles The mesocycles to check.
|
|
261
|
+
* @param mesocycleToMicrocyclesMap A map from mesocycle ID to its microcycles.
|
|
262
|
+
*/
|
|
263
|
+
static detectMesocycleOverlap(
|
|
264
|
+
mesocycles: WorkoutMesocycle[],
|
|
265
|
+
mesocycleToMicrocyclesMap: Map<UUID, WorkoutMicrocycle[]>
|
|
266
|
+
): { hasOverlap: boolean; overlappingPairs: Array<[UUID, UUID]> } {
|
|
267
|
+
const overlappingPairs: Array<[UUID, UUID]> = [];
|
|
268
|
+
|
|
269
|
+
const ranges: Array<{ id: UUID; start: Date; end: Date }> = [];
|
|
270
|
+
for (const mesocycle of mesocycles) {
|
|
271
|
+
const microcycles = mesocycleToMicrocyclesMap.get(mesocycle._id) ?? [];
|
|
272
|
+
const start = this.getProjectedStartDate(mesocycle, microcycles);
|
|
273
|
+
if (start == null) {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
const end = this.getProjectedEndDate(mesocycle, microcycles);
|
|
277
|
+
if (end == null) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
ranges.push({ id: mesocycle._id, start, end });
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
ranges.sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
284
|
+
|
|
285
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
286
|
+
for (let j = i + 1; j < ranges.length; j++) {
|
|
287
|
+
if (ranges[j].start.getTime() < ranges[i].end.getTime()) {
|
|
288
|
+
overlappingPairs.push([ranges[i].id, ranges[j].id]);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return { hasOverlap: overlappingPairs.length > 0, overlappingPairs };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Returns the earliest allowed start date for a new mesocycle. This is the later
|
|
298
|
+
* of: the projected end of the last existing mesocycle, or today.
|
|
299
|
+
*
|
|
300
|
+
* @param existingMesocycles All existing mesocycles.
|
|
301
|
+
* @param mesocycleToMicrocyclesMap A map from mesocycle ID to its microcycles.
|
|
302
|
+
*/
|
|
303
|
+
static getEarliestAllowedStartDate(
|
|
304
|
+
existingMesocycles: WorkoutMesocycle[],
|
|
305
|
+
mesocycleToMicrocyclesMap: Map<UUID, WorkoutMicrocycle[]>
|
|
306
|
+
): Date {
|
|
307
|
+
let latestEnd = new Date();
|
|
308
|
+
|
|
309
|
+
for (const mesocycle of existingMesocycles) {
|
|
310
|
+
if (mesocycle.completedDate != null) {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const microcycles = mesocycleToMicrocyclesMap.get(mesocycle._id) ?? [];
|
|
314
|
+
const projectedEnd = this.getProjectedEndDate(mesocycle, microcycles);
|
|
315
|
+
if (projectedEnd != null && projectedEnd.getTime() > latestEnd.getTime()) {
|
|
316
|
+
latestEnd = projectedEnd;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return latestEnd;
|
|
321
|
+
}
|
|
322
|
+
|
|
180
323
|
/**
|
|
181
324
|
* Cleans up incomplete microcycles and their associated documents.
|
|
182
325
|
*
|
|
@@ -22,6 +22,20 @@ export default class WorkoutSessionExerciseService {
|
|
|
22
22
|
* @param sessionExercise The workout session exercise.
|
|
23
23
|
*/
|
|
24
24
|
static getSFR(sessionExercise: WorkoutSessionExercise): number | null;
|
|
25
|
+
/**
|
|
26
|
+
* Calculates the performance score (0-3) for an exercise based on its sets.
|
|
27
|
+
*
|
|
28
|
+
* For each set with complete data, a surplus is computed as
|
|
29
|
+
* `(actualReps - plannedReps) + (rir - plannedRir)`. The per-set score is:
|
|
30
|
+
* - 0: surplus >= 2 (exceeded expectations)
|
|
31
|
+
* - 1: surplus 0-1 (on target)
|
|
32
|
+
* - 2: surplus < 0 but hit target reps (declining)
|
|
33
|
+
* - 3: did not hit target reps
|
|
34
|
+
*
|
|
35
|
+
* The exercise score is the rounded average of all per-set scores. Returns
|
|
36
|
+
* `null` if no sets have complete planned and actual data.
|
|
37
|
+
*/
|
|
38
|
+
static getPerformanceScore(sets: WorkoutSet[]): number | null;
|
|
25
39
|
/**
|
|
26
40
|
* Uses the soreness/performance table from the workout model notes to recommend whether to add
|
|
27
41
|
* sets next microcycle or employ recovery sessions.
|
|
@@ -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;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;;;;;OAKG;IACH,MAAM,CAAC,0BAA0B,CAC/B,eAAe,EAAE,sBAAsB,EACvC,YAAY,EAAE,UAAU,EAAE,GACzB,OAAO;IAWV;;;;OAIG;IACH,MAAM,CAAC,0BAA0B,CAC/B,eAAe,EAAE,sBAAsB,EACvC,YAAY,EAAE,UAAU,EAAE,GACzB,OAAO;CAWX"}
|
|
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;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,IAAI;IAqC7D;;;;;;;;;;;;;;;;;;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;;;;;OAKG;IACH,MAAM,CAAC,0BAA0B,CAC/B,eAAe,EAAE,sBAAsB,EACvC,YAAY,EAAE,UAAU,EAAE,GACzB,OAAO;IAWV;;;;OAIG;IACH,MAAM,CAAC,0BAA0B,CAC/B,eAAe,EAAE,sBAAsB,EACvC,YAAY,EAAE,UAAU,EAAE,GACzB,OAAO;CAWX"}
|
|
@@ -27,6 +27,49 @@ export default class WorkoutSessionExerciseService {
|
|
|
27
27
|
static getSFR(sessionExercise) {
|
|
28
28
|
return WorkoutSFRService.getSFR(sessionExercise.rsm, sessionExercise.fatigue);
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Calculates the performance score (0-3) for an exercise based on its sets.
|
|
32
|
+
*
|
|
33
|
+
* For each set with complete data, a surplus is computed as
|
|
34
|
+
* `(actualReps - plannedReps) + (rir - plannedRir)`. The per-set score is:
|
|
35
|
+
* - 0: surplus >= 2 (exceeded expectations)
|
|
36
|
+
* - 1: surplus 0-1 (on target)
|
|
37
|
+
* - 2: surplus < 0 but hit target reps (declining)
|
|
38
|
+
* - 3: did not hit target reps
|
|
39
|
+
*
|
|
40
|
+
* The exercise score is the rounded average of all per-set scores. Returns
|
|
41
|
+
* `null` if no sets have complete planned and actual data.
|
|
42
|
+
*/
|
|
43
|
+
static getPerformanceScore(sets) {
|
|
44
|
+
const setScores = [];
|
|
45
|
+
for (const set of sets) {
|
|
46
|
+
if (set.plannedReps == null ||
|
|
47
|
+
set.plannedRir == null ||
|
|
48
|
+
set.actualReps == null ||
|
|
49
|
+
set.rir == null) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (set.actualReps < set.plannedReps) {
|
|
53
|
+
setScores.push(3);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const surplus = set.actualReps - set.plannedReps + (set.rir - set.plannedRir);
|
|
57
|
+
if (surplus >= 2) {
|
|
58
|
+
setScores.push(0);
|
|
59
|
+
}
|
|
60
|
+
else if (surplus >= 0) {
|
|
61
|
+
setScores.push(1);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
setScores.push(2);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (setScores.length === 0) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const average = setScores.reduce((sum, score) => sum + score, 0) / setScores.length;
|
|
71
|
+
return Math.round(average);
|
|
72
|
+
}
|
|
30
73
|
/**
|
|
31
74
|
* Uses the soreness/performance table from the workout model notes to recommend whether to add
|
|
32
75
|
* sets next microcycle or employ recovery sessions.
|
|
@@ -1 +1 @@
|
|
|
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;;;;;OAKG;IACH,MAAM,CAAC,0BAA0B,CAC/B,eAAuC,EACvC,YAA0B;QAE1B,IAAI,6BAA6B,CAAC,gBAAgB,CAAC,YAAY,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9E,OAAO,CACL,eAAe,CAAC,GAAG,EAAE,oBAAoB,IAAI,IAAI;YACjD,eAAe,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI;YAChC,eAAe,CAAC,OAAO,EAAE,uBAAuB,IAAI,IAAI;YACxD,eAAe,CAAC,OAAO,CAAC,eAAe,IAAI,IAAI;YAC/C,eAAe,CAAC,gBAAgB,IAAI,IAAI,CACzC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,0BAA0B,CAC/B,eAAuC,EACvC,YAA0B;QAE1B,IAAI,CAAC,6BAA6B,CAAC,0BAA0B,CAAC,eAAe,EAAE,YAAY,CAAC,EAAE,CAAC;YAC7F,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,6BAA6B,CAAC,gBAAgB,CAAC,YAAY,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9E,OAAO,CACL,eAAe,CAAC,GAAG,EAAE,UAAU,IAAI,IAAI;YACvC,eAAe,CAAC,OAAO,EAAE,wBAAwB,IAAI,IAAI;YACzD,eAAe,CAAC,aAAa,IAAI,IAAI,CACtC,CAAC;IACJ,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"WorkoutSessionExerciseService.js","sourceRoot":"","sources":["../../../../src/services/workout/SessionExercise/WorkoutSessionExerciseService.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,56 @@ export default class WorkoutSessionExerciseService {
|
|
|
33
33
|
return WorkoutSFRService.getSFR(sessionExercise.rsm, sessionExercise.fatigue);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Calculates the performance score (0-3) for an exercise based on its sets.
|
|
38
|
+
*
|
|
39
|
+
* For each set with complete data, a surplus is computed as
|
|
40
|
+
* `(actualReps - plannedReps) + (rir - plannedRir)`. The per-set score is:
|
|
41
|
+
* - 0: surplus >= 2 (exceeded expectations)
|
|
42
|
+
* - 1: surplus 0-1 (on target)
|
|
43
|
+
* - 2: surplus < 0 but hit target reps (declining)
|
|
44
|
+
* - 3: did not hit target reps
|
|
45
|
+
*
|
|
46
|
+
* The exercise score is the rounded average of all per-set scores. Returns
|
|
47
|
+
* `null` if no sets have complete planned and actual data.
|
|
48
|
+
*/
|
|
49
|
+
static getPerformanceScore(sets: WorkoutSet[]): number | null {
|
|
50
|
+
const setScores: number[] = [];
|
|
51
|
+
|
|
52
|
+
for (const set of sets) {
|
|
53
|
+
if (
|
|
54
|
+
set.plannedReps == null ||
|
|
55
|
+
set.plannedRir == null ||
|
|
56
|
+
set.actualReps == null ||
|
|
57
|
+
set.rir == null
|
|
58
|
+
) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (set.actualReps < set.plannedReps) {
|
|
63
|
+
setScores.push(3);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const surplus = set.actualReps - set.plannedReps + (set.rir - set.plannedRir);
|
|
68
|
+
|
|
69
|
+
if (surplus >= 2) {
|
|
70
|
+
setScores.push(0);
|
|
71
|
+
} else if (surplus >= 0) {
|
|
72
|
+
setScores.push(1);
|
|
73
|
+
} else {
|
|
74
|
+
setScores.push(2);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (setScores.length === 0) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const average = setScores.reduce((sum, score) => sum + score, 0) / setScores.length;
|
|
83
|
+
return Math.round(average);
|
|
84
|
+
}
|
|
85
|
+
|
|
36
86
|
/**
|
|
37
87
|
* Uses the soreness/performance table from the workout model notes to recommend whether to add
|
|
38
88
|
* sets next microcycle or employ recovery sessions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkoutVolumePlanningService.d.ts","sourceRoot":"","sources":["../../../../../src/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC,OAAO,KAAK,2BAA2B,MAAM,gDAAgD,CAAC;AAG9F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,4BAA4B;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAK;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qCAAqC,CAAM;IAEnE;;OAEG;IACH,MAAM,CAAC,6BAA6B,CAClC,OAAO,EAAE,2BAA2B,EACpC,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,OAAO,GAC1B;QAAE,oBAAoB,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;KAAE;IA4B9E;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,6CAA6C;
|
|
1
|
+
{"version":3,"file":"WorkoutVolumePlanningService.d.ts","sourceRoot":"","sources":["../../../../../src/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC,OAAO,KAAK,2BAA2B,MAAM,gDAAgD,CAAC;AAG9F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,4BAA4B;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAK;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qCAAqC,CAAM;IAEnE;;OAEG;IACH,MAAM,CAAC,6BAA6B,CAClC,OAAO,EAAE,2BAA2B,EACpC,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,OAAO,GAC1B;QAAE,oBAAoB,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;KAAE;IA4B9E;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,6CAA6C;IAoP5D;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,yBAAyB;CA6BzC"}
|
|
@@ -109,13 +109,24 @@ export default class WorkoutVolumePlanningService {
|
|
|
109
109
|
}
|
|
110
110
|
if (exerciseIdToPrevSessionExercise.size === 0)
|
|
111
111
|
return { exerciseIdToSetCount, recoveryExerciseIds };
|
|
112
|
-
// Update baseline with historical set counts when available
|
|
112
|
+
// Update baseline with historical set counts when available.
|
|
113
|
+
// For deload microcycles, halve the historical count (minimum 1 set). We don't use baseline
|
|
114
|
+
// because the user may have adjusted over the mesocycle in a way that the baseline is actually
|
|
115
|
+
// a higher set count than what would be calculated by halving the previous microcycle's sets.
|
|
113
116
|
muscleGroupExercisePairs.forEach((pair) => {
|
|
114
117
|
const previousSessionExercise = exerciseIdToPrevSessionExercise.get(pair.exercise._id);
|
|
115
118
|
if (previousSessionExercise) {
|
|
116
|
-
|
|
119
|
+
let setCount = Math.min(previousSessionExercise.setOrder.length, this.MAX_SETS_PER_EXERCISE);
|
|
120
|
+
if (isDeloadMicrocycle) {
|
|
121
|
+
setCount = Math.max(1, Math.floor(setCount / 2));
|
|
122
|
+
}
|
|
123
|
+
exerciseIdToSetCount.set(pair.exercise._id, setCount);
|
|
117
124
|
}
|
|
118
125
|
});
|
|
126
|
+
// Deload microcycles use reduced volume — skip SFR-based set additions
|
|
127
|
+
if (isDeloadMicrocycle) {
|
|
128
|
+
return { exerciseIdToSetCount, recoveryExerciseIds };
|
|
129
|
+
}
|
|
119
130
|
/**
|
|
120
131
|
* Determines if the session for the given exercise is already capped for this muscle group.
|
|
121
132
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkoutVolumePlanningService.js","sourceRoot":"","sources":["../../../../../src/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"WorkoutVolumePlanningService.js","sourceRoot":"","sources":["../../../../../src/services/workout/util/VolumePlanning/WorkoutVolumePlanningService.ts"],"names":[],"mappings":"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"}
|
|
@@ -146,17 +146,29 @@ export default class WorkoutVolumePlanningService {
|
|
|
146
146
|
if (exerciseIdToPrevSessionExercise.size === 0)
|
|
147
147
|
return { exerciseIdToSetCount, recoveryExerciseIds };
|
|
148
148
|
|
|
149
|
-
// Update baseline with historical set counts when available
|
|
149
|
+
// Update baseline with historical set counts when available.
|
|
150
|
+
// For deload microcycles, halve the historical count (minimum 1 set). We don't use baseline
|
|
151
|
+
// because the user may have adjusted over the mesocycle in a way that the baseline is actually
|
|
152
|
+
// a higher set count than what would be calculated by halving the previous microcycle's sets.
|
|
150
153
|
muscleGroupExercisePairs.forEach((pair) => {
|
|
151
154
|
const previousSessionExercise = exerciseIdToPrevSessionExercise.get(pair.exercise._id);
|
|
152
155
|
if (previousSessionExercise) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
+
let setCount = Math.min(
|
|
157
|
+
previousSessionExercise.setOrder.length,
|
|
158
|
+
this.MAX_SETS_PER_EXERCISE
|
|
156
159
|
);
|
|
160
|
+
if (isDeloadMicrocycle) {
|
|
161
|
+
setCount = Math.max(1, Math.floor(setCount / 2));
|
|
162
|
+
}
|
|
163
|
+
exerciseIdToSetCount.set(pair.exercise._id, setCount);
|
|
157
164
|
}
|
|
158
165
|
});
|
|
159
166
|
|
|
167
|
+
// Deload microcycles use reduced volume — skip SFR-based set additions
|
|
168
|
+
if (isDeloadMicrocycle) {
|
|
169
|
+
return { exerciseIdToSetCount, recoveryExerciseIds };
|
|
170
|
+
}
|
|
171
|
+
|
|
160
172
|
/**
|
|
161
173
|
* Determines if the session for the given exercise is already capped for this muscle group.
|
|
162
174
|
*/
|
package/package.json
CHANGED