@blackcode_sa/metaestetics-api 1.7.41 → 1.7.43
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 +4 -4
- package/dist/admin/index.d.ts +4 -4
- package/dist/backoffice/index.d.mts +4 -4
- package/dist/backoffice/index.d.ts +4 -4
- package/dist/index.d.mts +215 -210
- package/dist/index.d.ts +215 -210
- package/dist/index.js +475 -381
- package/dist/index.mjs +602 -507
- package/package.json +1 -1
- package/src/services/auth/index.ts +21 -0
- package/src/services/auth/utils/error.utils.ts +90 -0
- package/src/services/auth/utils/firebase.utils.ts +49 -0
- package/src/services/auth/utils/index.ts +21 -0
- package/src/services/auth/utils/practitioner.utils.ts +125 -0
- package/src/services/auth.service.ts +143 -155
- package/src/services/practitioner/practitioner.service.ts +5 -3
- package/src/types/index.ts +3 -3
- package/src/types/practitioner/index.ts +4 -4
- package/src/validations/common.schema.ts +6 -1
- package/src/validations/practitioner.schema.ts +7 -4
- package/src/validations/schemas.ts +26 -14
package/dist/index.mjs
CHANGED
|
@@ -599,7 +599,8 @@ import {
|
|
|
599
599
|
import {
|
|
600
600
|
collection as collection14,
|
|
601
601
|
query as query14,
|
|
602
|
-
getDocs as getDocs14
|
|
602
|
+
getDocs as getDocs14,
|
|
603
|
+
runTransaction
|
|
603
604
|
} from "firebase/firestore";
|
|
604
605
|
|
|
605
606
|
// src/types/calendar/index.ts
|
|
@@ -645,7 +646,7 @@ var UserRole = /* @__PURE__ */ ((UserRole2) => {
|
|
|
645
646
|
var USERS_COLLECTION = "users";
|
|
646
647
|
|
|
647
648
|
// src/services/auth.service.ts
|
|
648
|
-
import { z as
|
|
649
|
+
import { z as z22 } from "zod";
|
|
649
650
|
|
|
650
651
|
// src/validations/schemas.ts
|
|
651
652
|
import { z as z4 } from "zod";
|
|
@@ -656,12 +657,21 @@ var passwordSchema = z4.string().min(8, "Password must be at least 8 characters"
|
|
|
656
657
|
);
|
|
657
658
|
var userRoleSchema = z4.nativeEnum(UserRole);
|
|
658
659
|
var userRolesSchema = z4.array(userRoleSchema).min(1, "User must have at least one role").max(3, "User cannot have more than 3 roles");
|
|
659
|
-
var timestampSchema = z4.custom(
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
660
|
+
var timestampSchema = z4.custom(
|
|
661
|
+
(data) => {
|
|
662
|
+
if (data && typeof data === "object" && "isEqual" in data) {
|
|
663
|
+
return true;
|
|
664
|
+
}
|
|
665
|
+
if (data && typeof data === "object" && "toDate" in data && "seconds" in data && "nanoseconds" in data) {
|
|
666
|
+
return true;
|
|
667
|
+
}
|
|
668
|
+
if (data instanceof Date) {
|
|
669
|
+
return true;
|
|
670
|
+
}
|
|
671
|
+
return false;
|
|
672
|
+
},
|
|
673
|
+
"Must be a Timestamp object, Date object, or serverTimestamp"
|
|
674
|
+
);
|
|
665
675
|
var clinicAdminOptionsSchema = z4.object({
|
|
666
676
|
isGroupOwner: z4.boolean(),
|
|
667
677
|
groupToken: z4.string().optional(),
|
|
@@ -1526,11 +1536,16 @@ var timestampSchema2 = z5.union([
|
|
|
1526
1536
|
seconds: z5.number(),
|
|
1527
1537
|
nanoseconds: z5.number()
|
|
1528
1538
|
}),
|
|
1529
|
-
z5.instanceof(Timestamp2)
|
|
1539
|
+
z5.instanceof(Timestamp2),
|
|
1540
|
+
z5.instanceof(Date)
|
|
1541
|
+
// Add support for Date objects that Firestore returns on client
|
|
1530
1542
|
]).transform((data) => {
|
|
1531
1543
|
if (data instanceof Timestamp2) {
|
|
1532
1544
|
return data;
|
|
1533
1545
|
}
|
|
1546
|
+
if (data instanceof Date) {
|
|
1547
|
+
return Timestamp2.fromDate(data);
|
|
1548
|
+
}
|
|
1534
1549
|
return new Timestamp2(data.seconds, data.nanoseconds);
|
|
1535
1550
|
});
|
|
1536
1551
|
|
|
@@ -4522,10 +4537,10 @@ var practitionerBasicInfoSchema = z14.object({
|
|
|
4522
4537
|
lastName: z14.string().min(2).max(50),
|
|
4523
4538
|
title: z14.string().min(2).max(100),
|
|
4524
4539
|
email: z14.string().email(),
|
|
4525
|
-
phoneNumber: z14.string().regex(/^\+?[1-9]\d{1,14}$/, "Invalid phone number"),
|
|
4526
|
-
dateOfBirth: z14.instanceof(Timestamp9).or(z14.date()),
|
|
4540
|
+
phoneNumber: z14.string().regex(/^\+?[1-9]\d{1,14}$/, "Invalid phone number").nullable(),
|
|
4541
|
+
dateOfBirth: z14.instanceof(Timestamp9).or(z14.date()).nullable(),
|
|
4527
4542
|
gender: z14.enum(["male", "female", "other"]),
|
|
4528
|
-
profileImageUrl: mediaResourceSchema.optional(),
|
|
4543
|
+
profileImageUrl: mediaResourceSchema.optional().nullable(),
|
|
4529
4544
|
bio: z14.string().max(1e3).optional(),
|
|
4530
4545
|
languages: z14.array(z14.string()).min(1)
|
|
4531
4546
|
});
|
|
@@ -4535,7 +4550,7 @@ var practitionerCertificationSchema = z14.object({
|
|
|
4535
4550
|
licenseNumber: z14.string().min(3).max(50),
|
|
4536
4551
|
issuingAuthority: z14.string().min(2).max(100),
|
|
4537
4552
|
issueDate: z14.instanceof(Timestamp9).or(z14.date()),
|
|
4538
|
-
expiryDate: z14.instanceof(Timestamp9).or(z14.date()).optional(),
|
|
4553
|
+
expiryDate: z14.instanceof(Timestamp9).or(z14.date()).optional().nullable(),
|
|
4539
4554
|
verificationStatus: z14.enum(["pending", "verified", "rejected"])
|
|
4540
4555
|
});
|
|
4541
4556
|
var timeSlotSchema = z14.object({
|
|
@@ -7693,6 +7708,125 @@ var ClinicService = class extends BaseService {
|
|
|
7693
7708
|
}
|
|
7694
7709
|
};
|
|
7695
7710
|
|
|
7711
|
+
// src/services/auth/utils/firebase.utils.ts
|
|
7712
|
+
import { fetchSignInMethodsForEmail } from "firebase/auth";
|
|
7713
|
+
var checkEmailExists = async (auth, email) => {
|
|
7714
|
+
try {
|
|
7715
|
+
const methods = await fetchSignInMethodsForEmail(auth, email);
|
|
7716
|
+
return methods.length > 0;
|
|
7717
|
+
} catch (error) {
|
|
7718
|
+
console.warn(
|
|
7719
|
+
"[FIREBASE] Could not check email existence, allowing signup to proceed:",
|
|
7720
|
+
error
|
|
7721
|
+
);
|
|
7722
|
+
return false;
|
|
7723
|
+
}
|
|
7724
|
+
};
|
|
7725
|
+
var cleanupFirebaseUser = async (firebaseUser) => {
|
|
7726
|
+
try {
|
|
7727
|
+
console.log("[FIREBASE] Cleaning up Firebase user", {
|
|
7728
|
+
uid: firebaseUser.uid
|
|
7729
|
+
});
|
|
7730
|
+
await firebaseUser.delete();
|
|
7731
|
+
console.log("[FIREBASE] Firebase user cleanup successful");
|
|
7732
|
+
} catch (cleanupError) {
|
|
7733
|
+
console.error("[FIREBASE] Failed to cleanup Firebase user:", cleanupError);
|
|
7734
|
+
}
|
|
7735
|
+
};
|
|
7736
|
+
|
|
7737
|
+
// src/services/auth/utils/error.utils.ts
|
|
7738
|
+
import { z as z20 } from "zod";
|
|
7739
|
+
var handleFirebaseError = (error) => {
|
|
7740
|
+
const firebaseError = error;
|
|
7741
|
+
switch (firebaseError.code) {
|
|
7742
|
+
case "auth/email-already-in-use" /* EMAIL_ALREADY_IN_USE */:
|
|
7743
|
+
return AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
|
|
7744
|
+
case "auth/weak-password":
|
|
7745
|
+
return new Error(
|
|
7746
|
+
"Password is too weak. Please choose a stronger password."
|
|
7747
|
+
);
|
|
7748
|
+
case "auth/invalid-email":
|
|
7749
|
+
return new Error("Please enter a valid email address.");
|
|
7750
|
+
case "auth/network-request-failed":
|
|
7751
|
+
return new Error(
|
|
7752
|
+
"Network error. Please check your internet connection and try again."
|
|
7753
|
+
);
|
|
7754
|
+
default:
|
|
7755
|
+
return new Error(
|
|
7756
|
+
`Account creation failed: ${firebaseError.message || "Unknown error"}`
|
|
7757
|
+
);
|
|
7758
|
+
}
|
|
7759
|
+
};
|
|
7760
|
+
var handleSignupError = (error) => {
|
|
7761
|
+
if (error instanceof z20.ZodError) {
|
|
7762
|
+
const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
|
|
7763
|
+
return new Error(`Validation failed: ${errorMessages}`);
|
|
7764
|
+
}
|
|
7765
|
+
if (error.code && error.code.startsWith("auth/")) {
|
|
7766
|
+
return handleFirebaseError(error);
|
|
7767
|
+
}
|
|
7768
|
+
if (error.message && error.message.includes("token")) {
|
|
7769
|
+
return new Error("Invalid or expired invitation token");
|
|
7770
|
+
}
|
|
7771
|
+
if (error.message && error.message.includes("validation")) {
|
|
7772
|
+
return new Error(`Invalid practitioner data: ${error.message}`);
|
|
7773
|
+
}
|
|
7774
|
+
return new Error(
|
|
7775
|
+
`Registration failed: ${error.message || "Unknown error occurred"}`
|
|
7776
|
+
);
|
|
7777
|
+
};
|
|
7778
|
+
|
|
7779
|
+
// src/services/auth/utils/practitioner.utils.ts
|
|
7780
|
+
import { z as z21 } from "zod";
|
|
7781
|
+
var profileDataSchema = z21.object({
|
|
7782
|
+
basicInfo: practitionerBasicInfoSchema.partial().optional(),
|
|
7783
|
+
certification: practitionerCertificationSchema.partial().optional()
|
|
7784
|
+
}).partial();
|
|
7785
|
+
var buildPractitionerData = (data, userRef) => {
|
|
7786
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
7787
|
+
const basicInfo = {
|
|
7788
|
+
firstName: data.firstName || "Name",
|
|
7789
|
+
lastName: data.lastName || "Surname",
|
|
7790
|
+
email: data.email,
|
|
7791
|
+
phoneNumber: ((_b = (_a = data.profileData) == null ? void 0 : _a.basicInfo) == null ? void 0 : _b.phoneNumber) || null,
|
|
7792
|
+
profileImageUrl: ((_d = (_c = data.profileData) == null ? void 0 : _c.basicInfo) == null ? void 0 : _d.profileImageUrl) || "",
|
|
7793
|
+
gender: ((_f = (_e = data.profileData) == null ? void 0 : _e.basicInfo) == null ? void 0 : _f.gender) || "other",
|
|
7794
|
+
bio: ((_h = (_g = data.profileData) == null ? void 0 : _g.basicInfo) == null ? void 0 : _h.bio) || "",
|
|
7795
|
+
title: "Practitioner",
|
|
7796
|
+
dateOfBirth: ((_j = (_i = data.profileData) == null ? void 0 : _i.basicInfo) == null ? void 0 : _j.dateOfBirth) || /* @__PURE__ */ new Date(),
|
|
7797
|
+
languages: ((_l = (_k = data.profileData) == null ? void 0 : _k.basicInfo) == null ? void 0 : _l.languages) || ["English"]
|
|
7798
|
+
};
|
|
7799
|
+
const certification = ((_m = data.profileData) == null ? void 0 : _m.certification) || {
|
|
7800
|
+
level: "aesthetician" /* AESTHETICIAN */,
|
|
7801
|
+
specialties: [],
|
|
7802
|
+
licenseNumber: "Pending",
|
|
7803
|
+
issuingAuthority: "Pending",
|
|
7804
|
+
issueDate: /* @__PURE__ */ new Date(),
|
|
7805
|
+
verificationStatus: "pending"
|
|
7806
|
+
};
|
|
7807
|
+
return {
|
|
7808
|
+
userRef,
|
|
7809
|
+
basicInfo,
|
|
7810
|
+
certification,
|
|
7811
|
+
status: "active" /* ACTIVE */,
|
|
7812
|
+
isActive: true,
|
|
7813
|
+
isVerified: false
|
|
7814
|
+
};
|
|
7815
|
+
};
|
|
7816
|
+
var validatePractitionerProfileData = async (profileData) => {
|
|
7817
|
+
try {
|
|
7818
|
+
await profileDataSchema.parseAsync(profileData);
|
|
7819
|
+
} catch (error) {
|
|
7820
|
+
if (error instanceof z21.ZodError) {
|
|
7821
|
+
const errorMessages = error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
|
|
7822
|
+
throw new Error(
|
|
7823
|
+
`Practitioner profile validation failed: ${errorMessages}`
|
|
7824
|
+
);
|
|
7825
|
+
}
|
|
7826
|
+
throw error;
|
|
7827
|
+
}
|
|
7828
|
+
};
|
|
7829
|
+
|
|
7696
7830
|
// src/services/auth.service.ts
|
|
7697
7831
|
var AuthService = class extends BaseService {
|
|
7698
7832
|
constructor(db, auth, app, userService) {
|
|
@@ -7700,10 +7834,7 @@ var AuthService = class extends BaseService {
|
|
|
7700
7834
|
this.googleProvider = new GoogleAuthProvider();
|
|
7701
7835
|
this.facebookProvider = new FacebookAuthProvider();
|
|
7702
7836
|
this.appleProvider = new OAuthProvider("apple.com");
|
|
7703
|
-
|
|
7704
|
-
userService = new UserService(db, auth, app);
|
|
7705
|
-
}
|
|
7706
|
-
this.userService = userService;
|
|
7837
|
+
this.userService = userService || new UserService(db, auth, app);
|
|
7707
7838
|
}
|
|
7708
7839
|
/**
|
|
7709
7840
|
* Registruje novog korisnika sa email-om i lozinkom
|
|
@@ -7752,7 +7883,7 @@ var AuthService = class extends BaseService {
|
|
|
7752
7883
|
});
|
|
7753
7884
|
} catch (firebaseError) {
|
|
7754
7885
|
console.error("[AUTH] Firebase user creation failed:", firebaseError);
|
|
7755
|
-
throw firebaseError;
|
|
7886
|
+
throw handleFirebaseError(firebaseError);
|
|
7756
7887
|
}
|
|
7757
7888
|
console.log("[AUTH] Creating user with CLINIC_ADMIN role");
|
|
7758
7889
|
let user;
|
|
@@ -8006,7 +8137,7 @@ var AuthService = class extends BaseService {
|
|
|
8006
8137
|
clinicAdmin: adminProfile
|
|
8007
8138
|
};
|
|
8008
8139
|
} catch (error) {
|
|
8009
|
-
if (error instanceof
|
|
8140
|
+
if (error instanceof z22.ZodError) {
|
|
8010
8141
|
console.error(
|
|
8011
8142
|
"[AUTH] Zod validation error in signUpClinicAdmin:",
|
|
8012
8143
|
JSON.stringify(error.errors, null, 2)
|
|
@@ -8181,7 +8312,7 @@ var AuthService = class extends BaseService {
|
|
|
8181
8312
|
email
|
|
8182
8313
|
);
|
|
8183
8314
|
} catch (error) {
|
|
8184
|
-
if (error instanceof
|
|
8315
|
+
if (error instanceof z22.ZodError) {
|
|
8185
8316
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
8186
8317
|
}
|
|
8187
8318
|
const firebaseError = error;
|
|
@@ -8304,7 +8435,7 @@ var AuthService = class extends BaseService {
|
|
|
8304
8435
|
await emailSchema.parseAsync(email);
|
|
8305
8436
|
await sendPasswordResetEmail(this.auth, email);
|
|
8306
8437
|
} catch (error) {
|
|
8307
|
-
if (error instanceof
|
|
8438
|
+
if (error instanceof z22.ZodError) {
|
|
8308
8439
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
8309
8440
|
}
|
|
8310
8441
|
const firebaseError = error;
|
|
@@ -8343,7 +8474,7 @@ var AuthService = class extends BaseService {
|
|
|
8343
8474
|
await passwordSchema.parseAsync(newPassword);
|
|
8344
8475
|
await confirmPasswordReset(this.auth, oobCode, newPassword);
|
|
8345
8476
|
} catch (error) {
|
|
8346
|
-
if (error instanceof
|
|
8477
|
+
if (error instanceof z22.ZodError) {
|
|
8347
8478
|
throw AUTH_ERRORS.VALIDATION_ERROR;
|
|
8348
8479
|
}
|
|
8349
8480
|
const firebaseError = error;
|
|
@@ -8358,31 +8489,21 @@ var AuthService = class extends BaseService {
|
|
|
8358
8489
|
}
|
|
8359
8490
|
}
|
|
8360
8491
|
/**
|
|
8361
|
-
* Registers a new practitioner user with email and password
|
|
8362
|
-
*
|
|
8492
|
+
* Registers a new practitioner user with email and password (ATOMIC VERSION)
|
|
8493
|
+
* Uses Firestore transactions to ensure atomicity and proper rollback on failures
|
|
8363
8494
|
*
|
|
8364
8495
|
* @param data - Practitioner signup data containing either new profile details or token for claiming draft profile
|
|
8365
8496
|
* @returns Object containing the created user and practitioner profile
|
|
8366
8497
|
*/
|
|
8367
8498
|
async signUpPractitioner(data) {
|
|
8368
|
-
|
|
8499
|
+
let firebaseUser = null;
|
|
8369
8500
|
try {
|
|
8370
|
-
console.log("[AUTH] Starting practitioner signup process", {
|
|
8501
|
+
console.log("[AUTH] Starting atomic practitioner signup process", {
|
|
8371
8502
|
email: data.email,
|
|
8372
8503
|
hasToken: !!data.token
|
|
8373
8504
|
});
|
|
8374
|
-
|
|
8375
|
-
await practitionerSignupSchema.parseAsync(data);
|
|
8376
|
-
console.log("[AUTH] Practitioner signup data validation passed");
|
|
8377
|
-
} catch (validationError) {
|
|
8378
|
-
console.error(
|
|
8379
|
-
"[AUTH] Validation error in signUpPractitioner:",
|
|
8380
|
-
validationError
|
|
8381
|
-
);
|
|
8382
|
-
throw validationError;
|
|
8383
|
-
}
|
|
8505
|
+
await this.validateSignupData(data);
|
|
8384
8506
|
console.log("[AUTH] Creating Firebase user");
|
|
8385
|
-
let firebaseUser;
|
|
8386
8507
|
try {
|
|
8387
8508
|
const result = await createUserWithEmailAndPassword(
|
|
8388
8509
|
this.auth,
|
|
@@ -8395,136 +8516,110 @@ var AuthService = class extends BaseService {
|
|
|
8395
8516
|
});
|
|
8396
8517
|
} catch (firebaseError) {
|
|
8397
8518
|
console.error("[AUTH] Firebase user creation failed:", firebaseError);
|
|
8398
|
-
throw firebaseError;
|
|
8519
|
+
throw handleFirebaseError(firebaseError);
|
|
8399
8520
|
}
|
|
8400
|
-
console.log("[AUTH]
|
|
8401
|
-
|
|
8402
|
-
try {
|
|
8403
|
-
user = await this.userService.createUser(
|
|
8404
|
-
firebaseUser,
|
|
8405
|
-
["practitioner" /* PRACTITIONER */],
|
|
8406
|
-
{
|
|
8407
|
-
skipProfileCreation: true
|
|
8408
|
-
// We'll create the profile separately
|
|
8409
|
-
}
|
|
8410
|
-
);
|
|
8411
|
-
console.log("[AUTH] User with PRACTITIONER role created successfully", {
|
|
8412
|
-
userId: user.uid
|
|
8413
|
-
});
|
|
8414
|
-
} catch (userCreationError) {
|
|
8415
|
-
console.error("[AUTH] User creation failed:", userCreationError);
|
|
8416
|
-
throw userCreationError;
|
|
8417
|
-
}
|
|
8418
|
-
console.log("[AUTH] Initializing practitioner service");
|
|
8419
|
-
const practitionerService = new PractitionerService(
|
|
8521
|
+
console.log("[AUTH] Starting Firestore transaction");
|
|
8522
|
+
const transactionResult = await runTransaction(
|
|
8420
8523
|
this.db,
|
|
8421
|
-
|
|
8422
|
-
this.app
|
|
8423
|
-
);
|
|
8424
|
-
let practitioner = null;
|
|
8425
|
-
if (data.token) {
|
|
8426
|
-
console.log("[AUTH] Token provided, attempting to claim draft profile");
|
|
8427
|
-
try {
|
|
8428
|
-
practitioner = await practitionerService.validateTokenAndClaimProfile(
|
|
8429
|
-
data.token,
|
|
8430
|
-
firebaseUser.uid
|
|
8431
|
-
);
|
|
8432
|
-
if (!practitioner) {
|
|
8433
|
-
throw new Error("Invalid or expired invitation token");
|
|
8434
|
-
}
|
|
8435
|
-
console.log("[AUTH] Successfully claimed draft profile", {
|
|
8436
|
-
practitionerId: practitioner.id
|
|
8437
|
-
});
|
|
8438
|
-
await this.userService.updateUser(firebaseUser.uid, {
|
|
8439
|
-
practitionerProfile: practitioner.id
|
|
8440
|
-
});
|
|
8524
|
+
async (transaction) => {
|
|
8441
8525
|
console.log(
|
|
8442
|
-
"[AUTH]
|
|
8526
|
+
"[AUTH] Transaction started - creating user and practitioner"
|
|
8443
8527
|
);
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
} else {
|
|
8449
|
-
console.log("[AUTH] Creating new practitioner profile");
|
|
8450
|
-
if (!data.profileData) {
|
|
8451
|
-
data.profileData = {};
|
|
8452
|
-
}
|
|
8453
|
-
const basicInfo = {
|
|
8454
|
-
firstName: data.firstName || "",
|
|
8455
|
-
lastName: data.lastName || "",
|
|
8456
|
-
email: data.email,
|
|
8457
|
-
phoneNumber: ((_a = data.profileData.basicInfo) == null ? void 0 : _a.phoneNumber) || "",
|
|
8458
|
-
profileImageUrl: ((_b = data.profileData.basicInfo) == null ? void 0 : _b.profileImageUrl) || "",
|
|
8459
|
-
gender: ((_c = data.profileData.basicInfo) == null ? void 0 : _c.gender) || "other",
|
|
8460
|
-
// Default to "other" if not provided
|
|
8461
|
-
bio: ((_d = data.profileData.basicInfo) == null ? void 0 : _d.bio) || "",
|
|
8462
|
-
title: "Practitioner",
|
|
8463
|
-
// Default title
|
|
8464
|
-
dateOfBirth: /* @__PURE__ */ new Date(),
|
|
8465
|
-
// Default to today
|
|
8466
|
-
languages: ["English"]
|
|
8467
|
-
// Default language
|
|
8468
|
-
};
|
|
8469
|
-
const certification = data.profileData.certification || {
|
|
8470
|
-
level: "aesthetician" /* AESTHETICIAN */,
|
|
8471
|
-
specialties: [],
|
|
8472
|
-
licenseNumber: "Pending",
|
|
8473
|
-
issuingAuthority: "Pending",
|
|
8474
|
-
issueDate: /* @__PURE__ */ new Date(),
|
|
8475
|
-
verificationStatus: "pending"
|
|
8476
|
-
};
|
|
8477
|
-
const createPractitionerData = {
|
|
8478
|
-
userRef: firebaseUser.uid,
|
|
8479
|
-
basicInfo,
|
|
8480
|
-
certification,
|
|
8481
|
-
status: "active" /* ACTIVE */,
|
|
8482
|
-
isActive: true,
|
|
8483
|
-
isVerified: false
|
|
8484
|
-
};
|
|
8485
|
-
try {
|
|
8486
|
-
practitioner = await practitionerService.createPractitioner(
|
|
8487
|
-
createPractitionerData
|
|
8528
|
+
const practitionerService = new PractitionerService(
|
|
8529
|
+
this.db,
|
|
8530
|
+
this.auth,
|
|
8531
|
+
this.app
|
|
8488
8532
|
);
|
|
8489
|
-
console.log("[AUTH]
|
|
8490
|
-
|
|
8491
|
-
|
|
8533
|
+
console.log("[AUTH] Creating user document");
|
|
8534
|
+
const user = await this.userService.createUser(
|
|
8535
|
+
firebaseUser,
|
|
8536
|
+
["practitioner" /* PRACTITIONER */],
|
|
8537
|
+
{ skipProfileCreation: true }
|
|
8538
|
+
);
|
|
8539
|
+
let practitioner;
|
|
8540
|
+
if (data.token) {
|
|
8541
|
+
console.log(
|
|
8542
|
+
"[AUTH] Claiming existing practitioner profile with token"
|
|
8543
|
+
);
|
|
8544
|
+
const claimedPractitioner = await practitionerService.validateTokenAndClaimProfile(
|
|
8545
|
+
data.token,
|
|
8546
|
+
firebaseUser.uid
|
|
8547
|
+
);
|
|
8548
|
+
if (!claimedPractitioner) {
|
|
8549
|
+
throw new Error("Invalid or expired invitation token");
|
|
8550
|
+
}
|
|
8551
|
+
practitioner = claimedPractitioner;
|
|
8552
|
+
} else {
|
|
8553
|
+
console.log("[AUTH] Creating new practitioner profile");
|
|
8554
|
+
const practitionerData = buildPractitionerData(
|
|
8555
|
+
data,
|
|
8556
|
+
firebaseUser.uid
|
|
8557
|
+
);
|
|
8558
|
+
practitioner = await practitionerService.createPractitioner(
|
|
8559
|
+
practitionerData
|
|
8560
|
+
);
|
|
8561
|
+
}
|
|
8562
|
+
console.log("[AUTH] Linking practitioner to user");
|
|
8492
8563
|
await this.userService.updateUser(firebaseUser.uid, {
|
|
8493
8564
|
practitionerProfile: practitioner.id
|
|
8494
8565
|
});
|
|
8495
|
-
console.log(
|
|
8496
|
-
|
|
8497
|
-
);
|
|
8498
|
-
} catch (createError) {
|
|
8499
|
-
console.error(
|
|
8500
|
-
"[AUTH] Failed to create practitioner profile:",
|
|
8501
|
-
createError
|
|
8502
|
-
);
|
|
8503
|
-
throw createError;
|
|
8566
|
+
console.log("[AUTH] Transaction operations completed successfully");
|
|
8567
|
+
return { user, practitioner };
|
|
8504
8568
|
}
|
|
8505
|
-
|
|
8506
|
-
console.log("[AUTH]
|
|
8507
|
-
userId: user.uid,
|
|
8508
|
-
practitionerId:
|
|
8569
|
+
);
|
|
8570
|
+
console.log("[AUTH] Atomic practitioner signup completed successfully", {
|
|
8571
|
+
userId: transactionResult.user.uid,
|
|
8572
|
+
practitionerId: transactionResult.practitioner.id
|
|
8509
8573
|
});
|
|
8510
|
-
return
|
|
8511
|
-
user,
|
|
8512
|
-
practitioner
|
|
8513
|
-
};
|
|
8574
|
+
return transactionResult;
|
|
8514
8575
|
} catch (error) {
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8576
|
+
console.error(
|
|
8577
|
+
"[AUTH] Atomic signup failed, initiating cleanup...",
|
|
8578
|
+
error
|
|
8579
|
+
);
|
|
8580
|
+
if (firebaseUser) {
|
|
8581
|
+
await cleanupFirebaseUser(firebaseUser);
|
|
8521
8582
|
}
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8583
|
+
throw handleSignupError(error);
|
|
8584
|
+
}
|
|
8585
|
+
}
|
|
8586
|
+
/**
|
|
8587
|
+
* Pre-validate all signup data before any mutations
|
|
8588
|
+
* Prevents partial creation by catching issues early
|
|
8589
|
+
*/
|
|
8590
|
+
async validateSignupData(data) {
|
|
8591
|
+
console.log("[AUTH] Pre-validating signup data");
|
|
8592
|
+
try {
|
|
8593
|
+
await practitionerSignupSchema.parseAsync(data);
|
|
8594
|
+
console.log("[AUTH] Schema validation passed");
|
|
8595
|
+
const emailExists = await checkEmailExists(this.auth, data.email);
|
|
8596
|
+
if (emailExists) {
|
|
8597
|
+
console.log("[AUTH] Email already exists:", data.email);
|
|
8525
8598
|
throw AUTH_ERRORS.EMAIL_ALREADY_EXISTS;
|
|
8526
8599
|
}
|
|
8527
|
-
console.
|
|
8600
|
+
console.log("[AUTH] Email availability confirmed");
|
|
8601
|
+
if (data.token) {
|
|
8602
|
+
const practitionerService = new PractitionerService(
|
|
8603
|
+
this.db,
|
|
8604
|
+
this.auth,
|
|
8605
|
+
this.app
|
|
8606
|
+
);
|
|
8607
|
+
const isValidToken = await practitionerService.validateToken(
|
|
8608
|
+
data.token
|
|
8609
|
+
);
|
|
8610
|
+
if (!isValidToken) {
|
|
8611
|
+
console.log("[AUTH] Invalid token provided:", data.token);
|
|
8612
|
+
throw new Error("Invalid or expired invitation token");
|
|
8613
|
+
}
|
|
8614
|
+
console.log("[AUTH] Token validation passed");
|
|
8615
|
+
}
|
|
8616
|
+
if (data.profileData) {
|
|
8617
|
+
await validatePractitionerProfileData(data.profileData);
|
|
8618
|
+
console.log("[AUTH] Profile data validation passed");
|
|
8619
|
+
}
|
|
8620
|
+
console.log("[AUTH] All pre-validation checks passed");
|
|
8621
|
+
} catch (error) {
|
|
8622
|
+
console.error("[AUTH] Pre-validation failed:", error);
|
|
8528
8623
|
throw error;
|
|
8529
8624
|
}
|
|
8530
8625
|
}
|
|
@@ -8596,8 +8691,8 @@ import {
|
|
|
8596
8691
|
query as query15,
|
|
8597
8692
|
where as where15,
|
|
8598
8693
|
updateDoc as updateDoc15,
|
|
8599
|
-
deleteDoc as
|
|
8600
|
-
orderBy as
|
|
8694
|
+
deleteDoc as deleteDoc9,
|
|
8695
|
+
orderBy as orderBy5,
|
|
8601
8696
|
Timestamp as Timestamp16,
|
|
8602
8697
|
addDoc as addDoc2,
|
|
8603
8698
|
writeBatch as writeBatch5
|
|
@@ -8681,7 +8776,7 @@ var NotificationService = class extends BaseService {
|
|
|
8681
8776
|
const q = query15(
|
|
8682
8777
|
collection15(this.db, NOTIFICATIONS_COLLECTION),
|
|
8683
8778
|
where15("userId", "==", userId),
|
|
8684
|
-
|
|
8779
|
+
orderBy5("notificationTime", "desc")
|
|
8685
8780
|
);
|
|
8686
8781
|
const querySnapshot = await getDocs15(q);
|
|
8687
8782
|
return querySnapshot.docs.map((doc36) => ({
|
|
@@ -8697,7 +8792,7 @@ var NotificationService = class extends BaseService {
|
|
|
8697
8792
|
collection15(this.db, NOTIFICATIONS_COLLECTION),
|
|
8698
8793
|
where15("userId", "==", userId),
|
|
8699
8794
|
where15("isRead", "==", false),
|
|
8700
|
-
|
|
8795
|
+
orderBy5("notificationTime", "desc")
|
|
8701
8796
|
);
|
|
8702
8797
|
const querySnapshot = await getDocs15(q);
|
|
8703
8798
|
return querySnapshot.docs.map((doc36) => ({
|
|
@@ -8761,7 +8856,7 @@ var NotificationService = class extends BaseService {
|
|
|
8761
8856
|
NOTIFICATIONS_COLLECTION,
|
|
8762
8857
|
notificationId
|
|
8763
8858
|
);
|
|
8764
|
-
await
|
|
8859
|
+
await deleteDoc9(notificationRef);
|
|
8765
8860
|
}
|
|
8766
8861
|
/**
|
|
8767
8862
|
* Dohvata notifikacije po tipu
|
|
@@ -8771,7 +8866,7 @@ var NotificationService = class extends BaseService {
|
|
|
8771
8866
|
collection15(this.db, NOTIFICATIONS_COLLECTION),
|
|
8772
8867
|
where15("userId", "==", userId),
|
|
8773
8868
|
where15("notificationType", "==", type),
|
|
8774
|
-
|
|
8869
|
+
orderBy5("notificationTime", "desc")
|
|
8775
8870
|
);
|
|
8776
8871
|
const querySnapshot = await getDocs15(q);
|
|
8777
8872
|
return querySnapshot.docs.map((doc36) => ({
|
|
@@ -8786,7 +8881,7 @@ var NotificationService = class extends BaseService {
|
|
|
8786
8881
|
const q = query15(
|
|
8787
8882
|
collection15(this.db, NOTIFICATIONS_COLLECTION),
|
|
8788
8883
|
where15("appointmentId", "==", appointmentId),
|
|
8789
|
-
|
|
8884
|
+
orderBy5("notificationTime", "desc")
|
|
8790
8885
|
);
|
|
8791
8886
|
const querySnapshot = await getDocs15(q);
|
|
8792
8887
|
return querySnapshot.docs.map((doc36) => ({
|
|
@@ -8806,74 +8901,74 @@ import {
|
|
|
8806
8901
|
where as where16,
|
|
8807
8902
|
updateDoc as updateDoc16,
|
|
8808
8903
|
setDoc as setDoc14,
|
|
8809
|
-
deleteDoc as
|
|
8810
|
-
serverTimestamp as
|
|
8811
|
-
orderBy as
|
|
8812
|
-
limit as
|
|
8813
|
-
startAfter as
|
|
8904
|
+
deleteDoc as deleteDoc10,
|
|
8905
|
+
serverTimestamp as serverTimestamp13,
|
|
8906
|
+
orderBy as orderBy6,
|
|
8907
|
+
limit as limit9,
|
|
8908
|
+
startAfter as startAfter8
|
|
8814
8909
|
} from "firebase/firestore";
|
|
8815
8910
|
|
|
8816
8911
|
// src/types/procedure/index.ts
|
|
8817
8912
|
var PROCEDURES_COLLECTION = "procedures";
|
|
8818
8913
|
|
|
8819
8914
|
// src/validations/procedure.schema.ts
|
|
8820
|
-
import { z as
|
|
8821
|
-
var createProcedureSchema =
|
|
8822
|
-
name:
|
|
8823
|
-
description:
|
|
8824
|
-
family:
|
|
8825
|
-
categoryId:
|
|
8826
|
-
subcategoryId:
|
|
8827
|
-
technologyId:
|
|
8828
|
-
productId:
|
|
8829
|
-
price:
|
|
8830
|
-
currency:
|
|
8831
|
-
pricingMeasure:
|
|
8832
|
-
duration:
|
|
8915
|
+
import { z as z23 } from "zod";
|
|
8916
|
+
var createProcedureSchema = z23.object({
|
|
8917
|
+
name: z23.string().min(1).max(200),
|
|
8918
|
+
description: z23.string().min(1).max(2e3),
|
|
8919
|
+
family: z23.nativeEnum(ProcedureFamily),
|
|
8920
|
+
categoryId: z23.string().min(1),
|
|
8921
|
+
subcategoryId: z23.string().min(1),
|
|
8922
|
+
technologyId: z23.string().min(1),
|
|
8923
|
+
productId: z23.string().min(1),
|
|
8924
|
+
price: z23.number().min(0),
|
|
8925
|
+
currency: z23.nativeEnum(Currency),
|
|
8926
|
+
pricingMeasure: z23.nativeEnum(PricingMeasure),
|
|
8927
|
+
duration: z23.number().min(1).max(480),
|
|
8833
8928
|
// Max 8 hours
|
|
8834
|
-
practitionerId:
|
|
8835
|
-
clinicBranchId:
|
|
8836
|
-
photos:
|
|
8929
|
+
practitionerId: z23.string().min(1),
|
|
8930
|
+
clinicBranchId: z23.string().min(1),
|
|
8931
|
+
photos: z23.array(mediaResourceSchema).optional()
|
|
8837
8932
|
});
|
|
8838
|
-
var updateProcedureSchema =
|
|
8839
|
-
name:
|
|
8840
|
-
description:
|
|
8841
|
-
price:
|
|
8842
|
-
currency:
|
|
8843
|
-
pricingMeasure:
|
|
8844
|
-
duration:
|
|
8845
|
-
isActive:
|
|
8846
|
-
practitionerId:
|
|
8847
|
-
categoryId:
|
|
8848
|
-
subcategoryId:
|
|
8849
|
-
technologyId:
|
|
8850
|
-
productId:
|
|
8851
|
-
clinicBranchId:
|
|
8852
|
-
photos:
|
|
8933
|
+
var updateProcedureSchema = z23.object({
|
|
8934
|
+
name: z23.string().min(3).max(100).optional(),
|
|
8935
|
+
description: z23.string().min(3).max(1e3).optional(),
|
|
8936
|
+
price: z23.number().min(0).optional(),
|
|
8937
|
+
currency: z23.nativeEnum(Currency).optional(),
|
|
8938
|
+
pricingMeasure: z23.nativeEnum(PricingMeasure).optional(),
|
|
8939
|
+
duration: z23.number().min(0).optional(),
|
|
8940
|
+
isActive: z23.boolean().optional(),
|
|
8941
|
+
practitionerId: z23.string().optional(),
|
|
8942
|
+
categoryId: z23.string().optional(),
|
|
8943
|
+
subcategoryId: z23.string().optional(),
|
|
8944
|
+
technologyId: z23.string().optional(),
|
|
8945
|
+
productId: z23.string().optional(),
|
|
8946
|
+
clinicBranchId: z23.string().optional(),
|
|
8947
|
+
photos: z23.array(mediaResourceSchema).optional()
|
|
8853
8948
|
});
|
|
8854
8949
|
var procedureSchema = createProcedureSchema.extend({
|
|
8855
|
-
id:
|
|
8856
|
-
category:
|
|
8950
|
+
id: z23.string().min(1),
|
|
8951
|
+
category: z23.any(),
|
|
8857
8952
|
// We'll validate the full category object separately
|
|
8858
|
-
subcategory:
|
|
8953
|
+
subcategory: z23.any(),
|
|
8859
8954
|
// We'll validate the full subcategory object separately
|
|
8860
|
-
technology:
|
|
8955
|
+
technology: z23.any(),
|
|
8861
8956
|
// We'll validate the full technology object separately
|
|
8862
|
-
product:
|
|
8957
|
+
product: z23.any(),
|
|
8863
8958
|
// We'll validate the full product object separately
|
|
8864
|
-
blockingConditions:
|
|
8959
|
+
blockingConditions: z23.array(z23.any()),
|
|
8865
8960
|
// We'll validate blocking conditions separately
|
|
8866
|
-
contraindications:
|
|
8961
|
+
contraindications: z23.array(z23.any()),
|
|
8867
8962
|
// We'll validate contraindications separately
|
|
8868
|
-
treatmentBenefits:
|
|
8963
|
+
treatmentBenefits: z23.array(z23.any()),
|
|
8869
8964
|
// We'll validate treatment benefits separately
|
|
8870
|
-
preRequirements:
|
|
8965
|
+
preRequirements: z23.array(z23.any()),
|
|
8871
8966
|
// We'll validate requirements separately
|
|
8872
|
-
postRequirements:
|
|
8967
|
+
postRequirements: z23.array(z23.any()),
|
|
8873
8968
|
// We'll validate requirements separately
|
|
8874
|
-
certificationRequirement:
|
|
8969
|
+
certificationRequirement: z23.any(),
|
|
8875
8970
|
// We'll validate certification requirement separately
|
|
8876
|
-
documentationTemplates:
|
|
8971
|
+
documentationTemplates: z23.array(z23.any()),
|
|
8877
8972
|
// We'll validate documentation templates separately
|
|
8878
8973
|
clinicInfo: clinicInfoSchema,
|
|
8879
8974
|
// Clinic info validation
|
|
@@ -8881,9 +8976,9 @@ var procedureSchema = createProcedureSchema.extend({
|
|
|
8881
8976
|
// Doctor info validation
|
|
8882
8977
|
reviewInfo: procedureReviewInfoSchema,
|
|
8883
8978
|
// Procedure review info validation
|
|
8884
|
-
isActive:
|
|
8885
|
-
createdAt:
|
|
8886
|
-
updatedAt:
|
|
8979
|
+
isActive: z23.boolean(),
|
|
8980
|
+
createdAt: z23.date(),
|
|
8981
|
+
updatedAt: z23.date()
|
|
8887
8982
|
});
|
|
8888
8983
|
|
|
8889
8984
|
// src/services/procedure/procedure.service.ts
|
|
@@ -9055,8 +9150,8 @@ var ProcedureService = class extends BaseService {
|
|
|
9055
9150
|
const procedureRef = doc16(this.db, PROCEDURES_COLLECTION, procedureId);
|
|
9056
9151
|
await setDoc14(procedureRef, {
|
|
9057
9152
|
...newProcedure,
|
|
9058
|
-
createdAt:
|
|
9059
|
-
updatedAt:
|
|
9153
|
+
createdAt: serverTimestamp13(),
|
|
9154
|
+
updatedAt: serverTimestamp13()
|
|
9060
9155
|
});
|
|
9061
9156
|
const savedDoc = await getDoc19(procedureRef);
|
|
9062
9157
|
return savedDoc.data();
|
|
@@ -9244,7 +9339,7 @@ var ProcedureService = class extends BaseService {
|
|
|
9244
9339
|
}
|
|
9245
9340
|
await updateDoc16(procedureRef, {
|
|
9246
9341
|
...updatedProcedureData,
|
|
9247
|
-
updatedAt:
|
|
9342
|
+
updatedAt: serverTimestamp13()
|
|
9248
9343
|
});
|
|
9249
9344
|
const updatedSnapshot = await getDoc19(procedureRef);
|
|
9250
9345
|
return updatedSnapshot.data();
|
|
@@ -9262,7 +9357,7 @@ var ProcedureService = class extends BaseService {
|
|
|
9262
9357
|
}
|
|
9263
9358
|
await updateDoc16(procedureRef, {
|
|
9264
9359
|
isActive: false,
|
|
9265
|
-
updatedAt:
|
|
9360
|
+
updatedAt: serverTimestamp13()
|
|
9266
9361
|
});
|
|
9267
9362
|
}
|
|
9268
9363
|
/**
|
|
@@ -9276,7 +9371,7 @@ var ProcedureService = class extends BaseService {
|
|
|
9276
9371
|
if (!procedureSnapshot.exists()) {
|
|
9277
9372
|
return false;
|
|
9278
9373
|
}
|
|
9279
|
-
await
|
|
9374
|
+
await deleteDoc10(procedureRef);
|
|
9280
9375
|
return true;
|
|
9281
9376
|
}
|
|
9282
9377
|
/**
|
|
@@ -9305,24 +9400,24 @@ var ProcedureService = class extends BaseService {
|
|
|
9305
9400
|
const proceduresCollection = collection16(this.db, PROCEDURES_COLLECTION);
|
|
9306
9401
|
let proceduresQuery = query16(proceduresCollection);
|
|
9307
9402
|
if (pagination && pagination > 0) {
|
|
9308
|
-
const { limit:
|
|
9403
|
+
const { limit: limit16, startAfter: startAfter14 } = await import("firebase/firestore");
|
|
9309
9404
|
if (lastDoc) {
|
|
9310
9405
|
proceduresQuery = query16(
|
|
9311
9406
|
proceduresCollection,
|
|
9312
|
-
|
|
9407
|
+
orderBy6("name"),
|
|
9313
9408
|
// Use imported orderBy
|
|
9314
|
-
|
|
9315
|
-
|
|
9409
|
+
startAfter14(lastDoc),
|
|
9410
|
+
limit16(pagination)
|
|
9316
9411
|
);
|
|
9317
9412
|
} else {
|
|
9318
9413
|
proceduresQuery = query16(
|
|
9319
9414
|
proceduresCollection,
|
|
9320
|
-
|
|
9321
|
-
|
|
9415
|
+
orderBy6("name"),
|
|
9416
|
+
limit16(pagination)
|
|
9322
9417
|
);
|
|
9323
9418
|
}
|
|
9324
9419
|
} else {
|
|
9325
|
-
proceduresQuery = query16(proceduresCollection,
|
|
9420
|
+
proceduresQuery = query16(proceduresCollection, orderBy6("name"));
|
|
9326
9421
|
}
|
|
9327
9422
|
const proceduresSnapshot = await getDocs16(proceduresQuery);
|
|
9328
9423
|
const lastVisible = proceduresSnapshot.docs[proceduresSnapshot.docs.length - 1];
|
|
@@ -9380,12 +9475,12 @@ var ProcedureService = class extends BaseService {
|
|
|
9380
9475
|
if (filters.procedureFamily) {
|
|
9381
9476
|
constraints.push(where16("family", "==", filters.procedureFamily));
|
|
9382
9477
|
}
|
|
9383
|
-
constraints.push(
|
|
9478
|
+
constraints.push(orderBy6("clinicInfo.location.geohash"));
|
|
9384
9479
|
if (filters.pagination && filters.pagination > 0 && filters.lastDoc) {
|
|
9385
|
-
constraints.push(
|
|
9386
|
-
constraints.push(
|
|
9480
|
+
constraints.push(startAfter8(filters.lastDoc));
|
|
9481
|
+
constraints.push(limit9(filters.pagination));
|
|
9387
9482
|
} else if (filters.pagination && filters.pagination > 0) {
|
|
9388
|
-
constraints.push(
|
|
9483
|
+
constraints.push(limit9(filters.pagination));
|
|
9389
9484
|
}
|
|
9390
9485
|
let proceduresResult = [];
|
|
9391
9486
|
let lastVisibleDoc = null;
|
|
@@ -9671,8 +9766,8 @@ var ProcedureService = class extends BaseService {
|
|
|
9671
9766
|
const procedureRef = doc16(this.db, PROCEDURES_COLLECTION, procedureId);
|
|
9672
9767
|
await setDoc14(procedureRef, {
|
|
9673
9768
|
...newProcedure,
|
|
9674
|
-
createdAt:
|
|
9675
|
-
updatedAt:
|
|
9769
|
+
createdAt: serverTimestamp13(),
|
|
9770
|
+
updatedAt: serverTimestamp13()
|
|
9676
9771
|
});
|
|
9677
9772
|
const savedDoc = await getDoc19(procedureRef);
|
|
9678
9773
|
return savedDoc.data();
|
|
@@ -9689,11 +9784,11 @@ import {
|
|
|
9689
9784
|
where as where17,
|
|
9690
9785
|
updateDoc as updateDoc17,
|
|
9691
9786
|
setDoc as setDoc15,
|
|
9692
|
-
deleteDoc as
|
|
9787
|
+
deleteDoc as deleteDoc11,
|
|
9693
9788
|
Timestamp as Timestamp18,
|
|
9694
|
-
serverTimestamp as
|
|
9695
|
-
orderBy as
|
|
9696
|
-
limit as
|
|
9789
|
+
serverTimestamp as serverTimestamp14,
|
|
9790
|
+
orderBy as orderBy7,
|
|
9791
|
+
limit as limit10
|
|
9697
9792
|
} from "firebase/firestore";
|
|
9698
9793
|
var PractitionerInviteService = class extends BaseService {
|
|
9699
9794
|
constructor(db, auth, app) {
|
|
@@ -9788,7 +9883,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
9788
9883
|
try {
|
|
9789
9884
|
const constraints = [
|
|
9790
9885
|
where17("practitionerId", "==", practitionerId),
|
|
9791
|
-
|
|
9886
|
+
orderBy7("createdAt", "desc")
|
|
9792
9887
|
];
|
|
9793
9888
|
if (statusFilter && statusFilter.length > 0) {
|
|
9794
9889
|
constraints.push(where17("status", "in", statusFilter));
|
|
@@ -9817,7 +9912,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
9817
9912
|
try {
|
|
9818
9913
|
const constraints = [
|
|
9819
9914
|
where17("clinicId", "==", clinicId),
|
|
9820
|
-
|
|
9915
|
+
orderBy7("createdAt", "desc")
|
|
9821
9916
|
];
|
|
9822
9917
|
if (statusFilter && statusFilter.length > 0) {
|
|
9823
9918
|
constraints.push(where17("status", "in", statusFilter));
|
|
@@ -9853,7 +9948,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
9853
9948
|
const updateData = {
|
|
9854
9949
|
status: "accepted" /* ACCEPTED */,
|
|
9855
9950
|
acceptedAt: Timestamp18.now(),
|
|
9856
|
-
updatedAt:
|
|
9951
|
+
updatedAt: serverTimestamp14()
|
|
9857
9952
|
};
|
|
9858
9953
|
const docRef = doc17(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
|
|
9859
9954
|
await updateDoc17(docRef, updateData);
|
|
@@ -9885,7 +9980,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
9885
9980
|
status: "rejected" /* REJECTED */,
|
|
9886
9981
|
rejectionReason: rejectionReason || null,
|
|
9887
9982
|
rejectedAt: Timestamp18.now(),
|
|
9888
|
-
updatedAt:
|
|
9983
|
+
updatedAt: serverTimestamp14()
|
|
9889
9984
|
};
|
|
9890
9985
|
const docRef = doc17(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
|
|
9891
9986
|
await updateDoc17(docRef, updateData);
|
|
@@ -9917,7 +10012,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
9917
10012
|
status: "cancelled" /* CANCELLED */,
|
|
9918
10013
|
cancelReason: cancelReason || null,
|
|
9919
10014
|
cancelledAt: Timestamp18.now(),
|
|
9920
|
-
updatedAt:
|
|
10015
|
+
updatedAt: serverTimestamp14()
|
|
9921
10016
|
};
|
|
9922
10017
|
const docRef = doc17(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
|
|
9923
10018
|
await updateDoc17(docRef, updateData);
|
|
@@ -9973,9 +10068,9 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
9973
10068
|
}
|
|
9974
10069
|
const orderField = filters.orderBy || "createdAt";
|
|
9975
10070
|
const orderDirection = filters.orderDirection || "desc";
|
|
9976
|
-
constraints.push(
|
|
10071
|
+
constraints.push(orderBy7(orderField, orderDirection));
|
|
9977
10072
|
if (filters.limit) {
|
|
9978
|
-
constraints.push(
|
|
10073
|
+
constraints.push(limit10(filters.limit));
|
|
9979
10074
|
}
|
|
9980
10075
|
const q = query17(
|
|
9981
10076
|
collection17(this.db, PRACTITIONER_INVITES_COLLECTION),
|
|
@@ -10011,7 +10106,7 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
10011
10106
|
async deleteInvite(inviteId) {
|
|
10012
10107
|
try {
|
|
10013
10108
|
const docRef = doc17(this.db, PRACTITIONER_INVITES_COLLECTION, inviteId);
|
|
10014
|
-
await
|
|
10109
|
+
await deleteDoc11(docRef);
|
|
10015
10110
|
} catch (error) {
|
|
10016
10111
|
console.error(
|
|
10017
10112
|
"[PractitionerInviteService] Error deleting invite:",
|
|
@@ -10066,8 +10161,8 @@ var PractitionerInviteService = class extends BaseService {
|
|
|
10066
10161
|
collection17(this.db, PRACTITIONER_INVITES_COLLECTION),
|
|
10067
10162
|
where17("practitionerId", "==", practitionerId),
|
|
10068
10163
|
where17("clinicId", "==", clinicId),
|
|
10069
|
-
|
|
10070
|
-
|
|
10164
|
+
orderBy7("createdAt", "desc"),
|
|
10165
|
+
limit10(1)
|
|
10071
10166
|
);
|
|
10072
10167
|
const querySnapshot = await getDocs17(q);
|
|
10073
10168
|
if (querySnapshot.empty) {
|
|
@@ -10092,12 +10187,12 @@ import {
|
|
|
10092
10187
|
getDocs as getDocs18,
|
|
10093
10188
|
setDoc as setDoc16,
|
|
10094
10189
|
updateDoc as updateDoc18,
|
|
10095
|
-
deleteDoc as
|
|
10190
|
+
deleteDoc as deleteDoc12,
|
|
10096
10191
|
query as query18,
|
|
10097
10192
|
where as where18,
|
|
10098
|
-
orderBy as
|
|
10099
|
-
limit as
|
|
10100
|
-
startAfter as
|
|
10193
|
+
orderBy as orderBy8,
|
|
10194
|
+
limit as limit11,
|
|
10195
|
+
startAfter as startAfter9
|
|
10101
10196
|
} from "firebase/firestore";
|
|
10102
10197
|
var DocumentationTemplateService = class extends BaseService {
|
|
10103
10198
|
constructor() {
|
|
@@ -10250,7 +10345,7 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
10250
10345
|
this.db,
|
|
10251
10346
|
`${DOCUMENTATION_TEMPLATES_COLLECTION}/${templateId}/versions`
|
|
10252
10347
|
);
|
|
10253
|
-
const q = query18(versionsCollectionRef,
|
|
10348
|
+
const q = query18(versionsCollectionRef, orderBy8("version", "desc"));
|
|
10254
10349
|
const querySnapshot = await getDocs18(q);
|
|
10255
10350
|
const versions = [];
|
|
10256
10351
|
querySnapshot.forEach((doc36) => {
|
|
@@ -10264,7 +10359,7 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
10264
10359
|
*/
|
|
10265
10360
|
async deleteTemplate(templateId) {
|
|
10266
10361
|
const docRef = doc18(this.collectionRef, templateId);
|
|
10267
|
-
await
|
|
10362
|
+
await deleteDoc12(docRef);
|
|
10268
10363
|
}
|
|
10269
10364
|
/**
|
|
10270
10365
|
* Get all active templates
|
|
@@ -10276,11 +10371,11 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
10276
10371
|
let q = query18(
|
|
10277
10372
|
this.collectionRef,
|
|
10278
10373
|
where18("isActive", "==", true),
|
|
10279
|
-
|
|
10280
|
-
|
|
10374
|
+
orderBy8("updatedAt", "desc"),
|
|
10375
|
+
limit11(pageSize)
|
|
10281
10376
|
);
|
|
10282
10377
|
if (lastDoc) {
|
|
10283
|
-
q = query18(q,
|
|
10378
|
+
q = query18(q, startAfter9(lastDoc));
|
|
10284
10379
|
}
|
|
10285
10380
|
const querySnapshot = await getDocs18(q);
|
|
10286
10381
|
const templates = [];
|
|
@@ -10306,11 +10401,11 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
10306
10401
|
this.collectionRef,
|
|
10307
10402
|
where18("isActive", "==", true),
|
|
10308
10403
|
where18("tags", "array-contains-any", tags),
|
|
10309
|
-
|
|
10310
|
-
|
|
10404
|
+
orderBy8("updatedAt", "desc"),
|
|
10405
|
+
limit11(pageSize)
|
|
10311
10406
|
);
|
|
10312
10407
|
if (lastDoc) {
|
|
10313
|
-
q = query18(q,
|
|
10408
|
+
q = query18(q, startAfter9(lastDoc));
|
|
10314
10409
|
}
|
|
10315
10410
|
const querySnapshot = await getDocs18(q);
|
|
10316
10411
|
const templates = [];
|
|
@@ -10335,11 +10430,11 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
10335
10430
|
let q = query18(
|
|
10336
10431
|
this.collectionRef,
|
|
10337
10432
|
where18("createdBy", "==", userId),
|
|
10338
|
-
|
|
10339
|
-
|
|
10433
|
+
orderBy8("updatedAt", "desc"),
|
|
10434
|
+
limit11(pageSize)
|
|
10340
10435
|
);
|
|
10341
10436
|
if (lastDoc) {
|
|
10342
|
-
q = query18(q,
|
|
10437
|
+
q = query18(q, startAfter9(lastDoc));
|
|
10343
10438
|
}
|
|
10344
10439
|
const querySnapshot = await getDocs18(q);
|
|
10345
10440
|
const templates = [];
|
|
@@ -10362,7 +10457,7 @@ var DocumentationTemplateService = class extends BaseService {
|
|
|
10362
10457
|
let q = query18(
|
|
10363
10458
|
this.collectionRef,
|
|
10364
10459
|
where18("isActive", "==", true),
|
|
10365
|
-
|
|
10460
|
+
orderBy8("updatedAt", "desc")
|
|
10366
10461
|
);
|
|
10367
10462
|
if ((options == null ? void 0 : options.isUserForm) !== void 0) {
|
|
10368
10463
|
q = query18(q, where18("isUserForm", "==", options.isUserForm));
|
|
@@ -10388,9 +10483,9 @@ import {
|
|
|
10388
10483
|
setDoc as setDoc17,
|
|
10389
10484
|
updateDoc as updateDoc19,
|
|
10390
10485
|
query as query19,
|
|
10391
|
-
orderBy as
|
|
10392
|
-
limit as
|
|
10393
|
-
startAfter as
|
|
10486
|
+
orderBy as orderBy9,
|
|
10487
|
+
limit as limit12,
|
|
10488
|
+
startAfter as startAfter10
|
|
10394
10489
|
} from "firebase/firestore";
|
|
10395
10490
|
var FilledDocumentService = class extends BaseService {
|
|
10396
10491
|
constructor(...args) {
|
|
@@ -10542,11 +10637,11 @@ var FilledDocumentService = class extends BaseService {
|
|
|
10542
10637
|
);
|
|
10543
10638
|
let q = query19(
|
|
10544
10639
|
subcollectionRef,
|
|
10545
|
-
|
|
10546
|
-
|
|
10640
|
+
orderBy9("updatedAt", "desc"),
|
|
10641
|
+
limit12(pageSize)
|
|
10547
10642
|
);
|
|
10548
10643
|
if (lastDoc) {
|
|
10549
|
-
q = query19(q,
|
|
10644
|
+
q = query19(q, startAfter10(lastDoc));
|
|
10550
10645
|
}
|
|
10551
10646
|
return this.executeQuery(q);
|
|
10552
10647
|
}
|
|
@@ -10566,11 +10661,11 @@ var FilledDocumentService = class extends BaseService {
|
|
|
10566
10661
|
);
|
|
10567
10662
|
let q = query19(
|
|
10568
10663
|
subcollectionRef,
|
|
10569
|
-
|
|
10570
|
-
|
|
10664
|
+
orderBy9("updatedAt", "desc"),
|
|
10665
|
+
limit12(pageSize)
|
|
10571
10666
|
);
|
|
10572
10667
|
if (lastDoc) {
|
|
10573
|
-
q = query19(q,
|
|
10668
|
+
q = query19(q, startAfter10(lastDoc));
|
|
10574
10669
|
}
|
|
10575
10670
|
return this.executeQuery(q);
|
|
10576
10671
|
}
|
|
@@ -10740,7 +10835,7 @@ var FilledDocumentService = class extends BaseService {
|
|
|
10740
10835
|
};
|
|
10741
10836
|
|
|
10742
10837
|
// src/services/calendar/calendar-refactored.service.ts
|
|
10743
|
-
import { Timestamp as Timestamp28, serverTimestamp as
|
|
10838
|
+
import { Timestamp as Timestamp28, serverTimestamp as serverTimestamp21 } from "firebase/firestore";
|
|
10744
10839
|
|
|
10745
10840
|
// src/types/calendar/synced-calendar.types.ts
|
|
10746
10841
|
var SyncedCalendarProvider = /* @__PURE__ */ ((SyncedCalendarProvider3) => {
|
|
@@ -10764,42 +10859,42 @@ import {
|
|
|
10764
10859
|
} from "firebase/firestore";
|
|
10765
10860
|
|
|
10766
10861
|
// src/validations/calendar.schema.ts
|
|
10767
|
-
import { z as
|
|
10862
|
+
import { z as z25 } from "zod";
|
|
10768
10863
|
import { Timestamp as Timestamp21 } from "firebase/firestore";
|
|
10769
10864
|
|
|
10770
10865
|
// src/validations/profile-info.schema.ts
|
|
10771
|
-
import { z as
|
|
10866
|
+
import { z as z24 } from "zod";
|
|
10772
10867
|
import { Timestamp as Timestamp20 } from "firebase/firestore";
|
|
10773
|
-
var clinicInfoSchema2 =
|
|
10774
|
-
id:
|
|
10775
|
-
featuredPhoto:
|
|
10776
|
-
name:
|
|
10777
|
-
description:
|
|
10868
|
+
var clinicInfoSchema2 = z24.object({
|
|
10869
|
+
id: z24.string(),
|
|
10870
|
+
featuredPhoto: z24.string(),
|
|
10871
|
+
name: z24.string(),
|
|
10872
|
+
description: z24.string(),
|
|
10778
10873
|
location: clinicLocationSchema,
|
|
10779
10874
|
contactInfo: clinicContactInfoSchema
|
|
10780
10875
|
});
|
|
10781
|
-
var practitionerProfileInfoSchema =
|
|
10782
|
-
id:
|
|
10783
|
-
practitionerPhoto:
|
|
10784
|
-
name:
|
|
10785
|
-
email:
|
|
10786
|
-
phone:
|
|
10876
|
+
var practitionerProfileInfoSchema = z24.object({
|
|
10877
|
+
id: z24.string(),
|
|
10878
|
+
practitionerPhoto: z24.string().nullable(),
|
|
10879
|
+
name: z24.string(),
|
|
10880
|
+
email: z24.string().email(),
|
|
10881
|
+
phone: z24.string().nullable(),
|
|
10787
10882
|
certification: practitionerCertificationSchema
|
|
10788
10883
|
});
|
|
10789
|
-
var patientProfileInfoSchema =
|
|
10790
|
-
id:
|
|
10791
|
-
fullName:
|
|
10792
|
-
email:
|
|
10793
|
-
phone:
|
|
10794
|
-
dateOfBirth:
|
|
10795
|
-
gender:
|
|
10884
|
+
var patientProfileInfoSchema = z24.object({
|
|
10885
|
+
id: z24.string(),
|
|
10886
|
+
fullName: z24.string(),
|
|
10887
|
+
email: z24.string().email(),
|
|
10888
|
+
phone: z24.string().nullable(),
|
|
10889
|
+
dateOfBirth: z24.instanceof(Timestamp20),
|
|
10890
|
+
gender: z24.nativeEnum(Gender)
|
|
10796
10891
|
});
|
|
10797
10892
|
|
|
10798
10893
|
// src/validations/calendar.schema.ts
|
|
10799
10894
|
var MIN_APPOINTMENT_DURATION = 15;
|
|
10800
|
-
var calendarEventTimeSchema =
|
|
10801
|
-
start:
|
|
10802
|
-
end:
|
|
10895
|
+
var calendarEventTimeSchema = z25.object({
|
|
10896
|
+
start: z25.instanceof(Date).or(z25.instanceof(Timestamp21)),
|
|
10897
|
+
end: z25.instanceof(Date).or(z25.instanceof(Timestamp21))
|
|
10803
10898
|
}).refine(
|
|
10804
10899
|
(data) => {
|
|
10805
10900
|
const startDate = data.start instanceof Timestamp21 ? data.start.toDate() : data.start;
|
|
@@ -10820,46 +10915,46 @@ var calendarEventTimeSchema = z23.object({
|
|
|
10820
10915
|
path: ["start"]
|
|
10821
10916
|
}
|
|
10822
10917
|
);
|
|
10823
|
-
var timeSlotSchema2 =
|
|
10824
|
-
start:
|
|
10825
|
-
end:
|
|
10826
|
-
isAvailable:
|
|
10918
|
+
var timeSlotSchema2 = z25.object({
|
|
10919
|
+
start: z25.date(),
|
|
10920
|
+
end: z25.date(),
|
|
10921
|
+
isAvailable: z25.boolean()
|
|
10827
10922
|
}).refine((data) => data.start < data.end, {
|
|
10828
10923
|
message: "End time must be after start time",
|
|
10829
10924
|
path: ["end"]
|
|
10830
10925
|
});
|
|
10831
|
-
var syncedCalendarEventSchema =
|
|
10832
|
-
eventId:
|
|
10833
|
-
syncedCalendarProvider:
|
|
10834
|
-
syncedAt:
|
|
10926
|
+
var syncedCalendarEventSchema = z25.object({
|
|
10927
|
+
eventId: z25.string(),
|
|
10928
|
+
syncedCalendarProvider: z25.nativeEnum(SyncedCalendarProvider),
|
|
10929
|
+
syncedAt: z25.instanceof(Date).or(z25.instanceof(Timestamp21))
|
|
10835
10930
|
});
|
|
10836
|
-
var procedureInfoSchema =
|
|
10837
|
-
name:
|
|
10838
|
-
description:
|
|
10839
|
-
duration:
|
|
10840
|
-
price:
|
|
10841
|
-
currency:
|
|
10931
|
+
var procedureInfoSchema = z25.object({
|
|
10932
|
+
name: z25.string(),
|
|
10933
|
+
description: z25.string(),
|
|
10934
|
+
duration: z25.number().min(MIN_APPOINTMENT_DURATION),
|
|
10935
|
+
price: z25.number().min(0),
|
|
10936
|
+
currency: z25.nativeEnum(Currency)
|
|
10842
10937
|
});
|
|
10843
|
-
var procedureCategorizationSchema =
|
|
10844
|
-
procedureFamily:
|
|
10938
|
+
var procedureCategorizationSchema = z25.object({
|
|
10939
|
+
procedureFamily: z25.string(),
|
|
10845
10940
|
// Replace with proper enum when available
|
|
10846
|
-
procedureCategory:
|
|
10941
|
+
procedureCategory: z25.string(),
|
|
10847
10942
|
// Replace with proper enum when available
|
|
10848
|
-
procedureSubcategory:
|
|
10943
|
+
procedureSubcategory: z25.string(),
|
|
10849
10944
|
// Replace with proper enum when available
|
|
10850
|
-
procedureTechnology:
|
|
10945
|
+
procedureTechnology: z25.string(),
|
|
10851
10946
|
// Replace with proper enum when available
|
|
10852
|
-
procedureProduct:
|
|
10947
|
+
procedureProduct: z25.string()
|
|
10853
10948
|
// Replace with proper enum when available
|
|
10854
10949
|
});
|
|
10855
|
-
var createAppointmentSchema2 =
|
|
10856
|
-
clinicId:
|
|
10857
|
-
doctorId:
|
|
10858
|
-
patientId:
|
|
10859
|
-
procedureId:
|
|
10950
|
+
var createAppointmentSchema2 = z25.object({
|
|
10951
|
+
clinicId: z25.string().min(1, "Clinic ID is required"),
|
|
10952
|
+
doctorId: z25.string().min(1, "Doctor ID is required"),
|
|
10953
|
+
patientId: z25.string().min(1, "Patient ID is required"),
|
|
10954
|
+
procedureId: z25.string().min(1, "Procedure ID is required"),
|
|
10860
10955
|
eventLocation: clinicLocationSchema,
|
|
10861
10956
|
eventTime: calendarEventTimeSchema,
|
|
10862
|
-
description:
|
|
10957
|
+
description: z25.string().optional()
|
|
10863
10958
|
}).refine(
|
|
10864
10959
|
(data) => {
|
|
10865
10960
|
return true;
|
|
@@ -10868,95 +10963,95 @@ var createAppointmentSchema2 = z23.object({
|
|
|
10868
10963
|
message: "Invalid appointment parameters"
|
|
10869
10964
|
}
|
|
10870
10965
|
);
|
|
10871
|
-
var updateAppointmentSchema2 =
|
|
10872
|
-
appointmentId:
|
|
10873
|
-
clinicId:
|
|
10874
|
-
doctorId:
|
|
10875
|
-
patientId:
|
|
10966
|
+
var updateAppointmentSchema2 = z25.object({
|
|
10967
|
+
appointmentId: z25.string().min(1, "Appointment ID is required"),
|
|
10968
|
+
clinicId: z25.string().min(1, "Clinic ID is required"),
|
|
10969
|
+
doctorId: z25.string().min(1, "Doctor ID is required"),
|
|
10970
|
+
patientId: z25.string().min(1, "Patient ID is required"),
|
|
10876
10971
|
eventTime: calendarEventTimeSchema.optional(),
|
|
10877
|
-
description:
|
|
10878
|
-
status:
|
|
10972
|
+
description: z25.string().optional(),
|
|
10973
|
+
status: z25.nativeEnum(CalendarEventStatus).optional()
|
|
10879
10974
|
});
|
|
10880
|
-
var createCalendarEventSchema =
|
|
10881
|
-
id:
|
|
10882
|
-
clinicBranchId:
|
|
10883
|
-
clinicBranchInfo:
|
|
10884
|
-
practitionerProfileId:
|
|
10975
|
+
var createCalendarEventSchema = z25.object({
|
|
10976
|
+
id: z25.string(),
|
|
10977
|
+
clinicBranchId: z25.string().nullable().optional(),
|
|
10978
|
+
clinicBranchInfo: z25.any().nullable().optional(),
|
|
10979
|
+
practitionerProfileId: z25.string().nullable().optional(),
|
|
10885
10980
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
10886
|
-
patientProfileId:
|
|
10981
|
+
patientProfileId: z25.string().nullable().optional(),
|
|
10887
10982
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
10888
|
-
procedureId:
|
|
10889
|
-
appointmentId:
|
|
10890
|
-
syncedCalendarEventId:
|
|
10891
|
-
eventName:
|
|
10983
|
+
procedureId: z25.string().nullable().optional(),
|
|
10984
|
+
appointmentId: z25.string().nullable().optional(),
|
|
10985
|
+
syncedCalendarEventId: z25.array(syncedCalendarEventSchema).nullable().optional(),
|
|
10986
|
+
eventName: z25.string().min(1, "Event name is required"),
|
|
10892
10987
|
eventLocation: clinicLocationSchema.optional(),
|
|
10893
10988
|
eventTime: calendarEventTimeSchema,
|
|
10894
|
-
description:
|
|
10895
|
-
status:
|
|
10896
|
-
syncStatus:
|
|
10897
|
-
eventType:
|
|
10898
|
-
createdAt:
|
|
10989
|
+
description: z25.string().optional(),
|
|
10990
|
+
status: z25.nativeEnum(CalendarEventStatus),
|
|
10991
|
+
syncStatus: z25.nativeEnum(CalendarSyncStatus),
|
|
10992
|
+
eventType: z25.nativeEnum(CalendarEventType),
|
|
10993
|
+
createdAt: z25.any(),
|
|
10899
10994
|
// FieldValue for server timestamp
|
|
10900
|
-
updatedAt:
|
|
10995
|
+
updatedAt: z25.any()
|
|
10901
10996
|
// FieldValue for server timestamp
|
|
10902
10997
|
});
|
|
10903
|
-
var updateCalendarEventSchema =
|
|
10904
|
-
syncedCalendarEventId:
|
|
10905
|
-
appointmentId:
|
|
10906
|
-
eventName:
|
|
10998
|
+
var updateCalendarEventSchema = z25.object({
|
|
10999
|
+
syncedCalendarEventId: z25.array(syncedCalendarEventSchema).nullable().optional(),
|
|
11000
|
+
appointmentId: z25.string().nullable().optional(),
|
|
11001
|
+
eventName: z25.string().optional(),
|
|
10907
11002
|
eventTime: calendarEventTimeSchema.optional(),
|
|
10908
|
-
description:
|
|
10909
|
-
status:
|
|
10910
|
-
syncStatus:
|
|
10911
|
-
eventType:
|
|
10912
|
-
updatedAt:
|
|
11003
|
+
description: z25.string().optional(),
|
|
11004
|
+
status: z25.nativeEnum(CalendarEventStatus).optional(),
|
|
11005
|
+
syncStatus: z25.nativeEnum(CalendarSyncStatus).optional(),
|
|
11006
|
+
eventType: z25.nativeEnum(CalendarEventType).optional(),
|
|
11007
|
+
updatedAt: z25.any()
|
|
10913
11008
|
// FieldValue for server timestamp
|
|
10914
11009
|
});
|
|
10915
|
-
var calendarEventSchema =
|
|
10916
|
-
id:
|
|
10917
|
-
clinicBranchId:
|
|
10918
|
-
clinicBranchInfo:
|
|
11010
|
+
var calendarEventSchema = z25.object({
|
|
11011
|
+
id: z25.string(),
|
|
11012
|
+
clinicBranchId: z25.string().nullable().optional(),
|
|
11013
|
+
clinicBranchInfo: z25.any().nullable().optional(),
|
|
10919
11014
|
// Will be replaced with proper clinic info schema
|
|
10920
|
-
practitionerProfileId:
|
|
11015
|
+
practitionerProfileId: z25.string().nullable().optional(),
|
|
10921
11016
|
practitionerProfileInfo: practitionerProfileInfoSchema.nullable().optional(),
|
|
10922
|
-
patientProfileId:
|
|
11017
|
+
patientProfileId: z25.string().nullable().optional(),
|
|
10923
11018
|
patientProfileInfo: patientProfileInfoSchema.nullable().optional(),
|
|
10924
|
-
procedureId:
|
|
11019
|
+
procedureId: z25.string().nullable().optional(),
|
|
10925
11020
|
procedureInfo: procedureInfoSchema.nullable().optional(),
|
|
10926
11021
|
procedureCategorization: procedureCategorizationSchema.nullable().optional(),
|
|
10927
|
-
appointmentId:
|
|
10928
|
-
syncedCalendarEventId:
|
|
10929
|
-
eventName:
|
|
11022
|
+
appointmentId: z25.string().nullable().optional(),
|
|
11023
|
+
syncedCalendarEventId: z25.array(syncedCalendarEventSchema).nullable().optional(),
|
|
11024
|
+
eventName: z25.string(),
|
|
10930
11025
|
eventLocation: clinicLocationSchema.optional(),
|
|
10931
11026
|
eventTime: calendarEventTimeSchema,
|
|
10932
|
-
description:
|
|
10933
|
-
status:
|
|
10934
|
-
syncStatus:
|
|
10935
|
-
eventType:
|
|
10936
|
-
createdAt:
|
|
10937
|
-
updatedAt:
|
|
11027
|
+
description: z25.string().optional(),
|
|
11028
|
+
status: z25.nativeEnum(CalendarEventStatus),
|
|
11029
|
+
syncStatus: z25.nativeEnum(CalendarSyncStatus),
|
|
11030
|
+
eventType: z25.nativeEnum(CalendarEventType),
|
|
11031
|
+
createdAt: z25.instanceof(Date).or(z25.instanceof(Timestamp21)),
|
|
11032
|
+
updatedAt: z25.instanceof(Date).or(z25.instanceof(Timestamp21))
|
|
10938
11033
|
});
|
|
10939
|
-
var createBlockingEventSchema =
|
|
10940
|
-
entityType:
|
|
10941
|
-
entityId:
|
|
10942
|
-
eventName:
|
|
11034
|
+
var createBlockingEventSchema = z25.object({
|
|
11035
|
+
entityType: z25.enum(["practitioner", "clinic"]),
|
|
11036
|
+
entityId: z25.string().min(1, "Entity ID is required"),
|
|
11037
|
+
eventName: z25.string().min(1, "Event name is required").max(200, "Event name too long"),
|
|
10943
11038
|
eventTime: calendarEventTimeSchema,
|
|
10944
|
-
eventType:
|
|
11039
|
+
eventType: z25.enum([
|
|
10945
11040
|
"blocking" /* BLOCKING */,
|
|
10946
11041
|
"break" /* BREAK */,
|
|
10947
11042
|
"free_day" /* FREE_DAY */,
|
|
10948
11043
|
"other" /* OTHER */
|
|
10949
11044
|
]),
|
|
10950
|
-
description:
|
|
11045
|
+
description: z25.string().max(1e3, "Description too long").optional()
|
|
10951
11046
|
});
|
|
10952
|
-
var updateBlockingEventSchema =
|
|
10953
|
-
entityType:
|
|
10954
|
-
entityId:
|
|
10955
|
-
eventId:
|
|
10956
|
-
eventName:
|
|
11047
|
+
var updateBlockingEventSchema = z25.object({
|
|
11048
|
+
entityType: z25.enum(["practitioner", "clinic"]),
|
|
11049
|
+
entityId: z25.string().min(1, "Entity ID is required"),
|
|
11050
|
+
eventId: z25.string().min(1, "Event ID is required"),
|
|
11051
|
+
eventName: z25.string().min(1, "Event name is required").max(200, "Event name too long").optional(),
|
|
10957
11052
|
eventTime: calendarEventTimeSchema.optional(),
|
|
10958
|
-
description:
|
|
10959
|
-
status:
|
|
11053
|
+
description: z25.string().max(1e3, "Description too long").optional(),
|
|
11054
|
+
status: z25.nativeEnum(CalendarEventStatus).optional()
|
|
10960
11055
|
});
|
|
10961
11056
|
|
|
10962
11057
|
// src/services/calendar/utils/clinic.utils.ts
|
|
@@ -10967,12 +11062,12 @@ import {
|
|
|
10967
11062
|
getDocs as getDocs20,
|
|
10968
11063
|
setDoc as setDoc18,
|
|
10969
11064
|
updateDoc as updateDoc20,
|
|
10970
|
-
deleteDoc as
|
|
11065
|
+
deleteDoc as deleteDoc13,
|
|
10971
11066
|
query as query20,
|
|
10972
11067
|
where as where20,
|
|
10973
|
-
orderBy as
|
|
11068
|
+
orderBy as orderBy10,
|
|
10974
11069
|
Timestamp as Timestamp22,
|
|
10975
|
-
serverTimestamp as
|
|
11070
|
+
serverTimestamp as serverTimestamp16
|
|
10976
11071
|
} from "firebase/firestore";
|
|
10977
11072
|
|
|
10978
11073
|
// src/services/calendar/utils/docs.utils.ts
|
|
@@ -11021,8 +11116,8 @@ async function createClinicCalendarEventUtil(db, clinicId, eventData, generateId
|
|
|
11021
11116
|
const newEvent = {
|
|
11022
11117
|
id: eventId,
|
|
11023
11118
|
...eventData,
|
|
11024
|
-
createdAt:
|
|
11025
|
-
updatedAt:
|
|
11119
|
+
createdAt: serverTimestamp16(),
|
|
11120
|
+
updatedAt: serverTimestamp16()
|
|
11026
11121
|
};
|
|
11027
11122
|
await setDoc18(eventRef, newEvent);
|
|
11028
11123
|
return {
|
|
@@ -11035,7 +11130,7 @@ async function updateClinicCalendarEventUtil(db, clinicId, eventId, updateData)
|
|
|
11035
11130
|
const eventRef = getClinicCalendarEventDocRef(db, clinicId, eventId);
|
|
11036
11131
|
const updates = {
|
|
11037
11132
|
...updateData,
|
|
11038
|
-
updatedAt:
|
|
11133
|
+
updatedAt: serverTimestamp16()
|
|
11039
11134
|
};
|
|
11040
11135
|
await updateDoc20(eventRef, updates);
|
|
11041
11136
|
const updatedDoc = await getDoc23(eventRef);
|
|
@@ -11071,12 +11166,12 @@ import {
|
|
|
11071
11166
|
getDocs as getDocs21,
|
|
11072
11167
|
setDoc as setDoc19,
|
|
11073
11168
|
updateDoc as updateDoc21,
|
|
11074
|
-
deleteDoc as
|
|
11169
|
+
deleteDoc as deleteDoc14,
|
|
11075
11170
|
query as query21,
|
|
11076
11171
|
where as where21,
|
|
11077
|
-
orderBy as
|
|
11172
|
+
orderBy as orderBy11,
|
|
11078
11173
|
Timestamp as Timestamp23,
|
|
11079
|
-
serverTimestamp as
|
|
11174
|
+
serverTimestamp as serverTimestamp17
|
|
11080
11175
|
} from "firebase/firestore";
|
|
11081
11176
|
async function createPatientCalendarEventUtil(db, patientId, eventData, generateId2) {
|
|
11082
11177
|
const eventId = generateId2();
|
|
@@ -11084,8 +11179,8 @@ async function createPatientCalendarEventUtil(db, patientId, eventData, generate
|
|
|
11084
11179
|
const newEvent = {
|
|
11085
11180
|
id: eventId,
|
|
11086
11181
|
...eventData,
|
|
11087
|
-
createdAt:
|
|
11088
|
-
updatedAt:
|
|
11182
|
+
createdAt: serverTimestamp17(),
|
|
11183
|
+
updatedAt: serverTimestamp17()
|
|
11089
11184
|
};
|
|
11090
11185
|
await setDoc19(eventRef, newEvent);
|
|
11091
11186
|
return {
|
|
@@ -11098,7 +11193,7 @@ async function updatePatientCalendarEventUtil(db, patientId, eventId, updateData
|
|
|
11098
11193
|
const eventRef = getPatientCalendarEventDocRef(db, patientId, eventId);
|
|
11099
11194
|
const updates = {
|
|
11100
11195
|
...updateData,
|
|
11101
|
-
updatedAt:
|
|
11196
|
+
updatedAt: serverTimestamp17()
|
|
11102
11197
|
};
|
|
11103
11198
|
await updateDoc21(eventRef, updates);
|
|
11104
11199
|
const updatedDoc = await getDoc24(eventRef);
|
|
@@ -11115,12 +11210,12 @@ import {
|
|
|
11115
11210
|
getDocs as getDocs22,
|
|
11116
11211
|
setDoc as setDoc20,
|
|
11117
11212
|
updateDoc as updateDoc22,
|
|
11118
|
-
deleteDoc as
|
|
11213
|
+
deleteDoc as deleteDoc15,
|
|
11119
11214
|
query as query22,
|
|
11120
11215
|
where as where22,
|
|
11121
|
-
orderBy as
|
|
11216
|
+
orderBy as orderBy12,
|
|
11122
11217
|
Timestamp as Timestamp24,
|
|
11123
|
-
serverTimestamp as
|
|
11218
|
+
serverTimestamp as serverTimestamp18
|
|
11124
11219
|
} from "firebase/firestore";
|
|
11125
11220
|
async function createPractitionerCalendarEventUtil(db, practitionerId, eventData, generateId2) {
|
|
11126
11221
|
const eventId = generateId2();
|
|
@@ -11132,8 +11227,8 @@ async function createPractitionerCalendarEventUtil(db, practitionerId, eventData
|
|
|
11132
11227
|
const newEvent = {
|
|
11133
11228
|
id: eventId,
|
|
11134
11229
|
...eventData,
|
|
11135
|
-
createdAt:
|
|
11136
|
-
updatedAt:
|
|
11230
|
+
createdAt: serverTimestamp18(),
|
|
11231
|
+
updatedAt: serverTimestamp18()
|
|
11137
11232
|
};
|
|
11138
11233
|
await setDoc20(eventRef, newEvent);
|
|
11139
11234
|
return {
|
|
@@ -11150,7 +11245,7 @@ async function updatePractitionerCalendarEventUtil(db, practitionerId, eventId,
|
|
|
11150
11245
|
);
|
|
11151
11246
|
const updates = {
|
|
11152
11247
|
...updateData,
|
|
11153
|
-
updatedAt:
|
|
11248
|
+
updatedAt: serverTimestamp18()
|
|
11154
11249
|
};
|
|
11155
11250
|
await updateDoc22(eventRef, updates);
|
|
11156
11251
|
const updatedDoc = await getDoc25(eventRef);
|
|
@@ -11218,12 +11313,12 @@ import {
|
|
|
11218
11313
|
getDocs as getDocs23,
|
|
11219
11314
|
setDoc as setDoc21,
|
|
11220
11315
|
updateDoc as updateDoc23,
|
|
11221
|
-
deleteDoc as
|
|
11316
|
+
deleteDoc as deleteDoc16,
|
|
11222
11317
|
query as query23,
|
|
11223
11318
|
where as where23,
|
|
11224
|
-
orderBy as
|
|
11319
|
+
orderBy as orderBy13,
|
|
11225
11320
|
Timestamp as Timestamp25,
|
|
11226
|
-
serverTimestamp as
|
|
11321
|
+
serverTimestamp as serverTimestamp19
|
|
11227
11322
|
} from "firebase/firestore";
|
|
11228
11323
|
async function searchCalendarEventsUtil(db, params) {
|
|
11229
11324
|
const { searchLocation, entityId, ...filters } = params;
|
|
@@ -11324,11 +11419,11 @@ import {
|
|
|
11324
11419
|
getDocs as getDocs24,
|
|
11325
11420
|
setDoc as setDoc22,
|
|
11326
11421
|
updateDoc as updateDoc24,
|
|
11327
|
-
deleteDoc as
|
|
11422
|
+
deleteDoc as deleteDoc17,
|
|
11328
11423
|
query as query24,
|
|
11329
|
-
orderBy as
|
|
11424
|
+
orderBy as orderBy14,
|
|
11330
11425
|
Timestamp as Timestamp26,
|
|
11331
|
-
serverTimestamp as
|
|
11426
|
+
serverTimestamp as serverTimestamp20
|
|
11332
11427
|
} from "firebase/firestore";
|
|
11333
11428
|
async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendarData, generateId2) {
|
|
11334
11429
|
const calendarId = generateId2();
|
|
@@ -11340,8 +11435,8 @@ async function createPractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
11340
11435
|
const newCalendar = {
|
|
11341
11436
|
id: calendarId,
|
|
11342
11437
|
...calendarData,
|
|
11343
|
-
createdAt:
|
|
11344
|
-
updatedAt:
|
|
11438
|
+
createdAt: serverTimestamp20(),
|
|
11439
|
+
updatedAt: serverTimestamp20()
|
|
11345
11440
|
};
|
|
11346
11441
|
await setDoc22(calendarRef, newCalendar);
|
|
11347
11442
|
return {
|
|
@@ -11356,8 +11451,8 @@ async function createPatientSyncedCalendarUtil(db, patientId, calendarData, gene
|
|
|
11356
11451
|
const newCalendar = {
|
|
11357
11452
|
id: calendarId,
|
|
11358
11453
|
...calendarData,
|
|
11359
|
-
createdAt:
|
|
11360
|
-
updatedAt:
|
|
11454
|
+
createdAt: serverTimestamp20(),
|
|
11455
|
+
updatedAt: serverTimestamp20()
|
|
11361
11456
|
};
|
|
11362
11457
|
await setDoc22(calendarRef, newCalendar);
|
|
11363
11458
|
return {
|
|
@@ -11372,8 +11467,8 @@ async function createClinicSyncedCalendarUtil(db, clinicId, calendarData, genera
|
|
|
11372
11467
|
const newCalendar = {
|
|
11373
11468
|
id: calendarId,
|
|
11374
11469
|
...calendarData,
|
|
11375
|
-
createdAt:
|
|
11376
|
-
updatedAt:
|
|
11470
|
+
createdAt: serverTimestamp20(),
|
|
11471
|
+
updatedAt: serverTimestamp20()
|
|
11377
11472
|
};
|
|
11378
11473
|
await setDoc22(calendarRef, newCalendar);
|
|
11379
11474
|
return {
|
|
@@ -11399,7 +11494,7 @@ async function getPractitionerSyncedCalendarsUtil(db, practitionerId) {
|
|
|
11399
11494
|
db,
|
|
11400
11495
|
`practitioners/${practitionerId}/${SYNCED_CALENDARS_COLLECTION}`
|
|
11401
11496
|
);
|
|
11402
|
-
const q = query24(calendarsRef,
|
|
11497
|
+
const q = query24(calendarsRef, orderBy14("createdAt", "desc"));
|
|
11403
11498
|
const querySnapshot = await getDocs24(q);
|
|
11404
11499
|
return querySnapshot.docs.map((doc36) => doc36.data());
|
|
11405
11500
|
}
|
|
@@ -11416,7 +11511,7 @@ async function getPatientSyncedCalendarsUtil(db, patientId) {
|
|
|
11416
11511
|
db,
|
|
11417
11512
|
`patients/${patientId}/${SYNCED_CALENDARS_COLLECTION}`
|
|
11418
11513
|
);
|
|
11419
|
-
const q = query24(calendarsRef,
|
|
11514
|
+
const q = query24(calendarsRef, orderBy14("createdAt", "desc"));
|
|
11420
11515
|
const querySnapshot = await getDocs24(q);
|
|
11421
11516
|
return querySnapshot.docs.map((doc36) => doc36.data());
|
|
11422
11517
|
}
|
|
@@ -11433,7 +11528,7 @@ async function getClinicSyncedCalendarsUtil(db, clinicId) {
|
|
|
11433
11528
|
db,
|
|
11434
11529
|
`clinics/${clinicId}/${SYNCED_CALENDARS_COLLECTION}`
|
|
11435
11530
|
);
|
|
11436
|
-
const q = query24(calendarsRef,
|
|
11531
|
+
const q = query24(calendarsRef, orderBy14("createdAt", "desc"));
|
|
11437
11532
|
const querySnapshot = await getDocs24(q);
|
|
11438
11533
|
return querySnapshot.docs.map((doc36) => doc36.data());
|
|
11439
11534
|
}
|
|
@@ -11445,7 +11540,7 @@ async function updatePractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
11445
11540
|
);
|
|
11446
11541
|
const updates = {
|
|
11447
11542
|
...updateData,
|
|
11448
|
-
updatedAt:
|
|
11543
|
+
updatedAt: serverTimestamp20()
|
|
11449
11544
|
};
|
|
11450
11545
|
await updateDoc24(calendarRef, updates);
|
|
11451
11546
|
const updatedDoc = await getDoc27(calendarRef);
|
|
@@ -11458,7 +11553,7 @@ async function updatePatientSyncedCalendarUtil(db, patientId, calendarId, update
|
|
|
11458
11553
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
11459
11554
|
const updates = {
|
|
11460
11555
|
...updateData,
|
|
11461
|
-
updatedAt:
|
|
11556
|
+
updatedAt: serverTimestamp20()
|
|
11462
11557
|
};
|
|
11463
11558
|
await updateDoc24(calendarRef, updates);
|
|
11464
11559
|
const updatedDoc = await getDoc27(calendarRef);
|
|
@@ -11471,7 +11566,7 @@ async function updateClinicSyncedCalendarUtil(db, clinicId, calendarId, updateDa
|
|
|
11471
11566
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
11472
11567
|
const updates = {
|
|
11473
11568
|
...updateData,
|
|
11474
|
-
updatedAt:
|
|
11569
|
+
updatedAt: serverTimestamp20()
|
|
11475
11570
|
};
|
|
11476
11571
|
await updateDoc24(calendarRef, updates);
|
|
11477
11572
|
const updatedDoc = await getDoc27(calendarRef);
|
|
@@ -11486,15 +11581,15 @@ async function deletePractitionerSyncedCalendarUtil(db, practitionerId, calendar
|
|
|
11486
11581
|
practitionerId,
|
|
11487
11582
|
calendarId
|
|
11488
11583
|
);
|
|
11489
|
-
await
|
|
11584
|
+
await deleteDoc17(calendarRef);
|
|
11490
11585
|
}
|
|
11491
11586
|
async function deletePatientSyncedCalendarUtil(db, patientId, calendarId) {
|
|
11492
11587
|
const calendarRef = getPatientSyncedCalendarDocRef(db, patientId, calendarId);
|
|
11493
|
-
await
|
|
11588
|
+
await deleteDoc17(calendarRef);
|
|
11494
11589
|
}
|
|
11495
11590
|
async function deleteClinicSyncedCalendarUtil(db, clinicId, calendarId) {
|
|
11496
11591
|
const calendarRef = getClinicSyncedCalendarDocRef(db, clinicId, calendarId);
|
|
11497
|
-
await
|
|
11592
|
+
await deleteDoc17(calendarRef);
|
|
11498
11593
|
}
|
|
11499
11594
|
async function updateLastSyncedTimestampUtil(db, entityType, entityId, calendarId) {
|
|
11500
11595
|
const updateData = {
|
|
@@ -12693,8 +12788,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12693
12788
|
const newEvent = {
|
|
12694
12789
|
id: eventId,
|
|
12695
12790
|
...eventData,
|
|
12696
|
-
createdAt:
|
|
12697
|
-
updatedAt:
|
|
12791
|
+
createdAt: serverTimestamp21(),
|
|
12792
|
+
updatedAt: serverTimestamp21()
|
|
12698
12793
|
};
|
|
12699
12794
|
await setDoc23(eventRef, newEvent);
|
|
12700
12795
|
return {
|
|
@@ -12910,7 +13005,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12910
13005
|
end: Timestamp28.fromDate(endTime)
|
|
12911
13006
|
},
|
|
12912
13007
|
description: externalEvent.description || "",
|
|
12913
|
-
updatedAt:
|
|
13008
|
+
updatedAt: serverTimestamp21()
|
|
12914
13009
|
});
|
|
12915
13010
|
console.log(`Updated local event ${eventId} from external event`);
|
|
12916
13011
|
} catch (error) {
|
|
@@ -12937,7 +13032,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
12937
13032
|
);
|
|
12938
13033
|
await updateDoc25(eventRef, {
|
|
12939
13034
|
status,
|
|
12940
|
-
updatedAt:
|
|
13035
|
+
updatedAt: serverTimestamp21()
|
|
12941
13036
|
});
|
|
12942
13037
|
console.log(`Updated event ${eventId} status to ${status}`);
|
|
12943
13038
|
} catch (error) {
|
|
@@ -13328,7 +13423,7 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
13328
13423
|
}
|
|
13329
13424
|
await updateDoc25(eventRef, {
|
|
13330
13425
|
syncedCalendarEventId: syncIds,
|
|
13331
|
-
updatedAt:
|
|
13426
|
+
updatedAt: serverTimestamp21()
|
|
13332
13427
|
});
|
|
13333
13428
|
console.log(
|
|
13334
13429
|
`Updated event ${eventId} with sync ID ${syncEvent.eventId}`
|
|
@@ -13551,8 +13646,8 @@ var CalendarServiceV2 = class extends BaseService {
|
|
|
13551
13646
|
};
|
|
13552
13647
|
|
|
13553
13648
|
// src/services/calendar/calendar.v3.service.ts
|
|
13554
|
-
import { Timestamp as Timestamp29, serverTimestamp as
|
|
13555
|
-
import { doc as doc27, getDoc as getDoc29, setDoc as setDoc24, updateDoc as updateDoc26, deleteDoc as
|
|
13649
|
+
import { Timestamp as Timestamp29, serverTimestamp as serverTimestamp22 } from "firebase/firestore";
|
|
13650
|
+
import { doc as doc27, getDoc as getDoc29, setDoc as setDoc24, updateDoc as updateDoc26, deleteDoc as deleteDoc18 } from "firebase/firestore";
|
|
13556
13651
|
var CalendarServiceV3 = class extends BaseService {
|
|
13557
13652
|
/**
|
|
13558
13653
|
* Creates a new CalendarServiceV3 instance
|
|
@@ -13586,8 +13681,8 @@ var CalendarServiceV3 = class extends BaseService {
|
|
|
13586
13681
|
status: "confirmed" /* CONFIRMED */,
|
|
13587
13682
|
// Blocking events are always confirmed
|
|
13588
13683
|
syncStatus: "internal" /* INTERNAL */,
|
|
13589
|
-
createdAt:
|
|
13590
|
-
updatedAt:
|
|
13684
|
+
createdAt: serverTimestamp22(),
|
|
13685
|
+
updatedAt: serverTimestamp22()
|
|
13591
13686
|
};
|
|
13592
13687
|
if (params.entityType === "practitioner") {
|
|
13593
13688
|
eventData.practitionerProfileId = params.entityId;
|
|
@@ -13617,7 +13712,7 @@ var CalendarServiceV3 = class extends BaseService {
|
|
|
13617
13712
|
throw new Error(`Blocking event with ID ${params.eventId} not found`);
|
|
13618
13713
|
}
|
|
13619
13714
|
const updateData = {
|
|
13620
|
-
updatedAt:
|
|
13715
|
+
updatedAt: serverTimestamp22()
|
|
13621
13716
|
};
|
|
13622
13717
|
if (params.eventName !== void 0) {
|
|
13623
13718
|
updateData.eventName = params.eventName;
|
|
@@ -13648,7 +13743,7 @@ var CalendarServiceV3 = class extends BaseService {
|
|
|
13648
13743
|
if (!eventDoc.exists()) {
|
|
13649
13744
|
throw new Error(`Blocking event with ID ${eventId} not found`);
|
|
13650
13745
|
}
|
|
13651
|
-
await
|
|
13746
|
+
await deleteDoc18(eventRef);
|
|
13652
13747
|
}
|
|
13653
13748
|
/**
|
|
13654
13749
|
* Gets a specific blocking event
|
|
@@ -13756,15 +13851,15 @@ import {
|
|
|
13756
13851
|
query as query26,
|
|
13757
13852
|
where as where26,
|
|
13758
13853
|
setDoc as setDoc25,
|
|
13759
|
-
deleteDoc as
|
|
13760
|
-
serverTimestamp as
|
|
13854
|
+
deleteDoc as deleteDoc19,
|
|
13855
|
+
serverTimestamp as serverTimestamp23
|
|
13761
13856
|
} from "firebase/firestore";
|
|
13762
13857
|
|
|
13763
13858
|
// src/types/reviews/index.ts
|
|
13764
13859
|
var REVIEWS_COLLECTION = "reviews";
|
|
13765
13860
|
|
|
13766
13861
|
// src/services/reviews/reviews.service.ts
|
|
13767
|
-
import { z as
|
|
13862
|
+
import { z as z26 } from "zod";
|
|
13768
13863
|
var ReviewService = class extends BaseService {
|
|
13769
13864
|
constructor(db, auth, app) {
|
|
13770
13865
|
super(db, auth, app);
|
|
@@ -13846,12 +13941,12 @@ var ReviewService = class extends BaseService {
|
|
|
13846
13941
|
const docRef = doc28(this.db, REVIEWS_COLLECTION, reviewId);
|
|
13847
13942
|
await setDoc25(docRef, {
|
|
13848
13943
|
...review,
|
|
13849
|
-
createdAt:
|
|
13850
|
-
updatedAt:
|
|
13944
|
+
createdAt: serverTimestamp23(),
|
|
13945
|
+
updatedAt: serverTimestamp23()
|
|
13851
13946
|
});
|
|
13852
13947
|
return review;
|
|
13853
13948
|
} catch (error) {
|
|
13854
|
-
if (error instanceof
|
|
13949
|
+
if (error instanceof z26.ZodError) {
|
|
13855
13950
|
throw new Error(`Invalid review data: ${error.message}`);
|
|
13856
13951
|
}
|
|
13857
13952
|
throw error;
|
|
@@ -13947,7 +14042,7 @@ var ReviewService = class extends BaseService {
|
|
|
13947
14042
|
if (!review) {
|
|
13948
14043
|
throw new Error(`Review with ID ${reviewId} not found`);
|
|
13949
14044
|
}
|
|
13950
|
-
await
|
|
14045
|
+
await deleteDoc19(doc28(this.db, REVIEWS_COLLECTION, reviewId));
|
|
13951
14046
|
}
|
|
13952
14047
|
/**
|
|
13953
14048
|
* Calculates the average of an array of numbers
|
|
@@ -13967,15 +14062,15 @@ var ReviewService = class extends BaseService {
|
|
|
13967
14062
|
// src/services/appointment/appointment.service.ts
|
|
13968
14063
|
import {
|
|
13969
14064
|
Timestamp as Timestamp31,
|
|
13970
|
-
serverTimestamp as
|
|
14065
|
+
serverTimestamp as serverTimestamp25,
|
|
13971
14066
|
arrayUnion as arrayUnion8,
|
|
13972
14067
|
arrayRemove as arrayRemove7,
|
|
13973
14068
|
where as where28,
|
|
13974
|
-
orderBy as
|
|
14069
|
+
orderBy as orderBy16,
|
|
13975
14070
|
collection as collection28,
|
|
13976
14071
|
query as query28,
|
|
13977
|
-
limit as
|
|
13978
|
-
startAfter as
|
|
14072
|
+
limit as limit14,
|
|
14073
|
+
startAfter as startAfter12,
|
|
13979
14074
|
getDocs as getDocs28
|
|
13980
14075
|
} from "firebase/firestore";
|
|
13981
14076
|
import { getFunctions as getFunctions2 } from "firebase/functions";
|
|
@@ -13990,11 +14085,11 @@ import {
|
|
|
13990
14085
|
where as where27,
|
|
13991
14086
|
setDoc as setDoc26,
|
|
13992
14087
|
updateDoc as updateDoc27,
|
|
13993
|
-
serverTimestamp as
|
|
14088
|
+
serverTimestamp as serverTimestamp24,
|
|
13994
14089
|
Timestamp as Timestamp30,
|
|
13995
|
-
orderBy as
|
|
13996
|
-
limit as
|
|
13997
|
-
startAfter as
|
|
14090
|
+
orderBy as orderBy15,
|
|
14091
|
+
limit as limit13,
|
|
14092
|
+
startAfter as startAfter11
|
|
13998
14093
|
} from "firebase/firestore";
|
|
13999
14094
|
|
|
14000
14095
|
// src/backoffice/types/technology.types.ts
|
|
@@ -14053,7 +14148,7 @@ async function updateAppointmentUtil2(db, appointmentId, data) {
|
|
|
14053
14148
|
...data,
|
|
14054
14149
|
completedPreRequirements,
|
|
14055
14150
|
completedPostRequirements,
|
|
14056
|
-
updatedAt:
|
|
14151
|
+
updatedAt: serverTimestamp24()
|
|
14057
14152
|
};
|
|
14058
14153
|
Object.keys(updateData).forEach((key) => {
|
|
14059
14154
|
if (updateData[key] === void 0) {
|
|
@@ -14113,7 +14208,7 @@ async function updateCalendarEventStatus(db, calendarEventId, appointmentStatus)
|
|
|
14113
14208
|
}
|
|
14114
14209
|
await updateDoc27(calendarEventRef, {
|
|
14115
14210
|
status: calendarStatus,
|
|
14116
|
-
updatedAt:
|
|
14211
|
+
updatedAt: serverTimestamp24()
|
|
14117
14212
|
});
|
|
14118
14213
|
} catch (error) {
|
|
14119
14214
|
console.error(`Error updating calendar event ${calendarEventId}:`, error);
|
|
@@ -14166,12 +14261,12 @@ async function searchAppointmentsUtil(db, params) {
|
|
|
14166
14261
|
constraints.push(where27("status", "==", params.status));
|
|
14167
14262
|
}
|
|
14168
14263
|
}
|
|
14169
|
-
constraints.push(
|
|
14264
|
+
constraints.push(orderBy15("appointmentStartTime", "asc"));
|
|
14170
14265
|
if (params.limit) {
|
|
14171
|
-
constraints.push(
|
|
14266
|
+
constraints.push(limit13(params.limit));
|
|
14172
14267
|
}
|
|
14173
14268
|
if (params.startAfter) {
|
|
14174
|
-
constraints.push(
|
|
14269
|
+
constraints.push(startAfter11(params.startAfter));
|
|
14175
14270
|
}
|
|
14176
14271
|
const q = query27(collection27(db, APPOINTMENTS_COLLECTION), ...constraints);
|
|
14177
14272
|
const querySnapshot = await getDocs27(q);
|
|
@@ -14545,7 +14640,7 @@ var AppointmentService = class extends BaseService {
|
|
|
14545
14640
|
);
|
|
14546
14641
|
const updateData = {
|
|
14547
14642
|
status: newStatus,
|
|
14548
|
-
updatedAt:
|
|
14643
|
+
updatedAt: serverTimestamp25()
|
|
14549
14644
|
};
|
|
14550
14645
|
if (newStatus === "canceled_clinic" /* CANCELED_CLINIC */ || newStatus === "canceled_patient" /* CANCELED_PATIENT */ || newStatus === "canceled_patient_rescheduled" /* CANCELED_PATIENT_RESCHEDULED */) {
|
|
14551
14646
|
if (!(details == null ? void 0 : details.cancellationReason)) {
|
|
@@ -14642,7 +14737,7 @@ var AppointmentService = class extends BaseService {
|
|
|
14642
14737
|
appointmentEndTime: endTimestamp,
|
|
14643
14738
|
rescheduleTime: Timestamp31.now(),
|
|
14644
14739
|
confirmationTime: null,
|
|
14645
|
-
updatedAt:
|
|
14740
|
+
updatedAt: serverTimestamp25()
|
|
14646
14741
|
};
|
|
14647
14742
|
return this.updateAppointment(validatedParams.appointmentId, updateData);
|
|
14648
14743
|
}
|
|
@@ -14773,7 +14868,7 @@ var AppointmentService = class extends BaseService {
|
|
|
14773
14868
|
status: "in_progress" /* IN_PROGRESS */,
|
|
14774
14869
|
procedureActualStartTime: Timestamp31.now(),
|
|
14775
14870
|
// Set actual start time
|
|
14776
|
-
updatedAt:
|
|
14871
|
+
updatedAt: serverTimestamp25()
|
|
14777
14872
|
};
|
|
14778
14873
|
return this.updateAppointment(appointmentId, updateData);
|
|
14779
14874
|
}
|
|
@@ -14814,7 +14909,7 @@ var AppointmentService = class extends BaseService {
|
|
|
14814
14909
|
},
|
|
14815
14910
|
// Optionally update appointmentEndTime to the actual completion time
|
|
14816
14911
|
// appointmentEndTime: procedureCompletionTime,
|
|
14817
|
-
updatedAt:
|
|
14912
|
+
updatedAt: serverTimestamp25()
|
|
14818
14913
|
};
|
|
14819
14914
|
return this.updateAppointment(appointmentId, updateData);
|
|
14820
14915
|
}
|
|
@@ -14857,7 +14952,7 @@ var AppointmentService = class extends BaseService {
|
|
|
14857
14952
|
};
|
|
14858
14953
|
const updateData = {
|
|
14859
14954
|
media: arrayUnion8(newMediaItem),
|
|
14860
|
-
updatedAt:
|
|
14955
|
+
updatedAt: serverTimestamp25()
|
|
14861
14956
|
};
|
|
14862
14957
|
return this.updateAppointment(appointmentId, updateData);
|
|
14863
14958
|
}
|
|
@@ -14878,7 +14973,7 @@ var AppointmentService = class extends BaseService {
|
|
|
14878
14973
|
}
|
|
14879
14974
|
const updateData = {
|
|
14880
14975
|
media: arrayRemove7(mediaToRemove),
|
|
14881
|
-
updatedAt:
|
|
14976
|
+
updatedAt: serverTimestamp25()
|
|
14882
14977
|
};
|
|
14883
14978
|
return this.updateAppointment(appointmentId, updateData);
|
|
14884
14979
|
}
|
|
@@ -14896,7 +14991,7 @@ var AppointmentService = class extends BaseService {
|
|
|
14896
14991
|
};
|
|
14897
14992
|
const updateData = {
|
|
14898
14993
|
reviewInfo: newReviewInfo,
|
|
14899
|
-
updatedAt:
|
|
14994
|
+
updatedAt: serverTimestamp25()
|
|
14900
14995
|
};
|
|
14901
14996
|
return this.updateAppointment(appointmentId, updateData);
|
|
14902
14997
|
}
|
|
@@ -14910,7 +15005,7 @@ var AppointmentService = class extends BaseService {
|
|
|
14910
15005
|
const updateData = {
|
|
14911
15006
|
paymentStatus,
|
|
14912
15007
|
paymentTransactionId: paymentTransactionId || null,
|
|
14913
|
-
updatedAt:
|
|
15008
|
+
updatedAt: serverTimestamp25()
|
|
14914
15009
|
};
|
|
14915
15010
|
return this.updateAppointment(appointmentId, updateData);
|
|
14916
15011
|
}
|
|
@@ -14970,12 +15065,12 @@ var AppointmentService = class extends BaseService {
|
|
|
14970
15065
|
)
|
|
14971
15066
|
);
|
|
14972
15067
|
}
|
|
14973
|
-
constraints.push(
|
|
15068
|
+
constraints.push(orderBy16("appointmentStartTime", "asc"));
|
|
14974
15069
|
if (options == null ? void 0 : options.limit) {
|
|
14975
|
-
constraints.push(
|
|
15070
|
+
constraints.push(limit14(options.limit));
|
|
14976
15071
|
}
|
|
14977
15072
|
if (options == null ? void 0 : options.startAfter) {
|
|
14978
|
-
constraints.push(
|
|
15073
|
+
constraints.push(startAfter12(options.startAfter));
|
|
14979
15074
|
}
|
|
14980
15075
|
const q = query28(
|
|
14981
15076
|
collection28(this.db, APPOINTMENTS_COLLECTION),
|
|
@@ -15043,12 +15138,12 @@ var AppointmentService = class extends BaseService {
|
|
|
15043
15138
|
Timestamp31.fromDate(effectiveEndDate)
|
|
15044
15139
|
)
|
|
15045
15140
|
);
|
|
15046
|
-
constraints.push(
|
|
15141
|
+
constraints.push(orderBy16("appointmentStartTime", "desc"));
|
|
15047
15142
|
if (options == null ? void 0 : options.limit) {
|
|
15048
|
-
constraints.push(
|
|
15143
|
+
constraints.push(limit14(options.limit));
|
|
15049
15144
|
}
|
|
15050
15145
|
if (options == null ? void 0 : options.startAfter) {
|
|
15051
|
-
constraints.push(
|
|
15146
|
+
constraints.push(startAfter12(options.startAfter));
|
|
15052
15147
|
}
|
|
15053
15148
|
const q = query28(
|
|
15054
15149
|
collection28(this.db, APPOINTMENTS_COLLECTION),
|
|
@@ -15082,9 +15177,9 @@ import {
|
|
|
15082
15177
|
doc as doc30,
|
|
15083
15178
|
updateDoc as updateDoc28,
|
|
15084
15179
|
Timestamp as Timestamp32,
|
|
15085
|
-
orderBy as
|
|
15086
|
-
limit as
|
|
15087
|
-
startAfter as
|
|
15180
|
+
orderBy as orderBy17,
|
|
15181
|
+
limit as limit15,
|
|
15182
|
+
startAfter as startAfter13,
|
|
15088
15183
|
getDoc as getDoc32
|
|
15089
15184
|
} from "firebase/firestore";
|
|
15090
15185
|
|
|
@@ -15154,7 +15249,7 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
15154
15249
|
*/
|
|
15155
15250
|
async getAllPatientRequirementInstances(patientId, filters, pageLimit = 20, lastVisible) {
|
|
15156
15251
|
const collRef = this.getPatientRequirementsCollectionRef(patientId);
|
|
15157
|
-
let q = query29(collRef,
|
|
15252
|
+
let q = query29(collRef, orderBy17("createdAt", "desc"));
|
|
15158
15253
|
const queryConstraints = [];
|
|
15159
15254
|
if ((filters == null ? void 0 : filters.appointmentId) && filters.appointmentId !== "all") {
|
|
15160
15255
|
queryConstraints.push(
|
|
@@ -15165,9 +15260,9 @@ var PatientRequirementsService = class extends BaseService {
|
|
|
15165
15260
|
queryConstraints.push(where29("overallStatus", "in", filters.statuses));
|
|
15166
15261
|
}
|
|
15167
15262
|
if (lastVisible) {
|
|
15168
|
-
queryConstraints.push(
|
|
15263
|
+
queryConstraints.push(startAfter13(lastVisible));
|
|
15169
15264
|
}
|
|
15170
|
-
queryConstraints.push(
|
|
15265
|
+
queryConstraints.push(limit15(pageLimit));
|
|
15171
15266
|
q = query29(collRef, ...queryConstraints);
|
|
15172
15267
|
const snapshot = await getDocs29(q);
|
|
15173
15268
|
let requirements = snapshot.docs.map((docSnap) => {
|
|
@@ -16137,63 +16232,63 @@ var ProductService = class extends BaseService {
|
|
|
16137
16232
|
};
|
|
16138
16233
|
|
|
16139
16234
|
// src/validations/notification.schema.ts
|
|
16140
|
-
import { z as
|
|
16141
|
-
var baseNotificationSchema =
|
|
16142
|
-
id:
|
|
16143
|
-
userId:
|
|
16144
|
-
notificationTime:
|
|
16235
|
+
import { z as z27 } from "zod";
|
|
16236
|
+
var baseNotificationSchema = z27.object({
|
|
16237
|
+
id: z27.string().optional(),
|
|
16238
|
+
userId: z27.string(),
|
|
16239
|
+
notificationTime: z27.any(),
|
|
16145
16240
|
// Timestamp
|
|
16146
|
-
notificationType:
|
|
16147
|
-
notificationTokens:
|
|
16148
|
-
status:
|
|
16149
|
-
createdAt:
|
|
16241
|
+
notificationType: z27.nativeEnum(NotificationType),
|
|
16242
|
+
notificationTokens: z27.array(z27.string()),
|
|
16243
|
+
status: z27.nativeEnum(NotificationStatus),
|
|
16244
|
+
createdAt: z27.any().optional(),
|
|
16150
16245
|
// Timestamp
|
|
16151
|
-
updatedAt:
|
|
16246
|
+
updatedAt: z27.any().optional(),
|
|
16152
16247
|
// Timestamp
|
|
16153
|
-
title:
|
|
16154
|
-
body:
|
|
16155
|
-
isRead:
|
|
16156
|
-
userRole:
|
|
16248
|
+
title: z27.string(),
|
|
16249
|
+
body: z27.string(),
|
|
16250
|
+
isRead: z27.boolean(),
|
|
16251
|
+
userRole: z27.nativeEnum(UserRole)
|
|
16157
16252
|
});
|
|
16158
16253
|
var preRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
16159
|
-
notificationType:
|
|
16160
|
-
treatmentId:
|
|
16161
|
-
requirements:
|
|
16162
|
-
deadline:
|
|
16254
|
+
notificationType: z27.literal("preRequirementInstructionDue" /* PRE_REQUIREMENT_INSTRUCTION_DUE */),
|
|
16255
|
+
treatmentId: z27.string(),
|
|
16256
|
+
requirements: z27.array(z27.string()),
|
|
16257
|
+
deadline: z27.any()
|
|
16163
16258
|
// Timestamp
|
|
16164
16259
|
});
|
|
16165
16260
|
var postRequirementNotificationSchema = baseNotificationSchema.extend({
|
|
16166
|
-
notificationType:
|
|
16261
|
+
notificationType: z27.literal(
|
|
16167
16262
|
"postRequirementInstructionDue" /* POST_REQUIREMENT_INSTRUCTION_DUE */
|
|
16168
16263
|
),
|
|
16169
|
-
treatmentId:
|
|
16170
|
-
requirements:
|
|
16171
|
-
deadline:
|
|
16264
|
+
treatmentId: z27.string(),
|
|
16265
|
+
requirements: z27.array(z27.string()),
|
|
16266
|
+
deadline: z27.any()
|
|
16172
16267
|
// Timestamp
|
|
16173
16268
|
});
|
|
16174
16269
|
var requirementInstructionDueNotificationSchema = baseNotificationSchema.extend({
|
|
16175
|
-
notificationType:
|
|
16176
|
-
appointmentId:
|
|
16177
|
-
patientRequirementInstanceId:
|
|
16178
|
-
instructionId:
|
|
16179
|
-
originalRequirementId:
|
|
16270
|
+
notificationType: z27.literal("requirementInstructionDue" /* REQUIREMENT_INSTRUCTION_DUE */),
|
|
16271
|
+
appointmentId: z27.string(),
|
|
16272
|
+
patientRequirementInstanceId: z27.string(),
|
|
16273
|
+
instructionId: z27.string(),
|
|
16274
|
+
originalRequirementId: z27.string().optional()
|
|
16180
16275
|
});
|
|
16181
16276
|
var appointmentReminderNotificationSchema = baseNotificationSchema.extend({
|
|
16182
|
-
notificationType:
|
|
16183
|
-
appointmentId:
|
|
16184
|
-
appointmentTime:
|
|
16277
|
+
notificationType: z27.literal("appointmentReminder" /* APPOINTMENT_REMINDER */),
|
|
16278
|
+
appointmentId: z27.string(),
|
|
16279
|
+
appointmentTime: z27.any(),
|
|
16185
16280
|
// Timestamp
|
|
16186
|
-
treatmentType:
|
|
16187
|
-
doctorName:
|
|
16281
|
+
treatmentType: z27.string(),
|
|
16282
|
+
doctorName: z27.string()
|
|
16188
16283
|
});
|
|
16189
16284
|
var appointmentNotificationSchema = baseNotificationSchema.extend({
|
|
16190
|
-
notificationType:
|
|
16191
|
-
appointmentId:
|
|
16192
|
-
appointmentStatus:
|
|
16193
|
-
previousStatus:
|
|
16194
|
-
reason:
|
|
16285
|
+
notificationType: z27.literal("appointmentStatusChange" /* APPOINTMENT_STATUS_CHANGE */),
|
|
16286
|
+
appointmentId: z27.string(),
|
|
16287
|
+
appointmentStatus: z27.string(),
|
|
16288
|
+
previousStatus: z27.string(),
|
|
16289
|
+
reason: z27.string().optional()
|
|
16195
16290
|
});
|
|
16196
|
-
var notificationSchema =
|
|
16291
|
+
var notificationSchema = z27.discriminatedUnion("notificationType", [
|
|
16197
16292
|
preRequirementNotificationSchema,
|
|
16198
16293
|
postRequirementNotificationSchema,
|
|
16199
16294
|
requirementInstructionDueNotificationSchema,
|