@blackcode_sa/metaestetics-api 1.13.3 → 1.13.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +15 -28
- package/dist/admin/index.d.ts +15 -28
- package/dist/index.d.mts +18 -30
- package/dist/index.d.ts +18 -30
- package/dist/index.js +11 -3
- package/dist/index.mjs +11 -3
- package/package.json +121 -119
- package/src/__mocks__/firstore.ts +10 -10
- package/src/admin/aggregation/README.md +79 -79
- package/src/admin/aggregation/appointment/README.md +128 -128
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +1984 -1984
- package/src/admin/aggregation/appointment/index.ts +1 -1
- package/src/admin/aggregation/clinic/README.md +52 -52
- package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +703 -703
- package/src/admin/aggregation/clinic/index.ts +1 -1
- package/src/admin/aggregation/forms/README.md +13 -13
- package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +322 -322
- package/src/admin/aggregation/forms/index.ts +1 -1
- package/src/admin/aggregation/index.ts +8 -8
- package/src/admin/aggregation/patient/README.md +27 -27
- package/src/admin/aggregation/patient/index.ts +1 -1
- package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -141
- package/src/admin/aggregation/practitioner/README.md +42 -42
- package/src/admin/aggregation/practitioner/index.ts +1 -1
- package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -433
- package/src/admin/aggregation/practitioner-invite/index.ts +1 -1
- package/src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts +961 -961
- package/src/admin/aggregation/procedure/README.md +43 -43
- package/src/admin/aggregation/procedure/index.ts +1 -1
- package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +702 -702
- package/src/admin/aggregation/reviews/index.ts +1 -1
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +689 -689
- package/src/admin/analytics/analytics.admin.service.ts +278 -278
- package/src/admin/analytics/index.ts +2 -2
- package/src/admin/booking/README.md +125 -125
- package/src/admin/booking/booking.admin.ts +1037 -1037
- package/src/admin/booking/booking.calculator.ts +712 -712
- package/src/admin/booking/booking.types.ts +59 -59
- package/src/admin/booking/index.ts +3 -3
- package/src/admin/booking/timezones-problem.md +185 -185
- package/src/admin/calendar/README.md +7 -7
- package/src/admin/calendar/calendar.admin.service.ts +345 -345
- package/src/admin/calendar/index.ts +1 -1
- package/src/admin/documentation-templates/document-manager.admin.ts +260 -260
- package/src/admin/documentation-templates/index.ts +1 -1
- package/src/admin/free-consultation/free-consultation-utils.admin.ts +148 -148
- package/src/admin/free-consultation/index.ts +1 -1
- package/src/admin/index.ts +81 -81
- package/src/admin/logger/index.ts +78 -78
- package/src/admin/mailing/README.md +95 -95
- package/src/admin/mailing/appointment/appointment.mailing.service.ts +732 -732
- package/src/admin/mailing/appointment/index.ts +1 -1
- package/src/admin/mailing/appointment/templates/patient/appointment-confirmed.html +40 -40
- package/src/admin/mailing/base.mailing.service.ts +208 -208
- package/src/admin/mailing/index.ts +3 -3
- package/src/admin/mailing/practitionerInvite/existing-practitioner-invite.mailing.ts +611 -611
- package/src/admin/mailing/practitionerInvite/index.ts +2 -2
- package/src/admin/mailing/practitionerInvite/practitionerInvite.mailing.ts +395 -395
- package/src/admin/mailing/practitionerInvite/templates/existing-practitioner-invitation.template.ts +155 -155
- package/src/admin/mailing/practitionerInvite/templates/invitation.template.ts +101 -101
- package/src/admin/mailing/practitionerInvite/templates/invite-accepted-notification.template.ts +228 -228
- package/src/admin/mailing/practitionerInvite/templates/invite-rejected-notification.template.ts +242 -242
- package/src/admin/notifications/index.ts +1 -1
- package/src/admin/notifications/notifications.admin.ts +710 -710
- package/src/admin/requirements/README.md +128 -128
- package/src/admin/requirements/index.ts +1 -1
- package/src/admin/requirements/patient-requirements.admin.service.ts +475 -475
- package/src/admin/users/index.ts +1 -1
- package/src/admin/users/user-profile.admin.ts +405 -405
- package/src/backoffice/constants/certification.constants.ts +13 -13
- package/src/backoffice/constants/index.ts +1 -1
- package/src/backoffice/errors/backoffice.errors.ts +181 -181
- package/src/backoffice/errors/index.ts +1 -1
- package/src/backoffice/expo-safe/README.md +26 -26
- package/src/backoffice/expo-safe/index.ts +41 -41
- package/src/backoffice/index.ts +5 -5
- package/src/backoffice/services/FIXES_README.md +102 -102
- package/src/backoffice/services/README.md +57 -57
- package/src/backoffice/services/analytics.service.proposal.md +863 -863
- package/src/backoffice/services/analytics.service.summary.md +143 -143
- package/src/backoffice/services/brand.service.ts +256 -256
- package/src/backoffice/services/category.service.ts +384 -384
- package/src/backoffice/services/constants.service.ts +385 -385
- package/src/backoffice/services/documentation-template.service.ts +202 -202
- package/src/backoffice/services/index.ts +10 -10
- package/src/backoffice/services/migrate-products.ts +116 -116
- package/src/backoffice/services/product.service.ts +553 -553
- package/src/backoffice/services/requirement.service.ts +235 -235
- package/src/backoffice/services/subcategory.service.ts +461 -461
- package/src/backoffice/services/technology.service.ts +1151 -1151
- package/src/backoffice/types/README.md +12 -12
- package/src/backoffice/types/admin-constants.types.ts +69 -69
- package/src/backoffice/types/brand.types.ts +29 -29
- package/src/backoffice/types/category.types.ts +67 -67
- package/src/backoffice/types/documentation-templates.types.ts +28 -28
- package/src/backoffice/types/index.ts +10 -10
- package/src/backoffice/types/procedure-product.types.ts +38 -38
- package/src/backoffice/types/product.types.ts +240 -240
- package/src/backoffice/types/requirement.types.ts +63 -63
- package/src/backoffice/types/static/README.md +18 -18
- package/src/backoffice/types/static/blocking-condition.types.ts +21 -21
- package/src/backoffice/types/static/certification.types.ts +37 -37
- package/src/backoffice/types/static/contraindication.types.ts +19 -19
- package/src/backoffice/types/static/index.ts +6 -6
- package/src/backoffice/types/static/pricing.types.ts +16 -16
- package/src/backoffice/types/static/procedure-family.types.ts +14 -14
- package/src/backoffice/types/static/treatment-benefit.types.ts +22 -22
- package/src/backoffice/types/subcategory.types.ts +34 -34
- package/src/backoffice/types/technology.types.ts +168 -168
- package/src/backoffice/validations/index.ts +1 -1
- package/src/backoffice/validations/schemas.ts +164 -164
- package/src/config/__mocks__/firebase.ts +99 -99
- package/src/config/firebase.ts +78 -78
- package/src/config/index.ts +9 -9
- package/src/errors/auth.error.ts +6 -6
- package/src/errors/auth.errors.ts +200 -200
- package/src/errors/clinic.errors.ts +32 -32
- package/src/errors/firebase.errors.ts +47 -47
- package/src/errors/user.errors.ts +99 -99
- package/src/index.backup.ts +407 -407
- package/src/index.ts +6 -6
- package/src/locales/en.ts +31 -31
- package/src/recommender/admin/index.ts +1 -1
- package/src/recommender/admin/services/recommender.service.admin.ts +5 -5
- package/src/recommender/front/index.ts +1 -1
- package/src/recommender/front/services/onboarding.service.ts +5 -5
- package/src/recommender/front/services/recommender.service.ts +3 -3
- package/src/recommender/index.ts +1 -1
- package/src/services/PATIENTAUTH.MD +197 -197
- package/src/services/README.md +106 -106
- package/src/services/__tests__/auth/auth.mock.test.ts +17 -17
- package/src/services/__tests__/auth/auth.setup.ts +293 -293
- package/src/services/__tests__/auth.service.test.ts +346 -346
- package/src/services/__tests__/base.service.test.ts +77 -77
- package/src/services/__tests__/user.service.test.ts +528 -528
- package/src/services/analytics/ARCHITECTURE.md +199 -199
- package/src/services/analytics/CLOUD_FUNCTIONS.md +225 -225
- package/src/services/analytics/GROUPED_ANALYTICS.md +501 -501
- package/src/services/analytics/QUICK_START.md +393 -393
- package/src/services/analytics/README.md +304 -304
- package/src/services/analytics/SUMMARY.md +141 -141
- package/src/services/analytics/TRENDS.md +380 -380
- package/src/services/analytics/USAGE_GUIDE.md +518 -518
- package/src/services/analytics/analytics-cloud.service.ts +222 -222
- package/src/services/analytics/analytics.service.ts +2142 -2142
- package/src/services/analytics/index.ts +4 -4
- package/src/services/analytics/review-analytics.service.ts +941 -941
- package/src/services/analytics/utils/appointment-filtering.utils.ts +138 -138
- package/src/services/analytics/utils/cost-calculation.utils.ts +182 -182
- package/src/services/analytics/utils/grouping.utils.ts +434 -434
- package/src/services/analytics/utils/stored-analytics.utils.ts +347 -347
- package/src/services/analytics/utils/time-calculation.utils.ts +186 -186
- package/src/services/analytics/utils/trend-calculation.utils.ts +200 -200
- package/src/services/appointment/README.md +17 -17
- package/src/services/appointment/appointment.service.ts +2558 -2558
- package/src/services/appointment/index.ts +1 -1
- package/src/services/appointment/utils/appointment.utils.ts +552 -552
- package/src/services/appointment/utils/extended-procedure.utils.ts +314 -314
- package/src/services/appointment/utils/form-initialization.utils.ts +225 -225
- package/src/services/appointment/utils/recommended-procedure.utils.ts +195 -195
- package/src/services/appointment/utils/zone-management.utils.ts +353 -353
- package/src/services/appointment/utils/zone-photo.utils.ts +152 -152
- package/src/services/auth/auth.service.ts +989 -989
- package/src/services/auth/auth.v2.service.ts +961 -961
- package/src/services/auth/index.ts +7 -7
- package/src/services/auth/utils/error.utils.ts +90 -90
- package/src/services/auth/utils/firebase.utils.ts +49 -49
- package/src/services/auth/utils/index.ts +21 -21
- package/src/services/auth/utils/practitioner.utils.ts +125 -125
- package/src/services/base.service.ts +41 -41
- package/src/services/calendar/calendar.service.ts +1077 -1077
- package/src/services/calendar/calendar.v2.service.ts +1683 -1683
- package/src/services/calendar/calendar.v3.service.ts +313 -313
- package/src/services/calendar/externalCalendar.service.ts +178 -178
- package/src/services/calendar/index.ts +5 -5
- package/src/services/calendar/synced-calendars.service.ts +743 -743
- package/src/services/calendar/utils/appointment.utils.ts +265 -265
- package/src/services/calendar/utils/calendar-event.utils.ts +646 -646
- package/src/services/calendar/utils/clinic.utils.ts +237 -237
- package/src/services/calendar/utils/docs.utils.ts +157 -157
- package/src/services/calendar/utils/google-calendar.utils.ts +697 -697
- package/src/services/calendar/utils/index.ts +8 -8
- package/src/services/calendar/utils/patient.utils.ts +198 -198
- package/src/services/calendar/utils/practitioner.utils.ts +221 -221
- package/src/services/calendar/utils/synced-calendar.utils.ts +472 -472
- package/src/services/clinic/README.md +204 -204
- package/src/services/clinic/__tests__/clinic-admin.service.test.ts +287 -287
- package/src/services/clinic/__tests__/clinic-group.service.test.ts +352 -352
- package/src/services/clinic/__tests__/clinic.service.test.ts +354 -354
- package/src/services/clinic/billing-transactions.service.ts +217 -217
- package/src/services/clinic/clinic-admin.service.ts +202 -202
- package/src/services/clinic/clinic-group.service.ts +310 -310
- package/src/services/clinic/clinic.service.ts +708 -708
- package/src/services/clinic/index.ts +5 -5
- package/src/services/clinic/practitioner-invite.service.ts +519 -519
- package/src/services/clinic/utils/admin.utils.ts +551 -551
- package/src/services/clinic/utils/clinic-group.utils.ts +646 -646
- package/src/services/clinic/utils/clinic.utils.ts +949 -949
- package/src/services/clinic/utils/filter.utils.d.ts +23 -23
- package/src/services/clinic/utils/filter.utils.ts +446 -446
- package/src/services/clinic/utils/index.ts +11 -11
- package/src/services/clinic/utils/photos.utils.ts +188 -188
- package/src/services/clinic/utils/search.utils.ts +84 -84
- package/src/services/clinic/utils/tag.utils.ts +124 -124
- package/src/services/documentation-templates/documentation-template.service.ts +537 -537
- package/src/services/documentation-templates/filled-document.service.ts +587 -587
- package/src/services/documentation-templates/index.ts +2 -2
- package/src/services/index.ts +14 -14
- package/src/services/media/index.ts +1 -1
- package/src/services/media/media.service.ts +418 -418
- package/src/services/notifications/__tests__/notification.service.test.ts +242 -242
- package/src/services/notifications/index.ts +1 -1
- package/src/services/notifications/notification.service.ts +215 -215
- package/src/services/patient/README.md +48 -48
- package/src/services/patient/To-Do.md +43 -43
- package/src/services/patient/__tests__/patient.service.test.ts +294 -294
- package/src/services/patient/index.ts +2 -2
- package/src/services/patient/patient.service.ts +883 -883
- package/src/services/patient/patientRequirements.service.ts +285 -285
- package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -176
- package/src/services/patient/utils/clinic.utils.ts +80 -80
- package/src/services/patient/utils/docs.utils.ts +142 -142
- package/src/services/patient/utils/index.ts +9 -9
- package/src/services/patient/utils/location.utils.ts +126 -126
- package/src/services/patient/utils/medical-stuff.utils.ts +143 -143
- package/src/services/patient/utils/medical.utils.ts +458 -458
- package/src/services/patient/utils/practitioner.utils.ts +260 -260
- package/src/services/patient/utils/profile.utils.ts +510 -510
- package/src/services/patient/utils/sensitive.utils.ts +260 -260
- package/src/services/patient/utils/token.utils.ts +211 -211
- package/src/services/practitioner/README.md +145 -145
- package/src/services/practitioner/index.ts +1 -1
- package/src/services/practitioner/practitioner.service.ts +1742 -1742
- package/src/services/procedure/README.md +163 -163
- package/src/services/procedure/index.ts +1 -1
- package/src/services/procedure/procedure.service.ts +2200 -2191
- package/src/services/reviews/index.ts +1 -1
- package/src/services/reviews/reviews.service.ts +734 -734
- package/src/services/user/index.ts +1 -1
- package/src/services/user/user.service.ts +489 -489
- package/src/services/user/user.v2.service.ts +466 -466
- package/src/types/analytics/analytics.types.ts +597 -597
- package/src/types/analytics/grouped-analytics.types.ts +173 -173
- package/src/types/analytics/index.ts +4 -4
- package/src/types/analytics/stored-analytics.types.ts +137 -137
- package/src/types/appointment/index.ts +480 -480
- package/src/types/calendar/index.ts +258 -258
- package/src/types/calendar/synced-calendar.types.ts +66 -66
- package/src/types/clinic/index.ts +498 -489
- package/src/types/clinic/practitioner-invite.types.ts +91 -91
- package/src/types/clinic/preferences.types.ts +159 -159
- package/src/types/clinic/to-do +3 -3
- package/src/types/documentation-templates/index.ts +308 -308
- package/src/types/index.ts +47 -47
- package/src/types/notifications/README.md +77 -77
- package/src/types/notifications/index.ts +286 -286
- package/src/types/patient/aesthetic-analysis.types.ts +66 -66
- package/src/types/patient/allergies.ts +58 -58
- package/src/types/patient/index.ts +275 -275
- package/src/types/patient/medical-info.types.ts +152 -152
- package/src/types/patient/patient-requirements.ts +92 -92
- package/src/types/patient/token.types.ts +61 -61
- package/src/types/practitioner/index.ts +206 -206
- package/src/types/procedure/index.ts +181 -181
- package/src/types/profile/index.ts +39 -39
- package/src/types/reviews/index.ts +132 -132
- package/src/types/tz-lookup.d.ts +4 -4
- package/src/types/user/index.ts +38 -38
- package/src/utils/TIMESTAMPS.md +176 -176
- package/src/utils/TimestampUtils.ts +241 -241
- package/src/utils/index.ts +1 -1
- package/src/validations/appointment.schema.ts +574 -574
- package/src/validations/calendar.schema.ts +225 -225
- package/src/validations/clinic.schema.ts +494 -493
- package/src/validations/common.schema.ts +25 -25
- package/src/validations/documentation-templates/index.ts +1 -1
- package/src/validations/documentation-templates/template.schema.ts +220 -220
- package/src/validations/documentation-templates.schema.ts +10 -10
- package/src/validations/index.ts +20 -20
- package/src/validations/media.schema.ts +10 -10
- package/src/validations/notification.schema.ts +90 -90
- package/src/validations/patient/aesthetic-analysis.schema.ts +55 -55
- package/src/validations/patient/medical-info.schema.ts +125 -125
- package/src/validations/patient/patient-requirements.schema.ts +84 -84
- package/src/validations/patient/token.schema.ts +29 -29
- package/src/validations/patient.schema.ts +217 -217
- package/src/validations/practitioner.schema.ts +222 -222
- package/src/validations/procedure-product.schema.ts +41 -41
- package/src/validations/procedure.schema.ts +124 -124
- package/src/validations/profile-info.schema.ts +41 -41
- package/src/validations/reviews.schema.ts +195 -195
- package/src/validations/schemas.ts +104 -104
- package/src/validations/shared.schema.ts +78 -78
|
@@ -1,304 +1,304 @@
|
|
|
1
|
-
# Analytics Service
|
|
2
|
-
|
|
3
|
-
Comprehensive financial and analytical intelligence service for the Clinic Admin app. Provides insights about doctors, procedures, appointments, patients, products, and clinic operations.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The `AnalyticsService` extends `BaseService` and provides methods to analyze appointment data, calculate metrics, and generate reports for clinic administration.
|
|
8
|
-
|
|
9
|
-
## Usage
|
|
10
|
-
|
|
11
|
-
### Initialization
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
import { AnalyticsService } from '@blackcode_sa/metaestetics-api';
|
|
15
|
-
import { AppointmentService } from '@blackcode_sa/metaestetics-api';
|
|
16
|
-
|
|
17
|
-
// Initialize dependencies
|
|
18
|
-
const appointmentService = new AppointmentService(db, auth, app, ...);
|
|
19
|
-
|
|
20
|
-
// Initialize analytics service
|
|
21
|
-
const analyticsService = new AnalyticsService(db, auth, app, appointmentService);
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Available Methods
|
|
25
|
-
|
|
26
|
-
### ⚡ **Grouped Analytics** (NEW!)
|
|
27
|
-
|
|
28
|
-
All analytics now support **consistent grouping** by clinic, practitioner, procedure, patient, or technology:
|
|
29
|
-
|
|
30
|
-
- `getRevenueMetricsByEntity(groupBy, dateRange?, filters?)` - Revenue by entity
|
|
31
|
-
- `getProductUsageMetricsByEntity(groupBy, dateRange?, filters?)` - Product usage by entity
|
|
32
|
-
- `getTimeEfficiencyMetricsByEntity(groupBy, dateRange?, filters?)` - Time efficiency by entity
|
|
33
|
-
- `getPatientBehaviorMetricsByEntity(groupBy, dateRange?, filters?)` - Patient behavior by entity
|
|
34
|
-
- `getCancellationMetrics(groupBy, dateRange?)` - Cancellations by entity (existing)
|
|
35
|
-
- `getNoShowMetrics(groupBy, dateRange?)` - No-shows by entity (existing)
|
|
36
|
-
|
|
37
|
-
**Technology Grouping**: Groups all procedures using the same technology across all doctors (e.g., all Botox treatments regardless of which doctor performed them).
|
|
38
|
-
|
|
39
|
-
**See [GROUPED_ANALYTICS.md](./GROUPED_ANALYTICS.md) for complete guide and examples.**
|
|
40
|
-
|
|
41
|
-
### Practitioner Analytics
|
|
42
|
-
|
|
43
|
-
#### `getPractitionerAnalytics(practitionerId, dateRange?)`
|
|
44
|
-
|
|
45
|
-
Get comprehensive performance metrics for a practitioner.
|
|
46
|
-
|
|
47
|
-
**Returns**: `PractitionerAnalytics`
|
|
48
|
-
|
|
49
|
-
**Example**:
|
|
50
|
-
```typescript
|
|
51
|
-
const metrics = await analyticsService.getPractitionerAnalytics(
|
|
52
|
-
'practitioner-id-123',
|
|
53
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
console.log(`Total appointments: ${metrics.totalAppointments}`);
|
|
57
|
-
console.log(`Cancellation rate: ${metrics.cancellationRate}%`);
|
|
58
|
-
console.log(`Total revenue: ${metrics.totalRevenue} ${metrics.currency}`);
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### Procedure Analytics
|
|
62
|
-
|
|
63
|
-
#### `getProcedureAnalytics(procedureId?, dateRange?)`
|
|
64
|
-
|
|
65
|
-
Get performance metrics for one or all procedures.
|
|
66
|
-
|
|
67
|
-
**Returns**: `ProcedureAnalytics | ProcedureAnalytics[]`
|
|
68
|
-
|
|
69
|
-
**Example**:
|
|
70
|
-
```typescript
|
|
71
|
-
// Get analytics for a specific procedure
|
|
72
|
-
const procedureMetrics = await analyticsService.getProcedureAnalytics(
|
|
73
|
-
'procedure-id-123',
|
|
74
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
// Get analytics for all procedures
|
|
78
|
-
const allProcedures = await analyticsService.getProcedureAnalytics(
|
|
79
|
-
undefined,
|
|
80
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
81
|
-
);
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
#### `getProcedurePopularity(dateRange?, limit?)`
|
|
85
|
-
|
|
86
|
-
Get the most popular procedures by appointment count.
|
|
87
|
-
|
|
88
|
-
**Returns**: `ProcedurePopularity[]`
|
|
89
|
-
|
|
90
|
-
**Example**:
|
|
91
|
-
```typescript
|
|
92
|
-
const topProcedures = await analyticsService.getProcedurePopularity(
|
|
93
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
94
|
-
10 // Top 10 procedures
|
|
95
|
-
);
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
#### `getProcedureProfitability(dateRange?, limit?)`
|
|
99
|
-
|
|
100
|
-
Get the most profitable procedures by revenue.
|
|
101
|
-
|
|
102
|
-
**Returns**: `ProcedureProfitability[]`
|
|
103
|
-
|
|
104
|
-
**Example**:
|
|
105
|
-
```typescript
|
|
106
|
-
const profitableProcedures = await analyticsService.getProcedureProfitability(
|
|
107
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
108
|
-
10
|
|
109
|
-
);
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Time Efficiency Analytics
|
|
113
|
-
|
|
114
|
-
#### `getTimeEfficiencyMetrics(filters?, dateRange?)`
|
|
115
|
-
|
|
116
|
-
Analyze booked time vs actual time spent on appointments.
|
|
117
|
-
|
|
118
|
-
**Returns**: `TimeEfficiencyMetrics`
|
|
119
|
-
|
|
120
|
-
**Example**:
|
|
121
|
-
```typescript
|
|
122
|
-
const timeMetrics = await analyticsService.getTimeEfficiencyMetrics(
|
|
123
|
-
{ clinicBranchId: 'clinic-123' },
|
|
124
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
console.log(`Average efficiency: ${timeMetrics.averageEfficiency}%`);
|
|
128
|
-
console.log(`Average overrun: ${timeMetrics.averageOverrun} minutes`);
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Cancellation & No-Show Analytics
|
|
132
|
-
|
|
133
|
-
#### `getCancellationMetrics(groupBy, dateRange?)`
|
|
134
|
-
|
|
135
|
-
Get cancellation metrics grouped by clinic, practitioner, patient, or procedure.
|
|
136
|
-
|
|
137
|
-
**Returns**: `CancellationMetrics | CancellationMetrics[]`
|
|
138
|
-
|
|
139
|
-
**Example**:
|
|
140
|
-
```typescript
|
|
141
|
-
// Get cancellations by clinic
|
|
142
|
-
const clinicCancellations = await analyticsService.getCancellationMetrics(
|
|
143
|
-
'clinic',
|
|
144
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
// Get cancellations by practitioner
|
|
148
|
-
const practitionerCancellations = await analyticsService.getCancellationMetrics(
|
|
149
|
-
'practitioner',
|
|
150
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
151
|
-
);
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
#### `getNoShowMetrics(groupBy, dateRange?)`
|
|
155
|
-
|
|
156
|
-
Get no-show metrics grouped by clinic, practitioner, patient, or procedure.
|
|
157
|
-
|
|
158
|
-
**Returns**: `NoShowMetrics | NoShowMetrics[]`
|
|
159
|
-
|
|
160
|
-
**Example**:
|
|
161
|
-
```typescript
|
|
162
|
-
const noShowMetrics = await analyticsService.getNoShowMetrics(
|
|
163
|
-
'patient',
|
|
164
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
165
|
-
);
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Financial Analytics
|
|
169
|
-
|
|
170
|
-
#### `getRevenueMetrics(filters?, dateRange?)`
|
|
171
|
-
|
|
172
|
-
Get comprehensive revenue metrics.
|
|
173
|
-
|
|
174
|
-
**Returns**: `RevenueMetrics`
|
|
175
|
-
|
|
176
|
-
**Example**:
|
|
177
|
-
```typescript
|
|
178
|
-
const revenue = await analyticsService.getRevenueMetrics(
|
|
179
|
-
{ clinicBranchId: 'clinic-123' },
|
|
180
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
console.log(`Total revenue: ${revenue.totalRevenue} ${revenue.currency}`);
|
|
184
|
-
console.log(`Unpaid revenue: ${revenue.unpaidRevenue}`);
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### Product Usage Analytics
|
|
188
|
-
|
|
189
|
-
#### `getProductUsageMetrics(productId?, dateRange?)`
|
|
190
|
-
|
|
191
|
-
Get product usage metrics for one or all products.
|
|
192
|
-
|
|
193
|
-
**Returns**: `ProductUsageMetrics | ProductUsageMetrics[]`
|
|
194
|
-
|
|
195
|
-
**Example**:
|
|
196
|
-
```typescript
|
|
197
|
-
// Get usage for a specific product
|
|
198
|
-
const productMetrics = await analyticsService.getProductUsageMetrics(
|
|
199
|
-
'product-id-123',
|
|
200
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
// Get usage for all products
|
|
204
|
-
const allProducts = await analyticsService.getProductUsageMetrics(
|
|
205
|
-
undefined,
|
|
206
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
207
|
-
);
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Patient Analytics
|
|
211
|
-
|
|
212
|
-
#### `getPatientAnalytics(patientId?, dateRange?)`
|
|
213
|
-
|
|
214
|
-
Get analytics for one or all patients.
|
|
215
|
-
|
|
216
|
-
**Returns**: `PatientAnalytics | PatientAnalytics[]`
|
|
217
|
-
|
|
218
|
-
**Example**:
|
|
219
|
-
```typescript
|
|
220
|
-
const patientMetrics = await analyticsService.getPatientAnalytics(
|
|
221
|
-
'patient-id-123',
|
|
222
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
console.log(`Lifetime value: ${patientMetrics.lifetimeValue}`);
|
|
226
|
-
console.log(`Average days between appointments: ${patientMetrics.averageDaysBetweenAppointments}`);
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Dashboard Analytics
|
|
230
|
-
|
|
231
|
-
#### `getDashboardData(filters?, dateRange?)`
|
|
232
|
-
|
|
233
|
-
Get comprehensive dashboard data aggregation.
|
|
234
|
-
|
|
235
|
-
**Returns**: `DashboardAnalytics`
|
|
236
|
-
|
|
237
|
-
**Example**:
|
|
238
|
-
```typescript
|
|
239
|
-
const dashboard = await analyticsService.getDashboardData(
|
|
240
|
-
{ clinicBranchId: 'clinic-123' },
|
|
241
|
-
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
console.log(`Total appointments: ${dashboard.overview.totalAppointments}`);
|
|
245
|
-
console.log(`Total revenue: ${dashboard.overview.totalRevenue}`);
|
|
246
|
-
console.log(`Top practitioners:`, dashboard.practitionerMetrics);
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
## Cost Calculation Priority
|
|
250
|
-
|
|
251
|
-
The service calculates appointment costs using the following priority:
|
|
252
|
-
|
|
253
|
-
1. **`metadata.finalbilling.finalPrice`** - If available, uses the final billing price
|
|
254
|
-
2. **`metadata.zonesData`** - Calculates from zone item subtotals
|
|
255
|
-
3. **`appointment.cost`** - Falls back to base appointment cost
|
|
256
|
-
|
|
257
|
-
## Time Efficiency Calculation
|
|
258
|
-
|
|
259
|
-
Time efficiency is calculated as:
|
|
260
|
-
- **Booked Duration**: `appointmentEndTime - appointmentStartTime` (minutes)
|
|
261
|
-
- **Actual Duration**: `actualDurationMinutes` or booked duration if not available
|
|
262
|
-
- **Efficiency**: `(actualDuration / bookedDuration) * 100` (percentage)
|
|
263
|
-
- **Overrun**: Positive difference if actual > booked
|
|
264
|
-
- **Underutilization**: Positive difference if booked > actual
|
|
265
|
-
|
|
266
|
-
## Status Filtering
|
|
267
|
-
|
|
268
|
-
The service filters appointments by status:
|
|
269
|
-
|
|
270
|
-
- **Completed**: `AppointmentStatus.COMPLETED`
|
|
271
|
-
- **Canceled**: `CANCELED_PATIENT`, `CANCELED_CLINIC`, `CANCELED_PATIENT_RESCHEDULED`
|
|
272
|
-
- **No-Show**: `AppointmentStatus.NO_SHOW`
|
|
273
|
-
- **Active**: All statuses except canceled and no-show
|
|
274
|
-
|
|
275
|
-
## Performance Considerations
|
|
276
|
-
|
|
277
|
-
- The service uses the `AppointmentService` to query appointments efficiently
|
|
278
|
-
- Large date ranges may require pagination (to be implemented)
|
|
279
|
-
- Consider caching dashboard data for frequently accessed metrics
|
|
280
|
-
- Use specific filters to reduce query scope when possible
|
|
281
|
-
|
|
282
|
-
### Trend Analysis (NEW!)
|
|
283
|
-
|
|
284
|
-
Analyze metrics over time with period-over-period comparisons:
|
|
285
|
-
|
|
286
|
-
- `getRevenueTrends(dateRange, period, filters?, groupBy?)` - Revenue trends
|
|
287
|
-
- `getDurationTrends(dateRange, period, filters?, groupBy?)` - Time efficiency trends
|
|
288
|
-
- `getAppointmentTrends(dateRange, period, filters?, groupBy?)` - Appointment volume trends
|
|
289
|
-
- `getCancellationRateTrends(dateRange, period, filters?, groupBy?)` - Cancellation/no-show rate trends
|
|
290
|
-
|
|
291
|
-
**Period Types**: Week, Month, Quarter, Year
|
|
292
|
-
|
|
293
|
-
**Features**: Percentage change calculations, direction indicators (up/down/stable), grouped trends
|
|
294
|
-
|
|
295
|
-
**See [TRENDS.md](./TRENDS.md) for complete guide and examples.**
|
|
296
|
-
|
|
297
|
-
## Related Documentation
|
|
298
|
-
|
|
299
|
-
- [Analytics Types](../../types/analytics/analytics.types.ts)
|
|
300
|
-
- [Grouped Analytics Guide](./GROUPED_ANALYTICS.md)
|
|
301
|
-
- [Trend Analysis Guide](./TRENDS.md)
|
|
302
|
-
- [Appointment Service](../appointment/README.md)
|
|
303
|
-
- [Full Proposal](../../backoffice/services/analytics.service.proposal.md)
|
|
304
|
-
|
|
1
|
+
# Analytics Service
|
|
2
|
+
|
|
3
|
+
Comprehensive financial and analytical intelligence service for the Clinic Admin app. Provides insights about doctors, procedures, appointments, patients, products, and clinic operations.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `AnalyticsService` extends `BaseService` and provides methods to analyze appointment data, calculate metrics, and generate reports for clinic administration.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
### Initialization
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { AnalyticsService } from '@blackcode_sa/metaestetics-api';
|
|
15
|
+
import { AppointmentService } from '@blackcode_sa/metaestetics-api';
|
|
16
|
+
|
|
17
|
+
// Initialize dependencies
|
|
18
|
+
const appointmentService = new AppointmentService(db, auth, app, ...);
|
|
19
|
+
|
|
20
|
+
// Initialize analytics service
|
|
21
|
+
const analyticsService = new AnalyticsService(db, auth, app, appointmentService);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Available Methods
|
|
25
|
+
|
|
26
|
+
### ⚡ **Grouped Analytics** (NEW!)
|
|
27
|
+
|
|
28
|
+
All analytics now support **consistent grouping** by clinic, practitioner, procedure, patient, or technology:
|
|
29
|
+
|
|
30
|
+
- `getRevenueMetricsByEntity(groupBy, dateRange?, filters?)` - Revenue by entity
|
|
31
|
+
- `getProductUsageMetricsByEntity(groupBy, dateRange?, filters?)` - Product usage by entity
|
|
32
|
+
- `getTimeEfficiencyMetricsByEntity(groupBy, dateRange?, filters?)` - Time efficiency by entity
|
|
33
|
+
- `getPatientBehaviorMetricsByEntity(groupBy, dateRange?, filters?)` - Patient behavior by entity
|
|
34
|
+
- `getCancellationMetrics(groupBy, dateRange?)` - Cancellations by entity (existing)
|
|
35
|
+
- `getNoShowMetrics(groupBy, dateRange?)` - No-shows by entity (existing)
|
|
36
|
+
|
|
37
|
+
**Technology Grouping**: Groups all procedures using the same technology across all doctors (e.g., all Botox treatments regardless of which doctor performed them).
|
|
38
|
+
|
|
39
|
+
**See [GROUPED_ANALYTICS.md](./GROUPED_ANALYTICS.md) for complete guide and examples.**
|
|
40
|
+
|
|
41
|
+
### Practitioner Analytics
|
|
42
|
+
|
|
43
|
+
#### `getPractitionerAnalytics(practitionerId, dateRange?)`
|
|
44
|
+
|
|
45
|
+
Get comprehensive performance metrics for a practitioner.
|
|
46
|
+
|
|
47
|
+
**Returns**: `PractitionerAnalytics`
|
|
48
|
+
|
|
49
|
+
**Example**:
|
|
50
|
+
```typescript
|
|
51
|
+
const metrics = await analyticsService.getPractitionerAnalytics(
|
|
52
|
+
'practitioner-id-123',
|
|
53
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
console.log(`Total appointments: ${metrics.totalAppointments}`);
|
|
57
|
+
console.log(`Cancellation rate: ${metrics.cancellationRate}%`);
|
|
58
|
+
console.log(`Total revenue: ${metrics.totalRevenue} ${metrics.currency}`);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Procedure Analytics
|
|
62
|
+
|
|
63
|
+
#### `getProcedureAnalytics(procedureId?, dateRange?)`
|
|
64
|
+
|
|
65
|
+
Get performance metrics for one or all procedures.
|
|
66
|
+
|
|
67
|
+
**Returns**: `ProcedureAnalytics | ProcedureAnalytics[]`
|
|
68
|
+
|
|
69
|
+
**Example**:
|
|
70
|
+
```typescript
|
|
71
|
+
// Get analytics for a specific procedure
|
|
72
|
+
const procedureMetrics = await analyticsService.getProcedureAnalytics(
|
|
73
|
+
'procedure-id-123',
|
|
74
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Get analytics for all procedures
|
|
78
|
+
const allProcedures = await analyticsService.getProcedureAnalytics(
|
|
79
|
+
undefined,
|
|
80
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
81
|
+
);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### `getProcedurePopularity(dateRange?, limit?)`
|
|
85
|
+
|
|
86
|
+
Get the most popular procedures by appointment count.
|
|
87
|
+
|
|
88
|
+
**Returns**: `ProcedurePopularity[]`
|
|
89
|
+
|
|
90
|
+
**Example**:
|
|
91
|
+
```typescript
|
|
92
|
+
const topProcedures = await analyticsService.getProcedurePopularity(
|
|
93
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
94
|
+
10 // Top 10 procedures
|
|
95
|
+
);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### `getProcedureProfitability(dateRange?, limit?)`
|
|
99
|
+
|
|
100
|
+
Get the most profitable procedures by revenue.
|
|
101
|
+
|
|
102
|
+
**Returns**: `ProcedureProfitability[]`
|
|
103
|
+
|
|
104
|
+
**Example**:
|
|
105
|
+
```typescript
|
|
106
|
+
const profitableProcedures = await analyticsService.getProcedureProfitability(
|
|
107
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
108
|
+
10
|
|
109
|
+
);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Time Efficiency Analytics
|
|
113
|
+
|
|
114
|
+
#### `getTimeEfficiencyMetrics(filters?, dateRange?)`
|
|
115
|
+
|
|
116
|
+
Analyze booked time vs actual time spent on appointments.
|
|
117
|
+
|
|
118
|
+
**Returns**: `TimeEfficiencyMetrics`
|
|
119
|
+
|
|
120
|
+
**Example**:
|
|
121
|
+
```typescript
|
|
122
|
+
const timeMetrics = await analyticsService.getTimeEfficiencyMetrics(
|
|
123
|
+
{ clinicBranchId: 'clinic-123' },
|
|
124
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
console.log(`Average efficiency: ${timeMetrics.averageEfficiency}%`);
|
|
128
|
+
console.log(`Average overrun: ${timeMetrics.averageOverrun} minutes`);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Cancellation & No-Show Analytics
|
|
132
|
+
|
|
133
|
+
#### `getCancellationMetrics(groupBy, dateRange?)`
|
|
134
|
+
|
|
135
|
+
Get cancellation metrics grouped by clinic, practitioner, patient, or procedure.
|
|
136
|
+
|
|
137
|
+
**Returns**: `CancellationMetrics | CancellationMetrics[]`
|
|
138
|
+
|
|
139
|
+
**Example**:
|
|
140
|
+
```typescript
|
|
141
|
+
// Get cancellations by clinic
|
|
142
|
+
const clinicCancellations = await analyticsService.getCancellationMetrics(
|
|
143
|
+
'clinic',
|
|
144
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
// Get cancellations by practitioner
|
|
148
|
+
const practitionerCancellations = await analyticsService.getCancellationMetrics(
|
|
149
|
+
'practitioner',
|
|
150
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
151
|
+
);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### `getNoShowMetrics(groupBy, dateRange?)`
|
|
155
|
+
|
|
156
|
+
Get no-show metrics grouped by clinic, practitioner, patient, or procedure.
|
|
157
|
+
|
|
158
|
+
**Returns**: `NoShowMetrics | NoShowMetrics[]`
|
|
159
|
+
|
|
160
|
+
**Example**:
|
|
161
|
+
```typescript
|
|
162
|
+
const noShowMetrics = await analyticsService.getNoShowMetrics(
|
|
163
|
+
'patient',
|
|
164
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
165
|
+
);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Financial Analytics
|
|
169
|
+
|
|
170
|
+
#### `getRevenueMetrics(filters?, dateRange?)`
|
|
171
|
+
|
|
172
|
+
Get comprehensive revenue metrics.
|
|
173
|
+
|
|
174
|
+
**Returns**: `RevenueMetrics`
|
|
175
|
+
|
|
176
|
+
**Example**:
|
|
177
|
+
```typescript
|
|
178
|
+
const revenue = await analyticsService.getRevenueMetrics(
|
|
179
|
+
{ clinicBranchId: 'clinic-123' },
|
|
180
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
console.log(`Total revenue: ${revenue.totalRevenue} ${revenue.currency}`);
|
|
184
|
+
console.log(`Unpaid revenue: ${revenue.unpaidRevenue}`);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Product Usage Analytics
|
|
188
|
+
|
|
189
|
+
#### `getProductUsageMetrics(productId?, dateRange?)`
|
|
190
|
+
|
|
191
|
+
Get product usage metrics for one or all products.
|
|
192
|
+
|
|
193
|
+
**Returns**: `ProductUsageMetrics | ProductUsageMetrics[]`
|
|
194
|
+
|
|
195
|
+
**Example**:
|
|
196
|
+
```typescript
|
|
197
|
+
// Get usage for a specific product
|
|
198
|
+
const productMetrics = await analyticsService.getProductUsageMetrics(
|
|
199
|
+
'product-id-123',
|
|
200
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
// Get usage for all products
|
|
204
|
+
const allProducts = await analyticsService.getProductUsageMetrics(
|
|
205
|
+
undefined,
|
|
206
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
207
|
+
);
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Patient Analytics
|
|
211
|
+
|
|
212
|
+
#### `getPatientAnalytics(patientId?, dateRange?)`
|
|
213
|
+
|
|
214
|
+
Get analytics for one or all patients.
|
|
215
|
+
|
|
216
|
+
**Returns**: `PatientAnalytics | PatientAnalytics[]`
|
|
217
|
+
|
|
218
|
+
**Example**:
|
|
219
|
+
```typescript
|
|
220
|
+
const patientMetrics = await analyticsService.getPatientAnalytics(
|
|
221
|
+
'patient-id-123',
|
|
222
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
console.log(`Lifetime value: ${patientMetrics.lifetimeValue}`);
|
|
226
|
+
console.log(`Average days between appointments: ${patientMetrics.averageDaysBetweenAppointments}`);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Dashboard Analytics
|
|
230
|
+
|
|
231
|
+
#### `getDashboardData(filters?, dateRange?)`
|
|
232
|
+
|
|
233
|
+
Get comprehensive dashboard data aggregation.
|
|
234
|
+
|
|
235
|
+
**Returns**: `DashboardAnalytics`
|
|
236
|
+
|
|
237
|
+
**Example**:
|
|
238
|
+
```typescript
|
|
239
|
+
const dashboard = await analyticsService.getDashboardData(
|
|
240
|
+
{ clinicBranchId: 'clinic-123' },
|
|
241
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
console.log(`Total appointments: ${dashboard.overview.totalAppointments}`);
|
|
245
|
+
console.log(`Total revenue: ${dashboard.overview.totalRevenue}`);
|
|
246
|
+
console.log(`Top practitioners:`, dashboard.practitionerMetrics);
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Cost Calculation Priority
|
|
250
|
+
|
|
251
|
+
The service calculates appointment costs using the following priority:
|
|
252
|
+
|
|
253
|
+
1. **`metadata.finalbilling.finalPrice`** - If available, uses the final billing price
|
|
254
|
+
2. **`metadata.zonesData`** - Calculates from zone item subtotals
|
|
255
|
+
3. **`appointment.cost`** - Falls back to base appointment cost
|
|
256
|
+
|
|
257
|
+
## Time Efficiency Calculation
|
|
258
|
+
|
|
259
|
+
Time efficiency is calculated as:
|
|
260
|
+
- **Booked Duration**: `appointmentEndTime - appointmentStartTime` (minutes)
|
|
261
|
+
- **Actual Duration**: `actualDurationMinutes` or booked duration if not available
|
|
262
|
+
- **Efficiency**: `(actualDuration / bookedDuration) * 100` (percentage)
|
|
263
|
+
- **Overrun**: Positive difference if actual > booked
|
|
264
|
+
- **Underutilization**: Positive difference if booked > actual
|
|
265
|
+
|
|
266
|
+
## Status Filtering
|
|
267
|
+
|
|
268
|
+
The service filters appointments by status:
|
|
269
|
+
|
|
270
|
+
- **Completed**: `AppointmentStatus.COMPLETED`
|
|
271
|
+
- **Canceled**: `CANCELED_PATIENT`, `CANCELED_CLINIC`, `CANCELED_PATIENT_RESCHEDULED`
|
|
272
|
+
- **No-Show**: `AppointmentStatus.NO_SHOW`
|
|
273
|
+
- **Active**: All statuses except canceled and no-show
|
|
274
|
+
|
|
275
|
+
## Performance Considerations
|
|
276
|
+
|
|
277
|
+
- The service uses the `AppointmentService` to query appointments efficiently
|
|
278
|
+
- Large date ranges may require pagination (to be implemented)
|
|
279
|
+
- Consider caching dashboard data for frequently accessed metrics
|
|
280
|
+
- Use specific filters to reduce query scope when possible
|
|
281
|
+
|
|
282
|
+
### Trend Analysis (NEW!)
|
|
283
|
+
|
|
284
|
+
Analyze metrics over time with period-over-period comparisons:
|
|
285
|
+
|
|
286
|
+
- `getRevenueTrends(dateRange, period, filters?, groupBy?)` - Revenue trends
|
|
287
|
+
- `getDurationTrends(dateRange, period, filters?, groupBy?)` - Time efficiency trends
|
|
288
|
+
- `getAppointmentTrends(dateRange, period, filters?, groupBy?)` - Appointment volume trends
|
|
289
|
+
- `getCancellationRateTrends(dateRange, period, filters?, groupBy?)` - Cancellation/no-show rate trends
|
|
290
|
+
|
|
291
|
+
**Period Types**: Week, Month, Quarter, Year
|
|
292
|
+
|
|
293
|
+
**Features**: Percentage change calculations, direction indicators (up/down/stable), grouped trends
|
|
294
|
+
|
|
295
|
+
**See [TRENDS.md](./TRENDS.md) for complete guide and examples.**
|
|
296
|
+
|
|
297
|
+
## Related Documentation
|
|
298
|
+
|
|
299
|
+
- [Analytics Types](../../types/analytics/analytics.types.ts)
|
|
300
|
+
- [Grouped Analytics Guide](./GROUPED_ANALYTICS.md)
|
|
301
|
+
- [Trend Analysis Guide](./TRENDS.md)
|
|
302
|
+
- [Appointment Service](../appointment/README.md)
|
|
303
|
+
- [Full Proposal](../../backoffice/services/analytics.service.proposal.md)
|
|
304
|
+
|