gymmonk-schema 0.36.0 → 0.37.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/dist/center.d.ts CHANGED
@@ -54,20 +54,20 @@ import { z } from 'zod';
54
54
  */
55
55
  export declare const CENTER_TYPES: readonly ["gym", "strength", "crossfit", "functional", "bodybuilding", "powerlifting", "calisthenics", "cardio", "hiit", "spinning", "bootcamp", "aerobics", "sports-conditioning", "yoga", "pilates", "meditation", "zumba", "dance", "boxing", "kickboxing", "mma", "martial-arts", "swimming", "physiotherapy"];
56
56
  export declare const centerTypeSchema: z.ZodEnum<{
57
- cardio: "cardio";
57
+ gym: "gym";
58
58
  strength: "strength";
59
- yoga: "yoga";
60
59
  crossfit: "crossfit";
61
- gym: "gym";
62
60
  functional: "functional";
63
61
  bodybuilding: "bodybuilding";
64
62
  powerlifting: "powerlifting";
65
63
  calisthenics: "calisthenics";
64
+ cardio: "cardio";
66
65
  hiit: "hiit";
67
66
  spinning: "spinning";
68
67
  bootcamp: "bootcamp";
69
68
  aerobics: "aerobics";
70
69
  "sports-conditioning": "sports-conditioning";
70
+ yoga: "yoga";
71
71
  pilates: "pilates";
72
72
  meditation: "meditation";
73
73
  zumba: "zumba";
@@ -92,20 +92,20 @@ export declare const createCenterBodySchema: z.ZodObject<{
92
92
  name: z.ZodString;
93
93
  description: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
94
94
  types: z.ZodArray<z.ZodEnum<{
95
- cardio: "cardio";
95
+ gym: "gym";
96
96
  strength: "strength";
97
- yoga: "yoga";
98
97
  crossfit: "crossfit";
99
- gym: "gym";
100
98
  functional: "functional";
101
99
  bodybuilding: "bodybuilding";
102
100
  powerlifting: "powerlifting";
103
101
  calisthenics: "calisthenics";
102
+ cardio: "cardio";
104
103
  hiit: "hiit";
105
104
  spinning: "spinning";
106
105
  bootcamp: "bootcamp";
107
106
  aerobics: "aerobics";
108
107
  "sports-conditioning": "sports-conditioning";
108
+ yoga: "yoga";
109
109
  pilates: "pilates";
110
110
  meditation: "meditation";
111
111
  zumba: "zumba";
@@ -206,20 +206,20 @@ export declare const updateCenterBodySchema: z.ZodObject<{
206
206
  name: z.ZodOptional<z.ZodString>;
207
207
  description: z.ZodOptional<z.ZodPreprocess<z.ZodOptional<z.ZodString>>>;
208
208
  types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
209
- cardio: "cardio";
209
+ gym: "gym";
210
210
  strength: "strength";
211
- yoga: "yoga";
212
211
  crossfit: "crossfit";
213
- gym: "gym";
214
212
  functional: "functional";
215
213
  bodybuilding: "bodybuilding";
216
214
  powerlifting: "powerlifting";
217
215
  calisthenics: "calisthenics";
216
+ cardio: "cardio";
218
217
  hiit: "hiit";
219
218
  spinning: "spinning";
220
219
  bootcamp: "bootcamp";
221
220
  aerobics: "aerobics";
222
221
  "sports-conditioning": "sports-conditioning";
222
+ yoga: "yoga";
223
223
  pilates: "pilates";
224
224
  meditation: "meditation";
225
225
  zumba: "zumba";
@@ -335,20 +335,20 @@ export declare const centerSchema: z.ZodObject<{
335
335
  name: z.ZodString;
336
336
  description: z.ZodNullable<z.ZodString>;
337
337
  types: z.ZodArray<z.ZodEnum<{
338
- cardio: "cardio";
338
+ gym: "gym";
339
339
  strength: "strength";
340
- yoga: "yoga";
341
340
  crossfit: "crossfit";
342
- gym: "gym";
343
341
  functional: "functional";
344
342
  bodybuilding: "bodybuilding";
345
343
  powerlifting: "powerlifting";
346
344
  calisthenics: "calisthenics";
345
+ cardio: "cardio";
347
346
  hiit: "hiit";
348
347
  spinning: "spinning";
349
348
  bootcamp: "bootcamp";
350
349
  aerobics: "aerobics";
351
350
  "sports-conditioning": "sports-conditioning";
351
+ yoga: "yoga";
352
352
  pilates: "pilates";
353
353
  meditation: "meditation";
354
354
  zumba: "zumba";
@@ -10,8 +10,8 @@ import { z } from 'zod';
10
10
  export declare const EQUIPMENT_CATEGORIES: readonly ["cardio", "strength", "weight", "training", "recovery", "custom"];
11
11
  export declare const equipmentCategorySchema: z.ZodEnum<{
12
12
  custom: "custom";
13
- cardio: "cardio";
14
13
  strength: "strength";
14
+ cardio: "cardio";
15
15
  weight: "weight";
16
16
  training: "training";
17
17
  recovery: "recovery";
@@ -22,8 +22,8 @@ export declare const equipmentSchema: z.ZodObject<{
22
22
  centerId: z.ZodString;
23
23
  category: z.ZodEnum<{
24
24
  custom: "custom";
25
- cardio: "cardio";
26
25
  strength: "strength";
26
+ cardio: "cardio";
27
27
  weight: "weight";
28
28
  training: "training";
29
29
  recovery: "recovery";
@@ -39,8 +39,8 @@ export type Equipment = z.infer<typeof equipmentSchema>;
39
39
  export declare const equipmentCategorySummarySchema: z.ZodObject<{
40
40
  category: z.ZodEnum<{
41
41
  custom: "custom";
42
- cardio: "cardio";
43
42
  strength: "strength";
43
+ cardio: "cardio";
44
44
  weight: "weight";
45
45
  training: "training";
46
46
  recovery: "recovery";
@@ -53,8 +53,8 @@ export declare const createEquipmentBodySchema: z.ZodObject<{
53
53
  centerId: z.ZodString;
54
54
  category: z.ZodEnum<{
55
55
  custom: "custom";
56
- cardio: "cardio";
57
56
  strength: "strength";
57
+ cardio: "cardio";
58
58
  weight: "weight";
59
59
  training: "training";
60
60
  recovery: "recovery";
@@ -68,8 +68,8 @@ export declare const updateEquipmentBodySchema: z.ZodObject<{
68
68
  name: z.ZodOptional<z.ZodString>;
69
69
  category: z.ZodOptional<z.ZodEnum<{
70
70
  custom: "custom";
71
- cardio: "cardio";
72
71
  strength: "strength";
72
+ cardio: "cardio";
73
73
  weight: "weight";
74
74
  training: "training";
75
75
  recovery: "recovery";
@@ -101,8 +101,8 @@ export declare const EQUIPMENT_CATALOG: Record<EquipmentCategory, readonly strin
101
101
  export declare const equipmentQuantityEntrySchema: z.ZodObject<{
102
102
  category: z.ZodEnum<{
103
103
  custom: "custom";
104
- cardio: "cardio";
105
104
  strength: "strength";
105
+ cardio: "cardio";
106
106
  weight: "weight";
107
107
  training: "training";
108
108
  recovery: "recovery";
@@ -116,8 +116,8 @@ export declare const setEquipmentQuantitiesBodySchema: z.ZodObject<{
116
116
  items: z.ZodArray<z.ZodObject<{
117
117
  category: z.ZodEnum<{
118
118
  custom: "custom";
119
- cardio: "cardio";
120
119
  strength: "strength";
120
+ cardio: "cardio";
121
121
  weight: "weight";
122
122
  training: "training";
123
123
  recovery: "recovery";
@@ -131,8 +131,8 @@ export declare const equipmentQuerySchema: z.ZodObject<{
131
131
  centerId: z.ZodString;
132
132
  category: z.ZodOptional<z.ZodEnum<{
133
133
  custom: "custom";
134
- cardio: "cardio";
135
134
  strength: "strength";
135
+ cardio: "cardio";
136
136
  weight: "weight";
137
137
  training: "training";
138
138
  recovery: "recovery";
@@ -88,20 +88,20 @@ export declare const gymRegistrationBodySchema: z.ZodObject<{
88
88
  name: z.ZodString;
89
89
  description: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
90
90
  types: z.ZodArray<z.ZodEnum<{
91
- cardio: "cardio";
91
+ gym: "gym";
92
92
  strength: "strength";
93
- yoga: "yoga";
94
93
  crossfit: "crossfit";
95
- gym: "gym";
96
94
  functional: "functional";
97
95
  bodybuilding: "bodybuilding";
98
96
  powerlifting: "powerlifting";
99
97
  calisthenics: "calisthenics";
98
+ cardio: "cardio";
100
99
  hiit: "hiit";
101
100
  spinning: "spinning";
102
101
  bootcamp: "bootcamp";
103
102
  aerobics: "aerobics";
104
103
  "sports-conditioning": "sports-conditioning";
104
+ yoga: "yoga";
105
105
  pilates: "pilates";
106
106
  meditation: "meditation";
107
107
  zumba: "zumba";
package/dist/member.d.ts CHANGED
@@ -32,12 +32,6 @@ export declare const memberRosterItemSchema: z.ZodObject<{
32
32
  phone: z.ZodNullable<z.ZodString>;
33
33
  email: z.ZodNullable<z.ZodEmail>;
34
34
  planName: z.ZodNullable<z.ZodString>;
35
- tier: z.ZodNullable<z.ZodEnum<{
36
- free: "free";
37
- basic: "basic";
38
- standard: "standard";
39
- premium: "premium";
40
- }>>;
41
35
  status: z.ZodNullable<z.ZodEnum<{
42
36
  invited: "invited";
43
37
  active: "active";
@@ -100,12 +94,6 @@ export declare const memberListQuerySchema: z.ZodObject<{
100
94
  expiry: "expiry";
101
95
  dues: "dues";
102
96
  }>>;
103
- tier: z.ZodOptional<z.ZodEnum<{
104
- free: "free";
105
- basic: "basic";
106
- standard: "standard";
107
- premium: "premium";
108
- }>>;
109
97
  q: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
110
98
  }, z.core.$strip>;
111
99
  export type MemberListQuery = z.infer<typeof memberListQuerySchema>;
@@ -206,20 +194,9 @@ export declare const memberDetailSchema: z.ZodObject<{
206
194
  userId: z.ZodNullable<z.ZodString>;
207
195
  centerId: z.ZodString;
208
196
  planId: z.ZodString;
209
- tier: z.ZodEnum<{
210
- free: "free";
211
- basic: "basic";
212
- standard: "standard";
213
- premium: "premium";
214
- }>;
215
197
  planName: z.ZodString;
216
- tenureId: z.ZodEnum<{
217
- "1m": "1m";
218
- "3m": "3m";
219
- "6m": "6m";
220
- "1y": "1y";
221
- }>;
222
- tenureLabel: z.ZodString;
198
+ variantId: z.ZodString;
199
+ variantLabel: z.ZodString;
223
200
  priceInr: z.ZodNumber;
224
201
  status: z.ZodEnum<{
225
202
  invited: "invited";
@@ -306,12 +283,7 @@ export declare const createMemberBodySchema: z.ZodObject<{
306
283
  assignedTrainerId: z.ZodOptional<z.ZodString>;
307
284
  initialPlan: z.ZodOptional<z.ZodObject<{
308
285
  planId: z.ZodString;
309
- tenureId: z.ZodEnum<{
310
- "1m": "1m";
311
- "3m": "3m";
312
- "6m": "6m";
313
- "1y": "1y";
314
- }>;
286
+ variantId: z.ZodString;
315
287
  startDate: z.ZodOptional<z.ZodString>;
316
288
  payment: z.ZodOptional<z.ZodObject<{
317
289
  amountInr: z.ZodNumber;
@@ -450,20 +422,9 @@ export declare const provisionResultSchema: z.ZodObject<{
450
422
  userId: z.ZodNullable<z.ZodString>;
451
423
  centerId: z.ZodString;
452
424
  planId: z.ZodString;
453
- tier: z.ZodEnum<{
454
- free: "free";
455
- basic: "basic";
456
- standard: "standard";
457
- premium: "premium";
458
- }>;
459
425
  planName: z.ZodString;
460
- tenureId: z.ZodEnum<{
461
- "1m": "1m";
462
- "3m": "3m";
463
- "6m": "6m";
464
- "1y": "1y";
465
- }>;
466
- tenureLabel: z.ZodString;
426
+ variantId: z.ZodString;
427
+ variantLabel: z.ZodString;
467
428
  priceInr: z.ZodNumber;
468
429
  status: z.ZodEnum<{
469
430
  invited: "invited";
@@ -1 +1 @@
1
- {"version":3,"file":"member.d.ts","sourceRoot":"","sources":["../src/member.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"member.d.ts","sourceRoot":"","sources":["../src/member.ts"],"names":[],"mappings":"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"}
package/dist/member.js CHANGED
@@ -13,7 +13,6 @@ import { isoDateSchema, isoDateTimeSchema, objectIdSchema, optionalTrimmedString
13
13
  import { enrolmentStatusSchema } from './enrolment.js';
14
14
  import { emergencyContactSchema, MAX_EMERGENCY_CONTACTS } from './member-profile.js';
15
15
  import { assignMembershipBodySchema, membershipSchema, membershipStatusSchema, } from './membership.js';
16
- import { planTierSchema } from './membership-plan.js';
17
16
  import { addressSchema, bloodGroupSchema, genderSchema } from './shared.js';
18
17
  // ─── Segments ────────────────────────────────────────────────────────────────
19
18
  /** Attention buckets surfaced on roster cards. */
@@ -46,7 +45,6 @@ export const memberRosterItemSchema = z.object({
46
45
  phone: z.string().nullable(),
47
46
  email: z.email().nullable(),
48
47
  planName: z.string().nullable(),
49
- tier: planTierSchema.nullable(),
50
48
  status: membershipStatusSchema.nullable(),
51
49
  endDate: isoDateSchema.nullable(),
52
50
  lastVisitAt: isoDateTimeSchema.nullable(),
@@ -88,7 +86,6 @@ export const memberListQuerySchema = paginationSchema.extend({
88
86
  centerId: objectIdSchema.optional(),
89
87
  filter: memberFilterSchema.default('all'),
90
88
  sort: memberSortSchema.default('recent'),
91
- tier: planTierSchema.optional(),
92
89
  q: optionalTrimmedString(120),
93
90
  });
94
91
  // ─── Detail projection ───────────────────────────────────────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"member.js","sourceRoot":"","sources":["../src/member.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * gymmonk-schema — Member management (owner console)\n * ==================================================\n * Owner-facing roster + detail projections (User × MemberProfile × Membership)\n * and the \"add member\" provisioning payload. Adding a member provisions a real\n * central-auth account, so the result carries the login email + temp password.\n *\n * @module gymmonk-schema/member\n */\n\nimport { z } from 'zod';\nimport { gymMemberCodeSchema } from './codes.js';\nimport {\n isoDateSchema,\n isoDateTimeSchema,\n objectIdSchema,\n optionalTrimmedString,\n paginationSchema,\n phoneSchema,\n priceInrSchema,\n} from './common.js';\nimport { enrolmentStatusSchema } from './enrolment.js';\nimport { emergencyContactSchema, MAX_EMERGENCY_CONTACTS } from './member-profile.js';\nimport {\n assignMembershipBodySchema,\n membershipSchema,\n membershipStatusSchema,\n} from './membership.js';\nimport { planTierSchema } from './membership-plan.js';\nimport { addressSchema, bloodGroupSchema, genderSchema } from './shared.js';\n\n// ─── Segments ────────────────────────────────────────────────────────────────\n\n/** Attention buckets surfaced on roster cards. */\nexport const memberSegmentSchema = z.enum(['expiring', 'new', 'at-risk']);\nexport type MemberSegment = z.infer<typeof memberSegmentSchema>;\n\n// ─── Roster item (list projection) ───────────────────────────────────────────\n\nexport const memberRosterItemSchema = z.object({\n /** The gym record id — always present, even before the member claims. */\n enrolmentId: objectIdSchema,\n /** Null until claimed; the roster shows an \"Invited\" pill in that state. */\n userId: objectIdSchema.nullable(),\n recordStatus: enrolmentStatusSchema,\n membershipId: objectIdSchema.nullable(),\n gymMemberCode: gymMemberCodeSchema,\n name: z.string(),\n avatarUrl: z.string().nullable(),\n verified: z.boolean(),\n /**\n * Contact details, on the ROSTER row rather than only the detail record.\n *\n * The card's whole job when someone is overdue is to let the owner chase it\n * without leaving the list — call, WhatsApp, email. Those are `tel:` /\n * `wa.me` / `mailto:` links, so the row cannot build them without the raw\n * values, and fetching the full member just to dial them would be one\n * request per card.\n *\n * Nullable because an invited record may have only one of the two: the gym\n * creates it with whatever it has, and the member fills in the rest on claim.\n * Phone is RAW 10 digits — `+91` is display-only, never stored.\n */\n phone: z.string().nullable(),\n email: z.email().nullable(),\n planName: z.string().nullable(),\n tier: planTierSchema.nullable(),\n status: membershipStatusSchema.nullable(),\n endDate: isoDateSchema.nullable(),\n lastVisitAt: isoDateTimeSchema.nullable(),\n balanceDueInr: priceInrSchema,\n overdueDays: z.number().int().nullable(),\n segments: z.array(memberSegmentSchema),\n\n /**\n * When the gym record was created — NOT when the person claimed it. The\n * roster's \"Joined Date\" filter groups by how long someone has been a member\n * of the gym, which starts at the desk, not at the login.\n */\n joinedAt: isoDateTimeSchema,\n\n /**\n * Check-ins in the trailing 14 days, used by the roster's attendance filters\n * to separate a no-show from an irregular from a regular.\n *\n * Counted rather than derived from `lastVisitAt`, because the two answer\n * different questions: someone who came once yesterday and someone who comes\n * daily share a last visit but are not the same member to chase.\n */\n visits14d: z.number().int().nonnegative(),\n\n /** Assigned trainer, so the roster can be filtered down to one trainer's people. */\n trainerId: objectIdSchema.nullable(),\n trainerName: z.string().nullable(),\n});\n\n/** Trailing window the roster's attendance filters and `visits14d` are measured over. */\nexport const ATTENDANCE_WINDOW_DAYS = 14;\nexport type MemberRosterItem = z.infer<typeof memberRosterItemSchema>;\n\n/** Header counts for the roster. */\nexport const memberListSummarySchema = z.object({\n total: z.number().int().nonnegative(),\n active: z.number().int().nonnegative(),\n expiring: z.number().int().nonnegative(),\n inactive: z.number().int().nonnegative(),\n});\nexport type MemberListSummary = z.infer<typeof memberListSummarySchema>;\n\n// ─── List query ──────────────────────────────────────────────────────────────\n\nexport const memberFilterSchema = z.enum(['all', 'active', 'inactive', 'verified']);\nexport type MemberFilter = z.infer<typeof memberFilterSchema>;\n\nexport const memberSortSchema = z.enum(['recent', 'az', 'expiry', 'dues']);\nexport type MemberSort = z.infer<typeof memberSortSchema>;\n\nexport const memberListQuerySchema = paginationSchema.extend({\n centerId: objectIdSchema.optional(),\n filter: memberFilterSchema.default('all'),\n sort: memberSortSchema.default('recent'),\n tier: planTierSchema.optional(),\n q: optionalTrimmedString(120),\n});\nexport type MemberListQuery = z.infer<typeof memberListQuerySchema>;\n\n// ─── Detail projection ───────────────────────────────────────────────────────\n\n/** The identity slice a projection pulls from the auth `User`. */\nexport const memberUserRefSchema = z.object({\n /** Null while the record is still `invited` (no central-auth account linked). */\n id: objectIdSchema.nullable(),\n name: z.string(),\n email: z.string(),\n phone: z.string().nullable(),\n avatarUrl: z.string().nullable(),\n verified: z.boolean(),\n});\nexport type MemberUserRef = z.infer<typeof memberUserRefSchema>;\n\nexport const memberDetailSchema = z.object({\n enrolmentId: objectIdSchema,\n recordStatus: enrolmentStatusSchema,\n /**\n * Identity from central auth once claimed. Before that the gym still knows the\n * person (name / contact captured at the desk), so this carries the invited\n * details with `id: null`.\n */\n user: memberUserRefSchema,\n gymMemberCode: gymMemberCodeSchema,\n gender: genderSchema.nullable(),\n dob: isoDateSchema.nullable(),\n bloodGroup: bloodGroupSchema.nullable(),\n address: addressSchema.nullable(),\n emergencyContacts: z.array(emergencyContactSchema),\n /**\n * Last four digits of the member's Aadhaar, when one was recorded at the desk.\n * The full number is never stored (see `member-profile`), so this is all the\n * owner console can ever show — enough to match against the physical card the\n * member presents, useless to anyone who sees the screen.\n */\n aadhaarLast4: z.string().nullable(),\n /**\n * The scanned ID the desk took, if any. Carried on the detail projection so\n * the owner's edit form can round-trip it: a form that cannot see a stored\n * value sends back a blank one, and blank means \"clear it\".\n */\n idProofUrl: z.string().nullable(),\n joinedAt: isoDateTimeSchema,\n lastVisitAt: isoDateTimeSchema.nullable(),\n assignedWorkoutPlanId: objectIdSchema.nullable(),\n assignedTrainerId: objectIdSchema.nullable(),\n /**\n * The member's current membership, in FULL rather than by id.\n *\n * The profile screen shows the plan name, its billing cycle, the lifecycle\n * status pill and the expiry date all at once, and every one of those lives\n * here. Sending only the id forced the owner console to re-query the roster\n * for the same member just to read the plan columns back, and to match the\n * plan by NAME to find its perk icons — both of which this removes.\n */\n membership: membershipSchema.nullable(),\n /**\n * Still owed on the current term: its price less what has been recorded as\n * collected. Zero when settled, when the membership was cancelled, or when\n * there is no membership at all. Same definition as the roster's column, so\n * the profile and the list can never disagree about who owes money.\n */\n balanceDueInr: z.number().int().nonnegative(),\n});\nexport type MemberDetail = z.infer<typeof memberDetailSchema>;\n\n// ─── Add member (provisioning) ───────────────────────────────────────────────\n\nexport const createMemberBodySchema = z.object({\n firstName: z.string().trim().min(1, 'First name is required').max(80),\n lastName: optionalTrimmedString(80),\n email: z.email('A valid email is required'),\n phone: phoneSchema,\n gender: genderSchema,\n dob: isoDateSchema.optional(),\n bloodGroup: bloodGroupSchema.optional(),\n address: addressSchema.optional(),\n emergencyContacts: z.array(emergencyContactSchema).max(MAX_EMERGENCY_CONTACTS).default([]),\n idProofUrl: optionalTrimmedString(2000),\n avatarUrl: optionalTrimmedString(2000),\n assignedTrainerId: objectIdSchema.optional(),\n /** Optionally assign a plan in the same step. */\n initialPlan: assignMembershipBodySchema.optional(),\n});\nexport type CreateMemberBody = z.infer<typeof createMemberBodySchema>;\n\n/**\n * Edit a member's record from the owner console.\n *\n * Every field is optional — the console sends what the form holds, and a field\n * left out is left alone.\n *\n * ## What the gym may and may not change\n * `firstName` / `lastName` / `email` / `phone` are the INVITE details, and the\n * server accepts them only while the record is unclaimed. Once the member has\n * linked their central-auth account, that account is the source of truth for\n * their identity and is shared with the other products — a gym must not be able\n * to rewrite someone's name or email out from under them. The server ignores\n * those four on a claimed record rather than failing the whole request, so an\n * owner correcting a blood group is never blocked by a name they cannot change.\n *\n * Nullable fields (`dob`, `bloodGroup`, `address`, `assignedTrainerId`) accept\n * `null` to CLEAR a value, which `undefined` cannot express.\n */\nexport const updateMemberBodySchema = createMemberBodySchema\n .omit({\n initialPlan: true,\n dob: true,\n bloodGroup: true,\n address: true,\n assignedTrainerId: true,\n })\n .partial()\n .extend({\n dob: isoDateSchema.nullish(),\n bloodGroup: bloodGroupSchema.nullish(),\n address: addressSchema.nullish(),\n assignedTrainerId: objectIdSchema.nullish(),\n /** Last four digits only — the full number is never stored. */\n aadhaarLast4: z\n .string()\n .trim()\n .regex(/^\\d{4}$/, 'Enter the last four digits of the Aadhaar number')\n .nullish(),\n });\nexport type UpdateMemberBody = z.infer<typeof updateMemberBodySchema>;\n\n// ─── Invite & claim ──────────────────────────────────────────────────────────\n\n/**\n * The invite a gym hands to a new member.\n *\n * GymMonk never mints credentials for anyone: central auth is the SSOT for\n * identity, and an account there is shared across products. So adding a member\n * creates a gym record only, plus an unguessable invite code. The member\n * registers/logs in themselves through central auth (exactly as in jansathi) and\n * then CLAIMS the record. The owner shares `url` over WhatsApp or shows the QR.\n */\nexport const memberInviteSchema = z.object({\n /** Single-use, unguessable. Regenerating an invite invalidates the old one. */\n code: z.string(),\n /** Absolute claim URL the owner shares (also encoded into the QR). */\n url: z.string(),\n /** The address the member MUST register with for the claim to succeed. */\n email: z.string(),\n /** WhatsApp number to share on, when the gym recorded one. */\n phone: z.string().nullable(),\n expiresAt: isoDateTimeSchema,\n});\nexport type MemberInvite = z.infer<typeof memberInviteSchema>;\n\n/** Result of adding a member: the gym record + the invite to hand over. */\nexport const provisionResultSchema = z.object({\n /** The new member record (NOT a central-auth user — none is created). */\n enrolmentId: objectIdSchema,\n code: z.string(),\n invite: memberInviteSchema,\n /**\n * The membership created from `initialPlan`, or `null`.\n *\n * Null means one of two DIFFERENT things, and the caller can tell them apart\n * because it knows whether it sent `initialPlan`: no plan was chosen, or the\n * chosen plan could not be assigned. Adding a member never fails over the\n * second case — the person is on the roster either way — so this is how the\n * owner finds out the plan still needs assigning rather than assuming it took.\n */\n membership: membershipSchema.nullable(),\n});\nexport type ProvisionResult = z.infer<typeof provisionResultSchema>;\n\n/**\n * What the claim screen shows BEFORE the member authenticates, so they know\n * which address to register with. Public (the code is the bearer secret), and\n * deliberately minimal — gym name, member code, and the expected email.\n */\nexport const invitePreviewSchema = z.object({\n gymName: z.string(),\n gymMemberCode: gymMemberCodeSchema,\n /** Shown verbatim: the member must know exactly which address to use. */\n email: z.string(),\n expiresAt: isoDateTimeSchema,\n /** True once claimed / expired, so the screen can explain why it failed. */\n claimed: z.boolean(),\n expired: z.boolean(),\n});\nexport type InvitePreview = z.infer<typeof invitePreviewSchema>;\n\n/**\n * Claim an invite as the authenticated caller. The server links the record only\n * when the code is valid AND the caller's central-auth email matches the address\n * the invite was issued to.\n */\nexport const claimInviteBodySchema = z.object({\n code: z.string().trim().min(1),\n});\nexport type ClaimInviteBody = z.infer<typeof claimInviteBodySchema>;\n\n// ─── Mutations ───────────────────────────────────────────────────────────────\n\nexport const setMemberStatusBodySchema = z.object({ active: z.boolean() });\nexport type SetMemberStatusBody = z.infer<typeof setMemberStatusBodySchema>;\n\nexport const assignTrainerBodySchema = z.object({\n trainerId: objectIdSchema.nullable(),\n});\nexport type AssignTrainerBody = z.infer<typeof assignTrainerBodySchema>;\n\nexport const assignWorkoutPlanBodySchema = z.object({\n planId: objectIdSchema.nullable(),\n});\nexport type AssignWorkoutPlanBody = z.infer<typeof assignWorkoutPlanBodySchema>;\n\n/** Remove a member from the gym — echoes the member code to confirm. */\nexport const deleteMemberBodySchema = z.object({\n confirmationCode: z.string().trim().min(1),\n});\nexport type DeleteMemberBody = z.infer<typeof deleteMemberBodySchema>;\n"]}
1
+ {"version":3,"file":"member.js","sourceRoot":"","sources":["../src/member.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * gymmonk-schema — Member management (owner console)\n * ==================================================\n * Owner-facing roster + detail projections (User × MemberProfile × Membership)\n * and the \"add member\" provisioning payload. Adding a member provisions a real\n * central-auth account, so the result carries the login email + temp password.\n *\n * @module gymmonk-schema/member\n */\n\nimport { z } from 'zod';\nimport { gymMemberCodeSchema } from './codes.js';\nimport {\n isoDateSchema,\n isoDateTimeSchema,\n objectIdSchema,\n optionalTrimmedString,\n paginationSchema,\n phoneSchema,\n priceInrSchema,\n} from './common.js';\nimport { enrolmentStatusSchema } from './enrolment.js';\nimport { emergencyContactSchema, MAX_EMERGENCY_CONTACTS } from './member-profile.js';\nimport {\n assignMembershipBodySchema,\n membershipSchema,\n membershipStatusSchema,\n} from './membership.js';\nimport { addressSchema, bloodGroupSchema, genderSchema } from './shared.js';\n\n// ─── Segments ────────────────────────────────────────────────────────────────\n\n/** Attention buckets surfaced on roster cards. */\nexport const memberSegmentSchema = z.enum(['expiring', 'new', 'at-risk']);\nexport type MemberSegment = z.infer<typeof memberSegmentSchema>;\n\n// ─── Roster item (list projection) ───────────────────────────────────────────\n\nexport const memberRosterItemSchema = z.object({\n /** The gym record id — always present, even before the member claims. */\n enrolmentId: objectIdSchema,\n /** Null until claimed; the roster shows an \"Invited\" pill in that state. */\n userId: objectIdSchema.nullable(),\n recordStatus: enrolmentStatusSchema,\n membershipId: objectIdSchema.nullable(),\n gymMemberCode: gymMemberCodeSchema,\n name: z.string(),\n avatarUrl: z.string().nullable(),\n verified: z.boolean(),\n /**\n * Contact details, on the ROSTER row rather than only the detail record.\n *\n * The card's whole job when someone is overdue is to let the owner chase it\n * without leaving the list — call, WhatsApp, email. Those are `tel:` /\n * `wa.me` / `mailto:` links, so the row cannot build them without the raw\n * values, and fetching the full member just to dial them would be one\n * request per card.\n *\n * Nullable because an invited record may have only one of the two: the gym\n * creates it with whatever it has, and the member fills in the rest on claim.\n * Phone is RAW 10 digits — `+91` is display-only, never stored.\n */\n phone: z.string().nullable(),\n email: z.email().nullable(),\n planName: z.string().nullable(),\n status: membershipStatusSchema.nullable(),\n endDate: isoDateSchema.nullable(),\n lastVisitAt: isoDateTimeSchema.nullable(),\n balanceDueInr: priceInrSchema,\n overdueDays: z.number().int().nullable(),\n segments: z.array(memberSegmentSchema),\n\n /**\n * When the gym record was created — NOT when the person claimed it. The\n * roster's \"Joined Date\" filter groups by how long someone has been a member\n * of the gym, which starts at the desk, not at the login.\n */\n joinedAt: isoDateTimeSchema,\n\n /**\n * Check-ins in the trailing 14 days, used by the roster's attendance filters\n * to separate a no-show from an irregular from a regular.\n *\n * Counted rather than derived from `lastVisitAt`, because the two answer\n * different questions: someone who came once yesterday and someone who comes\n * daily share a last visit but are not the same member to chase.\n */\n visits14d: z.number().int().nonnegative(),\n\n /** Assigned trainer, so the roster can be filtered down to one trainer's people. */\n trainerId: objectIdSchema.nullable(),\n trainerName: z.string().nullable(),\n});\n\n/** Trailing window the roster's attendance filters and `visits14d` are measured over. */\nexport const ATTENDANCE_WINDOW_DAYS = 14;\nexport type MemberRosterItem = z.infer<typeof memberRosterItemSchema>;\n\n/** Header counts for the roster. */\nexport const memberListSummarySchema = z.object({\n total: z.number().int().nonnegative(),\n active: z.number().int().nonnegative(),\n expiring: z.number().int().nonnegative(),\n inactive: z.number().int().nonnegative(),\n});\nexport type MemberListSummary = z.infer<typeof memberListSummarySchema>;\n\n// ─── List query ──────────────────────────────────────────────────────────────\n\nexport const memberFilterSchema = z.enum(['all', 'active', 'inactive', 'verified']);\nexport type MemberFilter = z.infer<typeof memberFilterSchema>;\n\nexport const memberSortSchema = z.enum(['recent', 'az', 'expiry', 'dues']);\nexport type MemberSort = z.infer<typeof memberSortSchema>;\n\nexport const memberListQuerySchema = paginationSchema.extend({\n centerId: objectIdSchema.optional(),\n filter: memberFilterSchema.default('all'),\n sort: memberSortSchema.default('recent'),\n q: optionalTrimmedString(120),\n});\nexport type MemberListQuery = z.infer<typeof memberListQuerySchema>;\n\n// ─── Detail projection ───────────────────────────────────────────────────────\n\n/** The identity slice a projection pulls from the auth `User`. */\nexport const memberUserRefSchema = z.object({\n /** Null while the record is still `invited` (no central-auth account linked). */\n id: objectIdSchema.nullable(),\n name: z.string(),\n email: z.string(),\n phone: z.string().nullable(),\n avatarUrl: z.string().nullable(),\n verified: z.boolean(),\n});\nexport type MemberUserRef = z.infer<typeof memberUserRefSchema>;\n\nexport const memberDetailSchema = z.object({\n enrolmentId: objectIdSchema,\n recordStatus: enrolmentStatusSchema,\n /**\n * Identity from central auth once claimed. Before that the gym still knows the\n * person (name / contact captured at the desk), so this carries the invited\n * details with `id: null`.\n */\n user: memberUserRefSchema,\n gymMemberCode: gymMemberCodeSchema,\n gender: genderSchema.nullable(),\n dob: isoDateSchema.nullable(),\n bloodGroup: bloodGroupSchema.nullable(),\n address: addressSchema.nullable(),\n emergencyContacts: z.array(emergencyContactSchema),\n /**\n * Last four digits of the member's Aadhaar, when one was recorded at the desk.\n * The full number is never stored (see `member-profile`), so this is all the\n * owner console can ever show — enough to match against the physical card the\n * member presents, useless to anyone who sees the screen.\n */\n aadhaarLast4: z.string().nullable(),\n /**\n * The scanned ID the desk took, if any. Carried on the detail projection so\n * the owner's edit form can round-trip it: a form that cannot see a stored\n * value sends back a blank one, and blank means \"clear it\".\n */\n idProofUrl: z.string().nullable(),\n joinedAt: isoDateTimeSchema,\n lastVisitAt: isoDateTimeSchema.nullable(),\n assignedWorkoutPlanId: objectIdSchema.nullable(),\n assignedTrainerId: objectIdSchema.nullable(),\n /**\n * The member's current membership, in FULL rather than by id.\n *\n * The profile screen shows the plan name, its billing cycle, the lifecycle\n * status pill and the expiry date all at once, and every one of those lives\n * here. Sending only the id forced the owner console to re-query the roster\n * for the same member just to read the plan columns back, and to match the\n * plan by NAME to find its perk icons — both of which this removes.\n */\n membership: membershipSchema.nullable(),\n /**\n * Still owed on the current term: its price less what has been recorded as\n * collected. Zero when settled, when the membership was cancelled, or when\n * there is no membership at all. Same definition as the roster's column, so\n * the profile and the list can never disagree about who owes money.\n */\n balanceDueInr: z.number().int().nonnegative(),\n});\nexport type MemberDetail = z.infer<typeof memberDetailSchema>;\n\n// ─── Add member (provisioning) ───────────────────────────────────────────────\n\nexport const createMemberBodySchema = z.object({\n firstName: z.string().trim().min(1, 'First name is required').max(80),\n lastName: optionalTrimmedString(80),\n email: z.email('A valid email is required'),\n phone: phoneSchema,\n gender: genderSchema,\n dob: isoDateSchema.optional(),\n bloodGroup: bloodGroupSchema.optional(),\n address: addressSchema.optional(),\n emergencyContacts: z.array(emergencyContactSchema).max(MAX_EMERGENCY_CONTACTS).default([]),\n idProofUrl: optionalTrimmedString(2000),\n avatarUrl: optionalTrimmedString(2000),\n assignedTrainerId: objectIdSchema.optional(),\n /** Optionally assign a plan in the same step. */\n initialPlan: assignMembershipBodySchema.optional(),\n});\nexport type CreateMemberBody = z.infer<typeof createMemberBodySchema>;\n\n/**\n * Edit a member's record from the owner console.\n *\n * Every field is optional — the console sends what the form holds, and a field\n * left out is left alone.\n *\n * ## What the gym may and may not change\n * `firstName` / `lastName` / `email` / `phone` are the INVITE details, and the\n * server accepts them only while the record is unclaimed. Once the member has\n * linked their central-auth account, that account is the source of truth for\n * their identity and is shared with the other products — a gym must not be able\n * to rewrite someone's name or email out from under them. The server ignores\n * those four on a claimed record rather than failing the whole request, so an\n * owner correcting a blood group is never blocked by a name they cannot change.\n *\n * Nullable fields (`dob`, `bloodGroup`, `address`, `assignedTrainerId`) accept\n * `null` to CLEAR a value, which `undefined` cannot express.\n */\nexport const updateMemberBodySchema = createMemberBodySchema\n .omit({\n initialPlan: true,\n dob: true,\n bloodGroup: true,\n address: true,\n assignedTrainerId: true,\n })\n .partial()\n .extend({\n dob: isoDateSchema.nullish(),\n bloodGroup: bloodGroupSchema.nullish(),\n address: addressSchema.nullish(),\n assignedTrainerId: objectIdSchema.nullish(),\n /** Last four digits only — the full number is never stored. */\n aadhaarLast4: z\n .string()\n .trim()\n .regex(/^\\d{4}$/, 'Enter the last four digits of the Aadhaar number')\n .nullish(),\n });\nexport type UpdateMemberBody = z.infer<typeof updateMemberBodySchema>;\n\n// ─── Invite & claim ──────────────────────────────────────────────────────────\n\n/**\n * The invite a gym hands to a new member.\n *\n * GymMonk never mints credentials for anyone: central auth is the SSOT for\n * identity, and an account there is shared across products. So adding a member\n * creates a gym record only, plus an unguessable invite code. The member\n * registers/logs in themselves through central auth (exactly as in jansathi) and\n * then CLAIMS the record. The owner shares `url` over WhatsApp or shows the QR.\n */\nexport const memberInviteSchema = z.object({\n /** Single-use, unguessable. Regenerating an invite invalidates the old one. */\n code: z.string(),\n /** Absolute claim URL the owner shares (also encoded into the QR). */\n url: z.string(),\n /** The address the member MUST register with for the claim to succeed. */\n email: z.string(),\n /** WhatsApp number to share on, when the gym recorded one. */\n phone: z.string().nullable(),\n expiresAt: isoDateTimeSchema,\n});\nexport type MemberInvite = z.infer<typeof memberInviteSchema>;\n\n/** Result of adding a member: the gym record + the invite to hand over. */\nexport const provisionResultSchema = z.object({\n /** The new member record (NOT a central-auth user — none is created). */\n enrolmentId: objectIdSchema,\n code: z.string(),\n invite: memberInviteSchema,\n /**\n * The membership created from `initialPlan`, or `null`.\n *\n * Null means one of two DIFFERENT things, and the caller can tell them apart\n * because it knows whether it sent `initialPlan`: no plan was chosen, or the\n * chosen plan could not be assigned. Adding a member never fails over the\n * second case — the person is on the roster either way — so this is how the\n * owner finds out the plan still needs assigning rather than assuming it took.\n */\n membership: membershipSchema.nullable(),\n});\nexport type ProvisionResult = z.infer<typeof provisionResultSchema>;\n\n/**\n * What the claim screen shows BEFORE the member authenticates, so they know\n * which address to register with. Public (the code is the bearer secret), and\n * deliberately minimal — gym name, member code, and the expected email.\n */\nexport const invitePreviewSchema = z.object({\n gymName: z.string(),\n gymMemberCode: gymMemberCodeSchema,\n /** Shown verbatim: the member must know exactly which address to use. */\n email: z.string(),\n expiresAt: isoDateTimeSchema,\n /** True once claimed / expired, so the screen can explain why it failed. */\n claimed: z.boolean(),\n expired: z.boolean(),\n});\nexport type InvitePreview = z.infer<typeof invitePreviewSchema>;\n\n/**\n * Claim an invite as the authenticated caller. The server links the record only\n * when the code is valid AND the caller's central-auth email matches the address\n * the invite was issued to.\n */\nexport const claimInviteBodySchema = z.object({\n code: z.string().trim().min(1),\n});\nexport type ClaimInviteBody = z.infer<typeof claimInviteBodySchema>;\n\n// ─── Mutations ───────────────────────────────────────────────────────────────\n\nexport const setMemberStatusBodySchema = z.object({ active: z.boolean() });\nexport type SetMemberStatusBody = z.infer<typeof setMemberStatusBodySchema>;\n\nexport const assignTrainerBodySchema = z.object({\n trainerId: objectIdSchema.nullable(),\n});\nexport type AssignTrainerBody = z.infer<typeof assignTrainerBodySchema>;\n\nexport const assignWorkoutPlanBodySchema = z.object({\n planId: objectIdSchema.nullable(),\n});\nexport type AssignWorkoutPlanBody = z.infer<typeof assignWorkoutPlanBodySchema>;\n\n/** Remove a member from the gym — echoes the member code to confirm. */\nexport const deleteMemberBodySchema = z.object({\n confirmationCode: z.string().trim().min(1),\n});\nexport type DeleteMemberBody = z.infer<typeof deleteMemberBodySchema>;\n"]}