@blackcode_sa/metaestetics-api 1.13.2 → 1.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -6794,9 +6794,10 @@ declare class ProcedureService extends BaseService {
6794
6794
  /**
6795
6795
  * Gets all procedures for a practitioner
6796
6796
  * @param practitionerId - The ID of the practitioner
6797
+ * @param clinicBranchId - Optional clinic branch ID to filter by
6797
6798
  * @returns List of procedures
6798
6799
  */
6799
- getProceduresByPractitioner(practitionerId: string): Promise<Procedure[]>;
6800
+ getProceduresByPractitioner(practitionerId: string, clinicBranchId?: string): Promise<Procedure[]>;
6800
6801
  /**
6801
6802
  * Gets all inactive procedures for a practitioner
6802
6803
  * @param practitionerId - The ID of the practitioner
package/dist/index.d.ts CHANGED
@@ -6794,9 +6794,10 @@ declare class ProcedureService extends BaseService {
6794
6794
  /**
6795
6795
  * Gets all procedures for a practitioner
6796
6796
  * @param practitionerId - The ID of the practitioner
6797
+ * @param clinicBranchId - Optional clinic branch ID to filter by
6797
6798
  * @returns List of procedures
6798
6799
  */
6799
- getProceduresByPractitioner(practitionerId: string): Promise<Procedure[]>;
6800
+ getProceduresByPractitioner(practitionerId: string, clinicBranchId?: string): Promise<Procedure[]>;
6800
6801
  /**
6801
6802
  * Gets all inactive procedures for a practitioner
6802
6803
  * @param practitionerId - The ID of the practitioner
package/dist/index.js CHANGED
@@ -20035,6 +20035,25 @@ var ProcedureService = class extends BaseService {
20035
20035
  throw new Error(`Practitioner with ID ${validatedData.practitionerId} not found`);
20036
20036
  }
20037
20037
  const practitioner = practitionerSnapshot.data();
20038
+ const existingProceduresQuery = (0, import_firestore58.query)(
20039
+ (0, import_firestore58.collection)(this.db, PROCEDURES_COLLECTION),
20040
+ (0, import_firestore58.where)("practitionerId", "==", validatedData.practitionerId),
20041
+ (0, import_firestore58.where)("clinicBranchId", "==", validatedData.clinicBranchId),
20042
+ (0, import_firestore58.where)("isActive", "==", true)
20043
+ );
20044
+ const existingProceduresSnapshot = await (0, import_firestore58.getDocs)(existingProceduresQuery);
20045
+ const existingProcedures = existingProceduresSnapshot.docs.map((doc47) => doc47.data());
20046
+ const hasSameTechnology = existingProcedures.some(
20047
+ (proc) => {
20048
+ var _a2;
20049
+ return ((_a2 = proc.technology) == null ? void 0 : _a2.id) === validatedData.technologyId;
20050
+ }
20051
+ );
20052
+ if (hasSameTechnology) {
20053
+ throw new Error(
20054
+ `Practitioner ${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName} already has a procedure with technology "${(technology == null ? void 0 : technology.name) || validatedData.technologyId}" in this clinic branch`
20055
+ );
20056
+ }
20038
20057
  let processedPhotos = [];
20039
20058
  if (validatedData.photos && validatedData.photos.length > 0) {
20040
20059
  processedPhotos = await this.processMediaArray(
@@ -20455,6 +20474,40 @@ var ProcedureService = class extends BaseService {
20455
20474
  const notFoundIds = practitionerIds.filter((id) => !foundIds.includes(id));
20456
20475
  throw new Error(`The following practitioners were not found: ${notFoundIds.join(", ")}`);
20457
20476
  }
20477
+ const duplicatePractitioners = [];
20478
+ const duplicateChecks = await Promise.all(
20479
+ practitionerIds.map(async (practitionerId) => {
20480
+ const existingProceduresQuery = (0, import_firestore58.query)(
20481
+ (0, import_firestore58.collection)(this.db, PROCEDURES_COLLECTION),
20482
+ (0, import_firestore58.where)("practitionerId", "==", practitionerId),
20483
+ (0, import_firestore58.where)("clinicBranchId", "==", validatedData.clinicBranchId),
20484
+ (0, import_firestore58.where)("isActive", "==", true)
20485
+ );
20486
+ const existingProceduresSnapshot = await (0, import_firestore58.getDocs)(existingProceduresQuery);
20487
+ const existingProcedures = existingProceduresSnapshot.docs.map((doc47) => doc47.data());
20488
+ const hasSameTechnology = existingProcedures.some(
20489
+ (proc) => {
20490
+ var _a2;
20491
+ return ((_a2 = proc.technology) == null ? void 0 : _a2.id) === validatedData.technologyId;
20492
+ }
20493
+ );
20494
+ return { practitionerId, hasSameTechnology };
20495
+ })
20496
+ );
20497
+ duplicateChecks.forEach(({ practitionerId, hasSameTechnology }) => {
20498
+ if (hasSameTechnology) {
20499
+ duplicatePractitioners.push(practitionerId);
20500
+ }
20501
+ });
20502
+ if (duplicatePractitioners.length > 0) {
20503
+ const duplicateNames = duplicatePractitioners.map((id) => {
20504
+ const practitioner = practitionersMap.get(id);
20505
+ return `${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`;
20506
+ }).join(", ");
20507
+ throw new Error(
20508
+ `The following practitioner(s) already have a procedure with technology "${(technology == null ? void 0 : technology.name) || validatedData.technologyId}" in this clinic branch: ${duplicateNames}. Please remove them from the selection and try again.`
20509
+ );
20510
+ }
20458
20511
  const batch = (0, import_firestore58.writeBatch)(this.db);
20459
20512
  const createdProcedureIds = [];
20460
20513
  const clinicInfo = {
@@ -20578,13 +20631,20 @@ var ProcedureService = class extends BaseService {
20578
20631
  /**
20579
20632
  * Gets all procedures for a practitioner
20580
20633
  * @param practitionerId - The ID of the practitioner
20634
+ * @param clinicBranchId - Optional clinic branch ID to filter by
20581
20635
  * @returns List of procedures
20582
20636
  */
20583
- async getProceduresByPractitioner(practitionerId) {
20584
- const q = (0, import_firestore58.query)(
20585
- (0, import_firestore58.collection)(this.db, PROCEDURES_COLLECTION),
20637
+ async getProceduresByPractitioner(practitionerId, clinicBranchId) {
20638
+ const constraints = [
20586
20639
  (0, import_firestore58.where)("practitionerId", "==", practitionerId),
20587
20640
  (0, import_firestore58.where)("isActive", "==", true)
20641
+ ];
20642
+ if (clinicBranchId) {
20643
+ constraints.push((0, import_firestore58.where)("clinicBranchId", "==", clinicBranchId));
20644
+ }
20645
+ const q = (0, import_firestore58.query)(
20646
+ (0, import_firestore58.collection)(this.db, PROCEDURES_COLLECTION),
20647
+ ...constraints
20588
20648
  );
20589
20649
  const snapshot = await (0, import_firestore58.getDocs)(q);
20590
20650
  return snapshot.docs.map((doc47) => doc47.data());
package/dist/index.mjs CHANGED
@@ -20271,6 +20271,25 @@ var ProcedureService = class extends BaseService {
20271
20271
  throw new Error(`Practitioner with ID ${validatedData.practitionerId} not found`);
20272
20272
  }
20273
20273
  const practitioner = practitionerSnapshot.data();
20274
+ const existingProceduresQuery = query33(
20275
+ collection33(this.db, PROCEDURES_COLLECTION),
20276
+ where33("practitionerId", "==", validatedData.practitionerId),
20277
+ where33("clinicBranchId", "==", validatedData.clinicBranchId),
20278
+ where33("isActive", "==", true)
20279
+ );
20280
+ const existingProceduresSnapshot = await getDocs33(existingProceduresQuery);
20281
+ const existingProcedures = existingProceduresSnapshot.docs.map((doc47) => doc47.data());
20282
+ const hasSameTechnology = existingProcedures.some(
20283
+ (proc) => {
20284
+ var _a2;
20285
+ return ((_a2 = proc.technology) == null ? void 0 : _a2.id) === validatedData.technologyId;
20286
+ }
20287
+ );
20288
+ if (hasSameTechnology) {
20289
+ throw new Error(
20290
+ `Practitioner ${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName} already has a procedure with technology "${(technology == null ? void 0 : technology.name) || validatedData.technologyId}" in this clinic branch`
20291
+ );
20292
+ }
20274
20293
  let processedPhotos = [];
20275
20294
  if (validatedData.photos && validatedData.photos.length > 0) {
20276
20295
  processedPhotos = await this.processMediaArray(
@@ -20691,6 +20710,40 @@ var ProcedureService = class extends BaseService {
20691
20710
  const notFoundIds = practitionerIds.filter((id) => !foundIds.includes(id));
20692
20711
  throw new Error(`The following practitioners were not found: ${notFoundIds.join(", ")}`);
20693
20712
  }
20713
+ const duplicatePractitioners = [];
20714
+ const duplicateChecks = await Promise.all(
20715
+ practitionerIds.map(async (practitionerId) => {
20716
+ const existingProceduresQuery = query33(
20717
+ collection33(this.db, PROCEDURES_COLLECTION),
20718
+ where33("practitionerId", "==", practitionerId),
20719
+ where33("clinicBranchId", "==", validatedData.clinicBranchId),
20720
+ where33("isActive", "==", true)
20721
+ );
20722
+ const existingProceduresSnapshot = await getDocs33(existingProceduresQuery);
20723
+ const existingProcedures = existingProceduresSnapshot.docs.map((doc47) => doc47.data());
20724
+ const hasSameTechnology = existingProcedures.some(
20725
+ (proc) => {
20726
+ var _a2;
20727
+ return ((_a2 = proc.technology) == null ? void 0 : _a2.id) === validatedData.technologyId;
20728
+ }
20729
+ );
20730
+ return { practitionerId, hasSameTechnology };
20731
+ })
20732
+ );
20733
+ duplicateChecks.forEach(({ practitionerId, hasSameTechnology }) => {
20734
+ if (hasSameTechnology) {
20735
+ duplicatePractitioners.push(practitionerId);
20736
+ }
20737
+ });
20738
+ if (duplicatePractitioners.length > 0) {
20739
+ const duplicateNames = duplicatePractitioners.map((id) => {
20740
+ const practitioner = practitionersMap.get(id);
20741
+ return `${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`;
20742
+ }).join(", ");
20743
+ throw new Error(
20744
+ `The following practitioner(s) already have a procedure with technology "${(technology == null ? void 0 : technology.name) || validatedData.technologyId}" in this clinic branch: ${duplicateNames}. Please remove them from the selection and try again.`
20745
+ );
20746
+ }
20694
20747
  const batch = writeBatch6(this.db);
20695
20748
  const createdProcedureIds = [];
20696
20749
  const clinicInfo = {
@@ -20814,13 +20867,20 @@ var ProcedureService = class extends BaseService {
20814
20867
  /**
20815
20868
  * Gets all procedures for a practitioner
20816
20869
  * @param practitionerId - The ID of the practitioner
20870
+ * @param clinicBranchId - Optional clinic branch ID to filter by
20817
20871
  * @returns List of procedures
20818
20872
  */
20819
- async getProceduresByPractitioner(practitionerId) {
20820
- const q = query33(
20821
- collection33(this.db, PROCEDURES_COLLECTION),
20873
+ async getProceduresByPractitioner(practitionerId, clinicBranchId) {
20874
+ const constraints = [
20822
20875
  where33("practitionerId", "==", practitionerId),
20823
20876
  where33("isActive", "==", true)
20877
+ ];
20878
+ if (clinicBranchId) {
20879
+ constraints.push(where33("clinicBranchId", "==", clinicBranchId));
20880
+ }
20881
+ const q = query33(
20882
+ collection33(this.db, PROCEDURES_COLLECTION),
20883
+ ...constraints
20824
20884
  );
20825
20885
  const snapshot = await getDocs33(q);
20826
20886
  return snapshot.docs.map((doc47) => doc47.data());
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blackcode_sa/metaestetics-api",
3
3
  "private": false,
4
- "version": "1.13.2",
4
+ "version": "1.13.4",
5
5
  "description": "Firebase authentication service with anonymous upgrade support",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -244,6 +244,25 @@ export class ProcedureService extends BaseService {
244
244
  }
245
245
  const practitioner = practitionerSnapshot.data() as Practitioner; // Assert type
246
246
 
247
+ // Check if practitioner already has a procedure with the same technology ID in this clinic branch
248
+ const existingProceduresQuery = query(
249
+ collection(this.db, PROCEDURES_COLLECTION),
250
+ where('practitionerId', '==', validatedData.practitionerId),
251
+ where('clinicBranchId', '==', validatedData.clinicBranchId),
252
+ where('isActive', '==', true)
253
+ );
254
+ const existingProceduresSnapshot = await getDocs(existingProceduresQuery);
255
+ const existingProcedures = existingProceduresSnapshot.docs.map(doc => doc.data() as Procedure);
256
+
257
+ const hasSameTechnology = existingProcedures.some(
258
+ proc => proc.technology?.id === validatedData.technologyId
259
+ );
260
+ if (hasSameTechnology) {
261
+ throw new Error(
262
+ `Practitioner ${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName} already has a procedure with technology "${technology?.name || validatedData.technologyId}" in this clinic branch`
263
+ );
264
+ }
265
+
247
266
  // Process photos if provided
248
267
  let processedPhotos: string[] = [];
249
268
  if (validatedData.photos && validatedData.photos.length > 0) {
@@ -787,7 +806,49 @@ export class ProcedureService extends BaseService {
787
806
  throw new Error(`The following practitioners were not found: ${notFoundIds.join(', ')}`);
788
807
  }
789
808
 
790
- // 5. Use a Firestore batch for atomic creation
809
+ // 5. Check for duplicates across all practitioners before creating any procedures
810
+ const duplicatePractitioners: string[] = [];
811
+ const duplicateChecks = await Promise.all(
812
+ practitionerIds.map(async (practitionerId) => {
813
+ const existingProceduresQuery = query(
814
+ collection(this.db, PROCEDURES_COLLECTION),
815
+ where('practitionerId', '==', practitionerId),
816
+ where('clinicBranchId', '==', validatedData.clinicBranchId),
817
+ where('isActive', '==', true)
818
+ );
819
+ const existingProceduresSnapshot = await getDocs(existingProceduresQuery);
820
+ const existingProcedures = existingProceduresSnapshot.docs.map(doc => doc.data() as Procedure);
821
+
822
+ const hasSameTechnology = existingProcedures.some(
823
+ proc => proc.technology?.id === validatedData.technologyId
824
+ );
825
+
826
+ return { practitionerId, hasSameTechnology };
827
+ })
828
+ );
829
+
830
+ // Collect all practitioners with duplicates
831
+ duplicateChecks.forEach(({ practitionerId, hasSameTechnology }) => {
832
+ if (hasSameTechnology) {
833
+ duplicatePractitioners.push(practitionerId);
834
+ }
835
+ });
836
+
837
+ // If any duplicates found, throw error listing all of them
838
+ if (duplicatePractitioners.length > 0) {
839
+ const duplicateNames = duplicatePractitioners
840
+ .map(id => {
841
+ const practitioner = practitionersMap.get(id)!;
842
+ return `${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`;
843
+ })
844
+ .join(', ');
845
+
846
+ throw new Error(
847
+ `The following practitioner(s) already have a procedure with technology "${technology?.name || validatedData.technologyId}" in this clinic branch: ${duplicateNames}. Please remove them from the selection and try again.`
848
+ );
849
+ }
850
+
851
+ // 6. Use a Firestore batch for atomic creation
791
852
  const batch = writeBatch(this.db);
792
853
  const createdProcedureIds: string[] = [];
793
854
  const clinicInfo = {
@@ -887,10 +948,10 @@ export class ProcedureService extends BaseService {
887
948
  });
888
949
  }
889
950
 
890
- // 6. Commit the atomic batch write
951
+ // 7. Commit the atomic batch write
891
952
  await batch.commit();
892
953
 
893
- // 7. Fetch and return the newly created procedures
954
+ // 8. Fetch and return the newly created procedures
894
955
  const fetchedProcedures: Procedure[] = [];
895
956
  for (let i = 0; i < createdProcedureIds.length; i += 30) {
896
957
  const chunk = createdProcedureIds.slice(i, i + 30);
@@ -938,13 +999,22 @@ export class ProcedureService extends BaseService {
938
999
  /**
939
1000
  * Gets all procedures for a practitioner
940
1001
  * @param practitionerId - The ID of the practitioner
1002
+ * @param clinicBranchId - Optional clinic branch ID to filter by
941
1003
  * @returns List of procedures
942
1004
  */
943
- async getProceduresByPractitioner(practitionerId: string): Promise<Procedure[]> {
944
- const q = query(
945
- collection(this.db, PROCEDURES_COLLECTION),
1005
+ async getProceduresByPractitioner(practitionerId: string, clinicBranchId?: string): Promise<Procedure[]> {
1006
+ const constraints: QueryConstraint[] = [
946
1007
  where('practitionerId', '==', practitionerId),
947
1008
  where('isActive', '==', true),
1009
+ ];
1010
+
1011
+ if (clinicBranchId) {
1012
+ constraints.push(where('clinicBranchId', '==', clinicBranchId));
1013
+ }
1014
+
1015
+ const q = query(
1016
+ collection(this.db, PROCEDURES_COLLECTION),
1017
+ ...constraints
948
1018
  );
949
1019
  const snapshot = await getDocs(q);
950
1020
  return snapshot.docs.map(doc => doc.data() as Procedure);