@blackcode_sa/metaestetics-api 1.12.62 → 1.12.63
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 -2
- package/dist/admin/index.d.ts +4 -2
- package/dist/admin/index.js +4 -45
- package/dist/admin/index.mjs +4 -45
- package/dist/backoffice/index.d.mts +9 -0
- package/dist/backoffice/index.d.ts +9 -0
- package/dist/backoffice/index.js +11 -0
- package/dist/backoffice/index.mjs +11 -0
- package/dist/index.d.mts +99 -3
- package/dist/index.d.ts +99 -3
- package/dist/index.js +545 -281
- package/dist/index.mjs +867 -603
- package/package.json +119 -119
- package/src/__mocks__/firstore.ts +10 -10
- package/src/admin/aggregation/README.md +79 -79
- package/src/admin/aggregation/appointment/README.md +128 -128
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +1844 -1844
- package/src/admin/aggregation/appointment/index.ts +1 -1
- package/src/admin/aggregation/clinic/README.md +52 -52
- package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +703 -703
- package/src/admin/aggregation/clinic/index.ts +1 -1
- package/src/admin/aggregation/forms/README.md +13 -13
- package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +322 -322
- package/src/admin/aggregation/forms/index.ts +1 -1
- package/src/admin/aggregation/index.ts +8 -8
- package/src/admin/aggregation/patient/README.md +27 -27
- package/src/admin/aggregation/patient/index.ts +1 -1
- package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -141
- package/src/admin/aggregation/practitioner/README.md +42 -42
- package/src/admin/aggregation/practitioner/index.ts +1 -1
- package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -433
- package/src/admin/aggregation/practitioner-invite/index.ts +1 -1
- package/src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts +961 -961
- package/src/admin/aggregation/procedure/README.md +43 -43
- package/src/admin/aggregation/procedure/index.ts +1 -1
- package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +702 -702
- package/src/admin/aggregation/reviews/index.ts +1 -1
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +641 -689
- package/src/admin/booking/README.md +125 -125
- package/src/admin/booking/booking.admin.ts +1037 -1037
- package/src/admin/booking/booking.calculator.ts +712 -712
- package/src/admin/booking/booking.types.ts +59 -59
- package/src/admin/booking/index.ts +3 -3
- package/src/admin/booking/timezones-problem.md +185 -185
- package/src/admin/calendar/README.md +7 -7
- package/src/admin/calendar/calendar.admin.service.ts +345 -345
- package/src/admin/calendar/index.ts +1 -1
- package/src/admin/documentation-templates/document-manager.admin.ts +260 -260
- package/src/admin/documentation-templates/index.ts +1 -1
- package/src/admin/free-consultation/free-consultation-utils.admin.ts +148 -148
- package/src/admin/free-consultation/index.ts +1 -1
- package/src/admin/index.ts +75 -75
- package/src/admin/logger/index.ts +78 -78
- package/src/admin/mailing/README.md +95 -95
- package/src/admin/mailing/appointment/appointment.mailing.service.ts +732 -732
- package/src/admin/mailing/appointment/index.ts +1 -1
- package/src/admin/mailing/appointment/templates/patient/appointment-confirmed.html +40 -40
- package/src/admin/mailing/base.mailing.service.ts +208 -208
- package/src/admin/mailing/index.ts +3 -3
- package/src/admin/mailing/practitionerInvite/existing-practitioner-invite.mailing.ts +611 -611
- package/src/admin/mailing/practitionerInvite/index.ts +2 -2
- package/src/admin/mailing/practitionerInvite/practitionerInvite.mailing.ts +395 -395
- package/src/admin/mailing/practitionerInvite/templates/existing-practitioner-invitation.template.ts +155 -155
- package/src/admin/mailing/practitionerInvite/templates/invitation.template.ts +101 -101
- package/src/admin/mailing/practitionerInvite/templates/invite-accepted-notification.template.ts +228 -228
- package/src/admin/mailing/practitionerInvite/templates/invite-rejected-notification.template.ts +242 -242
- package/src/admin/notifications/index.ts +1 -1
- package/src/admin/notifications/notifications.admin.ts +710 -710
- package/src/admin/requirements/README.md +128 -128
- package/src/admin/requirements/index.ts +1 -1
- package/src/admin/requirements/patient-requirements.admin.service.ts +475 -475
- package/src/admin/users/index.ts +1 -1
- package/src/admin/users/user-profile.admin.ts +405 -405
- package/src/backoffice/constants/certification.constants.ts +13 -13
- package/src/backoffice/constants/index.ts +1 -1
- package/src/backoffice/errors/backoffice.errors.ts +181 -181
- package/src/backoffice/errors/index.ts +1 -1
- package/src/backoffice/expo-safe/README.md +26 -26
- package/src/backoffice/expo-safe/index.ts +41 -41
- package/src/backoffice/index.ts +5 -5
- package/src/backoffice/services/FIXES_README.md +102 -102
- package/src/backoffice/services/README.md +40 -40
- package/src/backoffice/services/brand.service.ts +256 -256
- package/src/backoffice/services/category.service.ts +318 -318
- package/src/backoffice/services/constants.service.ts +385 -385
- package/src/backoffice/services/documentation-template.service.ts +202 -202
- package/src/backoffice/services/index.ts +8 -8
- package/src/backoffice/services/migrate-products.ts +116 -116
- package/src/backoffice/services/product.service.ts +553 -553
- package/src/backoffice/services/requirement.service.ts +235 -235
- package/src/backoffice/services/subcategory.service.ts +395 -395
- package/src/backoffice/services/technology.service.ts +1083 -1070
- package/src/backoffice/types/README.md +12 -12
- package/src/backoffice/types/admin-constants.types.ts +69 -69
- package/src/backoffice/types/brand.types.ts +29 -29
- package/src/backoffice/types/category.types.ts +62 -62
- package/src/backoffice/types/documentation-templates.types.ts +28 -28
- package/src/backoffice/types/index.ts +10 -10
- package/src/backoffice/types/procedure-product.types.ts +38 -38
- package/src/backoffice/types/product.types.ts +240 -240
- package/src/backoffice/types/requirement.types.ts +63 -63
- package/src/backoffice/types/static/README.md +18 -18
- package/src/backoffice/types/static/blocking-condition.types.ts +21 -21
- package/src/backoffice/types/static/certification.types.ts +37 -37
- package/src/backoffice/types/static/contraindication.types.ts +19 -19
- package/src/backoffice/types/static/index.ts +6 -6
- package/src/backoffice/types/static/pricing.types.ts +16 -16
- package/src/backoffice/types/static/procedure-family.types.ts +14 -14
- package/src/backoffice/types/static/treatment-benefit.types.ts +22 -22
- package/src/backoffice/types/subcategory.types.ts +34 -34
- package/src/backoffice/types/technology.types.ts +163 -161
- package/src/backoffice/validations/index.ts +1 -1
- package/src/backoffice/validations/schemas.ts +164 -163
- package/src/config/__mocks__/firebase.ts +99 -99
- package/src/config/firebase.ts +78 -78
- package/src/config/index.ts +9 -9
- package/src/errors/auth.error.ts +6 -6
- package/src/errors/auth.errors.ts +200 -200
- package/src/errors/clinic.errors.ts +32 -32
- package/src/errors/firebase.errors.ts +47 -47
- package/src/errors/user.errors.ts +99 -99
- package/src/index.backup.ts +407 -407
- package/src/index.ts +6 -6
- package/src/locales/en.ts +31 -31
- package/src/recommender/admin/index.ts +1 -1
- package/src/recommender/admin/services/recommender.service.admin.ts +5 -5
- package/src/recommender/front/index.ts +1 -1
- package/src/recommender/front/services/onboarding.service.ts +5 -5
- package/src/recommender/front/services/recommender.service.ts +3 -3
- package/src/recommender/index.ts +1 -1
- package/src/services/PATIENTAUTH.MD +197 -197
- package/src/services/README.md +106 -106
- package/src/services/__tests__/auth/auth.mock.test.ts +17 -17
- package/src/services/__tests__/auth/auth.setup.ts +293 -293
- package/src/services/__tests__/auth.service.test.ts +346 -346
- package/src/services/__tests__/base.service.test.ts +77 -77
- package/src/services/__tests__/user.service.test.ts +528 -528
- package/src/services/appointment/README.md +17 -17
- package/src/services/appointment/appointment.service.ts +2505 -2082
- package/src/services/appointment/index.ts +1 -1
- package/src/services/appointment/utils/appointment.utils.ts +552 -552
- package/src/services/appointment/utils/extended-procedure.utils.ts +314 -314
- package/src/services/appointment/utils/form-initialization.utils.ts +225 -225
- package/src/services/appointment/utils/recommended-procedure.utils.ts +195 -195
- package/src/services/appointment/utils/zone-management.utils.ts +353 -353
- package/src/services/appointment/utils/zone-photo.utils.ts +152 -152
- package/src/services/auth/auth.service.ts +989 -989
- package/src/services/auth/auth.v2.service.ts +961 -961
- package/src/services/auth/index.ts +7 -7
- package/src/services/auth/utils/error.utils.ts +90 -90
- package/src/services/auth/utils/firebase.utils.ts +49 -49
- package/src/services/auth/utils/index.ts +21 -21
- package/src/services/auth/utils/practitioner.utils.ts +125 -125
- package/src/services/base.service.ts +41 -41
- package/src/services/calendar/calendar.service.ts +1077 -1077
- package/src/services/calendar/calendar.v2.service.ts +1683 -1683
- package/src/services/calendar/calendar.v3.service.ts +313 -313
- package/src/services/calendar/externalCalendar.service.ts +178 -178
- package/src/services/calendar/index.ts +5 -5
- package/src/services/calendar/synced-calendars.service.ts +743 -743
- package/src/services/calendar/utils/appointment.utils.ts +265 -265
- package/src/services/calendar/utils/calendar-event.utils.ts +646 -646
- package/src/services/calendar/utils/clinic.utils.ts +237 -237
- package/src/services/calendar/utils/docs.utils.ts +157 -157
- package/src/services/calendar/utils/google-calendar.utils.ts +697 -697
- package/src/services/calendar/utils/index.ts +8 -8
- package/src/services/calendar/utils/patient.utils.ts +198 -198
- package/src/services/calendar/utils/practitioner.utils.ts +221 -221
- package/src/services/calendar/utils/synced-calendar.utils.ts +472 -472
- package/src/services/clinic/README.md +204 -204
- package/src/services/clinic/__tests__/clinic-admin.service.test.ts +287 -287
- package/src/services/clinic/__tests__/clinic-group.service.test.ts +352 -352
- package/src/services/clinic/__tests__/clinic.service.test.ts +354 -354
- package/src/services/clinic/billing-transactions.service.ts +217 -217
- package/src/services/clinic/clinic-admin.service.ts +202 -202
- package/src/services/clinic/clinic-group.service.ts +310 -310
- package/src/services/clinic/clinic.service.ts +708 -708
- package/src/services/clinic/index.ts +5 -5
- package/src/services/clinic/practitioner-invite.service.ts +519 -519
- package/src/services/clinic/utils/admin.utils.ts +551 -551
- package/src/services/clinic/utils/clinic-group.utils.ts +646 -646
- package/src/services/clinic/utils/clinic.utils.ts +949 -949
- package/src/services/clinic/utils/filter.utils.d.ts +23 -23
- package/src/services/clinic/utils/filter.utils.ts +446 -446
- package/src/services/clinic/utils/index.ts +11 -11
- package/src/services/clinic/utils/photos.utils.ts +188 -188
- package/src/services/clinic/utils/search.utils.ts +84 -84
- package/src/services/clinic/utils/tag.utils.ts +124 -124
- package/src/services/documentation-templates/documentation-template.service.ts +537 -537
- package/src/services/documentation-templates/filled-document.service.ts +587 -587
- package/src/services/documentation-templates/index.ts +2 -2
- package/src/services/index.ts +13 -13
- package/src/services/media/index.ts +1 -1
- package/src/services/media/media.service.ts +418 -418
- package/src/services/notifications/__tests__/notification.service.test.ts +242 -242
- package/src/services/notifications/index.ts +1 -1
- package/src/services/notifications/notification.service.ts +215 -215
- package/src/services/patient/README.md +48 -48
- package/src/services/patient/To-Do.md +43 -43
- package/src/services/patient/__tests__/patient.service.test.ts +294 -294
- package/src/services/patient/index.ts +2 -2
- package/src/services/patient/patient.service.ts +883 -883
- package/src/services/patient/patientRequirements.service.ts +285 -285
- package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -176
- package/src/services/patient/utils/clinic.utils.ts +80 -80
- package/src/services/patient/utils/docs.utils.ts +142 -142
- package/src/services/patient/utils/index.ts +9 -9
- package/src/services/patient/utils/location.utils.ts +126 -126
- package/src/services/patient/utils/medical-stuff.utils.ts +143 -143
- package/src/services/patient/utils/medical.utils.ts +458 -458
- package/src/services/patient/utils/practitioner.utils.ts +260 -260
- package/src/services/patient/utils/profile.utils.ts +510 -510
- package/src/services/patient/utils/sensitive.utils.ts +260 -260
- package/src/services/patient/utils/token.utils.ts +211 -211
- package/src/services/practitioner/README.md +145 -145
- package/src/services/practitioner/index.ts +1 -1
- package/src/services/practitioner/practitioner.service.ts +1742 -1742
- package/src/services/procedure/README.md +163 -163
- package/src/services/procedure/index.ts +1 -1
- package/src/services/procedure/procedure.service.ts +1682 -1682
- package/src/services/reviews/index.ts +1 -1
- package/src/services/reviews/reviews.service.ts +636 -683
- package/src/services/user/index.ts +1 -1
- package/src/services/user/user.service.ts +489 -489
- package/src/services/user/user.v2.service.ts +466 -466
- package/src/types/appointment/index.ts +481 -453
- package/src/types/calendar/index.ts +258 -258
- package/src/types/calendar/synced-calendar.types.ts +66 -66
- package/src/types/clinic/index.ts +489 -489
- package/src/types/clinic/practitioner-invite.types.ts +91 -91
- package/src/types/clinic/preferences.types.ts +159 -159
- package/src/types/clinic/to-do +3 -3
- package/src/types/documentation-templates/index.ts +308 -308
- package/src/types/index.ts +44 -44
- package/src/types/notifications/README.md +77 -77
- package/src/types/notifications/index.ts +265 -265
- package/src/types/patient/aesthetic-analysis.types.ts +66 -66
- package/src/types/patient/allergies.ts +58 -58
- package/src/types/patient/index.ts +275 -273
- package/src/types/patient/medical-info.types.ts +152 -152
- package/src/types/patient/patient-requirements.ts +92 -92
- package/src/types/patient/token.types.ts +61 -61
- package/src/types/practitioner/index.ts +206 -206
- package/src/types/procedure/index.ts +181 -181
- package/src/types/profile/index.ts +39 -39
- package/src/types/reviews/index.ts +130 -132
- package/src/types/tz-lookup.d.ts +4 -4
- package/src/types/user/index.ts +38 -38
- package/src/utils/TIMESTAMPS.md +176 -176
- package/src/utils/TimestampUtils.ts +241 -241
- package/src/utils/index.ts +1 -1
- package/src/validations/appointment.schema.ts +574 -574
- package/src/validations/calendar.schema.ts +225 -225
- package/src/validations/clinic.schema.ts +493 -493
- package/src/validations/common.schema.ts +25 -25
- package/src/validations/documentation-templates/index.ts +1 -1
- package/src/validations/documentation-templates/template.schema.ts +220 -220
- package/src/validations/documentation-templates.schema.ts +10 -10
- package/src/validations/index.ts +20 -20
- package/src/validations/media.schema.ts +10 -10
- package/src/validations/notification.schema.ts +90 -90
- package/src/validations/patient/aesthetic-analysis.schema.ts +55 -55
- package/src/validations/patient/medical-info.schema.ts +125 -125
- package/src/validations/patient/patient-requirements.schema.ts +84 -84
- package/src/validations/patient/token.schema.ts +29 -29
- package/src/validations/patient.schema.ts +217 -216
- package/src/validations/practitioner.schema.ts +222 -222
- package/src/validations/procedure-product.schema.ts +41 -41
- package/src/validations/procedure.schema.ts +124 -124
- package/src/validations/profile-info.schema.ts +41 -41
- package/src/validations/reviews.schema.ts +189 -195
- package/src/validations/schemas.ts +104 -104
- package/src/validations/shared.schema.ts +78 -78
|
@@ -1,260 +1,260 @@
|
|
|
1
|
-
import {
|
|
2
|
-
collection,
|
|
3
|
-
query,
|
|
4
|
-
where,
|
|
5
|
-
getDocs,
|
|
6
|
-
Firestore,
|
|
7
|
-
limit,
|
|
8
|
-
startAfter,
|
|
9
|
-
doc,
|
|
10
|
-
getDoc,
|
|
11
|
-
QueryConstraint,
|
|
12
|
-
} from "firebase/firestore";
|
|
13
|
-
import {
|
|
14
|
-
PatientProfile,
|
|
15
|
-
PatientSensitiveInfo,
|
|
16
|
-
PatientProfileForDoctor,
|
|
17
|
-
PATIENTS_COLLECTION,
|
|
18
|
-
} from "../../../types/patient";
|
|
19
|
-
import { getSensitiveInfoDocRef } from "./docs.utils";
|
|
20
|
-
import {
|
|
21
|
-
Practitioner,
|
|
22
|
-
PRACTITIONERS_COLLECTION,
|
|
23
|
-
} from "../../../types/practitioner";
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Retrieves all patients associated with a specific practitioner with pagination support.
|
|
27
|
-
*
|
|
28
|
-
* @param {Firestore} db - Firestore instance
|
|
29
|
-
* @param {string} practitionerId - ID of the practitioner whose patients to retrieve
|
|
30
|
-
* @param {Object} options - Optional parameters for pagination
|
|
31
|
-
* @param {number} options.limit - Maximum number of profiles to return
|
|
32
|
-
* @param {string} options.startAfter - The ID of the document to start after (for pagination)
|
|
33
|
-
* @returns {Promise<PatientProfile[]>} A promise resolving to an array of patient profiles
|
|
34
|
-
*/
|
|
35
|
-
export const getPatientsByPractitionerUtil = async (
|
|
36
|
-
db: Firestore,
|
|
37
|
-
practitionerId: string,
|
|
38
|
-
options?: { limit?: number; startAfter?: string }
|
|
39
|
-
): Promise<PatientProfile[]> => {
|
|
40
|
-
try {
|
|
41
|
-
console.log(
|
|
42
|
-
`[getPatientsByPractitionerUtil] Fetching patients for practitioner ID: ${practitionerId} with options:`,
|
|
43
|
-
options
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
const patientsCollection = collection(db, PATIENTS_COLLECTION);
|
|
47
|
-
const constraints: QueryConstraint[] = [
|
|
48
|
-
where("doctorIds", "array-contains", practitionerId),
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
let q = query(patientsCollection, ...constraints);
|
|
52
|
-
|
|
53
|
-
// Apply pagination if needed
|
|
54
|
-
if (options?.limit) {
|
|
55
|
-
q = query(q, limit(options.limit));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// If startAfter is provided, get that document and use it for pagination
|
|
59
|
-
if (options?.startAfter) {
|
|
60
|
-
const startAfterDoc = await getDoc(
|
|
61
|
-
doc(db, PATIENTS_COLLECTION, options.startAfter)
|
|
62
|
-
);
|
|
63
|
-
if (startAfterDoc.exists()) {
|
|
64
|
-
q = query(q, startAfter(startAfterDoc));
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const patientsSnapshot = await getDocs(q);
|
|
69
|
-
|
|
70
|
-
const patients: PatientProfile[] = [];
|
|
71
|
-
patientsSnapshot.forEach((doc) => {
|
|
72
|
-
patients.push(doc.data() as PatientProfile);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
console.log(
|
|
76
|
-
`[getPatientsByPractitionerUtil] Found ${patients.length} patients for practitioner ID: ${practitionerId}`
|
|
77
|
-
);
|
|
78
|
-
return patients;
|
|
79
|
-
} catch (error) {
|
|
80
|
-
console.error(
|
|
81
|
-
`[getPatientsByPractitionerUtil] Error fetching patients for practitioner:`,
|
|
82
|
-
error
|
|
83
|
-
);
|
|
84
|
-
throw new Error(
|
|
85
|
-
`Failed to retrieve patients for practitioner: ${
|
|
86
|
-
error instanceof Error ? error.message : String(error)
|
|
87
|
-
}`
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Retrieves all patients associated with a specific practitioner with their sensitive information.
|
|
94
|
-
*
|
|
95
|
-
* @param {Firestore} db - Firestore instance
|
|
96
|
-
* @param {string} practitionerId - ID of the practitioner whose patients to retrieve
|
|
97
|
-
* @param {Object} options - Optional parameters for pagination
|
|
98
|
-
* @param {number} options.limit - Maximum number of profiles to return
|
|
99
|
-
* @param {string} options.startAfter - The ID of the document to start after (for pagination)
|
|
100
|
-
* @returns {Promise<PatientProfileForDoctor[]>} A promise resolving to an array of patient profiles with sensitive info
|
|
101
|
-
*/
|
|
102
|
-
export const getPatientsByPractitionerWithDetailsUtil = async (
|
|
103
|
-
db: Firestore,
|
|
104
|
-
practitionerId: string,
|
|
105
|
-
options?: { limit?: number; startAfter?: string }
|
|
106
|
-
): Promise<PatientProfileForDoctor[]> => {
|
|
107
|
-
try {
|
|
108
|
-
console.log(
|
|
109
|
-
`[getPatientsByPractitionerWithDetailsUtil] Fetching detailed patient profiles for practitioner ID: ${practitionerId} with options:`,
|
|
110
|
-
options
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
// First, get all patient profiles for this practitioner
|
|
114
|
-
const patientProfiles = await getPatientsByPractitionerUtil(
|
|
115
|
-
db,
|
|
116
|
-
practitionerId,
|
|
117
|
-
options
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
// Then, fetch sensitive info for each patient
|
|
121
|
-
const patientProfilesWithDetails: PatientProfileForDoctor[] =
|
|
122
|
-
await Promise.all(
|
|
123
|
-
patientProfiles.map(async (profile) => {
|
|
124
|
-
try {
|
|
125
|
-
const sensitiveInfoDoc = await getDoc(
|
|
126
|
-
getSensitiveInfoDocRef(db, profile.id)
|
|
127
|
-
);
|
|
128
|
-
const sensitiveInfo = sensitiveInfoDoc.exists()
|
|
129
|
-
? (sensitiveInfoDoc.data() as PatientSensitiveInfo)
|
|
130
|
-
: undefined;
|
|
131
|
-
|
|
132
|
-
return {
|
|
133
|
-
patientProfile: profile,
|
|
134
|
-
patientSensitiveInfo: sensitiveInfo,
|
|
135
|
-
};
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.error(
|
|
138
|
-
`[getPatientsByPractitionerWithDetailsUtil] Error fetching sensitive info for patient ${profile.id}:`,
|
|
139
|
-
error
|
|
140
|
-
);
|
|
141
|
-
// Return profile without sensitive info in case of error
|
|
142
|
-
return { patientProfile: profile };
|
|
143
|
-
}
|
|
144
|
-
})
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
console.log(
|
|
148
|
-
`[getPatientsByPractitionerWithDetailsUtil] Found ${patientProfilesWithDetails.length} detailed patient profiles for practitioner ID: ${practitionerId}`
|
|
149
|
-
);
|
|
150
|
-
return patientProfilesWithDetails;
|
|
151
|
-
} catch (error) {
|
|
152
|
-
console.error(
|
|
153
|
-
`[getPatientsByPractitionerWithDetailsUtil] Error fetching detailed patient profiles:`,
|
|
154
|
-
error
|
|
155
|
-
);
|
|
156
|
-
throw new Error(
|
|
157
|
-
`Failed to retrieve detailed patient profiles: ${
|
|
158
|
-
error instanceof Error ? error.message : String(error)
|
|
159
|
-
}`
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Retrieves a practitioner profile by ID
|
|
166
|
-
*
|
|
167
|
-
* @param {Firestore} db - Firestore instance
|
|
168
|
-
* @param {string} practitionerId - ID of the practitioner to retrieve
|
|
169
|
-
* @returns {Promise<Practitioner | null>} A promise resolving to the practitioner profile or null if not found
|
|
170
|
-
*/
|
|
171
|
-
export const getPractitionerProfile = async (
|
|
172
|
-
db: Firestore,
|
|
173
|
-
practitionerId: string
|
|
174
|
-
): Promise<Practitioner | null> => {
|
|
175
|
-
try {
|
|
176
|
-
console.log(
|
|
177
|
-
`[getPractitionerProfile] Fetching practitioner with ID: ${practitionerId}`
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
const practitionerRef = doc(db, PRACTITIONERS_COLLECTION, practitionerId);
|
|
181
|
-
const practitionerSnapshot = await getDoc(practitionerRef);
|
|
182
|
-
|
|
183
|
-
if (!practitionerSnapshot.exists()) {
|
|
184
|
-
console.log(
|
|
185
|
-
`[getPractitionerProfile] Practitioner with ID ${practitionerId} not found`
|
|
186
|
-
);
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const practitioner = practitionerSnapshot.data() as Practitioner;
|
|
191
|
-
console.log(
|
|
192
|
-
`[getPractitionerProfile] Successfully retrieved practitioner: ${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
return practitioner;
|
|
196
|
-
} catch (error) {
|
|
197
|
-
console.error(
|
|
198
|
-
`[getPractitionerProfile] Error fetching practitioner:`,
|
|
199
|
-
error
|
|
200
|
-
);
|
|
201
|
-
throw new Error(
|
|
202
|
-
`Failed to retrieve practitioner: ${
|
|
203
|
-
error instanceof Error ? error.message : String(error)
|
|
204
|
-
}`
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Retrieves a practitioner profile by user reference ID
|
|
211
|
-
*
|
|
212
|
-
* @param {Firestore} db - Firestore instance
|
|
213
|
-
* @param {string} userRef - Firebase Auth user ID reference
|
|
214
|
-
* @returns {Promise<Practitioner | null>} A promise resolving to the practitioner profile or null if not found
|
|
215
|
-
*/
|
|
216
|
-
export const getPractitionerProfileByUserRef = async (
|
|
217
|
-
db: Firestore,
|
|
218
|
-
userRef: string
|
|
219
|
-
): Promise<Practitioner | null> => {
|
|
220
|
-
try {
|
|
221
|
-
console.log(
|
|
222
|
-
`[getPractitionerProfileByUserRef] Fetching practitioner with userRef: ${userRef}`
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
const practitionersCollection = collection(db, PRACTITIONERS_COLLECTION);
|
|
226
|
-
const q = query(
|
|
227
|
-
practitionersCollection,
|
|
228
|
-
where("userRef", "==", userRef),
|
|
229
|
-
limit(1)
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
const querySnapshot = await getDocs(q);
|
|
233
|
-
|
|
234
|
-
if (querySnapshot.empty) {
|
|
235
|
-
console.log(
|
|
236
|
-
`[getPractitionerProfileByUserRef] No practitioner found with userRef: ${userRef}`
|
|
237
|
-
);
|
|
238
|
-
return null;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
const practitionerDoc = querySnapshot.docs[0];
|
|
242
|
-
const practitioner = practitionerDoc.data() as Practitioner;
|
|
243
|
-
|
|
244
|
-
console.log(
|
|
245
|
-
`[getPractitionerProfileByUserRef] Successfully retrieved practitioner: ${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
return practitioner;
|
|
249
|
-
} catch (error) {
|
|
250
|
-
console.error(
|
|
251
|
-
`[getPractitionerProfileByUserRef] Error fetching practitioner:`,
|
|
252
|
-
error
|
|
253
|
-
);
|
|
254
|
-
throw new Error(
|
|
255
|
-
`Failed to retrieve practitioner by userRef: ${
|
|
256
|
-
error instanceof Error ? error.message : String(error)
|
|
257
|
-
}`
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
collection,
|
|
3
|
+
query,
|
|
4
|
+
where,
|
|
5
|
+
getDocs,
|
|
6
|
+
Firestore,
|
|
7
|
+
limit,
|
|
8
|
+
startAfter,
|
|
9
|
+
doc,
|
|
10
|
+
getDoc,
|
|
11
|
+
QueryConstraint,
|
|
12
|
+
} from "firebase/firestore";
|
|
13
|
+
import {
|
|
14
|
+
PatientProfile,
|
|
15
|
+
PatientSensitiveInfo,
|
|
16
|
+
PatientProfileForDoctor,
|
|
17
|
+
PATIENTS_COLLECTION,
|
|
18
|
+
} from "../../../types/patient";
|
|
19
|
+
import { getSensitiveInfoDocRef } from "./docs.utils";
|
|
20
|
+
import {
|
|
21
|
+
Practitioner,
|
|
22
|
+
PRACTITIONERS_COLLECTION,
|
|
23
|
+
} from "../../../types/practitioner";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Retrieves all patients associated with a specific practitioner with pagination support.
|
|
27
|
+
*
|
|
28
|
+
* @param {Firestore} db - Firestore instance
|
|
29
|
+
* @param {string} practitionerId - ID of the practitioner whose patients to retrieve
|
|
30
|
+
* @param {Object} options - Optional parameters for pagination
|
|
31
|
+
* @param {number} options.limit - Maximum number of profiles to return
|
|
32
|
+
* @param {string} options.startAfter - The ID of the document to start after (for pagination)
|
|
33
|
+
* @returns {Promise<PatientProfile[]>} A promise resolving to an array of patient profiles
|
|
34
|
+
*/
|
|
35
|
+
export const getPatientsByPractitionerUtil = async (
|
|
36
|
+
db: Firestore,
|
|
37
|
+
practitionerId: string,
|
|
38
|
+
options?: { limit?: number; startAfter?: string }
|
|
39
|
+
): Promise<PatientProfile[]> => {
|
|
40
|
+
try {
|
|
41
|
+
console.log(
|
|
42
|
+
`[getPatientsByPractitionerUtil] Fetching patients for practitioner ID: ${practitionerId} with options:`,
|
|
43
|
+
options
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const patientsCollection = collection(db, PATIENTS_COLLECTION);
|
|
47
|
+
const constraints: QueryConstraint[] = [
|
|
48
|
+
where("doctorIds", "array-contains", practitionerId),
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
let q = query(patientsCollection, ...constraints);
|
|
52
|
+
|
|
53
|
+
// Apply pagination if needed
|
|
54
|
+
if (options?.limit) {
|
|
55
|
+
q = query(q, limit(options.limit));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// If startAfter is provided, get that document and use it for pagination
|
|
59
|
+
if (options?.startAfter) {
|
|
60
|
+
const startAfterDoc = await getDoc(
|
|
61
|
+
doc(db, PATIENTS_COLLECTION, options.startAfter)
|
|
62
|
+
);
|
|
63
|
+
if (startAfterDoc.exists()) {
|
|
64
|
+
q = query(q, startAfter(startAfterDoc));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const patientsSnapshot = await getDocs(q);
|
|
69
|
+
|
|
70
|
+
const patients: PatientProfile[] = [];
|
|
71
|
+
patientsSnapshot.forEach((doc) => {
|
|
72
|
+
patients.push(doc.data() as PatientProfile);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
console.log(
|
|
76
|
+
`[getPatientsByPractitionerUtil] Found ${patients.length} patients for practitioner ID: ${practitionerId}`
|
|
77
|
+
);
|
|
78
|
+
return patients;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error(
|
|
81
|
+
`[getPatientsByPractitionerUtil] Error fetching patients for practitioner:`,
|
|
82
|
+
error
|
|
83
|
+
);
|
|
84
|
+
throw new Error(
|
|
85
|
+
`Failed to retrieve patients for practitioner: ${
|
|
86
|
+
error instanceof Error ? error.message : String(error)
|
|
87
|
+
}`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Retrieves all patients associated with a specific practitioner with their sensitive information.
|
|
94
|
+
*
|
|
95
|
+
* @param {Firestore} db - Firestore instance
|
|
96
|
+
* @param {string} practitionerId - ID of the practitioner whose patients to retrieve
|
|
97
|
+
* @param {Object} options - Optional parameters for pagination
|
|
98
|
+
* @param {number} options.limit - Maximum number of profiles to return
|
|
99
|
+
* @param {string} options.startAfter - The ID of the document to start after (for pagination)
|
|
100
|
+
* @returns {Promise<PatientProfileForDoctor[]>} A promise resolving to an array of patient profiles with sensitive info
|
|
101
|
+
*/
|
|
102
|
+
export const getPatientsByPractitionerWithDetailsUtil = async (
|
|
103
|
+
db: Firestore,
|
|
104
|
+
practitionerId: string,
|
|
105
|
+
options?: { limit?: number; startAfter?: string }
|
|
106
|
+
): Promise<PatientProfileForDoctor[]> => {
|
|
107
|
+
try {
|
|
108
|
+
console.log(
|
|
109
|
+
`[getPatientsByPractitionerWithDetailsUtil] Fetching detailed patient profiles for practitioner ID: ${practitionerId} with options:`,
|
|
110
|
+
options
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
// First, get all patient profiles for this practitioner
|
|
114
|
+
const patientProfiles = await getPatientsByPractitionerUtil(
|
|
115
|
+
db,
|
|
116
|
+
practitionerId,
|
|
117
|
+
options
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Then, fetch sensitive info for each patient
|
|
121
|
+
const patientProfilesWithDetails: PatientProfileForDoctor[] =
|
|
122
|
+
await Promise.all(
|
|
123
|
+
patientProfiles.map(async (profile) => {
|
|
124
|
+
try {
|
|
125
|
+
const sensitiveInfoDoc = await getDoc(
|
|
126
|
+
getSensitiveInfoDocRef(db, profile.id)
|
|
127
|
+
);
|
|
128
|
+
const sensitiveInfo = sensitiveInfoDoc.exists()
|
|
129
|
+
? (sensitiveInfoDoc.data() as PatientSensitiveInfo)
|
|
130
|
+
: undefined;
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
patientProfile: profile,
|
|
134
|
+
patientSensitiveInfo: sensitiveInfo,
|
|
135
|
+
};
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error(
|
|
138
|
+
`[getPatientsByPractitionerWithDetailsUtil] Error fetching sensitive info for patient ${profile.id}:`,
|
|
139
|
+
error
|
|
140
|
+
);
|
|
141
|
+
// Return profile without sensitive info in case of error
|
|
142
|
+
return { patientProfile: profile };
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
console.log(
|
|
148
|
+
`[getPatientsByPractitionerWithDetailsUtil] Found ${patientProfilesWithDetails.length} detailed patient profiles for practitioner ID: ${practitionerId}`
|
|
149
|
+
);
|
|
150
|
+
return patientProfilesWithDetails;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error(
|
|
153
|
+
`[getPatientsByPractitionerWithDetailsUtil] Error fetching detailed patient profiles:`,
|
|
154
|
+
error
|
|
155
|
+
);
|
|
156
|
+
throw new Error(
|
|
157
|
+
`Failed to retrieve detailed patient profiles: ${
|
|
158
|
+
error instanceof Error ? error.message : String(error)
|
|
159
|
+
}`
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Retrieves a practitioner profile by ID
|
|
166
|
+
*
|
|
167
|
+
* @param {Firestore} db - Firestore instance
|
|
168
|
+
* @param {string} practitionerId - ID of the practitioner to retrieve
|
|
169
|
+
* @returns {Promise<Practitioner | null>} A promise resolving to the practitioner profile or null if not found
|
|
170
|
+
*/
|
|
171
|
+
export const getPractitionerProfile = async (
|
|
172
|
+
db: Firestore,
|
|
173
|
+
practitionerId: string
|
|
174
|
+
): Promise<Practitioner | null> => {
|
|
175
|
+
try {
|
|
176
|
+
console.log(
|
|
177
|
+
`[getPractitionerProfile] Fetching practitioner with ID: ${practitionerId}`
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
const practitionerRef = doc(db, PRACTITIONERS_COLLECTION, practitionerId);
|
|
181
|
+
const practitionerSnapshot = await getDoc(practitionerRef);
|
|
182
|
+
|
|
183
|
+
if (!practitionerSnapshot.exists()) {
|
|
184
|
+
console.log(
|
|
185
|
+
`[getPractitionerProfile] Practitioner with ID ${practitionerId} not found`
|
|
186
|
+
);
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const practitioner = practitionerSnapshot.data() as Practitioner;
|
|
191
|
+
console.log(
|
|
192
|
+
`[getPractitionerProfile] Successfully retrieved practitioner: ${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
return practitioner;
|
|
196
|
+
} catch (error) {
|
|
197
|
+
console.error(
|
|
198
|
+
`[getPractitionerProfile] Error fetching practitioner:`,
|
|
199
|
+
error
|
|
200
|
+
);
|
|
201
|
+
throw new Error(
|
|
202
|
+
`Failed to retrieve practitioner: ${
|
|
203
|
+
error instanceof Error ? error.message : String(error)
|
|
204
|
+
}`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Retrieves a practitioner profile by user reference ID
|
|
211
|
+
*
|
|
212
|
+
* @param {Firestore} db - Firestore instance
|
|
213
|
+
* @param {string} userRef - Firebase Auth user ID reference
|
|
214
|
+
* @returns {Promise<Practitioner | null>} A promise resolving to the practitioner profile or null if not found
|
|
215
|
+
*/
|
|
216
|
+
export const getPractitionerProfileByUserRef = async (
|
|
217
|
+
db: Firestore,
|
|
218
|
+
userRef: string
|
|
219
|
+
): Promise<Practitioner | null> => {
|
|
220
|
+
try {
|
|
221
|
+
console.log(
|
|
222
|
+
`[getPractitionerProfileByUserRef] Fetching practitioner with userRef: ${userRef}`
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
const practitionersCollection = collection(db, PRACTITIONERS_COLLECTION);
|
|
226
|
+
const q = query(
|
|
227
|
+
practitionersCollection,
|
|
228
|
+
where("userRef", "==", userRef),
|
|
229
|
+
limit(1)
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const querySnapshot = await getDocs(q);
|
|
233
|
+
|
|
234
|
+
if (querySnapshot.empty) {
|
|
235
|
+
console.log(
|
|
236
|
+
`[getPractitionerProfileByUserRef] No practitioner found with userRef: ${userRef}`
|
|
237
|
+
);
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const practitionerDoc = querySnapshot.docs[0];
|
|
242
|
+
const practitioner = practitionerDoc.data() as Practitioner;
|
|
243
|
+
|
|
244
|
+
console.log(
|
|
245
|
+
`[getPractitionerProfileByUserRef] Successfully retrieved practitioner: ${practitioner.basicInfo.firstName} ${practitioner.basicInfo.lastName}`
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
return practitioner;
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.error(
|
|
251
|
+
`[getPractitionerProfileByUserRef] Error fetching practitioner:`,
|
|
252
|
+
error
|
|
253
|
+
);
|
|
254
|
+
throw new Error(
|
|
255
|
+
`Failed to retrieve practitioner by userRef: ${
|
|
256
|
+
error instanceof Error ? error.message : String(error)
|
|
257
|
+
}`
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
};
|