@tbs-fitness/contract 0.10.0 → 0.11.0

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 CHANGED
@@ -43,6 +43,19 @@ const result = createFlagSchema.safeParse(input); // The same rules as the API.
43
43
 
44
44
  Requests have two types. Clients use `*Input`, where fields with a default are optional. The backend uses `*Body`, which is the result after validation. List queries come from the URL as strings, so they have no `*Input`: use `Partial<PaginationQuery>` or `Partial<AuditLogQuery>`.
45
45
 
46
+ ## Version 0.11.0
47
+
48
+ Client onboarding and generic documents. Additive; consumers install `^0.11.0` explicitly.
49
+
50
+ - New `/documents`: `documentUploadRequestSchema` (checked against `DOCUMENT_LIMITS` per type), `documentUploadResponseSchema` (the document and a signed PUT), `documentResponseSchema` (never a link to the file), `documentViewUrlResponseSchema` (a short-lived link per view).
51
+ - New `/onboarding`:
52
+ - Steps: `ONBOARDING_STEP_SCHEMAS` (one per step), `ONBOARDING_FLOW` (order, section, optional), `ONBOARDING_LIMITS`, `localTimeSchema`.
53
+ - Library picks: `goalChoiceSchema`, `supplementChoiceSchema` and `foodChoiceSchema`; an id of `null` means a typed entry.
54
+ - Helpers: `nextOnboardingStep`, `missingOnboardingSteps`, `onboardingProgress`, `onboardingSections`, `normalizeItemName`, and the cm/ft-in and kg/lb conversions.
55
+ - Requests: `saveOnboardingStepSchema` (an answer or a skip, with `version` and `mode`), `onboardingVersionSchema`, `updatePlanDueSchema`.
56
+ - Responses: `onboardingDraftSchema`, `onboardingStateResponseSchema`, `onboardingSubmissionResponseSchema`, `coachOnboardingResponseSchema`.
57
+ - `/enums`: `DOCUMENT_TYPES`, `DOCUMENT_STATUSES`, `ONBOARDING_STATUSES`, `ONBOARDING_STEPS`, `ONBOARDING_SECTIONS`, the answer enums (`GENDERS`, `EXPERIENCE_LEVELS`, `TRAINING_TIMES`, `WEEKDAYS`, `SESSION_LENGTHS`, `ACTIVITY_LEVELS`, `DIET_TYPES`, `ALLERGENS`, `WATER_INTAKES`, `ANABOLIC_USE`, `BODY_AREAS`, `SLEEP_DURATIONS`, `DIGESTION_QUALITIES`, `REFLUX_FREQUENCIES`, `DIGESTIVE_SYMPTOMS`, `KIDNEY_TEST_ANSWERS`, `HEIGHT_UNITS`, `WEIGHT_UNITS`), and the permissions `documents:write:self`, `documents:read:self`, `documents:read:assigned` and `documents:read:any`.
58
+
46
59
  ## Version 0.10.0
47
60
 
48
61
  The supplement library. Additive; consumers install `^0.10.0` explicitly.
