@blackcode_sa/metaestetics-api 1.7.20 → 1.7.21

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.js CHANGED
@@ -1194,12 +1194,309 @@ var USER_ERRORS = {
1194
1194
  var import_zod16 = require("zod");
1195
1195
 
1196
1196
  // src/services/patient/patient.service.ts
1197
- var import_firestore12 = require("firebase/firestore");
1197
+ var import_firestore14 = require("firebase/firestore");
1198
1198
 
1199
- // src/services/patient/utils/profile.utils.ts
1200
- var import_firestore8 = require("firebase/firestore");
1199
+ // src/services/media/media.service.ts
1200
+ var import_firestore2 = require("firebase/firestore");
1201
1201
  var import_storage3 = require("firebase/storage");
1202
- var import_zod8 = require("zod");
1202
+ var import_firestore3 = require("firebase/firestore");
1203
+ var MediaAccessLevel = /* @__PURE__ */ ((MediaAccessLevel2) => {
1204
+ MediaAccessLevel2["PUBLIC"] = "public";
1205
+ MediaAccessLevel2["PRIVATE"] = "private";
1206
+ MediaAccessLevel2["CONFIDENTIAL"] = "confidential";
1207
+ return MediaAccessLevel2;
1208
+ })(MediaAccessLevel || {});
1209
+ var MEDIA_METADATA_COLLECTION = "media_metadata";
1210
+ var MediaService = class extends BaseService {
1211
+ constructor(db, auth, app) {
1212
+ super(db, auth, app);
1213
+ }
1214
+ /**
1215
+ * Upload a media file, store its metadata, and return the metadata including the URL.
1216
+ * @param file - The file to upload.
1217
+ * @param ownerId - ID of the owner (user, patient, clinic, etc.).
1218
+ * @param accessLevel - Access level (public, private, confidential).
1219
+ * @param collectionName - The logical collection name this media belongs to (e.g., 'patient_profile_pictures', 'clinic_logos').
1220
+ * @param originalFileName - Optional: the original name of the file, if not using file.name.
1221
+ * @returns Promise with the media metadata.
1222
+ */
1223
+ async uploadMedia(file, ownerId, accessLevel, collectionName, originalFileName) {
1224
+ const mediaId = this.generateId();
1225
+ const fileNameToUse = originalFileName || (file instanceof File ? file.name : file.toString());
1226
+ const uniqueFileName = `${mediaId}-${fileNameToUse}`;
1227
+ const filePath = `media/${accessLevel}/${ownerId}/${collectionName}/${uniqueFileName}`;
1228
+ console.log(`[MediaService] Uploading file to: ${filePath}`);
1229
+ const storageRef = (0, import_storage3.ref)(this.storage, filePath);
1230
+ try {
1231
+ const uploadResult = await (0, import_storage3.uploadBytes)(storageRef, file, {
1232
+ contentType: file.type
1233
+ });
1234
+ console.log("[MediaService] File uploaded successfully", uploadResult);
1235
+ const downloadURL = await (0, import_storage3.getDownloadURL)(uploadResult.ref);
1236
+ console.log("[MediaService] Got download URL:", downloadURL);
1237
+ const metadata = {
1238
+ id: mediaId,
1239
+ name: fileNameToUse,
1240
+ url: downloadURL,
1241
+ contentType: file.type,
1242
+ size: file.size,
1243
+ createdAt: import_firestore2.Timestamp.now(),
1244
+ accessLevel,
1245
+ ownerId,
1246
+ collectionName,
1247
+ path: filePath
1248
+ };
1249
+ const metadataDocRef = (0, import_firestore3.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
1250
+ await (0, import_firestore3.setDoc)(metadataDocRef, metadata);
1251
+ console.log("[MediaService] Metadata stored in Firestore:", mediaId);
1252
+ return metadata;
1253
+ } catch (error) {
1254
+ console.error("[MediaService] Error during media upload:", error);
1255
+ throw error;
1256
+ }
1257
+ }
1258
+ /**
1259
+ * Get media metadata from Firestore by its ID.
1260
+ * @param mediaId - ID of the media.
1261
+ * @returns Promise with the media metadata or null if not found.
1262
+ */
1263
+ async getMediaMetadata(mediaId) {
1264
+ console.log(`[MediaService] Getting media metadata for ID: ${mediaId}`);
1265
+ const docRef = (0, import_firestore3.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
1266
+ const docSnap = await (0, import_firestore3.getDoc)(docRef);
1267
+ if (docSnap.exists()) {
1268
+ console.log("[MediaService] Metadata found:", docSnap.data());
1269
+ return docSnap.data();
1270
+ }
1271
+ console.log("[MediaService] No metadata found for ID:", mediaId);
1272
+ return null;
1273
+ }
1274
+ /**
1275
+ * Get media metadata from Firestore by its public URL.
1276
+ * @param url - The public URL of the media file.
1277
+ * @returns Promise with the media metadata or null if not found.
1278
+ */
1279
+ async getMediaMetadataByUrl(url) {
1280
+ console.log(`[MediaService] Getting media metadata by URL: ${url}`);
1281
+ const q = (0, import_firestore3.query)(
1282
+ (0, import_firestore3.collection)(this.db, MEDIA_METADATA_COLLECTION),
1283
+ (0, import_firestore3.where)("url", "==", url),
1284
+ (0, import_firestore3.limit)(1)
1285
+ );
1286
+ try {
1287
+ const querySnapshot = await (0, import_firestore3.getDocs)(q);
1288
+ if (!querySnapshot.empty) {
1289
+ const metadata = querySnapshot.docs[0].data();
1290
+ console.log("[MediaService] Metadata found by URL:", metadata);
1291
+ return metadata;
1292
+ }
1293
+ console.log("[MediaService] No metadata found for URL:", url);
1294
+ return null;
1295
+ } catch (error) {
1296
+ console.error("[MediaService] Error fetching metadata by URL:", error);
1297
+ throw error;
1298
+ }
1299
+ }
1300
+ /**
1301
+ * Delete media from storage and remove metadata from Firestore.
1302
+ * @param mediaId - ID of the media to delete.
1303
+ */
1304
+ async deleteMedia(mediaId) {
1305
+ console.log(`[MediaService] Deleting media with ID: ${mediaId}`);
1306
+ const metadata = await this.getMediaMetadata(mediaId);
1307
+ if (!metadata) {
1308
+ console.warn(
1309
+ `[MediaService] Metadata not found for media ID ${mediaId}. Cannot delete.`
1310
+ );
1311
+ return;
1312
+ }
1313
+ const storageFileRef = (0, import_storage3.ref)(this.storage, metadata.path);
1314
+ try {
1315
+ await (0, import_storage3.deleteObject)(storageFileRef);
1316
+ console.log(`[MediaService] File deleted from Storage: ${metadata.path}`);
1317
+ const metadataDocRef = (0, import_firestore3.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
1318
+ await (0, import_firestore3.deleteDoc)(metadataDocRef);
1319
+ console.log(
1320
+ `[MediaService] Metadata deleted from Firestore for ID: ${mediaId}`
1321
+ );
1322
+ } catch (error) {
1323
+ console.error(`[MediaService] Error deleting media ${mediaId}:`, error);
1324
+ throw error;
1325
+ }
1326
+ }
1327
+ /**
1328
+ * Update media access level. This involves moving the file in Firebase Storage
1329
+ * to a new path reflecting the new access level, and updating its metadata.
1330
+ * @param mediaId - ID of the media to update.
1331
+ * @param newAccessLevel - New access level.
1332
+ * @returns Promise with the updated media metadata, or null if metadata not found.
1333
+ */
1334
+ async updateMediaAccessLevel(mediaId, newAccessLevel) {
1335
+ var _a;
1336
+ console.log(
1337
+ `[MediaService] Attempting to update access level for media ID: ${mediaId} to ${newAccessLevel}`
1338
+ );
1339
+ const metadata = await this.getMediaMetadata(mediaId);
1340
+ if (!metadata) {
1341
+ console.warn(
1342
+ `[MediaService] Metadata not found for media ID ${mediaId}. Cannot update access level.`
1343
+ );
1344
+ return null;
1345
+ }
1346
+ if (metadata.accessLevel === newAccessLevel) {
1347
+ console.log(
1348
+ `[MediaService] Media ID ${mediaId} already has access level ${newAccessLevel}. Updating timestamp only.`
1349
+ );
1350
+ const metadataDocRef = (0, import_firestore3.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
1351
+ try {
1352
+ await (0, import_firestore3.updateDoc)(metadataDocRef, { updatedAt: import_firestore2.Timestamp.now() });
1353
+ return { ...metadata, updatedAt: import_firestore2.Timestamp.now() };
1354
+ } catch (error) {
1355
+ console.error(
1356
+ `[MediaService] Error updating timestamp for media ID ${mediaId}:`,
1357
+ error
1358
+ );
1359
+ throw error;
1360
+ }
1361
+ }
1362
+ const oldStoragePath = metadata.path;
1363
+ const fileNamePart = `${metadata.id}-${metadata.name}`;
1364
+ const newStoragePath = `media/${newAccessLevel}/${metadata.ownerId}/${metadata.collectionName}/${fileNamePart}`;
1365
+ console.log(
1366
+ `[MediaService] Moving file for ${mediaId} from ${oldStoragePath} to ${newStoragePath}`
1367
+ );
1368
+ const oldStorageFileRef = (0, import_storage3.ref)(this.storage, oldStoragePath);
1369
+ const newStorageFileRef = (0, import_storage3.ref)(this.storage, newStoragePath);
1370
+ try {
1371
+ console.log(`[MediaService] Downloading bytes from ${oldStoragePath}`);
1372
+ const fileBytes = await (0, import_storage3.getBytes)(oldStorageFileRef);
1373
+ console.log(
1374
+ `[MediaService] Successfully downloaded ${fileBytes.byteLength} bytes from ${oldStoragePath}`
1375
+ );
1376
+ console.log(`[MediaService] Uploading bytes to ${newStoragePath}`);
1377
+ await (0, import_storage3.uploadBytes)(newStorageFileRef, fileBytes, {
1378
+ contentType: metadata.contentType
1379
+ });
1380
+ console.log(
1381
+ `[MediaService] Successfully uploaded bytes to ${newStoragePath}`
1382
+ );
1383
+ const newDownloadURL = await (0, import_storage3.getDownloadURL)(newStorageFileRef);
1384
+ console.log(
1385
+ `[MediaService] Got new download URL for ${newStoragePath}: ${newDownloadURL}`
1386
+ );
1387
+ const updateData = {
1388
+ accessLevel: newAccessLevel,
1389
+ path: newStoragePath,
1390
+ url: newDownloadURL,
1391
+ updatedAt: import_firestore2.Timestamp.now()
1392
+ };
1393
+ const metadataDocRef = (0, import_firestore3.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
1394
+ console.log(
1395
+ `[MediaService] Updating Firestore metadata for ${mediaId} with new data:`,
1396
+ updateData
1397
+ );
1398
+ await (0, import_firestore3.updateDoc)(metadataDocRef, updateData);
1399
+ console.log(
1400
+ `[MediaService] Successfully updated Firestore metadata for ${mediaId}`
1401
+ );
1402
+ try {
1403
+ console.log(`[MediaService] Deleting old file from ${oldStoragePath}`);
1404
+ await (0, import_storage3.deleteObject)(oldStorageFileRef);
1405
+ console.log(
1406
+ `[MediaService] Successfully deleted old file from ${oldStoragePath}`
1407
+ );
1408
+ } catch (deleteError) {
1409
+ console.error(
1410
+ `[MediaService] Failed to delete old file from ${oldStoragePath} for media ID ${mediaId}. This file is now orphaned. Error:`,
1411
+ deleteError
1412
+ );
1413
+ }
1414
+ return { ...metadata, ...updateData };
1415
+ } catch (error) {
1416
+ console.error(
1417
+ `[MediaService] Error updating media access level and moving file for ${mediaId}:`,
1418
+ error
1419
+ );
1420
+ if (newStorageFileRef && error.code !== "storage/object-not-found" && ((_a = error.message) == null ? void 0 : _a.includes("uploadBytes"))) {
1421
+ console.warn(
1422
+ `[MediaService] Attempting to delete partially uploaded file at ${newStoragePath} due to error.`
1423
+ );
1424
+ try {
1425
+ await (0, import_storage3.deleteObject)(newStorageFileRef);
1426
+ console.warn(
1427
+ `[MediaService] Cleaned up partially uploaded file at ${newStoragePath}.`
1428
+ );
1429
+ } catch (cleanupError) {
1430
+ console.error(
1431
+ `[MediaService] Failed to cleanup partially uploaded file at ${newStoragePath}:`,
1432
+ cleanupError
1433
+ );
1434
+ }
1435
+ }
1436
+ throw error;
1437
+ }
1438
+ }
1439
+ /**
1440
+ * List all media for an owner, optionally filtered by collection and access level.
1441
+ * @param ownerId - ID of the owner.
1442
+ * @param collectionName - Optional: Filter by collection name.
1443
+ * @param accessLevel - Optional: Filter by access level.
1444
+ * @param count - Optional: Number of items to fetch.
1445
+ * @param startAfterId - Optional: ID of the document to start after (for pagination).
1446
+ */
1447
+ async listMedia(ownerId, collectionName, accessLevel, count, startAfterId) {
1448
+ console.log(`[MediaService] Listing media for owner: ${ownerId}`);
1449
+ let qConstraints = [(0, import_firestore3.where)("ownerId", "==", ownerId)];
1450
+ if (collectionName) {
1451
+ qConstraints.push((0, import_firestore3.where)("collectionName", "==", collectionName));
1452
+ }
1453
+ if (accessLevel) {
1454
+ qConstraints.push((0, import_firestore3.where)("accessLevel", "==", accessLevel));
1455
+ }
1456
+ qConstraints.push((0, import_firestore3.orderBy)("createdAt", "desc"));
1457
+ if (count) {
1458
+ qConstraints.push((0, import_firestore3.limit)(count));
1459
+ }
1460
+ if (startAfterId) {
1461
+ const startAfterDoc = await this.getMediaMetadata(startAfterId);
1462
+ if (startAfterDoc) {
1463
+ }
1464
+ }
1465
+ const finalQuery = (0, import_firestore3.query)(
1466
+ (0, import_firestore3.collection)(this.db, MEDIA_METADATA_COLLECTION),
1467
+ ...qConstraints
1468
+ );
1469
+ try {
1470
+ const querySnapshot = await (0, import_firestore3.getDocs)(finalQuery);
1471
+ const mediaList = querySnapshot.docs.map(
1472
+ (doc34) => doc34.data()
1473
+ );
1474
+ console.log(`[MediaService] Found ${mediaList.length} media items.`);
1475
+ return mediaList;
1476
+ } catch (error) {
1477
+ console.error("[MediaService] Error listing media:", error);
1478
+ throw error;
1479
+ }
1480
+ }
1481
+ /**
1482
+ * Get download URL for media. (Convenience, as URL is in metadata)
1483
+ * @param mediaId - ID of the media.
1484
+ */
1485
+ async getMediaDownloadUrl(mediaId) {
1486
+ console.log(`[MediaService] Getting download URL for media ID: ${mediaId}`);
1487
+ const metadata = await this.getMediaMetadata(mediaId);
1488
+ if (metadata && metadata.url) {
1489
+ console.log(`[MediaService] URL found: ${metadata.url}`);
1490
+ return metadata.url;
1491
+ }
1492
+ console.log(`[MediaService] URL not found for media ID: ${mediaId}`);
1493
+ return null;
1494
+ }
1495
+ };
1496
+
1497
+ // src/services/patient/utils/profile.utils.ts
1498
+ var import_firestore10 = require("firebase/firestore");
1499
+ var import_zod9 = require("zod");
1203
1500
 
1204
1501
  // src/types/patient/medical-info.types.ts
1205
1502
  var PATIENT_MEDICAL_INFO_COLLECTION = "medical_info";
@@ -1228,11 +1525,19 @@ var Gender = /* @__PURE__ */ ((Gender2) => {
1228
1525
  })(Gender || {});
1229
1526
 
1230
1527
  // src/validations/patient.schema.ts
1231
- var import_zod6 = require("zod");
1232
- var import_firestore3 = require("firebase/firestore");
1528
+ var import_zod7 = require("zod");
1529
+ var import_firestore5 = require("firebase/firestore");
1530
+
1531
+ // src/validations/media.schema.ts
1532
+ var import_zod4 = require("zod");
1533
+ var mediaResourceSchema = import_zod4.z.union([
1534
+ import_zod4.z.string().url(),
1535
+ import_zod4.z.instanceof(File),
1536
+ import_zod4.z.instanceof(Blob)
1537
+ ]);
1233
1538
 
1234
1539
  // src/validations/patient/medical-info.schema.ts
1235
- var import_zod5 = require("zod");
1540
+ var import_zod6 = require("zod");
1236
1541
 
1237
1542
  // src/types/patient/allergies.ts
1238
1543
  var AllergyType = /* @__PURE__ */ ((AllergyType2) => {
@@ -1321,80 +1626,80 @@ var Contraindication = /* @__PURE__ */ ((Contraindication2) => {
1321
1626
  })(Contraindication || {});
1322
1627
 
1323
1628
  // src/validations/common.schema.ts
1324
- var import_zod4 = require("zod");
1325
- var import_firestore2 = require("firebase/firestore");
1326
- var timestampSchema2 = import_zod4.z.union([
1327
- import_zod4.z.object({
1328
- seconds: import_zod4.z.number(),
1329
- nanoseconds: import_zod4.z.number()
1629
+ var import_zod5 = require("zod");
1630
+ var import_firestore4 = require("firebase/firestore");
1631
+ var timestampSchema2 = import_zod5.z.union([
1632
+ import_zod5.z.object({
1633
+ seconds: import_zod5.z.number(),
1634
+ nanoseconds: import_zod5.z.number()
1330
1635
  }),
1331
- import_zod4.z.instanceof(import_firestore2.Timestamp)
1636
+ import_zod5.z.instanceof(import_firestore4.Timestamp)
1332
1637
  ]).transform((data) => {
1333
- if (data instanceof import_firestore2.Timestamp) {
1638
+ if (data instanceof import_firestore4.Timestamp) {
1334
1639
  return data;
1335
1640
  }
1336
- return new import_firestore2.Timestamp(data.seconds, data.nanoseconds);
1641
+ return new import_firestore4.Timestamp(data.seconds, data.nanoseconds);
1337
1642
  });
1338
1643
 
1339
1644
  // src/validations/patient/medical-info.schema.ts
1340
- var allergySubtypeSchema = import_zod5.z.union([
1341
- import_zod5.z.nativeEnum(MedicationAllergySubtype),
1342
- import_zod5.z.nativeEnum(FoodAllergySubtype),
1343
- import_zod5.z.nativeEnum(EnvironmentalAllergySubtype),
1344
- import_zod5.z.nativeEnum(CosmeticAllergySubtype),
1345
- import_zod5.z.literal("other")
1645
+ var allergySubtypeSchema = import_zod6.z.union([
1646
+ import_zod6.z.nativeEnum(MedicationAllergySubtype),
1647
+ import_zod6.z.nativeEnum(FoodAllergySubtype),
1648
+ import_zod6.z.nativeEnum(EnvironmentalAllergySubtype),
1649
+ import_zod6.z.nativeEnum(CosmeticAllergySubtype),
1650
+ import_zod6.z.literal("other")
1346
1651
  ]);
1347
- var allergySchema = import_zod5.z.object({
1348
- type: import_zod5.z.nativeEnum(AllergyType),
1652
+ var allergySchema = import_zod6.z.object({
1653
+ type: import_zod6.z.nativeEnum(AllergyType),
1349
1654
  subtype: allergySubtypeSchema,
1350
- name: import_zod5.z.string().optional().nullable(),
1351
- severity: import_zod5.z.enum(["mild", "moderate", "severe"]).optional(),
1352
- reaction: import_zod5.z.string().optional().nullable(),
1655
+ name: import_zod6.z.string().optional().nullable(),
1656
+ severity: import_zod6.z.enum(["mild", "moderate", "severe"]).optional(),
1657
+ reaction: import_zod6.z.string().optional().nullable(),
1353
1658
  diagnosed: timestampSchema2.optional().nullable(),
1354
- notes: import_zod5.z.string().optional().nullable()
1659
+ notes: import_zod6.z.string().optional().nullable()
1355
1660
  });
1356
- var vitalStatsSchema = import_zod5.z.object({
1357
- height: import_zod5.z.number().positive().optional(),
1358
- weight: import_zod5.z.number().positive().optional(),
1359
- bloodType: import_zod5.z.enum(["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"]).optional(),
1360
- bloodPressure: import_zod5.z.object({
1361
- systolic: import_zod5.z.number().min(70).max(200),
1362
- diastolic: import_zod5.z.number().min(40).max(130),
1661
+ var vitalStatsSchema = import_zod6.z.object({
1662
+ height: import_zod6.z.number().positive().optional(),
1663
+ weight: import_zod6.z.number().positive().optional(),
1664
+ bloodType: import_zod6.z.enum(["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"]).optional(),
1665
+ bloodPressure: import_zod6.z.object({
1666
+ systolic: import_zod6.z.number().min(70).max(200),
1667
+ diastolic: import_zod6.z.number().min(40).max(130),
1363
1668
  lastMeasured: timestampSchema2
1364
1669
  }).optional()
1365
1670
  });
1366
- var blockingConditionSchema = import_zod5.z.object({
1367
- condition: import_zod5.z.nativeEnum(BlockingCondition),
1671
+ var blockingConditionSchema = import_zod6.z.object({
1672
+ condition: import_zod6.z.nativeEnum(BlockingCondition),
1368
1673
  diagnosedAt: timestampSchema2,
1369
- notes: import_zod5.z.string().optional().nullable(),
1370
- isActive: import_zod5.z.boolean()
1674
+ notes: import_zod6.z.string().optional().nullable(),
1675
+ isActive: import_zod6.z.boolean()
1371
1676
  });
1372
- var contraindicationSchema = import_zod5.z.object({
1373
- condition: import_zod5.z.nativeEnum(Contraindication),
1677
+ var contraindicationSchema = import_zod6.z.object({
1678
+ condition: import_zod6.z.nativeEnum(Contraindication),
1374
1679
  lastOccurrence: timestampSchema2,
1375
- frequency: import_zod5.z.enum(["rare", "occasional", "frequent"]),
1376
- notes: import_zod5.z.string().optional().nullable(),
1377
- isActive: import_zod5.z.boolean()
1680
+ frequency: import_zod6.z.enum(["rare", "occasional", "frequent"]),
1681
+ notes: import_zod6.z.string().optional().nullable(),
1682
+ isActive: import_zod6.z.boolean()
1378
1683
  });
1379
- var medicationSchema = import_zod5.z.object({
1380
- name: import_zod5.z.string().min(1),
1381
- dosage: import_zod5.z.string().min(1),
1382
- frequency: import_zod5.z.string().min(1),
1684
+ var medicationSchema = import_zod6.z.object({
1685
+ name: import_zod6.z.string().min(1),
1686
+ dosage: import_zod6.z.string().min(1),
1687
+ frequency: import_zod6.z.string().min(1),
1383
1688
  startDate: timestampSchema2.optional().nullable(),
1384
1689
  endDate: timestampSchema2.optional().nullable(),
1385
- prescribedBy: import_zod5.z.string().optional().nullable()
1690
+ prescribedBy: import_zod6.z.string().optional().nullable()
1386
1691
  });
1387
- var patientMedicalInfoSchema = import_zod5.z.object({
1388
- patientId: import_zod5.z.string(),
1692
+ var patientMedicalInfoSchema = import_zod6.z.object({
1693
+ patientId: import_zod6.z.string(),
1389
1694
  vitalStats: vitalStatsSchema,
1390
- blockingConditions: import_zod5.z.array(blockingConditionSchema),
1391
- contraindications: import_zod5.z.array(contraindicationSchema),
1392
- allergies: import_zod5.z.array(allergySchema),
1393
- currentMedications: import_zod5.z.array(medicationSchema),
1394
- emergencyNotes: import_zod5.z.string().optional(),
1695
+ blockingConditions: import_zod6.z.array(blockingConditionSchema),
1696
+ contraindications: import_zod6.z.array(contraindicationSchema),
1697
+ allergies: import_zod6.z.array(allergySchema),
1698
+ currentMedications: import_zod6.z.array(medicationSchema),
1699
+ emergencyNotes: import_zod6.z.string().optional(),
1395
1700
  lastUpdated: timestampSchema2,
1396
- updatedBy: import_zod5.z.string(),
1397
- verifiedBy: import_zod5.z.string().optional(),
1701
+ updatedBy: import_zod6.z.string(),
1702
+ verifiedBy: import_zod6.z.string().optional(),
1398
1703
  verifiedAt: timestampSchema2.optional()
1399
1704
  });
1400
1705
  var createPatientMedicalInfoSchema = patientMedicalInfoSchema.omit({
@@ -1408,141 +1713,140 @@ var updatePatientMedicalInfoSchema = createPatientMedicalInfoSchema.partial();
1408
1713
  var updateVitalStatsSchema = vitalStatsSchema;
1409
1714
  var addAllergySchema = allergySchema;
1410
1715
  var updateAllergySchema = allergySchema.partial().extend({
1411
- allergyIndex: import_zod5.z.number().min(0)
1716
+ allergyIndex: import_zod6.z.number().min(0)
1412
1717
  });
1413
1718
  var addBlockingConditionSchema = blockingConditionSchema;
1414
1719
  var updateBlockingConditionSchema = blockingConditionSchema.partial().extend({
1415
- conditionIndex: import_zod5.z.number().min(0)
1720
+ conditionIndex: import_zod6.z.number().min(0)
1416
1721
  });
1417
1722
  var addContraindicationSchema = contraindicationSchema;
1418
1723
  var updateContraindicationSchema = contraindicationSchema.partial().extend({
1419
- contraindicationIndex: import_zod5.z.number().min(0)
1724
+ contraindicationIndex: import_zod6.z.number().min(0)
1420
1725
  });
1421
1726
  var addMedicationSchema = medicationSchema;
1422
1727
  var updateMedicationSchema = medicationSchema.partial().extend({
1423
- medicationIndex: import_zod5.z.number().min(0)
1728
+ medicationIndex: import_zod6.z.number().min(0)
1424
1729
  });
1425
1730
 
1426
1731
  // src/validations/patient.schema.ts
1427
- var locationDataSchema = import_zod6.z.object({
1428
- latitude: import_zod6.z.number().min(-90).max(90),
1429
- longitude: import_zod6.z.number().min(-180).max(180),
1430
- geohash: import_zod6.z.string().optional()
1732
+ var locationDataSchema = import_zod7.z.object({
1733
+ latitude: import_zod7.z.number().min(-90).max(90),
1734
+ longitude: import_zod7.z.number().min(-180).max(180),
1735
+ geohash: import_zod7.z.string().optional()
1431
1736
  });
1432
- var addressDataSchema = import_zod6.z.object({
1433
- address: import_zod6.z.string(),
1434
- city: import_zod6.z.string(),
1435
- country: import_zod6.z.string(),
1436
- postalCode: import_zod6.z.string()
1737
+ var addressDataSchema = import_zod7.z.object({
1738
+ address: import_zod7.z.string(),
1739
+ city: import_zod7.z.string(),
1740
+ country: import_zod7.z.string(),
1741
+ postalCode: import_zod7.z.string()
1437
1742
  });
1438
- var emergencyContactSchema = import_zod6.z.object({
1439
- name: import_zod6.z.string(),
1440
- relationship: import_zod6.z.string(),
1441
- phoneNumber: import_zod6.z.string(),
1442
- isNotifiable: import_zod6.z.boolean()
1743
+ var emergencyContactSchema = import_zod7.z.object({
1744
+ name: import_zod7.z.string(),
1745
+ relationship: import_zod7.z.string(),
1746
+ phoneNumber: import_zod7.z.string(),
1747
+ isNotifiable: import_zod7.z.boolean()
1443
1748
  });
1444
- var gamificationSchema = import_zod6.z.object({
1445
- level: import_zod6.z.number(),
1446
- points: import_zod6.z.number()
1749
+ var gamificationSchema = import_zod7.z.object({
1750
+ level: import_zod7.z.number(),
1751
+ points: import_zod7.z.number()
1447
1752
  });
1448
- var patientLocationInfoSchema = import_zod6.z.object({
1449
- patientId: import_zod6.z.string(),
1450
- userRef: import_zod6.z.string(),
1753
+ var patientLocationInfoSchema = import_zod7.z.object({
1754
+ patientId: import_zod7.z.string(),
1755
+ userRef: import_zod7.z.string(),
1451
1756
  locationData: locationDataSchema,
1452
- createdAt: import_zod6.z.instanceof(import_firestore3.Timestamp),
1453
- updatedAt: import_zod6.z.instanceof(import_firestore3.Timestamp)
1757
+ createdAt: import_zod7.z.instanceof(import_firestore5.Timestamp),
1758
+ updatedAt: import_zod7.z.instanceof(import_firestore5.Timestamp)
1454
1759
  });
1455
- var createPatientLocationInfoSchema = import_zod6.z.object({
1456
- patientId: import_zod6.z.string(),
1457
- userRef: import_zod6.z.string(),
1760
+ var createPatientLocationInfoSchema = import_zod7.z.object({
1761
+ patientId: import_zod7.z.string(),
1762
+ userRef: import_zod7.z.string(),
1458
1763
  locationData: locationDataSchema
1459
1764
  });
1460
- var patientSensitiveInfoSchema = import_zod6.z.object({
1461
- patientId: import_zod6.z.string(),
1462
- userRef: import_zod6.z.string(),
1463
- photoUrl: import_zod6.z.string().optional(),
1464
- firstName: import_zod6.z.string().min(2),
1465
- lastName: import_zod6.z.string().min(2),
1466
- dateOfBirth: import_zod6.z.instanceof(import_firestore3.Timestamp).nullable(),
1467
- gender: import_zod6.z.nativeEnum(Gender),
1468
- email: import_zod6.z.string().email().optional(),
1469
- phoneNumber: import_zod6.z.string().optional(),
1470
- alternativePhoneNumber: import_zod6.z.string().optional(),
1765
+ var patientSensitiveInfoSchema = import_zod7.z.object({
1766
+ patientId: import_zod7.z.string(),
1767
+ userRef: import_zod7.z.string(),
1768
+ firstName: import_zod7.z.string().min(2),
1769
+ lastName: import_zod7.z.string().min(2),
1770
+ dateOfBirth: import_zod7.z.instanceof(import_firestore5.Timestamp).nullable(),
1771
+ gender: import_zod7.z.nativeEnum(Gender),
1772
+ email: import_zod7.z.string().email().optional(),
1773
+ phoneNumber: import_zod7.z.string().optional(),
1774
+ alternativePhoneNumber: import_zod7.z.string().optional(),
1471
1775
  addressData: addressDataSchema.optional(),
1472
- emergencyContacts: import_zod6.z.array(emergencyContactSchema).optional(),
1473
- createdAt: import_zod6.z.instanceof(import_firestore3.Timestamp),
1474
- updatedAt: import_zod6.z.instanceof(import_firestore3.Timestamp)
1776
+ emergencyContacts: import_zod7.z.array(emergencyContactSchema).optional(),
1777
+ createdAt: import_zod7.z.instanceof(import_firestore5.Timestamp),
1778
+ updatedAt: import_zod7.z.instanceof(import_firestore5.Timestamp)
1475
1779
  });
1476
- var patientDoctorSchema = import_zod6.z.object({
1477
- userRef: import_zod6.z.string(),
1478
- assignedAt: import_zod6.z.instanceof(import_firestore3.Timestamp),
1479
- assignedBy: import_zod6.z.string().optional(),
1480
- isActive: import_zod6.z.boolean(),
1481
- notes: import_zod6.z.string().optional()
1780
+ var patientDoctorSchema = import_zod7.z.object({
1781
+ userRef: import_zod7.z.string(),
1782
+ assignedAt: import_zod7.z.instanceof(import_firestore5.Timestamp),
1783
+ assignedBy: import_zod7.z.string().optional(),
1784
+ isActive: import_zod7.z.boolean(),
1785
+ notes: import_zod7.z.string().optional()
1482
1786
  });
1483
- var patientClinicSchema = import_zod6.z.object({
1484
- clinicId: import_zod6.z.string(),
1485
- assignedAt: import_zod6.z.instanceof(import_firestore3.Timestamp),
1486
- assignedBy: import_zod6.z.string().optional(),
1487
- isActive: import_zod6.z.boolean(),
1488
- notes: import_zod6.z.string().optional()
1787
+ var patientClinicSchema = import_zod7.z.object({
1788
+ clinicId: import_zod7.z.string(),
1789
+ assignedAt: import_zod7.z.instanceof(import_firestore5.Timestamp),
1790
+ assignedBy: import_zod7.z.string().optional(),
1791
+ isActive: import_zod7.z.boolean(),
1792
+ notes: import_zod7.z.string().optional()
1489
1793
  });
1490
- var patientProfileSchema = import_zod6.z.object({
1491
- id: import_zod6.z.string(),
1492
- userRef: import_zod6.z.string(),
1493
- displayName: import_zod6.z.string(),
1494
- profilePhoto: import_zod6.z.string().url().nullable(),
1794
+ var patientProfileSchema = import_zod7.z.object({
1795
+ id: import_zod7.z.string(),
1796
+ userRef: import_zod7.z.string(),
1797
+ displayName: import_zod7.z.string(),
1495
1798
  gamification: gamificationSchema,
1496
- expoTokens: import_zod6.z.array(import_zod6.z.string()),
1497
- isActive: import_zod6.z.boolean(),
1498
- isVerified: import_zod6.z.boolean(),
1499
- doctors: import_zod6.z.array(patientDoctorSchema),
1500
- clinics: import_zod6.z.array(patientClinicSchema),
1501
- doctorIds: import_zod6.z.array(import_zod6.z.string()),
1502
- clinicIds: import_zod6.z.array(import_zod6.z.string()),
1503
- createdAt: import_zod6.z.instanceof(import_firestore3.Timestamp),
1504
- updatedAt: import_zod6.z.instanceof(import_firestore3.Timestamp)
1799
+ expoTokens: import_zod7.z.array(import_zod7.z.string()),
1800
+ isActive: import_zod7.z.boolean(),
1801
+ isVerified: import_zod7.z.boolean(),
1802
+ phoneNumber: import_zod7.z.string().nullable().optional(),
1803
+ dateOfBirth: import_zod7.z.instanceof(import_firestore5.Timestamp).nullable().optional(),
1804
+ doctors: import_zod7.z.array(patientDoctorSchema),
1805
+ clinics: import_zod7.z.array(patientClinicSchema),
1806
+ doctorIds: import_zod7.z.array(import_zod7.z.string()),
1807
+ clinicIds: import_zod7.z.array(import_zod7.z.string()),
1808
+ createdAt: import_zod7.z.instanceof(import_firestore5.Timestamp),
1809
+ updatedAt: import_zod7.z.instanceof(import_firestore5.Timestamp)
1505
1810
  });
1506
- var createPatientProfileSchema = import_zod6.z.object({
1507
- userRef: import_zod6.z.string(),
1508
- displayName: import_zod6.z.string(),
1509
- profilePhoto: import_zod6.z.string().url().nullable().optional(),
1510
- expoTokens: import_zod6.z.array(import_zod6.z.string()),
1811
+ var createPatientProfileSchema = import_zod7.z.object({
1812
+ userRef: import_zod7.z.string(),
1813
+ displayName: import_zod7.z.string(),
1814
+ expoTokens: import_zod7.z.array(import_zod7.z.string()),
1511
1815
  gamification: gamificationSchema.optional(),
1512
- isActive: import_zod6.z.boolean(),
1513
- isVerified: import_zod6.z.boolean(),
1514
- doctors: import_zod6.z.array(patientDoctorSchema).optional(),
1515
- clinics: import_zod6.z.array(patientClinicSchema).optional(),
1516
- doctorIds: import_zod6.z.array(import_zod6.z.string()).optional(),
1517
- clinicIds: import_zod6.z.array(import_zod6.z.string()).optional()
1816
+ isActive: import_zod7.z.boolean(),
1817
+ isVerified: import_zod7.z.boolean(),
1818
+ doctors: import_zod7.z.array(patientDoctorSchema).optional(),
1819
+ clinics: import_zod7.z.array(patientClinicSchema).optional(),
1820
+ doctorIds: import_zod7.z.array(import_zod7.z.string()).optional(),
1821
+ clinicIds: import_zod7.z.array(import_zod7.z.string()).optional()
1518
1822
  });
1519
- var createPatientSensitiveInfoSchema = import_zod6.z.object({
1520
- patientId: import_zod6.z.string(),
1521
- userRef: import_zod6.z.string(),
1522
- photoUrl: import_zod6.z.string().optional(),
1523
- firstName: import_zod6.z.string().min(2),
1524
- lastName: import_zod6.z.string().min(2),
1525
- dateOfBirth: import_zod6.z.instanceof(import_firestore3.Timestamp).nullable(),
1526
- gender: import_zod6.z.nativeEnum(Gender),
1527
- email: import_zod6.z.string().email().optional(),
1528
- phoneNumber: import_zod6.z.string().optional(),
1529
- alternativePhoneNumber: import_zod6.z.string().optional(),
1823
+ var createPatientSensitiveInfoSchema = import_zod7.z.object({
1824
+ patientId: import_zod7.z.string(),
1825
+ userRef: import_zod7.z.string(),
1826
+ photoUrl: mediaResourceSchema.nullable().optional(),
1827
+ firstName: import_zod7.z.string().min(2),
1828
+ lastName: import_zod7.z.string().min(2),
1829
+ dateOfBirth: import_zod7.z.instanceof(import_firestore5.Timestamp).nullable(),
1830
+ gender: import_zod7.z.nativeEnum(Gender),
1831
+ email: import_zod7.z.string().email().optional(),
1832
+ phoneNumber: import_zod7.z.string().optional(),
1833
+ alternativePhoneNumber: import_zod7.z.string().optional(),
1530
1834
  addressData: addressDataSchema.optional(),
1531
- emergencyContacts: import_zod6.z.array(emergencyContactSchema).optional()
1835
+ emergencyContacts: import_zod7.z.array(emergencyContactSchema).optional()
1532
1836
  });
1533
- var searchPatientsSchema = import_zod6.z.object({
1534
- clinicId: import_zod6.z.string().optional(),
1535
- practitionerId: import_zod6.z.string().optional()
1837
+ var searchPatientsSchema = import_zod7.z.object({
1838
+ clinicId: import_zod7.z.string().optional(),
1839
+ practitionerId: import_zod7.z.string().optional()
1536
1840
  }).refine((data) => data.clinicId || data.practitionerId, {
1537
1841
  message: "At least one of clinicId or practitionerId must be provided",
1538
1842
  path: []
1539
1843
  // Optional: specify a path like ['clinicId'] or ['practitionerId']
1540
1844
  });
1541
- var requesterInfoSchema = import_zod6.z.object({
1542
- id: import_zod6.z.string(),
1543
- role: import_zod6.z.enum(["clinic_admin", "practitioner"]),
1544
- associatedClinicId: import_zod6.z.string().optional(),
1545
- associatedPractitionerId: import_zod6.z.string().optional()
1845
+ var requesterInfoSchema = import_zod7.z.object({
1846
+ id: import_zod7.z.string(),
1847
+ role: import_zod7.z.enum(["clinic_admin", "practitioner"]),
1848
+ associatedClinicId: import_zod7.z.string().optional(),
1849
+ associatedPractitionerId: import_zod7.z.string().optional()
1546
1850
  }).refine(
1547
1851
  (data) => {
1548
1852
  if (data.role === "clinic_admin") {
@@ -1559,36 +1863,68 @@ var requesterInfoSchema = import_zod6.z.object({
1559
1863
  );
1560
1864
 
1561
1865
  // src/services/patient/utils/docs.utils.ts
1562
- var import_firestore5 = require("firebase/firestore");
1866
+ var import_firestore7 = require("firebase/firestore");
1563
1867
 
1564
1868
  // src/services/patient/utils/sensitive.utils.ts
1565
- var import_firestore4 = require("firebase/firestore");
1566
- var import_zod7 = require("zod");
1567
- var createSensitiveInfoUtil = async (db, data, requesterUserId) => {
1869
+ var import_firestore6 = require("firebase/firestore");
1870
+ var import_zod8 = require("zod");
1871
+ var handlePhotoUrlUpload = async (photoUrl, patientId, mediaService) => {
1872
+ if (!photoUrl) {
1873
+ return null;
1874
+ }
1875
+ if (typeof photoUrl === "string") {
1876
+ return photoUrl;
1877
+ }
1878
+ if (photoUrl instanceof File || photoUrl instanceof Blob) {
1879
+ const mediaMetadata = await mediaService.uploadMedia(
1880
+ photoUrl,
1881
+ patientId,
1882
+ // Using patientId as ownerId
1883
+ "private" /* PRIVATE */,
1884
+ // Sensitive info should be private
1885
+ "patient_sensitive_photos",
1886
+ photoUrl instanceof File ? photoUrl.name : `sensitive_photo_${patientId}`
1887
+ );
1888
+ return mediaMetadata.url;
1889
+ }
1890
+ return null;
1891
+ };
1892
+ var createSensitiveInfoUtil = async (db, data, requesterUserId, mediaService) => {
1568
1893
  try {
1569
1894
  if (data.userRef !== requesterUserId) {
1570
1895
  throw new Error("Only patient can create their sensitive information");
1571
1896
  }
1572
1897
  const validatedData = createPatientSensitiveInfoSchema.parse(data);
1573
- const sensitiveDoc = await (0, import_firestore4.getDoc)(
1898
+ const sensitiveDoc = await (0, import_firestore6.getDoc)(
1574
1899
  getSensitiveInfoDocRef(db, data.patientId)
1575
1900
  );
1576
1901
  if (sensitiveDoc.exists()) {
1577
1902
  throw new Error("Sensitive information already exists for this patient");
1578
1903
  }
1904
+ let processedPhotoUrl = null;
1905
+ if (validatedData.photoUrl && mediaService) {
1906
+ processedPhotoUrl = await handlePhotoUrlUpload(
1907
+ validatedData.photoUrl,
1908
+ data.patientId,
1909
+ mediaService
1910
+ );
1911
+ } else if (typeof validatedData.photoUrl === "string") {
1912
+ processedPhotoUrl = validatedData.photoUrl;
1913
+ }
1579
1914
  const sensitiveInfoData = {
1580
1915
  ...validatedData,
1581
- createdAt: (0, import_firestore4.serverTimestamp)(),
1582
- updatedAt: (0, import_firestore4.serverTimestamp)()
1916
+ photoUrl: processedPhotoUrl,
1917
+ createdAt: (0, import_firestore6.serverTimestamp)(),
1918
+ updatedAt: (0, import_firestore6.serverTimestamp)()
1583
1919
  };
1584
- await (0, import_firestore4.setDoc)(getSensitiveInfoDocRef(db, data.patientId), sensitiveInfoData);
1585
- const createdDoc = await (0, import_firestore4.getDoc)(getSensitiveInfoDocRef(db, data.patientId));
1920
+ await (0, import_firestore6.setDoc)(getSensitiveInfoDocRef(db, data.patientId), sensitiveInfoData);
1921
+ const createdDoc = await (0, import_firestore6.getDoc)(getSensitiveInfoDocRef(db, data.patientId));
1586
1922
  if (!createdDoc.exists()) {
1587
1923
  throw new Error("Failed to create sensitive information");
1588
1924
  }
1589
1925
  return createdDoc.data();
1590
1926
  } catch (error) {
1591
- if (error instanceof import_zod7.z.ZodError) {
1927
+ if (error instanceof import_zod8.z.ZodError) {
1592
1928
  throw new Error("Invalid sensitive info data: " + error.message);
1593
1929
  }
1594
1930
  throw error;
@@ -1596,17 +1932,32 @@ var createSensitiveInfoUtil = async (db, data, requesterUserId) => {
1596
1932
  };
1597
1933
  var getSensitiveInfoUtil = async (db, patientId, requesterUserId) => {
1598
1934
  await initSensitiveInfoDocIfNotExists(db, patientId, requesterUserId);
1599
- const sensitiveDoc = await (0, import_firestore4.getDoc)(getSensitiveInfoDocRef(db, patientId));
1935
+ const sensitiveDoc = await (0, import_firestore6.getDoc)(getSensitiveInfoDocRef(db, patientId));
1600
1936
  return sensitiveDoc.exists() ? sensitiveDoc.data() : null;
1601
1937
  };
1602
- var updateSensitiveInfoUtil = async (db, patientId, data, requesterUserId) => {
1938
+ var updateSensitiveInfoUtil = async (db, patientId, data, requesterUserId, mediaService) => {
1603
1939
  await initSensitiveInfoDocIfNotExists(db, patientId, requesterUserId);
1940
+ let processedPhotoUrl = void 0;
1941
+ if (data.photoUrl !== void 0) {
1942
+ if (mediaService) {
1943
+ processedPhotoUrl = await handlePhotoUrlUpload(
1944
+ data.photoUrl,
1945
+ patientId,
1946
+ mediaService
1947
+ );
1948
+ } else if (typeof data.photoUrl === "string" || data.photoUrl === null) {
1949
+ processedPhotoUrl = data.photoUrl;
1950
+ } else {
1951
+ throw new Error("MediaService required to process photo upload");
1952
+ }
1953
+ }
1604
1954
  const updateData = {
1605
1955
  ...data,
1606
- updatedAt: (0, import_firestore4.serverTimestamp)()
1956
+ photoUrl: processedPhotoUrl,
1957
+ updatedAt: (0, import_firestore6.serverTimestamp)()
1607
1958
  };
1608
- await (0, import_firestore4.updateDoc)(getSensitiveInfoDocRef(db, patientId), updateData);
1609
- const updatedDoc = await (0, import_firestore4.getDoc)(getSensitiveInfoDocRef(db, patientId));
1959
+ await (0, import_firestore6.updateDoc)(getSensitiveInfoDocRef(db, patientId), updateData);
1960
+ const updatedDoc = await (0, import_firestore6.getDoc)(getSensitiveInfoDocRef(db, patientId));
1610
1961
  if (!updatedDoc.exists()) {
1611
1962
  throw new Error("Failed to retrieve updated sensitive information");
1612
1963
  }
@@ -1615,21 +1966,21 @@ var updateSensitiveInfoUtil = async (db, patientId, data, requesterUserId) => {
1615
1966
 
1616
1967
  // src/services/patient/utils/docs.utils.ts
1617
1968
  var getPatientDocRef = (db, patientId) => {
1618
- return (0, import_firestore5.doc)(db, PATIENTS_COLLECTION, patientId);
1969
+ return (0, import_firestore7.doc)(db, PATIENTS_COLLECTION, patientId);
1619
1970
  };
1620
1971
  var getPatientDocRefByUserRef = async (db, userRef) => {
1621
- const patientsRef = (0, import_firestore5.collection)(db, PATIENTS_COLLECTION);
1622
- const q = (0, import_firestore5.query)(patientsRef, (0, import_firestore5.where)("userRef", "==", userRef));
1623
- const querySnapshot = await (0, import_firestore5.getDocs)(q);
1972
+ const patientsRef = (0, import_firestore7.collection)(db, PATIENTS_COLLECTION);
1973
+ const q = (0, import_firestore7.query)(patientsRef, (0, import_firestore7.where)("userRef", "==", userRef));
1974
+ const querySnapshot = await (0, import_firestore7.getDocs)(q);
1624
1975
  if (querySnapshot.empty) {
1625
1976
  throw new Error("Patient profile not found");
1626
1977
  }
1627
- return (0, import_firestore5.doc)(db, PATIENTS_COLLECTION, querySnapshot.docs[0].id);
1978
+ return (0, import_firestore7.doc)(db, PATIENTS_COLLECTION, querySnapshot.docs[0].id);
1628
1979
  };
1629
1980
  var getSensitiveInfoDocRef = (db, patientId) => {
1630
1981
  const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_SENSITIVE_INFO_COLLECTION}/${patientId}`;
1631
1982
  console.log(`[getSensitiveInfoDocRef] Creating reference with path: ${path}`);
1632
- return (0, import_firestore5.doc)(
1983
+ return (0, import_firestore7.doc)(
1633
1984
  db,
1634
1985
  PATIENTS_COLLECTION,
1635
1986
  patientId,
@@ -1640,7 +1991,7 @@ var getSensitiveInfoDocRef = (db, patientId) => {
1640
1991
  var getLocationInfoDocRef = (db, patientId) => {
1641
1992
  const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_LOCATION_INFO_COLLECTION}/${patientId}`;
1642
1993
  console.log(`[getLocationInfoDocRef] Creating reference with path: ${path}`);
1643
- return (0, import_firestore5.doc)(
1994
+ return (0, import_firestore7.doc)(
1644
1995
  db,
1645
1996
  PATIENTS_COLLECTION,
1646
1997
  patientId,
@@ -1651,7 +2002,7 @@ var getLocationInfoDocRef = (db, patientId) => {
1651
2002
  var getMedicalInfoDocRef = (db, patientId) => {
1652
2003
  const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_MEDICAL_INFO_COLLECTION}/${patientId}`;
1653
2004
  console.log(`[getMedicalInfoDocRef] Creating reference with path: ${path}`);
1654
- return (0, import_firestore5.doc)(
2005
+ return (0, import_firestore7.doc)(
1655
2006
  db,
1656
2007
  PATIENTS_COLLECTION,
1657
2008
  patientId,
@@ -1668,7 +2019,7 @@ var initSensitiveInfoDocIfNotExists = async (db, patientId, userRef) => {
1668
2019
  console.log(
1669
2020
  `[initSensitiveInfoDocIfNotExists] Got document reference: ${sensitiveInfoRef.path}`
1670
2021
  );
1671
- const sensitiveDoc = await (0, import_firestore5.getDoc)(sensitiveInfoRef);
2022
+ const sensitiveDoc = await (0, import_firestore7.getDoc)(sensitiveInfoRef);
1672
2023
  console.log(
1673
2024
  `[initSensitiveInfoDocIfNotExists] Document exists: ${sensitiveDoc.exists()}`
1674
2025
  );
@@ -1692,7 +2043,7 @@ var initSensitiveInfoDocIfNotExists = async (db, patientId, userRef) => {
1692
2043
  )
1693
2044
  );
1694
2045
  await createSensitiveInfoUtil(db, defaultSensitiveInfo, userRef);
1695
- const verifyDoc = await (0, import_firestore5.getDoc)(sensitiveInfoRef);
2046
+ const verifyDoc = await (0, import_firestore7.getDoc)(sensitiveInfoRef);
1696
2047
  console.log(
1697
2048
  `[initSensitiveInfoDocIfNotExists] Verification - document exists: ${verifyDoc.exists()}`
1698
2049
  );
@@ -1709,10 +2060,10 @@ var initSensitiveInfoDocIfNotExists = async (db, patientId, userRef) => {
1709
2060
  };
1710
2061
 
1711
2062
  // src/services/patient/utils/medical.utils.ts
1712
- var import_firestore7 = require("firebase/firestore");
2063
+ var import_firestore9 = require("firebase/firestore");
1713
2064
 
1714
2065
  // src/services/patient/utils/practitioner.utils.ts
1715
- var import_firestore6 = require("firebase/firestore");
2066
+ var import_firestore8 = require("firebase/firestore");
1716
2067
 
1717
2068
  // src/types/practitioner/index.ts
1718
2069
  var PRACTITIONERS_COLLECTION = "practitioners";
@@ -1737,23 +2088,23 @@ var getPatientsByPractitionerUtil = async (db, practitionerId, options) => {
1737
2088
  `[getPatientsByPractitionerUtil] Fetching patients for practitioner ID: ${practitionerId} with options:`,
1738
2089
  options
1739
2090
  );
1740
- const patientsCollection = (0, import_firestore6.collection)(db, PATIENTS_COLLECTION);
2091
+ const patientsCollection = (0, import_firestore8.collection)(db, PATIENTS_COLLECTION);
1741
2092
  const constraints = [
1742
- (0, import_firestore6.where)("doctorIds", "array-contains", practitionerId)
2093
+ (0, import_firestore8.where)("doctorIds", "array-contains", practitionerId)
1743
2094
  ];
1744
- let q = (0, import_firestore6.query)(patientsCollection, ...constraints);
2095
+ let q = (0, import_firestore8.query)(patientsCollection, ...constraints);
1745
2096
  if (options == null ? void 0 : options.limit) {
1746
- q = (0, import_firestore6.query)(q, (0, import_firestore6.limit)(options.limit));
2097
+ q = (0, import_firestore8.query)(q, (0, import_firestore8.limit)(options.limit));
1747
2098
  }
1748
2099
  if (options == null ? void 0 : options.startAfter) {
1749
- const startAfterDoc = await (0, import_firestore6.getDoc)(
1750
- (0, import_firestore6.doc)(db, PATIENTS_COLLECTION, options.startAfter)
2100
+ const startAfterDoc = await (0, import_firestore8.getDoc)(
2101
+ (0, import_firestore8.doc)(db, PATIENTS_COLLECTION, options.startAfter)
1751
2102
  );
1752
2103
  if (startAfterDoc.exists()) {
1753
- q = (0, import_firestore6.query)(q, (0, import_firestore6.startAfter)(startAfterDoc));
2104
+ q = (0, import_firestore8.query)(q, (0, import_firestore8.startAfter)(startAfterDoc));
1754
2105
  }
1755
2106
  }
1756
- const patientsSnapshot = await (0, import_firestore6.getDocs)(q);
2107
+ const patientsSnapshot = await (0, import_firestore8.getDocs)(q);
1757
2108
  const patients = [];
1758
2109
  patientsSnapshot.forEach((doc34) => {
1759
2110
  patients.push(doc34.data());
@@ -1786,7 +2137,7 @@ var getPatientsByPractitionerWithDetailsUtil = async (db, practitionerId, option
1786
2137
  const patientProfilesWithDetails = await Promise.all(
1787
2138
  patientProfiles.map(async (profile) => {
1788
2139
  try {
1789
- const sensitiveInfoDoc = await (0, import_firestore6.getDoc)(
2140
+ const sensitiveInfoDoc = await (0, import_firestore8.getDoc)(
1790
2141
  getSensitiveInfoDocRef(db, profile.id)
1791
2142
  );
1792
2143
  const sensitiveInfo = sensitiveInfoDoc.exists() ? sensitiveInfoDoc.data() : void 0;
@@ -1822,13 +2173,13 @@ var getPractitionerProfileByUserRef = async (db, userRef) => {
1822
2173
  console.log(
1823
2174
  `[getPractitionerProfileByUserRef] Fetching practitioner with userRef: ${userRef}`
1824
2175
  );
1825
- const practitionersCollection = (0, import_firestore6.collection)(db, PRACTITIONERS_COLLECTION);
1826
- const q = (0, import_firestore6.query)(
2176
+ const practitionersCollection = (0, import_firestore8.collection)(db, PRACTITIONERS_COLLECTION);
2177
+ const q = (0, import_firestore8.query)(
1827
2178
  practitionersCollection,
1828
- (0, import_firestore6.where)("userRef", "==", userRef),
1829
- (0, import_firestore6.limit)(1)
2179
+ (0, import_firestore8.where)("userRef", "==", userRef),
2180
+ (0, import_firestore8.limit)(1)
1830
2181
  );
1831
- const querySnapshot = await (0, import_firestore6.getDocs)(q);
2182
+ const querySnapshot = await (0, import_firestore8.getDocs)(q);
1832
2183
  if (querySnapshot.empty) {
1833
2184
  console.log(
1834
2185
  `[getPractitionerProfileByUserRef] No practitioner found with userRef: ${userRef}`
@@ -1862,7 +2213,7 @@ var ensureMedicalInfoExists = async (db, patientId, userRef) => {
1862
2213
  console.log(
1863
2214
  `[ensureMedicalInfoExists] Got document reference: ${medicalInfoRef.path}`
1864
2215
  );
1865
- const medicalInfoDoc = await (0, import_firestore7.getDoc)(medicalInfoRef);
2216
+ const medicalInfoDoc = await (0, import_firestore9.getDoc)(medicalInfoRef);
1866
2217
  console.log(
1867
2218
  `[ensureMedicalInfoExists] Document exists: ${medicalInfoDoc.exists()}`
1868
2219
  );
@@ -1870,7 +2221,7 @@ var ensureMedicalInfoExists = async (db, patientId, userRef) => {
1870
2221
  const defaultData = {
1871
2222
  ...DEFAULT_MEDICAL_INFO,
1872
2223
  patientId,
1873
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2224
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
1874
2225
  updatedBy: userRef
1875
2226
  };
1876
2227
  console.log(
@@ -1880,9 +2231,9 @@ var ensureMedicalInfoExists = async (db, patientId, userRef) => {
1880
2231
  (key, value) => value && typeof value === "object" && value.constructor && value.constructor.name === "Object" ? "[serverTimestamp]" : value
1881
2232
  )
1882
2233
  );
1883
- await (0, import_firestore7.setDoc)(medicalInfoRef, defaultData);
2234
+ await (0, import_firestore9.setDoc)(medicalInfoRef, defaultData);
1884
2235
  console.log(`[ensureMedicalInfoExists] Document created successfully`);
1885
- const verifyDoc = await (0, import_firestore7.getDoc)(medicalInfoRef);
2236
+ const verifyDoc = await (0, import_firestore9.getDoc)(medicalInfoRef);
1886
2237
  console.log(
1887
2238
  `[ensureMedicalInfoExists] Verification - document exists: ${verifyDoc.exists()}`
1888
2239
  );
@@ -1898,7 +2249,7 @@ var ensureMedicalInfoExists = async (db, patientId, userRef) => {
1898
2249
  };
1899
2250
  var checkMedicalAccessUtil = async (db, patientId, userRef, userRoles) => {
1900
2251
  var _a;
1901
- const patientDoc = await (0, import_firestore7.getDoc)(getPatientDocRef(db, patientId));
2252
+ const patientDoc = await (0, import_firestore9.getDoc)(getPatientDocRef(db, patientId));
1902
2253
  if (!patientDoc.exists()) {
1903
2254
  throw new Error("Patient profile not found");
1904
2255
  }
@@ -1931,17 +2282,17 @@ var checkMedicalAccessUtil = async (db, patientId, userRef, userRoles) => {
1931
2282
  var createMedicalInfoUtil = async (db, patientId, data, userRef, userRoles) => {
1932
2283
  await checkMedicalAccessUtil(db, patientId, userRef, userRoles);
1933
2284
  const validatedData = createPatientMedicalInfoSchema.parse(data);
1934
- await (0, import_firestore7.setDoc)(getMedicalInfoDocRef(db, patientId), {
2285
+ await (0, import_firestore9.setDoc)(getMedicalInfoDocRef(db, patientId), {
1935
2286
  ...validatedData,
1936
2287
  patientId,
1937
- lastUpdated: import_firestore7.Timestamp.now(),
2288
+ lastUpdated: import_firestore9.Timestamp.now(),
1938
2289
  updatedBy: userRef
1939
2290
  });
1940
2291
  };
1941
2292
  var getMedicalInfoUtil = async (db, patientId, userRef, userRoles) => {
1942
2293
  await checkMedicalAccessUtil(db, patientId, userRef, userRoles);
1943
2294
  const docRef = getMedicalInfoDocRef(db, patientId);
1944
- const snapshot = await (0, import_firestore7.getDoc)(docRef);
2295
+ const snapshot = await (0, import_firestore9.getDoc)(docRef);
1945
2296
  if (!snapshot.exists()) {
1946
2297
  throw new Error("Medicinske informacije nisu prona\u0111ene");
1947
2298
  }
@@ -1950,25 +2301,25 @@ var getMedicalInfoUtil = async (db, patientId, userRef, userRoles) => {
1950
2301
  var updateVitalStatsUtil = async (db, patientId, data, userRef) => {
1951
2302
  await ensureMedicalInfoExists(db, patientId, userRef);
1952
2303
  const validatedData = updateVitalStatsSchema.parse(data);
1953
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2304
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
1954
2305
  vitalStats: validatedData,
1955
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2306
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
1956
2307
  updatedBy: userRef
1957
2308
  });
1958
2309
  };
1959
2310
  var addAllergyUtil = async (db, patientId, data, userRef) => {
1960
2311
  await ensureMedicalInfoExists(db, patientId, userRef);
1961
2312
  const validatedData = addAllergySchema.parse(data);
1962
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
1963
- allergies: (0, import_firestore7.arrayUnion)(validatedData),
1964
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2313
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2314
+ allergies: (0, import_firestore9.arrayUnion)(validatedData),
2315
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
1965
2316
  updatedBy: userRef
1966
2317
  });
1967
2318
  };
1968
2319
  var updateAllergyUtil = async (db, patientId, data, userRef) => {
1969
2320
  const validatedData = updateAllergySchema.parse(data);
1970
2321
  const { allergyIndex, ...updateData } = validatedData;
1971
- const docSnapshot = await (0, import_firestore7.getDoc)(getMedicalInfoDocRef(db, patientId));
2322
+ const docSnapshot = await (0, import_firestore9.getDoc)(getMedicalInfoDocRef(db, patientId));
1972
2323
  if (!docSnapshot.exists()) throw new Error("Medical info not found");
1973
2324
  const medicalInfo = patientMedicalInfoSchema.parse(docSnapshot.data());
1974
2325
  if (allergyIndex >= medicalInfo.allergies.length) {
@@ -1979,14 +2330,14 @@ var updateAllergyUtil = async (db, patientId, data, userRef) => {
1979
2330
  ...updatedAllergies[allergyIndex],
1980
2331
  ...updateData
1981
2332
  };
1982
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2333
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
1983
2334
  allergies: updatedAllergies,
1984
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2335
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
1985
2336
  updatedBy: userRef
1986
2337
  });
1987
2338
  };
1988
2339
  var removeAllergyUtil = async (db, patientId, allergyIndex, userRef) => {
1989
- const doc34 = await (0, import_firestore7.getDoc)(getMedicalInfoDocRef(db, patientId));
2340
+ const doc34 = await (0, import_firestore9.getDoc)(getMedicalInfoDocRef(db, patientId));
1990
2341
  if (!doc34.exists()) throw new Error("Medical info not found");
1991
2342
  const medicalInfo = doc34.data();
1992
2343
  if (allergyIndex >= medicalInfo.allergies.length) {
@@ -1995,25 +2346,25 @@ var removeAllergyUtil = async (db, patientId, allergyIndex, userRef) => {
1995
2346
  const updatedAllergies = medicalInfo.allergies.filter(
1996
2347
  (_, index) => index !== allergyIndex
1997
2348
  );
1998
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2349
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
1999
2350
  allergies: updatedAllergies,
2000
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2351
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2001
2352
  updatedBy: userRef
2002
2353
  });
2003
2354
  };
2004
2355
  var addBlockingConditionUtil = async (db, patientId, data, userRef) => {
2005
2356
  await ensureMedicalInfoExists(db, patientId, userRef);
2006
2357
  const validatedData = addBlockingConditionSchema.parse(data);
2007
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2008
- blockingConditions: (0, import_firestore7.arrayUnion)(validatedData),
2009
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2358
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2359
+ blockingConditions: (0, import_firestore9.arrayUnion)(validatedData),
2360
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2010
2361
  updatedBy: userRef
2011
2362
  });
2012
2363
  };
2013
2364
  var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
2014
2365
  const validatedData = updateBlockingConditionSchema.parse(data);
2015
2366
  const { conditionIndex, ...updateData } = validatedData;
2016
- const doc34 = await (0, import_firestore7.getDoc)(getMedicalInfoDocRef(db, patientId));
2367
+ const doc34 = await (0, import_firestore9.getDoc)(getMedicalInfoDocRef(db, patientId));
2017
2368
  if (!doc34.exists()) throw new Error("Medical info not found");
2018
2369
  const medicalInfo = doc34.data();
2019
2370
  if (conditionIndex >= medicalInfo.blockingConditions.length) {
@@ -2024,14 +2375,14 @@ var updateBlockingConditionUtil = async (db, patientId, data, userRef) => {
2024
2375
  ...updatedConditions[conditionIndex],
2025
2376
  ...updateData
2026
2377
  };
2027
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2378
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2028
2379
  blockingConditions: updatedConditions,
2029
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2380
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2030
2381
  updatedBy: userRef
2031
2382
  });
2032
2383
  };
2033
2384
  var removeBlockingConditionUtil = async (db, patientId, conditionIndex, userRef) => {
2034
- const doc34 = await (0, import_firestore7.getDoc)(getMedicalInfoDocRef(db, patientId));
2385
+ const doc34 = await (0, import_firestore9.getDoc)(getMedicalInfoDocRef(db, patientId));
2035
2386
  if (!doc34.exists()) throw new Error("Medical info not found");
2036
2387
  const medicalInfo = doc34.data();
2037
2388
  if (conditionIndex >= medicalInfo.blockingConditions.length) {
@@ -2040,25 +2391,25 @@ var removeBlockingConditionUtil = async (db, patientId, conditionIndex, userRef)
2040
2391
  const updatedConditions = medicalInfo.blockingConditions.filter(
2041
2392
  (_, index) => index !== conditionIndex
2042
2393
  );
2043
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2394
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2044
2395
  blockingConditions: updatedConditions,
2045
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2396
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2046
2397
  updatedBy: userRef
2047
2398
  });
2048
2399
  };
2049
2400
  var addContraindicationUtil = async (db, patientId, data, userRef) => {
2050
2401
  await ensureMedicalInfoExists(db, patientId, userRef);
2051
2402
  const validatedData = addContraindicationSchema.parse(data);
2052
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2053
- contraindications: (0, import_firestore7.arrayUnion)(validatedData),
2054
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2403
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2404
+ contraindications: (0, import_firestore9.arrayUnion)(validatedData),
2405
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2055
2406
  updatedBy: userRef
2056
2407
  });
2057
2408
  };
2058
2409
  var updateContraindicationUtil = async (db, patientId, data, userRef) => {
2059
2410
  const validatedData = updateContraindicationSchema.parse(data);
2060
2411
  const { contraindicationIndex, ...updateData } = validatedData;
2061
- const doc34 = await (0, import_firestore7.getDoc)(getMedicalInfoDocRef(db, patientId));
2412
+ const doc34 = await (0, import_firestore9.getDoc)(getMedicalInfoDocRef(db, patientId));
2062
2413
  if (!doc34.exists()) throw new Error("Medical info not found");
2063
2414
  const medicalInfo = doc34.data();
2064
2415
  if (contraindicationIndex >= medicalInfo.contraindications.length) {
@@ -2069,14 +2420,14 @@ var updateContraindicationUtil = async (db, patientId, data, userRef) => {
2069
2420
  ...updatedContraindications[contraindicationIndex],
2070
2421
  ...updateData
2071
2422
  };
2072
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2423
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2073
2424
  contraindications: updatedContraindications,
2074
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2425
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2075
2426
  updatedBy: userRef
2076
2427
  });
2077
2428
  };
2078
2429
  var removeContraindicationUtil = async (db, patientId, contraindicationIndex, userRef) => {
2079
- const doc34 = await (0, import_firestore7.getDoc)(getMedicalInfoDocRef(db, patientId));
2430
+ const doc34 = await (0, import_firestore9.getDoc)(getMedicalInfoDocRef(db, patientId));
2080
2431
  if (!doc34.exists()) throw new Error("Medical info not found");
2081
2432
  const medicalInfo = doc34.data();
2082
2433
  if (contraindicationIndex >= medicalInfo.contraindications.length) {
@@ -2085,25 +2436,25 @@ var removeContraindicationUtil = async (db, patientId, contraindicationIndex, us
2085
2436
  const updatedContraindications = medicalInfo.contraindications.filter(
2086
2437
  (_, index) => index !== contraindicationIndex
2087
2438
  );
2088
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2439
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2089
2440
  contraindications: updatedContraindications,
2090
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2441
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2091
2442
  updatedBy: userRef
2092
2443
  });
2093
2444
  };
2094
2445
  var addMedicationUtil = async (db, patientId, data, userRef) => {
2095
2446
  await ensureMedicalInfoExists(db, patientId, userRef);
2096
2447
  const validatedData = addMedicationSchema.parse(data);
2097
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2098
- currentMedications: (0, import_firestore7.arrayUnion)(validatedData),
2099
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2448
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2449
+ currentMedications: (0, import_firestore9.arrayUnion)(validatedData),
2450
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2100
2451
  updatedBy: userRef
2101
2452
  });
2102
2453
  };
2103
2454
  var updateMedicationUtil = async (db, patientId, data, userRef) => {
2104
2455
  const validatedData = updateMedicationSchema.parse(data);
2105
2456
  const { medicationIndex, ...updateData } = validatedData;
2106
- const doc34 = await (0, import_firestore7.getDoc)(getMedicalInfoDocRef(db, patientId));
2457
+ const doc34 = await (0, import_firestore9.getDoc)(getMedicalInfoDocRef(db, patientId));
2107
2458
  if (!doc34.exists()) throw new Error("Medical info not found");
2108
2459
  const medicalInfo = doc34.data();
2109
2460
  if (medicationIndex >= medicalInfo.currentMedications.length) {
@@ -2114,14 +2465,14 @@ var updateMedicationUtil = async (db, patientId, data, userRef) => {
2114
2465
  ...updatedMedications[medicationIndex],
2115
2466
  ...updateData
2116
2467
  };
2117
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2468
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2118
2469
  currentMedications: updatedMedications,
2119
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2470
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2120
2471
  updatedBy: userRef
2121
2472
  });
2122
2473
  };
2123
2474
  var removeMedicationUtil = async (db, patientId, medicationIndex, userRef) => {
2124
- const doc34 = await (0, import_firestore7.getDoc)(getMedicalInfoDocRef(db, patientId));
2475
+ const doc34 = await (0, import_firestore9.getDoc)(getMedicalInfoDocRef(db, patientId));
2125
2476
  if (!doc34.exists()) throw new Error("Medical info not found");
2126
2477
  const medicalInfo = doc34.data();
2127
2478
  if (medicationIndex >= medicalInfo.currentMedications.length) {
@@ -2130,9 +2481,9 @@ var removeMedicationUtil = async (db, patientId, medicationIndex, userRef) => {
2130
2481
  const updatedMedications = medicalInfo.currentMedications.filter(
2131
2482
  (_, index) => index !== medicationIndex
2132
2483
  );
2133
- await (0, import_firestore7.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2484
+ await (0, import_firestore9.updateDoc)(getMedicalInfoDocRef(db, patientId), {
2134
2485
  currentMedications: updatedMedications,
2135
- lastUpdated: (0, import_firestore7.serverTimestamp)(),
2486
+ lastUpdated: (0, import_firestore9.serverTimestamp)(),
2136
2487
  updatedBy: userRef
2137
2488
  });
2138
2489
  };
@@ -2149,7 +2500,6 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
2149
2500
  id: patientId,
2150
2501
  userRef: validatedData.userRef,
2151
2502
  displayName: validatedData.displayName,
2152
- profilePhoto: validatedData.profilePhoto || null,
2153
2503
  expoTokens: validatedData.expoTokens,
2154
2504
  gamification: validatedData.gamification || {
2155
2505
  level: 1,
@@ -2161,15 +2511,15 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
2161
2511
  clinics: validatedData.clinics || [],
2162
2512
  doctorIds: ((_a = validatedData.doctors) == null ? void 0 : _a.map((d) => d.userRef)) || [],
2163
2513
  clinicIds: ((_b = validatedData.clinics) == null ? void 0 : _b.map((c) => c.clinicId)) || [],
2164
- createdAt: (0, import_firestore8.serverTimestamp)(),
2165
- updatedAt: (0, import_firestore8.serverTimestamp)()
2514
+ createdAt: (0, import_firestore10.serverTimestamp)(),
2515
+ updatedAt: (0, import_firestore10.serverTimestamp)()
2166
2516
  };
2167
2517
  patientProfileSchema.parse({
2168
2518
  ...patientData,
2169
- createdAt: import_firestore8.Timestamp.now(),
2170
- updatedAt: import_firestore8.Timestamp.now()
2519
+ createdAt: import_firestore10.Timestamp.now(),
2520
+ updatedAt: import_firestore10.Timestamp.now()
2171
2521
  });
2172
- await (0, import_firestore8.setDoc)(getPatientDocRef(db, patientId), patientData);
2522
+ await (0, import_firestore10.setDoc)(getPatientDocRef(db, patientId), patientData);
2173
2523
  console.log(`[createPatientProfileUtil] Creating sensitive info document`);
2174
2524
  let sensitiveInfoSuccess = false;
2175
2525
  try {
@@ -2183,81 +2533,103 @@ var createPatientProfileUtil = async (db, data, generateId2) => {
2183
2533
  );
2184
2534
  sensitiveInfoSuccess = true;
2185
2535
  } catch (sensitiveError) {
2186
- console.error(`[createPatientProfileUtil] Error creating sensitive info:`, sensitiveError);
2536
+ console.error(
2537
+ `[createPatientProfileUtil] Error creating sensitive info:`,
2538
+ sensitiveError
2539
+ );
2187
2540
  }
2188
2541
  console.log(`[createPatientProfileUtil] Creating medical info document`);
2189
2542
  let medicalInfoSuccess = false;
2190
2543
  try {
2191
2544
  await ensureMedicalInfoExists(db, patientId, validatedData.userRef);
2192
- console.log(`[createPatientProfileUtil] Medical info document created successfully`);
2545
+ console.log(
2546
+ `[createPatientProfileUtil] Medical info document created successfully`
2547
+ );
2193
2548
  medicalInfoSuccess = true;
2194
2549
  } catch (medicalError) {
2195
- console.error(`[createPatientProfileUtil] Error creating medical info:`, medicalError);
2550
+ console.error(
2551
+ `[createPatientProfileUtil] Error creating medical info:`,
2552
+ medicalError
2553
+ );
2196
2554
  }
2197
2555
  if (!sensitiveInfoSuccess || !medicalInfoSuccess) {
2198
- console.log(`[createPatientProfileUtil] Using fallback method to create documents`);
2556
+ console.log(
2557
+ `[createPatientProfileUtil] Using fallback method to create documents`
2558
+ );
2199
2559
  try {
2200
2560
  await testCreateSubDocuments(db, patientId, validatedData.userRef);
2201
- console.log(`[createPatientProfileUtil] Fallback method completed successfully`);
2561
+ console.log(
2562
+ `[createPatientProfileUtil] Fallback method completed successfully`
2563
+ );
2202
2564
  } catch (fallbackError) {
2203
- console.error(`[createPatientProfileUtil] Fallback method failed:`, fallbackError);
2565
+ console.error(
2566
+ `[createPatientProfileUtil] Fallback method failed:`,
2567
+ fallbackError
2568
+ );
2204
2569
  }
2205
2570
  }
2206
2571
  console.log(`[createPatientProfileUtil] Verifying patient document exists`);
2207
- const patientDoc = await (0, import_firestore8.getDoc)(getPatientDocRef(db, patientId));
2572
+ const patientDoc = await (0, import_firestore10.getDoc)(getPatientDocRef(db, patientId));
2208
2573
  if (!patientDoc.exists()) {
2209
- console.error(`[createPatientProfileUtil] Patient document not found after creation`);
2574
+ console.error(
2575
+ `[createPatientProfileUtil] Patient document not found after creation`
2576
+ );
2210
2577
  throw new Error("Failed to create patient profile");
2211
2578
  }
2212
- console.log(`[createPatientProfileUtil] Patient profile creation completed successfully`);
2579
+ console.log(
2580
+ `[createPatientProfileUtil] Patient profile creation completed successfully`
2581
+ );
2213
2582
  return patientDoc.data();
2214
2583
  } catch (error) {
2215
- console.error(`[createPatientProfileUtil] Error in patient profile creation:`, error);
2216
- if (error instanceof import_zod8.z.ZodError) {
2584
+ console.error(
2585
+ `[createPatientProfileUtil] Error in patient profile creation:`,
2586
+ error
2587
+ );
2588
+ if (error instanceof import_zod9.z.ZodError) {
2217
2589
  throw new Error("Invalid patient data: " + error.message);
2218
2590
  }
2219
2591
  throw error;
2220
2592
  }
2221
2593
  };
2222
2594
  var getPatientProfileUtil = async (db, patientId) => {
2223
- const patientDoc = await (0, import_firestore8.getDoc)(getPatientDocRef(db, patientId));
2595
+ const patientDoc = await (0, import_firestore10.getDoc)(getPatientDocRef(db, patientId));
2224
2596
  return patientDoc.exists() ? patientDoc.data() : null;
2225
2597
  };
2226
2598
  var getPatientProfileByUserRefUtil = async (db, userRef) => {
2227
2599
  try {
2228
2600
  const docRef = await getPatientDocRefByUserRef(db, userRef);
2229
- const patientDoc = await (0, import_firestore8.getDoc)(docRef);
2601
+ const patientDoc = await (0, import_firestore10.getDoc)(docRef);
2230
2602
  return patientDoc.exists() ? patientDoc.data() : null;
2231
2603
  } catch (error) {
2232
2604
  return null;
2233
2605
  }
2234
2606
  };
2235
2607
  var addExpoTokenUtil = async (db, patientId, token) => {
2236
- await (0, import_firestore8.updateDoc)(getPatientDocRef(db, patientId), {
2237
- expoTokens: (0, import_firestore8.arrayUnion)(token),
2238
- updatedAt: (0, import_firestore8.serverTimestamp)()
2608
+ await (0, import_firestore10.updateDoc)(getPatientDocRef(db, patientId), {
2609
+ expoTokens: (0, import_firestore10.arrayUnion)(token),
2610
+ updatedAt: (0, import_firestore10.serverTimestamp)()
2239
2611
  });
2240
2612
  };
2241
2613
  var removeExpoTokenUtil = async (db, patientId, token) => {
2242
- await (0, import_firestore8.updateDoc)(getPatientDocRef(db, patientId), {
2243
- expoTokens: (0, import_firestore8.arrayRemove)(token),
2244
- updatedAt: (0, import_firestore8.serverTimestamp)()
2614
+ await (0, import_firestore10.updateDoc)(getPatientDocRef(db, patientId), {
2615
+ expoTokens: (0, import_firestore10.arrayRemove)(token),
2616
+ updatedAt: (0, import_firestore10.serverTimestamp)()
2245
2617
  });
2246
2618
  };
2247
2619
  var addPointsUtil = async (db, patientId, points) => {
2248
- await (0, import_firestore8.updateDoc)(getPatientDocRef(db, patientId), {
2249
- "gamification.points": (0, import_firestore8.increment)(points),
2250
- updatedAt: (0, import_firestore8.serverTimestamp)()
2620
+ await (0, import_firestore10.updateDoc)(getPatientDocRef(db, patientId), {
2621
+ "gamification.points": (0, import_firestore10.increment)(points),
2622
+ updatedAt: (0, import_firestore10.serverTimestamp)()
2251
2623
  });
2252
2624
  };
2253
2625
  var updatePatientProfileUtil = async (db, patientId, data) => {
2254
2626
  try {
2255
2627
  const updateData = {
2256
2628
  ...data,
2257
- updatedAt: (0, import_firestore8.serverTimestamp)()
2629
+ updatedAt: (0, import_firestore10.serverTimestamp)()
2258
2630
  };
2259
- await (0, import_firestore8.updateDoc)(getPatientDocRef(db, patientId), updateData);
2260
- const updatedDoc = await (0, import_firestore8.getDoc)(getPatientDocRef(db, patientId));
2631
+ await (0, import_firestore10.updateDoc)(getPatientDocRef(db, patientId), updateData);
2632
+ const updatedDoc = await (0, import_firestore10.getDoc)(getPatientDocRef(db, patientId));
2261
2633
  if (!updatedDoc.exists()) {
2262
2634
  throw new Error("Patient profile not found after update");
2263
2635
  }
@@ -2270,7 +2642,7 @@ var updatePatientProfileUtil = async (db, patientId, data) => {
2270
2642
  var updatePatientProfileByUserRefUtil = async (db, userRef, data) => {
2271
2643
  try {
2272
2644
  const docRef = await getPatientDocRefByUserRef(db, userRef);
2273
- const patientDoc = await (0, import_firestore8.getDoc)(docRef);
2645
+ const patientDoc = await (0, import_firestore10.getDoc)(docRef);
2274
2646
  if (!patientDoc.exists()) {
2275
2647
  throw new Error("Patient profile not found");
2276
2648
  }
@@ -2278,49 +2650,10 @@ var updatePatientProfileByUserRefUtil = async (db, userRef, data) => {
2278
2650
  return updatePatientProfileUtil(db, patientData.id, data);
2279
2651
  } catch (error) {
2280
2652
  const errorMessage = error instanceof Error ? error.message : String(error);
2281
- throw new Error(`Failed to update patient profile by user ref: ${errorMessage}`);
2282
- }
2283
- };
2284
- var uploadProfilePhotoUtil = async (storage, patientId, file) => {
2285
- const photoRef = (0, import_storage3.ref)(storage, `patient-photos/${patientId}/profile-photo`);
2286
- await (0, import_storage3.uploadBytes)(photoRef, file);
2287
- return (0, import_storage3.getDownloadURL)(photoRef);
2288
- };
2289
- var updateProfilePhotoUtil = async (storage, db, patientId, file) => {
2290
- const patientDoc = await (0, import_firestore8.getDoc)(getPatientDocRef(db, patientId));
2291
- if (!patientDoc.exists()) throw new Error("Patient profile not found");
2292
- const patientData = patientDoc.data();
2293
- if (patientData.profilePhoto) {
2294
- try {
2295
- const oldPhotoRef = (0, import_storage3.ref)(storage, patientData.profilePhoto);
2296
- await (0, import_storage3.deleteObject)(oldPhotoRef);
2297
- } catch (error) {
2298
- console.warn("Failed to delete old profile photo:", error);
2299
- }
2300
- }
2301
- const newPhotoUrl = await uploadProfilePhotoUtil(storage, patientId, file);
2302
- await (0, import_firestore8.updateDoc)(getPatientDocRef(db, patientId), {
2303
- profilePhoto: newPhotoUrl,
2304
- updatedAt: (0, import_firestore8.serverTimestamp)()
2305
- });
2306
- return newPhotoUrl;
2307
- };
2308
- var deleteProfilePhotoUtil = async (storage, db, patientId) => {
2309
- const patientDoc = await (0, import_firestore8.getDoc)(getPatientDocRef(db, patientId));
2310
- if (!patientDoc.exists()) throw new Error("Patient profile not found");
2311
- const patientData = patientDoc.data();
2312
- if (patientData.profilePhoto) {
2313
- try {
2314
- const photoRef = (0, import_storage3.ref)(storage, patientData.profilePhoto);
2315
- await (0, import_storage3.deleteObject)(photoRef);
2316
- } catch (error) {
2317
- console.warn("Failed to delete profile photo:", error);
2318
- }
2653
+ throw new Error(
2654
+ `Failed to update patient profile by user ref: ${errorMessage}`
2655
+ );
2319
2656
  }
2320
- await (0, import_firestore8.updateDoc)(getPatientDocRef(db, patientId), {
2321
- profilePhoto: null,
2322
- updatedAt: (0, import_firestore8.serverTimestamp)()
2323
- });
2324
2657
  };
2325
2658
  var testCreateSubDocuments = async (db, patientId, userRef) => {
2326
2659
  console.log(
@@ -2329,33 +2662,41 @@ var testCreateSubDocuments = async (db, patientId, userRef) => {
2329
2662
  try {
2330
2663
  console.log(`[testCreateSubDocuments] Testing sensitive info creation`);
2331
2664
  const sensitiveInfoRef = getSensitiveInfoDocRef(db, patientId);
2332
- console.log(`[testCreateSubDocuments] Sensitive info path: ${sensitiveInfoRef.path}`);
2665
+ console.log(
2666
+ `[testCreateSubDocuments] Sensitive info path: ${sensitiveInfoRef.path}`
2667
+ );
2333
2668
  const defaultSensitiveInfo = {
2334
2669
  patientId,
2335
2670
  userRef,
2336
2671
  photoUrl: "",
2337
2672
  firstName: "Name",
2338
2673
  lastName: "Surname",
2339
- dateOfBirth: import_firestore8.Timestamp.now(),
2674
+ dateOfBirth: import_firestore10.Timestamp.now(),
2340
2675
  gender: "prefer_not_to_say" /* PREFER_NOT_TO_SAY */,
2341
2676
  email: "test@example.com",
2342
2677
  phoneNumber: "",
2343
- createdAt: import_firestore8.Timestamp.now(),
2344
- updatedAt: import_firestore8.Timestamp.now()
2678
+ createdAt: import_firestore10.Timestamp.now(),
2679
+ updatedAt: import_firestore10.Timestamp.now()
2345
2680
  };
2346
- await (0, import_firestore8.setDoc)(sensitiveInfoRef, defaultSensitiveInfo);
2347
- console.log(`[testCreateSubDocuments] Sensitive info document created directly`);
2681
+ await (0, import_firestore10.setDoc)(sensitiveInfoRef, defaultSensitiveInfo);
2682
+ console.log(
2683
+ `[testCreateSubDocuments] Sensitive info document created directly`
2684
+ );
2348
2685
  console.log(`[testCreateSubDocuments] Testing medical info creation`);
2349
2686
  const medicalInfoRef = getMedicalInfoDocRef(db, patientId);
2350
- console.log(`[testCreateSubDocuments] Medical info path: ${medicalInfoRef.path}`);
2687
+ console.log(
2688
+ `[testCreateSubDocuments] Medical info path: ${medicalInfoRef.path}`
2689
+ );
2351
2690
  const defaultMedicalInfo = {
2352
2691
  ...DEFAULT_MEDICAL_INFO,
2353
2692
  patientId,
2354
- lastUpdated: import_firestore8.Timestamp.now(),
2693
+ lastUpdated: import_firestore10.Timestamp.now(),
2355
2694
  updatedBy: userRef
2356
2695
  };
2357
- await (0, import_firestore8.setDoc)(medicalInfoRef, defaultMedicalInfo);
2358
- console.log(`[testCreateSubDocuments] Medical info document created directly`);
2696
+ await (0, import_firestore10.setDoc)(medicalInfoRef, defaultMedicalInfo);
2697
+ console.log(
2698
+ `[testCreateSubDocuments] Medical info document created directly`
2699
+ );
2359
2700
  console.log(`[testCreateSubDocuments] Test completed successfully`);
2360
2701
  } catch (error) {
2361
2702
  console.error(`[testCreateSubDocuments] Error:`, error);
@@ -2366,10 +2707,12 @@ var searchPatientsUtil = async (db, params, requester) => {
2366
2707
  searchPatientsSchema.parse(params);
2367
2708
  requesterInfoSchema.parse(requester);
2368
2709
  const constraints = [];
2369
- const patientsCollectionRef = (0, import_firestore8.collection)(db, PATIENTS_COLLECTION);
2710
+ const patientsCollectionRef = (0, import_firestore10.collection)(db, PATIENTS_COLLECTION);
2370
2711
  if (requester.role === "clinic_admin") {
2371
2712
  if (!requester.associatedClinicId) {
2372
- throw new Error("Associated clinic ID is required for clinic admin search.");
2713
+ throw new Error(
2714
+ "Associated clinic ID is required for clinic admin search."
2715
+ );
2373
2716
  }
2374
2717
  if (params.clinicId && params.clinicId !== requester.associatedClinicId) {
2375
2718
  console.warn(
@@ -2377,13 +2720,19 @@ var searchPatientsUtil = async (db, params, requester) => {
2377
2720
  );
2378
2721
  return [];
2379
2722
  }
2380
- constraints.push((0, import_firestore8.where)("clinicIds", "array-contains", requester.associatedClinicId));
2723
+ constraints.push(
2724
+ (0, import_firestore10.where)("clinicIds", "array-contains", requester.associatedClinicId)
2725
+ );
2381
2726
  if (params.practitionerId) {
2382
- constraints.push((0, import_firestore8.where)("doctorIds", "array-contains", params.practitionerId));
2727
+ constraints.push(
2728
+ (0, import_firestore10.where)("doctorIds", "array-contains", params.practitionerId)
2729
+ );
2383
2730
  }
2384
2731
  } else if (requester.role === "practitioner") {
2385
2732
  if (!requester.associatedPractitionerId) {
2386
- throw new Error("Associated practitioner ID is required for practitioner search.");
2733
+ throw new Error(
2734
+ "Associated practitioner ID is required for practitioner search."
2735
+ );
2387
2736
  }
2388
2737
  if (params.practitionerId && params.practitionerId !== requester.associatedPractitionerId) {
2389
2738
  console.warn(
@@ -2391,18 +2740,24 @@ var searchPatientsUtil = async (db, params, requester) => {
2391
2740
  );
2392
2741
  return [];
2393
2742
  }
2394
- constraints.push((0, import_firestore8.where)("doctorIds", "array-contains", requester.associatedPractitionerId));
2743
+ constraints.push(
2744
+ (0, import_firestore10.where)("doctorIds", "array-contains", requester.associatedPractitionerId)
2745
+ );
2395
2746
  if (params.clinicId) {
2396
- constraints.push((0, import_firestore8.where)("clinicIds", "array-contains", params.clinicId));
2747
+ constraints.push((0, import_firestore10.where)("clinicIds", "array-contains", params.clinicId));
2397
2748
  }
2398
2749
  } else {
2399
2750
  throw new Error("Invalid requester role.");
2400
2751
  }
2401
2752
  try {
2402
- const finalQuery = (0, import_firestore8.query)(patientsCollectionRef, ...constraints);
2403
- const querySnapshot = await (0, import_firestore8.getDocs)(finalQuery);
2404
- const patients = querySnapshot.docs.map((doc34) => doc34.data());
2405
- console.log(`[searchPatientsUtil] Found ${patients.length} patients matching criteria.`);
2753
+ const finalQuery = (0, import_firestore10.query)(patientsCollectionRef, ...constraints);
2754
+ const querySnapshot = await (0, import_firestore10.getDocs)(finalQuery);
2755
+ const patients = querySnapshot.docs.map(
2756
+ (doc34) => doc34.data()
2757
+ );
2758
+ console.log(
2759
+ `[searchPatientsUtil] Found ${patients.length} patients matching criteria.`
2760
+ );
2406
2761
  return patients;
2407
2762
  } catch (error) {
2408
2763
  console.error("[searchPatientsUtil] Error searching patients:", error);
@@ -2411,19 +2766,24 @@ var searchPatientsUtil = async (db, params, requester) => {
2411
2766
  };
2412
2767
  var getAllPatientsUtil = async (db, options) => {
2413
2768
  try {
2414
- console.log(`[getAllPatientsUtil] Fetching patients with options:`, options);
2415
- const patientsCollection = (0, import_firestore8.collection)(db, PATIENTS_COLLECTION);
2416
- let q = (0, import_firestore8.query)(patientsCollection);
2769
+ console.log(
2770
+ `[getAllPatientsUtil] Fetching patients with options:`,
2771
+ options
2772
+ );
2773
+ const patientsCollection = (0, import_firestore10.collection)(db, PATIENTS_COLLECTION);
2774
+ let q = (0, import_firestore10.query)(patientsCollection);
2417
2775
  if (options == null ? void 0 : options.limit) {
2418
- q = (0, import_firestore8.query)(q, (0, import_firestore8.limit)(options.limit));
2776
+ q = (0, import_firestore10.query)(q, (0, import_firestore10.limit)(options.limit));
2419
2777
  }
2420
2778
  if (options == null ? void 0 : options.startAfter) {
2421
- const startAfterDoc = await (0, import_firestore8.getDoc)((0, import_firestore8.doc)(db, PATIENTS_COLLECTION, options.startAfter));
2779
+ const startAfterDoc = await (0, import_firestore10.getDoc)(
2780
+ (0, import_firestore10.doc)(db, PATIENTS_COLLECTION, options.startAfter)
2781
+ );
2422
2782
  if (startAfterDoc.exists()) {
2423
- q = (0, import_firestore8.query)(q, (0, import_firestore8.startAfter)(startAfterDoc));
2783
+ q = (0, import_firestore10.query)(q, (0, import_firestore10.startAfter)(startAfterDoc));
2424
2784
  }
2425
2785
  }
2426
- const patientsSnapshot = await (0, import_firestore8.getDocs)(q);
2786
+ const patientsSnapshot = await (0, import_firestore10.getDocs)(q);
2427
2787
  const patients = [];
2428
2788
  patientsSnapshot.forEach((doc34) => {
2429
2789
  patients.push(doc34.data());
@@ -2439,8 +2799,8 @@ var getAllPatientsUtil = async (db, options) => {
2439
2799
  };
2440
2800
 
2441
2801
  // src/services/patient/utils/location.utils.ts
2442
- var import_firestore9 = require("firebase/firestore");
2443
- var import_zod9 = require("zod");
2802
+ var import_firestore11 = require("firebase/firestore");
2803
+ var import_zod10 = require("zod");
2444
2804
  var import_geofire_common = require("geofire-common");
2445
2805
  var updatePatientLocationUtil = async (db, patientId, latitude, longitude) => {
2446
2806
  const locationData = {
@@ -2450,9 +2810,9 @@ var updatePatientLocationUtil = async (db, patientId, latitude, longitude) => {
2450
2810
  };
2451
2811
  const updateData = {
2452
2812
  locationData,
2453
- updatedAt: (0, import_firestore9.serverTimestamp)()
2813
+ updatedAt: (0, import_firestore11.serverTimestamp)()
2454
2814
  };
2455
- await (0, import_firestore9.updateDoc)(getLocationInfoDocRef(db, patientId), updateData);
2815
+ await (0, import_firestore11.updateDoc)(getLocationInfoDocRef(db, patientId), updateData);
2456
2816
  };
2457
2817
  var createLocationInfoUtil = async (db, data, requesterId) => {
2458
2818
  try {
@@ -2469,17 +2829,17 @@ var createLocationInfoUtil = async (db, data, requesterId) => {
2469
2829
  validatedData.locationData.longitude
2470
2830
  ])
2471
2831
  },
2472
- createdAt: (0, import_firestore9.serverTimestamp)(),
2473
- updatedAt: (0, import_firestore9.serverTimestamp)()
2832
+ createdAt: (0, import_firestore11.serverTimestamp)(),
2833
+ updatedAt: (0, import_firestore11.serverTimestamp)()
2474
2834
  };
2475
- await (0, import_firestore9.setDoc)(getLocationInfoDocRef(db, data.patientId), locationData);
2476
- const locationDoc = await (0, import_firestore9.getDoc)(getLocationInfoDocRef(db, data.patientId));
2835
+ await (0, import_firestore11.setDoc)(getLocationInfoDocRef(db, data.patientId), locationData);
2836
+ const locationDoc = await (0, import_firestore11.getDoc)(getLocationInfoDocRef(db, data.patientId));
2477
2837
  if (!locationDoc.exists()) {
2478
2838
  throw new Error("Failed to create location information");
2479
2839
  }
2480
2840
  return locationDoc.data();
2481
2841
  } catch (error) {
2482
- if (error instanceof import_zod9.z.ZodError) {
2842
+ if (error instanceof import_zod10.z.ZodError) {
2483
2843
  throw new Error("Invalid location data: " + error.message);
2484
2844
  }
2485
2845
  throw error;
@@ -2489,7 +2849,7 @@ var getLocationInfoUtil = async (db, patientId, requesterId) => {
2489
2849
  if (patientId !== requesterId) {
2490
2850
  throw new Error("Unauthorized access to location information");
2491
2851
  }
2492
- const locationDoc = await (0, import_firestore9.getDoc)(getLocationInfoDocRef(db, patientId));
2852
+ const locationDoc = await (0, import_firestore11.getDoc)(getLocationInfoDocRef(db, patientId));
2493
2853
  return locationDoc.exists() ? locationDoc.data() : null;
2494
2854
  };
2495
2855
  var updateLocationInfoUtil = async (db, patientId, data, requesterId) => {
@@ -2506,8 +2866,8 @@ var updateLocationInfoUtil = async (db, patientId, data, requesterId) => {
2506
2866
  ])
2507
2867
  };
2508
2868
  }
2509
- updateData.updatedAt = (0, import_firestore9.serverTimestamp)();
2510
- await (0, import_firestore9.updateDoc)(getLocationInfoDocRef(db, patientId), updateData);
2869
+ updateData.updatedAt = (0, import_firestore11.serverTimestamp)();
2870
+ await (0, import_firestore11.updateDoc)(getLocationInfoDocRef(db, patientId), updateData);
2511
2871
  const updatedInfo = await getLocationInfoUtil(db, patientId, requesterId);
2512
2872
  if (!updatedInfo) {
2513
2873
  throw new Error("Failed to retrieve updated location information");
@@ -2516,127 +2876,127 @@ var updateLocationInfoUtil = async (db, patientId, data, requesterId) => {
2516
2876
  };
2517
2877
 
2518
2878
  // src/services/patient/utils/medical-stuff.utils.ts
2519
- var import_firestore10 = require("firebase/firestore");
2879
+ var import_firestore12 = require("firebase/firestore");
2520
2880
  var addDoctorUtil = async (db, patientId, doctorRef, assignedBy) => {
2521
2881
  var _a;
2522
2882
  const newDoctor = {
2523
2883
  userRef: doctorRef,
2524
- assignedAt: import_firestore10.Timestamp.now(),
2884
+ assignedAt: import_firestore12.Timestamp.now(),
2525
2885
  assignedBy,
2526
2886
  isActive: true
2527
2887
  };
2528
- const patientDoc = await (0, import_firestore10.getDoc)(getPatientDocRef(db, patientId));
2888
+ const patientDoc = await (0, import_firestore12.getDoc)(getPatientDocRef(db, patientId));
2529
2889
  if (!patientDoc.exists()) throw new Error("Patient profile not found");
2530
2890
  const patientData = patientDoc.data();
2531
2891
  const existingDoctorIndex = (_a = patientData.doctors) == null ? void 0 : _a.findIndex(
2532
2892
  (d) => d.userRef === doctorRef
2533
2893
  );
2534
2894
  const updates = {
2535
- updatedAt: (0, import_firestore10.serverTimestamp)(),
2536
- doctorIds: (0, import_firestore10.arrayUnion)(doctorRef)
2895
+ updatedAt: (0, import_firestore12.serverTimestamp)(),
2896
+ doctorIds: (0, import_firestore12.arrayUnion)(doctorRef)
2537
2897
  };
2538
2898
  if (existingDoctorIndex !== void 0 && existingDoctorIndex > -1) {
2539
2899
  const updatedDoctors = [...patientData.doctors];
2540
2900
  updatedDoctors[existingDoctorIndex] = {
2541
2901
  ...updatedDoctors[existingDoctorIndex],
2542
2902
  isActive: true,
2543
- assignedAt: import_firestore10.Timestamp.now(),
2903
+ assignedAt: import_firestore12.Timestamp.now(),
2544
2904
  assignedBy
2545
2905
  };
2546
2906
  updates.doctors = updatedDoctors;
2547
2907
  } else {
2548
- updates.doctors = (0, import_firestore10.arrayUnion)(newDoctor);
2908
+ updates.doctors = (0, import_firestore12.arrayUnion)(newDoctor);
2549
2909
  }
2550
- await (0, import_firestore10.updateDoc)(getPatientDocRef(db, patientId), updates);
2910
+ await (0, import_firestore12.updateDoc)(getPatientDocRef(db, patientId), updates);
2551
2911
  };
2552
2912
  var removeDoctorUtil = async (db, patientId, doctorRef) => {
2553
2913
  var _a;
2554
2914
  const patientDocRef = getPatientDocRef(db, patientId);
2555
- const patientDoc = await (0, import_firestore10.getDoc)(patientDocRef);
2915
+ const patientDoc = await (0, import_firestore12.getDoc)(patientDocRef);
2556
2916
  if (!patientDoc.exists()) throw new Error("Patient profile not found");
2557
2917
  const patientData = patientDoc.data();
2558
2918
  const updatedDoctors = ((_a = patientData.doctors) == null ? void 0 : _a.filter((doctor) => doctor.userRef !== doctorRef)) || [];
2559
- await (0, import_firestore10.updateDoc)(patientDocRef, {
2919
+ await (0, import_firestore12.updateDoc)(patientDocRef, {
2560
2920
  doctors: updatedDoctors,
2561
2921
  // Set the filtered array
2562
- doctorIds: (0, import_firestore10.arrayRemove)(doctorRef),
2922
+ doctorIds: (0, import_firestore12.arrayRemove)(doctorRef),
2563
2923
  // Remove ID from the denormalized list
2564
- updatedAt: (0, import_firestore10.serverTimestamp)()
2924
+ updatedAt: (0, import_firestore12.serverTimestamp)()
2565
2925
  });
2566
2926
  };
2567
2927
  var addClinicUtil = async (db, patientId, clinicId, assignedBy) => {
2568
2928
  var _a;
2569
2929
  const newClinic = {
2570
2930
  clinicId,
2571
- assignedAt: import_firestore10.Timestamp.now(),
2931
+ assignedAt: import_firestore12.Timestamp.now(),
2572
2932
  assignedBy,
2573
2933
  isActive: true
2574
2934
  };
2575
- const patientDoc = await (0, import_firestore10.getDoc)(getPatientDocRef(db, patientId));
2935
+ const patientDoc = await (0, import_firestore12.getDoc)(getPatientDocRef(db, patientId));
2576
2936
  if (!patientDoc.exists()) throw new Error("Patient profile not found");
2577
2937
  const patientData = patientDoc.data();
2578
2938
  const existingClinicIndex = (_a = patientData.clinics) == null ? void 0 : _a.findIndex(
2579
2939
  (c) => c.clinicId === clinicId
2580
2940
  );
2581
2941
  const updates = {
2582
- updatedAt: (0, import_firestore10.serverTimestamp)(),
2583
- clinicIds: (0, import_firestore10.arrayUnion)(clinicId)
2942
+ updatedAt: (0, import_firestore12.serverTimestamp)(),
2943
+ clinicIds: (0, import_firestore12.arrayUnion)(clinicId)
2584
2944
  };
2585
2945
  if (existingClinicIndex !== void 0 && existingClinicIndex > -1) {
2586
2946
  const updatedClinics = [...patientData.clinics];
2587
2947
  updatedClinics[existingClinicIndex] = {
2588
2948
  ...updatedClinics[existingClinicIndex],
2589
2949
  isActive: true,
2590
- assignedAt: import_firestore10.Timestamp.now(),
2950
+ assignedAt: import_firestore12.Timestamp.now(),
2591
2951
  assignedBy
2592
2952
  };
2593
2953
  updates.clinics = updatedClinics;
2594
2954
  } else {
2595
- updates.clinics = (0, import_firestore10.arrayUnion)(newClinic);
2955
+ updates.clinics = (0, import_firestore12.arrayUnion)(newClinic);
2596
2956
  }
2597
- await (0, import_firestore10.updateDoc)(getPatientDocRef(db, patientId), updates);
2957
+ await (0, import_firestore12.updateDoc)(getPatientDocRef(db, patientId), updates);
2598
2958
  };
2599
2959
  var removeClinicUtil = async (db, patientId, clinicId) => {
2600
2960
  var _a;
2601
2961
  const patientDocRef = getPatientDocRef(db, patientId);
2602
- const patientDoc = await (0, import_firestore10.getDoc)(patientDocRef);
2962
+ const patientDoc = await (0, import_firestore12.getDoc)(patientDocRef);
2603
2963
  if (!patientDoc.exists()) throw new Error("Patient profile not found");
2604
2964
  const patientData = patientDoc.data();
2605
2965
  const updatedClinics = ((_a = patientData.clinics) == null ? void 0 : _a.filter((clinic) => clinic.clinicId !== clinicId)) || [];
2606
- await (0, import_firestore10.updateDoc)(patientDocRef, {
2966
+ await (0, import_firestore12.updateDoc)(patientDocRef, {
2607
2967
  clinics: updatedClinics,
2608
2968
  // Set the filtered array
2609
- clinicIds: (0, import_firestore10.arrayRemove)(clinicId),
2969
+ clinicIds: (0, import_firestore12.arrayRemove)(clinicId),
2610
2970
  // Remove ID from the denormalized list
2611
- updatedAt: (0, import_firestore10.serverTimestamp)()
2971
+ updatedAt: (0, import_firestore12.serverTimestamp)()
2612
2972
  });
2613
2973
  };
2614
2974
 
2615
2975
  // src/services/patient/utils/clinic.utils.ts
2616
- var import_firestore11 = require("firebase/firestore");
2976
+ var import_firestore13 = require("firebase/firestore");
2617
2977
  var getPatientsByClinicUtil = async (db, clinicId, options) => {
2618
2978
  try {
2619
2979
  console.log(
2620
2980
  `[getPatientsByClinicUtil] Fetching patients for clinic ID: ${clinicId} with options:`,
2621
2981
  options
2622
2982
  );
2623
- const patientsCollection = (0, import_firestore11.collection)(db, PATIENTS_COLLECTION);
2983
+ const patientsCollection = (0, import_firestore13.collection)(db, PATIENTS_COLLECTION);
2624
2984
  const constraints = [
2625
- (0, import_firestore11.where)("clinicIds", "array-contains", clinicId)
2985
+ (0, import_firestore13.where)("clinicIds", "array-contains", clinicId)
2626
2986
  ];
2627
- let q = (0, import_firestore11.query)(patientsCollection, ...constraints);
2987
+ let q = (0, import_firestore13.query)(patientsCollection, ...constraints);
2628
2988
  if (options == null ? void 0 : options.limit) {
2629
- q = (0, import_firestore11.query)(q, (0, import_firestore11.limit)(options.limit));
2989
+ q = (0, import_firestore13.query)(q, (0, import_firestore13.limit)(options.limit));
2630
2990
  }
2631
2991
  if (options == null ? void 0 : options.startAfter) {
2632
- const startAfterDoc = await (0, import_firestore11.getDoc)(
2633
- (0, import_firestore11.doc)(db, PATIENTS_COLLECTION, options.startAfter)
2992
+ const startAfterDoc = await (0, import_firestore13.getDoc)(
2993
+ (0, import_firestore13.doc)(db, PATIENTS_COLLECTION, options.startAfter)
2634
2994
  );
2635
2995
  if (startAfterDoc.exists()) {
2636
- q = (0, import_firestore11.query)(q, (0, import_firestore11.startAfter)(startAfterDoc));
2996
+ q = (0, import_firestore13.query)(q, (0, import_firestore13.startAfter)(startAfterDoc));
2637
2997
  }
2638
2998
  }
2639
- const patientsSnapshot = await (0, import_firestore11.getDocs)(q);
2999
+ const patientsSnapshot = await (0, import_firestore13.getDocs)(q);
2640
3000
  const patients = [];
2641
3001
  patientsSnapshot.forEach((doc34) => {
2642
3002
  patients.push(doc34.data());
@@ -2660,6 +3020,7 @@ var getPatientsByClinicUtil = async (db, clinicId, options) => {
2660
3020
  var PatientService = class extends BaseService {
2661
3021
  constructor(db, auth, app) {
2662
3022
  super(db, auth, app);
3023
+ this.mediaService = new MediaService(db, auth, app);
2663
3024
  }
2664
3025
  // Metode za rad sa profilom pacijenta
2665
3026
  async createPatientProfile(data) {
@@ -2696,7 +3057,12 @@ var PatientService = class extends BaseService {
2696
3057
  }
2697
3058
  // Metode za rad sa osetljivim informacijama
2698
3059
  async createSensitiveInfo(data, requesterUserId) {
2699
- return createSensitiveInfoUtil(this.db, data, requesterUserId);
3060
+ return createSensitiveInfoUtil(
3061
+ this.db,
3062
+ data,
3063
+ requesterUserId,
3064
+ this.mediaService
3065
+ );
2700
3066
  }
2701
3067
  async getSensitiveInfo(patientId, requesterUserId) {
2702
3068
  return getSensitiveInfoUtil(this.db, patientId, requesterUserId);
@@ -2707,7 +3073,13 @@ var PatientService = class extends BaseService {
2707
3073
  return this.getSensitiveInfo(profile.id, requesterUserId);
2708
3074
  }
2709
3075
  async updateSensitiveInfo(patientId, data, requesterUserId) {
2710
- return updateSensitiveInfoUtil(this.db, patientId, data, requesterUserId);
3076
+ return updateSensitiveInfoUtil(
3077
+ this.db,
3078
+ patientId,
3079
+ data,
3080
+ requesterUserId,
3081
+ this.mediaService
3082
+ );
2711
3083
  }
2712
3084
  // Metode za rad sa medicinskim informacijama
2713
3085
  async createMedicalInfo(patientId, data) {
@@ -2840,8 +3212,8 @@ var PatientService = class extends BaseService {
2840
3212
  if (!this.auth.currentUser) {
2841
3213
  throw new Error("No authenticated user");
2842
3214
  }
2843
- const userDoc = await (0, import_firestore12.getDoc)(
2844
- (0, import_firestore12.doc)(this.db, "users", this.auth.currentUser.uid)
3215
+ const userDoc = await (0, import_firestore14.getDoc)(
3216
+ (0, import_firestore14.doc)(this.db, "users", this.auth.currentUser.uid)
2845
3217
  );
2846
3218
  if (!userDoc.exists()) {
2847
3219
  throw new Error("User not found");
@@ -2852,7 +3224,7 @@ var PatientService = class extends BaseService {
2852
3224
  * Briše profil pacijenta i sve povezane subkolekcije
2853
3225
  */
2854
3226
  async deletePatientProfile(patientId) {
2855
- const batch = (0, import_firestore12.writeBatch)(this.db);
3227
+ const batch = (0, import_firestore14.writeBatch)(this.db);
2856
3228
  batch.delete(getSensitiveInfoDocRef(this.db, patientId));
2857
3229
  batch.delete(getLocationInfoDocRef(this.db, patientId));
2858
3230
  batch.delete(getMedicalInfoDocRef(this.db, patientId));
@@ -2876,14 +3248,113 @@ var PatientService = class extends BaseService {
2876
3248
  await removeClinicUtil(this.db, patientId, clinicId);
2877
3249
  }
2878
3250
  // Metode za rad sa profilnom slikom
3251
+ /**
3252
+ * Uploads a profile photo for a patient
3253
+ * @param patientId - ID of the patient
3254
+ * @param file - File or Blob to upload
3255
+ * @returns URL of the uploaded photo
3256
+ */
2879
3257
  async uploadProfilePhoto(patientId, file) {
2880
- return uploadProfilePhotoUtil(this.storage, patientId, file);
3258
+ console.log(
3259
+ `[PatientService] Uploading profile photo for patient ${patientId}`
3260
+ );
3261
+ const mediaMetadata = await this.mediaService.uploadMedia(
3262
+ file,
3263
+ patientId,
3264
+ // Using patientId as ownerId
3265
+ "private" /* PRIVATE */,
3266
+ // Profile photos should be private
3267
+ "patient_profile_photos",
3268
+ file instanceof File ? file.name : `profile_photo_${patientId}`
3269
+ );
3270
+ await (0, import_firestore14.updateDoc)(getSensitiveInfoDocRef(this.db, patientId), {
3271
+ photoUrl: mediaMetadata.url,
3272
+ updatedAt: (0, import_firestore14.serverTimestamp)()
3273
+ });
3274
+ return mediaMetadata.url;
2881
3275
  }
3276
+ /**
3277
+ * Updates a patient's profile photo (replaces existing one)
3278
+ * @param patientId - ID of the patient
3279
+ * @param file - New file or Blob to upload
3280
+ * @returns URL of the new uploaded photo
3281
+ */
2882
3282
  async updateProfilePhoto(patientId, file) {
2883
- return updateProfilePhotoUtil(this.storage, this.db, patientId, file);
3283
+ console.log(
3284
+ `[PatientService] Updating profile photo for patient ${patientId}`
3285
+ );
3286
+ const currentUser = await this.getCurrentUser();
3287
+ const currentSensitiveInfo = await this.getSensitiveInfo(
3288
+ patientId,
3289
+ currentUser.uid
3290
+ );
3291
+ if ((currentSensitiveInfo == null ? void 0 : currentSensitiveInfo.photoUrl) && typeof currentSensitiveInfo.photoUrl === "string") {
3292
+ try {
3293
+ const existingMediaMetadata = await this.mediaService.getMediaMetadataByUrl(
3294
+ currentSensitiveInfo.photoUrl
3295
+ );
3296
+ if (existingMediaMetadata) {
3297
+ await this.mediaService.deleteMedia(existingMediaMetadata.id);
3298
+ }
3299
+ } catch (error) {
3300
+ console.warn(
3301
+ `[PatientService] Could not delete old profile photo for patient ${patientId}:`,
3302
+ error
3303
+ );
3304
+ }
3305
+ }
3306
+ return this.uploadProfilePhoto(patientId, file);
2884
3307
  }
3308
+ /**
3309
+ * Deletes a patient's profile photo
3310
+ * @param patientId - ID of the patient
3311
+ */
2885
3312
  async deleteProfilePhoto(patientId) {
2886
- await deleteProfilePhotoUtil(this.storage, this.db, patientId);
3313
+ console.log(
3314
+ `[PatientService] Deleting profile photo for patient ${patientId}`
3315
+ );
3316
+ const currentUser = await this.getCurrentUser();
3317
+ const currentSensitiveInfo = await this.getSensitiveInfo(
3318
+ patientId,
3319
+ currentUser.uid
3320
+ );
3321
+ if ((currentSensitiveInfo == null ? void 0 : currentSensitiveInfo.photoUrl) && typeof currentSensitiveInfo.photoUrl === "string") {
3322
+ try {
3323
+ const existingMediaMetadata = await this.mediaService.getMediaMetadataByUrl(
3324
+ currentSensitiveInfo.photoUrl
3325
+ );
3326
+ if (existingMediaMetadata) {
3327
+ await this.mediaService.deleteMedia(existingMediaMetadata.id);
3328
+ }
3329
+ } catch (error) {
3330
+ console.warn(
3331
+ `[PatientService] Could not delete profile photo for patient ${patientId}:`,
3332
+ error
3333
+ );
3334
+ }
3335
+ await (0, import_firestore14.updateDoc)(getSensitiveInfoDocRef(this.db, patientId), {
3336
+ photoUrl: null,
3337
+ updatedAt: (0, import_firestore14.serverTimestamp)()
3338
+ });
3339
+ }
3340
+ }
3341
+ /**
3342
+ * Handles profile photo upload for patients (supports MediaResource)
3343
+ * @param photoUrl - MediaResource (File, Blob, or URL string) from CreatePatientSensitiveInfoData
3344
+ * @param patientId - ID of the patient
3345
+ * @returns URL string of the uploaded or existing photo
3346
+ */
3347
+ async handleProfilePhotoUpload(photoUrl, patientId) {
3348
+ if (!photoUrl) {
3349
+ return void 0;
3350
+ }
3351
+ if (typeof photoUrl === "string") {
3352
+ return photoUrl;
3353
+ }
3354
+ if (photoUrl instanceof File || photoUrl instanceof Blob) {
3355
+ return this.uploadProfilePhoto(patientId, photoUrl);
3356
+ }
3357
+ return void 0;
2887
3358
  }
2888
3359
  // Metode za ažuriranje profila
2889
3360
  async updatePatientProfile(patientId, data) {
@@ -2976,7 +3447,7 @@ var PatientService = class extends BaseService {
2976
3447
  };
2977
3448
 
2978
3449
  // src/services/clinic/utils/admin.utils.ts
2979
- var import_firestore14 = require("firebase/firestore");
3450
+ var import_firestore16 = require("firebase/firestore");
2980
3451
 
2981
3452
  // src/types/clinic/preferences.types.ts
2982
3453
  var PracticeType = /* @__PURE__ */ ((PracticeType2) => {
@@ -3103,131 +3574,131 @@ var SubscriptionModel = /* @__PURE__ */ ((SubscriptionModel2) => {
3103
3574
 
3104
3575
  // src/validations/clinic.schema.ts
3105
3576
  var import_zod13 = require("zod");
3106
- var import_firestore13 = require("firebase/firestore");
3577
+ var import_firestore15 = require("firebase/firestore");
3107
3578
 
3108
3579
  // src/validations/reviews.schema.ts
3109
- var import_zod10 = require("zod");
3110
- var baseReviewSchema = import_zod10.z.object({
3111
- id: import_zod10.z.string().min(1),
3112
- patientId: import_zod10.z.string().min(1),
3113
- fullReviewId: import_zod10.z.string().min(1),
3114
- createdAt: import_zod10.z.date(),
3115
- updatedAt: import_zod10.z.date(),
3116
- comment: import_zod10.z.string().min(1).max(2e3),
3117
- isVerified: import_zod10.z.boolean(),
3118
- isPublished: import_zod10.z.boolean()
3580
+ var import_zod11 = require("zod");
3581
+ var baseReviewSchema = import_zod11.z.object({
3582
+ id: import_zod11.z.string().min(1),
3583
+ patientId: import_zod11.z.string().min(1),
3584
+ fullReviewId: import_zod11.z.string().min(1),
3585
+ createdAt: import_zod11.z.date(),
3586
+ updatedAt: import_zod11.z.date(),
3587
+ comment: import_zod11.z.string().min(1).max(2e3),
3588
+ isVerified: import_zod11.z.boolean(),
3589
+ isPublished: import_zod11.z.boolean()
3119
3590
  });
3120
- var baseReviewCreateSchema = import_zod10.z.object({
3121
- patientId: import_zod10.z.string().min(1),
3122
- comment: import_zod10.z.string().min(1).max(2e3),
3123
- isVerified: import_zod10.z.boolean().default(false),
3124
- isPublished: import_zod10.z.boolean().default(true)
3591
+ var baseReviewCreateSchema = import_zod11.z.object({
3592
+ patientId: import_zod11.z.string().min(1),
3593
+ comment: import_zod11.z.string().min(1).max(2e3),
3594
+ isVerified: import_zod11.z.boolean().default(false),
3595
+ isPublished: import_zod11.z.boolean().default(true)
3125
3596
  });
3126
3597
  var clinicReviewSchema = baseReviewSchema.extend({
3127
- clinicId: import_zod10.z.string().min(1),
3128
- cleanliness: import_zod10.z.number().min(1).max(5),
3129
- facilities: import_zod10.z.number().min(1).max(5),
3130
- staffFriendliness: import_zod10.z.number().min(1).max(5),
3131
- waitingTime: import_zod10.z.number().min(1).max(5),
3132
- accessibility: import_zod10.z.number().min(1).max(5),
3133
- overallRating: import_zod10.z.number().min(1).max(5),
3134
- wouldRecommend: import_zod10.z.boolean()
3598
+ clinicId: import_zod11.z.string().min(1),
3599
+ cleanliness: import_zod11.z.number().min(1).max(5),
3600
+ facilities: import_zod11.z.number().min(1).max(5),
3601
+ staffFriendliness: import_zod11.z.number().min(1).max(5),
3602
+ waitingTime: import_zod11.z.number().min(1).max(5),
3603
+ accessibility: import_zod11.z.number().min(1).max(5),
3604
+ overallRating: import_zod11.z.number().min(1).max(5),
3605
+ wouldRecommend: import_zod11.z.boolean()
3135
3606
  });
3136
3607
  var createClinicReviewSchema = baseReviewCreateSchema.extend({
3137
- clinicId: import_zod10.z.string().min(1),
3138
- cleanliness: import_zod10.z.number().min(1).max(5),
3139
- facilities: import_zod10.z.number().min(1).max(5),
3140
- staffFriendliness: import_zod10.z.number().min(1).max(5),
3141
- waitingTime: import_zod10.z.number().min(1).max(5),
3142
- accessibility: import_zod10.z.number().min(1).max(5),
3143
- wouldRecommend: import_zod10.z.boolean()
3608
+ clinicId: import_zod11.z.string().min(1),
3609
+ cleanliness: import_zod11.z.number().min(1).max(5),
3610
+ facilities: import_zod11.z.number().min(1).max(5),
3611
+ staffFriendliness: import_zod11.z.number().min(1).max(5),
3612
+ waitingTime: import_zod11.z.number().min(1).max(5),
3613
+ accessibility: import_zod11.z.number().min(1).max(5),
3614
+ wouldRecommend: import_zod11.z.boolean()
3144
3615
  });
3145
3616
  var practitionerReviewSchema = baseReviewSchema.extend({
3146
- practitionerId: import_zod10.z.string().min(1),
3147
- knowledgeAndExpertise: import_zod10.z.number().min(1).max(5),
3148
- communicationSkills: import_zod10.z.number().min(1).max(5),
3149
- bedSideManner: import_zod10.z.number().min(1).max(5),
3150
- thoroughness: import_zod10.z.number().min(1).max(5),
3151
- trustworthiness: import_zod10.z.number().min(1).max(5),
3152
- overallRating: import_zod10.z.number().min(1).max(5),
3153
- wouldRecommend: import_zod10.z.boolean()
3617
+ practitionerId: import_zod11.z.string().min(1),
3618
+ knowledgeAndExpertise: import_zod11.z.number().min(1).max(5),
3619
+ communicationSkills: import_zod11.z.number().min(1).max(5),
3620
+ bedSideManner: import_zod11.z.number().min(1).max(5),
3621
+ thoroughness: import_zod11.z.number().min(1).max(5),
3622
+ trustworthiness: import_zod11.z.number().min(1).max(5),
3623
+ overallRating: import_zod11.z.number().min(1).max(5),
3624
+ wouldRecommend: import_zod11.z.boolean()
3154
3625
  });
3155
3626
  var createPractitionerReviewSchema = baseReviewCreateSchema.extend({
3156
- practitionerId: import_zod10.z.string().min(1),
3157
- knowledgeAndExpertise: import_zod10.z.number().min(1).max(5),
3158
- communicationSkills: import_zod10.z.number().min(1).max(5),
3159
- bedSideManner: import_zod10.z.number().min(1).max(5),
3160
- thoroughness: import_zod10.z.number().min(1).max(5),
3161
- trustworthiness: import_zod10.z.number().min(1).max(5),
3162
- wouldRecommend: import_zod10.z.boolean()
3627
+ practitionerId: import_zod11.z.string().min(1),
3628
+ knowledgeAndExpertise: import_zod11.z.number().min(1).max(5),
3629
+ communicationSkills: import_zod11.z.number().min(1).max(5),
3630
+ bedSideManner: import_zod11.z.number().min(1).max(5),
3631
+ thoroughness: import_zod11.z.number().min(1).max(5),
3632
+ trustworthiness: import_zod11.z.number().min(1).max(5),
3633
+ wouldRecommend: import_zod11.z.boolean()
3163
3634
  });
3164
3635
  var procedureReviewSchema = baseReviewSchema.extend({
3165
- procedureId: import_zod10.z.string().min(1),
3166
- effectivenessOfTreatment: import_zod10.z.number().min(1).max(5),
3167
- outcomeExplanation: import_zod10.z.number().min(1).max(5),
3168
- painManagement: import_zod10.z.number().min(1).max(5),
3169
- followUpCare: import_zod10.z.number().min(1).max(5),
3170
- valueForMoney: import_zod10.z.number().min(1).max(5),
3171
- overallRating: import_zod10.z.number().min(1).max(5),
3172
- wouldRecommend: import_zod10.z.boolean()
3636
+ procedureId: import_zod11.z.string().min(1),
3637
+ effectivenessOfTreatment: import_zod11.z.number().min(1).max(5),
3638
+ outcomeExplanation: import_zod11.z.number().min(1).max(5),
3639
+ painManagement: import_zod11.z.number().min(1).max(5),
3640
+ followUpCare: import_zod11.z.number().min(1).max(5),
3641
+ valueForMoney: import_zod11.z.number().min(1).max(5),
3642
+ overallRating: import_zod11.z.number().min(1).max(5),
3643
+ wouldRecommend: import_zod11.z.boolean()
3173
3644
  });
3174
3645
  var createProcedureReviewSchema = baseReviewCreateSchema.extend({
3175
- procedureId: import_zod10.z.string().min(1),
3176
- effectivenessOfTreatment: import_zod10.z.number().min(1).max(5),
3177
- outcomeExplanation: import_zod10.z.number().min(1).max(5),
3178
- painManagement: import_zod10.z.number().min(1).max(5),
3179
- followUpCare: import_zod10.z.number().min(1).max(5),
3180
- valueForMoney: import_zod10.z.number().min(1).max(5),
3181
- wouldRecommend: import_zod10.z.boolean()
3646
+ procedureId: import_zod11.z.string().min(1),
3647
+ effectivenessOfTreatment: import_zod11.z.number().min(1).max(5),
3648
+ outcomeExplanation: import_zod11.z.number().min(1).max(5),
3649
+ painManagement: import_zod11.z.number().min(1).max(5),
3650
+ followUpCare: import_zod11.z.number().min(1).max(5),
3651
+ valueForMoney: import_zod11.z.number().min(1).max(5),
3652
+ wouldRecommend: import_zod11.z.boolean()
3182
3653
  });
3183
- var clinicReviewInfoSchema = import_zod10.z.object({
3184
- totalReviews: import_zod10.z.number().min(0),
3185
- averageRating: import_zod10.z.number().min(0).max(5),
3186
- cleanliness: import_zod10.z.number().min(0).max(5),
3187
- facilities: import_zod10.z.number().min(0).max(5),
3188
- staffFriendliness: import_zod10.z.number().min(0).max(5),
3189
- waitingTime: import_zod10.z.number().min(0).max(5),
3190
- accessibility: import_zod10.z.number().min(0).max(5),
3191
- recommendationPercentage: import_zod10.z.number().min(0).max(100)
3654
+ var clinicReviewInfoSchema = import_zod11.z.object({
3655
+ totalReviews: import_zod11.z.number().min(0),
3656
+ averageRating: import_zod11.z.number().min(0).max(5),
3657
+ cleanliness: import_zod11.z.number().min(0).max(5),
3658
+ facilities: import_zod11.z.number().min(0).max(5),
3659
+ staffFriendliness: import_zod11.z.number().min(0).max(5),
3660
+ waitingTime: import_zod11.z.number().min(0).max(5),
3661
+ accessibility: import_zod11.z.number().min(0).max(5),
3662
+ recommendationPercentage: import_zod11.z.number().min(0).max(100)
3192
3663
  });
3193
- var practitionerReviewInfoSchema = import_zod10.z.object({
3194
- totalReviews: import_zod10.z.number().min(0),
3195
- averageRating: import_zod10.z.number().min(0).max(5),
3196
- knowledgeAndExpertise: import_zod10.z.number().min(0).max(5),
3197
- communicationSkills: import_zod10.z.number().min(0).max(5),
3198
- bedSideManner: import_zod10.z.number().min(0).max(5),
3199
- thoroughness: import_zod10.z.number().min(0).max(5),
3200
- trustworthiness: import_zod10.z.number().min(0).max(5),
3201
- recommendationPercentage: import_zod10.z.number().min(0).max(100)
3664
+ var practitionerReviewInfoSchema = import_zod11.z.object({
3665
+ totalReviews: import_zod11.z.number().min(0),
3666
+ averageRating: import_zod11.z.number().min(0).max(5),
3667
+ knowledgeAndExpertise: import_zod11.z.number().min(0).max(5),
3668
+ communicationSkills: import_zod11.z.number().min(0).max(5),
3669
+ bedSideManner: import_zod11.z.number().min(0).max(5),
3670
+ thoroughness: import_zod11.z.number().min(0).max(5),
3671
+ trustworthiness: import_zod11.z.number().min(0).max(5),
3672
+ recommendationPercentage: import_zod11.z.number().min(0).max(100)
3202
3673
  });
3203
- var procedureReviewInfoSchema = import_zod10.z.object({
3204
- totalReviews: import_zod10.z.number().min(0),
3205
- averageRating: import_zod10.z.number().min(0).max(5),
3206
- effectivenessOfTreatment: import_zod10.z.number().min(0).max(5),
3207
- outcomeExplanation: import_zod10.z.number().min(0).max(5),
3208
- painManagement: import_zod10.z.number().min(0).max(5),
3209
- followUpCare: import_zod10.z.number().min(0).max(5),
3210
- valueForMoney: import_zod10.z.number().min(0).max(5),
3211
- recommendationPercentage: import_zod10.z.number().min(0).max(100)
3674
+ var procedureReviewInfoSchema = import_zod11.z.object({
3675
+ totalReviews: import_zod11.z.number().min(0),
3676
+ averageRating: import_zod11.z.number().min(0).max(5),
3677
+ effectivenessOfTreatment: import_zod11.z.number().min(0).max(5),
3678
+ outcomeExplanation: import_zod11.z.number().min(0).max(5),
3679
+ painManagement: import_zod11.z.number().min(0).max(5),
3680
+ followUpCare: import_zod11.z.number().min(0).max(5),
3681
+ valueForMoney: import_zod11.z.number().min(0).max(5),
3682
+ recommendationPercentage: import_zod11.z.number().min(0).max(100)
3212
3683
  });
3213
- var reviewSchema = import_zod10.z.object({
3214
- id: import_zod10.z.string().min(1),
3215
- appointmentId: import_zod10.z.string().min(1),
3216
- patientId: import_zod10.z.string().min(1),
3217
- createdAt: import_zod10.z.date(),
3218
- updatedAt: import_zod10.z.date(),
3684
+ var reviewSchema = import_zod11.z.object({
3685
+ id: import_zod11.z.string().min(1),
3686
+ appointmentId: import_zod11.z.string().min(1),
3687
+ patientId: import_zod11.z.string().min(1),
3688
+ createdAt: import_zod11.z.date(),
3689
+ updatedAt: import_zod11.z.date(),
3219
3690
  clinicReview: clinicReviewSchema.optional(),
3220
3691
  practitionerReview: practitionerReviewSchema.optional(),
3221
3692
  procedureReview: procedureReviewSchema.optional(),
3222
- overallComment: import_zod10.z.string().min(1).max(2e3),
3223
- overallRating: import_zod10.z.number().min(1).max(5)
3693
+ overallComment: import_zod11.z.string().min(1).max(2e3),
3694
+ overallRating: import_zod11.z.number().min(1).max(5)
3224
3695
  });
3225
- var createReviewSchema = import_zod10.z.object({
3226
- patientId: import_zod10.z.string().min(1),
3696
+ var createReviewSchema = import_zod11.z.object({
3697
+ patientId: import_zod11.z.string().min(1),
3227
3698
  clinicReview: createClinicReviewSchema.optional(),
3228
3699
  practitionerReview: createPractitionerReviewSchema.optional(),
3229
3700
  procedureReview: createProcedureReviewSchema.optional(),
3230
- overallComment: import_zod10.z.string().min(1).max(2e3)
3701
+ overallComment: import_zod11.z.string().min(1).max(2e3)
3231
3702
  }).refine(
3232
3703
  (data) => {
3233
3704
  return data.clinicReview || data.practitionerReview || data.procedureReview;
@@ -3239,7 +3710,7 @@ var createReviewSchema = import_zod10.z.object({
3239
3710
  );
3240
3711
 
3241
3712
  // src/validations/shared.schema.ts
3242
- var import_zod11 = require("zod");
3713
+ var import_zod12 = require("zod");
3243
3714
 
3244
3715
  // src/backoffice/types/static/procedure-family.types.ts
3245
3716
  var ProcedureFamily = /* @__PURE__ */ ((ProcedureFamily2) => {
@@ -3268,65 +3739,57 @@ var Currency = /* @__PURE__ */ ((Currency2) => {
3268
3739
  })(Currency || {});
3269
3740
 
3270
3741
  // src/validations/shared.schema.ts
3271
- var sharedClinicContactInfoSchema = import_zod11.z.object({
3272
- email: import_zod11.z.string().email(),
3273
- phoneNumber: import_zod11.z.string(),
3274
- alternativePhoneNumber: import_zod11.z.string().nullable().optional(),
3275
- website: import_zod11.z.string().nullable().optional()
3742
+ var sharedClinicContactInfoSchema = import_zod12.z.object({
3743
+ email: import_zod12.z.string().email(),
3744
+ phoneNumber: import_zod12.z.string(),
3745
+ alternativePhoneNumber: import_zod12.z.string().nullable().optional(),
3746
+ website: import_zod12.z.string().nullable().optional()
3276
3747
  });
3277
- var sharedClinicLocationSchema = import_zod11.z.object({
3278
- address: import_zod11.z.string(),
3279
- city: import_zod11.z.string(),
3280
- country: import_zod11.z.string(),
3281
- postalCode: import_zod11.z.string(),
3282
- latitude: import_zod11.z.number().min(-90).max(90),
3283
- longitude: import_zod11.z.number().min(-180).max(180),
3284
- geohash: import_zod11.z.string().nullable().optional()
3748
+ var sharedClinicLocationSchema = import_zod12.z.object({
3749
+ address: import_zod12.z.string(),
3750
+ city: import_zod12.z.string(),
3751
+ country: import_zod12.z.string(),
3752
+ postalCode: import_zod12.z.string(),
3753
+ latitude: import_zod12.z.number().min(-90).max(90),
3754
+ longitude: import_zod12.z.number().min(-180).max(180),
3755
+ geohash: import_zod12.z.string().nullable().optional()
3285
3756
  });
3286
- var procedureSummaryInfoSchema = import_zod11.z.object({
3287
- id: import_zod11.z.string().min(1),
3288
- name: import_zod11.z.string().min(1),
3289
- description: import_zod11.z.string().optional(),
3290
- photo: import_zod11.z.string().optional(),
3291
- family: import_zod11.z.nativeEnum(ProcedureFamily),
3292
- categoryName: import_zod11.z.string(),
3293
- subcategoryName: import_zod11.z.string(),
3294
- technologyName: import_zod11.z.string(),
3295
- price: import_zod11.z.number().nonnegative(),
3296
- pricingMeasure: import_zod11.z.nativeEnum(PricingMeasure),
3297
- currency: import_zod11.z.nativeEnum(Currency),
3298
- duration: import_zod11.z.number().int().positive(),
3299
- clinicId: import_zod11.z.string().min(1),
3300
- clinicName: import_zod11.z.string().min(1),
3301
- practitionerId: import_zod11.z.string().min(1),
3302
- practitionerName: import_zod11.z.string().min(1)
3757
+ var procedureSummaryInfoSchema = import_zod12.z.object({
3758
+ id: import_zod12.z.string().min(1),
3759
+ name: import_zod12.z.string().min(1),
3760
+ description: import_zod12.z.string().optional(),
3761
+ photo: import_zod12.z.string().optional(),
3762
+ family: import_zod12.z.nativeEnum(ProcedureFamily),
3763
+ categoryName: import_zod12.z.string(),
3764
+ subcategoryName: import_zod12.z.string(),
3765
+ technologyName: import_zod12.z.string(),
3766
+ price: import_zod12.z.number().nonnegative(),
3767
+ pricingMeasure: import_zod12.z.nativeEnum(PricingMeasure),
3768
+ currency: import_zod12.z.nativeEnum(Currency),
3769
+ duration: import_zod12.z.number().int().positive(),
3770
+ clinicId: import_zod12.z.string().min(1),
3771
+ clinicName: import_zod12.z.string().min(1),
3772
+ practitionerId: import_zod12.z.string().min(1),
3773
+ practitionerName: import_zod12.z.string().min(1)
3303
3774
  });
3304
- var clinicInfoSchema = import_zod11.z.object({
3305
- id: import_zod11.z.string(),
3306
- featuredPhoto: import_zod11.z.string(),
3307
- name: import_zod11.z.string(),
3308
- description: import_zod11.z.string().nullable().optional(),
3775
+ var clinicInfoSchema = import_zod12.z.object({
3776
+ id: import_zod12.z.string(),
3777
+ featuredPhoto: import_zod12.z.string(),
3778
+ name: import_zod12.z.string(),
3779
+ description: import_zod12.z.string().nullable().optional(),
3309
3780
  location: sharedClinicLocationSchema,
3310
3781
  contactInfo: sharedClinicContactInfoSchema
3311
3782
  });
3312
- var doctorInfoSchema = import_zod11.z.object({
3313
- id: import_zod11.z.string(),
3314
- name: import_zod11.z.string(),
3315
- description: import_zod11.z.string().nullable().optional(),
3316
- photo: import_zod11.z.string(),
3317
- rating: import_zod11.z.number().min(0).max(5),
3318
- services: import_zod11.z.array(import_zod11.z.string())
3783
+ var doctorInfoSchema = import_zod12.z.object({
3784
+ id: import_zod12.z.string(),
3785
+ name: import_zod12.z.string(),
3786
+ description: import_zod12.z.string().nullable().optional(),
3787
+ photo: import_zod12.z.string(),
3788
+ rating: import_zod12.z.number().min(0).max(5),
3789
+ services: import_zod12.z.array(import_zod12.z.string())
3319
3790
  // List of procedure IDs practitioner offers
3320
3791
  });
3321
3792
 
3322
- // src/validations/media.schema.ts
3323
- var import_zod12 = require("zod");
3324
- var mediaResourceSchema = import_zod12.z.union([
3325
- import_zod12.z.string().url(),
3326
- import_zod12.z.instanceof(File),
3327
- import_zod12.z.instanceof(Blob)
3328
- ]);
3329
-
3330
3793
  // src/validations/clinic.schema.ts
3331
3794
  var clinicContactInfoSchema = import_zod13.z.object({
3332
3795
  email: import_zod13.z.string().email(),
@@ -3386,8 +3849,8 @@ var clinicAdminSchema = import_zod13.z.object({
3386
3849
  clinicsManagedInfo: import_zod13.z.array(clinicInfoSchema),
3387
3850
  contactInfo: contactPersonSchema,
3388
3851
  roleTitle: import_zod13.z.string(),
3389
- createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
3390
- updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
3852
+ createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore15.Timestamp)),
3853
+ updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore15.Timestamp)),
3391
3854
  isActive: import_zod13.z.boolean()
3392
3855
  });
3393
3856
  var adminTokenSchema = import_zod13.z.object({
@@ -3396,9 +3859,9 @@ var adminTokenSchema = import_zod13.z.object({
3396
3859
  email: import_zod13.z.string().email().optional().nullable(),
3397
3860
  status: import_zod13.z.nativeEnum(AdminTokenStatus),
3398
3861
  usedByUserRef: import_zod13.z.string().optional(),
3399
- createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
3862
+ createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore15.Timestamp)),
3400
3863
  // Timestamp
3401
- expiresAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp))
3864
+ expiresAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore15.Timestamp))
3402
3865
  // Timestamp
3403
3866
  });
3404
3867
  var createAdminTokenSchema = import_zod13.z.object({
@@ -3418,9 +3881,9 @@ var clinicGroupSchema = import_zod13.z.object({
3418
3881
  adminsInfo: import_zod13.z.array(adminInfoSchema),
3419
3882
  adminTokens: import_zod13.z.array(adminTokenSchema),
3420
3883
  ownerId: import_zod13.z.string().nullable(),
3421
- createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
3884
+ createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore15.Timestamp)),
3422
3885
  // Timestamp
3423
- updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
3886
+ updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore15.Timestamp)),
3424
3887
  // Timestamp
3425
3888
  isActive: import_zod13.z.boolean(),
3426
3889
  logo: mediaResourceSchema.optional().nullable(),
@@ -3462,9 +3925,9 @@ var clinicSchema = import_zod13.z.object({
3462
3925
  // Use the correct schema for aggregated procedure info
3463
3926
  reviewInfo: clinicReviewInfoSchema,
3464
3927
  admins: import_zod13.z.array(import_zod13.z.string()),
3465
- createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
3928
+ createdAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore15.Timestamp)),
3466
3929
  // Timestamp
3467
- updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore13.Timestamp)),
3930
+ updatedAt: import_zod13.z.instanceof(Date).or(import_zod13.z.instanceof(import_firestore15.Timestamp)),
3468
3931
  // Timestamp
3469
3932
  isActive: import_zod13.z.boolean(),
3470
3933
  isVerified: import_zod13.z.boolean(),
@@ -3686,7 +4149,7 @@ async function createClinicAdmin(db, data, clinicGroupService) {
3686
4149
  }
3687
4150
  console.log("[CLINIC_ADMIN] Preparing admin data object");
3688
4151
  const adminData = {
3689
- id: (0, import_firestore14.doc)((0, import_firestore14.collection)(db, CLINIC_ADMINS_COLLECTION)).id,
4152
+ id: (0, import_firestore16.doc)((0, import_firestore16.collection)(db, CLINIC_ADMINS_COLLECTION)).id,
3690
4153
  // Generate a new ID for the admin document
3691
4154
  userRef: validatedData.userRef,
3692
4155
  clinicGroupId: clinicGroupId || "",
@@ -3699,15 +4162,15 @@ async function createClinicAdmin(db, data, clinicGroupService) {
3699
4162
  contactInfo: validatedData.contactInfo,
3700
4163
  roleTitle: validatedData.roleTitle,
3701
4164
  isActive: validatedData.isActive,
3702
- createdAt: (0, import_firestore14.serverTimestamp)(),
3703
- updatedAt: (0, import_firestore14.serverTimestamp)()
4165
+ createdAt: (0, import_firestore16.serverTimestamp)(),
4166
+ updatedAt: (0, import_firestore16.serverTimestamp)()
3704
4167
  };
3705
4168
  console.log("[CLINIC_ADMIN] Validating complete admin object");
3706
4169
  try {
3707
4170
  clinicAdminSchema.parse({
3708
4171
  ...adminData,
3709
- createdAt: import_firestore14.Timestamp.now(),
3710
- updatedAt: import_firestore14.Timestamp.now()
4172
+ createdAt: import_firestore16.Timestamp.now(),
4173
+ updatedAt: import_firestore16.Timestamp.now()
3711
4174
  });
3712
4175
  console.log("[CLINIC_ADMIN] Admin object validation passed");
3713
4176
  } catch (schemaError) {
@@ -3721,7 +4184,7 @@ async function createClinicAdmin(db, data, clinicGroupService) {
3721
4184
  adminId: adminData.id
3722
4185
  });
3723
4186
  try {
3724
- await (0, import_firestore14.setDoc)((0, import_firestore14.doc)(db, CLINIC_ADMINS_COLLECTION, adminData.id), adminData);
4187
+ await (0, import_firestore16.setDoc)((0, import_firestore16.doc)(db, CLINIC_ADMINS_COLLECTION, adminData.id), adminData);
3725
4188
  console.log("[CLINIC_ADMIN] Admin saved successfully");
3726
4189
  } catch (firestoreError) {
3727
4190
  console.error(
@@ -3770,30 +4233,30 @@ async function checkClinicGroupExists(db, groupId, clinicGroupService) {
3770
4233
  return !!group;
3771
4234
  }
3772
4235
  async function getClinicAdmin(db, adminId) {
3773
- const docRef = (0, import_firestore14.doc)(db, CLINIC_ADMINS_COLLECTION, adminId);
3774
- const docSnap = await (0, import_firestore14.getDoc)(docRef);
4236
+ const docRef = (0, import_firestore16.doc)(db, CLINIC_ADMINS_COLLECTION, adminId);
4237
+ const docSnap = await (0, import_firestore16.getDoc)(docRef);
3775
4238
  if (docSnap.exists()) {
3776
4239
  return docSnap.data();
3777
4240
  }
3778
4241
  return null;
3779
4242
  }
3780
4243
  async function getClinicAdminByUserRef(db, userRef) {
3781
- const q = (0, import_firestore14.query)(
3782
- (0, import_firestore14.collection)(db, CLINIC_ADMINS_COLLECTION),
3783
- (0, import_firestore14.where)("userRef", "==", userRef)
4244
+ const q = (0, import_firestore16.query)(
4245
+ (0, import_firestore16.collection)(db, CLINIC_ADMINS_COLLECTION),
4246
+ (0, import_firestore16.where)("userRef", "==", userRef)
3784
4247
  );
3785
- const querySnapshot = await (0, import_firestore14.getDocs)(q);
4248
+ const querySnapshot = await (0, import_firestore16.getDocs)(q);
3786
4249
  if (querySnapshot.empty) {
3787
4250
  return null;
3788
4251
  }
3789
4252
  return querySnapshot.docs[0].data();
3790
4253
  }
3791
4254
  async function getClinicAdminsByGroup(db, clinicGroupId) {
3792
- const q = (0, import_firestore14.query)(
3793
- (0, import_firestore14.collection)(db, CLINIC_ADMINS_COLLECTION),
3794
- (0, import_firestore14.where)("clinicGroupId", "==", clinicGroupId)
4255
+ const q = (0, import_firestore16.query)(
4256
+ (0, import_firestore16.collection)(db, CLINIC_ADMINS_COLLECTION),
4257
+ (0, import_firestore16.where)("clinicGroupId", "==", clinicGroupId)
3795
4258
  );
3796
- const querySnapshot = await (0, import_firestore14.getDocs)(q);
4259
+ const querySnapshot = await (0, import_firestore16.getDocs)(q);
3797
4260
  return querySnapshot.docs.map((doc34) => doc34.data());
3798
4261
  }
3799
4262
  async function updateClinicAdmin(db, adminId, data) {
@@ -3803,9 +4266,9 @@ async function updateClinicAdmin(db, adminId, data) {
3803
4266
  }
3804
4267
  const updatedData = {
3805
4268
  ...data,
3806
- updatedAt: (0, import_firestore14.serverTimestamp)()
4269
+ updatedAt: (0, import_firestore16.serverTimestamp)()
3807
4270
  };
3808
- await (0, import_firestore14.updateDoc)((0, import_firestore14.doc)(db, CLINIC_ADMINS_COLLECTION, adminId), updatedData);
4271
+ await (0, import_firestore16.updateDoc)((0, import_firestore16.doc)(db, CLINIC_ADMINS_COLLECTION, adminId), updatedData);
3809
4272
  const updatedAdmin = await getClinicAdmin(db, adminId);
3810
4273
  if (!updatedAdmin) {
3811
4274
  throw new Error("Failed to retrieve updated admin");
@@ -3817,7 +4280,7 @@ async function deleteClinicAdmin(db, adminId) {
3817
4280
  if (!admin) {
3818
4281
  throw new Error("Clinic admin not found");
3819
4282
  }
3820
- await (0, import_firestore14.deleteDoc)((0, import_firestore14.doc)(db, CLINIC_ADMINS_COLLECTION, adminId));
4283
+ await (0, import_firestore16.deleteDoc)((0, import_firestore16.doc)(db, CLINIC_ADMINS_COLLECTION, adminId));
3821
4284
  }
3822
4285
  async function addClinicToManaged(db, adminId, clinicId, requesterId, clinicService) {
3823
4286
  const admin = await getClinicAdmin(db, adminId);
@@ -3967,399 +4430,101 @@ var ClinicAdminService = class extends BaseService {
3967
4430
  async syncOwnerClinics(adminId) {
3968
4431
  return syncOwnerClinics(
3969
4432
  this.db,
3970
- adminId,
3971
- this.getClinicService(),
3972
- this.getClinicGroupService()
3973
- );
3974
- }
3975
- /**
3976
- * Kreira novi admin profil
3977
- */
3978
- async createClinicAdmin(data) {
3979
- return createClinicAdmin(
3980
- this.db,
3981
- data,
3982
- this.getClinicGroupService()
3983
- );
3984
- }
3985
- /**
3986
- * Dohvata admin profil po ID-u
3987
- */
3988
- async getClinicAdmin(adminId) {
3989
- return getClinicAdmin(this.db, adminId);
3990
- }
3991
- /**
3992
- * Dohvata admin profil po korisničkom ID-u
3993
- */
3994
- async getClinicAdminByUserRef(userRef) {
3995
- return getClinicAdminByUserRef(this.db, userRef);
3996
- }
3997
- /**
3998
- * Dohvata sve admine u grupi
3999
- */
4000
- async getClinicAdminsByGroup(clinicGroupId) {
4001
- return getClinicAdminsByGroup(this.db, clinicGroupId);
4002
- }
4003
- /**
4004
- * Ažurira admin profil
4005
- */
4006
- async updateClinicAdmin(adminId, data) {
4007
- return updateClinicAdmin(this.db, adminId, data);
4008
- }
4009
- /**
4010
- * Briše admin profil
4011
- */
4012
- async deleteClinicAdmin(adminId) {
4013
- return deleteClinicAdmin(this.db, adminId);
4014
- }
4015
- /**
4016
- * Dodaje kliniku u listu klinika kojima admin upravlja
4017
- */
4018
- async addClinicToManaged(adminId, clinicId, requesterId) {
4019
- return addClinicToManaged(
4020
- this.db,
4021
- adminId,
4022
- clinicId,
4023
- requesterId,
4024
- this.getClinicService()
4025
- );
4026
- }
4027
- /**
4028
- * Uklanja kliniku iz liste klinika kojima admin upravlja
4029
- */
4030
- async removeClinicFromManaged(adminId, clinicId, requesterId) {
4031
- return removeClinicFromManaged(
4032
- this.db,
4033
- adminId,
4034
- clinicId,
4035
- requesterId
4036
- );
4037
- }
4038
- /**
4039
- * Dohvata sve klinike kojima admin upravlja
4040
- */
4041
- async getManagedClinics(adminId) {
4042
- return getManagedClinics(
4043
- this.db,
4044
- adminId,
4045
- this.getClinicService()
4046
- );
4047
- }
4048
- /**
4049
- * Dohvata sve aktivne klinike kojima admin upravlja
4050
- */
4051
- async getActiveManagedClinics(adminId) {
4052
- return getActiveManagedClinics(
4053
- this.db,
4054
- adminId,
4055
- this.getClinicService()
4056
- );
4057
- }
4058
- // TODO: Add more methods for clinic admins for managing permissions, editing profiles by the admin, or by the clinic group owner and so on
4059
- // Generally refactor admin permissions and clinic group permissions and systems for admin management
4060
- };
4061
-
4062
- // src/services/practitioner/practitioner.service.ts
4063
- var import_firestore18 = require("firebase/firestore");
4064
-
4065
- // src/services/media/media.service.ts
4066
- var import_firestore15 = require("firebase/firestore");
4067
- var import_storage4 = require("firebase/storage");
4068
- var import_firestore16 = require("firebase/firestore");
4069
- var MediaAccessLevel = /* @__PURE__ */ ((MediaAccessLevel2) => {
4070
- MediaAccessLevel2["PUBLIC"] = "public";
4071
- MediaAccessLevel2["PRIVATE"] = "private";
4072
- MediaAccessLevel2["CONFIDENTIAL"] = "confidential";
4073
- return MediaAccessLevel2;
4074
- })(MediaAccessLevel || {});
4075
- var MEDIA_METADATA_COLLECTION = "media_metadata";
4076
- var MediaService = class extends BaseService {
4077
- constructor(db, auth, app) {
4078
- super(db, auth, app);
4079
- }
4080
- /**
4081
- * Upload a media file, store its metadata, and return the metadata including the URL.
4082
- * @param file - The file to upload.
4083
- * @param ownerId - ID of the owner (user, patient, clinic, etc.).
4084
- * @param accessLevel - Access level (public, private, confidential).
4085
- * @param collectionName - The logical collection name this media belongs to (e.g., 'patient_profile_pictures', 'clinic_logos').
4086
- * @param originalFileName - Optional: the original name of the file, if not using file.name.
4087
- * @returns Promise with the media metadata.
4088
- */
4089
- async uploadMedia(file, ownerId, accessLevel, collectionName, originalFileName) {
4090
- const mediaId = this.generateId();
4091
- const fileNameToUse = originalFileName || (file instanceof File ? file.name : file.toString());
4092
- const uniqueFileName = `${mediaId}-${fileNameToUse}`;
4093
- const filePath = `media/${accessLevel}/${ownerId}/${collectionName}/${uniqueFileName}`;
4094
- console.log(`[MediaService] Uploading file to: ${filePath}`);
4095
- const storageRef = (0, import_storage4.ref)(this.storage, filePath);
4096
- try {
4097
- const uploadResult = await (0, import_storage4.uploadBytes)(storageRef, file, {
4098
- contentType: file.type
4099
- });
4100
- console.log("[MediaService] File uploaded successfully", uploadResult);
4101
- const downloadURL = await (0, import_storage4.getDownloadURL)(uploadResult.ref);
4102
- console.log("[MediaService] Got download URL:", downloadURL);
4103
- const metadata = {
4104
- id: mediaId,
4105
- name: fileNameToUse,
4106
- url: downloadURL,
4107
- contentType: file.type,
4108
- size: file.size,
4109
- createdAt: import_firestore15.Timestamp.now(),
4110
- accessLevel,
4111
- ownerId,
4112
- collectionName,
4113
- path: filePath
4114
- };
4115
- const metadataDocRef = (0, import_firestore16.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
4116
- await (0, import_firestore16.setDoc)(metadataDocRef, metadata);
4117
- console.log("[MediaService] Metadata stored in Firestore:", mediaId);
4118
- return metadata;
4119
- } catch (error) {
4120
- console.error("[MediaService] Error during media upload:", error);
4121
- throw error;
4122
- }
4433
+ adminId,
4434
+ this.getClinicService(),
4435
+ this.getClinicGroupService()
4436
+ );
4123
4437
  }
4124
4438
  /**
4125
- * Get media metadata from Firestore by its ID.
4126
- * @param mediaId - ID of the media.
4127
- * @returns Promise with the media metadata or null if not found.
4439
+ * Kreira novi admin profil
4128
4440
  */
4129
- async getMediaMetadata(mediaId) {
4130
- console.log(`[MediaService] Getting media metadata for ID: ${mediaId}`);
4131
- const docRef = (0, import_firestore16.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
4132
- const docSnap = await (0, import_firestore16.getDoc)(docRef);
4133
- if (docSnap.exists()) {
4134
- console.log("[MediaService] Metadata found:", docSnap.data());
4135
- return docSnap.data();
4136
- }
4137
- console.log("[MediaService] No metadata found for ID:", mediaId);
4138
- return null;
4441
+ async createClinicAdmin(data) {
4442
+ return createClinicAdmin(
4443
+ this.db,
4444
+ data,
4445
+ this.getClinicGroupService()
4446
+ );
4139
4447
  }
4140
4448
  /**
4141
- * Get media metadata from Firestore by its public URL.
4142
- * @param url - The public URL of the media file.
4143
- * @returns Promise with the media metadata or null if not found.
4449
+ * Dohvata admin profil po ID-u
4144
4450
  */
4145
- async getMediaMetadataByUrl(url) {
4146
- console.log(`[MediaService] Getting media metadata by URL: ${url}`);
4147
- const q = (0, import_firestore16.query)(
4148
- (0, import_firestore16.collection)(this.db, MEDIA_METADATA_COLLECTION),
4149
- (0, import_firestore16.where)("url", "==", url),
4150
- (0, import_firestore16.limit)(1)
4151
- );
4152
- try {
4153
- const querySnapshot = await (0, import_firestore16.getDocs)(q);
4154
- if (!querySnapshot.empty) {
4155
- const metadata = querySnapshot.docs[0].data();
4156
- console.log("[MediaService] Metadata found by URL:", metadata);
4157
- return metadata;
4158
- }
4159
- console.log("[MediaService] No metadata found for URL:", url);
4160
- return null;
4161
- } catch (error) {
4162
- console.error("[MediaService] Error fetching metadata by URL:", error);
4163
- throw error;
4164
- }
4451
+ async getClinicAdmin(adminId) {
4452
+ return getClinicAdmin(this.db, adminId);
4165
4453
  }
4166
4454
  /**
4167
- * Delete media from storage and remove metadata from Firestore.
4168
- * @param mediaId - ID of the media to delete.
4455
+ * Dohvata admin profil po korisničkom ID-u
4169
4456
  */
4170
- async deleteMedia(mediaId) {
4171
- console.log(`[MediaService] Deleting media with ID: ${mediaId}`);
4172
- const metadata = await this.getMediaMetadata(mediaId);
4173
- if (!metadata) {
4174
- console.warn(
4175
- `[MediaService] Metadata not found for media ID ${mediaId}. Cannot delete.`
4176
- );
4177
- return;
4178
- }
4179
- const storageFileRef = (0, import_storage4.ref)(this.storage, metadata.path);
4180
- try {
4181
- await (0, import_storage4.deleteObject)(storageFileRef);
4182
- console.log(`[MediaService] File deleted from Storage: ${metadata.path}`);
4183
- const metadataDocRef = (0, import_firestore16.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
4184
- await (0, import_firestore16.deleteDoc)(metadataDocRef);
4185
- console.log(
4186
- `[MediaService] Metadata deleted from Firestore for ID: ${mediaId}`
4187
- );
4188
- } catch (error) {
4189
- console.error(`[MediaService] Error deleting media ${mediaId}:`, error);
4190
- throw error;
4191
- }
4457
+ async getClinicAdminByUserRef(userRef) {
4458
+ return getClinicAdminByUserRef(this.db, userRef);
4192
4459
  }
4193
4460
  /**
4194
- * Update media access level. This involves moving the file in Firebase Storage
4195
- * to a new path reflecting the new access level, and updating its metadata.
4196
- * @param mediaId - ID of the media to update.
4197
- * @param newAccessLevel - New access level.
4198
- * @returns Promise with the updated media metadata, or null if metadata not found.
4461
+ * Dohvata sve admine u grupi
4199
4462
  */
4200
- async updateMediaAccessLevel(mediaId, newAccessLevel) {
4201
- var _a;
4202
- console.log(
4203
- `[MediaService] Attempting to update access level for media ID: ${mediaId} to ${newAccessLevel}`
4463
+ async getClinicAdminsByGroup(clinicGroupId) {
4464
+ return getClinicAdminsByGroup(this.db, clinicGroupId);
4465
+ }
4466
+ /**
4467
+ * Ažurira admin profil
4468
+ */
4469
+ async updateClinicAdmin(adminId, data) {
4470
+ return updateClinicAdmin(this.db, adminId, data);
4471
+ }
4472
+ /**
4473
+ * Briše admin profil
4474
+ */
4475
+ async deleteClinicAdmin(adminId) {
4476
+ return deleteClinicAdmin(this.db, adminId);
4477
+ }
4478
+ /**
4479
+ * Dodaje kliniku u listu klinika kojima admin upravlja
4480
+ */
4481
+ async addClinicToManaged(adminId, clinicId, requesterId) {
4482
+ return addClinicToManaged(
4483
+ this.db,
4484
+ adminId,
4485
+ clinicId,
4486
+ requesterId,
4487
+ this.getClinicService()
4204
4488
  );
4205
- const metadata = await this.getMediaMetadata(mediaId);
4206
- if (!metadata) {
4207
- console.warn(
4208
- `[MediaService] Metadata not found for media ID ${mediaId}. Cannot update access level.`
4209
- );
4210
- return null;
4211
- }
4212
- if (metadata.accessLevel === newAccessLevel) {
4213
- console.log(
4214
- `[MediaService] Media ID ${mediaId} already has access level ${newAccessLevel}. Updating timestamp only.`
4215
- );
4216
- const metadataDocRef = (0, import_firestore16.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
4217
- try {
4218
- await (0, import_firestore16.updateDoc)(metadataDocRef, { updatedAt: import_firestore15.Timestamp.now() });
4219
- return { ...metadata, updatedAt: import_firestore15.Timestamp.now() };
4220
- } catch (error) {
4221
- console.error(
4222
- `[MediaService] Error updating timestamp for media ID ${mediaId}:`,
4223
- error
4224
- );
4225
- throw error;
4226
- }
4227
- }
4228
- const oldStoragePath = metadata.path;
4229
- const fileNamePart = `${metadata.id}-${metadata.name}`;
4230
- const newStoragePath = `media/${newAccessLevel}/${metadata.ownerId}/${metadata.collectionName}/${fileNamePart}`;
4231
- console.log(
4232
- `[MediaService] Moving file for ${mediaId} from ${oldStoragePath} to ${newStoragePath}`
4489
+ }
4490
+ /**
4491
+ * Uklanja kliniku iz liste klinika kojima admin upravlja
4492
+ */
4493
+ async removeClinicFromManaged(adminId, clinicId, requesterId) {
4494
+ return removeClinicFromManaged(
4495
+ this.db,
4496
+ adminId,
4497
+ clinicId,
4498
+ requesterId
4233
4499
  );
4234
- const oldStorageFileRef = (0, import_storage4.ref)(this.storage, oldStoragePath);
4235
- const newStorageFileRef = (0, import_storage4.ref)(this.storage, newStoragePath);
4236
- try {
4237
- console.log(`[MediaService] Downloading bytes from ${oldStoragePath}`);
4238
- const fileBytes = await (0, import_storage4.getBytes)(oldStorageFileRef);
4239
- console.log(
4240
- `[MediaService] Successfully downloaded ${fileBytes.byteLength} bytes from ${oldStoragePath}`
4241
- );
4242
- console.log(`[MediaService] Uploading bytes to ${newStoragePath}`);
4243
- await (0, import_storage4.uploadBytes)(newStorageFileRef, fileBytes, {
4244
- contentType: metadata.contentType
4245
- });
4246
- console.log(
4247
- `[MediaService] Successfully uploaded bytes to ${newStoragePath}`
4248
- );
4249
- const newDownloadURL = await (0, import_storage4.getDownloadURL)(newStorageFileRef);
4250
- console.log(
4251
- `[MediaService] Got new download URL for ${newStoragePath}: ${newDownloadURL}`
4252
- );
4253
- const updateData = {
4254
- accessLevel: newAccessLevel,
4255
- path: newStoragePath,
4256
- url: newDownloadURL,
4257
- updatedAt: import_firestore15.Timestamp.now()
4258
- };
4259
- const metadataDocRef = (0, import_firestore16.doc)(this.db, MEDIA_METADATA_COLLECTION, mediaId);
4260
- console.log(
4261
- `[MediaService] Updating Firestore metadata for ${mediaId} with new data:`,
4262
- updateData
4263
- );
4264
- await (0, import_firestore16.updateDoc)(metadataDocRef, updateData);
4265
- console.log(
4266
- `[MediaService] Successfully updated Firestore metadata for ${mediaId}`
4267
- );
4268
- try {
4269
- console.log(`[MediaService] Deleting old file from ${oldStoragePath}`);
4270
- await (0, import_storage4.deleteObject)(oldStorageFileRef);
4271
- console.log(
4272
- `[MediaService] Successfully deleted old file from ${oldStoragePath}`
4273
- );
4274
- } catch (deleteError) {
4275
- console.error(
4276
- `[MediaService] Failed to delete old file from ${oldStoragePath} for media ID ${mediaId}. This file is now orphaned. Error:`,
4277
- deleteError
4278
- );
4279
- }
4280
- return { ...metadata, ...updateData };
4281
- } catch (error) {
4282
- console.error(
4283
- `[MediaService] Error updating media access level and moving file for ${mediaId}:`,
4284
- error
4285
- );
4286
- if (newStorageFileRef && error.code !== "storage/object-not-found" && ((_a = error.message) == null ? void 0 : _a.includes("uploadBytes"))) {
4287
- console.warn(
4288
- `[MediaService] Attempting to delete partially uploaded file at ${newStoragePath} due to error.`
4289
- );
4290
- try {
4291
- await (0, import_storage4.deleteObject)(newStorageFileRef);
4292
- console.warn(
4293
- `[MediaService] Cleaned up partially uploaded file at ${newStoragePath}.`
4294
- );
4295
- } catch (cleanupError) {
4296
- console.error(
4297
- `[MediaService] Failed to cleanup partially uploaded file at ${newStoragePath}:`,
4298
- cleanupError
4299
- );
4300
- }
4301
- }
4302
- throw error;
4303
- }
4304
4500
  }
4305
4501
  /**
4306
- * List all media for an owner, optionally filtered by collection and access level.
4307
- * @param ownerId - ID of the owner.
4308
- * @param collectionName - Optional: Filter by collection name.
4309
- * @param accessLevel - Optional: Filter by access level.
4310
- * @param count - Optional: Number of items to fetch.
4311
- * @param startAfterId - Optional: ID of the document to start after (for pagination).
4502
+ * Dohvata sve klinike kojima admin upravlja
4312
4503
  */
4313
- async listMedia(ownerId, collectionName, accessLevel, count, startAfterId) {
4314
- console.log(`[MediaService] Listing media for owner: ${ownerId}`);
4315
- let qConstraints = [(0, import_firestore16.where)("ownerId", "==", ownerId)];
4316
- if (collectionName) {
4317
- qConstraints.push((0, import_firestore16.where)("collectionName", "==", collectionName));
4318
- }
4319
- if (accessLevel) {
4320
- qConstraints.push((0, import_firestore16.where)("accessLevel", "==", accessLevel));
4321
- }
4322
- qConstraints.push((0, import_firestore16.orderBy)("createdAt", "desc"));
4323
- if (count) {
4324
- qConstraints.push((0, import_firestore16.limit)(count));
4325
- }
4326
- if (startAfterId) {
4327
- const startAfterDoc = await this.getMediaMetadata(startAfterId);
4328
- if (startAfterDoc) {
4329
- }
4330
- }
4331
- const finalQuery = (0, import_firestore16.query)(
4332
- (0, import_firestore16.collection)(this.db, MEDIA_METADATA_COLLECTION),
4333
- ...qConstraints
4504
+ async getManagedClinics(adminId) {
4505
+ return getManagedClinics(
4506
+ this.db,
4507
+ adminId,
4508
+ this.getClinicService()
4334
4509
  );
4335
- try {
4336
- const querySnapshot = await (0, import_firestore16.getDocs)(finalQuery);
4337
- const mediaList = querySnapshot.docs.map(
4338
- (doc34) => doc34.data()
4339
- );
4340
- console.log(`[MediaService] Found ${mediaList.length} media items.`);
4341
- return mediaList;
4342
- } catch (error) {
4343
- console.error("[MediaService] Error listing media:", error);
4344
- throw error;
4345
- }
4346
4510
  }
4347
4511
  /**
4348
- * Get download URL for media. (Convenience, as URL is in metadata)
4349
- * @param mediaId - ID of the media.
4512
+ * Dohvata sve aktivne klinike kojima admin upravlja
4350
4513
  */
4351
- async getMediaDownloadUrl(mediaId) {
4352
- console.log(`[MediaService] Getting download URL for media ID: ${mediaId}`);
4353
- const metadata = await this.getMediaMetadata(mediaId);
4354
- if (metadata && metadata.url) {
4355
- console.log(`[MediaService] URL found: ${metadata.url}`);
4356
- return metadata.url;
4357
- }
4358
- console.log(`[MediaService] URL not found for media ID: ${mediaId}`);
4359
- return null;
4514
+ async getActiveManagedClinics(adminId) {
4515
+ return getActiveManagedClinics(
4516
+ this.db,
4517
+ adminId,
4518
+ this.getClinicService()
4519
+ );
4360
4520
  }
4521
+ // TODO: Add more methods for clinic admins for managing permissions, editing profiles by the admin, or by the clinic group owner and so on
4522
+ // Generally refactor admin permissions and clinic group permissions and systems for admin management
4361
4523
  };
4362
4524
 
4525
+ // src/services/practitioner/practitioner.service.ts
4526
+ var import_firestore18 = require("firebase/firestore");
4527
+
4363
4528
  // src/validations/practitioner.schema.ts
4364
4529
  var import_zod14 = require("zod");
4365
4530
  var import_firestore17 = require("firebase/firestore");
@@ -5647,7 +5812,7 @@ var import_geofire_common3 = require("geofire-common");
5647
5812
  var import_zod17 = require("zod");
5648
5813
 
5649
5814
  // src/services/clinic/utils/photos.utils.ts
5650
- var import_storage5 = require("firebase/storage");
5815
+ var import_storage4 = require("firebase/storage");
5651
5816
  async function uploadPhoto(photo, entityType, entityId, photoType, app, fileName) {
5652
5817
  if (!photo || typeof photo !== "string" || !photo.startsWith("data:")) {
5653
5818
  return photo;
@@ -5656,9 +5821,9 @@ async function uploadPhoto(photo, entityType, entityId, photoType, app, fileName
5656
5821
  console.log(
5657
5822
  `[PHOTO_UTILS] Uploading ${photoType} for ${entityType}/${entityId}`
5658
5823
  );
5659
- const storage = (0, import_storage5.getStorage)(app);
5824
+ const storage = (0, import_storage4.getStorage)(app);
5660
5825
  const storageFileName = fileName || `${photoType}-${Date.now()}`;
5661
- const storageRef = (0, import_storage5.ref)(
5826
+ const storageRef = (0, import_storage4.ref)(
5662
5827
  storage,
5663
5828
  `${entityType}/${entityId}/${storageFileName}`
5664
5829
  );
@@ -5670,8 +5835,8 @@ async function uploadPhoto(photo, entityType, entityId, photoType, app, fileName
5670
5835
  byteArrays.push(byteCharacters.charCodeAt(i));
5671
5836
  }
5672
5837
  const blob = new Blob([new Uint8Array(byteArrays)], { type: contentType });
5673
- await (0, import_storage5.uploadBytes)(storageRef, blob, { contentType });
5674
- const downloadUrl = await (0, import_storage5.getDownloadURL)(storageRef);
5838
+ await (0, import_storage4.uploadBytes)(storageRef, blob, { contentType });
5839
+ const downloadUrl = await (0, import_storage4.getDownloadURL)(storageRef);
5675
5840
  console.log(`[PHOTO_UTILS] ${photoType} uploaded successfully`, {
5676
5841
  downloadUrl
5677
5842
  });