@strong-together/shared 1.0.5
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 +612 -0
- package/dist/index.d.mts +5904 -0
- package/dist/index.d.ts +5904 -0
- package/dist/index.js +666 -0
- package/dist/index.mjs +559 -0
- package/package.json +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
# @strong-together/shared (v1.0.3)
|
|
2
|
+
|
|
3
|
+
Shared TypeScript library for the Strong Together ecosystem.
|
|
4
|
+
|
|
5
|
+
It centralizes:
|
|
6
|
+
|
|
7
|
+
- `zod` request/response schemas
|
|
8
|
+
- API contract types inferred from schemas
|
|
9
|
+
- DTOs and entity interfaces
|
|
10
|
+
- barrel exports for all modules
|
|
11
|
+
|
|
12
|
+
## Modules
|
|
13
|
+
|
|
14
|
+
The library currently exports these module groups from [`src/index.ts`](./src/index.ts):
|
|
15
|
+
|
|
16
|
+
- `aerobics`
|
|
17
|
+
- `analytics`
|
|
18
|
+
- `auth`
|
|
19
|
+
- `bootstrap`
|
|
20
|
+
- `exercises`
|
|
21
|
+
- `messages`
|
|
22
|
+
- `oauth`
|
|
23
|
+
- `push`
|
|
24
|
+
- `user`
|
|
25
|
+
- `video-analysis`
|
|
26
|
+
- `web-sockets`
|
|
27
|
+
- `workout`
|
|
28
|
+
|
|
29
|
+
## Structure
|
|
30
|
+
|
|
31
|
+
Most modules follow this shape:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
src/modules/<module>
|
|
35
|
+
├─ index.ts
|
|
36
|
+
├─ <module>.schemas.ts
|
|
37
|
+
├─ <module>.contracts.ts
|
|
38
|
+
├─ <module>.dtos.ts
|
|
39
|
+
└─ <module>.entities.ts
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Nested modules also expose submodule barrels:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
src/modules/<module>/<submodule>
|
|
46
|
+
├─ index.ts
|
|
47
|
+
├─ <submodule>.schemas.ts
|
|
48
|
+
├─ <submodule>.contracts.ts
|
|
49
|
+
├─ <submodule>.dtos.ts
|
|
50
|
+
└─ <submodule>.entities.ts
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install @strong-together/shared
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Build
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm run build
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Build output is generated into `dist/`:
|
|
66
|
+
|
|
67
|
+
- `dist/index.js`
|
|
68
|
+
- `dist/index.mjs`
|
|
69
|
+
- `dist/index.d.ts`
|
|
70
|
+
- `dist/index.d.mts`
|
|
71
|
+
|
|
72
|
+
## Development
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npm run dev
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
Import from the package root:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { loginRequest, type LoginRequestBody, updateUserRequest, type UpdateUserBody } from '@strong-together/shared';
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Validate runtime payloads with `zod` schemas:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const parsed = loginRequest.parse({
|
|
90
|
+
body: {
|
|
91
|
+
identifier: 'demo@example.com',
|
|
92
|
+
password: 'secret123',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Use inferred contracts for compile-time safety:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
const payload: UpdateUserBody = {
|
|
101
|
+
username: 'new_username',
|
|
102
|
+
};
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Type System
|
|
106
|
+
|
|
107
|
+
This library separates its exported TypeScript shapes into a few clear layers.
|
|
108
|
+
|
|
109
|
+
The core design principle is:
|
|
110
|
+
|
|
111
|
+
- define runtime schemas first with `zod`
|
|
112
|
+
- infer contract types from those schemas
|
|
113
|
+
- compose DTOs and entities around those inferred contracts
|
|
114
|
+
|
|
115
|
+
### `schemas`
|
|
116
|
+
|
|
117
|
+
`*.schemas.ts` files contain runtime validators built with `zod`.
|
|
118
|
+
|
|
119
|
+
Use schemas when you need to:
|
|
120
|
+
|
|
121
|
+
- validate incoming HTTP request payloads
|
|
122
|
+
- validate service responses
|
|
123
|
+
- infer TypeScript types from a single runtime source of truth
|
|
124
|
+
|
|
125
|
+
Typical examples:
|
|
126
|
+
|
|
127
|
+
- `loginRequest`
|
|
128
|
+
- `updateUserRequest`
|
|
129
|
+
- `bootstrapResponseSchema`
|
|
130
|
+
- `exerciseTrackingAndStatsSchema`
|
|
131
|
+
|
|
132
|
+
Example:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { loginRequest } from '@strong-together/shared';
|
|
136
|
+
|
|
137
|
+
type LoginBody = typeof loginRequest.shape.body;
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Zod-First Contracts
|
|
141
|
+
|
|
142
|
+
This package follows a `zod-first` approach.
|
|
143
|
+
|
|
144
|
+
That means the schema is the primary source of truth, and the TypeScript contract is derived from it instead of being written separately by hand.
|
|
145
|
+
|
|
146
|
+
Typical flow:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
export const updateUserRequest = z.object({
|
|
150
|
+
body: z.object({
|
|
151
|
+
username: z.string().optional(),
|
|
152
|
+
}),
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
export type UpdateUserBody = z.infer<typeof updateUserRequest.shape.body>;
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Why this matters:
|
|
159
|
+
|
|
160
|
+
- runtime validation and TypeScript types stay aligned
|
|
161
|
+
- changing a schema automatically updates the inferred contract
|
|
162
|
+
- there is less duplication between validation logic and type declarations
|
|
163
|
+
- request and response types are safer at API boundaries
|
|
164
|
+
|
|
165
|
+
In this library, the usual pattern is:
|
|
166
|
+
|
|
167
|
+
1. define a `zod` schema in `*.schemas.ts`
|
|
168
|
+
2. infer request or response types in `*.contracts.ts`
|
|
169
|
+
3. compose richer internal structures in `*.dtos.ts`
|
|
170
|
+
4. reuse domain fields from `*.entities.ts`
|
|
171
|
+
|
|
172
|
+
Common examples:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
export type LoginRequestBody = z.infer<typeof loginRequest.shape.body>;
|
|
176
|
+
export type GetWholeUserWorkoutPlanResponse = z.infer<typeof getWholeUserWorkoutPlanResponseSchema>;
|
|
177
|
+
export type GenerateTicketResponse = z.infer<typeof generateTicketResponseSchema>;
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Use `contracts` when you want the typed shape of an API boundary.
|
|
181
|
+
|
|
182
|
+
Use `schemas` when you need to parse or validate data at runtime.
|
|
183
|
+
|
|
184
|
+
### `contracts`
|
|
185
|
+
|
|
186
|
+
`*.contracts.ts` files expose public request and response types, usually via `z.infer<typeof ...>`.
|
|
187
|
+
|
|
188
|
+
These are the types you will usually import in controllers, clients, SDK adapters, and service boundaries when you want compile-time safety without re-declaring the shape.
|
|
189
|
+
|
|
190
|
+
Typical contract naming patterns:
|
|
191
|
+
|
|
192
|
+
- `SomethingBody`
|
|
193
|
+
- `SomethingQuery`
|
|
194
|
+
- `SomethingParams`
|
|
195
|
+
- `SomethingResponse`
|
|
196
|
+
|
|
197
|
+
Examples from the library:
|
|
198
|
+
|
|
199
|
+
- `LoginRequestBody`
|
|
200
|
+
- `LoginResponse`
|
|
201
|
+
- `UpdateUserBody`
|
|
202
|
+
- `GetWholeUserWorkoutPlanResponse`
|
|
203
|
+
- `GenerateTicketResponse`
|
|
204
|
+
|
|
205
|
+
Example:
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
import { type LoginRequestBody, type LoginResponse } from '@strong-together/shared';
|
|
209
|
+
|
|
210
|
+
async function login(body: LoginRequestBody): Promise<LoginResponse> {
|
|
211
|
+
// implementation
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### `dtos`
|
|
216
|
+
|
|
217
|
+
`*.dtos.ts` files describe transport or application-level shapes that are useful inside the codebase but are not always direct API contracts.
|
|
218
|
+
|
|
219
|
+
DTOs usually model:
|
|
220
|
+
|
|
221
|
+
- transformed query results
|
|
222
|
+
- service payloads
|
|
223
|
+
- nested response structures
|
|
224
|
+
- message queue payloads
|
|
225
|
+
- helper objects shared across modules
|
|
226
|
+
|
|
227
|
+
Examples:
|
|
228
|
+
|
|
229
|
+
- `WorkoutSplitsMap`
|
|
230
|
+
- `ExerciseTrackingAndStats`
|
|
231
|
+
- `AnalyzeVideoPayload`
|
|
232
|
+
- `MessageAfterSendResponse`
|
|
233
|
+
|
|
234
|
+
DTOs are especially useful when:
|
|
235
|
+
|
|
236
|
+
- database rows do not match the final shape you want to expose
|
|
237
|
+
- one feature composes data from multiple entities
|
|
238
|
+
- internal service flows need typed payloads not directly tied to one endpoint
|
|
239
|
+
|
|
240
|
+
### `entities`
|
|
241
|
+
|
|
242
|
+
`*.entities.ts` files represent core domain or persistence-level records.
|
|
243
|
+
|
|
244
|
+
These usually map closely to database tables or canonical stored models.
|
|
245
|
+
|
|
246
|
+
Examples:
|
|
247
|
+
|
|
248
|
+
- `UserEntity`
|
|
249
|
+
- `ExerciseEntity`
|
|
250
|
+
- `WorkoutPlanEntity`
|
|
251
|
+
- `MessageEntity`
|
|
252
|
+
- `ExerciseTrackingEntity`
|
|
253
|
+
|
|
254
|
+
Entities are often used as the building blocks for DTOs and contracts through `Pick`, `Omit`, intersections, and nested composition.
|
|
255
|
+
|
|
256
|
+
Example:
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
type PublicUserPreview = Pick<UserEntity, 'id' | 'username' | 'name'>;
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Common Type Patterns
|
|
263
|
+
|
|
264
|
+
The library uses a few recurring patterns worth knowing.
|
|
265
|
+
|
|
266
|
+
### Infer request and response types from schemas
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
export type UpdateUserBody = z.infer<typeof updateUserRequest.shape.body>;
|
|
270
|
+
export type LoginResponse = z.infer<typeof loginResponseSchema>;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
This keeps runtime validation and compile-time typing aligned.
|
|
274
|
+
|
|
275
|
+
### Build DTOs from entities
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
export type DeletedMessage = Pick<MessageEntity, 'id'>;
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
This avoids duplicating primitive field definitions and keeps model changes centralized.
|
|
282
|
+
|
|
283
|
+
### Compose nested feature shapes
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
export interface ExerciseTrackingAndStats {
|
|
287
|
+
exerciseTrackingAnalysis: ExerciseTrackingAnalysis;
|
|
288
|
+
exerciseTrackingMaps: {
|
|
289
|
+
byDate: Record<string, Array<Omit<TrackingMapItem, 'workoutdate'>>>;
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
This pattern is used in feature-heavy modules like `workout`, `analytics`, and `messages`.
|
|
295
|
+
|
|
296
|
+
## Exported Type Reference
|
|
297
|
+
|
|
298
|
+
Below is a practical reference of the main exported types and what they represent.
|
|
299
|
+
|
|
300
|
+
### `aerobics`
|
|
301
|
+
|
|
302
|
+
- `AddUserAerobicsBody`
|
|
303
|
+
Request body for adding aerobic records.
|
|
304
|
+
- `GetUserAerobicsQuery`
|
|
305
|
+
Query parameters for fetching aerobics data.
|
|
306
|
+
- `UserAerobicsResponse`
|
|
307
|
+
Full API response for user aerobics history/statistics.
|
|
308
|
+
- `AddAerobicInput`
|
|
309
|
+
Single aerobic record payload extracted from the request body.
|
|
310
|
+
- `AerobicsDailyRecord`
|
|
311
|
+
Normalized daily aerobics entry.
|
|
312
|
+
- `AerobicsWeeklyRecord`
|
|
313
|
+
Weekly aggregation shape for aerobics data.
|
|
314
|
+
- `WeeklyData`
|
|
315
|
+
Wrapper shape for grouped weekly output.
|
|
316
|
+
- `AerobicEntity`
|
|
317
|
+
Canonical persistence/domain representation of an aerobic record.
|
|
318
|
+
|
|
319
|
+
### `analytics`
|
|
320
|
+
|
|
321
|
+
- `GetAnalyticsResponse`
|
|
322
|
+
Public analytics response contract.
|
|
323
|
+
- `WorkoutRMRecord`
|
|
324
|
+
Per-exercise record describing best lifts or RM-related metrics.
|
|
325
|
+
- `WorkoutRMsResponse`
|
|
326
|
+
Map of workout RM records keyed by exercise identifier.
|
|
327
|
+
- `AdherenceExerciseStats`
|
|
328
|
+
Per-exercise adherence statistics.
|
|
329
|
+
- `GoalAdherenceResponse`
|
|
330
|
+
Aggregated adherence result keyed by exercise or grouping field.
|
|
331
|
+
|
|
332
|
+
### `auth`
|
|
333
|
+
|
|
334
|
+
#### `auth` root
|
|
335
|
+
|
|
336
|
+
- `UserByIndetifier`
|
|
337
|
+
User lookup result for login and identity checks.
|
|
338
|
+
|
|
339
|
+
#### `auth/password`
|
|
340
|
+
|
|
341
|
+
- `SendChangePassEmailBody`
|
|
342
|
+
Request body for sending a password reset/change email.
|
|
343
|
+
- `ResetPasswordBody`
|
|
344
|
+
Request body for submitting a new password.
|
|
345
|
+
- `ResetPasswordQuery`
|
|
346
|
+
Query params used when validating a reset flow.
|
|
347
|
+
- `ResetPasswordResponse`
|
|
348
|
+
Response returned after a password reset action.
|
|
349
|
+
- `ForgotPasswordPayload`
|
|
350
|
+
Internal token/email payload used in the forgot-password flow.
|
|
351
|
+
|
|
352
|
+
#### `auth/session`
|
|
353
|
+
|
|
354
|
+
- `LoginRequestBody`
|
|
355
|
+
Login request payload.
|
|
356
|
+
- `LoginResponse`
|
|
357
|
+
Login success response including auth tokens and user metadata.
|
|
358
|
+
- `RefreshTokenResponse`
|
|
359
|
+
Response returned when refreshing an authenticated session.
|
|
360
|
+
- `LogOutResponse`
|
|
361
|
+
Response returned after logout completes successfully.
|
|
362
|
+
- `AccessTokenPayload`
|
|
363
|
+
JWT payload stored in access tokens.
|
|
364
|
+
- `UserAfterBump`
|
|
365
|
+
User shape after token-version or auth-state refresh logic.
|
|
366
|
+
- `TokenVersionResult`
|
|
367
|
+
Result used when comparing or bumping token versions.
|
|
368
|
+
|
|
369
|
+
#### `auth/verification`
|
|
370
|
+
|
|
371
|
+
- `VerifyUserAccountQuery`
|
|
372
|
+
Query params for account verification callbacks.
|
|
373
|
+
- `SendVerifcationMailBody`
|
|
374
|
+
Request body for sending verification email.
|
|
375
|
+
- `ChangeEmailAndVerifyBody`
|
|
376
|
+
Request body for email change plus verification.
|
|
377
|
+
- `CheckUserVerifyQuery`
|
|
378
|
+
Query params used to check verification state.
|
|
379
|
+
- `EmailVerifyPayload`
|
|
380
|
+
Internal payload carried in verification tokens.
|
|
381
|
+
|
|
382
|
+
### `bootstrap`
|
|
383
|
+
|
|
384
|
+
- `BootstrapRequestQuery`
|
|
385
|
+
Query params for the bootstrap endpoint.
|
|
386
|
+
- `BootstrapResponse`
|
|
387
|
+
Aggregated startup payload combining user, workout, tracking, messages, and aerobics data.
|
|
388
|
+
|
|
389
|
+
### `exercises`
|
|
390
|
+
|
|
391
|
+
- `GetAllExercisesResponse`
|
|
392
|
+
Public response contract for the exercise catalog.
|
|
393
|
+
- `GetAllExercisesExercise`
|
|
394
|
+
Single exercise item in the catalog response.
|
|
395
|
+
- `ExercisesMapByMuscle`
|
|
396
|
+
Exercise collection grouped by target muscle.
|
|
397
|
+
- `QueryGetExerciseMapByMuscleRow`
|
|
398
|
+
Query/result row shape used to build grouped exercise maps.
|
|
399
|
+
- `ExerciseEntity`
|
|
400
|
+
Canonical exercise record.
|
|
401
|
+
|
|
402
|
+
### `messages`
|
|
403
|
+
|
|
404
|
+
- `GetAllUserMessagesQuery`
|
|
405
|
+
Query params for listing user messages.
|
|
406
|
+
- `GetAllUserMessagesResponse`
|
|
407
|
+
Full response for all user messages.
|
|
408
|
+
- `MarkMessageAsReadParams`
|
|
409
|
+
Route params for marking a message as read.
|
|
410
|
+
- `MarkMessageAsReadResponse`
|
|
411
|
+
Response after marking a message as read.
|
|
412
|
+
- `DeleteMessageParams`
|
|
413
|
+
Route params for deleting a message.
|
|
414
|
+
- `DeleteMessageResponse`
|
|
415
|
+
Response after deleting a message.
|
|
416
|
+
- `AllUserMessages`
|
|
417
|
+
DTO representing a message item in user-facing listings.
|
|
418
|
+
- `MessageAfterSendResponse`
|
|
419
|
+
Internal or service-layer message shape after send.
|
|
420
|
+
- `MessageAsRead`
|
|
421
|
+
Minimal updated shape for read-state mutations.
|
|
422
|
+
- `DeletedMessage`
|
|
423
|
+
Minimal response shape for delete mutations.
|
|
424
|
+
- `MessageEntity`
|
|
425
|
+
Canonical stored message record.
|
|
426
|
+
|
|
427
|
+
### `oauth`
|
|
428
|
+
|
|
429
|
+
- `OAuthLoginResponse`
|
|
430
|
+
Shared response for OAuth login flows.
|
|
431
|
+
|
|
432
|
+
#### `oauth/apple`
|
|
433
|
+
|
|
434
|
+
- `AppleOAuthBody`
|
|
435
|
+
Request body for Apple sign-in.
|
|
436
|
+
- `AppleTokenVerificationResult`
|
|
437
|
+
Result of Apple token validation.
|
|
438
|
+
|
|
439
|
+
#### `oauth/google`
|
|
440
|
+
|
|
441
|
+
- `GoogleOAuthBody`
|
|
442
|
+
Request body for Google sign-in.
|
|
443
|
+
- `GoogleTokenVerificationResult`
|
|
444
|
+
Result of Google token validation.
|
|
445
|
+
|
|
446
|
+
### `user`
|
|
447
|
+
|
|
448
|
+
#### `user` root
|
|
449
|
+
|
|
450
|
+
- `UserEntity`
|
|
451
|
+
Canonical stored user record.
|
|
452
|
+
|
|
453
|
+
#### `user/create`
|
|
454
|
+
|
|
455
|
+
- `CreateUserBody`
|
|
456
|
+
Request body for creating a user.
|
|
457
|
+
- `CreateUserResponse`
|
|
458
|
+
Response returned after successful user creation.
|
|
459
|
+
|
|
460
|
+
#### `user/push-tokens`
|
|
461
|
+
|
|
462
|
+
- `SaveUserPushTokenBody`
|
|
463
|
+
Request body for storing or updating a user push token.
|
|
464
|
+
|
|
465
|
+
#### `user/update`
|
|
466
|
+
|
|
467
|
+
- `UpdateUserBody`
|
|
468
|
+
Partial update payload for editable user profile fields.
|
|
469
|
+
- `UpdateAuthenticatedUserResponse`
|
|
470
|
+
Response returned after updating the authenticated user.
|
|
471
|
+
- `UserDataResponse`
|
|
472
|
+
Response wrapper containing user data.
|
|
473
|
+
- `GetAuthenticatedUserByIdResponse`
|
|
474
|
+
Direct user lookup response for an authenticated user.
|
|
475
|
+
- `DeleteUserProfilePicBody`
|
|
476
|
+
Request body for removing a profile image.
|
|
477
|
+
- `SetProfilePicAndUpdateDBResponse`
|
|
478
|
+
Response after setting profile picture storage path and database state.
|
|
479
|
+
- `ChangeEmailTokenPayload`
|
|
480
|
+
Internal token payload for secure email-change flows.
|
|
481
|
+
- `AuthenticatedUserForUpdate`
|
|
482
|
+
Derived update-safe user payload type.
|
|
483
|
+
|
|
484
|
+
### `video-analysis`
|
|
485
|
+
|
|
486
|
+
- `GetPresignedUrlFromS3Body`
|
|
487
|
+
Request body for generating an upload URL.
|
|
488
|
+
- `GetPresignedUrlFromS3Response`
|
|
489
|
+
Response containing the generated S3 presigned URL details.
|
|
490
|
+
- `EnqueueAanalyzeVideoParams`
|
|
491
|
+
Queue/job parameters used when scheduling analysis.
|
|
492
|
+
- `AnalyzeVideoPayload`
|
|
493
|
+
Worker/job payload for video analysis execution.
|
|
494
|
+
- `SquatRepetition`
|
|
495
|
+
Single detected squat repetition shape.
|
|
496
|
+
- `AnalyzeVideoResultPayload<T>`
|
|
497
|
+
Generic wrapper for analysis results returned by the processor.
|
|
498
|
+
|
|
499
|
+
### `web-sockets`
|
|
500
|
+
|
|
501
|
+
- `GenerateTicketBody`
|
|
502
|
+
Request body for creating a websocket/session ticket.
|
|
503
|
+
- `GenerateTicketResponse`
|
|
504
|
+
Response returned after generating a websocket ticket.
|
|
505
|
+
|
|
506
|
+
### `workout`
|
|
507
|
+
|
|
508
|
+
#### `workout/plan`
|
|
509
|
+
|
|
510
|
+
- `GetWholeUserWorkoutPlanQuery`
|
|
511
|
+
Query params for fetching a user's full workout plan.
|
|
512
|
+
- `GetWholeUserWorkoutPlanResponse`
|
|
513
|
+
Full workout-plan response contract.
|
|
514
|
+
- `AddWorkoutBody`
|
|
515
|
+
Request payload for creating or replacing workout plan data.
|
|
516
|
+
- `AddWorkoutResponse`
|
|
517
|
+
Response after workout-plan creation/update.
|
|
518
|
+
- `ExerciseInPlan`
|
|
519
|
+
DTO describing an exercise nested inside a workout plan.
|
|
520
|
+
- `ExerciseMetadata`
|
|
521
|
+
Small shared exercise metadata subset used in plan composition.
|
|
522
|
+
- `WholeUserWorkoutPlan`
|
|
523
|
+
DTO representing the complete nested workout plan structure.
|
|
524
|
+
- `AddWorkoutSplitPayload`
|
|
525
|
+
Input shape grouped by split for creating workout splits.
|
|
526
|
+
- `WorkoutSplitsMap`
|
|
527
|
+
Normalized map of split names to exercises.
|
|
528
|
+
- `WorkoutPlanEntity`
|
|
529
|
+
Canonical workout plan record.
|
|
530
|
+
- `WorkoutSplitEntity`
|
|
531
|
+
Canonical workout split record.
|
|
532
|
+
- `ExerciseToWorkoutSplitEntity`
|
|
533
|
+
Join entity connecting exercises to workout splits.
|
|
534
|
+
|
|
535
|
+
#### `workout/tracking`
|
|
536
|
+
|
|
537
|
+
- `GetExerciseTrackingQuery`
|
|
538
|
+
Query params for fetching exercise tracking/statistics.
|
|
539
|
+
- `GetExerciseTrackingResponse`
|
|
540
|
+
Response contract for workout tracking data.
|
|
541
|
+
- `FinishUserWorkoutBody`
|
|
542
|
+
Request body sent when finishing a workout.
|
|
543
|
+
- `FinishUserWorkoutResponse`
|
|
544
|
+
Response returned after completing a workout.
|
|
545
|
+
- `ExerciseTrackingAnalysis`
|
|
546
|
+
Aggregated analysis of exercise history and PR-related stats.
|
|
547
|
+
- `TrackingMapItem`
|
|
548
|
+
Normalized single tracking row with joined workout and exercise metadata.
|
|
549
|
+
- `ExerciseTrackingAndStats`
|
|
550
|
+
Main DTO returned by tracking flows, combining analysis and grouped maps.
|
|
551
|
+
- `FinishedWorkoutEntry`
|
|
552
|
+
Single finished exercise entry submitted at workout completion.
|
|
553
|
+
- `ExerciseTrackingEntity`
|
|
554
|
+
Canonical stored exercise-tracking record.
|
|
555
|
+
- `WorkoutSummaryEntity`
|
|
556
|
+
Canonical workout summary/session record.
|
|
557
|
+
|
|
558
|
+
## How To Choose What To Import
|
|
559
|
+
|
|
560
|
+
- Import a `schema` when you need runtime validation.
|
|
561
|
+
- Import a `contract` when you need a public request or response type.
|
|
562
|
+
- Import a `dto` when you need a composed internal data shape.
|
|
563
|
+
- Import an `entity` when you need a canonical domain record or want to derive another type from it.
|
|
564
|
+
|
|
565
|
+
As a rule of thumb:
|
|
566
|
+
|
|
567
|
+
- API boundary: prefer `schemas` and `contracts`
|
|
568
|
+
- business logic: prefer `dtos`
|
|
569
|
+
- storage/domain modeling: prefer `entities`
|
|
570
|
+
|
|
571
|
+
## Example Workflow
|
|
572
|
+
|
|
573
|
+
A typical endpoint flow can look like this:
|
|
574
|
+
|
|
575
|
+
1. Validate the incoming payload with a schema such as `updateUserRequest`.
|
|
576
|
+
2. Use the inferred contract type such as `UpdateUserBody` in the controller/service signature.
|
|
577
|
+
3. Read or write persistence data using entity types such as `UserEntity`.
|
|
578
|
+
4. Transform data into a DTO or response contract such as `UserDataResponse`.
|
|
579
|
+
|
|
580
|
+
That gives you:
|
|
581
|
+
|
|
582
|
+
- runtime validation
|
|
583
|
+
- strongly typed controller and service interfaces
|
|
584
|
+
- reusable shared domain shapes
|
|
585
|
+
- minimal duplication between validation and typing
|
|
586
|
+
|
|
587
|
+
## Design Notes
|
|
588
|
+
|
|
589
|
+
- `*.schemas.ts` contains runtime validation schemas.
|
|
590
|
+
- `*.contracts.ts` contains exported request/response types, usually inferred from schemas.
|
|
591
|
+
- `*.dtos.ts` contains internal transport or service-layer shapes.
|
|
592
|
+
- `*.entities.ts` contains entity-style interfaces representing stored/domain objects.
|
|
593
|
+
- Each module and submodule exposes an `index.ts` barrel for simple imports.
|
|
594
|
+
|
|
595
|
+
## Scripts
|
|
596
|
+
|
|
597
|
+
```json
|
|
598
|
+
{
|
|
599
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
600
|
+
"dev": "tsup src/index.ts --format cjs,esm --watch --dts"
|
|
601
|
+
}
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
## Requirements
|
|
605
|
+
|
|
606
|
+
- Node.js
|
|
607
|
+
- npm
|
|
608
|
+
|
|
609
|
+
## Notes
|
|
610
|
+
|
|
611
|
+
- The package depends on [`zod`](https://github.com/colinhacks/zod).
|
|
612
|
+
- The project is compiled with TypeScript and bundled with `tsup`.
|