@blackcode_sa/metaestetics-api 1.7.11 → 1.7.13
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 +200 -1
- package/dist/admin/index.d.ts +200 -1
- package/dist/admin/index.js +691 -35
- package/dist/admin/index.mjs +689 -35
- package/dist/index.d.mts +138 -37
- package/dist/index.d.ts +138 -37
- package/dist/index.js +543 -875
- package/dist/index.mjs +588 -922
- package/package.json +1 -1
- package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +316 -0
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +641 -0
- package/src/admin/index.ts +8 -1
- 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/reviews/reviews.service.ts +6 -572
- package/src/types/clinic/index.ts +16 -0
- package/src/validations/clinic.schema.ts +25 -9
- package/src/validations/media.schema.ts +10 -0
package/dist/index.js
CHANGED
|
@@ -796,7 +796,7 @@ var UserRole = /* @__PURE__ */ ((UserRole2) => {
|
|
|
796
796
|
var USERS_COLLECTION = "users";
|
|
797
797
|
|
|
798
798
|
// src/services/auth.service.ts
|
|
799
|
-
var
|
|
799
|
+
var import_zod20 = require("zod");
|
|
800
800
|
|
|
801
801
|
// src/validations/schemas.ts
|
|
802
802
|
var import_zod3 = require("zod");
|
|
@@ -1191,7 +1191,7 @@ var USER_ERRORS = {
|
|
|
1191
1191
|
};
|
|
1192
1192
|
|
|
1193
1193
|
// src/services/user.service.ts
|
|
1194
|
-
var
|
|
1194
|
+
var import_zod16 = require("zod");
|
|
1195
1195
|
|
|
1196
1196
|
// src/services/patient/patient.service.ts
|
|
1197
1197
|
var import_firestore12 = require("firebase/firestore");
|
|
@@ -3102,7 +3102,7 @@ var SubscriptionModel = /* @__PURE__ */ ((SubscriptionModel2) => {
|
|
|
3102
3102
|
})(SubscriptionModel || {});
|
|
3103
3103
|
|
|
3104
3104
|
// src/validations/clinic.schema.ts
|
|
3105
|
-
var
|
|
3105
|
+
var import_zod13 = require("zod");
|
|
3106
3106
|
var import_firestore13 = require("firebase/firestore");
|
|
3107
3107
|
|
|
3108
3108
|
// src/validations/reviews.schema.ts
|
|
@@ -3319,38 +3319,41 @@ var doctorInfoSchema = import_zod11.z.object({
|
|
|
3319
3319
|
// List of procedure IDs practitioner offers
|
|
3320
3320
|
});
|
|
3321
3321
|
|
|
3322
|
-
// src/validations/
|
|
3322
|
+
// src/validations/media.schema.ts
|
|
3323
|
+
var import_zod12 = require("zod");
|
|
3323
3324
|
var mediaResourceSchema = import_zod12.z.union([
|
|
3324
3325
|
import_zod12.z.string(),
|
|
3325
3326
|
import_zod12.z.instanceof(File),
|
|
3326
3327
|
import_zod12.z.instanceof(Blob)
|
|
3327
3328
|
]);
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
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()
|
|
3333
3336
|
});
|
|
3334
|
-
var clinicLocationSchema =
|
|
3335
|
-
address:
|
|
3336
|
-
city:
|
|
3337
|
-
country:
|
|
3338
|
-
postalCode:
|
|
3339
|
-
latitude:
|
|
3340
|
-
longitude:
|
|
3341
|
-
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()
|
|
3342
3345
|
});
|
|
3343
|
-
var workingHoursTimeSchema =
|
|
3344
|
-
open:
|
|
3345
|
-
close:
|
|
3346
|
-
breaks:
|
|
3347
|
-
|
|
3348
|
-
start:
|
|
3349
|
-
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()
|
|
3350
3353
|
})
|
|
3351
3354
|
).optional()
|
|
3352
3355
|
});
|
|
3353
|
-
var workingHoursSchema =
|
|
3356
|
+
var workingHoursSchema = import_zod13.z.object({
|
|
3354
3357
|
monday: workingHoursTimeSchema.nullable(),
|
|
3355
3358
|
tuesday: workingHoursTimeSchema.nullable(),
|
|
3356
3359
|
wednesday: workingHoursTimeSchema.nullable(),
|
|
@@ -3359,239 +3362,255 @@ var workingHoursSchema = import_zod12.z.object({
|
|
|
3359
3362
|
saturday: workingHoursTimeSchema.nullable(),
|
|
3360
3363
|
sunday: workingHoursTimeSchema.nullable()
|
|
3361
3364
|
});
|
|
3362
|
-
var clinicTagsSchema =
|
|
3363
|
-
tags:
|
|
3365
|
+
var clinicTagsSchema = import_zod13.z.object({
|
|
3366
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag))
|
|
3364
3367
|
});
|
|
3365
|
-
var contactPersonSchema =
|
|
3366
|
-
firstName:
|
|
3367
|
-
lastName:
|
|
3368
|
-
title:
|
|
3369
|
-
email:
|
|
3370
|
-
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()
|
|
3371
3374
|
});
|
|
3372
|
-
var adminInfoSchema =
|
|
3373
|
-
id:
|
|
3374
|
-
name:
|
|
3375
|
-
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()
|
|
3376
3379
|
});
|
|
3377
|
-
var clinicAdminSchema =
|
|
3378
|
-
id:
|
|
3379
|
-
userRef:
|
|
3380
|
-
clinicGroupId:
|
|
3381
|
-
isGroupOwner:
|
|
3382
|
-
clinicsManaged:
|
|
3383
|
-
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),
|
|
3384
3387
|
contactInfo: contactPersonSchema,
|
|
3385
|
-
roleTitle:
|
|
3386
|
-
createdAt:
|
|
3387
|
-
updatedAt:
|
|
3388
|
-
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()
|
|
3389
3392
|
});
|
|
3390
|
-
var adminTokenSchema =
|
|
3391
|
-
id:
|
|
3392
|
-
token:
|
|
3393
|
-
email:
|
|
3394
|
-
status:
|
|
3395
|
-
usedByUserRef:
|
|
3396
|
-
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)),
|
|
3397
3400
|
// Timestamp
|
|
3398
|
-
expiresAt:
|
|
3401
|
+
expiresAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp))
|
|
3399
3402
|
// Timestamp
|
|
3400
3403
|
});
|
|
3401
|
-
var createAdminTokenSchema =
|
|
3402
|
-
expiresInDays:
|
|
3403
|
-
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()
|
|
3404
3407
|
});
|
|
3405
|
-
var clinicGroupSchema =
|
|
3406
|
-
id:
|
|
3407
|
-
name:
|
|
3408
|
-
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(),
|
|
3409
3412
|
hqLocation: clinicLocationSchema,
|
|
3410
3413
|
contactInfo: clinicContactInfoSchema,
|
|
3411
3414
|
contactPerson: contactPersonSchema,
|
|
3412
|
-
clinics:
|
|
3413
|
-
clinicsInfo:
|
|
3414
|
-
admins:
|
|
3415
|
-
adminsInfo:
|
|
3416
|
-
adminTokens:
|
|
3417
|
-
ownerId:
|
|
3418
|
-
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)),
|
|
3419
3422
|
// Timestamp
|
|
3420
|
-
updatedAt:
|
|
3423
|
+
updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
|
|
3421
3424
|
// Timestamp
|
|
3422
|
-
isActive:
|
|
3425
|
+
isActive: import_zod13.z.boolean(),
|
|
3423
3426
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3424
|
-
practiceType:
|
|
3425
|
-
languages:
|
|
3426
|
-
subscriptionModel:
|
|
3427
|
-
calendarSyncEnabled:
|
|
3428
|
-
autoConfirmAppointments:
|
|
3429
|
-
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()
|
|
3430
3437
|
});
|
|
3431
|
-
var clinicSchema =
|
|
3432
|
-
id:
|
|
3433
|
-
clinicGroupId:
|
|
3434
|
-
name:
|
|
3435
|
-
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(),
|
|
3436
3443
|
location: clinicLocationSchema,
|
|
3437
3444
|
contactInfo: clinicContactInfoSchema,
|
|
3438
3445
|
workingHours: workingHoursSchema,
|
|
3439
|
-
tags:
|
|
3440
|
-
featuredPhotos:
|
|
3446
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag)),
|
|
3447
|
+
featuredPhotos: import_zod13.z.array(mediaResourceSchema),
|
|
3441
3448
|
coverPhoto: mediaResourceSchema.nullable(),
|
|
3442
|
-
photosWithTags:
|
|
3443
|
-
|
|
3449
|
+
photosWithTags: import_zod13.z.array(
|
|
3450
|
+
import_zod13.z.object({
|
|
3444
3451
|
url: mediaResourceSchema,
|
|
3445
|
-
tag:
|
|
3452
|
+
tag: import_zod13.z.string()
|
|
3446
3453
|
})
|
|
3447
3454
|
).optional(),
|
|
3448
|
-
doctors:
|
|
3455
|
+
doctors: import_zod13.z.array(import_zod13.z.string()),
|
|
3449
3456
|
// List of practitioner IDs
|
|
3450
|
-
doctorsInfo:
|
|
3457
|
+
doctorsInfo: import_zod13.z.array(doctorInfoSchema),
|
|
3451
3458
|
// Aggregated doctor info
|
|
3452
|
-
procedures:
|
|
3459
|
+
procedures: import_zod13.z.array(import_zod13.z.string()),
|
|
3453
3460
|
// List of procedure IDs offered by clinic
|
|
3454
|
-
proceduresInfo:
|
|
3461
|
+
proceduresInfo: import_zod13.z.array(procedureSummaryInfoSchema),
|
|
3455
3462
|
// Use the correct schema for aggregated procedure info
|
|
3456
3463
|
reviewInfo: clinicReviewInfoSchema,
|
|
3457
|
-
admins:
|
|
3458
|
-
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)),
|
|
3459
3466
|
// Timestamp
|
|
3460
|
-
updatedAt:
|
|
3467
|
+
updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
|
|
3461
3468
|
// Timestamp
|
|
3462
|
-
isActive:
|
|
3463
|
-
isVerified:
|
|
3469
|
+
isActive: import_zod13.z.boolean(),
|
|
3470
|
+
isVerified: import_zod13.z.boolean(),
|
|
3464
3471
|
logo: mediaResourceSchema.optional().nullable()
|
|
3465
3472
|
});
|
|
3466
|
-
var createClinicAdminSchema =
|
|
3467
|
-
userRef:
|
|
3468
|
-
clinicGroupId:
|
|
3469
|
-
isGroupOwner:
|
|
3470
|
-
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()),
|
|
3471
3478
|
contactInfo: contactPersonSchema,
|
|
3472
|
-
roleTitle:
|
|
3473
|
-
isActive:
|
|
3479
|
+
roleTitle: import_zod13.z.string(),
|
|
3480
|
+
isActive: import_zod13.z.boolean()
|
|
3474
3481
|
// clinicsManagedInfo is aggregated, not provided on creation
|
|
3475
3482
|
});
|
|
3476
|
-
var createClinicGroupSchema =
|
|
3477
|
-
name:
|
|
3478
|
-
description:
|
|
3483
|
+
var createClinicGroupSchema = import_zod13.z.object({
|
|
3484
|
+
name: import_zod13.z.string(),
|
|
3485
|
+
description: import_zod13.z.string().optional(),
|
|
3479
3486
|
hqLocation: clinicLocationSchema,
|
|
3480
3487
|
contactInfo: clinicContactInfoSchema,
|
|
3481
3488
|
contactPerson: contactPersonSchema,
|
|
3482
|
-
ownerId:
|
|
3483
|
-
isActive:
|
|
3489
|
+
ownerId: import_zod13.z.string().nullable(),
|
|
3490
|
+
isActive: import_zod13.z.boolean(),
|
|
3484
3491
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3485
|
-
practiceType:
|
|
3486
|
-
languages:
|
|
3487
|
-
subscriptionModel:
|
|
3488
|
-
calendarSyncEnabled:
|
|
3489
|
-
autoConfirmAppointments:
|
|
3490
|
-
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()
|
|
3491
3502
|
// clinics, clinicsInfo, admins, adminsInfo, adminTokens are managed internally
|
|
3492
3503
|
});
|
|
3493
|
-
var createClinicSchema =
|
|
3494
|
-
clinicGroupId:
|
|
3495
|
-
name:
|
|
3496
|
-
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(),
|
|
3497
3508
|
location: clinicLocationSchema,
|
|
3498
3509
|
contactInfo: clinicContactInfoSchema,
|
|
3499
3510
|
workingHours: workingHoursSchema,
|
|
3500
|
-
tags:
|
|
3511
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag)),
|
|
3501
3512
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
3502
|
-
photosWithTags:
|
|
3503
|
-
|
|
3513
|
+
photosWithTags: import_zod13.z.array(
|
|
3514
|
+
import_zod13.z.object({
|
|
3504
3515
|
url: mediaResourceSchema,
|
|
3505
|
-
tag:
|
|
3516
|
+
tag: import_zod13.z.string()
|
|
3506
3517
|
})
|
|
3507
3518
|
).optional(),
|
|
3508
|
-
doctors:
|
|
3509
|
-
procedures:
|
|
3510
|
-
proceduresInfo:
|
|
3511
|
-
admins:
|
|
3512
|
-
isActive:
|
|
3513
|
-
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),
|
|
3514
3525
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3515
|
-
featuredPhotos:
|
|
3526
|
+
featuredPhotos: import_zod13.z.array(mediaResourceSchema).optional().default([])
|
|
3516
3527
|
});
|
|
3517
|
-
var createDefaultClinicGroupSchema =
|
|
3518
|
-
name:
|
|
3519
|
-
ownerId:
|
|
3528
|
+
var createDefaultClinicGroupSchema = import_zod13.z.object({
|
|
3529
|
+
name: import_zod13.z.string(),
|
|
3530
|
+
ownerId: import_zod13.z.string().nullable(),
|
|
3520
3531
|
contactPerson: contactPersonSchema,
|
|
3521
3532
|
contactInfo: clinicContactInfoSchema,
|
|
3522
3533
|
hqLocation: clinicLocationSchema,
|
|
3523
|
-
isActive:
|
|
3534
|
+
isActive: import_zod13.z.boolean(),
|
|
3524
3535
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3525
|
-
practiceType:
|
|
3526
|
-
languages:
|
|
3527
|
-
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()
|
|
3528
3543
|
});
|
|
3529
|
-
var clinicAdminSignupSchema =
|
|
3530
|
-
email:
|
|
3531
|
-
password:
|
|
3532
|
-
firstName:
|
|
3533
|
-
lastName:
|
|
3534
|
-
title:
|
|
3535
|
-
phoneNumber:
|
|
3536
|
-
isCreatingNewGroup:
|
|
3537
|
-
inviteToken:
|
|
3538
|
-
clinicGroupData:
|
|
3539
|
-
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(),
|
|
3540
3555
|
hqLocation: clinicLocationSchema,
|
|
3541
3556
|
logo: mediaResourceSchema.optional(),
|
|
3542
3557
|
contactInfo: clinicContactInfoSchema,
|
|
3543
|
-
subscriptionModel:
|
|
3558
|
+
subscriptionModel: import_zod13.z.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */)
|
|
3544
3559
|
}).optional()
|
|
3545
3560
|
});
|
|
3546
|
-
var clinicGroupSetupSchema =
|
|
3547
|
-
languages:
|
|
3548
|
-
practiceType:
|
|
3549
|
-
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(),
|
|
3550
3565
|
logo: mediaResourceSchema,
|
|
3551
|
-
calendarSyncEnabled:
|
|
3552
|
-
autoConfirmAppointments:
|
|
3553
|
-
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()
|
|
3554
3573
|
});
|
|
3555
|
-
var clinicBranchSetupSchema =
|
|
3556
|
-
name:
|
|
3574
|
+
var clinicBranchSetupSchema = import_zod13.z.object({
|
|
3575
|
+
name: import_zod13.z.string(),
|
|
3557
3576
|
location: clinicLocationSchema,
|
|
3558
|
-
description:
|
|
3577
|
+
description: import_zod13.z.string().optional(),
|
|
3559
3578
|
contactInfo: clinicContactInfoSchema,
|
|
3560
3579
|
workingHours: workingHoursSchema,
|
|
3561
|
-
tags:
|
|
3580
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag)),
|
|
3562
3581
|
logo: mediaResourceSchema.optional(),
|
|
3563
3582
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
3564
|
-
photosWithTags:
|
|
3565
|
-
|
|
3583
|
+
photosWithTags: import_zod13.z.array(
|
|
3584
|
+
import_zod13.z.object({
|
|
3566
3585
|
url: mediaResourceSchema,
|
|
3567
|
-
tag:
|
|
3586
|
+
tag: import_zod13.z.string()
|
|
3568
3587
|
})
|
|
3569
3588
|
).optional(),
|
|
3570
|
-
featuredPhotos:
|
|
3589
|
+
featuredPhotos: import_zod13.z.array(mediaResourceSchema).optional()
|
|
3571
3590
|
});
|
|
3572
3591
|
var updateClinicAdminSchema = createClinicAdminSchema.partial();
|
|
3573
3592
|
var updateClinicGroupSchema = createClinicGroupSchema.partial();
|
|
3574
|
-
var updateClinicSchema =
|
|
3575
|
-
name:
|
|
3576
|
-
description:
|
|
3593
|
+
var updateClinicSchema = import_zod13.z.object({
|
|
3594
|
+
name: import_zod13.z.string().optional(),
|
|
3595
|
+
description: import_zod13.z.string().optional(),
|
|
3577
3596
|
location: clinicLocationSchema.optional(),
|
|
3578
3597
|
contactInfo: clinicContactInfoSchema.optional(),
|
|
3579
3598
|
workingHours: workingHoursSchema.optional(),
|
|
3580
|
-
tags:
|
|
3599
|
+
tags: import_zod13.z.array(import_zod13.z.nativeEnum(ClinicTag)).optional(),
|
|
3581
3600
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
3582
|
-
photosWithTags:
|
|
3583
|
-
|
|
3601
|
+
photosWithTags: import_zod13.z.array(
|
|
3602
|
+
import_zod13.z.object({
|
|
3584
3603
|
url: mediaResourceSchema,
|
|
3585
|
-
tag:
|
|
3604
|
+
tag: import_zod13.z.string()
|
|
3586
3605
|
})
|
|
3587
3606
|
).optional(),
|
|
3588
|
-
doctors:
|
|
3589
|
-
procedures:
|
|
3590
|
-
proceduresInfo:
|
|
3591
|
-
isActive:
|
|
3592
|
-
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(),
|
|
3593
3612
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3594
|
-
featuredPhotos:
|
|
3613
|
+
featuredPhotos: import_zod13.z.array(mediaResourceSchema).optional()
|
|
3595
3614
|
});
|
|
3596
3615
|
|
|
3597
3616
|
// src/services/clinic/utils/admin.utils.ts
|
|
@@ -4044,7 +4063,7 @@ var ClinicAdminService = class extends BaseService {
|
|
|
4044
4063
|
var import_firestore16 = require("firebase/firestore");
|
|
4045
4064
|
|
|
4046
4065
|
// src/validations/practitioner.schema.ts
|
|
4047
|
-
var
|
|
4066
|
+
var import_zod14 = require("zod");
|
|
4048
4067
|
var import_firestore15 = require("firebase/firestore");
|
|
4049
4068
|
|
|
4050
4069
|
// src/backoffice/types/static/certification.types.ts
|
|
@@ -4072,34 +4091,34 @@ var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
|
|
|
4072
4091
|
})(CertificationSpecialty || {});
|
|
4073
4092
|
|
|
4074
4093
|
// src/validations/practitioner.schema.ts
|
|
4075
|
-
var practitionerBasicInfoSchema =
|
|
4076
|
-
firstName:
|
|
4077
|
-
lastName:
|
|
4078
|
-
title:
|
|
4079
|
-
email:
|
|
4080
|
-
phoneNumber:
|
|
4081
|
-
dateOfBirth:
|
|
4082
|
-
gender:
|
|
4083
|
-
profileImageUrl:
|
|
4084
|
-
bio:
|
|
4085
|
-
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)
|
|
4086
4105
|
});
|
|
4087
|
-
var practitionerCertificationSchema =
|
|
4088
|
-
level:
|
|
4089
|
-
specialties:
|
|
4090
|
-
licenseNumber:
|
|
4091
|
-
issuingAuthority:
|
|
4092
|
-
issueDate:
|
|
4093
|
-
expiryDate:
|
|
4094
|
-
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"])
|
|
4095
4114
|
});
|
|
4096
|
-
var timeSlotSchema =
|
|
4097
|
-
start:
|
|
4098
|
-
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")
|
|
4099
4118
|
}).nullable();
|
|
4100
|
-
var practitionerWorkingHoursSchema =
|
|
4101
|
-
practitionerId:
|
|
4102
|
-
clinicId:
|
|
4119
|
+
var practitionerWorkingHoursSchema = import_zod14.z.object({
|
|
4120
|
+
practitionerId: import_zod14.z.string().min(1),
|
|
4121
|
+
clinicId: import_zod14.z.string().min(1),
|
|
4103
4122
|
monday: timeSlotSchema,
|
|
4104
4123
|
tuesday: timeSlotSchema,
|
|
4105
4124
|
wednesday: timeSlotSchema,
|
|
@@ -4107,12 +4126,12 @@ var practitionerWorkingHoursSchema = import_zod13.z.object({
|
|
|
4107
4126
|
friday: timeSlotSchema,
|
|
4108
4127
|
saturday: timeSlotSchema,
|
|
4109
4128
|
sunday: timeSlotSchema,
|
|
4110
|
-
createdAt:
|
|
4111
|
-
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())
|
|
4112
4131
|
});
|
|
4113
|
-
var practitionerClinicWorkingHoursSchema =
|
|
4114
|
-
clinicId:
|
|
4115
|
-
workingHours:
|
|
4132
|
+
var practitionerClinicWorkingHoursSchema = import_zod14.z.object({
|
|
4133
|
+
clinicId: import_zod14.z.string().min(1),
|
|
4134
|
+
workingHours: import_zod14.z.object({
|
|
4116
4135
|
monday: timeSlotSchema,
|
|
4117
4136
|
tuesday: timeSlotSchema,
|
|
4118
4137
|
wednesday: timeSlotSchema,
|
|
@@ -4121,87 +4140,87 @@ var practitionerClinicWorkingHoursSchema = import_zod13.z.object({
|
|
|
4121
4140
|
saturday: timeSlotSchema,
|
|
4122
4141
|
sunday: timeSlotSchema
|
|
4123
4142
|
}),
|
|
4124
|
-
isActive:
|
|
4125
|
-
createdAt:
|
|
4126
|
-
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())
|
|
4127
4146
|
});
|
|
4128
|
-
var practitionerSchema =
|
|
4129
|
-
id:
|
|
4130
|
-
userRef:
|
|
4147
|
+
var practitionerSchema = import_zod14.z.object({
|
|
4148
|
+
id: import_zod14.z.string().min(1),
|
|
4149
|
+
userRef: import_zod14.z.string().min(1),
|
|
4131
4150
|
basicInfo: practitionerBasicInfoSchema,
|
|
4132
4151
|
certification: practitionerCertificationSchema,
|
|
4133
|
-
clinics:
|
|
4134
|
-
clinicWorkingHours:
|
|
4135
|
-
clinicsInfo:
|
|
4136
|
-
procedures:
|
|
4137
|
-
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),
|
|
4138
4157
|
reviewInfo: practitionerReviewInfoSchema,
|
|
4139
|
-
isActive:
|
|
4140
|
-
isVerified:
|
|
4141
|
-
status:
|
|
4142
|
-
createdAt:
|
|
4143
|
-
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())
|
|
4144
4163
|
});
|
|
4145
|
-
var createPractitionerSchema =
|
|
4146
|
-
userRef:
|
|
4164
|
+
var createPractitionerSchema = import_zod14.z.object({
|
|
4165
|
+
userRef: import_zod14.z.string().min(1),
|
|
4147
4166
|
basicInfo: practitionerBasicInfoSchema,
|
|
4148
4167
|
certification: practitionerCertificationSchema,
|
|
4149
|
-
clinics:
|
|
4150
|
-
clinicWorkingHours:
|
|
4151
|
-
clinicsInfo:
|
|
4152
|
-
proceduresInfo:
|
|
4153
|
-
isActive:
|
|
4154
|
-
isVerified:
|
|
4155
|
-
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()
|
|
4156
4175
|
});
|
|
4157
|
-
var createDraftPractitionerSchema =
|
|
4176
|
+
var createDraftPractitionerSchema = import_zod14.z.object({
|
|
4158
4177
|
basicInfo: practitionerBasicInfoSchema,
|
|
4159
4178
|
certification: practitionerCertificationSchema,
|
|
4160
|
-
clinics:
|
|
4161
|
-
clinicWorkingHours:
|
|
4162
|
-
clinicsInfo:
|
|
4163
|
-
proceduresInfo:
|
|
4164
|
-
isActive:
|
|
4165
|
-
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)
|
|
4166
4185
|
});
|
|
4167
|
-
var practitionerTokenSchema =
|
|
4168
|
-
id:
|
|
4169
|
-
token:
|
|
4170
|
-
practitionerId:
|
|
4171
|
-
email:
|
|
4172
|
-
clinicId:
|
|
4173
|
-
status:
|
|
4174
|
-
createdBy:
|
|
4175
|
-
createdAt:
|
|
4176
|
-
expiresAt:
|
|
4177
|
-
usedBy:
|
|
4178
|
-
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()
|
|
4179
4198
|
});
|
|
4180
|
-
var createPractitionerTokenSchema =
|
|
4181
|
-
practitionerId:
|
|
4182
|
-
email:
|
|
4183
|
-
clinicId:
|
|
4184
|
-
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()
|
|
4185
4204
|
});
|
|
4186
|
-
var practitionerSignupSchema =
|
|
4187
|
-
email:
|
|
4188
|
-
password:
|
|
4189
|
-
firstName:
|
|
4190
|
-
lastName:
|
|
4191
|
-
token:
|
|
4192
|
-
profileData:
|
|
4193
|
-
basicInfo:
|
|
4194
|
-
phoneNumber:
|
|
4195
|
-
profileImageUrl:
|
|
4196
|
-
gender:
|
|
4197
|
-
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()
|
|
4198
4217
|
}).optional(),
|
|
4199
|
-
certification:
|
|
4218
|
+
certification: import_zod14.z.any().optional()
|
|
4200
4219
|
}).optional()
|
|
4201
4220
|
});
|
|
4202
4221
|
|
|
4203
4222
|
// src/services/practitioner/practitioner.service.ts
|
|
4204
|
-
var
|
|
4223
|
+
var import_zod15 = require("zod");
|
|
4205
4224
|
var import_geofire_common2 = require("geofire-common");
|
|
4206
4225
|
var PractitionerService = class extends BaseService {
|
|
4207
4226
|
constructor(db, auth, app, clinicService) {
|
|
@@ -4270,7 +4289,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4270
4289
|
}
|
|
4271
4290
|
return createdPractitioner;
|
|
4272
4291
|
} catch (error) {
|
|
4273
|
-
if (error instanceof
|
|
4292
|
+
if (error instanceof import_zod15.z.ZodError) {
|
|
4274
4293
|
throw new Error(`Invalid practitioner data: ${error.message}`);
|
|
4275
4294
|
}
|
|
4276
4295
|
console.error("Error creating practitioner:", error);
|
|
@@ -4383,7 +4402,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4383
4402
|
await (0, import_firestore16.setDoc)((0, import_firestore16.doc)(this.db, tokenPath), token);
|
|
4384
4403
|
return { practitioner: savedPractitioner, token };
|
|
4385
4404
|
} catch (error) {
|
|
4386
|
-
if (error instanceof
|
|
4405
|
+
if (error instanceof import_zod15.z.ZodError) {
|
|
4387
4406
|
throw new Error("Invalid practitioner data: " + error.message);
|
|
4388
4407
|
}
|
|
4389
4408
|
throw error;
|
|
@@ -4436,7 +4455,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4436
4455
|
await (0, import_firestore16.setDoc)((0, import_firestore16.doc)(this.db, tokenPath), token);
|
|
4437
4456
|
return token;
|
|
4438
4457
|
} catch (error) {
|
|
4439
|
-
if (error instanceof
|
|
4458
|
+
if (error instanceof import_zod15.z.ZodError) {
|
|
4440
4459
|
throw new Error("Invalid token data: " + error.message);
|
|
4441
4460
|
}
|
|
4442
4461
|
throw error;
|
|
@@ -4623,7 +4642,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4623
4642
|
}
|
|
4624
4643
|
return updatedPractitioner;
|
|
4625
4644
|
} catch (error) {
|
|
4626
|
-
if (error instanceof
|
|
4645
|
+
if (error instanceof import_zod15.z.ZodError) {
|
|
4627
4646
|
throw new Error(`Invalid practitioner update data: ${error.message}`);
|
|
4628
4647
|
}
|
|
4629
4648
|
console.error(`Error updating practitioner ${practitionerId}:`, error);
|
|
@@ -5179,7 +5198,7 @@ var UserService = class extends BaseService {
|
|
|
5179
5198
|
});
|
|
5180
5199
|
return this.getUserById(uid);
|
|
5181
5200
|
} catch (error) {
|
|
5182
|
-
if (error instanceof
|
|
5201
|
+
if (error instanceof import_zod16.z.ZodError) {
|
|
5183
5202
|
throw USER_ERRORS.VALIDATION_ERROR;
|
|
5184
5203
|
}
|
|
5185
5204
|
throw error;
|
|
@@ -5266,7 +5285,7 @@ var UserService = class extends BaseService {
|
|
|
5266
5285
|
// src/services/clinic/utils/clinic-group.utils.ts
|
|
5267
5286
|
var import_firestore18 = require("firebase/firestore");
|
|
5268
5287
|
var import_geofire_common3 = require("geofire-common");
|
|
5269
|
-
var
|
|
5288
|
+
var import_zod17 = require("zod");
|
|
5270
5289
|
|
|
5271
5290
|
// src/services/clinic/utils/photos.utils.ts
|
|
5272
5291
|
var import_storage4 = require("firebase/storage");
|
|
@@ -5464,7 +5483,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
5464
5483
|
});
|
|
5465
5484
|
return groupData;
|
|
5466
5485
|
} catch (error) {
|
|
5467
|
-
if (error instanceof
|
|
5486
|
+
if (error instanceof import_zod17.z.ZodError) {
|
|
5468
5487
|
console.error(
|
|
5469
5488
|
"[CLINIC_GROUP] Zod validation error:",
|
|
5470
5489
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -5869,17 +5888,54 @@ var ClinicGroupService = class extends BaseService {
|
|
|
5869
5888
|
// but to add them to a subcollection called adminTokens that belongs to a specific clinicGroup document
|
|
5870
5889
|
// TODO: Add granular control over admin permissions, e.g. only allow admins to manage certain clinics to tokens directly
|
|
5871
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
|
+
}
|
|
5872
5928
|
};
|
|
5873
5929
|
|
|
5874
5930
|
// src/services/clinic/clinic.service.ts
|
|
5875
5931
|
var import_firestore24 = require("firebase/firestore");
|
|
5876
5932
|
var import_geofire_common7 = require("geofire-common");
|
|
5877
|
-
var
|
|
5933
|
+
var import_zod19 = require("zod");
|
|
5878
5934
|
|
|
5879
5935
|
// src/services/clinic/utils/clinic.utils.ts
|
|
5880
5936
|
var import_firestore19 = require("firebase/firestore");
|
|
5881
5937
|
var import_geofire_common4 = require("geofire-common");
|
|
5882
|
-
var
|
|
5938
|
+
var import_zod18 = require("zod");
|
|
5883
5939
|
async function getClinic(db, clinicId) {
|
|
5884
5940
|
const docRef = (0, import_firestore19.doc)(db, CLINICS_COLLECTION, clinicId);
|
|
5885
5941
|
const docSnap = await (0, import_firestore19.getDoc)(docRef);
|
|
@@ -6941,7 +6997,7 @@ var ClinicService = class extends BaseService {
|
|
|
6941
6997
|
if (!savedClinic) throw new Error("Failed to retrieve created clinic");
|
|
6942
6998
|
return savedClinic;
|
|
6943
6999
|
} catch (error) {
|
|
6944
|
-
if (error instanceof
|
|
7000
|
+
if (error instanceof import_zod19.z.ZodError) {
|
|
6945
7001
|
throw new Error("Invalid clinic data: " + error.message);
|
|
6946
7002
|
}
|
|
6947
7003
|
console.error("Error creating clinic:", error);
|
|
@@ -7021,7 +7077,7 @@ var ClinicService = class extends BaseService {
|
|
|
7021
7077
|
if (!updatedClinic) throw new Error("Failed to retrieve updated clinic");
|
|
7022
7078
|
return updatedClinic;
|
|
7023
7079
|
} catch (error) {
|
|
7024
|
-
if (error instanceof
|
|
7080
|
+
if (error instanceof import_zod19.z.ZodError) {
|
|
7025
7081
|
throw new Error("Invalid clinic update data: " + error.message);
|
|
7026
7082
|
}
|
|
7027
7083
|
console.error(`Error updating clinic ${clinicId}:`, error);
|
|
@@ -7038,6 +7094,16 @@ var ClinicService = class extends BaseService {
|
|
|
7038
7094
|
updatedAt: (0, import_firestore24.serverTimestamp)()
|
|
7039
7095
|
});
|
|
7040
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
|
+
}
|
|
7041
7107
|
/**
|
|
7042
7108
|
* Dohvata kliniku po ID-u
|
|
7043
7109
|
*/
|
|
@@ -7343,7 +7409,11 @@ var AuthService = class extends BaseService {
|
|
|
7343
7409
|
// Use admin profile ID, not user UID
|
|
7344
7410
|
isActive: true,
|
|
7345
7411
|
logo: data.clinicGroupData.logo || null,
|
|
7346
|
-
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
|
+
}
|
|
7347
7417
|
};
|
|
7348
7418
|
console.log("[AUTH] Clinic group data prepared", {
|
|
7349
7419
|
groupName: createClinicGroupData.name
|
|
@@ -7483,7 +7553,7 @@ var AuthService = class extends BaseService {
|
|
|
7483
7553
|
clinicAdmin: adminProfile
|
|
7484
7554
|
};
|
|
7485
7555
|
} catch (error) {
|
|
7486
|
-
if (error instanceof
|
|
7556
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7487
7557
|
console.error(
|
|
7488
7558
|
"[AUTH] Zod validation error in signUpClinicAdmin:",
|
|
7489
7559
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -7658,7 +7728,7 @@ var AuthService = class extends BaseService {
|
|
|
7658
7728
|
email
|
|
7659
7729
|
);
|
|
7660
7730
|
} catch (error) {
|
|
7661
|
-
if (error instanceof
|
|
7731
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7662
7732
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7663
7733
|
}
|
|
7664
7734
|
const firebaseError = error;
|
|
@@ -7781,7 +7851,7 @@ var AuthService = class extends BaseService {
|
|
|
7781
7851
|
await emailSchema.parseAsync(email);
|
|
7782
7852
|
await (0, import_auth5.sendPasswordResetEmail)(this.auth, email);
|
|
7783
7853
|
} catch (error) {
|
|
7784
|
-
if (error instanceof
|
|
7854
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7785
7855
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7786
7856
|
}
|
|
7787
7857
|
const firebaseError = error;
|
|
@@ -7820,7 +7890,7 @@ var AuthService = class extends BaseService {
|
|
|
7820
7890
|
await passwordSchema.parseAsync(newPassword);
|
|
7821
7891
|
await (0, import_auth5.confirmPasswordReset)(this.auth, oobCode, newPassword);
|
|
7822
7892
|
} catch (error) {
|
|
7823
|
-
if (error instanceof
|
|
7893
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7824
7894
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7825
7895
|
}
|
|
7826
7896
|
const firebaseError = error;
|
|
@@ -7989,7 +8059,7 @@ var AuthService = class extends BaseService {
|
|
|
7989
8059
|
practitioner
|
|
7990
8060
|
};
|
|
7991
8061
|
} catch (error) {
|
|
7992
|
-
if (error instanceof
|
|
8062
|
+
if (error instanceof import_zod20.z.ZodError) {
|
|
7993
8063
|
console.error(
|
|
7994
8064
|
"[AUTH] Zod validation error in signUpPractitioner:",
|
|
7995
8065
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -8267,63 +8337,63 @@ var import_firestore27 = require("firebase/firestore");
|
|
|
8267
8337
|
var PROCEDURES_COLLECTION = "procedures";
|
|
8268
8338
|
|
|
8269
8339
|
// src/validations/procedure.schema.ts
|
|
8270
|
-
var
|
|
8271
|
-
var createProcedureSchema =
|
|
8272
|
-
name:
|
|
8273
|
-
description:
|
|
8274
|
-
family:
|
|
8275
|
-
categoryId:
|
|
8276
|
-
subcategoryId:
|
|
8277
|
-
technologyId:
|
|
8278
|
-
productId:
|
|
8279
|
-
price:
|
|
8280
|
-
currency:
|
|
8281
|
-
pricingMeasure:
|
|
8282
|
-
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),
|
|
8283
8353
|
// Max 8 hours
|
|
8284
|
-
practitionerId:
|
|
8285
|
-
clinicBranchId:
|
|
8286
|
-
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()
|
|
8287
8357
|
});
|
|
8288
|
-
var updateProcedureSchema =
|
|
8289
|
-
name:
|
|
8290
|
-
description:
|
|
8291
|
-
price:
|
|
8292
|
-
currency:
|
|
8293
|
-
pricingMeasure:
|
|
8294
|
-
duration:
|
|
8295
|
-
isActive:
|
|
8296
|
-
practitionerId:
|
|
8297
|
-
categoryId:
|
|
8298
|
-
subcategoryId:
|
|
8299
|
-
technologyId:
|
|
8300
|
-
productId:
|
|
8301
|
-
clinicBranchId:
|
|
8302
|
-
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()
|
|
8303
8373
|
});
|
|
8304
8374
|
var procedureSchema = createProcedureSchema.extend({
|
|
8305
|
-
id:
|
|
8306
|
-
category:
|
|
8375
|
+
id: import_zod21.z.string().min(1),
|
|
8376
|
+
category: import_zod21.z.any(),
|
|
8307
8377
|
// We'll validate the full category object separately
|
|
8308
|
-
subcategory:
|
|
8378
|
+
subcategory: import_zod21.z.any(),
|
|
8309
8379
|
// We'll validate the full subcategory object separately
|
|
8310
|
-
technology:
|
|
8380
|
+
technology: import_zod21.z.any(),
|
|
8311
8381
|
// We'll validate the full technology object separately
|
|
8312
|
-
product:
|
|
8382
|
+
product: import_zod21.z.any(),
|
|
8313
8383
|
// We'll validate the full product object separately
|
|
8314
|
-
blockingConditions:
|
|
8384
|
+
blockingConditions: import_zod21.z.array(import_zod21.z.any()),
|
|
8315
8385
|
// We'll validate blocking conditions separately
|
|
8316
|
-
contraindications:
|
|
8386
|
+
contraindications: import_zod21.z.array(import_zod21.z.any()),
|
|
8317
8387
|
// We'll validate contraindications separately
|
|
8318
|
-
treatmentBenefits:
|
|
8388
|
+
treatmentBenefits: import_zod21.z.array(import_zod21.z.any()),
|
|
8319
8389
|
// We'll validate treatment benefits separately
|
|
8320
|
-
preRequirements:
|
|
8390
|
+
preRequirements: import_zod21.z.array(import_zod21.z.any()),
|
|
8321
8391
|
// We'll validate requirements separately
|
|
8322
|
-
postRequirements:
|
|
8392
|
+
postRequirements: import_zod21.z.array(import_zod21.z.any()),
|
|
8323
8393
|
// We'll validate requirements separately
|
|
8324
|
-
certificationRequirement:
|
|
8394
|
+
certificationRequirement: import_zod21.z.any(),
|
|
8325
8395
|
// We'll validate certification requirement separately
|
|
8326
|
-
documentationTemplates:
|
|
8396
|
+
documentationTemplates: import_zod21.z.array(import_zod21.z.any()),
|
|
8327
8397
|
// We'll validate documentation templates separately
|
|
8328
8398
|
clinicInfo: clinicInfoSchema,
|
|
8329
8399
|
// Clinic info validation
|
|
@@ -8331,9 +8401,9 @@ var procedureSchema = createProcedureSchema.extend({
|
|
|
8331
8401
|
// Doctor info validation
|
|
8332
8402
|
reviewInfo: procedureReviewInfoSchema,
|
|
8333
8403
|
// Procedure review info validation
|
|
8334
|
-
isActive:
|
|
8335
|
-
createdAt:
|
|
8336
|
-
updatedAt:
|
|
8404
|
+
isActive: import_zod21.z.boolean(),
|
|
8405
|
+
createdAt: import_zod21.z.date(),
|
|
8406
|
+
updatedAt: import_zod21.z.date()
|
|
8337
8407
|
});
|
|
8338
8408
|
|
|
8339
8409
|
// src/services/procedure/procedure.service.ts
|
|
@@ -9508,42 +9578,42 @@ var SYNCED_CALENDARS_COLLECTION = "syncedCalendars";
|
|
|
9508
9578
|
var import_firestore40 = require("firebase/firestore");
|
|
9509
9579
|
|
|
9510
9580
|
// src/validations/calendar.schema.ts
|
|
9511
|
-
var
|
|
9581
|
+
var import_zod23 = require("zod");
|
|
9512
9582
|
var import_firestore31 = require("firebase/firestore");
|
|
9513
9583
|
|
|
9514
9584
|
// src/validations/profile-info.schema.ts
|
|
9515
|
-
var
|
|
9585
|
+
var import_zod22 = require("zod");
|
|
9516
9586
|
var import_firestore30 = require("firebase/firestore");
|
|
9517
|
-
var clinicInfoSchema2 =
|
|
9518
|
-
id:
|
|
9519
|
-
featuredPhoto:
|
|
9520
|
-
name:
|
|
9521
|
-
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(),
|
|
9522
9592
|
location: clinicLocationSchema,
|
|
9523
9593
|
contactInfo: clinicContactInfoSchema
|
|
9524
9594
|
});
|
|
9525
|
-
var practitionerProfileInfoSchema =
|
|
9526
|
-
id:
|
|
9527
|
-
practitionerPhoto:
|
|
9528
|
-
name:
|
|
9529
|
-
email:
|
|
9530
|
-
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(),
|
|
9531
9601
|
certification: practitionerCertificationSchema
|
|
9532
9602
|
});
|
|
9533
|
-
var patientProfileInfoSchema =
|
|
9534
|
-
id:
|
|
9535
|
-
fullName:
|
|
9536
|
-
email:
|
|
9537
|
-
phone:
|
|
9538
|
-
dateOfBirth:
|
|
9539
|
-
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)
|
|
9540
9610
|
});
|
|
9541
9611
|
|
|
9542
9612
|
// src/validations/calendar.schema.ts
|
|
9543
9613
|
var MIN_APPOINTMENT_DURATION = 15;
|
|
9544
|
-
var calendarEventTimeSchema =
|
|
9545
|
-
start:
|
|
9546
|
-
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))
|
|
9547
9617
|
}).refine(
|
|
9548
9618
|
(data) => {
|
|
9549
9619
|
const startDate = data.start instanceof import_firestore31.Timestamp ? data.start.toDate() : data.start;
|
|
@@ -9564,46 +9634,46 @@ var calendarEventTimeSchema = import_zod22.z.object({
|
|
|
9564
9634
|
path: ["start"]
|
|
9565
9635
|
}
|
|
9566
9636
|
);
|
|
9567
|
-
var timeSlotSchema2 =
|
|
9568
|
-
start:
|
|
9569
|
-
end:
|
|
9570
|
-
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()
|
|
9571
9641
|
}).refine((data) => data.start < data.end, {
|
|
9572
9642
|
message: "End time must be after start time",
|
|
9573
9643
|
path: ["end"]
|
|
9574
9644
|
});
|
|
9575
|
-
var syncedCalendarEventSchema =
|
|
9576
|
-
eventId:
|
|
9577
|
-
syncedCalendarProvider:
|
|
9578
|
-
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))
|
|
9579
9649
|
});
|
|
9580
|
-
var procedureInfoSchema =
|
|
9581
|
-
name:
|
|
9582
|
-
description:
|
|
9583
|
-
duration:
|
|
9584
|
-
price:
|
|
9585
|
-
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)
|
|
9586
9656
|
});
|
|
9587
|
-
var procedureCategorizationSchema =
|
|
9588
|
-
procedureFamily:
|
|
9657
|
+
var procedureCategorizationSchema = import_zod23.z.object({
|
|
9658
|
+
procedureFamily: import_zod23.z.string(),
|
|
9589
9659
|
// Replace with proper enum when available
|
|
9590
|
-
procedureCategory:
|
|
9660
|
+
procedureCategory: import_zod23.z.string(),
|
|
9591
9661
|
// Replace with proper enum when available
|
|
9592
|
-
procedureSubcategory:
|
|
9662
|
+
procedureSubcategory: import_zod23.z.string(),
|
|
9593
9663
|
// Replace with proper enum when available
|
|
9594
|
-
procedureTechnology:
|
|
9664
|
+
procedureTechnology: import_zod23.z.string(),
|
|
9595
9665
|
// Replace with proper enum when available
|
|
9596
|
-
procedureProduct:
|
|
9666
|
+
procedureProduct: import_zod23.z.string()
|
|
9597
9667
|
// Replace with proper enum when available
|
|
9598
9668
|
});
|
|
9599
|
-
var createAppointmentSchema2 =
|
|
9600
|
-
clinicId:
|
|
9601
|
-
doctorId:
|
|
9602
|
-
patientId:
|
|
9603
|
-
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"),
|
|
9604
9674
|
eventLocation: clinicLocationSchema,
|
|
9605
9675
|
eventTime: calendarEventTimeSchema,
|
|
9606
|
-
description:
|
|
9676
|
+
description: import_zod23.z.string().optional()
|
|
9607
9677
|
}).refine(
|
|
9608
9678
|
(data) => {
|
|
9609
9679
|
return true;
|
|
@@ -9612,73 +9682,73 @@ var createAppointmentSchema2 = import_zod22.z.object({
|
|
|
9612
9682
|
message: "Invalid appointment parameters"
|
|
9613
9683
|
}
|
|
9614
9684
|
);
|
|
9615
|
-
var updateAppointmentSchema2 =
|
|
9616
|
-
appointmentId:
|
|
9617
|
-
clinicId:
|
|
9618
|
-
doctorId:
|
|
9619
|
-
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"),
|
|
9620
9690
|
eventTime: calendarEventTimeSchema.optional(),
|
|
9621
|
-
description:
|
|
9622
|
-
status:
|
|
9691
|
+
description: import_zod23.z.string().optional(),
|
|
9692
|
+
status: import_zod23.z.nativeEnum(CalendarEventStatus).optional()
|
|
9623
9693
|
});
|
|
9624
|
-
var createCalendarEventSchema =
|
|
9625
|
-
id:
|
|
9626
|
-
clinicBranchId:
|
|
9627
|
-
clinicBranchInfo:
|
|
9628
|
-
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(),
|
|
9629
9699
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
9630
|
-
patientProfileId:
|
|
9700
|
+
patientProfileId: import_zod23.z.string().nullable().optional(),
|
|
9631
9701
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
9632
|
-
procedureId:
|
|
9633
|
-
appointmentId:
|
|
9634
|
-
syncedCalendarEventId:
|
|
9635
|
-
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"),
|
|
9636
9706
|
eventLocation: clinicLocationSchema.optional(),
|
|
9637
9707
|
eventTime: calendarEventTimeSchema,
|
|
9638
|
-
description:
|
|
9639
|
-
status:
|
|
9640
|
-
syncStatus:
|
|
9641
|
-
eventType:
|
|
9642
|
-
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(),
|
|
9643
9713
|
// FieldValue for server timestamp
|
|
9644
|
-
updatedAt:
|
|
9714
|
+
updatedAt: import_zod23.z.any()
|
|
9645
9715
|
// FieldValue for server timestamp
|
|
9646
9716
|
});
|
|
9647
|
-
var updateCalendarEventSchema =
|
|
9648
|
-
syncedCalendarEventId:
|
|
9649
|
-
appointmentId:
|
|
9650
|
-
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(),
|
|
9651
9721
|
eventTime: calendarEventTimeSchema.optional(),
|
|
9652
|
-
description:
|
|
9653
|
-
status:
|
|
9654
|
-
syncStatus:
|
|
9655
|
-
eventType:
|
|
9656
|
-
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()
|
|
9657
9727
|
// FieldValue for server timestamp
|
|
9658
9728
|
});
|
|
9659
|
-
var calendarEventSchema =
|
|
9660
|
-
id:
|
|
9661
|
-
clinicBranchId:
|
|
9662
|
-
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(),
|
|
9663
9733
|
// Will be replaced with proper clinic info schema
|
|
9664
|
-
practitionerProfileId:
|
|
9734
|
+
practitionerProfileId: import_zod23.z.string().nullable().optional(),
|
|
9665
9735
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
9666
|
-
patientProfileId:
|
|
9736
|
+
patientProfileId: import_zod23.z.string().nullable().optional(),
|
|
9667
9737
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
9668
|
-
procedureId:
|
|
9738
|
+
procedureId: import_zod23.z.string().nullable().optional(),
|
|
9669
9739
|
procedureInfo: procedureInfoSchema.nullable().optional(),
|
|
9670
9740
|
procedureCategorization: procedureCategorizationSchema.nullable().optional(),
|
|
9671
|
-
appointmentId:
|
|
9672
|
-
syncedCalendarEventId:
|
|
9673
|
-
eventName:
|
|
9741
|
+
appointmentId: import_zod23.z.string().nullable().optional(),
|
|
9742
|
+
syncedCalendarEventId: import_zod23.z.array(syncedCalendarEventSchema).nullable().optional(),
|
|
9743
|
+
eventName: import_zod23.z.string(),
|
|
9674
9744
|
eventLocation: clinicLocationSchema.optional(),
|
|
9675
9745
|
eventTime: calendarEventTimeSchema,
|
|
9676
|
-
description:
|
|
9677
|
-
status:
|
|
9678
|
-
syncStatus:
|
|
9679
|
-
eventType:
|
|
9680
|
-
createdAt:
|
|
9681
|
-
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))
|
|
9682
9752
|
});
|
|
9683
9753
|
|
|
9684
9754
|
// src/services/calendar/utils/clinic.utils.ts
|
|
@@ -12218,13 +12288,13 @@ var import_firestore41 = require("firebase/firestore");
|
|
|
12218
12288
|
var REVIEWS_COLLECTION = "reviews";
|
|
12219
12289
|
|
|
12220
12290
|
// src/services/reviews/reviews.service.ts
|
|
12221
|
-
var
|
|
12291
|
+
var import_zod24 = require("zod");
|
|
12222
12292
|
var ReviewService = class extends BaseService {
|
|
12223
12293
|
constructor(db, auth, app) {
|
|
12224
12294
|
super(db, auth, app);
|
|
12225
12295
|
}
|
|
12226
12296
|
/**
|
|
12227
|
-
* Creates a new review
|
|
12297
|
+
* Creates a new review
|
|
12228
12298
|
* @param data - The review data to create
|
|
12229
12299
|
* @param appointmentId - ID of the completed appointment
|
|
12230
12300
|
* @returns The created review
|
|
@@ -12303,28 +12373,9 @@ var ReviewService = class extends BaseService {
|
|
|
12303
12373
|
createdAt: (0, import_firestore41.serverTimestamp)(),
|
|
12304
12374
|
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12305
12375
|
});
|
|
12306
|
-
const updatePromises = [];
|
|
12307
|
-
if (data.clinicReview) {
|
|
12308
|
-
updatePromises.push(
|
|
12309
|
-
this.updateClinicReviewInfo(data.clinicReview.clinicId)
|
|
12310
|
-
);
|
|
12311
|
-
}
|
|
12312
|
-
if (data.practitionerReview) {
|
|
12313
|
-
updatePromises.push(
|
|
12314
|
-
this.updatePractitionerReviewInfo(
|
|
12315
|
-
data.practitionerReview.practitionerId
|
|
12316
|
-
)
|
|
12317
|
-
);
|
|
12318
|
-
}
|
|
12319
|
-
if (data.procedureReview) {
|
|
12320
|
-
updatePromises.push(
|
|
12321
|
-
this.updateProcedureReviewInfo(data.procedureReview.procedureId)
|
|
12322
|
-
);
|
|
12323
|
-
}
|
|
12324
|
-
await Promise.all(updatePromises);
|
|
12325
12376
|
return review;
|
|
12326
12377
|
} catch (error) {
|
|
12327
|
-
if (error instanceof
|
|
12378
|
+
if (error instanceof import_zod24.z.ZodError) {
|
|
12328
12379
|
throw new Error(`Invalid review data: ${error.message}`);
|
|
12329
12380
|
}
|
|
12330
12381
|
throw error;
|
|
@@ -12412,7 +12463,7 @@ var ReviewService = class extends BaseService {
|
|
|
12412
12463
|
return snapshot.docs[0].data();
|
|
12413
12464
|
}
|
|
12414
12465
|
/**
|
|
12415
|
-
* Deletes a review
|
|
12466
|
+
* Deletes a review
|
|
12416
12467
|
* @param reviewId The ID of the review to delete
|
|
12417
12468
|
*/
|
|
12418
12469
|
async deleteReview(reviewId) {
|
|
@@ -12421,389 +12472,6 @@ var ReviewService = class extends BaseService {
|
|
|
12421
12472
|
throw new Error(`Review with ID ${reviewId} not found`);
|
|
12422
12473
|
}
|
|
12423
12474
|
await (0, import_firestore41.deleteDoc)((0, import_firestore41.doc)(this.db, REVIEWS_COLLECTION, reviewId));
|
|
12424
|
-
const updatePromises = [];
|
|
12425
|
-
if (review.clinicReview) {
|
|
12426
|
-
updatePromises.push(
|
|
12427
|
-
this.updateClinicReviewInfo(
|
|
12428
|
-
review.clinicReview.clinicId,
|
|
12429
|
-
review.clinicReview,
|
|
12430
|
-
true
|
|
12431
|
-
)
|
|
12432
|
-
);
|
|
12433
|
-
}
|
|
12434
|
-
if (review.practitionerReview) {
|
|
12435
|
-
updatePromises.push(
|
|
12436
|
-
this.updatePractitionerReviewInfo(
|
|
12437
|
-
review.practitionerReview.practitionerId,
|
|
12438
|
-
review.practitionerReview,
|
|
12439
|
-
true
|
|
12440
|
-
)
|
|
12441
|
-
);
|
|
12442
|
-
}
|
|
12443
|
-
if (review.procedureReview) {
|
|
12444
|
-
updatePromises.push(
|
|
12445
|
-
this.updateProcedureReviewInfo(
|
|
12446
|
-
review.procedureReview.procedureId,
|
|
12447
|
-
review.procedureReview,
|
|
12448
|
-
true
|
|
12449
|
-
)
|
|
12450
|
-
);
|
|
12451
|
-
}
|
|
12452
|
-
await Promise.all(updatePromises);
|
|
12453
|
-
}
|
|
12454
|
-
/**
|
|
12455
|
-
* Updates the review info for a clinic
|
|
12456
|
-
* @param clinicId The ID of the clinic to update
|
|
12457
|
-
* @param newReview Optional new review being added or removed
|
|
12458
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12459
|
-
* @returns The updated clinic review info
|
|
12460
|
-
*/
|
|
12461
|
-
async updateClinicReviewInfo(clinicId, newReview, isRemoval = false) {
|
|
12462
|
-
const clinicDoc = await (0, import_firestore41.getDoc)((0, import_firestore41.doc)(this.db, CLINICS_COLLECTION, clinicId));
|
|
12463
|
-
if (!clinicDoc.exists()) {
|
|
12464
|
-
throw new Error(`Clinic with ID ${clinicId} not found`);
|
|
12465
|
-
}
|
|
12466
|
-
const clinicData = clinicDoc.data();
|
|
12467
|
-
const currentReviewInfo = clinicData.reviewInfo || {
|
|
12468
|
-
totalReviews: 0,
|
|
12469
|
-
averageRating: 0,
|
|
12470
|
-
cleanliness: 0,
|
|
12471
|
-
facilities: 0,
|
|
12472
|
-
staffFriendliness: 0,
|
|
12473
|
-
waitingTime: 0,
|
|
12474
|
-
accessibility: 0,
|
|
12475
|
-
recommendationPercentage: 0
|
|
12476
|
-
};
|
|
12477
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12478
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, CLINICS_COLLECTION, clinicId), {
|
|
12479
|
-
reviewInfo: currentReviewInfo,
|
|
12480
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12481
|
-
});
|
|
12482
|
-
return currentReviewInfo;
|
|
12483
|
-
}
|
|
12484
|
-
let updatedReviewInfo;
|
|
12485
|
-
if (newReview) {
|
|
12486
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12487
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12488
|
-
if (newTotal === 0) {
|
|
12489
|
-
updatedReviewInfo = {
|
|
12490
|
-
totalReviews: 0,
|
|
12491
|
-
averageRating: 0,
|
|
12492
|
-
cleanliness: 0,
|
|
12493
|
-
facilities: 0,
|
|
12494
|
-
staffFriendliness: 0,
|
|
12495
|
-
waitingTime: 0,
|
|
12496
|
-
accessibility: 0,
|
|
12497
|
-
recommendationPercentage: 0
|
|
12498
|
-
};
|
|
12499
|
-
} else {
|
|
12500
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12501
|
-
const currentSum = currentAvg * oldTotal;
|
|
12502
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12503
|
-
const newAvg = newSum / newTotal;
|
|
12504
|
-
return Math.round(newAvg * 10) / 10;
|
|
12505
|
-
};
|
|
12506
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12507
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12508
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12509
|
-
updatedReviewInfo = {
|
|
12510
|
-
totalReviews: newTotal,
|
|
12511
|
-
averageRating: updateAverage(
|
|
12512
|
-
currentReviewInfo.averageRating,
|
|
12513
|
-
newReview.overallRating
|
|
12514
|
-
),
|
|
12515
|
-
cleanliness: updateAverage(
|
|
12516
|
-
currentReviewInfo.cleanliness,
|
|
12517
|
-
newReview.cleanliness
|
|
12518
|
-
),
|
|
12519
|
-
facilities: updateAverage(
|
|
12520
|
-
currentReviewInfo.facilities,
|
|
12521
|
-
newReview.facilities
|
|
12522
|
-
),
|
|
12523
|
-
staffFriendliness: updateAverage(
|
|
12524
|
-
currentReviewInfo.staffFriendliness,
|
|
12525
|
-
newReview.staffFriendliness
|
|
12526
|
-
),
|
|
12527
|
-
waitingTime: updateAverage(
|
|
12528
|
-
currentReviewInfo.waitingTime,
|
|
12529
|
-
newReview.waitingTime
|
|
12530
|
-
),
|
|
12531
|
-
accessibility: updateAverage(
|
|
12532
|
-
currentReviewInfo.accessibility,
|
|
12533
|
-
newReview.accessibility
|
|
12534
|
-
),
|
|
12535
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12536
|
-
};
|
|
12537
|
-
}
|
|
12538
|
-
} else {
|
|
12539
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12540
|
-
}
|
|
12541
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, CLINICS_COLLECTION, clinicId), {
|
|
12542
|
-
reviewInfo: updatedReviewInfo,
|
|
12543
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12544
|
-
});
|
|
12545
|
-
return updatedReviewInfo;
|
|
12546
|
-
}
|
|
12547
|
-
/**
|
|
12548
|
-
* Updates the review info for a practitioner
|
|
12549
|
-
* @param practitionerId The ID of the practitioner to update
|
|
12550
|
-
* @param newReview Optional new review being added or removed
|
|
12551
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12552
|
-
* @returns The updated practitioner review info
|
|
12553
|
-
*/
|
|
12554
|
-
async updatePractitionerReviewInfo(practitionerId, newReview, isRemoval = false) {
|
|
12555
|
-
const practitionerDoc = await (0, import_firestore41.getDoc)(
|
|
12556
|
-
(0, import_firestore41.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId)
|
|
12557
|
-
);
|
|
12558
|
-
if (!practitionerDoc.exists()) {
|
|
12559
|
-
throw new Error(`Practitioner with ID ${practitionerId} not found`);
|
|
12560
|
-
}
|
|
12561
|
-
const practitionerData = practitionerDoc.data();
|
|
12562
|
-
const currentReviewInfo = practitionerData.reviewInfo || {
|
|
12563
|
-
totalReviews: 0,
|
|
12564
|
-
averageRating: 0,
|
|
12565
|
-
knowledgeAndExpertise: 0,
|
|
12566
|
-
communicationSkills: 0,
|
|
12567
|
-
bedSideManner: 0,
|
|
12568
|
-
thoroughness: 0,
|
|
12569
|
-
trustworthiness: 0,
|
|
12570
|
-
recommendationPercentage: 0
|
|
12571
|
-
};
|
|
12572
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12573
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
12574
|
-
reviewInfo: currentReviewInfo,
|
|
12575
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12576
|
-
});
|
|
12577
|
-
return currentReviewInfo;
|
|
12578
|
-
}
|
|
12579
|
-
let updatedReviewInfo;
|
|
12580
|
-
if (newReview) {
|
|
12581
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12582
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12583
|
-
if (newTotal === 0) {
|
|
12584
|
-
updatedReviewInfo = {
|
|
12585
|
-
totalReviews: 0,
|
|
12586
|
-
averageRating: 0,
|
|
12587
|
-
knowledgeAndExpertise: 0,
|
|
12588
|
-
communicationSkills: 0,
|
|
12589
|
-
bedSideManner: 0,
|
|
12590
|
-
thoroughness: 0,
|
|
12591
|
-
trustworthiness: 0,
|
|
12592
|
-
recommendationPercentage: 0
|
|
12593
|
-
};
|
|
12594
|
-
} else {
|
|
12595
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12596
|
-
const currentSum = currentAvg * oldTotal;
|
|
12597
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12598
|
-
const newAvg = newSum / newTotal;
|
|
12599
|
-
return Math.round(newAvg * 10) / 10;
|
|
12600
|
-
};
|
|
12601
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12602
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12603
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12604
|
-
updatedReviewInfo = {
|
|
12605
|
-
totalReviews: newTotal,
|
|
12606
|
-
averageRating: updateAverage(
|
|
12607
|
-
currentReviewInfo.averageRating,
|
|
12608
|
-
newReview.overallRating
|
|
12609
|
-
),
|
|
12610
|
-
knowledgeAndExpertise: updateAverage(
|
|
12611
|
-
currentReviewInfo.knowledgeAndExpertise,
|
|
12612
|
-
newReview.knowledgeAndExpertise
|
|
12613
|
-
),
|
|
12614
|
-
communicationSkills: updateAverage(
|
|
12615
|
-
currentReviewInfo.communicationSkills,
|
|
12616
|
-
newReview.communicationSkills
|
|
12617
|
-
),
|
|
12618
|
-
bedSideManner: updateAverage(
|
|
12619
|
-
currentReviewInfo.bedSideManner,
|
|
12620
|
-
newReview.bedSideManner
|
|
12621
|
-
),
|
|
12622
|
-
thoroughness: updateAverage(
|
|
12623
|
-
currentReviewInfo.thoroughness,
|
|
12624
|
-
newReview.thoroughness
|
|
12625
|
-
),
|
|
12626
|
-
trustworthiness: updateAverage(
|
|
12627
|
-
currentReviewInfo.trustworthiness,
|
|
12628
|
-
newReview.trustworthiness
|
|
12629
|
-
),
|
|
12630
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12631
|
-
};
|
|
12632
|
-
}
|
|
12633
|
-
} else {
|
|
12634
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12635
|
-
}
|
|
12636
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
12637
|
-
reviewInfo: updatedReviewInfo,
|
|
12638
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12639
|
-
});
|
|
12640
|
-
await this.updateDoctorInfoInProcedures(
|
|
12641
|
-
practitionerId,
|
|
12642
|
-
updatedReviewInfo.averageRating
|
|
12643
|
-
);
|
|
12644
|
-
return updatedReviewInfo;
|
|
12645
|
-
}
|
|
12646
|
-
/**
|
|
12647
|
-
* Updates the review info for a procedure
|
|
12648
|
-
* @param procedureId The ID of the procedure to update
|
|
12649
|
-
* @param newReview Optional new review being added or removed
|
|
12650
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12651
|
-
* @returns The updated procedure review info
|
|
12652
|
-
*/
|
|
12653
|
-
async updateProcedureReviewInfo(procedureId, newReview, isRemoval = false) {
|
|
12654
|
-
const procedureDoc = await (0, import_firestore41.getDoc)(
|
|
12655
|
-
(0, import_firestore41.doc)(this.db, PROCEDURES_COLLECTION, procedureId)
|
|
12656
|
-
);
|
|
12657
|
-
if (!procedureDoc.exists()) {
|
|
12658
|
-
throw new Error(`Procedure with ID ${procedureId} not found`);
|
|
12659
|
-
}
|
|
12660
|
-
const procedureData = procedureDoc.data();
|
|
12661
|
-
const currentReviewInfo = procedureData.reviewInfo || {
|
|
12662
|
-
totalReviews: 0,
|
|
12663
|
-
averageRating: 0,
|
|
12664
|
-
effectivenessOfTreatment: 0,
|
|
12665
|
-
outcomeExplanation: 0,
|
|
12666
|
-
painManagement: 0,
|
|
12667
|
-
followUpCare: 0,
|
|
12668
|
-
valueForMoney: 0,
|
|
12669
|
-
recommendationPercentage: 0
|
|
12670
|
-
};
|
|
12671
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12672
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
12673
|
-
reviewInfo: currentReviewInfo,
|
|
12674
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12675
|
-
});
|
|
12676
|
-
return currentReviewInfo;
|
|
12677
|
-
}
|
|
12678
|
-
let updatedReviewInfo;
|
|
12679
|
-
if (newReview) {
|
|
12680
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12681
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12682
|
-
if (newTotal === 0) {
|
|
12683
|
-
updatedReviewInfo = {
|
|
12684
|
-
totalReviews: 0,
|
|
12685
|
-
averageRating: 0,
|
|
12686
|
-
effectivenessOfTreatment: 0,
|
|
12687
|
-
outcomeExplanation: 0,
|
|
12688
|
-
painManagement: 0,
|
|
12689
|
-
followUpCare: 0,
|
|
12690
|
-
valueForMoney: 0,
|
|
12691
|
-
recommendationPercentage: 0
|
|
12692
|
-
};
|
|
12693
|
-
} else {
|
|
12694
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12695
|
-
const currentSum = currentAvg * oldTotal;
|
|
12696
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12697
|
-
const newAvg = newSum / newTotal;
|
|
12698
|
-
return Math.round(newAvg * 10) / 10;
|
|
12699
|
-
};
|
|
12700
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12701
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12702
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12703
|
-
updatedReviewInfo = {
|
|
12704
|
-
totalReviews: newTotal,
|
|
12705
|
-
averageRating: updateAverage(
|
|
12706
|
-
currentReviewInfo.averageRating,
|
|
12707
|
-
newReview.overallRating
|
|
12708
|
-
),
|
|
12709
|
-
effectivenessOfTreatment: updateAverage(
|
|
12710
|
-
currentReviewInfo.effectivenessOfTreatment,
|
|
12711
|
-
newReview.effectivenessOfTreatment
|
|
12712
|
-
),
|
|
12713
|
-
outcomeExplanation: updateAverage(
|
|
12714
|
-
currentReviewInfo.outcomeExplanation,
|
|
12715
|
-
newReview.outcomeExplanation
|
|
12716
|
-
),
|
|
12717
|
-
painManagement: updateAverage(
|
|
12718
|
-
currentReviewInfo.painManagement,
|
|
12719
|
-
newReview.painManagement
|
|
12720
|
-
),
|
|
12721
|
-
followUpCare: updateAverage(
|
|
12722
|
-
currentReviewInfo.followUpCare,
|
|
12723
|
-
newReview.followUpCare
|
|
12724
|
-
),
|
|
12725
|
-
valueForMoney: updateAverage(
|
|
12726
|
-
currentReviewInfo.valueForMoney,
|
|
12727
|
-
newReview.valueForMoney
|
|
12728
|
-
),
|
|
12729
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12730
|
-
};
|
|
12731
|
-
}
|
|
12732
|
-
} else {
|
|
12733
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12734
|
-
}
|
|
12735
|
-
await (0, import_firestore41.updateDoc)((0, import_firestore41.doc)(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
12736
|
-
reviewInfo: updatedReviewInfo,
|
|
12737
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12738
|
-
});
|
|
12739
|
-
return updatedReviewInfo;
|
|
12740
|
-
}
|
|
12741
|
-
/**
|
|
12742
|
-
* Updates doctorInfo rating in all procedures for a practitioner
|
|
12743
|
-
* @param practitionerId The ID of the practitioner
|
|
12744
|
-
* @param rating The new rating to set
|
|
12745
|
-
*/
|
|
12746
|
-
async updateDoctorInfoInProcedures(practitionerId, rating) {
|
|
12747
|
-
const q = (0, import_firestore41.query)(
|
|
12748
|
-
(0, import_firestore41.collection)(this.db, PROCEDURES_COLLECTION),
|
|
12749
|
-
(0, import_firestore41.where)("practitionerId", "==", practitionerId)
|
|
12750
|
-
);
|
|
12751
|
-
const snapshot = await (0, import_firestore41.getDocs)(q);
|
|
12752
|
-
if (snapshot.empty) {
|
|
12753
|
-
return;
|
|
12754
|
-
}
|
|
12755
|
-
const batch = (0, import_firestore41.writeBatch)(this.db);
|
|
12756
|
-
snapshot.docs.forEach((docSnapshot) => {
|
|
12757
|
-
const procedureRef = (0, import_firestore41.doc)(this.db, PROCEDURES_COLLECTION, docSnapshot.id);
|
|
12758
|
-
batch.update(procedureRef, {
|
|
12759
|
-
"doctorInfo.rating": rating,
|
|
12760
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12761
|
-
});
|
|
12762
|
-
});
|
|
12763
|
-
await batch.commit();
|
|
12764
|
-
}
|
|
12765
|
-
/**
|
|
12766
|
-
* Verifies a review as checked by admin/staff
|
|
12767
|
-
* @param reviewId The ID of the review to verify
|
|
12768
|
-
*/
|
|
12769
|
-
async verifyReview(reviewId) {
|
|
12770
|
-
const review = await this.getReview(reviewId);
|
|
12771
|
-
if (!review) {
|
|
12772
|
-
throw new Error(`Review with ID ${reviewId} not found`);
|
|
12773
|
-
}
|
|
12774
|
-
const batch = (0, import_firestore41.writeBatch)(this.db);
|
|
12775
|
-
batch.update((0, import_firestore41.doc)(this.db, REVIEWS_COLLECTION, reviewId), {
|
|
12776
|
-
updatedAt: (0, import_firestore41.serverTimestamp)()
|
|
12777
|
-
});
|
|
12778
|
-
if (review.clinicReview) {
|
|
12779
|
-
review.clinicReview.isVerified = true;
|
|
12780
|
-
}
|
|
12781
|
-
if (review.practitionerReview) {
|
|
12782
|
-
review.practitionerReview.isVerified = true;
|
|
12783
|
-
}
|
|
12784
|
-
if (review.procedureReview) {
|
|
12785
|
-
review.procedureReview.isVerified = true;
|
|
12786
|
-
}
|
|
12787
|
-
await batch.commit();
|
|
12788
|
-
const updatePromises = [];
|
|
12789
|
-
if (review.clinicReview) {
|
|
12790
|
-
updatePromises.push(
|
|
12791
|
-
this.updateClinicReviewInfo(review.clinicReview.clinicId)
|
|
12792
|
-
);
|
|
12793
|
-
}
|
|
12794
|
-
if (review.practitionerReview) {
|
|
12795
|
-
updatePromises.push(
|
|
12796
|
-
this.updatePractitionerReviewInfo(
|
|
12797
|
-
review.practitionerReview.practitionerId
|
|
12798
|
-
)
|
|
12799
|
-
);
|
|
12800
|
-
}
|
|
12801
|
-
if (review.procedureReview) {
|
|
12802
|
-
updatePromises.push(
|
|
12803
|
-
this.updateProcedureReviewInfo(review.procedureReview.procedureId)
|
|
12804
|
-
);
|
|
12805
|
-
}
|
|
12806
|
-
await Promise.all(updatePromises);
|
|
12807
12475
|
}
|
|
12808
12476
|
/**
|
|
12809
12477
|
* Calculates the average of an array of numbers
|
|
@@ -14867,63 +14535,63 @@ var ProductService = class extends BaseService {
|
|
|
14867
14535
|
};
|
|
14868
14536
|
|
|
14869
14537
|
// src/validations/notification.schema.ts
|
|
14870
|
-
var
|
|
14871
|
-
var baseNotificationSchema =
|
|
14872
|
-
id:
|
|
14873
|
-
userId:
|
|
14874
|
-
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(),
|
|
14875
14543
|
// Timestamp
|
|
14876
|
-
notificationType:
|
|
14877
|
-
notificationTokens:
|
|
14878
|
-
status:
|
|
14879
|
-
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(),
|
|
14880
14548
|
// Timestamp
|
|
14881
|
-
updatedAt:
|
|
14549
|
+
updatedAt: import_zod25.z.any().optional(),
|
|
14882
14550
|
// Timestamp
|
|
14883
|
-
title:
|
|
14884
|
-
body:
|
|
14885
|
-
isRead:
|
|
14886
|
-
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)
|
|
14887
14555
|
});
|
|
14888
14556
|
var preRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
14889
|
-
notificationType:
|
|
14890
|
-
treatmentId:
|
|
14891
|
-
requirements:
|
|
14892
|
-
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()
|
|
14893
14561
|
// Timestamp
|
|
14894
14562
|
});
|
|
14895
14563
|
var postRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
14896
|
-
notificationType:
|
|
14564
|
+
notificationType: import_zod25.z.literal(
|
|
14897
14565
|
"postRequirementInstructionDue" /* POST_REQUIREMENT_INSTRUCTION_DUE */
|
|
14898
14566
|
),
|
|
14899
|
-
treatmentId:
|
|
14900
|
-
requirements:
|
|
14901
|
-
deadline:
|
|
14567
|
+
treatmentId: import_zod25.z.string(),
|
|
14568
|
+
requirements: import_zod25.z.array(import_zod25.z.string()),
|
|
14569
|
+
deadline: import_zod25.z.any()
|
|
14902
14570
|
// Timestamp
|
|
14903
14571
|
});
|
|
14904
14572
|
var requirementInstructionDueNotificationSchema = baseNotificationSchema.extend({
|
|
14905
|
-
notificationType:
|
|
14906
|
-
appointmentId:
|
|
14907
|
-
patientRequirementInstanceId:
|
|
14908
|
-
instructionId:
|
|
14909
|
-
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()
|
|
14910
14578
|
});
|
|
14911
14579
|
var appointmentReminderNotificationSchema = baseNotificationSchema.extend({
|
|
14912
|
-
notificationType:
|
|
14913
|
-
appointmentId:
|
|
14914
|
-
appointmentTime:
|
|
14580
|
+
notificationType: import_zod25.z.literal("appointmentReminder" /* APPOINTMENT_REMINDER */),
|
|
14581
|
+
appointmentId: import_zod25.z.string(),
|
|
14582
|
+
appointmentTime: import_zod25.z.any(),
|
|
14915
14583
|
// Timestamp
|
|
14916
|
-
treatmentType:
|
|
14917
|
-
doctorName:
|
|
14584
|
+
treatmentType: import_zod25.z.string(),
|
|
14585
|
+
doctorName: import_zod25.z.string()
|
|
14918
14586
|
});
|
|
14919
14587
|
var appointmentNotificationSchema = baseNotificationSchema.extend({
|
|
14920
|
-
notificationType:
|
|
14921
|
-
appointmentId:
|
|
14922
|
-
appointmentStatus:
|
|
14923
|
-
previousStatus:
|
|
14924
|
-
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()
|
|
14925
14593
|
});
|
|
14926
|
-
var notificationSchema =
|
|
14594
|
+
var notificationSchema = import_zod25.z.discriminatedUnion("notificationType", [
|
|
14927
14595
|
preRequirementNotificationSchema,
|
|
14928
14596
|
postRequirementNotificationSchema,
|
|
14929
14597
|
requirementInstructionDueNotificationSchema,
|