@blackcode_sa/metaestetics-api 1.15.16 → 1.15.17-staging.1
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 +377 -222
- package/dist/admin/index.d.ts +377 -222
- package/dist/admin/index.js +625 -206
- package/dist/admin/index.mjs +624 -206
- package/dist/backoffice/index.d.mts +24 -0
- package/dist/backoffice/index.d.ts +24 -0
- package/dist/index.d.mts +292 -4
- package/dist/index.d.ts +292 -4
- package/dist/index.js +1142 -630
- package/dist/index.mjs +1137 -617
- package/package.json +2 -1
- package/src/__mocks__/firstore.ts +10 -10
- package/src/admin/aggregation/README.md +79 -79
- package/src/admin/aggregation/appointment/README.md +151 -129
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +2137 -2091
- 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 -966
- 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 +184 -125
- package/src/admin/booking/booking.admin.ts +1330 -1073
- package/src/admin/booking/booking.calculator.ts +850 -712
- package/src/admin/booking/booking.types.ts +76 -59
- package/src/admin/booking/index.ts +3 -3
- package/src/admin/booking/timezones-problem.md +185 -185
- package/src/admin/calendar/README.md +62 -7
- package/src/admin/calendar/calendar.admin.service.ts +345 -345
- package/src/admin/calendar/index.ts +2 -1
- package/src/admin/calendar/resource-calendar.admin.ts +198 -0
- 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 +83 -83
- package/src/admin/logger/index.ts +78 -78
- package/src/admin/mailing/README.md +139 -139
- package/src/admin/mailing/appointment/appointment.mailing.service.ts +1253 -1253
- 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/clinicWelcome/clinicWelcome.mailing.ts +292 -292
- package/src/admin/mailing/clinicWelcome/index.ts +1 -1
- package/src/admin/mailing/clinicWelcome/templates/welcome.template.ts +225 -225
- package/src/admin/mailing/index.ts +5 -5
- package/src/admin/mailing/patientInvite/index.ts +2 -2
- package/src/admin/mailing/patientInvite/patientInvite.mailing.ts +415 -415
- package/src/admin/mailing/patientInvite/templates/invitation.template.ts +105 -105
- 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 +818 -818
- 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 +260 -260
- 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 +557 -557
- 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 +1153 -1153
- 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 +239 -239
- 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 +17 -17
- package/src/config/tiers.config.ts +255 -229
- package/src/errors/auth.error.ts +6 -6
- package/src/errors/auth.errors.ts +211 -211
- 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 +298 -298
- package/src/services/__tests__/auth.service.test.ts +310 -310
- package/src/services/__tests__/base.service.test.ts +36 -36
- package/src/services/__tests__/user.service.test.ts +530 -530
- 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 +2148 -2148
- 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 +2943 -2941
- package/src/services/appointment/index.ts +1 -1
- package/src/services/appointment/utils/appointment.utils.ts +620 -620
- package/src/services/appointment/utils/extended-procedure.utils.ts +354 -354
- package/src/services/appointment/utils/form-initialization.utils.ts +516 -516
- package/src/services/appointment/utils/recommended-procedure.utils.ts +195 -195
- package/src/services/appointment/utils/zone-management.utils.ts +468 -468
- package/src/services/appointment/utils/zone-photo.utils.ts +302 -302
- package/src/services/auth/auth.service.ts +1435 -1435
- 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 +1693 -1693
- 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 +676 -676
- 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 +265 -265
- package/src/services/clinic/__tests__/clinic-group.service.test.ts +222 -222
- package/src/services/clinic/__tests__/clinic.service.test.ts +302 -302
- 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 +720 -720
- 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 +1023 -1023
- package/src/services/clinic/utils/filter.utils.d.ts +23 -23
- package/src/services/clinic/utils/filter.utils.ts +462 -462
- package/src/services/clinic/utils/index.ts +10 -10
- package/src/services/clinic/utils/photos.utils.ts +188 -188
- package/src/services/clinic/utils/search.utils.ts +83 -83
- 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 +597 -597
- package/src/services/documentation-templates/index.ts +2 -2
- package/src/services/index.ts +16 -15
- 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 +286 -286
- package/src/services/patient/index.ts +2 -2
- package/src/services/patient/patient.service.ts +1021 -1021
- package/src/services/patient/patientRequirements.service.ts +309 -309
- package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -176
- package/src/services/patient/utils/body-assessment.utils.ts +159 -159
- package/src/services/patient/utils/clinic.utils.ts +159 -159
- package/src/services/patient/utils/docs.utils.ts +142 -142
- package/src/services/patient/utils/hair-scalp-assessment.utils.ts +158 -158
- 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/pre-surgical-assessment.utils.ts +161 -161
- 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/skin-quality-assessment.utils.ts +160 -160
- 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 +2355 -2354
- package/src/services/procedure/README.md +163 -163
- package/src/services/procedure/index.ts +1 -1
- package/src/services/procedure/procedure.service.ts +2521 -2521
- package/src/services/resource/README.md +119 -0
- package/src/services/resource/index.ts +1 -0
- package/src/services/resource/resource.service.ts +555 -0
- package/src/services/reviews/index.ts +1 -1
- package/src/services/reviews/reviews.service.ts +745 -745
- package/src/services/tier-enforcement.ts +240 -240
- package/src/services/user/index.ts +1 -1
- package/src/services/user/user.service.ts +533 -533
- package/src/services/user/user.v2.service.ts +467 -467
- 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 +524 -517
- package/src/types/calendar/index.ts +261 -260
- package/src/types/calendar/synced-calendar.types.ts +66 -66
- package/src/types/clinic/index.ts +530 -529
- package/src/types/clinic/practitioner-invite.types.ts +91 -91
- package/src/types/clinic/preferences.types.ts +159 -159
- package/src/types/clinic/rbac.types.ts +64 -63
- package/src/types/clinic/to-do +3 -3
- package/src/types/documentation-templates/index.ts +308 -308
- package/src/types/index.ts +50 -47
- package/src/types/notifications/README.md +77 -77
- package/src/types/notifications/index.ts +300 -300
- package/src/types/patient/aesthetic-analysis.types.ts +66 -66
- package/src/types/patient/allergies.ts +58 -58
- package/src/types/patient/body-assessment.types.ts +93 -93
- package/src/types/patient/hair-scalp-assessment.types.ts +98 -98
- package/src/types/patient/index.ts +279 -279
- package/src/types/patient/medical-info.types.ts +152 -152
- package/src/types/patient/patient-requirements.ts +92 -92
- package/src/types/patient/pre-surgical-assessment.types.ts +95 -95
- package/src/types/patient/skin-quality-assessment.types.ts +105 -105
- package/src/types/patient/token.types.ts +61 -61
- package/src/types/practitioner/index.ts +208 -208
- package/src/types/procedure/index.ts +189 -183
- package/src/types/profile/index.ts +39 -39
- package/src/types/resource/README.md +153 -0
- package/src/types/resource/index.ts +199 -0
- package/src/types/reviews/index.ts +132 -132
- package/src/types/tz-lookup.d.ts +4 -4
- package/src/types/user/index.ts +60 -60
- package/src/utils/TIMESTAMPS.md +176 -176
- package/src/utils/TimestampUtils.ts +241 -241
- package/src/utils/index.ts +1 -1
- package/src/validations/README.md +94 -0
- package/src/validations/appointment.schema.ts +589 -589
- 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 +21 -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/body-assessment.schema.ts +82 -82
- package/src/validations/patient/hair-scalp-assessment.schema.ts +70 -70
- package/src/validations/patient/medical-info.schema.ts +177 -177
- package/src/validations/patient/patient-requirements.schema.ts +84 -84
- package/src/validations/patient/pre-surgical-assessment.schema.ts +78 -78
- package/src/validations/patient/skin-quality-assessment.schema.ts +70 -70
- package/src/validations/patient/token.schema.ts +29 -29
- package/src/validations/patient.schema.ts +217 -217
- package/src/validations/practitioner.schema.ts +224 -224
- package/src/validations/procedure-product.schema.ts +41 -41
- package/src/validations/procedure.schema.ts +136 -124
- package/src/validations/profile-info.schema.ts +41 -41
- package/src/validations/resource.schema.ts +57 -0
- package/src/validations/reviews.schema.ts +195 -195
- package/src/validations/schemas.ts +109 -109
- package/src/validations/shared.schema.ts +78 -78
|
@@ -1,241 +1,241 @@
|
|
|
1
|
-
import * as admin from "firebase-admin";
|
|
2
|
-
import { Timestamp as ClientTimestamp } from "firebase/firestore";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Detect if we're running in a server environment (like Cloud Functions)
|
|
6
|
-
* or compiled for server usage
|
|
7
|
-
*/
|
|
8
|
-
const IS_SERVER_ENV =
|
|
9
|
-
process.env.NODE_ENV === "production" ||
|
|
10
|
-
process.env.FUNCTIONS_EMULATOR === "true" ||
|
|
11
|
-
process.env.FIREBASE_CONFIG !== undefined;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Utilities for managing timestamps across client and server-side Firebase code.
|
|
15
|
-
* This module provides conversion functions to ensure timestamp compatibility
|
|
16
|
-
* between admin and client Firebase SDKs.
|
|
17
|
-
*/
|
|
18
|
-
export class TimestampUtils {
|
|
19
|
-
/**
|
|
20
|
-
* Flag to force server mode where admin timestamps are preserved
|
|
21
|
-
* This should be true in Cloud Functions environments
|
|
22
|
-
*/
|
|
23
|
-
private static serverMode = IS_SERVER_ENV;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Enables server mode where admin timestamps are preserved when saving
|
|
27
|
-
* to Firestore via the admin SDK
|
|
28
|
-
*/
|
|
29
|
-
static enableServerMode(): void {
|
|
30
|
-
this.serverMode = true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Disables server mode - use this only for client-side or mixed environments
|
|
35
|
-
*/
|
|
36
|
-
static disableServerMode(): void {
|
|
37
|
-
this.serverMode = false;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Converts an admin Firestore Timestamp to a client Firestore Timestamp
|
|
42
|
-
* In server mode, returns the original admin timestamp for storage consistency
|
|
43
|
-
*
|
|
44
|
-
* @param adminTimestamp - Admin SDK Timestamp (from firebase-admin)
|
|
45
|
-
* @returns A client SDK Timestamp (from firebase/firestore) with same seconds/nanoseconds,
|
|
46
|
-
* or the original admin timestamp in server mode,
|
|
47
|
-
* or null if input is null
|
|
48
|
-
*/
|
|
49
|
-
static adminToClient(
|
|
50
|
-
adminTimestamp: admin.firestore.Timestamp | null
|
|
51
|
-
): ClientTimestamp | admin.firestore.Timestamp | null {
|
|
52
|
-
if (!adminTimestamp) return null;
|
|
53
|
-
|
|
54
|
-
// In server mode (Cloud Functions), just return the admin timestamp
|
|
55
|
-
if (this.serverMode) {
|
|
56
|
-
return adminTimestamp;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// In client mode, convert to client timestamp
|
|
60
|
-
return new ClientTimestamp(
|
|
61
|
-
adminTimestamp.seconds,
|
|
62
|
-
adminTimestamp.nanoseconds
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Converts a client Firestore Timestamp to an admin Firestore Timestamp
|
|
68
|
-
* @param clientTimestamp - Client SDK Timestamp (from firebase/firestore)
|
|
69
|
-
* @returns An admin SDK Timestamp (from firebase-admin) with same seconds/nanoseconds or null if input is null
|
|
70
|
-
*/
|
|
71
|
-
static clientToAdmin(
|
|
72
|
-
clientTimestamp: ClientTimestamp | null
|
|
73
|
-
): admin.firestore.Timestamp | null {
|
|
74
|
-
if (!clientTimestamp) return null;
|
|
75
|
-
|
|
76
|
-
return new admin.firestore.Timestamp(
|
|
77
|
-
clientTimestamp.seconds,
|
|
78
|
-
clientTimestamp.nanoseconds
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Creates a timestamp for the current time in the appropriate format based on environment
|
|
84
|
-
* @returns A timestamp for the current time (admin timestamp in server mode, client in client mode)
|
|
85
|
-
*/
|
|
86
|
-
static nowAsTimestamp(): admin.firestore.Timestamp | ClientTimestamp {
|
|
87
|
-
const now = admin.firestore.Timestamp.now();
|
|
88
|
-
// In server mode, return the admin timestamp directly
|
|
89
|
-
if (this.serverMode) {
|
|
90
|
-
return now;
|
|
91
|
-
}
|
|
92
|
-
// In client mode, convert to client timestamp
|
|
93
|
-
return this.adminToClient(now) as ClientTimestamp;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @deprecated Use nowAsTimestamp() instead for better cross-environment compatibility
|
|
98
|
-
*/
|
|
99
|
-
static nowAsClient(): ClientTimestamp {
|
|
100
|
-
const now = admin.firestore.Timestamp.now();
|
|
101
|
-
return this.adminToClient(now) as ClientTimestamp;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Converts a Date object to a timestamp in the appropriate format based on environment
|
|
106
|
-
* @param date - JavaScript Date object
|
|
107
|
-
* @returns A timestamp (admin timestamp in server mode, client in client mode) or null if input is null
|
|
108
|
-
*/
|
|
109
|
-
static dateToTimestamp(
|
|
110
|
-
date: Date | null
|
|
111
|
-
): admin.firestore.Timestamp | ClientTimestamp | null {
|
|
112
|
-
if (!date) return null;
|
|
113
|
-
|
|
114
|
-
if (this.serverMode) {
|
|
115
|
-
return admin.firestore.Timestamp.fromDate(date);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return ClientTimestamp.fromDate(date);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
|
|
123
|
-
*/
|
|
124
|
-
static dateToClientTimestamp(date: Date | null): ClientTimestamp | null {
|
|
125
|
-
if (!date) return null;
|
|
126
|
-
return ClientTimestamp.fromDate(date);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
|
|
131
|
-
*/
|
|
132
|
-
static dateToAdminTimestamp(
|
|
133
|
-
date: Date | null
|
|
134
|
-
): admin.firestore.Timestamp | null {
|
|
135
|
-
if (!date) return null;
|
|
136
|
-
return admin.firestore.Timestamp.fromDate(date);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Gets a server timestamp field value for use in create/update operations
|
|
141
|
-
* Works in both admin and client environments
|
|
142
|
-
*/
|
|
143
|
-
static serverTimestamp(): admin.firestore.FieldValue | any {
|
|
144
|
-
if (this.serverMode) {
|
|
145
|
-
return admin.firestore.FieldValue.serverTimestamp();
|
|
146
|
-
}
|
|
147
|
-
// In client mode, we'd need to import from firebase/firestore
|
|
148
|
-
// This would be implemented for client environments
|
|
149
|
-
throw new Error("Server timestamp in client mode not implemented");
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* For objects with mixed timestamp types, ensures all timestamps are
|
|
154
|
-
* in the correct format for the current environment
|
|
155
|
-
*/
|
|
156
|
-
static normalizeTimestamps<T>(obj: T): T {
|
|
157
|
-
if (!obj || typeof obj !== "object") {
|
|
158
|
-
return obj;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (obj instanceof admin.firestore.Timestamp) {
|
|
162
|
-
return this.serverMode ? obj : (this.adminToClient(obj) as unknown as T);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (obj instanceof ClientTimestamp && this.serverMode) {
|
|
166
|
-
return this.clientToAdmin(obj) as unknown as T;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (Array.isArray(obj)) {
|
|
170
|
-
return obj.map((item) => this.normalizeTimestamps(item)) as unknown as T;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const result = { ...obj } as any;
|
|
174
|
-
|
|
175
|
-
for (const key in result) {
|
|
176
|
-
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
177
|
-
result[key] = this.normalizeTimestamps(result[key]);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return result as T;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* @deprecated Use normalizeTimestamps() instead for better cross-environment compatibility
|
|
186
|
-
*/
|
|
187
|
-
static convertObjectTimestampsAdminToClient<T>(obj: T): T {
|
|
188
|
-
if (!obj || typeof obj !== "object") {
|
|
189
|
-
return obj;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (obj instanceof admin.firestore.Timestamp) {
|
|
193
|
-
return this.adminToClient(obj) as unknown as T;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (Array.isArray(obj)) {
|
|
197
|
-
return obj.map((item) =>
|
|
198
|
-
this.convertObjectTimestampsAdminToClient(item)
|
|
199
|
-
) as unknown as T;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const result = { ...obj } as any;
|
|
203
|
-
|
|
204
|
-
for (const key in result) {
|
|
205
|
-
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
206
|
-
result[key] = this.convertObjectTimestampsAdminToClient(result[key]);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return result as T;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* @deprecated Use normalizeTimestamps() instead for better cross-environment compatibility
|
|
215
|
-
*/
|
|
216
|
-
static convertObjectTimestampsClientToAdmin<T>(obj: T): T {
|
|
217
|
-
if (!obj || typeof obj !== "object") {
|
|
218
|
-
return obj;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (obj instanceof ClientTimestamp) {
|
|
222
|
-
return this.clientToAdmin(obj) as unknown as T;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (Array.isArray(obj)) {
|
|
226
|
-
return obj.map((item) =>
|
|
227
|
-
this.convertObjectTimestampsClientToAdmin(item)
|
|
228
|
-
) as unknown as T;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const result = { ...obj } as any;
|
|
232
|
-
|
|
233
|
-
for (const key in result) {
|
|
234
|
-
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
235
|
-
result[key] = this.convertObjectTimestampsClientToAdmin(result[key]);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return result as T;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
1
|
+
import * as admin from "firebase-admin";
|
|
2
|
+
import { Timestamp as ClientTimestamp } from "firebase/firestore";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Detect if we're running in a server environment (like Cloud Functions)
|
|
6
|
+
* or compiled for server usage
|
|
7
|
+
*/
|
|
8
|
+
const IS_SERVER_ENV =
|
|
9
|
+
process.env.NODE_ENV === "production" ||
|
|
10
|
+
process.env.FUNCTIONS_EMULATOR === "true" ||
|
|
11
|
+
process.env.FIREBASE_CONFIG !== undefined;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Utilities for managing timestamps across client and server-side Firebase code.
|
|
15
|
+
* This module provides conversion functions to ensure timestamp compatibility
|
|
16
|
+
* between admin and client Firebase SDKs.
|
|
17
|
+
*/
|
|
18
|
+
export class TimestampUtils {
|
|
19
|
+
/**
|
|
20
|
+
* Flag to force server mode where admin timestamps are preserved
|
|
21
|
+
* This should be true in Cloud Functions environments
|
|
22
|
+
*/
|
|
23
|
+
private static serverMode = IS_SERVER_ENV;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Enables server mode where admin timestamps are preserved when saving
|
|
27
|
+
* to Firestore via the admin SDK
|
|
28
|
+
*/
|
|
29
|
+
static enableServerMode(): void {
|
|
30
|
+
this.serverMode = true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Disables server mode - use this only for client-side or mixed environments
|
|
35
|
+
*/
|
|
36
|
+
static disableServerMode(): void {
|
|
37
|
+
this.serverMode = false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Converts an admin Firestore Timestamp to a client Firestore Timestamp
|
|
42
|
+
* In server mode, returns the original admin timestamp for storage consistency
|
|
43
|
+
*
|
|
44
|
+
* @param adminTimestamp - Admin SDK Timestamp (from firebase-admin)
|
|
45
|
+
* @returns A client SDK Timestamp (from firebase/firestore) with same seconds/nanoseconds,
|
|
46
|
+
* or the original admin timestamp in server mode,
|
|
47
|
+
* or null if input is null
|
|
48
|
+
*/
|
|
49
|
+
static adminToClient(
|
|
50
|
+
adminTimestamp: admin.firestore.Timestamp | null
|
|
51
|
+
): ClientTimestamp | admin.firestore.Timestamp | null {
|
|
52
|
+
if (!adminTimestamp) return null;
|
|
53
|
+
|
|
54
|
+
// In server mode (Cloud Functions), just return the admin timestamp
|
|
55
|
+
if (this.serverMode) {
|
|
56
|
+
return adminTimestamp;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// In client mode, convert to client timestamp
|
|
60
|
+
return new ClientTimestamp(
|
|
61
|
+
adminTimestamp.seconds,
|
|
62
|
+
adminTimestamp.nanoseconds
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Converts a client Firestore Timestamp to an admin Firestore Timestamp
|
|
68
|
+
* @param clientTimestamp - Client SDK Timestamp (from firebase/firestore)
|
|
69
|
+
* @returns An admin SDK Timestamp (from firebase-admin) with same seconds/nanoseconds or null if input is null
|
|
70
|
+
*/
|
|
71
|
+
static clientToAdmin(
|
|
72
|
+
clientTimestamp: ClientTimestamp | null
|
|
73
|
+
): admin.firestore.Timestamp | null {
|
|
74
|
+
if (!clientTimestamp) return null;
|
|
75
|
+
|
|
76
|
+
return new admin.firestore.Timestamp(
|
|
77
|
+
clientTimestamp.seconds,
|
|
78
|
+
clientTimestamp.nanoseconds
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Creates a timestamp for the current time in the appropriate format based on environment
|
|
84
|
+
* @returns A timestamp for the current time (admin timestamp in server mode, client in client mode)
|
|
85
|
+
*/
|
|
86
|
+
static nowAsTimestamp(): admin.firestore.Timestamp | ClientTimestamp {
|
|
87
|
+
const now = admin.firestore.Timestamp.now();
|
|
88
|
+
// In server mode, return the admin timestamp directly
|
|
89
|
+
if (this.serverMode) {
|
|
90
|
+
return now;
|
|
91
|
+
}
|
|
92
|
+
// In client mode, convert to client timestamp
|
|
93
|
+
return this.adminToClient(now) as ClientTimestamp;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @deprecated Use nowAsTimestamp() instead for better cross-environment compatibility
|
|
98
|
+
*/
|
|
99
|
+
static nowAsClient(): ClientTimestamp {
|
|
100
|
+
const now = admin.firestore.Timestamp.now();
|
|
101
|
+
return this.adminToClient(now) as ClientTimestamp;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Converts a Date object to a timestamp in the appropriate format based on environment
|
|
106
|
+
* @param date - JavaScript Date object
|
|
107
|
+
* @returns A timestamp (admin timestamp in server mode, client in client mode) or null if input is null
|
|
108
|
+
*/
|
|
109
|
+
static dateToTimestamp(
|
|
110
|
+
date: Date | null
|
|
111
|
+
): admin.firestore.Timestamp | ClientTimestamp | null {
|
|
112
|
+
if (!date) return null;
|
|
113
|
+
|
|
114
|
+
if (this.serverMode) {
|
|
115
|
+
return admin.firestore.Timestamp.fromDate(date);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return ClientTimestamp.fromDate(date);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
|
|
123
|
+
*/
|
|
124
|
+
static dateToClientTimestamp(date: Date | null): ClientTimestamp | null {
|
|
125
|
+
if (!date) return null;
|
|
126
|
+
return ClientTimestamp.fromDate(date);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated Use dateToTimestamp() instead for better cross-environment compatibility
|
|
131
|
+
*/
|
|
132
|
+
static dateToAdminTimestamp(
|
|
133
|
+
date: Date | null
|
|
134
|
+
): admin.firestore.Timestamp | null {
|
|
135
|
+
if (!date) return null;
|
|
136
|
+
return admin.firestore.Timestamp.fromDate(date);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Gets a server timestamp field value for use in create/update operations
|
|
141
|
+
* Works in both admin and client environments
|
|
142
|
+
*/
|
|
143
|
+
static serverTimestamp(): admin.firestore.FieldValue | any {
|
|
144
|
+
if (this.serverMode) {
|
|
145
|
+
return admin.firestore.FieldValue.serverTimestamp();
|
|
146
|
+
}
|
|
147
|
+
// In client mode, we'd need to import from firebase/firestore
|
|
148
|
+
// This would be implemented for client environments
|
|
149
|
+
throw new Error("Server timestamp in client mode not implemented");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* For objects with mixed timestamp types, ensures all timestamps are
|
|
154
|
+
* in the correct format for the current environment
|
|
155
|
+
*/
|
|
156
|
+
static normalizeTimestamps<T>(obj: T): T {
|
|
157
|
+
if (!obj || typeof obj !== "object") {
|
|
158
|
+
return obj;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (obj instanceof admin.firestore.Timestamp) {
|
|
162
|
+
return this.serverMode ? obj : (this.adminToClient(obj) as unknown as T);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (obj instanceof ClientTimestamp && this.serverMode) {
|
|
166
|
+
return this.clientToAdmin(obj) as unknown as T;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (Array.isArray(obj)) {
|
|
170
|
+
return obj.map((item) => this.normalizeTimestamps(item)) as unknown as T;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const result = { ...obj } as any;
|
|
174
|
+
|
|
175
|
+
for (const key in result) {
|
|
176
|
+
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
177
|
+
result[key] = this.normalizeTimestamps(result[key]);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return result as T;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @deprecated Use normalizeTimestamps() instead for better cross-environment compatibility
|
|
186
|
+
*/
|
|
187
|
+
static convertObjectTimestampsAdminToClient<T>(obj: T): T {
|
|
188
|
+
if (!obj || typeof obj !== "object") {
|
|
189
|
+
return obj;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (obj instanceof admin.firestore.Timestamp) {
|
|
193
|
+
return this.adminToClient(obj) as unknown as T;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (Array.isArray(obj)) {
|
|
197
|
+
return obj.map((item) =>
|
|
198
|
+
this.convertObjectTimestampsAdminToClient(item)
|
|
199
|
+
) as unknown as T;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const result = { ...obj } as any;
|
|
203
|
+
|
|
204
|
+
for (const key in result) {
|
|
205
|
+
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
206
|
+
result[key] = this.convertObjectTimestampsAdminToClient(result[key]);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return result as T;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @deprecated Use normalizeTimestamps() instead for better cross-environment compatibility
|
|
215
|
+
*/
|
|
216
|
+
static convertObjectTimestampsClientToAdmin<T>(obj: T): T {
|
|
217
|
+
if (!obj || typeof obj !== "object") {
|
|
218
|
+
return obj;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (obj instanceof ClientTimestamp) {
|
|
222
|
+
return this.clientToAdmin(obj) as unknown as T;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (Array.isArray(obj)) {
|
|
226
|
+
return obj.map((item) =>
|
|
227
|
+
this.convertObjectTimestampsClientToAdmin(item)
|
|
228
|
+
) as unknown as T;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const result = { ...obj } as any;
|
|
232
|
+
|
|
233
|
+
for (const key in result) {
|
|
234
|
+
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
235
|
+
result[key] = this.convertObjectTimestampsClientToAdmin(result[key]);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return result as T;
|
|
240
|
+
}
|
|
241
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./TimestampUtils";
|
|
1
|
+
export * from "./TimestampUtils";
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Validation Schemas (`Api/src/validations/`)
|
|
2
|
+
|
|
3
|
+
Zod validation schemas for API input validation. Each schema file corresponds to a domain entity.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| File | Domain | Description |
|
|
8
|
+
|------|--------|-------------|
|
|
9
|
+
| `appointment.schema.ts` | Appointments | Create/update appointment validation |
|
|
10
|
+
| `calendar.schema.ts` | Calendar | Calendar event validation |
|
|
11
|
+
| `clinic.schema.ts` | Clinics | Clinic CRUD validation |
|
|
12
|
+
| `common.schema.ts` | Shared | Common reusable schemas |
|
|
13
|
+
| `media.schema.ts` | Media | File upload validation |
|
|
14
|
+
| `notification.schema.ts` | Notifications | Notification payload validation |
|
|
15
|
+
| `patient.schema.ts` | Patients | Patient profile validation |
|
|
16
|
+
| `practitioner.schema.ts` | Practitioners | Practitioner profile validation |
|
|
17
|
+
| `procedure.schema.ts` | Procedures | Procedure CRUD validation |
|
|
18
|
+
| `procedure-product.schema.ts` | Products | Procedure product pricing validation |
|
|
19
|
+
| `profile-info.schema.ts` | Profiles | Shared profile info validation |
|
|
20
|
+
| **`resource.schema.ts`** | **Resources** | **Resource CRUD + blocking event validation** |
|
|
21
|
+
| `reviews.schema.ts` | Reviews | Patient review validation |
|
|
22
|
+
| `shared.schema.ts` | Shared | Cross-domain shared schemas |
|
|
23
|
+
|
|
24
|
+
## Resource Validation (`resource.schema.ts`)
|
|
25
|
+
|
|
26
|
+
Part of the [Clinic Resources System](../../../docs/RESOURCE_SYSTEM.md).
|
|
27
|
+
|
|
28
|
+
### `createResourceSchema`
|
|
29
|
+
|
|
30
|
+
Validates input for creating a new resource.
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
{
|
|
34
|
+
clinicBranchId: z.string().min(1), // Required clinic branch ID
|
|
35
|
+
name: z.string().min(1).max(200), // Resource name (1-200 chars)
|
|
36
|
+
category: z.nativeEnum(ResourceCategory), // Must be valid ResourceCategory
|
|
37
|
+
description: z.string().max(1000).optional(), // Optional description
|
|
38
|
+
quantity: z.number().int().min(1).max(100), // 1-100 instances
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `updateResourceSchema`
|
|
43
|
+
|
|
44
|
+
Validates input for updating an existing resource. All fields are optional.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
{
|
|
48
|
+
name: z.string().min(1).max(200).optional(),
|
|
49
|
+
category: z.nativeEnum(ResourceCategory).optional(),
|
|
50
|
+
description: z.string().max(1000).optional(),
|
|
51
|
+
quantity: z.number().int().min(1).max(100).optional(),
|
|
52
|
+
status: z.nativeEnum(ResourceStatus).optional(),
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Note on quantity updates:** Validation only ensures the value is within range. The business logic for quantity decrease (checking for active bookings on affected instances) is handled by `ResourceService.updateResource()`.
|
|
57
|
+
|
|
58
|
+
### `createResourceBlockingEventSchema`
|
|
59
|
+
|
|
60
|
+
Validates input for creating a blocking event on a resource instance.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
{
|
|
64
|
+
clinicBranchId: z.string().min(1),
|
|
65
|
+
resourceId: z.string().min(1),
|
|
66
|
+
resourceInstanceId: z.string().min(1),
|
|
67
|
+
eventName: z.string().min(1).max(200), // Event name (1-200 chars)
|
|
68
|
+
eventTime: z.object({
|
|
69
|
+
start: z.any(), // Firestore Timestamp
|
|
70
|
+
end: z.any(), // Firestore Timestamp
|
|
71
|
+
}),
|
|
72
|
+
description: z.string().max(1000).optional(), // Optional reason
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `updateResourceBlockingEventSchema`
|
|
77
|
+
|
|
78
|
+
Validates input for updating a blocking event. All fields except IDs are optional.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
{
|
|
82
|
+
clinicBranchId: z.string().min(1),
|
|
83
|
+
resourceId: z.string().min(1),
|
|
84
|
+
resourceInstanceId: z.string().min(1),
|
|
85
|
+
eventId: z.string().min(1),
|
|
86
|
+
eventName: z.string().min(1).max(200).optional(),
|
|
87
|
+
eventTime: z.object({ start: z.any(), end: z.any() }).optional(),
|
|
88
|
+
description: z.string().max(1000).optional(),
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Export
|
|
93
|
+
|
|
94
|
+
All schemas are exported via `index.ts`.
|