@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.mjs
CHANGED
|
@@ -576,7 +576,7 @@ var UserRole = /* @__PURE__ */ ((UserRole2) => {
|
|
|
576
576
|
var USERS_COLLECTION = "users";
|
|
577
577
|
|
|
578
578
|
// src/services/auth.service.ts
|
|
579
|
-
import { z as
|
|
579
|
+
import { z as z20 } from "zod";
|
|
580
580
|
|
|
581
581
|
// src/validations/schemas.ts
|
|
582
582
|
import { z as z3 } from "zod";
|
|
@@ -983,7 +983,7 @@ var USER_ERRORS = {
|
|
|
983
983
|
};
|
|
984
984
|
|
|
985
985
|
// src/services/user.service.ts
|
|
986
|
-
import { z as
|
|
986
|
+
import { z as z16 } from "zod";
|
|
987
987
|
|
|
988
988
|
// src/services/patient/patient.service.ts
|
|
989
989
|
import {
|
|
@@ -2975,7 +2975,7 @@ var SubscriptionModel = /* @__PURE__ */ ((SubscriptionModel2) => {
|
|
|
2975
2975
|
})(SubscriptionModel || {});
|
|
2976
2976
|
|
|
2977
2977
|
// src/validations/clinic.schema.ts
|
|
2978
|
-
import { z as
|
|
2978
|
+
import { z as z13 } from "zod";
|
|
2979
2979
|
import { Timestamp as Timestamp6 } from "firebase/firestore";
|
|
2980
2980
|
|
|
2981
2981
|
// src/validations/reviews.schema.ts
|
|
@@ -3192,38 +3192,41 @@ var doctorInfoSchema = z11.object({
|
|
|
3192
3192
|
// List of procedure IDs practitioner offers
|
|
3193
3193
|
});
|
|
3194
3194
|
|
|
3195
|
-
// src/validations/
|
|
3195
|
+
// src/validations/media.schema.ts
|
|
3196
|
+
import { z as z12 } from "zod";
|
|
3196
3197
|
var mediaResourceSchema = z12.union([
|
|
3197
3198
|
z12.string(),
|
|
3198
3199
|
z12.instanceof(File),
|
|
3199
3200
|
z12.instanceof(Blob)
|
|
3200
3201
|
]);
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3202
|
+
|
|
3203
|
+
// src/validations/clinic.schema.ts
|
|
3204
|
+
var clinicContactInfoSchema = z13.object({
|
|
3205
|
+
email: z13.string().email(),
|
|
3206
|
+
phoneNumber: z13.string(),
|
|
3207
|
+
alternativePhoneNumber: z13.string().nullable().optional(),
|
|
3208
|
+
website: z13.string().nullable().optional()
|
|
3206
3209
|
});
|
|
3207
|
-
var clinicLocationSchema =
|
|
3208
|
-
address:
|
|
3209
|
-
city:
|
|
3210
|
-
country:
|
|
3211
|
-
postalCode:
|
|
3212
|
-
latitude:
|
|
3213
|
-
longitude:
|
|
3214
|
-
geohash:
|
|
3210
|
+
var clinicLocationSchema = z13.object({
|
|
3211
|
+
address: z13.string(),
|
|
3212
|
+
city: z13.string(),
|
|
3213
|
+
country: z13.string(),
|
|
3214
|
+
postalCode: z13.string(),
|
|
3215
|
+
latitude: z13.number().min(-90).max(90),
|
|
3216
|
+
longitude: z13.number().min(-180).max(180),
|
|
3217
|
+
geohash: z13.string().nullable().optional()
|
|
3215
3218
|
});
|
|
3216
|
-
var workingHoursTimeSchema =
|
|
3217
|
-
open:
|
|
3218
|
-
close:
|
|
3219
|
-
breaks:
|
|
3220
|
-
|
|
3221
|
-
start:
|
|
3222
|
-
end:
|
|
3219
|
+
var workingHoursTimeSchema = z13.object({
|
|
3220
|
+
open: z13.string(),
|
|
3221
|
+
close: z13.string(),
|
|
3222
|
+
breaks: z13.array(
|
|
3223
|
+
z13.object({
|
|
3224
|
+
start: z13.string(),
|
|
3225
|
+
end: z13.string()
|
|
3223
3226
|
})
|
|
3224
3227
|
).optional()
|
|
3225
3228
|
});
|
|
3226
|
-
var workingHoursSchema =
|
|
3229
|
+
var workingHoursSchema = z13.object({
|
|
3227
3230
|
monday: workingHoursTimeSchema.nullable(),
|
|
3228
3231
|
tuesday: workingHoursTimeSchema.nullable(),
|
|
3229
3232
|
wednesday: workingHoursTimeSchema.nullable(),
|
|
@@ -3232,239 +3235,255 @@ var workingHoursSchema = z12.object({
|
|
|
3232
3235
|
saturday: workingHoursTimeSchema.nullable(),
|
|
3233
3236
|
sunday: workingHoursTimeSchema.nullable()
|
|
3234
3237
|
});
|
|
3235
|
-
var clinicTagsSchema =
|
|
3236
|
-
tags:
|
|
3238
|
+
var clinicTagsSchema = z13.object({
|
|
3239
|
+
tags: z13.array(z13.nativeEnum(ClinicTag))
|
|
3237
3240
|
});
|
|
3238
|
-
var contactPersonSchema =
|
|
3239
|
-
firstName:
|
|
3240
|
-
lastName:
|
|
3241
|
-
title:
|
|
3242
|
-
email:
|
|
3243
|
-
phoneNumber:
|
|
3241
|
+
var contactPersonSchema = z13.object({
|
|
3242
|
+
firstName: z13.string(),
|
|
3243
|
+
lastName: z13.string(),
|
|
3244
|
+
title: z13.string().nullable().optional(),
|
|
3245
|
+
email: z13.string().email(),
|
|
3246
|
+
phoneNumber: z13.string().nullable().optional()
|
|
3244
3247
|
});
|
|
3245
|
-
var adminInfoSchema =
|
|
3246
|
-
id:
|
|
3247
|
-
name:
|
|
3248
|
-
email:
|
|
3248
|
+
var adminInfoSchema = z13.object({
|
|
3249
|
+
id: z13.string(),
|
|
3250
|
+
name: z13.string(),
|
|
3251
|
+
email: z13.string().email()
|
|
3249
3252
|
});
|
|
3250
|
-
var clinicAdminSchema =
|
|
3251
|
-
id:
|
|
3252
|
-
userRef:
|
|
3253
|
-
clinicGroupId:
|
|
3254
|
-
isGroupOwner:
|
|
3255
|
-
clinicsManaged:
|
|
3256
|
-
clinicsManagedInfo:
|
|
3253
|
+
var clinicAdminSchema = z13.object({
|
|
3254
|
+
id: z13.string(),
|
|
3255
|
+
userRef: z13.string(),
|
|
3256
|
+
clinicGroupId: z13.string(),
|
|
3257
|
+
isGroupOwner: z13.boolean(),
|
|
3258
|
+
clinicsManaged: z13.array(z13.string()),
|
|
3259
|
+
clinicsManagedInfo: z13.array(clinicInfoSchema),
|
|
3257
3260
|
contactInfo: contactPersonSchema,
|
|
3258
|
-
roleTitle:
|
|
3259
|
-
createdAt:
|
|
3260
|
-
updatedAt:
|
|
3261
|
-
isActive:
|
|
3261
|
+
roleTitle: z13.string(),
|
|
3262
|
+
createdAt: z13.instanceof(Date).or(z13.instanceof(Timestamp6)),
|
|
3263
|
+
updatedAt: z13.instanceof(Date).or(z13.instanceof(Timestamp6)),
|
|
3264
|
+
isActive: z13.boolean()
|
|
3262
3265
|
});
|
|
3263
|
-
var adminTokenSchema =
|
|
3264
|
-
id:
|
|
3265
|
-
token:
|
|
3266
|
-
email:
|
|
3267
|
-
status:
|
|
3268
|
-
usedByUserRef:
|
|
3269
|
-
createdAt:
|
|
3266
|
+
var adminTokenSchema = z13.object({
|
|
3267
|
+
id: z13.string(),
|
|
3268
|
+
token: z13.string(),
|
|
3269
|
+
email: z13.string().email().optional().nullable(),
|
|
3270
|
+
status: z13.nativeEnum(AdminTokenStatus),
|
|
3271
|
+
usedByUserRef: z13.string().optional(),
|
|
3272
|
+
createdAt: z13.instanceof(Date).or(z13.instanceof(Timestamp6)),
|
|
3270
3273
|
// Timestamp
|
|
3271
|
-
expiresAt:
|
|
3274
|
+
expiresAt: z13.instanceof(Date).or(z13.instanceof(Timestamp6))
|
|
3272
3275
|
// Timestamp
|
|
3273
3276
|
});
|
|
3274
|
-
var createAdminTokenSchema =
|
|
3275
|
-
expiresInDays:
|
|
3276
|
-
email:
|
|
3277
|
+
var createAdminTokenSchema = z13.object({
|
|
3278
|
+
expiresInDays: z13.number().min(1).max(30).optional(),
|
|
3279
|
+
email: z13.string().email().optional().nullable()
|
|
3277
3280
|
});
|
|
3278
|
-
var clinicGroupSchema =
|
|
3279
|
-
id:
|
|
3280
|
-
name:
|
|
3281
|
-
description:
|
|
3281
|
+
var clinicGroupSchema = z13.object({
|
|
3282
|
+
id: z13.string(),
|
|
3283
|
+
name: z13.string(),
|
|
3284
|
+
description: z13.string().nullable().optional(),
|
|
3282
3285
|
hqLocation: clinicLocationSchema,
|
|
3283
3286
|
contactInfo: clinicContactInfoSchema,
|
|
3284
3287
|
contactPerson: contactPersonSchema,
|
|
3285
|
-
clinics:
|
|
3286
|
-
clinicsInfo:
|
|
3287
|
-
admins:
|
|
3288
|
-
adminsInfo:
|
|
3289
|
-
adminTokens:
|
|
3290
|
-
ownerId:
|
|
3291
|
-
createdAt:
|
|
3288
|
+
clinics: z13.array(z13.string()),
|
|
3289
|
+
clinicsInfo: z13.array(clinicInfoSchema),
|
|
3290
|
+
admins: z13.array(z13.string()),
|
|
3291
|
+
adminsInfo: z13.array(adminInfoSchema),
|
|
3292
|
+
adminTokens: z13.array(adminTokenSchema),
|
|
3293
|
+
ownerId: z13.string().nullable(),
|
|
3294
|
+
createdAt: z13.instanceof(Date).or(z13.instanceof(Timestamp6)),
|
|
3292
3295
|
// Timestamp
|
|
3293
|
-
updatedAt:
|
|
3296
|
+
updatedAt: z13.instanceof(Date).or(z13.instanceof(Timestamp6)),
|
|
3294
3297
|
// Timestamp
|
|
3295
|
-
isActive:
|
|
3298
|
+
isActive: z13.boolean(),
|
|
3296
3299
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3297
|
-
practiceType:
|
|
3298
|
-
languages:
|
|
3299
|
-
subscriptionModel:
|
|
3300
|
-
calendarSyncEnabled:
|
|
3301
|
-
autoConfirmAppointments:
|
|
3302
|
-
businessIdentificationNumber:
|
|
3300
|
+
practiceType: z13.nativeEnum(PracticeType).optional(),
|
|
3301
|
+
languages: z13.array(z13.nativeEnum(Language)).optional(),
|
|
3302
|
+
subscriptionModel: z13.nativeEnum(SubscriptionModel),
|
|
3303
|
+
calendarSyncEnabled: z13.boolean().optional(),
|
|
3304
|
+
autoConfirmAppointments: z13.boolean().optional(),
|
|
3305
|
+
businessIdentificationNumber: z13.string().optional().nullable(),
|
|
3306
|
+
onboarding: z13.object({
|
|
3307
|
+
completed: z13.boolean().optional().default(false),
|
|
3308
|
+
step: z13.number().optional().default(1)
|
|
3309
|
+
}).optional()
|
|
3303
3310
|
});
|
|
3304
|
-
var clinicSchema =
|
|
3305
|
-
id:
|
|
3306
|
-
clinicGroupId:
|
|
3307
|
-
name:
|
|
3308
|
-
description:
|
|
3311
|
+
var clinicSchema = z13.object({
|
|
3312
|
+
id: z13.string(),
|
|
3313
|
+
clinicGroupId: z13.string(),
|
|
3314
|
+
name: z13.string(),
|
|
3315
|
+
description: z13.string().nullable().optional(),
|
|
3309
3316
|
location: clinicLocationSchema,
|
|
3310
3317
|
contactInfo: clinicContactInfoSchema,
|
|
3311
3318
|
workingHours: workingHoursSchema,
|
|
3312
|
-
tags:
|
|
3313
|
-
featuredPhotos:
|
|
3319
|
+
tags: z13.array(z13.nativeEnum(ClinicTag)),
|
|
3320
|
+
featuredPhotos: z13.array(mediaResourceSchema),
|
|
3314
3321
|
coverPhoto: mediaResourceSchema.nullable(),
|
|
3315
|
-
photosWithTags:
|
|
3316
|
-
|
|
3322
|
+
photosWithTags: z13.array(
|
|
3323
|
+
z13.object({
|
|
3317
3324
|
url: mediaResourceSchema,
|
|
3318
|
-
tag:
|
|
3325
|
+
tag: z13.string()
|
|
3319
3326
|
})
|
|
3320
3327
|
).optional(),
|
|
3321
|
-
doctors:
|
|
3328
|
+
doctors: z13.array(z13.string()),
|
|
3322
3329
|
// List of practitioner IDs
|
|
3323
|
-
doctorsInfo:
|
|
3330
|
+
doctorsInfo: z13.array(doctorInfoSchema),
|
|
3324
3331
|
// Aggregated doctor info
|
|
3325
|
-
procedures:
|
|
3332
|
+
procedures: z13.array(z13.string()),
|
|
3326
3333
|
// List of procedure IDs offered by clinic
|
|
3327
|
-
proceduresInfo:
|
|
3334
|
+
proceduresInfo: z13.array(procedureSummaryInfoSchema),
|
|
3328
3335
|
// Use the correct schema for aggregated procedure info
|
|
3329
3336
|
reviewInfo: clinicReviewInfoSchema,
|
|
3330
|
-
admins:
|
|
3331
|
-
createdAt:
|
|
3337
|
+
admins: z13.array(z13.string()),
|
|
3338
|
+
createdAt: z13.instanceof(Date).or(z13.instanceof(Timestamp6)),
|
|
3332
3339
|
// Timestamp
|
|
3333
|
-
updatedAt:
|
|
3340
|
+
updatedAt: z13.instanceof(Date).or(z13.instanceof(Timestamp6)),
|
|
3334
3341
|
// Timestamp
|
|
3335
|
-
isActive:
|
|
3336
|
-
isVerified:
|
|
3342
|
+
isActive: z13.boolean(),
|
|
3343
|
+
isVerified: z13.boolean(),
|
|
3337
3344
|
logo: mediaResourceSchema.optional().nullable()
|
|
3338
3345
|
});
|
|
3339
|
-
var createClinicAdminSchema =
|
|
3340
|
-
userRef:
|
|
3341
|
-
clinicGroupId:
|
|
3342
|
-
isGroupOwner:
|
|
3343
|
-
clinicsManaged:
|
|
3346
|
+
var createClinicAdminSchema = z13.object({
|
|
3347
|
+
userRef: z13.string(),
|
|
3348
|
+
clinicGroupId: z13.string().optional(),
|
|
3349
|
+
isGroupOwner: z13.boolean(),
|
|
3350
|
+
clinicsManaged: z13.array(z13.string()),
|
|
3344
3351
|
contactInfo: contactPersonSchema,
|
|
3345
|
-
roleTitle:
|
|
3346
|
-
isActive:
|
|
3352
|
+
roleTitle: z13.string(),
|
|
3353
|
+
isActive: z13.boolean()
|
|
3347
3354
|
// clinicsManagedInfo is aggregated, not provided on creation
|
|
3348
3355
|
});
|
|
3349
|
-
var createClinicGroupSchema =
|
|
3350
|
-
name:
|
|
3351
|
-
description:
|
|
3356
|
+
var createClinicGroupSchema = z13.object({
|
|
3357
|
+
name: z13.string(),
|
|
3358
|
+
description: z13.string().optional(),
|
|
3352
3359
|
hqLocation: clinicLocationSchema,
|
|
3353
3360
|
contactInfo: clinicContactInfoSchema,
|
|
3354
3361
|
contactPerson: contactPersonSchema,
|
|
3355
|
-
ownerId:
|
|
3356
|
-
isActive:
|
|
3362
|
+
ownerId: z13.string().nullable(),
|
|
3363
|
+
isActive: z13.boolean(),
|
|
3357
3364
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3358
|
-
practiceType:
|
|
3359
|
-
languages:
|
|
3360
|
-
subscriptionModel:
|
|
3361
|
-
calendarSyncEnabled:
|
|
3362
|
-
autoConfirmAppointments:
|
|
3363
|
-
businessIdentificationNumber:
|
|
3365
|
+
practiceType: z13.nativeEnum(PracticeType).optional(),
|
|
3366
|
+
languages: z13.array(z13.nativeEnum(Language)).optional(),
|
|
3367
|
+
subscriptionModel: z13.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
|
|
3368
|
+
calendarSyncEnabled: z13.boolean().optional(),
|
|
3369
|
+
autoConfirmAppointments: z13.boolean().optional(),
|
|
3370
|
+
businessIdentificationNumber: z13.string().optional().nullable(),
|
|
3371
|
+
onboarding: z13.object({
|
|
3372
|
+
completed: z13.boolean().optional().default(false),
|
|
3373
|
+
step: z13.number().optional().default(1)
|
|
3374
|
+
}).optional()
|
|
3364
3375
|
// clinics, clinicsInfo, admins, adminsInfo, adminTokens are managed internally
|
|
3365
3376
|
});
|
|
3366
|
-
var createClinicSchema =
|
|
3367
|
-
clinicGroupId:
|
|
3368
|
-
name:
|
|
3369
|
-
description:
|
|
3377
|
+
var createClinicSchema = z13.object({
|
|
3378
|
+
clinicGroupId: z13.string(),
|
|
3379
|
+
name: z13.string(),
|
|
3380
|
+
description: z13.string().optional(),
|
|
3370
3381
|
location: clinicLocationSchema,
|
|
3371
3382
|
contactInfo: clinicContactInfoSchema,
|
|
3372
3383
|
workingHours: workingHoursSchema,
|
|
3373
|
-
tags:
|
|
3384
|
+
tags: z13.array(z13.nativeEnum(ClinicTag)),
|
|
3374
3385
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
3375
|
-
photosWithTags:
|
|
3376
|
-
|
|
3386
|
+
photosWithTags: z13.array(
|
|
3387
|
+
z13.object({
|
|
3377
3388
|
url: mediaResourceSchema,
|
|
3378
|
-
tag:
|
|
3389
|
+
tag: z13.string()
|
|
3379
3390
|
})
|
|
3380
3391
|
).optional(),
|
|
3381
|
-
doctors:
|
|
3382
|
-
procedures:
|
|
3383
|
-
proceduresInfo:
|
|
3384
|
-
admins:
|
|
3385
|
-
isActive:
|
|
3386
|
-
isVerified:
|
|
3392
|
+
doctors: z13.array(z13.string()).optional().default([]),
|
|
3393
|
+
procedures: z13.array(z13.string()).optional().default([]),
|
|
3394
|
+
proceduresInfo: z13.array(procedureSummaryInfoSchema).optional(),
|
|
3395
|
+
admins: z13.array(z13.string()),
|
|
3396
|
+
isActive: z13.boolean().optional().default(true),
|
|
3397
|
+
isVerified: z13.boolean().optional().default(false),
|
|
3387
3398
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3388
|
-
featuredPhotos:
|
|
3399
|
+
featuredPhotos: z13.array(mediaResourceSchema).optional().default([])
|
|
3389
3400
|
});
|
|
3390
|
-
var createDefaultClinicGroupSchema =
|
|
3391
|
-
name:
|
|
3392
|
-
ownerId:
|
|
3401
|
+
var createDefaultClinicGroupSchema = z13.object({
|
|
3402
|
+
name: z13.string(),
|
|
3403
|
+
ownerId: z13.string().nullable(),
|
|
3393
3404
|
contactPerson: contactPersonSchema,
|
|
3394
3405
|
contactInfo: clinicContactInfoSchema,
|
|
3395
3406
|
hqLocation: clinicLocationSchema,
|
|
3396
|
-
isActive:
|
|
3407
|
+
isActive: z13.boolean(),
|
|
3397
3408
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3398
|
-
practiceType:
|
|
3399
|
-
languages:
|
|
3400
|
-
subscriptionModel:
|
|
3409
|
+
practiceType: z13.nativeEnum(PracticeType).optional(),
|
|
3410
|
+
languages: z13.array(z13.nativeEnum(Language)).optional(),
|
|
3411
|
+
subscriptionModel: z13.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */),
|
|
3412
|
+
onboarding: z13.object({
|
|
3413
|
+
completed: z13.boolean().optional().default(false),
|
|
3414
|
+
step: z13.number().optional().default(1)
|
|
3415
|
+
}).optional()
|
|
3401
3416
|
});
|
|
3402
|
-
var clinicAdminSignupSchema =
|
|
3403
|
-
email:
|
|
3404
|
-
password:
|
|
3405
|
-
firstName:
|
|
3406
|
-
lastName:
|
|
3407
|
-
title:
|
|
3408
|
-
phoneNumber:
|
|
3409
|
-
isCreatingNewGroup:
|
|
3410
|
-
inviteToken:
|
|
3411
|
-
clinicGroupData:
|
|
3412
|
-
name:
|
|
3417
|
+
var clinicAdminSignupSchema = z13.object({
|
|
3418
|
+
email: z13.string().email(),
|
|
3419
|
+
password: z13.string().min(8),
|
|
3420
|
+
firstName: z13.string(),
|
|
3421
|
+
lastName: z13.string(),
|
|
3422
|
+
title: z13.string(),
|
|
3423
|
+
phoneNumber: z13.string(),
|
|
3424
|
+
isCreatingNewGroup: z13.boolean(),
|
|
3425
|
+
inviteToken: z13.string().optional(),
|
|
3426
|
+
clinicGroupData: z13.object({
|
|
3427
|
+
name: z13.string(),
|
|
3413
3428
|
hqLocation: clinicLocationSchema,
|
|
3414
3429
|
logo: mediaResourceSchema.optional(),
|
|
3415
3430
|
contactInfo: clinicContactInfoSchema,
|
|
3416
|
-
subscriptionModel:
|
|
3431
|
+
subscriptionModel: z13.nativeEnum(SubscriptionModel).optional().default("no_subscription" /* NO_SUBSCRIPTION */)
|
|
3417
3432
|
}).optional()
|
|
3418
3433
|
});
|
|
3419
|
-
var clinicGroupSetupSchema =
|
|
3420
|
-
languages:
|
|
3421
|
-
practiceType:
|
|
3422
|
-
description:
|
|
3434
|
+
var clinicGroupSetupSchema = z13.object({
|
|
3435
|
+
languages: z13.array(z13.nativeEnum(Language)),
|
|
3436
|
+
practiceType: z13.nativeEnum(PracticeType),
|
|
3437
|
+
description: z13.string(),
|
|
3423
3438
|
logo: mediaResourceSchema,
|
|
3424
|
-
calendarSyncEnabled:
|
|
3425
|
-
autoConfirmAppointments:
|
|
3426
|
-
businessIdentificationNumber:
|
|
3439
|
+
calendarSyncEnabled: z13.boolean(),
|
|
3440
|
+
autoConfirmAppointments: z13.boolean(),
|
|
3441
|
+
businessIdentificationNumber: z13.string().optional().nullable(),
|
|
3442
|
+
onboarding: z13.object({
|
|
3443
|
+
completed: z13.boolean().optional().default(false),
|
|
3444
|
+
step: z13.number().optional().default(1)
|
|
3445
|
+
}).optional()
|
|
3427
3446
|
});
|
|
3428
|
-
var clinicBranchSetupSchema =
|
|
3429
|
-
name:
|
|
3447
|
+
var clinicBranchSetupSchema = z13.object({
|
|
3448
|
+
name: z13.string(),
|
|
3430
3449
|
location: clinicLocationSchema,
|
|
3431
|
-
description:
|
|
3450
|
+
description: z13.string().optional(),
|
|
3432
3451
|
contactInfo: clinicContactInfoSchema,
|
|
3433
3452
|
workingHours: workingHoursSchema,
|
|
3434
|
-
tags:
|
|
3453
|
+
tags: z13.array(z13.nativeEnum(ClinicTag)),
|
|
3435
3454
|
logo: mediaResourceSchema.optional(),
|
|
3436
3455
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
3437
|
-
photosWithTags:
|
|
3438
|
-
|
|
3456
|
+
photosWithTags: z13.array(
|
|
3457
|
+
z13.object({
|
|
3439
3458
|
url: mediaResourceSchema,
|
|
3440
|
-
tag:
|
|
3459
|
+
tag: z13.string()
|
|
3441
3460
|
})
|
|
3442
3461
|
).optional(),
|
|
3443
|
-
featuredPhotos:
|
|
3462
|
+
featuredPhotos: z13.array(mediaResourceSchema).optional()
|
|
3444
3463
|
});
|
|
3445
3464
|
var updateClinicAdminSchema = createClinicAdminSchema.partial();
|
|
3446
3465
|
var updateClinicGroupSchema = createClinicGroupSchema.partial();
|
|
3447
|
-
var updateClinicSchema =
|
|
3448
|
-
name:
|
|
3449
|
-
description:
|
|
3466
|
+
var updateClinicSchema = z13.object({
|
|
3467
|
+
name: z13.string().optional(),
|
|
3468
|
+
description: z13.string().optional(),
|
|
3450
3469
|
location: clinicLocationSchema.optional(),
|
|
3451
3470
|
contactInfo: clinicContactInfoSchema.optional(),
|
|
3452
3471
|
workingHours: workingHoursSchema.optional(),
|
|
3453
|
-
tags:
|
|
3472
|
+
tags: z13.array(z13.nativeEnum(ClinicTag)).optional(),
|
|
3454
3473
|
coverPhoto: mediaResourceSchema.nullable().optional(),
|
|
3455
|
-
photosWithTags:
|
|
3456
|
-
|
|
3474
|
+
photosWithTags: z13.array(
|
|
3475
|
+
z13.object({
|
|
3457
3476
|
url: mediaResourceSchema,
|
|
3458
|
-
tag:
|
|
3477
|
+
tag: z13.string()
|
|
3459
3478
|
})
|
|
3460
3479
|
).optional(),
|
|
3461
|
-
doctors:
|
|
3462
|
-
procedures:
|
|
3463
|
-
proceduresInfo:
|
|
3464
|
-
isActive:
|
|
3465
|
-
isVerified:
|
|
3480
|
+
doctors: z13.array(z13.string()).optional(),
|
|
3481
|
+
procedures: z13.array(z13.string()).optional(),
|
|
3482
|
+
proceduresInfo: z13.array(procedureSummaryInfoSchema).optional(),
|
|
3483
|
+
isActive: z13.boolean().optional(),
|
|
3484
|
+
isVerified: z13.boolean().optional(),
|
|
3466
3485
|
logo: mediaResourceSchema.optional().nullable(),
|
|
3467
|
-
featuredPhotos:
|
|
3486
|
+
featuredPhotos: z13.array(mediaResourceSchema).optional()
|
|
3468
3487
|
});
|
|
3469
3488
|
|
|
3470
3489
|
// src/services/clinic/utils/admin.utils.ts
|
|
@@ -3934,7 +3953,7 @@ import {
|
|
|
3934
3953
|
} from "firebase/firestore";
|
|
3935
3954
|
|
|
3936
3955
|
// src/validations/practitioner.schema.ts
|
|
3937
|
-
import { z as
|
|
3956
|
+
import { z as z14 } from "zod";
|
|
3938
3957
|
import { Timestamp as Timestamp8 } from "firebase/firestore";
|
|
3939
3958
|
|
|
3940
3959
|
// src/backoffice/types/static/certification.types.ts
|
|
@@ -3962,34 +3981,34 @@ var CertificationSpecialty = /* @__PURE__ */ ((CertificationSpecialty3) => {
|
|
|
3962
3981
|
})(CertificationSpecialty || {});
|
|
3963
3982
|
|
|
3964
3983
|
// src/validations/practitioner.schema.ts
|
|
3965
|
-
var practitionerBasicInfoSchema =
|
|
3966
|
-
firstName:
|
|
3967
|
-
lastName:
|
|
3968
|
-
title:
|
|
3969
|
-
email:
|
|
3970
|
-
phoneNumber:
|
|
3971
|
-
dateOfBirth:
|
|
3972
|
-
gender:
|
|
3973
|
-
profileImageUrl:
|
|
3974
|
-
bio:
|
|
3975
|
-
languages:
|
|
3984
|
+
var practitionerBasicInfoSchema = z14.object({
|
|
3985
|
+
firstName: z14.string().min(2).max(50),
|
|
3986
|
+
lastName: z14.string().min(2).max(50),
|
|
3987
|
+
title: z14.string().min(2).max(100),
|
|
3988
|
+
email: z14.string().email(),
|
|
3989
|
+
phoneNumber: z14.string().regex(/^\+?[1-9]\d{1,14}$/, "Invalid phone number"),
|
|
3990
|
+
dateOfBirth: z14.instanceof(Timestamp8).or(z14.date()),
|
|
3991
|
+
gender: z14.enum(["male", "female", "other"]),
|
|
3992
|
+
profileImageUrl: z14.string().url().optional(),
|
|
3993
|
+
bio: z14.string().max(1e3).optional(),
|
|
3994
|
+
languages: z14.array(z14.string()).min(1)
|
|
3976
3995
|
});
|
|
3977
|
-
var practitionerCertificationSchema =
|
|
3978
|
-
level:
|
|
3979
|
-
specialties:
|
|
3980
|
-
licenseNumber:
|
|
3981
|
-
issuingAuthority:
|
|
3982
|
-
issueDate:
|
|
3983
|
-
expiryDate:
|
|
3984
|
-
verificationStatus:
|
|
3996
|
+
var practitionerCertificationSchema = z14.object({
|
|
3997
|
+
level: z14.nativeEnum(CertificationLevel),
|
|
3998
|
+
specialties: z14.array(z14.nativeEnum(CertificationSpecialty)),
|
|
3999
|
+
licenseNumber: z14.string().min(3).max(50),
|
|
4000
|
+
issuingAuthority: z14.string().min(2).max(100),
|
|
4001
|
+
issueDate: z14.instanceof(Timestamp8).or(z14.date()),
|
|
4002
|
+
expiryDate: z14.instanceof(Timestamp8).or(z14.date()).optional(),
|
|
4003
|
+
verificationStatus: z14.enum(["pending", "verified", "rejected"])
|
|
3985
4004
|
});
|
|
3986
|
-
var timeSlotSchema =
|
|
3987
|
-
start:
|
|
3988
|
-
end:
|
|
4005
|
+
var timeSlotSchema = z14.object({
|
|
4006
|
+
start: z14.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format"),
|
|
4007
|
+
end: z14.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "Invalid time format")
|
|
3989
4008
|
}).nullable();
|
|
3990
|
-
var practitionerWorkingHoursSchema =
|
|
3991
|
-
practitionerId:
|
|
3992
|
-
clinicId:
|
|
4009
|
+
var practitionerWorkingHoursSchema = z14.object({
|
|
4010
|
+
practitionerId: z14.string().min(1),
|
|
4011
|
+
clinicId: z14.string().min(1),
|
|
3993
4012
|
monday: timeSlotSchema,
|
|
3994
4013
|
tuesday: timeSlotSchema,
|
|
3995
4014
|
wednesday: timeSlotSchema,
|
|
@@ -3997,12 +4016,12 @@ var practitionerWorkingHoursSchema = z13.object({
|
|
|
3997
4016
|
friday: timeSlotSchema,
|
|
3998
4017
|
saturday: timeSlotSchema,
|
|
3999
4018
|
sunday: timeSlotSchema,
|
|
4000
|
-
createdAt:
|
|
4001
|
-
updatedAt:
|
|
4019
|
+
createdAt: z14.instanceof(Timestamp8).or(z14.date()),
|
|
4020
|
+
updatedAt: z14.instanceof(Timestamp8).or(z14.date())
|
|
4002
4021
|
});
|
|
4003
|
-
var practitionerClinicWorkingHoursSchema =
|
|
4004
|
-
clinicId:
|
|
4005
|
-
workingHours:
|
|
4022
|
+
var practitionerClinicWorkingHoursSchema = z14.object({
|
|
4023
|
+
clinicId: z14.string().min(1),
|
|
4024
|
+
workingHours: z14.object({
|
|
4006
4025
|
monday: timeSlotSchema,
|
|
4007
4026
|
tuesday: timeSlotSchema,
|
|
4008
4027
|
wednesday: timeSlotSchema,
|
|
@@ -4011,87 +4030,87 @@ var practitionerClinicWorkingHoursSchema = z13.object({
|
|
|
4011
4030
|
saturday: timeSlotSchema,
|
|
4012
4031
|
sunday: timeSlotSchema
|
|
4013
4032
|
}),
|
|
4014
|
-
isActive:
|
|
4015
|
-
createdAt:
|
|
4016
|
-
updatedAt:
|
|
4033
|
+
isActive: z14.boolean(),
|
|
4034
|
+
createdAt: z14.instanceof(Timestamp8).or(z14.date()),
|
|
4035
|
+
updatedAt: z14.instanceof(Timestamp8).or(z14.date())
|
|
4017
4036
|
});
|
|
4018
|
-
var practitionerSchema =
|
|
4019
|
-
id:
|
|
4020
|
-
userRef:
|
|
4037
|
+
var practitionerSchema = z14.object({
|
|
4038
|
+
id: z14.string().min(1),
|
|
4039
|
+
userRef: z14.string().min(1),
|
|
4021
4040
|
basicInfo: practitionerBasicInfoSchema,
|
|
4022
4041
|
certification: practitionerCertificationSchema,
|
|
4023
|
-
clinics:
|
|
4024
|
-
clinicWorkingHours:
|
|
4025
|
-
clinicsInfo:
|
|
4026
|
-
procedures:
|
|
4027
|
-
proceduresInfo:
|
|
4042
|
+
clinics: z14.array(z14.string()),
|
|
4043
|
+
clinicWorkingHours: z14.array(practitionerClinicWorkingHoursSchema),
|
|
4044
|
+
clinicsInfo: z14.array(clinicInfoSchema),
|
|
4045
|
+
procedures: z14.array(z14.string()),
|
|
4046
|
+
proceduresInfo: z14.array(procedureSummaryInfoSchema),
|
|
4028
4047
|
reviewInfo: practitionerReviewInfoSchema,
|
|
4029
|
-
isActive:
|
|
4030
|
-
isVerified:
|
|
4031
|
-
status:
|
|
4032
|
-
createdAt:
|
|
4033
|
-
updatedAt:
|
|
4048
|
+
isActive: z14.boolean(),
|
|
4049
|
+
isVerified: z14.boolean(),
|
|
4050
|
+
status: z14.nativeEnum(PractitionerStatus),
|
|
4051
|
+
createdAt: z14.instanceof(Timestamp8).or(z14.date()),
|
|
4052
|
+
updatedAt: z14.instanceof(Timestamp8).or(z14.date())
|
|
4034
4053
|
});
|
|
4035
|
-
var createPractitionerSchema =
|
|
4036
|
-
userRef:
|
|
4054
|
+
var createPractitionerSchema = z14.object({
|
|
4055
|
+
userRef: z14.string().min(1),
|
|
4037
4056
|
basicInfo: practitionerBasicInfoSchema,
|
|
4038
4057
|
certification: practitionerCertificationSchema,
|
|
4039
|
-
clinics:
|
|
4040
|
-
clinicWorkingHours:
|
|
4041
|
-
clinicsInfo:
|
|
4042
|
-
proceduresInfo:
|
|
4043
|
-
isActive:
|
|
4044
|
-
isVerified:
|
|
4045
|
-
status:
|
|
4058
|
+
clinics: z14.array(z14.string()).optional(),
|
|
4059
|
+
clinicWorkingHours: z14.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
4060
|
+
clinicsInfo: z14.array(clinicInfoSchema).optional(),
|
|
4061
|
+
proceduresInfo: z14.array(procedureSummaryInfoSchema).optional(),
|
|
4062
|
+
isActive: z14.boolean(),
|
|
4063
|
+
isVerified: z14.boolean(),
|
|
4064
|
+
status: z14.nativeEnum(PractitionerStatus).optional()
|
|
4046
4065
|
});
|
|
4047
|
-
var createDraftPractitionerSchema =
|
|
4066
|
+
var createDraftPractitionerSchema = z14.object({
|
|
4048
4067
|
basicInfo: practitionerBasicInfoSchema,
|
|
4049
4068
|
certification: practitionerCertificationSchema,
|
|
4050
|
-
clinics:
|
|
4051
|
-
clinicWorkingHours:
|
|
4052
|
-
clinicsInfo:
|
|
4053
|
-
proceduresInfo:
|
|
4054
|
-
isActive:
|
|
4055
|
-
isVerified:
|
|
4069
|
+
clinics: z14.array(z14.string()).optional(),
|
|
4070
|
+
clinicWorkingHours: z14.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
4071
|
+
clinicsInfo: z14.array(clinicInfoSchema).optional(),
|
|
4072
|
+
proceduresInfo: z14.array(procedureSummaryInfoSchema).optional(),
|
|
4073
|
+
isActive: z14.boolean().optional().default(false),
|
|
4074
|
+
isVerified: z14.boolean().optional().default(false)
|
|
4056
4075
|
});
|
|
4057
|
-
var practitionerTokenSchema =
|
|
4058
|
-
id:
|
|
4059
|
-
token:
|
|
4060
|
-
practitionerId:
|
|
4061
|
-
email:
|
|
4062
|
-
clinicId:
|
|
4063
|
-
status:
|
|
4064
|
-
createdBy:
|
|
4065
|
-
createdAt:
|
|
4066
|
-
expiresAt:
|
|
4067
|
-
usedBy:
|
|
4068
|
-
usedAt:
|
|
4076
|
+
var practitionerTokenSchema = z14.object({
|
|
4077
|
+
id: z14.string().min(1),
|
|
4078
|
+
token: z14.string().min(6),
|
|
4079
|
+
practitionerId: z14.string().min(1),
|
|
4080
|
+
email: z14.string().email(),
|
|
4081
|
+
clinicId: z14.string().min(1),
|
|
4082
|
+
status: z14.nativeEnum(PractitionerTokenStatus),
|
|
4083
|
+
createdBy: z14.string().min(1),
|
|
4084
|
+
createdAt: z14.instanceof(Timestamp8).or(z14.date()),
|
|
4085
|
+
expiresAt: z14.instanceof(Timestamp8).or(z14.date()),
|
|
4086
|
+
usedBy: z14.string().optional(),
|
|
4087
|
+
usedAt: z14.instanceof(Timestamp8).or(z14.date()).optional()
|
|
4069
4088
|
});
|
|
4070
|
-
var createPractitionerTokenSchema =
|
|
4071
|
-
practitionerId:
|
|
4072
|
-
email:
|
|
4073
|
-
clinicId:
|
|
4074
|
-
expiresAt:
|
|
4089
|
+
var createPractitionerTokenSchema = z14.object({
|
|
4090
|
+
practitionerId: z14.string().min(1),
|
|
4091
|
+
email: z14.string().email(),
|
|
4092
|
+
clinicId: z14.string().min(1),
|
|
4093
|
+
expiresAt: z14.date().optional()
|
|
4075
4094
|
});
|
|
4076
|
-
var practitionerSignupSchema =
|
|
4077
|
-
email:
|
|
4078
|
-
password:
|
|
4079
|
-
firstName:
|
|
4080
|
-
lastName:
|
|
4081
|
-
token:
|
|
4082
|
-
profileData:
|
|
4083
|
-
basicInfo:
|
|
4084
|
-
phoneNumber:
|
|
4085
|
-
profileImageUrl:
|
|
4086
|
-
gender:
|
|
4087
|
-
bio:
|
|
4095
|
+
var practitionerSignupSchema = z14.object({
|
|
4096
|
+
email: z14.string().email(),
|
|
4097
|
+
password: z14.string().min(8),
|
|
4098
|
+
firstName: z14.string().min(2).max(50).optional(),
|
|
4099
|
+
lastName: z14.string().min(2).max(50).optional(),
|
|
4100
|
+
token: z14.string().optional(),
|
|
4101
|
+
profileData: z14.object({
|
|
4102
|
+
basicInfo: z14.object({
|
|
4103
|
+
phoneNumber: z14.string().optional(),
|
|
4104
|
+
profileImageUrl: z14.string().optional(),
|
|
4105
|
+
gender: z14.enum(["male", "female", "other"]).optional(),
|
|
4106
|
+
bio: z14.string().optional()
|
|
4088
4107
|
}).optional(),
|
|
4089
|
-
certification:
|
|
4108
|
+
certification: z14.any().optional()
|
|
4090
4109
|
}).optional()
|
|
4091
4110
|
});
|
|
4092
4111
|
|
|
4093
4112
|
// src/services/practitioner/practitioner.service.ts
|
|
4094
|
-
import { z as
|
|
4113
|
+
import { z as z15 } from "zod";
|
|
4095
4114
|
import { distanceBetween } from "geofire-common";
|
|
4096
4115
|
var PractitionerService = class extends BaseService {
|
|
4097
4116
|
constructor(db, auth, app, clinicService) {
|
|
@@ -4160,7 +4179,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4160
4179
|
}
|
|
4161
4180
|
return createdPractitioner;
|
|
4162
4181
|
} catch (error) {
|
|
4163
|
-
if (error instanceof
|
|
4182
|
+
if (error instanceof z15.ZodError) {
|
|
4164
4183
|
throw new Error(`Invalid practitioner data: ${error.message}`);
|
|
4165
4184
|
}
|
|
4166
4185
|
console.error("Error creating practitioner:", error);
|
|
@@ -4273,7 +4292,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4273
4292
|
await setDoc7(doc8(this.db, tokenPath), token);
|
|
4274
4293
|
return { practitioner: savedPractitioner, token };
|
|
4275
4294
|
} catch (error) {
|
|
4276
|
-
if (error instanceof
|
|
4295
|
+
if (error instanceof z15.ZodError) {
|
|
4277
4296
|
throw new Error("Invalid practitioner data: " + error.message);
|
|
4278
4297
|
}
|
|
4279
4298
|
throw error;
|
|
@@ -4326,7 +4345,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4326
4345
|
await setDoc7(doc8(this.db, tokenPath), token);
|
|
4327
4346
|
return token;
|
|
4328
4347
|
} catch (error) {
|
|
4329
|
-
if (error instanceof
|
|
4348
|
+
if (error instanceof z15.ZodError) {
|
|
4330
4349
|
throw new Error("Invalid token data: " + error.message);
|
|
4331
4350
|
}
|
|
4332
4351
|
throw error;
|
|
@@ -4513,7 +4532,7 @@ var PractitionerService = class extends BaseService {
|
|
|
4513
4532
|
}
|
|
4514
4533
|
return updatedPractitioner;
|
|
4515
4534
|
} catch (error) {
|
|
4516
|
-
if (error instanceof
|
|
4535
|
+
if (error instanceof z15.ZodError) {
|
|
4517
4536
|
throw new Error(`Invalid practitioner update data: ${error.message}`);
|
|
4518
4537
|
}
|
|
4519
4538
|
console.error(`Error updating practitioner ${practitionerId}:`, error);
|
|
@@ -5069,7 +5088,7 @@ var UserService = class extends BaseService {
|
|
|
5069
5088
|
});
|
|
5070
5089
|
return this.getUserById(uid);
|
|
5071
5090
|
} catch (error) {
|
|
5072
|
-
if (error instanceof
|
|
5091
|
+
if (error instanceof z16.ZodError) {
|
|
5073
5092
|
throw USER_ERRORS.VALIDATION_ERROR;
|
|
5074
5093
|
}
|
|
5075
5094
|
throw error;
|
|
@@ -5166,7 +5185,7 @@ import {
|
|
|
5166
5185
|
Timestamp as Timestamp11
|
|
5167
5186
|
} from "firebase/firestore";
|
|
5168
5187
|
import { geohashForLocation as geohashForLocation2 } from "geofire-common";
|
|
5169
|
-
import { z as
|
|
5188
|
+
import { z as z17 } from "zod";
|
|
5170
5189
|
|
|
5171
5190
|
// src/services/clinic/utils/photos.utils.ts
|
|
5172
5191
|
import {
|
|
@@ -5370,7 +5389,7 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
5370
5389
|
});
|
|
5371
5390
|
return groupData;
|
|
5372
5391
|
} catch (error) {
|
|
5373
|
-
if (error instanceof
|
|
5392
|
+
if (error instanceof z17.ZodError) {
|
|
5374
5393
|
console.error(
|
|
5375
5394
|
"[CLINIC_GROUP] Zod validation error:",
|
|
5376
5395
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -5775,6 +5794,43 @@ var ClinicGroupService = class extends BaseService {
|
|
|
5775
5794
|
// but to add them to a subcollection called adminTokens that belongs to a specific clinicGroup document
|
|
5776
5795
|
// TODO: Add granular control over admin permissions, e.g. only allow admins to manage certain clinics to tokens directly
|
|
5777
5796
|
// TODO: Generally refactor admin tokens and invites, also create cloud function to send invites and send updates when sombody uses the token
|
|
5797
|
+
/**
|
|
5798
|
+
* Updates the onboarding status for a clinic group
|
|
5799
|
+
*
|
|
5800
|
+
* @param groupId - The ID of the clinic group to update
|
|
5801
|
+
* @param onboardingData - The onboarding data to update
|
|
5802
|
+
* @returns The updated clinic group
|
|
5803
|
+
*/
|
|
5804
|
+
async setOnboarding(groupId, onboardingData) {
|
|
5805
|
+
console.log("[CLINIC_GROUP] Updating onboarding status", {
|
|
5806
|
+
groupId,
|
|
5807
|
+
onboardingData
|
|
5808
|
+
});
|
|
5809
|
+
return this.updateClinicGroup(groupId, {
|
|
5810
|
+
onboarding: onboardingData
|
|
5811
|
+
});
|
|
5812
|
+
}
|
|
5813
|
+
/**
|
|
5814
|
+
* Sets the current onboarding step for a clinic group
|
|
5815
|
+
*
|
|
5816
|
+
* @param groupId - The ID of the clinic group to update
|
|
5817
|
+
* @param step - The current onboarding step number
|
|
5818
|
+
* @returns The updated clinic group
|
|
5819
|
+
*/
|
|
5820
|
+
async setOnboardingStep(groupId, step) {
|
|
5821
|
+
console.log("[CLINIC_GROUP] Setting onboarding step", { groupId, step });
|
|
5822
|
+
return this.setOnboarding(groupId, { step, completed: false });
|
|
5823
|
+
}
|
|
5824
|
+
/**
|
|
5825
|
+
* Marks the onboarding process as completed for a clinic group
|
|
5826
|
+
*
|
|
5827
|
+
* @param groupId - The ID of the clinic group to update
|
|
5828
|
+
* @returns The updated clinic group
|
|
5829
|
+
*/
|
|
5830
|
+
async completeOnboarding(groupId) {
|
|
5831
|
+
console.log("[CLINIC_GROUP] Completing onboarding", { groupId });
|
|
5832
|
+
return this.setOnboarding(groupId, { completed: true });
|
|
5833
|
+
}
|
|
5778
5834
|
};
|
|
5779
5835
|
|
|
5780
5836
|
// src/services/clinic/clinic.service.ts
|
|
@@ -5789,7 +5845,7 @@ import {
|
|
|
5789
5845
|
import {
|
|
5790
5846
|
geohashForLocation as geohashForLocation4
|
|
5791
5847
|
} from "geofire-common";
|
|
5792
|
-
import { z as
|
|
5848
|
+
import { z as z19 } from "zod";
|
|
5793
5849
|
|
|
5794
5850
|
// src/services/clinic/utils/clinic.utils.ts
|
|
5795
5851
|
import {
|
|
@@ -5810,7 +5866,7 @@ import {
|
|
|
5810
5866
|
distanceBetween as distanceBetween2,
|
|
5811
5867
|
geohashQueryBounds
|
|
5812
5868
|
} from "geofire-common";
|
|
5813
|
-
import { z as
|
|
5869
|
+
import { z as z18 } from "zod";
|
|
5814
5870
|
async function getClinic(db, clinicId) {
|
|
5815
5871
|
const docRef = doc11(db, CLINICS_COLLECTION, clinicId);
|
|
5816
5872
|
const docSnap = await getDoc14(docRef);
|
|
@@ -6442,6 +6498,12 @@ import {
|
|
|
6442
6498
|
deleteDoc as deleteDoc6,
|
|
6443
6499
|
orderBy as orderBy3
|
|
6444
6500
|
} from "firebase/firestore";
|
|
6501
|
+
var MediaAccessLevel = /* @__PURE__ */ ((MediaAccessLevel2) => {
|
|
6502
|
+
MediaAccessLevel2["PUBLIC"] = "public";
|
|
6503
|
+
MediaAccessLevel2["PRIVATE"] = "private";
|
|
6504
|
+
MediaAccessLevel2["CONFIDENTIAL"] = "confidential";
|
|
6505
|
+
return MediaAccessLevel2;
|
|
6506
|
+
})(MediaAccessLevel || {});
|
|
6445
6507
|
var MEDIA_METADATA_COLLECTION = "media_metadata";
|
|
6446
6508
|
var MediaService = class extends BaseService {
|
|
6447
6509
|
constructor(db, auth, app) {
|
|
@@ -6897,7 +6959,7 @@ var ClinicService = class extends BaseService {
|
|
|
6897
6959
|
if (!savedClinic) throw new Error("Failed to retrieve created clinic");
|
|
6898
6960
|
return savedClinic;
|
|
6899
6961
|
} catch (error) {
|
|
6900
|
-
if (error instanceof
|
|
6962
|
+
if (error instanceof z19.ZodError) {
|
|
6901
6963
|
throw new Error("Invalid clinic data: " + error.message);
|
|
6902
6964
|
}
|
|
6903
6965
|
console.error("Error creating clinic:", error);
|
|
@@ -6977,7 +7039,7 @@ var ClinicService = class extends BaseService {
|
|
|
6977
7039
|
if (!updatedClinic) throw new Error("Failed to retrieve updated clinic");
|
|
6978
7040
|
return updatedClinic;
|
|
6979
7041
|
} catch (error) {
|
|
6980
|
-
if (error instanceof
|
|
7042
|
+
if (error instanceof z19.ZodError) {
|
|
6981
7043
|
throw new Error("Invalid clinic update data: " + error.message);
|
|
6982
7044
|
}
|
|
6983
7045
|
console.error(`Error updating clinic ${clinicId}:`, error);
|
|
@@ -6994,6 +7056,16 @@ var ClinicService = class extends BaseService {
|
|
|
6994
7056
|
updatedAt: serverTimestamp12()
|
|
6995
7057
|
});
|
|
6996
7058
|
}
|
|
7059
|
+
/**
|
|
7060
|
+
* Activates a clinic.
|
|
7061
|
+
*/
|
|
7062
|
+
async activateClinic(clinicId, adminId) {
|
|
7063
|
+
const clinicRef = doc13(this.db, CLINICS_COLLECTION, clinicId);
|
|
7064
|
+
await updateDoc13(clinicRef, {
|
|
7065
|
+
isActive: true,
|
|
7066
|
+
updatedAt: serverTimestamp12()
|
|
7067
|
+
});
|
|
7068
|
+
}
|
|
6997
7069
|
/**
|
|
6998
7070
|
* Dohvata kliniku po ID-u
|
|
6999
7071
|
*/
|
|
@@ -7299,7 +7371,11 @@ var AuthService = class extends BaseService {
|
|
|
7299
7371
|
// Use admin profile ID, not user UID
|
|
7300
7372
|
isActive: true,
|
|
7301
7373
|
logo: data.clinicGroupData.logo || null,
|
|
7302
|
-
subscriptionModel: data.clinicGroupData.subscriptionModel || "no_subscription" /* NO_SUBSCRIPTION
|
|
7374
|
+
subscriptionModel: data.clinicGroupData.subscriptionModel || "no_subscription" /* NO_SUBSCRIPTION */,
|
|
7375
|
+
onboarding: {
|
|
7376
|
+
completed: false,
|
|
7377
|
+
step: 1
|
|
7378
|
+
}
|
|
7303
7379
|
};
|
|
7304
7380
|
console.log("[AUTH] Clinic group data prepared", {
|
|
7305
7381
|
groupName: createClinicGroupData.name
|
|
@@ -7439,7 +7515,7 @@ var AuthService = class extends BaseService {
|
|
|
7439
7515
|
clinicAdmin: adminProfile
|
|
7440
7516
|
};
|
|
7441
7517
|
} catch (error) {
|
|
7442
|
-
if (error instanceof
|
|
7518
|
+
if (error instanceof z20.ZodError) {
|
|
7443
7519
|
console.error(
|
|
7444
7520
|
"[AUTH] Zod validation error in signUpClinicAdmin:",
|
|
7445
7521
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -7614,7 +7690,7 @@ var AuthService = class extends BaseService {
|
|
|
7614
7690
|
email
|
|
7615
7691
|
);
|
|
7616
7692
|
} catch (error) {
|
|
7617
|
-
if (error instanceof
|
|
7693
|
+
if (error instanceof z20.ZodError) {
|
|
7618
7694
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7619
7695
|
}
|
|
7620
7696
|
const firebaseError = error;
|
|
@@ -7737,7 +7813,7 @@ var AuthService = class extends BaseService {
|
|
|
7737
7813
|
await emailSchema.parseAsync(email);
|
|
7738
7814
|
await sendPasswordResetEmail(this.auth, email);
|
|
7739
7815
|
} catch (error) {
|
|
7740
|
-
if (error instanceof
|
|
7816
|
+
if (error instanceof z20.ZodError) {
|
|
7741
7817
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7742
7818
|
}
|
|
7743
7819
|
const firebaseError = error;
|
|
@@ -7776,7 +7852,7 @@ var AuthService = class extends BaseService {
|
|
|
7776
7852
|
await passwordSchema.parseAsync(newPassword);
|
|
7777
7853
|
await confirmPasswordReset(this.auth, oobCode, newPassword);
|
|
7778
7854
|
} catch (error) {
|
|
7779
|
-
if (error instanceof
|
|
7855
|
+
if (error instanceof z20.ZodError) {
|
|
7780
7856
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7781
7857
|
}
|
|
7782
7858
|
const firebaseError = error;
|
|
@@ -7945,7 +8021,7 @@ var AuthService = class extends BaseService {
|
|
|
7945
8021
|
practitioner
|
|
7946
8022
|
};
|
|
7947
8023
|
} catch (error) {
|
|
7948
|
-
if (error instanceof
|
|
8024
|
+
if (error instanceof z20.ZodError) {
|
|
7949
8025
|
console.error(
|
|
7950
8026
|
"[AUTH] Zod validation error in signUpPractitioner:",
|
|
7951
8027
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -8250,63 +8326,63 @@ import {
|
|
|
8250
8326
|
var PROCEDURES_COLLECTION = "procedures";
|
|
8251
8327
|
|
|
8252
8328
|
// src/validations/procedure.schema.ts
|
|
8253
|
-
import { z as
|
|
8254
|
-
var createProcedureSchema =
|
|
8255
|
-
name:
|
|
8256
|
-
description:
|
|
8257
|
-
family:
|
|
8258
|
-
categoryId:
|
|
8259
|
-
subcategoryId:
|
|
8260
|
-
technologyId:
|
|
8261
|
-
productId:
|
|
8262
|
-
price:
|
|
8263
|
-
currency:
|
|
8264
|
-
pricingMeasure:
|
|
8265
|
-
duration:
|
|
8329
|
+
import { z as z21 } from "zod";
|
|
8330
|
+
var createProcedureSchema = z21.object({
|
|
8331
|
+
name: z21.string().min(1).max(200),
|
|
8332
|
+
description: z21.string().min(1).max(2e3),
|
|
8333
|
+
family: z21.nativeEnum(ProcedureFamily),
|
|
8334
|
+
categoryId: z21.string().min(1),
|
|
8335
|
+
subcategoryId: z21.string().min(1),
|
|
8336
|
+
technologyId: z21.string().min(1),
|
|
8337
|
+
productId: z21.string().min(1),
|
|
8338
|
+
price: z21.number().min(0),
|
|
8339
|
+
currency: z21.nativeEnum(Currency),
|
|
8340
|
+
pricingMeasure: z21.nativeEnum(PricingMeasure),
|
|
8341
|
+
duration: z21.number().min(1).max(480),
|
|
8266
8342
|
// Max 8 hours
|
|
8267
|
-
practitionerId:
|
|
8268
|
-
clinicBranchId:
|
|
8269
|
-
photos:
|
|
8343
|
+
practitionerId: z21.string().min(1),
|
|
8344
|
+
clinicBranchId: z21.string().min(1),
|
|
8345
|
+
photos: z21.array(z21.string()).optional()
|
|
8270
8346
|
});
|
|
8271
|
-
var updateProcedureSchema =
|
|
8272
|
-
name:
|
|
8273
|
-
description:
|
|
8274
|
-
price:
|
|
8275
|
-
currency:
|
|
8276
|
-
pricingMeasure:
|
|
8277
|
-
duration:
|
|
8278
|
-
isActive:
|
|
8279
|
-
practitionerId:
|
|
8280
|
-
categoryId:
|
|
8281
|
-
subcategoryId:
|
|
8282
|
-
technologyId:
|
|
8283
|
-
productId:
|
|
8284
|
-
clinicBranchId:
|
|
8285
|
-
photos:
|
|
8347
|
+
var updateProcedureSchema = z21.object({
|
|
8348
|
+
name: z21.string().min(3).max(100).optional(),
|
|
8349
|
+
description: z21.string().min(3).max(1e3).optional(),
|
|
8350
|
+
price: z21.number().min(0).optional(),
|
|
8351
|
+
currency: z21.nativeEnum(Currency).optional(),
|
|
8352
|
+
pricingMeasure: z21.nativeEnum(PricingMeasure).optional(),
|
|
8353
|
+
duration: z21.number().min(0).optional(),
|
|
8354
|
+
isActive: z21.boolean().optional(),
|
|
8355
|
+
practitionerId: z21.string().optional(),
|
|
8356
|
+
categoryId: z21.string().optional(),
|
|
8357
|
+
subcategoryId: z21.string().optional(),
|
|
8358
|
+
technologyId: z21.string().optional(),
|
|
8359
|
+
productId: z21.string().optional(),
|
|
8360
|
+
clinicBranchId: z21.string().optional(),
|
|
8361
|
+
photos: z21.array(z21.string()).optional()
|
|
8286
8362
|
});
|
|
8287
8363
|
var procedureSchema = createProcedureSchema.extend({
|
|
8288
|
-
id:
|
|
8289
|
-
category:
|
|
8364
|
+
id: z21.string().min(1),
|
|
8365
|
+
category: z21.any(),
|
|
8290
8366
|
// We'll validate the full category object separately
|
|
8291
|
-
subcategory:
|
|
8367
|
+
subcategory: z21.any(),
|
|
8292
8368
|
// We'll validate the full subcategory object separately
|
|
8293
|
-
technology:
|
|
8369
|
+
technology: z21.any(),
|
|
8294
8370
|
// We'll validate the full technology object separately
|
|
8295
|
-
product:
|
|
8371
|
+
product: z21.any(),
|
|
8296
8372
|
// We'll validate the full product object separately
|
|
8297
|
-
blockingConditions:
|
|
8373
|
+
blockingConditions: z21.array(z21.any()),
|
|
8298
8374
|
// We'll validate blocking conditions separately
|
|
8299
|
-
contraindications:
|
|
8375
|
+
contraindications: z21.array(z21.any()),
|
|
8300
8376
|
// We'll validate contraindications separately
|
|
8301
|
-
treatmentBenefits:
|
|
8377
|
+
treatmentBenefits: z21.array(z21.any()),
|
|
8302
8378
|
// We'll validate treatment benefits separately
|
|
8303
|
-
preRequirements:
|
|
8379
|
+
preRequirements: z21.array(z21.any()),
|
|
8304
8380
|
// We'll validate requirements separately
|
|
8305
|
-
postRequirements:
|
|
8381
|
+
postRequirements: z21.array(z21.any()),
|
|
8306
8382
|
// We'll validate requirements separately
|
|
8307
|
-
certificationRequirement:
|
|
8383
|
+
certificationRequirement: z21.any(),
|
|
8308
8384
|
// We'll validate certification requirement separately
|
|
8309
|
-
documentationTemplates:
|
|
8385
|
+
documentationTemplates: z21.array(z21.any()),
|
|
8310
8386
|
// We'll validate documentation templates separately
|
|
8311
8387
|
clinicInfo: clinicInfoSchema,
|
|
8312
8388
|
// Clinic info validation
|
|
@@ -8314,9 +8390,9 @@ var procedureSchema = createProcedureSchema.extend({
|
|
|
8314
8390
|
// Doctor info validation
|
|
8315
8391
|
reviewInfo: procedureReviewInfoSchema,
|
|
8316
8392
|
// Procedure review info validation
|
|
8317
|
-
isActive:
|
|
8318
|
-
createdAt:
|
|
8319
|
-
updatedAt:
|
|
8393
|
+
isActive: z21.boolean(),
|
|
8394
|
+
createdAt: z21.date(),
|
|
8395
|
+
updatedAt: z21.date()
|
|
8320
8396
|
});
|
|
8321
8397
|
|
|
8322
8398
|
// src/services/procedure/procedure.service.ts
|
|
@@ -9524,42 +9600,42 @@ import {
|
|
|
9524
9600
|
} from "firebase/firestore";
|
|
9525
9601
|
|
|
9526
9602
|
// src/validations/calendar.schema.ts
|
|
9527
|
-
import { z as
|
|
9603
|
+
import { z as z23 } from "zod";
|
|
9528
9604
|
import { Timestamp as Timestamp20 } from "firebase/firestore";
|
|
9529
9605
|
|
|
9530
9606
|
// src/validations/profile-info.schema.ts
|
|
9531
|
-
import { z as
|
|
9607
|
+
import { z as z22 } from "zod";
|
|
9532
9608
|
import { Timestamp as Timestamp19 } from "firebase/firestore";
|
|
9533
|
-
var clinicInfoSchema2 =
|
|
9534
|
-
id:
|
|
9535
|
-
featuredPhoto:
|
|
9536
|
-
name:
|
|
9537
|
-
description:
|
|
9609
|
+
var clinicInfoSchema2 = z22.object({
|
|
9610
|
+
id: z22.string(),
|
|
9611
|
+
featuredPhoto: z22.string(),
|
|
9612
|
+
name: z22.string(),
|
|
9613
|
+
description: z22.string(),
|
|
9538
9614
|
location: clinicLocationSchema,
|
|
9539
9615
|
contactInfo: clinicContactInfoSchema
|
|
9540
9616
|
});
|
|
9541
|
-
var practitionerProfileInfoSchema =
|
|
9542
|
-
id:
|
|
9543
|
-
practitionerPhoto:
|
|
9544
|
-
name:
|
|
9545
|
-
email:
|
|
9546
|
-
phone:
|
|
9617
|
+
var practitionerProfileInfoSchema = z22.object({
|
|
9618
|
+
id: z22.string(),
|
|
9619
|
+
practitionerPhoto: z22.string().nullable(),
|
|
9620
|
+
name: z22.string(),
|
|
9621
|
+
email: z22.string().email(),
|
|
9622
|
+
phone: z22.string().nullable(),
|
|
9547
9623
|
certification: practitionerCertificationSchema
|
|
9548
9624
|
});
|
|
9549
|
-
var patientProfileInfoSchema =
|
|
9550
|
-
id:
|
|
9551
|
-
fullName:
|
|
9552
|
-
email:
|
|
9553
|
-
phone:
|
|
9554
|
-
dateOfBirth:
|
|
9555
|
-
gender:
|
|
9625
|
+
var patientProfileInfoSchema = z22.object({
|
|
9626
|
+
id: z22.string(),
|
|
9627
|
+
fullName: z22.string(),
|
|
9628
|
+
email: z22.string().email(),
|
|
9629
|
+
phone: z22.string().nullable(),
|
|
9630
|
+
dateOfBirth: z22.instanceof(Timestamp19),
|
|
9631
|
+
gender: z22.nativeEnum(Gender)
|
|
9556
9632
|
});
|
|
9557
9633
|
|
|
9558
9634
|
// src/validations/calendar.schema.ts
|
|
9559
9635
|
var MIN_APPOINTMENT_DURATION = 15;
|
|
9560
|
-
var calendarEventTimeSchema =
|
|
9561
|
-
start:
|
|
9562
|
-
end:
|
|
9636
|
+
var calendarEventTimeSchema = z23.object({
|
|
9637
|
+
start: z23.instanceof(Date).or(z23.instanceof(Timestamp20)),
|
|
9638
|
+
end: z23.instanceof(Date).or(z23.instanceof(Timestamp20))
|
|
9563
9639
|
}).refine(
|
|
9564
9640
|
(data) => {
|
|
9565
9641
|
const startDate = data.start instanceof Timestamp20 ? data.start.toDate() : data.start;
|
|
@@ -9580,46 +9656,46 @@ var calendarEventTimeSchema = z22.object({
|
|
|
9580
9656
|
path: ["start"]
|
|
9581
9657
|
}
|
|
9582
9658
|
);
|
|
9583
|
-
var timeSlotSchema2 =
|
|
9584
|
-
start:
|
|
9585
|
-
end:
|
|
9586
|
-
isAvailable:
|
|
9659
|
+
var timeSlotSchema2 = z23.object({
|
|
9660
|
+
start: z23.date(),
|
|
9661
|
+
end: z23.date(),
|
|
9662
|
+
isAvailable: z23.boolean()
|
|
9587
9663
|
}).refine((data) => data.start < data.end, {
|
|
9588
9664
|
message: "End time must be after start time",
|
|
9589
9665
|
path: ["end"]
|
|
9590
9666
|
});
|
|
9591
|
-
var syncedCalendarEventSchema =
|
|
9592
|
-
eventId:
|
|
9593
|
-
syncedCalendarProvider:
|
|
9594
|
-
syncedAt:
|
|
9667
|
+
var syncedCalendarEventSchema = z23.object({
|
|
9668
|
+
eventId: z23.string(),
|
|
9669
|
+
syncedCalendarProvider: z23.nativeEnum(SyncedCalendarProvider),
|
|
9670
|
+
syncedAt: z23.instanceof(Date).or(z23.instanceof(Timestamp20))
|
|
9595
9671
|
});
|
|
9596
|
-
var procedureInfoSchema =
|
|
9597
|
-
name:
|
|
9598
|
-
description:
|
|
9599
|
-
duration:
|
|
9600
|
-
price:
|
|
9601
|
-
currency:
|
|
9672
|
+
var procedureInfoSchema = z23.object({
|
|
9673
|
+
name: z23.string(),
|
|
9674
|
+
description: z23.string(),
|
|
9675
|
+
duration: z23.number().min(MIN_APPOINTMENT_DURATION),
|
|
9676
|
+
price: z23.number().min(0),
|
|
9677
|
+
currency: z23.nativeEnum(Currency)
|
|
9602
9678
|
});
|
|
9603
|
-
var procedureCategorizationSchema =
|
|
9604
|
-
procedureFamily:
|
|
9679
|
+
var procedureCategorizationSchema = z23.object({
|
|
9680
|
+
procedureFamily: z23.string(),
|
|
9605
9681
|
// Replace with proper enum when available
|
|
9606
|
-
procedureCategory:
|
|
9682
|
+
procedureCategory: z23.string(),
|
|
9607
9683
|
// Replace with proper enum when available
|
|
9608
|
-
procedureSubcategory:
|
|
9684
|
+
procedureSubcategory: z23.string(),
|
|
9609
9685
|
// Replace with proper enum when available
|
|
9610
|
-
procedureTechnology:
|
|
9686
|
+
procedureTechnology: z23.string(),
|
|
9611
9687
|
// Replace with proper enum when available
|
|
9612
|
-
procedureProduct:
|
|
9688
|
+
procedureProduct: z23.string()
|
|
9613
9689
|
// Replace with proper enum when available
|
|
9614
9690
|
});
|
|
9615
|
-
var createAppointmentSchema2 =
|
|
9616
|
-
clinicId:
|
|
9617
|
-
doctorId:
|
|
9618
|
-
patientId:
|
|
9619
|
-
procedureId:
|
|
9691
|
+
var createAppointmentSchema2 = z23.object({
|
|
9692
|
+
clinicId: z23.string().min(1, "Clinic ID is required"),
|
|
9693
|
+
doctorId: z23.string().min(1, "Doctor ID is required"),
|
|
9694
|
+
patientId: z23.string().min(1, "Patient ID is required"),
|
|
9695
|
+
procedureId: z23.string().min(1, "Procedure ID is required"),
|
|
9620
9696
|
eventLocation: clinicLocationSchema,
|
|
9621
9697
|
eventTime: calendarEventTimeSchema,
|
|
9622
|
-
description:
|
|
9698
|
+
description: z23.string().optional()
|
|
9623
9699
|
}).refine(
|
|
9624
9700
|
(data) => {
|
|
9625
9701
|
return true;
|
|
@@ -9628,73 +9704,73 @@ var createAppointmentSchema2 = z22.object({
|
|
|
9628
9704
|
message: "Invalid appointment parameters"
|
|
9629
9705
|
}
|
|
9630
9706
|
);
|
|
9631
|
-
var updateAppointmentSchema2 =
|
|
9632
|
-
appointmentId:
|
|
9633
|
-
clinicId:
|
|
9634
|
-
doctorId:
|
|
9635
|
-
patientId:
|
|
9707
|
+
var updateAppointmentSchema2 = z23.object({
|
|
9708
|
+
appointmentId: z23.string().min(1, "Appointment ID is required"),
|
|
9709
|
+
clinicId: z23.string().min(1, "Clinic ID is required"),
|
|
9710
|
+
doctorId: z23.string().min(1, "Doctor ID is required"),
|
|
9711
|
+
patientId: z23.string().min(1, "Patient ID is required"),
|
|
9636
9712
|
eventTime: calendarEventTimeSchema.optional(),
|
|
9637
|
-
description:
|
|
9638
|
-
status:
|
|
9713
|
+
description: z23.string().optional(),
|
|
9714
|
+
status: z23.nativeEnum(CalendarEventStatus).optional()
|
|
9639
9715
|
});
|
|
9640
|
-
var createCalendarEventSchema =
|
|
9641
|
-
id:
|
|
9642
|
-
clinicBranchId:
|
|
9643
|
-
clinicBranchInfo:
|
|
9644
|
-
practitionerProfileId:
|
|
9716
|
+
var createCalendarEventSchema = z23.object({
|
|
9717
|
+
id: z23.string(),
|
|
9718
|
+
clinicBranchId: z23.string().nullable().optional(),
|
|
9719
|
+
clinicBranchInfo: z23.any().nullable().optional(),
|
|
9720
|
+
practitionerProfileId: z23.string().nullable().optional(),
|
|
9645
9721
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
9646
|
-
patientProfileId:
|
|
9722
|
+
patientProfileId: z23.string().nullable().optional(),
|
|
9647
9723
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
9648
|
-
procedureId:
|
|
9649
|
-
appointmentId:
|
|
9650
|
-
syncedCalendarEventId:
|
|
9651
|
-
eventName:
|
|
9724
|
+
procedureId: z23.string().nullable().optional(),
|
|
9725
|
+
appointmentId: z23.string().nullable().optional(),
|
|
9726
|
+
syncedCalendarEventId: z23.array(syncedCalendarEventSchema).nullable().optional(),
|
|
9727
|
+
eventName: z23.string().min(1, "Event name is required"),
|
|
9652
9728
|
eventLocation: clinicLocationSchema.optional(),
|
|
9653
9729
|
eventTime: calendarEventTimeSchema,
|
|
9654
|
-
description:
|
|
9655
|
-
status:
|
|
9656
|
-
syncStatus:
|
|
9657
|
-
eventType:
|
|
9658
|
-
createdAt:
|
|
9730
|
+
description: z23.string().optional(),
|
|
9731
|
+
status: z23.nativeEnum(CalendarEventStatus),
|
|
9732
|
+
syncStatus: z23.nativeEnum(CalendarSyncStatus),
|
|
9733
|
+
eventType: z23.nativeEnum(CalendarEventType),
|
|
9734
|
+
createdAt: z23.any(),
|
|
9659
9735
|
// FieldValue for server timestamp
|
|
9660
|
-
updatedAt:
|
|
9736
|
+
updatedAt: z23.any()
|
|
9661
9737
|
// FieldValue for server timestamp
|
|
9662
9738
|
});
|
|
9663
|
-
var updateCalendarEventSchema =
|
|
9664
|
-
syncedCalendarEventId:
|
|
9665
|
-
appointmentId:
|
|
9666
|
-
eventName:
|
|
9739
|
+
var updateCalendarEventSchema = z23.object({
|
|
9740
|
+
syncedCalendarEventId: z23.array(syncedCalendarEventSchema).nullable().optional(),
|
|
9741
|
+
appointmentId: z23.string().nullable().optional(),
|
|
9742
|
+
eventName: z23.string().optional(),
|
|
9667
9743
|
eventTime: calendarEventTimeSchema.optional(),
|
|
9668
|
-
description:
|
|
9669
|
-
status:
|
|
9670
|
-
syncStatus:
|
|
9671
|
-
eventType:
|
|
9672
|
-
updatedAt:
|
|
9744
|
+
description: z23.string().optional(),
|
|
9745
|
+
status: z23.nativeEnum(CalendarEventStatus).optional(),
|
|
9746
|
+
syncStatus: z23.nativeEnum(CalendarSyncStatus).optional(),
|
|
9747
|
+
eventType: z23.nativeEnum(CalendarEventType).optional(),
|
|
9748
|
+
updatedAt: z23.any()
|
|
9673
9749
|
// FieldValue for server timestamp
|
|
9674
9750
|
});
|
|
9675
|
-
var calendarEventSchema =
|
|
9676
|
-
id:
|
|
9677
|
-
clinicBranchId:
|
|
9678
|
-
clinicBranchInfo:
|
|
9751
|
+
var calendarEventSchema = z23.object({
|
|
9752
|
+
id: z23.string(),
|
|
9753
|
+
clinicBranchId: z23.string().nullable().optional(),
|
|
9754
|
+
clinicBranchInfo: z23.any().nullable().optional(),
|
|
9679
9755
|
// Will be replaced with proper clinic info schema
|
|
9680
|
-
practitionerProfileId:
|
|
9756
|
+
practitionerProfileId: z23.string().nullable().optional(),
|
|
9681
9757
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
9682
|
-
patientProfileId:
|
|
9758
|
+
patientProfileId: z23.string().nullable().optional(),
|
|
9683
9759
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
9684
|
-
procedureId:
|
|
9760
|
+
procedureId: z23.string().nullable().optional(),
|
|
9685
9761
|
procedureInfo: procedureInfoSchema.nullable().optional(),
|
|
9686
9762
|
procedureCategorization: procedureCategorizationSchema.nullable().optional(),
|
|
9687
|
-
appointmentId:
|
|
9688
|
-
syncedCalendarEventId:
|
|
9689
|
-
eventName:
|
|
9763
|
+
appointmentId: z23.string().nullable().optional(),
|
|
9764
|
+
syncedCalendarEventId: z23.array(syncedCalendarEventSchema).nullable().optional(),
|
|
9765
|
+
eventName: z23.string(),
|
|
9690
9766
|
eventLocation: clinicLocationSchema.optional(),
|
|
9691
9767
|
eventTime: calendarEventTimeSchema,
|
|
9692
|
-
description:
|
|
9693
|
-
status:
|
|
9694
|
-
syncStatus:
|
|
9695
|
-
eventType:
|
|
9696
|
-
createdAt:
|
|
9697
|
-
updatedAt:
|
|
9768
|
+
description: z23.string().optional(),
|
|
9769
|
+
status: z23.nativeEnum(CalendarEventStatus),
|
|
9770
|
+
syncStatus: z23.nativeEnum(CalendarSyncStatus),
|
|
9771
|
+
eventType: z23.nativeEnum(CalendarEventType),
|
|
9772
|
+
createdAt: z23.instanceof(Date).or(z23.instanceof(Timestamp20)),
|
|
9773
|
+
updatedAt: z23.instanceof(Date).or(z23.instanceof(Timestamp20))
|
|
9698
9774
|
});
|
|
9699
9775
|
|
|
9700
9776
|
// src/services/calendar/utils/clinic.utils.ts
|
|
@@ -12296,24 +12372,22 @@ import {
|
|
|
12296
12372
|
getDocs as getDocs25,
|
|
12297
12373
|
query as query25,
|
|
12298
12374
|
where as where25,
|
|
12299
|
-
updateDoc as updateDoc25,
|
|
12300
12375
|
setDoc as setDoc23,
|
|
12301
12376
|
deleteDoc as deleteDoc16,
|
|
12302
|
-
serverTimestamp as serverTimestamp22
|
|
12303
|
-
writeBatch as writeBatch7
|
|
12377
|
+
serverTimestamp as serverTimestamp22
|
|
12304
12378
|
} from "firebase/firestore";
|
|
12305
12379
|
|
|
12306
12380
|
// src/types/reviews/index.ts
|
|
12307
12381
|
var REVIEWS_COLLECTION = "reviews";
|
|
12308
12382
|
|
|
12309
12383
|
// src/services/reviews/reviews.service.ts
|
|
12310
|
-
import { z as
|
|
12384
|
+
import { z as z24 } from "zod";
|
|
12311
12385
|
var ReviewService = class extends BaseService {
|
|
12312
12386
|
constructor(db, auth, app) {
|
|
12313
12387
|
super(db, auth, app);
|
|
12314
12388
|
}
|
|
12315
12389
|
/**
|
|
12316
|
-
* Creates a new review
|
|
12390
|
+
* Creates a new review
|
|
12317
12391
|
* @param data - The review data to create
|
|
12318
12392
|
* @param appointmentId - ID of the completed appointment
|
|
12319
12393
|
* @returns The created review
|
|
@@ -12392,28 +12466,9 @@ var ReviewService = class extends BaseService {
|
|
|
12392
12466
|
createdAt: serverTimestamp22(),
|
|
12393
12467
|
updatedAt: serverTimestamp22()
|
|
12394
12468
|
});
|
|
12395
|
-
const updatePromises = [];
|
|
12396
|
-
if (data.clinicReview) {
|
|
12397
|
-
updatePromises.push(
|
|
12398
|
-
this.updateClinicReviewInfo(data.clinicReview.clinicId)
|
|
12399
|
-
);
|
|
12400
|
-
}
|
|
12401
|
-
if (data.practitionerReview) {
|
|
12402
|
-
updatePromises.push(
|
|
12403
|
-
this.updatePractitionerReviewInfo(
|
|
12404
|
-
data.practitionerReview.practitionerId
|
|
12405
|
-
)
|
|
12406
|
-
);
|
|
12407
|
-
}
|
|
12408
|
-
if (data.procedureReview) {
|
|
12409
|
-
updatePromises.push(
|
|
12410
|
-
this.updateProcedureReviewInfo(data.procedureReview.procedureId)
|
|
12411
|
-
);
|
|
12412
|
-
}
|
|
12413
|
-
await Promise.all(updatePromises);
|
|
12414
12469
|
return review;
|
|
12415
12470
|
} catch (error) {
|
|
12416
|
-
if (error instanceof
|
|
12471
|
+
if (error instanceof z24.ZodError) {
|
|
12417
12472
|
throw new Error(`Invalid review data: ${error.message}`);
|
|
12418
12473
|
}
|
|
12419
12474
|
throw error;
|
|
@@ -12501,7 +12556,7 @@ var ReviewService = class extends BaseService {
|
|
|
12501
12556
|
return snapshot.docs[0].data();
|
|
12502
12557
|
}
|
|
12503
12558
|
/**
|
|
12504
|
-
* Deletes a review
|
|
12559
|
+
* Deletes a review
|
|
12505
12560
|
* @param reviewId The ID of the review to delete
|
|
12506
12561
|
*/
|
|
12507
12562
|
async deleteReview(reviewId) {
|
|
@@ -12510,389 +12565,6 @@ var ReviewService = class extends BaseService {
|
|
|
12510
12565
|
throw new Error(`Review with ID ${reviewId} not found`);
|
|
12511
12566
|
}
|
|
12512
12567
|
await deleteDoc16(doc26(this.db, REVIEWS_COLLECTION, reviewId));
|
|
12513
|
-
const updatePromises = [];
|
|
12514
|
-
if (review.clinicReview) {
|
|
12515
|
-
updatePromises.push(
|
|
12516
|
-
this.updateClinicReviewInfo(
|
|
12517
|
-
review.clinicReview.clinicId,
|
|
12518
|
-
review.clinicReview,
|
|
12519
|
-
true
|
|
12520
|
-
)
|
|
12521
|
-
);
|
|
12522
|
-
}
|
|
12523
|
-
if (review.practitionerReview) {
|
|
12524
|
-
updatePromises.push(
|
|
12525
|
-
this.updatePractitionerReviewInfo(
|
|
12526
|
-
review.practitionerReview.practitionerId,
|
|
12527
|
-
review.practitionerReview,
|
|
12528
|
-
true
|
|
12529
|
-
)
|
|
12530
|
-
);
|
|
12531
|
-
}
|
|
12532
|
-
if (review.procedureReview) {
|
|
12533
|
-
updatePromises.push(
|
|
12534
|
-
this.updateProcedureReviewInfo(
|
|
12535
|
-
review.procedureReview.procedureId,
|
|
12536
|
-
review.procedureReview,
|
|
12537
|
-
true
|
|
12538
|
-
)
|
|
12539
|
-
);
|
|
12540
|
-
}
|
|
12541
|
-
await Promise.all(updatePromises);
|
|
12542
|
-
}
|
|
12543
|
-
/**
|
|
12544
|
-
* Updates the review info for a clinic
|
|
12545
|
-
* @param clinicId The ID of the clinic to update
|
|
12546
|
-
* @param newReview Optional new review being added or removed
|
|
12547
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12548
|
-
* @returns The updated clinic review info
|
|
12549
|
-
*/
|
|
12550
|
-
async updateClinicReviewInfo(clinicId, newReview, isRemoval = false) {
|
|
12551
|
-
const clinicDoc = await getDoc28(doc26(this.db, CLINICS_COLLECTION, clinicId));
|
|
12552
|
-
if (!clinicDoc.exists()) {
|
|
12553
|
-
throw new Error(`Clinic with ID ${clinicId} not found`);
|
|
12554
|
-
}
|
|
12555
|
-
const clinicData = clinicDoc.data();
|
|
12556
|
-
const currentReviewInfo = clinicData.reviewInfo || {
|
|
12557
|
-
totalReviews: 0,
|
|
12558
|
-
averageRating: 0,
|
|
12559
|
-
cleanliness: 0,
|
|
12560
|
-
facilities: 0,
|
|
12561
|
-
staffFriendliness: 0,
|
|
12562
|
-
waitingTime: 0,
|
|
12563
|
-
accessibility: 0,
|
|
12564
|
-
recommendationPercentage: 0
|
|
12565
|
-
};
|
|
12566
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12567
|
-
await updateDoc25(doc26(this.db, CLINICS_COLLECTION, clinicId), {
|
|
12568
|
-
reviewInfo: currentReviewInfo,
|
|
12569
|
-
updatedAt: serverTimestamp22()
|
|
12570
|
-
});
|
|
12571
|
-
return currentReviewInfo;
|
|
12572
|
-
}
|
|
12573
|
-
let updatedReviewInfo;
|
|
12574
|
-
if (newReview) {
|
|
12575
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12576
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12577
|
-
if (newTotal === 0) {
|
|
12578
|
-
updatedReviewInfo = {
|
|
12579
|
-
totalReviews: 0,
|
|
12580
|
-
averageRating: 0,
|
|
12581
|
-
cleanliness: 0,
|
|
12582
|
-
facilities: 0,
|
|
12583
|
-
staffFriendliness: 0,
|
|
12584
|
-
waitingTime: 0,
|
|
12585
|
-
accessibility: 0,
|
|
12586
|
-
recommendationPercentage: 0
|
|
12587
|
-
};
|
|
12588
|
-
} else {
|
|
12589
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12590
|
-
const currentSum = currentAvg * oldTotal;
|
|
12591
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12592
|
-
const newAvg = newSum / newTotal;
|
|
12593
|
-
return Math.round(newAvg * 10) / 10;
|
|
12594
|
-
};
|
|
12595
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12596
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12597
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12598
|
-
updatedReviewInfo = {
|
|
12599
|
-
totalReviews: newTotal,
|
|
12600
|
-
averageRating: updateAverage(
|
|
12601
|
-
currentReviewInfo.averageRating,
|
|
12602
|
-
newReview.overallRating
|
|
12603
|
-
),
|
|
12604
|
-
cleanliness: updateAverage(
|
|
12605
|
-
currentReviewInfo.cleanliness,
|
|
12606
|
-
newReview.cleanliness
|
|
12607
|
-
),
|
|
12608
|
-
facilities: updateAverage(
|
|
12609
|
-
currentReviewInfo.facilities,
|
|
12610
|
-
newReview.facilities
|
|
12611
|
-
),
|
|
12612
|
-
staffFriendliness: updateAverage(
|
|
12613
|
-
currentReviewInfo.staffFriendliness,
|
|
12614
|
-
newReview.staffFriendliness
|
|
12615
|
-
),
|
|
12616
|
-
waitingTime: updateAverage(
|
|
12617
|
-
currentReviewInfo.waitingTime,
|
|
12618
|
-
newReview.waitingTime
|
|
12619
|
-
),
|
|
12620
|
-
accessibility: updateAverage(
|
|
12621
|
-
currentReviewInfo.accessibility,
|
|
12622
|
-
newReview.accessibility
|
|
12623
|
-
),
|
|
12624
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12625
|
-
};
|
|
12626
|
-
}
|
|
12627
|
-
} else {
|
|
12628
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12629
|
-
}
|
|
12630
|
-
await updateDoc25(doc26(this.db, CLINICS_COLLECTION, clinicId), {
|
|
12631
|
-
reviewInfo: updatedReviewInfo,
|
|
12632
|
-
updatedAt: serverTimestamp22()
|
|
12633
|
-
});
|
|
12634
|
-
return updatedReviewInfo;
|
|
12635
|
-
}
|
|
12636
|
-
/**
|
|
12637
|
-
* Updates the review info for a practitioner
|
|
12638
|
-
* @param practitionerId The ID of the practitioner to update
|
|
12639
|
-
* @param newReview Optional new review being added or removed
|
|
12640
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12641
|
-
* @returns The updated practitioner review info
|
|
12642
|
-
*/
|
|
12643
|
-
async updatePractitionerReviewInfo(practitionerId, newReview, isRemoval = false) {
|
|
12644
|
-
const practitionerDoc = await getDoc28(
|
|
12645
|
-
doc26(this.db, PRACTITIONERS_COLLECTION, practitionerId)
|
|
12646
|
-
);
|
|
12647
|
-
if (!practitionerDoc.exists()) {
|
|
12648
|
-
throw new Error(`Practitioner with ID ${practitionerId} not found`);
|
|
12649
|
-
}
|
|
12650
|
-
const practitionerData = practitionerDoc.data();
|
|
12651
|
-
const currentReviewInfo = practitionerData.reviewInfo || {
|
|
12652
|
-
totalReviews: 0,
|
|
12653
|
-
averageRating: 0,
|
|
12654
|
-
knowledgeAndExpertise: 0,
|
|
12655
|
-
communicationSkills: 0,
|
|
12656
|
-
bedSideManner: 0,
|
|
12657
|
-
thoroughness: 0,
|
|
12658
|
-
trustworthiness: 0,
|
|
12659
|
-
recommendationPercentage: 0
|
|
12660
|
-
};
|
|
12661
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12662
|
-
await updateDoc25(doc26(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
12663
|
-
reviewInfo: currentReviewInfo,
|
|
12664
|
-
updatedAt: serverTimestamp22()
|
|
12665
|
-
});
|
|
12666
|
-
return currentReviewInfo;
|
|
12667
|
-
}
|
|
12668
|
-
let updatedReviewInfo;
|
|
12669
|
-
if (newReview) {
|
|
12670
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12671
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12672
|
-
if (newTotal === 0) {
|
|
12673
|
-
updatedReviewInfo = {
|
|
12674
|
-
totalReviews: 0,
|
|
12675
|
-
averageRating: 0,
|
|
12676
|
-
knowledgeAndExpertise: 0,
|
|
12677
|
-
communicationSkills: 0,
|
|
12678
|
-
bedSideManner: 0,
|
|
12679
|
-
thoroughness: 0,
|
|
12680
|
-
trustworthiness: 0,
|
|
12681
|
-
recommendationPercentage: 0
|
|
12682
|
-
};
|
|
12683
|
-
} else {
|
|
12684
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12685
|
-
const currentSum = currentAvg * oldTotal;
|
|
12686
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12687
|
-
const newAvg = newSum / newTotal;
|
|
12688
|
-
return Math.round(newAvg * 10) / 10;
|
|
12689
|
-
};
|
|
12690
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12691
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12692
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12693
|
-
updatedReviewInfo = {
|
|
12694
|
-
totalReviews: newTotal,
|
|
12695
|
-
averageRating: updateAverage(
|
|
12696
|
-
currentReviewInfo.averageRating,
|
|
12697
|
-
newReview.overallRating
|
|
12698
|
-
),
|
|
12699
|
-
knowledgeAndExpertise: updateAverage(
|
|
12700
|
-
currentReviewInfo.knowledgeAndExpertise,
|
|
12701
|
-
newReview.knowledgeAndExpertise
|
|
12702
|
-
),
|
|
12703
|
-
communicationSkills: updateAverage(
|
|
12704
|
-
currentReviewInfo.communicationSkills,
|
|
12705
|
-
newReview.communicationSkills
|
|
12706
|
-
),
|
|
12707
|
-
bedSideManner: updateAverage(
|
|
12708
|
-
currentReviewInfo.bedSideManner,
|
|
12709
|
-
newReview.bedSideManner
|
|
12710
|
-
),
|
|
12711
|
-
thoroughness: updateAverage(
|
|
12712
|
-
currentReviewInfo.thoroughness,
|
|
12713
|
-
newReview.thoroughness
|
|
12714
|
-
),
|
|
12715
|
-
trustworthiness: updateAverage(
|
|
12716
|
-
currentReviewInfo.trustworthiness,
|
|
12717
|
-
newReview.trustworthiness
|
|
12718
|
-
),
|
|
12719
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12720
|
-
};
|
|
12721
|
-
}
|
|
12722
|
-
} else {
|
|
12723
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12724
|
-
}
|
|
12725
|
-
await updateDoc25(doc26(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
12726
|
-
reviewInfo: updatedReviewInfo,
|
|
12727
|
-
updatedAt: serverTimestamp22()
|
|
12728
|
-
});
|
|
12729
|
-
await this.updateDoctorInfoInProcedures(
|
|
12730
|
-
practitionerId,
|
|
12731
|
-
updatedReviewInfo.averageRating
|
|
12732
|
-
);
|
|
12733
|
-
return updatedReviewInfo;
|
|
12734
|
-
}
|
|
12735
|
-
/**
|
|
12736
|
-
* Updates the review info for a procedure
|
|
12737
|
-
* @param procedureId The ID of the procedure to update
|
|
12738
|
-
* @param newReview Optional new review being added or removed
|
|
12739
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12740
|
-
* @returns The updated procedure review info
|
|
12741
|
-
*/
|
|
12742
|
-
async updateProcedureReviewInfo(procedureId, newReview, isRemoval = false) {
|
|
12743
|
-
const procedureDoc = await getDoc28(
|
|
12744
|
-
doc26(this.db, PROCEDURES_COLLECTION, procedureId)
|
|
12745
|
-
);
|
|
12746
|
-
if (!procedureDoc.exists()) {
|
|
12747
|
-
throw new Error(`Procedure with ID ${procedureId} not found`);
|
|
12748
|
-
}
|
|
12749
|
-
const procedureData = procedureDoc.data();
|
|
12750
|
-
const currentReviewInfo = procedureData.reviewInfo || {
|
|
12751
|
-
totalReviews: 0,
|
|
12752
|
-
averageRating: 0,
|
|
12753
|
-
effectivenessOfTreatment: 0,
|
|
12754
|
-
outcomeExplanation: 0,
|
|
12755
|
-
painManagement: 0,
|
|
12756
|
-
followUpCare: 0,
|
|
12757
|
-
valueForMoney: 0,
|
|
12758
|
-
recommendationPercentage: 0
|
|
12759
|
-
};
|
|
12760
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12761
|
-
await updateDoc25(doc26(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
12762
|
-
reviewInfo: currentReviewInfo,
|
|
12763
|
-
updatedAt: serverTimestamp22()
|
|
12764
|
-
});
|
|
12765
|
-
return currentReviewInfo;
|
|
12766
|
-
}
|
|
12767
|
-
let updatedReviewInfo;
|
|
12768
|
-
if (newReview) {
|
|
12769
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12770
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12771
|
-
if (newTotal === 0) {
|
|
12772
|
-
updatedReviewInfo = {
|
|
12773
|
-
totalReviews: 0,
|
|
12774
|
-
averageRating: 0,
|
|
12775
|
-
effectivenessOfTreatment: 0,
|
|
12776
|
-
outcomeExplanation: 0,
|
|
12777
|
-
painManagement: 0,
|
|
12778
|
-
followUpCare: 0,
|
|
12779
|
-
valueForMoney: 0,
|
|
12780
|
-
recommendationPercentage: 0
|
|
12781
|
-
};
|
|
12782
|
-
} else {
|
|
12783
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12784
|
-
const currentSum = currentAvg * oldTotal;
|
|
12785
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12786
|
-
const newAvg = newSum / newTotal;
|
|
12787
|
-
return Math.round(newAvg * 10) / 10;
|
|
12788
|
-
};
|
|
12789
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12790
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12791
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12792
|
-
updatedReviewInfo = {
|
|
12793
|
-
totalReviews: newTotal,
|
|
12794
|
-
averageRating: updateAverage(
|
|
12795
|
-
currentReviewInfo.averageRating,
|
|
12796
|
-
newReview.overallRating
|
|
12797
|
-
),
|
|
12798
|
-
effectivenessOfTreatment: updateAverage(
|
|
12799
|
-
currentReviewInfo.effectivenessOfTreatment,
|
|
12800
|
-
newReview.effectivenessOfTreatment
|
|
12801
|
-
),
|
|
12802
|
-
outcomeExplanation: updateAverage(
|
|
12803
|
-
currentReviewInfo.outcomeExplanation,
|
|
12804
|
-
newReview.outcomeExplanation
|
|
12805
|
-
),
|
|
12806
|
-
painManagement: updateAverage(
|
|
12807
|
-
currentReviewInfo.painManagement,
|
|
12808
|
-
newReview.painManagement
|
|
12809
|
-
),
|
|
12810
|
-
followUpCare: updateAverage(
|
|
12811
|
-
currentReviewInfo.followUpCare,
|
|
12812
|
-
newReview.followUpCare
|
|
12813
|
-
),
|
|
12814
|
-
valueForMoney: updateAverage(
|
|
12815
|
-
currentReviewInfo.valueForMoney,
|
|
12816
|
-
newReview.valueForMoney
|
|
12817
|
-
),
|
|
12818
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12819
|
-
};
|
|
12820
|
-
}
|
|
12821
|
-
} else {
|
|
12822
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12823
|
-
}
|
|
12824
|
-
await updateDoc25(doc26(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
12825
|
-
reviewInfo: updatedReviewInfo,
|
|
12826
|
-
updatedAt: serverTimestamp22()
|
|
12827
|
-
});
|
|
12828
|
-
return updatedReviewInfo;
|
|
12829
|
-
}
|
|
12830
|
-
/**
|
|
12831
|
-
* Updates doctorInfo rating in all procedures for a practitioner
|
|
12832
|
-
* @param practitionerId The ID of the practitioner
|
|
12833
|
-
* @param rating The new rating to set
|
|
12834
|
-
*/
|
|
12835
|
-
async updateDoctorInfoInProcedures(practitionerId, rating) {
|
|
12836
|
-
const q = query25(
|
|
12837
|
-
collection25(this.db, PROCEDURES_COLLECTION),
|
|
12838
|
-
where25("practitionerId", "==", practitionerId)
|
|
12839
|
-
);
|
|
12840
|
-
const snapshot = await getDocs25(q);
|
|
12841
|
-
if (snapshot.empty) {
|
|
12842
|
-
return;
|
|
12843
|
-
}
|
|
12844
|
-
const batch = writeBatch7(this.db);
|
|
12845
|
-
snapshot.docs.forEach((docSnapshot) => {
|
|
12846
|
-
const procedureRef = doc26(this.db, PROCEDURES_COLLECTION, docSnapshot.id);
|
|
12847
|
-
batch.update(procedureRef, {
|
|
12848
|
-
"doctorInfo.rating": rating,
|
|
12849
|
-
updatedAt: serverTimestamp22()
|
|
12850
|
-
});
|
|
12851
|
-
});
|
|
12852
|
-
await batch.commit();
|
|
12853
|
-
}
|
|
12854
|
-
/**
|
|
12855
|
-
* Verifies a review as checked by admin/staff
|
|
12856
|
-
* @param reviewId The ID of the review to verify
|
|
12857
|
-
*/
|
|
12858
|
-
async verifyReview(reviewId) {
|
|
12859
|
-
const review = await this.getReview(reviewId);
|
|
12860
|
-
if (!review) {
|
|
12861
|
-
throw new Error(`Review with ID ${reviewId} not found`);
|
|
12862
|
-
}
|
|
12863
|
-
const batch = writeBatch7(this.db);
|
|
12864
|
-
batch.update(doc26(this.db, REVIEWS_COLLECTION, reviewId), {
|
|
12865
|
-
updatedAt: serverTimestamp22()
|
|
12866
|
-
});
|
|
12867
|
-
if (review.clinicReview) {
|
|
12868
|
-
review.clinicReview.isVerified = true;
|
|
12869
|
-
}
|
|
12870
|
-
if (review.practitionerReview) {
|
|
12871
|
-
review.practitionerReview.isVerified = true;
|
|
12872
|
-
}
|
|
12873
|
-
if (review.procedureReview) {
|
|
12874
|
-
review.procedureReview.isVerified = true;
|
|
12875
|
-
}
|
|
12876
|
-
await batch.commit();
|
|
12877
|
-
const updatePromises = [];
|
|
12878
|
-
if (review.clinicReview) {
|
|
12879
|
-
updatePromises.push(
|
|
12880
|
-
this.updateClinicReviewInfo(review.clinicReview.clinicId)
|
|
12881
|
-
);
|
|
12882
|
-
}
|
|
12883
|
-
if (review.practitionerReview) {
|
|
12884
|
-
updatePromises.push(
|
|
12885
|
-
this.updatePractitionerReviewInfo(
|
|
12886
|
-
review.practitionerReview.practitionerId
|
|
12887
|
-
)
|
|
12888
|
-
);
|
|
12889
|
-
}
|
|
12890
|
-
if (review.procedureReview) {
|
|
12891
|
-
updatePromises.push(
|
|
12892
|
-
this.updateProcedureReviewInfo(review.procedureReview.procedureId)
|
|
12893
|
-
);
|
|
12894
|
-
}
|
|
12895
|
-
await Promise.all(updatePromises);
|
|
12896
12568
|
}
|
|
12897
12569
|
/**
|
|
12898
12570
|
* Calculates the average of an array of numbers
|
|
@@ -12911,7 +12583,7 @@ var ReviewService = class extends BaseService {
|
|
|
12911
12583
|
|
|
12912
12584
|
// src/services/appointment/appointment.service.ts
|
|
12913
12585
|
import {
|
|
12914
|
-
Timestamp as
|
|
12586
|
+
Timestamp as Timestamp29,
|
|
12915
12587
|
serverTimestamp as serverTimestamp24,
|
|
12916
12588
|
arrayUnion as arrayUnion8,
|
|
12917
12589
|
arrayRemove as arrayRemove7,
|
|
@@ -12934,9 +12606,9 @@ import {
|
|
|
12934
12606
|
query as query26,
|
|
12935
12607
|
where as where26,
|
|
12936
12608
|
setDoc as setDoc24,
|
|
12937
|
-
updateDoc as
|
|
12609
|
+
updateDoc as updateDoc25,
|
|
12938
12610
|
serverTimestamp as serverTimestamp23,
|
|
12939
|
-
Timestamp as
|
|
12611
|
+
Timestamp as Timestamp28,
|
|
12940
12612
|
orderBy as orderBy13,
|
|
12941
12613
|
limit as limit11,
|
|
12942
12614
|
startAfter as startAfter10
|
|
@@ -13007,7 +12679,7 @@ async function updateAppointmentUtil2(db, appointmentId, data) {
|
|
|
13007
12679
|
});
|
|
13008
12680
|
if (data.status && data.status !== currentAppointment.status) {
|
|
13009
12681
|
if (data.status === "confirmed" /* CONFIRMED */ && !updateData.confirmationTime) {
|
|
13010
|
-
updateData.confirmationTime =
|
|
12682
|
+
updateData.confirmationTime = Timestamp28.now();
|
|
13011
12683
|
}
|
|
13012
12684
|
if (currentAppointment.calendarEventId) {
|
|
13013
12685
|
await updateCalendarEventStatus(
|
|
@@ -13017,7 +12689,7 @@ async function updateAppointmentUtil2(db, appointmentId, data) {
|
|
|
13017
12689
|
);
|
|
13018
12690
|
}
|
|
13019
12691
|
}
|
|
13020
|
-
await
|
|
12692
|
+
await updateDoc25(appointmentRef, updateData);
|
|
13021
12693
|
const updatedAppointmentDoc = await getDoc29(appointmentRef);
|
|
13022
12694
|
if (!updatedAppointmentDoc.exists()) {
|
|
13023
12695
|
throw new Error(
|
|
@@ -13056,7 +12728,7 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
|
|
|
13056
12728
|
default:
|
|
13057
12729
|
return;
|
|
13058
12730
|
}
|
|
13059
|
-
await
|
|
12731
|
+
await updateDoc25(calendarEventRef, {
|
|
13060
12732
|
status: calendarStatus,
|
|
13061
12733
|
updatedAt: serverTimestamp23()
|
|
13062
12734
|
});
|
|
@@ -13095,13 +12767,13 @@ async function searchAppointmentsUtil(db, params) {
|
|
|
13095
12767
|
where26(
|
|
13096
12768
|
"appointmentStartTime",
|
|
13097
12769
|
">=",
|
|
13098
|
-
|
|
12770
|
+
Timestamp28.fromDate(params.startDate)
|
|
13099
12771
|
)
|
|
13100
12772
|
);
|
|
13101
12773
|
}
|
|
13102
12774
|
if (params.endDate) {
|
|
13103
12775
|
constraints.push(
|
|
13104
|
-
where26("appointmentStartTime", "<=",
|
|
12776
|
+
where26("appointmentStartTime", "<=", Timestamp28.fromDate(params.endDate))
|
|
13105
12777
|
);
|
|
13106
12778
|
}
|
|
13107
12779
|
if (params.status) {
|
|
@@ -13501,13 +13173,13 @@ var AppointmentService = class extends BaseService {
|
|
|
13501
13173
|
}
|
|
13502
13174
|
updateData.cancellationReason = details.cancellationReason;
|
|
13503
13175
|
updateData.canceledBy = details.canceledBy;
|
|
13504
|
-
updateData.cancellationTime =
|
|
13176
|
+
updateData.cancellationTime = Timestamp29.now();
|
|
13505
13177
|
}
|
|
13506
13178
|
if (newStatus === "confirmed" /* CONFIRMED */) {
|
|
13507
|
-
updateData.confirmationTime =
|
|
13179
|
+
updateData.confirmationTime = Timestamp29.now();
|
|
13508
13180
|
}
|
|
13509
13181
|
if (newStatus === "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */) {
|
|
13510
|
-
updateData.rescheduleTime =
|
|
13182
|
+
updateData.rescheduleTime = Timestamp29.now();
|
|
13511
13183
|
}
|
|
13512
13184
|
return this.updateAppointment(appointmentId, updateData);
|
|
13513
13185
|
}
|
|
@@ -13578,7 +13250,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13578
13250
|
status: "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */,
|
|
13579
13251
|
appointmentStartTime: newStartTime,
|
|
13580
13252
|
appointmentEndTime: newEndTime,
|
|
13581
|
-
rescheduleTime:
|
|
13253
|
+
rescheduleTime: Timestamp29.now(),
|
|
13582
13254
|
confirmationTime: null,
|
|
13583
13255
|
updatedAt: serverTimestamp24()
|
|
13584
13256
|
};
|
|
@@ -13675,7 +13347,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13675
13347
|
}
|
|
13676
13348
|
const updateData = {
|
|
13677
13349
|
status: "in_progress" /* IN_PROGRESS */,
|
|
13678
|
-
procedureActualStartTime:
|
|
13350
|
+
procedureActualStartTime: Timestamp29.now(),
|
|
13679
13351
|
// Set actual start time
|
|
13680
13352
|
updatedAt: serverTimestamp24()
|
|
13681
13353
|
};
|
|
@@ -13695,7 +13367,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13695
13367
|
if (!appointment)
|
|
13696
13368
|
throw new Error(`Appointment ${appointmentId} not found.`);
|
|
13697
13369
|
let calculatedDurationMinutes = actualDurationMinutesInput;
|
|
13698
|
-
const procedureCompletionTime =
|
|
13370
|
+
const procedureCompletionTime = Timestamp29.now();
|
|
13699
13371
|
if (calculatedDurationMinutes === void 0 && appointment.procedureActualStartTime) {
|
|
13700
13372
|
const startTimeMillis = appointment.procedureActualStartTime.toMillis();
|
|
13701
13373
|
const endTimeMillis = procedureCompletionTime.toMillis();
|
|
@@ -13732,7 +13404,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13732
13404
|
const appointment = await this.getAppointmentById(appointmentId);
|
|
13733
13405
|
if (!appointment)
|
|
13734
13406
|
throw new Error(`Appointment ${appointmentId} not found.`);
|
|
13735
|
-
if (
|
|
13407
|
+
if (Timestamp29.now().toMillis() < appointment.appointmentStartTime.toMillis()) {
|
|
13736
13408
|
throw new Error("Cannot mark no-show before appointment start time.");
|
|
13737
13409
|
}
|
|
13738
13410
|
return this.updateAppointmentStatus(
|
|
@@ -13756,7 +13428,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13756
13428
|
const newMediaItem = {
|
|
13757
13429
|
...mediaItemData,
|
|
13758
13430
|
id: this.generateId(),
|
|
13759
|
-
uploadedAt:
|
|
13431
|
+
uploadedAt: Timestamp29.now(),
|
|
13760
13432
|
uploadedBy: currentUser.uid
|
|
13761
13433
|
};
|
|
13762
13434
|
const updateData = {
|
|
@@ -13796,7 +13468,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13796
13468
|
const newReviewInfo = {
|
|
13797
13469
|
...reviewData,
|
|
13798
13470
|
reviewId: this.generateId(),
|
|
13799
|
-
reviewedAt:
|
|
13471
|
+
reviewedAt: Timestamp29.now()
|
|
13800
13472
|
};
|
|
13801
13473
|
const updateData = {
|
|
13802
13474
|
reviewInfo: newReviewInfo,
|
|
@@ -13862,7 +13534,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13862
13534
|
where27(
|
|
13863
13535
|
"appointmentStartTime",
|
|
13864
13536
|
">=",
|
|
13865
|
-
|
|
13537
|
+
Timestamp29.fromDate(effectiveStartDate)
|
|
13866
13538
|
)
|
|
13867
13539
|
);
|
|
13868
13540
|
if (options == null ? void 0 : options.endDate) {
|
|
@@ -13870,7 +13542,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13870
13542
|
where27(
|
|
13871
13543
|
"appointmentStartTime",
|
|
13872
13544
|
"<=",
|
|
13873
|
-
|
|
13545
|
+
Timestamp29.fromDate(options.endDate)
|
|
13874
13546
|
)
|
|
13875
13547
|
);
|
|
13876
13548
|
}
|
|
@@ -13936,7 +13608,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13936
13608
|
where27(
|
|
13937
13609
|
"appointmentStartTime",
|
|
13938
13610
|
">=",
|
|
13939
|
-
|
|
13611
|
+
Timestamp29.fromDate(options.startDate)
|
|
13940
13612
|
)
|
|
13941
13613
|
);
|
|
13942
13614
|
}
|
|
@@ -13944,7 +13616,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13944
13616
|
where27(
|
|
13945
13617
|
"appointmentStartTime",
|
|
13946
13618
|
"<=",
|
|
13947
|
-
|
|
13619
|
+
Timestamp29.fromDate(effectiveEndDate)
|
|
13948
13620
|
)
|
|
13949
13621
|
);
|
|
13950
13622
|
constraints.push(orderBy14("appointmentStartTime", "desc"));
|
|
@@ -13984,8 +13656,8 @@ import {
|
|
|
13984
13656
|
query as query28,
|
|
13985
13657
|
where as where28,
|
|
13986
13658
|
doc as doc28,
|
|
13987
|
-
updateDoc as
|
|
13988
|
-
Timestamp as
|
|
13659
|
+
updateDoc as updateDoc26,
|
|
13660
|
+
Timestamp as Timestamp30,
|
|
13989
13661
|
orderBy as orderBy15,
|
|
13990
13662
|
limit as limit13,
|
|
13991
13663
|
startAfter as startAfter12,
|
|
@@ -14144,7 +13816,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14144
13816
|
`Instruction ${instructionId} is in status ${instructionToUpdate.status} and cannot be marked as completed.`
|
|
14145
13817
|
);
|
|
14146
13818
|
}
|
|
14147
|
-
const now =
|
|
13819
|
+
const now = Timestamp30.now();
|
|
14148
13820
|
const updatedInstructions = [...instance.instructions];
|
|
14149
13821
|
updatedInstructions[instructionIndex] = {
|
|
14150
13822
|
...instructionToUpdate,
|
|
@@ -14171,7 +13843,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14171
13843
|
if (newOverallStatus !== instance.overallStatus) {
|
|
14172
13844
|
updatePayload.overallStatus = newOverallStatus;
|
|
14173
13845
|
}
|
|
14174
|
-
await
|
|
13846
|
+
await updateDoc26(instanceRef, updatePayload);
|
|
14175
13847
|
return {
|
|
14176
13848
|
...instance,
|
|
14177
13849
|
instructions: updatedInstructions,
|
|
@@ -14191,7 +13863,7 @@ import {
|
|
|
14191
13863
|
getDoc as getDoc31,
|
|
14192
13864
|
getDocs as getDocs29,
|
|
14193
13865
|
query as query29,
|
|
14194
|
-
updateDoc as
|
|
13866
|
+
updateDoc as updateDoc27,
|
|
14195
13867
|
where as where29
|
|
14196
13868
|
} from "firebase/firestore";
|
|
14197
13869
|
|
|
@@ -14242,7 +13914,7 @@ var BrandService = class extends BaseService {
|
|
|
14242
13914
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14243
13915
|
};
|
|
14244
13916
|
const docRef = doc29(this.getBrandsRef(), brandId);
|
|
14245
|
-
await
|
|
13917
|
+
await updateDoc27(docRef, updateData);
|
|
14246
13918
|
return this.getById(brandId);
|
|
14247
13919
|
}
|
|
14248
13920
|
/**
|
|
@@ -14275,7 +13947,7 @@ import {
|
|
|
14275
13947
|
getDoc as getDoc32,
|
|
14276
13948
|
getDocs as getDocs30,
|
|
14277
13949
|
query as query30,
|
|
14278
|
-
updateDoc as
|
|
13950
|
+
updateDoc as updateDoc28,
|
|
14279
13951
|
where as where30
|
|
14280
13952
|
} from "firebase/firestore";
|
|
14281
13953
|
|
|
@@ -14351,7 +14023,7 @@ var CategoryService = class extends BaseService {
|
|
|
14351
14023
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14352
14024
|
};
|
|
14353
14025
|
const docRef = doc30(this.categoriesRef, id);
|
|
14354
|
-
await
|
|
14026
|
+
await updateDoc28(docRef, updateData);
|
|
14355
14027
|
return this.getById(id);
|
|
14356
14028
|
}
|
|
14357
14029
|
/**
|
|
@@ -14385,7 +14057,7 @@ import {
|
|
|
14385
14057
|
getDoc as getDoc33,
|
|
14386
14058
|
getDocs as getDocs31,
|
|
14387
14059
|
query as query31,
|
|
14388
|
-
updateDoc as
|
|
14060
|
+
updateDoc as updateDoc29,
|
|
14389
14061
|
where as where31
|
|
14390
14062
|
} from "firebase/firestore";
|
|
14391
14063
|
|
|
@@ -14458,7 +14130,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
14458
14130
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14459
14131
|
};
|
|
14460
14132
|
const docRef = doc31(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
14461
|
-
await
|
|
14133
|
+
await updateDoc29(docRef, updateData);
|
|
14462
14134
|
return this.getById(categoryId, subcategoryId);
|
|
14463
14135
|
}
|
|
14464
14136
|
/**
|
|
@@ -14494,7 +14166,7 @@ import {
|
|
|
14494
14166
|
getDoc as getDoc34,
|
|
14495
14167
|
getDocs as getDocs32,
|
|
14496
14168
|
query as query32,
|
|
14497
|
-
updateDoc as
|
|
14169
|
+
updateDoc as updateDoc30,
|
|
14498
14170
|
where as where32,
|
|
14499
14171
|
arrayUnion as arrayUnion9,
|
|
14500
14172
|
arrayRemove as arrayRemove8
|
|
@@ -14617,7 +14289,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14617
14289
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14618
14290
|
};
|
|
14619
14291
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14620
|
-
await
|
|
14292
|
+
await updateDoc30(docRef, updateData);
|
|
14621
14293
|
return this.getById(technologyId);
|
|
14622
14294
|
}
|
|
14623
14295
|
/**
|
|
@@ -14652,7 +14324,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14652
14324
|
async addRequirement(technologyId, requirement) {
|
|
14653
14325
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14654
14326
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
14655
|
-
await
|
|
14327
|
+
await updateDoc30(docRef, {
|
|
14656
14328
|
[requirementType]: arrayUnion9(requirement),
|
|
14657
14329
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14658
14330
|
});
|
|
@@ -14667,7 +14339,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14667
14339
|
async removeRequirement(technologyId, requirement) {
|
|
14668
14340
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14669
14341
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
14670
|
-
await
|
|
14342
|
+
await updateDoc30(docRef, {
|
|
14671
14343
|
[requirementType]: arrayRemove8(requirement),
|
|
14672
14344
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14673
14345
|
});
|
|
@@ -14706,7 +14378,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14706
14378
|
*/
|
|
14707
14379
|
async addBlockingCondition(technologyId, condition) {
|
|
14708
14380
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14709
|
-
await
|
|
14381
|
+
await updateDoc30(docRef, {
|
|
14710
14382
|
blockingConditions: arrayUnion9(condition),
|
|
14711
14383
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14712
14384
|
});
|
|
@@ -14720,7 +14392,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14720
14392
|
*/
|
|
14721
14393
|
async removeBlockingCondition(technologyId, condition) {
|
|
14722
14394
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14723
|
-
await
|
|
14395
|
+
await updateDoc30(docRef, {
|
|
14724
14396
|
blockingConditions: arrayRemove8(condition),
|
|
14725
14397
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14726
14398
|
});
|
|
@@ -14734,7 +14406,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14734
14406
|
*/
|
|
14735
14407
|
async addContraindication(technologyId, contraindication) {
|
|
14736
14408
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14737
|
-
await
|
|
14409
|
+
await updateDoc30(docRef, {
|
|
14738
14410
|
contraindications: arrayUnion9(contraindication),
|
|
14739
14411
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14740
14412
|
});
|
|
@@ -14748,7 +14420,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14748
14420
|
*/
|
|
14749
14421
|
async removeContraindication(technologyId, contraindication) {
|
|
14750
14422
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14751
|
-
await
|
|
14423
|
+
await updateDoc30(docRef, {
|
|
14752
14424
|
contraindications: arrayRemove8(contraindication),
|
|
14753
14425
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14754
14426
|
});
|
|
@@ -14762,7 +14434,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14762
14434
|
*/
|
|
14763
14435
|
async addBenefit(technologyId, benefit) {
|
|
14764
14436
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14765
|
-
await
|
|
14437
|
+
await updateDoc30(docRef, {
|
|
14766
14438
|
benefits: arrayUnion9(benefit),
|
|
14767
14439
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14768
14440
|
});
|
|
@@ -14776,7 +14448,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14776
14448
|
*/
|
|
14777
14449
|
async removeBenefit(technologyId, benefit) {
|
|
14778
14450
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14779
|
-
await
|
|
14451
|
+
await updateDoc30(docRef, {
|
|
14780
14452
|
benefits: arrayRemove8(benefit),
|
|
14781
14453
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14782
14454
|
});
|
|
@@ -14817,7 +14489,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14817
14489
|
*/
|
|
14818
14490
|
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
14819
14491
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14820
|
-
await
|
|
14492
|
+
await updateDoc30(docRef, {
|
|
14821
14493
|
certificationRequirement,
|
|
14822
14494
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14823
14495
|
});
|
|
@@ -14924,7 +14596,7 @@ import {
|
|
|
14924
14596
|
getDoc as getDoc35,
|
|
14925
14597
|
getDocs as getDocs33,
|
|
14926
14598
|
query as query33,
|
|
14927
|
-
updateDoc as
|
|
14599
|
+
updateDoc as updateDoc31,
|
|
14928
14600
|
where as where33
|
|
14929
14601
|
} from "firebase/firestore";
|
|
14930
14602
|
|
|
@@ -15015,7 +14687,7 @@ var ProductService = class extends BaseService {
|
|
|
15015
14687
|
updatedAt: /* @__PURE__ */ new Date()
|
|
15016
14688
|
};
|
|
15017
14689
|
const docRef = doc33(this.getProductsRef(technologyId), productId);
|
|
15018
|
-
await
|
|
14690
|
+
await updateDoc31(docRef, updateData);
|
|
15019
14691
|
return this.getById(technologyId, productId);
|
|
15020
14692
|
}
|
|
15021
14693
|
/**
|
|
@@ -15041,63 +14713,63 @@ var ProductService = class extends BaseService {
|
|
|
15041
14713
|
};
|
|
15042
14714
|
|
|
15043
14715
|
// src/validations/notification.schema.ts
|
|
15044
|
-
import { z as
|
|
15045
|
-
var baseNotificationSchema =
|
|
15046
|
-
id:
|
|
15047
|
-
userId:
|
|
15048
|
-
notificationTime:
|
|
14716
|
+
import { z as z25 } from "zod";
|
|
14717
|
+
var baseNotificationSchema = z25.object({
|
|
14718
|
+
id: z25.string().optional(),
|
|
14719
|
+
userId: z25.string(),
|
|
14720
|
+
notificationTime: z25.any(),
|
|
15049
14721
|
// Timestamp
|
|
15050
|
-
notificationType:
|
|
15051
|
-
notificationTokens:
|
|
15052
|
-
status:
|
|
15053
|
-
createdAt:
|
|
14722
|
+
notificationType: z25.nativeEnum(NotificationType),
|
|
14723
|
+
notificationTokens: z25.array(z25.string()),
|
|
14724
|
+
status: z25.nativeEnum(NotificationStatus),
|
|
14725
|
+
createdAt: z25.any().optional(),
|
|
15054
14726
|
// Timestamp
|
|
15055
|
-
updatedAt:
|
|
14727
|
+
updatedAt: z25.any().optional(),
|
|
15056
14728
|
// Timestamp
|
|
15057
|
-
title:
|
|
15058
|
-
body:
|
|
15059
|
-
isRead:
|
|
15060
|
-
userRole:
|
|
14729
|
+
title: z25.string(),
|
|
14730
|
+
body: z25.string(),
|
|
14731
|
+
isRead: z25.boolean(),
|
|
14732
|
+
userRole: z25.nativeEnum(UserRole)
|
|
15061
14733
|
});
|
|
15062
14734
|
var preRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
15063
|
-
notificationType:
|
|
15064
|
-
treatmentId:
|
|
15065
|
-
requirements:
|
|
15066
|
-
deadline:
|
|
14735
|
+
notificationType: z25.literal("preRequirementInstructionDue" /* PRE_REQUIREMENT_INSTRUCTION_DUE */),
|
|
14736
|
+
treatmentId: z25.string(),
|
|
14737
|
+
requirements: z25.array(z25.string()),
|
|
14738
|
+
deadline: z25.any()
|
|
15067
14739
|
// Timestamp
|
|
15068
14740
|
});
|
|
15069
14741
|
var postRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
15070
|
-
notificationType:
|
|
14742
|
+
notificationType: z25.literal(
|
|
15071
14743
|
"postRequirementInstructionDue" /* POST_REQUIREMENT_INSTRUCTION_DUE */
|
|
15072
14744
|
),
|
|
15073
|
-
treatmentId:
|
|
15074
|
-
requirements:
|
|
15075
|
-
deadline:
|
|
14745
|
+
treatmentId: z25.string(),
|
|
14746
|
+
requirements: z25.array(z25.string()),
|
|
14747
|
+
deadline: z25.any()
|
|
15076
14748
|
// Timestamp
|
|
15077
14749
|
});
|
|
15078
14750
|
var requirementInstructionDueNotificationSchema = baseNotificationSchema.extend({
|
|
15079
|
-
notificationType:
|
|
15080
|
-
appointmentId:
|
|
15081
|
-
patientRequirementInstanceId:
|
|
15082
|
-
instructionId:
|
|
15083
|
-
originalRequirementId:
|
|
14751
|
+
notificationType: z25.literal("requirementInstructionDue" /* REQUIREMENT_INSTRUCTION_DUE */),
|
|
14752
|
+
appointmentId: z25.string(),
|
|
14753
|
+
patientRequirementInstanceId: z25.string(),
|
|
14754
|
+
instructionId: z25.string(),
|
|
14755
|
+
originalRequirementId: z25.string().optional()
|
|
15084
14756
|
});
|
|
15085
14757
|
var appointmentReminderNotificationSchema = baseNotificationSchema.extend({
|
|
15086
|
-
notificationType:
|
|
15087
|
-
appointmentId:
|
|
15088
|
-
appointmentTime:
|
|
14758
|
+
notificationType: z25.literal("appointmentReminder" /* APPOINTMENT_REMINDER */),
|
|
14759
|
+
appointmentId: z25.string(),
|
|
14760
|
+
appointmentTime: z25.any(),
|
|
15089
14761
|
// Timestamp
|
|
15090
|
-
treatmentType:
|
|
15091
|
-
doctorName:
|
|
14762
|
+
treatmentType: z25.string(),
|
|
14763
|
+
doctorName: z25.string()
|
|
15092
14764
|
});
|
|
15093
14765
|
var appointmentNotificationSchema = baseNotificationSchema.extend({
|
|
15094
|
-
notificationType:
|
|
15095
|
-
appointmentId:
|
|
15096
|
-
appointmentStatus:
|
|
15097
|
-
previousStatus:
|
|
15098
|
-
reason:
|
|
14766
|
+
notificationType: z25.literal("appointmentStatusChange" /* APPOINTMENT_STATUS_CHANGE */),
|
|
14767
|
+
appointmentId: z25.string(),
|
|
14768
|
+
appointmentStatus: z25.string(),
|
|
14769
|
+
previousStatus: z25.string(),
|
|
14770
|
+
reason: z25.string().optional()
|
|
15099
14771
|
});
|
|
15100
|
-
var notificationSchema =
|
|
14772
|
+
var notificationSchema = z25.discriminatedUnion("notificationType", [
|
|
15101
14773
|
preRequirementNotificationSchema,
|
|
15102
14774
|
postRequirementNotificationSchema,
|
|
15103
14775
|
requirementInstructionDueNotificationSchema,
|
|
@@ -15180,6 +14852,9 @@ export {
|
|
|
15180
14852
|
HeadingLevel,
|
|
15181
14853
|
Language,
|
|
15182
14854
|
ListType,
|
|
14855
|
+
MEDIA_METADATA_COLLECTION,
|
|
14856
|
+
MediaAccessLevel,
|
|
14857
|
+
MediaService,
|
|
15183
14858
|
MedicationAllergySubtype,
|
|
15184
14859
|
NotificationService,
|
|
15185
14860
|
NotificationStatus,
|