@dgpholdings/greatoak-shared 1.2.53 → 1.2.55
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/dist/__mocks__/exercises.mock.d.ts +35 -0
- package/dist/__mocks__/exercises.mock.js +144 -0
- package/dist/__mocks__/templateExercises.mock.d.ts +90 -0
- package/dist/__mocks__/templateExercises.mock.js +258 -0
- package/dist/__mocks__/user.mock.d.ts +2 -0
- package/dist/__mocks__/user.mock.js +36 -0
- package/dist/types/TApiUser.d.ts +3 -1
- package/dist/utils/exerciseRecord/__mocks__/exercises.mock.d.ts +30 -0
- package/dist/utils/exerciseRecord/__mocks__/exercises.mock.js +138 -0
- package/dist/utils/exerciseRecord/recordValidator.d.ts +12 -0
- package/dist/utils/exerciseRecord/recordValidator.integration.test.d.ts +1 -0
- package/dist/utils/exerciseRecord/recordValidator.integration.test.js +51 -0
- package/dist/utils/exerciseRecord/recordValidator.js +85 -0
- package/dist/utils/exerciseRecord/recordValidator.test.d.ts +1 -0
- package/dist/utils/exerciseRecord/recordValidator.test.js +165 -0
- package/dist/utils/exerciseRecord/workoutMath.d.ts +28 -0
- package/dist/utils/exerciseRecord/workoutMath.js +116 -0
- package/dist/utils/exerciseRecord/workoutMath.test.d.ts +1 -0
- package/dist/utils/exerciseRecord/workoutMath.test.js +238 -0
- package/dist/utils/index.d.ts +3 -1
- package/dist/utils/index.js +5 -3
- package/dist/utils/scoringWorkout/calculateCalories.d.ts +67 -0
- package/dist/utils/scoringWorkout/calculateCalories.js +351 -0
- package/dist/utils/scoringWorkout/calculateMuscleFatiue.d.ts +67 -0
- package/dist/utils/scoringWorkout/calculateMuscleFatiue.js +330 -0
- package/dist/utils/scoringWorkout/calculateQualityScore.d.ts +73 -0
- package/dist/utils/scoringWorkout/calculateQualityScore.js +357 -0
- package/dist/utils/scoringWorkout/calculateTotalVolume.d.ts +15 -0
- package/dist/utils/scoringWorkout/calculateTotalVolume.js +73 -0
- package/dist/utils/scoringWorkout/constants.d.ts +211 -0
- package/dist/utils/scoringWorkout/constants.js +247 -0
- package/dist/utils/scoringWorkout/helpers.d.ts +127 -0
- package/dist/utils/scoringWorkout/helpers.js +245 -0
- package/dist/utils/scoringWorkout/index.d.ts +27 -0
- package/dist/utils/scoringWorkout/index.js +56 -0
- package/dist/utils/scoringWorkout/parseRecords.d.ts +68 -0
- package/dist/utils/scoringWorkout/parseRecords.js +281 -0
- package/dist/utils/scoringWorkout/scoringWorkout.integration.test.d.ts +1 -0
- package/dist/utils/scoringWorkout/scoringWorkout.integration.test.js +439 -0
- package/dist/utils/scoringWorkout/types.d.ts +104 -0
- package/dist/utils/scoringWorkout/types.js +11 -0
- package/package.json +6 -3
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { TExercise } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* MOCK EXERCISE: Weight-Reps
|
|
4
|
+
* Simulates a standard compound lift (e.g., Barbell Squat).
|
|
5
|
+
*/
|
|
6
|
+
export declare const mockExerciseWeightReps: TExercise;
|
|
7
|
+
/**
|
|
8
|
+
* MOCK EXERCISE: Reps-Only
|
|
9
|
+
* Simulates a bodyweight movement (e.g., Push-up).
|
|
10
|
+
*/
|
|
11
|
+
export declare const mockExerciseRepsOnly: TExercise;
|
|
12
|
+
/**
|
|
13
|
+
* MOCK EXERCISE: Duration
|
|
14
|
+
* Simulates an isometric hold (e.g., Plank).
|
|
15
|
+
*/
|
|
16
|
+
export declare const mockExerciseDuration: TExercise;
|
|
17
|
+
/**
|
|
18
|
+
* MOCK EXERCISE: Cardio-Machine
|
|
19
|
+
* Simulates a machine cardio session (e.g., Treadmill).
|
|
20
|
+
*/
|
|
21
|
+
export declare const mockExerciseCardioMachine: TExercise;
|
|
22
|
+
/**
|
|
23
|
+
* MOCK EXERCISE: Cardio-Free
|
|
24
|
+
* Simulates an outdoor/untracked cardio session (e.g., Outdoor Run).
|
|
25
|
+
*/
|
|
26
|
+
export declare const mockExerciseCardioFree: TExercise;
|
|
27
|
+
/**
|
|
28
|
+
* MOCK EXERCISE: No Guardrails
|
|
29
|
+
* Simulates an older DB entry or custom exercise missing guardrails.
|
|
30
|
+
*/
|
|
31
|
+
export declare const mockExerciseNoGuardrails: TExercise;
|
|
32
|
+
/**
|
|
33
|
+
* Helper dictionary containing all mock exercises mapped by their ID.
|
|
34
|
+
*/
|
|
35
|
+
export declare const mockExercisesDictionary: Record<string, TExercise>;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mockExercisesDictionary = exports.mockExerciseNoGuardrails = exports.mockExerciseCardioFree = exports.mockExerciseCardioMachine = exports.mockExerciseDuration = exports.mockExerciseRepsOnly = exports.mockExerciseWeightReps = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* MOCK EXERCISE: Weight-Reps
|
|
6
|
+
* Simulates a standard compound lift (e.g., Barbell Squat).
|
|
7
|
+
*/
|
|
8
|
+
exports.mockExerciseWeightReps = {
|
|
9
|
+
exerciseId: "mock-exercise-weight-reps-123",
|
|
10
|
+
name: "Generic Barbell Squat",
|
|
11
|
+
bodyPart: ["Legs"],
|
|
12
|
+
recordType: "weight-reps",
|
|
13
|
+
primaryMuscles: ["quadriceps"],
|
|
14
|
+
secondaryMuscles: ["glutes-maximus"],
|
|
15
|
+
trainingTypes: ["weight"],
|
|
16
|
+
difficultyLevel: 2,
|
|
17
|
+
hypertrophyLevel: 4,
|
|
18
|
+
strengthGainLevel: 4,
|
|
19
|
+
flexibilityLevel: 1,
|
|
20
|
+
calorieBurnLevel: 3,
|
|
21
|
+
stabilityLevel: 2,
|
|
22
|
+
enduranceLevel: 1,
|
|
23
|
+
metabolicData: {
|
|
24
|
+
baseMET: 6.0,
|
|
25
|
+
metRange: [4.0, 8.0],
|
|
26
|
+
compoundMultiplier: 1.5,
|
|
27
|
+
muscleGroupFactor: 2.0,
|
|
28
|
+
intensityScaling: "exponential",
|
|
29
|
+
epocFactor: 0.15,
|
|
30
|
+
},
|
|
31
|
+
timingGuardrails: {
|
|
32
|
+
type: "weight-reps",
|
|
33
|
+
stressRestBonus: 5,
|
|
34
|
+
fatigueMultiplier: 1.2,
|
|
35
|
+
setupTypicalSecs: 10,
|
|
36
|
+
restPeriods: {
|
|
37
|
+
minimum: 60,
|
|
38
|
+
typical: 120,
|
|
39
|
+
maximum: 300,
|
|
40
|
+
optimalRange: [90, 180],
|
|
41
|
+
},
|
|
42
|
+
singleRep: {
|
|
43
|
+
min: 2.0,
|
|
44
|
+
max: 5.0,
|
|
45
|
+
typical: 3.5,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
youtubeVideoUrl: ["https://youtube.com/watch?v=mock1"],
|
|
49
|
+
modelVideoUrl: "https://example.com/mock-video.mp4",
|
|
50
|
+
thumbnailUrl: "https://example.com/mock-thumb.png",
|
|
51
|
+
instructionsHtml: "<ul><li>Mock instruction 1</li></ul>",
|
|
52
|
+
importantTipsHtml: "<ul><li>Mock tip 1</li></ul>",
|
|
53
|
+
popularityIndex: 90,
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* MOCK EXERCISE: Reps-Only
|
|
57
|
+
* Simulates a bodyweight movement (e.g., Push-up).
|
|
58
|
+
*/
|
|
59
|
+
exports.mockExerciseRepsOnly = Object.assign(Object.assign({}, exports.mockExerciseWeightReps), { exerciseId: "mock-exercise-reps-only-456", name: "Generic Push-Up", bodyPart: ["Chest", "Core"], recordType: "reps-only", primaryMuscles: ["pectoralis-major"], secondaryMuscles: ["tricep-brachii-lateral", "abs-lower"], trainingTypes: ["body-weight"], timingGuardrails: {
|
|
60
|
+
type: "reps-only",
|
|
61
|
+
stressRestBonus: 2,
|
|
62
|
+
fatigueMultiplier: 1.05,
|
|
63
|
+
setupTypicalSecs: 5,
|
|
64
|
+
restPeriods: {
|
|
65
|
+
minimum: 30,
|
|
66
|
+
typical: 60,
|
|
67
|
+
maximum: 180,
|
|
68
|
+
optimalRange: [45, 90],
|
|
69
|
+
},
|
|
70
|
+
singleRep: {
|
|
71
|
+
min: 1.0,
|
|
72
|
+
max: 3.0,
|
|
73
|
+
typical: 1.8,
|
|
74
|
+
},
|
|
75
|
+
} });
|
|
76
|
+
/**
|
|
77
|
+
* MOCK EXERCISE: Duration
|
|
78
|
+
* Simulates an isometric hold (e.g., Plank).
|
|
79
|
+
*/
|
|
80
|
+
exports.mockExerciseDuration = Object.assign(Object.assign({}, exports.mockExerciseWeightReps), { exerciseId: "mock-exercise-duration-789", name: "Generic Forearm Plank", bodyPart: ["Core"], recordType: "duration", primaryMuscles: ["abs-lower", "abs-upper"], secondaryMuscles: ["lower-back"], trainingTypes: ["body-weight", "isometric"], timingGuardrails: {
|
|
81
|
+
type: "duration",
|
|
82
|
+
stressRestBonus: 3,
|
|
83
|
+
fatigueMultiplier: 1.1,
|
|
84
|
+
setupTypicalSecs: 5,
|
|
85
|
+
restPeriods: {
|
|
86
|
+
minimum: 30,
|
|
87
|
+
typical: 60,
|
|
88
|
+
maximum: 120,
|
|
89
|
+
optimalRange: [45, 60],
|
|
90
|
+
},
|
|
91
|
+
setDuration: {
|
|
92
|
+
min: 15,
|
|
93
|
+
max: 300,
|
|
94
|
+
typical: 60,
|
|
95
|
+
},
|
|
96
|
+
} });
|
|
97
|
+
/**
|
|
98
|
+
* MOCK EXERCISE: Cardio-Machine
|
|
99
|
+
* Simulates a machine cardio session (e.g., Treadmill).
|
|
100
|
+
*/
|
|
101
|
+
exports.mockExerciseCardioMachine = Object.assign(Object.assign({}, exports.mockExerciseWeightReps), { exerciseId: "mock-exercise-cardio-machine-101", name: "Generic Treadmill Run", bodyPart: ["Legs"], recordType: "cardio-machine", primaryMuscles: ["quadriceps", "hamstrings", "calves"], secondaryMuscles: ["glutes-maximus"], trainingTypes: ["cardio"], timingGuardrails: {
|
|
102
|
+
type: "cardio-machine",
|
|
103
|
+
stressRestBonus: 0,
|
|
104
|
+
fatigueMultiplier: 1.0,
|
|
105
|
+
setupTypicalSecs: 15,
|
|
106
|
+
restPeriods: {
|
|
107
|
+
minimum: 0,
|
|
108
|
+
typical: 0,
|
|
109
|
+
maximum: 300,
|
|
110
|
+
optimalRange: [0, 60],
|
|
111
|
+
},
|
|
112
|
+
} });
|
|
113
|
+
/**
|
|
114
|
+
* MOCK EXERCISE: Cardio-Free
|
|
115
|
+
* Simulates an outdoor/untracked cardio session (e.g., Outdoor Run).
|
|
116
|
+
*/
|
|
117
|
+
exports.mockExerciseCardioFree = Object.assign(Object.assign({}, exports.mockExerciseWeightReps), { exerciseId: "mock-exercise-cardio-free-202", name: "Generic Outdoor Jog", bodyPart: ["Legs"], recordType: "cardio-free", primaryMuscles: ["quadriceps", "hamstrings", "calves"], secondaryMuscles: ["glutes-maximus"], trainingTypes: ["cardio"], timingGuardrails: {
|
|
118
|
+
type: "cardio-free",
|
|
119
|
+
stressRestBonus: 0,
|
|
120
|
+
fatigueMultiplier: 1.0,
|
|
121
|
+
setupTypicalSecs: 0,
|
|
122
|
+
restPeriods: {
|
|
123
|
+
minimum: 0,
|
|
124
|
+
typical: 0,
|
|
125
|
+
maximum: 300,
|
|
126
|
+
optimalRange: [0, 0],
|
|
127
|
+
},
|
|
128
|
+
} });
|
|
129
|
+
/**
|
|
130
|
+
* MOCK EXERCISE: No Guardrails
|
|
131
|
+
* Simulates an older DB entry or custom exercise missing guardrails.
|
|
132
|
+
*/
|
|
133
|
+
exports.mockExerciseNoGuardrails = Object.assign(Object.assign({}, exports.mockExerciseWeightReps), { exerciseId: "mock-exercise-no-guardrails-303", name: "Legacy Exercise", timingGuardrails: undefined });
|
|
134
|
+
/**
|
|
135
|
+
* Helper dictionary containing all mock exercises mapped by their ID.
|
|
136
|
+
*/
|
|
137
|
+
exports.mockExercisesDictionary = {
|
|
138
|
+
[exports.mockExerciseWeightReps.exerciseId]: exports.mockExerciseWeightReps,
|
|
139
|
+
[exports.mockExerciseRepsOnly.exerciseId]: exports.mockExerciseRepsOnly,
|
|
140
|
+
[exports.mockExerciseDuration.exerciseId]: exports.mockExerciseDuration,
|
|
141
|
+
[exports.mockExerciseCardioMachine.exerciseId]: exports.mockExerciseCardioMachine,
|
|
142
|
+
[exports.mockExerciseCardioFree.exerciseId]: exports.mockExerciseCardioFree,
|
|
143
|
+
[exports.mockExerciseNoGuardrails.exerciseId]: exports.mockExerciseNoGuardrails,
|
|
144
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { TTemplateExercise } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* SCENARIO 1: The "Textbook" Perfect Workout
|
|
4
|
+
* Standard 4 sets of weight-reps (e.g., Squat/Bench). All sets done cleanly.
|
|
5
|
+
*/
|
|
6
|
+
export declare const mockTemplateWeightRepsStandard: TTemplateExercise;
|
|
7
|
+
/**
|
|
8
|
+
* SCENARIO 2: The "Micro-loaded" Edge Case
|
|
9
|
+
* Fractional weights and varying reps.
|
|
10
|
+
*/
|
|
11
|
+
export declare const mockTemplateWeightRepsMicroLoaded: TTemplateExercise;
|
|
12
|
+
/**
|
|
13
|
+
* SCENARIO 3: The "Zero Reps / Failed Set" Edge Case
|
|
14
|
+
* User attempts a PR, fails to get a single rep, but logs the set for fatigue tracking.
|
|
15
|
+
*/
|
|
16
|
+
export declare const mockTemplateWeightRepsFailedSet: TTemplateExercise;
|
|
17
|
+
/**
|
|
18
|
+
* SCENARIO 4: The "Abandoned / Partial" Workout
|
|
19
|
+
* User planned 4 sets, did 2, and then left the app/gym.
|
|
20
|
+
*/
|
|
21
|
+
export declare const mockTemplateWeightRepsPartial: TTemplateExercise;
|
|
22
|
+
/**
|
|
23
|
+
* SCENARIO 5: Reps-Only (Bodyweight) with and without Aux Weight
|
|
24
|
+
* Mix of pure bodyweight and weighted bodyweight (e.g., dip belt).
|
|
25
|
+
*/
|
|
26
|
+
export declare const mockTemplateRepsOnly: TTemplateExercise;
|
|
27
|
+
/**
|
|
28
|
+
* SCENARIO 6: Duration (Isometric)
|
|
29
|
+
* e.g., Plank holds with a target duration.
|
|
30
|
+
*/
|
|
31
|
+
export declare const mockTemplateDuration: TTemplateExercise;
|
|
32
|
+
/**
|
|
33
|
+
* SCENARIO 7: Cardio-Machine
|
|
34
|
+
* Rich data collection for machines (Speed, Incline, Resistance).
|
|
35
|
+
*/
|
|
36
|
+
export declare const mockTemplateCardioMachine: TTemplateExercise;
|
|
37
|
+
/**
|
|
38
|
+
* SCENARIO 8: Cardio-Free
|
|
39
|
+
* Outdoor running. Only distance and duration are captured.
|
|
40
|
+
*/
|
|
41
|
+
export declare const mockTemplateCardioFree: TTemplateExercise;
|
|
42
|
+
/**
|
|
43
|
+
* SCENARIO 9: Dirty / Malformed Payload (For Gatekeeper Testing)
|
|
44
|
+
* The frontend sends properties that the Config specifically disallows.
|
|
45
|
+
*/
|
|
46
|
+
export declare const mockTemplateDirtyPayload: TTemplateExercise;
|
|
47
|
+
/**
|
|
48
|
+
* SCENARIO 10: "Distracted Logger"
|
|
49
|
+
* User leaves the timer running and logs 600 seconds of rest. Should trigger clamping.
|
|
50
|
+
*/
|
|
51
|
+
export declare const mockTemplateDistractedLogger: TTemplateExercise;
|
|
52
|
+
/**
|
|
53
|
+
* SCENARIO 11: "Lazy Logger"
|
|
54
|
+
* User completes the workout and batches the input later. All rest durations are undefined.
|
|
55
|
+
*/
|
|
56
|
+
export declare const mockTemplateLazyLogger: TTemplateExercise;
|
|
57
|
+
/**
|
|
58
|
+
* SCENARIO 12: "All Undone"
|
|
59
|
+
* User adopts the plan but skips this exercise entirely.
|
|
60
|
+
*/
|
|
61
|
+
export declare const mockTemplateAllUndone: TTemplateExercise;
|
|
62
|
+
/**
|
|
63
|
+
* SCENARIO 13: Single-Set Weight-Reps
|
|
64
|
+
* Tests that the total duration ignores rest entirely for a single set.
|
|
65
|
+
*/
|
|
66
|
+
export declare const mockTemplateSingleSet: TTemplateExercise;
|
|
67
|
+
/**
|
|
68
|
+
* SCENARIO 14: Non-Sequential Completion
|
|
69
|
+
* User did sets 1 and 3, but skipped 2. Tests filter ordering.
|
|
70
|
+
*/
|
|
71
|
+
export declare const mockTemplateNonSequential: TTemplateExercise;
|
|
72
|
+
/**
|
|
73
|
+
* Dictionary of all template mocks for easy access in test files.
|
|
74
|
+
*/
|
|
75
|
+
export declare const mockTemplateExercisesDictionary: {
|
|
76
|
+
weightRepsStandard: TTemplateExercise;
|
|
77
|
+
weightRepsMicroLoaded: TTemplateExercise;
|
|
78
|
+
weightRepsFailedSet: TTemplateExercise;
|
|
79
|
+
weightRepsPartial: TTemplateExercise;
|
|
80
|
+
repsOnly: TTemplateExercise;
|
|
81
|
+
duration: TTemplateExercise;
|
|
82
|
+
cardioMachine: TTemplateExercise;
|
|
83
|
+
cardioFree: TTemplateExercise;
|
|
84
|
+
dirtyPayload: TTemplateExercise;
|
|
85
|
+
distractedLogger: TTemplateExercise;
|
|
86
|
+
lazyLogger: TTemplateExercise;
|
|
87
|
+
allUndone: TTemplateExercise;
|
|
88
|
+
singleSet: TTemplateExercise;
|
|
89
|
+
nonSequential: TTemplateExercise;
|
|
90
|
+
};
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mockTemplateExercisesDictionary = exports.mockTemplateNonSequential = exports.mockTemplateSingleSet = exports.mockTemplateAllUndone = exports.mockTemplateLazyLogger = exports.mockTemplateDistractedLogger = exports.mockTemplateDirtyPayload = exports.mockTemplateCardioFree = exports.mockTemplateCardioMachine = exports.mockTemplateDuration = exports.mockTemplateRepsOnly = exports.mockTemplateWeightRepsPartial = exports.mockTemplateWeightRepsFailedSet = exports.mockTemplateWeightRepsMicroLoaded = exports.mockTemplateWeightRepsStandard = void 0;
|
|
4
|
+
const exercises_mock_1 = require("./exercises.mock");
|
|
5
|
+
/**
|
|
6
|
+
* Standard configurations
|
|
7
|
+
*/
|
|
8
|
+
const defaultConfigAllEnabled = {
|
|
9
|
+
enableRpe: true,
|
|
10
|
+
enableRir: true,
|
|
11
|
+
enableSetNote: true,
|
|
12
|
+
enableExerciseNote: true,
|
|
13
|
+
enableTimeIntervalMode: true,
|
|
14
|
+
enableAuxWeight: true,
|
|
15
|
+
enableDistance: true,
|
|
16
|
+
enableInclinePercentage: true,
|
|
17
|
+
enableResistanceLevel: true,
|
|
18
|
+
enableSpeed: true,
|
|
19
|
+
};
|
|
20
|
+
const defaultConfigMinimal = {
|
|
21
|
+
// Everything false or undefined
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* SCENARIO 1: The "Textbook" Perfect Workout
|
|
25
|
+
* Standard 4 sets of weight-reps (e.g., Squat/Bench). All sets done cleanly.
|
|
26
|
+
*/
|
|
27
|
+
exports.mockTemplateWeightRepsStandard = {
|
|
28
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
29
|
+
exerciseNote: "Standard working sets, focused on form.",
|
|
30
|
+
restTimeSecs: 90,
|
|
31
|
+
config: defaultConfigAllEnabled,
|
|
32
|
+
initialRecords: [
|
|
33
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "60", reps: "10", rpe: "6", restDurationSecs: 90 },
|
|
34
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "80", reps: "8", rpe: "7.5", restDurationSecs: 90 },
|
|
35
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "85", reps: "8", rpe: "8", restDurationSecs: 120 },
|
|
36
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "85", reps: "6", rpe: "9.5", setNote: "Grinded the last rep", restDurationSecs: 180 },
|
|
37
|
+
],
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* SCENARIO 2: The "Micro-loaded" Edge Case
|
|
41
|
+
* Fractional weights and varying reps.
|
|
42
|
+
*/
|
|
43
|
+
exports.mockTemplateWeightRepsMicroLoaded = {
|
|
44
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
45
|
+
exerciseNote: "Micro-cycle progression day.",
|
|
46
|
+
restTimeSecs: 120,
|
|
47
|
+
config: defaultConfigAllEnabled,
|
|
48
|
+
initialRecords: [
|
|
49
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "42.5", reps: "5", restDurationSecs: 120 },
|
|
50
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "43.75", reps: "5", restDurationSecs: 120 },
|
|
51
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "45.0", reps: "5", restDurationSecs: 120 },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* SCENARIO 3: The "Zero Reps / Failed Set" Edge Case
|
|
56
|
+
* User attempts a PR, fails to get a single rep, but logs the set for fatigue tracking.
|
|
57
|
+
*/
|
|
58
|
+
exports.mockTemplateWeightRepsFailedSet = {
|
|
59
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
60
|
+
exerciseNote: "Going for 1RM PR today.",
|
|
61
|
+
restTimeSecs: 180,
|
|
62
|
+
config: defaultConfigAllEnabled,
|
|
63
|
+
initialRecords: [
|
|
64
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "100", reps: "1", rir: "0", restDurationSecs: 180 },
|
|
65
|
+
// Failed Set
|
|
66
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "105", reps: "0", rir: "0", setNote: "Failed midway", restDurationSecs: 60 },
|
|
67
|
+
// Skipped subsequent sets due to failure
|
|
68
|
+
{ type: "weight-reps", isDone: false, isStrictMode: false, kg: "105", reps: "1" },
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* SCENARIO 4: The "Abandoned / Partial" Workout
|
|
73
|
+
* User planned 4 sets, did 2, and then left the app/gym.
|
|
74
|
+
*/
|
|
75
|
+
exports.mockTemplateWeightRepsPartial = {
|
|
76
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
77
|
+
exerciseNote: "",
|
|
78
|
+
restTimeSecs: 60,
|
|
79
|
+
config: defaultConfigAllEnabled,
|
|
80
|
+
initialRecords: [
|
|
81
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "50", reps: "8", restDurationSecs: 60 },
|
|
82
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "50", reps: "8", restDurationSecs: 60 },
|
|
83
|
+
// Planned but never completed
|
|
84
|
+
{ type: "weight-reps", isDone: false, isStrictMode: false, kg: "50", reps: "8" },
|
|
85
|
+
{ type: "weight-reps", isDone: false, isStrictMode: false, kg: "50", reps: "8" },
|
|
86
|
+
],
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* SCENARIO 5: Reps-Only (Bodyweight) with and without Aux Weight
|
|
90
|
+
* Mix of pure bodyweight and weighted bodyweight (e.g., dip belt).
|
|
91
|
+
*/
|
|
92
|
+
exports.mockTemplateRepsOnly = {
|
|
93
|
+
exerciseId: exercises_mock_1.mockExerciseRepsOnly.exerciseId,
|
|
94
|
+
exerciseNote: "Pushups: first set unweighted, next sets with vest.",
|
|
95
|
+
restTimeSecs: 60,
|
|
96
|
+
config: defaultConfigAllEnabled,
|
|
97
|
+
initialRecords: [
|
|
98
|
+
{ type: "reps-only", isDone: true, isStrictMode: false, reps: "20", auxWeightKg: "", restDurationSecs: 60 }, // pure bodyweight
|
|
99
|
+
{ type: "reps-only", isDone: true, isStrictMode: false, reps: "15", auxWeightKg: "10", restDurationSecs: 60 }, // 10kg vest
|
|
100
|
+
{ type: "reps-only", isDone: true, isStrictMode: false, reps: "12", auxWeightKg: "10", restDurationSecs: 60 },
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* SCENARIO 6: Duration (Isometric)
|
|
105
|
+
* e.g., Plank holds with a target duration.
|
|
106
|
+
*/
|
|
107
|
+
exports.mockTemplateDuration = {
|
|
108
|
+
exerciseId: exercises_mock_1.mockExerciseDuration.exerciseId,
|
|
109
|
+
exerciseNote: "Hold until failure.",
|
|
110
|
+
restTimeSecs: 45,
|
|
111
|
+
config: defaultConfigAllEnabled,
|
|
112
|
+
initialRecords: [
|
|
113
|
+
{ type: "duration", isDone: true, isStrictMode: false, durationMmSs: "01:30", auxWeightKg: "0", restDurationSecs: 45 },
|
|
114
|
+
{ type: "duration", isDone: true, isStrictMode: false, durationMmSs: "01:15", auxWeightKg: "0", restDurationSecs: 45 },
|
|
115
|
+
{ type: "duration", isDone: true, isStrictMode: false, durationMmSs: "00:50", auxWeightKg: "0", restDurationSecs: 45 },
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* SCENARIO 7: Cardio-Machine
|
|
120
|
+
* Rich data collection for machines (Speed, Incline, Resistance).
|
|
121
|
+
*/
|
|
122
|
+
exports.mockTemplateCardioMachine = {
|
|
123
|
+
exerciseId: exercises_mock_1.mockExerciseCardioMachine.exerciseId,
|
|
124
|
+
exerciseNote: "HIIT Intervals on Treadmill",
|
|
125
|
+
restTimeSecs: 0,
|
|
126
|
+
config: defaultConfigAllEnabled,
|
|
127
|
+
initialRecords: [
|
|
128
|
+
{ type: "cardio-machine", isDone: true, isStrictMode: false, durationMmSs: "05:00", speed: "5", inclinePercentage: "2", distance: "0.5" }, // Warmup
|
|
129
|
+
{ type: "cardio-machine", isDone: true, isStrictMode: false, durationMmSs: "10:00", speed: "12", inclinePercentage: "0", distance: "2.0" }, // Run
|
|
130
|
+
{ type: "cardio-machine", isDone: true, isStrictMode: false, durationMmSs: "05:00", speed: "4", inclinePercentage: "0", distance: "0.3" }, // Cooldown
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* SCENARIO 8: Cardio-Free
|
|
135
|
+
* Outdoor running. Only distance and duration are captured.
|
|
136
|
+
*/
|
|
137
|
+
exports.mockTemplateCardioFree = {
|
|
138
|
+
exerciseId: exercises_mock_1.mockExerciseCardioFree.exerciseId,
|
|
139
|
+
exerciseNote: "Morning 5k",
|
|
140
|
+
restTimeSecs: 0,
|
|
141
|
+
config: defaultConfigAllEnabled,
|
|
142
|
+
initialRecords: [
|
|
143
|
+
{ type: "cardio-free", isDone: true, isStrictMode: false, durationMmSs: "25:30", distance: "5.0", auxWeightKg: "" },
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* SCENARIO 9: Dirty / Malformed Payload (For Gatekeeper Testing)
|
|
148
|
+
* The frontend sends properties that the Config specifically disallows.
|
|
149
|
+
*/
|
|
150
|
+
exports.mockTemplateDirtyPayload = {
|
|
151
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
152
|
+
exerciseNote: "Checking if validator strips the extra stuff.",
|
|
153
|
+
restTimeSecs: 60,
|
|
154
|
+
config: defaultConfigMinimal, // Everything is disabled!
|
|
155
|
+
initialRecords: [
|
|
156
|
+
{
|
|
157
|
+
type: "weight-reps",
|
|
158
|
+
isDone: true,
|
|
159
|
+
isStrictMode: false,
|
|
160
|
+
kg: "100",
|
|
161
|
+
reps: "10",
|
|
162
|
+
// The following should be stripped by validator because config disables them:
|
|
163
|
+
rpe: "8",
|
|
164
|
+
rir: "2",
|
|
165
|
+
setNote: "Should be removed",
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* SCENARIO 10: "Distracted Logger"
|
|
171
|
+
* User leaves the timer running and logs 600 seconds of rest. Should trigger clamping.
|
|
172
|
+
*/
|
|
173
|
+
exports.mockTemplateDistractedLogger = {
|
|
174
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
175
|
+
exerciseNote: "Got a phone call between sets.",
|
|
176
|
+
restTimeSecs: 90,
|
|
177
|
+
config: defaultConfigAllEnabled,
|
|
178
|
+
initialRecords: [
|
|
179
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "60", reps: "10", restDurationSecs: 600 },
|
|
180
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "60", reps: "10", restDurationSecs: 90 },
|
|
181
|
+
],
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* SCENARIO 11: "Lazy Logger"
|
|
185
|
+
* User completes the workout and batches the input later. All rest durations are undefined.
|
|
186
|
+
*/
|
|
187
|
+
exports.mockTemplateLazyLogger = {
|
|
188
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
189
|
+
exerciseNote: "Logged after walking to the car.",
|
|
190
|
+
restTimeSecs: 90,
|
|
191
|
+
config: defaultConfigAllEnabled,
|
|
192
|
+
initialRecords: [
|
|
193
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "60", reps: "10" }, // restDurationSecs is undefined
|
|
194
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "60", reps: "10" },
|
|
195
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "60", reps: "10" },
|
|
196
|
+
],
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* SCENARIO 12: "All Undone"
|
|
200
|
+
* User adopts the plan but skips this exercise entirely.
|
|
201
|
+
*/
|
|
202
|
+
exports.mockTemplateAllUndone = {
|
|
203
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
204
|
+
exerciseNote: "Skipped today.",
|
|
205
|
+
restTimeSecs: 90,
|
|
206
|
+
config: defaultConfigAllEnabled,
|
|
207
|
+
initialRecords: [
|
|
208
|
+
{ type: "weight-reps", isDone: false, isStrictMode: false, kg: "60", reps: "10" },
|
|
209
|
+
{ type: "weight-reps", isDone: false, isStrictMode: false, kg: "60", reps: "10" },
|
|
210
|
+
],
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* SCENARIO 13: Single-Set Weight-Reps
|
|
214
|
+
* Tests that the total duration ignores rest entirely for a single set.
|
|
215
|
+
*/
|
|
216
|
+
exports.mockTemplateSingleSet = {
|
|
217
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
218
|
+
exerciseNote: "One heavy set.",
|
|
219
|
+
restTimeSecs: 90,
|
|
220
|
+
config: defaultConfigAllEnabled,
|
|
221
|
+
initialRecords: [
|
|
222
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "140", reps: "5", restDurationSecs: 180 },
|
|
223
|
+
],
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* SCENARIO 14: Non-Sequential Completion
|
|
227
|
+
* User did sets 1 and 3, but skipped 2. Tests filter ordering.
|
|
228
|
+
*/
|
|
229
|
+
exports.mockTemplateNonSequential = {
|
|
230
|
+
exerciseId: exercises_mock_1.mockExerciseWeightReps.exerciseId,
|
|
231
|
+
exerciseNote: "Skipped the middle set.",
|
|
232
|
+
restTimeSecs: 90,
|
|
233
|
+
config: defaultConfigAllEnabled,
|
|
234
|
+
initialRecords: [
|
|
235
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "60", reps: "10", restDurationSecs: 90 },
|
|
236
|
+
{ type: "weight-reps", isDone: false, isStrictMode: false, kg: "60", reps: "10" },
|
|
237
|
+
{ type: "weight-reps", isDone: true, isStrictMode: false, kg: "60", reps: "10", restDurationSecs: 90 },
|
|
238
|
+
],
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* Dictionary of all template mocks for easy access in test files.
|
|
242
|
+
*/
|
|
243
|
+
exports.mockTemplateExercisesDictionary = {
|
|
244
|
+
weightRepsStandard: exports.mockTemplateWeightRepsStandard,
|
|
245
|
+
weightRepsMicroLoaded: exports.mockTemplateWeightRepsMicroLoaded,
|
|
246
|
+
weightRepsFailedSet: exports.mockTemplateWeightRepsFailedSet,
|
|
247
|
+
weightRepsPartial: exports.mockTemplateWeightRepsPartial,
|
|
248
|
+
repsOnly: exports.mockTemplateRepsOnly,
|
|
249
|
+
duration: exports.mockTemplateDuration,
|
|
250
|
+
cardioMachine: exports.mockTemplateCardioMachine,
|
|
251
|
+
cardioFree: exports.mockTemplateCardioFree,
|
|
252
|
+
dirtyPayload: exports.mockTemplateDirtyPayload,
|
|
253
|
+
distractedLogger: exports.mockTemplateDistractedLogger,
|
|
254
|
+
lazyLogger: exports.mockTemplateLazyLogger,
|
|
255
|
+
allUndone: exports.mockTemplateAllUndone,
|
|
256
|
+
singleSet: exports.mockTemplateSingleSet,
|
|
257
|
+
nonSequential: exports.mockTemplateNonSequential,
|
|
258
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mockUser = void 0;
|
|
4
|
+
exports.mockUser = {
|
|
5
|
+
userId: "mock-user-123",
|
|
6
|
+
userCode: "MOCK123",
|
|
7
|
+
userType: "regular",
|
|
8
|
+
fullName: "Mock User",
|
|
9
|
+
dob: new Date("1990-01-01"),
|
|
10
|
+
weightKg: 75,
|
|
11
|
+
heightCm: 180,
|
|
12
|
+
gender: "male",
|
|
13
|
+
appLanguage: "en",
|
|
14
|
+
metricSystem: "EU",
|
|
15
|
+
fitnessLevel: "moderately-active",
|
|
16
|
+
fitnessGoal: "hypertrophy",
|
|
17
|
+
bodyFatPercentage: 15,
|
|
18
|
+
subscriptionStatus: "none",
|
|
19
|
+
subscriptionType: "trial", // Using a valid type from TSubscriptionType
|
|
20
|
+
subscriptionTier: "none",
|
|
21
|
+
subscriptionWillRenew: false,
|
|
22
|
+
subscriptionStore: null,
|
|
23
|
+
subscriptionLastUpdatedAt: Date.now(),
|
|
24
|
+
gdpr: {
|
|
25
|
+
consentVersion: "1.0",
|
|
26
|
+
consentTimestamp: new Date().toISOString(),
|
|
27
|
+
consentStatus: "full",
|
|
28
|
+
dataSharing: {
|
|
29
|
+
withTrainers: false,
|
|
30
|
+
marketplaceAnalytics: false,
|
|
31
|
+
marketingCommunications: false,
|
|
32
|
+
},
|
|
33
|
+
consentHistory: [],
|
|
34
|
+
},
|
|
35
|
+
createdAt: new Date("2023-01-01"),
|
|
36
|
+
};
|
package/dist/types/TApiUser.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type TUserTrainerType = "personal_trainer" | "strength_conditioning_coach
|
|
|
7
7
|
export type TFitnessGoal = "strength" | "hypertrophy" | "endurance" | "general" | "fat_burn" | "flexibility";
|
|
8
8
|
export type TSubscriptionStatus = "active" | "cancelled" | "expired" | "trial" | "grace" | "none";
|
|
9
9
|
export type TSubscriptionType = "monthly" | "yearly" | "trial";
|
|
10
|
+
export type TSubscriptionTier = "enthusiast" | "pro" | "none";
|
|
10
11
|
export type TAppStore = "app_store" | "play_store" | null;
|
|
11
12
|
export type TActivityLevel = "sedentary" | "lightly-active" | "moderately-active" | "very-active";
|
|
12
13
|
export type TUserMetric = {
|
|
@@ -27,6 +28,7 @@ export type TUserMetric = {
|
|
|
27
28
|
metricSystem: "US" | "EU";
|
|
28
29
|
subscriptionStatus: TSubscriptionStatus;
|
|
29
30
|
subscriptionType: TSubscriptionType;
|
|
31
|
+
subscriptionTier: TSubscriptionTier;
|
|
30
32
|
subscriptionExpiresAt?: number;
|
|
31
33
|
subscriptionStartedAt?: number;
|
|
32
34
|
subscriptionWillRenew: boolean;
|
|
@@ -36,7 +38,7 @@ export type TUserMetric = {
|
|
|
36
38
|
createdAt: Date;
|
|
37
39
|
updatedAt?: Date;
|
|
38
40
|
};
|
|
39
|
-
export type TApiUserUpdateReq = Omit<TUserMetric, "userId" | "subscriptionStatus" | "subscriptionType" | "subscriptionExpiresAt" | "subscriptionStartedAt" | "subscriptionWillRenew" | "subscriptionStore" | "subscriptionLastUpdatedAt" | "createdAt" | "gdpr"> & {
|
|
41
|
+
export type TApiUserUpdateReq = Omit<TUserMetric, "userId" | "subscriptionStatus" | "subscriptionType" | "subscriptionTier" | "subscriptionExpiresAt" | "subscriptionStartedAt" | "subscriptionWillRenew" | "subscriptionStore" | "subscriptionLastUpdatedAt" | "createdAt" | "gdpr"> & {
|
|
40
42
|
gdpr: Pick<TGdprData, "dataSharing">;
|
|
41
43
|
};
|
|
42
44
|
export type TApiUserUpdateRes = {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { TExercise } from "../../../types";
|
|
2
|
+
/**
|
|
3
|
+
* MOCK EXERCISE: Weight-Reps
|
|
4
|
+
* Simulates a standard compound lift (e.g., Barbell Squat).
|
|
5
|
+
*/
|
|
6
|
+
export declare const mockExerciseWeightReps: TExercise;
|
|
7
|
+
/**
|
|
8
|
+
* MOCK EXERCISE: Reps-Only
|
|
9
|
+
* Simulates a bodyweight movement (e.g., Push-up).
|
|
10
|
+
*/
|
|
11
|
+
export declare const mockExerciseRepsOnly: TExercise;
|
|
12
|
+
/**
|
|
13
|
+
* MOCK EXERCISE: Duration
|
|
14
|
+
* Simulates an isometric hold (e.g., Plank).
|
|
15
|
+
*/
|
|
16
|
+
export declare const mockExerciseDuration: TExercise;
|
|
17
|
+
/**
|
|
18
|
+
* MOCK EXERCISE: Cardio-Machine
|
|
19
|
+
* Simulates a machine cardio session (e.g., Treadmill).
|
|
20
|
+
*/
|
|
21
|
+
export declare const mockExerciseCardioMachine: TExercise;
|
|
22
|
+
/**
|
|
23
|
+
* MOCK EXERCISE: Cardio-Free
|
|
24
|
+
* Simulates an outdoor/untracked cardio session (e.g., Outdoor Run).
|
|
25
|
+
*/
|
|
26
|
+
export declare const mockExerciseCardioFree: TExercise;
|
|
27
|
+
/**
|
|
28
|
+
* Helper dictionary containing all mock exercises mapped by their ID.
|
|
29
|
+
*/
|
|
30
|
+
export declare const mockExercisesDictionary: Record<string, TExercise>;
|