@blackcode_sa/metaestetics-api 1.12.72 → 1.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +872 -1
- package/dist/admin/index.d.ts +872 -1
- package/dist/admin/index.js +3604 -356
- package/dist/admin/index.mjs +3594 -357
- package/dist/index.d.mts +1349 -1
- package/dist/index.d.ts +1349 -1
- package/dist/index.js +5325 -2141
- package/dist/index.mjs +4939 -1767
- package/package.json +1 -1
- 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/analytics.service.proposal.md +4 -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 +304 -0
- package/src/services/analytics/SUMMARY.md +141 -0
- package/src/services/analytics/TRENDS.md +380 -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 +2142 -0
- package/src/services/analytics/index.ts +4 -0
- package/src/services/analytics/review-analytics.service.ts +941 -0
- package/src/services/analytics/utils/appointment-filtering.utils.ts +138 -0
- package/src/services/analytics/utils/cost-calculation.utils.ts +182 -0
- package/src/services/analytics/utils/grouping.utils.ts +434 -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/analytics/utils/trend-calculation.utils.ts +200 -0
- package/src/services/index.ts +1 -0
- package/src/types/analytics/analytics.types.ts +597 -0
- package/src/types/analytics/grouped-analytics.types.ts +173 -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
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Analytics Service - Complete Summary
|
|
2
|
+
|
|
3
|
+
## 🎯 What We Built
|
|
4
|
+
|
|
5
|
+
A **comprehensive analytics service** with **consistent grouping** across all metrics, supporting analysis by:
|
|
6
|
+
- **Clinic** 🏢
|
|
7
|
+
- **Practitioner (Doctor)** 👨⚕️
|
|
8
|
+
- **Procedure** 🏥 (doctor-specific procedures)
|
|
9
|
+
- **Technology** 🔬 (aggregates all procedures using same technology across all doctors)
|
|
10
|
+
- **Patient** 👥
|
|
11
|
+
|
|
12
|
+
## 📊 Available Analytics (All Support Grouping)
|
|
13
|
+
|
|
14
|
+
### 1. **Revenue Analytics** 💰
|
|
15
|
+
- **Grouped**: `getRevenueMetricsByEntity(groupBy, dateRange?, filters?)`
|
|
16
|
+
- **Aggregate**: `getRevenueMetrics(filters?, dateRange?)`
|
|
17
|
+
- **Group by**: clinic, practitioner, procedure, patient, technology
|
|
18
|
+
|
|
19
|
+
### 2. **Product Usage Analytics** 📦
|
|
20
|
+
- **Grouped**: `getProductUsageMetricsByEntity(groupBy, dateRange?, filters?)`
|
|
21
|
+
- **Aggregate**: `getProductUsageMetrics(productId?, dateRange?)`
|
|
22
|
+
- **Group by**: clinic, practitioner, procedure, patient, technology
|
|
23
|
+
|
|
24
|
+
### 3. **Time Efficiency Analytics** ⏱️
|
|
25
|
+
- **Grouped**: `getTimeEfficiencyMetricsByEntity(groupBy, dateRange?, filters?)`
|
|
26
|
+
- **Aggregate**: `getTimeEfficiencyMetrics(filters?, dateRange?)`
|
|
27
|
+
- **Group by**: clinic, practitioner, procedure, patient, technology
|
|
28
|
+
|
|
29
|
+
### 4. **Patient Behavior Analytics** 👥
|
|
30
|
+
- **Grouped**: `getPatientBehaviorMetricsByEntity(groupBy, dateRange?, filters?)`
|
|
31
|
+
- **Aggregate**: `getPatientAnalytics(patientId?, dateRange?)`
|
|
32
|
+
- **Group by**: clinic, practitioner, procedure, technology
|
|
33
|
+
- Shows: no-show patterns, cancellation patterns, top problematic patients
|
|
34
|
+
|
|
35
|
+
### 5. **Cancellation Analytics** ❌
|
|
36
|
+
- **Grouped**: `getCancellationMetrics(groupBy, dateRange?)`
|
|
37
|
+
- **Group by**: clinic, practitioner, patient, procedure, technology
|
|
38
|
+
- Shows: rates, reasons, lead times
|
|
39
|
+
|
|
40
|
+
### 6. **No-Show Analytics** 🚫
|
|
41
|
+
- **Grouped**: `getNoShowMetrics(groupBy, dateRange?)`
|
|
42
|
+
- **Group by**: clinic, practitioner, patient, procedure, technology
|
|
43
|
+
- Shows: rates, patterns
|
|
44
|
+
|
|
45
|
+
### 7. **Practitioner Analytics** 👨⚕️
|
|
46
|
+
- **Individual**: `getPractitionerAnalytics(practitionerId, dateRange?)`
|
|
47
|
+
- Comprehensive metrics for a single practitioner
|
|
48
|
+
|
|
49
|
+
### 8. **Procedure Analytics** 🏥
|
|
50
|
+
- **Individual**: `getProcedureAnalytics(procedureId?, dateRange?)`
|
|
51
|
+
- **Popularity**: `getProcedurePopularity(dateRange?, limit?)`
|
|
52
|
+
- **Profitability**: `getProcedureProfitability(dateRange?, limit?)`
|
|
53
|
+
|
|
54
|
+
### 9. **Dashboard Analytics** 📊
|
|
55
|
+
- **Comprehensive**: `getDashboardData(filters?, dateRange?, options?)`
|
|
56
|
+
- Aggregated dashboard with all metrics
|
|
57
|
+
|
|
58
|
+
## 🔄 How It Works
|
|
59
|
+
|
|
60
|
+
### **Pre-Computed (Default)** ⚡
|
|
61
|
+
- Cloud Function runs every 12 hours
|
|
62
|
+
- Computes and stores analytics
|
|
63
|
+
- Client reads cached data (instant!)
|
|
64
|
+
- **Cost**: 1 Firestore read
|
|
65
|
+
|
|
66
|
+
### **On-Demand (Fallback)** 🔄
|
|
67
|
+
- Calculates in real-time when cache is stale/missing
|
|
68
|
+
- **Cost**: Variable (depends on appointment count)
|
|
69
|
+
|
|
70
|
+
## 📝 Usage Examples
|
|
71
|
+
|
|
72
|
+
### Example 1: Revenue by Doctor
|
|
73
|
+
```typescript
|
|
74
|
+
const revenueByDoctor = await analyticsService.getRevenueMetricsByEntity(
|
|
75
|
+
'practitioner',
|
|
76
|
+
dateRange
|
|
77
|
+
);
|
|
78
|
+
// Returns array with revenue for each doctor
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Example 2: Patient No-Show by Doctor
|
|
82
|
+
```typescript
|
|
83
|
+
const patientBehaviorByDoctor = await analyticsService.getPatientBehaviorMetricsByEntity(
|
|
84
|
+
'practitioner',
|
|
85
|
+
dateRange
|
|
86
|
+
);
|
|
87
|
+
// Shows which patients have highest no-show rates for each doctor
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Example 3: Product Usage by Procedure
|
|
91
|
+
```typescript
|
|
92
|
+
const productUsageByProcedure = await analyticsService.getProductUsageMetricsByEntity(
|
|
93
|
+
'procedure',
|
|
94
|
+
dateRange
|
|
95
|
+
);
|
|
96
|
+
// Shows product usage patterns for each procedure
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Example 4: Time Efficiency by Clinic
|
|
100
|
+
```typescript
|
|
101
|
+
const timeEfficiencyByClinic = await analyticsService.getTimeEfficiencyMetricsByEntity(
|
|
102
|
+
'clinic',
|
|
103
|
+
dateRange
|
|
104
|
+
);
|
|
105
|
+
// Compares time efficiency across clinics
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Example 5: Combined Analysis
|
|
109
|
+
```typescript
|
|
110
|
+
// Get multiple grouped metrics
|
|
111
|
+
const [revenue, products, time, behavior] = await Promise.all([
|
|
112
|
+
analyticsService.getRevenueMetricsByEntity('practitioner', dateRange),
|
|
113
|
+
analyticsService.getProductUsageMetricsByEntity('practitioner', dateRange),
|
|
114
|
+
analyticsService.getTimeEfficiencyMetricsByEntity('practitioner', dateRange),
|
|
115
|
+
analyticsService.getPatientBehaviorMetricsByEntity('practitioner', dateRange),
|
|
116
|
+
]);
|
|
117
|
+
// Combine for comprehensive analysis
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 🎯 Key Features
|
|
121
|
+
|
|
122
|
+
✅ **Consistent Grouping** - All metrics support clinic/practitioner/procedure/patient/technology grouping
|
|
123
|
+
✅ **Pre-Computed** - Fast cached reads (default)
|
|
124
|
+
✅ **On-Demand** - Real-time calculation when needed
|
|
125
|
+
✅ **Flexible Filtering** - Filter by clinic, practitioner, procedure, patient, date range
|
|
126
|
+
✅ **Comprehensive** - 9+ analytics categories
|
|
127
|
+
✅ **Type-Safe** - Full TypeScript support
|
|
128
|
+
✅ **Well-Documented** - Complete guides and examples
|
|
129
|
+
|
|
130
|
+
## 📚 Documentation
|
|
131
|
+
|
|
132
|
+
- **QUICK_START.md** - Quick reference guide
|
|
133
|
+
- **USAGE_GUIDE.md** - Complete usage guide with examples
|
|
134
|
+
- **GROUPED_ANALYTICS.md** - Grouped analytics guide
|
|
135
|
+
- **ARCHITECTURE.md** - Technical architecture
|
|
136
|
+
- **README.md** - API reference
|
|
137
|
+
|
|
138
|
+
## 🚀 Ready to Use!
|
|
139
|
+
|
|
140
|
+
The service is fully implemented and ready for use. All methods support consistent grouping patterns, making it easy to analyze your clinic data from any perspective.
|
|
141
|
+
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
# Trend Analysis - Complete Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Trend analysis provides time-series insights into key metrics, showing how values change over time and comparing current periods to previous periods. Trends help identify patterns, growth, and areas for improvement.
|
|
6
|
+
|
|
7
|
+
## Key Features
|
|
8
|
+
|
|
9
|
+
- **Period-based grouping**: Week, Month, Quarter, or Year
|
|
10
|
+
- **Percentage change calculations**: Compare current period to previous period
|
|
11
|
+
- **Direction indicators**: Up, down, or stable trends
|
|
12
|
+
- **Grouped trends**: Analyze trends by clinic, practitioner, procedure, technology, or patient
|
|
13
|
+
- **Visualization ready**: Data structured for easy chart rendering
|
|
14
|
+
|
|
15
|
+
## Available Trend Methods
|
|
16
|
+
|
|
17
|
+
### 1. **Revenue Trends** 💰
|
|
18
|
+
|
|
19
|
+
Analyze revenue changes over time with period-over-period comparisons.
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
const revenueTrends = await analyticsService.getRevenueTrends(
|
|
23
|
+
dateRange,
|
|
24
|
+
'month', // Period: 'week' | 'month' | 'quarter' | 'year'
|
|
25
|
+
{ clinicBranchId: 'clinic-123' }, // Optional filters
|
|
26
|
+
'practitioner' // Optional: group by entity
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
// Returns: RevenueTrend[]
|
|
30
|
+
// [
|
|
31
|
+
// {
|
|
32
|
+
// period: '2024-01',
|
|
33
|
+
// startDate: Date,
|
|
34
|
+
// endDate: Date,
|
|
35
|
+
// revenue: 50000,
|
|
36
|
+
// appointmentCount: 100,
|
|
37
|
+
// averageRevenue: 500,
|
|
38
|
+
// currency: 'CHF',
|
|
39
|
+
// previousPeriod: {
|
|
40
|
+
// revenue: 45000,
|
|
41
|
+
// appointmentCount: 90,
|
|
42
|
+
// percentageChange: 11.1, // 11.1% increase
|
|
43
|
+
// direction: 'up'
|
|
44
|
+
// }
|
|
45
|
+
// },
|
|
46
|
+
// ...
|
|
47
|
+
// ]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Use Cases:**
|
|
51
|
+
- Track revenue growth month-over-month
|
|
52
|
+
- Compare revenue by practitioner over quarters
|
|
53
|
+
- Analyze seasonal patterns
|
|
54
|
+
- Identify revenue trends by technology
|
|
55
|
+
|
|
56
|
+
### 2. **Duration/Efficiency Trends** ⏱️
|
|
57
|
+
|
|
58
|
+
Monitor time efficiency trends to optimize scheduling and resource allocation.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const durationTrends = await analyticsService.getDurationTrends(
|
|
62
|
+
dateRange,
|
|
63
|
+
'month',
|
|
64
|
+
{ clinicBranchId: 'clinic-123' },
|
|
65
|
+
'procedure' // Optional: group by entity
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Returns: DurationTrend[]
|
|
69
|
+
// [
|
|
70
|
+
// {
|
|
71
|
+
// period: '2024-01',
|
|
72
|
+
// startDate: Date,
|
|
73
|
+
// endDate: Date,
|
|
74
|
+
// averageBookedDuration: 60, // minutes
|
|
75
|
+
// averageActualDuration: 55, // minutes
|
|
76
|
+
// averageEfficiency: 91.7, // percentage
|
|
77
|
+
// appointmentCount: 100,
|
|
78
|
+
// previousPeriod: {
|
|
79
|
+
// averageBookedDuration: 60,
|
|
80
|
+
// averageActualDuration: 58,
|
|
81
|
+
// averageEfficiency: 96.7,
|
|
82
|
+
// efficiencyPercentageChange: 5.0, // 5% decrease in efficiency
|
|
83
|
+
// direction: 'down'
|
|
84
|
+
// }
|
|
85
|
+
// },
|
|
86
|
+
// ...
|
|
87
|
+
// ]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Use Cases:**
|
|
91
|
+
- Track efficiency improvements over time
|
|
92
|
+
- Identify scheduling optimization opportunities
|
|
93
|
+
- Compare efficiency across practitioners
|
|
94
|
+
- Monitor time management trends
|
|
95
|
+
|
|
96
|
+
### 3. **Appointment Trends** 📅
|
|
97
|
+
|
|
98
|
+
Analyze appointment volume and status distribution over time.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const appointmentTrends = await analyticsService.getAppointmentTrends(
|
|
102
|
+
dateRange,
|
|
103
|
+
'week',
|
|
104
|
+
{ clinicBranchId: 'clinic-123' }
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// Returns: AppointmentTrend[]
|
|
108
|
+
// [
|
|
109
|
+
// {
|
|
110
|
+
// period: '2024-W01',
|
|
111
|
+
// startDate: Date,
|
|
112
|
+
// endDate: Date,
|
|
113
|
+
// totalAppointments: 50,
|
|
114
|
+
// completedAppointments: 45,
|
|
115
|
+
// canceledAppointments: 3,
|
|
116
|
+
// noShowAppointments: 2,
|
|
117
|
+
// pendingAppointments: 0,
|
|
118
|
+
// confirmedAppointments: 0,
|
|
119
|
+
// previousPeriod: {
|
|
120
|
+
// totalAppointments: 48,
|
|
121
|
+
// completedAppointments: 43,
|
|
122
|
+
// percentageChange: 4.2, // 4.2% increase
|
|
123
|
+
// direction: 'up'
|
|
124
|
+
// }
|
|
125
|
+
// },
|
|
126
|
+
// ...
|
|
127
|
+
// ]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Use Cases:**
|
|
131
|
+
- Track appointment volume growth
|
|
132
|
+
- Monitor completion rates over time
|
|
133
|
+
- Analyze cancellation patterns
|
|
134
|
+
- Compare appointment trends across clinics
|
|
135
|
+
|
|
136
|
+
### 4. **Cancellation Rate Trends** ❌
|
|
137
|
+
|
|
138
|
+
Track cancellation and no-show rates to identify patterns and improve patient retention.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
const cancellationTrends = await analyticsService.getCancellationRateTrends(
|
|
142
|
+
dateRange,
|
|
143
|
+
'month',
|
|
144
|
+
{ clinicBranchId: 'clinic-123' },
|
|
145
|
+
'practitioner' // Optional: group by entity
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// Returns: CancellationRateTrend[]
|
|
149
|
+
// [
|
|
150
|
+
// {
|
|
151
|
+
// period: '2024-01',
|
|
152
|
+
// startDate: Date,
|
|
153
|
+
// endDate: Date,
|
|
154
|
+
// cancellationRate: 5.0, // percentage
|
|
155
|
+
// noShowRate: 2.0, // percentage
|
|
156
|
+
// totalAppointments: 100,
|
|
157
|
+
// canceledAppointments: 5,
|
|
158
|
+
// noShowAppointments: 2,
|
|
159
|
+
// previousPeriod: {
|
|
160
|
+
// cancellationRate: 6.0,
|
|
161
|
+
// noShowRate: 2.5,
|
|
162
|
+
// cancellationRateChange: 1.0, // 1% decrease (improvement)
|
|
163
|
+
// noShowRateChange: 0.5, // 0.5% decrease (improvement)
|
|
164
|
+
// direction: 'down' // Lower is better for cancellations
|
|
165
|
+
// }
|
|
166
|
+
// },
|
|
167
|
+
// ...
|
|
168
|
+
// ]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Use Cases:**
|
|
172
|
+
- Monitor cancellation rate improvements
|
|
173
|
+
- Compare cancellation rates across practitioners
|
|
174
|
+
- Identify problematic time periods
|
|
175
|
+
- Track effectiveness of retention strategies
|
|
176
|
+
|
|
177
|
+
## Period Types
|
|
178
|
+
|
|
179
|
+
Trends support four period types:
|
|
180
|
+
|
|
181
|
+
### Week (`'week'`)
|
|
182
|
+
- Groups data by ISO week (Monday to Sunday)
|
|
183
|
+
- Period format: `"2024-W01"` (Year-WeekNumber)
|
|
184
|
+
- Best for: Short-term analysis, weekly patterns
|
|
185
|
+
|
|
186
|
+
### Month (`'month'`)
|
|
187
|
+
- Groups data by calendar month
|
|
188
|
+
- Period format: `"2024-01"` (Year-Month)
|
|
189
|
+
- Best for: Monthly reporting, seasonal analysis
|
|
190
|
+
|
|
191
|
+
### Quarter (`'quarter'`)
|
|
192
|
+
- Groups data by calendar quarter (3 months)
|
|
193
|
+
- Period format: `"2024-Q1"` (Year-Quarter)
|
|
194
|
+
- Best for: Quarterly business reviews, long-term trends
|
|
195
|
+
|
|
196
|
+
### Year (`'year'`)
|
|
197
|
+
- Groups data by calendar year
|
|
198
|
+
- Period format: `"2024"` (Year)
|
|
199
|
+
- Best for: Annual comparisons, long-term growth
|
|
200
|
+
|
|
201
|
+
## Percentage Change Calculation
|
|
202
|
+
|
|
203
|
+
All trends include `previousPeriod` comparison data:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
previousPeriod: {
|
|
207
|
+
// Previous period value
|
|
208
|
+
value: number,
|
|
209
|
+
|
|
210
|
+
// Percentage change (absolute value)
|
|
211
|
+
percentageChange: number, // e.g., 11.1 means 11.1% change
|
|
212
|
+
|
|
213
|
+
// Direction: 'up' | 'down' | 'stable'
|
|
214
|
+
direction: 'up' // Indicates if trend is increasing, decreasing, or stable
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Calculation Formula:**
|
|
219
|
+
```typescript
|
|
220
|
+
percentageChange = ((current - previous) / previous) * 100
|
|
221
|
+
direction = percentageChange > 0.01 ? 'up' : percentageChange < -0.01 ? 'down' : 'stable'
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Note:** For cancellation/no-show rates, lower values are better, so the direction may be inverted in UI (e.g., a decrease in cancellation rate shows as 'up' trend).
|
|
225
|
+
|
|
226
|
+
## Grouped Trends
|
|
227
|
+
|
|
228
|
+
All trend methods support optional grouping by entity:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
// Overall trends (no grouping)
|
|
232
|
+
const overallTrends = await analyticsService.getRevenueTrends(
|
|
233
|
+
dateRange,
|
|
234
|
+
'month',
|
|
235
|
+
{ clinicBranchId: 'clinic-123' }
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
// Trends grouped by practitioner
|
|
239
|
+
const practitionerTrends = await analyticsService.getRevenueTrends(
|
|
240
|
+
dateRange,
|
|
241
|
+
'month',
|
|
242
|
+
{ clinicBranchId: 'clinic-123' },
|
|
243
|
+
'practitioner' // Groups trends by practitioner
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// Trends grouped by technology
|
|
247
|
+
const technologyTrends = await analyticsService.getRevenueTrends(
|
|
248
|
+
dateRange,
|
|
249
|
+
'quarter',
|
|
250
|
+
{ clinicBranchId: 'clinic-123' },
|
|
251
|
+
'technology' // Aggregates all procedures using same technology
|
|
252
|
+
);
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Supported Grouping:**
|
|
256
|
+
- `'clinic'` - Trends by clinic
|
|
257
|
+
- `'practitioner'` - Trends by doctor
|
|
258
|
+
- `'procedure'` - Trends by procedure (includes practitioner association)
|
|
259
|
+
- `'technology'` - Trends by technology (aggregates procedures)
|
|
260
|
+
- `'patient'` - Trends by patient
|
|
261
|
+
|
|
262
|
+
## Frontend Integration
|
|
263
|
+
|
|
264
|
+
### Trend Indicators
|
|
265
|
+
|
|
266
|
+
Display percentage changes with visual indicators:
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import { TrendIndicator } from '@/pages/Analytics/components/TrendIndicator';
|
|
270
|
+
|
|
271
|
+
<TrendIndicator
|
|
272
|
+
percentageChange={11.1}
|
|
273
|
+
direction="up"
|
|
274
|
+
size="small"
|
|
275
|
+
/>
|
|
276
|
+
// Displays: ↑ 11.1%
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Trend Charts
|
|
280
|
+
|
|
281
|
+
Visualize trends over time using line charts:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
import { TrendChart } from '@/pages/Analytics/components/TrendChart';
|
|
285
|
+
|
|
286
|
+
<TrendChart
|
|
287
|
+
data={trendData.map(t => ({ period: t.period, value: t.revenue }))}
|
|
288
|
+
dataKey="value"
|
|
289
|
+
name="Revenue"
|
|
290
|
+
color="#3b82f6"
|
|
291
|
+
height={300}
|
|
292
|
+
formatValue={(value) => `CHF ${value.toLocaleString()}`}
|
|
293
|
+
/>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Period Selector
|
|
297
|
+
|
|
298
|
+
Allow users to switch between period types:
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
import { PeriodSelector } from '@/pages/Analytics/components/PeriodSelector';
|
|
302
|
+
|
|
303
|
+
<PeriodSelector
|
|
304
|
+
value={trendPeriod}
|
|
305
|
+
onChange={setTrendPeriod}
|
|
306
|
+
/>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Complete Example
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { AnalyticsService } from '@blackcode_sa/metaestetics-api';
|
|
313
|
+
|
|
314
|
+
const analyticsService = new AnalyticsService(db, auth, app, appointmentService);
|
|
315
|
+
|
|
316
|
+
// Define date range
|
|
317
|
+
const dateRange = {
|
|
318
|
+
start: new Date('2024-01-01'),
|
|
319
|
+
end: new Date('2024-12-31')
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// Get revenue trends by month
|
|
323
|
+
const revenueTrends = await analyticsService.getRevenueTrends(
|
|
324
|
+
dateRange,
|
|
325
|
+
'month',
|
|
326
|
+
{ clinicBranchId: 'clinic-123' }
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
// Process trends
|
|
330
|
+
revenueTrends.forEach(trend => {
|
|
331
|
+
console.log(`Period: ${trend.period}`);
|
|
332
|
+
console.log(`Revenue: ${trend.currency} ${trend.revenue.toLocaleString()}`);
|
|
333
|
+
console.log(`Appointments: ${trend.appointmentCount}`);
|
|
334
|
+
|
|
335
|
+
if (trend.previousPeriod) {
|
|
336
|
+
const change = trend.previousPeriod.percentageChange;
|
|
337
|
+
const direction = trend.previousPeriod.direction;
|
|
338
|
+
console.log(`Change: ${direction === 'up' ? '+' : '-'}${change.toFixed(1)}%`);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Get efficiency trends grouped by practitioner
|
|
343
|
+
const efficiencyTrends = await analyticsService.getDurationTrends(
|
|
344
|
+
dateRange,
|
|
345
|
+
'quarter',
|
|
346
|
+
{ clinicBranchId: 'clinic-123' },
|
|
347
|
+
'practitioner'
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
// Analyze efficiency improvements
|
|
351
|
+
efficiencyTrends.forEach(trend => {
|
|
352
|
+
if (trend.previousPeriod && trend.previousPeriod.direction === 'up') {
|
|
353
|
+
console.log(`Efficiency improved by ${trend.previousPeriod.efficiencyPercentageChange}%`);
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Best Practices
|
|
359
|
+
|
|
360
|
+
1. **Choose appropriate period**: Use weeks for short-term analysis, quarters/years for strategic planning
|
|
361
|
+
2. **Compare periods**: Always check `previousPeriod` data to understand context
|
|
362
|
+
3. **Group when needed**: Use entity grouping to drill down into specific areas
|
|
363
|
+
4. **Visualize trends**: Use charts to make trends easier to understand
|
|
364
|
+
5. **Consider seasonality**: Account for seasonal patterns when analyzing trends
|
|
365
|
+
6. **Monitor direction**: Pay attention to trend direction (up/down/stable) for quick insights
|
|
366
|
+
|
|
367
|
+
## Limitations
|
|
368
|
+
|
|
369
|
+
- **No custom periods**: Trends only support week, month, quarter, and year periods
|
|
370
|
+
- **No trailing periods**: Trends require predefined periods (not "last 7 days" style)
|
|
371
|
+
- **Period alignment**: Date ranges should align with period boundaries for best results
|
|
372
|
+
- **In-memory calculation**: Trends are calculated on-demand (consider caching for large datasets)
|
|
373
|
+
|
|
374
|
+
## Related Documentation
|
|
375
|
+
|
|
376
|
+
- [Analytics Service README](./README.md)
|
|
377
|
+
- [Grouped Analytics Guide](./GROUPED_ANALYTICS.md)
|
|
378
|
+
- [Analytics Types](../../types/analytics/analytics.types.ts)
|
|
379
|
+
- [Trend Calculation Utils](./utils/trend-calculation.utils.ts)
|
|
380
|
+
|