@blackcode_sa/metaestetics-api 1.12.58 → 1.12.61
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 +36 -4
- package/dist/admin/index.d.ts +36 -4
- package/dist/admin/index.js +156 -28
- package/dist/admin/index.mjs +156 -28
- package/dist/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/package.json +119 -119
- package/src/__mocks__/firstore.ts +10 -10
- package/src/admin/aggregation/README.md +79 -79
- package/src/admin/aggregation/appointment/README.md +128 -128
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +1844 -1689
- package/src/admin/aggregation/appointment/index.ts +1 -1
- package/src/admin/aggregation/clinic/README.md +52 -52
- package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +703 -703
- package/src/admin/aggregation/clinic/index.ts +1 -1
- package/src/admin/aggregation/forms/README.md +13 -13
- package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +322 -322
- package/src/admin/aggregation/forms/index.ts +1 -1
- package/src/admin/aggregation/index.ts +8 -8
- package/src/admin/aggregation/patient/README.md +27 -27
- package/src/admin/aggregation/patient/index.ts +1 -1
- package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -141
- package/src/admin/aggregation/practitioner/README.md +42 -42
- package/src/admin/aggregation/practitioner/index.ts +1 -1
- package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -433
- package/src/admin/aggregation/practitioner-invite/index.ts +1 -1
- package/src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts +961 -961
- package/src/admin/aggregation/procedure/README.md +43 -43
- package/src/admin/aggregation/procedure/index.ts +1 -1
- package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +702 -702
- package/src/admin/aggregation/reviews/index.ts +1 -1
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +641 -641
- 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 -699
- package/src/admin/booking/booking.types.ts +59 -59
- package/src/admin/booking/index.ts +3 -3
- package/src/admin/booking/timezones-problem.md +185 -185
- package/src/admin/calendar/README.md +7 -7
- package/src/admin/calendar/calendar.admin.service.ts +345 -345
- package/src/admin/calendar/index.ts +1 -1
- package/src/admin/documentation-templates/document-manager.admin.ts +260 -260
- package/src/admin/documentation-templates/index.ts +1 -1
- package/src/admin/free-consultation/free-consultation-utils.admin.ts +148 -148
- package/src/admin/free-consultation/index.ts +1 -1
- package/src/admin/index.ts +75 -75
- package/src/admin/logger/index.ts +78 -78
- package/src/admin/mailing/README.md +95 -95
- package/src/admin/mailing/appointment/appointment.mailing.service.ts +732 -732
- package/src/admin/mailing/appointment/index.ts +1 -1
- package/src/admin/mailing/appointment/templates/patient/appointment-confirmed.html +40 -40
- package/src/admin/mailing/base.mailing.service.ts +208 -208
- package/src/admin/mailing/index.ts +3 -3
- package/src/admin/mailing/practitionerInvite/existing-practitioner-invite.mailing.ts +611 -611
- package/src/admin/mailing/practitionerInvite/index.ts +2 -2
- package/src/admin/mailing/practitionerInvite/practitionerInvite.mailing.ts +395 -395
- package/src/admin/mailing/practitionerInvite/templates/existing-practitioner-invitation.template.ts +155 -155
- package/src/admin/mailing/practitionerInvite/templates/invitation.template.ts +101 -101
- package/src/admin/mailing/practitionerInvite/templates/invite-accepted-notification.template.ts +228 -228
- package/src/admin/mailing/practitionerInvite/templates/invite-rejected-notification.template.ts +242 -242
- package/src/admin/notifications/index.ts +1 -1
- package/src/admin/notifications/notifications.admin.ts +710 -710
- package/src/admin/requirements/README.md +128 -128
- package/src/admin/requirements/index.ts +1 -1
- package/src/admin/requirements/patient-requirements.admin.service.ts +475 -475
- package/src/admin/users/index.ts +1 -1
- package/src/admin/users/user-profile.admin.ts +405 -405
- package/src/backoffice/constants/certification.constants.ts +13 -13
- package/src/backoffice/constants/index.ts +1 -1
- package/src/backoffice/errors/backoffice.errors.ts +181 -181
- package/src/backoffice/errors/index.ts +1 -1
- package/src/backoffice/expo-safe/README.md +26 -26
- package/src/backoffice/expo-safe/index.ts +41 -41
- package/src/backoffice/index.ts +5 -5
- package/src/backoffice/services/FIXES_README.md +102 -102
- package/src/backoffice/services/README.md +40 -40
- package/src/backoffice/services/brand.service.ts +256 -256
- package/src/backoffice/services/category.service.ts +318 -318
- package/src/backoffice/services/constants.service.ts +385 -385
- package/src/backoffice/services/documentation-template.service.ts +202 -202
- package/src/backoffice/services/index.ts +8 -8
- package/src/backoffice/services/migrate-products.ts +116 -116
- package/src/backoffice/services/product.service.ts +553 -553
- package/src/backoffice/services/requirement.service.ts +235 -235
- package/src/backoffice/services/subcategory.service.ts +395 -395
- package/src/backoffice/services/technology.service.ts +1070 -1070
- package/src/backoffice/types/README.md +12 -12
- package/src/backoffice/types/admin-constants.types.ts +69 -69
- package/src/backoffice/types/brand.types.ts +29 -29
- package/src/backoffice/types/category.types.ts +62 -62
- package/src/backoffice/types/documentation-templates.types.ts +28 -28
- package/src/backoffice/types/index.ts +10 -10
- package/src/backoffice/types/procedure-product.types.ts +38 -38
- package/src/backoffice/types/product.types.ts +240 -240
- package/src/backoffice/types/requirement.types.ts +63 -63
- package/src/backoffice/types/static/README.md +18 -18
- package/src/backoffice/types/static/blocking-condition.types.ts +21 -21
- package/src/backoffice/types/static/certification.types.ts +37 -37
- package/src/backoffice/types/static/contraindication.types.ts +19 -19
- package/src/backoffice/types/static/index.ts +6 -6
- package/src/backoffice/types/static/pricing.types.ts +16 -16
- package/src/backoffice/types/static/procedure-family.types.ts +14 -14
- package/src/backoffice/types/static/treatment-benefit.types.ts +22 -22
- package/src/backoffice/types/subcategory.types.ts +34 -34
- package/src/backoffice/types/technology.types.ts +161 -161
- package/src/backoffice/validations/index.ts +1 -1
- package/src/backoffice/validations/schemas.ts +163 -163
- package/src/config/__mocks__/firebase.ts +99 -99
- package/src/config/firebase.ts +78 -78
- package/src/config/index.ts +9 -9
- package/src/errors/auth.error.ts +6 -6
- package/src/errors/auth.errors.ts +200 -200
- package/src/errors/clinic.errors.ts +32 -32
- package/src/errors/firebase.errors.ts +47 -47
- package/src/errors/user.errors.ts +99 -99
- package/src/index.backup.ts +407 -407
- package/src/index.ts +6 -6
- package/src/locales/en.ts +31 -31
- package/src/recommender/admin/index.ts +1 -1
- package/src/recommender/admin/services/recommender.service.admin.ts +5 -5
- package/src/recommender/front/index.ts +1 -1
- package/src/recommender/front/services/onboarding.service.ts +5 -5
- package/src/recommender/front/services/recommender.service.ts +3 -3
- package/src/recommender/index.ts +1 -1
- package/src/services/PATIENTAUTH.MD +197 -197
- package/src/services/README.md +106 -106
- package/src/services/__tests__/auth/auth.mock.test.ts +17 -17
- package/src/services/__tests__/auth/auth.setup.ts +293 -293
- package/src/services/__tests__/auth.service.test.ts +346 -346
- package/src/services/__tests__/base.service.test.ts +77 -77
- package/src/services/__tests__/user.service.test.ts +528 -528
- package/src/services/appointment/README.md +17 -17
- package/src/services/appointment/appointment.service.ts +2082 -2082
- package/src/services/appointment/index.ts +1 -1
- package/src/services/appointment/utils/appointment.utils.ts +552 -552
- package/src/services/appointment/utils/extended-procedure.utils.ts +314 -314
- package/src/services/appointment/utils/form-initialization.utils.ts +225 -225
- package/src/services/appointment/utils/recommended-procedure.utils.ts +195 -195
- package/src/services/appointment/utils/zone-management.utils.ts +353 -353
- package/src/services/appointment/utils/zone-photo.utils.ts +152 -152
- package/src/services/auth/auth.service.ts +989 -989
- package/src/services/auth/auth.v2.service.ts +961 -961
- package/src/services/auth/index.ts +7 -7
- package/src/services/auth/utils/error.utils.ts +90 -90
- package/src/services/auth/utils/firebase.utils.ts +49 -49
- package/src/services/auth/utils/index.ts +21 -21
- package/src/services/auth/utils/practitioner.utils.ts +125 -125
- package/src/services/base.service.ts +41 -41
- package/src/services/calendar/calendar.service.ts +1077 -1077
- package/src/services/calendar/calendar.v2.service.ts +1683 -1683
- package/src/services/calendar/calendar.v3.service.ts +313 -313
- package/src/services/calendar/externalCalendar.service.ts +178 -178
- package/src/services/calendar/index.ts +5 -5
- package/src/services/calendar/synced-calendars.service.ts +743 -743
- package/src/services/calendar/utils/appointment.utils.ts +265 -265
- package/src/services/calendar/utils/calendar-event.utils.ts +646 -646
- package/src/services/calendar/utils/clinic.utils.ts +237 -237
- package/src/services/calendar/utils/docs.utils.ts +157 -157
- package/src/services/calendar/utils/google-calendar.utils.ts +697 -697
- package/src/services/calendar/utils/index.ts +8 -8
- package/src/services/calendar/utils/patient.utils.ts +198 -198
- package/src/services/calendar/utils/practitioner.utils.ts +221 -221
- package/src/services/calendar/utils/synced-calendar.utils.ts +472 -472
- package/src/services/clinic/README.md +204 -204
- package/src/services/clinic/__tests__/clinic-admin.service.test.ts +287 -287
- package/src/services/clinic/__tests__/clinic-group.service.test.ts +352 -352
- package/src/services/clinic/__tests__/clinic.service.test.ts +354 -354
- package/src/services/clinic/billing-transactions.service.ts +217 -217
- package/src/services/clinic/clinic-admin.service.ts +202 -202
- package/src/services/clinic/clinic-group.service.ts +310 -310
- package/src/services/clinic/clinic.service.ts +708 -708
- package/src/services/clinic/index.ts +5 -5
- package/src/services/clinic/practitioner-invite.service.ts +519 -519
- package/src/services/clinic/utils/admin.utils.ts +551 -551
- package/src/services/clinic/utils/clinic-group.utils.ts +646 -646
- package/src/services/clinic/utils/clinic.utils.ts +949 -949
- package/src/services/clinic/utils/filter.utils.d.ts +23 -23
- package/src/services/clinic/utils/filter.utils.ts +446 -446
- package/src/services/clinic/utils/index.ts +11 -11
- package/src/services/clinic/utils/photos.utils.ts +188 -188
- package/src/services/clinic/utils/search.utils.ts +84 -84
- package/src/services/clinic/utils/tag.utils.ts +124 -124
- package/src/services/documentation-templates/documentation-template.service.ts +537 -537
- package/src/services/documentation-templates/filled-document.service.ts +587 -587
- package/src/services/documentation-templates/index.ts +2 -2
- package/src/services/index.ts +13 -13
- package/src/services/media/index.ts +1 -1
- package/src/services/media/media.service.ts +418 -418
- package/src/services/notifications/__tests__/notification.service.test.ts +242 -242
- package/src/services/notifications/index.ts +1 -1
- package/src/services/notifications/notification.service.ts +215 -215
- package/src/services/patient/README.md +48 -48
- package/src/services/patient/To-Do.md +43 -43
- package/src/services/patient/__tests__/patient.service.test.ts +294 -294
- package/src/services/patient/index.ts +2 -2
- package/src/services/patient/patient.service.ts +883 -883
- package/src/services/patient/patientRequirements.service.ts +285 -285
- package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -176
- package/src/services/patient/utils/clinic.utils.ts +80 -80
- package/src/services/patient/utils/docs.utils.ts +142 -142
- package/src/services/patient/utils/index.ts +9 -9
- package/src/services/patient/utils/location.utils.ts +126 -126
- package/src/services/patient/utils/medical-stuff.utils.ts +143 -143
- package/src/services/patient/utils/medical.utils.ts +458 -458
- package/src/services/patient/utils/practitioner.utils.ts +260 -260
- package/src/services/patient/utils/profile.utils.ts +510 -510
- package/src/services/patient/utils/sensitive.utils.ts +260 -260
- package/src/services/patient/utils/token.utils.ts +211 -211
- package/src/services/practitioner/README.md +145 -145
- package/src/services/practitioner/index.ts +1 -1
- package/src/services/practitioner/practitioner.service.ts +1742 -1742
- package/src/services/procedure/README.md +163 -163
- package/src/services/procedure/index.ts +1 -1
- package/src/services/procedure/procedure.service.ts +1682 -1682
- package/src/services/reviews/index.ts +1 -1
- package/src/services/reviews/reviews.service.ts +636 -636
- package/src/services/user/index.ts +1 -1
- package/src/services/user/user.service.ts +489 -489
- package/src/services/user/user.v2.service.ts +466 -466
- package/src/types/appointment/index.ts +453 -453
- package/src/types/calendar/index.ts +258 -258
- package/src/types/calendar/synced-calendar.types.ts +66 -66
- package/src/types/clinic/index.ts +489 -489
- package/src/types/clinic/practitioner-invite.types.ts +91 -91
- package/src/types/clinic/preferences.types.ts +159 -159
- package/src/types/clinic/to-do +3 -3
- package/src/types/documentation-templates/index.ts +308 -308
- package/src/types/index.ts +44 -44
- package/src/types/notifications/README.md +77 -77
- package/src/types/notifications/index.ts +265 -265
- package/src/types/patient/aesthetic-analysis.types.ts +66 -66
- package/src/types/patient/allergies.ts +58 -58
- package/src/types/patient/index.ts +273 -273
- package/src/types/patient/medical-info.types.ts +152 -152
- package/src/types/patient/patient-requirements.ts +92 -81
- package/src/types/patient/token.types.ts +61 -61
- package/src/types/practitioner/index.ts +206 -206
- package/src/types/procedure/index.ts +181 -181
- package/src/types/profile/index.ts +39 -39
- package/src/types/reviews/index.ts +130 -130
- package/src/types/tz-lookup.d.ts +4 -4
- package/src/types/user/index.ts +38 -38
- package/src/utils/TIMESTAMPS.md +176 -176
- package/src/utils/TimestampUtils.ts +241 -241
- package/src/utils/index.ts +1 -1
- package/src/validations/appointment.schema.ts +574 -574
- package/src/validations/calendar.schema.ts +225 -225
- package/src/validations/clinic.schema.ts +493 -493
- package/src/validations/common.schema.ts +25 -25
- package/src/validations/documentation-templates/index.ts +1 -1
- package/src/validations/documentation-templates/template.schema.ts +220 -220
- package/src/validations/documentation-templates.schema.ts +10 -10
- package/src/validations/index.ts +20 -20
- package/src/validations/media.schema.ts +10 -10
- package/src/validations/notification.schema.ts +90 -90
- package/src/validations/patient/aesthetic-analysis.schema.ts +55 -55
- package/src/validations/patient/medical-info.schema.ts +125 -125
- package/src/validations/patient/patient-requirements.schema.ts +84 -75
- package/src/validations/patient/token.schema.ts +29 -29
- package/src/validations/patient.schema.ts +216 -216
- package/src/validations/practitioner.schema.ts +222 -222
- package/src/validations/procedure-product.schema.ts +41 -41
- package/src/validations/procedure.schema.ts +124 -124
- package/src/validations/profile-info.schema.ts +41 -41
- package/src/validations/reviews.schema.ts +189 -189
- package/src/validations/schemas.ts +104 -104
- package/src/validations/shared.schema.ts +78 -78
package/dist/admin/index.d.mts
CHANGED
|
@@ -2002,6 +2002,13 @@ declare enum PatientRequirementOverallStatus {
|
|
|
2002
2002
|
SUPERSEDED_RESCHEDULE = "supersededReschedule",// This instance was replaced by a new one due to appointment reschedule.
|
|
2003
2003
|
FAILED_TO_PROCESS = "failedToProcess"
|
|
2004
2004
|
}
|
|
2005
|
+
/**
|
|
2006
|
+
* Represents source procedure information for a requirement instance
|
|
2007
|
+
*/
|
|
2008
|
+
interface RequirementSourceProcedure {
|
|
2009
|
+
procedureId: string;
|
|
2010
|
+
procedureName: string;
|
|
2011
|
+
}
|
|
2005
2012
|
/**
|
|
2006
2013
|
* Represents an instance of a backoffice Requirement, tailored to a specific patient and appointment.
|
|
2007
2014
|
* This document lives in the patient's subcollection: `patients/{patientId}/patientRequirements/{instanceId}`.
|
|
@@ -2017,6 +2024,7 @@ interface PatientRequirementInstance {
|
|
|
2017
2024
|
requirementImportance: RequirementImportance;
|
|
2018
2025
|
overallStatus: PatientRequirementOverallStatus;
|
|
2019
2026
|
instructions: PatientRequirementInstruction[];
|
|
2027
|
+
sourceProcedures?: RequirementSourceProcedure[];
|
|
2020
2028
|
createdAt: Timestamp;
|
|
2021
2029
|
updatedAt: Timestamp;
|
|
2022
2030
|
}
|
|
@@ -2548,11 +2556,35 @@ declare class AppointmentAggregationService {
|
|
|
2548
2556
|
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
2549
2557
|
*/
|
|
2550
2558
|
private createPreAppointmentRequirementInstances;
|
|
2559
|
+
/**
|
|
2560
|
+
* Fetches post-requirements from a procedure document
|
|
2561
|
+
* @param procedureId - The procedure ID to fetch requirements from
|
|
2562
|
+
* @returns Promise resolving to array of post-requirements with source procedure info
|
|
2563
|
+
*/
|
|
2564
|
+
private fetchPostRequirementsFromProcedure;
|
|
2565
|
+
/**
|
|
2566
|
+
* Collects all post-requirements from primary and extended procedures
|
|
2567
|
+
* @param appointment - The appointment to collect requirements for
|
|
2568
|
+
* @returns Promise resolving to array of requirements with source procedures
|
|
2569
|
+
*/
|
|
2570
|
+
private collectAllPostRequirements;
|
|
2571
|
+
/**
|
|
2572
|
+
* Generates a unique key for a requirement based on ID and timeframe
|
|
2573
|
+
* @param requirement - The requirement to generate a key for
|
|
2574
|
+
* @returns Unique key string
|
|
2575
|
+
*/
|
|
2576
|
+
private getRequirementKey;
|
|
2577
|
+
/**
|
|
2578
|
+
* Deduplicates requirements based on requirement ID and timeframe
|
|
2579
|
+
* Merges source procedures when requirements match
|
|
2580
|
+
* @param requirements - Array of requirements with sources
|
|
2581
|
+
* @returns Deduplicated array of requirements
|
|
2582
|
+
*/
|
|
2583
|
+
private deduplicateRequirements;
|
|
2551
2584
|
/**
|
|
2552
2585
|
* Creates POST_APPOINTMENT PatientRequirementInstance documents for a given appointment.
|
|
2553
|
-
*
|
|
2554
|
-
*
|
|
2555
|
-
* with derived instructions and batch writes them to Firestore under the patient's `patient_requirements` subcollection.
|
|
2586
|
+
* Fetches requirements from primary and extended procedures, deduplicates them,
|
|
2587
|
+
* and creates requirement instances with source procedure tracking.
|
|
2556
2588
|
*
|
|
2557
2589
|
* @param {Appointment} appointment - The appointment for which to create post-requirement instances.
|
|
2558
2590
|
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
@@ -3728,4 +3760,4 @@ declare class UserProfileAdminService {
|
|
|
3728
3760
|
initializePractitionerRole(userId: string): Promise<User>;
|
|
3729
3761
|
}
|
|
3730
3762
|
|
|
3731
|
-
export { type Appointment, AppointmentAggregationService, type AppointmentCancellationEmailData, type AppointmentConfirmationEmailData, type AppointmentEmailDataBase, AppointmentMailingService, type AppointmentReminderNotification, type AppointmentRequestedEmailData, type AppointmentRescheduledProposalEmailData, AppointmentStatus, type AvailableSlot, BaseMailingService, type BaseNotification, type BillingInfo, type BillingTransaction, BillingTransactionType, BookingAdmin, BookingAvailabilityCalculator, type BookingAvailabilityRequest, type BookingAvailabilityResponse, CalendarAdminService, type Clinic, type ClinicAdminNotificationData, ClinicAggregationService, type ClinicInfo, type ClinicLocation, type CreateBillingTransactionData, type DoctorInfo, DocumentManagerAdminService, type ExistingPractitionerInviteEmailData, ExistingPractitionerInviteMailingService, type FilledDocument, FilledFormsAggregationService, type InitializeAppointmentFormsResult, Logger, NOTIFICATIONS_COLLECTION, type NewMailgunClient$2 as NewMailgunClient, type Notification, NotificationStatus, NotificationType, NotificationsAdmin, type OrchestrateAppointmentCreationData, PATIENTS_COLLECTION, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, PATIENT_SENSITIVE_INFO_COLLECTION, type PatientProfile as Patient, PatientAggregationService, PatientInstructionStatus, type PatientProfile, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, PatientRequirementsAdminService, type PatientSensitiveInfo, type PlanDetails, type PostRequirementNotification, type Practitioner, PractitionerAggregationService, type PractitionerInvite, PractitionerInviteAggregationService, type PractitionerInviteEmailData, PractitionerInviteMailingService, PractitionerInviteStatus, type PractitionerToken, PractitionerTokenStatus, type PreRequirementNotification, type Procedure, ProcedureAggregationService, type ProcedureSummaryInfo, type Review, type ReviewAddedEmailData, type ReviewRequestEmailData, ReviewsAggregationService, type StripeTransactionData, SubscriptionStatus, type TimeInterval, UserProfileAdminService, UserRole, freeConsultationInfrastructure };
|
|
3763
|
+
export { type Appointment, AppointmentAggregationService, type AppointmentCancellationEmailData, type AppointmentConfirmationEmailData, type AppointmentEmailDataBase, AppointmentMailingService, type AppointmentReminderNotification, type AppointmentRequestedEmailData, type AppointmentRescheduledProposalEmailData, AppointmentStatus, type AvailableSlot, BaseMailingService, type BaseNotification, type BillingInfo, type BillingTransaction, BillingTransactionType, BookingAdmin, BookingAvailabilityCalculator, type BookingAvailabilityRequest, type BookingAvailabilityResponse, CalendarAdminService, type Clinic, type ClinicAdminNotificationData, ClinicAggregationService, type ClinicInfo, type ClinicLocation, type CreateBillingTransactionData, type DoctorInfo, DocumentManagerAdminService, type ExistingPractitionerInviteEmailData, ExistingPractitionerInviteMailingService, type FilledDocument, FilledFormsAggregationService, type InitializeAppointmentFormsResult, Logger, NOTIFICATIONS_COLLECTION, type NewMailgunClient$2 as NewMailgunClient, type Notification, NotificationStatus, NotificationType, NotificationsAdmin, type OrchestrateAppointmentCreationData, PATIENTS_COLLECTION, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, PATIENT_SENSITIVE_INFO_COLLECTION, type PatientProfile as Patient, PatientAggregationService, PatientInstructionStatus, type PatientProfile, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, PatientRequirementsAdminService, type PatientSensitiveInfo, type PlanDetails, type PostRequirementNotification, type Practitioner, PractitionerAggregationService, type PractitionerInvite, PractitionerInviteAggregationService, type PractitionerInviteEmailData, PractitionerInviteMailingService, PractitionerInviteStatus, type PractitionerToken, PractitionerTokenStatus, type PreRequirementNotification, type Procedure, ProcedureAggregationService, type ProcedureSummaryInfo, type RequirementSourceProcedure, type Review, type ReviewAddedEmailData, type ReviewRequestEmailData, ReviewsAggregationService, type StripeTransactionData, SubscriptionStatus, type TimeInterval, UserProfileAdminService, UserRole, freeConsultationInfrastructure };
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -2002,6 +2002,13 @@ declare enum PatientRequirementOverallStatus {
|
|
|
2002
2002
|
SUPERSEDED_RESCHEDULE = "supersededReschedule",// This instance was replaced by a new one due to appointment reschedule.
|
|
2003
2003
|
FAILED_TO_PROCESS = "failedToProcess"
|
|
2004
2004
|
}
|
|
2005
|
+
/**
|
|
2006
|
+
* Represents source procedure information for a requirement instance
|
|
2007
|
+
*/
|
|
2008
|
+
interface RequirementSourceProcedure {
|
|
2009
|
+
procedureId: string;
|
|
2010
|
+
procedureName: string;
|
|
2011
|
+
}
|
|
2005
2012
|
/**
|
|
2006
2013
|
* Represents an instance of a backoffice Requirement, tailored to a specific patient and appointment.
|
|
2007
2014
|
* This document lives in the patient's subcollection: `patients/{patientId}/patientRequirements/{instanceId}`.
|
|
@@ -2017,6 +2024,7 @@ interface PatientRequirementInstance {
|
|
|
2017
2024
|
requirementImportance: RequirementImportance;
|
|
2018
2025
|
overallStatus: PatientRequirementOverallStatus;
|
|
2019
2026
|
instructions: PatientRequirementInstruction[];
|
|
2027
|
+
sourceProcedures?: RequirementSourceProcedure[];
|
|
2020
2028
|
createdAt: Timestamp;
|
|
2021
2029
|
updatedAt: Timestamp;
|
|
2022
2030
|
}
|
|
@@ -2548,11 +2556,35 @@ declare class AppointmentAggregationService {
|
|
|
2548
2556
|
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
2549
2557
|
*/
|
|
2550
2558
|
private createPreAppointmentRequirementInstances;
|
|
2559
|
+
/**
|
|
2560
|
+
* Fetches post-requirements from a procedure document
|
|
2561
|
+
* @param procedureId - The procedure ID to fetch requirements from
|
|
2562
|
+
* @returns Promise resolving to array of post-requirements with source procedure info
|
|
2563
|
+
*/
|
|
2564
|
+
private fetchPostRequirementsFromProcedure;
|
|
2565
|
+
/**
|
|
2566
|
+
* Collects all post-requirements from primary and extended procedures
|
|
2567
|
+
* @param appointment - The appointment to collect requirements for
|
|
2568
|
+
* @returns Promise resolving to array of requirements with source procedures
|
|
2569
|
+
*/
|
|
2570
|
+
private collectAllPostRequirements;
|
|
2571
|
+
/**
|
|
2572
|
+
* Generates a unique key for a requirement based on ID and timeframe
|
|
2573
|
+
* @param requirement - The requirement to generate a key for
|
|
2574
|
+
* @returns Unique key string
|
|
2575
|
+
*/
|
|
2576
|
+
private getRequirementKey;
|
|
2577
|
+
/**
|
|
2578
|
+
* Deduplicates requirements based on requirement ID and timeframe
|
|
2579
|
+
* Merges source procedures when requirements match
|
|
2580
|
+
* @param requirements - Array of requirements with sources
|
|
2581
|
+
* @returns Deduplicated array of requirements
|
|
2582
|
+
*/
|
|
2583
|
+
private deduplicateRequirements;
|
|
2551
2584
|
/**
|
|
2552
2585
|
* Creates POST_APPOINTMENT PatientRequirementInstance documents for a given appointment.
|
|
2553
|
-
*
|
|
2554
|
-
*
|
|
2555
|
-
* with derived instructions and batch writes them to Firestore under the patient's `patient_requirements` subcollection.
|
|
2586
|
+
* Fetches requirements from primary and extended procedures, deduplicates them,
|
|
2587
|
+
* and creates requirement instances with source procedure tracking.
|
|
2556
2588
|
*
|
|
2557
2589
|
* @param {Appointment} appointment - The appointment for which to create post-requirement instances.
|
|
2558
2590
|
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
@@ -3728,4 +3760,4 @@ declare class UserProfileAdminService {
|
|
|
3728
3760
|
initializePractitionerRole(userId: string): Promise<User>;
|
|
3729
3761
|
}
|
|
3730
3762
|
|
|
3731
|
-
export { type Appointment, AppointmentAggregationService, type AppointmentCancellationEmailData, type AppointmentConfirmationEmailData, type AppointmentEmailDataBase, AppointmentMailingService, type AppointmentReminderNotification, type AppointmentRequestedEmailData, type AppointmentRescheduledProposalEmailData, AppointmentStatus, type AvailableSlot, BaseMailingService, type BaseNotification, type BillingInfo, type BillingTransaction, BillingTransactionType, BookingAdmin, BookingAvailabilityCalculator, type BookingAvailabilityRequest, type BookingAvailabilityResponse, CalendarAdminService, type Clinic, type ClinicAdminNotificationData, ClinicAggregationService, type ClinicInfo, type ClinicLocation, type CreateBillingTransactionData, type DoctorInfo, DocumentManagerAdminService, type ExistingPractitionerInviteEmailData, ExistingPractitionerInviteMailingService, type FilledDocument, FilledFormsAggregationService, type InitializeAppointmentFormsResult, Logger, NOTIFICATIONS_COLLECTION, type NewMailgunClient$2 as NewMailgunClient, type Notification, NotificationStatus, NotificationType, NotificationsAdmin, type OrchestrateAppointmentCreationData, PATIENTS_COLLECTION, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, PATIENT_SENSITIVE_INFO_COLLECTION, type PatientProfile as Patient, PatientAggregationService, PatientInstructionStatus, type PatientProfile, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, PatientRequirementsAdminService, type PatientSensitiveInfo, type PlanDetails, type PostRequirementNotification, type Practitioner, PractitionerAggregationService, type PractitionerInvite, PractitionerInviteAggregationService, type PractitionerInviteEmailData, PractitionerInviteMailingService, PractitionerInviteStatus, type PractitionerToken, PractitionerTokenStatus, type PreRequirementNotification, type Procedure, ProcedureAggregationService, type ProcedureSummaryInfo, type Review, type ReviewAddedEmailData, type ReviewRequestEmailData, ReviewsAggregationService, type StripeTransactionData, SubscriptionStatus, type TimeInterval, UserProfileAdminService, UserRole, freeConsultationInfrastructure };
|
|
3763
|
+
export { type Appointment, AppointmentAggregationService, type AppointmentCancellationEmailData, type AppointmentConfirmationEmailData, type AppointmentEmailDataBase, AppointmentMailingService, type AppointmentReminderNotification, type AppointmentRequestedEmailData, type AppointmentRescheduledProposalEmailData, AppointmentStatus, type AvailableSlot, BaseMailingService, type BaseNotification, type BillingInfo, type BillingTransaction, BillingTransactionType, BookingAdmin, BookingAvailabilityCalculator, type BookingAvailabilityRequest, type BookingAvailabilityResponse, CalendarAdminService, type Clinic, type ClinicAdminNotificationData, ClinicAggregationService, type ClinicInfo, type ClinicLocation, type CreateBillingTransactionData, type DoctorInfo, DocumentManagerAdminService, type ExistingPractitionerInviteEmailData, ExistingPractitionerInviteMailingService, type FilledDocument, FilledFormsAggregationService, type InitializeAppointmentFormsResult, Logger, NOTIFICATIONS_COLLECTION, type NewMailgunClient$2 as NewMailgunClient, type Notification, NotificationStatus, NotificationType, NotificationsAdmin, type OrchestrateAppointmentCreationData, PATIENTS_COLLECTION, PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME, PATIENT_SENSITIVE_INFO_COLLECTION, type PatientProfile as Patient, PatientAggregationService, PatientInstructionStatus, type PatientProfile, type PatientRequirementInstance, type PatientRequirementInstruction, PatientRequirementOverallStatus, PatientRequirementsAdminService, type PatientSensitiveInfo, type PlanDetails, type PostRequirementNotification, type Practitioner, PractitionerAggregationService, type PractitionerInvite, PractitionerInviteAggregationService, type PractitionerInviteEmailData, PractitionerInviteMailingService, PractitionerInviteStatus, type PractitionerToken, PractitionerTokenStatus, type PreRequirementNotification, type Procedure, ProcedureAggregationService, type ProcedureSummaryInfo, type RequirementSourceProcedure, type Review, type ReviewAddedEmailData, type ReviewRequestEmailData, ReviewsAggregationService, type StripeTransactionData, SubscriptionStatus, type TimeInterval, UserProfileAdminService, UserRole, freeConsultationInfrastructure };
|
package/dist/admin/index.js
CHANGED
|
@@ -569,6 +569,9 @@ var PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME = "patientRequirements";
|
|
|
569
569
|
// src/admin/aggregation/appointment/appointment.aggregation.service.ts
|
|
570
570
|
var admin6 = __toESM(require("firebase-admin"));
|
|
571
571
|
|
|
572
|
+
// src/types/procedure/index.ts
|
|
573
|
+
var PROCEDURES_COLLECTION = "procedures";
|
|
574
|
+
|
|
572
575
|
// src/admin/requirements/patient-requirements.admin.service.ts
|
|
573
576
|
var admin3 = __toESM(require("firebase-admin"));
|
|
574
577
|
|
|
@@ -580,9 +583,6 @@ var DOCUMENTATION_TEMPLATES_COLLECTION = "documentation-templates";
|
|
|
580
583
|
var USER_FORMS_SUBCOLLECTION = "user-forms";
|
|
581
584
|
var DOCTOR_FORMS_SUBCOLLECTION = "doctor-forms";
|
|
582
585
|
|
|
583
|
-
// src/types/procedure/index.ts
|
|
584
|
-
var PROCEDURES_COLLECTION = "procedures";
|
|
585
|
-
|
|
586
586
|
// src/types/reviews/index.ts
|
|
587
587
|
var REVIEWS_COLLECTION = "reviews";
|
|
588
588
|
|
|
@@ -3193,17 +3193,122 @@ var AppointmentAggregationService = class {
|
|
|
3193
3193
|
throw error;
|
|
3194
3194
|
}
|
|
3195
3195
|
}
|
|
3196
|
+
/**
|
|
3197
|
+
* Fetches post-requirements from a procedure document
|
|
3198
|
+
* @param procedureId - The procedure ID to fetch requirements from
|
|
3199
|
+
* @returns Promise resolving to array of post-requirements with source procedure info
|
|
3200
|
+
*/
|
|
3201
|
+
async fetchPostRequirementsFromProcedure(procedureId) {
|
|
3202
|
+
try {
|
|
3203
|
+
const procedureDoc = await this.db.collection(PROCEDURES_COLLECTION).doc(procedureId).get();
|
|
3204
|
+
if (!procedureDoc.exists) {
|
|
3205
|
+
Logger.warn(`[AggService] Procedure ${procedureId} not found when fetching requirements`);
|
|
3206
|
+
return [];
|
|
3207
|
+
}
|
|
3208
|
+
const procedure = procedureDoc.data();
|
|
3209
|
+
const postRequirements = procedure.postRequirements || [];
|
|
3210
|
+
if (postRequirements.length === 0) {
|
|
3211
|
+
return [];
|
|
3212
|
+
}
|
|
3213
|
+
return postRequirements.map((req) => ({
|
|
3214
|
+
requirement: req,
|
|
3215
|
+
sourceProcedures: [
|
|
3216
|
+
{
|
|
3217
|
+
procedureId: procedure.id,
|
|
3218
|
+
procedureName: procedure.name
|
|
3219
|
+
}
|
|
3220
|
+
]
|
|
3221
|
+
}));
|
|
3222
|
+
} catch (error) {
|
|
3223
|
+
Logger.error(
|
|
3224
|
+
`[AggService] Error fetching post-requirements from procedure ${procedureId}:`,
|
|
3225
|
+
error
|
|
3226
|
+
);
|
|
3227
|
+
return [];
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
/**
|
|
3231
|
+
* Collects all post-requirements from primary and extended procedures
|
|
3232
|
+
* @param appointment - The appointment to collect requirements for
|
|
3233
|
+
* @returns Promise resolving to array of requirements with source procedures
|
|
3234
|
+
*/
|
|
3235
|
+
async collectAllPostRequirements(appointment) {
|
|
3236
|
+
var _a;
|
|
3237
|
+
const allRequirements = [];
|
|
3238
|
+
if (appointment.procedureId) {
|
|
3239
|
+
const primaryRequirements = await this.fetchPostRequirementsFromProcedure(
|
|
3240
|
+
appointment.procedureId
|
|
3241
|
+
);
|
|
3242
|
+
allRequirements.push(...primaryRequirements);
|
|
3243
|
+
}
|
|
3244
|
+
const extendedProcedures = ((_a = appointment.metadata) == null ? void 0 : _a.extendedProcedures) || [];
|
|
3245
|
+
if (extendedProcedures.length > 0) {
|
|
3246
|
+
Logger.info(
|
|
3247
|
+
`[AggService] Fetching post-requirements from ${extendedProcedures.length} extended procedures`
|
|
3248
|
+
);
|
|
3249
|
+
const extendedRequirementsPromises = extendedProcedures.map(
|
|
3250
|
+
(extProc) => this.fetchPostRequirementsFromProcedure(extProc.procedureId)
|
|
3251
|
+
);
|
|
3252
|
+
const extendedRequirementsArrays = await Promise.all(extendedRequirementsPromises);
|
|
3253
|
+
extendedRequirementsArrays.forEach((reqs) => {
|
|
3254
|
+
allRequirements.push(...reqs);
|
|
3255
|
+
});
|
|
3256
|
+
}
|
|
3257
|
+
return allRequirements;
|
|
3258
|
+
}
|
|
3259
|
+
/**
|
|
3260
|
+
* Generates a unique key for a requirement based on ID and timeframe
|
|
3261
|
+
* @param requirement - The requirement to generate a key for
|
|
3262
|
+
* @returns Unique key string
|
|
3263
|
+
*/
|
|
3264
|
+
getRequirementKey(requirement) {
|
|
3265
|
+
var _a, _b, _c;
|
|
3266
|
+
const timeframeSig = JSON.stringify({
|
|
3267
|
+
duration: ((_a = requirement.timeframe) == null ? void 0 : _a.duration) || 0,
|
|
3268
|
+
unit: ((_b = requirement.timeframe) == null ? void 0 : _b.unit) || "",
|
|
3269
|
+
notifyAt: (((_c = requirement.timeframe) == null ? void 0 : _c.notifyAt) || []).slice().sort((a, b) => a - b)
|
|
3270
|
+
});
|
|
3271
|
+
return `${requirement.id}:${timeframeSig}`;
|
|
3272
|
+
}
|
|
3273
|
+
/**
|
|
3274
|
+
* Deduplicates requirements based on requirement ID and timeframe
|
|
3275
|
+
* Merges source procedures when requirements match
|
|
3276
|
+
* @param requirements - Array of requirements with sources
|
|
3277
|
+
* @returns Deduplicated array of requirements
|
|
3278
|
+
*/
|
|
3279
|
+
deduplicateRequirements(requirements) {
|
|
3280
|
+
const requirementMap = /* @__PURE__ */ new Map();
|
|
3281
|
+
for (const reqWithSource of requirements) {
|
|
3282
|
+
const key = this.getRequirementKey(reqWithSource.requirement);
|
|
3283
|
+
if (requirementMap.has(key)) {
|
|
3284
|
+
const existing = requirementMap.get(key);
|
|
3285
|
+
const existingProcedureIds = new Set(
|
|
3286
|
+
existing.sourceProcedures.map((sp) => sp.procedureId)
|
|
3287
|
+
);
|
|
3288
|
+
reqWithSource.sourceProcedures.forEach((sp) => {
|
|
3289
|
+
if (!existingProcedureIds.has(sp.procedureId)) {
|
|
3290
|
+
existing.sourceProcedures.push(sp);
|
|
3291
|
+
}
|
|
3292
|
+
});
|
|
3293
|
+
} else {
|
|
3294
|
+
requirementMap.set(key, {
|
|
3295
|
+
requirement: reqWithSource.requirement,
|
|
3296
|
+
sourceProcedures: [...reqWithSource.sourceProcedures]
|
|
3297
|
+
});
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3300
|
+
return Array.from(requirementMap.values());
|
|
3301
|
+
}
|
|
3196
3302
|
/**
|
|
3197
3303
|
* Creates POST_APPOINTMENT PatientRequirementInstance documents for a given appointment.
|
|
3198
|
-
*
|
|
3199
|
-
*
|
|
3200
|
-
* with derived instructions and batch writes them to Firestore under the patient's `patient_requirements` subcollection.
|
|
3304
|
+
* Fetches requirements from primary and extended procedures, deduplicates them,
|
|
3305
|
+
* and creates requirement instances with source procedure tracking.
|
|
3201
3306
|
*
|
|
3202
3307
|
* @param {Appointment} appointment - The appointment for which to create post-requirement instances.
|
|
3203
3308
|
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
3204
3309
|
*/
|
|
3205
3310
|
async createPostAppointmentRequirementInstances(appointment) {
|
|
3206
|
-
var _a;
|
|
3311
|
+
var _a, _b;
|
|
3207
3312
|
Logger.info(
|
|
3208
3313
|
`[AggService] Creating POST-appointment requirement instances for appt: ${appointment.id}, patient: ${appointment.patientId}`
|
|
3209
3314
|
);
|
|
@@ -3213,32 +3318,42 @@ var AppointmentAggregationService = class {
|
|
|
3213
3318
|
);
|
|
3214
3319
|
return;
|
|
3215
3320
|
}
|
|
3216
|
-
|
|
3321
|
+
try {
|
|
3322
|
+
const allRequirements = await this.collectAllPostRequirements(appointment);
|
|
3323
|
+
if (allRequirements.length === 0) {
|
|
3324
|
+
Logger.info(
|
|
3325
|
+
`[AggService] No post-requirements found from any procedures for appointment ${appointment.id}. Nothing to create.`
|
|
3326
|
+
);
|
|
3327
|
+
return;
|
|
3328
|
+
}
|
|
3329
|
+
const deduplicatedRequirements = this.deduplicateRequirements(allRequirements);
|
|
3217
3330
|
Logger.info(
|
|
3218
|
-
`[AggService]
|
|
3331
|
+
`[AggService] Found ${allRequirements.length} total post-requirements, ${deduplicatedRequirements.length} after deduplication`
|
|
3219
3332
|
);
|
|
3220
|
-
return;
|
|
3221
|
-
}
|
|
3222
|
-
try {
|
|
3223
|
-
const batch = this.db.batch();
|
|
3224
|
-
let instancesCreatedCount = 0;
|
|
3225
|
-
let createdInstances = [];
|
|
3226
3333
|
Logger.info(
|
|
3227
|
-
`[AggService]
|
|
3228
|
-
|
|
3229
|
-
var _a2,
|
|
3334
|
+
`[AggService] Processing deduplicated post-requirements: ${JSON.stringify(
|
|
3335
|
+
deduplicatedRequirements.map((r) => {
|
|
3336
|
+
var _a2, _b2;
|
|
3230
3337
|
return {
|
|
3231
|
-
id: r.id,
|
|
3232
|
-
name: r.name,
|
|
3233
|
-
type: r.type,
|
|
3234
|
-
isActive: r.isActive,
|
|
3235
|
-
hasTimeframe: !!r.timeframe,
|
|
3236
|
-
notifyAtLength: ((
|
|
3338
|
+
id: r.requirement.id,
|
|
3339
|
+
name: r.requirement.name,
|
|
3340
|
+
type: r.requirement.type,
|
|
3341
|
+
isActive: r.requirement.isActive,
|
|
3342
|
+
hasTimeframe: !!r.requirement.timeframe,
|
|
3343
|
+
notifyAtLength: ((_b2 = (_a2 = r.requirement.timeframe) == null ? void 0 : _a2.notifyAt) == null ? void 0 : _b2.length) || 0,
|
|
3344
|
+
sourceProcedures: r.sourceProcedures.map((sp) => ({
|
|
3345
|
+
procedureId: sp.procedureId,
|
|
3346
|
+
procedureName: sp.procedureName
|
|
3347
|
+
}))
|
|
3237
3348
|
};
|
|
3238
3349
|
})
|
|
3239
3350
|
)}`
|
|
3240
3351
|
);
|
|
3241
|
-
|
|
3352
|
+
const batch = this.db.batch();
|
|
3353
|
+
let instancesCreatedCount = 0;
|
|
3354
|
+
let createdInstances = [];
|
|
3355
|
+
for (const reqWithSource of deduplicatedRequirements) {
|
|
3356
|
+
const template = reqWithSource.requirement;
|
|
3242
3357
|
if (!template) {
|
|
3243
3358
|
Logger.warn(
|
|
3244
3359
|
`[AggService] Found null/undefined template in postProcedureRequirements array`
|
|
@@ -3301,6 +3416,8 @@ var AppointmentAggregationService = class {
|
|
|
3301
3416
|
requirementImportance: template.importance,
|
|
3302
3417
|
overallStatus: "active" /* ACTIVE */,
|
|
3303
3418
|
instructions,
|
|
3419
|
+
sourceProcedures: reqWithSource.sourceProcedures,
|
|
3420
|
+
// Track which procedures this requirement comes from
|
|
3304
3421
|
createdAt: admin6.firestore.FieldValue.serverTimestamp(),
|
|
3305
3422
|
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
3306
3423
|
};
|
|
@@ -3310,7 +3427,11 @@ var AppointmentAggregationService = class {
|
|
|
3310
3427
|
patientId: newInstanceData.patientId,
|
|
3311
3428
|
appointmentId: newInstanceData.appointmentId,
|
|
3312
3429
|
requirementName: newInstanceData.requirementName,
|
|
3313
|
-
instructionsCount: newInstanceData.instructions.length
|
|
3430
|
+
instructionsCount: newInstanceData.instructions.length,
|
|
3431
|
+
sourceProcedures: ((_b = newInstanceData.sourceProcedures) == null ? void 0 : _b.map((sp) => ({
|
|
3432
|
+
procedureId: sp.procedureId,
|
|
3433
|
+
procedureName: sp.procedureName
|
|
3434
|
+
}))) || []
|
|
3314
3435
|
})}`
|
|
3315
3436
|
);
|
|
3316
3437
|
batch.set(newInstanceRef, newInstanceData);
|
|
@@ -6979,6 +7100,12 @@ var BookingAvailabilityCalculator = class {
|
|
|
6979
7100
|
console.log(
|
|
6980
7101
|
`Generating slots with ${intervalMinutes}min intervals for ${durationMinutes}min procedure in timezone ${tz}`
|
|
6981
7102
|
);
|
|
7103
|
+
const nowInClinicTz = import_luxon2.DateTime.now().setZone(tz);
|
|
7104
|
+
const MINIMUM_BOOKING_WINDOW_MINUTES = 15;
|
|
7105
|
+
const earliestBookableTime = nowInClinicTz.plus({ minutes: MINIMUM_BOOKING_WINDOW_MINUTES });
|
|
7106
|
+
console.log(
|
|
7107
|
+
`Current time in ${tz}: ${nowInClinicTz.toISO()}, earliest bookable: ${earliestBookableTime.toISO()}`
|
|
7108
|
+
);
|
|
6982
7109
|
const durationMs = durationMinutes * 60 * 1e3;
|
|
6983
7110
|
const intervalMs = intervalMinutes * 60 * 1e3;
|
|
6984
7111
|
for (const interval of intervals) {
|
|
@@ -6994,7 +7121,8 @@ var BookingAvailabilityCalculator = class {
|
|
|
6994
7121
|
}
|
|
6995
7122
|
while (slotStart.toMillis() + durationMs <= intervalEnd.getTime()) {
|
|
6996
7123
|
const slotEnd = slotStart.plus({ minutes: durationMinutes });
|
|
6997
|
-
|
|
7124
|
+
const isInFuture = slotStart >= earliestBookableTime;
|
|
7125
|
+
if (isInFuture && this.isSlotFullyAvailable(slotStart, slotEnd, intervals, tz)) {
|
|
6998
7126
|
slots.push({
|
|
6999
7127
|
start: import_firestore2.Timestamp.fromMillis(slotStart.toMillis())
|
|
7000
7128
|
});
|
|
@@ -7002,7 +7130,7 @@ var BookingAvailabilityCalculator = class {
|
|
|
7002
7130
|
slotStart = slotStart.plus({ minutes: intervalMinutes });
|
|
7003
7131
|
}
|
|
7004
7132
|
}
|
|
7005
|
-
console.log(`Generated ${slots.length} available slots`);
|
|
7133
|
+
console.log(`Generated ${slots.length} available slots (filtered for future times with ${MINIMUM_BOOKING_WINDOW_MINUTES}min minimum window)`);
|
|
7006
7134
|
return slots;
|
|
7007
7135
|
}
|
|
7008
7136
|
/**
|
package/dist/admin/index.mjs
CHANGED
|
@@ -507,6 +507,9 @@ var PATIENT_REQUIREMENTS_SUBCOLLECTION_NAME = "patientRequirements";
|
|
|
507
507
|
// src/admin/aggregation/appointment/appointment.aggregation.service.ts
|
|
508
508
|
import * as admin6 from "firebase-admin";
|
|
509
509
|
|
|
510
|
+
// src/types/procedure/index.ts
|
|
511
|
+
var PROCEDURES_COLLECTION = "procedures";
|
|
512
|
+
|
|
510
513
|
// src/admin/requirements/patient-requirements.admin.service.ts
|
|
511
514
|
import * as admin3 from "firebase-admin";
|
|
512
515
|
|
|
@@ -518,9 +521,6 @@ var DOCUMENTATION_TEMPLATES_COLLECTION = "documentation-templates";
|
|
|
518
521
|
var USER_FORMS_SUBCOLLECTION = "user-forms";
|
|
519
522
|
var DOCTOR_FORMS_SUBCOLLECTION = "doctor-forms";
|
|
520
523
|
|
|
521
|
-
// src/types/procedure/index.ts
|
|
522
|
-
var PROCEDURES_COLLECTION = "procedures";
|
|
523
|
-
|
|
524
524
|
// src/types/reviews/index.ts
|
|
525
525
|
var REVIEWS_COLLECTION = "reviews";
|
|
526
526
|
|
|
@@ -3131,17 +3131,122 @@ var AppointmentAggregationService = class {
|
|
|
3131
3131
|
throw error;
|
|
3132
3132
|
}
|
|
3133
3133
|
}
|
|
3134
|
+
/**
|
|
3135
|
+
* Fetches post-requirements from a procedure document
|
|
3136
|
+
* @param procedureId - The procedure ID to fetch requirements from
|
|
3137
|
+
* @returns Promise resolving to array of post-requirements with source procedure info
|
|
3138
|
+
*/
|
|
3139
|
+
async fetchPostRequirementsFromProcedure(procedureId) {
|
|
3140
|
+
try {
|
|
3141
|
+
const procedureDoc = await this.db.collection(PROCEDURES_COLLECTION).doc(procedureId).get();
|
|
3142
|
+
if (!procedureDoc.exists) {
|
|
3143
|
+
Logger.warn(`[AggService] Procedure ${procedureId} not found when fetching requirements`);
|
|
3144
|
+
return [];
|
|
3145
|
+
}
|
|
3146
|
+
const procedure = procedureDoc.data();
|
|
3147
|
+
const postRequirements = procedure.postRequirements || [];
|
|
3148
|
+
if (postRequirements.length === 0) {
|
|
3149
|
+
return [];
|
|
3150
|
+
}
|
|
3151
|
+
return postRequirements.map((req) => ({
|
|
3152
|
+
requirement: req,
|
|
3153
|
+
sourceProcedures: [
|
|
3154
|
+
{
|
|
3155
|
+
procedureId: procedure.id,
|
|
3156
|
+
procedureName: procedure.name
|
|
3157
|
+
}
|
|
3158
|
+
]
|
|
3159
|
+
}));
|
|
3160
|
+
} catch (error) {
|
|
3161
|
+
Logger.error(
|
|
3162
|
+
`[AggService] Error fetching post-requirements from procedure ${procedureId}:`,
|
|
3163
|
+
error
|
|
3164
|
+
);
|
|
3165
|
+
return [];
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
/**
|
|
3169
|
+
* Collects all post-requirements from primary and extended procedures
|
|
3170
|
+
* @param appointment - The appointment to collect requirements for
|
|
3171
|
+
* @returns Promise resolving to array of requirements with source procedures
|
|
3172
|
+
*/
|
|
3173
|
+
async collectAllPostRequirements(appointment) {
|
|
3174
|
+
var _a;
|
|
3175
|
+
const allRequirements = [];
|
|
3176
|
+
if (appointment.procedureId) {
|
|
3177
|
+
const primaryRequirements = await this.fetchPostRequirementsFromProcedure(
|
|
3178
|
+
appointment.procedureId
|
|
3179
|
+
);
|
|
3180
|
+
allRequirements.push(...primaryRequirements);
|
|
3181
|
+
}
|
|
3182
|
+
const extendedProcedures = ((_a = appointment.metadata) == null ? void 0 : _a.extendedProcedures) || [];
|
|
3183
|
+
if (extendedProcedures.length > 0) {
|
|
3184
|
+
Logger.info(
|
|
3185
|
+
`[AggService] Fetching post-requirements from ${extendedProcedures.length} extended procedures`
|
|
3186
|
+
);
|
|
3187
|
+
const extendedRequirementsPromises = extendedProcedures.map(
|
|
3188
|
+
(extProc) => this.fetchPostRequirementsFromProcedure(extProc.procedureId)
|
|
3189
|
+
);
|
|
3190
|
+
const extendedRequirementsArrays = await Promise.all(extendedRequirementsPromises);
|
|
3191
|
+
extendedRequirementsArrays.forEach((reqs) => {
|
|
3192
|
+
allRequirements.push(...reqs);
|
|
3193
|
+
});
|
|
3194
|
+
}
|
|
3195
|
+
return allRequirements;
|
|
3196
|
+
}
|
|
3197
|
+
/**
|
|
3198
|
+
* Generates a unique key for a requirement based on ID and timeframe
|
|
3199
|
+
* @param requirement - The requirement to generate a key for
|
|
3200
|
+
* @returns Unique key string
|
|
3201
|
+
*/
|
|
3202
|
+
getRequirementKey(requirement) {
|
|
3203
|
+
var _a, _b, _c;
|
|
3204
|
+
const timeframeSig = JSON.stringify({
|
|
3205
|
+
duration: ((_a = requirement.timeframe) == null ? void 0 : _a.duration) || 0,
|
|
3206
|
+
unit: ((_b = requirement.timeframe) == null ? void 0 : _b.unit) || "",
|
|
3207
|
+
notifyAt: (((_c = requirement.timeframe) == null ? void 0 : _c.notifyAt) || []).slice().sort((a, b) => a - b)
|
|
3208
|
+
});
|
|
3209
|
+
return `${requirement.id}:${timeframeSig}`;
|
|
3210
|
+
}
|
|
3211
|
+
/**
|
|
3212
|
+
* Deduplicates requirements based on requirement ID and timeframe
|
|
3213
|
+
* Merges source procedures when requirements match
|
|
3214
|
+
* @param requirements - Array of requirements with sources
|
|
3215
|
+
* @returns Deduplicated array of requirements
|
|
3216
|
+
*/
|
|
3217
|
+
deduplicateRequirements(requirements) {
|
|
3218
|
+
const requirementMap = /* @__PURE__ */ new Map();
|
|
3219
|
+
for (const reqWithSource of requirements) {
|
|
3220
|
+
const key = this.getRequirementKey(reqWithSource.requirement);
|
|
3221
|
+
if (requirementMap.has(key)) {
|
|
3222
|
+
const existing = requirementMap.get(key);
|
|
3223
|
+
const existingProcedureIds = new Set(
|
|
3224
|
+
existing.sourceProcedures.map((sp) => sp.procedureId)
|
|
3225
|
+
);
|
|
3226
|
+
reqWithSource.sourceProcedures.forEach((sp) => {
|
|
3227
|
+
if (!existingProcedureIds.has(sp.procedureId)) {
|
|
3228
|
+
existing.sourceProcedures.push(sp);
|
|
3229
|
+
}
|
|
3230
|
+
});
|
|
3231
|
+
} else {
|
|
3232
|
+
requirementMap.set(key, {
|
|
3233
|
+
requirement: reqWithSource.requirement,
|
|
3234
|
+
sourceProcedures: [...reqWithSource.sourceProcedures]
|
|
3235
|
+
});
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
return Array.from(requirementMap.values());
|
|
3239
|
+
}
|
|
3134
3240
|
/**
|
|
3135
3241
|
* Creates POST_APPOINTMENT PatientRequirementInstance documents for a given appointment.
|
|
3136
|
-
*
|
|
3137
|
-
*
|
|
3138
|
-
* with derived instructions and batch writes them to Firestore under the patient's `patient_requirements` subcollection.
|
|
3242
|
+
* Fetches requirements from primary and extended procedures, deduplicates them,
|
|
3243
|
+
* and creates requirement instances with source procedure tracking.
|
|
3139
3244
|
*
|
|
3140
3245
|
* @param {Appointment} appointment - The appointment for which to create post-requirement instances.
|
|
3141
3246
|
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
3142
3247
|
*/
|
|
3143
3248
|
async createPostAppointmentRequirementInstances(appointment) {
|
|
3144
|
-
var _a;
|
|
3249
|
+
var _a, _b;
|
|
3145
3250
|
Logger.info(
|
|
3146
3251
|
`[AggService] Creating POST-appointment requirement instances for appt: ${appointment.id}, patient: ${appointment.patientId}`
|
|
3147
3252
|
);
|
|
@@ -3151,32 +3256,42 @@ var AppointmentAggregationService = class {
|
|
|
3151
3256
|
);
|
|
3152
3257
|
return;
|
|
3153
3258
|
}
|
|
3154
|
-
|
|
3259
|
+
try {
|
|
3260
|
+
const allRequirements = await this.collectAllPostRequirements(appointment);
|
|
3261
|
+
if (allRequirements.length === 0) {
|
|
3262
|
+
Logger.info(
|
|
3263
|
+
`[AggService] No post-requirements found from any procedures for appointment ${appointment.id}. Nothing to create.`
|
|
3264
|
+
);
|
|
3265
|
+
return;
|
|
3266
|
+
}
|
|
3267
|
+
const deduplicatedRequirements = this.deduplicateRequirements(allRequirements);
|
|
3155
3268
|
Logger.info(
|
|
3156
|
-
`[AggService]
|
|
3269
|
+
`[AggService] Found ${allRequirements.length} total post-requirements, ${deduplicatedRequirements.length} after deduplication`
|
|
3157
3270
|
);
|
|
3158
|
-
return;
|
|
3159
|
-
}
|
|
3160
|
-
try {
|
|
3161
|
-
const batch = this.db.batch();
|
|
3162
|
-
let instancesCreatedCount = 0;
|
|
3163
|
-
let createdInstances = [];
|
|
3164
3271
|
Logger.info(
|
|
3165
|
-
`[AggService]
|
|
3166
|
-
|
|
3167
|
-
var _a2,
|
|
3272
|
+
`[AggService] Processing deduplicated post-requirements: ${JSON.stringify(
|
|
3273
|
+
deduplicatedRequirements.map((r) => {
|
|
3274
|
+
var _a2, _b2;
|
|
3168
3275
|
return {
|
|
3169
|
-
id: r.id,
|
|
3170
|
-
name: r.name,
|
|
3171
|
-
type: r.type,
|
|
3172
|
-
isActive: r.isActive,
|
|
3173
|
-
hasTimeframe: !!r.timeframe,
|
|
3174
|
-
notifyAtLength: ((
|
|
3276
|
+
id: r.requirement.id,
|
|
3277
|
+
name: r.requirement.name,
|
|
3278
|
+
type: r.requirement.type,
|
|
3279
|
+
isActive: r.requirement.isActive,
|
|
3280
|
+
hasTimeframe: !!r.requirement.timeframe,
|
|
3281
|
+
notifyAtLength: ((_b2 = (_a2 = r.requirement.timeframe) == null ? void 0 : _a2.notifyAt) == null ? void 0 : _b2.length) || 0,
|
|
3282
|
+
sourceProcedures: r.sourceProcedures.map((sp) => ({
|
|
3283
|
+
procedureId: sp.procedureId,
|
|
3284
|
+
procedureName: sp.procedureName
|
|
3285
|
+
}))
|
|
3175
3286
|
};
|
|
3176
3287
|
})
|
|
3177
3288
|
)}`
|
|
3178
3289
|
);
|
|
3179
|
-
|
|
3290
|
+
const batch = this.db.batch();
|
|
3291
|
+
let instancesCreatedCount = 0;
|
|
3292
|
+
let createdInstances = [];
|
|
3293
|
+
for (const reqWithSource of deduplicatedRequirements) {
|
|
3294
|
+
const template = reqWithSource.requirement;
|
|
3180
3295
|
if (!template) {
|
|
3181
3296
|
Logger.warn(
|
|
3182
3297
|
`[AggService] Found null/undefined template in postProcedureRequirements array`
|
|
@@ -3239,6 +3354,8 @@ var AppointmentAggregationService = class {
|
|
|
3239
3354
|
requirementImportance: template.importance,
|
|
3240
3355
|
overallStatus: "active" /* ACTIVE */,
|
|
3241
3356
|
instructions,
|
|
3357
|
+
sourceProcedures: reqWithSource.sourceProcedures,
|
|
3358
|
+
// Track which procedures this requirement comes from
|
|
3242
3359
|
createdAt: admin6.firestore.FieldValue.serverTimestamp(),
|
|
3243
3360
|
updatedAt: admin6.firestore.FieldValue.serverTimestamp()
|
|
3244
3361
|
};
|
|
@@ -3248,7 +3365,11 @@ var AppointmentAggregationService = class {
|
|
|
3248
3365
|
patientId: newInstanceData.patientId,
|
|
3249
3366
|
appointmentId: newInstanceData.appointmentId,
|
|
3250
3367
|
requirementName: newInstanceData.requirementName,
|
|
3251
|
-
instructionsCount: newInstanceData.instructions.length
|
|
3368
|
+
instructionsCount: newInstanceData.instructions.length,
|
|
3369
|
+
sourceProcedures: ((_b = newInstanceData.sourceProcedures) == null ? void 0 : _b.map((sp) => ({
|
|
3370
|
+
procedureId: sp.procedureId,
|
|
3371
|
+
procedureName: sp.procedureName
|
|
3372
|
+
}))) || []
|
|
3252
3373
|
})}`
|
|
3253
3374
|
);
|
|
3254
3375
|
batch.set(newInstanceRef, newInstanceData);
|
|
@@ -6917,6 +7038,12 @@ var BookingAvailabilityCalculator = class {
|
|
|
6917
7038
|
console.log(
|
|
6918
7039
|
`Generating slots with ${intervalMinutes}min intervals for ${durationMinutes}min procedure in timezone ${tz}`
|
|
6919
7040
|
);
|
|
7041
|
+
const nowInClinicTz = DateTime2.now().setZone(tz);
|
|
7042
|
+
const MINIMUM_BOOKING_WINDOW_MINUTES = 15;
|
|
7043
|
+
const earliestBookableTime = nowInClinicTz.plus({ minutes: MINIMUM_BOOKING_WINDOW_MINUTES });
|
|
7044
|
+
console.log(
|
|
7045
|
+
`Current time in ${tz}: ${nowInClinicTz.toISO()}, earliest bookable: ${earliestBookableTime.toISO()}`
|
|
7046
|
+
);
|
|
6920
7047
|
const durationMs = durationMinutes * 60 * 1e3;
|
|
6921
7048
|
const intervalMs = intervalMinutes * 60 * 1e3;
|
|
6922
7049
|
for (const interval of intervals) {
|
|
@@ -6932,7 +7059,8 @@ var BookingAvailabilityCalculator = class {
|
|
|
6932
7059
|
}
|
|
6933
7060
|
while (slotStart.toMillis() + durationMs <= intervalEnd.getTime()) {
|
|
6934
7061
|
const slotEnd = slotStart.plus({ minutes: durationMinutes });
|
|
6935
|
-
|
|
7062
|
+
const isInFuture = slotStart >= earliestBookableTime;
|
|
7063
|
+
if (isInFuture && this.isSlotFullyAvailable(slotStart, slotEnd, intervals, tz)) {
|
|
6936
7064
|
slots.push({
|
|
6937
7065
|
start: Timestamp.fromMillis(slotStart.toMillis())
|
|
6938
7066
|
});
|
|
@@ -6940,7 +7068,7 @@ var BookingAvailabilityCalculator = class {
|
|
|
6940
7068
|
slotStart = slotStart.plus({ minutes: intervalMinutes });
|
|
6941
7069
|
}
|
|
6942
7070
|
}
|
|
6943
|
-
console.log(`Generated ${slots.length} available slots`);
|
|
7071
|
+
console.log(`Generated ${slots.length} available slots (filtered for future times with ${MINIMUM_BOOKING_WINDOW_MINUTES}min minimum window)`);
|
|
6944
7072
|
return slots;
|
|
6945
7073
|
}
|
|
6946
7074
|
/**
|