@blackcode_sa/metaestetics-api 1.7.11 → 1.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +200 -1
- package/dist/admin/index.d.ts +200 -1
- package/dist/admin/index.js +691 -35
- package/dist/admin/index.mjs +689 -35
- package/dist/index.d.mts +138 -37
- package/dist/index.d.ts +138 -37
- package/dist/index.js +543 -875
- package/dist/index.mjs +588 -922
- package/package.json +1 -1
- package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +316 -0
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +641 -0
- package/src/admin/index.ts +8 -1
- package/src/services/auth.service.ts +4 -0
- package/src/services/clinic/clinic-group.service.ts +49 -0
- package/src/services/clinic/clinic.service.ts +12 -0
- package/src/services/reviews/reviews.service.ts +6 -572
- package/src/types/clinic/index.ts +16 -0
- package/src/validations/clinic.schema.ts +25 -9
- package/src/validations/media.schema.ts +10 -0
package/dist/index.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);
|
|
@@ -6903,7 +6959,7 @@ var ClinicService = class extends BaseService {
|
|
|
6903
6959
|
if (!savedClinic) throw new Error("Failed to retrieve created clinic");
|
|
6904
6960
|
return savedClinic;
|
|
6905
6961
|
} catch (error) {
|
|
6906
|
-
if (error instanceof
|
|
6962
|
+
if (error instanceof z19.ZodError) {
|
|
6907
6963
|
throw new Error("Invalid clinic data: " + error.message);
|
|
6908
6964
|
}
|
|
6909
6965
|
console.error("Error creating clinic:", error);
|
|
@@ -6983,7 +7039,7 @@ var ClinicService = class extends BaseService {
|
|
|
6983
7039
|
if (!updatedClinic) throw new Error("Failed to retrieve updated clinic");
|
|
6984
7040
|
return updatedClinic;
|
|
6985
7041
|
} catch (error) {
|
|
6986
|
-
if (error instanceof
|
|
7042
|
+
if (error instanceof z19.ZodError) {
|
|
6987
7043
|
throw new Error("Invalid clinic update data: " + error.message);
|
|
6988
7044
|
}
|
|
6989
7045
|
console.error(`Error updating clinic ${clinicId}:`, error);
|
|
@@ -7000,6 +7056,16 @@ var ClinicService = class extends BaseService {
|
|
|
7000
7056
|
updatedAt: serverTimestamp12()
|
|
7001
7057
|
});
|
|
7002
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
|
+
}
|
|
7003
7069
|
/**
|
|
7004
7070
|
* Dohvata kliniku po ID-u
|
|
7005
7071
|
*/
|
|
@@ -7305,7 +7371,11 @@ var AuthService = class extends BaseService {
|
|
|
7305
7371
|
// Use admin profile ID, not user UID
|
|
7306
7372
|
isActive: true,
|
|
7307
7373
|
logo: data.clinicGroupData.logo || null,
|
|
7308
|
-
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
|
+
}
|
|
7309
7379
|
};
|
|
7310
7380
|
console.log("[AUTH] Clinic group data prepared", {
|
|
7311
7381
|
groupName: createClinicGroupData.name
|
|
@@ -7445,7 +7515,7 @@ var AuthService = class extends BaseService {
|
|
|
7445
7515
|
clinicAdmin: adminProfile
|
|
7446
7516
|
};
|
|
7447
7517
|
} catch (error) {
|
|
7448
|
-
if (error instanceof
|
|
7518
|
+
if (error instanceof z20.ZodError) {
|
|
7449
7519
|
console.error(
|
|
7450
7520
|
"[AUTH] Zod validation error in signUpClinicAdmin:",
|
|
7451
7521
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -7620,7 +7690,7 @@ var AuthService = class extends BaseService {
|
|
|
7620
7690
|
email
|
|
7621
7691
|
);
|
|
7622
7692
|
} catch (error) {
|
|
7623
|
-
if (error instanceof
|
|
7693
|
+
if (error instanceof z20.ZodError) {
|
|
7624
7694
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7625
7695
|
}
|
|
7626
7696
|
const firebaseError = error;
|
|
@@ -7743,7 +7813,7 @@ var AuthService = class extends BaseService {
|
|
|
7743
7813
|
await emailSchema.parseAsync(email);
|
|
7744
7814
|
await sendPasswordResetEmail(this.auth, email);
|
|
7745
7815
|
} catch (error) {
|
|
7746
|
-
if (error instanceof
|
|
7816
|
+
if (error instanceof z20.ZodError) {
|
|
7747
7817
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7748
7818
|
}
|
|
7749
7819
|
const firebaseError = error;
|
|
@@ -7782,7 +7852,7 @@ var AuthService = class extends BaseService {
|
|
|
7782
7852
|
await passwordSchema.parseAsync(newPassword);
|
|
7783
7853
|
await confirmPasswordReset(this.auth, oobCode, newPassword);
|
|
7784
7854
|
} catch (error) {
|
|
7785
|
-
if (error instanceof
|
|
7855
|
+
if (error instanceof z20.ZodError) {
|
|
7786
7856
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
7787
7857
|
}
|
|
7788
7858
|
const firebaseError = error;
|
|
@@ -7951,7 +8021,7 @@ var AuthService = class extends BaseService {
|
|
|
7951
8021
|
practitioner
|
|
7952
8022
|
};
|
|
7953
8023
|
} catch (error) {
|
|
7954
|
-
if (error instanceof
|
|
8024
|
+
if (error instanceof z20.ZodError) {
|
|
7955
8025
|
console.error(
|
|
7956
8026
|
"[AUTH] Zod validation error in signUpPractitioner:",
|
|
7957
8027
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -8256,63 +8326,63 @@ import {
|
|
|
8256
8326
|
var PROCEDURES_COLLECTION = "procedures";
|
|
8257
8327
|
|
|
8258
8328
|
// src/validations/procedure.schema.ts
|
|
8259
|
-
import { z as
|
|
8260
|
-
var createProcedureSchema =
|
|
8261
|
-
name:
|
|
8262
|
-
description:
|
|
8263
|
-
family:
|
|
8264
|
-
categoryId:
|
|
8265
|
-
subcategoryId:
|
|
8266
|
-
technologyId:
|
|
8267
|
-
productId:
|
|
8268
|
-
price:
|
|
8269
|
-
currency:
|
|
8270
|
-
pricingMeasure:
|
|
8271
|
-
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),
|
|
8272
8342
|
// Max 8 hours
|
|
8273
|
-
practitionerId:
|
|
8274
|
-
clinicBranchId:
|
|
8275
|
-
photos:
|
|
8343
|
+
practitionerId: z21.string().min(1),
|
|
8344
|
+
clinicBranchId: z21.string().min(1),
|
|
8345
|
+
photos: z21.array(z21.string()).optional()
|
|
8276
8346
|
});
|
|
8277
|
-
var updateProcedureSchema =
|
|
8278
|
-
name:
|
|
8279
|
-
description:
|
|
8280
|
-
price:
|
|
8281
|
-
currency:
|
|
8282
|
-
pricingMeasure:
|
|
8283
|
-
duration:
|
|
8284
|
-
isActive:
|
|
8285
|
-
practitionerId:
|
|
8286
|
-
categoryId:
|
|
8287
|
-
subcategoryId:
|
|
8288
|
-
technologyId:
|
|
8289
|
-
productId:
|
|
8290
|
-
clinicBranchId:
|
|
8291
|
-
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()
|
|
8292
8362
|
});
|
|
8293
8363
|
var procedureSchema = createProcedureSchema.extend({
|
|
8294
|
-
id:
|
|
8295
|
-
category:
|
|
8364
|
+
id: z21.string().min(1),
|
|
8365
|
+
category: z21.any(),
|
|
8296
8366
|
// We'll validate the full category object separately
|
|
8297
|
-
subcategory:
|
|
8367
|
+
subcategory: z21.any(),
|
|
8298
8368
|
// We'll validate the full subcategory object separately
|
|
8299
|
-
technology:
|
|
8369
|
+
technology: z21.any(),
|
|
8300
8370
|
// We'll validate the full technology object separately
|
|
8301
|
-
product:
|
|
8371
|
+
product: z21.any(),
|
|
8302
8372
|
// We'll validate the full product object separately
|
|
8303
|
-
blockingConditions:
|
|
8373
|
+
blockingConditions: z21.array(z21.any()),
|
|
8304
8374
|
// We'll validate blocking conditions separately
|
|
8305
|
-
contraindications:
|
|
8375
|
+
contraindications: z21.array(z21.any()),
|
|
8306
8376
|
// We'll validate contraindications separately
|
|
8307
|
-
treatmentBenefits:
|
|
8377
|
+
treatmentBenefits: z21.array(z21.any()),
|
|
8308
8378
|
// We'll validate treatment benefits separately
|
|
8309
|
-
preRequirements:
|
|
8379
|
+
preRequirements: z21.array(z21.any()),
|
|
8310
8380
|
// We'll validate requirements separately
|
|
8311
|
-
postRequirements:
|
|
8381
|
+
postRequirements: z21.array(z21.any()),
|
|
8312
8382
|
// We'll validate requirements separately
|
|
8313
|
-
certificationRequirement:
|
|
8383
|
+
certificationRequirement: z21.any(),
|
|
8314
8384
|
// We'll validate certification requirement separately
|
|
8315
|
-
documentationTemplates:
|
|
8385
|
+
documentationTemplates: z21.array(z21.any()),
|
|
8316
8386
|
// We'll validate documentation templates separately
|
|
8317
8387
|
clinicInfo: clinicInfoSchema,
|
|
8318
8388
|
// Clinic info validation
|
|
@@ -8320,9 +8390,9 @@ var procedureSchema = createProcedureSchema.extend({
|
|
|
8320
8390
|
// Doctor info validation
|
|
8321
8391
|
reviewInfo: procedureReviewInfoSchema,
|
|
8322
8392
|
// Procedure review info validation
|
|
8323
|
-
isActive:
|
|
8324
|
-
createdAt:
|
|
8325
|
-
updatedAt:
|
|
8393
|
+
isActive: z21.boolean(),
|
|
8394
|
+
createdAt: z21.date(),
|
|
8395
|
+
updatedAt: z21.date()
|
|
8326
8396
|
});
|
|
8327
8397
|
|
|
8328
8398
|
// src/services/procedure/procedure.service.ts
|
|
@@ -9530,42 +9600,42 @@ import {
|
|
|
9530
9600
|
} from "firebase/firestore";
|
|
9531
9601
|
|
|
9532
9602
|
// src/validations/calendar.schema.ts
|
|
9533
|
-
import { z as
|
|
9603
|
+
import { z as z23 } from "zod";
|
|
9534
9604
|
import { Timestamp as Timestamp20 } from "firebase/firestore";
|
|
9535
9605
|
|
|
9536
9606
|
// src/validations/profile-info.schema.ts
|
|
9537
|
-
import { z as
|
|
9607
|
+
import { z as z22 } from "zod";
|
|
9538
9608
|
import { Timestamp as Timestamp19 } from "firebase/firestore";
|
|
9539
|
-
var clinicInfoSchema2 =
|
|
9540
|
-
id:
|
|
9541
|
-
featuredPhoto:
|
|
9542
|
-
name:
|
|
9543
|
-
description:
|
|
9609
|
+
var clinicInfoSchema2 = z22.object({
|
|
9610
|
+
id: z22.string(),
|
|
9611
|
+
featuredPhoto: z22.string(),
|
|
9612
|
+
name: z22.string(),
|
|
9613
|
+
description: z22.string(),
|
|
9544
9614
|
location: clinicLocationSchema,
|
|
9545
9615
|
contactInfo: clinicContactInfoSchema
|
|
9546
9616
|
});
|
|
9547
|
-
var practitionerProfileInfoSchema =
|
|
9548
|
-
id:
|
|
9549
|
-
practitionerPhoto:
|
|
9550
|
-
name:
|
|
9551
|
-
email:
|
|
9552
|
-
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(),
|
|
9553
9623
|
certification: practitionerCertificationSchema
|
|
9554
9624
|
});
|
|
9555
|
-
var patientProfileInfoSchema =
|
|
9556
|
-
id:
|
|
9557
|
-
fullName:
|
|
9558
|
-
email:
|
|
9559
|
-
phone:
|
|
9560
|
-
dateOfBirth:
|
|
9561
|
-
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)
|
|
9562
9632
|
});
|
|
9563
9633
|
|
|
9564
9634
|
// src/validations/calendar.schema.ts
|
|
9565
9635
|
var MIN_APPOINTMENT_DURATION = 15;
|
|
9566
|
-
var calendarEventTimeSchema =
|
|
9567
|
-
start:
|
|
9568
|
-
end:
|
|
9636
|
+
var calendarEventTimeSchema = z23.object({
|
|
9637
|
+
start: z23.instanceof(Date).or(z23.instanceof(Timestamp20)),
|
|
9638
|
+
end: z23.instanceof(Date).or(z23.instanceof(Timestamp20))
|
|
9569
9639
|
}).refine(
|
|
9570
9640
|
(data) => {
|
|
9571
9641
|
const startDate = data.start instanceof Timestamp20 ? data.start.toDate() : data.start;
|
|
@@ -9586,46 +9656,46 @@ var calendarEventTimeSchema = z22.object({
|
|
|
9586
9656
|
path: ["start"]
|
|
9587
9657
|
}
|
|
9588
9658
|
);
|
|
9589
|
-
var timeSlotSchema2 =
|
|
9590
|
-
start:
|
|
9591
|
-
end:
|
|
9592
|
-
isAvailable:
|
|
9659
|
+
var timeSlotSchema2 = z23.object({
|
|
9660
|
+
start: z23.date(),
|
|
9661
|
+
end: z23.date(),
|
|
9662
|
+
isAvailable: z23.boolean()
|
|
9593
9663
|
}).refine((data) => data.start < data.end, {
|
|
9594
9664
|
message: "End time must be after start time",
|
|
9595
9665
|
path: ["end"]
|
|
9596
9666
|
});
|
|
9597
|
-
var syncedCalendarEventSchema =
|
|
9598
|
-
eventId:
|
|
9599
|
-
syncedCalendarProvider:
|
|
9600
|
-
syncedAt:
|
|
9667
|
+
var syncedCalendarEventSchema = z23.object({
|
|
9668
|
+
eventId: z23.string(),
|
|
9669
|
+
syncedCalendarProvider: z23.nativeEnum(SyncedCalendarProvider),
|
|
9670
|
+
syncedAt: z23.instanceof(Date).or(z23.instanceof(Timestamp20))
|
|
9601
9671
|
});
|
|
9602
|
-
var procedureInfoSchema =
|
|
9603
|
-
name:
|
|
9604
|
-
description:
|
|
9605
|
-
duration:
|
|
9606
|
-
price:
|
|
9607
|
-
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)
|
|
9608
9678
|
});
|
|
9609
|
-
var procedureCategorizationSchema =
|
|
9610
|
-
procedureFamily:
|
|
9679
|
+
var procedureCategorizationSchema = z23.object({
|
|
9680
|
+
procedureFamily: z23.string(),
|
|
9611
9681
|
// Replace with proper enum when available
|
|
9612
|
-
procedureCategory:
|
|
9682
|
+
procedureCategory: z23.string(),
|
|
9613
9683
|
// Replace with proper enum when available
|
|
9614
|
-
procedureSubcategory:
|
|
9684
|
+
procedureSubcategory: z23.string(),
|
|
9615
9685
|
// Replace with proper enum when available
|
|
9616
|
-
procedureTechnology:
|
|
9686
|
+
procedureTechnology: z23.string(),
|
|
9617
9687
|
// Replace with proper enum when available
|
|
9618
|
-
procedureProduct:
|
|
9688
|
+
procedureProduct: z23.string()
|
|
9619
9689
|
// Replace with proper enum when available
|
|
9620
9690
|
});
|
|
9621
|
-
var createAppointmentSchema2 =
|
|
9622
|
-
clinicId:
|
|
9623
|
-
doctorId:
|
|
9624
|
-
patientId:
|
|
9625
|
-
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"),
|
|
9626
9696
|
eventLocation: clinicLocationSchema,
|
|
9627
9697
|
eventTime: calendarEventTimeSchema,
|
|
9628
|
-
description:
|
|
9698
|
+
description: z23.string().optional()
|
|
9629
9699
|
}).refine(
|
|
9630
9700
|
(data) => {
|
|
9631
9701
|
return true;
|
|
@@ -9634,73 +9704,73 @@ var createAppointmentSchema2 = z22.object({
|
|
|
9634
9704
|
message: "Invalid appointment parameters"
|
|
9635
9705
|
}
|
|
9636
9706
|
);
|
|
9637
|
-
var updateAppointmentSchema2 =
|
|
9638
|
-
appointmentId:
|
|
9639
|
-
clinicId:
|
|
9640
|
-
doctorId:
|
|
9641
|
-
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"),
|
|
9642
9712
|
eventTime: calendarEventTimeSchema.optional(),
|
|
9643
|
-
description:
|
|
9644
|
-
status:
|
|
9713
|
+
description: z23.string().optional(),
|
|
9714
|
+
status: z23.nativeEnum(CalendarEventStatus).optional()
|
|
9645
9715
|
});
|
|
9646
|
-
var createCalendarEventSchema =
|
|
9647
|
-
id:
|
|
9648
|
-
clinicBranchId:
|
|
9649
|
-
clinicBranchInfo:
|
|
9650
|
-
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(),
|
|
9651
9721
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
9652
|
-
patientProfileId:
|
|
9722
|
+
patientProfileId: z23.string().nullable().optional(),
|
|
9653
9723
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
9654
|
-
procedureId:
|
|
9655
|
-
appointmentId:
|
|
9656
|
-
syncedCalendarEventId:
|
|
9657
|
-
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"),
|
|
9658
9728
|
eventLocation: clinicLocationSchema.optional(),
|
|
9659
9729
|
eventTime: calendarEventTimeSchema,
|
|
9660
|
-
description:
|
|
9661
|
-
status:
|
|
9662
|
-
syncStatus:
|
|
9663
|
-
eventType:
|
|
9664
|
-
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(),
|
|
9665
9735
|
// FieldValue for server timestamp
|
|
9666
|
-
updatedAt:
|
|
9736
|
+
updatedAt: z23.any()
|
|
9667
9737
|
// FieldValue for server timestamp
|
|
9668
9738
|
});
|
|
9669
|
-
var updateCalendarEventSchema =
|
|
9670
|
-
syncedCalendarEventId:
|
|
9671
|
-
appointmentId:
|
|
9672
|
-
eventName:
|
|
9739
|
+
var updateCalendarEventSchema = z23.object({
|
|
9740
|
+
syncedCalendarEventId: z23.array(syncedCalendarEventSchema).nullable().optional(),
|
|
9741
|
+
appointmentId: z23.string().nullable().optional(),
|
|
9742
|
+
eventName: z23.string().optional(),
|
|
9673
9743
|
eventTime: calendarEventTimeSchema.optional(),
|
|
9674
|
-
description:
|
|
9675
|
-
status:
|
|
9676
|
-
syncStatus:
|
|
9677
|
-
eventType:
|
|
9678
|
-
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()
|
|
9679
9749
|
// FieldValue for server timestamp
|
|
9680
9750
|
});
|
|
9681
|
-
var calendarEventSchema =
|
|
9682
|
-
id:
|
|
9683
|
-
clinicBranchId:
|
|
9684
|
-
clinicBranchInfo:
|
|
9751
|
+
var calendarEventSchema = z23.object({
|
|
9752
|
+
id: z23.string(),
|
|
9753
|
+
clinicBranchId: z23.string().nullable().optional(),
|
|
9754
|
+
clinicBranchInfo: z23.any().nullable().optional(),
|
|
9685
9755
|
// Will be replaced with proper clinic info schema
|
|
9686
|
-
practitionerProfileId:
|
|
9756
|
+
practitionerProfileId: z23.string().nullable().optional(),
|
|
9687
9757
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
9688
|
-
patientProfileId:
|
|
9758
|
+
patientProfileId: z23.string().nullable().optional(),
|
|
9689
9759
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
9690
|
-
procedureId:
|
|
9760
|
+
procedureId: z23.string().nullable().optional(),
|
|
9691
9761
|
procedureInfo: procedureInfoSchema.nullable().optional(),
|
|
9692
9762
|
procedureCategorization: procedureCategorizationSchema.nullable().optional(),
|
|
9693
|
-
appointmentId:
|
|
9694
|
-
syncedCalendarEventId:
|
|
9695
|
-
eventName:
|
|
9763
|
+
appointmentId: z23.string().nullable().optional(),
|
|
9764
|
+
syncedCalendarEventId: z23.array(syncedCalendarEventSchema).nullable().optional(),
|
|
9765
|
+
eventName: z23.string(),
|
|
9696
9766
|
eventLocation: clinicLocationSchema.optional(),
|
|
9697
9767
|
eventTime: calendarEventTimeSchema,
|
|
9698
|
-
description:
|
|
9699
|
-
status:
|
|
9700
|
-
syncStatus:
|
|
9701
|
-
eventType:
|
|
9702
|
-
createdAt:
|
|
9703
|
-
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))
|
|
9704
9774
|
});
|
|
9705
9775
|
|
|
9706
9776
|
// src/services/calendar/utils/clinic.utils.ts
|
|
@@ -12302,24 +12372,22 @@ import {
|
|
|
12302
12372
|
getDocs as getDocs25,
|
|
12303
12373
|
query as query25,
|
|
12304
12374
|
where as where25,
|
|
12305
|
-
updateDoc as updateDoc25,
|
|
12306
12375
|
setDoc as setDoc23,
|
|
12307
12376
|
deleteDoc as deleteDoc16,
|
|
12308
|
-
serverTimestamp as serverTimestamp22
|
|
12309
|
-
writeBatch as writeBatch7
|
|
12377
|
+
serverTimestamp as serverTimestamp22
|
|
12310
12378
|
} from "firebase/firestore";
|
|
12311
12379
|
|
|
12312
12380
|
// src/types/reviews/index.ts
|
|
12313
12381
|
var REVIEWS_COLLECTION = "reviews";
|
|
12314
12382
|
|
|
12315
12383
|
// src/services/reviews/reviews.service.ts
|
|
12316
|
-
import { z as
|
|
12384
|
+
import { z as z24 } from "zod";
|
|
12317
12385
|
var ReviewService = class extends BaseService {
|
|
12318
12386
|
constructor(db, auth, app) {
|
|
12319
12387
|
super(db, auth, app);
|
|
12320
12388
|
}
|
|
12321
12389
|
/**
|
|
12322
|
-
* Creates a new review
|
|
12390
|
+
* Creates a new review
|
|
12323
12391
|
* @param data - The review data to create
|
|
12324
12392
|
* @param appointmentId - ID of the completed appointment
|
|
12325
12393
|
* @returns The created review
|
|
@@ -12398,28 +12466,9 @@ var ReviewService = class extends BaseService {
|
|
|
12398
12466
|
createdAt: serverTimestamp22(),
|
|
12399
12467
|
updatedAt: serverTimestamp22()
|
|
12400
12468
|
});
|
|
12401
|
-
const updatePromises = [];
|
|
12402
|
-
if (data.clinicReview) {
|
|
12403
|
-
updatePromises.push(
|
|
12404
|
-
this.updateClinicReviewInfo(data.clinicReview.clinicId)
|
|
12405
|
-
);
|
|
12406
|
-
}
|
|
12407
|
-
if (data.practitionerReview) {
|
|
12408
|
-
updatePromises.push(
|
|
12409
|
-
this.updatePractitionerReviewInfo(
|
|
12410
|
-
data.practitionerReview.practitionerId
|
|
12411
|
-
)
|
|
12412
|
-
);
|
|
12413
|
-
}
|
|
12414
|
-
if (data.procedureReview) {
|
|
12415
|
-
updatePromises.push(
|
|
12416
|
-
this.updateProcedureReviewInfo(data.procedureReview.procedureId)
|
|
12417
|
-
);
|
|
12418
|
-
}
|
|
12419
|
-
await Promise.all(updatePromises);
|
|
12420
12469
|
return review;
|
|
12421
12470
|
} catch (error) {
|
|
12422
|
-
if (error instanceof
|
|
12471
|
+
if (error instanceof z24.ZodError) {
|
|
12423
12472
|
throw new Error(`Invalid review data: ${error.message}`);
|
|
12424
12473
|
}
|
|
12425
12474
|
throw error;
|
|
@@ -12507,7 +12556,7 @@ var ReviewService = class extends BaseService {
|
|
|
12507
12556
|
return snapshot.docs[0].data();
|
|
12508
12557
|
}
|
|
12509
12558
|
/**
|
|
12510
|
-
* Deletes a review
|
|
12559
|
+
* Deletes a review
|
|
12511
12560
|
* @param reviewId The ID of the review to delete
|
|
12512
12561
|
*/
|
|
12513
12562
|
async deleteReview(reviewId) {
|
|
@@ -12516,389 +12565,6 @@ var ReviewService = class extends BaseService {
|
|
|
12516
12565
|
throw new Error(`Review with ID ${reviewId} not found`);
|
|
12517
12566
|
}
|
|
12518
12567
|
await deleteDoc16(doc26(this.db, REVIEWS_COLLECTION, reviewId));
|
|
12519
|
-
const updatePromises = [];
|
|
12520
|
-
if (review.clinicReview) {
|
|
12521
|
-
updatePromises.push(
|
|
12522
|
-
this.updateClinicReviewInfo(
|
|
12523
|
-
review.clinicReview.clinicId,
|
|
12524
|
-
review.clinicReview,
|
|
12525
|
-
true
|
|
12526
|
-
)
|
|
12527
|
-
);
|
|
12528
|
-
}
|
|
12529
|
-
if (review.practitionerReview) {
|
|
12530
|
-
updatePromises.push(
|
|
12531
|
-
this.updatePractitionerReviewInfo(
|
|
12532
|
-
review.practitionerReview.practitionerId,
|
|
12533
|
-
review.practitionerReview,
|
|
12534
|
-
true
|
|
12535
|
-
)
|
|
12536
|
-
);
|
|
12537
|
-
}
|
|
12538
|
-
if (review.procedureReview) {
|
|
12539
|
-
updatePromises.push(
|
|
12540
|
-
this.updateProcedureReviewInfo(
|
|
12541
|
-
review.procedureReview.procedureId,
|
|
12542
|
-
review.procedureReview,
|
|
12543
|
-
true
|
|
12544
|
-
)
|
|
12545
|
-
);
|
|
12546
|
-
}
|
|
12547
|
-
await Promise.all(updatePromises);
|
|
12548
|
-
}
|
|
12549
|
-
/**
|
|
12550
|
-
* Updates the review info for a clinic
|
|
12551
|
-
* @param clinicId The ID of the clinic to update
|
|
12552
|
-
* @param newReview Optional new review being added or removed
|
|
12553
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12554
|
-
* @returns The updated clinic review info
|
|
12555
|
-
*/
|
|
12556
|
-
async updateClinicReviewInfo(clinicId, newReview, isRemoval = false) {
|
|
12557
|
-
const clinicDoc = await getDoc28(doc26(this.db, CLINICS_COLLECTION, clinicId));
|
|
12558
|
-
if (!clinicDoc.exists()) {
|
|
12559
|
-
throw new Error(`Clinic with ID ${clinicId} not found`);
|
|
12560
|
-
}
|
|
12561
|
-
const clinicData = clinicDoc.data();
|
|
12562
|
-
const currentReviewInfo = clinicData.reviewInfo || {
|
|
12563
|
-
totalReviews: 0,
|
|
12564
|
-
averageRating: 0,
|
|
12565
|
-
cleanliness: 0,
|
|
12566
|
-
facilities: 0,
|
|
12567
|
-
staffFriendliness: 0,
|
|
12568
|
-
waitingTime: 0,
|
|
12569
|
-
accessibility: 0,
|
|
12570
|
-
recommendationPercentage: 0
|
|
12571
|
-
};
|
|
12572
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12573
|
-
await updateDoc25(doc26(this.db, CLINICS_COLLECTION, clinicId), {
|
|
12574
|
-
reviewInfo: currentReviewInfo,
|
|
12575
|
-
updatedAt: serverTimestamp22()
|
|
12576
|
-
});
|
|
12577
|
-
return currentReviewInfo;
|
|
12578
|
-
}
|
|
12579
|
-
let updatedReviewInfo;
|
|
12580
|
-
if (newReview) {
|
|
12581
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12582
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12583
|
-
if (newTotal === 0) {
|
|
12584
|
-
updatedReviewInfo = {
|
|
12585
|
-
totalReviews: 0,
|
|
12586
|
-
averageRating: 0,
|
|
12587
|
-
cleanliness: 0,
|
|
12588
|
-
facilities: 0,
|
|
12589
|
-
staffFriendliness: 0,
|
|
12590
|
-
waitingTime: 0,
|
|
12591
|
-
accessibility: 0,
|
|
12592
|
-
recommendationPercentage: 0
|
|
12593
|
-
};
|
|
12594
|
-
} else {
|
|
12595
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12596
|
-
const currentSum = currentAvg * oldTotal;
|
|
12597
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12598
|
-
const newAvg = newSum / newTotal;
|
|
12599
|
-
return Math.round(newAvg * 10) / 10;
|
|
12600
|
-
};
|
|
12601
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12602
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12603
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12604
|
-
updatedReviewInfo = {
|
|
12605
|
-
totalReviews: newTotal,
|
|
12606
|
-
averageRating: updateAverage(
|
|
12607
|
-
currentReviewInfo.averageRating,
|
|
12608
|
-
newReview.overallRating
|
|
12609
|
-
),
|
|
12610
|
-
cleanliness: updateAverage(
|
|
12611
|
-
currentReviewInfo.cleanliness,
|
|
12612
|
-
newReview.cleanliness
|
|
12613
|
-
),
|
|
12614
|
-
facilities: updateAverage(
|
|
12615
|
-
currentReviewInfo.facilities,
|
|
12616
|
-
newReview.facilities
|
|
12617
|
-
),
|
|
12618
|
-
staffFriendliness: updateAverage(
|
|
12619
|
-
currentReviewInfo.staffFriendliness,
|
|
12620
|
-
newReview.staffFriendliness
|
|
12621
|
-
),
|
|
12622
|
-
waitingTime: updateAverage(
|
|
12623
|
-
currentReviewInfo.waitingTime,
|
|
12624
|
-
newReview.waitingTime
|
|
12625
|
-
),
|
|
12626
|
-
accessibility: updateAverage(
|
|
12627
|
-
currentReviewInfo.accessibility,
|
|
12628
|
-
newReview.accessibility
|
|
12629
|
-
),
|
|
12630
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12631
|
-
};
|
|
12632
|
-
}
|
|
12633
|
-
} else {
|
|
12634
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12635
|
-
}
|
|
12636
|
-
await updateDoc25(doc26(this.db, CLINICS_COLLECTION, clinicId), {
|
|
12637
|
-
reviewInfo: updatedReviewInfo,
|
|
12638
|
-
updatedAt: serverTimestamp22()
|
|
12639
|
-
});
|
|
12640
|
-
return updatedReviewInfo;
|
|
12641
|
-
}
|
|
12642
|
-
/**
|
|
12643
|
-
* Updates the review info for a practitioner
|
|
12644
|
-
* @param practitionerId The ID of the practitioner to update
|
|
12645
|
-
* @param newReview Optional new review being added or removed
|
|
12646
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12647
|
-
* @returns The updated practitioner review info
|
|
12648
|
-
*/
|
|
12649
|
-
async updatePractitionerReviewInfo(practitionerId, newReview, isRemoval = false) {
|
|
12650
|
-
const practitionerDoc = await getDoc28(
|
|
12651
|
-
doc26(this.db, PRACTITIONERS_COLLECTION, practitionerId)
|
|
12652
|
-
);
|
|
12653
|
-
if (!practitionerDoc.exists()) {
|
|
12654
|
-
throw new Error(`Practitioner with ID ${practitionerId} not found`);
|
|
12655
|
-
}
|
|
12656
|
-
const practitionerData = practitionerDoc.data();
|
|
12657
|
-
const currentReviewInfo = practitionerData.reviewInfo || {
|
|
12658
|
-
totalReviews: 0,
|
|
12659
|
-
averageRating: 0,
|
|
12660
|
-
knowledgeAndExpertise: 0,
|
|
12661
|
-
communicationSkills: 0,
|
|
12662
|
-
bedSideManner: 0,
|
|
12663
|
-
thoroughness: 0,
|
|
12664
|
-
trustworthiness: 0,
|
|
12665
|
-
recommendationPercentage: 0
|
|
12666
|
-
};
|
|
12667
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12668
|
-
await updateDoc25(doc26(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
12669
|
-
reviewInfo: currentReviewInfo,
|
|
12670
|
-
updatedAt: serverTimestamp22()
|
|
12671
|
-
});
|
|
12672
|
-
return currentReviewInfo;
|
|
12673
|
-
}
|
|
12674
|
-
let updatedReviewInfo;
|
|
12675
|
-
if (newReview) {
|
|
12676
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12677
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12678
|
-
if (newTotal === 0) {
|
|
12679
|
-
updatedReviewInfo = {
|
|
12680
|
-
totalReviews: 0,
|
|
12681
|
-
averageRating: 0,
|
|
12682
|
-
knowledgeAndExpertise: 0,
|
|
12683
|
-
communicationSkills: 0,
|
|
12684
|
-
bedSideManner: 0,
|
|
12685
|
-
thoroughness: 0,
|
|
12686
|
-
trustworthiness: 0,
|
|
12687
|
-
recommendationPercentage: 0
|
|
12688
|
-
};
|
|
12689
|
-
} else {
|
|
12690
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12691
|
-
const currentSum = currentAvg * oldTotal;
|
|
12692
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12693
|
-
const newAvg = newSum / newTotal;
|
|
12694
|
-
return Math.round(newAvg * 10) / 10;
|
|
12695
|
-
};
|
|
12696
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12697
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12698
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12699
|
-
updatedReviewInfo = {
|
|
12700
|
-
totalReviews: newTotal,
|
|
12701
|
-
averageRating: updateAverage(
|
|
12702
|
-
currentReviewInfo.averageRating,
|
|
12703
|
-
newReview.overallRating
|
|
12704
|
-
),
|
|
12705
|
-
knowledgeAndExpertise: updateAverage(
|
|
12706
|
-
currentReviewInfo.knowledgeAndExpertise,
|
|
12707
|
-
newReview.knowledgeAndExpertise
|
|
12708
|
-
),
|
|
12709
|
-
communicationSkills: updateAverage(
|
|
12710
|
-
currentReviewInfo.communicationSkills,
|
|
12711
|
-
newReview.communicationSkills
|
|
12712
|
-
),
|
|
12713
|
-
bedSideManner: updateAverage(
|
|
12714
|
-
currentReviewInfo.bedSideManner,
|
|
12715
|
-
newReview.bedSideManner
|
|
12716
|
-
),
|
|
12717
|
-
thoroughness: updateAverage(
|
|
12718
|
-
currentReviewInfo.thoroughness,
|
|
12719
|
-
newReview.thoroughness
|
|
12720
|
-
),
|
|
12721
|
-
trustworthiness: updateAverage(
|
|
12722
|
-
currentReviewInfo.trustworthiness,
|
|
12723
|
-
newReview.trustworthiness
|
|
12724
|
-
),
|
|
12725
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12726
|
-
};
|
|
12727
|
-
}
|
|
12728
|
-
} else {
|
|
12729
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12730
|
-
}
|
|
12731
|
-
await updateDoc25(doc26(this.db, PRACTITIONERS_COLLECTION, practitionerId), {
|
|
12732
|
-
reviewInfo: updatedReviewInfo,
|
|
12733
|
-
updatedAt: serverTimestamp22()
|
|
12734
|
-
});
|
|
12735
|
-
await this.updateDoctorInfoInProcedures(
|
|
12736
|
-
practitionerId,
|
|
12737
|
-
updatedReviewInfo.averageRating
|
|
12738
|
-
);
|
|
12739
|
-
return updatedReviewInfo;
|
|
12740
|
-
}
|
|
12741
|
-
/**
|
|
12742
|
-
* Updates the review info for a procedure
|
|
12743
|
-
* @param procedureId The ID of the procedure to update
|
|
12744
|
-
* @param newReview Optional new review being added or removed
|
|
12745
|
-
* @param isRemoval Whether this update is for a review removal
|
|
12746
|
-
* @returns The updated procedure review info
|
|
12747
|
-
*/
|
|
12748
|
-
async updateProcedureReviewInfo(procedureId, newReview, isRemoval = false) {
|
|
12749
|
-
const procedureDoc = await getDoc28(
|
|
12750
|
-
doc26(this.db, PROCEDURES_COLLECTION, procedureId)
|
|
12751
|
-
);
|
|
12752
|
-
if (!procedureDoc.exists()) {
|
|
12753
|
-
throw new Error(`Procedure with ID ${procedureId} not found`);
|
|
12754
|
-
}
|
|
12755
|
-
const procedureData = procedureDoc.data();
|
|
12756
|
-
const currentReviewInfo = procedureData.reviewInfo || {
|
|
12757
|
-
totalReviews: 0,
|
|
12758
|
-
averageRating: 0,
|
|
12759
|
-
effectivenessOfTreatment: 0,
|
|
12760
|
-
outcomeExplanation: 0,
|
|
12761
|
-
painManagement: 0,
|
|
12762
|
-
followUpCare: 0,
|
|
12763
|
-
valueForMoney: 0,
|
|
12764
|
-
recommendationPercentage: 0
|
|
12765
|
-
};
|
|
12766
|
-
if (currentReviewInfo.totalReviews === 0 && !newReview) {
|
|
12767
|
-
await updateDoc25(doc26(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
12768
|
-
reviewInfo: currentReviewInfo,
|
|
12769
|
-
updatedAt: serverTimestamp22()
|
|
12770
|
-
});
|
|
12771
|
-
return currentReviewInfo;
|
|
12772
|
-
}
|
|
12773
|
-
let updatedReviewInfo;
|
|
12774
|
-
if (newReview) {
|
|
12775
|
-
const oldTotal = currentReviewInfo.totalReviews;
|
|
12776
|
-
const newTotal = isRemoval ? oldTotal - 1 : oldTotal + 1;
|
|
12777
|
-
if (newTotal === 0) {
|
|
12778
|
-
updatedReviewInfo = {
|
|
12779
|
-
totalReviews: 0,
|
|
12780
|
-
averageRating: 0,
|
|
12781
|
-
effectivenessOfTreatment: 0,
|
|
12782
|
-
outcomeExplanation: 0,
|
|
12783
|
-
painManagement: 0,
|
|
12784
|
-
followUpCare: 0,
|
|
12785
|
-
valueForMoney: 0,
|
|
12786
|
-
recommendationPercentage: 0
|
|
12787
|
-
};
|
|
12788
|
-
} else {
|
|
12789
|
-
const updateAverage = (currentAvg, newValue) => {
|
|
12790
|
-
const currentSum = currentAvg * oldTotal;
|
|
12791
|
-
const newSum = isRemoval ? currentSum - newValue : currentSum + newValue;
|
|
12792
|
-
const newAvg = newSum / newTotal;
|
|
12793
|
-
return Math.round(newAvg * 10) / 10;
|
|
12794
|
-
};
|
|
12795
|
-
const currentRecommendations = currentReviewInfo.recommendationPercentage / 100 * oldTotal;
|
|
12796
|
-
const newRecommendations = isRemoval ? newReview.wouldRecommend ? currentRecommendations - 1 : currentRecommendations : newReview.wouldRecommend ? currentRecommendations + 1 : currentRecommendations;
|
|
12797
|
-
const newRecommendationPercentage = newRecommendations / newTotal * 100;
|
|
12798
|
-
updatedReviewInfo = {
|
|
12799
|
-
totalReviews: newTotal,
|
|
12800
|
-
averageRating: updateAverage(
|
|
12801
|
-
currentReviewInfo.averageRating,
|
|
12802
|
-
newReview.overallRating
|
|
12803
|
-
),
|
|
12804
|
-
effectivenessOfTreatment: updateAverage(
|
|
12805
|
-
currentReviewInfo.effectivenessOfTreatment,
|
|
12806
|
-
newReview.effectivenessOfTreatment
|
|
12807
|
-
),
|
|
12808
|
-
outcomeExplanation: updateAverage(
|
|
12809
|
-
currentReviewInfo.outcomeExplanation,
|
|
12810
|
-
newReview.outcomeExplanation
|
|
12811
|
-
),
|
|
12812
|
-
painManagement: updateAverage(
|
|
12813
|
-
currentReviewInfo.painManagement,
|
|
12814
|
-
newReview.painManagement
|
|
12815
|
-
),
|
|
12816
|
-
followUpCare: updateAverage(
|
|
12817
|
-
currentReviewInfo.followUpCare,
|
|
12818
|
-
newReview.followUpCare
|
|
12819
|
-
),
|
|
12820
|
-
valueForMoney: updateAverage(
|
|
12821
|
-
currentReviewInfo.valueForMoney,
|
|
12822
|
-
newReview.valueForMoney
|
|
12823
|
-
),
|
|
12824
|
-
recommendationPercentage: Math.round(newRecommendationPercentage * 10) / 10
|
|
12825
|
-
};
|
|
12826
|
-
}
|
|
12827
|
-
} else {
|
|
12828
|
-
updatedReviewInfo = { ...currentReviewInfo };
|
|
12829
|
-
}
|
|
12830
|
-
await updateDoc25(doc26(this.db, PROCEDURES_COLLECTION, procedureId), {
|
|
12831
|
-
reviewInfo: updatedReviewInfo,
|
|
12832
|
-
updatedAt: serverTimestamp22()
|
|
12833
|
-
});
|
|
12834
|
-
return updatedReviewInfo;
|
|
12835
|
-
}
|
|
12836
|
-
/**
|
|
12837
|
-
* Updates doctorInfo rating in all procedures for a practitioner
|
|
12838
|
-
* @param practitionerId The ID of the practitioner
|
|
12839
|
-
* @param rating The new rating to set
|
|
12840
|
-
*/
|
|
12841
|
-
async updateDoctorInfoInProcedures(practitionerId, rating) {
|
|
12842
|
-
const q = query25(
|
|
12843
|
-
collection25(this.db, PROCEDURES_COLLECTION),
|
|
12844
|
-
where25("practitionerId", "==", practitionerId)
|
|
12845
|
-
);
|
|
12846
|
-
const snapshot = await getDocs25(q);
|
|
12847
|
-
if (snapshot.empty) {
|
|
12848
|
-
return;
|
|
12849
|
-
}
|
|
12850
|
-
const batch = writeBatch7(this.db);
|
|
12851
|
-
snapshot.docs.forEach((docSnapshot) => {
|
|
12852
|
-
const procedureRef = doc26(this.db, PROCEDURES_COLLECTION, docSnapshot.id);
|
|
12853
|
-
batch.update(procedureRef, {
|
|
12854
|
-
"doctorInfo.rating": rating,
|
|
12855
|
-
updatedAt: serverTimestamp22()
|
|
12856
|
-
});
|
|
12857
|
-
});
|
|
12858
|
-
await batch.commit();
|
|
12859
|
-
}
|
|
12860
|
-
/**
|
|
12861
|
-
* Verifies a review as checked by admin/staff
|
|
12862
|
-
* @param reviewId The ID of the review to verify
|
|
12863
|
-
*/
|
|
12864
|
-
async verifyReview(reviewId) {
|
|
12865
|
-
const review = await this.getReview(reviewId);
|
|
12866
|
-
if (!review) {
|
|
12867
|
-
throw new Error(`Review with ID ${reviewId} not found`);
|
|
12868
|
-
}
|
|
12869
|
-
const batch = writeBatch7(this.db);
|
|
12870
|
-
batch.update(doc26(this.db, REVIEWS_COLLECTION, reviewId), {
|
|
12871
|
-
updatedAt: serverTimestamp22()
|
|
12872
|
-
});
|
|
12873
|
-
if (review.clinicReview) {
|
|
12874
|
-
review.clinicReview.isVerified = true;
|
|
12875
|
-
}
|
|
12876
|
-
if (review.practitionerReview) {
|
|
12877
|
-
review.practitionerReview.isVerified = true;
|
|
12878
|
-
}
|
|
12879
|
-
if (review.procedureReview) {
|
|
12880
|
-
review.procedureReview.isVerified = true;
|
|
12881
|
-
}
|
|
12882
|
-
await batch.commit();
|
|
12883
|
-
const updatePromises = [];
|
|
12884
|
-
if (review.clinicReview) {
|
|
12885
|
-
updatePromises.push(
|
|
12886
|
-
this.updateClinicReviewInfo(review.clinicReview.clinicId)
|
|
12887
|
-
);
|
|
12888
|
-
}
|
|
12889
|
-
if (review.practitionerReview) {
|
|
12890
|
-
updatePromises.push(
|
|
12891
|
-
this.updatePractitionerReviewInfo(
|
|
12892
|
-
review.practitionerReview.practitionerId
|
|
12893
|
-
)
|
|
12894
|
-
);
|
|
12895
|
-
}
|
|
12896
|
-
if (review.procedureReview) {
|
|
12897
|
-
updatePromises.push(
|
|
12898
|
-
this.updateProcedureReviewInfo(review.procedureReview.procedureId)
|
|
12899
|
-
);
|
|
12900
|
-
}
|
|
12901
|
-
await Promise.all(updatePromises);
|
|
12902
12568
|
}
|
|
12903
12569
|
/**
|
|
12904
12570
|
* Calculates the average of an array of numbers
|
|
@@ -12917,7 +12583,7 @@ var ReviewService = class extends BaseService {
|
|
|
12917
12583
|
|
|
12918
12584
|
// src/services/appointment/appointment.service.ts
|
|
12919
12585
|
import {
|
|
12920
|
-
Timestamp as
|
|
12586
|
+
Timestamp as Timestamp29,
|
|
12921
12587
|
serverTimestamp as serverTimestamp24,
|
|
12922
12588
|
arrayUnion as arrayUnion8,
|
|
12923
12589
|
arrayRemove as arrayRemove7,
|
|
@@ -12940,9 +12606,9 @@ import {
|
|
|
12940
12606
|
query as query26,
|
|
12941
12607
|
where as where26,
|
|
12942
12608
|
setDoc as setDoc24,
|
|
12943
|
-
updateDoc as
|
|
12609
|
+
updateDoc as updateDoc25,
|
|
12944
12610
|
serverTimestamp as serverTimestamp23,
|
|
12945
|
-
Timestamp as
|
|
12611
|
+
Timestamp as Timestamp28,
|
|
12946
12612
|
orderBy as orderBy13,
|
|
12947
12613
|
limit as limit11,
|
|
12948
12614
|
startAfter as startAfter10
|
|
@@ -13013,7 +12679,7 @@ async function updateAppointmentUtil2(db, appointmentId, data) {
|
|
|
13013
12679
|
});
|
|
13014
12680
|
if (data.status && data.status !== currentAppointment.status) {
|
|
13015
12681
|
if (data.status === "confirmed" /* CONFIRMED */ && !updateData.confirmationTime) {
|
|
13016
|
-
updateData.confirmationTime =
|
|
12682
|
+
updateData.confirmationTime = Timestamp28.now();
|
|
13017
12683
|
}
|
|
13018
12684
|
if (currentAppointment.calendarEventId) {
|
|
13019
12685
|
await updateCalendarEventStatus(
|
|
@@ -13023,7 +12689,7 @@ async function updateAppointmentUtil2(db, appointmentId, data) {
|
|
|
13023
12689
|
);
|
|
13024
12690
|
}
|
|
13025
12691
|
}
|
|
13026
|
-
await
|
|
12692
|
+
await updateDoc25(appointmentRef, updateData);
|
|
13027
12693
|
const updatedAppointmentDoc = await getDoc29(appointmentRef);
|
|
13028
12694
|
if (!updatedAppointmentDoc.exists()) {
|
|
13029
12695
|
throw new Error(
|
|
@@ -13062,7 +12728,7 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
|
|
|
13062
12728
|
default:
|
|
13063
12729
|
return;
|
|
13064
12730
|
}
|
|
13065
|
-
await
|
|
12731
|
+
await updateDoc25(calendarEventRef, {
|
|
13066
12732
|
status: calendarStatus,
|
|
13067
12733
|
updatedAt: serverTimestamp23()
|
|
13068
12734
|
});
|
|
@@ -13101,13 +12767,13 @@ async function searchAppointmentsUtil(db, params) {
|
|
|
13101
12767
|
where26(
|
|
13102
12768
|
"appointmentStartTime",
|
|
13103
12769
|
">=",
|
|
13104
|
-
|
|
12770
|
+
Timestamp28.fromDate(params.startDate)
|
|
13105
12771
|
)
|
|
13106
12772
|
);
|
|
13107
12773
|
}
|
|
13108
12774
|
if (params.endDate) {
|
|
13109
12775
|
constraints.push(
|
|
13110
|
-
where26("appointmentStartTime", "<=",
|
|
12776
|
+
where26("appointmentStartTime", "<=", Timestamp28.fromDate(params.endDate))
|
|
13111
12777
|
);
|
|
13112
12778
|
}
|
|
13113
12779
|
if (params.status) {
|
|
@@ -13507,13 +13173,13 @@ var AppointmentService = class extends BaseService {
|
|
|
13507
13173
|
}
|
|
13508
13174
|
updateData.cancellationReason = details.cancellationReason;
|
|
13509
13175
|
updateData.canceledBy = details.canceledBy;
|
|
13510
|
-
updateData.cancellationTime =
|
|
13176
|
+
updateData.cancellationTime = Timestamp29.now();
|
|
13511
13177
|
}
|
|
13512
13178
|
if (newStatus === "confirmed" /* CONFIRMED */) {
|
|
13513
|
-
updateData.confirmationTime =
|
|
13179
|
+
updateData.confirmationTime = Timestamp29.now();
|
|
13514
13180
|
}
|
|
13515
13181
|
if (newStatus === "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */) {
|
|
13516
|
-
updateData.rescheduleTime =
|
|
13182
|
+
updateData.rescheduleTime = Timestamp29.now();
|
|
13517
13183
|
}
|
|
13518
13184
|
return this.updateAppointment(appointmentId, updateData);
|
|
13519
13185
|
}
|
|
@@ -13584,7 +13250,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13584
13250
|
status: "rescheduled_by_clinic" /* RESCHEDULED_BY_CLINIC */,
|
|
13585
13251
|
appointmentStartTime: newStartTime,
|
|
13586
13252
|
appointmentEndTime: newEndTime,
|
|
13587
|
-
rescheduleTime:
|
|
13253
|
+
rescheduleTime: Timestamp29.now(),
|
|
13588
13254
|
confirmationTime: null,
|
|
13589
13255
|
updatedAt: serverTimestamp24()
|
|
13590
13256
|
};
|
|
@@ -13681,7 +13347,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13681
13347
|
}
|
|
13682
13348
|
const updateData = {
|
|
13683
13349
|
status: "in_progress" /* IN_PROGRESS */,
|
|
13684
|
-
procedureActualStartTime:
|
|
13350
|
+
procedureActualStartTime: Timestamp29.now(),
|
|
13685
13351
|
// Set actual start time
|
|
13686
13352
|
updatedAt: serverTimestamp24()
|
|
13687
13353
|
};
|
|
@@ -13701,7 +13367,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13701
13367
|
if (!appointment)
|
|
13702
13368
|
throw new Error(`Appointment ${appointmentId} not found.`);
|
|
13703
13369
|
let calculatedDurationMinutes = actualDurationMinutesInput;
|
|
13704
|
-
const procedureCompletionTime =
|
|
13370
|
+
const procedureCompletionTime = Timestamp29.now();
|
|
13705
13371
|
if (calculatedDurationMinutes === void 0 && appointment.procedureActualStartTime) {
|
|
13706
13372
|
const startTimeMillis = appointment.procedureActualStartTime.toMillis();
|
|
13707
13373
|
const endTimeMillis = procedureCompletionTime.toMillis();
|
|
@@ -13738,7 +13404,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13738
13404
|
const appointment = await this.getAppointmentById(appointmentId);
|
|
13739
13405
|
if (!appointment)
|
|
13740
13406
|
throw new Error(`Appointment ${appointmentId} not found.`);
|
|
13741
|
-
if (
|
|
13407
|
+
if (Timestamp29.now().toMillis() < appointment.appointmentStartTime.toMillis()) {
|
|
13742
13408
|
throw new Error("Cannot mark no-show before appointment start time.");
|
|
13743
13409
|
}
|
|
13744
13410
|
return this.updateAppointmentStatus(
|
|
@@ -13762,7 +13428,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13762
13428
|
const newMediaItem = {
|
|
13763
13429
|
...mediaItemData,
|
|
13764
13430
|
id: this.generateId(),
|
|
13765
|
-
uploadedAt:
|
|
13431
|
+
uploadedAt: Timestamp29.now(),
|
|
13766
13432
|
uploadedBy: currentUser.uid
|
|
13767
13433
|
};
|
|
13768
13434
|
const updateData = {
|
|
@@ -13802,7 +13468,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13802
13468
|
const newReviewInfo = {
|
|
13803
13469
|
...reviewData,
|
|
13804
13470
|
reviewId: this.generateId(),
|
|
13805
|
-
reviewedAt:
|
|
13471
|
+
reviewedAt: Timestamp29.now()
|
|
13806
13472
|
};
|
|
13807
13473
|
const updateData = {
|
|
13808
13474
|
reviewInfo: newReviewInfo,
|
|
@@ -13868,7 +13534,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13868
13534
|
where27(
|
|
13869
13535
|
"appointmentStartTime",
|
|
13870
13536
|
">=",
|
|
13871
|
-
|
|
13537
|
+
Timestamp29.fromDate(effectiveStartDate)
|
|
13872
13538
|
)
|
|
13873
13539
|
);
|
|
13874
13540
|
if (options == null ? void 0 : options.endDate) {
|
|
@@ -13876,7 +13542,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13876
13542
|
where27(
|
|
13877
13543
|
"appointmentStartTime",
|
|
13878
13544
|
"<=",
|
|
13879
|
-
|
|
13545
|
+
Timestamp29.fromDate(options.endDate)
|
|
13880
13546
|
)
|
|
13881
13547
|
);
|
|
13882
13548
|
}
|
|
@@ -13942,7 +13608,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13942
13608
|
where27(
|
|
13943
13609
|
"appointmentStartTime",
|
|
13944
13610
|
">=",
|
|
13945
|
-
|
|
13611
|
+
Timestamp29.fromDate(options.startDate)
|
|
13946
13612
|
)
|
|
13947
13613
|
);
|
|
13948
13614
|
}
|
|
@@ -13950,7 +13616,7 @@ var AppointmentService = class extends BaseService {
|
|
|
13950
13616
|
where27(
|
|
13951
13617
|
"appointmentStartTime",
|
|
13952
13618
|
"<=",
|
|
13953
|
-
|
|
13619
|
+
Timestamp29.fromDate(effectiveEndDate)
|
|
13954
13620
|
)
|
|
13955
13621
|
);
|
|
13956
13622
|
constraints.push(orderBy14("appointmentStartTime", "desc"));
|
|
@@ -13990,8 +13656,8 @@ import {
|
|
|
13990
13656
|
query as query28,
|
|
13991
13657
|
where as where28,
|
|
13992
13658
|
doc as doc28,
|
|
13993
|
-
updateDoc as
|
|
13994
|
-
Timestamp as
|
|
13659
|
+
updateDoc as updateDoc26,
|
|
13660
|
+
Timestamp as Timestamp30,
|
|
13995
13661
|
orderBy as orderBy15,
|
|
13996
13662
|
limit as limit13,
|
|
13997
13663
|
startAfter as startAfter12,
|
|
@@ -14150,7 +13816,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14150
13816
|
`Instruction ${instructionId} is in status ${instructionToUpdate.status} and cannot be marked as completed.`
|
|
14151
13817
|
);
|
|
14152
13818
|
}
|
|
14153
|
-
const now =
|
|
13819
|
+
const now = Timestamp30.now();
|
|
14154
13820
|
const updatedInstructions = [...instance.instructions];
|
|
14155
13821
|
updatedInstructions[instructionIndex] = {
|
|
14156
13822
|
...instructionToUpdate,
|
|
@@ -14177,7 +13843,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
14177
13843
|
if (newOverallStatus !== instance.overallStatus) {
|
|
14178
13844
|
updatePayload.overallStatus = newOverallStatus;
|
|
14179
13845
|
}
|
|
14180
|
-
await
|
|
13846
|
+
await updateDoc26(instanceRef, updatePayload);
|
|
14181
13847
|
return {
|
|
14182
13848
|
...instance,
|
|
14183
13849
|
instructions: updatedInstructions,
|
|
@@ -14197,7 +13863,7 @@ import {
|
|
|
14197
13863
|
getDoc as getDoc31,
|
|
14198
13864
|
getDocs as getDocs29,
|
|
14199
13865
|
query as query29,
|
|
14200
|
-
updateDoc as
|
|
13866
|
+
updateDoc as updateDoc27,
|
|
14201
13867
|
where as where29
|
|
14202
13868
|
} from "firebase/firestore";
|
|
14203
13869
|
|
|
@@ -14248,7 +13914,7 @@ var BrandService = class extends BaseService {
|
|
|
14248
13914
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14249
13915
|
};
|
|
14250
13916
|
const docRef = doc29(this.getBrandsRef(), brandId);
|
|
14251
|
-
await
|
|
13917
|
+
await updateDoc27(docRef, updateData);
|
|
14252
13918
|
return this.getById(brandId);
|
|
14253
13919
|
}
|
|
14254
13920
|
/**
|
|
@@ -14281,7 +13947,7 @@ import {
|
|
|
14281
13947
|
getDoc as getDoc32,
|
|
14282
13948
|
getDocs as getDocs30,
|
|
14283
13949
|
query as query30,
|
|
14284
|
-
updateDoc as
|
|
13950
|
+
updateDoc as updateDoc28,
|
|
14285
13951
|
where as where30
|
|
14286
13952
|
} from "firebase/firestore";
|
|
14287
13953
|
|
|
@@ -14357,7 +14023,7 @@ var CategoryService = class extends BaseService {
|
|
|
14357
14023
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14358
14024
|
};
|
|
14359
14025
|
const docRef = doc30(this.categoriesRef, id);
|
|
14360
|
-
await
|
|
14026
|
+
await updateDoc28(docRef, updateData);
|
|
14361
14027
|
return this.getById(id);
|
|
14362
14028
|
}
|
|
14363
14029
|
/**
|
|
@@ -14391,7 +14057,7 @@ import {
|
|
|
14391
14057
|
getDoc as getDoc33,
|
|
14392
14058
|
getDocs as getDocs31,
|
|
14393
14059
|
query as query31,
|
|
14394
|
-
updateDoc as
|
|
14060
|
+
updateDoc as updateDoc29,
|
|
14395
14061
|
where as where31
|
|
14396
14062
|
} from "firebase/firestore";
|
|
14397
14063
|
|
|
@@ -14464,7 +14130,7 @@ var SubcategoryService = class extends BaseService {
|
|
|
14464
14130
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14465
14131
|
};
|
|
14466
14132
|
const docRef = doc31(this.getSubcategoriesRef(categoryId), subcategoryId);
|
|
14467
|
-
await
|
|
14133
|
+
await updateDoc29(docRef, updateData);
|
|
14468
14134
|
return this.getById(categoryId, subcategoryId);
|
|
14469
14135
|
}
|
|
14470
14136
|
/**
|
|
@@ -14500,7 +14166,7 @@ import {
|
|
|
14500
14166
|
getDoc as getDoc34,
|
|
14501
14167
|
getDocs as getDocs32,
|
|
14502
14168
|
query as query32,
|
|
14503
|
-
updateDoc as
|
|
14169
|
+
updateDoc as updateDoc30,
|
|
14504
14170
|
where as where32,
|
|
14505
14171
|
arrayUnion as arrayUnion9,
|
|
14506
14172
|
arrayRemove as arrayRemove8
|
|
@@ -14623,7 +14289,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14623
14289
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14624
14290
|
};
|
|
14625
14291
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14626
|
-
await
|
|
14292
|
+
await updateDoc30(docRef, updateData);
|
|
14627
14293
|
return this.getById(technologyId);
|
|
14628
14294
|
}
|
|
14629
14295
|
/**
|
|
@@ -14658,7 +14324,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14658
14324
|
async addRequirement(technologyId, requirement) {
|
|
14659
14325
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14660
14326
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
14661
|
-
await
|
|
14327
|
+
await updateDoc30(docRef, {
|
|
14662
14328
|
[requirementType]: arrayUnion9(requirement),
|
|
14663
14329
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14664
14330
|
});
|
|
@@ -14673,7 +14339,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14673
14339
|
async removeRequirement(technologyId, requirement) {
|
|
14674
14340
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14675
14341
|
const requirementType = requirement.type === "pre" ? "requirements.pre" : "requirements.post";
|
|
14676
|
-
await
|
|
14342
|
+
await updateDoc30(docRef, {
|
|
14677
14343
|
[requirementType]: arrayRemove8(requirement),
|
|
14678
14344
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14679
14345
|
});
|
|
@@ -14712,7 +14378,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14712
14378
|
*/
|
|
14713
14379
|
async addBlockingCondition(technologyId, condition) {
|
|
14714
14380
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14715
|
-
await
|
|
14381
|
+
await updateDoc30(docRef, {
|
|
14716
14382
|
blockingConditions: arrayUnion9(condition),
|
|
14717
14383
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14718
14384
|
});
|
|
@@ -14726,7 +14392,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14726
14392
|
*/
|
|
14727
14393
|
async removeBlockingCondition(technologyId, condition) {
|
|
14728
14394
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14729
|
-
await
|
|
14395
|
+
await updateDoc30(docRef, {
|
|
14730
14396
|
blockingConditions: arrayRemove8(condition),
|
|
14731
14397
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14732
14398
|
});
|
|
@@ -14740,7 +14406,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14740
14406
|
*/
|
|
14741
14407
|
async addContraindication(technologyId, contraindication) {
|
|
14742
14408
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14743
|
-
await
|
|
14409
|
+
await updateDoc30(docRef, {
|
|
14744
14410
|
contraindications: arrayUnion9(contraindication),
|
|
14745
14411
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14746
14412
|
});
|
|
@@ -14754,7 +14420,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14754
14420
|
*/
|
|
14755
14421
|
async removeContraindication(technologyId, contraindication) {
|
|
14756
14422
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14757
|
-
await
|
|
14423
|
+
await updateDoc30(docRef, {
|
|
14758
14424
|
contraindications: arrayRemove8(contraindication),
|
|
14759
14425
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14760
14426
|
});
|
|
@@ -14768,7 +14434,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14768
14434
|
*/
|
|
14769
14435
|
async addBenefit(technologyId, benefit) {
|
|
14770
14436
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14771
|
-
await
|
|
14437
|
+
await updateDoc30(docRef, {
|
|
14772
14438
|
benefits: arrayUnion9(benefit),
|
|
14773
14439
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14774
14440
|
});
|
|
@@ -14782,7 +14448,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14782
14448
|
*/
|
|
14783
14449
|
async removeBenefit(technologyId, benefit) {
|
|
14784
14450
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14785
|
-
await
|
|
14451
|
+
await updateDoc30(docRef, {
|
|
14786
14452
|
benefits: arrayRemove8(benefit),
|
|
14787
14453
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14788
14454
|
});
|
|
@@ -14823,7 +14489,7 @@ var TechnologyService = class extends BaseService {
|
|
|
14823
14489
|
*/
|
|
14824
14490
|
async updateCertificationRequirement(technologyId, certificationRequirement) {
|
|
14825
14491
|
const docRef = doc32(this.getTechnologiesRef(), technologyId);
|
|
14826
|
-
await
|
|
14492
|
+
await updateDoc30(docRef, {
|
|
14827
14493
|
certificationRequirement,
|
|
14828
14494
|
updatedAt: /* @__PURE__ */ new Date()
|
|
14829
14495
|
});
|
|
@@ -14930,7 +14596,7 @@ import {
|
|
|
14930
14596
|
getDoc as getDoc35,
|
|
14931
14597
|
getDocs as getDocs33,
|
|
14932
14598
|
query as query33,
|
|
14933
|
-
updateDoc as
|
|
14599
|
+
updateDoc as updateDoc31,
|
|
14934
14600
|
where as where33
|
|
14935
14601
|
} from "firebase/firestore";
|
|
14936
14602
|
|
|
@@ -15021,7 +14687,7 @@ var ProductService = class extends BaseService {
|
|
|
15021
14687
|
updatedAt: /* @__PURE__ */ new Date()
|
|
15022
14688
|
};
|
|
15023
14689
|
const docRef = doc33(this.getProductsRef(technologyId), productId);
|
|
15024
|
-
await
|
|
14690
|
+
await updateDoc31(docRef, updateData);
|
|
15025
14691
|
return this.getById(technologyId, productId);
|
|
15026
14692
|
}
|
|
15027
14693
|
/**
|
|
@@ -15047,63 +14713,63 @@ var ProductService = class extends BaseService {
|
|
|
15047
14713
|
};
|
|
15048
14714
|
|
|
15049
14715
|
// src/validations/notification.schema.ts
|
|
15050
|
-
import { z as
|
|
15051
|
-
var baseNotificationSchema =
|
|
15052
|
-
id:
|
|
15053
|
-
userId:
|
|
15054
|
-
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(),
|
|
15055
14721
|
// Timestamp
|
|
15056
|
-
notificationType:
|
|
15057
|
-
notificationTokens:
|
|
15058
|
-
status:
|
|
15059
|
-
createdAt:
|
|
14722
|
+
notificationType: z25.nativeEnum(NotificationType),
|
|
14723
|
+
notificationTokens: z25.array(z25.string()),
|
|
14724
|
+
status: z25.nativeEnum(NotificationStatus),
|
|
14725
|
+
createdAt: z25.any().optional(),
|
|
15060
14726
|
// Timestamp
|
|
15061
|
-
updatedAt:
|
|
14727
|
+
updatedAt: z25.any().optional(),
|
|
15062
14728
|
// Timestamp
|
|
15063
|
-
title:
|
|
15064
|
-
body:
|
|
15065
|
-
isRead:
|
|
15066
|
-
userRole:
|
|
14729
|
+
title: z25.string(),
|
|
14730
|
+
body: z25.string(),
|
|
14731
|
+
isRead: z25.boolean(),
|
|
14732
|
+
userRole: z25.nativeEnum(UserRole)
|
|
15067
14733
|
});
|
|
15068
14734
|
var preRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
15069
|
-
notificationType:
|
|
15070
|
-
treatmentId:
|
|
15071
|
-
requirements:
|
|
15072
|
-
deadline:
|
|
14735
|
+
notificationType: z25.literal("preRequirementInstructionDue" /* PRE_REQUIREMENT_INSTRUCTION_DUE */),
|
|
14736
|
+
treatmentId: z25.string(),
|
|
14737
|
+
requirements: z25.array(z25.string()),
|
|
14738
|
+
deadline: z25.any()
|
|
15073
14739
|
// Timestamp
|
|
15074
14740
|
});
|
|
15075
14741
|
var postRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
15076
|
-
notificationType:
|
|
14742
|
+
notificationType: z25.literal(
|
|
15077
14743
|
"postRequirementInstructionDue" /* POST_REQUIREMENT_INSTRUCTION_DUE */
|
|
15078
14744
|
),
|
|
15079
|
-
treatmentId:
|
|
15080
|
-
requirements:
|
|
15081
|
-
deadline:
|
|
14745
|
+
treatmentId: z25.string(),
|
|
14746
|
+
requirements: z25.array(z25.string()),
|
|
14747
|
+
deadline: z25.any()
|
|
15082
14748
|
// Timestamp
|
|
15083
14749
|
});
|
|
15084
14750
|
var requirementInstructionDueNotificationSchema = baseNotificationSchema.extend({
|
|
15085
|
-
notificationType:
|
|
15086
|
-
appointmentId:
|
|
15087
|
-
patientRequirementInstanceId:
|
|
15088
|
-
instructionId:
|
|
15089
|
-
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()
|
|
15090
14756
|
});
|
|
15091
14757
|
var appointmentReminderNotificationSchema = baseNotificationSchema.extend({
|
|
15092
|
-
notificationType:
|
|
15093
|
-
appointmentId:
|
|
15094
|
-
appointmentTime:
|
|
14758
|
+
notificationType: z25.literal("appointmentReminder" /* APPOINTMENT_REMINDER */),
|
|
14759
|
+
appointmentId: z25.string(),
|
|
14760
|
+
appointmentTime: z25.any(),
|
|
15095
14761
|
// Timestamp
|
|
15096
|
-
treatmentType:
|
|
15097
|
-
doctorName:
|
|
14762
|
+
treatmentType: z25.string(),
|
|
14763
|
+
doctorName: z25.string()
|
|
15098
14764
|
});
|
|
15099
14765
|
var appointmentNotificationSchema = baseNotificationSchema.extend({
|
|
15100
|
-
notificationType:
|
|
15101
|
-
appointmentId:
|
|
15102
|
-
appointmentStatus:
|
|
15103
|
-
previousStatus:
|
|
15104
|
-
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()
|
|
15105
14771
|
});
|
|
15106
|
-
var notificationSchema =
|
|
14772
|
+
var notificationSchema = z25.discriminatedUnion("notificationType", [
|
|
15107
14773
|
preRequirementNotificationSchema,
|
|
15108
14774
|
postRequirementNotificationSchema,
|
|
15109
14775
|
requirementInstructionDueNotificationSchema,
|