@blackcode_sa/metaestetics-api 1.5.0 → 1.5.2
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/index.d.mts +571 -7
- package/dist/index.d.ts +571 -7
- package/dist/index.js +293 -21
- package/dist/index.mjs +287 -21
- package/package.json +1 -1
- package/src/index.ts +9 -1
- package/src/services/practitioner/practitioner.service.ts +345 -1
- package/src/services/user.service.ts +2 -22
- package/src/types/practitioner/index.ts +60 -0
- package/src/validations/practitioner.schema.ts +45 -0
package/dist/index.js
CHANGED
|
@@ -71,8 +71,11 @@ __export(index_exports, {
|
|
|
71
71
|
PatientService: () => PatientService,
|
|
72
72
|
PracticeType: () => PracticeType,
|
|
73
73
|
PractitionerService: () => PractitionerService,
|
|
74
|
+
PractitionerStatus: () => PractitionerStatus,
|
|
75
|
+
PractitionerTokenStatus: () => PractitionerTokenStatus,
|
|
74
76
|
PricingMeasure: () => PricingMeasure,
|
|
75
77
|
ProcedureFamily: () => ProcedureFamily,
|
|
78
|
+
REGISTER_TOKENS_COLLECTION: () => REGISTER_TOKENS_COLLECTION,
|
|
76
79
|
SYNCED_CALENDARS_COLLECTION: () => SYNCED_CALENDARS_COLLECTION,
|
|
77
80
|
SubscriptionModel: () => SubscriptionModel,
|
|
78
81
|
SyncedCalendarProvider: () => SyncedCalendarProvider,
|
|
@@ -117,11 +120,13 @@ __export(index_exports, {
|
|
|
117
120
|
createClinicSchema: () => createClinicSchema,
|
|
118
121
|
createDefaultClinicGroupSchema: () => createDefaultClinicGroupSchema,
|
|
119
122
|
createDocumentTemplateSchema: () => createDocumentTemplateSchema,
|
|
123
|
+
createDraftPractitionerSchema: () => createDraftPractitionerSchema,
|
|
120
124
|
createPatientLocationInfoSchema: () => createPatientLocationInfoSchema,
|
|
121
125
|
createPatientMedicalInfoSchema: () => createPatientMedicalInfoSchema,
|
|
122
126
|
createPatientProfileSchema: () => createPatientProfileSchema,
|
|
123
127
|
createPatientSensitiveInfoSchema: () => createPatientSensitiveInfoSchema,
|
|
124
128
|
createPractitionerSchema: () => createPractitionerSchema,
|
|
129
|
+
createPractitionerTokenSchema: () => createPractitionerTokenSchema,
|
|
125
130
|
createUserOptionsSchema: () => createUserOptionsSchema,
|
|
126
131
|
doctorInfoSchema: () => doctorInfoSchema,
|
|
127
132
|
documentElementSchema: () => documentElementSchema,
|
|
@@ -154,6 +159,7 @@ __export(index_exports, {
|
|
|
154
159
|
practitionerProfileInfoSchema: () => practitionerProfileInfoSchema,
|
|
155
160
|
practitionerReviewSchema: () => practitionerReviewSchema,
|
|
156
161
|
practitionerSchema: () => practitionerSchema,
|
|
162
|
+
practitionerTokenSchema: () => practitionerTokenSchema,
|
|
157
163
|
practitionerWorkingHoursSchema: () => practitionerWorkingHoursSchema,
|
|
158
164
|
preRequirementNotificationSchema: () => preRequirementNotificationSchema,
|
|
159
165
|
procedureCategorizationSchema: () => procedureCategorizationSchema,
|
|
@@ -3135,6 +3141,19 @@ var import_firestore13 = require("firebase/firestore");
|
|
|
3135
3141
|
|
|
3136
3142
|
// src/types/practitioner/index.ts
|
|
3137
3143
|
var PRACTITIONERS_COLLECTION = "practitioners";
|
|
3144
|
+
var REGISTER_TOKENS_COLLECTION = "register_tokens";
|
|
3145
|
+
var PractitionerStatus = /* @__PURE__ */ ((PractitionerStatus2) => {
|
|
3146
|
+
PractitionerStatus2["DRAFT"] = "draft";
|
|
3147
|
+
PractitionerStatus2["ACTIVE"] = "active";
|
|
3148
|
+
return PractitionerStatus2;
|
|
3149
|
+
})(PractitionerStatus || {});
|
|
3150
|
+
var PractitionerTokenStatus = /* @__PURE__ */ ((PractitionerTokenStatus2) => {
|
|
3151
|
+
PractitionerTokenStatus2["ACTIVE"] = "active";
|
|
3152
|
+
PractitionerTokenStatus2["USED"] = "used";
|
|
3153
|
+
PractitionerTokenStatus2["EXPIRED"] = "expired";
|
|
3154
|
+
PractitionerTokenStatus2["REVOKED"] = "revoked";
|
|
3155
|
+
return PractitionerTokenStatus2;
|
|
3156
|
+
})(PractitionerTokenStatus || {});
|
|
3138
3157
|
|
|
3139
3158
|
// src/validations/practitioner.schema.ts
|
|
3140
3159
|
var import_zod10 = require("zod");
|
|
@@ -3246,6 +3265,7 @@ var practitionerSchema = import_zod10.z.object({
|
|
|
3246
3265
|
clinicWorkingHours: import_zod10.z.array(practitionerClinicWorkingHoursSchema),
|
|
3247
3266
|
isActive: import_zod10.z.boolean(),
|
|
3248
3267
|
isVerified: import_zod10.z.boolean(),
|
|
3268
|
+
status: import_zod10.z.nativeEnum(PractitionerStatus),
|
|
3249
3269
|
createdAt: import_zod10.z.instanceof(import_firestore12.Timestamp),
|
|
3250
3270
|
updatedAt: import_zod10.z.instanceof(import_firestore12.Timestamp)
|
|
3251
3271
|
});
|
|
@@ -3256,7 +3276,35 @@ var createPractitionerSchema = import_zod10.z.object({
|
|
|
3256
3276
|
clinics: import_zod10.z.array(import_zod10.z.string()).optional(),
|
|
3257
3277
|
clinicWorkingHours: import_zod10.z.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
3258
3278
|
isActive: import_zod10.z.boolean(),
|
|
3259
|
-
isVerified: import_zod10.z.boolean()
|
|
3279
|
+
isVerified: import_zod10.z.boolean(),
|
|
3280
|
+
status: import_zod10.z.nativeEnum(PractitionerStatus).optional()
|
|
3281
|
+
});
|
|
3282
|
+
var createDraftPractitionerSchema = import_zod10.z.object({
|
|
3283
|
+
basicInfo: practitionerBasicInfoSchema,
|
|
3284
|
+
certification: practitionerCertificationSchema,
|
|
3285
|
+
clinics: import_zod10.z.array(import_zod10.z.string()).optional(),
|
|
3286
|
+
clinicWorkingHours: import_zod10.z.array(practitionerClinicWorkingHoursSchema).optional(),
|
|
3287
|
+
isActive: import_zod10.z.boolean().optional().default(false),
|
|
3288
|
+
isVerified: import_zod10.z.boolean().optional().default(false)
|
|
3289
|
+
});
|
|
3290
|
+
var practitionerTokenSchema = import_zod10.z.object({
|
|
3291
|
+
id: import_zod10.z.string().min(1),
|
|
3292
|
+
token: import_zod10.z.string().min(6),
|
|
3293
|
+
practitionerId: import_zod10.z.string().min(1),
|
|
3294
|
+
email: import_zod10.z.string().email(),
|
|
3295
|
+
clinicId: import_zod10.z.string().min(1),
|
|
3296
|
+
status: import_zod10.z.nativeEnum(PractitionerTokenStatus),
|
|
3297
|
+
createdBy: import_zod10.z.string().min(1),
|
|
3298
|
+
createdAt: import_zod10.z.instanceof(import_firestore12.Timestamp),
|
|
3299
|
+
expiresAt: import_zod10.z.instanceof(import_firestore12.Timestamp),
|
|
3300
|
+
usedBy: import_zod10.z.string().optional(),
|
|
3301
|
+
usedAt: import_zod10.z.instanceof(import_firestore12.Timestamp).optional()
|
|
3302
|
+
});
|
|
3303
|
+
var createPractitionerTokenSchema = import_zod10.z.object({
|
|
3304
|
+
practitionerId: import_zod10.z.string().min(1),
|
|
3305
|
+
email: import_zod10.z.string().email(),
|
|
3306
|
+
clinicId: import_zod10.z.string().min(1),
|
|
3307
|
+
expiresAt: import_zod10.z.date().optional()
|
|
3260
3308
|
});
|
|
3261
3309
|
|
|
3262
3310
|
// src/services/practitioner/practitioner.service.ts
|
|
@@ -3307,6 +3355,7 @@ var PractitionerService = class extends BaseService {
|
|
|
3307
3355
|
clinicWorkingHours: validatedData.clinicWorkingHours || [],
|
|
3308
3356
|
isActive: validatedData.isActive,
|
|
3309
3357
|
isVerified: validatedData.isVerified,
|
|
3358
|
+
status: validatedData.status || "active" /* ACTIVE */,
|
|
3310
3359
|
createdAt: (0, import_firestore13.serverTimestamp)(),
|
|
3311
3360
|
updatedAt: (0, import_firestore13.serverTimestamp)()
|
|
3312
3361
|
};
|
|
@@ -3331,6 +3380,200 @@ var PractitionerService = class extends BaseService {
|
|
|
3331
3380
|
throw error;
|
|
3332
3381
|
}
|
|
3333
3382
|
}
|
|
3383
|
+
/**
|
|
3384
|
+
* Kreira novi draft profil zdravstvenog radnika bez povezanog korisnika
|
|
3385
|
+
* Koristi se od strane administratora klinike za kreiranje profila i kasnije pozivanje
|
|
3386
|
+
* @param data Podaci za kreiranje draft profila
|
|
3387
|
+
* @param createdBy ID administratora koji kreira profil
|
|
3388
|
+
* @param clinicId ID klinike za koju se kreira profil
|
|
3389
|
+
* @returns Objekt koji sadrži kreirani draft profil i token za registraciju
|
|
3390
|
+
*/
|
|
3391
|
+
async createDraftPractitioner(data, createdBy, clinicId) {
|
|
3392
|
+
try {
|
|
3393
|
+
const validatedData = createDraftPractitionerSchema.parse(data);
|
|
3394
|
+
const clinic = await this.getClinicService().getClinic(clinicId);
|
|
3395
|
+
if (!clinic) {
|
|
3396
|
+
throw new Error(`Clinic ${clinicId} not found`);
|
|
3397
|
+
}
|
|
3398
|
+
const clinics = data.clinics || [clinicId];
|
|
3399
|
+
if (data.clinics) {
|
|
3400
|
+
for (const cId of data.clinics) {
|
|
3401
|
+
if (cId !== clinicId) {
|
|
3402
|
+
const otherClinic = await this.getClinicService().getClinic(cId);
|
|
3403
|
+
if (!otherClinic) {
|
|
3404
|
+
throw new Error(`Clinic ${cId} not found`);
|
|
3405
|
+
}
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
const practitionerId = this.generateId();
|
|
3410
|
+
const practitionerData = {
|
|
3411
|
+
id: practitionerId,
|
|
3412
|
+
userRef: "",
|
|
3413
|
+
// Prazno - biće popunjeno kada korisnik kreira nalog
|
|
3414
|
+
basicInfo: validatedData.basicInfo,
|
|
3415
|
+
certification: validatedData.certification,
|
|
3416
|
+
clinics,
|
|
3417
|
+
clinicWorkingHours: validatedData.clinicWorkingHours || [],
|
|
3418
|
+
isActive: validatedData.isActive !== void 0 ? validatedData.isActive : false,
|
|
3419
|
+
isVerified: validatedData.isVerified !== void 0 ? validatedData.isVerified : false,
|
|
3420
|
+
status: "draft" /* DRAFT */,
|
|
3421
|
+
createdAt: (0, import_firestore13.serverTimestamp)(),
|
|
3422
|
+
updatedAt: (0, import_firestore13.serverTimestamp)()
|
|
3423
|
+
};
|
|
3424
|
+
practitionerSchema.parse({
|
|
3425
|
+
...practitionerData,
|
|
3426
|
+
userRef: "temp-for-validation",
|
|
3427
|
+
createdAt: import_firestore13.Timestamp.now(),
|
|
3428
|
+
updatedAt: import_firestore13.Timestamp.now()
|
|
3429
|
+
});
|
|
3430
|
+
await (0, import_firestore13.setDoc)(
|
|
3431
|
+
(0, import_firestore13.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerData.id),
|
|
3432
|
+
practitionerData
|
|
3433
|
+
);
|
|
3434
|
+
const savedPractitioner = await this.getPractitioner(practitionerData.id);
|
|
3435
|
+
if (!savedPractitioner) {
|
|
3436
|
+
throw new Error("Failed to create draft practitioner profile");
|
|
3437
|
+
}
|
|
3438
|
+
const tokenString = this.generateId().slice(0, 6).toUpperCase();
|
|
3439
|
+
const expiration = new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3);
|
|
3440
|
+
const token = {
|
|
3441
|
+
id: this.generateId(),
|
|
3442
|
+
token: tokenString,
|
|
3443
|
+
practitionerId,
|
|
3444
|
+
email: practitionerData.basicInfo.email,
|
|
3445
|
+
clinicId,
|
|
3446
|
+
status: "active" /* ACTIVE */,
|
|
3447
|
+
createdBy,
|
|
3448
|
+
createdAt: import_firestore13.Timestamp.now(),
|
|
3449
|
+
expiresAt: import_firestore13.Timestamp.fromDate(expiration)
|
|
3450
|
+
};
|
|
3451
|
+
practitionerTokenSchema.parse(token);
|
|
3452
|
+
const tokenPath = `${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}/${token.id}`;
|
|
3453
|
+
await (0, import_firestore13.setDoc)((0, import_firestore13.doc)(this.db, tokenPath), token);
|
|
3454
|
+
return { practitioner: savedPractitioner, token };
|
|
3455
|
+
} catch (error) {
|
|
3456
|
+
if (error instanceof import_zod11.z.ZodError) {
|
|
3457
|
+
throw new Error("Invalid practitioner data: " + error.message);
|
|
3458
|
+
}
|
|
3459
|
+
throw error;
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
/**
|
|
3463
|
+
* Creates a token for inviting practitioner to claim their profile
|
|
3464
|
+
* @param data Data for creating token
|
|
3465
|
+
* @param createdBy ID of the user creating the token
|
|
3466
|
+
* @returns Created token
|
|
3467
|
+
*/
|
|
3468
|
+
async createPractitionerToken(data, createdBy) {
|
|
3469
|
+
try {
|
|
3470
|
+
const validatedData = createPractitionerTokenSchema.parse(data);
|
|
3471
|
+
const practitioner = await this.getPractitioner(
|
|
3472
|
+
validatedData.practitionerId
|
|
3473
|
+
);
|
|
3474
|
+
if (!practitioner) {
|
|
3475
|
+
throw new Error("Practitioner not found");
|
|
3476
|
+
}
|
|
3477
|
+
if (practitioner.status !== "draft" /* DRAFT */) {
|
|
3478
|
+
throw new Error(
|
|
3479
|
+
"Can only create tokens for practitioners in DRAFT status"
|
|
3480
|
+
);
|
|
3481
|
+
}
|
|
3482
|
+
const clinic = await this.getClinicService().getClinic(
|
|
3483
|
+
validatedData.clinicId
|
|
3484
|
+
);
|
|
3485
|
+
if (!clinic) {
|
|
3486
|
+
throw new Error(`Clinic ${validatedData.clinicId} not found`);
|
|
3487
|
+
}
|
|
3488
|
+
if (!practitioner.clinics.includes(validatedData.clinicId)) {
|
|
3489
|
+
throw new Error("Practitioner is not associated with this clinic");
|
|
3490
|
+
}
|
|
3491
|
+
const expiration = validatedData.expiresAt || new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3);
|
|
3492
|
+
const tokenString = this.generateId().slice(0, 6).toUpperCase();
|
|
3493
|
+
const token = {
|
|
3494
|
+
id: this.generateId(),
|
|
3495
|
+
token: tokenString,
|
|
3496
|
+
practitionerId: validatedData.practitionerId,
|
|
3497
|
+
email: validatedData.email,
|
|
3498
|
+
clinicId: validatedData.clinicId,
|
|
3499
|
+
status: "active" /* ACTIVE */,
|
|
3500
|
+
createdBy,
|
|
3501
|
+
createdAt: import_firestore13.Timestamp.now(),
|
|
3502
|
+
expiresAt: import_firestore13.Timestamp.fromDate(expiration)
|
|
3503
|
+
};
|
|
3504
|
+
practitionerTokenSchema.parse(token);
|
|
3505
|
+
const tokenPath = `${PRACTITIONERS_COLLECTION}/${validatedData.practitionerId}/${REGISTER_TOKENS_COLLECTION}/${token.id}`;
|
|
3506
|
+
await (0, import_firestore13.setDoc)((0, import_firestore13.doc)(this.db, tokenPath), token);
|
|
3507
|
+
return token;
|
|
3508
|
+
} catch (error) {
|
|
3509
|
+
if (error instanceof import_zod11.z.ZodError) {
|
|
3510
|
+
throw new Error("Invalid token data: " + error.message);
|
|
3511
|
+
}
|
|
3512
|
+
throw error;
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
/**
|
|
3516
|
+
* Gets active tokens for a practitioner
|
|
3517
|
+
* @param practitionerId ID of the practitioner
|
|
3518
|
+
* @returns Array of active tokens
|
|
3519
|
+
*/
|
|
3520
|
+
async getPractitionerActiveTokens(practitionerId) {
|
|
3521
|
+
const tokensRef = (0, import_firestore13.collection)(
|
|
3522
|
+
this.db,
|
|
3523
|
+
`${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}`
|
|
3524
|
+
);
|
|
3525
|
+
const q = (0, import_firestore13.query)(
|
|
3526
|
+
tokensRef,
|
|
3527
|
+
(0, import_firestore13.where)("status", "==", "active" /* ACTIVE */),
|
|
3528
|
+
(0, import_firestore13.where)("expiresAt", ">", import_firestore13.Timestamp.now())
|
|
3529
|
+
);
|
|
3530
|
+
const querySnapshot = await (0, import_firestore13.getDocs)(q);
|
|
3531
|
+
return querySnapshot.docs.map((doc20) => doc20.data());
|
|
3532
|
+
}
|
|
3533
|
+
/**
|
|
3534
|
+
* Gets a token by its string value and validates it
|
|
3535
|
+
* @param tokenString The token string to find
|
|
3536
|
+
* @returns The token if found and valid, null otherwise
|
|
3537
|
+
*/
|
|
3538
|
+
async validateToken(tokenString) {
|
|
3539
|
+
const practitionersRef = (0, import_firestore13.collection)(this.db, PRACTITIONERS_COLLECTION);
|
|
3540
|
+
const practitionersSnapshot = await (0, import_firestore13.getDocs)(practitionersRef);
|
|
3541
|
+
for (const practitionerDoc of practitionersSnapshot.docs) {
|
|
3542
|
+
const practitionerId = practitionerDoc.id;
|
|
3543
|
+
const tokensRef = (0, import_firestore13.collection)(
|
|
3544
|
+
this.db,
|
|
3545
|
+
`${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}`
|
|
3546
|
+
);
|
|
3547
|
+
const q = (0, import_firestore13.query)(
|
|
3548
|
+
tokensRef,
|
|
3549
|
+
(0, import_firestore13.where)("token", "==", tokenString),
|
|
3550
|
+
(0, import_firestore13.where)("status", "==", "active" /* ACTIVE */),
|
|
3551
|
+
(0, import_firestore13.where)("expiresAt", ">", import_firestore13.Timestamp.now())
|
|
3552
|
+
);
|
|
3553
|
+
const tokenSnapshot = await (0, import_firestore13.getDocs)(q);
|
|
3554
|
+
if (!tokenSnapshot.empty) {
|
|
3555
|
+
return tokenSnapshot.docs[0].data();
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3558
|
+
return null;
|
|
3559
|
+
}
|
|
3560
|
+
/**
|
|
3561
|
+
* Marks a token as used
|
|
3562
|
+
* @param tokenId ID of the token
|
|
3563
|
+
* @param practitionerId ID of the practitioner
|
|
3564
|
+
* @param userId ID of the user using the token
|
|
3565
|
+
*/
|
|
3566
|
+
async markTokenAsUsed(tokenId, practitionerId, userId) {
|
|
3567
|
+
const tokenRef = (0, import_firestore13.doc)(
|
|
3568
|
+
this.db,
|
|
3569
|
+
`${PRACTITIONERS_COLLECTION}/${practitionerId}/${REGISTER_TOKENS_COLLECTION}/${tokenId}`
|
|
3570
|
+
);
|
|
3571
|
+
await (0, import_firestore13.updateDoc)(tokenRef, {
|
|
3572
|
+
status: "used" /* USED */,
|
|
3573
|
+
usedBy: userId,
|
|
3574
|
+
usedAt: import_firestore13.Timestamp.now()
|
|
3575
|
+
});
|
|
3576
|
+
}
|
|
3334
3577
|
/**
|
|
3335
3578
|
* Dohvata zdravstvenog radnika po ID-u
|
|
3336
3579
|
*/
|
|
@@ -3364,7 +3607,20 @@ var PractitionerService = class extends BaseService {
|
|
|
3364
3607
|
const q = (0, import_firestore13.query)(
|
|
3365
3608
|
(0, import_firestore13.collection)(this.db, PRACTITIONERS_COLLECTION),
|
|
3366
3609
|
(0, import_firestore13.where)("clinics", "array-contains", clinicId),
|
|
3367
|
-
(0, import_firestore13.where)("isActive", "==", true)
|
|
3610
|
+
(0, import_firestore13.where)("isActive", "==", true),
|
|
3611
|
+
(0, import_firestore13.where)("status", "==", "active" /* ACTIVE */)
|
|
3612
|
+
);
|
|
3613
|
+
const querySnapshot = await (0, import_firestore13.getDocs)(q);
|
|
3614
|
+
return querySnapshot.docs.map((doc20) => doc20.data());
|
|
3615
|
+
}
|
|
3616
|
+
/**
|
|
3617
|
+
* Dohvata sve draft zdravstvene radnike za određenu kliniku
|
|
3618
|
+
*/
|
|
3619
|
+
async getDraftPractitionersByClinic(clinicId) {
|
|
3620
|
+
const q = (0, import_firestore13.query)(
|
|
3621
|
+
(0, import_firestore13.collection)(this.db, PRACTITIONERS_COLLECTION),
|
|
3622
|
+
(0, import_firestore13.where)("clinics", "array-contains", clinicId),
|
|
3623
|
+
(0, import_firestore13.where)("status", "==", "draft" /* DRAFT */)
|
|
3368
3624
|
);
|
|
3369
3625
|
const querySnapshot = await (0, import_firestore13.getDocs)(q);
|
|
3370
3626
|
return querySnapshot.docs.map((doc20) => doc20.data());
|
|
@@ -3473,6 +3729,35 @@ var PractitionerService = class extends BaseService {
|
|
|
3473
3729
|
}
|
|
3474
3730
|
await (0, import_firestore13.deleteDoc)((0, import_firestore13.doc)(this.db, PRACTITIONERS_COLLECTION, practitionerId));
|
|
3475
3731
|
}
|
|
3732
|
+
/**
|
|
3733
|
+
* Validates a registration token and claims the associated draft practitioner profile
|
|
3734
|
+
* @param tokenString The token provided by the practitioner
|
|
3735
|
+
* @param userId The ID of the user claiming the profile
|
|
3736
|
+
* @returns The claimed practitioner profile or null if token is invalid
|
|
3737
|
+
*/
|
|
3738
|
+
async validateTokenAndClaimProfile(tokenString, userId) {
|
|
3739
|
+
const token = await this.validateToken(tokenString);
|
|
3740
|
+
if (!token) {
|
|
3741
|
+
return null;
|
|
3742
|
+
}
|
|
3743
|
+
const practitioner = await this.getPractitioner(token.practitionerId);
|
|
3744
|
+
if (!practitioner) {
|
|
3745
|
+
return null;
|
|
3746
|
+
}
|
|
3747
|
+
if (practitioner.status !== "draft" /* DRAFT */) {
|
|
3748
|
+
throw new Error("This practitioner profile has already been claimed");
|
|
3749
|
+
}
|
|
3750
|
+
const existingPractitioner = await this.getPractitionerByUserRef(userId);
|
|
3751
|
+
if (existingPractitioner) {
|
|
3752
|
+
throw new Error("User already has a practitioner profile");
|
|
3753
|
+
}
|
|
3754
|
+
const updatedPractitioner = await this.updatePractitioner(practitioner.id, {
|
|
3755
|
+
userRef: userId,
|
|
3756
|
+
status: "active" /* ACTIVE */
|
|
3757
|
+
});
|
|
3758
|
+
await this.markTokenAsUsed(token.id, token.practitionerId, userId);
|
|
3759
|
+
return updatedPractitioner;
|
|
3760
|
+
}
|
|
3476
3761
|
};
|
|
3477
3762
|
|
|
3478
3763
|
// src/services/user.service.ts
|
|
@@ -3691,25 +3976,6 @@ var UserService = class extends BaseService {
|
|
|
3691
3976
|
...updates,
|
|
3692
3977
|
updatedAt: (0, import_firestore14.serverTimestamp)()
|
|
3693
3978
|
};
|
|
3694
|
-
updatedUser.roles.forEach((role) => {
|
|
3695
|
-
switch (role) {
|
|
3696
|
-
case "patient" /* PATIENT */:
|
|
3697
|
-
if (!updatedUser.patientProfile) {
|
|
3698
|
-
throw new Error(`Missing patient profile for role ${role}`);
|
|
3699
|
-
}
|
|
3700
|
-
break;
|
|
3701
|
-
case "practitioner" /* PRACTITIONER */:
|
|
3702
|
-
if (!updatedUser.practitionerProfile) {
|
|
3703
|
-
throw new Error(`Missing practitioner profile for role ${role}`);
|
|
3704
|
-
}
|
|
3705
|
-
break;
|
|
3706
|
-
case "clinic_admin" /* CLINIC_ADMIN */:
|
|
3707
|
-
if (!updatedUser.adminProfile) {
|
|
3708
|
-
throw new Error(`Missing admin profile for role ${role}`);
|
|
3709
|
-
}
|
|
3710
|
-
break;
|
|
3711
|
-
}
|
|
3712
|
-
});
|
|
3713
3979
|
userSchema.parse(updatedUser);
|
|
3714
3980
|
await (0, import_firestore14.updateDoc)(userRef, {
|
|
3715
3981
|
...updates,
|
|
@@ -9080,8 +9346,11 @@ var notificationSchema = import_zod18.z.discriminatedUnion("notificationType", [
|
|
|
9080
9346
|
PatientService,
|
|
9081
9347
|
PracticeType,
|
|
9082
9348
|
PractitionerService,
|
|
9349
|
+
PractitionerStatus,
|
|
9350
|
+
PractitionerTokenStatus,
|
|
9083
9351
|
PricingMeasure,
|
|
9084
9352
|
ProcedureFamily,
|
|
9353
|
+
REGISTER_TOKENS_COLLECTION,
|
|
9085
9354
|
SYNCED_CALENDARS_COLLECTION,
|
|
9086
9355
|
SubscriptionModel,
|
|
9087
9356
|
SyncedCalendarProvider,
|
|
@@ -9126,11 +9395,13 @@ var notificationSchema = import_zod18.z.discriminatedUnion("notificationType", [
|
|
|
9126
9395
|
createClinicSchema,
|
|
9127
9396
|
createDefaultClinicGroupSchema,
|
|
9128
9397
|
createDocumentTemplateSchema,
|
|
9398
|
+
createDraftPractitionerSchema,
|
|
9129
9399
|
createPatientLocationInfoSchema,
|
|
9130
9400
|
createPatientMedicalInfoSchema,
|
|
9131
9401
|
createPatientProfileSchema,
|
|
9132
9402
|
createPatientSensitiveInfoSchema,
|
|
9133
9403
|
createPractitionerSchema,
|
|
9404
|
+
createPractitionerTokenSchema,
|
|
9134
9405
|
createUserOptionsSchema,
|
|
9135
9406
|
doctorInfoSchema,
|
|
9136
9407
|
documentElementSchema,
|
|
@@ -9163,6 +9434,7 @@ var notificationSchema = import_zod18.z.discriminatedUnion("notificationType", [
|
|
|
9163
9434
|
practitionerProfileInfoSchema,
|
|
9164
9435
|
practitionerReviewSchema,
|
|
9165
9436
|
practitionerSchema,
|
|
9437
|
+
practitionerTokenSchema,
|
|
9166
9438
|
practitionerWorkingHoursSchema,
|
|
9167
9439
|
preRequirementNotificationSchema,
|
|
9168
9440
|
procedureCategorizationSchema,
|