gymmonk-schema 0.2.0 → 0.3.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/announcement.d.ts +56 -0
- package/dist/announcement.d.ts.map +1 -0
- package/dist/announcement.js +40 -0
- package/dist/announcement.js.map +1 -0
- package/dist/center.d.ts +381 -0
- package/dist/center.d.ts.map +1 -0
- package/dist/center.js +96 -0
- package/dist/center.js.map +1 -0
- package/dist/common.d.ts +28 -0
- package/dist/common.d.ts.map +1 -1
- package/dist/common.js +37 -0
- package/dist/common.js.map +1 -1
- package/dist/equipment.d.ts +93 -0
- package/dist/equipment.d.ts.map +1 -0
- package/dist/equipment.js +54 -0
- package/dist/equipment.js.map +1 -0
- package/dist/exercise.d.ts +234 -0
- package/dist/exercise.d.ts.map +1 -0
- package/dist/exercise.js +93 -0
- package/dist/exercise.js.map +1 -0
- package/dist/feedback.d.ts +119 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +77 -0
- package/dist/feedback.js.map +1 -0
- package/dist/home.d.ts +74 -0
- package/dist/home.d.ts.map +1 -0
- package/dist/home.js +28 -0
- package/dist/home.js.map +1 -0
- package/dist/index.d.ts +27 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -5
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +143 -0
- package/dist/insights.d.ts.map +1 -0
- package/dist/insights.js +79 -0
- package/dist/insights.js.map +1 -0
- package/dist/member-profile.d.ts +312 -0
- package/dist/member-profile.d.ts.map +1 -0
- package/dist/member-profile.js +103 -0
- package/dist/member-profile.js.map +1 -0
- package/dist/member.d.ts +365 -0
- package/dist/member.d.ts.map +1 -0
- package/dist/member.js +169 -0
- package/dist/member.js.map +1 -0
- package/dist/membership-plan.d.ts +244 -0
- package/dist/membership-plan.d.ts.map +1 -0
- package/dist/membership-plan.js +80 -0
- package/dist/membership-plan.js.map +1 -0
- package/dist/membership.d.ts +154 -0
- package/dist/membership.d.ts.map +1 -0
- package/dist/membership.js +103 -0
- package/dist/membership.js.map +1 -0
- package/dist/notification.d.ts +59 -0
- package/dist/notification.d.ts.map +1 -0
- package/dist/notification.js +49 -0
- package/dist/notification.js.map +1 -0
- package/dist/onboarding.d.ts +361 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +74 -0
- package/dist/onboarding.js.map +1 -0
- package/dist/organisation.d.ts +199 -0
- package/dist/organisation.d.ts.map +1 -0
- package/dist/organisation.js +51 -0
- package/dist/organisation.js.map +1 -0
- package/dist/owner-profile.d.ts +50 -0
- package/dist/owner-profile.d.ts.map +1 -0
- package/dist/owner-profile.js +34 -0
- package/dist/owner-profile.js.map +1 -0
- package/dist/pricing.d.ts +103 -0
- package/dist/pricing.d.ts.map +1 -0
- package/dist/pricing.js +73 -0
- package/dist/pricing.js.map +1 -0
- package/dist/session.d.ts +90 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +59 -0
- package/dist/session.js.map +1 -0
- package/dist/shared.d.ts +199 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +107 -0
- package/dist/shared.js.map +1 -0
- package/dist/staff.d.ts +288 -0
- package/dist/staff.d.ts.map +1 -0
- package/dist/staff.js +115 -0
- package/dist/staff.js.map +1 -0
- package/dist/subscription.d.ts +69 -0
- package/dist/subscription.d.ts.map +1 -0
- package/dist/subscription.js +47 -0
- package/dist/subscription.js.map +1 -0
- package/dist/user.d.ts +63 -0
- package/dist/user.d.ts.map +1 -0
- package/dist/user.js +44 -0
- package/dist/user.js.map +1 -0
- package/dist/workout-plan.d.ts +201 -0
- package/dist/workout-plan.d.ts.map +1 -0
- package/dist/workout-plan.js +71 -0
- package/dist/workout-plan.js.map +1 -0
- package/package.json +1 -1
package/dist/member.d.ts
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gymmonk-schema — Member management (owner console)
|
|
3
|
+
* ==================================================
|
|
4
|
+
* Owner-facing roster + detail projections (User × MemberProfile × Membership)
|
|
5
|
+
* and the "add member" provisioning payload. Adding a member provisions a real
|
|
6
|
+
* central-auth account, so the result carries the login email + temp password.
|
|
7
|
+
*
|
|
8
|
+
* @module gymmonk-schema/member
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
/** Attention buckets surfaced on roster cards. */
|
|
12
|
+
export declare const memberSegmentSchema: z.ZodEnum<{
|
|
13
|
+
expiring: "expiring";
|
|
14
|
+
new: "new";
|
|
15
|
+
"at-risk": "at-risk";
|
|
16
|
+
}>;
|
|
17
|
+
export type MemberSegment = z.infer<typeof memberSegmentSchema>;
|
|
18
|
+
export declare const memberRosterItemSchema: z.ZodObject<{
|
|
19
|
+
memberProfileId: z.ZodString;
|
|
20
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
21
|
+
recordStatus: z.ZodEnum<{
|
|
22
|
+
active: "active";
|
|
23
|
+
invited: "invited";
|
|
24
|
+
}>;
|
|
25
|
+
membershipId: z.ZodNullable<z.ZodString>;
|
|
26
|
+
memberCode: z.ZodString;
|
|
27
|
+
name: z.ZodString;
|
|
28
|
+
avatarUrl: z.ZodNullable<z.ZodString>;
|
|
29
|
+
verified: z.ZodBoolean;
|
|
30
|
+
planName: z.ZodNullable<z.ZodString>;
|
|
31
|
+
tier: z.ZodNullable<z.ZodEnum<{
|
|
32
|
+
free: "free";
|
|
33
|
+
basic: "basic";
|
|
34
|
+
standard: "standard";
|
|
35
|
+
premium: "premium";
|
|
36
|
+
}>>;
|
|
37
|
+
status: z.ZodNullable<z.ZodEnum<{
|
|
38
|
+
active: "active";
|
|
39
|
+
invited: "invited";
|
|
40
|
+
paused: "paused";
|
|
41
|
+
expired: "expired";
|
|
42
|
+
cancelled: "cancelled";
|
|
43
|
+
}>>;
|
|
44
|
+
endDate: z.ZodNullable<z.ZodString>;
|
|
45
|
+
lastVisitAt: z.ZodNullable<z.ZodISODateTime>;
|
|
46
|
+
balanceDueInr: z.ZodNumber;
|
|
47
|
+
overdueDays: z.ZodNullable<z.ZodNumber>;
|
|
48
|
+
segments: z.ZodArray<z.ZodEnum<{
|
|
49
|
+
expiring: "expiring";
|
|
50
|
+
new: "new";
|
|
51
|
+
"at-risk": "at-risk";
|
|
52
|
+
}>>;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
export type MemberRosterItem = z.infer<typeof memberRosterItemSchema>;
|
|
55
|
+
/** Header counts for the roster. */
|
|
56
|
+
export declare const memberListSummarySchema: z.ZodObject<{
|
|
57
|
+
total: z.ZodNumber;
|
|
58
|
+
active: z.ZodNumber;
|
|
59
|
+
expiring: z.ZodNumber;
|
|
60
|
+
inactive: z.ZodNumber;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export type MemberListSummary = z.infer<typeof memberListSummarySchema>;
|
|
63
|
+
export declare const memberFilterSchema: z.ZodEnum<{
|
|
64
|
+
active: "active";
|
|
65
|
+
inactive: "inactive";
|
|
66
|
+
verified: "verified";
|
|
67
|
+
all: "all";
|
|
68
|
+
}>;
|
|
69
|
+
export type MemberFilter = z.infer<typeof memberFilterSchema>;
|
|
70
|
+
export declare const memberSortSchema: z.ZodEnum<{
|
|
71
|
+
recent: "recent";
|
|
72
|
+
az: "az";
|
|
73
|
+
expiry: "expiry";
|
|
74
|
+
dues: "dues";
|
|
75
|
+
}>;
|
|
76
|
+
export type MemberSort = z.infer<typeof memberSortSchema>;
|
|
77
|
+
export declare const memberListQuerySchema: z.ZodObject<{
|
|
78
|
+
page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
79
|
+
limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
80
|
+
centerId: z.ZodOptional<z.ZodString>;
|
|
81
|
+
filter: z.ZodDefault<z.ZodEnum<{
|
|
82
|
+
active: "active";
|
|
83
|
+
inactive: "inactive";
|
|
84
|
+
verified: "verified";
|
|
85
|
+
all: "all";
|
|
86
|
+
}>>;
|
|
87
|
+
sort: z.ZodDefault<z.ZodEnum<{
|
|
88
|
+
recent: "recent";
|
|
89
|
+
az: "az";
|
|
90
|
+
expiry: "expiry";
|
|
91
|
+
dues: "dues";
|
|
92
|
+
}>>;
|
|
93
|
+
tier: z.ZodOptional<z.ZodEnum<{
|
|
94
|
+
free: "free";
|
|
95
|
+
basic: "basic";
|
|
96
|
+
standard: "standard";
|
|
97
|
+
premium: "premium";
|
|
98
|
+
}>>;
|
|
99
|
+
q: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
|
|
100
|
+
}, z.core.$strip>;
|
|
101
|
+
export type MemberListQuery = z.infer<typeof memberListQuerySchema>;
|
|
102
|
+
/** The identity slice a projection pulls from the auth `User`. */
|
|
103
|
+
export declare const memberUserRefSchema: z.ZodObject<{
|
|
104
|
+
id: z.ZodNullable<z.ZodString>;
|
|
105
|
+
name: z.ZodString;
|
|
106
|
+
email: z.ZodString;
|
|
107
|
+
phone: z.ZodNullable<z.ZodString>;
|
|
108
|
+
avatarUrl: z.ZodNullable<z.ZodString>;
|
|
109
|
+
verified: z.ZodBoolean;
|
|
110
|
+
}, z.core.$strip>;
|
|
111
|
+
export type MemberUserRef = z.infer<typeof memberUserRefSchema>;
|
|
112
|
+
export declare const memberDetailSchema: z.ZodObject<{
|
|
113
|
+
memberProfileId: z.ZodString;
|
|
114
|
+
recordStatus: z.ZodEnum<{
|
|
115
|
+
active: "active";
|
|
116
|
+
invited: "invited";
|
|
117
|
+
}>;
|
|
118
|
+
user: z.ZodObject<{
|
|
119
|
+
id: z.ZodNullable<z.ZodString>;
|
|
120
|
+
name: z.ZodString;
|
|
121
|
+
email: z.ZodString;
|
|
122
|
+
phone: z.ZodNullable<z.ZodString>;
|
|
123
|
+
avatarUrl: z.ZodNullable<z.ZodString>;
|
|
124
|
+
verified: z.ZodBoolean;
|
|
125
|
+
}, z.core.$strip>;
|
|
126
|
+
memberCode: z.ZodString;
|
|
127
|
+
gender: z.ZodNullable<z.ZodEnum<{
|
|
128
|
+
male: "male";
|
|
129
|
+
female: "female";
|
|
130
|
+
other: "other";
|
|
131
|
+
}>>;
|
|
132
|
+
dob: z.ZodNullable<z.ZodString>;
|
|
133
|
+
bloodGroup: z.ZodNullable<z.ZodEnum<{
|
|
134
|
+
"A+": "A+";
|
|
135
|
+
"A-": "A-";
|
|
136
|
+
"B+": "B+";
|
|
137
|
+
"B-": "B-";
|
|
138
|
+
"O+": "O+";
|
|
139
|
+
"O-": "O-";
|
|
140
|
+
"AB+": "AB+";
|
|
141
|
+
"AB-": "AB-";
|
|
142
|
+
}>>;
|
|
143
|
+
address: z.ZodNullable<z.ZodObject<{
|
|
144
|
+
street: z.ZodString;
|
|
145
|
+
city: z.ZodString;
|
|
146
|
+
state: z.ZodEnum<{
|
|
147
|
+
"Andhra Pradesh": "Andhra Pradesh";
|
|
148
|
+
"Arunachal Pradesh": "Arunachal Pradesh";
|
|
149
|
+
Assam: "Assam";
|
|
150
|
+
Bihar: "Bihar";
|
|
151
|
+
Chhattisgarh: "Chhattisgarh";
|
|
152
|
+
Goa: "Goa";
|
|
153
|
+
Gujarat: "Gujarat";
|
|
154
|
+
Haryana: "Haryana";
|
|
155
|
+
"Himachal Pradesh": "Himachal Pradesh";
|
|
156
|
+
Jharkhand: "Jharkhand";
|
|
157
|
+
Karnataka: "Karnataka";
|
|
158
|
+
Kerala: "Kerala";
|
|
159
|
+
"Madhya Pradesh": "Madhya Pradesh";
|
|
160
|
+
Maharashtra: "Maharashtra";
|
|
161
|
+
Manipur: "Manipur";
|
|
162
|
+
Meghalaya: "Meghalaya";
|
|
163
|
+
Mizoram: "Mizoram";
|
|
164
|
+
Nagaland: "Nagaland";
|
|
165
|
+
Odisha: "Odisha";
|
|
166
|
+
Punjab: "Punjab";
|
|
167
|
+
Rajasthan: "Rajasthan";
|
|
168
|
+
Sikkim: "Sikkim";
|
|
169
|
+
"Tamil Nadu": "Tamil Nadu";
|
|
170
|
+
Telangana: "Telangana";
|
|
171
|
+
Tripura: "Tripura";
|
|
172
|
+
"Uttar Pradesh": "Uttar Pradesh";
|
|
173
|
+
Uttarakhand: "Uttarakhand";
|
|
174
|
+
"West Bengal": "West Bengal";
|
|
175
|
+
"Andaman and Nicobar Islands": "Andaman and Nicobar Islands";
|
|
176
|
+
Chandigarh: "Chandigarh";
|
|
177
|
+
"Dadra and Nagar Haveli and Daman and Diu": "Dadra and Nagar Haveli and Daman and Diu";
|
|
178
|
+
Delhi: "Delhi";
|
|
179
|
+
"Jammu and Kashmir": "Jammu and Kashmir";
|
|
180
|
+
Ladakh: "Ladakh";
|
|
181
|
+
Lakshadweep: "Lakshadweep";
|
|
182
|
+
Puducherry: "Puducherry";
|
|
183
|
+
}>;
|
|
184
|
+
pincode: z.ZodString;
|
|
185
|
+
}, z.core.$strip>>;
|
|
186
|
+
emergencyContacts: z.ZodArray<z.ZodObject<{
|
|
187
|
+
name: z.ZodString;
|
|
188
|
+
phone: z.ZodString;
|
|
189
|
+
relationship: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
|
|
190
|
+
}, z.core.$strip>>;
|
|
191
|
+
joinedAt: z.ZodISODateTime;
|
|
192
|
+
lastVisitAt: z.ZodNullable<z.ZodISODateTime>;
|
|
193
|
+
assignedWorkoutPlanId: z.ZodNullable<z.ZodString>;
|
|
194
|
+
assignedTrainerId: z.ZodNullable<z.ZodString>;
|
|
195
|
+
membershipId: z.ZodNullable<z.ZodString>;
|
|
196
|
+
}, z.core.$strip>;
|
|
197
|
+
export type MemberDetail = z.infer<typeof memberDetailSchema>;
|
|
198
|
+
export declare const createMemberBodySchema: z.ZodObject<{
|
|
199
|
+
firstName: z.ZodString;
|
|
200
|
+
lastName: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
|
|
201
|
+
email: z.ZodEmail;
|
|
202
|
+
phone: z.ZodString;
|
|
203
|
+
gender: z.ZodEnum<{
|
|
204
|
+
male: "male";
|
|
205
|
+
female: "female";
|
|
206
|
+
other: "other";
|
|
207
|
+
}>;
|
|
208
|
+
dob: z.ZodOptional<z.ZodString>;
|
|
209
|
+
bloodGroup: z.ZodOptional<z.ZodEnum<{
|
|
210
|
+
"A+": "A+";
|
|
211
|
+
"A-": "A-";
|
|
212
|
+
"B+": "B+";
|
|
213
|
+
"B-": "B-";
|
|
214
|
+
"O+": "O+";
|
|
215
|
+
"O-": "O-";
|
|
216
|
+
"AB+": "AB+";
|
|
217
|
+
"AB-": "AB-";
|
|
218
|
+
}>>;
|
|
219
|
+
address: z.ZodOptional<z.ZodObject<{
|
|
220
|
+
street: z.ZodString;
|
|
221
|
+
city: z.ZodString;
|
|
222
|
+
state: z.ZodEnum<{
|
|
223
|
+
"Andhra Pradesh": "Andhra Pradesh";
|
|
224
|
+
"Arunachal Pradesh": "Arunachal Pradesh";
|
|
225
|
+
Assam: "Assam";
|
|
226
|
+
Bihar: "Bihar";
|
|
227
|
+
Chhattisgarh: "Chhattisgarh";
|
|
228
|
+
Goa: "Goa";
|
|
229
|
+
Gujarat: "Gujarat";
|
|
230
|
+
Haryana: "Haryana";
|
|
231
|
+
"Himachal Pradesh": "Himachal Pradesh";
|
|
232
|
+
Jharkhand: "Jharkhand";
|
|
233
|
+
Karnataka: "Karnataka";
|
|
234
|
+
Kerala: "Kerala";
|
|
235
|
+
"Madhya Pradesh": "Madhya Pradesh";
|
|
236
|
+
Maharashtra: "Maharashtra";
|
|
237
|
+
Manipur: "Manipur";
|
|
238
|
+
Meghalaya: "Meghalaya";
|
|
239
|
+
Mizoram: "Mizoram";
|
|
240
|
+
Nagaland: "Nagaland";
|
|
241
|
+
Odisha: "Odisha";
|
|
242
|
+
Punjab: "Punjab";
|
|
243
|
+
Rajasthan: "Rajasthan";
|
|
244
|
+
Sikkim: "Sikkim";
|
|
245
|
+
"Tamil Nadu": "Tamil Nadu";
|
|
246
|
+
Telangana: "Telangana";
|
|
247
|
+
Tripura: "Tripura";
|
|
248
|
+
"Uttar Pradesh": "Uttar Pradesh";
|
|
249
|
+
Uttarakhand: "Uttarakhand";
|
|
250
|
+
"West Bengal": "West Bengal";
|
|
251
|
+
"Andaman and Nicobar Islands": "Andaman and Nicobar Islands";
|
|
252
|
+
Chandigarh: "Chandigarh";
|
|
253
|
+
"Dadra and Nagar Haveli and Daman and Diu": "Dadra and Nagar Haveli and Daman and Diu";
|
|
254
|
+
Delhi: "Delhi";
|
|
255
|
+
"Jammu and Kashmir": "Jammu and Kashmir";
|
|
256
|
+
Ladakh: "Ladakh";
|
|
257
|
+
Lakshadweep: "Lakshadweep";
|
|
258
|
+
Puducherry: "Puducherry";
|
|
259
|
+
}>;
|
|
260
|
+
pincode: z.ZodString;
|
|
261
|
+
}, z.core.$strip>>;
|
|
262
|
+
emergencyContacts: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
263
|
+
name: z.ZodString;
|
|
264
|
+
phone: z.ZodString;
|
|
265
|
+
relationship: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
|
|
266
|
+
}, z.core.$strip>>>;
|
|
267
|
+
idProofUrl: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
|
|
268
|
+
avatarUrl: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
|
|
269
|
+
assignedTrainerId: z.ZodOptional<z.ZodString>;
|
|
270
|
+
initialPlan: z.ZodOptional<z.ZodObject<{
|
|
271
|
+
planId: z.ZodString;
|
|
272
|
+
tenureId: z.ZodEnum<{
|
|
273
|
+
"1m": "1m";
|
|
274
|
+
"3m": "3m";
|
|
275
|
+
"6m": "6m";
|
|
276
|
+
"1y": "1y";
|
|
277
|
+
}>;
|
|
278
|
+
startDate: z.ZodOptional<z.ZodString>;
|
|
279
|
+
payment: z.ZodOptional<z.ZodObject<{
|
|
280
|
+
amountInr: z.ZodNumber;
|
|
281
|
+
method: z.ZodEnum<{
|
|
282
|
+
upi: "upi";
|
|
283
|
+
cash: "cash";
|
|
284
|
+
card: "card";
|
|
285
|
+
}>;
|
|
286
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
287
|
+
success: "success";
|
|
288
|
+
failed: "failed";
|
|
289
|
+
pending: "pending";
|
|
290
|
+
}>>;
|
|
291
|
+
}, z.core.$strip>>;
|
|
292
|
+
}, z.core.$strip>>;
|
|
293
|
+
}, z.core.$strip>;
|
|
294
|
+
export type CreateMemberBody = z.infer<typeof createMemberBodySchema>;
|
|
295
|
+
/**
|
|
296
|
+
* The invite a gym hands to a new member.
|
|
297
|
+
*
|
|
298
|
+
* GymMonk never mints credentials for anyone: central auth is the SSOT for
|
|
299
|
+
* identity, and an account there is shared across products. So adding a member
|
|
300
|
+
* creates a gym record only, plus an unguessable invite code. The member
|
|
301
|
+
* registers/logs in themselves through central auth (exactly as in jansathi) and
|
|
302
|
+
* then CLAIMS the record. The owner shares `url` over WhatsApp or shows the QR.
|
|
303
|
+
*/
|
|
304
|
+
export declare const memberInviteSchema: z.ZodObject<{
|
|
305
|
+
code: z.ZodString;
|
|
306
|
+
url: z.ZodString;
|
|
307
|
+
email: z.ZodString;
|
|
308
|
+
phone: z.ZodNullable<z.ZodString>;
|
|
309
|
+
expiresAt: z.ZodISODateTime;
|
|
310
|
+
}, z.core.$strip>;
|
|
311
|
+
export type MemberInvite = z.infer<typeof memberInviteSchema>;
|
|
312
|
+
/** Result of adding a member: the gym record + the invite to hand over. */
|
|
313
|
+
export declare const provisionResultSchema: z.ZodObject<{
|
|
314
|
+
memberProfileId: z.ZodString;
|
|
315
|
+
code: z.ZodString;
|
|
316
|
+
invite: z.ZodObject<{
|
|
317
|
+
code: z.ZodString;
|
|
318
|
+
url: z.ZodString;
|
|
319
|
+
email: z.ZodString;
|
|
320
|
+
phone: z.ZodNullable<z.ZodString>;
|
|
321
|
+
expiresAt: z.ZodISODateTime;
|
|
322
|
+
}, z.core.$strip>;
|
|
323
|
+
}, z.core.$strip>;
|
|
324
|
+
export type ProvisionResult = z.infer<typeof provisionResultSchema>;
|
|
325
|
+
/**
|
|
326
|
+
* What the claim screen shows BEFORE the member authenticates, so they know
|
|
327
|
+
* which address to register with. Public (the code is the bearer secret), and
|
|
328
|
+
* deliberately minimal — gym name, member code, and the expected email.
|
|
329
|
+
*/
|
|
330
|
+
export declare const invitePreviewSchema: z.ZodObject<{
|
|
331
|
+
gymName: z.ZodString;
|
|
332
|
+
memberCode: z.ZodString;
|
|
333
|
+
email: z.ZodString;
|
|
334
|
+
expiresAt: z.ZodISODateTime;
|
|
335
|
+
claimed: z.ZodBoolean;
|
|
336
|
+
expired: z.ZodBoolean;
|
|
337
|
+
}, z.core.$strip>;
|
|
338
|
+
export type InvitePreview = z.infer<typeof invitePreviewSchema>;
|
|
339
|
+
/**
|
|
340
|
+
* Claim an invite as the authenticated caller. The server links the record only
|
|
341
|
+
* when the code is valid AND the caller's central-auth email matches the address
|
|
342
|
+
* the invite was issued to.
|
|
343
|
+
*/
|
|
344
|
+
export declare const claimInviteBodySchema: z.ZodObject<{
|
|
345
|
+
code: z.ZodString;
|
|
346
|
+
}, z.core.$strip>;
|
|
347
|
+
export type ClaimInviteBody = z.infer<typeof claimInviteBodySchema>;
|
|
348
|
+
export declare const setMemberStatusBodySchema: z.ZodObject<{
|
|
349
|
+
active: z.ZodBoolean;
|
|
350
|
+
}, z.core.$strip>;
|
|
351
|
+
export type SetMemberStatusBody = z.infer<typeof setMemberStatusBodySchema>;
|
|
352
|
+
export declare const assignTrainerBodySchema: z.ZodObject<{
|
|
353
|
+
trainerId: z.ZodNullable<z.ZodString>;
|
|
354
|
+
}, z.core.$strip>;
|
|
355
|
+
export type AssignTrainerBody = z.infer<typeof assignTrainerBodySchema>;
|
|
356
|
+
export declare const assignWorkoutPlanBodySchema: z.ZodObject<{
|
|
357
|
+
planId: z.ZodNullable<z.ZodString>;
|
|
358
|
+
}, z.core.$strip>;
|
|
359
|
+
export type AssignWorkoutPlanBody = z.infer<typeof assignWorkoutPlanBodySchema>;
|
|
360
|
+
/** Remove a member from the gym — echoes the member code to confirm. */
|
|
361
|
+
export declare const deleteMemberBodySchema: z.ZodObject<{
|
|
362
|
+
confirmationCode: z.ZodString;
|
|
363
|
+
}, z.core.$strip>;
|
|
364
|
+
export type DeleteMemberBody = z.infer<typeof deleteMemberBodySchema>;
|
|
365
|
+
//# sourceMappingURL=member.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"member.d.ts","sourceRoot":"","sources":["../src/member.ts"],"names":[],"mappings":"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"}
|
package/dist/member.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gymmonk-schema — Member management (owner console)
|
|
3
|
+
* ==================================================
|
|
4
|
+
* Owner-facing roster + detail projections (User × MemberProfile × Membership)
|
|
5
|
+
* and the "add member" provisioning payload. Adding a member provisions a real
|
|
6
|
+
* central-auth account, so the result carries the login email + temp password.
|
|
7
|
+
*
|
|
8
|
+
* @module gymmonk-schema/member
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { isoDateSchema, isoDateTimeSchema, objectIdSchema, optionalTrimmedString, paginationSchema, phoneSchema, priceInrSchema, } from './common.js';
|
|
12
|
+
import { emergencyContactSchema, memberRecordStatusSchema } from './member-profile.js';
|
|
13
|
+
import { assignMembershipBodySchema, membershipStatusSchema } from './membership.js';
|
|
14
|
+
import { planTierSchema } from './membership-plan.js';
|
|
15
|
+
import { addressSchema, bloodGroupSchema, genderSchema } from './shared.js';
|
|
16
|
+
// ─── Segments ────────────────────────────────────────────────────────────────
|
|
17
|
+
/** Attention buckets surfaced on roster cards. */
|
|
18
|
+
export const memberSegmentSchema = z.enum(['expiring', 'new', 'at-risk']);
|
|
19
|
+
// ─── Roster item (list projection) ───────────────────────────────────────────
|
|
20
|
+
export const memberRosterItemSchema = z.object({
|
|
21
|
+
/** The gym record id — always present, even before the member claims. */
|
|
22
|
+
memberProfileId: objectIdSchema,
|
|
23
|
+
/** Null until claimed; the roster shows an "Invited" pill in that state. */
|
|
24
|
+
userId: objectIdSchema.nullable(),
|
|
25
|
+
recordStatus: memberRecordStatusSchema,
|
|
26
|
+
membershipId: objectIdSchema.nullable(),
|
|
27
|
+
memberCode: z.string(),
|
|
28
|
+
name: z.string(),
|
|
29
|
+
avatarUrl: z.string().nullable(),
|
|
30
|
+
verified: z.boolean(),
|
|
31
|
+
planName: z.string().nullable(),
|
|
32
|
+
tier: planTierSchema.nullable(),
|
|
33
|
+
status: membershipStatusSchema.nullable(),
|
|
34
|
+
endDate: isoDateSchema.nullable(),
|
|
35
|
+
lastVisitAt: isoDateTimeSchema.nullable(),
|
|
36
|
+
balanceDueInr: priceInrSchema,
|
|
37
|
+
overdueDays: z.number().int().nullable(),
|
|
38
|
+
segments: z.array(memberSegmentSchema),
|
|
39
|
+
});
|
|
40
|
+
/** Header counts for the roster. */
|
|
41
|
+
export const memberListSummarySchema = z.object({
|
|
42
|
+
total: z.number().int().nonnegative(),
|
|
43
|
+
active: z.number().int().nonnegative(),
|
|
44
|
+
expiring: z.number().int().nonnegative(),
|
|
45
|
+
inactive: z.number().int().nonnegative(),
|
|
46
|
+
});
|
|
47
|
+
// ─── List query ──────────────────────────────────────────────────────────────
|
|
48
|
+
export const memberFilterSchema = z.enum(['all', 'active', 'inactive', 'verified']);
|
|
49
|
+
export const memberSortSchema = z.enum(['recent', 'az', 'expiry', 'dues']);
|
|
50
|
+
export const memberListQuerySchema = paginationSchema.extend({
|
|
51
|
+
centerId: objectIdSchema.optional(),
|
|
52
|
+
filter: memberFilterSchema.default('all'),
|
|
53
|
+
sort: memberSortSchema.default('recent'),
|
|
54
|
+
tier: planTierSchema.optional(),
|
|
55
|
+
q: optionalTrimmedString(120),
|
|
56
|
+
});
|
|
57
|
+
// ─── Detail projection ───────────────────────────────────────────────────────
|
|
58
|
+
/** The identity slice a projection pulls from the auth `User`. */
|
|
59
|
+
export const memberUserRefSchema = z.object({
|
|
60
|
+
/** Null while the record is still `invited` (no central-auth account linked). */
|
|
61
|
+
id: objectIdSchema.nullable(),
|
|
62
|
+
name: z.string(),
|
|
63
|
+
email: z.string(),
|
|
64
|
+
phone: z.string().nullable(),
|
|
65
|
+
avatarUrl: z.string().nullable(),
|
|
66
|
+
verified: z.boolean(),
|
|
67
|
+
});
|
|
68
|
+
export const memberDetailSchema = z.object({
|
|
69
|
+
memberProfileId: objectIdSchema,
|
|
70
|
+
recordStatus: memberRecordStatusSchema,
|
|
71
|
+
/**
|
|
72
|
+
* Identity from central auth once claimed. Before that the gym still knows the
|
|
73
|
+
* person (name / contact captured at the desk), so this carries the invited
|
|
74
|
+
* details with `id: null`.
|
|
75
|
+
*/
|
|
76
|
+
user: memberUserRefSchema,
|
|
77
|
+
memberCode: z.string(),
|
|
78
|
+
gender: genderSchema.nullable(),
|
|
79
|
+
dob: isoDateSchema.nullable(),
|
|
80
|
+
bloodGroup: bloodGroupSchema.nullable(),
|
|
81
|
+
address: addressSchema.nullable(),
|
|
82
|
+
emergencyContacts: z.array(emergencyContactSchema),
|
|
83
|
+
joinedAt: isoDateTimeSchema,
|
|
84
|
+
lastVisitAt: isoDateTimeSchema.nullable(),
|
|
85
|
+
assignedWorkoutPlanId: objectIdSchema.nullable(),
|
|
86
|
+
assignedTrainerId: objectIdSchema.nullable(),
|
|
87
|
+
membershipId: objectIdSchema.nullable(),
|
|
88
|
+
});
|
|
89
|
+
// ─── Add member (provisioning) ───────────────────────────────────────────────
|
|
90
|
+
export const createMemberBodySchema = z.object({
|
|
91
|
+
firstName: z.string().trim().min(1, 'First name is required').max(80),
|
|
92
|
+
lastName: optionalTrimmedString(80),
|
|
93
|
+
email: z.email('A valid email is required'),
|
|
94
|
+
phone: phoneSchema,
|
|
95
|
+
gender: genderSchema,
|
|
96
|
+
dob: isoDateSchema.optional(),
|
|
97
|
+
bloodGroup: bloodGroupSchema.optional(),
|
|
98
|
+
address: addressSchema.optional(),
|
|
99
|
+
emergencyContacts: z.array(emergencyContactSchema).max(5).default([]),
|
|
100
|
+
idProofUrl: optionalTrimmedString(2000),
|
|
101
|
+
avatarUrl: optionalTrimmedString(2000),
|
|
102
|
+
assignedTrainerId: objectIdSchema.optional(),
|
|
103
|
+
/** Optionally assign a plan in the same step. */
|
|
104
|
+
initialPlan: assignMembershipBodySchema.optional(),
|
|
105
|
+
});
|
|
106
|
+
// ─── Invite & claim ──────────────────────────────────────────────────────────
|
|
107
|
+
/**
|
|
108
|
+
* The invite a gym hands to a new member.
|
|
109
|
+
*
|
|
110
|
+
* GymMonk never mints credentials for anyone: central auth is the SSOT for
|
|
111
|
+
* identity, and an account there is shared across products. So adding a member
|
|
112
|
+
* creates a gym record only, plus an unguessable invite code. The member
|
|
113
|
+
* registers/logs in themselves through central auth (exactly as in jansathi) and
|
|
114
|
+
* then CLAIMS the record. The owner shares `url` over WhatsApp or shows the QR.
|
|
115
|
+
*/
|
|
116
|
+
export const memberInviteSchema = z.object({
|
|
117
|
+
/** Single-use, unguessable. Regenerating an invite invalidates the old one. */
|
|
118
|
+
code: z.string(),
|
|
119
|
+
/** Absolute claim URL the owner shares (also encoded into the QR). */
|
|
120
|
+
url: z.string(),
|
|
121
|
+
/** The address the member MUST register with for the claim to succeed. */
|
|
122
|
+
email: z.string(),
|
|
123
|
+
/** WhatsApp number to share on, when the gym recorded one. */
|
|
124
|
+
phone: z.string().nullable(),
|
|
125
|
+
expiresAt: isoDateTimeSchema,
|
|
126
|
+
});
|
|
127
|
+
/** Result of adding a member: the gym record + the invite to hand over. */
|
|
128
|
+
export const provisionResultSchema = z.object({
|
|
129
|
+
/** The new member record (NOT a central-auth user — none is created). */
|
|
130
|
+
memberProfileId: objectIdSchema,
|
|
131
|
+
code: z.string(),
|
|
132
|
+
invite: memberInviteSchema,
|
|
133
|
+
});
|
|
134
|
+
/**
|
|
135
|
+
* What the claim screen shows BEFORE the member authenticates, so they know
|
|
136
|
+
* which address to register with. Public (the code is the bearer secret), and
|
|
137
|
+
* deliberately minimal — gym name, member code, and the expected email.
|
|
138
|
+
*/
|
|
139
|
+
export const invitePreviewSchema = z.object({
|
|
140
|
+
gymName: z.string(),
|
|
141
|
+
memberCode: z.string(),
|
|
142
|
+
/** Shown verbatim: the member must know exactly which address to use. */
|
|
143
|
+
email: z.string(),
|
|
144
|
+
expiresAt: isoDateTimeSchema,
|
|
145
|
+
/** True once claimed / expired, so the screen can explain why it failed. */
|
|
146
|
+
claimed: z.boolean(),
|
|
147
|
+
expired: z.boolean(),
|
|
148
|
+
});
|
|
149
|
+
/**
|
|
150
|
+
* Claim an invite as the authenticated caller. The server links the record only
|
|
151
|
+
* when the code is valid AND the caller's central-auth email matches the address
|
|
152
|
+
* the invite was issued to.
|
|
153
|
+
*/
|
|
154
|
+
export const claimInviteBodySchema = z.object({
|
|
155
|
+
code: z.string().trim().min(1),
|
|
156
|
+
});
|
|
157
|
+
// ─── Mutations ───────────────────────────────────────────────────────────────
|
|
158
|
+
export const setMemberStatusBodySchema = z.object({ active: z.boolean() });
|
|
159
|
+
export const assignTrainerBodySchema = z.object({
|
|
160
|
+
trainerId: objectIdSchema.nullable(),
|
|
161
|
+
});
|
|
162
|
+
export const assignWorkoutPlanBodySchema = z.object({
|
|
163
|
+
planId: objectIdSchema.nullable(),
|
|
164
|
+
});
|
|
165
|
+
/** Remove a member from the gym — echoes the member code to confirm. */
|
|
166
|
+
export const deleteMemberBodySchema = z.object({
|
|
167
|
+
confirmationCode: z.string().trim().min(1),
|
|
168
|
+
});
|
|
169
|
+
//# sourceMappingURL=member.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"member.js","sourceRoot":"","sources":["../src/member.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5E,gFAAgF;AAEhF,kDAAkD;AAClD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AAG1E,gFAAgF;AAEhF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,yEAAyE;IACzE,eAAe,EAAE,cAAc;IAC/B,4EAA4E;IAC5E,MAAM,EAAE,cAAc,CAAC,QAAQ,EAAE;IACjC,YAAY,EAAE,wBAAwB;IACtC,YAAY,EAAE,cAAc,CAAC,QAAQ,EAAE;IACvC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;IACrB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,IAAI,EAAE,cAAc,CAAC,QAAQ,EAAE;IAC/B,MAAM,EAAE,sBAAsB,CAAC,QAAQ,EAAE;IACzC,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE;IACjC,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACzC,aAAa,EAAE,cAAc;IAC7B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACxC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC;CACvC,CAAC,CAAC;AAGH,oCAAoC;AACpC,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACrC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACxC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CACzC,CAAC,CAAC;AAGH,gFAAgF;AAEhF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;AAGpF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAG3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,MAAM,CAAC;IAC3D,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC;IACzC,IAAI,EAAE,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC;IACxC,IAAI,EAAE,cAAc,CAAC,QAAQ,EAAE;IAC/B,CAAC,EAAE,qBAAqB,CAAC,GAAG,CAAC;CAC9B,CAAC,CAAC;AAGH,gFAAgF;AAEhF,kEAAkE;AAClE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,iFAAiF;IACjF,EAAE,EAAE,cAAc,CAAC,QAAQ,EAAE;IAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;CACtB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,eAAe,EAAE,cAAc;IAC/B,YAAY,EAAE,wBAAwB;IACtC;;;;OAIG;IACH,IAAI,EAAE,mBAAmB;IACzB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE;IAC/B,GAAG,EAAE,aAAa,CAAC,QAAQ,EAAE;IAC7B,UAAU,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IACvC,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE;IACjC,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC;IAClD,QAAQ,EAAE,iBAAiB;IAC3B,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACzC,qBAAqB,EAAE,cAAc,CAAC,QAAQ,EAAE;IAChD,iBAAiB,EAAE,cAAc,CAAC,QAAQ,EAAE;IAC5C,YAAY,EAAE,cAAc,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC;AAGH,gFAAgF;AAEhF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACrE,QAAQ,EAAE,qBAAqB,CAAC,EAAE,CAAC;IACnC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,2BAA2B,CAAC;IAC3C,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,YAAY;IACpB,GAAG,EAAE,aAAa,CAAC,QAAQ,EAAE;IAC7B,UAAU,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IACvC,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE;IACjC,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACrE,UAAU,EAAE,qBAAqB,CAAC,IAAI,CAAC;IACvC,SAAS,EAAE,qBAAqB,CAAC,IAAI,CAAC;IACtC,iBAAiB,EAAE,cAAc,CAAC,QAAQ,EAAE;IAC5C,iDAAiD;IACjD,WAAW,EAAE,0BAA0B,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC;AAGH,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,+EAA+E;IAC/E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,sEAAsE;IACtE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,0EAA0E;IAC1E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,8DAA8D;IAC9D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,SAAS,EAAE,iBAAiB;CAC7B,CAAC,CAAC;AAGH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,yEAAyE;IACzE,eAAe,EAAE,cAAc;IAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,kBAAkB;CAC3B,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,yEAAyE;IACzE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,SAAS,EAAE,iBAAiB;IAC5B,4EAA4E;IAC5E,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;CACrB,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC/B,CAAC,CAAC;AAGH,gFAAgF;AAEhF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAG3E,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,SAAS,EAAE,cAAc,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,MAAM,EAAE,cAAc,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAC;AAGH,wEAAwE;AACxE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3C,CAAC,CAAC","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 {\n isoDateSchema,\n isoDateTimeSchema,\n objectIdSchema,\n optionalTrimmedString,\n paginationSchema,\n phoneSchema,\n priceInrSchema,\n} from './common.js';\nimport { emergencyContactSchema, memberRecordStatusSchema } from './member-profile.js';\nimport { assignMembershipBodySchema, membershipStatusSchema } 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 memberProfileId: objectIdSchema,\n /** Null until claimed; the roster shows an \"Invited\" pill in that state. */\n userId: objectIdSchema.nullable(),\n recordStatus: memberRecordStatusSchema,\n membershipId: objectIdSchema.nullable(),\n memberCode: z.string(),\n name: z.string(),\n avatarUrl: z.string().nullable(),\n verified: z.boolean(),\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});\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 memberProfileId: objectIdSchema,\n recordStatus: memberRecordStatusSchema,\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 memberCode: z.string(),\n gender: genderSchema.nullable(),\n dob: isoDateSchema.nullable(),\n bloodGroup: bloodGroupSchema.nullable(),\n address: addressSchema.nullable(),\n emergencyContacts: z.array(emergencyContactSchema),\n joinedAt: isoDateTimeSchema,\n lastVisitAt: isoDateTimeSchema.nullable(),\n assignedWorkoutPlanId: objectIdSchema.nullable(),\n assignedTrainerId: objectIdSchema.nullable(),\n membershipId: objectIdSchema.nullable(),\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(5).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// ─── 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 memberProfileId: objectIdSchema,\n code: z.string(),\n invite: memberInviteSchema,\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 memberCode: z.string(),\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"]}
|