@blackcode_sa/metaestetics-api 1.12.21 → 1.12.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +4 -0
- package/dist/admin/index.d.ts +4 -0
- package/dist/index.d.mts +15 -11
- package/dist/index.d.ts +15 -11
- package/dist/index.js +298 -19
- package/dist/index.mjs +298 -19
- package/package.json +1 -1
- package/src/services/reviews/README.md +129 -0
- package/src/services/reviews/reviews.service.ts +399 -39
- package/src/types/reviews/index.ts +5 -1
package/dist/index.mjs
CHANGED
|
@@ -16491,7 +16491,17 @@ var ReviewService = class extends BaseService {
|
|
|
16491
16491
|
* @returns The created review
|
|
16492
16492
|
*/
|
|
16493
16493
|
async createReview(data, appointmentId) {
|
|
16494
|
+
var _a, _b, _c, _d, _e, _f;
|
|
16494
16495
|
try {
|
|
16496
|
+
console.log("\u{1F50D} ReviewService.createReview - Input data:", {
|
|
16497
|
+
appointmentId,
|
|
16498
|
+
hasClinicReview: !!data.clinicReview,
|
|
16499
|
+
hasPractitionerReview: !!data.practitionerReview,
|
|
16500
|
+
hasProcedureReview: !!data.procedureReview,
|
|
16501
|
+
practitionerId: (_a = data.practitionerReview) == null ? void 0 : _a.practitionerId,
|
|
16502
|
+
clinicId: (_b = data.clinicReview) == null ? void 0 : _b.clinicId,
|
|
16503
|
+
procedureId: (_c = data.procedureReview) == null ? void 0 : _c.procedureId
|
|
16504
|
+
});
|
|
16495
16505
|
const validatedData = createReviewSchema.parse(data);
|
|
16496
16506
|
const ratings = [];
|
|
16497
16507
|
if (data.clinicReview) {
|
|
@@ -16564,6 +16574,12 @@ var ReviewService = class extends BaseService {
|
|
|
16564
16574
|
createdAt: serverTimestamp26(),
|
|
16565
16575
|
updatedAt: serverTimestamp26()
|
|
16566
16576
|
});
|
|
16577
|
+
console.log("\u2705 ReviewService.createReview - Review saved to Firestore:", {
|
|
16578
|
+
reviewId,
|
|
16579
|
+
practitionerId: (_d = review.practitionerReview) == null ? void 0 : _d.practitionerId,
|
|
16580
|
+
clinicId: (_e = review.clinicReview) == null ? void 0 : _e.clinicId,
|
|
16581
|
+
procedureId: (_f = review.procedureReview) == null ? void 0 : _f.procedureId
|
|
16582
|
+
});
|
|
16567
16583
|
return review;
|
|
16568
16584
|
} catch (error) {
|
|
16569
16585
|
if (error instanceof z26.ZodError) {
|
|
@@ -16573,69 +16589,332 @@ var ReviewService = class extends BaseService {
|
|
|
16573
16589
|
}
|
|
16574
16590
|
}
|
|
16575
16591
|
/**
|
|
16576
|
-
* Gets a review by ID
|
|
16592
|
+
* Gets a review by ID with enhanced entity names
|
|
16577
16593
|
* @param reviewId The ID of the review to get
|
|
16578
|
-
* @returns The review if found, null otherwise
|
|
16594
|
+
* @returns The review with entity names if found, null otherwise
|
|
16579
16595
|
*/
|
|
16580
16596
|
async getReview(reviewId) {
|
|
16597
|
+
var _a, _b, _c;
|
|
16598
|
+
console.log("\u{1F50D} ReviewService.getReview - Getting review:", reviewId);
|
|
16581
16599
|
const docRef = doc31(this.db, REVIEWS_COLLECTION, reviewId);
|
|
16582
16600
|
const docSnap = await getDoc33(docRef);
|
|
16583
16601
|
if (!docSnap.exists()) {
|
|
16602
|
+
console.log("\u274C ReviewService.getReview - Review not found:", reviewId);
|
|
16584
16603
|
return null;
|
|
16585
16604
|
}
|
|
16586
|
-
|
|
16605
|
+
const review = { ...docSnap.data(), id: reviewId };
|
|
16606
|
+
try {
|
|
16607
|
+
const appointmentDoc = await getDoc33(
|
|
16608
|
+
doc31(this.db, APPOINTMENTS_COLLECTION, review.appointmentId)
|
|
16609
|
+
);
|
|
16610
|
+
if (appointmentDoc.exists()) {
|
|
16611
|
+
const appointment = appointmentDoc.data();
|
|
16612
|
+
const enhancedReview = { ...review };
|
|
16613
|
+
if (enhancedReview.clinicReview && appointment.clinicInfo) {
|
|
16614
|
+
enhancedReview.clinicReview = {
|
|
16615
|
+
...enhancedReview.clinicReview,
|
|
16616
|
+
clinicName: appointment.clinicInfo.name
|
|
16617
|
+
};
|
|
16618
|
+
}
|
|
16619
|
+
if (enhancedReview.practitionerReview && appointment.practitionerInfo) {
|
|
16620
|
+
enhancedReview.practitionerReview = {
|
|
16621
|
+
...enhancedReview.practitionerReview,
|
|
16622
|
+
practitionerName: appointment.practitionerInfo.name
|
|
16623
|
+
};
|
|
16624
|
+
}
|
|
16625
|
+
if (enhancedReview.procedureReview && appointment.procedureInfo) {
|
|
16626
|
+
enhancedReview.procedureReview = {
|
|
16627
|
+
...enhancedReview.procedureReview,
|
|
16628
|
+
procedureName: appointment.procedureInfo.name
|
|
16629
|
+
};
|
|
16630
|
+
}
|
|
16631
|
+
if (appointment.patientInfo) {
|
|
16632
|
+
enhancedReview.patientName = appointment.patientInfo.fullName;
|
|
16633
|
+
}
|
|
16634
|
+
console.log("\u2705 ReviewService.getReview - Enhanced review:", {
|
|
16635
|
+
reviewId,
|
|
16636
|
+
hasEntityNames: !!(((_a = enhancedReview.clinicReview) == null ? void 0 : _a.clinicName) || ((_b = enhancedReview.practitionerReview) == null ? void 0 : _b.practitionerName) || ((_c = enhancedReview.procedureReview) == null ? void 0 : _c.procedureName) || enhancedReview.patientName)
|
|
16637
|
+
});
|
|
16638
|
+
return enhancedReview;
|
|
16639
|
+
}
|
|
16640
|
+
console.log("\u26A0\uFE0F ReviewService.getReview - Appointment not found for review:", reviewId);
|
|
16641
|
+
return review;
|
|
16642
|
+
} catch (error) {
|
|
16643
|
+
console.warn(`Failed to enhance review ${reviewId} with entity names:`, error);
|
|
16644
|
+
return review;
|
|
16645
|
+
}
|
|
16587
16646
|
}
|
|
16588
16647
|
/**
|
|
16589
|
-
* Gets all reviews for a specific patient
|
|
16648
|
+
* Gets all reviews for a specific patient with enhanced entity names
|
|
16590
16649
|
* @param patientId The ID of the patient
|
|
16591
|
-
* @returns Array of reviews for the patient
|
|
16650
|
+
* @returns Array of reviews for the patient with clinic, practitioner, and procedure names
|
|
16592
16651
|
*/
|
|
16593
16652
|
async getReviewsByPatient(patientId) {
|
|
16594
|
-
const q = query31(
|
|
16595
|
-
collection31(this.db, REVIEWS_COLLECTION),
|
|
16596
|
-
where31("patientId", "==", patientId)
|
|
16597
|
-
);
|
|
16653
|
+
const q = query31(collection31(this.db, REVIEWS_COLLECTION), where31("patientId", "==", patientId));
|
|
16598
16654
|
const snapshot = await getDocs31(q);
|
|
16599
|
-
|
|
16655
|
+
const reviews = snapshot.docs.map((doc38) => doc38.data());
|
|
16656
|
+
const enhancedReviews = await Promise.all(
|
|
16657
|
+
reviews.map(async (review) => {
|
|
16658
|
+
try {
|
|
16659
|
+
const appointmentDoc = await getDoc33(
|
|
16660
|
+
doc31(this.db, APPOINTMENTS_COLLECTION, review.appointmentId)
|
|
16661
|
+
);
|
|
16662
|
+
if (appointmentDoc.exists()) {
|
|
16663
|
+
const appointment = appointmentDoc.data();
|
|
16664
|
+
const enhancedReview = { ...review };
|
|
16665
|
+
if (enhancedReview.clinicReview && appointment.clinicInfo) {
|
|
16666
|
+
enhancedReview.clinicReview = {
|
|
16667
|
+
...enhancedReview.clinicReview,
|
|
16668
|
+
clinicName: appointment.clinicInfo.name
|
|
16669
|
+
};
|
|
16670
|
+
}
|
|
16671
|
+
if (enhancedReview.practitionerReview && appointment.practitionerInfo) {
|
|
16672
|
+
enhancedReview.practitionerReview = {
|
|
16673
|
+
...enhancedReview.practitionerReview,
|
|
16674
|
+
practitionerName: appointment.practitionerInfo.name
|
|
16675
|
+
};
|
|
16676
|
+
}
|
|
16677
|
+
if (enhancedReview.procedureReview && appointment.procedureInfo) {
|
|
16678
|
+
enhancedReview.procedureReview = {
|
|
16679
|
+
...enhancedReview.procedureReview,
|
|
16680
|
+
procedureName: appointment.procedureInfo.name
|
|
16681
|
+
};
|
|
16682
|
+
}
|
|
16683
|
+
if (appointment.patientInfo) {
|
|
16684
|
+
enhancedReview.patientName = appointment.patientInfo.fullName;
|
|
16685
|
+
}
|
|
16686
|
+
return enhancedReview;
|
|
16687
|
+
}
|
|
16688
|
+
return review;
|
|
16689
|
+
} catch (error) {
|
|
16690
|
+
console.warn(`Failed to enhance review ${review.id} with entity names:`, error);
|
|
16691
|
+
return review;
|
|
16692
|
+
}
|
|
16693
|
+
})
|
|
16694
|
+
);
|
|
16695
|
+
return enhancedReviews;
|
|
16600
16696
|
}
|
|
16601
16697
|
/**
|
|
16602
|
-
* Gets all reviews for a specific clinic
|
|
16698
|
+
* Gets all reviews for a specific clinic with enhanced entity names
|
|
16603
16699
|
* @param clinicId The ID of the clinic
|
|
16604
|
-
* @returns Array of reviews containing clinic reviews
|
|
16700
|
+
* @returns Array of reviews containing clinic reviews with clinic, practitioner, and procedure names
|
|
16605
16701
|
*/
|
|
16606
16702
|
async getReviewsByClinic(clinicId) {
|
|
16703
|
+
console.log("\u{1F50D} ReviewService.getReviewsByClinic - Querying for clinic:", clinicId);
|
|
16607
16704
|
const q = query31(
|
|
16608
16705
|
collection31(this.db, REVIEWS_COLLECTION),
|
|
16609
16706
|
where31("clinicReview.clinicId", "==", clinicId)
|
|
16610
16707
|
);
|
|
16611
16708
|
const snapshot = await getDocs31(q);
|
|
16612
|
-
|
|
16709
|
+
const reviews = snapshot.docs.map((doc38) => {
|
|
16710
|
+
const data = doc38.data();
|
|
16711
|
+
return { ...data, id: doc38.id };
|
|
16712
|
+
});
|
|
16713
|
+
console.log("\u{1F50D} ReviewService.getReviewsByClinic - Found reviews before enhancement:", {
|
|
16714
|
+
clinicId,
|
|
16715
|
+
reviewCount: reviews.length,
|
|
16716
|
+
reviewIds: reviews.map((r) => r.id)
|
|
16717
|
+
});
|
|
16718
|
+
const enhancedReviews = await Promise.all(
|
|
16719
|
+
reviews.map(async (review) => {
|
|
16720
|
+
try {
|
|
16721
|
+
const appointmentDoc = await getDoc33(
|
|
16722
|
+
doc31(this.db, APPOINTMENTS_COLLECTION, review.appointmentId)
|
|
16723
|
+
);
|
|
16724
|
+
if (appointmentDoc.exists()) {
|
|
16725
|
+
const appointment = appointmentDoc.data();
|
|
16726
|
+
const enhancedReview = { ...review };
|
|
16727
|
+
if (enhancedReview.clinicReview && appointment.clinicInfo) {
|
|
16728
|
+
enhancedReview.clinicReview = {
|
|
16729
|
+
...enhancedReview.clinicReview,
|
|
16730
|
+
clinicName: appointment.clinicInfo.name
|
|
16731
|
+
};
|
|
16732
|
+
}
|
|
16733
|
+
if (enhancedReview.practitionerReview && appointment.practitionerInfo) {
|
|
16734
|
+
enhancedReview.practitionerReview = {
|
|
16735
|
+
...enhancedReview.practitionerReview,
|
|
16736
|
+
practitionerName: appointment.practitionerInfo.name
|
|
16737
|
+
};
|
|
16738
|
+
}
|
|
16739
|
+
if (enhancedReview.procedureReview && appointment.procedureInfo) {
|
|
16740
|
+
enhancedReview.procedureReview = {
|
|
16741
|
+
...enhancedReview.procedureReview,
|
|
16742
|
+
procedureName: appointment.procedureInfo.name
|
|
16743
|
+
};
|
|
16744
|
+
}
|
|
16745
|
+
if (appointment.patientInfo) {
|
|
16746
|
+
enhancedReview.patientName = appointment.patientInfo.fullName;
|
|
16747
|
+
}
|
|
16748
|
+
return enhancedReview;
|
|
16749
|
+
}
|
|
16750
|
+
return review;
|
|
16751
|
+
} catch (error) {
|
|
16752
|
+
console.warn(`Failed to enhance review ${review.id} with entity names:`, error);
|
|
16753
|
+
return review;
|
|
16754
|
+
}
|
|
16755
|
+
})
|
|
16756
|
+
);
|
|
16757
|
+
console.log("\u2705 ReviewService.getReviewsByClinic - Enhanced reviews:", {
|
|
16758
|
+
clinicId,
|
|
16759
|
+
reviewCount: enhancedReviews.length,
|
|
16760
|
+
reviewIds: enhancedReviews.map((r) => r.id),
|
|
16761
|
+
hasEntityNames: enhancedReviews.some(
|
|
16762
|
+
(r) => {
|
|
16763
|
+
var _a, _b, _c;
|
|
16764
|
+
return ((_a = r.clinicReview) == null ? void 0 : _a.clinicName) || ((_b = r.practitionerReview) == null ? void 0 : _b.practitionerName) || ((_c = r.procedureReview) == null ? void 0 : _c.procedureName) || r.patientName;
|
|
16765
|
+
}
|
|
16766
|
+
)
|
|
16767
|
+
});
|
|
16768
|
+
return enhancedReviews;
|
|
16613
16769
|
}
|
|
16614
16770
|
/**
|
|
16615
|
-
* Gets all reviews for a specific practitioner
|
|
16771
|
+
* Gets all reviews for a specific practitioner with enhanced entity names
|
|
16616
16772
|
* @param practitionerId The ID of the practitioner
|
|
16617
|
-
* @returns Array of reviews containing practitioner reviews
|
|
16773
|
+
* @returns Array of reviews containing practitioner reviews with clinic, practitioner, and procedure names
|
|
16618
16774
|
*/
|
|
16619
16775
|
async getReviewsByPractitioner(practitionerId) {
|
|
16776
|
+
console.log(
|
|
16777
|
+
"\u{1F50D} ReviewService.getReviewsByPractitioner - Querying for practitioner:",
|
|
16778
|
+
practitionerId
|
|
16779
|
+
);
|
|
16620
16780
|
const q = query31(
|
|
16621
16781
|
collection31(this.db, REVIEWS_COLLECTION),
|
|
16622
16782
|
where31("practitionerReview.practitionerId", "==", practitionerId)
|
|
16623
16783
|
);
|
|
16624
16784
|
const snapshot = await getDocs31(q);
|
|
16625
|
-
|
|
16785
|
+
const reviews = snapshot.docs.map((doc38) => {
|
|
16786
|
+
const data = doc38.data();
|
|
16787
|
+
return { ...data, id: doc38.id };
|
|
16788
|
+
});
|
|
16789
|
+
console.log("\u{1F50D} ReviewService.getReviewsByPractitioner - Found reviews before enhancement:", {
|
|
16790
|
+
practitionerId,
|
|
16791
|
+
reviewCount: reviews.length,
|
|
16792
|
+
reviewIds: reviews.map((r) => r.id)
|
|
16793
|
+
});
|
|
16794
|
+
const enhancedReviews = await Promise.all(
|
|
16795
|
+
reviews.map(async (review) => {
|
|
16796
|
+
try {
|
|
16797
|
+
const appointmentDoc = await getDoc33(
|
|
16798
|
+
doc31(this.db, APPOINTMENTS_COLLECTION, review.appointmentId)
|
|
16799
|
+
);
|
|
16800
|
+
if (appointmentDoc.exists()) {
|
|
16801
|
+
const appointment = appointmentDoc.data();
|
|
16802
|
+
const enhancedReview = { ...review };
|
|
16803
|
+
if (enhancedReview.clinicReview && appointment.clinicInfo) {
|
|
16804
|
+
enhancedReview.clinicReview = {
|
|
16805
|
+
...enhancedReview.clinicReview,
|
|
16806
|
+
clinicName: appointment.clinicInfo.name
|
|
16807
|
+
};
|
|
16808
|
+
}
|
|
16809
|
+
if (enhancedReview.practitionerReview && appointment.practitionerInfo) {
|
|
16810
|
+
enhancedReview.practitionerReview = {
|
|
16811
|
+
...enhancedReview.practitionerReview,
|
|
16812
|
+
practitionerName: appointment.practitionerInfo.name
|
|
16813
|
+
};
|
|
16814
|
+
}
|
|
16815
|
+
if (enhancedReview.procedureReview && appointment.procedureInfo) {
|
|
16816
|
+
enhancedReview.procedureReview = {
|
|
16817
|
+
...enhancedReview.procedureReview,
|
|
16818
|
+
procedureName: appointment.procedureInfo.name
|
|
16819
|
+
};
|
|
16820
|
+
}
|
|
16821
|
+
if (appointment.patientInfo) {
|
|
16822
|
+
enhancedReview.patientName = appointment.patientInfo.fullName;
|
|
16823
|
+
}
|
|
16824
|
+
return enhancedReview;
|
|
16825
|
+
}
|
|
16826
|
+
return review;
|
|
16827
|
+
} catch (error) {
|
|
16828
|
+
console.warn(`Failed to enhance review ${review.id} with entity names:`, error);
|
|
16829
|
+
return review;
|
|
16830
|
+
}
|
|
16831
|
+
})
|
|
16832
|
+
);
|
|
16833
|
+
console.log("\u2705 ReviewService.getReviewsByPractitioner - Enhanced reviews:", {
|
|
16834
|
+
practitionerId,
|
|
16835
|
+
reviewCount: enhancedReviews.length,
|
|
16836
|
+
reviewIds: enhancedReviews.map((r) => r.id),
|
|
16837
|
+
hasEntityNames: enhancedReviews.some(
|
|
16838
|
+
(r) => {
|
|
16839
|
+
var _a, _b, _c;
|
|
16840
|
+
return ((_a = r.clinicReview) == null ? void 0 : _a.clinicName) || ((_b = r.practitionerReview) == null ? void 0 : _b.practitionerName) || ((_c = r.procedureReview) == null ? void 0 : _c.procedureName);
|
|
16841
|
+
}
|
|
16842
|
+
)
|
|
16843
|
+
});
|
|
16844
|
+
return enhancedReviews;
|
|
16626
16845
|
}
|
|
16627
16846
|
/**
|
|
16628
|
-
* Gets all reviews for a specific procedure
|
|
16847
|
+
* Gets all reviews for a specific procedure with enhanced entity names
|
|
16629
16848
|
* @param procedureId The ID of the procedure
|
|
16630
|
-
* @returns Array of reviews containing procedure reviews
|
|
16849
|
+
* @returns Array of reviews containing procedure reviews with clinic, practitioner, and procedure names
|
|
16631
16850
|
*/
|
|
16632
16851
|
async getReviewsByProcedure(procedureId) {
|
|
16852
|
+
console.log("\u{1F50D} ReviewService.getReviewsByProcedure - Querying for procedure:", procedureId);
|
|
16633
16853
|
const q = query31(
|
|
16634
16854
|
collection31(this.db, REVIEWS_COLLECTION),
|
|
16635
16855
|
where31("procedureReview.procedureId", "==", procedureId)
|
|
16636
16856
|
);
|
|
16637
16857
|
const snapshot = await getDocs31(q);
|
|
16638
|
-
|
|
16858
|
+
const reviews = snapshot.docs.map((doc38) => {
|
|
16859
|
+
const data = doc38.data();
|
|
16860
|
+
return { ...data, id: doc38.id };
|
|
16861
|
+
});
|
|
16862
|
+
console.log("\u{1F50D} ReviewService.getReviewsByProcedure - Found reviews before enhancement:", {
|
|
16863
|
+
procedureId,
|
|
16864
|
+
reviewCount: reviews.length,
|
|
16865
|
+
reviewIds: reviews.map((r) => r.id)
|
|
16866
|
+
});
|
|
16867
|
+
const enhancedReviews = await Promise.all(
|
|
16868
|
+
reviews.map(async (review) => {
|
|
16869
|
+
try {
|
|
16870
|
+
const appointmentDoc = await getDoc33(
|
|
16871
|
+
doc31(this.db, APPOINTMENTS_COLLECTION, review.appointmentId)
|
|
16872
|
+
);
|
|
16873
|
+
if (appointmentDoc.exists()) {
|
|
16874
|
+
const appointment = appointmentDoc.data();
|
|
16875
|
+
const enhancedReview = { ...review };
|
|
16876
|
+
if (enhancedReview.clinicReview && appointment.clinicInfo) {
|
|
16877
|
+
enhancedReview.clinicReview = {
|
|
16878
|
+
...enhancedReview.clinicReview,
|
|
16879
|
+
clinicName: appointment.clinicInfo.name
|
|
16880
|
+
};
|
|
16881
|
+
}
|
|
16882
|
+
if (enhancedReview.practitionerReview && appointment.practitionerInfo) {
|
|
16883
|
+
enhancedReview.practitionerReview = {
|
|
16884
|
+
...enhancedReview.practitionerReview,
|
|
16885
|
+
practitionerName: appointment.practitionerInfo.name
|
|
16886
|
+
};
|
|
16887
|
+
}
|
|
16888
|
+
if (enhancedReview.procedureReview && appointment.procedureInfo) {
|
|
16889
|
+
enhancedReview.procedureReview = {
|
|
16890
|
+
...enhancedReview.procedureReview,
|
|
16891
|
+
procedureName: appointment.procedureInfo.name
|
|
16892
|
+
};
|
|
16893
|
+
}
|
|
16894
|
+
if (appointment.patientInfo) {
|
|
16895
|
+
enhancedReview.patientName = appointment.patientInfo.fullName;
|
|
16896
|
+
}
|
|
16897
|
+
return enhancedReview;
|
|
16898
|
+
}
|
|
16899
|
+
return review;
|
|
16900
|
+
} catch (error) {
|
|
16901
|
+
console.warn(`Failed to enhance review ${review.id} with entity names:`, error);
|
|
16902
|
+
return review;
|
|
16903
|
+
}
|
|
16904
|
+
})
|
|
16905
|
+
);
|
|
16906
|
+
console.log("\u2705 ReviewService.getReviewsByProcedure - Enhanced reviews:", {
|
|
16907
|
+
procedureId,
|
|
16908
|
+
reviewCount: enhancedReviews.length,
|
|
16909
|
+
reviewIds: enhancedReviews.map((r) => r.id),
|
|
16910
|
+
hasEntityNames: enhancedReviews.some(
|
|
16911
|
+
(r) => {
|
|
16912
|
+
var _a, _b, _c;
|
|
16913
|
+
return ((_a = r.clinicReview) == null ? void 0 : _a.clinicName) || ((_b = r.practitionerReview) == null ? void 0 : _b.practitionerName) || ((_c = r.procedureReview) == null ? void 0 : _c.procedureName) || r.patientName;
|
|
16914
|
+
}
|
|
16915
|
+
)
|
|
16916
|
+
});
|
|
16917
|
+
return enhancedReviews;
|
|
16639
16918
|
}
|
|
16640
16919
|
/**
|
|
16641
16920
|
* Gets all reviews for a specific appointment
|
package/package.json
CHANGED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Reviews Service - Enhanced with Entity Names
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Reviews Service has been enhanced to automatically include entity names (clinic, practitioner, procedure, and patient names) in all review responses. This eliminates the need for frontend applications to make additional API calls to fetch entity details.
|
|
6
|
+
|
|
7
|
+
## Enhanced Methods
|
|
8
|
+
|
|
9
|
+
All review retrieval methods now include entity names from associated appointments:
|
|
10
|
+
|
|
11
|
+
### 1. `getReview(reviewId: string)`
|
|
12
|
+
- **Enhanced**: ✅ Returns single review with entity names
|
|
13
|
+
- **Entity Names**: Clinic name, practitioner name, procedure name, patient name
|
|
14
|
+
- **Source**: Fetched from associated appointment data
|
|
15
|
+
|
|
16
|
+
### 2. `getReviewsByPatient(patientId: string)`
|
|
17
|
+
- **Enhanced**: ✅ Returns patient reviews with entity names
|
|
18
|
+
- **Entity Names**: Clinic name, practitioner name, procedure name, patient name
|
|
19
|
+
- **Use Case**: Patient app - "My Reviews" screen
|
|
20
|
+
|
|
21
|
+
### 3. `getReviewsByPractitioner(practitionerId: string)`
|
|
22
|
+
- **Enhanced**: ✅ Returns practitioner reviews with entity names
|
|
23
|
+
- **Entity Names**: Clinic name, practitioner name, procedure name, patient name
|
|
24
|
+
- **Use Case**: Doctor app - "Reviews" screen
|
|
25
|
+
|
|
26
|
+
### 4. `getReviewsByClinic(clinicId: string)`
|
|
27
|
+
- **Enhanced**: ✅ Returns clinic reviews with entity names
|
|
28
|
+
- **Entity Names**: Clinic name, practitioner name, procedure name, patient name
|
|
29
|
+
- **Use Case**: Clinic dashboard - "Reviews" section
|
|
30
|
+
|
|
31
|
+
### 5. `getReviewsByProcedure(procedureId: string)`
|
|
32
|
+
- **Enhanced**: ✅ Returns procedure reviews with entity names
|
|
33
|
+
- **Entity Names**: Clinic name, practitioner name, procedure name, patient name
|
|
34
|
+
- **Use Case**: Procedure analytics and reporting
|
|
35
|
+
|
|
36
|
+
## Enhanced Review Structure
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
interface Review {
|
|
40
|
+
id: string;
|
|
41
|
+
appointmentId: string;
|
|
42
|
+
patientId: string;
|
|
43
|
+
patientName?: string; // 🆕 Enhanced field
|
|
44
|
+
createdAt: Date;
|
|
45
|
+
updatedAt: Date;
|
|
46
|
+
clinicReview?: {
|
|
47
|
+
// ... existing fields
|
|
48
|
+
clinicName?: string; // 🆕 Enhanced field
|
|
49
|
+
};
|
|
50
|
+
practitionerReview?: {
|
|
51
|
+
// ... existing fields
|
|
52
|
+
practitionerName?: string; // 🆕 Enhanced field
|
|
53
|
+
};
|
|
54
|
+
procedureReview?: {
|
|
55
|
+
// ... existing fields
|
|
56
|
+
procedureName?: string; // 🆕 Enhanced field
|
|
57
|
+
};
|
|
58
|
+
overallComment: string;
|
|
59
|
+
overallRating: number;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Data Sources
|
|
64
|
+
|
|
65
|
+
Entity names are fetched from the associated appointment's aggregated information:
|
|
66
|
+
|
|
67
|
+
- **Clinic Name**: `appointment.clinicInfo.name`
|
|
68
|
+
- **Practitioner Name**: `appointment.practitionerInfo.name`
|
|
69
|
+
- **Procedure Name**: `appointment.procedureInfo.name`
|
|
70
|
+
- **Patient Name**: `appointment.patientInfo.fullName`
|
|
71
|
+
|
|
72
|
+
## Error Handling
|
|
73
|
+
|
|
74
|
+
- If appointment is not found, review is returned without enhancement
|
|
75
|
+
- Individual enhancement failures are logged but don't break the entire operation
|
|
76
|
+
- Graceful fallback ensures API reliability
|
|
77
|
+
|
|
78
|
+
## Logging
|
|
79
|
+
|
|
80
|
+
Enhanced logging provides detailed information about:
|
|
81
|
+
- Query parameters
|
|
82
|
+
- Number of reviews found
|
|
83
|
+
- Enhancement success/failure
|
|
84
|
+
- Entity names availability
|
|
85
|
+
|
|
86
|
+
## Performance Considerations
|
|
87
|
+
|
|
88
|
+
- Each review requires one additional Firestore read for appointment data
|
|
89
|
+
- Enhancement is performed in parallel for multiple reviews
|
|
90
|
+
- Consider caching strategies for high-volume applications
|
|
91
|
+
|
|
92
|
+
## Migration Notes
|
|
93
|
+
|
|
94
|
+
- **Backward Compatible**: Existing code continues to work
|
|
95
|
+
- **Optional Fields**: All enhanced fields are optional
|
|
96
|
+
- **No Breaking Changes**: API signature remains the same
|
|
97
|
+
|
|
98
|
+
## Usage Examples
|
|
99
|
+
|
|
100
|
+
### Doctor App - Reviews Screen
|
|
101
|
+
```typescript
|
|
102
|
+
const reviews = await reviewService.getReviewsByPractitioner(practitionerId);
|
|
103
|
+
// Now includes practitioner names, clinic names, procedure names, and patient names
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Patient App - My Reviews
|
|
107
|
+
```typescript
|
|
108
|
+
const reviews = await reviewService.getReviewsByPatient(patientId);
|
|
109
|
+
// Now includes all entity names for better UX
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Clinic Dashboard
|
|
113
|
+
```typescript
|
|
114
|
+
const reviews = await reviewService.getReviewsByClinic(clinicId);
|
|
115
|
+
// Now includes practitioner and procedure names for each review
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Testing
|
|
119
|
+
|
|
120
|
+
All enhanced methods include comprehensive logging for debugging:
|
|
121
|
+
- Input parameters
|
|
122
|
+
- Query results
|
|
123
|
+
- Enhancement status
|
|
124
|
+
- Entity name availability
|
|
125
|
+
|
|
126
|
+
Monitor logs with:
|
|
127
|
+
```bash
|
|
128
|
+
firebase functions:log --only reviewService
|
|
129
|
+
```
|