@@ -0,0 +1,105 @@
1
+ import { z } from 'zod';
2
+ /** What each document type may be, so the upload screen can say it up front. */
3
+ export declare const DOCUMENT_LIMITS: {
4
+ readonly PROGRESS_PHOTO_FRONT: {
5
+ readonly contentTypes: readonly ["image/jpeg", "image/png", "image/webp"];
6
+ readonly maxBytes: number;
7
+ };
8
+ readonly PROGRESS_PHOTO_BACK: {
9
+ readonly contentTypes: readonly ["image/jpeg", "image/png", "image/webp"];
10
+ readonly maxBytes: number;
11
+ };
12
+ readonly PROGRESS_PHOTO_SIDE: {
13
+ readonly contentTypes: readonly ["image/jpeg", "image/png", "image/webp"];
14
+ readonly maxBytes: number;
15
+ };
16
+ readonly BLOODWORK_REPORT: {
17
+ readonly contentTypes: readonly ["application/pdf", "image/jpeg", "image/png"];
18
+ readonly maxBytes: number;
19
+ };
20
+ readonly OTHER: {
21
+ readonly contentTypes: readonly ["application/pdf", "image/jpeg", "image/png"];
22
+ readonly maxBytes: number;
23
+ };
24
+ };
25
+ export declare const documentIdParamSchema: z.ZodUUID;
26
+ /** Asks for an upload link. The content type and size are signed into it. */
27
+ export declare const documentUploadRequestSchema: z.ZodObject<{
28
+ documentType: z.ZodEnum<{
29
+ PROGRESS_PHOTO_FRONT: "PROGRESS_PHOTO_FRONT";
30
+ PROGRESS_PHOTO_BACK: "PROGRESS_PHOTO_BACK";
31
+ PROGRESS_PHOTO_SIDE: "PROGRESS_PHOTO_SIDE";
32
+ BLOODWORK_REPORT: "BLOODWORK_REPORT";
33
+ OTHER: "OTHER";
34
+ }>;
35
+ contentType: z.ZodString;
36
+ sizeBytes: z.ZodNumber;
37
+ }, z.core.$strict>;
38
+ export type DocumentUploadInput = z.input<typeof documentUploadRequestSchema>;
39
+ export type DocumentUploadBody = z.output<typeof documentUploadRequestSchema>;
40
+ /** A stored document. Never carries a link to the file. */
41
+ export declare const documentResponseSchema: z.ZodObject<{
42
+ id: z.ZodUUID;
43
+ userId: z.ZodUUID;
44
+ userRole: z.ZodEnum<{
45
+ ADMIN: "ADMIN";
46
+ COACH: "COACH";
47
+ CLIENT: "CLIENT";
48
+ }>;
49
+ documentType: z.ZodEnum<{
50
+ PROGRESS_PHOTO_FRONT: "PROGRESS_PHOTO_FRONT";
51
+ PROGRESS_PHOTO_BACK: "PROGRESS_PHOTO_BACK";
52
+ PROGRESS_PHOTO_SIDE: "PROGRESS_PHOTO_SIDE";
53
+ BLOODWORK_REPORT: "BLOODWORK_REPORT";
54
+ OTHER: "OTHER";
55
+ }>;
56
+ contentType: z.ZodString;
57
+ sizeBytes: z.ZodNumber;
58
+ status: z.ZodEnum<{
59
+ PENDING: "PENDING";
60
+ UPLOADED: "UPLOADED";
61
+ }>;
62
+ createdAt: z.ZodISODateTime;
63
+ confirmedAt: z.ZodNullable<z.ZodISODateTime>;
64
+ }, z.core.$strip>;
65
+ export type DocumentResponse = z.output<typeof documentResponseSchema>;
66
+ /** Where to PUT the file. Send exactly these headers, before `expiresAt`. */
67
+ export declare const documentUploadResponseSchema: z.ZodObject<{
68
+ document: z.ZodObject<{
69
+ id: z.ZodUUID;
70
+ userId: z.ZodUUID;
71
+ userRole: z.ZodEnum<{
72
+ ADMIN: "ADMIN";
73
+ COACH: "COACH";
74
+ CLIENT: "CLIENT";
75
+ }>;
76
+ documentType: z.ZodEnum<{
77
+ PROGRESS_PHOTO_FRONT: "PROGRESS_PHOTO_FRONT";
78
+ PROGRESS_PHOTO_BACK: "PROGRESS_PHOTO_BACK";
79
+ PROGRESS_PHOTO_SIDE: "PROGRESS_PHOTO_SIDE";
80
+ BLOODWORK_REPORT: "BLOODWORK_REPORT";
81
+ OTHER: "OTHER";
82
+ }>;
83
+ contentType: z.ZodString;
84
+ sizeBytes: z.ZodNumber;
85
+ status: z.ZodEnum<{
86
+ PENDING: "PENDING";
87
+ UPLOADED: "UPLOADED";
88
+ }>;
89
+ createdAt: z.ZodISODateTime;
90
+ confirmedAt: z.ZodNullable<z.ZodISODateTime>;
91
+ }, z.core.$strip>;
92
+ upload: z.ZodObject<{
93
+ url: z.ZodURL;
94
+ method: z.ZodLiteral<"PUT">;
95
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
96
+ expiresAt: z.ZodISODateTime;
97
+ }, z.core.$strip>;
98
+ }, z.core.$strip>;
99
+ export type DocumentUploadResponse = z.output<typeof documentUploadResponseSchema>;
100
+ /** A short-lived link to view or download a document. Ask again after it expires. */
101
+ export declare const documentViewUrlResponseSchema: z.ZodObject<{
102
+ url: z.ZodURL;
103
+ expiresAt: z.ZodISODateTime;
104
+ }, z.core.$strip>;
105
+ export type DocumentViewUrlResponse = z.output<typeof documentViewUrlResponseSchema>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.documentViewUrlResponseSchema = exports.documentUploadResponseSchema = exports.documentResponseSchema = exports.documentUploadRequestSchema = exports.documentIdParamSchema = exports.DOCUMENT_LIMITS = void 0;
4
+ const zod_1 = require("zod");
5
+ const date_time_schema_js_1 = require("../common/date-time.schema.js");
6
+ const index_js_1 = require("../enums/index.js");
7
+ // A document is any file the app keeps for a user: progress photos, reports and
8
+ // more. The file itself lives in private storage. The API never stores or
9
+ // returns a lasting link: each view asks for a fresh one that expires quickly.
10
+ const MB = 1024 * 1024;
11
+ const PHOTO_TYPES = ['image/jpeg', 'image/png', 'image/webp'];
12
+ const REPORT_TYPES = ['application/pdf', 'image/jpeg', 'image/png'];
13
+ /** What each document type may be, so the upload screen can say it up front. */
14
+ exports.DOCUMENT_LIMITS = {
15
+ PROGRESS_PHOTO_FRONT: { contentTypes: PHOTO_TYPES, maxBytes: 10 * MB },
16
+ PROGRESS_PHOTO_BACK: { contentTypes: PHOTO_TYPES, maxBytes: 10 * MB },
17
+ PROGRESS_PHOTO_SIDE: { contentTypes: PHOTO_TYPES, maxBytes: 10 * MB },
18
+ BLOODWORK_REPORT: { contentTypes: REPORT_TYPES, maxBytes: 10 * MB },
19
+ OTHER: { contentTypes: REPORT_TYPES, maxBytes: 10 * MB },
20
+ };
21
+ exports.documentIdParamSchema = zod_1.z.uuid();
22
+ /** Asks for an upload link. The content type and size are signed into it. */
23
+ exports.documentUploadRequestSchema = zod_1.z
24
+ .strictObject({
25
+ documentType: zod_1.z.enum(index_js_1.DOCUMENT_TYPES),
26
+ contentType: zod_1.z.string().trim().toLowerCase(),
27
+ sizeBytes: zod_1.z.number().int().positive(),
28
+ })
29
+ .superRefine((body, ctx) => {
30
+ const limits = exports.DOCUMENT_LIMITS[body.documentType];
31
+ if (!limits.contentTypes.includes(body.contentType)) {
32
+ ctx.addIssue({
33
+ code: 'custom',
34
+ path: ['contentType'],
35
+ message: `Upload one of: ${limits.contentTypes.join(', ')}`,
36
+ });
37
+ }
38
+ if (body.sizeBytes > limits.maxBytes) {
39
+ ctx.addIssue({
40
+ code: 'custom',
41
+ path: ['sizeBytes'],
42
+ message: `The file is larger than ${String(limits.maxBytes / MB)} MB`,
43
+ });
44
+ }
45
+ });
46
+ // Responses
47
+ /** A stored document. Never carries a link to the file. */
48
+ exports.documentResponseSchema = zod_1.z.object({
49
+ id: zod_1.z.uuid(),
50
+ userId: zod_1.z.uuid(),
51
+ userRole: zod_1.z.enum(index_js_1.ROLES),
52
+ documentType: zod_1.z.enum(index_js_1.DOCUMENT_TYPES),
53
+ contentType: zod_1.z.string(),
54
+ sizeBytes: zod_1.z.number().int(),
55
+ status: zod_1.z.enum(index_js_1.DOCUMENT_STATUSES),
56
+ createdAt: date_time_schema_js_1.utcTimestampSchema,
57
+ confirmedAt: date_time_schema_js_1.utcTimestampSchema.nullable(),
58
+ });
59
+ /** Where to PUT the file. Send exactly these headers, before `expiresAt`. */
60
+ exports.documentUploadResponseSchema = zod_1.z.object({
61
+ document: exports.documentResponseSchema,
62
+ upload: zod_1.z.object({
63
+ url: zod_1.z.url(),
64
+ method: zod_1.z.literal('PUT'),
65
+ headers: zod_1.z.record(zod_1.z.string(), zod_1.z.string()),
66
+ expiresAt: date_time_schema_js_1.utcTimestampSchema,
67
+ }),
68
+ });
69
+ /** A short-lived link to view or download a document. Ask again after it expires. */
70
+ exports.documentViewUrlResponseSchema = zod_1.z.object({
71
+ url: zod_1.z.url(),
72
+ expiresAt: date_time_schema_js_1.utcTimestampSchema,
73
+ });
@@ -0,0 +1 @@
1
+ export * from './document.dto.js';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./document.dto.js"), exports);
@@ -44,6 +44,10 @@ export declare const PERMISSIONS: {
44
44
  readonly supplementsImport: "supplements:import";
45
45
  readonly supplementMetadataManage: "supplement_metadata:manage";
46
46
  readonly supplementsSearchSelf: "supplements:search:self";
47
+ readonly documentsWriteSelf: "documents:write:self";
48
+ readonly documentsReadSelf: "documents:read:self";
49
+ readonly documentsReadAssigned: "documents:read:assigned";
50
+ readonly documentsReadAny: "documents:read:any";
47
51
  };
