@blackcode_sa/metaestetics-api 1.7.38 → 1.7.39
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/admin/index.d.mts +46 -3
- package/dist/admin/index.d.ts +46 -3
- package/dist/index.d.mts +232 -10
- package/dist/index.d.ts +232 -10
- package/dist/index.js +170 -150
- package/dist/index.mjs +167 -147
- package/package.json +1 -1
- package/src/index.ts +3 -0
- package/src/types/appointment/index.ts +53 -3
- package/src/validations/appointment.schema.ts +38 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/validations/appointment.schema.ts
|
|
2
|
-
import { z as
|
|
2
|
+
import { z as z3 } from "zod";
|
|
3
3
|
|
|
4
4
|
// src/types/appointment/index.ts
|
|
5
5
|
var AppointmentStatus = /* @__PURE__ */ ((AppointmentStatus2) => {
|
|
@@ -267,140 +267,187 @@ var updateFilledDocumentDataSchema = z.object({
|
|
|
267
267
|
status: filledDocumentStatusSchema.optional()
|
|
268
268
|
});
|
|
269
269
|
|
|
270
|
+
// src/backoffice/types/static/pricing.types.ts
|
|
271
|
+
var PricingMeasure = /* @__PURE__ */ ((PricingMeasure3) => {
|
|
272
|
+
PricingMeasure3["PER_ML"] = "per_ml";
|
|
273
|
+
PricingMeasure3["PER_ZONE"] = "per_zone";
|
|
274
|
+
PricingMeasure3["PER_AREA"] = "per_area";
|
|
275
|
+
PricingMeasure3["PER_SESSION"] = "per_session";
|
|
276
|
+
PricingMeasure3["PER_TREATMENT"] = "per_treatment";
|
|
277
|
+
PricingMeasure3["PER_PACKAGE"] = "per_package";
|
|
278
|
+
return PricingMeasure3;
|
|
279
|
+
})(PricingMeasure || {});
|
|
280
|
+
var Currency = /* @__PURE__ */ ((Currency2) => {
|
|
281
|
+
Currency2["EUR"] = "EUR";
|
|
282
|
+
Currency2["USD"] = "USD";
|
|
283
|
+
Currency2["GBP"] = "GBP";
|
|
284
|
+
Currency2["CHF"] = "CHF";
|
|
285
|
+
Currency2["AUD"] = "AUD";
|
|
286
|
+
return Currency2;
|
|
287
|
+
})(Currency || {});
|
|
288
|
+
|
|
289
|
+
// src/validations/media.schema.ts
|
|
290
|
+
import { z as z2 } from "zod";
|
|
291
|
+
var mediaResourceSchema = z2.union([
|
|
292
|
+
z2.string().url(),
|
|
293
|
+
z2.instanceof(File),
|
|
294
|
+
z2.instanceof(Blob)
|
|
295
|
+
]);
|
|
296
|
+
|
|
270
297
|
// src/validations/appointment.schema.ts
|
|
271
298
|
var MIN_STRING_LENGTH = 1;
|
|
272
299
|
var MAX_STRING_LENGTH = 1024;
|
|
273
300
|
var MAX_STRING_LENGTH_LONG = 4096;
|
|
274
301
|
var MAX_ARRAY_LENGTH = 100;
|
|
275
|
-
var appointmentStatusSchema =
|
|
276
|
-
var paymentStatusSchema =
|
|
277
|
-
var mediaTypeSchema =
|
|
278
|
-
var appointmentMediaItemSchema =
|
|
279
|
-
id:
|
|
302
|
+
var appointmentStatusSchema = z3.nativeEnum(AppointmentStatus);
|
|
303
|
+
var paymentStatusSchema = z3.nativeEnum(PaymentStatus);
|
|
304
|
+
var mediaTypeSchema = z3.nativeEnum(MediaType);
|
|
305
|
+
var appointmentMediaItemSchema = z3.object({
|
|
306
|
+
id: z3.string().min(MIN_STRING_LENGTH, "Media item ID is required"),
|
|
280
307
|
type: mediaTypeSchema,
|
|
281
|
-
url:
|
|
282
|
-
fileName:
|
|
283
|
-
uploadedAt:
|
|
308
|
+
url: z3.string().url("Media URL must be a valid URL"),
|
|
309
|
+
fileName: z3.string().optional(),
|
|
310
|
+
uploadedAt: z3.any().refine(
|
|
284
311
|
(val) => val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
285
312
|
"uploadedAt must be a valid timestamp or Date object"
|
|
286
313
|
),
|
|
287
|
-
uploadedBy:
|
|
288
|
-
description:
|
|
314
|
+
uploadedBy: z3.string().min(MIN_STRING_LENGTH, "Uploaded by user ID is required"),
|
|
315
|
+
description: z3.string().max(MAX_STRING_LENGTH, "Description too long").optional()
|
|
289
316
|
});
|
|
290
|
-
var procedureExtendedInfoSchema =
|
|
291
|
-
id:
|
|
292
|
-
name:
|
|
293
|
-
description:
|
|
294
|
-
cost:
|
|
295
|
-
duration:
|
|
296
|
-
procedureFamily:
|
|
297
|
-
procedureCategoryId:
|
|
298
|
-
procedureCategoryName:
|
|
299
|
-
procedureSubCategoryId:
|
|
300
|
-
procedureSubCategoryName:
|
|
301
|
-
procedureTechnologyId:
|
|
302
|
-
procedureTechnologyName:
|
|
303
|
-
procedureProductBrandId:
|
|
304
|
-
procedureProductBrandName:
|
|
305
|
-
procedureProductId:
|
|
306
|
-
procedureProductName:
|
|
317
|
+
var procedureExtendedInfoSchema = z3.object({
|
|
318
|
+
id: z3.string().min(MIN_STRING_LENGTH),
|
|
319
|
+
name: z3.string().min(MIN_STRING_LENGTH),
|
|
320
|
+
description: z3.string(),
|
|
321
|
+
cost: z3.number().min(0),
|
|
322
|
+
duration: z3.number().min(0),
|
|
323
|
+
procedureFamily: z3.any(),
|
|
324
|
+
procedureCategoryId: z3.string(),
|
|
325
|
+
procedureCategoryName: z3.string(),
|
|
326
|
+
procedureSubCategoryId: z3.string(),
|
|
327
|
+
procedureSubCategoryName: z3.string(),
|
|
328
|
+
procedureTechnologyId: z3.string(),
|
|
329
|
+
procedureTechnologyName: z3.string(),
|
|
330
|
+
procedureProductBrandId: z3.string(),
|
|
331
|
+
procedureProductBrandName: z3.string(),
|
|
332
|
+
procedureProductId: z3.string(),
|
|
333
|
+
procedureProductName: z3.string()
|
|
307
334
|
});
|
|
308
|
-
var linkedFormInfoSchema =
|
|
309
|
-
formId:
|
|
310
|
-
templateId:
|
|
311
|
-
templateVersion:
|
|
312
|
-
title:
|
|
313
|
-
isUserForm:
|
|
314
|
-
isRequired:
|
|
335
|
+
var linkedFormInfoSchema = z3.object({
|
|
336
|
+
formId: z3.string().min(MIN_STRING_LENGTH, "Form ID is required"),
|
|
337
|
+
templateId: z3.string().min(MIN_STRING_LENGTH, "Template ID is required"),
|
|
338
|
+
templateVersion: z3.number().int().positive("Template version must be a positive integer"),
|
|
339
|
+
title: z3.string().min(MIN_STRING_LENGTH, "Form title is required"),
|
|
340
|
+
isUserForm: z3.boolean(),
|
|
341
|
+
isRequired: z3.boolean().optional(),
|
|
315
342
|
status: filledDocumentStatusSchema,
|
|
316
|
-
path:
|
|
317
|
-
submittedAt:
|
|
343
|
+
path: z3.string().min(MIN_STRING_LENGTH, "Form path is required"),
|
|
344
|
+
submittedAt: z3.any().refine(
|
|
318
345
|
(val) => val === void 0 || val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
319
346
|
"submittedAt must be a valid timestamp or Date object"
|
|
320
347
|
).optional(),
|
|
321
|
-
completedAt:
|
|
348
|
+
completedAt: z3.any().refine(
|
|
322
349
|
(val) => val === void 0 || val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
323
350
|
"completedAt must be a valid timestamp or Date object"
|
|
324
351
|
).optional()
|
|
325
352
|
});
|
|
326
|
-
var patientReviewInfoSchema =
|
|
327
|
-
reviewId:
|
|
328
|
-
rating:
|
|
329
|
-
comment:
|
|
330
|
-
reviewedAt:
|
|
353
|
+
var patientReviewInfoSchema = z3.object({
|
|
354
|
+
reviewId: z3.string().min(MIN_STRING_LENGTH, "Review ID is required"),
|
|
355
|
+
rating: z3.number().min(1).max(5, "Rating must be between 1 and 5"),
|
|
356
|
+
comment: z3.string().max(MAX_STRING_LENGTH_LONG, "Comment too long").optional(),
|
|
357
|
+
reviewedAt: z3.any().refine(
|
|
331
358
|
(val) => val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
332
359
|
"reviewedAt must be a valid timestamp or Date object"
|
|
333
360
|
)
|
|
334
361
|
});
|
|
335
|
-
var finalizedDetailsSchema =
|
|
336
|
-
by:
|
|
337
|
-
at:
|
|
362
|
+
var finalizedDetailsSchema = z3.object({
|
|
363
|
+
by: z3.string().min(MIN_STRING_LENGTH, "Finalized by user ID is required"),
|
|
364
|
+
at: z3.any().refine(
|
|
338
365
|
(val) => val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
339
366
|
"Finalized at must be a valid timestamp or Date object"
|
|
340
367
|
),
|
|
341
|
-
notes:
|
|
368
|
+
notes: z3.string().max(MAX_STRING_LENGTH_LONG, "Finalization notes too long").optional()
|
|
369
|
+
});
|
|
370
|
+
var beforeAfterPerZoneSchema = z3.object({
|
|
371
|
+
before: mediaResourceSchema.nullable(),
|
|
372
|
+
after: mediaResourceSchema.nullable(),
|
|
373
|
+
note: z3.string().nullable()
|
|
374
|
+
});
|
|
375
|
+
var billingPerZoneSchema = z3.object({
|
|
376
|
+
Product: z3.string().min(MIN_STRING_LENGTH, "Product name is required"),
|
|
377
|
+
ProductId: z3.string().nullable(),
|
|
378
|
+
Quantity: z3.number().min(0, "Quantity must be non-negative"),
|
|
379
|
+
UnitOfMeasurement: z3.nativeEnum(PricingMeasure),
|
|
380
|
+
UnitPrice: z3.number().min(0, "Unit price must be non-negative"),
|
|
381
|
+
UnitCurency: z3.nativeEnum(Currency),
|
|
382
|
+
Subtotal: z3.number().min(0, "Subtotal must be non-negative"),
|
|
383
|
+
Note: z3.string().nullable()
|
|
342
384
|
});
|
|
343
|
-
var
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
385
|
+
var appointmentMetadataSchema = z3.object({
|
|
386
|
+
selectedZones: z3.array(z3.string()).nullable(),
|
|
387
|
+
zonePhotos: z3.record(z3.string(), beforeAfterPerZoneSchema).nullable(),
|
|
388
|
+
zoneBilling: z3.record(z3.string(), billingPerZoneSchema).nullable()
|
|
389
|
+
});
|
|
390
|
+
var createAppointmentSchema = z3.object({
|
|
391
|
+
clinicBranchId: z3.string().min(MIN_STRING_LENGTH, "Clinic branch ID is required"),
|
|
392
|
+
practitionerId: z3.string().min(MIN_STRING_LENGTH, "Practitioner ID is required"),
|
|
393
|
+
patientId: z3.string().min(MIN_STRING_LENGTH, "Patient ID is required"),
|
|
394
|
+
procedureId: z3.string().min(MIN_STRING_LENGTH, "Procedure ID is required"),
|
|
395
|
+
appointmentStartTime: z3.any().refine(
|
|
349
396
|
(val) => val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
350
397
|
"Appointment start time must be a valid timestamp or Date object"
|
|
351
398
|
),
|
|
352
|
-
appointmentEndTime:
|
|
399
|
+
appointmentEndTime: z3.any().refine(
|
|
353
400
|
(val) => val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
354
401
|
"Appointment end time must be a valid timestamp or Date object"
|
|
355
402
|
),
|
|
356
|
-
cost:
|
|
357
|
-
currency:
|
|
358
|
-
patientNotes:
|
|
403
|
+
cost: z3.number().min(0, "Cost must be a non-negative number"),
|
|
404
|
+
currency: z3.string().min(1, "Currency is required"),
|
|
405
|
+
patientNotes: z3.string().max(MAX_STRING_LENGTH, "Patient notes too long").nullable().optional(),
|
|
359
406
|
initialStatus: appointmentStatusSchema,
|
|
360
407
|
initialPaymentStatus: paymentStatusSchema.optional().default("unpaid" /* UNPAID */)
|
|
361
408
|
}).refine((data) => data.appointmentEndTime > data.appointmentStartTime, {
|
|
362
409
|
message: "Appointment end time must be after start time",
|
|
363
410
|
path: ["appointmentEndTime"]
|
|
364
411
|
});
|
|
365
|
-
var updateAppointmentSchema =
|
|
412
|
+
var updateAppointmentSchema = z3.object({
|
|
366
413
|
status: appointmentStatusSchema.optional(),
|
|
367
|
-
confirmationTime:
|
|
368
|
-
cancellationTime:
|
|
369
|
-
rescheduleTime:
|
|
370
|
-
procedureActualStartTime:
|
|
371
|
-
actualDurationMinutes:
|
|
372
|
-
cancellationReason:
|
|
373
|
-
canceledBy:
|
|
374
|
-
internalNotes:
|
|
375
|
-
patientNotes:
|
|
414
|
+
confirmationTime: z3.any().optional().nullable(),
|
|
415
|
+
cancellationTime: z3.any().optional().nullable(),
|
|
416
|
+
rescheduleTime: z3.any().optional().nullable(),
|
|
417
|
+
procedureActualStartTime: z3.any().optional().nullable(),
|
|
418
|
+
actualDurationMinutes: z3.number().int().positive("Duration must be a positive integer").optional(),
|
|
419
|
+
cancellationReason: z3.string().max(MAX_STRING_LENGTH, "Cancellation reason too long").nullable().optional(),
|
|
420
|
+
canceledBy: z3.enum(["patient", "clinic", "practitioner", "system"]).optional(),
|
|
421
|
+
internalNotes: z3.string().max(MAX_STRING_LENGTH_LONG, "Internal notes too long").nullable().optional(),
|
|
422
|
+
patientNotes: z3.any().optional().nullable(),
|
|
376
423
|
paymentStatus: paymentStatusSchema.optional(),
|
|
377
|
-
paymentTransactionId:
|
|
378
|
-
completedPreRequirements:
|
|
379
|
-
completedPostRequirements:
|
|
380
|
-
linkedFormIds:
|
|
381
|
-
pendingUserFormsIds:
|
|
382
|
-
appointmentStartTime:
|
|
424
|
+
paymentTransactionId: z3.any().optional().nullable(),
|
|
425
|
+
completedPreRequirements: z3.union([z3.array(z3.string()), z3.any()]).optional(),
|
|
426
|
+
completedPostRequirements: z3.union([z3.array(z3.string()), z3.any()]).optional(),
|
|
427
|
+
linkedFormIds: z3.union([z3.array(z3.string()), z3.any()]).optional(),
|
|
428
|
+
pendingUserFormsIds: z3.union([z3.array(z3.string()), z3.any()]).optional(),
|
|
429
|
+
appointmentStartTime: z3.any().refine(
|
|
383
430
|
(val) => val === void 0 || val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
384
431
|
"Appointment start time must be a valid timestamp or Date object"
|
|
385
432
|
).optional(),
|
|
386
|
-
appointmentEndTime:
|
|
433
|
+
appointmentEndTime: z3.any().refine(
|
|
387
434
|
(val) => val === void 0 || val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
388
435
|
"Appointment end time must be a valid timestamp or Date object"
|
|
389
436
|
).optional(),
|
|
390
|
-
calendarEventId:
|
|
391
|
-
cost:
|
|
392
|
-
clinicBranchId:
|
|
393
|
-
practitionerId:
|
|
394
|
-
linkedForms:
|
|
395
|
-
media:
|
|
396
|
-
|
|
397
|
-
|
|
437
|
+
calendarEventId: z3.string().min(MIN_STRING_LENGTH).optional(),
|
|
438
|
+
cost: z3.number().min(0).optional(),
|
|
439
|
+
clinicBranchId: z3.string().min(MIN_STRING_LENGTH).optional(),
|
|
440
|
+
practitionerId: z3.string().min(MIN_STRING_LENGTH).optional(),
|
|
441
|
+
linkedForms: z3.union([z3.array(linkedFormInfoSchema).max(MAX_ARRAY_LENGTH), z3.any()]).optional(),
|
|
442
|
+
media: z3.union([
|
|
443
|
+
z3.array(appointmentMediaItemSchema).max(MAX_ARRAY_LENGTH),
|
|
444
|
+
z3.any()
|
|
398
445
|
]).optional(),
|
|
399
|
-
reviewInfo:
|
|
400
|
-
finalizedDetails:
|
|
401
|
-
isArchived:
|
|
402
|
-
updatedAt:
|
|
403
|
-
metadata:
|
|
446
|
+
reviewInfo: z3.union([patientReviewInfoSchema.nullable(), z3.any()]).optional(),
|
|
447
|
+
finalizedDetails: z3.union([finalizedDetailsSchema.nullable(), z3.any()]).optional(),
|
|
448
|
+
isArchived: z3.boolean().optional(),
|
|
449
|
+
updatedAt: z3.any().optional(),
|
|
450
|
+
metadata: appointmentMetadataSchema.optional()
|
|
404
451
|
}).refine(
|
|
405
452
|
(data) => {
|
|
406
453
|
if (data.status === "canceled_clinic" /* CANCELED_CLINIC */ || data.status === "canceled_patient" /* CANCELED_PATIENT */ || data.status === "canceled_patient_rescheduled" /* CANCELED_PATIENT_RESCHEDULED */) {
|
|
@@ -424,24 +471,24 @@ var updateAppointmentSchema = z2.object({
|
|
|
424
471
|
path: ["appointmentEndTime"]
|
|
425
472
|
}
|
|
426
473
|
);
|
|
427
|
-
var searchAppointmentsSchema =
|
|
428
|
-
patientId:
|
|
429
|
-
practitionerId:
|
|
430
|
-
clinicBranchId:
|
|
431
|
-
startDate:
|
|
474
|
+
var searchAppointmentsSchema = z3.object({
|
|
475
|
+
patientId: z3.string().optional(),
|
|
476
|
+
practitionerId: z3.string().optional(),
|
|
477
|
+
clinicBranchId: z3.string().optional(),
|
|
478
|
+
startDate: z3.any().refine(
|
|
432
479
|
(val) => val === void 0 || val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
433
480
|
"Start date must be a valid timestamp or Date object"
|
|
434
481
|
).optional(),
|
|
435
|
-
endDate:
|
|
482
|
+
endDate: z3.any().refine(
|
|
436
483
|
(val) => val === void 0 || val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
437
484
|
"End date must be a valid timestamp or Date object"
|
|
438
485
|
).optional(),
|
|
439
|
-
status:
|
|
486
|
+
status: z3.union([
|
|
440
487
|
appointmentStatusSchema,
|
|
441
|
-
|
|
488
|
+
z3.array(appointmentStatusSchema).nonempty()
|
|
442
489
|
]).optional(),
|
|
443
|
-
limit:
|
|
444
|
-
startAfter:
|
|
490
|
+
limit: z3.number().positive().int().optional().default(20),
|
|
491
|
+
startAfter: z3.any().optional()
|
|
445
492
|
}).refine(
|
|
446
493
|
(data) => {
|
|
447
494
|
if (!data.startDate && !data.endDate && !data.status) {
|
|
@@ -465,13 +512,13 @@ var searchAppointmentsSchema = z2.object({
|
|
|
465
512
|
path: ["endDate"]
|
|
466
513
|
}
|
|
467
514
|
);
|
|
468
|
-
var rescheduleAppointmentSchema =
|
|
469
|
-
appointmentId:
|
|
470
|
-
newStartTime:
|
|
515
|
+
var rescheduleAppointmentSchema = z3.object({
|
|
516
|
+
appointmentId: z3.string().min(MIN_STRING_LENGTH, "Appointment ID is required"),
|
|
517
|
+
newStartTime: z3.any().refine(
|
|
471
518
|
(val) => val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
472
519
|
"New start time must be a valid timestamp, Date object, number, or string"
|
|
473
520
|
),
|
|
474
|
-
newEndTime:
|
|
521
|
+
newEndTime: z3.any().refine(
|
|
475
522
|
(val) => val instanceof Date || (val == null ? void 0 : val._seconds) !== void 0 || (val == null ? void 0 : val.seconds) !== void 0 || typeof val === "number" || typeof val === "string" || val && typeof val.toMillis === "function",
|
|
476
523
|
"New end time must be a valid timestamp, Date object, number, or string"
|
|
477
524
|
)
|
|
@@ -591,24 +638,24 @@ var USERS_COLLECTION = "users";
|
|
|
591
638
|
import { z as z20 } from "zod";
|
|
592
639
|
|
|
593
640
|
// src/validations/schemas.ts
|
|
594
|
-
import { z as
|
|
595
|
-
var emailSchema =
|
|
596
|
-
var passwordSchema =
|
|
641
|
+
import { z as z4 } from "zod";
|
|
642
|
+
var emailSchema = z4.string().email("Invalid email format").min(5, "Email must be at least 5 characters").max(255, "Email must be less than 255 characters");
|
|
643
|
+
var passwordSchema = z4.string().min(8, "Password must be at least 8 characters").max(100, "Password must be less than 100 characters").regex(
|
|
597
644
|
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d\w\W]{8,}$/,
|
|
598
645
|
"Password must contain at least one uppercase letter, one lowercase letter, and one number"
|
|
599
646
|
);
|
|
600
|
-
var userRoleSchema =
|
|
601
|
-
var userRolesSchema =
|
|
602
|
-
var timestampSchema =
|
|
647
|
+
var userRoleSchema = z4.nativeEnum(UserRole);
|
|
648
|
+
var userRolesSchema = z4.array(userRoleSchema).min(1, "User must have at least one role").max(3, "User cannot have more than 3 roles");
|
|
649
|
+
var timestampSchema = z4.custom((data) => {
|
|
603
650
|
if (data && typeof data === "object" && "isEqual" in data) {
|
|
604
651
|
return true;
|
|
605
652
|
}
|
|
606
653
|
return data && typeof data === "object" && "toDate" in data && "seconds" in data && "nanoseconds" in data;
|
|
607
654
|
}, "Must be a Timestamp object or serverTimestamp");
|
|
608
|
-
var clinicAdminOptionsSchema =
|
|
609
|
-
isGroupOwner:
|
|
610
|
-
groupToken:
|
|
611
|
-
groupId:
|
|
655
|
+
var clinicAdminOptionsSchema = z4.object({
|
|
656
|
+
isGroupOwner: z4.boolean(),
|
|
657
|
+
groupToken: z4.string().optional(),
|
|
658
|
+
groupId: z4.string().optional()
|
|
612
659
|
}).refine(
|
|
613
660
|
(data) => {
|
|
614
661
|
if (!data.isGroupOwner && (!data.groupToken || !data.groupId)) {
|
|
@@ -623,20 +670,20 @@ var clinicAdminOptionsSchema = z3.object({
|
|
|
623
670
|
message: "Invalid clinic admin options configuration"
|
|
624
671
|
}
|
|
625
672
|
);
|
|
626
|
-
var createUserOptionsSchema =
|
|
673
|
+
var createUserOptionsSchema = z4.object({
|
|
627
674
|
clinicAdminData: clinicAdminOptionsSchema.optional()
|
|
628
675
|
});
|
|
629
|
-
var userSchema =
|
|
630
|
-
uid:
|
|
631
|
-
email:
|
|
632
|
-
roles:
|
|
633
|
-
isAnonymous:
|
|
676
|
+
var userSchema = z4.object({
|
|
677
|
+
uid: z4.string(),
|
|
678
|
+
email: z4.string().email().nullable(),
|
|
679
|
+
roles: z4.array(userRoleSchema),
|
|
680
|
+
isAnonymous: z4.boolean(),
|
|
634
681
|
createdAt: timestampSchema,
|
|
635
682
|
updatedAt: timestampSchema,
|
|
636
683
|
lastLoginAt: timestampSchema,
|
|
637
|
-
patientProfile:
|
|
638
|
-
practitionerProfile:
|
|
639
|
-
adminProfile:
|
|
684
|
+
patientProfile: z4.string().optional(),
|
|
685
|
+
practitionerProfile: z4.string().optional(),
|
|
686
|
+
adminProfile: z4.string().optional()
|
|
640
687
|
});
|
|
641
688
|
|
|
642
689
|
// src/errors/auth.errors.ts
|
|
@@ -1372,14 +1419,6 @@ var Gender = /* @__PURE__ */ ((Gender2) => {
|
|
|
1372
1419
|
import { z as z7 } from "zod";
|
|
1373
1420
|
import { Timestamp as Timestamp3 } from "firebase/firestore";
|
|
1374
1421
|
|
|
1375
|
-
// src/validations/media.schema.ts
|
|
1376
|
-
import { z as z4 } from "zod";
|
|
1377
|
-
var mediaResourceSchema = z4.union([
|
|
1378
|
-
z4.string().url(),
|
|
1379
|
-
z4.instanceof(File),
|
|
1380
|
-
z4.instanceof(Blob)
|
|
1381
|
-
]);
|
|
1382
|
-
|
|
1383
1422
|
// src/validations/patient/medical-info.schema.ts
|
|
1384
1423
|
import { z as z6 } from "zod";
|
|
1385
1424
|
|
|
@@ -3634,25 +3673,6 @@ var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
|
|
|
3634
3673
|
return ProcedureFamily2;
|
|
3635
3674
|
})(ProcedureFamily || {});
|
|
3636
3675
|
|
|
3637
|
-
// src/backoffice/types/static/pricing.types.ts
|
|
3638
|
-
var PricingMeasure = /* @__PURE__ */ ((PricingMeasure3) => {
|
|
3639
|
-
PricingMeasure3["PER_ML"] = "per_ml";
|
|
3640
|
-
PricingMeasure3["PER_ZONE"] = "per_zone";
|
|
3641
|
-
PricingMeasure3["PER_AREA"] = "per_area";
|
|
3642
|
-
PricingMeasure3["PER_SESSION"] = "per_session";
|
|
3643
|
-
PricingMeasure3["PER_TREATMENT"] = "per_treatment";
|
|
3644
|
-
PricingMeasure3["PER_PACKAGE"] = "per_package";
|
|
3645
|
-
return PricingMeasure3;
|
|
3646
|
-
})(PricingMeasure || {});
|
|
3647
|
-
var Currency = /* @__PURE__ */ ((Currency2) => {
|
|
3648
|
-
Currency2["EUR"] = "EUR";
|
|
3649
|
-
Currency2["USD"] = "USD";
|
|
3650
|
-
Currency2["GBP"] = "GBP";
|
|
3651
|
-
Currency2["CHF"] = "CHF";
|
|
3652
|
-
Currency2["AUD"] = "AUD";
|
|
3653
|
-
return Currency2;
|
|
3654
|
-
})(Currency || {});
|
|
3655
|
-
|
|
3656
3676
|
// src/validations/shared.schema.ts
|
|
3657
3677
|
var sharedClinicContactInfoSchema = z12.object({
|
|
3658
3678
|
email: z12.string().email(),
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -5,12 +5,16 @@ import {
|
|
|
5
5
|
PatientProfileInfo,
|
|
6
6
|
} from "../profile";
|
|
7
7
|
import { ProcedureSummaryInfo } from "../procedure";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
Currency,
|
|
10
|
+
type PricingMeasure,
|
|
11
|
+
} from "../../backoffice/types/static/pricing.types";
|
|
9
12
|
import { BlockingCondition } from "../../backoffice/types/static/blocking-condition.types";
|
|
10
13
|
import { Contraindication } from "../../backoffice/types/static/contraindication.types";
|
|
11
14
|
import { Requirement } from "../../backoffice/types/requirement.types";
|
|
12
15
|
import { FilledDocumentStatus } from "../documentation-templates";
|
|
13
16
|
import type { ProcedureFamily } from "../../backoffice";
|
|
17
|
+
import type { MediaResource } from "../../services/media/media.service";
|
|
14
18
|
|
|
15
19
|
/**
|
|
16
20
|
* Enum defining the possible statuses of an appointment.
|
|
@@ -111,6 +115,52 @@ export interface PatientReviewInfo {
|
|
|
111
115
|
reviewedAt: Timestamp;
|
|
112
116
|
}
|
|
113
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Interface for before/after photos and notes per zone
|
|
120
|
+
*/
|
|
121
|
+
export interface BeforeAfterPerZone {
|
|
122
|
+
/** URL for before photo or null if not available */
|
|
123
|
+
before: MediaResource | null;
|
|
124
|
+
/** URL for after photo or null if not available */
|
|
125
|
+
after: MediaResource | null;
|
|
126
|
+
/** Optional note for the zone */
|
|
127
|
+
note: string | null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Interface for billing information per zone
|
|
132
|
+
*/
|
|
133
|
+
export interface BillingPerZone {
|
|
134
|
+
/** Product name/description */
|
|
135
|
+
Product: string;
|
|
136
|
+
/** Product ID */
|
|
137
|
+
ProductId: string | null;
|
|
138
|
+
/** Quantity used (can be decimal) */
|
|
139
|
+
Quantity: number;
|
|
140
|
+
/** Unit of measurement */
|
|
141
|
+
UnitOfMeasurement: PricingMeasure;
|
|
142
|
+
/** Unit price for the product */
|
|
143
|
+
UnitPrice: number;
|
|
144
|
+
/** Currency for the unit price */
|
|
145
|
+
UnitCurency: Currency;
|
|
146
|
+
/** Calculated subtotal */
|
|
147
|
+
Subtotal: number;
|
|
148
|
+
/** Optional billing note */
|
|
149
|
+
Note: string | null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Interface for appointment metadata containing zone-specific information
|
|
154
|
+
*/
|
|
155
|
+
export interface AppointmentMetadata {
|
|
156
|
+
/** Array of selected zones for the appointment */
|
|
157
|
+
selectedZones: string[] | null;
|
|
158
|
+
/** Map of zone photos with before/after images and notes */
|
|
159
|
+
zonePhotos: Record<string, BeforeAfterPerZone> | null;
|
|
160
|
+
/** Map of billing information per zone */
|
|
161
|
+
zoneBilling: Record<string, BillingPerZone> | null;
|
|
162
|
+
}
|
|
163
|
+
|
|
114
164
|
/**
|
|
115
165
|
* Represents a booked appointment, aggregating key information and relevant procedure rules.
|
|
116
166
|
*/
|
|
@@ -209,7 +259,7 @@ export interface Appointment {
|
|
|
209
259
|
isArchived?: boolean;
|
|
210
260
|
|
|
211
261
|
/** NEW: Metadata for the appointment - used for area selection and photos */
|
|
212
|
-
metadata?:
|
|
262
|
+
metadata?: AppointmentMetadata;
|
|
213
263
|
}
|
|
214
264
|
|
|
215
265
|
/**
|
|
@@ -284,7 +334,7 @@ export interface UpdateAppointmentData {
|
|
|
284
334
|
updatedAt?: FieldValue; // To set server timestamp
|
|
285
335
|
|
|
286
336
|
/** NEW: For updating metadata */
|
|
287
|
-
metadata?:
|
|
337
|
+
metadata?: AppointmentMetadata;
|
|
288
338
|
}
|
|
289
339
|
|
|
290
340
|
/**
|
|
@@ -5,6 +5,11 @@ import {
|
|
|
5
5
|
MediaType,
|
|
6
6
|
} from "../types/appointment";
|
|
7
7
|
import { filledDocumentStatusSchema } from "./documentation-templates.schema";
|
|
8
|
+
import {
|
|
9
|
+
Currency,
|
|
10
|
+
PricingMeasure,
|
|
11
|
+
} from "../backoffice/types/static/pricing.types";
|
|
12
|
+
import { mediaResourceSchema } from "./media.schema";
|
|
8
13
|
|
|
9
14
|
// Define common constants locally if not available from common.schema.ts
|
|
10
15
|
const MIN_STRING_LENGTH = 1;
|
|
@@ -147,6 +152,38 @@ export const finalizedDetailsSchema = z.object({
|
|
|
147
152
|
.optional(),
|
|
148
153
|
});
|
|
149
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Schema for before/after photos and notes per zone
|
|
157
|
+
*/
|
|
158
|
+
export const beforeAfterPerZoneSchema = z.object({
|
|
159
|
+
before: mediaResourceSchema.nullable(),
|
|
160
|
+
after: mediaResourceSchema.nullable(),
|
|
161
|
+
note: z.string().nullable(),
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Schema for billing information per zone
|
|
166
|
+
*/
|
|
167
|
+
export const billingPerZoneSchema = z.object({
|
|
168
|
+
Product: z.string().min(MIN_STRING_LENGTH, "Product name is required"),
|
|
169
|
+
ProductId: z.string().nullable(),
|
|
170
|
+
Quantity: z.number().min(0, "Quantity must be non-negative"),
|
|
171
|
+
UnitOfMeasurement: z.nativeEnum(PricingMeasure),
|
|
172
|
+
UnitPrice: z.number().min(0, "Unit price must be non-negative"),
|
|
173
|
+
UnitCurency: z.nativeEnum(Currency),
|
|
174
|
+
Subtotal: z.number().min(0, "Subtotal must be non-negative"),
|
|
175
|
+
Note: z.string().nullable(),
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Schema for appointment metadata containing zone-specific information
|
|
180
|
+
*/
|
|
181
|
+
export const appointmentMetadataSchema = z.object({
|
|
182
|
+
selectedZones: z.array(z.string()).nullable(),
|
|
183
|
+
zonePhotos: z.record(z.string(), beforeAfterPerZoneSchema).nullable(),
|
|
184
|
+
zoneBilling: z.record(z.string(), billingPerZoneSchema).nullable(),
|
|
185
|
+
});
|
|
186
|
+
|
|
150
187
|
// --- Main Appointment Schemas ---
|
|
151
188
|
|
|
152
189
|
/**
|
|
@@ -291,7 +328,7 @@ export const updateAppointmentSchema = z
|
|
|
291
328
|
.optional(),
|
|
292
329
|
isArchived: z.boolean().optional(),
|
|
293
330
|
updatedAt: z.any().optional(),
|
|
294
|
-
metadata:
|
|
331
|
+
metadata: appointmentMetadataSchema.optional(),
|
|
295
332
|
})
|
|
296
333
|
.refine(
|
|
297
334
|
(data) => {
|