@dgpholdings/greatoak-shared 1.2.86 → 1.2.88
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/README.md +148 -148
- package/dist/__mocks__/catalog.fixture.d.ts +2 -0
- package/dist/__mocks__/catalog.fixture.js +208 -0
- package/dist/__mocks__/exercises.mock.d.ts +4 -11
- package/dist/__mocks__/exercises.mock.js +82 -41
- package/dist/__mocks__/sessions.mock.d.ts +28 -0
- package/dist/__mocks__/sessions.mock.js +394 -0
- package/dist/__mocks__/testIds.d.ts +9 -0
- package/dist/__mocks__/testIds.js +13 -0
- package/dist/__mocks__/user.mock.js +3 -1
- package/dist/constants/goalJourney.d.ts +108 -0
- package/dist/constants/goalJourney.js +443 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/types/TApiAiExerciseAnalysis.d.ts +2 -1
- package/dist/types/TApiClientConstellation.d.ts +33 -0
- package/dist/types/TApiClientConstellation.js +13 -0
- package/dist/types/TApiExercise.d.ts +5 -3
- package/dist/types/TApiUser.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/utils/adoptionEngine/scaleProPlan.util.js +9 -4
- package/dist/utils/constellation/computeNormalisedLoad.d.ts +48 -0
- package/dist/utils/constellation/computeNormalisedLoad.js +150 -0
- package/dist/utils/constellation/computeNormalisedLoad.test.d.ts +1 -0
- package/dist/utils/constellation/computeNormalisedLoad.test.js +218 -0
- package/dist/utils/constellation/evaluateConstellation.d.ts +27 -0
- package/dist/utils/constellation/evaluateConstellation.js +135 -0
- package/dist/utils/constellation/evaluateConstellation.test.d.ts +1 -0
- package/dist/utils/constellation/evaluateConstellation.test.js +93 -0
- package/dist/utils/constellation/index.d.ts +18 -0
- package/dist/utils/constellation/index.js +29 -0
- package/dist/utils/constellation/levelThresholds.d.ts +99 -0
- package/dist/utils/constellation/levelThresholds.js +123 -0
- package/dist/utils/constellation/starFoundation.d.ts +25 -0
- package/dist/utils/constellation/starFoundation.js +54 -0
- package/dist/utils/constellation/starFoundation.test.d.ts +1 -0
- package/dist/utils/constellation/starFoundation.test.js +75 -0
- package/dist/utils/constellation/stars/consistency.d.ts +29 -0
- package/dist/utils/constellation/stars/consistency.js +142 -0
- package/dist/utils/constellation/stars/consistency.test.d.ts +1 -0
- package/dist/utils/constellation/stars/consistency.test.js +94 -0
- package/dist/utils/constellation/stars/lowerBody.d.ts +17 -0
- package/dist/utils/constellation/stars/lowerBody.js +30 -0
- package/dist/utils/constellation/stars/pull.d.ts +11 -0
- package/dist/utils/constellation/stars/pull.js +24 -0
- package/dist/utils/constellation/stars/push.d.ts +11 -0
- package/dist/utils/constellation/stars/push.js +24 -0
- package/dist/utils/constellation/stars/quality.d.ts +19 -0
- package/dist/utils/constellation/stars/quality.js +98 -0
- package/dist/utils/constellation/stars/quality.test.d.ts +1 -0
- package/dist/utils/constellation/stars/quality.test.js +113 -0
- package/dist/utils/constellation/stars/recovery.d.ts +29 -0
- package/dist/utils/constellation/stars/recovery.js +169 -0
- package/dist/utils/constellation/stars/recovery.test.d.ts +1 -0
- package/dist/utils/constellation/stars/recovery.test.js +131 -0
- package/dist/utils/constellation/strengthStar.test.d.ts +1 -0
- package/dist/utils/constellation/strengthStar.test.js +190 -0
- package/dist/utils/constellation/strengthStarHelpers.d.ts +41 -0
- package/dist/utils/constellation/strengthStarHelpers.js +104 -0
- package/dist/utils/constellation/types.d.ts +124 -0
- package/dist/utils/constellation/types.js +18 -0
- package/dist/utils/exerciseRecord/recordValidator.integration.test.js +1 -1
- package/dist/utils/exerciseRecord/recordValidator.js +1 -1
- package/dist/utils/exerciseRecord/recordValidator.test.js +8 -8
- package/dist/utils/index.d.ts +5 -3
- package/dist/utils/index.js +1 -0
- package/dist/utils/scoringWorkout/calculateQualityScore.d.ts +59 -36
- package/dist/utils/scoringWorkout/calculateQualityScore.js +234 -233
- package/dist/utils/scoringWorkout/computeMuscleFatigueMap.d.ts +8 -5
- package/dist/utils/scoringWorkout/computeMuscleFatigueMap.js +72 -88
- package/dist/utils/scoringWorkout/constants.d.ts +20 -6
- package/dist/utils/scoringWorkout/constants.js +23 -9
- package/dist/utils/scoringWorkout/helpers.d.ts +7 -0
- package/dist/utils/scoringWorkout/helpers.js +24 -18
- package/dist/utils/scoringWorkout/index.d.ts +12 -8
- package/dist/utils/scoringWorkout/index.js +23 -15
- package/dist/utils/scoringWorkout/parseRecords.js +4 -3
- package/dist/utils/scoringWorkout/scoringWorkout.integration.test.js +223 -185
- package/dist/utils/scoringWorkout/types.d.ts +34 -14
- package/package.json +31 -31
- package/dist/utils/exerciseRecord/__mocks__/exercises.mock.d.ts +0 -30
- package/dist/utils/exerciseRecord/__mocks__/exercises.mock.js +0 -138
- package/dist/utils/scaleProPlan.util.d.ts +0 -9
- package/dist/utils/scaleProPlan.util.js +0 -139
- package/dist/utils/scoring/calculateCalories.d.ts +0 -67
- package/dist/utils/scoring/calculateCalories.js +0 -345
- package/dist/utils/scoring/calculateMuscleFatiue.d.ts +0 -67
- package/dist/utils/scoring/calculateMuscleFatiue.js +0 -310
- package/dist/utils/scoring/calculateQualityScore.d.ts +0 -71
- package/dist/utils/scoring/calculateQualityScore.js +0 -334
- package/dist/utils/scoring/calculateTotalVolume.d.ts +0 -15
- package/dist/utils/scoring/calculateTotalVolume.js +0 -73
- package/dist/utils/scoring/constants.d.ts +0 -211
- package/dist/utils/scoring/constants.js +0 -247
- package/dist/utils/scoring/helpers.d.ts +0 -119
- package/dist/utils/scoring/helpers.js +0 -229
- package/dist/utils/scoring/index.d.ts +0 -28
- package/dist/utils/scoring/index.js +0 -47
- package/dist/utils/scoring/parseRecords.d.ts +0 -98
- package/dist/utils/scoring/parseRecords.js +0 -284
- package/dist/utils/scoring/types.d.ts +0 -86
- package/dist/utils/scoring/types.js +0 -11
- package/dist/utils/scoring.utils.d.ts +0 -14
- package/dist/utils/scoring.utils.js +0 -243
- /package/dist/utils/scoringWorkout/{calculateMuscleFatiue.d.ts → calculateMuscleFatigue.d.ts} +0 -0
- /package/dist/utils/scoringWorkout/{calculateMuscleFatiue.js → calculateMuscleFatigue.js} +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { TAiFitnessGoal } from "./AiExerciseVocabulary";
|
|
2
|
+
import { QUICK_START_CLEAR_INTENTS } from "./quickStartIntents";
|
|
3
|
+
export declare const USER_FITNESS_GOALS: readonly ["lose_weight", "build_muscle", "lean_and_toned", "glutes_and_legs", "get_stronger", "boost_endurance", "athletic_performance", "general_fitness", "posture_and_back", "stress_relief", "rehabilitation", "core_strength", "mobility_flexibility"];
|
|
4
|
+
export type TUserFitnessGoal = (typeof USER_FITNESS_GOALS)[number];
|
|
5
|
+
export type TSessionIntent = (typeof QUICK_START_CLEAR_INTENTS)[keyof typeof QUICK_START_CLEAR_INTENTS] | "rest";
|
|
6
|
+
export declare const GOAL_SESSION_INTENTS: Record<TUserFitnessGoal, TWeeklyIntentTemplate>;
|
|
7
|
+
export declare const GOAL_TO_AI_FITNESS_GOAL: Record<TUserFitnessGoal, TAiFitnessGoal>;
|
|
8
|
+
export declare const TRAINING_PHASES: readonly [1, 2, 3, 4];
|
|
9
|
+
export type TTrainingPhase = (typeof TRAINING_PHASES)[number];
|
|
10
|
+
export type TPhaseDisplay = {
|
|
11
|
+
/** i18n key for the phase name — e.g. "goalPhase.foundation.name" */
|
|
12
|
+
nameKey: string;
|
|
13
|
+
/** English fallback for nameKey */
|
|
14
|
+
nameEn: string;
|
|
15
|
+
/** i18n key for the short subtitle — e.g. "goalPhase.foundation.subtitle" */
|
|
16
|
+
subtitleKey: string;
|
|
17
|
+
/** English fallback for subtitleKey */
|
|
18
|
+
subtitleEn: string;
|
|
19
|
+
/** i18n key for the longer purpose description shown in phase detail */
|
|
20
|
+
purposeKey: string;
|
|
21
|
+
/** English fallback for purposeKey */
|
|
22
|
+
purposeEn: string;
|
|
23
|
+
/** i18n key for the week range label — e.g. "goalPhase.foundation.duration" */
|
|
24
|
+
durationKey: string;
|
|
25
|
+
/** English fallback for durationKey */
|
|
26
|
+
durationEn: string;
|
|
27
|
+
/** Inclusive week range [startWeek, endWeek]. Phase 4 end is open (99). */
|
|
28
|
+
weekRange: [number, number];
|
|
29
|
+
/**
|
|
30
|
+
* Reference intensity as a percentage (0–100).
|
|
31
|
+
* For UI progress bars / intensity indicators only — not used in algorithm.
|
|
32
|
+
*/
|
|
33
|
+
intensityPercent: number;
|
|
34
|
+
};
|
|
35
|
+
export declare const PHASE_DISPLAY: Record<TTrainingPhase, TPhaseDisplay>;
|
|
36
|
+
export type TIntentDisplay = {
|
|
37
|
+
/** i18n key for the full label — e.g. "sessionIntent.push.label" */
|
|
38
|
+
labelKey: string;
|
|
39
|
+
/** English fallback for labelKey */
|
|
40
|
+
labelEn: string;
|
|
41
|
+
/**
|
|
42
|
+
* i18n key for the short label used in compact journey nodes.
|
|
43
|
+
* e.g. "sessionIntent.push.shortLabel"
|
|
44
|
+
*/
|
|
45
|
+
shortLabelKey: string;
|
|
46
|
+
/** English fallback for shortLabelKey */
|
|
47
|
+
shortLabelEn: string;
|
|
48
|
+
/**
|
|
49
|
+
* Emoji for the session node icon.
|
|
50
|
+
* Not translated — emoji is universal.
|
|
51
|
+
*/
|
|
52
|
+
emoji: string;
|
|
53
|
+
};
|
|
54
|
+
export declare const INTENT_DISPLAY: Record<TSessionIntent, TIntentDisplay>;
|
|
55
|
+
export type TGoalDisplay = {
|
|
56
|
+
/** i18n key for the goal name — e.g. "userGoal.loseWeight.name" */
|
|
57
|
+
nameKey: string;
|
|
58
|
+
/** English fallback for nameKey */
|
|
59
|
+
nameEn: string;
|
|
60
|
+
/** i18n key for the short description shown on goal selection screen */
|
|
61
|
+
descriptionKey: string;
|
|
62
|
+
/** English fallback for descriptionKey */
|
|
63
|
+
descriptionEn: string;
|
|
64
|
+
/**
|
|
65
|
+
* i18n key for the motivational tagline shown on the goal journey screen.
|
|
66
|
+
* e.g. "userGoal.loseWeight.tagline"
|
|
67
|
+
*/
|
|
68
|
+
taglineKey: string;
|
|
69
|
+
/** English fallback for taglineKey */
|
|
70
|
+
taglineEn: string;
|
|
71
|
+
/** Emoji representing the goal — universal, not translated */
|
|
72
|
+
emoji: string;
|
|
73
|
+
/**
|
|
74
|
+
* Goal category — used to group goals on the selection screen.
|
|
75
|
+
* Category label itself is also translated via categoryKey.
|
|
76
|
+
*/
|
|
77
|
+
category: "appearance" | "performance" | "health" | "focused";
|
|
78
|
+
};
|
|
79
|
+
export declare const GOAL_DISPLAY: Record<TUserFitnessGoal, TGoalDisplay>;
|
|
80
|
+
export type TGoalCategory = TGoalDisplay["category"];
|
|
81
|
+
export type TGoalCategoryDisplay = {
|
|
82
|
+
labelKey: string;
|
|
83
|
+
labelEn: string;
|
|
84
|
+
};
|
|
85
|
+
export declare const GOAL_CATEGORY_DISPLAY: Record<TGoalCategory, TGoalCategoryDisplay>;
|
|
86
|
+
/**
|
|
87
|
+
* Derive the current training phase from the week number since goal start.
|
|
88
|
+
* Week is 1-indexed (week 1 = first week on the program).
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* derivePhase(1) // → 1 (Foundation)
|
|
92
|
+
* derivePhase(3) // → 2 (Momentum)
|
|
93
|
+
* derivePhase(7) // → 3 (Push)
|
|
94
|
+
* derivePhase(10) // → 4 (Peak)
|
|
95
|
+
*/
|
|
96
|
+
export declare function derivePhase(weekNumber: number): TTrainingPhase;
|
|
97
|
+
export declare const DAYS_PER_WEEK_OPTIONS: readonly [2, 3, 4, 5];
|
|
98
|
+
export type TDaysPerWeek = (typeof DAYS_PER_WEEK_OPTIONS)[number];
|
|
99
|
+
export type TDurationHint = "short" | "medium" | "long";
|
|
100
|
+
export type TWeeklyIntentTemplate = [
|
|
101
|
+
TSessionIntent,
|
|
102
|
+
TSessionIntent,
|
|
103
|
+
TSessionIntent,
|
|
104
|
+
TSessionIntent,
|
|
105
|
+
TSessionIntent,
|
|
106
|
+
TSessionIntent,
|
|
107
|
+
TSessionIntent
|
|
108
|
+
];
|
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DAYS_PER_WEEK_OPTIONS = exports.GOAL_CATEGORY_DISPLAY = exports.GOAL_DISPLAY = exports.INTENT_DISPLAY = exports.PHASE_DISPLAY = exports.TRAINING_PHASES = exports.GOAL_TO_AI_FITNESS_GOAL = exports.GOAL_SESSION_INTENTS = exports.USER_FITNESS_GOALS = void 0;
|
|
4
|
+
exports.derivePhase = derivePhase;
|
|
5
|
+
exports.USER_FITNESS_GOALS = [
|
|
6
|
+
// Appearance
|
|
7
|
+
"lose_weight",
|
|
8
|
+
"build_muscle",
|
|
9
|
+
"lean_and_toned",
|
|
10
|
+
"glutes_and_legs",
|
|
11
|
+
// Performance
|
|
12
|
+
"get_stronger",
|
|
13
|
+
"boost_endurance",
|
|
14
|
+
"athletic_performance",
|
|
15
|
+
// Health
|
|
16
|
+
"general_fitness",
|
|
17
|
+
"posture_and_back",
|
|
18
|
+
"stress_relief",
|
|
19
|
+
"rehabilitation",
|
|
20
|
+
// Focused
|
|
21
|
+
"core_strength",
|
|
22
|
+
"mobility_flexibility",
|
|
23
|
+
];
|
|
24
|
+
// The canonical weekly template per goal (7 slots, Mon→Sun)
|
|
25
|
+
// Phase-aware structures live in the app layer, not shared
|
|
26
|
+
// This is the "default" / Phase 2-3 reference structure
|
|
27
|
+
exports.GOAL_SESSION_INTENTS = {
|
|
28
|
+
lose_weight: [
|
|
29
|
+
"cardio",
|
|
30
|
+
"full-body",
|
|
31
|
+
"rest",
|
|
32
|
+
"cardio",
|
|
33
|
+
"full-body",
|
|
34
|
+
"cardio",
|
|
35
|
+
"rest",
|
|
36
|
+
],
|
|
37
|
+
build_muscle: ["push", "pull", "legs", "rest", "upper", "lower", "rest"],
|
|
38
|
+
lean_and_toned: [
|
|
39
|
+
"full-body",
|
|
40
|
+
"cardio",
|
|
41
|
+
"full-body",
|
|
42
|
+
"rest",
|
|
43
|
+
"full-body",
|
|
44
|
+
"cardio",
|
|
45
|
+
"rest",
|
|
46
|
+
],
|
|
47
|
+
glutes_and_legs: ["legs", "upper", "legs", "rest", "legs", "cardio", "rest"],
|
|
48
|
+
get_stronger: ["push", "pull", "legs", "rest", "push", "pull", "rest"],
|
|
49
|
+
boost_endurance: [
|
|
50
|
+
"cardio",
|
|
51
|
+
"legs",
|
|
52
|
+
"cardio",
|
|
53
|
+
"upper",
|
|
54
|
+
"cardio",
|
|
55
|
+
"full-body",
|
|
56
|
+
"rest",
|
|
57
|
+
],
|
|
58
|
+
athletic_performance: [
|
|
59
|
+
"legs",
|
|
60
|
+
"upper",
|
|
61
|
+
"cardio",
|
|
62
|
+
"core",
|
|
63
|
+
"full-body",
|
|
64
|
+
"rest",
|
|
65
|
+
"rest",
|
|
66
|
+
],
|
|
67
|
+
general_fitness: [
|
|
68
|
+
"full-body",
|
|
69
|
+
"rest",
|
|
70
|
+
"full-body",
|
|
71
|
+
"cardio",
|
|
72
|
+
"full-body",
|
|
73
|
+
"rest",
|
|
74
|
+
"rest",
|
|
75
|
+
],
|
|
76
|
+
posture_and_back: [
|
|
77
|
+
"pull",
|
|
78
|
+
"core",
|
|
79
|
+
"mobility",
|
|
80
|
+
"pull",
|
|
81
|
+
"core",
|
|
82
|
+
"mobility",
|
|
83
|
+
"rest",
|
|
84
|
+
],
|
|
85
|
+
stress_relief: [
|
|
86
|
+
"cardio",
|
|
87
|
+
"mobility",
|
|
88
|
+
"full-body",
|
|
89
|
+
"rest",
|
|
90
|
+
"cardio",
|
|
91
|
+
"mobility",
|
|
92
|
+
"rest",
|
|
93
|
+
],
|
|
94
|
+
rehabilitation: [
|
|
95
|
+
"mobility",
|
|
96
|
+
"core",
|
|
97
|
+
"mobility",
|
|
98
|
+
"rest",
|
|
99
|
+
"mobility",
|
|
100
|
+
"core",
|
|
101
|
+
"rest",
|
|
102
|
+
],
|
|
103
|
+
core_strength: ["core", "pull", "legs", "core", "push", "rest", "rest"],
|
|
104
|
+
mobility_flexibility: [
|
|
105
|
+
"mobility",
|
|
106
|
+
"full-body",
|
|
107
|
+
"mobility",
|
|
108
|
+
"rest",
|
|
109
|
+
"mobility",
|
|
110
|
+
"full-body",
|
|
111
|
+
"rest",
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
exports.GOAL_TO_AI_FITNESS_GOAL = {
|
|
115
|
+
lose_weight: "fat_loss",
|
|
116
|
+
build_muscle: "hypertrophy",
|
|
117
|
+
lean_and_toned: "fat_loss",
|
|
118
|
+
glutes_and_legs: "hypertrophy",
|
|
119
|
+
get_stronger: "strength",
|
|
120
|
+
boost_endurance: "endurance",
|
|
121
|
+
athletic_performance: "sport_performance",
|
|
122
|
+
general_fitness: "general_fitness",
|
|
123
|
+
posture_and_back: "strength",
|
|
124
|
+
stress_relief: "general_fitness",
|
|
125
|
+
rehabilitation: "rehabilitation",
|
|
126
|
+
core_strength: "core_strength",
|
|
127
|
+
mobility_flexibility: "mobility",
|
|
128
|
+
};
|
|
129
|
+
exports.TRAINING_PHASES = [1, 2, 3, 4];
|
|
130
|
+
exports.PHASE_DISPLAY = {
|
|
131
|
+
1: {
|
|
132
|
+
nameKey: "goalPhase.foundation.name",
|
|
133
|
+
nameEn: "Foundation",
|
|
134
|
+
subtitleKey: "goalPhase.foundation.subtitle",
|
|
135
|
+
subtitleEn: "Build the base",
|
|
136
|
+
purposeKey: "goalPhase.foundation.purpose",
|
|
137
|
+
purposeEn: "Preparing your joints, learning movement patterns, and building the work capacity for what's ahead. Every great physique starts here — don't skip it.",
|
|
138
|
+
durationKey: "goalPhase.foundation.duration",
|
|
139
|
+
durationEn: "Weeks 1–2",
|
|
140
|
+
weekRange: [1, 2],
|
|
141
|
+
intensityPercent: 40,
|
|
142
|
+
},
|
|
143
|
+
2: {
|
|
144
|
+
nameKey: "goalPhase.momentum.name",
|
|
145
|
+
nameEn: "Momentum",
|
|
146
|
+
subtitleKey: "goalPhase.momentum.subtitle",
|
|
147
|
+
subtitleEn: "Volume builds here",
|
|
148
|
+
purposeKey: "goalPhase.momentum.purpose",
|
|
149
|
+
purposeEn: "Your body has adapted. Now we increase the work. Splits begin, sessions get more specific. This is where the habit locks in.",
|
|
150
|
+
durationKey: "goalPhase.momentum.duration",
|
|
151
|
+
durationEn: "Weeks 3–5",
|
|
152
|
+
weekRange: [3, 5],
|
|
153
|
+
intensityPercent: 60,
|
|
154
|
+
},
|
|
155
|
+
3: {
|
|
156
|
+
nameKey: "goalPhase.push.name",
|
|
157
|
+
nameEn: "Push",
|
|
158
|
+
subtitleKey: "goalPhase.push.subtitle",
|
|
159
|
+
subtitleEn: "This is where change happens",
|
|
160
|
+
purposeKey: "goalPhase.push.purpose",
|
|
161
|
+
purposeEn: "Goal-specific intensity. Your muscles are conditioned — now we challenge them. Expect to feel this one.",
|
|
162
|
+
durationKey: "goalPhase.push.duration",
|
|
163
|
+
durationEn: "Weeks 6–8",
|
|
164
|
+
weekRange: [6, 8],
|
|
165
|
+
intensityPercent: 80,
|
|
166
|
+
},
|
|
167
|
+
4: {
|
|
168
|
+
nameKey: "goalPhase.peak.name",
|
|
169
|
+
nameEn: "Peak",
|
|
170
|
+
subtitleKey: "goalPhase.peak.subtitle",
|
|
171
|
+
subtitleEn: "Maximum output",
|
|
172
|
+
purposeKey: "goalPhase.peak.purpose",
|
|
173
|
+
purposeEn: "Highest specificity to your goal. You have earned this — now execute. A deload is built into the final week.",
|
|
174
|
+
durationKey: "goalPhase.peak.duration",
|
|
175
|
+
durationEn: "Weeks 9+",
|
|
176
|
+
weekRange: [9, 99],
|
|
177
|
+
intensityPercent: 95,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
exports.INTENT_DISPLAY = {
|
|
181
|
+
push: {
|
|
182
|
+
labelKey: "sessionIntent.push.label",
|
|
183
|
+
labelEn: "Push Day",
|
|
184
|
+
shortLabelKey: "sessionIntent.push.shortLabel",
|
|
185
|
+
shortLabelEn: "Push",
|
|
186
|
+
emoji: "💪",
|
|
187
|
+
},
|
|
188
|
+
pull: {
|
|
189
|
+
labelKey: "sessionIntent.pull.label",
|
|
190
|
+
labelEn: "Pull Day",
|
|
191
|
+
shortLabelKey: "sessionIntent.pull.shortLabel",
|
|
192
|
+
shortLabelEn: "Pull",
|
|
193
|
+
emoji: "🔗",
|
|
194
|
+
},
|
|
195
|
+
legs: {
|
|
196
|
+
labelKey: "sessionIntent.legs.label",
|
|
197
|
+
labelEn: "Leg Day",
|
|
198
|
+
shortLabelKey: "sessionIntent.legs.shortLabel",
|
|
199
|
+
shortLabelEn: "Legs",
|
|
200
|
+
emoji: "🦵",
|
|
201
|
+
},
|
|
202
|
+
lower: {
|
|
203
|
+
labelKey: "sessionIntent.lower.label",
|
|
204
|
+
labelEn: "Lower Body",
|
|
205
|
+
shortLabelKey: "sessionIntent.lower.shortLabel",
|
|
206
|
+
shortLabelEn: "Lower",
|
|
207
|
+
emoji: "🦵",
|
|
208
|
+
},
|
|
209
|
+
upper: {
|
|
210
|
+
labelKey: "sessionIntent.upper.label",
|
|
211
|
+
labelEn: "Upper Body",
|
|
212
|
+
shortLabelKey: "sessionIntent.upper.shortLabel",
|
|
213
|
+
shortLabelEn: "Upper",
|
|
214
|
+
emoji: "💪",
|
|
215
|
+
},
|
|
216
|
+
core: {
|
|
217
|
+
labelKey: "sessionIntent.core.label",
|
|
218
|
+
labelEn: "Core & Abs",
|
|
219
|
+
shortLabelKey: "sessionIntent.core.shortLabel",
|
|
220
|
+
shortLabelEn: "Core",
|
|
221
|
+
emoji: "⚡",
|
|
222
|
+
},
|
|
223
|
+
cardio: {
|
|
224
|
+
labelKey: "sessionIntent.cardio.label",
|
|
225
|
+
labelEn: "Cardio",
|
|
226
|
+
shortLabelKey: "sessionIntent.cardio.shortLabel",
|
|
227
|
+
shortLabelEn: "Cardio",
|
|
228
|
+
emoji: "🏃",
|
|
229
|
+
},
|
|
230
|
+
strength: {
|
|
231
|
+
labelKey: "sessionIntent.strength.label",
|
|
232
|
+
labelEn: "Strength",
|
|
233
|
+
shortLabelKey: "sessionIntent.strength.shortLabel",
|
|
234
|
+
shortLabelEn: "Strength",
|
|
235
|
+
emoji: "🏋️",
|
|
236
|
+
},
|
|
237
|
+
fatburn: {
|
|
238
|
+
labelKey: "sessionIntent.fatburn.label",
|
|
239
|
+
labelEn: "Fat Burn",
|
|
240
|
+
shortLabelKey: "sessionIntent.fatburn.shortLabel",
|
|
241
|
+
shortLabelEn: "Burn",
|
|
242
|
+
emoji: "🔥",
|
|
243
|
+
},
|
|
244
|
+
mobility: {
|
|
245
|
+
labelKey: "sessionIntent.mobility.label",
|
|
246
|
+
labelEn: "Mobility",
|
|
247
|
+
shortLabelKey: "sessionIntent.mobility.shortLabel",
|
|
248
|
+
shortLabelEn: "Mobility",
|
|
249
|
+
emoji: "🧘",
|
|
250
|
+
},
|
|
251
|
+
"full-body": {
|
|
252
|
+
labelKey: "sessionIntent.fullBody.label",
|
|
253
|
+
labelEn: "Full Body",
|
|
254
|
+
shortLabelKey: "sessionIntent.fullBody.shortLabel",
|
|
255
|
+
shortLabelEn: "Full",
|
|
256
|
+
emoji: "⭐",
|
|
257
|
+
},
|
|
258
|
+
rest: {
|
|
259
|
+
labelKey: "sessionIntent.rest.label",
|
|
260
|
+
labelEn: "Rest Day",
|
|
261
|
+
shortLabelKey: "sessionIntent.rest.shortLabel",
|
|
262
|
+
shortLabelEn: "Rest",
|
|
263
|
+
emoji: "😴",
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
exports.GOAL_DISPLAY = {
|
|
267
|
+
// ── Appearance ────────────────────────────────────────────────────────────
|
|
268
|
+
lose_weight: {
|
|
269
|
+
nameKey: "userGoal.loseWeight.name",
|
|
270
|
+
nameEn: "Lose Weight",
|
|
271
|
+
descriptionKey: "userGoal.loseWeight.description",
|
|
272
|
+
descriptionEn: "Burn fat and drop weight through cardio and full-body training.",
|
|
273
|
+
taglineKey: "userGoal.loseWeight.tagline",
|
|
274
|
+
taglineEn: "Every session burns, every week counts.",
|
|
275
|
+
emoji: "🔥",
|
|
276
|
+
category: "appearance",
|
|
277
|
+
},
|
|
278
|
+
build_muscle: {
|
|
279
|
+
nameKey: "userGoal.buildMuscle.name",
|
|
280
|
+
nameEn: "Build Muscle",
|
|
281
|
+
descriptionKey: "userGoal.buildMuscle.description",
|
|
282
|
+
descriptionEn: "Add size and strength with structured push, pull, and leg splits.",
|
|
283
|
+
taglineKey: "userGoal.buildMuscle.tagline",
|
|
284
|
+
taglineEn: "Progressive overload. Every rep builds the next.",
|
|
285
|
+
emoji: "💪",
|
|
286
|
+
category: "appearance",
|
|
287
|
+
},
|
|
288
|
+
lean_and_toned: {
|
|
289
|
+
nameKey: "userGoal.leanAndToned.name",
|
|
290
|
+
nameEn: "Get Lean & Toned",
|
|
291
|
+
descriptionKey: "userGoal.leanAndToned.description",
|
|
292
|
+
descriptionEn: "Burn fat while preserving muscle for a lean, defined look.",
|
|
293
|
+
taglineKey: "userGoal.leanAndToned.tagline",
|
|
294
|
+
taglineEn: "Defined. Lean. Confident.",
|
|
295
|
+
emoji: "✨",
|
|
296
|
+
category: "appearance",
|
|
297
|
+
},
|
|
298
|
+
glutes_and_legs: {
|
|
299
|
+
nameKey: "userGoal.glutesAndLegs.name",
|
|
300
|
+
nameEn: "Grow Glutes & Legs",
|
|
301
|
+
descriptionKey: "userGoal.glutesAndLegs.description",
|
|
302
|
+
descriptionEn: "Build powerful glutes and legs with targeted lower-body training.",
|
|
303
|
+
taglineKey: "userGoal.glutesAndLegs.tagline",
|
|
304
|
+
taglineEn: "Strong legs carry everything.",
|
|
305
|
+
emoji: "🦵",
|
|
306
|
+
category: "appearance",
|
|
307
|
+
},
|
|
308
|
+
// ── Performance ───────────────────────────────────────────────────────────
|
|
309
|
+
get_stronger: {
|
|
310
|
+
nameKey: "userGoal.getStronger.name",
|
|
311
|
+
nameEn: "Get Stronger",
|
|
312
|
+
descriptionKey: "userGoal.getStronger.description",
|
|
313
|
+
descriptionEn: "Build real-world strength through compound lifts and progressive overload.",
|
|
314
|
+
taglineKey: "userGoal.getStronger.tagline",
|
|
315
|
+
taglineEn: "Lift more. Be more.",
|
|
316
|
+
emoji: "🏋️",
|
|
317
|
+
category: "performance",
|
|
318
|
+
},
|
|
319
|
+
boost_endurance: {
|
|
320
|
+
nameKey: "userGoal.boostEndurance.name",
|
|
321
|
+
nameEn: "Build Endurance",
|
|
322
|
+
descriptionKey: "userGoal.boostEndurance.description",
|
|
323
|
+
descriptionEn: "Increase stamina and cardiovascular capacity through progressive cardio and leg work.",
|
|
324
|
+
taglineKey: "userGoal.boostEndurance.tagline",
|
|
325
|
+
taglineEn: "Go further. Last longer.",
|
|
326
|
+
emoji: "🏃",
|
|
327
|
+
category: "performance",
|
|
328
|
+
},
|
|
329
|
+
athletic_performance: {
|
|
330
|
+
nameKey: "userGoal.athleticPerformance.name",
|
|
331
|
+
nameEn: "Athletic Performance",
|
|
332
|
+
descriptionKey: "userGoal.athleticPerformance.description",
|
|
333
|
+
descriptionEn: "Train like an athlete — explosive power, speed, agility, and conditioning.",
|
|
334
|
+
taglineKey: "userGoal.athleticPerformance.tagline",
|
|
335
|
+
taglineEn: "Train hard. Perform harder.",
|
|
336
|
+
emoji: "⚡",
|
|
337
|
+
category: "performance",
|
|
338
|
+
},
|
|
339
|
+
// ── Health ────────────────────────────────────────────────────────────────
|
|
340
|
+
general_fitness: {
|
|
341
|
+
nameKey: "userGoal.generalFitness.name",
|
|
342
|
+
nameEn: "Stay Active & Healthy",
|
|
343
|
+
descriptionKey: "userGoal.generalFitness.description",
|
|
344
|
+
descriptionEn: "A balanced mix of strength, cardio, and mobility for a healthy, active lifestyle.",
|
|
345
|
+
taglineKey: "userGoal.generalFitness.tagline",
|
|
346
|
+
taglineEn: "Move well. Feel well. Live well.",
|
|
347
|
+
emoji: "🌟",
|
|
348
|
+
category: "health",
|
|
349
|
+
},
|
|
350
|
+
posture_and_back: {
|
|
351
|
+
nameKey: "userGoal.postureAndBack.name",
|
|
352
|
+
nameEn: "Fix Posture & Back",
|
|
353
|
+
descriptionKey: "userGoal.postureAndBack.description",
|
|
354
|
+
descriptionEn: "Strengthen the posterior chain and core to fix posture and eliminate back pain.",
|
|
355
|
+
taglineKey: "userGoal.postureAndBack.tagline",
|
|
356
|
+
taglineEn: "Stand tall. Move pain-free.",
|
|
357
|
+
emoji: "🧍",
|
|
358
|
+
category: "health",
|
|
359
|
+
},
|
|
360
|
+
stress_relief: {
|
|
361
|
+
nameKey: "userGoal.stressRelief.name",
|
|
362
|
+
nameEn: "Reduce Stress",
|
|
363
|
+
descriptionKey: "userGoal.stressRelief.description",
|
|
364
|
+
descriptionEn: "Use movement to reset your mind — cardio endorphins and mobility to decompress.",
|
|
365
|
+
taglineKey: "userGoal.stressRelief.tagline",
|
|
366
|
+
taglineEn: "Move it out. Breathe it out.",
|
|
367
|
+
emoji: "🧘",
|
|
368
|
+
category: "health",
|
|
369
|
+
},
|
|
370
|
+
rehabilitation: {
|
|
371
|
+
nameKey: "userGoal.rehabilitation.name",
|
|
372
|
+
nameEn: "Recover from Injury",
|
|
373
|
+
descriptionKey: "userGoal.rehabilitation.description",
|
|
374
|
+
descriptionEn: "Gentle, progressive sessions to rebuild strength and movement after injury.",
|
|
375
|
+
taglineKey: "userGoal.rehabilitation.tagline",
|
|
376
|
+
taglineEn: "Slow and steady. Built to last.",
|
|
377
|
+
emoji: "🩹",
|
|
378
|
+
category: "health",
|
|
379
|
+
},
|
|
380
|
+
// ── Focused ───────────────────────────────────────────────────────────────
|
|
381
|
+
core_strength: {
|
|
382
|
+
nameKey: "userGoal.coreStrength.name",
|
|
383
|
+
nameEn: "Build a Strong Core",
|
|
384
|
+
descriptionKey: "userGoal.coreStrength.description",
|
|
385
|
+
descriptionEn: "Develop deep core stability and strength — the foundation of every movement.",
|
|
386
|
+
taglineKey: "userGoal.coreStrength.tagline",
|
|
387
|
+
taglineEn: "Strong core. Strong everything.",
|
|
388
|
+
emoji: "🎯",
|
|
389
|
+
category: "focused",
|
|
390
|
+
},
|
|
391
|
+
mobility_flexibility: {
|
|
392
|
+
nameKey: "userGoal.mobilityFlexibility.name",
|
|
393
|
+
nameEn: "Improve Flexibility",
|
|
394
|
+
descriptionKey: "userGoal.mobilityFlexibility.description",
|
|
395
|
+
descriptionEn: "Increase range of motion and joint health through consistent mobility work.",
|
|
396
|
+
taglineKey: "userGoal.mobilityFlexibility.tagline",
|
|
397
|
+
taglineEn: "Move freely. Age well.",
|
|
398
|
+
emoji: "🌀",
|
|
399
|
+
category: "focused",
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
exports.GOAL_CATEGORY_DISPLAY = {
|
|
403
|
+
appearance: {
|
|
404
|
+
labelKey: "goalCategory.appearance.label",
|
|
405
|
+
labelEn: "Appearance",
|
|
406
|
+
},
|
|
407
|
+
performance: {
|
|
408
|
+
labelKey: "goalCategory.performance.label",
|
|
409
|
+
labelEn: "Performance",
|
|
410
|
+
},
|
|
411
|
+
health: {
|
|
412
|
+
labelKey: "goalCategory.health.label",
|
|
413
|
+
labelEn: "Health & Wellbeing",
|
|
414
|
+
},
|
|
415
|
+
focused: {
|
|
416
|
+
labelKey: "goalCategory.focused.label",
|
|
417
|
+
labelEn: "Focused Training",
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
// ---------------------------------------------------------------------------
|
|
421
|
+
// derivePhase — pure helper
|
|
422
|
+
// Shared between Lambda and client — lives here so neither duplicates it
|
|
423
|
+
// ---------------------------------------------------------------------------
|
|
424
|
+
/**
|
|
425
|
+
* Derive the current training phase from the week number since goal start.
|
|
426
|
+
* Week is 1-indexed (week 1 = first week on the program).
|
|
427
|
+
*
|
|
428
|
+
* @example
|
|
429
|
+
* derivePhase(1) // → 1 (Foundation)
|
|
430
|
+
* derivePhase(3) // → 2 (Momentum)
|
|
431
|
+
* derivePhase(7) // → 3 (Push)
|
|
432
|
+
* derivePhase(10) // → 4 (Peak)
|
|
433
|
+
*/
|
|
434
|
+
function derivePhase(weekNumber) {
|
|
435
|
+
if (weekNumber <= 2)
|
|
436
|
+
return 1;
|
|
437
|
+
if (weekNumber <= 5)
|
|
438
|
+
return 2;
|
|
439
|
+
if (weekNumber <= 8)
|
|
440
|
+
return 3;
|
|
441
|
+
return 4;
|
|
442
|
+
}
|
|
443
|
+
exports.DAYS_PER_WEEK_OPTIONS = [2, 3, 4, 5];
|
package/dist/constants/index.js
CHANGED
|
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./BodyCategories"), exports);
|
|
18
18
|
__exportStar(require("./AiExerciseVocabulary"), exports);
|
|
19
19
|
__exportStar(require("./quickStartIntents"), exports);
|
|
20
|
+
__exportStar(require("./goalJourney"), exports);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TAiMovementPattern } from "../constants";
|
|
1
2
|
export type TConfidence = "high" | "medium" | null;
|
|
2
3
|
export type TNameReviewStatus = "pending" | "approved";
|
|
3
4
|
export type TQdrantSyncStatus = "pending" | "synced" | "failed";
|
|
@@ -66,7 +67,7 @@ export type TApiAiExerciseAnalysis = {
|
|
|
66
67
|
exercise_name: string;
|
|
67
68
|
alternative_names: string[];
|
|
68
69
|
movement_description: string;
|
|
69
|
-
movement_pattern:
|
|
70
|
+
movement_pattern: TAiMovementPattern;
|
|
70
71
|
exercise_type: string;
|
|
71
72
|
contraction_type: string;
|
|
72
73
|
plane_of_motion: string[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================================
|
|
3
|
+
* API CONTRACT — Client Constellation
|
|
4
|
+
* ============================================================================
|
|
5
|
+
*
|
|
6
|
+
* Request/response types for GET /api/constellation. The response is the
|
|
7
|
+
* render-ready TConstellationState produced by the constellation util; these
|
|
8
|
+
* types are re-exported here so the backend (and app) consume one stable
|
|
9
|
+
* contract from the published package.
|
|
10
|
+
*/
|
|
11
|
+
import type { TConstellationState } from "../utils/constellation/types";
|
|
12
|
+
export type { TConstellationState };
|
|
13
|
+
/**
|
|
14
|
+
* Request: no body. The user is resolved from the JWT. `level` is optional and
|
|
15
|
+
* may be supplied as a query param to preview a specific level; it defaults to
|
|
16
|
+
* the user's current level (1) and is clamped to a valid level server-side.
|
|
17
|
+
*/
|
|
18
|
+
export type TApiClientConstellationReq = {
|
|
19
|
+
level?: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Response envelope, matching the shape your other controllers return
|
|
23
|
+
* (status + state + message) with the constellation payload under `data`.
|
|
24
|
+
*/
|
|
25
|
+
export type TApiClientConstellationRes = {
|
|
26
|
+
status: 200;
|
|
27
|
+
state: "success";
|
|
28
|
+
data: TConstellationState;
|
|
29
|
+
} | {
|
|
30
|
+
status: 401 | 500;
|
|
31
|
+
state: "failed";
|
|
32
|
+
message: string;
|
|
33
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// shared/src/types/TApiClientConstellation.ts
|
|
3
|
+
/**
|
|
4
|
+
* ============================================================================
|
|
5
|
+
* API CONTRACT — Client Constellation
|
|
6
|
+
* ============================================================================
|
|
7
|
+
*
|
|
8
|
+
* Request/response types for GET /api/constellation. The response is the
|
|
9
|
+
* render-ready TConstellationState produced by the constellation util; these
|
|
10
|
+
* types are re-exported here so the backend (and app) consume one stable
|
|
11
|
+
* contract from the published package.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TAiMovementPattern } from "../constants";
|
|
1
2
|
import { TRecord } from "./commonTypes";
|
|
2
3
|
export type TBodyPart = "Chest" | "Core" | "Shoulders" | "Back" | "Biceps" | "Triceps" | "Forearms" | "Legs" | "Glutes" | "Calves" | "Hamstrings" | "Quadriceps" | "Lower Back" | "Trapezius";
|
|
3
4
|
export declare enum EBodyParts {
|
|
@@ -141,9 +142,10 @@ export type TExercise = {
|
|
|
141
142
|
female: number;
|
|
142
143
|
default: number;
|
|
143
144
|
};
|
|
144
|
-
movementPattern
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
movementPattern: TAiMovementPattern;
|
|
146
|
+
exerciseType: "isolation" | "compound" | "bodyweight" | "mobility" | "plyometric" | "isometric" | "cardio";
|
|
147
|
+
stabilityDemand: "low" | "moderate" | "high";
|
|
148
|
+
progressionTier: "beginner" | "intermediate" | "advanced" | "elite";
|
|
147
149
|
};
|
|
148
150
|
export type TBodyPartExercises = Record<TBodyPart, TExercise[]>;
|
|
149
151
|
export type TApiCreateOrUpdateExerciseReq = {
|
package/dist/types/TApiUser.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TAiFitnessGoal, TAiUserInjury } from "../constants/AiExerciseVocabulary";
|
|
2
|
+
import { TConstellationUserLevel } from "../utils";
|
|
2
3
|
import { TGdprData } from "./commonTypes";
|
|
3
4
|
import { TUserPreferences } from "./TUserPreferences";
|
|
4
5
|
export type TAuthType = "email" | "apple" | "anonymous" | "token";
|
|
@@ -37,6 +38,7 @@ export type TUserMetric = TUserPreferences & {
|
|
|
37
38
|
subscriptionStore: TAppStore;
|
|
38
39
|
subscriptionLastUpdatedAt: number;
|
|
39
40
|
gdpr: TGdprData;
|
|
41
|
+
constellationLevel: TConstellationUserLevel;
|
|
40
42
|
createdAt: Date;
|
|
41
43
|
updatedAt?: Date;
|
|
42
44
|
};
|
package/dist/types/index.d.ts
CHANGED