48
52
  export type Permission = (typeof PERMISSIONS)[keyof typeof PERMISSIONS];
49
53
  /**
@@ -147,3 +151,53 @@ export type GoalSortField = (typeof GOAL_SORT_FIELDS)[number];
147
151
  /** Where a supplement came from. Clients cannot suggest supplements, unlike foods. */
148
152
  export declare const SUPPLEMENT_SOURCES: readonly ["ADMIN", "COACH", "IMPORT"];
149
153
  export type SupplementSource = (typeof SUPPLEMENT_SOURCES)[number];
154
+ /** What a stored file is. Each feature that keeps files adds its own types here. */
155
+ export declare const DOCUMENT_TYPES: readonly ["PROGRESS_PHOTO_FRONT", "PROGRESS_PHOTO_BACK", "PROGRESS_PHOTO_SIDE", "BLOODWORK_REPORT", "OTHER"];
156
+ export type DocumentType = (typeof DOCUMENT_TYPES)[number];
157
+ /** A document is `PENDING` until its upload is confirmed. */
158
+ export declare const DOCUMENT_STATUSES: readonly ["PENDING", "UPLOADED"];
159
+ export type DocumentStatus = (typeof DOCUMENT_STATUSES)[number];
160
+ export declare const ONBOARDING_STATUSES: readonly ["NOT_STARTED", "IN_PROGRESS", "LOCKED", "PLEDGED"];
161
+ export type OnboardingStatus = (typeof ONBOARDING_STATUSES)[number];
162
+ /** Every question step, in the order the client answers them. */
163
+ export declare const ONBOARDING_STEPS: readonly ["name", "age", "gender", "height", "weight", "goal", "level", "schedule", "day", "working_hours", "diet", "fuel", "eating_routine", "supplements", "body", "sleep", "digestion", "photos", "bloodwork", "notes"];
164
+ export type OnboardingStep = (typeof ONBOARDING_STEPS)[number];
165
+ /** The sections of The File, in the order it lists them. */
166
+ export declare const ONBOARDING_SECTIONS: readonly ["basics", "goal_level", "training", "your_day", "sleep", "food_fuel", "body_health", "photos_bloodwork"];
167
+ export type OnboardingSection = (typeof ONBOARDING_SECTIONS)[number];
168
+ export declare const GENDERS: readonly ["MALE", "FEMALE"];
169
+ export type Gender = (typeof GENDERS)[number];
170
+ export declare const EXPERIENCE_LEVELS: readonly ["BEGINNER", "INTERMEDIATE", "ADVANCED"];
171
+ export type ExperienceLevel = (typeof EXPERIENCE_LEVELS)[number];
172
+ export declare const TRAINING_TIMES: readonly ["MORNING", "MIDDAY", "EVENING", "NIGHT"];
173
+ export type TrainingTime = (typeof TRAINING_TIMES)[number];
174
+ export declare const WEEKDAYS: readonly ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"];
175
+ export type Weekday = (typeof WEEKDAYS)[number];
176
+ export declare const SESSION_LENGTHS: readonly ["MIN_30", "MIN_45", "MIN_60", "MIN_90_PLUS"];
177
+ export type SessionLength = (typeof SESSION_LENGTHS)[number];
178
+ export declare const ACTIVITY_LEVELS: readonly ["SEDENTARY", "LIGHTLY_ACTIVE", "MODERATELY_ACTIVE", "VERY_ACTIVE", "PHYSICALLY_DEMANDING"];
179
+ export type ActivityLevel = (typeof ACTIVITY_LEVELS)[number];
180
+ export declare const DIET_TYPES: readonly ["VEGETARIAN", "NON_VEGETARIAN", "EGGETARIAN", "VEGAN"];
181
+ export type DietType = (typeof DIET_TYPES)[number];
182
+ export declare const ALLERGENS: readonly ["PEANUT", "DAIRY", "GLUTEN", "SHELLFISH", "SOY", "EGGS"];
183
+ export type Allergen = (typeof ALLERGENS)[number];
184
+ export declare const WATER_INTAKES: readonly ["UNDER_1L", "L1_TO_2", "L2_TO_3", "OVER_3L"];
185
+ export type WaterIntake = (typeof WATER_INTAKES)[number];
186
+ export declare const ANABOLIC_USE: readonly ["NONE", "PAST", "CURRENT"];
187
+ export type AnabolicUse = (typeof ANABOLIC_USE)[number];
188
+ export declare const BODY_AREAS: readonly ["SHOULDER", "LOWER_BACK", "KNEE", "WRIST_ELBOW", "NECK", "HIP"];
189
+ export type BodyArea = (typeof BODY_AREAS)[number];
190
+ export declare const SLEEP_DURATIONS: readonly ["UNDER_5H", "H5_TO_6", "H6_TO_7", "H7_TO_8", "OVER_8H"];
191
+ export type SleepDuration = (typeof SLEEP_DURATIONS)[number];
192
+ export declare const DIGESTION_QUALITIES: readonly ["GOOD", "AVERAGE", "POOR"];
193
+ export type DigestionQuality = (typeof DIGESTION_QUALITIES)[number];
194
+ export declare const REFLUX_FREQUENCIES: readonly ["NEVER", "OCCASIONALLY", "FREQUENTLY", "DAILY"];
195
+ export type RefluxFrequency = (typeof REFLUX_FREQUENCIES)[number];
196
+ export declare const DIGESTIVE_SYMPTOMS: readonly ["BLOATING", "CONSTIPATION", "GAS", "STOMACH_PAIN", "LOOSE_MOTIONS"];
197
+ export type DigestiveSymptom = (typeof DIGESTIVE_SYMPTOMS)[number];
198
+ export declare const KIDNEY_TEST_ANSWERS: readonly ["YES", "NO", "NOT_SURE"];
199
+ export type KidneyTestAnswer = (typeof KIDNEY_TEST_ANSWERS)[number];
200
+ export declare const HEIGHT_UNITS: readonly ["CM", "FT"];
201
+ export type HeightUnit = (typeof HEIGHT_UNITS)[number];
202
+ export declare const WEIGHT_UNITS: readonly ["KG", "LB"];
203
+ export type WeightUnit = (typeof WEIGHT_UNITS)[number];
@@ -2,7 +2,8 @@
2
2
  // These values are stored in the database and sent over the API. Renaming or
