@blackcode_sa/metaestetics-api 1.13.5 → 1.13.6
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 +20 -1
- package/dist/admin/index.d.ts +20 -1
- package/dist/admin/index.js +217 -1
- package/dist/admin/index.mjs +217 -1
- package/package.json +121 -121
- 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 +966 -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 -2200
- 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 -498
- 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 -494
- 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,152 +1,152 @@
|
|
|
1
|
-
import { Firestore, updateDoc, serverTimestamp, doc } from 'firebase/firestore';
|
|
2
|
-
import {
|
|
3
|
-
Appointment,
|
|
4
|
-
BeforeAfterPerZone,
|
|
5
|
-
APPOINTMENTS_COLLECTION,
|
|
6
|
-
} from '../../../types/appointment';
|
|
7
|
-
import { getAppointmentOrThrow } from './zone-management.utils';
|
|
8
|
-
import { MediaResource } from '../../media/media.service';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Updates a specific photo entry in a zone by index
|
|
12
|
-
* Can update before/after photos and their notes
|
|
13
|
-
*
|
|
14
|
-
* @param db Firestore instance
|
|
15
|
-
* @param appointmentId Appointment ID
|
|
16
|
-
* @param zoneId Zone ID
|
|
17
|
-
* @param photoIndex Index of the photo entry to update
|
|
18
|
-
* @param updates Partial updates to apply
|
|
19
|
-
* @returns Updated appointment
|
|
20
|
-
*/
|
|
21
|
-
export async function updateZonePhotoEntryUtil(
|
|
22
|
-
db: Firestore,
|
|
23
|
-
appointmentId: string,
|
|
24
|
-
zoneId: string,
|
|
25
|
-
photoIndex: number,
|
|
26
|
-
updates: Partial<BeforeAfterPerZone>
|
|
27
|
-
): Promise<Appointment> {
|
|
28
|
-
const appointment = await getAppointmentOrThrow(db, appointmentId);
|
|
29
|
-
|
|
30
|
-
const zonePhotos = appointment.metadata?.zonePhotos as
|
|
31
|
-
| Record<string, BeforeAfterPerZone[]>
|
|
32
|
-
| undefined
|
|
33
|
-
| null;
|
|
34
|
-
|
|
35
|
-
if (!zonePhotos || !zonePhotos[zoneId] || !Array.isArray(zonePhotos[zoneId])) {
|
|
36
|
-
throw new Error(`No photos found for zone ${zoneId} in appointment ${appointmentId}`);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const zoneArray = zonePhotos[zoneId];
|
|
40
|
-
if (photoIndex < 0 || photoIndex >= zoneArray.length) {
|
|
41
|
-
throw new Error(`Invalid photo index ${photoIndex} for zone ${zoneId}. Must be between 0 and ${zoneArray.length - 1}`);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Update the entry
|
|
45
|
-
const updatedZonePhotos = { ...zonePhotos };
|
|
46
|
-
updatedZonePhotos[zoneId] = [...zoneArray];
|
|
47
|
-
updatedZonePhotos[zoneId][photoIndex] = {
|
|
48
|
-
...zoneArray[photoIndex],
|
|
49
|
-
...updates,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// Update appointment
|
|
53
|
-
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
54
|
-
await updateDoc(appointmentRef, {
|
|
55
|
-
'metadata.zonePhotos': updatedZonePhotos,
|
|
56
|
-
updatedAt: serverTimestamp(),
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
return getAppointmentOrThrow(db, appointmentId);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Adds an after photo to an existing before photo entry
|
|
64
|
-
*
|
|
65
|
-
* @param db Firestore instance
|
|
66
|
-
* @param appointmentId Appointment ID
|
|
67
|
-
* @param zoneId Zone ID
|
|
68
|
-
* @param photoIndex Index of the entry to add after photo to
|
|
69
|
-
* @param afterPhotoUrl URL of the after photo
|
|
70
|
-
* @param afterNote Optional note for the after photo
|
|
71
|
-
* @returns Updated appointment
|
|
72
|
-
*/
|
|
73
|
-
export async function addAfterPhotoToEntryUtil(
|
|
74
|
-
db: Firestore,
|
|
75
|
-
appointmentId: string,
|
|
76
|
-
zoneId: string,
|
|
77
|
-
photoIndex: number,
|
|
78
|
-
afterPhotoUrl: MediaResource,
|
|
79
|
-
afterNote?: string
|
|
80
|
-
): Promise<Appointment> {
|
|
81
|
-
return updateZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex, {
|
|
82
|
-
after: afterPhotoUrl,
|
|
83
|
-
afterNote: afterNote || null,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Updates notes for a photo entry
|
|
89
|
-
*
|
|
90
|
-
* @param db Firestore instance
|
|
91
|
-
* @param appointmentId Appointment ID
|
|
92
|
-
* @param zoneId Zone ID
|
|
93
|
-
* @param photoIndex Index of the entry
|
|
94
|
-
* @param beforeNote Optional note for before photo
|
|
95
|
-
* @param afterNote Optional note for after photo
|
|
96
|
-
* @returns Updated appointment
|
|
97
|
-
*/
|
|
98
|
-
export async function updateZonePhotoNotesUtil(
|
|
99
|
-
db: Firestore,
|
|
100
|
-
appointmentId: string,
|
|
101
|
-
zoneId: string,
|
|
102
|
-
photoIndex: number,
|
|
103
|
-
beforeNote?: string,
|
|
104
|
-
afterNote?: string
|
|
105
|
-
): Promise<Appointment> {
|
|
106
|
-
const updates: Partial<BeforeAfterPerZone> = {};
|
|
107
|
-
|
|
108
|
-
if (beforeNote !== undefined) {
|
|
109
|
-
updates.beforeNote = beforeNote || null;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (afterNote !== undefined) {
|
|
113
|
-
updates.afterNote = afterNote || null;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return updateZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex, updates);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Gets a specific photo entry from a zone
|
|
121
|
-
*
|
|
122
|
-
* @param db Firestore instance
|
|
123
|
-
* @param appointmentId Appointment ID
|
|
124
|
-
* @param zoneId Zone ID
|
|
125
|
-
* @param photoIndex Index of the entry
|
|
126
|
-
* @returns Photo entry
|
|
127
|
-
*/
|
|
128
|
-
export async function getZonePhotoEntryUtil(
|
|
129
|
-
db: Firestore,
|
|
130
|
-
appointmentId: string,
|
|
131
|
-
zoneId: string,
|
|
132
|
-
photoIndex: number
|
|
133
|
-
): Promise<BeforeAfterPerZone> {
|
|
134
|
-
const appointment = await getAppointmentOrThrow(db, appointmentId);
|
|
135
|
-
|
|
136
|
-
const zonePhotos = appointment.metadata?.zonePhotos as
|
|
137
|
-
| Record<string, BeforeAfterPerZone[]>
|
|
138
|
-
| undefined
|
|
139
|
-
| null;
|
|
140
|
-
|
|
141
|
-
if (!zonePhotos || !zonePhotos[zoneId] || !Array.isArray(zonePhotos[zoneId])) {
|
|
142
|
-
throw new Error(`No photos found for zone ${zoneId} in appointment ${appointmentId}`);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const zoneArray = zonePhotos[zoneId];
|
|
146
|
-
if (photoIndex < 0 || photoIndex >= zoneArray.length) {
|
|
147
|
-
throw new Error(`Invalid photo index ${photoIndex} for zone ${zoneId}`);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return zoneArray[photoIndex];
|
|
151
|
-
}
|
|
152
|
-
|
|
1
|
+
import { Firestore, updateDoc, serverTimestamp, doc } from 'firebase/firestore';
|
|
2
|
+
import {
|
|
3
|
+
Appointment,
|
|
4
|
+
BeforeAfterPerZone,
|
|
5
|
+
APPOINTMENTS_COLLECTION,
|
|
6
|
+
} from '../../../types/appointment';
|
|
7
|
+
import { getAppointmentOrThrow } from './zone-management.utils';
|
|
8
|
+
import { MediaResource } from '../../media/media.service';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Updates a specific photo entry in a zone by index
|
|
12
|
+
* Can update before/after photos and their notes
|
|
13
|
+
*
|
|
14
|
+
* @param db Firestore instance
|
|
15
|
+
* @param appointmentId Appointment ID
|
|
16
|
+
* @param zoneId Zone ID
|
|
17
|
+
* @param photoIndex Index of the photo entry to update
|
|
18
|
+
* @param updates Partial updates to apply
|
|
19
|
+
* @returns Updated appointment
|
|
20
|
+
*/
|
|
21
|
+
export async function updateZonePhotoEntryUtil(
|
|
22
|
+
db: Firestore,
|
|
23
|
+
appointmentId: string,
|
|
24
|
+
zoneId: string,
|
|
25
|
+
photoIndex: number,
|
|
26
|
+
updates: Partial<BeforeAfterPerZone>
|
|
27
|
+
): Promise<Appointment> {
|
|
28
|
+
const appointment = await getAppointmentOrThrow(db, appointmentId);
|
|
29
|
+
|
|
30
|
+
const zonePhotos = appointment.metadata?.zonePhotos as
|
|
31
|
+
| Record<string, BeforeAfterPerZone[]>
|
|
32
|
+
| undefined
|
|
33
|
+
| null;
|
|
34
|
+
|
|
35
|
+
if (!zonePhotos || !zonePhotos[zoneId] || !Array.isArray(zonePhotos[zoneId])) {
|
|
36
|
+
throw new Error(`No photos found for zone ${zoneId} in appointment ${appointmentId}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const zoneArray = zonePhotos[zoneId];
|
|
40
|
+
if (photoIndex < 0 || photoIndex >= zoneArray.length) {
|
|
41
|
+
throw new Error(`Invalid photo index ${photoIndex} for zone ${zoneId}. Must be between 0 and ${zoneArray.length - 1}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Update the entry
|
|
45
|
+
const updatedZonePhotos = { ...zonePhotos };
|
|
46
|
+
updatedZonePhotos[zoneId] = [...zoneArray];
|
|
47
|
+
updatedZonePhotos[zoneId][photoIndex] = {
|
|
48
|
+
...zoneArray[photoIndex],
|
|
49
|
+
...updates,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Update appointment
|
|
53
|
+
const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
|
|
54
|
+
await updateDoc(appointmentRef, {
|
|
55
|
+
'metadata.zonePhotos': updatedZonePhotos,
|
|
56
|
+
updatedAt: serverTimestamp(),
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
return getAppointmentOrThrow(db, appointmentId);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Adds an after photo to an existing before photo entry
|
|
64
|
+
*
|
|
65
|
+
* @param db Firestore instance
|
|
66
|
+
* @param appointmentId Appointment ID
|
|
67
|
+
* @param zoneId Zone ID
|
|
68
|
+
* @param photoIndex Index of the entry to add after photo to
|
|
69
|
+
* @param afterPhotoUrl URL of the after photo
|
|
70
|
+
* @param afterNote Optional note for the after photo
|
|
71
|
+
* @returns Updated appointment
|
|
72
|
+
*/
|
|
73
|
+
export async function addAfterPhotoToEntryUtil(
|
|
74
|
+
db: Firestore,
|
|
75
|
+
appointmentId: string,
|
|
76
|
+
zoneId: string,
|
|
77
|
+
photoIndex: number,
|
|
78
|
+
afterPhotoUrl: MediaResource,
|
|
79
|
+
afterNote?: string
|
|
80
|
+
): Promise<Appointment> {
|
|
81
|
+
return updateZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex, {
|
|
82
|
+
after: afterPhotoUrl,
|
|
83
|
+
afterNote: afterNote || null,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Updates notes for a photo entry
|
|
89
|
+
*
|
|
90
|
+
* @param db Firestore instance
|
|
91
|
+
* @param appointmentId Appointment ID
|
|
92
|
+
* @param zoneId Zone ID
|
|
93
|
+
* @param photoIndex Index of the entry
|
|
94
|
+
* @param beforeNote Optional note for before photo
|
|
95
|
+
* @param afterNote Optional note for after photo
|
|
96
|
+
* @returns Updated appointment
|
|
97
|
+
*/
|
|
98
|
+
export async function updateZonePhotoNotesUtil(
|
|
99
|
+
db: Firestore,
|
|
100
|
+
appointmentId: string,
|
|
101
|
+
zoneId: string,
|
|
102
|
+
photoIndex: number,
|
|
103
|
+
beforeNote?: string,
|
|
104
|
+
afterNote?: string
|
|
105
|
+
): Promise<Appointment> {
|
|
106
|
+
const updates: Partial<BeforeAfterPerZone> = {};
|
|
107
|
+
|
|
108
|
+
if (beforeNote !== undefined) {
|
|
109
|
+
updates.beforeNote = beforeNote || null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (afterNote !== undefined) {
|
|
113
|
+
updates.afterNote = afterNote || null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return updateZonePhotoEntryUtil(db, appointmentId, zoneId, photoIndex, updates);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Gets a specific photo entry from a zone
|
|
121
|
+
*
|
|
122
|
+
* @param db Firestore instance
|
|
123
|
+
* @param appointmentId Appointment ID
|
|
124
|
+
* @param zoneId Zone ID
|
|
125
|
+
* @param photoIndex Index of the entry
|
|
126
|
+
* @returns Photo entry
|
|
127
|
+
*/
|
|
128
|
+
export async function getZonePhotoEntryUtil(
|
|
129
|
+
db: Firestore,
|
|
130
|
+
appointmentId: string,
|
|
131
|
+
zoneId: string,
|
|
132
|
+
photoIndex: number
|
|
133
|
+
): Promise<BeforeAfterPerZone> {
|
|
134
|
+
const appointment = await getAppointmentOrThrow(db, appointmentId);
|
|
135
|
+
|
|
136
|
+
const zonePhotos = appointment.metadata?.zonePhotos as
|
|
137
|
+
| Record<string, BeforeAfterPerZone[]>
|
|
138
|
+
| undefined
|
|
139
|
+
| null;
|
|
140
|
+
|
|
141
|
+
if (!zonePhotos || !zonePhotos[zoneId] || !Array.isArray(zonePhotos[zoneId])) {
|
|
142
|
+
throw new Error(`No photos found for zone ${zoneId} in appointment ${appointmentId}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const zoneArray = zonePhotos[zoneId];
|
|
146
|
+
if (photoIndex < 0 || photoIndex >= zoneArray.length) {
|
|
147
|
+
throw new Error(`Invalid photo index ${photoIndex} for zone ${zoneId}`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return zoneArray[photoIndex];
|
|
151
|
+
}
|
|
152
|
+
|