@blackcode_sa/metaestetics-api 1.12.68 → 1.13.0
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 +801 -2
- package/dist/admin/index.d.ts +801 -2
- package/dist/admin/index.js +2332 -153
- package/dist/admin/index.mjs +2321 -153
- package/dist/index.d.mts +1057 -2
- package/dist/index.d.ts +1057 -2
- package/dist/index.js +4150 -2117
- package/dist/index.mjs +3832 -1810
- package/package.json +1 -1
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +140 -0
- package/src/admin/analytics/analytics.admin.service.ts +278 -0
- package/src/admin/analytics/index.ts +2 -0
- package/src/admin/index.ts +6 -0
- package/src/backoffice/services/README.md +17 -0
- package/src/backoffice/services/analytics.service.proposal.md +863 -0
- package/src/backoffice/services/analytics.service.summary.md +143 -0
- package/src/services/analytics/ARCHITECTURE.md +199 -0
- package/src/services/analytics/CLOUD_FUNCTIONS.md +225 -0
- package/src/services/analytics/GROUPED_ANALYTICS.md +501 -0
- package/src/services/analytics/QUICK_START.md +393 -0
- package/src/services/analytics/README.md +287 -0
- package/src/services/analytics/SUMMARY.md +141 -0
- package/src/services/analytics/USAGE_GUIDE.md +518 -0
- package/src/services/analytics/analytics-cloud.service.ts +222 -0
- package/src/services/analytics/analytics.service.ts +1632 -0
- package/src/services/analytics/index.ts +3 -0
- package/src/services/analytics/utils/appointment-filtering.utils.ts +138 -0
- package/src/services/analytics/utils/cost-calculation.utils.ts +154 -0
- package/src/services/analytics/utils/grouping.utils.ts +394 -0
- package/src/services/analytics/utils/stored-analytics.utils.ts +347 -0
- package/src/services/analytics/utils/time-calculation.utils.ts +186 -0
- package/src/services/appointment/appointment.service.ts +50 -6
- package/src/services/index.ts +1 -0
- package/src/types/analytics/analytics.types.ts +500 -0
- package/src/types/analytics/grouped-analytics.types.ts +148 -0
- package/src/types/analytics/index.ts +4 -0
- package/src/types/analytics/stored-analytics.types.ts +137 -0
- package/src/types/index.ts +3 -0
- package/src/types/notifications/index.ts +21 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Analytics Service - Executive Summary
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This document provides a high-level summary of the proposed Analytics Service for the Clinic Admin app. The full detailed proposal can be found in [analytics.service.proposal.md](./analytics.service.proposal.md).
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
The Analytics Service will provide comprehensive financial and operational intelligence to clinic administrators, enabling data-driven decision making across:
|
|
10
|
+
|
|
11
|
+
- **Practitioner Performance**: Track doctor efficiency, revenue generation, and patient satisfaction
|
|
12
|
+
- **Procedure Analytics**: Understand procedure popularity, profitability, and product usage
|
|
13
|
+
- **Financial Intelligence**: Monitor revenue, costs, payment status, and trends
|
|
14
|
+
- **Operational Efficiency**: Analyze time utilization, cancellations, and no-shows
|
|
15
|
+
- **Patient Insights**: Track patient lifetime value, retention, and behavior patterns
|
|
16
|
+
|
|
17
|
+
## Key Data Sources
|
|
18
|
+
|
|
19
|
+
The service will aggregate data from:
|
|
20
|
+
|
|
21
|
+
1. **Appointments Collection**: Primary source for all appointment-related metrics
|
|
22
|
+
2. **Procedures Collection**: Procedure metadata and categorization
|
|
23
|
+
3. **Practitioners Collection**: Doctor information and associations
|
|
24
|
+
4. **Patients Collection**: Patient profiles and history
|
|
25
|
+
5. **Clinics Collection**: Clinic and branch information
|
|
26
|
+
6. **Products Collection**: Product usage and pricing data
|
|
27
|
+
|
|
28
|
+
## Core Analytics Categories
|
|
29
|
+
|
|
30
|
+
### 1. Practitioner Analytics
|
|
31
|
+
- Total and completed appointments
|
|
32
|
+
- Cancellation and no-show rates
|
|
33
|
+
- Time efficiency (booked vs actual)
|
|
34
|
+
- Revenue generation
|
|
35
|
+
- Patient retention
|
|
36
|
+
|
|
37
|
+
### 2. Procedure Analytics
|
|
38
|
+
- Appointment counts and popularity
|
|
39
|
+
- Revenue and profitability
|
|
40
|
+
- Cancellation rates
|
|
41
|
+
- Product usage patterns
|
|
42
|
+
- Performance by category/technology
|
|
43
|
+
|
|
44
|
+
### 3. Time Analytics
|
|
45
|
+
- Booked vs actual time comparison
|
|
46
|
+
- Efficiency percentages
|
|
47
|
+
- Overrun/underutilization analysis
|
|
48
|
+
- Peak hours and trends
|
|
49
|
+
|
|
50
|
+
### 4. Cancellation & No-Show Analytics
|
|
51
|
+
- Rates by clinic, practitioner, patient, procedure
|
|
52
|
+
- Cancellation reasons breakdown
|
|
53
|
+
- Patterns and trends
|
|
54
|
+
- Lead time analysis
|
|
55
|
+
|
|
56
|
+
### 5. Financial Analytics
|
|
57
|
+
- Total and average revenue
|
|
58
|
+
- Cost per patient/appointment
|
|
59
|
+
- Payment status breakdown
|
|
60
|
+
- Revenue trends
|
|
61
|
+
- Product cost analysis
|
|
62
|
+
|
|
63
|
+
### 6. Product Usage Analytics
|
|
64
|
+
- Products used per appointment
|
|
65
|
+
- Revenue contribution
|
|
66
|
+
- Usage by procedure/zone
|
|
67
|
+
- Quantity and pricing trends
|
|
68
|
+
|
|
69
|
+
### 7. Patient Analytics
|
|
70
|
+
- Lifetime value
|
|
71
|
+
- Retention rates
|
|
72
|
+
- Appointment frequency
|
|
73
|
+
- Cancellation patterns
|
|
74
|
+
|
|
75
|
+
### 8. Clinic Analytics
|
|
76
|
+
- Overall performance metrics
|
|
77
|
+
- Practitioner comparisons
|
|
78
|
+
- Procedure popularity
|
|
79
|
+
- Efficiency metrics
|
|
80
|
+
|
|
81
|
+
## Proposed Service Structure
|
|
82
|
+
|
|
83
|
+
The `AnalyticsService` will extend `BaseService` and provide methods organized by analytics category:
|
|
84
|
+
|
|
85
|
+
- `getPractitionerAnalytics()` - Comprehensive practitioner metrics
|
|
86
|
+
- `getProcedureAnalytics()` - Procedure performance data
|
|
87
|
+
- `getTimeEfficiencyMetrics()` - Time utilization analysis
|
|
88
|
+
- `getCancellationMetrics()` - Cancellation insights
|
|
89
|
+
- `getRevenueMetrics()` - Financial intelligence
|
|
90
|
+
- `getProductUsageMetrics()` - Product analytics
|
|
91
|
+
- `getPatientAnalytics()` - Patient insights
|
|
92
|
+
- `getClinicAnalytics()` - Clinic performance
|
|
93
|
+
- `getDashboardData()` - Comprehensive dashboard aggregation
|
|
94
|
+
|
|
95
|
+
## Key Calculations
|
|
96
|
+
|
|
97
|
+
### Cost Calculation Priority
|
|
98
|
+
1. `metadata.finalbilling.finalPrice` (if available)
|
|
99
|
+
2. Sum of `metadata.zonesData` subtotals
|
|
100
|
+
3. `appointment.cost` (fallback)
|
|
101
|
+
|
|
102
|
+
### Time Efficiency
|
|
103
|
+
```
|
|
104
|
+
efficiency = (actualDuration / bookedDuration) * 100
|
|
105
|
+
overrun = actualDuration > bookedDuration ? difference : 0
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Cancellation Rate
|
|
109
|
+
```
|
|
110
|
+
cancellationRate = (canceledCount / totalAppointments) * 100
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Implementation Phases
|
|
114
|
+
|
|
115
|
+
1. **Phase 1**: Core infrastructure and utilities
|
|
116
|
+
2. **Phase 2**: Basic metrics (practitioner, procedure, financial)
|
|
117
|
+
3. **Phase 3**: Advanced analytics (time, products, patients)
|
|
118
|
+
4. **Phase 4**: Dashboard and trend analysis
|
|
119
|
+
|
|
120
|
+
## Performance Considerations
|
|
121
|
+
|
|
122
|
+
- Firestore composite indexes for query optimization
|
|
123
|
+
- Pagination for large datasets
|
|
124
|
+
- Caching strategy for frequently accessed metrics
|
|
125
|
+
- Batch processing for complex aggregations
|
|
126
|
+
- Server-side calculations via Cloud Functions
|
|
127
|
+
|
|
128
|
+
## Next Steps
|
|
129
|
+
|
|
130
|
+
1. Review and approve the detailed proposal
|
|
131
|
+
2. Create TypeScript type definitions
|
|
132
|
+
3. Implement core service structure
|
|
133
|
+
4. Build utility functions for calculations
|
|
134
|
+
5. Implement metrics methods incrementally
|
|
135
|
+
6. Add comprehensive tests
|
|
136
|
+
7. Create API documentation
|
|
137
|
+
8. Integrate with Clinic Admin app
|
|
138
|
+
|
|
139
|
+
## Documentation
|
|
140
|
+
|
|
141
|
+
- **Full Proposal**: [analytics.service.proposal.md](./analytics.service.proposal.md)
|
|
142
|
+
- **Service README**: [README.md](./README.md)
|
|
143
|
+
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Analytics Service Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Analytics Service uses a **hybrid approach** combining **pre-computed analytics** (stored in Firestore) with **on-demand calculation** (fallback). This architecture optimizes for:
|
|
6
|
+
|
|
7
|
+
- **Performance**: Fast reads from pre-computed data
|
|
8
|
+
- **Cost**: Reduced Firestore reads and compute time
|
|
9
|
+
- **Flexibility**: Can still calculate on-demand when needed
|
|
10
|
+
|
|
11
|
+
## Architecture Components
|
|
12
|
+
|
|
13
|
+
### 1. Cloud Functions (Pre-computation)
|
|
14
|
+
|
|
15
|
+
**Location**: `Cloud/functions/src/analytics/computeAnalytics.ts`
|
|
16
|
+
|
|
17
|
+
**Schedule**: Runs every 12 hours via Cloud Scheduler
|
|
18
|
+
|
|
19
|
+
**What it does**:
|
|
20
|
+
- Queries all appointments for each clinic
|
|
21
|
+
- Computes analytics for multiple periods (daily, weekly, monthly, yearly, all_time)
|
|
22
|
+
- Stores computed analytics in Firestore subcollections
|
|
23
|
+
|
|
24
|
+
**Storage Structure**:
|
|
25
|
+
```
|
|
26
|
+
clinics/{clinicBranchId}/
|
|
27
|
+
└── analytics/
|
|
28
|
+
├── dashboard/
|
|
29
|
+
│ └── {period}/
|
|
30
|
+
│ └── current
|
|
31
|
+
├── clinic/
|
|
32
|
+
│ └── {period}/
|
|
33
|
+
│ └── current
|
|
34
|
+
├── practitioners/
|
|
35
|
+
│ └── {period}/
|
|
36
|
+
│ └── {practitionerId}
|
|
37
|
+
├── procedures/
|
|
38
|
+
│ └── {period}/
|
|
39
|
+
│ └── {procedureId}
|
|
40
|
+
├── time_efficiency/
|
|
41
|
+
│ └── {period}/
|
|
42
|
+
│ └── current
|
|
43
|
+
├── revenue/
|
|
44
|
+
│ └── {period}/
|
|
45
|
+
│ └── current
|
|
46
|
+
├── cancellations/
|
|
47
|
+
│ └── {period}/
|
|
48
|
+
│ └── clinic
|
|
49
|
+
└── no_shows/
|
|
50
|
+
└── {period}/
|
|
51
|
+
└── clinic
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Analytics Service (Client-side)
|
|
55
|
+
|
|
56
|
+
**Location**: `Api/src/services/analytics/analytics.service.ts`
|
|
57
|
+
|
|
58
|
+
**Behavior**:
|
|
59
|
+
1. **First**: Tries to read from stored analytics
|
|
60
|
+
2. **Checks**: If data is fresh (within maxCacheAgeHours, default 12 hours)
|
|
61
|
+
3. **Falls back**: Calculates on-demand if:
|
|
62
|
+
- No stored data exists
|
|
63
|
+
- Data is stale (older than maxCacheAgeHours)
|
|
64
|
+
- `useCache: false` is specified
|
|
65
|
+
|
|
66
|
+
### 3. Storage Types
|
|
67
|
+
|
|
68
|
+
**Location**: `Api/src/types/analytics/stored-analytics.types.ts`
|
|
69
|
+
|
|
70
|
+
Defines types for stored analytics documents, including metadata about when and how they were computed.
|
|
71
|
+
|
|
72
|
+
## Data Flow
|
|
73
|
+
|
|
74
|
+
### Pre-computation Flow (Cloud Function)
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
Cloud Scheduler (every 12 hours)
|
|
78
|
+
↓
|
|
79
|
+
computeAnalyticsForAllClinics()
|
|
80
|
+
↓
|
|
81
|
+
For each clinic:
|
|
82
|
+
├── Compute dashboard analytics
|
|
83
|
+
├── Compute clinic analytics
|
|
84
|
+
├── Compute practitioner analytics (for each practitioner)
|
|
85
|
+
├── Compute procedure analytics (for each procedure)
|
|
86
|
+
├── Compute time efficiency metrics
|
|
87
|
+
├── Compute revenue metrics
|
|
88
|
+
├── Compute cancellation metrics
|
|
89
|
+
└── Compute no-show metrics
|
|
90
|
+
↓
|
|
91
|
+
Store in Firestore subcollections
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Client Read Flow
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Client requests analytics
|
|
98
|
+
↓
|
|
99
|
+
AnalyticsService.getDashboardData()
|
|
100
|
+
↓
|
|
101
|
+
Check stored analytics?
|
|
102
|
+
├── Yes → Read from Firestore
|
|
103
|
+
│ ├── Fresh? → Return cached data ✅
|
|
104
|
+
│ └── Stale? → Calculate on-demand
|
|
105
|
+
└── No → Calculate on-demand
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Benefits
|
|
109
|
+
|
|
110
|
+
### Performance
|
|
111
|
+
- **Fast reads**: Single document read vs. querying hundreds/thousands of appointments
|
|
112
|
+
- **Reduced latency**: Pre-computed data returns instantly
|
|
113
|
+
- **Scalable**: Works efficiently even with large datasets
|
|
114
|
+
|
|
115
|
+
### Cost Optimization
|
|
116
|
+
- **Fewer reads**: 1 read vs. potentially hundreds/thousands
|
|
117
|
+
- **Reduced compute**: Calculations run server-side, not on every client request
|
|
118
|
+
- **Predictable costs**: Fixed cost per clinic per period
|
|
119
|
+
|
|
120
|
+
### Flexibility
|
|
121
|
+
- **On-demand fallback**: Can still calculate when needed
|
|
122
|
+
- **Custom date ranges**: Can override cached data for specific queries
|
|
123
|
+
- **Real-time option**: Can disable caching for live data
|
|
124
|
+
|
|
125
|
+
## Usage Examples
|
|
126
|
+
|
|
127
|
+
### Using Pre-computed Analytics (Default)
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// Automatically uses cached data if available and fresh
|
|
131
|
+
const dashboard = await analyticsService.getDashboardData(
|
|
132
|
+
{ clinicBranchId: 'clinic-123' },
|
|
133
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') }
|
|
134
|
+
);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Forcing On-demand Calculation
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
// Bypass cache and calculate on-demand
|
|
141
|
+
const dashboard = await analyticsService.getDashboardData(
|
|
142
|
+
{ clinicBranchId: 'clinic-123' },
|
|
143
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
144
|
+
{ useCache: false }
|
|
145
|
+
);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Custom Cache Age
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// Use cache if data is less than 6 hours old (instead of default 12)
|
|
152
|
+
const dashboard = await analyticsService.getDashboardData(
|
|
153
|
+
{ clinicBranchId: 'clinic-123' },
|
|
154
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
155
|
+
{ maxCacheAgeHours: 6 }
|
|
156
|
+
);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Configuration
|
|
160
|
+
|
|
161
|
+
### Cloud Function Schedule
|
|
162
|
+
|
|
163
|
+
Edit `Cloud/functions/src/analytics/computeAnalytics.ts`:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
schedule: "every 12 hours" // Change to "every 6 hours", "every 24 hours", etc.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Default Cache Age
|
|
170
|
+
|
|
171
|
+
Edit `Api/src/services/analytics/utils/stored-analytics.utils.ts`:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
maxCacheAgeHours = 12 // Change default cache age
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Monitoring
|
|
178
|
+
|
|
179
|
+
### Cloud Function Logs
|
|
180
|
+
|
|
181
|
+
Check Cloud Function logs for:
|
|
182
|
+
- Computation success/failure
|
|
183
|
+
- Processing time per clinic
|
|
184
|
+
- Errors during computation
|
|
185
|
+
|
|
186
|
+
### Firestore Usage
|
|
187
|
+
|
|
188
|
+
Monitor Firestore reads:
|
|
189
|
+
- Pre-computed reads: 1 per analytics request
|
|
190
|
+
- On-demand reads: Variable (depends on appointment count)
|
|
191
|
+
|
|
192
|
+
## Future Enhancements
|
|
193
|
+
|
|
194
|
+
1. **Incremental Updates**: Only recompute changed periods
|
|
195
|
+
2. **Real-time Triggers**: Update analytics when appointments change
|
|
196
|
+
3. **Aggregated Views**: Pre-compute common dashboard views
|
|
197
|
+
4. **Historical Snapshots**: Keep historical analytics for trend analysis
|
|
198
|
+
5. **Multi-clinic Aggregation**: Aggregate analytics across clinic groups
|
|
199
|
+
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Analytics Cloud Functions Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Analytics Service supports **on-demand calculation via Cloud Functions**, allowing you to trigger fresh analytics calculations server-side and optionally cache the results.
|
|
6
|
+
|
|
7
|
+
## Available Cloud Functions
|
|
8
|
+
|
|
9
|
+
### 1. `calculateAnalyticsOnDemand` (Callable)
|
|
10
|
+
|
|
11
|
+
A callable Cloud Function that calculates analytics on-demand and optionally stores results in cache.
|
|
12
|
+
|
|
13
|
+
**Location**: `Cloud/functions/src/analytics/calculateAnalyticsOnDemand.ts`
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Using the Client Service Helper
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { AnalyticsCloudService } from '@blackcode_sa/metaestetics-api';
|
|
21
|
+
import { getApp } from 'firebase/app';
|
|
22
|
+
|
|
23
|
+
const app = getApp();
|
|
24
|
+
const cloudService = new AnalyticsCloudService(app);
|
|
25
|
+
|
|
26
|
+
// Calculate dashboard analytics on-demand
|
|
27
|
+
const dashboard = await cloudService.calculateDashboard(
|
|
28
|
+
{ clinicBranchId: 'clinic-123' },
|
|
29
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
30
|
+
{ storeInCache: true } // Store result for future use
|
|
31
|
+
);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Direct Callable Function Usage
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { getFunctions, httpsCallable } from 'firebase/functions';
|
|
38
|
+
import { getApp } from 'firebase/app';
|
|
39
|
+
|
|
40
|
+
const functions = getFunctions(getApp(), 'europe-west6');
|
|
41
|
+
const calculateAnalytics = httpsCallable(functions, 'calculateAnalyticsOnDemand');
|
|
42
|
+
|
|
43
|
+
// Calculate revenue metrics grouped by practitioner
|
|
44
|
+
const result = await calculateAnalytics({
|
|
45
|
+
analyticsType: 'revenueByEntity',
|
|
46
|
+
groupBy: 'practitioner',
|
|
47
|
+
filters: { clinicBranchId: 'clinic-123' },
|
|
48
|
+
dateRange: {
|
|
49
|
+
start: '2024-01-01T00:00:00Z',
|
|
50
|
+
end: '2024-12-31T23:59:59Z',
|
|
51
|
+
},
|
|
52
|
+
options: {
|
|
53
|
+
storeInCache: true, // Store in cache after calculation
|
|
54
|
+
useCache: false, // Force fresh calculation
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const revenueByPractitioner = result.data.data;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Supported Analytics Types
|
|
62
|
+
|
|
63
|
+
### Top-Level Analytics
|
|
64
|
+
|
|
65
|
+
- `dashboard` - Complete dashboard analytics
|
|
66
|
+
- `practitioner` - Individual practitioner analytics (requires `entityId`)
|
|
67
|
+
- `procedure` - Individual procedure analytics (requires `entityId`)
|
|
68
|
+
- `clinic` - Clinic-level analytics
|
|
69
|
+
- `timeEfficiency` - Time efficiency metrics
|
|
70
|
+
- `revenue` - Revenue metrics
|
|
71
|
+
- `productUsage` - Product usage metrics
|
|
72
|
+
- `patient` - Patient analytics (optional `entityId`)
|
|
73
|
+
|
|
74
|
+
### Grouped Analytics
|
|
75
|
+
|
|
76
|
+
- `revenueByEntity` - Revenue grouped by clinic/practitioner/procedure/patient/technology (requires `groupBy`)
|
|
77
|
+
- `productUsageByEntity` - Product usage grouped by entity (requires `groupBy`)
|
|
78
|
+
- `timeEfficiencyByEntity` - Time efficiency grouped by entity (requires `groupBy`)
|
|
79
|
+
- `patientBehaviorByEntity` - Patient behavior grouped by entity (requires `groupBy`)
|
|
80
|
+
- `cancellation` - Cancellation metrics grouped by entity (requires `groupBy`)
|
|
81
|
+
- `noShow` - No-show metrics grouped by entity (requires `groupBy`)
|
|
82
|
+
|
|
83
|
+
## Request Parameters
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
interface CalculateAnalyticsRequest {
|
|
87
|
+
analyticsType: string; // Required: Type of analytics to calculate
|
|
88
|
+
filters?: AnalyticsFilters; // Optional: Filters (clinicBranchId, etc.)
|
|
89
|
+
dateRange?: { // Optional: Date range
|
|
90
|
+
start: string; // ISO date string
|
|
91
|
+
end: string; // ISO date string
|
|
92
|
+
};
|
|
93
|
+
entityId?: string; // Required for practitioner/procedure/patient
|
|
94
|
+
groupBy?: EntityType; // Required for grouped analytics
|
|
95
|
+
options?: {
|
|
96
|
+
storeInCache?: boolean; // Default: true - Store result in cache
|
|
97
|
+
useCache?: boolean; // Default: false - Use cache if available
|
|
98
|
+
maxCacheAgeHours?: number; // Default: 12 - Max cache age
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Response Format
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
interface CalculateAnalyticsResponse {
|
|
107
|
+
success: boolean;
|
|
108
|
+
data: any; // The calculated analytics data
|
|
109
|
+
computedAt: string; // ISO timestamp of when it was computed
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Examples
|
|
114
|
+
|
|
115
|
+
### Example 1: Calculate Dashboard Analytics
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
const dashboard = await cloudService.calculateDashboard(
|
|
119
|
+
{ clinicBranchId: 'clinic-123' },
|
|
120
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
121
|
+
{ storeInCache: true }
|
|
122
|
+
);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Example 2: Calculate Revenue by Technology
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
const revenueByTechnology = await cloudService.calculateRevenueByEntity(
|
|
129
|
+
'technology',
|
|
130
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
131
|
+
{ clinicBranchId: 'clinic-123' },
|
|
132
|
+
{ storeInCache: true }
|
|
133
|
+
);
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Example 3: Force Fresh Calculation (Bypass Cache)
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const result = await calculateAnalytics({
|
|
140
|
+
analyticsType: 'dashboard',
|
|
141
|
+
filters: { clinicBranchId: 'clinic-123' },
|
|
142
|
+
dateRange: {
|
|
143
|
+
start: '2024-01-01T00:00:00Z',
|
|
144
|
+
end: '2024-12-31T23:59:59Z',
|
|
145
|
+
},
|
|
146
|
+
options: {
|
|
147
|
+
useCache: false, // Don't use cache
|
|
148
|
+
storeInCache: true, // But store the result
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Example 4: Calculate Practitioner Analytics
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
const practitionerMetrics = await cloudService.calculatePractitioner(
|
|
157
|
+
'practitioner-123',
|
|
158
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-12-31') },
|
|
159
|
+
{
|
|
160
|
+
storeInCache: true,
|
|
161
|
+
clinicBranchId: 'clinic-123',
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Benefits
|
|
167
|
+
|
|
168
|
+
### Performance
|
|
169
|
+
- **Server-side computation**: Faster than client-side for large datasets
|
|
170
|
+
- **Parallel processing**: Cloud Functions can handle multiple requests simultaneously
|
|
171
|
+
- **No client resource usage**: Computation happens in the cloud
|
|
172
|
+
|
|
173
|
+
### Caching
|
|
174
|
+
- **Automatic caching**: Results can be stored automatically
|
|
175
|
+
- **Future reads**: Cached results can be read instantly by `AnalyticsService`
|
|
176
|
+
- **Configurable**: Control whether to use/store cache
|
|
177
|
+
|
|
178
|
+
### Cost Optimization
|
|
179
|
+
- **Efficient**: Server-side computation is optimized
|
|
180
|
+
- **Scalable**: Handles large datasets without client limitations
|
|
181
|
+
- **Predictable**: Fixed cost per calculation
|
|
182
|
+
|
|
183
|
+
## When to Use
|
|
184
|
+
|
|
185
|
+
### Use Cloud Function When:
|
|
186
|
+
- ✅ Cache is stale and you need fresh data immediately
|
|
187
|
+
- ✅ Calculating analytics for large date ranges
|
|
188
|
+
- ✅ Need to calculate multiple analytics types
|
|
189
|
+
- ✅ Want to store results for future use
|
|
190
|
+
- ✅ Client device has limited resources
|
|
191
|
+
|
|
192
|
+
### Use Client Service When:
|
|
193
|
+
- ✅ Cache is fresh (< 12 hours old)
|
|
194
|
+
- ✅ Small date ranges
|
|
195
|
+
- ✅ Quick reads from cache
|
|
196
|
+
- ✅ Offline-first scenarios
|
|
197
|
+
|
|
198
|
+
## Error Handling
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
try {
|
|
202
|
+
const result = await cloudService.calculateDashboard(...);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
if (error.code === 'invalid-argument') {
|
|
205
|
+
// Invalid parameters provided
|
|
206
|
+
} else if (error.code === 'internal') {
|
|
207
|
+
// Server error during calculation
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Integration with AnalyticsService
|
|
213
|
+
|
|
214
|
+
The Cloud Function works seamlessly with `AnalyticsService`:
|
|
215
|
+
|
|
216
|
+
1. **Client checks cache first** (via `AnalyticsService`)
|
|
217
|
+
2. **If cache is stale/missing**, call Cloud Function
|
|
218
|
+
3. **Cloud Function calculates** and optionally stores result
|
|
219
|
+
4. **Future reads** use the cached data
|
|
220
|
+
|
|
221
|
+
This creates a **hybrid approach**:
|
|
222
|
+
- Fast reads from cache (default)
|
|
223
|
+
- On-demand fresh calculations when needed
|
|
224
|
+
- Automatic caching for future use
|
|
225
|
+
|