3
3
  // removing one is a breaking change, so it needs a major version.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.SUPPLEMENT_SOURCES = exports.GOAL_SORT_FIELDS = exports.GOAL_STATUSES = exports.GOAL_ICONS = exports.SORT_ORDERS = exports.FOOD_SORT_FIELDS = exports.FOOD_METADATA_SELECTIONS = exports.FOOD_IMPORT_ISSUE_SEVERITIES = exports.FOOD_IMPORT_FILE_TYPES = exports.FOOD_IMPORT_ROW_STATUSES = exports.FOOD_IMPORT_STATUSES = exports.FOOD_IMPORT_MODES = exports.FOOD_SUGGESTION_RESOLUTIONS = exports.FOOD_SUGGESTION_STATUSES = exports.NUTRITION_BASES = exports.PORTION_UNITS = exports.SERVING_UNITS = exports.FOOD_SOURCES = exports.TEMPLATE_STATUSES = exports.DELIVERY_STATUSES = exports.MESSAGE_TYPES = exports.COMMUNICATION_CHANNELS = exports.FEATURE_FLAG_RULE_TYPES = exports.AUDIT_OUTCOMES = exports.CSRF_HEADER = exports.CSRF_COOKIE_NAMES = exports.TOKEN_TRANSPORTS = exports.TIMEZONE_SOURCES = exports.ADMIN_SETTABLE_ACCOUNT_STATUSES = exports.ACCOUNT_STATUSES = exports.PERMISSIONS = exports.ROLES = exports.APP_ENVIRONMENTS = void 0;
