@blackcode_sa/metaestetics-api 1.13.4 → 1.13.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +15 -28
- package/dist/admin/index.d.ts +15 -28
- package/dist/index.d.mts +16 -29
- package/dist/index.d.ts +16 -29
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/package.json +121 -119
- package/src/__mocks__/firstore.ts +10 -10
- package/src/admin/aggregation/README.md +79 -79
- package/src/admin/aggregation/appointment/README.md +128 -128
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +1984 -1984
- package/src/admin/aggregation/appointment/index.ts +1 -1
- package/src/admin/aggregation/clinic/README.md +52 -52
- package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +703 -703
- package/src/admin/aggregation/clinic/index.ts +1 -1
- package/src/admin/aggregation/forms/README.md +13 -13
- package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +322 -322
- package/src/admin/aggregation/forms/index.ts +1 -1
- package/src/admin/aggregation/index.ts +8 -8
- package/src/admin/aggregation/patient/README.md +27 -27
- package/src/admin/aggregation/patient/index.ts +1 -1
- package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -141
- package/src/admin/aggregation/practitioner/README.md +42 -42
- package/src/admin/aggregation/practitioner/index.ts +1 -1
- package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -433
- package/src/admin/aggregation/practitioner-invite/index.ts +1 -1
- package/src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts +961 -961
- package/src/admin/aggregation/procedure/README.md +43 -43
- package/src/admin/aggregation/procedure/index.ts +1 -1
- package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +702 -702
- package/src/admin/aggregation/reviews/index.ts +1 -1
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +689 -689
- package/src/admin/analytics/analytics.admin.service.ts +278 -278
- package/src/admin/analytics/index.ts +2 -2
- package/src/admin/booking/README.md +125 -125
- package/src/admin/booking/booking.admin.ts +1037 -1037
- package/src/admin/booking/booking.calculator.ts +712 -712
- package/src/admin/booking/booking.types.ts +59 -59
- package/src/admin/booking/index.ts +3 -3
- package/src/admin/booking/timezones-problem.md +185 -185
- package/src/admin/calendar/README.md +7 -7
- package/src/admin/calendar/calendar.admin.service.ts +345 -345
- package/src/admin/calendar/index.ts +1 -1
- package/src/admin/documentation-templates/document-manager.admin.ts +260 -260
- package/src/admin/documentation-templates/index.ts +1 -1
- package/src/admin/free-consultation/free-consultation-utils.admin.ts +148 -148
- package/src/admin/free-consultation/index.ts +1 -1
- package/src/admin/index.ts +81 -81
- package/src/admin/logger/index.ts +78 -78
- package/src/admin/mailing/README.md +95 -95
- package/src/admin/mailing/appointment/appointment.mailing.service.ts +732 -732
- package/src/admin/mailing/appointment/index.ts +1 -1
- package/src/admin/mailing/appointment/templates/patient/appointment-confirmed.html +40 -40
- package/src/admin/mailing/base.mailing.service.ts +208 -208
- package/src/admin/mailing/index.ts +3 -3
- package/src/admin/mailing/practitionerInvite/existing-practitioner-invite.mailing.ts +611 -611
- package/src/admin/mailing/practitionerInvite/index.ts +2 -2
- package/src/admin/mailing/practitionerInvite/practitionerInvite.mailing.ts +395 -395
- package/src/admin/mailing/practitionerInvite/templates/existing-practitioner-invitation.template.ts +155 -155
- package/src/admin/mailing/practitionerInvite/templates/invitation.template.ts +101 -101
- package/src/admin/mailing/practitionerInvite/templates/invite-accepted-notification.template.ts +228 -228
- package/src/admin/mailing/practitionerInvite/templates/invite-rejected-notification.template.ts +242 -242
- package/src/admin/notifications/index.ts +1 -1
- package/src/admin/notifications/notifications.admin.ts +710 -710
- package/src/admin/requirements/README.md +128 -128
- package/src/admin/requirements/index.ts +1 -1
- package/src/admin/requirements/patient-requirements.admin.service.ts +475 -475
- package/src/admin/users/index.ts +1 -1
- package/src/admin/users/user-profile.admin.ts +405 -405
- package/src/backoffice/constants/certification.constants.ts +13 -13
- package/src/backoffice/constants/index.ts +1 -1
- package/src/backoffice/errors/backoffice.errors.ts +181 -181
- package/src/backoffice/errors/index.ts +1 -1
- package/src/backoffice/expo-safe/README.md +26 -26
- package/src/backoffice/expo-safe/index.ts +41 -41
- package/src/backoffice/index.ts +5 -5
- package/src/backoffice/services/FIXES_README.md +102 -102
- package/src/backoffice/services/README.md +57 -57
- package/src/backoffice/services/analytics.service.proposal.md +863 -863
- package/src/backoffice/services/analytics.service.summary.md +143 -143
- package/src/backoffice/services/brand.service.ts +256 -256
- package/src/backoffice/services/category.service.ts +384 -384
- package/src/backoffice/services/constants.service.ts +385 -385
- package/src/backoffice/services/documentation-template.service.ts +202 -202
- package/src/backoffice/services/index.ts +10 -10
- package/src/backoffice/services/migrate-products.ts +116 -116
- package/src/backoffice/services/product.service.ts +553 -553
- package/src/backoffice/services/requirement.service.ts +235 -235
- package/src/backoffice/services/subcategory.service.ts +461 -461
- package/src/backoffice/services/technology.service.ts +1151 -1151
- package/src/backoffice/types/README.md +12 -12
- package/src/backoffice/types/admin-constants.types.ts +69 -69
- package/src/backoffice/types/brand.types.ts +29 -29
- package/src/backoffice/types/category.types.ts +67 -67
- package/src/backoffice/types/documentation-templates.types.ts +28 -28
- package/src/backoffice/types/index.ts +10 -10
- package/src/backoffice/types/procedure-product.types.ts +38 -38
- package/src/backoffice/types/product.types.ts +240 -240
- package/src/backoffice/types/requirement.types.ts +63 -63
- package/src/backoffice/types/static/README.md +18 -18
- package/src/backoffice/types/static/blocking-condition.types.ts +21 -21
- package/src/backoffice/types/static/certification.types.ts +37 -37
- package/src/backoffice/types/static/contraindication.types.ts +19 -19
- package/src/backoffice/types/static/index.ts +6 -6
- package/src/backoffice/types/static/pricing.types.ts +16 -16
- package/src/backoffice/types/static/procedure-family.types.ts +14 -14
- package/src/backoffice/types/static/treatment-benefit.types.ts +22 -22
- package/src/backoffice/types/subcategory.types.ts +34 -34
- package/src/backoffice/types/technology.types.ts +168 -168
- package/src/backoffice/validations/index.ts +1 -1
- package/src/backoffice/validations/schemas.ts +164 -164
- package/src/config/__mocks__/firebase.ts +99 -99
- package/src/config/firebase.ts +78 -78
- package/src/config/index.ts +9 -9
- package/src/errors/auth.error.ts +6 -6
- package/src/errors/auth.errors.ts +200 -200
- package/src/errors/clinic.errors.ts +32 -32
- package/src/errors/firebase.errors.ts +47 -47
- package/src/errors/user.errors.ts +99 -99
- package/src/index.backup.ts +407 -407
- package/src/index.ts +6 -6
- package/src/locales/en.ts +31 -31
- package/src/recommender/admin/index.ts +1 -1
- package/src/recommender/admin/services/recommender.service.admin.ts +5 -5
- package/src/recommender/front/index.ts +1 -1
- package/src/recommender/front/services/onboarding.service.ts +5 -5
- package/src/recommender/front/services/recommender.service.ts +3 -3
- package/src/recommender/index.ts +1 -1
- package/src/services/PATIENTAUTH.MD +197 -197
- package/src/services/README.md +106 -106
- package/src/services/__tests__/auth/auth.mock.test.ts +17 -17
- package/src/services/__tests__/auth/auth.setup.ts +293 -293
- package/src/services/__tests__/auth.service.test.ts +346 -346
- package/src/services/__tests__/base.service.test.ts +77 -77
- package/src/services/__tests__/user.service.test.ts +528 -528
- package/src/services/analytics/ARCHITECTURE.md +199 -199
- package/src/services/analytics/CLOUD_FUNCTIONS.md +225 -225
- package/src/services/analytics/GROUPED_ANALYTICS.md +501 -501
- package/src/services/analytics/QUICK_START.md +393 -393
- package/src/services/analytics/README.md +304 -304
- package/src/services/analytics/SUMMARY.md +141 -141
- package/src/services/analytics/TRENDS.md +380 -380
- package/src/services/analytics/USAGE_GUIDE.md +518 -518
- package/src/services/analytics/analytics-cloud.service.ts +222 -222
- package/src/services/analytics/analytics.service.ts +2142 -2142
- package/src/services/analytics/index.ts +4 -4
- package/src/services/analytics/review-analytics.service.ts +941 -941
- package/src/services/analytics/utils/appointment-filtering.utils.ts +138 -138
- package/src/services/analytics/utils/cost-calculation.utils.ts +182 -182
- package/src/services/analytics/utils/grouping.utils.ts +434 -434
- package/src/services/analytics/utils/stored-analytics.utils.ts +347 -347
- package/src/services/analytics/utils/time-calculation.utils.ts +186 -186
- package/src/services/analytics/utils/trend-calculation.utils.ts +200 -200
- package/src/services/appointment/README.md +17 -17
- package/src/services/appointment/appointment.service.ts +2558 -2558
- package/src/services/appointment/index.ts +1 -1
- package/src/services/appointment/utils/appointment.utils.ts +552 -552
- package/src/services/appointment/utils/extended-procedure.utils.ts +314 -314
- package/src/services/appointment/utils/form-initialization.utils.ts +225 -225
- package/src/services/appointment/utils/recommended-procedure.utils.ts +195 -195
- package/src/services/appointment/utils/zone-management.utils.ts +353 -353
- package/src/services/appointment/utils/zone-photo.utils.ts +152 -152
- package/src/services/auth/auth.service.ts +989 -989
- package/src/services/auth/auth.v2.service.ts +961 -961
- package/src/services/auth/index.ts +7 -7
- package/src/services/auth/utils/error.utils.ts +90 -90
- package/src/services/auth/utils/firebase.utils.ts +49 -49
- package/src/services/auth/utils/index.ts +21 -21
- package/src/services/auth/utils/practitioner.utils.ts +125 -125
- package/src/services/base.service.ts +41 -41
- package/src/services/calendar/calendar.service.ts +1077 -1077
- package/src/services/calendar/calendar.v2.service.ts +1683 -1683
- package/src/services/calendar/calendar.v3.service.ts +313 -313
- package/src/services/calendar/externalCalendar.service.ts +178 -178
- package/src/services/calendar/index.ts +5 -5
- package/src/services/calendar/synced-calendars.service.ts +743 -743
- package/src/services/calendar/utils/appointment.utils.ts +265 -265
- package/src/services/calendar/utils/calendar-event.utils.ts +646 -646
- package/src/services/calendar/utils/clinic.utils.ts +237 -237
- package/src/services/calendar/utils/docs.utils.ts +157 -157
- package/src/services/calendar/utils/google-calendar.utils.ts +697 -697
- package/src/services/calendar/utils/index.ts +8 -8
- package/src/services/calendar/utils/patient.utils.ts +198 -198
- package/src/services/calendar/utils/practitioner.utils.ts +221 -221
- package/src/services/calendar/utils/synced-calendar.utils.ts +472 -472
- package/src/services/clinic/README.md +204 -204
- package/src/services/clinic/__tests__/clinic-admin.service.test.ts +287 -287
- package/src/services/clinic/__tests__/clinic-group.service.test.ts +352 -352
- package/src/services/clinic/__tests__/clinic.service.test.ts +354 -354
- package/src/services/clinic/billing-transactions.service.ts +217 -217
- package/src/services/clinic/clinic-admin.service.ts +202 -202
- package/src/services/clinic/clinic-group.service.ts +310 -310
- package/src/services/clinic/clinic.service.ts +708 -708
- package/src/services/clinic/index.ts +5 -5
- package/src/services/clinic/practitioner-invite.service.ts +519 -519
- package/src/services/clinic/utils/admin.utils.ts +551 -551
- package/src/services/clinic/utils/clinic-group.utils.ts +646 -646
- package/src/services/clinic/utils/clinic.utils.ts +949 -949
- package/src/services/clinic/utils/filter.utils.d.ts +23 -23
- package/src/services/clinic/utils/filter.utils.ts +446 -446
- package/src/services/clinic/utils/index.ts +11 -11
- package/src/services/clinic/utils/photos.utils.ts +188 -188
- package/src/services/clinic/utils/search.utils.ts +84 -84
- package/src/services/clinic/utils/tag.utils.ts +124 -124
- package/src/services/documentation-templates/documentation-template.service.ts +537 -537
- package/src/services/documentation-templates/filled-document.service.ts +587 -587
- package/src/services/documentation-templates/index.ts +2 -2
- package/src/services/index.ts +14 -14
- package/src/services/media/index.ts +1 -1
- package/src/services/media/media.service.ts +418 -418
- package/src/services/notifications/__tests__/notification.service.test.ts +242 -242
- package/src/services/notifications/index.ts +1 -1
- package/src/services/notifications/notification.service.ts +215 -215
- package/src/services/patient/README.md +48 -48
- package/src/services/patient/To-Do.md +43 -43
- package/src/services/patient/__tests__/patient.service.test.ts +294 -294
- package/src/services/patient/index.ts +2 -2
- package/src/services/patient/patient.service.ts +883 -883
- package/src/services/patient/patientRequirements.service.ts +285 -285
- package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -176
- package/src/services/patient/utils/clinic.utils.ts +80 -80
- package/src/services/patient/utils/docs.utils.ts +142 -142
- package/src/services/patient/utils/index.ts +9 -9
- package/src/services/patient/utils/location.utils.ts +126 -126
- package/src/services/patient/utils/medical-stuff.utils.ts +143 -143
- package/src/services/patient/utils/medical.utils.ts +458 -458
- package/src/services/patient/utils/practitioner.utils.ts +260 -260
- package/src/services/patient/utils/profile.utils.ts +510 -510
- package/src/services/patient/utils/sensitive.utils.ts +260 -260
- package/src/services/patient/utils/token.utils.ts +211 -211
- package/src/services/practitioner/README.md +145 -145
- package/src/services/practitioner/index.ts +1 -1
- package/src/services/practitioner/practitioner.service.ts +1742 -1742
- package/src/services/procedure/README.md +163 -163
- package/src/services/procedure/index.ts +1 -1
- package/src/services/procedure/procedure.service.ts +2200 -2200
- package/src/services/reviews/index.ts +1 -1
- package/src/services/reviews/reviews.service.ts +734 -734
- package/src/services/user/index.ts +1 -1
- package/src/services/user/user.service.ts +489 -489
- package/src/services/user/user.v2.service.ts +466 -466
- package/src/types/analytics/analytics.types.ts +597 -597
- package/src/types/analytics/grouped-analytics.types.ts +173 -173
- package/src/types/analytics/index.ts +4 -4
- package/src/types/analytics/stored-analytics.types.ts +137 -137
- package/src/types/appointment/index.ts +480 -480
- package/src/types/calendar/index.ts +258 -258
- package/src/types/calendar/synced-calendar.types.ts +66 -66
- package/src/types/clinic/index.ts +498 -489
- package/src/types/clinic/practitioner-invite.types.ts +91 -91
- package/src/types/clinic/preferences.types.ts +159 -159
- package/src/types/clinic/to-do +3 -3
- package/src/types/documentation-templates/index.ts +308 -308
- package/src/types/index.ts +47 -47
- package/src/types/notifications/README.md +77 -77
- package/src/types/notifications/index.ts +286 -286
- package/src/types/patient/aesthetic-analysis.types.ts +66 -66
- package/src/types/patient/allergies.ts +58 -58
- package/src/types/patient/index.ts +275 -275
- package/src/types/patient/medical-info.types.ts +152 -152
- package/src/types/patient/patient-requirements.ts +92 -92
- package/src/types/patient/token.types.ts +61 -61
- package/src/types/practitioner/index.ts +206 -206
- package/src/types/procedure/index.ts +181 -181
- package/src/types/profile/index.ts +39 -39
- package/src/types/reviews/index.ts +132 -132
- package/src/types/tz-lookup.d.ts +4 -4
- package/src/types/user/index.ts +38 -38
- package/src/utils/TIMESTAMPS.md +176 -176
- package/src/utils/TimestampUtils.ts +241 -241
- package/src/utils/index.ts +1 -1
- package/src/validations/appointment.schema.ts +574 -574
- package/src/validations/calendar.schema.ts +225 -225
- package/src/validations/clinic.schema.ts +494 -493
- package/src/validations/common.schema.ts +25 -25
- package/src/validations/documentation-templates/index.ts +1 -1
- package/src/validations/documentation-templates/template.schema.ts +220 -220
- package/src/validations/documentation-templates.schema.ts +10 -10
- package/src/validations/index.ts +20 -20
- package/src/validations/media.schema.ts +10 -10
- package/src/validations/notification.schema.ts +90 -90
- package/src/validations/patient/aesthetic-analysis.schema.ts +55 -55
- package/src/validations/patient/medical-info.schema.ts +125 -125
- package/src/validations/patient/patient-requirements.schema.ts +84 -84
- package/src/validations/patient/token.schema.ts +29 -29
- package/src/validations/patient.schema.ts +217 -217
- package/src/validations/practitioner.schema.ts +222 -222
- package/src/validations/procedure-product.schema.ts +41 -41
- package/src/validations/procedure.schema.ts +124 -124
- package/src/validations/profile-info.schema.ts +41 -41
- package/src/validations/reviews.schema.ts +195 -195
- package/src/validations/schemas.ts +104 -104
- package/src/validations/shared.schema.ts +78 -78
|
@@ -1,278 +1,278 @@
|
|
|
1
|
-
import * as admin from 'firebase-admin';
|
|
2
|
-
import { AnalyticsService } from '../../services/analytics/analytics.service';
|
|
3
|
-
import {
|
|
4
|
-
AnalyticsDateRange,
|
|
5
|
-
AnalyticsFilters,
|
|
6
|
-
EntityType,
|
|
7
|
-
} from '../../types/analytics';
|
|
8
|
-
import {
|
|
9
|
-
PractitionerAnalytics,
|
|
10
|
-
ProcedureAnalytics,
|
|
11
|
-
TimeEfficiencyMetrics,
|
|
12
|
-
CancellationMetrics,
|
|
13
|
-
NoShowMetrics,
|
|
14
|
-
RevenueMetrics,
|
|
15
|
-
ProductUsageMetrics,
|
|
16
|
-
PatientAnalytics,
|
|
17
|
-
ClinicAnalytics,
|
|
18
|
-
DashboardAnalytics,
|
|
19
|
-
GroupedRevenueMetrics,
|
|
20
|
-
GroupedProductUsageMetrics,
|
|
21
|
-
GroupedTimeEfficiencyMetrics,
|
|
22
|
-
GroupedPatientBehaviorMetrics,
|
|
23
|
-
} from '../../types/analytics';
|
|
24
|
-
import { Appointment } from '../../types/appointment';
|
|
25
|
-
import { APPOINTMENTS_COLLECTION } from '../../types/appointment';
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Admin version of AnalyticsService that uses Firebase Admin SDK
|
|
29
|
-
* This is intended for use in Cloud Functions and server-side code
|
|
30
|
-
*/
|
|
31
|
-
export class AnalyticsAdminService {
|
|
32
|
-
private analyticsService: AnalyticsService;
|
|
33
|
-
private db: admin.firestore.Firestore;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Creates a new AnalyticsAdminService instance
|
|
37
|
-
*
|
|
38
|
-
* @param firestore - Admin Firestore instance (optional, defaults to admin.firestore())
|
|
39
|
-
*/
|
|
40
|
-
constructor(firestore?: admin.firestore.Firestore) {
|
|
41
|
-
this.db = firestore || admin.firestore();
|
|
42
|
-
|
|
43
|
-
// Create a mock Firebase App for client SDK compatibility
|
|
44
|
-
const mockApp = {
|
|
45
|
-
name: '[DEFAULT]',
|
|
46
|
-
options: {},
|
|
47
|
-
automaticDataCollectionEnabled: false,
|
|
48
|
-
} as any;
|
|
49
|
-
|
|
50
|
-
// Create mock Auth (not used by AnalyticsService)
|
|
51
|
-
const mockAuth = {} as any;
|
|
52
|
-
|
|
53
|
-
// Create AppointmentService adapter that uses admin SDK
|
|
54
|
-
const appointmentService = this.createAppointmentServiceAdapter();
|
|
55
|
-
|
|
56
|
-
// Initialize AnalyticsService with adapted dependencies
|
|
57
|
-
this.analyticsService = new AnalyticsService(
|
|
58
|
-
this.db as any, // Cast admin Firestore to client Firestore type
|
|
59
|
-
mockAuth,
|
|
60
|
-
mockApp,
|
|
61
|
-
appointmentService,
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Creates an adapter for AppointmentService to work with admin SDK
|
|
67
|
-
*/
|
|
68
|
-
private createAppointmentServiceAdapter(): any {
|
|
69
|
-
return {
|
|
70
|
-
searchAppointments: async (params: any) => {
|
|
71
|
-
// Build query using admin SDK
|
|
72
|
-
let query: admin.firestore.Query = this.db.collection(APPOINTMENTS_COLLECTION);
|
|
73
|
-
|
|
74
|
-
if (params.clinicBranchId) {
|
|
75
|
-
query = query.where('clinicBranchId', '==', params.clinicBranchId);
|
|
76
|
-
}
|
|
77
|
-
if (params.practitionerId) {
|
|
78
|
-
query = query.where('practitionerId', '==', params.practitionerId);
|
|
79
|
-
}
|
|
80
|
-
if (params.procedureId) {
|
|
81
|
-
query = query.where('procedureId', '==', params.procedureId);
|
|
82
|
-
}
|
|
83
|
-
if (params.patientId) {
|
|
84
|
-
query = query.where('patientId', '==', params.patientId);
|
|
85
|
-
}
|
|
86
|
-
if (params.startDate) {
|
|
87
|
-
const startDate = params.startDate instanceof Date
|
|
88
|
-
? params.startDate
|
|
89
|
-
: params.startDate.toDate();
|
|
90
|
-
const startTimestamp = admin.firestore.Timestamp.fromDate(startDate);
|
|
91
|
-
query = query.where('appointmentStartTime', '>=', startTimestamp);
|
|
92
|
-
}
|
|
93
|
-
if (params.endDate) {
|
|
94
|
-
const endDate = params.endDate instanceof Date
|
|
95
|
-
? params.endDate
|
|
96
|
-
: params.endDate.toDate();
|
|
97
|
-
const endTimestamp = admin.firestore.Timestamp.fromDate(endDate);
|
|
98
|
-
query = query.where('appointmentStartTime', '<=', endTimestamp);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const snapshot = await query.get();
|
|
102
|
-
const appointments = snapshot.docs.map(doc => ({
|
|
103
|
-
id: doc.id,
|
|
104
|
-
...doc.data(),
|
|
105
|
-
})) as Appointment[];
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
appointments,
|
|
109
|
-
total: appointments.length,
|
|
110
|
-
};
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Delegate all methods to the underlying AnalyticsService
|
|
116
|
-
// We expose them here so they can be called with admin SDK context
|
|
117
|
-
|
|
118
|
-
async getPractitionerAnalytics(
|
|
119
|
-
practitionerId: string,
|
|
120
|
-
dateRange?: AnalyticsDateRange,
|
|
121
|
-
options?: any,
|
|
122
|
-
): Promise<PractitionerAnalytics> {
|
|
123
|
-
return this.analyticsService.getPractitionerAnalytics(practitionerId, dateRange, options);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async getProcedureAnalytics(
|
|
127
|
-
procedureId?: string,
|
|
128
|
-
dateRange?: AnalyticsDateRange,
|
|
129
|
-
options?: any,
|
|
130
|
-
): Promise<ProcedureAnalytics | ProcedureAnalytics[]> {
|
|
131
|
-
return this.analyticsService.getProcedureAnalytics(procedureId, dateRange, options);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async getTimeEfficiencyMetrics(
|
|
135
|
-
filters?: AnalyticsFilters,
|
|
136
|
-
dateRange?: AnalyticsDateRange,
|
|
137
|
-
options?: any,
|
|
138
|
-
): Promise<TimeEfficiencyMetrics> {
|
|
139
|
-
return this.analyticsService.getTimeEfficiencyMetrics(filters, dateRange, options);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async getTimeEfficiencyMetricsByEntity(
|
|
143
|
-
groupBy: EntityType,
|
|
144
|
-
dateRange?: AnalyticsDateRange,
|
|
145
|
-
filters?: AnalyticsFilters,
|
|
146
|
-
): Promise<GroupedTimeEfficiencyMetrics[]> {
|
|
147
|
-
return this.analyticsService.getTimeEfficiencyMetricsByEntity(groupBy, dateRange, filters);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async getCancellationMetrics(
|
|
151
|
-
groupBy: EntityType,
|
|
152
|
-
dateRange?: AnalyticsDateRange,
|
|
153
|
-
options?: any,
|
|
154
|
-
): Promise<CancellationMetrics | CancellationMetrics[]> {
|
|
155
|
-
return this.analyticsService.getCancellationMetrics(groupBy, dateRange, options);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async getNoShowMetrics(
|
|
159
|
-
groupBy: EntityType,
|
|
160
|
-
dateRange?: AnalyticsDateRange,
|
|
161
|
-
options?: any,
|
|
162
|
-
): Promise<NoShowMetrics | NoShowMetrics[]> {
|
|
163
|
-
return this.analyticsService.getNoShowMetrics(groupBy, dateRange, options);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async getRevenueMetrics(
|
|
167
|
-
filters?: AnalyticsFilters,
|
|
168
|
-
dateRange?: AnalyticsDateRange,
|
|
169
|
-
options?: any,
|
|
170
|
-
): Promise<RevenueMetrics> {
|
|
171
|
-
return this.analyticsService.getRevenueMetrics(filters, dateRange, options);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async getRevenueMetricsByEntity(
|
|
175
|
-
groupBy: EntityType,
|
|
176
|
-
dateRange?: AnalyticsDateRange,
|
|
177
|
-
filters?: AnalyticsFilters,
|
|
178
|
-
): Promise<GroupedRevenueMetrics[]> {
|
|
179
|
-
return this.analyticsService.getRevenueMetricsByEntity(groupBy, dateRange, filters);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
async getProductUsageMetrics(
|
|
183
|
-
productId?: string,
|
|
184
|
-
dateRange?: AnalyticsDateRange,
|
|
185
|
-
): Promise<ProductUsageMetrics | ProductUsageMetrics[]> {
|
|
186
|
-
return this.analyticsService.getProductUsageMetrics(productId, dateRange);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async getProductUsageMetricsByEntity(
|
|
190
|
-
groupBy: EntityType,
|
|
191
|
-
dateRange?: AnalyticsDateRange,
|
|
192
|
-
filters?: AnalyticsFilters,
|
|
193
|
-
): Promise<GroupedProductUsageMetrics[]> {
|
|
194
|
-
return this.analyticsService.getProductUsageMetricsByEntity(groupBy, dateRange, filters);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
async getPatientAnalytics(
|
|
198
|
-
patientId?: string,
|
|
199
|
-
dateRange?: AnalyticsDateRange,
|
|
200
|
-
): Promise<PatientAnalytics | PatientAnalytics[]> {
|
|
201
|
-
return this.analyticsService.getPatientAnalytics(patientId, dateRange);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
async getPatientBehaviorMetricsByEntity(
|
|
205
|
-
groupBy: 'clinic' | 'practitioner' | 'procedure' | 'technology',
|
|
206
|
-
dateRange?: AnalyticsDateRange,
|
|
207
|
-
filters?: AnalyticsFilters,
|
|
208
|
-
): Promise<GroupedPatientBehaviorMetrics[]> {
|
|
209
|
-
return this.analyticsService.getPatientBehaviorMetricsByEntity(groupBy, dateRange, filters);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
async getClinicAnalytics(
|
|
213
|
-
clinicBranchId: string,
|
|
214
|
-
dateRange?: AnalyticsDateRange,
|
|
215
|
-
): Promise<ClinicAnalytics | ClinicAnalytics[]> {
|
|
216
|
-
// Use getDashboardData to get clinic-level analytics
|
|
217
|
-
const dashboard = await this.analyticsService.getDashboardData(
|
|
218
|
-
{ clinicBranchId },
|
|
219
|
-
dateRange,
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
// Get clinic info
|
|
223
|
-
const clinicDoc = await this.db.collection('clinics').doc(clinicBranchId).get();
|
|
224
|
-
const clinicData = clinicDoc.data();
|
|
225
|
-
const clinicName = clinicData?.name || 'Unknown';
|
|
226
|
-
|
|
227
|
-
// Convert DashboardAnalytics to ClinicAnalytics format
|
|
228
|
-
return {
|
|
229
|
-
clinicBranchId,
|
|
230
|
-
clinicName,
|
|
231
|
-
totalAppointments: dashboard.overview.totalAppointments,
|
|
232
|
-
completedAppointments: dashboard.overview.completedAppointments,
|
|
233
|
-
canceledAppointments: dashboard.overview.canceledAppointments,
|
|
234
|
-
noShowAppointments: dashboard.overview.noShowAppointments,
|
|
235
|
-
cancellationRate: dashboard.overview.cancellationRate,
|
|
236
|
-
noShowRate: dashboard.overview.noShowRate,
|
|
237
|
-
totalRevenue: dashboard.overview.totalRevenue,
|
|
238
|
-
averageRevenuePerAppointment: dashboard.overview.averageRevenuePerAppointment,
|
|
239
|
-
currency: dashboard.overview.currency,
|
|
240
|
-
practitionerCount: dashboard.overview.uniquePractitioners,
|
|
241
|
-
patientCount: dashboard.overview.uniquePatients,
|
|
242
|
-
procedureCount: dashboard.overview.uniqueProcedures,
|
|
243
|
-
topPractitioners: dashboard.practitionerMetrics.slice(0, 5).map(p => ({
|
|
244
|
-
practitionerId: p.practitionerId,
|
|
245
|
-
practitionerName: p.practitionerName,
|
|
246
|
-
appointmentCount: p.totalAppointments,
|
|
247
|
-
revenue: p.totalRevenue,
|
|
248
|
-
})),
|
|
249
|
-
topProcedures: dashboard.procedureMetrics.slice(0, 5).map(p => ({
|
|
250
|
-
procedureId: p.procedureId,
|
|
251
|
-
procedureName: p.procedureName,
|
|
252
|
-
appointmentCount: p.totalAppointments,
|
|
253
|
-
revenue: p.totalRevenue,
|
|
254
|
-
})),
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
async getDashboardData(
|
|
259
|
-
filters?: AnalyticsFilters,
|
|
260
|
-
dateRange?: AnalyticsDateRange,
|
|
261
|
-
options?: any,
|
|
262
|
-
): Promise<DashboardAnalytics> {
|
|
263
|
-
return this.analyticsService.getDashboardData(filters, dateRange, options);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Expose fetchAppointments for direct access if needed
|
|
268
|
-
* This method is used internally by AnalyticsService
|
|
269
|
-
*/
|
|
270
|
-
async fetchAppointments(
|
|
271
|
-
filters?: AnalyticsFilters,
|
|
272
|
-
dateRange?: AnalyticsDateRange,
|
|
273
|
-
): Promise<any[]> {
|
|
274
|
-
// Access the private method via the service
|
|
275
|
-
return (this.analyticsService as any).fetchAppointments(filters, dateRange);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
1
|
+
import * as admin from 'firebase-admin';
|
|
2
|
+
import { AnalyticsService } from '../../services/analytics/analytics.service';
|
|
3
|
+
import {
|
|
4
|
+
AnalyticsDateRange,
|
|
5
|
+
AnalyticsFilters,
|
|
6
|
+
EntityType,
|
|
7
|
+
} from '../../types/analytics';
|
|
8
|
+
import {
|
|
9
|
+
PractitionerAnalytics,
|
|
10
|
+
ProcedureAnalytics,
|
|
11
|
+
TimeEfficiencyMetrics,
|
|
12
|
+
CancellationMetrics,
|
|
13
|
+
NoShowMetrics,
|
|
14
|
+
RevenueMetrics,
|
|
15
|
+
ProductUsageMetrics,
|
|
16
|
+
PatientAnalytics,
|
|
17
|
+
ClinicAnalytics,
|
|
18
|
+
DashboardAnalytics,
|
|
19
|
+
GroupedRevenueMetrics,
|
|
20
|
+
GroupedProductUsageMetrics,
|
|
21
|
+
GroupedTimeEfficiencyMetrics,
|
|
22
|
+
GroupedPatientBehaviorMetrics,
|
|
23
|
+
} from '../../types/analytics';
|
|
24
|
+
import { Appointment } from '../../types/appointment';
|
|
25
|
+
import { APPOINTMENTS_COLLECTION } from '../../types/appointment';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Admin version of AnalyticsService that uses Firebase Admin SDK
|
|
29
|
+
* This is intended for use in Cloud Functions and server-side code
|
|
30
|
+
*/
|
|
31
|
+
export class AnalyticsAdminService {
|
|
32
|
+
private analyticsService: AnalyticsService;
|
|
33
|
+
private db: admin.firestore.Firestore;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Creates a new AnalyticsAdminService instance
|
|
37
|
+
*
|
|
38
|
+
* @param firestore - Admin Firestore instance (optional, defaults to admin.firestore())
|
|
39
|
+
*/
|
|
40
|
+
constructor(firestore?: admin.firestore.Firestore) {
|
|
41
|
+
this.db = firestore || admin.firestore();
|
|
42
|
+
|
|
43
|
+
// Create a mock Firebase App for client SDK compatibility
|
|
44
|
+
const mockApp = {
|
|
45
|
+
name: '[DEFAULT]',
|
|
46
|
+
options: {},
|
|
47
|
+
automaticDataCollectionEnabled: false,
|
|
48
|
+
} as any;
|
|
49
|
+
|
|
50
|
+
// Create mock Auth (not used by AnalyticsService)
|
|
51
|
+
const mockAuth = {} as any;
|
|
52
|
+
|
|
53
|
+
// Create AppointmentService adapter that uses admin SDK
|
|
54
|
+
const appointmentService = this.createAppointmentServiceAdapter();
|
|
55
|
+
|
|
56
|
+
// Initialize AnalyticsService with adapted dependencies
|
|
57
|
+
this.analyticsService = new AnalyticsService(
|
|
58
|
+
this.db as any, // Cast admin Firestore to client Firestore type
|
|
59
|
+
mockAuth,
|
|
60
|
+
mockApp,
|
|
61
|
+
appointmentService,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Creates an adapter for AppointmentService to work with admin SDK
|
|
67
|
+
*/
|
|
68
|
+
private createAppointmentServiceAdapter(): any {
|
|
69
|
+
return {
|
|
70
|
+
searchAppointments: async (params: any) => {
|
|
71
|
+
// Build query using admin SDK
|
|
72
|
+
let query: admin.firestore.Query = this.db.collection(APPOINTMENTS_COLLECTION);
|
|
73
|
+
|
|
74
|
+
if (params.clinicBranchId) {
|
|
75
|
+
query = query.where('clinicBranchId', '==', params.clinicBranchId);
|
|
76
|
+
}
|
|
77
|
+
if (params.practitionerId) {
|
|
78
|
+
query = query.where('practitionerId', '==', params.practitionerId);
|
|
79
|
+
}
|
|
80
|
+
if (params.procedureId) {
|
|
81
|
+
query = query.where('procedureId', '==', params.procedureId);
|
|
82
|
+
}
|
|
83
|
+
if (params.patientId) {
|
|
84
|
+
query = query.where('patientId', '==', params.patientId);
|
|
85
|
+
}
|
|
86
|
+
if (params.startDate) {
|
|
87
|
+
const startDate = params.startDate instanceof Date
|
|
88
|
+
? params.startDate
|
|
89
|
+
: params.startDate.toDate();
|
|
90
|
+
const startTimestamp = admin.firestore.Timestamp.fromDate(startDate);
|
|
91
|
+
query = query.where('appointmentStartTime', '>=', startTimestamp);
|
|
92
|
+
}
|
|
93
|
+
if (params.endDate) {
|
|
94
|
+
const endDate = params.endDate instanceof Date
|
|
95
|
+
? params.endDate
|
|
96
|
+
: params.endDate.toDate();
|
|
97
|
+
const endTimestamp = admin.firestore.Timestamp.fromDate(endDate);
|
|
98
|
+
query = query.where('appointmentStartTime', '<=', endTimestamp);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const snapshot = await query.get();
|
|
102
|
+
const appointments = snapshot.docs.map(doc => ({
|
|
103
|
+
id: doc.id,
|
|
104
|
+
...doc.data(),
|
|
105
|
+
})) as Appointment[];
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
appointments,
|
|
109
|
+
total: appointments.length,
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Delegate all methods to the underlying AnalyticsService
|
|
116
|
+
// We expose them here so they can be called with admin SDK context
|
|
117
|
+
|
|
118
|
+
async getPractitionerAnalytics(
|
|
119
|
+
practitionerId: string,
|
|
120
|
+
dateRange?: AnalyticsDateRange,
|
|
121
|
+
options?: any,
|
|
122
|
+
): Promise<PractitionerAnalytics> {
|
|
123
|
+
return this.analyticsService.getPractitionerAnalytics(practitionerId, dateRange, options);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async getProcedureAnalytics(
|
|
127
|
+
procedureId?: string,
|
|
128
|
+
dateRange?: AnalyticsDateRange,
|
|
129
|
+
options?: any,
|
|
130
|
+
): Promise<ProcedureAnalytics | ProcedureAnalytics[]> {
|
|
131
|
+
return this.analyticsService.getProcedureAnalytics(procedureId, dateRange, options);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async getTimeEfficiencyMetrics(
|
|
135
|
+
filters?: AnalyticsFilters,
|
|
136
|
+
dateRange?: AnalyticsDateRange,
|
|
137
|
+
options?: any,
|
|
138
|
+
): Promise<TimeEfficiencyMetrics> {
|
|
139
|
+
return this.analyticsService.getTimeEfficiencyMetrics(filters, dateRange, options);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async getTimeEfficiencyMetricsByEntity(
|
|
143
|
+
groupBy: EntityType,
|
|
144
|
+
dateRange?: AnalyticsDateRange,
|
|
145
|
+
filters?: AnalyticsFilters,
|
|
146
|
+
): Promise<GroupedTimeEfficiencyMetrics[]> {
|
|
147
|
+
return this.analyticsService.getTimeEfficiencyMetricsByEntity(groupBy, dateRange, filters);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async getCancellationMetrics(
|
|
151
|
+
groupBy: EntityType,
|
|
152
|
+
dateRange?: AnalyticsDateRange,
|
|
153
|
+
options?: any,
|
|
154
|
+
): Promise<CancellationMetrics | CancellationMetrics[]> {
|
|
155
|
+
return this.analyticsService.getCancellationMetrics(groupBy, dateRange, options);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async getNoShowMetrics(
|
|
159
|
+
groupBy: EntityType,
|
|
160
|
+
dateRange?: AnalyticsDateRange,
|
|
161
|
+
options?: any,
|
|
162
|
+
): Promise<NoShowMetrics | NoShowMetrics[]> {
|
|
163
|
+
return this.analyticsService.getNoShowMetrics(groupBy, dateRange, options);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async getRevenueMetrics(
|
|
167
|
+
filters?: AnalyticsFilters,
|
|
168
|
+
dateRange?: AnalyticsDateRange,
|
|
169
|
+
options?: any,
|
|
170
|
+
): Promise<RevenueMetrics> {
|
|
171
|
+
return this.analyticsService.getRevenueMetrics(filters, dateRange, options);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async getRevenueMetricsByEntity(
|
|
175
|
+
groupBy: EntityType,
|
|
176
|
+
dateRange?: AnalyticsDateRange,
|
|
177
|
+
filters?: AnalyticsFilters,
|
|
178
|
+
): Promise<GroupedRevenueMetrics[]> {
|
|
179
|
+
return this.analyticsService.getRevenueMetricsByEntity(groupBy, dateRange, filters);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async getProductUsageMetrics(
|
|
183
|
+
productId?: string,
|
|
184
|
+
dateRange?: AnalyticsDateRange,
|
|
185
|
+
): Promise<ProductUsageMetrics | ProductUsageMetrics[]> {
|
|
186
|
+
return this.analyticsService.getProductUsageMetrics(productId, dateRange);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async getProductUsageMetricsByEntity(
|
|
190
|
+
groupBy: EntityType,
|
|
191
|
+
dateRange?: AnalyticsDateRange,
|
|
192
|
+
filters?: AnalyticsFilters,
|
|
193
|
+
): Promise<GroupedProductUsageMetrics[]> {
|
|
194
|
+
return this.analyticsService.getProductUsageMetricsByEntity(groupBy, dateRange, filters);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async getPatientAnalytics(
|
|
198
|
+
patientId?: string,
|
|
199
|
+
dateRange?: AnalyticsDateRange,
|
|
200
|
+
): Promise<PatientAnalytics | PatientAnalytics[]> {
|
|
201
|
+
return this.analyticsService.getPatientAnalytics(patientId, dateRange);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async getPatientBehaviorMetricsByEntity(
|
|
205
|
+
groupBy: 'clinic' | 'practitioner' | 'procedure' | 'technology',
|
|
206
|
+
dateRange?: AnalyticsDateRange,
|
|
207
|
+
filters?: AnalyticsFilters,
|
|
208
|
+
): Promise<GroupedPatientBehaviorMetrics[]> {
|
|
209
|
+
return this.analyticsService.getPatientBehaviorMetricsByEntity(groupBy, dateRange, filters);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async getClinicAnalytics(
|
|
213
|
+
clinicBranchId: string,
|
|
214
|
+
dateRange?: AnalyticsDateRange,
|
|
215
|
+
): Promise<ClinicAnalytics | ClinicAnalytics[]> {
|
|
216
|
+
// Use getDashboardData to get clinic-level analytics
|
|
217
|
+
const dashboard = await this.analyticsService.getDashboardData(
|
|
218
|
+
{ clinicBranchId },
|
|
219
|
+
dateRange,
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
// Get clinic info
|
|
223
|
+
const clinicDoc = await this.db.collection('clinics').doc(clinicBranchId).get();
|
|
224
|
+
const clinicData = clinicDoc.data();
|
|
225
|
+
const clinicName = clinicData?.name || 'Unknown';
|
|
226
|
+
|
|
227
|
+
// Convert DashboardAnalytics to ClinicAnalytics format
|
|
228
|
+
return {
|
|
229
|
+
clinicBranchId,
|
|
230
|
+
clinicName,
|
|
231
|
+
totalAppointments: dashboard.overview.totalAppointments,
|
|
232
|
+
completedAppointments: dashboard.overview.completedAppointments,
|
|
233
|
+
canceledAppointments: dashboard.overview.canceledAppointments,
|
|
234
|
+
noShowAppointments: dashboard.overview.noShowAppointments,
|
|
235
|
+
cancellationRate: dashboard.overview.cancellationRate,
|
|
236
|
+
noShowRate: dashboard.overview.noShowRate,
|
|
237
|
+
totalRevenue: dashboard.overview.totalRevenue,
|
|
238
|
+
averageRevenuePerAppointment: dashboard.overview.averageRevenuePerAppointment,
|
|
239
|
+
currency: dashboard.overview.currency,
|
|
240
|
+
practitionerCount: dashboard.overview.uniquePractitioners,
|
|
241
|
+
patientCount: dashboard.overview.uniquePatients,
|
|
242
|
+
procedureCount: dashboard.overview.uniqueProcedures,
|
|
243
|
+
topPractitioners: dashboard.practitionerMetrics.slice(0, 5).map(p => ({
|
|
244
|
+
practitionerId: p.practitionerId,
|
|
245
|
+
practitionerName: p.practitionerName,
|
|
246
|
+
appointmentCount: p.totalAppointments,
|
|
247
|
+
revenue: p.totalRevenue,
|
|
248
|
+
})),
|
|
249
|
+
topProcedures: dashboard.procedureMetrics.slice(0, 5).map(p => ({
|
|
250
|
+
procedureId: p.procedureId,
|
|
251
|
+
procedureName: p.procedureName,
|
|
252
|
+
appointmentCount: p.totalAppointments,
|
|
253
|
+
revenue: p.totalRevenue,
|
|
254
|
+
})),
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async getDashboardData(
|
|
259
|
+
filters?: AnalyticsFilters,
|
|
260
|
+
dateRange?: AnalyticsDateRange,
|
|
261
|
+
options?: any,
|
|
262
|
+
): Promise<DashboardAnalytics> {
|
|
263
|
+
return this.analyticsService.getDashboardData(filters, dateRange, options);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Expose fetchAppointments for direct access if needed
|
|
268
|
+
* This method is used internally by AnalyticsService
|
|
269
|
+
*/
|
|
270
|
+
async fetchAppointments(
|
|
271
|
+
filters?: AnalyticsFilters,
|
|
272
|
+
dateRange?: AnalyticsDateRange,
|
|
273
|
+
): Promise<any[]> {
|
|
274
|
+
// Access the private method via the service
|
|
275
|
+
return (this.analyticsService as any).fetchAppointments(filters, dateRange);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './analytics.admin.service';
|
|
2
|
-
|
|
1
|
+
export * from './analytics.admin.service';
|
|
2
|
+
|