@blackcode_sa/metaestetics-api 1.7.10 → 1.7.12
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 +5 -4
- package/dist/admin/index.d.ts +5 -4
- package/dist/index.d.mts +246 -144
- package/dist/index.d.ts +246 -144
- package/dist/index.js +555 -875
- package/dist/index.mjs +597 -922
- package/package.json +1 -1
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +641 -0
- package/src/index.ts +8 -0
- package/src/services/auth.service.ts +4 -0
- package/src/services/clinic/clinic-group.service.ts +49 -0
- package/src/services/clinic/clinic.service.ts +12 -0
- package/src/services/media/media.service.ts +6 -1
- package/src/services/reviews/reviews.service.ts +6 -572
- package/src/types/clinic/index.ts +17 -5
- package/src/validations/clinic.schema.ts +25 -9
- package/src/validations/media.schema.ts +10 -0
package/dist/index.js
CHANGED
|
@@ -73,6 +73,9 @@ __export(index_exports, {
|
|
|
73
73
|
HeadingLevel: () => HeadingLevel,
|
|
74
74
|
Language: () => Language,
|
|
75
75
|
ListType: () => ListType,
|
|
76
|
+
MEDIA_METADATA_COLLECTION: () => MEDIA_METADATA_COLLECTION,
|
|
77
|
+
MediaAccessLevel: () => MediaAccessLevel,
|
|
78
|
+
MediaService: () => MediaService,
|
|
76
79
|
MedicationAllergySubtype: () => MedicationAllergySubtype,
|
|
77
80
|
NotificationService: () => NotificationService,
|
|
78
81
|
NotificationStatus: () => NotificationStatus,
|
|
@@ -793,7 +796,7 @@ var UserRole = /* @__PURE__ */ ((UserRole2) => {
|
|
|
793
796
|
var USERS_COLLECTION = "users";
|
|
794
797
|
|
|
795
798
|
// src/services/auth.service.ts
|
|
796
|
-
var
|
|
799
|
+
var import_zod20 = require("zod");
|
|
797
800
|
|
|
798
801
|
// src/validations/schemas.ts
|
|
799
802
|
var import_zod3 = require("zod");
|
|
@@ -1188,7 +1191,7 @@ var USER_ERRORS = {
|
|
|
1188
1191
|
};
|
|
1189
1192
|
|
|
1190
1193
|
// src/services/user.service.ts
|
|
1191
|
-
var
|
|
1194
|
+
var import_zod16 = require("zod");
|
|
1192
1195
|
|
|
1193
1196
|
// src/services/patient/patient.service.ts
|
|
1194
1197
|
var import_firestore12 = require("firebase/firestore");
|
|
@@ -3099,7 +3102,7 @@ var SubscriptionModel = /* @__PURE__ */ ((SubscriptionModel2) => {
|
|
|
3099
3102
|
})(SubscriptionModel || {});
|
|
3100
3103
|
|
|
3101
3104
|
// src/validations/clinic.schema.ts
|
|
3102
|
-
var
|
|
3105
|
+
var import_zod13 = require("zod");
|
|
3103
3106
|
var import_firestore13 = require("firebase/firestore");
|
|
3104
3107
|
|
|
3105
3108
|
// src/validations/reviews.schema.ts
|
|
@@ -3316,38 +3319,41 @@ var doctorInfoSchema = import_zod11.z.object({
|
|
|
3316
3319
|
// List of procedure IDs practitioner offers
|
|
3317
3320
|
});
|
|
3318
3321
|
|
|
3319
|
-
// src/validations/
|
|
3322
|
+
// src/validations/media.schema.ts
|
|
3323
|
+
var import_zod12 = require("zod");
|
|
3320
3324
|
var mediaResourceSchema = import_zod12.z.union([
|
|
3321
3325
|
import_zod12.z.string(),
|
|
3322
3326
|
import_zod12.z.instanceof(File),
|
|
3323
3327
|
import_zod12.z.instanceof(Blob)
|
|
3324
3328
|
]);
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3329
|
+
|
|
3330
|
+
// src/validations/clinic.schema.ts
|
|
3331
|
+
var clinicContactInfoSchema = import_zod13.z.object({
|
|
3332
|
+
email: import_zod13.z.string().email(),
|
|
3333
|
+
phoneNumber: import_zod13.z.string(),
|
|
3334
|
+
alternativePhoneNumber: import_zod13.z.string().nullable().optional(),
|
|
3335
|
+
website: import_zod13.z.string().nullable().optional()
|
|
3330
3336
|
});
|
|
3331
|
-
var clinicLocationSchema =
|
|
3332
|
-
address:
|
|
3333
|
-
city:
|
|
3334
|
-
country:
|
|
3335
|
-
postalCode:
|
|
3336
|
-
latitude:
|
|
3337
|
-
longitude:
|
|
3338
|
-
geohash:
|
|
3337
|
+
var clinicLocationSchema = import_zod13.z.object({
|
|
3338
|
+
address: import_zod13.z.string(),
|
|
3339
|
+
city: import_zod13.z.string(),
|
|
3340
|
+
country: import_zod13.z.string(),
|
|
3341
|
+
postalCode: import_zod13.z.string(),
|
|
3342
|
+
latitude: import_zod13.z.number().min(-90).max(90),
|
|
3343
|
+
longitude: import_zod13.z.number().min(-180).max(180),
|
|
3344
|
+
geohash: import_zod13.z.string().nullable().optional()
|
|
3339
3345
|
});
|
|
3340
|
-
var workingHoursTimeSchema =
|
|
3341
|
-
open:
|
|
3342
|
-
close:
|
|
3343
|
-
breaks:
|
|
3344
|
-
|
|
3345
|
-
start:
|
|
3346
|
-
end:
|
|
3346
|
+
var workingHoursTimeSchema = import_zod13.z.object({
|
|
3347
|
+
open: import_zod13.z.string(),
|
|
3348
|
+
close: import_zod13.z.string(),
|
|
3349
|
+
breaks: import_zod13.z.array(
|
|
3350
|
+
import_zod13.z.object({
|
|
3351
|
+
start: import_zod13.z.string(),
|
|
3352
|
+
end: import_zod13.z.string()
|
|
3347
3353
|
})
|
|
3348
3354
|
).optional()
|
|
3349
3355
|
});
|
|
3350
|
-
var workingHoursSchema =
|
|
3356
|
+
var workingHoursSchema = import_zod13.z.object({
|
|
3351
3357
|
monday: workingHoursTimeSchema.nullable(),
|
|
3352
3358
|
tuesday: workingHoursTimeSchema.nullable(),
|
|
3353
3359
|
wednesday: workingHoursTimeSchema.nullable(),
|
|
@@ -3356,239 +3362,255 @@ var workingHoursSchema = import_zod12.z.object({
|
|
|
3356
3362
|
saturday: workingHoursTimeSchema.nullable(),
|
|
3357
3363
|
sunday: workingHoursTimeSchema.nullable()
|
|
3358
3364
|
});
|
|
3359
|
-
var clinicTagsSchema =
|
|
3360
|
-
tags:
|
|
3365
|
+
var clinicTagsSchema = import_zod13.z.object({
|
|
3366
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag))
|
|
3361
3367
|
});
|
|
3362
|
-
var contactPersonSchema =
|
|
3363
|
-
firstName:
|
|
3364
|
-
lastName:
|
|
3365
|
-
title:
|
|
3366
|
-
email:
|
|
3367
|
-
phoneNumber:
|
|
3368
|
+
var contactPersonSchema = import_zod13.z.object({
|
|
3369
|
+
firstName: import_zod13.z.string(),
|
|
3370
|
+
lastName: import_zod13.z.string(),
|
|
3371
|
+
title: import_zod13.z.string().nullable().optional(),
|
|
3372
|
+
email: import_zod13.z.string().email(),
|
|
3373
|
+
phoneNumber: import_zod13.z.string().nullable().optional()
|
|
3368
3374
|
});
|
|
3369
|
-
var adminInfoSchema =
|
|
3370
|
-
id:
|
|
3371
|
-
name:
|
|
3372
|
-
email:
|
|
3375
|
+
var adminInfoSchema = import_zod13.z.object({
|
|
3376
|
+
id: import_zod13.z.string(),
|
|
3377
|
+
name: import_zod13.z.string(),
|
|
3378
|
+
email: import_zod13.z.string().email()
|
|
3373
3379
|
});
|
|
3374
|
-
var clinicAdminSchema =
|
|
3375
|
-
id:
|
|
3376
|
-
userRef:
|
|
3377
|
-
clinicGroupId:
|
|
3378
|
-
isGroupOwner:
|
|
3379
|
-
clinicsManaged:
|
|
3380
|
-
clinicsManagedInfo:
|
|
3380
|
+
var clinicAdminSchema = import_zod13.z.object({
|
|
3381
|
+
id: import_zod13.z.string(),
|
|
3382
|
+
userRef: import_zod13.z.string(),
|
|
3383
|
+
clinicGroupId: import_zod13.z.string(),
|
|
3384
|
+
isGroupOwner: import_zod13.z.boolean(),
|
|
3385
|
+
clinicsManaged: import_zod13.z.array(import_zod13.z.string()),
|
|
3386
|
+
clinicsManagedInfo: import_zod13.z.array(clinicInfoSchema),
|
|
3381
3387
|
contactInfo: contactPersonSchema,
|
|
3382
|
-
roleTitle:
|
|
3383
|
-
createdAt:
|
|
3384
|
-
updatedAt:
|
|
3385
|
-
isActive:
|
|
3388
|
+
roleTitle: import_zod13.z.string(),
|
|
3389
|
+
createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
|
|
3390
|
+
updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
|
|
3391
|
+
isActive: import_zod13.z.boolean()
|
|
3386
3392
|
});
|
|
3387
|
-
var adminTokenSchema =
|
|
3388
|
-
id:
|
|
3389
|
-
token:
|
|
3390
|
-
email:
|
|
3391
|
-
status:
|
|
3392
|
-
usedByUserRef:
|
|
3393
|
-
createdAt:
|
|
3393
|
+
var adminTokenSchema = import_zod13.z.object({
|
|
3394
|
+
id: import_zod13.z.string(),
|
|
3395
|
+
token: import_zod13.z.string(),
|
|
3396
|
+
email: import_zod13.z.string().email().optional().nullable(),
|
|
3397
|
+
status: import_zod13.z.nativeEnum(AdminTokenStatus),
|
|
3398
|
+
usedByUserRef: import_zod13.z.string().optional(),
|
|
3399
|
+
createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
|
|
3394
3400
|
// Timestamp
|
|
3395
|
-
expiresAt:
|
|
3401
|
+
expiresAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp))
|
|
3396
3402
|
// Timestamp
|
|
3397
3403
|
});
|
|
3398
|
-
var createAdminTokenSchema =
|
|
3399
|
-
expiresInDays:
|
|
3400
|
-
email:
|
|
3404
|
+
var createAdminTokenSchema = import_zod13.z.object({
|
|
3405
|
+
expiresInDays: import_zod13.z.number().min(1).max(30).optional(),
|
|
3406
|
+
email: import_zod13.z.string().email().optional().nullable()
|
|
3401
3407
|
});
|
|
3402
|
-
var clinicGroupSchema =
|
|
3403
|
-
id:
|
|
3404
|
-
name:
|
|
3405
|
-
description:
|
|
3408
|
+
var clinicGroupSchema = import_zod13.z.object({
|
|
3409
|
+
id: import_zod13.z.string(),
|
|
3410
|
+
name: import_zod13.z.string(),
|
|
3411
|
+
description: import_zod13.z.string().nullable().optional(),
|
|
3406
3412
|
hqLocation: clinicLocationSchema,
|
|
3407
3413
|
contactInfo: clinicContactInfoSchema,
|
|
3408
3414
|
contactPerson: contactPersonSchema,
|
|
3409
|
-
clinics:
|
|
3410
|
-
clinicsInfo:
|
|
3411
|
-
admins:
|
|
3412
|
-
adminsInfo:
|
|
3413
|
-
adminTokens:
|
|
3414
|
-
ownerId:
|
|
3415
|
-
createdAt:
|
|
3415
|
+
clinics: import_zod13.z.array(import_zod13.z.string()),
|
|
3416
|
+
clinicsInfo: import_zod13.z.array(clinicInfoSchema),
|
|
3417
|
+
admins: import_zod13.z.array(import_zod13.z.string()),
|
|
3418
|
+
adminsInfo: import_zod13.z.array(adminInfoSchema),
|
|
3419
|
+
adminTokens: import_zod13.z.array(adminTokenSchema),
|
|
3420
|
+
ownerId: import_zod13.z.string().nullable(),
|
|
3421
|
+
createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
|
|
3416
3422
|
// Timestamp
|
|
3417
|
-
updatedAt:
|
|
3423
|
+
updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
|
|
3418
3424
|
// Timestamp
|
|
3419
|
-
isActive:
|
|
3425
|
+
isActive: import_zod13.z.boolean(),
|
|
3420
3426
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3421
|
-
practiceType:
|
|
3422
|
-
languages:
|
|
3423
|
-
subscriptionModel:
|
|
3424
|
-
calendarSyncEnabled:
|
|
3425
|
-
autoConfirmAppointments:
|
|
3426
|
-
businessIdentificationNumber:
|
|
3427
|
+
practiceType: import_zod13.z.nativeEnum(PracticeType).optional(),
|
|
3428
|
+
languages: import_zod13.z.array(import_zod13.z.nativeEnum(Language)).optional(),
|
|
3429
|
+
subscriptionModel: import_zod13.z.nativeEnum(SubscriptionModel),
|
|
3430
|
+
calendarSyncEnabled: import_zod13.z.boolean().optional(),
|
|
3431
|
+
autoConfirmAppointments: import_zod13.z.boolean().optional(),
|
|
3432
|
+
businessIdentificationNumber: import_zod13.z.string().optional().nullable(),
|
|
3433
|
+
onboarding: import_zod13.z.object({
|
|
3434
|
+
completed: import_zod13.z.boolean().optional().default(false),
|
|
3435
|
+
step: import_zod13.z.number().optional().default(1)
|
|
3436
|
+
}).optional()
|
|
3427
3437
|
});
|
|
3428
|
-
var clinicSchema =
|
|
3429
|
-
id:
|
|
3430
|
-
clinicGroupId:
|
|
3431
|
-
name:
|
|
3432
|
-
description:
|
|
3438
|
+
var clinicSchema = import_zod13.z.object({
|
|
3439
|
+
id: import_zod13.z.string(),
|
|
3440
|
+
clinicGroupId: import_zod13.z.string(),
|
|
3441
|
+
name: import_zod13.z.string(),
|
|
3442
|
+
description: import_zod13.z.string().nullable().optional(),
|
|
3433
3443
|
location: clinicLocationSchema,
|
|
3434
3444
|
contactInfo: clinicContactInfoSchema,
|
|
3435
3445
|
workingHours: workingHoursSchema,
|
|
3436
|
-
tags:
|
|
3437
|
-
featuredPhotos:
|
|
3446
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag)),
|
|
3447
|
+
featuredPhotos: import_zod13.z.array(mediaResourceSchema),
|
|
3438
3448
|
coverPhoto: mediaResourceSchema.nullable(),
|
|
3439
|
-
photosWithTags:
|
|
3440
|
-
|
|
3449
|
+
photosWithTags: import_zod13.z.array(
|
|
3450
|
+
import_zod13.z.object({
|
|
3441
3451
|
url: mediaResourceSchema,
|
|
3442
|
-
tag:
|
|
3452
|
+
tag: import_zod13.z.string()
|
|
3443
3453
|
})
|
|
3444
3454
|
).optional(),
|
|
3445
|
-
doctors:
|
|
3455
|
+
doctors: import_zod13.z.array(import_zod13.z.string()),
|
|
3446
3456
|
// List of practitioner IDs
|
|
3447
|
-
doctorsInfo:
|
|
3457
|
+
doctorsInfo: import_zod13.z.array(doctorInfoSchema),
|
|
3448
3458
|
// Aggregated doctor info
|
|
3449
|
-
procedures:
|
|
3459
|
+
procedures: import_zod13.z.array(import_zod13.z.string()),
|
|
3450
3460
|
// List of procedure IDs offered by clinic
|
|
3451
|
-
proceduresInfo:
|
|
3461
|
+
proceduresInfo: import_zod13.z.array(procedureSummaryInfoSchema),
|
|
3452
3462
|
// Use the correct schema for aggregated procedure info
|
|
3453
3463
|
reviewInfo: clinicReviewInfoSchema,
|
|
3454
|
-
admins:
|
|
3455
|
-
createdAt:
|
|
3464
|
+
admins: import_zod13.z.array(import_zod13.z.string()),
|
|
3465
|
+
createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
|
|
3456
3466
|
// Timestamp
|
|
3457
|
-
updatedAt:
|
|
3467
|
+
updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
|
|
3458
3468
|
// Timestamp
|
|
3459
|
-
isActive:
|
|
3460
|
-
isVerified:
|
|
3469
|
+
isActive: import_zod13.z.boolean(),
|
|
3470
|
+
isVerified: import_zod13.z.boolean(),
|
|
3461
3471
|
logo: mediaResourceSchema.optional().nullable()
|
|
3462
3472
|
});
|
|
3463
|
-
var createClinicAdminSchema =
|
|
3464
|
-
userRef:
|
|
3465
|
-
clinicGroupId:
|
|
3466
|
-
isGroupOwner:
|
|
3467
|
-
clinicsManaged:
|
|
3473
|
+
var createClinicAdminSchema = import_zod13.z.object({
|
|
3474
|
+
userRef: import_zod13.z.string(),
|
|
3475
|
+
clinicGroupId: import_zod13.z.string().optional(),
|
|
3476
|
+
isGroupOwner: import_zod13.z.boolean(),
|
|
3477
|
+
clinicsManaged: import_zod13.z.array(import_zod13.z.string()),
|
|
3468
3478
|
contactInfo: contactPersonSchema,
|
|
3469
|
-
roleTitle:
|
|
3470
|
-
isActive:
|
|
3479
|
+
roleTitle: import_zod13.z.string(),
|
|
3480
|
+
isActive: import_zod13.z.boolean()
|
|
3471
3481
|
// clinicsManagedInfo is aggregated, not provided on creation
|
|
3472
3482
|
});
|
|
3473
|
-
var createClinicGroupSchema =
|
|
3474
|
-
name:
|
|
3475
|
-
description:
|
|
3483
|
+
var createClinicGroupSchema = import_zod13.z.object({
|
|
3484
|
+
name: import_zod13.z.string(),
|
|
3485
|
+
description: import_zod13.z.string().optional(),
|
|
3476
3486
|
hqLocation: clinicLocationSchema,
|
|
3477
3487
|
contactInfo: clinicContactInfoSchema,
|
|
3478
3488
|
contactPerson: contactPersonSchema,
|
|
3479
|
-
ownerId:
|
|
3480
|
-
isActive:
|
|
3489
|
+
ownerId: import_zod13.z.string().nullable(),
|
|
3490
|
+
isActive: import_zod13.z.boolean(),
|
|
3481
3491
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3482
|
-
practiceType:
|
|
3483
|
-
languages:
|
|
3484
|
-
subscriptionModel:
|
|
3485
|
-
calendarSyncEnabled:
|
|
3486
|
-
autoConfirmAppointments:
|
|
3487
|
-
businessIdentificationNumber:
|
|
3492
|
+
practiceType: import_zod13.z.nativeEnum(PracticeType).optional(),
|
|
3493
|
+
languages: import_zod13.z.array(import_zod13.z.nativeEnum(Language)).optional(),
|
|
3494
|
+
subscriptionModel: import_zod13.z.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
|
|
3495
|
+
calendarSyncEnabled: import_zod13.z.boolean().optional(),
|
|
3496
|
+
autoConfirmAppointments: import_zod13.z.boolean().optional(),
|
|
3497
|
+
businessIdentificationNumber: import_zod13.z.string().optional().nullable(),
|
|
3498
|
+
onboarding: import_zod13.z.object({
|
|
3499
|
+
completed: import_zod13.z.boolean().optional().default(false),
|
|
3500
|
+
step: import_zod13.z.number().optional().default(1)
|
|
3501
|
+
}).optional()
|
|
3488
3502
|
// clinics, clinicsInfo, admins, adminsInfo, adminTokens are managed internally
|
|
3489
3503
|
});
|
|
3490
|
-
var createClinicSchema =
|
|
3491
|
-
clinicGroupId:
|
|
3492
|
-
name:
|
|
3493
|
-
description:
|
|
3504
|
+
var createClinicSchema = import_zod13.z.object({
|
|
3505
|
+
clinicGroupId: import_zod13.z.string(),
|
|
3506
|
+
name: import_zod13.z.string(),
|
|
3507
|
+
description: import_zod13.z.string().optional(),
|
|
3494
3508
|
location: clinicLocationSchema,
|
|
3495
3509
|
contactInfo: clinicContactInfoSchema,
|
|
3496
3510
|
workingHours: workingHoursSchema,
|
|
3497
|
-
tags:
|
|
3511
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag)),
|
|
3498
3512
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
3499
|
-
photosWithTags:
|
|
3500
|
-
|
|
3513
|
+
photosWithTags: import_zod13.z.array(
|
|
3514
|
+
import_zod13.z.object({
|
|
3501
3515
|
url: mediaResourceSchema,
|
|
3502
|
-
tag:
|
|
3516
|
+
tag: import_zod13.z.string()
|
|
3503
3517
|
})
|
|
3504
3518
|
).optional(),
|
|
3505
|
-
doctors:
|
|
3506
|
-
procedures:
|
|
3507
|
-
proceduresInfo:
|
|
3508
|
-
admins:
|
|
3509
|
-
isActive:
|
|
3510
|
-
isVerified:
|
|
3519
|
+
doctors: import_zod13.z.array(import_zod13.z.string()).optional().default([]),
|
|
3520
|
+
procedures: import_zod13.z.array(import_zod13.z.string()).optional().default([]),
|
|
3521
|
+
proceduresInfo: import_zod13.z.array(procedureSummaryInfoSchema).optional(),
|
|
3522
|
+
admins: import_zod13.z.array(import_zod13.z.string()),
|
|
3523
|
+
isActive: import_zod13.z.boolean().optional().default(true),
|
|
3524
|
+
isVerified: import_zod13.z.boolean().optional().default(false),
|
|
3511
3525
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3512
|
-
featuredPhotos:
|
|
3526
|
+
featuredPhotos: import_zod13.z.array(mediaResourceSchema).optional().default([])
|
|
3513
3527
|
});
|
|
3514
|
-
var createDefaultClinicGroupSchema =
|
|
3515
|
-
name:
|
|
3516
|
-
ownerId:
|
|
3528
|
+
var createDefaultClinicGroupSchema = import_zod13.z.object({
|
|
3529
|
+
name: import_zod13.z.string(),
|
|
3530
|
+
ownerId: import_zod13.z.string().nullable(),
|
|
3517
3531
|
contactPerson: contactPersonSchema,
|
|
3518
3532
|
contactInfo: clinicContactInfoSchema,
|
|
3519
3533
|
hqLocation: clinicLocationSchema,
|
|
3520
|
-
isActive:
|
|
3534
|
+
isActive: import_zod13.z.boolean(),
|
|
3521
3535
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3522
|
-
practiceType:
|
|
3523
|
-
languages:
|
|
3524
|
-
subscriptionModel:
|
|
3536
|
+
practiceType: import_zod13.z.nativeEnum(PracticeType).optional(),
|
|
3537
|
+
languages: import_zod13.z.array(import_zod13.z.nativeEnum(Language)).optional(),
|
|
3538
|
+
subscriptionModel: import_zod13.z.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
|
|
3539
|
+
onboarding: import_zod13.z.object({
|
|
3540
|
+
completed: import_zod13.z.boolean().optional().default(false),
|
|
3541
|
+
step: import_zod13.z.number().optional().default(1)
|
|
3542
|
+
}).optional()
|
|
3525
3543
|
});
|
|
3526
|
-
var clinicAdminSignupSchema =
|
|
3527
|
-
email:
|
|
3528
|
-
password:
|
|
3529
|
-
firstName:
|
|
3530
|
-
lastName:
|
|
3531
|
-
title:
|
|
3532
|
-
phoneNumber:
|
|
3533
|
-
isCreatingNewGroup:
|
|
3534
|
-
inviteToken:
|
|
3535
|
-
clinicGroupData:
|
|
3536
|
-
name:
|
|
3544
|
+
var clinicAdminSignupSchema = import_zod13.z.object({
|
|
3545
|
+
email: import_zod13.z.string().email(),
|
|
3546
|
+
password: import_zod13.z.string().min(8),
|
|
3547
|
+
firstName: import_zod13.z.string(),
|
|
3548
|
+
lastName: import_zod13.z.string(),
|
|
3549
|
+
title: import_zod13.z.string(),
|
|
3550
|
+
phoneNumber: import_zod13.z.string(),
|
|
3551
|
+
isCreatingNewGroup: import_zod13.z.boolean(),
|
|
3552
|
+
inviteToken: import_zod13.z.string().optional(),
|
|
3553
|
+
clinicGroupData: import_zod13.z.object({
|
|
3554
|
+
name: import_zod13.z.string(),
|
|
3537
3555
|
hqLocation: clinicLocationSchema,
|
|
3538
3556
|
logo: mediaResourceSchema.optional(),
|
|
3539
3557
|
contactInfo: clinicContactInfoSchema,
|
|
3540
|
-
subscriptionModel:
|
|
3558
|
+
subscriptionModel: import_zod13.z.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */)
|
|
3541
3559
|
}).optional()
|
|
3542
3560
|
});
|
|
3543
|
-
var clinicGroupSetupSchema =
|
|
3544
|
-
languages:
|
|
3545
|
-
practiceType:
|
|
3546
|
-
description:
|
|
3561
|
+
var clinicGroupSetupSchema = import_zod13.z.object({
|
|
3562
|
+
languages: import_zod13.z.array(import_zod13.z.nativeEnum(Language)),
|
|
3563
|
+
practiceType: import_zod13.z.nativeEnum(PracticeType),
|
|
3564
|
+
description: import_zod13.z.string(),
|
|
3547
3565
|
logo: mediaResourceSchema,
|
|
3548
|
-
calendarSyncEnabled:
|
|
3549
|
-
autoConfirmAppointments:
|
|
3550
|
-
businessIdentificationNumber:
|
|
3566
|
+
calendarSyncEnabled: import_zod13.z.boolean(),
|
|
3567
|
+
autoConfirmAppointments: import_zod13.z.boolean(),
|
|
3568
|
+
businessIdentificationNumber: import_zod13.z.string().optional().nullable(),
|
|
3569
|
+
onboarding: import_zod13.z.object({
|
|
3570
|
+
completed: import_zod13.z.boolean().optional().default(false),
|
|
3571
|
+
step: import_zod13.z.number().optional().default(1)
|
|
3572
|
+
}).optional()
|
|
3551
3573
|
});
|
|
3552
|
-
var clinicBranchSetupSchema =
|
|
3553
|
-
name:
|
|
3574
|
+
var clinicBranchSetupSchema = import_zod13.z.object({
|
|
3575
|
+
name: import_zod13.z.string(),
|
|
3554
3576
|
location: clinicLocationSchema,
|
|
3555
|
-
description:
|
|
3577
|
+
description: import_zod13.z.string().optional(),
|
|
3556
3578
|
contactInfo: clinicContactInfoSchema,
|
|
3557
3579
|
workingHours: workingHoursSchema,
|
|
3558
|
-
tags:
|
|
3580
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag)),
|
|
3559
3581
|
logo: mediaResourceSchema.optional(),
|
|
3560
3582
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
3561
|
-
photosWithTags:
|
|
3562
|
-
|
|
3583
|
+
photosWithTags: import_zod13.z.array(
|
|
3584
|
+
import_zod13.z.object({
|
|
3563
3585
|
url: mediaResourceSchema,
|
|
3564
|
-
tag:
|
|
3586
|
+
tag: import_zod13.z.string()
|
|
3565
3587
|
})
|
|
3566
3588
|
).optional(),
|
|
3567
|
-
featuredPhotos:
|
|
3589
|
+
featuredPhotos: import_zod13.z.array(mediaResourceSchema).optional()
|
|
3568
3590
|
});
|
|
3569
3591
|
var updateClinicAdminSchema = createClinicAdminSchema.partial();
|
|
3570
3592
|
var updateClinicGroupSchema = createClinicGroupSchema.partial();
|
|
3571
|
-
var updateClinicSchema =
|
|
3572
|
-
name:
|
|
3573
|
-
description:
|
|
3593
|
+
var updateClinicSchema = import_zod13.z.object({
|
|
3594
|
+
name: import_zod13.z.string().optional(),
|
|
3595
|
+
description: import_zod13.z.string().optional(),
|
|
3574
3596
|
location: clinicLocationSchema.optional(),
|
|
3575
3597
|
contactInfo: clinicContactInfoSchema.optional(),
|
|
3576
3598
|
workingHours: workingHoursSchema.optional(),
|
|
3577
|
-
tags:
|
|
3599
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag)).optional(),
|
|
3578
3600
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
3579
|
-
photosWithTags:
|
|
3580
|
-
|
|
3601
|
+
photosWithTags: import_zod13.z.array(
|
|
3602
|
+
import_zod13.z.object({
|
|
3581
3603
|
url: mediaResourceSchema,
|
|
3582
|
-
tag:
|
|
3604
|
+
tag: import_zod13.z.string()
|
|
3583
3605
|
})
|
|
3584
3606
|
).optional(),
|
|
3585
|
-
doctors:
|
|
3586
|
-
procedures:
|
|
3587
|
-
proceduresInfo:
|
|
3588
|
-
isActive:
|
|
3589
|
-
isVerified:
|
|
3607
|
+
doctors: import_zod13.z.array(import_zod13.z.string()).optional(),
|
|
3608
|
+
procedures: import_zod13.z.array(import_zod13.z.string()).optional(),
|
|
3609
|
+
proceduresInfo: import_zod13.z.array(procedureSummaryInfoSchema).optional(),
|
|
3610
|
+
isActive: import_zod13.z.boolean().optional(),
|
|
3611
|
+
isVerified: import_zod13.z.boolean().optional(),
|
|
3590
3612
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3591
|
-
featuredPhotos:
|
|
3613
|
+
featuredPhotos: import_zod13.z.array(mediaResourceSchema).optional()
|
|
3592
3614
|
});
|
|
3593
3615
|
|
|
3594
3616
|
// src/services/clinic/utils/admin.utils.ts
|
|
@@ -4041,7 +4063,7 @@ var ClinicAdminService = class extends BaseService {
|
|
|
4041
4063
|
var import_firestore16 = require("firebase/firestore");
|
|
4042
4064
|
|
|
4043
4065
|
// src/validations/practitioner.schema.ts
|
|
4044
|
-
var
|
|
4066
|
+
var import_zod14 = require("zod");
|
|
4045
4067
|
var import_firestore15 = require("firebase/firestore");
|
|
4046
4068
|
|
|
4047
4069
|
// src/backoffice/types/static/certification.types.ts
|
|
@@ -4069,34 +4091,34 @@ var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
|
|
|
4069
4091
|
})(CertificationSpecialty || {});
|
|
4070
4092
|
|
|
4071
4093
|
// src/validations/practitioner.schema.ts
|
|
4072
|
-
var practitionerBasicInfoSchema =
|
|
4073
|
-
firstName:
|
|
4074
|
-
lastName:
|
|
4075
|
-
title:
|
|
4076
|
-
email:
|
|
4077
|
-
phoneNumber:
|
|
4078
|
-
dateOfBirth:
|
|
4079
|
-
gender:
|
|
4080
|
-
profileImageUrl:
|
|
4081
|
-
bio:
|
|
4082
|
-
languages:
|
|
4094
|
+
var practitionerBasicInfoSchema = import_zod14.z.object({
|
|
4095
|
+
firstName: import_zod14.z.string().min(2).max(50),
|
|
4096
|
+
lastName: import_zod14.z.string().min(2).max(50),
|
|
4097
|
+
title: import_zod14.z.string().min(2).max(100),
|
|
4098
|
+
email: import_zod14.z.string().email(),
|
|
4099
|
+
phoneNumber: import_zod14.z.string().regex(/^\+?[1-9]\d{1,14}$/, "Invalid phone number"),
|
|
4100
|
+
dateOfBirth: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date()),
|
|
4101
|
+
gender: import_zod14.z.enum(["male", "female", "other"]),
|
|
4102
|
+
profileImageUrl: import_zod14.z.string().url().optional(),
|
|
4103
|
+
bio: import_zod14.z.string().max(1e3).optional(),
|
|
4104
|
+
languages: import_zod14.z.array(import_zod14.z.string()).min(1)
|
|
4083
4105
|
});
|
|
4084
|
-
var practitionerCertificationSchema =
|
|
4085
|
-
level:
|
|
4086
|
-
specialties:
|
|
4087
|
-
licenseNumber:
|
|
4088
|
-
issuingAuthority:
|
|
4089
|
-
issueDate:
|
|
4090
|
-
expiryDate:
|
|
4091
|
-
verificationStatus:
|
|
4106
|
+
var practitionerCertificationSchema = import_zod14.z.object({
|
|
4107
|
+
level: import_zod14.z.nativeEnum(CertificationLevel),
|
|
4108
|
+
specialties: import_zod14.z.array(import_zod14.z.nativeEnum(CertificationSpecialty)),
|
|
4109
|
+
licenseNumber: import_zod14.z.string().min(3).max(50),
|
|
4110
|
+
issuingAuthority: import_zod14.z.string().min(2).max(100),
|
|
4111
|
+
issueDate: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date()),
|
|
4112
|
+
expiryDate: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date()).optional(),
|
|
4113
|
+
verificationStatus: import_zod14.z.enum(["pending", "verified", "rejected"])
|
|
4092
4114
|
});
|
|
4093
|
-
var timeSlotSchema =
|
|
4094
|
-
start:
|
|
4095
|
-
end:
|
|
4115
|
+
var timeSlotSchema = import_zod14.z.object({
|
|
4116
|
+
start: import_zod14.z.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format"),
|
|
4117
|
+
end: import_zod14.z.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format")
|
|
4096
4118
|
}).nullable();
|
|
4097
|
-
var practitionerWorkingHoursSchema =
|
|
4098
|
-
practitionerId:
|
|
4099
|
-
clinicId:
|
|
4119
|
+
var practitionerWorkingHoursSchema = import_zod14.z.object({
|
|
4120
|
+
practitionerId: import_zod14.z.string().min(1),
|
|
4121
|
+
clinicId: import_zod14.z.string().min(1),
|
|
4100
4122
|
monday: timeSlotSchema,
|
|
4101
4123
|
tuesday: timeSlotSchema,
|
|
4102
4124
|
wednesday: timeSlotSchema,
|
|
@@ -4104,12 +4126,12 @@ var practitionerWorkingHoursSchema = import_zod13.z.object({
|
|
|
4104
4126
|
friday: timeSlotSchema,
|
|
4105
4127
|
saturday: timeSlotSchema,
|
|
4106
4128
|
sunday: timeSlotSchema,
|
|
4107
|
-
createdAt:
|
|
4108
|
-
updatedAt:
|
|
4129
|
+
createdAt: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date()),
|
|
4130
|
+
updatedAt: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date())
|
|
4109
4131
|
});
|
|
4110
|
-
var practitionerClinicWorkingHoursSchema =
|
|
4111
|
-
clinicId:
|
|
4112
|
-
workingHours:
|
|
4132
|
+
var practitionerClinicWorkingHoursSchema = import_zod14.z.object({
|
|
4133
|
+
clinicId: import_zod14.z.string().min(1),
|
|
4134
|
+
workingHours: import_zod14.z.object({
|
|
4113
4135
|
monday: timeSlotSchema,
|
|
4114
4136
|
tuesday: timeSlotSchema,
|
|
4115
4137
|
wednesday: timeSlotSchema,
|
|
@@ -4118,87 +4140,87 @@ var practitionerClinicWorkingHoursSchema = import_zod13.z.object({
|
|
|
4118
4140
|
saturday: timeSlotSchema,
|
|
4119
4141
|
sunday: timeSlotSchema
|
|
4120
4142
|
}),
|
|
4121
|
-
isActive:
|
|
4122
|
-
createdAt:
|
|
4123
|
-
updatedAt:
|
|
4143
|
+
isActive: import_zod14.z.boolean(),
|
|
4144
|
+
createdAt: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date()),
|
|
4145
|
+
updatedAt: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date())
|
|
4124
4146
|
});
|
|
4125
|
-
var practitionerSchema =
|
|
4126
|
-
id:
|
|
4127
|
-
userRef:
|
|
4147
|
+
var practitionerSchema = import_zod14.z.object({
|
|
4148
|
+
id: import_zod14.z.string().min(1),
|
|
4149
|
+
userRef: import_zod14.z.string().min(1),
|
|
4128
4150
|
basicInfo: practitionerBasicInfoSchema,
|
|
4129
4151
|
certification: practitionerCertificationSchema,
|
|
4130
|
-
clinics:
|
|
4131
|
-
clinicWorkingHours:
|
|
4132
|
-
clinicsInfo:
|
|
4133
|
-
procedures:
|
|
4134
|
-
proceduresInfo:
|
|
4152
|
+
clinics: import_zod14.z.array(import_zod14.z.string()),
|
|
4153
|
+
clinicWorkingHours: import_zod14.z.array(practitionerClinicWorkingHoursSchema),
|
|
4154
|
+
clinicsInfo: import_zod14.z.array(clinicInfoSchema),
|
|
4155
|
+
procedures: import_zod14.z.array(import_zod14.z.string()),
|
|
4156
|
+
proceduresInfo: import_zod14.z.array(procedureSummaryInfoSchema),
|
|
4135
4157
|
reviewInfo: practitionerReviewInfoSchema,
|
|
4136
|
-
isActive:
|
|
4137
|
-
isVerified:
|
|
4138
|
-
status:
|
|
4139
|
-
createdAt:
|
|
4140
|
-
updatedAt:
|
|
4158
|
+
isActive: import_zod14.z.boolean(),
|
|
4159
|
+
isVerified: import_zod14.z.boolean(),
|
|
4160
|
+
status: import_zod14.z.nativeEnum(PractitionerStatus),
|
|
4161
|
+
createdAt: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date()),
|
|
4162
|
+
updatedAt: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date())
|
|
4141
4163
|
});
|
|
4142
|
-
var createPractitionerSchema =
|
|
4143
|
-
userRef:
|
|
4164
|
+
var createPractitionerSchema = import_zod14.z.object({
|
|
4165
|
+
userRef: import_zod14.z.string().min(1),
|
|
4144
4166
|
basicInfo: practitionerBasicInfoSchema,
|
|
4145
4167
|
certification: practitionerCertificationSchema,
|
|
4146
|
-
clinics:
|
|
4147
|
-
clinicWorkingHours:
|
|
4148
|
-
clinicsInfo:
|
|
4149
|
-
proceduresInfo:
|
|
4150
|
-
isActive:
|
|
4151
|
-
isVerified:
|
|
4152
|
-
status:
|
|
4168
|
+
clinics: import_zod14.z.array(import_zod14.z.string()).optional(),
|
|
4169
|
+
clinicWorkingHours: import_zod14.z.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
4170
|
+
clinicsInfo: import_zod14.z.array(clinicInfoSchema).optional(),
|
|
4171
|
+
proceduresInfo: import_zod14.z.array(procedureSummaryInfoSchema).optional(),
|
|
4172
|
+
isActive: import_zod14.z.boolean(),
|
|
4173
|
+
isVerified: import_zod14.z.boolean(),
|
|
4174
|
+
status: import_zod14.z.nativeEnum(PractitionerStatus).optional()
|
|
4153
4175
|
});
|
|
4154
|
-
var createDraftPractitionerSchema =
|
|
4176
|
+
var createDraftPractitionerSchema = import_zod14.z.object({
|
|
4155
4177
|
basicInfo: practitionerBasicInfoSchema,
|
|
4156
4178
|
certification: practitionerCertificationSchema,
|
|
4157
|
-
clinics:
|
|
4158
|
-
clinicWorkingHours:
|
|
4159
|
-
clinicsInfo:
|
|
4160
|
-
proceduresInfo:
|
|
4161
|
-
isActive:
|
|
4162
|
-
isVerified:
|
|
4179
|
+
clinics: import_zod14.z.array(import_zod14.z.string()).optional(),
|
|
4180
|
+
clinicWorkingHours: import_zod14.z.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
4181
|
+
clinicsInfo: import_zod14.z.array(clinicInfoSchema).optional(),
|
|
4182
|
+
proceduresInfo: import_zod14.z.array(procedureSummaryInfoSchema).optional(),
|
|
4183
|
+
isActive: import_zod14.z.boolean().optional().default(false),
|
|
4184
|
+
isVerified: import_zod14.z.boolean().optional().default(false)
|
|
4163
4185
|
});
|
|
4164
|
-
var practitionerTokenSchema =
|
|
4165
|
-
id:
|
|
4166
|
-
token:
|
|
4167
|
-
practitionerId:
|
|
4168
|
-
email:
|
|
4169
|
-
clinicId:
|
|
4170
|
-
status:
|
|
4171
|
-
createdBy:
|
|
4172
|
-
createdAt:
|
|
4173
|
-
expiresAt:
|
|
4174
|
-
usedBy:
|
|
4175
|
-
usedAt:
|
|
4186
|
+
var practitionerTokenSchema = import_zod14.z.object({
|
|
4187
|
+
id: import_zod14.z.string().min(1),
|
|
4188
|
+
token: import_zod14.z.string().min(6),
|
|
4189
|
+
practitionerId: import_zod14.z.string().min(1),
|
|
4190
|
+
email: import_zod14.z.string().email(),
|
|
4191
|
+
clinicId: import_zod14.z.string().min(1),
|
|
4192
|
+
status: import_zod14.z.nativeEnum(PractitionerTokenStatus),
|
|
4193
|
+
createdBy: import_zod14.z.string().min(1),
|
|
4194
|
+
createdAt: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date()),
|
|
4195
|
+
expiresAt: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date()),
|
|
4196
|
+
usedBy: import_zod14.z.string().optional(),
|
|
4197
|
+
usedAt: import_zod14.z.instanceof(import_firestore15.Timestamp).or(import_zod14.z.date()).optional()
|
|
4176
4198
|
});
|
|
4177
|
-
var createPractitionerTokenSchema =
|
|
4178
|
-
practitionerId:
|
|
4179
|
-
email:
|
|
4180
|
-
clinicId:
|
|
4181
|
-
expiresAt:
|
|
4199
|
+
var createPractitionerTokenSchema = import_zod14.z.object({
|
|
4200
|
+
practitionerId: import_zod14.z.string().min(1),
|
|
4201
|
+
email: import_zod14.z.string().email(),
|
|
4202
|
+
clinicId: import_zod14.z.string().min(1),
|
|
4203
|
+
expiresAt: import_zod14.z.date().optional()
|
|
4182
4204
|
});
|
|
4183
|
-
var practitionerSignupSchema =
|
|
4184
|
-
email:
|
|
4185
|
-
password:
|
|
4186
|
-
firstName:
|
|
4187
|
-
lastName:
|
|
4188
|
-
token:
|
|
4189
|
-
profileData:
|
|
4190
|
-
basicInfo:
|
|
4191
|
-
phoneNumber:
|
|
4192
|
-
profileImageUrl:
|
|
4193
|
-
gender:
|
|
4194
|
-
bio:
|
|
4205
|
+
var practitionerSignupSchema = import_zod14.z.object({
|
|
4206
|
+
email: import_zod14.z.string().email(),
|
|
4207
|
+
password: import_zod14.z.string().min(8),
|
|
4208
|
+
firstName: import_zod14.z.string().min(2).max(50).optional(),
|
|
4209
|
+
lastName: import_zod14.z.string().min(2).max(50).optional(),
|
|
4210
|
+
token: import_zod14.z.string().optional(),
|
|
4211
|
+
profileData: import_zod14.z.object({
|
|
4212
|
+
basicInfo: import_zod14.z.object({
|
|
4213
|
+
phoneNumber: import_zod14.z.string().optional(),
|
|
4214
|
+
profileImageUrl: import_zod14.z.string().optional(),
|
|
4215
|
+
gender: import_zod14.z.enum(["male", "female", "other"]).optional(),
|
|
4216
|
+
bio: import_zod14.z.string().optional()
|
|
4195
4217
|
}).optional(),
|
|
4196
|
-
certification:
|
|
4218
|
+
certification: import_zod14.z.any().optional()
|
|
4197
4219
|
}).optional()
|
|
4198
4220
|
});
|
|
4199
4221
|
|
|
4200
4222
|
// src/services/practitioner/practitioner.service.ts
|
|
4201
|
-
var
|
|
4223
|
+
var import_zod15 = require("zod");
|
|
4202
4224
|
var import_geofire_common2 = require("geofire-common");
|
|
4203
4225
|
var PractitionerService = class extends BaseService {
|
|
4204
4226
|
constructor(db, auth, app, clinicService) {
|
|
@@ -4267,7 +4289,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4267
4289
|
}
|
|
4268
4290
|
return createdPractitioner;
|
|
4269
4291
|
} catch (error) {
|
|
4270
|
-
if (error instanceof
|
|
4292
|
+
if (error instanceof import_zod15.z.ZodError) {
|
|
4271
4293
|
throw new Error(`Invalid practitioner data: ${error.message}`);
|
|
4272
4294
|
}
|
|
4273
4295
|
console.error("Error creating practitioner:", error);
|
|
@@ -4380,7 +4402,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4380
4402
|
await (0, import_firestore16.setDoc)((0, import_firestore16.doc)(this.db, tokenPath), token);
|
|
4381
4403
|
return { practitioner: savedPractitioner, token };
|
|
4382
4404
|
} catch (error) {
|
|
4383
|
-
if (error instanceof
|
|
4405
|
+
if (error instanceof import_zod15.z.ZodError) {
|
|
4384
4406
|
throw new Error("Invalid practitioner data: " + error.message);
|
|
4385
4407
|
}
|
|
4386
4408
|
throw error;
|
|
@@ -4433,7 +4455,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4433
4455
|
await (0, import_firestore16.setDoc)((0, import_firestore16.doc)(this.db, tokenPath), token);
|
|
4434
4456
|
return token;
|
|
4435
4457
|
} catch (error) {
|
|
4436
|
-
if (error instanceof
|
|
4458
|
+
if (error instanceof import_zod15.z.ZodError) {
|
|
4437
4459
|
throw new Error("Invalid token data: " + error.message);
|
|
4438
4460
|
}
|
|
4439
4461
|
throw error;
|
|
@@ -4620,7 +4642,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4620
4642
|
}
|
|
4621
4643
|
return updatedPractitioner;
|
|
4622
4644
|
} catch (error) {
|
|
4623
|
-
if (error instanceof
|
|
4645
|
+
if (error instanceof import_zod15.z.ZodError) {
|
|
4624
4646
|
throw new Error(`Invalid practitioner update data: ${error.message}`);
|
|
4625
4647
|
}
|
|
4626
4648
|
console.error(`Error updating practitioner ${practitionerId}:`, error);
|
|
@@ -5176,7 +5198,7 @@ var UserService = class extends BaseService {
|
|
|
5176
5198
|
});
|
|
5177
5199
|
return this.getUserById(uid);
|
|
5178
5200
|
} catch (error) {
|
|
5179
|
-
if (error instanceof
|
|
5201
|
+
if (error instanceof import_zod16.z.ZodError) {
|
|
5180
5202
|
throw USER_ERRORS.VALIDATION_ERROR;
|
|
5181
5203
|
}
|
|
5182
5204
|
throw error;
|
|
@@ -5263,7 +5285,7 @@ var UserService = class extends BaseService {
|
|
|
5263
5285
|
// src/services/clinic/utils/clinic-group.utils.ts
|
|
5264
5286
|
var import_firestore18 = require("firebase/firestore");
|
|
5265
5287
|
var import_geofire_common3 = require("geofire-common");
|
|
5266
|
-
var
|
|
5288
|
+
var import_zod17 = require("zod");
|
|
5267
5289
|
|
|
5268
5290
|
// src/services/clinic/utils/photos.utils.ts
|
|
5269
5291
|
var import_storage4 = require("firebase/storage");
|
|
@@ -5461,7 +5483,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
5461
5483
|
});
|
|
5462
5484
|
return groupData;
|
|
5463
5485
|
} catch (error) {
|
|
5464
|
-
if (error instanceof
|
|
5486
|
+
if (error instanceof import_zod17.z.ZodError) {
|
|
5465
5487
|
console.error(
|
|
5466
5488
|
"[CLINIC_GROUP] Zod validation error:",
|
|
5467
5489
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -5866,17 +5888,54 @@ var ClinicGroupService = class extends BaseService {
|
|
|
5866
5888
|
// but to add them to a subcollection called adminTokens that belongs to a specific clinicGroup document
|
|
5867
5889
|
// TODO: Add granular control over admin permissions, e.g. only allow admins to manage certain clinics to tokens directly
|
|
5868
5890
|
// TODO: Generally refactor admin tokens and invites, also create cloud function to send invites and send updates when sombody uses the token
|
|
5891
|
+
/**
|
|
5892
|
+
* Updates the onboarding status for a clinic group
|
|
5893
|
+
*
|
|
5894
|
+
* @param groupId - The ID of the clinic group to update
|
|
5895
|
+
* @param onboardingData - The onboarding data to update
|
|
5896
|
+
* @returns The updated clinic group
|
|
5897
|
+
*/
|
|
5898
|
+
async setOnboarding(groupId, onboardingData) {
|
|
5899
|
+
console.log("[CLINIC_GROUP] Updating onboarding status", {
|
|
5900
|
+
groupId,
|
|
5901
|
+
onboardingData
|
|
5902
|
+
});
|
|
5903
|
+
return this.updateClinicGroup(groupId, {
|
|
5904
|
+
onboarding: onboardingData
|
|
5905
|
+
});
|
|
5906
|
+
}
|
|
5907
|
+
/**
|
|
5908
|
+
* Sets the current onboarding step for a clinic group
|
|
5909
|
+
*
|
|
5910
|
+
* @param groupId - The ID of the clinic group to update
|
|
5911
|
+
* @param step - The current onboarding step number
|
|
5912
|
+
* @returns The updated clinic group
|
|
5913
|
+
*/
|
|
5914
|
+
async setOnboardingStep(groupId, step) {
|
|
5915
|
+
console.log("[CLINIC_GROUP] Setting onboarding step", { groupId, step });
|
|
5916
|
+
return this.setOnboarding(groupId, { step, completed: false });
|
|
5917
|
+
}
|
|
5918
|
+
/**
|
|
5919
|
+
* Marks the onboarding process as completed for a clinic group
|
|
5920
|
+
*
|
|
5921
|
+
* @param groupId - The ID of the clinic group to update
|
|
5922
|
+
* @returns The updated clinic group
|
|
5923
|
+
*/
|
|
5924
|
+
async completeOnboarding(groupId) {
|
|
5925
|
+
console.log("[CLINIC_GROUP] Completing onboarding", { groupId });
|
|
5926
|
+
return this.setOnboarding(groupId, { completed: true });
|
|
5927
|
+
}
|
|
5869
5928
|
};
|
|
5870
5929
|
|
|
5871
5930
|
// src/services/clinic/clinic.service.ts
|
|
5872
5931
|
var import_firestore24 = require("firebase/firestore");
|
|
5873
5932
|
var import_geofire_common7 = require("geofire-common");
|
|
5874
|
-
var
|
|
5933
|
+
var import_zod19 = require("zod");
|
|
5875
5934
|
|
|
5876
5935
|
// src/services/clinic/utils/clinic.utils.ts
|
|
5877
5936
|
var import_firestore19 = require("firebase/firestore");
|
|
5878
5937
|
var import_geofire_common4 = require("geofire-common");
|
|
5879
|
-
var
|
|
5938
|
+
var import_zod18 = require("zod");
|
|
5880
5939
|
async function getClinic(db, clinicId) {
|
|
5881
5940
|
const docRef = (0, import_firestore19.doc)(db, CLINICS_COLLECTION, clinicId);
|
|
5882
5941
|
const docSnap = await (0, import_firestore19.getDoc)(docRef);
|
|
@@ -6477,6 +6536,12 @@ async function getClinicsByFilters(db, filters) {
|
|
|
6477
6536
|
var import_firestore22 = require("firebase/firestore");
|
|
6478
6537
|
var import_storage5 = require("firebase/storage");
|
|
6479
6538
|
var import_firestore23 = require("firebase/firestore");
|
|
6539
|
+
var MediaAccessLevel = /* @__PURE__ */ ((MediaAccessLevel2) => {
|
|
6540
|
+
MediaAccessLevel2["PUBLIC"] = "public";
|
|
6541
|
+
MediaAccessLevel2["PRIVATE"] = "private";
|
|
6542
|
+
MediaAccessLevel2["CONFIDENTIAL"] = "confidential";
|
|
6543
|
+
return MediaAccessLevel2;
|
|
6544
|
+
})(MediaAccessLevel || {});
|
|
6480
6545
|
var MEDIA_METADATA_COLLECTION = "media_metadata";
|
|
6481
6546
|
var MediaService = class extends BaseService {
|
|
6482
6547
|
constructor(db, auth, app) {
|
|
@@ -6932,7 +6997,7 @@ var ClinicService = class extends BaseService {
|
|
|
6932
6997
|
if (!savedClinic) throw new Error("Failed to retrieve created clinic");
|
|
6933
6998
|
return savedClinic;
|
|
6934
6999
|
} catch (error) {
|
|
6935
|
-
if (error instanceof
|
|
7000
|
+
if (error instanceof import_zod19.z.ZodError) {
|
|
6936
7001
|
throw new Error("Invalid clinic data: " + error.message);
|
|
6937
7002
|
}
|
|
6938
7003
|
console.error("Error creating clinic:", error);
|
|
@@ -7012,7 +7077,7 @@ var ClinicService = class extends BaseService {
|
|
|
7012
7077
|
if (!updatedClinic) throw new Error("Failed to retrieve updated clinic");
|
|
7013
7078
|
return updatedClinic;
|
|
7014
7079
|
} catch (error) {
|
|
7015
|
-
if (error instanceof
|
|
7080
|
+
if (error instanceof import_zod19.z.ZodError) {
|
|
7016
7081
|
throw new Error("Invalid clinic update data: " + error.message);
|
|
7017
7082
|
}
|
|
7018
7083
|
console.error(`Error updating clinic ${clinicId}:`, error);
|
|
@@ -7029,6 +7094,16 @@ var ClinicService = class extends BaseService {
|
|
|
7029
7094
|
updatedAt: (0, import_firestore24.serverTimestamp)()
|
|
7030
7095
|
});
|
|
7031
7096
|
}
|
|
7097
|
+
/**
|
|
7098
|
+
* Activates a clinic.
|
|
7099
|
+
*/
|
|
7100
|
+
async activateClinic(clinicId, adminId) {
|
|
7101
|
+
const clinicRef = (0, import_firestore24.doc)(this.db, CLINICS_COLLECTION, clinicId);
|
|
7102
|
+
await (0, import_firestore24.updateDoc)(clinicRef, {
|
|
7103
|
+
isActive: true,
|
|
7104
|
+
updatedAt: (0, import_firestore24.serverTimestamp)()
|
|
7105
|
+
});
|
|
7106
|
+
}
|
|
7032
7107
|
/**
|
|
7033
7108
|
* Dohvata kliniku po ID-u
|
|
7034
7109
|
*/
|
|
@@ -7334,7 +7409,11 @@ var AuthService = class extends BaseService {
|
|
|
7334
7409
|
// Use admin profile ID, not user UID
|
|
7335
7410
|
isActive: true,
|
|
7336
7411
|
logo: data.clinicGroupData.logo || null,
|
|
7337
|
-
subscriptionModel: data.clinicGroupData.subscriptionModel || "no_subscription" /* NO_SUBSCRIPTION
|
|
7412
|
+
subscriptionModel: data.clinicGroupData.subscriptionModel || "no_subscription" /* NO_SUBSCRIPTION */,
|
|
7413
|
+
onboarding: {
|
|
7414
|
+
completed: false,
|
|
7415
|
+
step: 1
|
|
7416
|
+
}
|
|
7338
7417
|
};
|
|
7339
7418
|
console.log("[AUTH] Clinic group data prepared", {
|
|
7340
7419
|
groupName: createClinicGroupData.name
|
|
@@ -7474,7 +7553,7 @@ var AuthService = class extends BaseService {
|
|
|
7474
7553
|
clinicAdmin: adminProfile
|
|
7475
7554
|
};
|
|
7476
7555
|
} catch (error) {
|
|
7477
|
-
if (error instanceof
|
|
7556
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7478
7557
|
console.error(
|
|
7479
7558
|
"[AUTH] Zod validation error in signUpClinicAdmin:",
|
|
7480
7559
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -7649,7 +7728,7 @@ var AuthService = class extends BaseService {
|
|
|
7649
7728
|
email
|
|
7650
7729
|
);
|
|
7651
7730
|
} catch (error) {
|
|
7652
|
-
if (error instanceof
|
|
7731
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7653
7732
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7654
7733
|
}
|
|
7655
7734
|
const firebaseError = error;
|
|
@@ -7772,7 +7851,7 @@ var AuthService = class extends BaseService {
|
|
|
7772
7851
|
await emailSchema.parseAsync(email);
|
|
7773
7852
|
await (0, import_auth5.sendPasswordResetEmail)(this.auth, email);
|
|
7774
7853
|
} catch (error) {
|
|
7775
|
-
if (error instanceof
|
|
7854
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7776
7855
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7777
7856
|
}
|
|
7778
7857
|
const firebaseError = error;
|
|
@@ -7811,7 +7890,7 @@ var AuthService = class extends BaseService {
|
|
|
7811
7890
|
await passwordSchema.parseAsync(newPassword);
|
|
7812
7891
|
await (0, import_auth5.confirmPasswordReset)(this.auth, oobCode, newPassword);
|
|
7813
7892
|
} catch (error) {
|
|
7814
|
-
if (error instanceof
|
|
7893
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7815
7894
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7816
7895
|
}
|
|
7817
7896
|
const firebaseError = error;
|
|
@@ -7980,7 +8059,7 @@ var AuthService = class extends BaseService {
|
|
|
7980
8059
|
practitioner
|
|
7981
8060
|
};
|
|
7982
8061
|
} catch (error) {
|
|
7983
|
-
if (error instanceof
|
|
8062
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7984
8063
|
console.error(
|
|
7985
8064
|
"[AUTH] Zod validation error in signUpPractitioner:",
|
|
7986
8065
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -8258,63 +8337,63 @@ var import_firestore27 = require("firebase/firestore");
|
|
|
8258
8337
|
var PROCEDURES_COLLECTION = "procedures";
|
|
8259
8338
|
|
|
8260
8339
|
// src/validations/procedure.schema.ts
|
|
8261
|
-
var
|
|
8262
|
-
var createProcedureSchema =
|
|
8263
|
-
name:
|
|
8264
|
-
description:
|
|
8265
|
-
family:
|
|
8266
|
-
categoryId:
|
|
8267
|
-
subcategoryId:
|
|
8268
|
-
technologyId:
|
|
8269
|
-
productId:
|
|
8270
|
-
price:
|
|
8271
|
-
currency:
|
|
8272
|
-
pricingMeasure:
|
|
8273
|
-
duration:
|
|
8340
|
+
var import_zod21 = require("zod");
|
|
8341
|
+
var createProcedureSchema = import_zod21.z.object({
|
|
8342
|
+
name: import_zod21.z.string().min(1).max(200),
|
|
8343
|
+
description: import_zod21.z.string().min(1).max(2e3),
|
|
8344
|
+
family: import_zod21.z.nativeEnum(ProcedureFamily),
|
|
8345
|
+
categoryId: import_zod21.z.string().min(1),
|
|
8346
|
+
subcategoryId: import_zod21.z.string().min(1),
|
|
8347
|
+
technologyId: import_zod21.z.string().min(1),
|
|
8348
|
+
productId: import_zod21.z.string().min(1),
|
|
8349
|
+
price: import_zod21.z.number().min(0),
|
|
8350
|
+
currency: import_zod21.z.nativeEnum(Currency),
|
|
8351
|
+
pricingMeasure: import_zod21.z.nativeEnum(PricingMeasure),
|
|
8352
|
+
duration: import_zod21.z.number().min(1).max(480),
|
|
8274
8353
|
// Max 8 hours
|
|
8275
|
-
practitionerId:
|
|
8276
|
-
clinicBranchId:
|
|
8277
|
-
photos:
|
|
8354
|
+
practitionerId: import_zod21.z.string().min(1),
|
|
8355
|
+
clinicBranchId: import_zod21.z.string().min(1),
|
|
8356
|
+
photos: import_zod21.z.array(import_zod21.z.string()).optional()
|
|
8278
8357
|
});
|
|
8279
|
-
var updateProcedureSchema =
|
|
8280
|
-
name:
|
|
8281
|
-
description:
|
|
8282
|
-
price:
|
|
8283
|
-
currency:
|
|
8284
|
-
pricingMeasure:
|
|
8285
|
-
duration:
|
|
8286
|
-
isActive:
|
|
8287
|
-
practitionerId:
|
|
8288
|
-
categoryId:
|
|
8289
|
-
subcategoryId:
|
|
8290
|
-
technologyId:
|
|
8291
|
-
productId:
|
|
8292
|
-
clinicBranchId:
|
|
8293
|
-
photos:
|
|
8358
|
+
var updateProcedureSchema = import_zod21.z.object({
|
|
8359
|
+
name: import_zod21.z.string().min(3).max(100).optional(),
|
|
8360
|
+
description: import_zod21.z.string().min(3).max(1e3).optional(),
|
|
8361
|
+
price: import_zod21.z.number().min(0).optional(),
|
|
8362
|
+
currency: import_zod21.z.nativeEnum(Currency).optional(),
|
|
8363
|
+
pricingMeasure: import_zod21.z.nativeEnum(PricingMeasure).optional(),
|
|
8364
|
+
duration: import_zod21.z.number().min(0).optional(),
|
|
8365
|
+
isActive: import_zod21.z.boolean().optional(),
|
|
8366
|
+
practitionerId: import_zod21.z.string().optional(),
|
|
8367
|
+
categoryId: import_zod21.z.string().optional(),
|
|
8368
|
+
subcategoryId: import_zod21.z.string().optional(),
|
|
8369
|
+
technologyId: import_zod21.z.string().optional(),
|
|
8370
|
+
productId: import_zod21.z.string().optional(),
|
|
8371
|
+
clinicBranchId: import_zod21.z.string().optional(),
|
|
8372
|
+
photos: import_zod21.z.array(import_zod21.z.string()).optional()
|
|
8294
8373
|
});
|
|
8295
8374
|
var procedureSchema = createProcedureSchema.extend({
|
|
8296
|
-
id:
|
|
8297
|
-
category:
|
|
8375
|
+
id: import_zod21.z.string().min(1),
|
|
8376
|
+
category: import_zod21.z.any(),
|
|
8298
8377
|
// We'll validate the full category object separately
|
|
8299
|
-
subcategory:
|
|
8378
|
+
subcategory: import_zod21.z.any(),
|
|
8300
8379
|
// We'll validate the full subcategory object separately
|
|
8301
|
-
technology:
|
|
8380
|
+
technology: import_zod21.z.any(),
|
|
8302
8381
|
// We'll validate the full technology object separately
|
|
8303
|
-
product:
|
|
8382
|
+
product: import_zod21.z.any(),
|
|
8304
8383
|
// We'll validate the full product object separately
|
|
8305
|
-
blockingConditions:
|
|
8384
|
+
blockingConditions: import_zod21.z.array(import_zod21.z.any()),
|
|
8306
8385
|
// We'll validate blocking conditions separately
|
|
8307
|
-
contraindications:
|
|
8386
|
+
contraindications: import_zod21.z.array(import_zod21.z.any()),
|
|
8308
8387
|
// We'll validate contraindications separately
|
|
8309
|
-
treatmentBenefits:
|
|
8388
|
+
treatmentBenefits: import_zod21.z.array(import_zod21.z.any()),
|
|
8310
8389
|
// We'll validate treatment benefits separately
|
|
8311
|
-
preRequirements:
|
|
8390
|
+
preRequirements: import_zod21.z.array(import_zod21.z.any()),
|
|
8312
8391
|
// We'll validate requirements separately
|
|
8313
|
-
postRequirements:
|
|
8392
|
+
postRequirements: import_zod21.z.array(import_zod21.z.any()),
|
|
8314
8393
|
// We'll validate requirements separately
|
|
8315
|
-
certificationRequirement:
|
|
8394
|
+
certificationRequirement: import_zod21.z.any(),
|
|
8316
8395
|
// We'll validate certification requirement separately
|
|
8317
|
-
documentationTemplates:
|
|
8396
|
+
documentationTemplates: import_zod21.z.array(import_zod21.z.any()),
|
|
8318
8397
|
// We'll validate documentation templates separately
|
|
8319
8398
|
clinicInfo: clinicInfoSchema,
|
|
8320
8399
|
// Clinic info validation
|
|
@@ -8322,9 +8401,9 @@ var procedureSchema = createProcedureSchema.extend({
|
|
|
8322
8401
|
// Doctor info validation
|
|
8323
8402
|
reviewInfo: procedureReviewInfoSchema,
|
|
8324
8403
|
// Procedure review info validation
|
|
8325
|
-
isActive:
|
|
8326
|
-
createdAt:
|
|
8327
|
-
updatedAt:
|
|
8404
|
+
isActive: import_zod21.z.boolean(),
|
|
8405
|
+
createdAt: import_zod21.z.date(),
|
|
8406
|
+
updatedAt: import_zod21.z.date()
|
|
8328
8407
|
});
|
|
8329
8408
|
|
|
8330
8409
|
// src/services/procedure/procedure.service.ts
|
|
@@ -9499,42 +9578,42 @@ var SYNCED_CALENDARS_COLLECTION = "syncedCalendars";
|
|
|
9499
9578
|
var import_firestore40 = require("firebase/firestore");
|
|
9500
9579
|
|
|
9501
9580
|
// src/validations/calendar.schema.ts
|
|
9502
|
-
var
|
|
9581
|
+
var import_zod23 = require("zod");
|
|
9503
9582
|
var import_firestore31 = require("firebase/firestore");
|
|
9504
9583
|
|
|
9505
9584
|
// src/validations/profile-info.schema.ts
|
|
9506
|
-
var
|
|
9585
|
+
var import_zod22 = require("zod");
|
|
9507
9586
|
var import_firestore30 = require("firebase/firestore");
|
|
9508
|
-
var clinicInfoSchema2 =
|
|
9509
|
-
id:
|
|
9510
|
-
featuredPhoto:
|
|
9511
|
-
name:
|
|
9512
|
-
description:
|
|
9587
|
+
var clinicInfoSchema2 = import_zod22.z.object({
|
|
9588
|
+
id: import_zod22.z.string(),
|
|
9589
|
+
featuredPhoto: import_zod22.z.string(),
|
|
9590
|
+
name: import_zod22.z.string(),
|
|
9591
|
+
description: import_zod22.z.string(),
|
|
9513
9592
|
location: clinicLocationSchema,
|
|
9514
9593
|
contactInfo: clinicContactInfoSchema
|
|
9515
9594
|
});
|
|
9516
|
-
var practitionerProfileInfoSchema =
|
|
9517
|
-
id:
|
|
9518
|
-
practitionerPhoto:
|
|
9519
|
-
name:
|
|
9520
|
-
email:
|
|
9521
|
-
phone:
|
|
9595
|
+
var practitionerProfileInfoSchema = import_zod22.z.object({
|
|
9596
|
+
id: import_zod22.z.string(),
|
|
9597
|
+
practitionerPhoto: import_zod22.z.string().nullable(),
|
|
9598
|
+
name: import_zod22.z.string(),
|
|
9599
|
+
email: import_zod22.z.string().email(),
|
|
9600
|
+
phone: import_zod22.z.string().nullable(),
|
|
9522
9601
|
certification: practitionerCertificationSchema
|
|
9523
9602
|
});
|
|
9524
|
-
var patientProfileInfoSchema =
|
|
9525
|
-
id:
|
|
9526
|
-
fullName:
|
|
9527
|
-
email:
|
|
9528
|
-
phone:
|
|
9529
|
-
dateOfBirth:
|
|
9530
|
-
gender:
|
|
9603
|
+
var patientProfileInfoSchema = import_zod22.z.object({
|
|
9604
|
+
id: import_zod22.z.string(),
|
|
9605
|
+
fullName: import_zod22.z.string(),
|
|
9606
|
+
email: import_zod22.z.string().email(),
|
|
9607
|
+
phone: import_zod22.z.string().nullable(),
|
|
9608
|
+
dateOfBirth: import_zod22.z.instanceof(import_firestore30.Timestamp),
|
|
9609
|
+
gender: import_zod22.z.nativeEnum(Gender)
|
|
9531
9610
|
});
|
|
9532
9611
|
|
|
9533
9612
|
// src/validations/calendar.schema.ts
|
|
9534
9613
|
var MIN_APPOINTMENT_DURATION = 15;
|
|
9535
|
-
var calendarEventTimeSchema =
|
|
9536
|
-
start:
|
|
9537
|
-
end:
|
|
9614
|
+
var calendarEventTimeSchema = import_zod23.z.object({
|
|
9615
|
+
start: import_zod23.z.instanceof(Date).or(import_zod23.z.instanceof(import_firestore31.Timestamp)),
|
|
9616
|
+
end: import_zod23.z.instanceof(Date).or(import_zod23.z.instanceof(import_firestore31.Timestamp))
|
|
9538
9617
|
}).refine(
|
|
9539
9618
|
(data) => {
|
|
9540
9619
|
const startDate = data.start instanceof import_firestore31.Timestamp ? data.start.toDate() : data.start;
|
|
@@ -9555,46 +9634,46 @@ var calendarEventTimeSchema = import_zod22.z.object({
|
|
|
9555
9634
|
path: ["start"]
|
|
9556
9635
|
}
|
|
9557
9636
|
);
|
|
9558
|
-
var timeSlotSchema2 =
|
|
9559
|
-
start:
|
|
9560
|
-
end:
|
|
9561
|
-
isAvailable:
|
|
9637
|
+
var timeSlotSchema2 = import_zod23.z.object({
|
|
9638
|
+
start: import_zod23.z.date(),
|
|
9639
|
+
end: import_zod23.z.date(),
|
|
9640
|
+
isAvailable: import_zod23.z.boolean()
|
|
9562
9641
|
}).refine((data) => data.start < data.end, {
|
|
9563
9642
|
message: "End time must be after start time",
|
|
9564
9643
|
path: ["end"]
|
|
9565
9644
|
});
|
|
9566
|
-
var syncedCalendarEventSchema =
|
|
9567
|
-
eventId:
|
|
9568
|
-
syncedCalendarProvider:
|
|
9569
|
-
syncedAt:
|
|
9645
|
+
var syncedCalendarEventSchema = import_zod23.z.object({
|
|
9646
|
+
eventId: import_zod23.z.string(),
|
|
9647
|
+
syncedCalendarProvider: import_zod23.z.nativeEnum(SyncedCalendarProvider),
|
|
9648
|
+
syncedAt: import_zod23.z.instanceof(Date).or(import_zod23.z.instanceof(import_firestore31.Timestamp))
|
|
9570
9649
|
});
|
|
9571
|
-
var procedureInfoSchema =
|
|
9572
|
-
name:
|
|
9573
|
-
description:
|
|
9574
|
-
duration:
|
|
9575
|
-
price:
|
|
9576
|
-
currency:
|
|
9650
|
+
var procedureInfoSchema = import_zod23.z.object({
|
|
9651
|
+
name: import_zod23.z.string(),
|
|
9652
|
+
description: import_zod23.z.string(),
|
|
9653
|
+
duration: import_zod23.z.number().min(MIN_APPOINTMENT_DURATION),
|
|
9654
|
+
price: import_zod23.z.number().min(0),
|
|
9655
|
+
currency: import_zod23.z.nativeEnum(Currency)
|
|
9577
9656
|
});
|
|
9578
|
-
var procedureCategorizationSchema =
|
|
9579
|
-
procedureFamily:
|
|
9657
|
+
var procedureCategorizationSchema = import_zod23.z.object({
|
|
9658
|
+
procedureFamily: import_zod23.z.string(),
|
|
9580
9659
|
// Replace with proper enum when available
|
|
9581
|
-
procedureCategory:
|
|
9660
|
+
procedureCategory: import_zod23.z.string(),
|
|
9582
9661
|
// Replace with proper enum when available
|
|
9583
|
-
procedureSubcategory:
|
|
9662
|
+
procedureSubcategory: import_zod23.z.string(),
|
|
9584
9663
|
// Replace with proper enum when available
|
|
9585
|
-
procedureTechnology:
|
|
9664
|
+
procedureTechnology: import_zod23.z.string(),
|
|
9586
9665
|
// Replace with proper enum when available
|
|
9587
|
-
procedureProduct:
|
|
9666
|
+
procedureProduct: import_zod23.z.string()
|
|
9588
9667
|
// Replace with proper enum when available
|
|
9589
9668
|
});
|
|
9590
|
-
var createAppointmentSchema2 =
|
|
9591
|
-
clinicId:
|
|
9592
|
-
doctorId:
|
|
9593
|
-
patientId:
|
|
9594
|
-
procedureId:
|
|
9669
|
+
var createAppointmentSchema2 = import_zod23.z.object({
|
|
9670
|
+
clinicId: import_zod23.z.string().min(1, "Clinic ID is required"),
|
|
9671
|
+
doctorId: import_zod23.z.string().min(1, "Doctor ID is required"),
|
|
9672
|
+
patientId: import_zod23.z.string().min(1, "Patient ID is required"),
|
|
9673
|
+
procedureId: import_zod23.z.string().min(1, "Procedure ID is required"),
|
|
9595
9674
|
eventLocation: clinicLocationSchema,
|
|
9596
9675
|
eventTime: calendarEventTimeSchema,
|
|
9597
|
-
description:
|
|
9676
|
+
description: import_zod23.z.string().optional()
|
|
9598
9677
|
}).refine(
|
|
9599
9678
|
(data) => {
|
|
9600
9679
|
return true;
|
|
@@ -9603,73 +9682,73 @@ var createAppointmentSchema2 = import_zod22.z.object({
|
|
|
9603
9682
|
message: "Invalid appointment parameters"
|
|
9604
9683
|
}
|
|
9605
9684
|
);
|
|
9606
|
-
var updateAppointmentSchema2 =
|
|
9607
|
-
appointmentId:
|
|
9608
|
-
clinicId:
|
|
9609
|
-
doctorId:
|
|
9610
|
-
patientId:
|
|
9685
|
+
var updateAppointmentSchema2 = import_zod23.z.object({
|
|
9686
|
+
appointmentId: import_zod23.z.string().min(1, "Appointment ID is required"),
|
|
9687
|
+
clinicId: import_zod23.z.string().min(1, "Clinic ID is required"),
|
|
9688
|
+
doctorId: import_zod23.z.string().min(1, "Doctor ID is required"),
|
|
9689
|
+
patientId: import_zod23.z.string().min(1, "Patient ID is required"),
|
|
9611
9690
|
eventTime: calendarEventTimeSchema.optional(),
|
|
9612
|
-
description:
|
|
9613
|
-
status:
|
|
9691
|
+
description: import_zod23.z.string().optional(),
|
|
9692
|
+
status: import_zod23.z.nativeEnum(CalendarEventStatus).optional()
|
|
9614
9693
|
});
|
|
9615
|
-
var createCalendarEventSchema =
|
|
9616
|
-
id:
|
|
9617
|
-
clinicBranchId:
|
|
9618
|
-
clinicBranchInfo:
|
|
9619
|
-
practitionerProfileId:
|
|
9694
|
+
var createCalendarEventSchema = import_zod23.z.object({
|
|
9695
|
+
id: import_zod23.z.string(),
|
|
9696
|
+
clinicBranchId: import_zod23.z.string().nullable().optional(),
|
|
9697
|
+
clinicBranchInfo: import_zod23.z.any().nullable().optional(),
|
|
9698
|
+
practitionerProfileId: import_zod23.z.string().nullable().optional(),
|
|
9620
9699
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
9621
|
-
patientProfileId:
|
|
9700
|
+
patientProfileId: import_zod23.z.string().nullable().optional(),
|
|
9622
9701
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
9623
|
-
procedureId:
|
|
9624
|
-
appointmentId:
|
|
9625
|
-
syncedCalendarEventId:
|
|
9626
|
-
eventName:
|
|
9702
|
+
procedureId: import_zod23.z.string().nullable().optional(),
|
|
9703
|
+
appointmentId: import_zod23.z.string().nullable().optional(),
|
|
9704
|
+
syncedCalendarEventId: import_zod23.z.array(syncedCalendarEventSchema).nullable().optional(),
|
|
9705
|
+
eventName: import_zod23.z.string().min(1, "Event name is required"),
|
|
9627
9706
|
eventLocation: clinicLocationSchema.optional(),
|
|
9628
9707
|
eventTime: calendarEventTimeSchema,
|
|
9629
|
-
description:
|
|
9630
|
-
status:
|
|
9631
|
-
syncStatus:
|
|
9632
|
-
eventType:
|
|
9633
|
-
createdAt:
|
|
9708
|
+
description: import_zod23.z.string().optional(),
|
|
9709
|
+
status: import_zod23.z.nativeEnum(CalendarEventStatus),
|
|
9710
|
+
syncStatus: import_zod23.z.nativeEnum(CalendarSyncStatus),
|
|
9711
|
+
eventType: import_zod23.z.nativeEnum(CalendarEventType),
|
|
9712
|
+
createdAt: import_zod23.z.any(),
|
|
9634
9713
|
// FieldValue for server timestamp
|
|
9635
|
-
updatedAt:
|
|
9714
|
+
updatedAt: import_zod23.z.any()
|
|
9636
9715
|
// FieldValue for server timestamp
|
|
9637
9716
|
});
|
|
9638
|
-
var updateCalendarEventSchema =
|
|
9639
|
-
syncedCalendarEventId:
|
|
9640
|
-
appointmentId:
|
|
9641
|
-
eventName:
|
|
9717
|
+
var updateCalendarEventSchema = import_zod23.z.object({
|
|
9718
|
+
syncedCalendarEventId: import_zod23.z.array(syncedCalendarEventSchema).nullable().optional(),
|
|
9719
|
+
appointmentId: import_zod23.z.string().nullable().optional(),
|
|
9720
|
+
eventName: import_zod23.z.string().optional(),
|
|
9642
9721
|
eventTime: calendarEventTimeSchema.optional(),
|
|
9643
|
-
description:
|
|
9644
|
-
status:
|
|
9645
|
-
syncStatus:
|
|
9646
|
-
eventType:
|
|
9647
|
-
updatedAt:
|
|
9722
|
+
description: import_zod23.z.string().optional(),
|
|
9723
|
+
status: import_zod23.z.nativeEnum(CalendarEventStatus).optional(),
|
|
9724
|
+
syncStatus: import_zod23.z.nativeEnum(CalendarSyncStatus).optional(),
|
|
9725
|
+
eventType: import_zod23.z.nativeEnum(CalendarEventType).optional(),
|
|
9726
|
+
updatedAt: import_zod23.z.any()
|
|
9648
9727
|
// FieldValue for server timestamp
|
|
9649
9728
|
});
|
|
9650
|
-
var calendarEventSchema =
|
|
9651
|
-
id:
|
|
9652
|
-
clinicBranchId:
|
|
9653
|
-
clinicBranchInfo:
|
|
9729
|
+
var calendarEventSchema = import_zod23.z.object({
|
|
9730
|
+
id: import_zod23.z.string(),
|
|
9731
|
+
clinicBranchId: import_zod23.z.string().nullable().optional(),
|
|
9732
|
+
clinicBranchInfo: import_zod23.z.any().nullable().optional(),
|
|
9654
9733
|
// Will be replaced with proper clinic info schema
|
|
9655
|
-
practitionerProfileId:
|
|
9734
|
+
practitionerProfileId: import_zod23.z.string().nullable().optional(),
|
|
9656
9735
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
9657
|
-
patientProfileId:
|
|
9736
|
+
patientProfileId: import_zod23.z.string().nullable().optional(),
|
|
9658
9737
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
9659
|
-
procedureId:
|
|
9738
|
+
procedureId: import_zod23.z.string().nullable().optional(),
|
|
9660
9739
|
procedureInfo: procedureInfoSchema.nullable().optional(),
|
|
9661
9740
|
procedureCategorization: procedureCategorizationSchema.nullable().optional(),
|
|
9662
|
-
appointmentId:
|
|
9663
|
-
syncedCalendarEventId:
|
|
9664
|
-
eventName:
|
|
9741
|
+
appointmentId: import_zod23.z.string().nullable().optional(),
|
|
9742
|
+
syncedCalendarEventId: import_zod23.z.array(syncedCalendarEventSchema).nullable().optional(),
|
|
9743
|
+
eventName: import_zod23.z.string(),
|
|
9665
9744
|
eventLocation: clinicLocationSchema.optional(),
|
|
9666
9745
|
eventTime: calendarEventTimeSchema,
|
|
9667
|
-
description:
|
|
9668
|
-
status:
|
|
9669
|
-
syncStatus:
|
|
9670
|
-
eventType:
|
|
9671
|
-
createdAt:
|
|
9672
|
-
updatedAt:
|
|
9746
|
+
description: import_zod23.z.string().optional(),
|
|
9747
|
+
status: import_zod23.z.nativeEnum(CalendarEventStatus),
|
|
9748
|
+
syncStatus: import_zod23.z.nativeEnum(CalendarSyncStatus),
|
|
9749
|
+
eventType: import_zod23.z.nativeEnum(CalendarEventType),
|
|
9750
|
+
createdAt: import_zod23.z.instanceof(Date).or(import_zod23.z.instanceof(import_firestore31.Timestamp)),
|
|
9751
|
+
updatedAt: import_zod23.z.instanceof(Date).or(import_zod23.z.instanceof(import_firestore31.Timestamp))
|
|
9673
9752
|
});
|
|
9674
9753
|
|
|
9675
9754
|
// src/services/calendar/utils/clinic.utils.ts
|
|
@@ -12209,13 +12288,13 @@ var import_firestore41 = require("firebase/firestore");
|
|
|
12209
12288
|
var REVIEWS_COLLECTION = "reviews";
|
|
12210
12289
|
|
|
12211
12290
|
// src/services/reviews/reviews.service.ts
|
|
12212
|
-
var
|
|
12291
|
+
var import_zod24 = require("zod");
|
|
12213
12292
|
var ReviewService = class extends BaseService {
|
|
12214
12293
|
constructor(db, auth, app) {
|
|
12215
12294
|
super(db, auth, app);
|
|
12216
12295
|
}
|
|
12217
12296
|
/**
|
|
12218
|
-
* Creates a new review
|
|
12297
|
+
* Creates a new review
|
|
12219
12298
|
* @param data - The review data to create
|
|
12220
12299
|
* @param appointmentId - ID of the completed appointment
|
|
12221
12300
|
* @returns The created review
|
|
@@ -12294,28 +12373,9 @@ var ReviewService = class extends BaseService {
|
|
|
12294
12373
|
createdAt: (0, import_firestore41.serverTimestamp)(),
|
|
12295
12374
|
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12296
12375
|
});
|
|
12297
|
-
const updatePromises = [];
|
|
12298
|
-
if (data.clinicReview) {
|
|
12299
|
-
updatePromises.push(
|
|
12300
|
-
this.updateClinicReviewInfo(data.clinicReview.clinicId)
|
|
12301
|
-
);
|
|
12302
|
-
}
|
|
12303
|
-
if (data.practitionerReview) {
|
|
12304
|
-
updatePromises.push(
|
|
12305
|
-
this.updatePractitionerReviewInfo(
|
|
12306
|
-
data.practitionerReview.practitionerId
|
|
12307
|
-
)
|
|
12308
|
-
);
|
|
12309
|
-
}
|
|
12310
|
-
if (data.procedureReview) {
|
|
12311
|
-
updatePromises.push(
|
|
12312
|
-
this.updateProcedureReviewInfo(data.procedureReview.procedureId)
|
|
12313
|
-
);
|
|
12314
|
-
}
|
|
12315
|
-
await Promise.all(updatePromises);
|
|
12316
12376
|
return review;
|
|
12317
12377
|
} catch (error) {
|
|
12318
|
-
if (error instanceof
|
|
12378
|
+
if (error instanceof import_zod24.z.ZodError) {
|
|
12319
12379
|
throw new Error(`Invalid review data: ${error.message}`);
|
|
12320
12380
|
}
|
|
12321
12381
|
throw error;
|
|
@@ -12403,7 +12463,7 @@ var ReviewService = class extends BaseService {
|
|
|
12403
12463
|
return snapshot.docs[0].data();
|
|
12404
12464
|
}
|
|
12405
12465
|
/**
|
|
12406
|
-
* Deletes a review
|
|
12466
|
+
* Deletes a review
|
|
12407
12467
|
* @param reviewId The ID of the review to delete
|
|
12408
12468
|
*/
|
|
12409
12469
|
async deleteReview(reviewId) {
|
|
@@ -12412,389 +12472,6 @@ var ReviewService = class extends BaseService {
|
|
|
12412
12472
|
throw new Error(`Review with ID ${reviewId} not found`);
|
|
12413
12473
|
}
|
|
12414
12474
|
await (0, import_firestore41.deleteDoc)((0, import_firestore41.doc)(this.db, REVIEWS_COLLECTION, reviewId));
|
|
12415
|
-
const updatePromises = [];
|
|
12416
|
-
if (review.clinicReview) {
|
|
12417
|
-
updatePromises.push(
|
|
12418
|
-
this.updateClinicReviewInfo(
|
|
12419
|
-
review.clinicReview.clinicId,
|
|
12420
|
-
review.clinicReview,
|
|
12421
|
-
true
|
|
12422
|
-
)
|
|
12423
|
-
);
|
|
12424
|
-
}
|
|
12425
|
-
if (review.practitionerReview) {
|
|
12426
|
-
updatePromises.push(
|
|
12427
|
-
this.updatePractitionerReviewInfo(
|
|
12428
|
-
review.practitionerReview.practitionerId,
|
|
12429
|
-
review.practitionerReview,
|
|
12430
|
-
true
|
|
12431
|
-
)
|
|
12432
|
-
);
|
|
12433
|
-
}
|
|
12434
|
-
if (review.procedureReview) {
|
|
12435
|
-
updatePromises.push(
|
|
12436
|
-
this.updateProcedureReviewInfo(
|
|
12437
|
-
review.procedureReview.procedureId,
|
|
12438
|
-
review.procedureReview,
|
|
12439
|
-
true
|
|
12440
|
-
)
|
|
12441
|
-
);
|
|
12442
|
-
}
|
|
12443
|
-
await Promise.all(updatePromises);
|
|
12444
|
-
}
|
|
12445
|
-
/**
|
|
12446
|
-
* Updates the review info for a clinic
|
|
12447
|
-
* @param clinicId The ID of the clinic to update
|
|
12448
|
-
* @param newReview Optional new review being added or removed
|
|
12449
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12450
|
-
* @returns The updated clinic review info
|
|
12451
|
-
*/
|
|
12452
|
-
async updateClinicReviewInfo(clinicId, newReview, isRemoval = false) {
|
|
12453
|
-
const clinicDoc = await (0, import_firestore41.getDoc)((0, import_firestore41.doc)(this.db, CLINICS_COLLECTION, clinicId));
|
|
12454
|
-
if (!clinicDoc.exists()) {
|
|
12455
|
-
throw new Error(`Clinic with ID ${clinicId} not found`);
|
|
12456
|
-
}
|
|
12457
|
-
const clinicData = clinicDoc.data();
|
|
12458
|
-
const currentReviewInfo = clinicData.reviewInfo || {
|
|
12459
|
-
totalReviews: 0,
|
|
12460
|
-
averageRating: 0,
|
|
12461
|
-
cleanliness: 0,
|
|
12462
|
-
facilities: 0,
|
|
12463
|
-
staffFriendliness: 0,
|
|
12464
|
-
waitingTime: 0,
|
|
12465
|
-
accessibility: 0,
|
|
12466
|
-
recommendationPercentage: 0
|
|
12467
|
-
};
|
|
12468
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12469
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, CLINICS_COLLECTION, clinicId), {
|
|
12470
|
-
reviewInfo: currentReviewInfo,
|
|
12471
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12472
|
-
});
|
|
12473
|
-
return currentReviewInfo;
|
|
12474
|
-
}
|
|
12475
|
-
let updatedReviewInfo;
|
|
12476
|
-
if (newReview) {
|
|
12477
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12478
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12479
|
-
if (newTotal === 0) {
|
|
12480
|
-
updatedReviewInfo = {
|
|
12481
|
-
totalReviews: 0,
|
|
12482
|
-
averageRating: 0,
|
|
12483
|
-
cleanliness: 0,
|
|
12484
|
-
facilities: 0,
|
|
12485
|
-
staffFriendliness: 0,
|
|
12486
|
-
waitingTime: 0,
|
|
12487
|
-
accessibility: 0,
|
|
12488
|
-
recommendationPercentage: 0
|
|
12489
|
-
};
|
|
12490
|
-
} else {
|
|
12491
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12492
|
-
const currentSum = currentAvg * oldTotal;
|
|
12493
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12494
|
-
const newAvg = newSum / newTotal;
|
|
12495
|
-
return Math.round(newAvg * 10) / 10;
|
|
12496
|
-
};
|
|
12497
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12498
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12499
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12500
|
-
updatedReviewInfo = {
|
|
12501
|
-
totalReviews: newTotal,
|
|
12502
|
-
averageRating: updateAverage(
|
|
12503
|
-
currentReviewInfo.averageRating,
|
|
12504
|
-
newReview.overallRating
|
|
12505
|
-
),
|
|
12506
|
-
cleanliness: updateAverage(
|
|
12507
|
-
currentReviewInfo.cleanliness,
|
|
12508
|
-
newReview.cleanliness
|
|
12509
|
-
),
|
|
12510
|
-
facilities: updateAverage(
|
|
12511
|
-
currentReviewInfo.facilities,
|
|
12512
|
-
newReview.facilities
|
|
12513
|
-
),
|
|
12514
|
-
staffFriendliness: updateAverage(
|
|
12515
|
-
currentReviewInfo.staffFriendliness,
|
|
12516
|
-
newReview.staffFriendliness
|
|
12517
|
-
),
|
|
12518
|
-
waitingTime: updateAverage(
|
|
12519
|
-
currentReviewInfo.waitingTime,
|
|
12520
|
-
newReview.waitingTime
|
|
12521
|
-
),
|
|
12522
|
-
accessibility: updateAverage(
|
|
12523
|
-
currentReviewInfo.accessibility,
|
|
12524
|
-
newReview.accessibility
|
|
12525
|
-
),
|
|
12526
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12527
|
-
};
|
|
12528
|
-
}
|
|
12529
|
-
} else {
|
|
12530
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12531
|
-
}
|
|
12532
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, CLINICS_COLLECTION, clinicId), {
|
|
12533
|
-
reviewInfo: updatedReviewInfo,
|
|
12534
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12535
|
-
});
|
|
12536
|
-
return updatedReviewInfo;
|
|
12537
|
-
}
|
|
12538
|
-
/**
|
|
12539
|
-
* Updates the review info for a practitioner
|
|
12540
|
-
* @param practitionerId The ID of the practitioner to update
|
|
12541
|
-
* @param newReview Optional new review being added or removed
|
|
12542
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12543
|
-
* @returns The updated practitioner review info
|
|
12544
|
-
*/
|
|
12545
|
-
async updatePractitionerReviewInfo(practitionerId, newReview, isRemoval = false) {
|
|
12546
|
-
const practitionerDoc = await (0, import_firestore41.getDoc)(
|
|
12547
|
-
(0, import_firestore41.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId)
|
|
12548
|
-
);
|
|
12549
|
-
if (!practitionerDoc.exists()) {
|
|
12550
|
-
throw new Error(`Practitioner with ID ${practitionerId} not found`);
|
|
12551
|
-
}
|
|
12552
|
-
const practitionerData = practitionerDoc.data();
|
|
12553
|
-
const currentReviewInfo = practitionerData.reviewInfo || {
|
|
12554
|
-
totalReviews: 0,
|
|
12555
|
-
averageRating: 0,
|
|
12556
|
-
knowledgeAndExpertise: 0,
|
|
12557
|
-
communicationSkills: 0,
|
|
12558
|
-
bedSideManner: 0,
|
|
12559
|
-
thoroughness: 0,
|
|
12560
|
-
trustworthiness: 0,
|
|
12561
|
-
recommendationPercentage: 0
|
|
12562
|
-
};
|
|
12563
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12564
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
12565
|
-
reviewInfo: currentReviewInfo,
|
|
12566
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12567
|
-
});
|
|
12568
|
-
return currentReviewInfo;
|
|
12569
|
-
}
|
|
12570
|
-
let updatedReviewInfo;
|
|
12571
|
-
if (newReview) {
|
|
12572
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12573
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12574
|
-
if (newTotal === 0) {
|
|
12575
|
-
updatedReviewInfo = {
|
|
12576
|
-
totalReviews: 0,
|
|
12577
|
-
averageRating: 0,
|
|
12578
|
-
knowledgeAndExpertise: 0,
|
|
12579
|
-
communicationSkills: 0,
|
|
12580
|
-
bedSideManner: 0,
|
|
12581
|
-
thoroughness: 0,
|
|
12582
|
-
trustworthiness: 0,
|
|
12583
|
-
recommendationPercentage: 0
|
|
12584
|
-
};
|
|
12585
|
-
} else {
|
|
12586
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12587
|
-
const currentSum = currentAvg * oldTotal;
|
|
12588
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12589
|
-
const newAvg = newSum / newTotal;
|
|
12590
|
-
return Math.round(newAvg * 10) / 10;
|
|
12591
|
-
};
|
|
12592
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12593
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12594
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12595
|
-
updatedReviewInfo = {
|
|
12596
|
-
totalReviews: newTotal,
|
|
12597
|
-
averageRating: updateAverage(
|
|
12598
|
-
currentReviewInfo.averageRating,
|
|
12599
|
-
newReview.overallRating
|
|
12600
|
-
),
|
|
12601
|
-
knowledgeAndExpertise: updateAverage(
|
|
12602
|
-
currentReviewInfo.knowledgeAndExpertise,
|
|
12603
|
-
newReview.knowledgeAndExpertise
|
|
12604
|
-
),
|
|
12605
|
-
communicationSkills: updateAverage(
|
|
12606
|
-
currentReviewInfo.communicationSkills,
|
|
12607
|
-
newReview.communicationSkills
|
|
12608
|
-
),
|
|
12609
|
-
bedSideManner: updateAverage(
|
|
12610
|
-
currentReviewInfo.bedSideManner,
|
|
12611
|
-
newReview.bedSideManner
|
|
12612
|
-
),
|
|
12613
|
-
thoroughness: updateAverage(
|
|
12614
|
-
currentReviewInfo.thoroughness,
|
|
12615
|
-
newReview.thoroughness
|
|
12616
|
-
),
|
|
12617
|
-
trustworthiness: updateAverage(
|
|
12618
|
-
currentReviewInfo.trustworthiness,
|
|
12619
|
-
newReview.trustworthiness
|
|
12620
|
-
),
|
|
12621
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12622
|
-
};
|
|
12623
|
-
}
|
|
12624
|
-
} else {
|
|
12625
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12626
|
-
}
|
|
12627
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
12628
|
-
reviewInfo: updatedReviewInfo,
|
|
12629
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12630
|
-
});
|
|
12631
|
-
await this.updateDoctorInfoInProcedures(
|
|
12632
|
-
practitionerId,
|
|
12633
|
-
updatedReviewInfo.averageRating
|
|
12634
|
-
);
|
|
12635
|
-
return updatedReviewInfo;
|
|
12636
|
-
}
|
|
12637
|
-
/**
|
|
12638
|
-
* Updates the review info for a procedure
|
|
12639
|
-
* @param procedureId The ID of the procedure to update
|
|
12640
|
-
* @param newReview Optional new review being added or removed
|
|
12641
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12642
|
-
* @returns The updated procedure review info
|
|
12643
|
-
*/
|
|
12644
|
-
async updateProcedureReviewInfo(procedureId, newReview, isRemoval = false) {
|
|
12645
|
-
const procedureDoc = await (0, import_firestore41.getDoc)(
|
|
12646
|
-
(0, import_firestore41.doc)(this.db, PROCEDURES_COLLECTION, procedureId)
|
|
12647
|
-
);
|
|
12648
|
-
if (!procedureDoc.exists()) {
|
|
12649
|
-
throw new Error(`Procedure with ID ${procedureId} not found`);
|
|
12650
|
-
}
|
|
12651
|
-
const procedureData = procedureDoc.data();
|
|
12652
|
-
const currentReviewInfo = procedureData.reviewInfo || {
|
|
12653
|
-
totalReviews: 0,
|
|
12654
|
-
averageRating: 0,
|
|
12655
|
-
effectivenessOfTreatment: 0,
|
|
12656
|
-
outcomeExplanation: 0,
|
|
12657
|
-
painManagement: 0,
|
|
12658
|
-
followUpCare: 0,
|
|
12659
|
-
valueForMoney: 0,
|
|
12660
|
-
recommendationPercentage: 0
|
|
12661
|
-
};
|
|
12662
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12663
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
12664
|
-
reviewInfo: currentReviewInfo,
|
|
12665
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12666
|
-
});
|
|
12667
|
-
return currentReviewInfo;
|
|
12668
|
-
}
|
|
12669
|
-
let updatedReviewInfo;
|
|
12670
|
-
if (newReview) {
|
|
12671
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12672
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12673
|
-
if (newTotal === 0) {
|
|
12674
|
-
updatedReviewInfo = {
|
|
12675
|
-
totalReviews: 0,
|
|
12676
|
-
averageRating: 0,
|
|
12677
|
-
effectivenessOfTreatment: 0,
|
|
12678
|
-
outcomeExplanation: 0,
|
|
12679
|
-
painManagement: 0,
|
|
12680
|
-
followUpCare: 0,
|
|
12681
|
-
valueForMoney: 0,
|
|
12682
|
-
recommendationPercentage: 0
|
|
12683
|
-
};
|
|
12684
|
-
} else {
|
|
12685
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12686
|
-
const currentSum = currentAvg * oldTotal;
|
|
12687
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12688
|
-
const newAvg = newSum / newTotal;
|
|
12689
|
-
return Math.round(newAvg * 10) / 10;
|
|
12690
|
-
};
|
|
12691
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12692
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12693
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12694
|
-
updatedReviewInfo = {
|
|
12695
|
-
totalReviews: newTotal,
|
|
12696
|
-
averageRating: updateAverage(
|
|
12697
|
-
currentReviewInfo.averageRating,
|
|
12698
|
-
newReview.overallRating
|
|
12699
|
-
),
|
|
12700
|
-
effectivenessOfTreatment: updateAverage(
|
|
12701
|
-
currentReviewInfo.effectivenessOfTreatment,
|
|
12702
|
-
newReview.effectivenessOfTreatment
|
|
12703
|
-
),
|
|
12704
|
-
outcomeExplanation: updateAverage(
|
|
12705
|
-
currentReviewInfo.outcomeExplanation,
|
|
12706
|
-
newReview.outcomeExplanation
|
|
12707
|
-
),
|
|
12708
|
-
painManagement: updateAverage(
|
|
12709
|
-
currentReviewInfo.painManagement,
|
|
12710
|
-
newReview.painManagement
|
|
12711
|
-
),
|
|
12712
|
-
followUpCare: updateAverage(
|
|
12713
|
-
currentReviewInfo.followUpCare,
|
|
12714
|
-
newReview.followUpCare
|
|
12715
|
-
),
|
|
12716
|
-
valueForMoney: updateAverage(
|
|
12717
|
-
currentReviewInfo.valueForMoney,
|
|
12718
|
-
newReview.valueForMoney
|
|
12719
|
-
),
|
|
12720
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12721
|
-
};
|
|
12722
|
-
}
|
|
12723
|
-
} else {
|
|
12724
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12725
|
-
}
|
|
12726
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
12727
|
-
reviewInfo: updatedReviewInfo,
|
|
12728
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12729
|
-
});
|
|
12730
|
-
return updatedReviewInfo;
|
|
12731
|
-
}
|
|
12732
|
-
/**
|
|
12733
|
-
* Updates doctorInfo rating in all procedures for a practitioner
|
|
12734
|
-
* @param practitionerId The ID of the practitioner
|
|
12735
|
-
* @param rating The new rating to set
|
|
12736
|
-
*/
|
|
12737
|
-
async updateDoctorInfoInProcedures(practitionerId, rating) {
|
|
12738
|
-
const q = (0, import_firestore41.query)(
|
|
12739
|
-
(0, import_firestore41.collection)(this.db, PROCEDURES_COLLECTION),
|
|
12740
|
-
(0, import_firestore41.where)("practitionerId", "==", practitionerId)
|
|
12741
|
-
);
|
|
12742
|
-
const snapshot = await (0, import_firestore41.getDocs)(q);
|
|
12743
|
-
if (snapshot.empty) {
|
|
12744
|
-
return;
|
|
12745
|
-
}
|
|
12746
|
-
const batch = (0, import_firestore41.writeBatch)(this.db);
|
|
12747
|
-
snapshot.docs.forEach((docSnapshot) => {
|
|
12748
|
-
const procedureRef = (0, import_firestore41.doc)(this.db, PROCEDURES_COLLECTION, docSnapshot.id);
|
|
12749
|
-
batch.update(procedureRef, {
|
|
12750
|
-
"doctorInfo.rating": rating,
|
|
12751
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12752
|
-
});
|
|
12753
|
-
});
|
|
12754
|
-
await batch.commit();
|
|
12755
|
-
}
|
|
12756
|
-
/**
|
|
12757
|
-
* Verifies a review as checked by admin/staff
|
|
12758
|
-
* @param reviewId The ID of the review to verify
|
|
12759
|
-
*/
|
|
12760
|
-
async verifyReview(reviewId) {
|
|
12761
|
-
const review = await this.getReview(reviewId);
|
|
12762
|
-
if (!review) {
|
|
12763
|
-
throw new Error(`Review with ID ${reviewId} not found`);
|
|
12764
|
-
}
|
|
12765
|
-
const batch = (0, import_firestore41.writeBatch)(this.db);
|
|
12766
|
-
batch.update((0, import_firestore41.doc)(this.db, REVIEWS_COLLECTION, reviewId), {
|
|
12767
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12768
|
-
});
|
|
12769
|
-
if (review.clinicReview) {
|
|
12770
|
-
review.clinicReview.isVerified = true;
|
|
12771
|
-
}
|
|
12772
|
-
if (review.practitionerReview) {
|
|
12773
|
-
review.practitionerReview.isVerified = true;
|
|
12774
|
-
}
|
|
12775
|
-
if (review.procedureReview) {
|
|
12776
|
-
review.procedureReview.isVerified = true;
|
|
12777
|
-
}
|
|
12778
|
-
await batch.commit();
|
|
12779
|
-
const updatePromises = [];
|
|
12780
|
-
if (review.clinicReview) {
|
|
12781
|
-
updatePromises.push(
|
|
12782
|
-
this.updateClinicReviewInfo(review.clinicReview.clinicId)
|
|
12783
|
-
);
|
|
12784
|
-
}
|
|
12785
|
-
if (review.practitionerReview) {
|
|
12786
|
-
updatePromises.push(
|
|
12787
|
-
this.updatePractitionerReviewInfo(
|
|
12788
|
-
review.practitionerReview.practitionerId
|
|
12789
|
-
)
|
|
12790
|
-
);
|
|
12791
|
-
}
|
|
12792
|
-
if (review.procedureReview) {
|
|
12793
|
-
updatePromises.push(
|
|
12794
|
-
this.updateProcedureReviewInfo(review.procedureReview.procedureId)
|
|
12795
|
-
);
|
|
12796
|
-
}
|
|
12797
|
-
await Promise.all(updatePromises);
|
|
12798
12475
|
}
|
|
12799
12476
|
/**
|
|
12800
12477
|
* Calculates the average of an array of numbers
|
|
@@ -14858,63 +14535,63 @@ var ProductService = class extends BaseService {
|
|
|
14858
14535
|
};
|
|
14859
14536
|
|
|
14860
14537
|
// src/validations/notification.schema.ts
|
|
14861
|
-
var
|
|
14862
|
-
var baseNotificationSchema =
|
|
14863
|
-
id:
|
|
14864
|
-
userId:
|
|
14865
|
-
notificationTime:
|
|
14538
|
+
var import_zod25 = require("zod");
|
|
14539
|
+
var baseNotificationSchema = import_zod25.z.object({
|
|
14540
|
+
id: import_zod25.z.string().optional(),
|
|
14541
|
+
userId: import_zod25.z.string(),
|
|
14542
|
+
notificationTime: import_zod25.z.any(),
|
|
14866
14543
|
// Timestamp
|
|
14867
|
-
notificationType:
|
|
14868
|
-
notificationTokens:
|
|
14869
|
-
status:
|
|
14870
|
-
createdAt:
|
|
14544
|
+
notificationType: import_zod25.z.nativeEnum(NotificationType),
|
|
14545
|
+
notificationTokens: import_zod25.z.array(import_zod25.z.string()),
|
|
14546
|
+
status: import_zod25.z.nativeEnum(NotificationStatus),
|
|
14547
|
+
createdAt: import_zod25.z.any().optional(),
|
|
14871
14548
|
// Timestamp
|
|
14872
|
-
updatedAt:
|
|
14549
|
+
updatedAt: import_zod25.z.any().optional(),
|
|
14873
14550
|
// Timestamp
|
|
14874
|
-
title:
|
|
14875
|
-
body:
|
|
14876
|
-
isRead:
|
|
14877
|
-
userRole:
|
|
14551
|
+
title: import_zod25.z.string(),
|
|
14552
|
+
body: import_zod25.z.string(),
|
|
14553
|
+
isRead: import_zod25.z.boolean(),
|
|
14554
|
+
userRole: import_zod25.z.nativeEnum(UserRole)
|
|
14878
14555
|
});
|
|
14879
14556
|
var preRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
14880
|
-
notificationType:
|
|
14881
|
-
treatmentId:
|
|
14882
|
-
requirements:
|
|
14883
|
-
deadline:
|
|
14557
|
+
notificationType: import_zod25.z.literal("preRequirementInstructionDue" /* PRE_REQUIREMENT_INSTRUCTION_DUE */),
|
|
14558
|
+
treatmentId: import_zod25.z.string(),
|
|
14559
|
+
requirements: import_zod25.z.array(import_zod25.z.string()),
|
|
14560
|
+
deadline: import_zod25.z.any()
|
|
14884
14561
|
// Timestamp
|
|
14885
14562
|
});
|
|
14886
14563
|
var postRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
14887
|
-
notificationType:
|
|
14564
|
+
notificationType: import_zod25.z.literal(
|
|
14888
14565
|
"postRequirementInstructionDue" /* POST_REQUIREMENT_INSTRUCTION_DUE */
|
|
14889
14566
|
),
|
|
14890
|
-
treatmentId:
|
|
14891
|
-
requirements:
|
|
14892
|
-
deadline:
|
|
14567
|
+
treatmentId: import_zod25.z.string(),
|
|
14568
|
+
requirements: import_zod25.z.array(import_zod25.z.string()),
|
|
14569
|
+
deadline: import_zod25.z.any()
|
|
14893
14570
|
// Timestamp
|
|
14894
14571
|
});
|
|
14895
14572
|
var requirementInstructionDueNotificationSchema = baseNotificationSchema.extend({
|
|
14896
|
-
notificationType:
|
|
14897
|
-
appointmentId:
|
|
14898
|
-
patientRequirementInstanceId:
|
|
14899
|
-
instructionId:
|
|
14900
|
-
originalRequirementId:
|
|
14573
|
+
notificationType: import_zod25.z.literal("requirementInstructionDue" /* REQUIREMENT_INSTRUCTION_DUE */),
|
|
14574
|
+
appointmentId: import_zod25.z.string(),
|
|
14575
|
+
patientRequirementInstanceId: import_zod25.z.string(),
|
|
14576
|
+
instructionId: import_zod25.z.string(),
|
|
14577
|
+
originalRequirementId: import_zod25.z.string().optional()
|
|
14901
14578
|
});
|
|
14902
14579
|
var appointmentReminderNotificationSchema = baseNotificationSchema.extend({
|
|
14903
|
-
notificationType:
|
|
14904
|
-
appointmentId:
|
|
14905
|
-
appointmentTime:
|
|
14580
|
+
notificationType: import_zod25.z.literal("appointmentReminder" /* APPOINTMENT_REMINDER */),
|
|
14581
|
+
appointmentId: import_zod25.z.string(),
|
|
14582
|
+
appointmentTime: import_zod25.z.any(),
|
|
14906
14583
|
// Timestamp
|
|
14907
|
-
treatmentType:
|
|
14908
|
-
doctorName:
|
|
14584
|
+
treatmentType: import_zod25.z.string(),
|
|
14585
|
+
doctorName: import_zod25.z.string()
|
|
14909
14586
|
});
|
|
14910
14587
|
var appointmentNotificationSchema = baseNotificationSchema.extend({
|
|
14911
|
-
notificationType:
|
|
14912
|
-
appointmentId:
|
|
14913
|
-
appointmentStatus:
|
|
14914
|
-
previousStatus:
|
|
14915
|
-
reason:
|
|
14588
|
+
notificationType: import_zod25.z.literal("appointmentStatusChange" /* APPOINTMENT_STATUS_CHANGE */),
|
|
14589
|
+
appointmentId: import_zod25.z.string(),
|
|
14590
|
+
appointmentStatus: import_zod25.z.string(),
|
|
14591
|
+
previousStatus: import_zod25.z.string(),
|
|
14592
|
+
reason: import_zod25.z.string().optional()
|
|
14916
14593
|
});
|
|
14917
|
-
var notificationSchema =
|
|
14594
|
+
var notificationSchema = import_zod25.z.discriminatedUnion("notificationType", [
|
|
14918
14595
|
preRequirementNotificationSchema,
|
|
14919
14596
|
postRequirementNotificationSchema,
|
|
14920
14597
|
requirementInstructionDueNotificationSchema,
|
|
@@ -14998,6 +14675,9 @@ var RequirementType = /* @__PURE__ */ ((RequirementType2) => {
|
|
|
14998
14675
|
HeadingLevel,
|
|
14999
14676
|
Language,
|
|
15000
14677
|
ListType,
|
|
14678
|
+
MEDIA_METADATA_COLLECTION,
|
|
14679
|
+
MediaAccessLevel,
|
|
14680
|
+
MediaService,
|
|
15001
14681
|
MedicationAllergySubtype,
|
|
15002
14682
|
NotificationService,
|
|
15003
14683
|
NotificationStatus,
|