@blackcode_sa/metaestetics-api 1.4.8 → 1.4.9
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 +16 -16
- package/dist/index.d.ts +16 -16
- package/dist/index.js +736 -184
- package/dist/index.mjs +755 -196
- package/package.json +1 -1
- package/src/services/auth.service.ts +33 -11
- package/src/services/clinic/clinic-group.service.ts +63 -9
- package/src/services/clinic/clinic.service.ts +32 -9
- package/src/services/clinic/utils/admin.utils.ts +6 -51
- package/src/services/clinic/utils/clinic-group.utils.ts +178 -45
- package/src/services/clinic/utils/clinic.utils.ts +482 -39
- package/src/services/clinic/utils/photos.utils.ts +188 -0
- package/src/services/clinic/utils/review.utils.ts +24 -17
- package/src/services/clinic/utils/tag.utils.ts +33 -8
- package/src/types/clinic/index.ts +5 -5
- package/src/validations/clinic.schema.ts +3 -3
package/dist/index.js
CHANGED
|
@@ -2447,7 +2447,7 @@ var clinicGroupSchema = import_zod9.z.object({
|
|
|
2447
2447
|
admins: import_zod9.z.array(import_zod9.z.string()),
|
|
2448
2448
|
adminsInfo: import_zod9.z.array(adminInfoSchema),
|
|
2449
2449
|
adminTokens: import_zod9.z.array(adminTokenSchema),
|
|
2450
|
-
ownerId: import_zod9.z.string(),
|
|
2450
|
+
ownerId: import_zod9.z.string().nullable(),
|
|
2451
2451
|
createdAt: import_zod9.z.instanceof(Date).or(import_zod9.z.instanceof(import_firestore10.Timestamp)),
|
|
2452
2452
|
// Timestamp
|
|
2453
2453
|
updatedAt: import_zod9.z.instanceof(Date).or(import_zod9.z.instanceof(import_firestore10.Timestamp)),
|
|
@@ -2523,7 +2523,7 @@ var createClinicGroupSchema = import_zod9.z.object({
|
|
|
2523
2523
|
hqLocation: clinicLocationSchema,
|
|
2524
2524
|
contactInfo: clinicContactInfoSchema,
|
|
2525
2525
|
contactPerson: contactPersonSchema,
|
|
2526
|
-
ownerId: import_zod9.z.string(),
|
|
2526
|
+
ownerId: import_zod9.z.string().nullable(),
|
|
2527
2527
|
isActive: import_zod9.z.boolean(),
|
|
2528
2528
|
logo: import_zod9.z.string().optional().nullable(),
|
|
2529
2529
|
practiceType: import_zod9.z.nativeEnum(PracticeType).optional(),
|
|
@@ -2557,7 +2557,7 @@ var createClinicSchema = import_zod9.z.object({
|
|
|
2557
2557
|
});
|
|
2558
2558
|
var createDefaultClinicGroupSchema = import_zod9.z.object({
|
|
2559
2559
|
name: import_zod9.z.string(),
|
|
2560
|
-
ownerId: import_zod9.z.string(),
|
|
2560
|
+
ownerId: import_zod9.z.string().nullable(),
|
|
2561
2561
|
contactPerson: contactPersonSchema,
|
|
2562
2562
|
contactInfo: clinicContactInfoSchema,
|
|
2563
2563
|
hqLocation: clinicLocationSchema,
|
|
@@ -2655,45 +2655,7 @@ async function createClinicAdmin(db, data, clinicGroupService) {
|
|
|
2655
2655
|
hasGroupId: !!clinicGroupId
|
|
2656
2656
|
});
|
|
2657
2657
|
if (validatedData.isGroupOwner && !clinicGroupId) {
|
|
2658
|
-
console.log("[CLINIC_ADMIN]
|
|
2659
|
-
const defaultGroup = {
|
|
2660
|
-
name: `${validatedData.contactInfo.firstName}'s Group`,
|
|
2661
|
-
ownerId: validatedData.userRef,
|
|
2662
|
-
contactPerson: validatedData.contactInfo,
|
|
2663
|
-
contactInfo: {
|
|
2664
|
-
email: validatedData.contactInfo.email,
|
|
2665
|
-
phoneNumber: validatedData.contactInfo.phoneNumber || ""
|
|
2666
|
-
},
|
|
2667
|
-
hqLocation: {
|
|
2668
|
-
address: "",
|
|
2669
|
-
city: "",
|
|
2670
|
-
country: "",
|
|
2671
|
-
postalCode: "",
|
|
2672
|
-
latitude: 0,
|
|
2673
|
-
longitude: 0
|
|
2674
|
-
},
|
|
2675
|
-
isActive: true
|
|
2676
|
-
};
|
|
2677
|
-
console.log("[CLINIC_ADMIN] Default group data prepared", {
|
|
2678
|
-
groupName: defaultGroup.name
|
|
2679
|
-
});
|
|
2680
|
-
try {
|
|
2681
|
-
const clinicGroup = await clinicGroupService.createClinicGroup(
|
|
2682
|
-
defaultGroup,
|
|
2683
|
-
validatedData.userRef,
|
|
2684
|
-
true
|
|
2685
|
-
);
|
|
2686
|
-
clinicGroupId = clinicGroup.id;
|
|
2687
|
-
console.log("[CLINIC_ADMIN] Default group created successfully", {
|
|
2688
|
-
groupId: clinicGroupId
|
|
2689
|
-
});
|
|
2690
|
-
} catch (groupCreationError) {
|
|
2691
|
-
console.error(
|
|
2692
|
-
"[CLINIC_ADMIN] Error creating default group:",
|
|
2693
|
-
groupCreationError
|
|
2694
|
-
);
|
|
2695
|
-
throw groupCreationError;
|
|
2696
|
-
}
|
|
2658
|
+
console.log("[CLINIC_ADMIN] Owner will be assigned to group later");
|
|
2697
2659
|
} else if (!validatedData.isGroupOwner && !clinicGroupId) {
|
|
2698
2660
|
console.error("[CLINIC_ADMIN] Missing clinic group ID for non-owner admin");
|
|
2699
2661
|
throw new Error("Clinic group ID is required for non-owner admins");
|
|
@@ -2723,16 +2685,12 @@ async function createClinicAdmin(db, data, clinicGroupService) {
|
|
|
2723
2685
|
}
|
|
2724
2686
|
}
|
|
2725
2687
|
console.log("[CLINIC_ADMIN] Preparing admin data object");
|
|
2726
|
-
if (!clinicGroupId) {
|
|
2727
|
-
console.error(
|
|
2728
|
-
"[CLINIC_ADMIN] clinicGroupId is undefined, which should not happen at this point"
|
|
2729
|
-
);
|
|
2730
|
-
throw new Error("clinicGroupId is required but was undefined");
|
|
2731
|
-
}
|
|
2732
2688
|
const adminData = {
|
|
2733
|
-
id:
|
|
2689
|
+
id: (0, import_firestore11.doc)((0, import_firestore11.collection)(db, CLINIC_ADMINS_COLLECTION)).id,
|
|
2690
|
+
// Generate a new ID for the admin document
|
|
2734
2691
|
userRef: validatedData.userRef,
|
|
2735
|
-
clinicGroupId,
|
|
2692
|
+
clinicGroupId: clinicGroupId || "",
|
|
2693
|
+
// Empty string for now if no group ID
|
|
2736
2694
|
isGroupOwner: validatedData.isGroupOwner,
|
|
2737
2695
|
clinicsManaged: [],
|
|
2738
2696
|
// Uvek krećemo od prazne liste
|
|
@@ -3756,6 +3714,59 @@ var UserService = class extends BaseService {
|
|
|
3756
3714
|
var import_firestore15 = require("firebase/firestore");
|
|
3757
3715
|
var import_geofire_common2 = require("geofire-common");
|
|
3758
3716
|
var import_zod13 = require("zod");
|
|
3717
|
+
|
|
3718
|
+
// src/services/clinic/utils/photos.utils.ts
|
|
3719
|
+
var import_storage3 = require("firebase/storage");
|
|
3720
|
+
async function uploadPhoto(photo, entityType, entityId, photoType, app, fileName) {
|
|
3721
|
+
if (!photo || typeof photo !== "string" || !photo.startsWith("data:")) {
|
|
3722
|
+
return photo;
|
|
3723
|
+
}
|
|
3724
|
+
try {
|
|
3725
|
+
console.log(
|
|
3726
|
+
`[PHOTO_UTILS] Uploading ${photoType} for ${entityType}/${entityId}`
|
|
3727
|
+
);
|
|
3728
|
+
const storage = (0, import_storage3.getStorage)(app);
|
|
3729
|
+
const storageFileName = fileName || `${photoType}-${Date.now()}`;
|
|
3730
|
+
const storageRef = (0, import_storage3.ref)(
|
|
3731
|
+
storage,
|
|
3732
|
+
`${entityType}/${entityId}/${storageFileName}`
|
|
3733
|
+
);
|
|
3734
|
+
const base64Data = photo.split(",")[1];
|
|
3735
|
+
const contentType = photo.split(";")[0].split(":")[1];
|
|
3736
|
+
const byteCharacters = atob(base64Data);
|
|
3737
|
+
const byteArrays = [];
|
|
3738
|
+
for (let i = 0; i < byteCharacters.length; i++) {
|
|
3739
|
+
byteArrays.push(byteCharacters.charCodeAt(i));
|
|
3740
|
+
}
|
|
3741
|
+
const blob = new Blob([new Uint8Array(byteArrays)], { type: contentType });
|
|
3742
|
+
await (0, import_storage3.uploadBytes)(storageRef, blob, { contentType });
|
|
3743
|
+
const downloadUrl = await (0, import_storage3.getDownloadURL)(storageRef);
|
|
3744
|
+
console.log(`[PHOTO_UTILS] ${photoType} uploaded successfully`, {
|
|
3745
|
+
downloadUrl
|
|
3746
|
+
});
|
|
3747
|
+
return downloadUrl;
|
|
3748
|
+
} catch (error) {
|
|
3749
|
+
console.error(`[PHOTO_UTILS] Error uploading ${photoType}:`, error);
|
|
3750
|
+
return null;
|
|
3751
|
+
}
|
|
3752
|
+
}
|
|
3753
|
+
async function uploadMultiplePhotos(photos, entityType, entityId, photoType, app) {
|
|
3754
|
+
if (!photos || !Array.isArray(photos) || photos.length === 0) {
|
|
3755
|
+
return [];
|
|
3756
|
+
}
|
|
3757
|
+
const uploadPromises = photos.map(
|
|
3758
|
+
(photo, index) => uploadPhoto(photo, entityType, entityId, `${photoType}-${index}`, app)
|
|
3759
|
+
);
|
|
3760
|
+
try {
|
|
3761
|
+
const results = await Promise.all(uploadPromises);
|
|
3762
|
+
return results.filter((url) => url !== null);
|
|
3763
|
+
} catch (error) {
|
|
3764
|
+
console.error(`[PHOTO_UTILS] Error uploading multiple photos:`, error);
|
|
3765
|
+
return photos.filter((photo) => !photo.startsWith("data:"));
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
|
|
3769
|
+
// src/services/clinic/utils/clinic-group.utils.ts
|
|
3759
3770
|
function generateId() {
|
|
3760
3771
|
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
3761
3772
|
const timestamp = Date.now().toString(36);
|
|
@@ -3765,7 +3776,8 @@ function generateId() {
|
|
|
3765
3776
|
).join("");
|
|
3766
3777
|
return `${randomPart}-${timestamp}`;
|
|
3767
3778
|
}
|
|
3768
|
-
async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdminService) {
|
|
3779
|
+
async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdminService, app) {
|
|
3780
|
+
var _a, _b, _c, _d, _e;
|
|
3769
3781
|
console.log("[CLINIC_GROUP] Starting clinic group creation", {
|
|
3770
3782
|
ownerId,
|
|
3771
3783
|
isDefault
|
|
@@ -3819,23 +3831,49 @@ async function createClinicGroup(db, data, ownerId, isDefault = false, clinicAdm
|
|
|
3819
3831
|
}
|
|
3820
3832
|
const now = import_firestore15.Timestamp.now();
|
|
3821
3833
|
console.log("[CLINIC_GROUP] Preparing clinic group data object");
|
|
3834
|
+
const groupId = (0, import_firestore15.doc)((0, import_firestore15.collection)(db, CLINIC_GROUPS_COLLECTION)).id;
|
|
3822
3835
|
console.log("[CLINIC_GROUP] Logo value:", {
|
|
3823
3836
|
logoValue: validatedData.logo,
|
|
3824
3837
|
logoType: validatedData.logo === null ? "null" : typeof validatedData.logo
|
|
3825
3838
|
});
|
|
3839
|
+
let logoUrl = await uploadPhoto(
|
|
3840
|
+
validatedData.logo || null,
|
|
3841
|
+
"clinic-groups",
|
|
3842
|
+
groupId,
|
|
3843
|
+
"logo",
|
|
3844
|
+
app
|
|
3845
|
+
);
|
|
3846
|
+
console.log("[CLINIC_GROUP] Logo processed", { logoUrl });
|
|
3826
3847
|
const groupData = {
|
|
3827
3848
|
...validatedData,
|
|
3828
|
-
id:
|
|
3849
|
+
id: groupId,
|
|
3850
|
+
name: validatedData.name,
|
|
3851
|
+
logo: logoUrl,
|
|
3852
|
+
// Use the uploaded logo URL or the original value
|
|
3829
3853
|
description: isDefault ? void 0 : validatedData.description || void 0,
|
|
3830
3854
|
hqLocation: {
|
|
3831
|
-
|
|
3855
|
+
address: validatedData.hqLocation.address || "",
|
|
3856
|
+
city: validatedData.hqLocation.city || "",
|
|
3857
|
+
country: validatedData.hqLocation.country || "",
|
|
3858
|
+
postalCode: validatedData.hqLocation.postalCode || "",
|
|
3859
|
+
latitude: validatedData.hqLocation.latitude || 0,
|
|
3860
|
+
longitude: validatedData.hqLocation.longitude || 0,
|
|
3832
3861
|
geohash: validatedData.hqLocation.geohash || void 0
|
|
3833
3862
|
},
|
|
3834
3863
|
contactInfo: {
|
|
3835
|
-
|
|
3864
|
+
email: validatedData.contactInfo.email || "",
|
|
3865
|
+
phoneNumber: validatedData.contactInfo.phoneNumber || "",
|
|
3836
3866
|
alternativePhoneNumber: isDefault ? void 0 : validatedData.contactInfo.alternativePhoneNumber || void 0,
|
|
3837
3867
|
website: isDefault ? void 0 : validatedData.contactInfo.website || void 0
|
|
3838
3868
|
},
|
|
3869
|
+
contactPerson: {
|
|
3870
|
+
firstName: ((_a = validatedData.contactPerson) == null ? void 0 : _a.firstName) || "",
|
|
3871
|
+
lastName: ((_b = validatedData.contactPerson) == null ? void 0 : _b.lastName) || "",
|
|
3872
|
+
email: ((_c = validatedData.contactPerson) == null ? void 0 : _c.email) || "",
|
|
3873
|
+
title: ((_d = validatedData.contactPerson) == null ? void 0 : _d.title) || null,
|
|
3874
|
+
phoneNumber: ((_e = validatedData.contactPerson) == null ? void 0 : _e.phoneNumber) || null
|
|
3875
|
+
},
|
|
3876
|
+
subscriptionModel: validatedData.subscriptionModel || "no_subscription" /* NO_SUBSCRIPTION */,
|
|
3839
3877
|
clinics: [],
|
|
3840
3878
|
clinicsInfo: [],
|
|
3841
3879
|
admins: [ownerId],
|
|
@@ -3923,35 +3961,75 @@ async function getAllActiveGroups(db) {
|
|
|
3923
3961
|
const querySnapshot = await (0, import_firestore15.getDocs)(q);
|
|
3924
3962
|
return querySnapshot.docs.map((doc14) => doc14.data());
|
|
3925
3963
|
}
|
|
3926
|
-
async function updateClinicGroup(db, groupId, data) {
|
|
3964
|
+
async function updateClinicGroup(db, groupId, data, app) {
|
|
3965
|
+
console.log("[CLINIC_GROUP] Updating clinic group", { groupId });
|
|
3927
3966
|
const group = await getClinicGroup(db, groupId);
|
|
3928
3967
|
if (!group) {
|
|
3968
|
+
console.error("[CLINIC_GROUP] Clinic group not found", { groupId });
|
|
3929
3969
|
throw new Error("Clinic group not found");
|
|
3930
3970
|
}
|
|
3931
|
-
|
|
3932
|
-
|
|
3971
|
+
let updatedData = { ...data };
|
|
3972
|
+
if (data.logo && typeof data.logo === "string" && data.logo.startsWith("data:")) {
|
|
3973
|
+
console.log("[CLINIC_GROUP] Processing logo for update");
|
|
3974
|
+
try {
|
|
3975
|
+
const logoUrl = await uploadPhoto(
|
|
3976
|
+
data.logo,
|
|
3977
|
+
"clinic-groups",
|
|
3978
|
+
groupId,
|
|
3979
|
+
"logo",
|
|
3980
|
+
app
|
|
3981
|
+
);
|
|
3982
|
+
console.log("[CLINIC_GROUP] Logo processed for update", { logoUrl });
|
|
3983
|
+
updatedData.logo = logoUrl;
|
|
3984
|
+
} catch (error) {
|
|
3985
|
+
console.error("[CLINIC_GROUP] Error processing logo for update:", error);
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
updatedData = {
|
|
3989
|
+
...updatedData,
|
|
3933
3990
|
updatedAt: import_firestore15.Timestamp.now()
|
|
3934
3991
|
};
|
|
3992
|
+
console.log("[CLINIC_GROUP] Updating clinic group in Firestore");
|
|
3935
3993
|
await (0, import_firestore15.updateDoc)((0, import_firestore15.doc)(db, CLINIC_GROUPS_COLLECTION, groupId), updatedData);
|
|
3994
|
+
console.log("[CLINIC_GROUP] Clinic group updated successfully");
|
|
3936
3995
|
const updatedGroup = await getClinicGroup(db, groupId);
|
|
3937
3996
|
if (!updatedGroup) {
|
|
3997
|
+
console.error("[CLINIC_GROUP] Failed to retrieve updated clinic group");
|
|
3938
3998
|
throw new Error("Failed to retrieve updated clinic group");
|
|
3939
3999
|
}
|
|
3940
4000
|
return updatedGroup;
|
|
3941
4001
|
}
|
|
3942
|
-
async function addAdminToGroup(db, groupId, adminId) {
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
4002
|
+
async function addAdminToGroup(db, groupId, adminId, app) {
|
|
4003
|
+
console.log("[CLINIC_GROUP] Adding admin to group", { groupId, adminId });
|
|
4004
|
+
try {
|
|
4005
|
+
const group = await getClinicGroup(db, groupId);
|
|
4006
|
+
if (!group) {
|
|
4007
|
+
console.error("[CLINIC_GROUP] Clinic group not found", { groupId });
|
|
4008
|
+
throw new Error("Clinic group not found");
|
|
4009
|
+
}
|
|
4010
|
+
if (group.admins.includes(adminId)) {
|
|
4011
|
+
console.log("[CLINIC_GROUP] Admin is already in the group", {
|
|
4012
|
+
adminId,
|
|
4013
|
+
groupId
|
|
4014
|
+
});
|
|
4015
|
+
return;
|
|
4016
|
+
}
|
|
4017
|
+
console.log("[CLINIC_GROUP] Updating group with new admin");
|
|
4018
|
+
await updateClinicGroup(
|
|
4019
|
+
db,
|
|
4020
|
+
groupId,
|
|
4021
|
+
{
|
|
4022
|
+
admins: [...group.admins, adminId]
|
|
4023
|
+
},
|
|
4024
|
+
app
|
|
4025
|
+
);
|
|
4026
|
+
console.log("[CLINIC_GROUP] Admin added to group successfully");
|
|
4027
|
+
} catch (error) {
|
|
4028
|
+
console.error("[CLINIC_GROUP] Error adding admin to group:", error);
|
|
4029
|
+
throw error;
|
|
3949
4030
|
}
|
|
3950
|
-
await updateClinicGroup(db, groupId, {
|
|
3951
|
-
admins: [...group.admins, adminId]
|
|
3952
|
-
});
|
|
3953
4031
|
}
|
|
3954
|
-
async function removeAdminFromGroup(db, groupId, adminId) {
|
|
4032
|
+
async function removeAdminFromGroup(db, groupId, adminId, app) {
|
|
3955
4033
|
const group = await getClinicGroup(db, groupId);
|
|
3956
4034
|
if (!group) {
|
|
3957
4035
|
throw new Error("Clinic group not found");
|
|
@@ -3962,21 +4040,30 @@ async function removeAdminFromGroup(db, groupId, adminId) {
|
|
|
3962
4040
|
if (!group.admins.includes(adminId)) {
|
|
3963
4041
|
return;
|
|
3964
4042
|
}
|
|
3965
|
-
await updateClinicGroup(
|
|
3966
|
-
|
|
3967
|
-
|
|
4043
|
+
await updateClinicGroup(
|
|
4044
|
+
db,
|
|
4045
|
+
groupId,
|
|
4046
|
+
{
|
|
4047
|
+
admins: group.admins.filter((id) => id !== adminId)
|
|
4048
|
+
},
|
|
4049
|
+
app
|
|
4050
|
+
);
|
|
3968
4051
|
}
|
|
3969
|
-
async function deactivateClinicGroup(db, groupId) {
|
|
4052
|
+
async function deactivateClinicGroup(db, groupId, app) {
|
|
3970
4053
|
const group = await getClinicGroup(db, groupId);
|
|
3971
4054
|
if (!group) {
|
|
3972
4055
|
throw new Error("Clinic group not found");
|
|
3973
4056
|
}
|
|
3974
|
-
await (
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
4057
|
+
await updateClinicGroup(
|
|
4058
|
+
db,
|
|
4059
|
+
groupId,
|
|
4060
|
+
{
|
|
4061
|
+
isActive: false
|
|
4062
|
+
},
|
|
4063
|
+
app
|
|
4064
|
+
);
|
|
3978
4065
|
}
|
|
3979
|
-
async function createAdminToken(db, groupId, creatorAdminId, data) {
|
|
4066
|
+
async function createAdminToken(db, groupId, creatorAdminId, app, data) {
|
|
3980
4067
|
const group = await getClinicGroup(db, groupId);
|
|
3981
4068
|
if (!group) {
|
|
3982
4069
|
throw new Error("Clinic group not found");
|
|
@@ -3997,12 +4084,17 @@ async function createAdminToken(db, groupId, creatorAdminId, data) {
|
|
|
3997
4084
|
createdAt: now,
|
|
3998
4085
|
expiresAt
|
|
3999
4086
|
};
|
|
4000
|
-
await updateClinicGroup(
|
|
4001
|
-
|
|
4002
|
-
|
|
4087
|
+
await updateClinicGroup(
|
|
4088
|
+
db,
|
|
4089
|
+
groupId,
|
|
4090
|
+
{
|
|
4091
|
+
adminTokens: [...group.adminTokens, token]
|
|
4092
|
+
},
|
|
4093
|
+
app
|
|
4094
|
+
);
|
|
4003
4095
|
return token;
|
|
4004
4096
|
}
|
|
4005
|
-
async function verifyAndUseAdminToken(db, groupId, token, userRef) {
|
|
4097
|
+
async function verifyAndUseAdminToken(db, groupId, token, userRef, app) {
|
|
4006
4098
|
const group = await getClinicGroup(db, groupId);
|
|
4007
4099
|
if (!group) {
|
|
4008
4100
|
throw new Error("Clinic group not found");
|
|
@@ -4019,9 +4111,14 @@ async function verifyAndUseAdminToken(db, groupId, token, userRef) {
|
|
|
4019
4111
|
const updatedTokens2 = group.adminTokens.map(
|
|
4020
4112
|
(t) => t.id === adminToken.id ? { ...t, status: "expired" /* EXPIRED */ } : t
|
|
4021
4113
|
);
|
|
4022
|
-
await updateClinicGroup(
|
|
4023
|
-
|
|
4024
|
-
|
|
4114
|
+
await updateClinicGroup(
|
|
4115
|
+
db,
|
|
4116
|
+
groupId,
|
|
4117
|
+
{
|
|
4118
|
+
adminTokens: updatedTokens2
|
|
4119
|
+
},
|
|
4120
|
+
app
|
|
4121
|
+
);
|
|
4025
4122
|
throw new Error("Admin token has expired");
|
|
4026
4123
|
}
|
|
4027
4124
|
const updatedTokens = group.adminTokens.map(
|
|
@@ -4031,12 +4128,17 @@ async function verifyAndUseAdminToken(db, groupId, token, userRef) {
|
|
|
4031
4128
|
usedByUserRef: userRef
|
|
4032
4129
|
} : t
|
|
4033
4130
|
);
|
|
4034
|
-
await updateClinicGroup(
|
|
4035
|
-
|
|
4036
|
-
|
|
4131
|
+
await updateClinicGroup(
|
|
4132
|
+
db,
|
|
4133
|
+
groupId,
|
|
4134
|
+
{
|
|
4135
|
+
adminTokens: updatedTokens
|
|
4136
|
+
},
|
|
4137
|
+
app
|
|
4138
|
+
);
|
|
4037
4139
|
return true;
|
|
4038
4140
|
}
|
|
4039
|
-
async function deleteAdminToken(db, groupId, tokenId, adminId) {
|
|
4141
|
+
async function deleteAdminToken(db, groupId, tokenId, adminId, app) {
|
|
4040
4142
|
const group = await getClinicGroup(db, groupId);
|
|
4041
4143
|
if (!group) {
|
|
4042
4144
|
throw new Error("Clinic group not found");
|
|
@@ -4045,11 +4147,16 @@ async function deleteAdminToken(db, groupId, tokenId, adminId) {
|
|
|
4045
4147
|
throw new Error("Admin does not belong to this clinic group");
|
|
4046
4148
|
}
|
|
4047
4149
|
const updatedTokens = group.adminTokens.filter((t) => t.id !== tokenId);
|
|
4048
|
-
await updateClinicGroup(
|
|
4049
|
-
|
|
4050
|
-
|
|
4150
|
+
await updateClinicGroup(
|
|
4151
|
+
db,
|
|
4152
|
+
groupId,
|
|
4153
|
+
{
|
|
4154
|
+
adminTokens: updatedTokens
|
|
4155
|
+
},
|
|
4156
|
+
app
|
|
4157
|
+
);
|
|
4051
4158
|
}
|
|
4052
|
-
async function getActiveAdminTokens(db, groupId, adminId) {
|
|
4159
|
+
async function getActiveAdminTokens(db, groupId, adminId, app) {
|
|
4053
4160
|
const group = await getClinicGroup(db, groupId);
|
|
4054
4161
|
if (!group) {
|
|
4055
4162
|
throw new Error("Clinic group not found");
|
|
@@ -4075,7 +4182,8 @@ var ClinicGroupService = class extends BaseService {
|
|
|
4075
4182
|
data,
|
|
4076
4183
|
ownerId,
|
|
4077
4184
|
isDefault,
|
|
4078
|
-
this.clinicAdminService
|
|
4185
|
+
this.clinicAdminService,
|
|
4186
|
+
this.app
|
|
4079
4187
|
);
|
|
4080
4188
|
}
|
|
4081
4189
|
/**
|
|
@@ -4094,25 +4202,35 @@ var ClinicGroupService = class extends BaseService {
|
|
|
4094
4202
|
* Ažurira grupaciju klinika
|
|
4095
4203
|
*/
|
|
4096
4204
|
async updateClinicGroup(groupId, data) {
|
|
4097
|
-
return updateClinicGroup(this.db, groupId, data);
|
|
4205
|
+
return updateClinicGroup(this.db, groupId, data, this.app);
|
|
4098
4206
|
}
|
|
4099
4207
|
/**
|
|
4100
4208
|
* Dodaje admina u grupaciju
|
|
4101
4209
|
*/
|
|
4102
4210
|
async addAdminToGroup(groupId, adminId) {
|
|
4103
|
-
return addAdminToGroup(
|
|
4211
|
+
return addAdminToGroup(
|
|
4212
|
+
this.db,
|
|
4213
|
+
groupId,
|
|
4214
|
+
adminId,
|
|
4215
|
+
this.app
|
|
4216
|
+
);
|
|
4104
4217
|
}
|
|
4105
4218
|
/**
|
|
4106
4219
|
* Uklanja admina iz grupacije
|
|
4107
4220
|
*/
|
|
4108
4221
|
async removeAdminFromGroup(groupId, adminId) {
|
|
4109
|
-
return removeAdminFromGroup(
|
|
4222
|
+
return removeAdminFromGroup(
|
|
4223
|
+
this.db,
|
|
4224
|
+
groupId,
|
|
4225
|
+
adminId,
|
|
4226
|
+
this.app
|
|
4227
|
+
);
|
|
4110
4228
|
}
|
|
4111
4229
|
/**
|
|
4112
4230
|
* Deaktivira grupaciju klinika
|
|
4113
4231
|
*/
|
|
4114
4232
|
async deactivateClinicGroup(groupId) {
|
|
4115
|
-
return deactivateClinicGroup(this.db, groupId);
|
|
4233
|
+
return deactivateClinicGroup(this.db, groupId, this.app);
|
|
4116
4234
|
}
|
|
4117
4235
|
/**
|
|
4118
4236
|
* Sets up additional clinic group information after initial creation
|
|
@@ -4122,18 +4240,45 @@ var ClinicGroupService = class extends BaseService {
|
|
|
4122
4240
|
* @returns The updated clinic group
|
|
4123
4241
|
*/
|
|
4124
4242
|
async setupClinicGroup(groupId, setupData) {
|
|
4243
|
+
console.log("[CLINIC_GROUP] Setting up clinic group", { groupId });
|
|
4125
4244
|
const clinicGroup = await this.getClinicGroup(groupId);
|
|
4126
4245
|
if (!clinicGroup) {
|
|
4246
|
+
console.error("[CLINIC_GROUP] Clinic group not found", { groupId });
|
|
4127
4247
|
throw new Error(`Clinic group with ID ${groupId} not found`);
|
|
4128
4248
|
}
|
|
4249
|
+
let logoUrl = setupData.logo;
|
|
4250
|
+
if (logoUrl && typeof logoUrl === "string" && logoUrl.startsWith("data:")) {
|
|
4251
|
+
console.log("[CLINIC_GROUP] Processing logo in setupClinicGroup");
|
|
4252
|
+
try {
|
|
4253
|
+
const uploadedLogoUrl = await uploadPhoto(
|
|
4254
|
+
logoUrl,
|
|
4255
|
+
"clinic-groups",
|
|
4256
|
+
groupId,
|
|
4257
|
+
"logo",
|
|
4258
|
+
this.app
|
|
4259
|
+
);
|
|
4260
|
+
console.log("[CLINIC_GROUP] Logo processed in setupClinicGroup", {
|
|
4261
|
+
uploadedLogoUrl
|
|
4262
|
+
});
|
|
4263
|
+
if (uploadedLogoUrl !== null) {
|
|
4264
|
+
logoUrl = uploadedLogoUrl;
|
|
4265
|
+
}
|
|
4266
|
+
} catch (error) {
|
|
4267
|
+
console.error(
|
|
4268
|
+
"[CLINIC_GROUP] Error processing logo in setupClinicGroup:",
|
|
4269
|
+
error
|
|
4270
|
+
);
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4129
4273
|
const updateData = {
|
|
4130
4274
|
languages: setupData.languages,
|
|
4131
4275
|
practiceType: setupData.practiceType,
|
|
4132
4276
|
description: setupData.description,
|
|
4133
|
-
logo:
|
|
4277
|
+
logo: logoUrl,
|
|
4134
4278
|
calendarSyncEnabled: setupData.calendarSyncEnabled,
|
|
4135
4279
|
autoConfirmAppointments: setupData.autoConfirmAppointments
|
|
4136
4280
|
};
|
|
4281
|
+
console.log("[CLINIC_GROUP] Updating clinic group with setup data");
|
|
4137
4282
|
return this.updateClinicGroup(groupId, updateData);
|
|
4138
4283
|
}
|
|
4139
4284
|
/**
|
|
@@ -4144,6 +4289,7 @@ var ClinicGroupService = class extends BaseService {
|
|
|
4144
4289
|
this.db,
|
|
4145
4290
|
groupId,
|
|
4146
4291
|
creatorAdminId,
|
|
4292
|
+
this.app,
|
|
4147
4293
|
data
|
|
4148
4294
|
);
|
|
4149
4295
|
}
|
|
@@ -4155,7 +4301,8 @@ var ClinicGroupService = class extends BaseService {
|
|
|
4155
4301
|
this.db,
|
|
4156
4302
|
groupId,
|
|
4157
4303
|
token,
|
|
4158
|
-
userRef
|
|
4304
|
+
userRef,
|
|
4305
|
+
this.app
|
|
4159
4306
|
);
|
|
4160
4307
|
}
|
|
4161
4308
|
/**
|
|
@@ -4166,14 +4313,20 @@ var ClinicGroupService = class extends BaseService {
|
|
|
4166
4313
|
this.db,
|
|
4167
4314
|
groupId,
|
|
4168
4315
|
tokenId,
|
|
4169
|
-
adminId
|
|
4316
|
+
adminId,
|
|
4317
|
+
this.app
|
|
4170
4318
|
);
|
|
4171
4319
|
}
|
|
4172
4320
|
/**
|
|
4173
4321
|
* Dohvata aktivne admin tokene
|
|
4174
4322
|
*/
|
|
4175
4323
|
async getActiveAdminTokens(groupId, adminId) {
|
|
4176
|
-
return getActiveAdminTokens(
|
|
4324
|
+
return getActiveAdminTokens(
|
|
4325
|
+
this.db,
|
|
4326
|
+
groupId,
|
|
4327
|
+
adminId,
|
|
4328
|
+
this.app
|
|
4329
|
+
);
|
|
4177
4330
|
}
|
|
4178
4331
|
};
|
|
4179
4332
|
|
|
@@ -4181,44 +4334,193 @@ var ClinicGroupService = class extends BaseService {
|
|
|
4181
4334
|
var import_firestore16 = require("firebase/firestore");
|
|
4182
4335
|
var import_geofire_common3 = require("geofire-common");
|
|
4183
4336
|
var import_zod14 = require("zod");
|
|
4184
|
-
async function createClinic(db, data, creatorAdminId, clinicGroupService, clinicAdminService) {
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4337
|
+
async function createClinic(db, data, creatorAdminId, clinicGroupService, clinicAdminService, app) {
|
|
4338
|
+
var _a;
|
|
4339
|
+
console.log("[CLINIC] Starting clinic creation", { creatorAdminId });
|
|
4340
|
+
console.log("[CLINIC] Input data:", JSON.stringify(data, null, 2));
|
|
4341
|
+
try {
|
|
4342
|
+
const validatedData2 = createClinicSchema.parse(data);
|
|
4343
|
+
console.log("[CLINIC] Data validation passed");
|
|
4344
|
+
} catch (validationError) {
|
|
4345
|
+
console.error("[CLINIC] Data validation failed:", validationError);
|
|
4346
|
+
throw validationError;
|
|
4189
4347
|
}
|
|
4190
|
-
|
|
4191
|
-
|
|
4348
|
+
const validatedData = createClinicSchema.parse(data);
|
|
4349
|
+
try {
|
|
4350
|
+
console.log("[CLINIC] Checking if admin exists and belongs to group");
|
|
4351
|
+
const admin = await clinicAdminService.getClinicAdmin(creatorAdminId);
|
|
4352
|
+
if (!admin) {
|
|
4353
|
+
console.error("[CLINIC] Admin not found", { creatorAdminId });
|
|
4354
|
+
throw new Error("Admin not found");
|
|
4355
|
+
}
|
|
4356
|
+
if (admin.clinicGroupId !== validatedData.clinicGroupId) {
|
|
4357
|
+
console.error("[CLINIC] Admin does not belong to this clinic group", {
|
|
4358
|
+
adminGroupId: admin.clinicGroupId,
|
|
4359
|
+
requestedGroupId: validatedData.clinicGroupId
|
|
4360
|
+
});
|
|
4361
|
+
throw new Error("Admin does not belong to this clinic group");
|
|
4362
|
+
}
|
|
4363
|
+
console.log("[CLINIC] Admin verified");
|
|
4364
|
+
} catch (adminError) {
|
|
4365
|
+
console.error("[CLINIC] Error verifying admin:", adminError);
|
|
4366
|
+
throw adminError;
|
|
4192
4367
|
}
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4368
|
+
try {
|
|
4369
|
+
console.log("[CLINIC] Checking if clinic group exists");
|
|
4370
|
+
const group = await clinicGroupService.getClinicGroup(
|
|
4371
|
+
validatedData.clinicGroupId
|
|
4372
|
+
);
|
|
4373
|
+
if (!group) {
|
|
4374
|
+
console.error("[CLINIC] Clinic group not found", {
|
|
4375
|
+
groupId: validatedData.clinicGroupId
|
|
4376
|
+
});
|
|
4377
|
+
throw new Error("Clinic group not found");
|
|
4378
|
+
}
|
|
4379
|
+
console.log("[CLINIC] Clinic group verified");
|
|
4380
|
+
} catch (groupError) {
|
|
4381
|
+
console.error("[CLINIC] Error verifying clinic group:", groupError);
|
|
4382
|
+
throw groupError;
|
|
4198
4383
|
}
|
|
4384
|
+
console.log("[CLINIC] Generating geohash for location");
|
|
4199
4385
|
if (validatedData.location) {
|
|
4200
|
-
|
|
4201
|
-
validatedData.location.
|
|
4202
|
-
|
|
4203
|
-
|
|
4386
|
+
try {
|
|
4387
|
+
validatedData.location.geohash = (0, import_geofire_common3.geohashForLocation)([
|
|
4388
|
+
validatedData.location.latitude,
|
|
4389
|
+
validatedData.location.longitude
|
|
4390
|
+
]);
|
|
4391
|
+
console.log("[CLINIC] Geohash generated successfully", {
|
|
4392
|
+
geohash: validatedData.location.geohash
|
|
4393
|
+
});
|
|
4394
|
+
} catch (geohashError) {
|
|
4395
|
+
console.error("[CLINIC] Error generating geohash:", geohashError);
|
|
4396
|
+
throw geohashError;
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4399
|
+
const clinicId = (0, import_firestore16.doc)((0, import_firestore16.collection)(db, CLINICS_COLLECTION)).id;
|
|
4400
|
+
console.log("[CLINIC] Generated clinic ID:", clinicId);
|
|
4401
|
+
console.log("[CLINIC] Processing photos");
|
|
4402
|
+
let logoUrl = null;
|
|
4403
|
+
if (validatedData.logo) {
|
|
4404
|
+
console.log("[CLINIC] Processing logo");
|
|
4405
|
+
try {
|
|
4406
|
+
logoUrl = await uploadPhoto(
|
|
4407
|
+
validatedData.logo,
|
|
4408
|
+
"clinics",
|
|
4409
|
+
clinicId,
|
|
4410
|
+
"logo",
|
|
4411
|
+
app
|
|
4412
|
+
);
|
|
4413
|
+
console.log("[CLINIC] Logo processed", { logoUrl });
|
|
4414
|
+
} catch (logoError) {
|
|
4415
|
+
console.error("[CLINIC] Error processing logo:", logoError);
|
|
4416
|
+
}
|
|
4417
|
+
}
|
|
4418
|
+
let processedPhotos = [];
|
|
4419
|
+
if (validatedData.photos && validatedData.photos.length > 0) {
|
|
4420
|
+
console.log("[CLINIC] Processing regular photos");
|
|
4421
|
+
try {
|
|
4422
|
+
processedPhotos = await uploadMultiplePhotos(
|
|
4423
|
+
validatedData.photos,
|
|
4424
|
+
"clinics",
|
|
4425
|
+
clinicId,
|
|
4426
|
+
"photo",
|
|
4427
|
+
app
|
|
4428
|
+
);
|
|
4429
|
+
console.log("[CLINIC] Regular photos processed", {
|
|
4430
|
+
count: processedPhotos.length
|
|
4431
|
+
});
|
|
4432
|
+
} catch (photosError) {
|
|
4433
|
+
console.error("[CLINIC] Error processing regular photos:", photosError);
|
|
4434
|
+
processedPhotos = validatedData.photos.filter(
|
|
4435
|
+
(photo) => !photo.startsWith("data:")
|
|
4436
|
+
);
|
|
4437
|
+
}
|
|
4438
|
+
}
|
|
4439
|
+
let processedFeaturedPhotos = [];
|
|
4440
|
+
if (validatedData.featuredPhotos && validatedData.featuredPhotos.length > 0) {
|
|
4441
|
+
console.log("[CLINIC] Processing featured photos");
|
|
4442
|
+
try {
|
|
4443
|
+
processedFeaturedPhotos = await uploadMultiplePhotos(
|
|
4444
|
+
validatedData.featuredPhotos,
|
|
4445
|
+
"clinics",
|
|
4446
|
+
clinicId,
|
|
4447
|
+
"featured",
|
|
4448
|
+
app
|
|
4449
|
+
);
|
|
4450
|
+
console.log("[CLINIC] Featured photos processed", {
|
|
4451
|
+
count: processedFeaturedPhotos.length
|
|
4452
|
+
});
|
|
4453
|
+
} catch (featuredError) {
|
|
4454
|
+
console.error(
|
|
4455
|
+
"[CLINIC] Error processing featured photos:",
|
|
4456
|
+
featuredError
|
|
4457
|
+
);
|
|
4458
|
+
processedFeaturedPhotos = validatedData.featuredPhotos.filter(
|
|
4459
|
+
(photo) => !photo.startsWith("data:")
|
|
4460
|
+
);
|
|
4461
|
+
}
|
|
4462
|
+
}
|
|
4463
|
+
let processedPhotosWithTags = validatedData.photosWithTags || [];
|
|
4464
|
+
if (processedPhotosWithTags.length > 0) {
|
|
4465
|
+
console.log("[CLINIC] Processing photos with tags");
|
|
4466
|
+
try {
|
|
4467
|
+
const updatedPhotosWithTags = [];
|
|
4468
|
+
for (const photoWithTag of processedPhotosWithTags) {
|
|
4469
|
+
if (photoWithTag.url && photoWithTag.url.startsWith("data:")) {
|
|
4470
|
+
const uploadedUrl = await uploadPhoto(
|
|
4471
|
+
photoWithTag.url,
|
|
4472
|
+
"clinics",
|
|
4473
|
+
clinicId,
|
|
4474
|
+
`tagged-${photoWithTag.tag}`,
|
|
4475
|
+
app
|
|
4476
|
+
);
|
|
4477
|
+
if (uploadedUrl) {
|
|
4478
|
+
updatedPhotosWithTags.push({
|
|
4479
|
+
url: uploadedUrl,
|
|
4480
|
+
tag: photoWithTag.tag
|
|
4481
|
+
});
|
|
4482
|
+
}
|
|
4483
|
+
} else {
|
|
4484
|
+
updatedPhotosWithTags.push(photoWithTag);
|
|
4485
|
+
}
|
|
4486
|
+
}
|
|
4487
|
+
processedPhotosWithTags = updatedPhotosWithTags;
|
|
4488
|
+
console.log("[CLINIC] Photos with tags processed", {
|
|
4489
|
+
count: processedPhotosWithTags.length
|
|
4490
|
+
});
|
|
4491
|
+
} catch (tagsError) {
|
|
4492
|
+
console.error("[CLINIC] Error processing photos with tags:", tagsError);
|
|
4493
|
+
processedPhotosWithTags = ((_a = validatedData.photosWithTags) == null ? void 0 : _a.filter(
|
|
4494
|
+
(photo) => !photo.url.startsWith("data:")
|
|
4495
|
+
)) || [];
|
|
4496
|
+
}
|
|
4204
4497
|
}
|
|
4205
4498
|
const now = import_firestore16.Timestamp.now();
|
|
4499
|
+
console.log("[CLINIC] Preparing clinic data object");
|
|
4206
4500
|
const clinicData = {
|
|
4207
4501
|
...validatedData,
|
|
4208
|
-
id:
|
|
4502
|
+
id: clinicId,
|
|
4209
4503
|
description: validatedData.description || void 0,
|
|
4210
4504
|
location: {
|
|
4211
|
-
|
|
4505
|
+
address: validatedData.location.address || "",
|
|
4506
|
+
city: validatedData.location.city || "",
|
|
4507
|
+
country: validatedData.location.country || "",
|
|
4508
|
+
postalCode: validatedData.location.postalCode || "",
|
|
4509
|
+
latitude: validatedData.location.latitude || 0,
|
|
4510
|
+
longitude: validatedData.location.longitude || 0,
|
|
4212
4511
|
geohash: validatedData.location.geohash || void 0
|
|
4213
4512
|
},
|
|
4214
4513
|
contactInfo: {
|
|
4215
|
-
|
|
4514
|
+
email: validatedData.contactInfo.email || "",
|
|
4515
|
+
phoneNumber: validatedData.contactInfo.phoneNumber || "",
|
|
4216
4516
|
alternativePhoneNumber: validatedData.contactInfo.alternativePhoneNumber || void 0,
|
|
4217
4517
|
website: validatedData.contactInfo.website || void 0
|
|
4218
4518
|
},
|
|
4519
|
+
logo: logoUrl || void 0,
|
|
4219
4520
|
tags: validatedData.tags || [],
|
|
4220
|
-
featuredPhotos: [],
|
|
4221
|
-
photos:
|
|
4521
|
+
featuredPhotos: processedFeaturedPhotos || [],
|
|
4522
|
+
photos: processedPhotos || [],
|
|
4523
|
+
photosWithTags: processedPhotosWithTags,
|
|
4222
4524
|
doctors: [],
|
|
4223
4525
|
doctorsInfo: [],
|
|
4224
4526
|
services: [],
|
|
@@ -4233,17 +4535,73 @@ async function createClinic(db, data, creatorAdminId, clinicGroupService, clinic
|
|
|
4233
4535
|
isVerified: false
|
|
4234
4536
|
};
|
|
4235
4537
|
try {
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4538
|
+
console.log("[CLINIC] Validating complete clinic object");
|
|
4539
|
+
try {
|
|
4540
|
+
clinicSchema.parse(clinicData);
|
|
4541
|
+
console.log("[CLINIC] Clinic validation passed");
|
|
4542
|
+
} catch (schemaError) {
|
|
4543
|
+
console.error(
|
|
4544
|
+
"[CLINIC] Clinic validation failed:",
|
|
4545
|
+
JSON.stringify(schemaError, null, 2)
|
|
4546
|
+
);
|
|
4547
|
+
throw schemaError;
|
|
4548
|
+
}
|
|
4549
|
+
console.log("[CLINIC] Saving clinic to Firestore", {
|
|
4550
|
+
clinicId: clinicData.id
|
|
4551
|
+
});
|
|
4552
|
+
try {
|
|
4553
|
+
await (0, import_firestore16.setDoc)((0, import_firestore16.doc)(db, CLINICS_COLLECTION, clinicData.id), clinicData);
|
|
4554
|
+
console.log("[CLINIC] Clinic saved successfully");
|
|
4555
|
+
} catch (firestoreError) {
|
|
4556
|
+
console.error("[CLINIC] Error saving to Firestore:", firestoreError);
|
|
4557
|
+
throw firestoreError;
|
|
4558
|
+
}
|
|
4559
|
+
console.log("[CLINIC] Adding clinic to clinic group");
|
|
4560
|
+
try {
|
|
4561
|
+
const group = await clinicGroupService.getClinicGroup(
|
|
4562
|
+
validatedData.clinicGroupId
|
|
4563
|
+
);
|
|
4564
|
+
if (group) {
|
|
4565
|
+
await clinicGroupService.updateClinicGroup(
|
|
4566
|
+
validatedData.clinicGroupId,
|
|
4567
|
+
{
|
|
4568
|
+
clinics: [...group.clinics, clinicData.id]
|
|
4569
|
+
}
|
|
4570
|
+
);
|
|
4571
|
+
console.log("[CLINIC] Clinic added to group successfully");
|
|
4572
|
+
}
|
|
4573
|
+
} catch (groupUpdateError) {
|
|
4574
|
+
console.error("[CLINIC] Error adding clinic to group:", groupUpdateError);
|
|
4575
|
+
}
|
|
4576
|
+
console.log("[CLINIC] Adding clinic to admin's managed clinics");
|
|
4577
|
+
try {
|
|
4578
|
+
await clinicAdminService.addClinicToManaged(
|
|
4579
|
+
creatorAdminId,
|
|
4580
|
+
clinicData.id
|
|
4581
|
+
);
|
|
4582
|
+
console.log(
|
|
4583
|
+
"[CLINIC] Clinic added to admin's managed clinics successfully"
|
|
4584
|
+
);
|
|
4585
|
+
} catch (adminUpdateError) {
|
|
4586
|
+
console.error(
|
|
4587
|
+
"[CLINIC] Error adding clinic to admin's managed clinics:",
|
|
4588
|
+
adminUpdateError
|
|
4589
|
+
);
|
|
4590
|
+
}
|
|
4591
|
+
console.log("[CLINIC] Clinic creation completed successfully", {
|
|
4592
|
+
clinicId: clinicData.id,
|
|
4593
|
+
clinicName: clinicData.name
|
|
4240
4594
|
});
|
|
4241
|
-
await clinicAdminService.addClinicToManaged(creatorAdminId, clinicData.id);
|
|
4242
4595
|
return clinicData;
|
|
4243
4596
|
} catch (error) {
|
|
4244
4597
|
if (error instanceof import_zod14.z.ZodError) {
|
|
4598
|
+
console.error(
|
|
4599
|
+
"[CLINIC] Zod validation error:",
|
|
4600
|
+
JSON.stringify(error.errors, null, 2)
|
|
4601
|
+
);
|
|
4245
4602
|
throw new Error("Invalid clinic data: " + error.message);
|
|
4246
4603
|
}
|
|
4604
|
+
console.error("[CLINIC] Unhandled error in createClinic:", error);
|
|
4247
4605
|
throw error;
|
|
4248
4606
|
}
|
|
4249
4607
|
}
|
|
@@ -4264,27 +4622,177 @@ async function getClinicsByGroup(db, groupId) {
|
|
|
4264
4622
|
const querySnapshot = await (0, import_firestore16.getDocs)(q);
|
|
4265
4623
|
return querySnapshot.docs.map((doc14) => doc14.data());
|
|
4266
4624
|
}
|
|
4267
|
-
async function updateClinic(db, clinicId, data, adminId, clinicAdminService) {
|
|
4625
|
+
async function updateClinic(db, clinicId, data, adminId, clinicAdminService, app) {
|
|
4626
|
+
console.log("[CLINIC] Starting clinic update", { clinicId, adminId });
|
|
4268
4627
|
const clinic = await getClinic(db, clinicId);
|
|
4269
4628
|
if (!clinic) {
|
|
4629
|
+
console.error("[CLINIC] Clinic not found", { clinicId });
|
|
4270
4630
|
throw new Error("Clinic not found");
|
|
4271
4631
|
}
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4632
|
+
try {
|
|
4633
|
+
console.log("[CLINIC] Checking admin permissions");
|
|
4634
|
+
const admin = await clinicAdminService.getClinicAdmin(adminId);
|
|
4635
|
+
if (!admin) {
|
|
4636
|
+
console.error("[CLINIC] Admin not found", { adminId });
|
|
4637
|
+
throw new Error("Admin not found");
|
|
4638
|
+
}
|
|
4639
|
+
const hasPermission = admin.isGroupOwner && admin.clinicGroupId === clinic.clinicGroupId || admin.clinicsManaged.includes(clinicId) && clinic.admins && clinic.admins.includes(adminId);
|
|
4640
|
+
if (!hasPermission) {
|
|
4641
|
+
console.error(
|
|
4642
|
+
"[CLINIC] Admin does not have permission to update this clinic",
|
|
4643
|
+
{
|
|
4644
|
+
adminId,
|
|
4645
|
+
clinicId,
|
|
4646
|
+
isGroupOwner: admin.isGroupOwner,
|
|
4647
|
+
clinicsManaged: admin.clinicsManaged,
|
|
4648
|
+
isClinicAdmin: clinic.admins && clinic.admins.includes(adminId)
|
|
4649
|
+
}
|
|
4650
|
+
);
|
|
4651
|
+
throw new Error("Admin does not have permission to update this clinic");
|
|
4652
|
+
}
|
|
4653
|
+
console.log("[CLINIC] Admin permissions verified");
|
|
4654
|
+
} catch (adminError) {
|
|
4655
|
+
console.error("[CLINIC] Error verifying admin permissions:", adminError);
|
|
4656
|
+
throw adminError;
|
|
4657
|
+
}
|
|
4658
|
+
let updatedData = { ...data };
|
|
4659
|
+
if (data.logo && typeof data.logo === "string" && data.logo.startsWith("data:")) {
|
|
4660
|
+
console.log("[CLINIC] Processing logo update");
|
|
4661
|
+
try {
|
|
4662
|
+
const logoUrl = await uploadPhoto(
|
|
4663
|
+
data.logo,
|
|
4664
|
+
"clinics",
|
|
4665
|
+
clinicId,
|
|
4666
|
+
"logo",
|
|
4667
|
+
app
|
|
4668
|
+
);
|
|
4669
|
+
console.log("[CLINIC] Logo update processed", { logoUrl });
|
|
4670
|
+
if (logoUrl !== null) {
|
|
4671
|
+
updatedData.logo = logoUrl;
|
|
4672
|
+
}
|
|
4673
|
+
} catch (logoError) {
|
|
4674
|
+
console.error("[CLINIC] Error processing logo update:", logoError);
|
|
4675
|
+
}
|
|
4275
4676
|
}
|
|
4276
|
-
if (
|
|
4277
|
-
|
|
4677
|
+
if (data.photos && data.photos.length > 0) {
|
|
4678
|
+
console.log("[CLINIC] Processing regular photos update");
|
|
4679
|
+
try {
|
|
4680
|
+
const dataUrlPhotos = data.photos.filter(
|
|
4681
|
+
(photo) => typeof photo === "string" && photo.startsWith("data:")
|
|
4682
|
+
);
|
|
4683
|
+
const existingPhotos = data.photos.filter(
|
|
4684
|
+
(photo) => typeof photo === "string" && !photo.startsWith("data:")
|
|
4685
|
+
);
|
|
4686
|
+
if (dataUrlPhotos.length > 0) {
|
|
4687
|
+
const uploadedPhotos = await uploadMultiplePhotos(
|
|
4688
|
+
dataUrlPhotos,
|
|
4689
|
+
"clinics",
|
|
4690
|
+
clinicId,
|
|
4691
|
+
"photo",
|
|
4692
|
+
app
|
|
4693
|
+
);
|
|
4694
|
+
console.log("[CLINIC] Regular photos update processed", {
|
|
4695
|
+
count: uploadedPhotos.length
|
|
4696
|
+
});
|
|
4697
|
+
updatedData.photos = [...existingPhotos, ...uploadedPhotos];
|
|
4698
|
+
}
|
|
4699
|
+
} catch (photosError) {
|
|
4700
|
+
console.error(
|
|
4701
|
+
"[CLINIC] Error processing regular photos update:",
|
|
4702
|
+
photosError
|
|
4703
|
+
);
|
|
4704
|
+
updatedData.photos = data.photos.filter(
|
|
4705
|
+
(photo) => typeof photo === "string" && !photo.startsWith("data:")
|
|
4706
|
+
);
|
|
4707
|
+
}
|
|
4278
4708
|
}
|
|
4279
|
-
|
|
4280
|
-
|
|
4709
|
+
if (data.featuredPhotos && data.featuredPhotos.length > 0) {
|
|
4710
|
+
console.log("[CLINIC] Processing featured photos update");
|
|
4711
|
+
try {
|
|
4712
|
+
const dataUrlPhotos = data.featuredPhotos.filter(
|
|
4713
|
+
(photo) => typeof photo === "string" && photo.startsWith("data:")
|
|
4714
|
+
);
|
|
4715
|
+
const existingPhotos = data.featuredPhotos.filter(
|
|
4716
|
+
(photo) => typeof photo === "string" && !photo.startsWith("data:")
|
|
4717
|
+
);
|
|
4718
|
+
if (dataUrlPhotos.length > 0) {
|
|
4719
|
+
const uploadedPhotos = await uploadMultiplePhotos(
|
|
4720
|
+
dataUrlPhotos,
|
|
4721
|
+
"clinics",
|
|
4722
|
+
clinicId,
|
|
4723
|
+
"featured",
|
|
4724
|
+
app
|
|
4725
|
+
);
|
|
4726
|
+
console.log("[CLINIC] Featured photos update processed", {
|
|
4727
|
+
count: uploadedPhotos.length
|
|
4728
|
+
});
|
|
4729
|
+
updatedData.featuredPhotos = [...existingPhotos, ...uploadedPhotos];
|
|
4730
|
+
}
|
|
4731
|
+
} catch (featuredError) {
|
|
4732
|
+
console.error(
|
|
4733
|
+
"[CLINIC] Error processing featured photos update:",
|
|
4734
|
+
featuredError
|
|
4735
|
+
);
|
|
4736
|
+
updatedData.featuredPhotos = data.featuredPhotos.filter(
|
|
4737
|
+
(photo) => typeof photo === "string" && !photo.startsWith("data:")
|
|
4738
|
+
);
|
|
4739
|
+
}
|
|
4740
|
+
}
|
|
4741
|
+
if (data.photosWithTags && data.photosWithTags.length > 0) {
|
|
4742
|
+
console.log("[CLINIC] Processing photos with tags update");
|
|
4743
|
+
try {
|
|
4744
|
+
const updatedPhotosWithTags = [];
|
|
4745
|
+
for (const photoWithTag of data.photosWithTags) {
|
|
4746
|
+
if (photoWithTag.url && photoWithTag.url.startsWith("data:")) {
|
|
4747
|
+
const uploadedUrl = await uploadPhoto(
|
|
4748
|
+
photoWithTag.url,
|
|
4749
|
+
"clinics",
|
|
4750
|
+
clinicId,
|
|
4751
|
+
`tagged-${photoWithTag.tag}`,
|
|
4752
|
+
app
|
|
4753
|
+
);
|
|
4754
|
+
if (uploadedUrl) {
|
|
4755
|
+
updatedPhotosWithTags.push({
|
|
4756
|
+
url: uploadedUrl,
|
|
4757
|
+
tag: photoWithTag.tag
|
|
4758
|
+
});
|
|
4759
|
+
}
|
|
4760
|
+
} else {
|
|
4761
|
+
updatedPhotosWithTags.push(photoWithTag);
|
|
4762
|
+
}
|
|
4763
|
+
}
|
|
4764
|
+
updatedData.photosWithTags = updatedPhotosWithTags;
|
|
4765
|
+
console.log("[CLINIC] Photos with tags update processed", {
|
|
4766
|
+
count: updatedPhotosWithTags.length
|
|
4767
|
+
});
|
|
4768
|
+
} catch (tagsError) {
|
|
4769
|
+
console.error(
|
|
4770
|
+
"[CLINIC] Error processing photos with tags update:",
|
|
4771
|
+
tagsError
|
|
4772
|
+
);
|
|
4773
|
+
updatedData.photosWithTags = data.photosWithTags.filter(
|
|
4774
|
+
(photo) => !photo.url.startsWith("data:")
|
|
4775
|
+
);
|
|
4776
|
+
}
|
|
4777
|
+
}
|
|
4778
|
+
updatedData = {
|
|
4779
|
+
...updatedData,
|
|
4281
4780
|
updatedAt: import_firestore16.Timestamp.now()
|
|
4282
4781
|
};
|
|
4283
|
-
|
|
4782
|
+
console.log("[CLINIC] Updating clinic in Firestore");
|
|
4783
|
+
try {
|
|
4784
|
+
await (0, import_firestore16.updateDoc)((0, import_firestore16.doc)(db, CLINICS_COLLECTION, clinicId), updatedData);
|
|
4785
|
+
console.log("[CLINIC] Clinic updated successfully");
|
|
4786
|
+
} catch (updateError) {
|
|
4787
|
+
console.error("[CLINIC] Error updating clinic in Firestore:", updateError);
|
|
4788
|
+
throw updateError;
|
|
4789
|
+
}
|
|
4284
4790
|
const updatedClinic = await getClinic(db, clinicId);
|
|
4285
4791
|
if (!updatedClinic) {
|
|
4792
|
+
console.error("[CLINIC] Failed to retrieve updated clinic");
|
|
4286
4793
|
throw new Error("Failed to retrieve updated clinic");
|
|
4287
4794
|
}
|
|
4795
|
+
console.log("[CLINIC] Clinic update completed successfully");
|
|
4288
4796
|
return updatedClinic;
|
|
4289
4797
|
}
|
|
4290
4798
|
async function deactivateClinic(db, clinicId, adminId, clinicAdminService) {
|
|
@@ -4296,7 +4804,8 @@ async function deactivateClinic(db, clinicId, adminId, clinicAdminService) {
|
|
|
4296
4804
|
if (!admin) {
|
|
4297
4805
|
throw new Error("Admin not found");
|
|
4298
4806
|
}
|
|
4299
|
-
|
|
4807
|
+
const hasPermission = admin.isGroupOwner && admin.clinicGroupId === clinic.clinicGroupId || admin.clinicsManaged.includes(clinicId) && clinic.admins && clinic.admins.includes(adminId);
|
|
4808
|
+
if (!hasPermission) {
|
|
4300
4809
|
throw new Error("Admin does not have permission to deactivate this clinic");
|
|
4301
4810
|
}
|
|
4302
4811
|
await (0, import_firestore16.updateDoc)((0, import_firestore16.doc)(db, CLINICS_COLLECTION, clinicId), {
|
|
@@ -4339,24 +4848,24 @@ async function getActiveClinicsByAdmin(db, adminId, clinicAdminService, clinicGr
|
|
|
4339
4848
|
|
|
4340
4849
|
// src/services/clinic/utils/review.utils.ts
|
|
4341
4850
|
var import_firestore17 = require("firebase/firestore");
|
|
4342
|
-
async function addReview(db, clinicId, review) {
|
|
4343
|
-
const
|
|
4344
|
-
|
|
4851
|
+
async function addReview(db, clinicId, review, app) {
|
|
4852
|
+
const clinicRef = (0, import_firestore17.doc)(db, "clinics", clinicId);
|
|
4853
|
+
const clinicSnap = await (0, import_firestore17.getDoc)(clinicRef);
|
|
4854
|
+
if (!clinicSnap.exists()) {
|
|
4345
4855
|
throw new Error("Clinic not found");
|
|
4346
4856
|
}
|
|
4857
|
+
const clinic = clinicSnap.data();
|
|
4347
4858
|
const now = import_firestore17.Timestamp.now();
|
|
4348
4859
|
const reviewData = {
|
|
4860
|
+
...review,
|
|
4349
4861
|
id: (0, import_firestore17.doc)((0, import_firestore17.collection)(db, "clinic_reviews")).id,
|
|
4350
4862
|
clinicId,
|
|
4351
|
-
patientId: review.patientId,
|
|
4352
|
-
rating: review.rating,
|
|
4353
|
-
comment: review.comment,
|
|
4354
4863
|
createdAt: now,
|
|
4355
4864
|
updatedAt: now,
|
|
4356
4865
|
isVerified: false
|
|
4357
4866
|
};
|
|
4358
4867
|
clinicReviewSchema.parse(reviewData);
|
|
4359
|
-
await (0, import_firestore17.
|
|
4868
|
+
await (0, import_firestore17.addDoc)((0, import_firestore17.collection)(db, "clinic_reviews"), reviewData);
|
|
4360
4869
|
const newRating = clinic.rating ? {
|
|
4361
4870
|
average: (clinic.rating.average * clinic.rating.count + review.rating) / (clinic.rating.count + 1),
|
|
4362
4871
|
count: clinic.rating.count + 1
|
|
@@ -4372,28 +4881,24 @@ async function addReview(db, clinicId, review) {
|
|
|
4372
4881
|
...clinic.reviewsInfo,
|
|
4373
4882
|
{
|
|
4374
4883
|
id: reviewData.id,
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
// This should be fetched from patient service
|
|
4380
|
-
patientPhoto: "",
|
|
4381
|
-
// This should be fetched from patient service
|
|
4382
|
-
createdAt: now,
|
|
4383
|
-
updatedAt: now
|
|
4884
|
+
patientId: reviewData.patientId,
|
|
4885
|
+
rating: reviewData.rating,
|
|
4886
|
+
comment: reviewData.comment,
|
|
4887
|
+
createdAt: reviewData.createdAt
|
|
4384
4888
|
}
|
|
4385
4889
|
]
|
|
4386
4890
|
},
|
|
4387
|
-
|
|
4388
|
-
//
|
|
4389
|
-
|
|
4390
|
-
//
|
|
4891
|
+
"system",
|
|
4892
|
+
// System update, no admin ID needed
|
|
4893
|
+
null,
|
|
4894
|
+
// No clinic admin service needed for system updates
|
|
4895
|
+
app
|
|
4391
4896
|
);
|
|
4392
4897
|
return reviewData;
|
|
4393
4898
|
}
|
|
4394
4899
|
|
|
4395
4900
|
// src/services/clinic/utils/tag.utils.ts
|
|
4396
|
-
async function addTags(db, clinicId, adminId, newTags, clinicAdminService) {
|
|
4901
|
+
async function addTags(db, clinicId, adminId, newTags, clinicAdminService, app) {
|
|
4397
4902
|
const clinic = await getClinic(db, clinicId);
|
|
4398
4903
|
if (!clinic) {
|
|
4399
4904
|
throw new Error("Clinic not found");
|
|
@@ -4402,7 +4907,8 @@ async function addTags(db, clinicId, adminId, newTags, clinicAdminService) {
|
|
|
4402
4907
|
if (!admin) {
|
|
4403
4908
|
throw new Error("Admin not found");
|
|
4404
4909
|
}
|
|
4405
|
-
|
|
4910
|
+
const hasPermission = admin.isGroupOwner && admin.clinicGroupId === clinic.clinicGroupId || admin.clinicsManaged.includes(clinicId) && clinic.admins && clinic.admins.includes(adminId);
|
|
4911
|
+
if (!hasPermission) {
|
|
4406
4912
|
throw new Error("Admin does not have permission to update this clinic");
|
|
4407
4913
|
}
|
|
4408
4914
|
const updatedTags = [.../* @__PURE__ */ new Set([...clinic.tags, ...newTags.tags || []])];
|
|
@@ -4413,10 +4919,11 @@ async function addTags(db, clinicId, adminId, newTags, clinicAdminService) {
|
|
|
4413
4919
|
tags: updatedTags
|
|
4414
4920
|
},
|
|
4415
4921
|
adminId,
|
|
4416
|
-
clinicAdminService
|
|
4922
|
+
clinicAdminService,
|
|
4923
|
+
app
|
|
4417
4924
|
);
|
|
4418
4925
|
}
|
|
4419
|
-
async function removeTags(db, clinicId, adminId, tagsToRemove, clinicAdminService) {
|
|
4926
|
+
async function removeTags(db, clinicId, adminId, tagsToRemove, clinicAdminService, app) {
|
|
4420
4927
|
const clinic = await getClinic(db, clinicId);
|
|
4421
4928
|
if (!clinic) {
|
|
4422
4929
|
throw new Error("Clinic not found");
|
|
@@ -4425,14 +4932,12 @@ async function removeTags(db, clinicId, adminId, tagsToRemove, clinicAdminServic
|
|
|
4425
4932
|
if (!admin) {
|
|
4426
4933
|
throw new Error("Admin not found");
|
|
4427
4934
|
}
|
|
4428
|
-
|
|
4935
|
+
const hasPermission = admin.isGroupOwner && admin.clinicGroupId === clinic.clinicGroupId || admin.clinicsManaged.includes(clinicId) && clinic.admins && clinic.admins.includes(adminId);
|
|
4936
|
+
if (!hasPermission) {
|
|
4429
4937
|
throw new Error("Admin does not have permission to update this clinic");
|
|
4430
4938
|
}
|
|
4431
4939
|
const updatedTags = clinic.tags.filter(
|
|
4432
|
-
(tag) =>
|
|
4433
|
-
var _a;
|
|
4434
|
-
return !((_a = tagsToRemove.tags) == null ? void 0 : _a.includes(tag));
|
|
4435
|
-
}
|
|
4940
|
+
(tag) => !tagsToRemove.tags || !tagsToRemove.tags.includes(tag)
|
|
4436
4941
|
);
|
|
4437
4942
|
return updateClinic(
|
|
4438
4943
|
db,
|
|
@@ -4441,7 +4946,8 @@ async function removeTags(db, clinicId, adminId, tagsToRemove, clinicAdminServic
|
|
|
4441
4946
|
tags: updatedTags
|
|
4442
4947
|
},
|
|
4443
4948
|
adminId,
|
|
4444
|
-
clinicAdminService
|
|
4949
|
+
clinicAdminService,
|
|
4950
|
+
app
|
|
4445
4951
|
);
|
|
4446
4952
|
}
|
|
4447
4953
|
|
|
@@ -4511,7 +5017,8 @@ var ClinicService = class extends BaseService {
|
|
|
4511
5017
|
data,
|
|
4512
5018
|
creatorAdminId,
|
|
4513
5019
|
this.clinicGroupService,
|
|
4514
|
-
this.clinicAdminService
|
|
5020
|
+
this.clinicAdminService,
|
|
5021
|
+
this.app
|
|
4515
5022
|
);
|
|
4516
5023
|
}
|
|
4517
5024
|
/**
|
|
@@ -4546,14 +5053,15 @@ var ClinicService = class extends BaseService {
|
|
|
4546
5053
|
clinicId,
|
|
4547
5054
|
data,
|
|
4548
5055
|
adminId,
|
|
4549
|
-
this.clinicAdminService
|
|
5056
|
+
this.clinicAdminService,
|
|
5057
|
+
this.app
|
|
4550
5058
|
);
|
|
4551
5059
|
}
|
|
4552
5060
|
/**
|
|
4553
5061
|
* Dodaje recenziju klinici
|
|
4554
5062
|
*/
|
|
4555
5063
|
async addReview(clinicId, review) {
|
|
4556
|
-
return addReview(this.db, clinicId, review);
|
|
5064
|
+
return addReview(this.db, clinicId, review, this.app);
|
|
4557
5065
|
}
|
|
4558
5066
|
/**
|
|
4559
5067
|
* Deaktivira kliniku
|
|
@@ -4575,7 +5083,8 @@ var ClinicService = class extends BaseService {
|
|
|
4575
5083
|
clinicId,
|
|
4576
5084
|
adminId,
|
|
4577
5085
|
newTags,
|
|
4578
|
-
this.clinicAdminService
|
|
5086
|
+
this.clinicAdminService,
|
|
5087
|
+
this.app
|
|
4579
5088
|
);
|
|
4580
5089
|
}
|
|
4581
5090
|
/**
|
|
@@ -4587,7 +5096,8 @@ var ClinicService = class extends BaseService {
|
|
|
4587
5096
|
clinicId,
|
|
4588
5097
|
adminId,
|
|
4589
5098
|
tagsToRemove,
|
|
4590
|
-
this.clinicAdminService
|
|
5099
|
+
this.clinicAdminService,
|
|
5100
|
+
this.app
|
|
4591
5101
|
);
|
|
4592
5102
|
}
|
|
4593
5103
|
/**
|
|
@@ -4622,12 +5132,21 @@ var ClinicService = class extends BaseService {
|
|
|
4622
5132
|
* @returns The created clinic
|
|
4623
5133
|
*/
|
|
4624
5134
|
async createClinicBranch(clinicGroupId, setupData, adminId) {
|
|
5135
|
+
var _a, _b;
|
|
5136
|
+
console.log("[CLINIC_SERVICE] Starting clinic branch creation", {
|
|
5137
|
+
clinicGroupId,
|
|
5138
|
+
adminId
|
|
5139
|
+
});
|
|
4625
5140
|
const clinicGroup = await this.clinicGroupService.getClinicGroup(
|
|
4626
5141
|
clinicGroupId
|
|
4627
5142
|
);
|
|
4628
5143
|
if (!clinicGroup) {
|
|
5144
|
+
console.error("[CLINIC_SERVICE] Clinic group not found", {
|
|
5145
|
+
clinicGroupId
|
|
5146
|
+
});
|
|
4629
5147
|
throw new Error(`Clinic group with ID ${clinicGroupId} not found`);
|
|
4630
5148
|
}
|
|
5149
|
+
console.log("[CLINIC_SERVICE] Clinic group verified");
|
|
4631
5150
|
const createClinicData = {
|
|
4632
5151
|
clinicGroupId,
|
|
4633
5152
|
name: setupData.name,
|
|
@@ -4636,8 +5155,8 @@ var ClinicService = class extends BaseService {
|
|
|
4636
5155
|
contactInfo: setupData.contactInfo,
|
|
4637
5156
|
workingHours: setupData.workingHours,
|
|
4638
5157
|
tags: setupData.tags,
|
|
4639
|
-
photos: setupData.photos,
|
|
4640
|
-
photosWithTags: setupData.photosWithTags,
|
|
5158
|
+
photos: setupData.photos || [],
|
|
5159
|
+
photosWithTags: setupData.photosWithTags || [],
|
|
4641
5160
|
doctors: [],
|
|
4642
5161
|
services: [],
|
|
4643
5162
|
admins: [adminId],
|
|
@@ -4646,7 +5165,17 @@ var ClinicService = class extends BaseService {
|
|
|
4646
5165
|
logo: setupData.logo,
|
|
4647
5166
|
featuredPhotos: setupData.featuredPhotos || []
|
|
4648
5167
|
};
|
|
5168
|
+
console.log("[CLINIC_SERVICE] Creating clinic branch with data", {
|
|
5169
|
+
name: createClinicData.name,
|
|
5170
|
+
hasLogo: !!createClinicData.logo,
|
|
5171
|
+
photosCount: createClinicData.photos.length,
|
|
5172
|
+
featuredPhotosCount: ((_a = createClinicData.featuredPhotos) == null ? void 0 : _a.length) || 0,
|
|
5173
|
+
photosWithTagsCount: ((_b = createClinicData.photosWithTags) == null ? void 0 : _b.length) || 0
|
|
5174
|
+
});
|
|
4649
5175
|
const clinic = await this.createClinic(createClinicData, adminId);
|
|
5176
|
+
console.log("[CLINIC_SERVICE] Clinic branch created successfully", {
|
|
5177
|
+
clinicId: clinic.id
|
|
5178
|
+
});
|
|
4650
5179
|
return clinic;
|
|
4651
5180
|
}
|
|
4652
5181
|
};
|
|
@@ -4768,7 +5297,7 @@ var AuthService = class extends BaseService {
|
|
|
4768
5297
|
"Clinic group data is required when creating a new group"
|
|
4769
5298
|
);
|
|
4770
5299
|
}
|
|
4771
|
-
console.log("[AUTH] Creating clinic admin first");
|
|
5300
|
+
console.log("[AUTH] Creating clinic admin first (without group)");
|
|
4772
5301
|
const createClinicAdminData = {
|
|
4773
5302
|
userRef: firebaseUser.uid,
|
|
4774
5303
|
isGroupOwner: true,
|
|
@@ -4776,10 +5305,16 @@ var AuthService = class extends BaseService {
|
|
|
4776
5305
|
contactInfo: contactPerson,
|
|
4777
5306
|
roleTitle: data.title,
|
|
4778
5307
|
isActive: true
|
|
5308
|
+
// No clinicGroupId yet
|
|
4779
5309
|
};
|
|
5310
|
+
let adminProfile;
|
|
4780
5311
|
try {
|
|
4781
|
-
await clinicAdminService.createClinicAdmin(
|
|
4782
|
-
|
|
5312
|
+
adminProfile = await clinicAdminService.createClinicAdmin(
|
|
5313
|
+
createClinicAdminData
|
|
5314
|
+
);
|
|
5315
|
+
console.log("[AUTH] Clinic admin created successfully", {
|
|
5316
|
+
adminId: adminProfile.id
|
|
5317
|
+
});
|
|
4783
5318
|
} catch (adminCreationError) {
|
|
4784
5319
|
console.error(
|
|
4785
5320
|
"[AUTH] Clinic admin creation failed:",
|
|
@@ -4792,7 +5327,8 @@ var AuthService = class extends BaseService {
|
|
|
4792
5327
|
hqLocation: data.clinicGroupData.hqLocation,
|
|
4793
5328
|
contactInfo: data.clinicGroupData.contactInfo,
|
|
4794
5329
|
contactPerson,
|
|
4795
|
-
ownerId:
|
|
5330
|
+
ownerId: adminProfile.id,
|
|
5331
|
+
// Use admin profile ID, not user UID
|
|
4796
5332
|
isActive: true,
|
|
4797
5333
|
logo: data.clinicGroupData.logo || null,
|
|
4798
5334
|
subscriptionModel: data.clinicGroupData.subscriptionModel || "no_subscription" /* NO_SUBSCRIPTION */
|
|
@@ -4800,13 +5336,24 @@ var AuthService = class extends BaseService {
|
|
|
4800
5336
|
console.log("[AUTH] Clinic group data prepared", {
|
|
4801
5337
|
groupName: createClinicGroupData.name
|
|
4802
5338
|
});
|
|
5339
|
+
let clinicGroup;
|
|
4803
5340
|
try {
|
|
4804
|
-
await clinicGroupService.createClinicGroup(
|
|
5341
|
+
clinicGroup = await clinicGroupService.createClinicGroup(
|
|
4805
5342
|
createClinicGroupData,
|
|
4806
|
-
|
|
4807
|
-
|
|
5343
|
+
adminProfile.id,
|
|
5344
|
+
// Use admin profile ID, not user UID
|
|
5345
|
+
false
|
|
5346
|
+
// This is not a default group since we're providing complete data
|
|
4808
5347
|
);
|
|
4809
|
-
console.log("[AUTH] Clinic group created successfully"
|
|
5348
|
+
console.log("[AUTH] Clinic group created successfully", {
|
|
5349
|
+
groupId: clinicGroup.id
|
|
5350
|
+
});
|
|
5351
|
+
console.log("[AUTH] Updating admin with clinic group ID");
|
|
5352
|
+
await clinicAdminService.updateClinicAdmin(adminProfile.id, {
|
|
5353
|
+
// Use admin profile ID, not user UID
|
|
5354
|
+
clinicGroupId: clinicGroup.id
|
|
5355
|
+
});
|
|
5356
|
+
console.log("[AUTH] Admin updated with clinic group ID successfully");
|
|
4810
5357
|
} catch (groupCreationError) {
|
|
4811
5358
|
console.error(
|
|
4812
5359
|
"[AUTH] Clinic group creation failed:",
|
|
@@ -4879,9 +5426,14 @@ var AuthService = class extends BaseService {
|
|
|
4879
5426
|
roleTitle: data.title,
|
|
4880
5427
|
isActive: true
|
|
4881
5428
|
};
|
|
5429
|
+
let adminProfile;
|
|
4882
5430
|
try {
|
|
4883
|
-
await clinicAdminService.createClinicAdmin(
|
|
4884
|
-
|
|
5431
|
+
adminProfile = await clinicAdminService.createClinicAdmin(
|
|
5432
|
+
createClinicAdminData
|
|
5433
|
+
);
|
|
5434
|
+
console.log("[AUTH] Clinic admin created successfully", {
|
|
5435
|
+
adminId: adminProfile.id
|
|
5436
|
+
});
|
|
4885
5437
|
} catch (adminCreationError) {
|
|
4886
5438
|
console.error(
|
|
4887
5439
|
"[AUTH] Clinic admin creation failed:",
|