@dgpholdings/greatoak-shared 1.2.85 → 1.2.87
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__/exercises.mock.js +1 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/constants/quickStartIntents.d.ts +19 -0
- package/dist/constants/quickStartIntents.js +39 -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/index.d.ts +1 -0
- package/dist/utils/constellation/computeNormalisedLoad.d.ts +48 -0
- package/dist/utils/constellation/computeNormalisedLoad.js +150 -0
- package/dist/utils/constellation/evaluateConstellation.d.ts +27 -0
- package/dist/utils/constellation/evaluateConstellation.js +135 -0
- package/dist/utils/constellation/index.d.ts +17 -0
- package/dist/utils/constellation/index.js +26 -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/stars/consistency.d.ts +29 -0
- package/dist/utils/constellation/stars/consistency.js +142 -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/recovery.d.ts +29 -0
- package/dist/utils/constellation/stars/recovery.js +169 -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/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 +210 -172
- 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
package/README.md
CHANGED
|
@@ -1,149 +1,149 @@
|
|
|
1
|
-
# @dgpholdings/greatoak-shared
|
|
2
|
-
|
|
3
|
-
The shared library for the Fitfrix ecosystem. Contains all types, utilities, and the scoring engine used across:
|
|
4
|
-
|
|
5
|
-
- `v2/fitfrix` — the mobile app (React Native / Expo)
|
|
6
|
-
- `backend/api-service` — the NestJS backend
|
|
7
|
-
- `fitfrix.com` — the web/landing (Vite + React)
|
|
8
|
-
|
|
9
|
-
Any type, constant, or utility that is used by more than one package lives here. If you're about to define a type locally in a consuming app — check here first.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Install / Import
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
// Types
|
|
17
|
-
import type { TExercise, TRecord, TUserMetric } from '@dgpholdings/greatoak-shared';
|
|
18
|
-
|
|
19
|
-
// Utils
|
|
20
|
-
import { calculateExerciseScoreV2, calculateTotalVolume, isDefined, toError } from '@dgpholdings/greatoak-shared';
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## What's Inside
|
|
26
|
-
|
|
27
|
-
| Category | Location | Doc |
|
|
28
|
-
|---|---|---|
|
|
29
|
-
| **Types** | `src/types/` | [docs/types.md](docs/types.md) |
|
|
30
|
-
| **Utils** | `src/utils/` | [docs/utils.md](docs/utils.md) |
|
|
31
|
-
| **Scoring Engine** | `src/utils/scoring/` | [docs/scoring.md](docs/scoring.md) |
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Types — Quick Reference
|
|
36
|
-
|
|
37
|
-
| File | What it defines |
|
|
38
|
-
|---|---|
|
|
39
|
-
| `commonTypes.ts` | `TRecord`, `TExerciseConfig`, `TTemplateExercise`, `TGdprData`, `TDayKey` |
|
|
40
|
-
| `TApiExercise.ts` | `TExercise`, `TBodyPart`, `EBodyParts`, `TTrainingType`, `TTimingGuardrails` |
|
|
41
|
-
| `TApiUser.ts` | `TUserMetric`, `TFitnessGoal`, `TUserType`, `TSubscriptionStatus`, `TGender` |
|
|
42
|
-
| `TApiAuth.ts` | Signup/signin request & response types (`TApiSignupAnonymousReq`, `TSignInRes`, etc.) |
|
|
43
|
-
| `TApiExerciseRecord.ts` | Record save/fetch request & response types |
|
|
44
|
-
| `TApiTemplateData.ts` | `TTemplate`, `TTemplateDb`, `TTemplateData`, `TExerciseLatestRecord` |
|
|
45
|
-
| `TApiProPlan.ts` | `TProPlan`, pro plan CRUD request & response types |
|
|
46
|
-
| `TApiTemplateShop.ts` | `TTemplateShopDb`, shop CRUD & shared plan types |
|
|
47
|
-
| `TApiBillingPlan.ts` | `TBillingPlan`, `TBillingCountries`, billing API types |
|
|
48
|
-
| `TApiRevenueCat.ts` | `TApiRevenueCatWebhookReq`, RevenueCat event types |
|
|
49
|
-
| `TApiClientProgress.ts` | `TClientWorkoutHistory`, trainer dashboard types |
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## Utils — Quick Reference
|
|
54
|
-
|
|
55
|
-
| Export | What it does |
|
|
56
|
-
|---|---|
|
|
57
|
-
| `calculateExerciseScoreV2` | Full exercise scoring → `{ score, muscleScores }` |
|
|
58
|
-
| `calculateTotalVolume` | Total workout volume for charts |
|
|
59
|
-
| `isDefined` / `isDefinedNumber` | Null/undefined type guards |
|
|
60
|
-
| `toError` | Converts unknown catch values to `Error` |
|
|
61
|
-
| `toNumber` | Safe string/number → `number \| undefined` |
|
|
62
|
-
| `mmssToSecs` | `"MM:SS"` → seconds |
|
|
63
|
-
| `getDaysAndHoursDifference` | Date diff → `{ days, hours }` |
|
|
64
|
-
| `isUserAllowedToUpdate` | Profile update rate-limit guard |
|
|
65
|
-
| `countryToCurrencyCode` | Country code → ISO currency string |
|
|
66
|
-
| `slugifyText` | Text → URL-safe slug |
|
|
67
|
-
| `generatePlanCode` | Generates a unique 9-char Crockford Base32 plan code |
|
|
68
|
-
| `maskEmail` / `isEmail` / `isAnonymousEmail` | Email utilities |
|
|
69
|
-
| `NOOP` | Empty function `() => {}` |
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## Source Structure
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
shared/
|
|
77
|
-
├── src/
|
|
78
|
-
│ ├── types/
|
|
79
|
-
│ │ ├── index.ts # Re-exports all types
|
|
80
|
-
│ │ ├── commonTypes.ts # TRecord, TExerciseConfig, TTemplateExercise, TGdprData, TDayKey
|
|
81
|
-
│ │ ├── TApiExercise.ts # TExercise and related
|
|
82
|
-
│ │ ├── TApiUser.ts # TUserMetric and related
|
|
83
|
-
│ │ ├── TApiAuth.ts # Auth flows
|
|
84
|
-
│ │ ├── TApiExerciseRecord.ts # Workout record save/fetch
|
|
85
|
-
│ │ ├── TApiTemplateData.ts # User workout templates
|
|
86
|
-
│ │ ├── TApiProPlan.ts # Pro/trainer plans
|
|
87
|
-
│ │ ├── TApiTemplateShop.ts # Template shop (legacy, see TApiProPlan)
|
|
88
|
-
│ │ ├── TApiBillingPlan.ts # Billing plans
|
|
89
|
-
│ │ ├── TApiRevenueCat.ts # In-app purchase webhooks
|
|
90
|
-
│ │ └── TApiClientProgress.ts # Trainer client tracking
|
|
91
|
-
│ └── utils/
|
|
92
|
-
│ ├── index.ts # Re-exports all utils
|
|
93
|
-
│ ├── billing.utils.ts
|
|
94
|
-
│ ├── email.utils.ts
|
|
95
|
-
│ ├── isDefined.utils.ts
|
|
96
|
-
│ ├── noop.utils.ts
|
|
97
|
-
│ ├── number.util.ts
|
|
98
|
-
│ ├── planCode.util.ts
|
|
99
|
-
│ ├── slugify.util.ts
|
|
100
|
-
│ ├── time.util.ts
|
|
101
|
-
│ ├── toError.util.ts
|
|
102
|
-
│ └── scoring/ # Exercise scoring engine
|
|
103
|
-
│ └── README.md # Full scoring documentation
|
|
104
|
-
├── docs/
|
|
105
|
-
│ ├── types.md # All types documented in detail
|
|
106
|
-
│ ├── utils.md # All utils documented with examples
|
|
107
|
-
│ └── scoring.md # Scoring system overview
|
|
108
|
-
└── README.md # This file
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
## Key Design Rules
|
|
114
|
-
|
|
115
|
-
- **No local duplication** — if a type or utility is needed by ≥2 packages, it belongs here
|
|
116
|
-
- **No framework code** — this package must stay framework-agnostic (no React, no NestJS decorators)
|
|
117
|
-
- **Strict types** — no `any`. Use generics, discriminated unions, or `unknown`
|
|
118
|
-
- **Scoring is the business core** — the scoring engine drives the muscle fatigue diagram and progress charts. Read [docs/scoring.md](docs/scoring.md) before touching it
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
## Renewing token
|
|
122
|
-
|
|
123
|
-
1. Login using the token (recommended way)
|
|
124
|
-
|
|
125
|
-
In your Git Bash, run:
|
|
126
|
-
|
|
127
|
-
`npm login`
|
|
128
|
-
|
|
129
|
-
It will prompt:
|
|
130
|
-
|
|
131
|
-
Username:
|
|
132
|
-
Password:
|
|
133
|
-
Email:
|
|
134
|
-
|
|
135
|
-
Use this:
|
|
136
|
-
|
|
137
|
-
Username → your npm username
|
|
138
|
-
|
|
139
|
-
Password → paste the granular token (NOT your npm password)
|
|
140
|
-
|
|
141
|
-
Email → your npm email
|
|
142
|
-
|
|
143
|
-
After that, npm stores the token in:
|
|
144
|
-
|
|
145
|
-
`shared\.npmrc`
|
|
146
|
-
|
|
147
|
-
Then publishing works normally:
|
|
148
|
-
|
|
1
|
+
# @dgpholdings/greatoak-shared
|
|
2
|
+
|
|
3
|
+
The shared library for the Fitfrix ecosystem. Contains all types, utilities, and the scoring engine used across:
|
|
4
|
+
|
|
5
|
+
- `v2/fitfrix` — the mobile app (React Native / Expo)
|
|
6
|
+
- `backend/api-service` — the NestJS backend
|
|
7
|
+
- `fitfrix.com` — the web/landing (Vite + React)
|
|
8
|
+
|
|
9
|
+
Any type, constant, or utility that is used by more than one package lives here. If you're about to define a type locally in a consuming app — check here first.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Install / Import
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
// Types
|
|
17
|
+
import type { TExercise, TRecord, TUserMetric } from '@dgpholdings/greatoak-shared';
|
|
18
|
+
|
|
19
|
+
// Utils
|
|
20
|
+
import { calculateExerciseScoreV2, calculateTotalVolume, isDefined, toError } from '@dgpholdings/greatoak-shared';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## What's Inside
|
|
26
|
+
|
|
27
|
+
| Category | Location | Doc |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| **Types** | `src/types/` | [docs/types.md](docs/types.md) |
|
|
30
|
+
| **Utils** | `src/utils/` | [docs/utils.md](docs/utils.md) |
|
|
31
|
+
| **Scoring Engine** | `src/utils/scoring/` | [docs/scoring.md](docs/scoring.md) |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Types — Quick Reference
|
|
36
|
+
|
|
37
|
+
| File | What it defines |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `commonTypes.ts` | `TRecord`, `TExerciseConfig`, `TTemplateExercise`, `TGdprData`, `TDayKey` |
|
|
40
|
+
| `TApiExercise.ts` | `TExercise`, `TBodyPart`, `EBodyParts`, `TTrainingType`, `TTimingGuardrails` |
|
|
41
|
+
| `TApiUser.ts` | `TUserMetric`, `TFitnessGoal`, `TUserType`, `TSubscriptionStatus`, `TGender` |
|
|
42
|
+
| `TApiAuth.ts` | Signup/signin request & response types (`TApiSignupAnonymousReq`, `TSignInRes`, etc.) |
|
|
43
|
+
| `TApiExerciseRecord.ts` | Record save/fetch request & response types |
|
|
44
|
+
| `TApiTemplateData.ts` | `TTemplate`, `TTemplateDb`, `TTemplateData`, `TExerciseLatestRecord` |
|
|
45
|
+
| `TApiProPlan.ts` | `TProPlan`, pro plan CRUD request & response types |
|
|
46
|
+
| `TApiTemplateShop.ts` | `TTemplateShopDb`, shop CRUD & shared plan types |
|
|
47
|
+
| `TApiBillingPlan.ts` | `TBillingPlan`, `TBillingCountries`, billing API types |
|
|
48
|
+
| `TApiRevenueCat.ts` | `TApiRevenueCatWebhookReq`, RevenueCat event types |
|
|
49
|
+
| `TApiClientProgress.ts` | `TClientWorkoutHistory`, trainer dashboard types |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Utils — Quick Reference
|
|
54
|
+
|
|
55
|
+
| Export | What it does |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `calculateExerciseScoreV2` | Full exercise scoring → `{ score, muscleScores }` |
|
|
58
|
+
| `calculateTotalVolume` | Total workout volume for charts |
|
|
59
|
+
| `isDefined` / `isDefinedNumber` | Null/undefined type guards |
|
|
60
|
+
| `toError` | Converts unknown catch values to `Error` |
|
|
61
|
+
| `toNumber` | Safe string/number → `number \| undefined` |
|
|
62
|
+
| `mmssToSecs` | `"MM:SS"` → seconds |
|
|
63
|
+
| `getDaysAndHoursDifference` | Date diff → `{ days, hours }` |
|
|
64
|
+
| `isUserAllowedToUpdate` | Profile update rate-limit guard |
|
|
65
|
+
| `countryToCurrencyCode` | Country code → ISO currency string |
|
|
66
|
+
| `slugifyText` | Text → URL-safe slug |
|
|
67
|
+
| `generatePlanCode` | Generates a unique 9-char Crockford Base32 plan code |
|
|
68
|
+
| `maskEmail` / `isEmail` / `isAnonymousEmail` | Email utilities |
|
|
69
|
+
| `NOOP` | Empty function `() => {}` |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Source Structure
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
shared/
|
|
77
|
+
├── src/
|
|
78
|
+
│ ├── types/
|
|
79
|
+
│ │ ├── index.ts # Re-exports all types
|
|
80
|
+
│ │ ├── commonTypes.ts # TRecord, TExerciseConfig, TTemplateExercise, TGdprData, TDayKey
|
|
81
|
+
│ │ ├── TApiExercise.ts # TExercise and related
|
|
82
|
+
│ │ ├── TApiUser.ts # TUserMetric and related
|
|
83
|
+
│ │ ├── TApiAuth.ts # Auth flows
|
|
84
|
+
│ │ ├── TApiExerciseRecord.ts # Workout record save/fetch
|
|
85
|
+
│ │ ├── TApiTemplateData.ts # User workout templates
|
|
86
|
+
│ │ ├── TApiProPlan.ts # Pro/trainer plans
|
|
87
|
+
│ │ ├── TApiTemplateShop.ts # Template shop (legacy, see TApiProPlan)
|
|
88
|
+
│ │ ├── TApiBillingPlan.ts # Billing plans
|
|
89
|
+
│ │ ├── TApiRevenueCat.ts # In-app purchase webhooks
|
|
90
|
+
│ │ └── TApiClientProgress.ts # Trainer client tracking
|
|
91
|
+
│ └── utils/
|
|
92
|
+
│ ├── index.ts # Re-exports all utils
|
|
93
|
+
│ ├── billing.utils.ts
|
|
94
|
+
│ ├── email.utils.ts
|
|
95
|
+
│ ├── isDefined.utils.ts
|
|
96
|
+
│ ├── noop.utils.ts
|
|
97
|
+
│ ├── number.util.ts
|
|
98
|
+
│ ├── planCode.util.ts
|
|
99
|
+
│ ├── slugify.util.ts
|
|
100
|
+
│ ├── time.util.ts
|
|
101
|
+
│ ├── toError.util.ts
|
|
102
|
+
│ └── scoring/ # Exercise scoring engine
|
|
103
|
+
│ └── README.md # Full scoring documentation
|
|
104
|
+
├── docs/
|
|
105
|
+
│ ├── types.md # All types documented in detail
|
|
106
|
+
│ ├── utils.md # All utils documented with examples
|
|
107
|
+
│ └── scoring.md # Scoring system overview
|
|
108
|
+
└── README.md # This file
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Key Design Rules
|
|
114
|
+
|
|
115
|
+
- **No local duplication** — if a type or utility is needed by ≥2 packages, it belongs here
|
|
116
|
+
- **No framework code** — this package must stay framework-agnostic (no React, no NestJS decorators)
|
|
117
|
+
- **Strict types** — no `any`. Use generics, discriminated unions, or `unknown`
|
|
118
|
+
- **Scoring is the business core** — the scoring engine drives the muscle fatigue diagram and progress charts. Read [docs/scoring.md](docs/scoring.md) before touching it
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
## Renewing token
|
|
122
|
+
|
|
123
|
+
1. Login using the token (recommended way)
|
|
124
|
+
|
|
125
|
+
In your Git Bash, run:
|
|
126
|
+
|
|
127
|
+
`npm login`
|
|
128
|
+
|
|
129
|
+
It will prompt:
|
|
130
|
+
|
|
131
|
+
Username:
|
|
132
|
+
Password:
|
|
133
|
+
Email:
|
|
134
|
+
|
|
135
|
+
Use this:
|
|
136
|
+
|
|
137
|
+
Username → your npm username
|
|
138
|
+
|
|
139
|
+
Password → paste the granular token (NOT your npm password)
|
|
140
|
+
|
|
141
|
+
Email → your npm email
|
|
142
|
+
|
|
143
|
+
After that, npm stores the token in:
|
|
144
|
+
|
|
145
|
+
`shared\.npmrc`
|
|
146
|
+
|
|
147
|
+
Then publishing works normally:
|
|
148
|
+
|
|
149
149
|
`npm publish`
|
|
@@ -5,6 +5,7 @@ exports.mockExercisesDictionary = exports.mockExerciseNoGuardrails = exports.moc
|
|
|
5
5
|
* MOCK EXERCISE: Weight-Reps
|
|
6
6
|
* Simulates a standard compound lift (e.g., Barbell Squat).
|
|
7
7
|
*/
|
|
8
|
+
// @ts-ignore
|
|
8
9
|
exports.mockExerciseWeightReps = {
|
|
9
10
|
exerciseId: "mock-exercise-weight-reps-123",
|
|
10
11
|
name: "Generic Barbell Squat",
|
package/dist/constants/index.js
CHANGED
|
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./BodyCategories"), exports);
|
|
18
18
|
__exportStar(require("./AiExerciseVocabulary"), exports);
|
|
19
|
+
__exportStar(require("./quickStartIntents"), exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const QUICK_START_CLEAR_INTENTS: {
|
|
2
|
+
readonly push: "push";
|
|
3
|
+
readonly pull: "pull";
|
|
4
|
+
readonly core: "core";
|
|
5
|
+
readonly legs: "legs";
|
|
6
|
+
readonly upper: "upper";
|
|
7
|
+
readonly lower: "lower";
|
|
8
|
+
readonly cardio: "cardio";
|
|
9
|
+
readonly strength: "strength";
|
|
10
|
+
readonly fatburn: "fatburn";
|
|
11
|
+
readonly mobility: "mobility";
|
|
12
|
+
readonly fullBody: "full-body";
|
|
13
|
+
};
|
|
14
|
+
export declare const QUICK_START_INTENT_PREFIX_SEPARATOR = ": ";
|
|
15
|
+
/**
|
|
16
|
+
* Inverse map: chip-key strings ("full-body", "push") → TWorkoutType[].
|
|
17
|
+
* Order in the array matters when an intent maps to multiple types.
|
|
18
|
+
*/
|
|
19
|
+
export declare const QUICK_START_INTENT_TO_WORKOUT_TYPE: Record<(typeof QUICK_START_CLEAR_INTENTS)[keyof typeof QUICK_START_CLEAR_INTENTS], string[]>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// shared/src/constants/quickStartIntents.ts
|
|
3
|
+
//
|
|
4
|
+
// Shared between Quick Plan frontend (IntentInput chips) and backend (worker).
|
|
5
|
+
// When the frontend prefixes intentText with one of these keys followed by ":",
|
|
6
|
+
// the backend skips intent classification (Haiku) and uses the prefix directly.
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.QUICK_START_INTENT_TO_WORKOUT_TYPE = exports.QUICK_START_INTENT_PREFIX_SEPARATOR = exports.QUICK_START_CLEAR_INTENTS = void 0;
|
|
9
|
+
exports.QUICK_START_CLEAR_INTENTS = {
|
|
10
|
+
push: "push",
|
|
11
|
+
pull: "pull",
|
|
12
|
+
core: "core",
|
|
13
|
+
legs: "legs",
|
|
14
|
+
upper: "upper",
|
|
15
|
+
lower: "lower",
|
|
16
|
+
cardio: "cardio",
|
|
17
|
+
strength: "strength",
|
|
18
|
+
fatburn: "fatburn",
|
|
19
|
+
mobility: "mobility",
|
|
20
|
+
fullBody: "full-body",
|
|
21
|
+
};
|
|
22
|
+
exports.QUICK_START_INTENT_PREFIX_SEPARATOR = ": ";
|
|
23
|
+
/**
|
|
24
|
+
* Inverse map: chip-key strings ("full-body", "push") → TWorkoutType[].
|
|
25
|
+
* Order in the array matters when an intent maps to multiple types.
|
|
26
|
+
*/
|
|
27
|
+
exports.QUICK_START_INTENT_TO_WORKOUT_TYPE = {
|
|
28
|
+
push: ["push"],
|
|
29
|
+
pull: ["pull"],
|
|
30
|
+
core: ["core"],
|
|
31
|
+
legs: ["legs"],
|
|
32
|
+
upper: ["upper"],
|
|
33
|
+
lower: ["lower"],
|
|
34
|
+
cardio: ["cardio"],
|
|
35
|
+
strength: ["strength"],
|
|
36
|
+
fatburn: ["fatburn"],
|
|
37
|
+
mobility: ["mobility"],
|
|
38
|
+
"full-body": ["full-body"],
|
|
39
|
+
};
|
|
@@ -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/index.d.ts
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================================
|
|
3
|
+
* FITFRIX CONSTELLATION — Normalised Load (strength-star helper)
|
|
4
|
+
* ============================================================================
|
|
5
|
+
*
|
|
6
|
+
* Turns a user's sessions into a single strength number for a movement pattern:
|
|
7
|
+
* the best estimated-1RM achieved on any matching exercise in the rolling
|
|
8
|
+
* window, expressed as a ratio of bodyweight.
|
|
9
|
+
*
|
|
10
|
+
* Estimated-1RM (Epley, rep-capped at 12) is used instead of raw top weight so
|
|
11
|
+
* that 60kg x5 ~ 70kg x1 — it rewards productive training over ego-lifting.
|
|
12
|
+
*
|
|
13
|
+
* Bodyweight loading (the home-user path): a bodyweight exercise's effective
|
|
14
|
+
* load is the REAL fraction of bodyweight it moves, taken from the exercise's
|
|
15
|
+
* own `weightMultiplier` (per-sex), falling back to a coarse map keyed off
|
|
16
|
+
* `bodyweightDependency`. This is what lets a home user honestly reach a
|
|
17
|
+
* strength threshold with pull-ups / pistol squats etc., instead of being
|
|
18
|
+
* capped by a flat guess.
|
|
19
|
+
*
|
|
20
|
+
* Returns a bodyweight ratio (e.g. 0.78 = "0.78x bodyweight"). 0 = no data.
|
|
21
|
+
*/
|
|
22
|
+
import type { TExercise } from "../../types";
|
|
23
|
+
import type { TSessionRecord } from "./types";
|
|
24
|
+
/** Epley reps cap: reps beyond this don't increase the 1RM estimate. */
|
|
25
|
+
export declare const EPLEY_REP_CAP = 12;
|
|
26
|
+
/** Estimated 1RM via Epley, with reps capped to avoid endurance-range inflation. */
|
|
27
|
+
export declare function estimateOneRepMax(weightKg: number, reps: number): number;
|
|
28
|
+
export interface INormalisedLoadResult {
|
|
29
|
+
/** Best estimated-1RM in the window as a ratio of bodyweight. 0 if none. */
|
|
30
|
+
ratio: number;
|
|
31
|
+
/** The raw best estimated-1RM in kg (pre-normalisation), for detail display. */
|
|
32
|
+
bestOneRepMaxKg: number;
|
|
33
|
+
/** Exercise id that produced the best load (for "your best: Bench Press"). */
|
|
34
|
+
bestExerciseId?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Compute the best normalised load for a set of matching exercises within the
|
|
38
|
+
* window.
|
|
39
|
+
*
|
|
40
|
+
* @param matchingExerciseIds Exercise ids belonging to the target pattern.
|
|
41
|
+
* @param sessions All sessions.
|
|
42
|
+
* @param exerciseCatalog Full catalog (unfiltered).
|
|
43
|
+
* @param bodyweightKg User bodyweight (falls back to default).
|
|
44
|
+
* @param gender User sex (selects the weightMultiplier column).
|
|
45
|
+
* @param windowStartMs Only sessions on/after this count.
|
|
46
|
+
* @param now Upper bound (sessions after `now` ignored).
|
|
47
|
+
*/
|
|
48
|
+
export declare function computeNormalisedLoad(matchingExerciseIds: Set<string>, sessions: TSessionRecord[], exerciseCatalog: Record<string, TExercise>, bodyweightKg: number, gender: string | undefined, windowStartMs: number, now: number): INormalisedLoadResult;
|