@bizmap/sdk 0.0.132 → 0.0.134

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.
Files changed (3) hide show
  1. package/dist/main.d.ts +195 -166
  2. package/dist/main.js +281 -246
  3. package/package.json +2 -2
package/dist/main.js CHANGED
@@ -37,46 +37,71 @@ var vitalKeys = z3.enum([
37
37
  ]);
38
38
 
39
39
  // src/schemas/company/CompanyDetails.ts
40
- import * as z14 from "zod";
40
+ import * as z15 from "zod";
41
41
 
42
42
  // src/schemas/company/components/Billing.ts
43
- import * as z7 from "zod";
43
+ import * as z8 from "zod";
44
44
 
45
- // src/schemas/utils/billing.ts
46
- import * as z5 from "zod";
45
+ // src/schemas/user/Details.ts
46
+ import { UserModel } from "@wavy/util";
47
+ import * as z6 from "zod";
47
48
 
48
- // src/schemas/utils/core.ts
49
+ // src/constants.ts
50
+ var NOTIF_ID_DELIM = "::";
51
+ var MAX_NAME_LENGTH = 21;
52
+
53
+ // src/schemas/company/components/utils.ts
49
54
  import * as z4 from "zod";
50
- var InvoiceNo = z4.string().trim().refine(
55
+ var CompanyId = z4.string().toLowerCase().trim().min(3).max(63).transform(
56
+ (data) => data.replace(/-+/g, "-").replace(/_+/g, "_").replace(/\.+/g, ".").replace(/\s+/g, "")
57
+ ).superRefine((data, ctx) => {
58
+ const invalidCharIdx = data.search(/[^a-z0-9\-_\.]/);
59
+ if (invalidCharIdx >= 0) {
60
+ const char = data[invalidCharIdx];
61
+ ctx.addIssue(
62
+ `${/"|'|`/.test(char) ? `(${char})` : `"${char}"`} is not an allowed character.`
63
+ );
64
+ }
65
+ if (!/[a-z]/.test(data[0])) {
66
+ ctx.addIssue("The first character must be a letter.");
67
+ }
68
+ if (!/[a-z0-9]/.test(data[data.length - 1])) {
69
+ ctx.addIssue("The last character must either be a letter or a number.");
70
+ }
71
+ });
72
+
73
+ // src/schemas/utils/core.ts
74
+ import * as z5 from "zod";
75
+ var InvoiceNo = z5.string().trim().refine(
51
76
  (d) => d && d.replace(
52
77
  /^[0-9]{4}-(01|(0[2-9])|(1[0-2]))-(30|31|([1-2][0-9])|0[1-9])-[0-9]{7}/,
53
78
  ""
54
79
  ).length === 0,
55
80
  'Invalid invoice no.: must match the pattern "yyyy-mm-dd-0000000"'
56
81
  );
57
- var Trn = z4.string().trim().refine(
82
+ var Trn = z5.string().trim().refine(
58
83
  (data) => data && data.replace(/^[0-9]{3}-[0-9]{3}-[0-9]{3}/, "").length === 0,
59
84
  'Invalid trn: must match the pattern "000-000-000"'
60
85
  );
61
- var StandardTime = z4.string().trim().refine(
86
+ var StandardTime = z5.string().trim().refine(
62
87
  (d) => d && d.replace(/^(01|(0[2-9])|(1[0-2])):(([1-5][0-9])|0[0-9]) (am|pm)/i, "").length === 0,
63
88
  'Invalid standard time: must match the pattern "hh:mm A"'
64
89
  );
65
- var Timestamp = z4.iso.datetime();
66
- var InviteResponse = z4.enum(["accepted", "declined"]);
67
- var TimeLog = z4.object({
90
+ var Timestamp = z5.iso.datetime();
91
+ var InviteResponse = z5.enum(["accepted", "declined"]);
92
+ var TimeLog = z5.object({
68
93
  createdAt: Timestamp.readonly(),
69
94
  lastModified: Timestamp.optional()
70
95
  });
71
- var TicketNo = z4.int().positive().refine(
96
+ var TicketNo = z5.int().positive().refine(
72
97
  (t) => t.toString().length <= 10,
73
98
  "A ticket no. can only have (10) max digits."
74
99
  ).readonly();
75
- var Reason = z4.object({
76
- value: z4.string().trim().min(3).max(100),
100
+ var Reason = z5.object({
101
+ value: z5.string().trim().min(3).max(100),
77
102
  lastModified: Timestamp
78
103
  });
79
- var AlphaNumeric = z4.string().trim().superRefine((data, ctx) => {
104
+ var AlphaNumeric = z5.string().trim().superRefine((data, ctx) => {
80
105
  const invalidCharIdx = data.search(/[^a-z0-9]/i);
81
106
  if (invalidCharIdx > -1) {
82
107
  const char = `"'`.includes(data[invalidCharIdx]) ? `(${data[invalidCharIdx]})` : `"${data[invalidCharIdx]}"`;
@@ -84,90 +109,89 @@ var AlphaNumeric = z4.string().trim().superRefine((data, ctx) => {
84
109
  }
85
110
  });
86
111
 
112
+ // src/schemas/user/Details.ts
113
+ var UserDetails = z6.object({
114
+ ...UserModel.shape,
115
+ _id: z6.uuidv4(),
116
+ name: z6.string().transform((data) => {
117
+ const [firstName = "", lastName = ""] = data.split(" ");
118
+ return (firstName + " " + lastName).trim();
119
+ }).superRefine((data, ctx) => {
120
+ data.split(" ").forEach((name, idx) => {
121
+ const nty = idx === 0 ? "First" : "Last";
122
+ if (idx === 0 && name.length < 2) {
123
+ ctx.addIssue(`${nty} name must have at least (2) characters.`);
124
+ }
125
+ if (name.length > MAX_NAME_LENGTH) {
126
+ ctx.addIssue(
127
+ `${nty} name can't have more than (${MAX_NAME_LENGTH}) characters.`
128
+ );
129
+ }
130
+ });
131
+ }),
132
+ email: UserModel.shape.email,
133
+ publicKey: z6.string().optional(),
134
+ // Used to track the user's general purpose (gp) storage and the total storage used by
135
+ // their companies.
136
+ // storageTracker: ,
137
+ // storageTracker:
138
+ // .readonly(),
139
+ // usedStorageInBytes: z.number().min(0),
140
+ // notifications: z.array(Notification),
141
+ lastSignedIn: z6.object({
142
+ auto: Timestamp,
143
+ manual: Timestamp
144
+ }).partial(),
145
+ // This is useful for tracking the companies that a non-company owner belongs to.
146
+ companyIds: z6.array(CompanyId).min(1).optional(),
147
+ // resumeToken: z.uuidv4().optional(),
148
+ ...TimeLog.shape
149
+ }).omit({ uid: true });
150
+
87
151
  // src/schemas/utils/billing.ts
88
- var PriceMod = z5.object({
89
- description: z5.string().trim().min(3, "A description must have atleast (3) characters.").max(25, "A description can't have more that (25) characters.").superRefine((data, ctx) => {
152
+ import * as z7 from "zod";
153
+ var PriceMod = z7.object({
154
+ description: z7.string().trim().min(3, "A description must have atleast (3) characters.").max(25, "A description can't have more that (25) characters.").superRefine((data, ctx) => {
90
155
  const invalidCharIdx = data.search(/[^a-zA-Z0-9-\.:\(\)]/);
91
156
  if (invalidCharIdx > -1) {
92
157
  ctx.addIssue("");
93
158
  }
94
159
  }),
95
- fixedAmount: z5.object({
96
- value: z5.number().min(0).max(1e6, "The max fixed amount is $1,000,000.00"),
160
+ fixedAmount: z7.object({
161
+ value: z7.number().min(0).max(1e6, "The max fixed amount is $1,000,000.00"),
97
162
  currency: acceptedCurrencies
98
163
  }),
99
- percentage: z5.number().min(0).max(1e3, "The max percentage is 1,000%"),
100
- isOptional: z5.boolean(),
164
+ percentage: z7.number().min(0).max(1e3, "The max percentage is 1,000%"),
165
+ isOptional: z7.boolean(),
101
166
  ...TimeLog.shape
102
167
  });
103
- var PriceModList = z5.record(z5.uuidv4(), PriceMod);
104
- var PriceTag = z5.object({
105
- uid: z5.uuidv4(),
168
+ var PriceModList = z7.record(z7.uuidv4(), PriceMod);
169
+ var PriceTag = z7.object({
170
+ uid: z7.uuidv4(),
106
171
  /**The name of the item that's being priced */
107
- item: z5.string().trim().min(3, "The price item must be atleast (3) characters long.").max(50, "The price item can't be more than (50) characters long."),
108
- cost: z5.number().min(1, "The minimum allowed cost is $1.00").max(1e9, "The max allowed cost is $1,000,000,000.00."),
172
+ item: z7.string().trim().min(3, "The price item must be atleast (3) characters long.").max(50, "The price item can't be more than (50) characters long."),
173
+ cost: z7.number().min(1, "The minimum allowed cost is $1.00").max(1e9, "The max allowed cost is $1,000,000,000.00."),
109
174
  currency: acceptedCurrencies,
110
175
  ...TimeLog.shape
111
176
  });
112
- var Receipts = z5.array(
177
+ var Receipts = z7.array(
113
178
  PriceTag.omit({ uid: true, lastModified: true })
114
179
  );
115
180
 
116
- // src/schemas/company/components/State.ts
117
- import * as z6 from "zod";
118
- var CompanyState = z6.object({
119
- _id: z6.string().toLowerCase().trim().min(3).max(63).transform(
120
- (data) => data.replace(/-+/g, "-").replace(/_+/g, "_").replace(/\.+/g, ".").replace(/\s+/g, "")
121
- ).superRefine((data, ctx) => {
122
- const invalidCharIdx = data.search(/[^a-z0-9\-_\.]/);
123
- if (invalidCharIdx >= 0) {
124
- const char = data[invalidCharIdx];
125
- ctx.addIssue(
126
- `${/"|'|`/.test(char) ? `(${char})` : `"${char}"`} is not an allowed character.`
127
- );
128
- }
129
- if (!/[a-z]/.test(data[0])) {
130
- ctx.addIssue("The first character must be a letter.");
131
- }
132
- if (!/[a-z0-9]/.test(data[data.length - 1])) {
133
- ctx.addIssue("The last character must either be a letter or a number.");
134
- }
135
- }),
136
- credits: z6.object({
137
- current: z6.number(),
138
- lastModified: Timestamp.optional()
139
- }),
140
- usedStorageInBytes: z6.object({
141
- current: z6.number(),
142
- lastModified: Timestamp.optional()
143
- }),
144
- tierId: z6.object({
145
- current: z6.string(),
146
- lastModified: Timestamp.optional()
147
- }),
148
- count: z6.object({
149
- invoiceNo: z6.int().min(0),
150
- tktNo: z6.int().min(1)
151
- }),
152
- // distRoleIds: z.array(z.string()),
153
- /** Data retention period in months */
154
- // drpInMonths: z.int().min(1),
155
- ...TimeLog.shape
156
- });
157
-
158
181
  // src/schemas/company/components/Billing.ts
159
182
  var MAX_COMPANY_PRICE_MODS = 100;
160
183
  var createMod = (resource) => PriceModList.refine(
161
184
  (d) => Object.values(d).length <= MAX_COMPANY_PRICE_MODS,
162
185
  `Adding more than 100 ${resource}s is prohibited.`
163
186
  );
164
- var CompanyBilling = z7.object({
165
- _id: CompanyState.shape._id,
187
+ var CompanyBilling = z8.object({
188
+ _id: CompanyId,
189
+ ownerId: UserDetails.shape._id,
166
190
  additionalFees: createMod("additional fee").optional(),
167
191
  discounts: createMod("discount").optional(),
168
192
  /** Optionally deductable from bills */
169
193
  prepayments: createMod("pre-payment").optional(),
170
- offeredServices: z7.record(z7.uuidv4(), PriceTag.omit({ uid: true })).superRefine((data, ctx) => {
194
+ offeredServices: z8.record(z8.uuidv4(), PriceTag.omit({ uid: true })).superRefine((data, ctx) => {
171
195
  const services = Object.entries(data);
172
196
  if (services.length > 150) {
173
197
  ctx.addIssue(
@@ -184,14 +208,14 @@ var MutableCompanyBilling = CompanyBilling.omit({
184
208
 
185
209
  // src/schemas/company/components/Identity.ts
186
210
  import { Address, PhoneNumber } from "@wavy/util";
187
- import * as z9 from "zod";
211
+ import * as z10 from "zod";
188
212
 
189
213
  // src/schemas/company/entities/Industry.ts
190
- import * as z8 from "zod";
191
- var CompanyIndustry = z8.object({
192
- healthcare: z8.object({
193
- medicalCare: z8.object({
194
- roles: z8.enum(["doc", "physAsst"])
214
+ import * as z9 from "zod";
215
+ var CompanyIndustry = z9.object({
216
+ healthcare: z9.object({
217
+ medicalCare: z9.object({
218
+ roles: z9.enum(["doc", "physAsst"])
195
219
  })
196
220
  // "pharmaceuticals": z.object({
197
221
  // })
@@ -202,9 +226,10 @@ var safeParseSector = (industry, sector) => {
202
226
  };
203
227
 
204
228
  // src/schemas/company/components/Identity.ts
205
- var CompanyIdentity = z9.object({
206
- _id: CompanyState.shape._id,
207
- alias: z9.string().trim().min(3).max(63).transform((data) => data.replace(/\s+/g, " ")).superRefine((data, ctx) => {
229
+ var CompanyIdentity = z10.object({
230
+ _id: CompanyId,
231
+ ownerId: UserDetails.shape._id,
232
+ alias: z10.string().trim().min(3).max(63).transform((data) => data.replace(/\s+/g, " ")).superRefine((data, ctx) => {
208
233
  const invalidCharIdx = data.search(/[^a-z1-9 ]/i);
209
234
  if (invalidCharIdx >= 0) {
210
235
  ctx.addIssue(
@@ -213,18 +238,18 @@ var CompanyIdentity = z9.object({
213
238
  }
214
239
  }),
215
240
  address: Address,
216
- logo: z9.string().optional(),
241
+ logo: z10.string().optional(),
217
242
  industry: CompanyIndustry.keyof(),
218
- sector: z9.string(),
219
- email: z9.email().max(45),
243
+ sector: z10.string(),
244
+ email: z10.email().max(45),
220
245
  phoneNumber: PhoneNumber.optional(),
221
- emailVerified: z9.boolean(),
222
- verified: z9.boolean(),
223
- legal: z9.object({
224
- regNo: z9.string().max(20).readonly(),
246
+ emailVerified: z10.boolean(),
247
+ verified: z10.boolean(),
248
+ legal: z10.object({
249
+ regNo: z10.string().max(20).readonly(),
225
250
  // The company's registration number
226
- trn: z9.string().regex(/[0-9]{3}-[0-9]{3}-[0-9]{3}/).nullish(),
227
- gctRegNo: z9.string().max(15).nullish()
251
+ trn: z10.string().regex(/[0-9]{3}-[0-9]{3}-[0-9]{3}/).nullish(),
252
+ gctRegNo: z10.string().max(15).nullish()
228
253
  }).optional(),
229
254
  ...TimeLog.shape
230
255
  }).superRefine((data, ctx) => {
@@ -251,19 +276,20 @@ var MutableCompanyIdentity = CompanyIdentity.pick({
251
276
  });
252
277
 
253
278
  // src/schemas/company/components/Preferences.ts
254
- import * as z10 from "zod";
255
- var CompanyPreference = z10.object({
256
- _id: CompanyState.shape._id,
279
+ import * as z11 from "zod";
280
+ var CompanyPreference = z11.object({
281
+ _id: CompanyId,
282
+ ownerId: UserDetails.shape._id,
257
283
  /** The user that's allowed to record the client's services. */
258
284
  serviceSelector: companyServiceSelectors,
259
285
  /** Pay per service */
260
- pps: z10.boolean(),
286
+ pps: z11.boolean(),
261
287
  /**
262
288
  * @property RR (Round Robin): Even distribution.
263
289
  * @property LOR (Least Outstanding Requests): Distribute based on availability.
264
290
  */
265
291
  serviceDistAlg: serviceDistAlgs,
266
- servicesDeployed: z10.boolean(),
292
+ servicesDeployed: z11.boolean(),
267
293
  ...TimeLog.shape
268
294
  }).refine(
269
295
  (data) => !data.pps || data.pps && data.serviceSelector === "scheduler",
@@ -274,60 +300,40 @@ var MutableCompanyPreferences = CompanyPreference.omit({
274
300
  lastModified: true
275
301
  });
276
302
 
303
+ // src/schemas/company/components/State.ts
304
+ import * as z12 from "zod";
305
+ var CompanyState = z12.object({
306
+ _id: CompanyId,
307
+ ownerId: UserDetails.shape._id,
308
+ credits: z12.object({
309
+ current: z12.number(),
310
+ lastModified: Timestamp.optional()
311
+ }),
312
+ tierId: z12.object({
313
+ current: z12.string(),
314
+ lastModified: Timestamp.optional()
315
+ }),
316
+ count: z12.object({
317
+ invoiceNo: z12.int().min(0),
318
+ tktNo: z12.int().min(1)
319
+ }),
320
+ // distRoleIds: z.array(z.string()),
321
+ /** Data retention period in months */
322
+ // drpInMonths: z.int().min(1),
323
+ ...TimeLog.shape
324
+ });
325
+
277
326
  // src/schemas/company/components/Staff.ts
278
327
  import { distinct } from "@wavy/fn";
279
- import * as z13 from "zod";
328
+ import * as z14 from "zod";
280
329
 
281
330
  // src/functions/helper-functions.ts
282
331
  import { camelCaseToLetter, upperFirst } from "@wavy/fn";
283
332
 
284
333
  // src/schemas/company/entities/client/Details.ts
285
- import * as z12 from "zod";
286
-
287
- // src/schemas/user/Details.ts
288
- import { UserModel } from "@wavy/util";
289
- import * as z11 from "zod";
290
-
291
- // src/constants.ts
292
- var NOTIF_ID_DELIM = "::";
293
- var MAX_NAME_LENGTH = 21;
294
-
295
- // src/schemas/user/Details.ts
296
- var UserDetails = z11.object({
297
- ...UserModel.shape,
298
- _id: z11.uuidv4(),
299
- name: z11.string().transform((data) => {
300
- const [firstName = "", lastName = ""] = data.split(" ");
301
- return (firstName + " " + lastName).trim();
302
- }).superRefine((data, ctx) => {
303
- data.split(" ").forEach((name, idx) => {
304
- const nty = idx === 0 ? "First" : "Last";
305
- if (idx === 0 && name.length < 2) {
306
- ctx.addIssue(`${nty} name must have at least (2) characters.`);
307
- }
308
- if (name.length > MAX_NAME_LENGTH) {
309
- ctx.addIssue(
310
- `${nty} name can't have more than (${MAX_NAME_LENGTH}) characters.`
311
- );
312
- }
313
- });
314
- }),
315
- email: UserModel.shape.email,
316
- publicKey: z11.string().optional(),
317
- availableStorageInBytes: z11.number().optional(),
318
- // notifications: z.array(Notification),
319
- lastSignedIn: z11.object({
320
- auto: Timestamp,
321
- manual: Timestamp
322
- }).partial(),
323
- companyIds: z11.array(CompanyState.shape._id).min(1).optional(),
324
- // resumeToken: z.uuidv4().optional(),
325
- ...TimeLog.shape
326
- }).omit({ uid: true });
327
-
328
- // src/schemas/company/entities/client/Details.ts
334
+ import * as z13 from "zod";
329
335
  import { Address as Address2, PhoneNumber as PhoneNumber2 } from "@wavy/util";
330
- var Name = z12.string().trim().min(2).max(MAX_NAME_LENGTH).transform((d) => d.replace(/-+/g, "-").replace(/'+/g, "'")).superRefine((data, ctx) => {
336
+ var Name = z13.string().trim().min(2).max(MAX_NAME_LENGTH).transform((d) => d.replace(/-+/g, "-").replace(/'+/g, "'")).superRefine((data, ctx) => {
331
337
  const invalidCharIdx = data.search(/[^a-z'-]/i);
332
338
  if (invalidCharIdx >= 0) {
333
339
  const char = data[invalidCharIdx].includes('"') ? `(${data[invalidCharIdx]})` : `"${data[invalidCharIdx]}"`;
@@ -341,31 +347,31 @@ var ClientDetails = UserDetails.pick({
341
347
  phoneNumber: true,
342
348
  photoUrl: true
343
349
  }).safeExtend(
344
- z12.object({
350
+ z13.object({
345
351
  firstName: Name,
346
352
  middleName: Name,
347
353
  lastName: Name,
348
354
  email: UserDetails.shape.email.optional(),
349
355
  dob: Timestamp,
350
356
  sex: genders,
351
- isGlobal: z12.boolean(),
357
+ isGlobal: z13.boolean(),
352
358
  origin: CompanyIdentity.shape._id,
353
- visits: z12.record(CompanyIdentity.shape._id, z12.array(Timestamp).min(1)).optional(),
359
+ visits: z13.record(CompanyIdentity.shape._id, z13.array(Timestamp).min(1)).optional(),
354
360
  phoneNumber: PhoneNumber2.optional(),
355
361
  // aka. National id
356
- nid: z12.object({
362
+ nid: z13.object({
357
363
  trn: Trn,
358
364
  nin: AlphaNumeric.toLowerCase().min(5).max(20),
359
365
  passportNo: AlphaNumeric.toLowerCase().min(5).max(15)
360
366
  }).partial().optional(),
361
367
  // Don't hash the attributes, they can be used to help accurately identify a client by whoever is searching for
362
368
  // the client
363
- attributes: z12.object({
369
+ attributes: z13.object({
364
370
  motherMaidenName: Name,
365
371
  fatherMiddleName: Name,
366
372
  motherMiddleName: Name,
367
373
  oldestSiblingMiddleName: Name,
368
- firstSchoolName: z12.string().trim().min(3).max(60)
374
+ firstSchoolName: z13.string().trim().min(3).max(60)
369
375
  }).partial().refine(
370
376
  (data) => Object.keys(data).length > 0,
371
377
  "At least (1) attribute must be defined."
@@ -409,55 +415,59 @@ var parseClientName = ({
409
415
  }) => [firstName, middleName[0] + ".", lastName].join(" ");
410
416
 
411
417
  // src/schemas/company/components/Staff.ts
412
- var CompanyMemberRoles = z13.array(companyUserRoles).transform((roles) => distinct(roles).sort()).refine((roles) => {
418
+ var CompanyMemberRoles = z14.array(companyUserRoles).transform((roles) => distinct(roles).sort()).refine((roles) => {
413
419
  return !roles.find(
414
420
  (role) => getIncompatibleRoles(role).some((r) => roles.includes(r))
415
421
  );
416
422
  }, "A user is not allowed to have conflicting roles.");
417
- var CompanyStaff = z13.object({
418
- _id: CompanyState.shape._id,
419
- members: z13.record(
423
+ var CompanyStaff = z14.object({
424
+ _id: CompanyId,
425
+ ownerId: UserDetails.shape._id,
426
+ members: z14.record(
420
427
  UserDetails.shape._id,
421
- z13.object({
428
+ z14.object({
422
429
  invitedAt: Timestamp.optional(),
423
430
  joinedAt: Timestamp,
424
- lastSession: z13.object({
431
+ lastSession: z14.object({
425
432
  startedAt: Timestamp,
426
433
  endedAt: Timestamp
427
434
  }).partial().optional(),
428
435
  roles: CompanyMemberRoles,
429
- serviceCounter: z13.record(z13.literal(["undone", "done"]), z13.int().min(0)).optional()
436
+ serviceCounter: z14.record(z14.literal(["undone", "done"]), z14.int().min(0)).optional()
430
437
  })
431
438
  ),
432
439
  /**
433
440
  * @relationship one -> many
434
441
  *@description A map of doctor `uids` to their assistants `uids` */
435
- partnerMap: z13.record(
442
+ partnerMap: z14.record(
436
443
  UserDetails.shape._id,
437
- z13.record(UserDetails.shape._id, z13.object({ addedAt: Timestamp }))
444
+ z14.record(UserDetails.shape._id, z14.object({ addedAt: Timestamp }))
438
445
  ).optional(),
439
- updateQueue: z13.record(
446
+ updateQueue: z14.record(
440
447
  UserDetails.shape._id,
441
- z13.object({
442
- $REMOVE: z13.object({ addedAt: Timestamp }),
443
- $CHANGE_ROLES: z13.object({
448
+ z14.object({
449
+ $REMOVE: z14.object({ addedAt: Timestamp }),
450
+ $CHANGE_ROLES: z14.object({
444
451
  newRoles: CompanyMemberRoles,
445
452
  addedAt: Timestamp
446
453
  })
447
454
  }).partial()
448
455
  ).optional(),
449
456
  ...TimeLog.shape
450
- }).superRefine((details, ctx) => {
451
- for (const [_id, user] of Object.entries(details.members)) {
452
- if (user.roles.includes("doc") && details.partnerMap && _id in details.partnerMap) {
453
- for (const asstUid of Object.keys(details.partnerMap[_id])) {
454
- if (!details.members[asstUid].roles.includes("physAsst")) {
457
+ }).superRefine((data, ctx) => {
458
+ if (!(data.ownerId in data.members)) {
459
+ ctx.addIssue('"ownerId" missing from "members" object.');
460
+ }
461
+ for (const [_id, user] of Object.entries(data.members)) {
462
+ if (user.roles.includes("doc") && data.partnerMap && _id in data.partnerMap) {
463
+ for (const asstUid of Object.keys(data.partnerMap[_id])) {
464
+ if (!data.members[asstUid].roles.includes("physAsst")) {
455
465
  ctx.addIssue(
456
466
  `A partner group member must have the "physAsst" role (${_id}) -> (${asstUid}).`
457
467
  );
458
468
  }
459
469
  }
460
- } else if (details.partnerMap && _id in details.partnerMap) {
470
+ } else if (data.partnerMap && _id in data.partnerMap) {
461
471
  ctx.addIssue(
462
472
  `A partner group leader must have the "doc" role. (${_id})`
463
473
  );
@@ -474,7 +484,7 @@ var MutableCompanyStaff = CompanyStaff.pick({
474
484
  });
475
485
 
476
486
  // src/schemas/company/CompanyDetails.ts
477
- var CompanyDetails = z14.object({
487
+ var CompanyDetails = z15.object({
478
488
  _id: CompanyState.shape._id,
479
489
  identity: CompanyIdentity.omit({ _id: true }),
480
490
  // notifications: CompanyNotifications,
@@ -484,14 +494,14 @@ var CompanyDetails = z14.object({
484
494
  billing: CompanyBilling.omit({ _id: true }),
485
495
  staff: CompanyStaff.omit({ _id: true })
486
496
  });
487
- var _CompanyDetails = z14.object({
497
+ var _CompanyDetails = z15.object({
488
498
  identity: CompanyIdentity,
489
499
  state: CompanyState,
490
500
  preference: CompanyPreference,
491
501
  billing: CompanyBilling,
492
502
  staff: CompanyStaff
493
503
  });
494
- var MutableCompanyDetails = z14.object({
504
+ var MutableCompanyDetails = z15.object({
495
505
  _id: CompanyDetails.shape._id,
496
506
  identity: MutableCompanyIdentity.partial().optional(),
497
507
  preferences: MutableCompanyPreferences.partial().optional(),
@@ -500,28 +510,28 @@ var MutableCompanyDetails = z14.object({
500
510
  });
501
511
 
502
512
  // src/schemas/company/components/Notifications.ts
503
- import * as z16 from "zod";
513
+ import * as z17 from "zod";
504
514
 
505
515
  // src/schemas/Global.ts
506
- import * as z15 from "zod";
507
- var TierList = z15.record(
516
+ import * as z16 from "zod";
517
+ var TierList = z16.record(
508
518
  tiers,
509
- z15.object({
510
- cost: z15.number().min(0),
511
- perks: z15.array(z15.string()).min(1)
519
+ z16.object({
520
+ cost: z16.number().min(0),
521
+ perks: z16.array(z16.string()).min(1)
512
522
  })
513
523
  ).superRefine((data, ctx) => {
514
524
  if (data.basic.cost !== 0) {
515
525
  ctx.addIssue("The basic tier must always cost $0.00");
516
526
  }
517
527
  });
518
- var Notification = z15.object({
519
- _id: z15.string().superRefine((data, ctx) => {
520
- const isUUidV4 = z15.uuidv4().safeParse(data).success;
528
+ var Notification = z16.object({
529
+ _id: z16.string().superRefine((data, ctx) => {
530
+ const isUUidV4 = z16.uuidv4().safeParse(data).success;
521
531
  if (isUUidV4) return;
522
532
  let [from, to, nonce] = data.split(NOTIF_ID_DELIM);
523
533
  nonce = nonce?.trim() || "";
524
- const parsedFrom = z15.uuidv4().or(z15.uuidv7()).safeParse(from);
534
+ const parsedFrom = z16.uuidv4().or(z16.uuidv7()).safeParse(from);
525
535
  if (!parsedFrom.success) {
526
536
  ctx.addIssue({
527
537
  code: "custom",
@@ -529,7 +539,7 @@ var Notification = z15.object({
529
539
  path: ["from"]
530
540
  });
531
541
  }
532
- const parsedTo = z15.uuidv4().safeParse(to);
542
+ const parsedTo = z16.uuidv4().safeParse(to);
533
543
  if (!parsedTo.success) {
534
544
  ctx.addIssue({
535
545
  code: "custom",
@@ -545,19 +555,19 @@ var Notification = z15.object({
545
555
  });
546
556
  }
547
557
  }),
548
- code: z15.literal([
558
+ code: z16.literal([
549
559
  "INVITE_RESPONSE",
550
560
  "COMPANY_INVITE",
551
561
  "DEV_MESSAGE",
552
562
  "ALERT"
553
563
  ]),
554
- payload: z15.string(),
555
- isArchived: z15.boolean().optional(),
556
- rcpt: z15.uuidv4().or(z15.uuidv7()).nullable(),
557
- src: z15.object({
558
- _id: z15.uuidv4().or(z15.uuidv7()),
559
- name: z15.string(),
560
- photoUrl: z15.string().nullish()
564
+ payload: z16.string(),
565
+ isArchived: z16.boolean().optional(),
566
+ rcpt: z16.uuidv4().or(z16.uuidv7()).nullable(),
567
+ src: z16.object({
568
+ _id: z16.uuidv4().or(z16.uuidv7()),
569
+ name: z16.string(),
570
+ photoUrl: z16.string().nullish()
561
571
  }),
562
572
  createdAt: Timestamp
563
573
  }).superRefine((data, ctx) => {
@@ -568,7 +578,7 @@ var Notification = z15.object({
568
578
  };
569
579
  switch (data.code) {
570
580
  case "COMPANY_INVITE":
571
- if (!z15.jwt().safeParse(data.payload).success) {
581
+ if (!z16.jwt().safeParse(data.payload).success) {
572
582
  ctx.addIssue("The payload of company invite must be a valid jwt.");
573
583
  }
574
584
  break;
@@ -589,25 +599,25 @@ var Notification = z15.object({
589
599
  return data.code;
590
600
  }
591
601
  });
592
- var CreditCurrency = z15.object({
593
- uid: z15.uuidv4(),
594
- cost: z15.object({ value: z15.number().min(0), currency: acceptedCurrencies }),
595
- value: z15.int().min(0),
602
+ var CreditCurrency = z16.object({
603
+ uid: z16.uuidv4(),
604
+ cost: z16.object({ value: z16.number().min(0), currency: acceptedCurrencies }),
605
+ value: z16.int().min(0),
596
606
  ...TimeLog.shape
597
607
  });
598
- var PaymentDetails = z15.object({
608
+ var PaymentDetails = z16.object({
599
609
  // Used to track the payments recorded by each paymentCollector
600
- uid: z15.uuidv4(),
610
+ uid: z16.uuidv4(),
601
611
  method: paymentMethods,
602
612
  currency: acceptedCurrencies,
603
- amount: z15.number().min(1),
613
+ amount: z16.number().min(1),
604
614
  // Rate chart id (used to identify the rate chart used to convert the amount )
605
615
  // rcid: z.uuidv4(),
606
616
  ...TimeLog.shape
607
617
  });
608
618
 
609
619
  // src/schemas/company/components/Notifications.ts
610
- var CompanyNotifications = z16.array(Notification).refine(
620
+ var CompanyNotifications = z17.array(Notification).refine(
611
621
  (data) => data.every((notif) => notif.code !== "COMPANY_INVITE"),
612
622
  "A company can't receive a company invite."
613
623
  );
@@ -622,8 +632,8 @@ var ClientForm = ClientDetails.pick({
622
632
  }).required();
623
633
 
624
634
  // src/schemas/company/entities/CreateCompanyForm.ts
625
- import * as z17 from "zod";
626
- var CreateCompanyForm = z17.object({
635
+ import * as z18 from "zod";
636
+ var CreateCompanyForm = z18.object({
627
637
  alias: CompanyIdentity.shape.alias.optional(),
628
638
  ...CompanyIdentity.pick({
629
639
  _id: true,
@@ -642,81 +652,81 @@ var CreateCompanyForm = z17.object({
642
652
  });
643
653
 
644
654
  // src/schemas/company/entities/Session.ts
645
- import * as z18 from "zod";
646
- var CompanySession = z18.object({
647
- _id: z18.uuidv4(),
648
- user: z18.object({
655
+ import * as z19 from "zod";
656
+ var CompanySession = z19.object({
657
+ _id: z19.uuidv4(),
658
+ user: z19.object({
649
659
  _id: UserDetails.shape._id,
650
- ip: z18.string(),
660
+ ip: z19.string(),
651
661
  email: UserDetails.shape.email,
652
662
  roles: CompanyMemberRoles,
653
- available: z18.boolean(),
654
- busy: z18.boolean(),
663
+ available: z19.boolean(),
664
+ busy: z19.boolean(),
655
665
  serviceCounter: CompanyStaff.shape.members.valueType.shape.serviceCounter.nonoptional()
656
666
  }),
657
- companyId: CompanyState.shape._id,
658
- ttl: z18.number(),
659
- expiresAfter: z18.date(),
667
+ companyId: CompanyId,
668
+ ttl: z19.number(),
669
+ expiresAfter: z19.date(),
660
670
  // Add in a future update...
661
671
  // logs: z.record(Timestamp, z.object({ resource: z.string(), action: "remove" })),
662
672
  ...TimeLog.shape
663
673
  });
664
674
 
665
675
  // src/schemas/company/entities/service/payloads/Medical.ts
666
- import * as z19 from "zod";
667
- var Vitals = z19.record(
676
+ import * as z20 from "zod";
677
+ var Vitals = z20.record(
668
678
  vitalKeys,
669
- z19.object({
670
- value: z19.string().trim().regex(/^\d{0,3}((\/|\.)\d{1,3})?/),
679
+ z20.object({
680
+ value: z20.string().trim().regex(/^\d{0,3}((\/|\.)\d{1,3})?/),
671
681
  lastModified: Timestamp.nullable()
672
682
  })
673
683
  );
674
- var Medicine = z19.object({
675
- brand: z19.string().trim(),
684
+ var Medicine = z20.object({
685
+ brand: z20.string().trim(),
676
686
  expiresAt: Timestamp.nullish(),
677
- quantity: z19.string().trim().regex(/^\d+(\.\d{1,3})? ?[a-zA-Z]{1,20}/, {
687
+ quantity: z20.string().trim().regex(/^\d+(\.\d{1,3})? ?[a-zA-Z]{1,20}/, {
678
688
  error: "Failed to match the pattern <number>+(.<number>{1,3})? ?[a-zA-Z]{1,20}"
679
689
  }),
680
- refills: z19.string().trim().regex(/^[0-8]/, { error: "Must be between 0 and 8" }),
681
- directions: z19.string().trim().max(100, { error: "Must be 100 characters or less" }),
690
+ refills: z20.string().trim().regex(/^[0-8]/, { error: "Must be between 0 and 8" }),
691
+ directions: z20.string().trim().max(100, { error: "Must be 100 characters or less" }),
682
692
  ...TimeLog.shape
683
693
  });
684
- var MedicalDetails = z19.object({
694
+ var MedicalDetails = z20.object({
685
695
  vitals: Vitals,
686
- prescriptions: z19.array(z19.array(Medicine)).nullish(),
687
- doctorNote: z19.object({
688
- value: z19.string(),
696
+ prescriptions: z20.array(z20.array(Medicine)).nullish(),
697
+ doctorNote: z20.object({
698
+ value: z20.string(),
689
699
  lastModified: Timestamp.nullable()
690
700
  }),
691
- physAsstNotes: z19.array(
692
- z19.object({
693
- title: z19.string(),
694
- content: z19.string(),
701
+ physAsstNotes: z20.array(
702
+ z20.object({
703
+ title: z20.string(),
704
+ content: z20.string(),
695
705
  ...TimeLog.shape
696
706
  })
697
707
  ).optional()
698
708
  });
699
709
 
700
710
  // src/schemas/company/entities/service/ServiceDetails.ts
701
- import * as z20 from "zod";
702
- var ServiceSeverity = z20.object({
703
- "1": z20.literal("Emergency"),
704
- "2": z20.literal("Important"),
705
- "3": z20.literal("Average")
711
+ import * as z21 from "zod";
712
+ var ServiceSeverity = z21.object({
713
+ "1": z21.literal("Emergency"),
714
+ "2": z21.literal("Important"),
715
+ "3": z21.literal("Average")
706
716
  });
707
- var ServiceDetails = z20.object({
717
+ var ServiceDetails = z21.object({
708
718
  /** A random uid that identifies the document. */
709
- _id: z20.uuidv4(),
719
+ _id: z21.uuidv4(),
710
720
  /** The amount of credits used to create the appointment */
711
- _cost: z20.number().readonly(),
721
+ _cost: z21.number().readonly(),
712
722
  // This helps to identify the urgency of the appointment
713
- severity: z20.string().refine((data) => ServiceSeverity.keyof().safeParse(data).success),
723
+ severity: z21.string().refine((data) => ServiceSeverity.keyof().safeParse(data).success),
714
724
  /** The company's uid */
715
725
  src: CompanyState.shape._id,
716
726
  /** The ticket number */
717
727
  tkt: TicketNo,
718
728
  /**The reason for the service */
719
- reason: z20.object({
729
+ reason: z21.object({
720
730
  value: Reason.shape.value,
721
731
  ...TimeLog.shape
722
732
  }),
@@ -737,23 +747,23 @@ var ServiceDetails = z20.object({
737
747
  /**Required to calculate the accurate grandTotal of the charges */
738
748
  discounts: CompanyBilling.shape.discounts.optional(),
739
749
  prepayments: CompanyBilling.shape.prepayments.optional(),
740
- payments: z20.array(PaymentDetails).max(100).optional(),
750
+ payments: z21.array(PaymentDetails).max(100).optional(),
741
751
  /** The client's identity */
742
752
  clientId: ClientDetails.shape._id,
743
753
  /**
744
754
  * Data that is specific to the entity (for now it's just medical data).
745
755
  * It will only be defined for the participants that have access to it.
746
756
  */
747
- payload: z20.object({
757
+ payload: z21.object({
748
758
  ...MedicalDetails.shape,
749
759
  lastModified: Timestamp.optional()
750
760
  }).optional(),
751
761
  /** Only defined when either the service provider or the client cancelled their appointment */
752
- cancelled: z20.object({
762
+ cancelled: z21.object({
753
763
  /** The time that the confirm cancel button was clicked */
754
764
  doneAt: Timestamp,
755
765
  reason: Reason,
756
- doneBy: companyUserRoles.extract(["doc", "physAsst", "rcpst"]).or(z20.literal("client"))
766
+ doneBy: companyUserRoles.extract(["doc", "physAsst", "rcpst"]).or(z21.literal("client"))
757
767
  }).optional(),
758
768
  //** Add this after consulting with company owners about payment expectations */
759
769
  // paymentDueDate: Timestamp.nullish(),
@@ -764,17 +774,17 @@ var ServiceDetails = z20.object({
764
774
  * [1] Ommitted -> any user with that role that's from the same company can access the ServiceDetails.
765
775
  * [1] Addded -> only the users that have that role and an id in the respective array can access the ServiceDetails.
766
776
  */
767
- rbac: z20.record(companyUserRoles, z20.array(UserDetails.shape._id).optional()),
768
- timeline: z20.record(
777
+ rbac: z21.record(companyUserRoles, z21.array(UserDetails.shape._id).optional()),
778
+ timeline: z21.record(
769
779
  UserDetails.shape._id,
770
- z20.object({
780
+ z21.object({
771
781
  /** Removed to rely on a single source of truth (audit logs stored in s3)
772
782
  * as it relates to a user's roles at any given time.
773
783
  */
774
784
  // roles: CompanyMemberRoles,
775
785
  postedAt: Timestamp,
776
786
  // Use null as an indicator that this is intentionally undefined.
777
- changes: z20.record(z20.string(), z20.any()).nullable()
787
+ changes: z21.record(z21.string(), z21.any()).nullable()
778
788
  }).optional()
779
789
  ),
780
790
  // z.object({
@@ -796,15 +806,39 @@ var ServiceDetails = z20.object({
796
806
  ...TimeLog.shape
797
807
  });
798
808
  var MutableServiceDetails = ServiceDetails.safeExtend(
799
- z20.object({
809
+ z21.object({
800
810
  /**
801
811
  * @description An encrypted copy of the last state of the appointment.
802
812
  * @note Used to accurately update the appointment without having to query the database
803
813
  */
804
- _hash: z20.string()
814
+ _hash: z21.string()
805
815
  }).shape
806
816
  );
807
817
 
818
+ // src/schemas/user/Storage.ts
819
+ import * as z22 from "zod";
820
+ var UserStorage = z22.object({
821
+ profile: z22.object({
822
+ current: z22.number().min(0),
823
+ class: z22.string().trim(),
824
+ lastModified: Timestamp.optional()
825
+ }),
826
+ company: z22.record(
827
+ CompanyId,
828
+ z22.object({
829
+ class: z22.string().trim(),
830
+ items: z22.record(
831
+ _CompanyDetails.keyof(),
832
+ z22.object({
833
+ current: z22.number().min(0),
834
+ lastModified: Timestamp.optional()
835
+ })
836
+ )
837
+ })
838
+ ),
839
+ createdAt: Timestamp
840
+ });
841
+
808
842
  // src/functions/calc.ts
809
843
  import { sumOf } from "@wavy/fn";
810
844
  function calcBalance(components, options) {
@@ -891,6 +925,7 @@ export {
891
925
  Timestamp,
892
926
  Trn,
893
927
  UserDetails,
928
+ UserStorage,
894
929
  Vitals,
895
930
  _CompanyDetails,
896
931
  acceptedCurrencies,