@blackcode_sa/metaestetics-api 1.13.3 → 1.13.5
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 +15 -28
- package/dist/admin/index.d.ts +15 -28
- package/dist/index.d.mts +18 -30
- package/dist/index.d.ts +18 -30
- package/dist/index.js +11 -3
- package/dist/index.mjs +11 -3
- package/package.json +121 -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 +1984 -1984
- 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 +689 -689
- package/src/admin/analytics/analytics.admin.service.ts +278 -278
- package/src/admin/analytics/index.ts +2 -2
- 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 +81 -81
- 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 +57 -57
- package/src/backoffice/services/analytics.service.proposal.md +863 -863
- package/src/backoffice/services/analytics.service.summary.md +143 -143
- package/src/backoffice/services/brand.service.ts +256 -256
- package/src/backoffice/services/category.service.ts +384 -384
- 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 +10 -10
- 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 +461 -461
- package/src/backoffice/services/technology.service.ts +1151 -1151
- 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 +67 -67
- 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 +168 -168
- package/src/backoffice/validations/index.ts +1 -1
- package/src/backoffice/validations/schemas.ts +164 -164
- 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/analytics/ARCHITECTURE.md +199 -199
- package/src/services/analytics/CLOUD_FUNCTIONS.md +225 -225
- package/src/services/analytics/GROUPED_ANALYTICS.md +501 -501
- package/src/services/analytics/QUICK_START.md +393 -393
- package/src/services/analytics/README.md +304 -304
- package/src/services/analytics/SUMMARY.md +141 -141
- package/src/services/analytics/TRENDS.md +380 -380
- package/src/services/analytics/USAGE_GUIDE.md +518 -518
- package/src/services/analytics/analytics-cloud.service.ts +222 -222
- package/src/services/analytics/analytics.service.ts +2142 -2142
- package/src/services/analytics/index.ts +4 -4
- package/src/services/analytics/review-analytics.service.ts +941 -941
- package/src/services/analytics/utils/appointment-filtering.utils.ts +138 -138
- package/src/services/analytics/utils/cost-calculation.utils.ts +182 -182
- package/src/services/analytics/utils/grouping.utils.ts +434 -434
- package/src/services/analytics/utils/stored-analytics.utils.ts +347 -347
- package/src/services/analytics/utils/time-calculation.utils.ts +186 -186
- package/src/services/analytics/utils/trend-calculation.utils.ts +200 -200
- package/src/services/appointment/README.md +17 -17
- package/src/services/appointment/appointment.service.ts +2558 -2558
- 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 +14 -14
- 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 +2200 -2191
- package/src/services/reviews/index.ts +1 -1
- package/src/services/reviews/reviews.service.ts +734 -734
- 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/analytics/analytics.types.ts +597 -597
- package/src/types/analytics/grouped-analytics.types.ts +173 -173
- package/src/types/analytics/index.ts +4 -4
- package/src/types/analytics/stored-analytics.types.ts +137 -137
- package/src/types/appointment/index.ts +480 -480
- package/src/types/calendar/index.ts +258 -258
- package/src/types/calendar/synced-calendar.types.ts +66 -66
- package/src/types/clinic/index.ts +498 -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 +47 -47
- package/src/types/notifications/README.md +77 -77
- package/src/types/notifications/index.ts +286 -286
- 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 -275
- 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 +132 -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 +494 -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 -217
- 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 +195 -195
- package/src/validations/schemas.ts +104 -104
- package/src/validations/shared.schema.ts +78 -78
|
@@ -1,142 +1,142 @@
|
|
|
1
|
-
import {
|
|
2
|
-
doc,
|
|
3
|
-
collection,
|
|
4
|
-
query,
|
|
5
|
-
where,
|
|
6
|
-
getDocs,
|
|
7
|
-
Firestore,
|
|
8
|
-
getDoc,
|
|
9
|
-
setDoc,
|
|
10
|
-
serverTimestamp,
|
|
11
|
-
} from "firebase/firestore";
|
|
12
|
-
import {
|
|
13
|
-
PATIENTS_COLLECTION,
|
|
14
|
-
PATIENT_SENSITIVE_INFO_COLLECTION,
|
|
15
|
-
PATIENT_LOCATION_INFO_COLLECTION,
|
|
16
|
-
PATIENT_MEDICAL_INFO_COLLECTION,
|
|
17
|
-
} from "../../../types/patient";
|
|
18
|
-
import { createSensitiveInfoUtil } from "./sensitive.utils";
|
|
19
|
-
import { Gender } from "../../../types/patient";
|
|
20
|
-
|
|
21
|
-
// Osnovne reference
|
|
22
|
-
export const getPatientDocRef = (db: Firestore, patientId: string) => {
|
|
23
|
-
return doc(db, PATIENTS_COLLECTION, patientId);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const getPatientDocRefByUserRef = async (
|
|
27
|
-
db: Firestore,
|
|
28
|
-
userRef: string
|
|
29
|
-
) => {
|
|
30
|
-
const patientsRef = collection(db, PATIENTS_COLLECTION);
|
|
31
|
-
const q = query(patientsRef, where("userRef", "==", userRef));
|
|
32
|
-
const querySnapshot = await getDocs(q);
|
|
33
|
-
|
|
34
|
-
if (querySnapshot.empty) {
|
|
35
|
-
throw new Error("Patient profile not found");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return doc(db, PATIENTS_COLLECTION, querySnapshot.docs[0].id);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// Reference za subkolekcije
|
|
42
|
-
export const getSensitiveInfoDocRef = (db: Firestore, patientId: string) => {
|
|
43
|
-
const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_SENSITIVE_INFO_COLLECTION}/${patientId}`;
|
|
44
|
-
console.log(`[getSensitiveInfoDocRef] Creating reference with path: ${path}`);
|
|
45
|
-
return doc(
|
|
46
|
-
db,
|
|
47
|
-
PATIENTS_COLLECTION,
|
|
48
|
-
patientId,
|
|
49
|
-
PATIENT_SENSITIVE_INFO_COLLECTION,
|
|
50
|
-
patientId
|
|
51
|
-
);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const getLocationInfoDocRef = (db: Firestore, patientId: string) => {
|
|
55
|
-
const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_LOCATION_INFO_COLLECTION}/${patientId}`;
|
|
56
|
-
console.log(`[getLocationInfoDocRef] Creating reference with path: ${path}`);
|
|
57
|
-
return doc(
|
|
58
|
-
db,
|
|
59
|
-
PATIENTS_COLLECTION,
|
|
60
|
-
patientId,
|
|
61
|
-
PATIENT_LOCATION_INFO_COLLECTION,
|
|
62
|
-
patientId
|
|
63
|
-
);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export const getMedicalInfoDocRef = (db: Firestore, patientId: string) => {
|
|
67
|
-
const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_MEDICAL_INFO_COLLECTION}/${patientId}`;
|
|
68
|
-
console.log(`[getMedicalInfoDocRef] Creating reference with path: ${path}`);
|
|
69
|
-
return doc(
|
|
70
|
-
db,
|
|
71
|
-
PATIENTS_COLLECTION,
|
|
72
|
-
patientId,
|
|
73
|
-
PATIENT_MEDICAL_INFO_COLLECTION,
|
|
74
|
-
patientId
|
|
75
|
-
);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
// Funkcija za inicijalizaciju dokumenta sa osetljivim informacijama ako ne postoji
|
|
79
|
-
export const initSensitiveInfoDocIfNotExists = async (
|
|
80
|
-
db: Firestore,
|
|
81
|
-
patientId: string,
|
|
82
|
-
userRef: string
|
|
83
|
-
) => {
|
|
84
|
-
console.log(
|
|
85
|
-
`[initSensitiveInfoDocIfNotExists] Starting for patientId: ${patientId}, userRef: ${userRef}`
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
const sensitiveInfoRef = getSensitiveInfoDocRef(db, patientId);
|
|
90
|
-
console.log(
|
|
91
|
-
`[initSensitiveInfoDocIfNotExists] Got document reference: ${sensitiveInfoRef.path}`
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
const sensitiveDoc = await getDoc(sensitiveInfoRef);
|
|
95
|
-
console.log(
|
|
96
|
-
`[initSensitiveInfoDocIfNotExists] Document exists: ${sensitiveDoc.exists()}`
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
if (!sensitiveDoc.exists()) {
|
|
100
|
-
// Inicijalizacija sa podrazumevanim vrednostima prema strukturi iz index.ts
|
|
101
|
-
const defaultSensitiveInfo = {
|
|
102
|
-
patientId,
|
|
103
|
-
userRef,
|
|
104
|
-
firstName: "Name",
|
|
105
|
-
lastName: "Surname",
|
|
106
|
-
dateOfBirth: null, // Koristimo serverTimestamp kao placeholder
|
|
107
|
-
gender: Gender.PREFER_NOT_TO_SAY, // Koristimo podrazumevanu vrednost iz Gender enuma
|
|
108
|
-
phoneNumber: "",
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
console.log(
|
|
112
|
-
`[initSensitiveInfoDocIfNotExists] Creating new document with data:`,
|
|
113
|
-
JSON.stringify(defaultSensitiveInfo, (key, value) =>
|
|
114
|
-
value &&
|
|
115
|
-
typeof value === "object" &&
|
|
116
|
-
value.constructor &&
|
|
117
|
-
value.constructor.name === "Object"
|
|
118
|
-
? "[serverTimestamp]"
|
|
119
|
-
: value
|
|
120
|
-
)
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
await createSensitiveInfoUtil(db, defaultSensitiveInfo, userRef);
|
|
124
|
-
|
|
125
|
-
// Verify document was created
|
|
126
|
-
const verifyDoc = await getDoc(sensitiveInfoRef);
|
|
127
|
-
console.log(
|
|
128
|
-
`[initSensitiveInfoDocIfNotExists] Verification - document exists: ${verifyDoc.exists()}`
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
return false; // Dokument nije postojao, kreiran je novi
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
console.log(
|
|
135
|
-
`[initSensitiveInfoDocIfNotExists] Document already exists, no action taken`
|
|
136
|
-
);
|
|
137
|
-
return true; // Dokument već postoji
|
|
138
|
-
} catch (error) {
|
|
139
|
-
console.error(`[initSensitiveInfoDocIfNotExists] Error:`, error);
|
|
140
|
-
throw error;
|
|
141
|
-
}
|
|
142
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
doc,
|
|
3
|
+
collection,
|
|
4
|
+
query,
|
|
5
|
+
where,
|
|
6
|
+
getDocs,
|
|
7
|
+
Firestore,
|
|
8
|
+
getDoc,
|
|
9
|
+
setDoc,
|
|
10
|
+
serverTimestamp,
|
|
11
|
+
} from "firebase/firestore";
|
|
12
|
+
import {
|
|
13
|
+
PATIENTS_COLLECTION,
|
|
14
|
+
PATIENT_SENSITIVE_INFO_COLLECTION,
|
|
15
|
+
PATIENT_LOCATION_INFO_COLLECTION,
|
|
16
|
+
PATIENT_MEDICAL_INFO_COLLECTION,
|
|
17
|
+
} from "../../../types/patient";
|
|
18
|
+
import { createSensitiveInfoUtil } from "./sensitive.utils";
|
|
19
|
+
import { Gender } from "../../../types/patient";
|
|
20
|
+
|
|
21
|
+
// Osnovne reference
|
|
22
|
+
export const getPatientDocRef = (db: Firestore, patientId: string) => {
|
|
23
|
+
return doc(db, PATIENTS_COLLECTION, patientId);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const getPatientDocRefByUserRef = async (
|
|
27
|
+
db: Firestore,
|
|
28
|
+
userRef: string
|
|
29
|
+
) => {
|
|
30
|
+
const patientsRef = collection(db, PATIENTS_COLLECTION);
|
|
31
|
+
const q = query(patientsRef, where("userRef", "==", userRef));
|
|
32
|
+
const querySnapshot = await getDocs(q);
|
|
33
|
+
|
|
34
|
+
if (querySnapshot.empty) {
|
|
35
|
+
throw new Error("Patient profile not found");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return doc(db, PATIENTS_COLLECTION, querySnapshot.docs[0].id);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Reference za subkolekcije
|
|
42
|
+
export const getSensitiveInfoDocRef = (db: Firestore, patientId: string) => {
|
|
43
|
+
const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_SENSITIVE_INFO_COLLECTION}/${patientId}`;
|
|
44
|
+
console.log(`[getSensitiveInfoDocRef] Creating reference with path: ${path}`);
|
|
45
|
+
return doc(
|
|
46
|
+
db,
|
|
47
|
+
PATIENTS_COLLECTION,
|
|
48
|
+
patientId,
|
|
49
|
+
PATIENT_SENSITIVE_INFO_COLLECTION,
|
|
50
|
+
patientId
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const getLocationInfoDocRef = (db: Firestore, patientId: string) => {
|
|
55
|
+
const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_LOCATION_INFO_COLLECTION}/${patientId}`;
|
|
56
|
+
console.log(`[getLocationInfoDocRef] Creating reference with path: ${path}`);
|
|
57
|
+
return doc(
|
|
58
|
+
db,
|
|
59
|
+
PATIENTS_COLLECTION,
|
|
60
|
+
patientId,
|
|
61
|
+
PATIENT_LOCATION_INFO_COLLECTION,
|
|
62
|
+
patientId
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const getMedicalInfoDocRef = (db: Firestore, patientId: string) => {
|
|
67
|
+
const path = `${PATIENTS_COLLECTION}/${patientId}/${PATIENT_MEDICAL_INFO_COLLECTION}/${patientId}`;
|
|
68
|
+
console.log(`[getMedicalInfoDocRef] Creating reference with path: ${path}`);
|
|
69
|
+
return doc(
|
|
70
|
+
db,
|
|
71
|
+
PATIENTS_COLLECTION,
|
|
72
|
+
patientId,
|
|
73
|
+
PATIENT_MEDICAL_INFO_COLLECTION,
|
|
74
|
+
patientId
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Funkcija za inicijalizaciju dokumenta sa osetljivim informacijama ako ne postoji
|
|
79
|
+
export const initSensitiveInfoDocIfNotExists = async (
|
|
80
|
+
db: Firestore,
|
|
81
|
+
patientId: string,
|
|
82
|
+
userRef: string
|
|
83
|
+
) => {
|
|
84
|
+
console.log(
|
|
85
|
+
`[initSensitiveInfoDocIfNotExists] Starting for patientId: ${patientId}, userRef: ${userRef}`
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const sensitiveInfoRef = getSensitiveInfoDocRef(db, patientId);
|
|
90
|
+
console.log(
|
|
91
|
+
`[initSensitiveInfoDocIfNotExists] Got document reference: ${sensitiveInfoRef.path}`
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const sensitiveDoc = await getDoc(sensitiveInfoRef);
|
|
95
|
+
console.log(
|
|
96
|
+
`[initSensitiveInfoDocIfNotExists] Document exists: ${sensitiveDoc.exists()}`
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
if (!sensitiveDoc.exists()) {
|
|
100
|
+
// Inicijalizacija sa podrazumevanim vrednostima prema strukturi iz index.ts
|
|
101
|
+
const defaultSensitiveInfo = {
|
|
102
|
+
patientId,
|
|
103
|
+
userRef,
|
|
104
|
+
firstName: "Name",
|
|
105
|
+
lastName: "Surname",
|
|
106
|
+
dateOfBirth: null, // Koristimo serverTimestamp kao placeholder
|
|
107
|
+
gender: Gender.PREFER_NOT_TO_SAY, // Koristimo podrazumevanu vrednost iz Gender enuma
|
|
108
|
+
phoneNumber: "",
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
console.log(
|
|
112
|
+
`[initSensitiveInfoDocIfNotExists] Creating new document with data:`,
|
|
113
|
+
JSON.stringify(defaultSensitiveInfo, (key, value) =>
|
|
114
|
+
value &&
|
|
115
|
+
typeof value === "object" &&
|
|
116
|
+
value.constructor &&
|
|
117
|
+
value.constructor.name === "Object"
|
|
118
|
+
? "[serverTimestamp]"
|
|
119
|
+
: value
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
await createSensitiveInfoUtil(db, defaultSensitiveInfo, userRef);
|
|
124
|
+
|
|
125
|
+
// Verify document was created
|
|
126
|
+
const verifyDoc = await getDoc(sensitiveInfoRef);
|
|
127
|
+
console.log(
|
|
128
|
+
`[initSensitiveInfoDocIfNotExists] Verification - document exists: ${verifyDoc.exists()}`
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
return false; // Dokument nije postojao, kreiran je novi
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
console.log(
|
|
135
|
+
`[initSensitiveInfoDocIfNotExists] Document already exists, no action taken`
|
|
136
|
+
);
|
|
137
|
+
return true; // Dokument već postoji
|
|
138
|
+
} catch (error) {
|
|
139
|
+
console.error(`[initSensitiveInfoDocIfNotExists] Error:`, error);
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export * from "./clinic.utils";
|
|
2
|
-
export * from "./docs.utils";
|
|
3
|
-
export * from "./location.utils";
|
|
4
|
-
export * from "./medical-stuff.utils";
|
|
5
|
-
export * from "./medical.utils";
|
|
6
|
-
export * from "./practitioner.utils";
|
|
7
|
-
export * from "./profile.utils";
|
|
8
|
-
export * from "./sensitive.utils";
|
|
9
|
-
export * from "./token.utils";
|
|
1
|
+
export * from "./clinic.utils";
|
|
2
|
+
export * from "./docs.utils";
|
|
3
|
+
export * from "./location.utils";
|
|
4
|
+
export * from "./medical-stuff.utils";
|
|
5
|
+
export * from "./medical.utils";
|
|
6
|
+
export * from "./practitioner.utils";
|
|
7
|
+
export * from "./profile.utils";
|
|
8
|
+
export * from "./sensitive.utils";
|
|
9
|
+
export * from "./token.utils";
|
|
@@ -1,126 +1,126 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getDoc,
|
|
3
|
-
updateDoc,
|
|
4
|
-
setDoc,
|
|
5
|
-
serverTimestamp,
|
|
6
|
-
Firestore,
|
|
7
|
-
} from "firebase/firestore";
|
|
8
|
-
import {
|
|
9
|
-
PatientLocationInfo,
|
|
10
|
-
CreatePatientLocationInfoData,
|
|
11
|
-
UpdatePatientLocationInfoData,
|
|
12
|
-
} from "../../../types/patient";
|
|
13
|
-
import { createPatientLocationInfoSchema } from "../../../validations/patient.schema";
|
|
14
|
-
import { z } from "zod";
|
|
15
|
-
import { geohashForLocation } from "geofire-common";
|
|
16
|
-
import { getLocationInfoDocRef } from "./docs.utils";
|
|
17
|
-
|
|
18
|
-
// Funkcije za rad sa lokacijom
|
|
19
|
-
export const updatePatientLocationUtil = async (
|
|
20
|
-
db: Firestore,
|
|
21
|
-
patientId: string,
|
|
22
|
-
latitude: number,
|
|
23
|
-
longitude: number
|
|
24
|
-
): Promise<void> => {
|
|
25
|
-
const locationData = {
|
|
26
|
-
latitude,
|
|
27
|
-
longitude,
|
|
28
|
-
geohash: geohashForLocation([latitude, longitude]),
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const updateData = {
|
|
32
|
-
locationData,
|
|
33
|
-
updatedAt: serverTimestamp(),
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
await updateDoc(getLocationInfoDocRef(db, patientId), updateData);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const createLocationInfoUtil = async (
|
|
40
|
-
db: Firestore,
|
|
41
|
-
data: CreatePatientLocationInfoData,
|
|
42
|
-
requesterId: string
|
|
43
|
-
): Promise<PatientLocationInfo> => {
|
|
44
|
-
try {
|
|
45
|
-
if (data.patientId !== requesterId) {
|
|
46
|
-
throw new Error("Only patient can create their location information");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const validatedData = createPatientLocationInfoSchema.parse(data);
|
|
50
|
-
|
|
51
|
-
const locationData = {
|
|
52
|
-
...validatedData,
|
|
53
|
-
locationData: {
|
|
54
|
-
...validatedData.locationData,
|
|
55
|
-
geohash: geohashForLocation([
|
|
56
|
-
validatedData.locationData.latitude,
|
|
57
|
-
validatedData.locationData.longitude,
|
|
58
|
-
]),
|
|
59
|
-
},
|
|
60
|
-
createdAt: serverTimestamp(),
|
|
61
|
-
updatedAt: serverTimestamp(),
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
await setDoc(getLocationInfoDocRef(db, data.patientId), locationData);
|
|
65
|
-
|
|
66
|
-
const locationDoc = await getDoc(getLocationInfoDocRef(db, data.patientId));
|
|
67
|
-
if (!locationDoc.exists()) {
|
|
68
|
-
throw new Error("Failed to create location information");
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return locationDoc.data() as PatientLocationInfo;
|
|
72
|
-
} catch (error) {
|
|
73
|
-
if (error instanceof z.ZodError) {
|
|
74
|
-
throw new Error("Invalid location data: " + error.message);
|
|
75
|
-
}
|
|
76
|
-
throw error;
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export const getLocationInfoUtil = async (
|
|
81
|
-
db: Firestore,
|
|
82
|
-
patientId: string,
|
|
83
|
-
requesterId: string
|
|
84
|
-
): Promise<PatientLocationInfo | null> => {
|
|
85
|
-
if (patientId !== requesterId) {
|
|
86
|
-
throw new Error("Unauthorized access to location information");
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const locationDoc = await getDoc(getLocationInfoDocRef(db, patientId));
|
|
90
|
-
return locationDoc.exists()
|
|
91
|
-
? (locationDoc.data() as PatientLocationInfo)
|
|
92
|
-
: null;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export const updateLocationInfoUtil = async (
|
|
96
|
-
db: Firestore,
|
|
97
|
-
patientId: string,
|
|
98
|
-
data: UpdatePatientLocationInfoData,
|
|
99
|
-
requesterId: string
|
|
100
|
-
): Promise<PatientLocationInfo> => {
|
|
101
|
-
if (patientId !== requesterId) {
|
|
102
|
-
throw new Error("Only patient can update their location information");
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
let updateData = { ...data };
|
|
106
|
-
if (data.locationData) {
|
|
107
|
-
updateData.locationData = {
|
|
108
|
-
...data.locationData,
|
|
109
|
-
geohash: geohashForLocation([
|
|
110
|
-
data.locationData.latitude,
|
|
111
|
-
data.locationData.longitude,
|
|
112
|
-
]),
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
updateData.updatedAt = serverTimestamp();
|
|
117
|
-
|
|
118
|
-
await updateDoc(getLocationInfoDocRef(db, patientId), updateData);
|
|
119
|
-
|
|
120
|
-
const updatedInfo = await getLocationInfoUtil(db, patientId, requesterId);
|
|
121
|
-
if (!updatedInfo) {
|
|
122
|
-
throw new Error("Failed to retrieve updated location information");
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return updatedInfo;
|
|
126
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
getDoc,
|
|
3
|
+
updateDoc,
|
|
4
|
+
setDoc,
|
|
5
|
+
serverTimestamp,
|
|
6
|
+
Firestore,
|
|
7
|
+
} from "firebase/firestore";
|
|
8
|
+
import {
|
|
9
|
+
PatientLocationInfo,
|
|
10
|
+
CreatePatientLocationInfoData,
|
|
11
|
+
UpdatePatientLocationInfoData,
|
|
12
|
+
} from "../../../types/patient";
|
|
13
|
+
import { createPatientLocationInfoSchema } from "../../../validations/patient.schema";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
import { geohashForLocation } from "geofire-common";
|
|
16
|
+
import { getLocationInfoDocRef } from "./docs.utils";
|
|
17
|
+
|
|
18
|
+
// Funkcije za rad sa lokacijom
|
|
19
|
+
export const updatePatientLocationUtil = async (
|
|
20
|
+
db: Firestore,
|
|
21
|
+
patientId: string,
|
|
22
|
+
latitude: number,
|
|
23
|
+
longitude: number
|
|
24
|
+
): Promise<void> => {
|
|
25
|
+
const locationData = {
|
|
26
|
+
latitude,
|
|
27
|
+
longitude,
|
|
28
|
+
geohash: geohashForLocation([latitude, longitude]),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const updateData = {
|
|
32
|
+
locationData,
|
|
33
|
+
updatedAt: serverTimestamp(),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
await updateDoc(getLocationInfoDocRef(db, patientId), updateData);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const createLocationInfoUtil = async (
|
|
40
|
+
db: Firestore,
|
|
41
|
+
data: CreatePatientLocationInfoData,
|
|
42
|
+
requesterId: string
|
|
43
|
+
): Promise<PatientLocationInfo> => {
|
|
44
|
+
try {
|
|
45
|
+
if (data.patientId !== requesterId) {
|
|
46
|
+
throw new Error("Only patient can create their location information");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const validatedData = createPatientLocationInfoSchema.parse(data);
|
|
50
|
+
|
|
51
|
+
const locationData = {
|
|
52
|
+
...validatedData,
|
|
53
|
+
locationData: {
|
|
54
|
+
...validatedData.locationData,
|
|
55
|
+
geohash: geohashForLocation([
|
|
56
|
+
validatedData.locationData.latitude,
|
|
57
|
+
validatedData.locationData.longitude,
|
|
58
|
+
]),
|
|
59
|
+
},
|
|
60
|
+
createdAt: serverTimestamp(),
|
|
61
|
+
updatedAt: serverTimestamp(),
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
await setDoc(getLocationInfoDocRef(db, data.patientId), locationData);
|
|
65
|
+
|
|
66
|
+
const locationDoc = await getDoc(getLocationInfoDocRef(db, data.patientId));
|
|
67
|
+
if (!locationDoc.exists()) {
|
|
68
|
+
throw new Error("Failed to create location information");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return locationDoc.data() as PatientLocationInfo;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
if (error instanceof z.ZodError) {
|
|
74
|
+
throw new Error("Invalid location data: " + error.message);
|
|
75
|
+
}
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const getLocationInfoUtil = async (
|
|
81
|
+
db: Firestore,
|
|
82
|
+
patientId: string,
|
|
83
|
+
requesterId: string
|
|
84
|
+
): Promise<PatientLocationInfo | null> => {
|
|
85
|
+
if (patientId !== requesterId) {
|
|
86
|
+
throw new Error("Unauthorized access to location information");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const locationDoc = await getDoc(getLocationInfoDocRef(db, patientId));
|
|
90
|
+
return locationDoc.exists()
|
|
91
|
+
? (locationDoc.data() as PatientLocationInfo)
|
|
92
|
+
: null;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const updateLocationInfoUtil = async (
|
|
96
|
+
db: Firestore,
|
|
97
|
+
patientId: string,
|
|
98
|
+
data: UpdatePatientLocationInfoData,
|
|
99
|
+
requesterId: string
|
|
100
|
+
): Promise<PatientLocationInfo> => {
|
|
101
|
+
if (patientId !== requesterId) {
|
|
102
|
+
throw new Error("Only patient can update their location information");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let updateData = { ...data };
|
|
106
|
+
if (data.locationData) {
|
|
107
|
+
updateData.locationData = {
|
|
108
|
+
...data.locationData,
|
|
109
|
+
geohash: geohashForLocation([
|
|
110
|
+
data.locationData.latitude,
|
|
111
|
+
data.locationData.longitude,
|
|
112
|
+
]),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
updateData.updatedAt = serverTimestamp();
|
|
117
|
+
|
|
118
|
+
await updateDoc(getLocationInfoDocRef(db, patientId), updateData);
|
|
119
|
+
|
|
120
|
+
const updatedInfo = await getLocationInfoUtil(db, patientId, requesterId);
|
|
121
|
+
if (!updatedInfo) {
|
|
122
|
+
throw new Error("Failed to retrieve updated location information");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return updatedInfo;
|
|
126
|
+
};
|