5
+ exports.SLEEP_DURATIONS = exports.BODY_AREAS = exports.ANABOLIC_USE = exports.WATER_INTAKES = exports.ALLERGENS = exports.DIET_TYPES = exports.ACTIVITY_LEVELS = exports.SESSION_LENGTHS = exports.WEEKDAYS = exports.TRAINING_TIMES = exports.EXPERIENCE_LEVELS = exports.GENDERS = exports.ONBOARDING_SECTIONS = exports.ONBOARDING_STEPS = exports.ONBOARDING_STATUSES = exports.DOCUMENT_STATUSES = exports.DOCUMENT_TYPES = exports.SUPPLEMENT_SOURCES = exports.GOAL_SORT_FIELDS = exports.GOAL_STATUSES = exports.GOAL_ICONS = exports.SORT_ORDERS = exports.FOOD_SORT_FIELDS = exports.FOOD_METADATA_SELECTIONS = exports.FOOD_IMPORT_ISSUE_SEVERITIES = exports.FOOD_IMPORT_FILE_TYPES = exports.FOOD_IMPORT_ROW_STATUSES = exports.FOOD_IMPORT_STATUSES = exports.FOOD_IMPORT_MODES = exports.FOOD_SUGGESTION_RESOLUTIONS = exports.FOOD_SUGGESTION_STATUSES = exports.NUTRITION_BASES = exports.PORTION_UNITS = exports.SERVING_UNITS = exports.FOOD_SOURCES = exports.TEMPLATE_STATUSES = exports.DELIVERY_STATUSES = exports.MESSAGE_TYPES = exports.COMMUNICATION_CHANNELS = exports.FEATURE_FLAG_RULE_TYPES = exports.AUDIT_OUTCOMES = exports.CSRF_HEADER = exports.CSRF_COOKIE_NAMES = exports.TOKEN_TRANSPORTS = exports.TIMEZONE_SOURCES = exports.ADMIN_SETTABLE_ACCOUNT_STATUSES = exports.ACCOUNT_STATUSES = exports.PERMISSIONS = exports.ROLES = exports.APP_ENVIRONMENTS = void 0;
6
+ exports.WEIGHT_UNITS = exports.HEIGHT_UNITS = exports.KIDNEY_TEST_ANSWERS = exports.DIGESTIVE_SYMPTOMS = exports.REFLUX_FREQUENCIES = exports.DIGESTION_QUALITIES = void 0;
6
7
  exports.APP_ENVIRONMENTS = [
7
8
  'development',
8
9
  'staging',
@@ -51,6 +52,10 @@ exports.PERMISSIONS = {
51
52
  supplementsImport: 'supplements:import',
52
53
  supplementMetadataManage: 'supplement_metadata:manage',
53
54
  supplementsSearchSelf: 'supplements:search:self',
55
+ documentsWriteSelf: 'documents:write:self',
56
+ documentsReadSelf: 'documents:read:self',
57
+ documentsReadAssigned: 'documents:read:assigned',
58
+ documentsReadAny: 'documents:read:any',
54
59
  };
55
60
  /**
56
61
  * `pending_verification` is a self-registered user who has not yet proved they
@@ -186,3 +191,141 @@ exports.GOAL_STATUSES = ['active', 'inactive'];
186
191
  exports.GOAL_SORT_FIELDS = ['sortOrder', 'name', 'updatedAt'];
187
192
  /** Where a supplement came from. Clients cannot suggest supplements, unlike foods. */
188
193
  exports.SUPPLEMENT_SOURCES = ['ADMIN', 'COACH', 'IMPORT'];
194
+ /** What a stored file is. Each feature that keeps files adds its own types here. */
195
+ exports.DOCUMENT_TYPES = [
196
+ 'PROGRESS_PHOTO_FRONT',
197
+ 'PROGRESS_PHOTO_BACK',
198
+ 'PROGRESS_PHOTO_SIDE',
199
+ 'BLOODWORK_REPORT',
200
+ 'OTHER',
201
+ ];
202
+ /** A document is `PENDING` until its upload is confirmed. */
203
+ exports.DOCUMENT_STATUSES = ['PENDING', 'UPLOADED'];
204
+ // Client onboarding
205
+ exports.ONBOARDING_STATUSES = [
206
+ 'NOT_STARTED',
207
+ 'IN_PROGRESS',
208
+ 'LOCKED',
209
+ 'PLEDGED',
210
+ ];
211
+ /** Every question step, in the order the client answers them. */
212
+ exports.ONBOARDING_STEPS = [
213
+ 'name',
214
+ 'age',
215
+ 'gender',
216
+ 'height',
217
+ 'weight',
218
+ 'goal',
219
+ 'level',
220
+ 'schedule',
221
+ 'day',
222
+ 'working_hours',
223
+ 'diet',
224
+ 'fuel',
225
+ 'eating_routine',
226
+ 'supplements',
227
+ 'body',
228
+ 'sleep',
229
+ 'digestion',
230
+ 'photos',
231
+ 'bloodwork',
232
+ 'notes',
233
+ ];
234
+ /** The sections of The File, in the order it lists them. */
235
+ exports.ONBOARDING_SECTIONS = [
236
+ 'basics',
237
+ 'goal_level',
238
+ 'training',
239
+ 'your_day',
240
+ 'sleep',
241
+ 'food_fuel',
242
+ 'body_health',
243
+ 'photos_bloodwork',
244
+ ];
245
+ exports.GENDERS = ['MALE', 'FEMALE'];
246
+ exports.EXPERIENCE_LEVELS = [
247
+ 'BEGINNER',
248
+ 'INTERMEDIATE',
249
+ 'ADVANCED',
250
+ ];
251
+ exports.TRAINING_TIMES = [
252
+ 'MORNING',
253
+ 'MIDDAY',
254
+ 'EVENING',
255
+ 'NIGHT',
256
+ ];
257
+ exports.WEEKDAYS = [
258
+ 'MON',
259
+ 'TUE',
260
+ 'WED',
261
+ 'THU',
262
+ 'FRI',
263
+ 'SAT',
264
+ 'SUN',
265
+ ];
266
+ exports.SESSION_LENGTHS = [
267
+ 'MIN_30',
268
+ 'MIN_45',
269
+ 'MIN_60',
270
+ 'MIN_90_PLUS',
271
+ ];
272
+ exports.ACTIVITY_LEVELS = [
273
+ 'SEDENTARY',
274
+ 'LIGHTLY_ACTIVE',
275
+ 'MODERATELY_ACTIVE',
276
+ 'VERY_ACTIVE',
277
+ 'PHYSICALLY_DEMANDING',
278
+ ];
279
+ exports.DIET_TYPES = [
280
+ 'VEGETARIAN',
281
+ 'NON_VEGETARIAN',
282
+ 'EGGETARIAN',
283
+ 'VEGAN',
284
+ ];
285
+ exports.ALLERGENS = [
286
+ 'PEANUT',
287
+ 'DAIRY',
288
+ 'GLUTEN',
289
+ 'SHELLFISH',
290
+ 'SOY',
291
+ 'EGGS',
292
+ ];
293
+ exports.WATER_INTAKES = [
294
+ 'UNDER_1L',
295
+ 'L1_TO_2',
296
+ 'L2_TO_3',
297
+ 'OVER_3L',
298
+ ];
299
+ exports.ANABOLIC_USE = ['NONE', 'PAST', 'CURRENT'];
300
+ exports.BODY_AREAS = [
301
+ 'SHOULDER',
302
+ 'LOWER_BACK',
303
+ 'KNEE',
304
+ 'WRIST_ELBOW',
305
+ 'NECK',
306
+ 'HIP',
307
+ ];
308
+ exports.SLEEP_DURATIONS = [
309
+ 'UNDER_5H',
310
+ 'H5_TO_6',
311
+ 'H6_TO_7',
312
+ 'H7_TO_8',
313
+ 'OVER_8H',
314
+ ];
315
+ exports.DIGESTION_QUALITIES = ['GOOD', 'AVERAGE', 'POOR'];
316
+ exports.REFLUX_FREQUENCIES = [
317
+ 'NEVER',
318
+ 'OCCASIONALLY',
319
+ 'FREQUENTLY',
320
+ 'DAILY',
321
+ ];
322
+ exports.DIGESTIVE_SYMPTOMS = [
323
+ 'BLOATING',
324
+ 'CONSTIPATION',
325
+ 'GAS',
326
+ 'STOMACH_PAIN',
327
+ 'LOOSE_MOTIONS',
328
+ ];
329
+ exports.KIDNEY_TEST_ANSWERS = ['YES', 'NO', 'NOT_SURE'];
330
+ exports.HEIGHT_UNITS = ['CM', 'FT'];
331
+ exports.WEIGHT_UNITS = ['KG', 'LB'];
@@ -0,0 +1,2 @@
1
+ export * from './onboarding.dto.js';
2
+ export * from './onboarding-steps.js';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./onboarding.dto.js"), exports);
18
+ __exportStar(require("./onboarding-steps.js"), exports);