@blackcode_sa/metaestetics-api 1.12.67 → 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/backoffice/index.d.mts +40 -0
- package/dist/backoffice/index.d.ts +40 -0
- package/dist/backoffice/index.js +118 -18
- package/dist/backoffice/index.mjs +118 -20
- package/dist/index.d.mts +1097 -2
- package/dist/index.d.ts +1097 -2
- package/dist/index.js +4224 -2091
- package/dist/index.mjs +3941 -1821
- 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/backoffice/services/category.service.ts +49 -6
- package/src/backoffice/services/subcategory.service.ts +50 -6
- package/src/backoffice/services/technology.service.ts +53 -6
- 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/services/procedure/procedure.service.ts +3 -3
- 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,222 @@
|
|
|
1
|
+
import { Functions, getFunctions, httpsCallable } from 'firebase/functions';
|
|
2
|
+
import { FirebaseApp } from 'firebase/app';
|
|
3
|
+
import {
|
|
4
|
+
AnalyticsDateRange,
|
|
5
|
+
AnalyticsFilters,
|
|
6
|
+
EntityType,
|
|
7
|
+
} from '../../types/analytics';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Request data for on-demand analytics calculation
|
|
11
|
+
*/
|
|
12
|
+
interface CalculateAnalyticsRequest {
|
|
13
|
+
analyticsType:
|
|
14
|
+
| 'dashboard'
|
|
15
|
+
| 'practitioner'
|
|
16
|
+
| 'procedure'
|
|
17
|
+
| 'clinic'
|
|
18
|
+
| 'timeEfficiency'
|
|
19
|
+
| 'revenue'
|
|
20
|
+
| 'cancellation'
|
|
21
|
+
| 'noShow'
|
|
22
|
+
| 'productUsage'
|
|
23
|
+
| 'patient'
|
|
24
|
+
| 'revenueByEntity'
|
|
25
|
+
| 'productUsageByEntity'
|
|
26
|
+
| 'timeEfficiencyByEntity'
|
|
27
|
+
| 'patientBehaviorByEntity';
|
|
28
|
+
filters?: AnalyticsFilters;
|
|
29
|
+
dateRange?: {
|
|
30
|
+
start: string; // ISO date string
|
|
31
|
+
end: string; // ISO date string
|
|
32
|
+
};
|
|
33
|
+
entityId?: string;
|
|
34
|
+
groupBy?: EntityType;
|
|
35
|
+
options?: {
|
|
36
|
+
storeInCache?: boolean;
|
|
37
|
+
useCache?: boolean;
|
|
38
|
+
maxCacheAgeHours?: number;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Response from on-demand analytics calculation
|
|
44
|
+
*/
|
|
45
|
+
interface CalculateAnalyticsResponse {
|
|
46
|
+
success: boolean;
|
|
47
|
+
data: any;
|
|
48
|
+
computedAt: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Client-side service for calling analytics Cloud Functions
|
|
53
|
+
*
|
|
54
|
+
* This service provides a convenient way to trigger on-demand analytics
|
|
55
|
+
* calculations via Cloud Functions, which can be faster and more efficient
|
|
56
|
+
* than calculating on the client.
|
|
57
|
+
*/
|
|
58
|
+
export class AnalyticsCloudService {
|
|
59
|
+
private functions: Functions;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates a new AnalyticsCloudService instance
|
|
63
|
+
*
|
|
64
|
+
* @param app - Firebase App instance
|
|
65
|
+
* @param region - Functions region (default: 'europe-west6')
|
|
66
|
+
*/
|
|
67
|
+
constructor(app: FirebaseApp, region: string = 'europe-west6') {
|
|
68
|
+
this.functions = getFunctions(app, region);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Calls the Cloud Function to calculate analytics on-demand
|
|
73
|
+
*
|
|
74
|
+
* @param request - Analytics calculation request
|
|
75
|
+
* @returns Promise resolving to the calculated analytics data
|
|
76
|
+
*/
|
|
77
|
+
async calculateOnDemand(request: CalculateAnalyticsRequest): Promise<any> {
|
|
78
|
+
const callable = httpsCallable<CalculateAnalyticsRequest, CalculateAnalyticsResponse>(
|
|
79
|
+
this.functions,
|
|
80
|
+
'calculateAnalyticsOnDemand',
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const response = await callable(request);
|
|
84
|
+
|
|
85
|
+
if (!response.data.success) {
|
|
86
|
+
throw new Error('Analytics calculation failed');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return response.data.data;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Calculate dashboard analytics on-demand
|
|
94
|
+
*/
|
|
95
|
+
async calculateDashboard(
|
|
96
|
+
filters: AnalyticsFilters,
|
|
97
|
+
dateRange: AnalyticsDateRange,
|
|
98
|
+
options?: { storeInCache?: boolean },
|
|
99
|
+
) {
|
|
100
|
+
return this.calculateOnDemand({
|
|
101
|
+
analyticsType: 'dashboard',
|
|
102
|
+
filters,
|
|
103
|
+
dateRange: {
|
|
104
|
+
start: dateRange.start.toISOString(),
|
|
105
|
+
end: dateRange.end.toISOString(),
|
|
106
|
+
},
|
|
107
|
+
options,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Calculate practitioner analytics on-demand
|
|
113
|
+
*/
|
|
114
|
+
async calculatePractitioner(
|
|
115
|
+
practitionerId: string,
|
|
116
|
+
dateRange?: AnalyticsDateRange,
|
|
117
|
+
options?: { storeInCache?: boolean; clinicBranchId?: string },
|
|
118
|
+
) {
|
|
119
|
+
return this.calculateOnDemand({
|
|
120
|
+
analyticsType: 'practitioner',
|
|
121
|
+
entityId: practitionerId,
|
|
122
|
+
filters: options?.clinicBranchId ? { clinicBranchId: options.clinicBranchId } : undefined,
|
|
123
|
+
dateRange: dateRange
|
|
124
|
+
? {
|
|
125
|
+
start: dateRange.start.toISOString(),
|
|
126
|
+
end: dateRange.end.toISOString(),
|
|
127
|
+
}
|
|
128
|
+
: undefined,
|
|
129
|
+
options,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Calculate procedure analytics on-demand
|
|
135
|
+
*/
|
|
136
|
+
async calculateProcedure(
|
|
137
|
+
procedureId: string,
|
|
138
|
+
dateRange?: AnalyticsDateRange,
|
|
139
|
+
options?: { storeInCache?: boolean; clinicBranchId?: string },
|
|
140
|
+
) {
|
|
141
|
+
return this.calculateOnDemand({
|
|
142
|
+
analyticsType: 'procedure',
|
|
143
|
+
entityId: procedureId,
|
|
144
|
+
filters: options?.clinicBranchId ? { clinicBranchId: options.clinicBranchId } : undefined,
|
|
145
|
+
dateRange: dateRange
|
|
146
|
+
? {
|
|
147
|
+
start: dateRange.start.toISOString(),
|
|
148
|
+
end: dateRange.end.toISOString(),
|
|
149
|
+
}
|
|
150
|
+
: undefined,
|
|
151
|
+
options,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Calculate revenue metrics grouped by entity on-demand
|
|
157
|
+
*/
|
|
158
|
+
async calculateRevenueByEntity(
|
|
159
|
+
groupBy: EntityType,
|
|
160
|
+
dateRange?: AnalyticsDateRange,
|
|
161
|
+
filters?: AnalyticsFilters,
|
|
162
|
+
options?: { storeInCache?: boolean },
|
|
163
|
+
) {
|
|
164
|
+
return this.calculateOnDemand({
|
|
165
|
+
analyticsType: 'revenueByEntity',
|
|
166
|
+
groupBy,
|
|
167
|
+
filters,
|
|
168
|
+
dateRange: dateRange
|
|
169
|
+
? {
|
|
170
|
+
start: dateRange.start.toISOString(),
|
|
171
|
+
end: dateRange.end.toISOString(),
|
|
172
|
+
}
|
|
173
|
+
: undefined,
|
|
174
|
+
options,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Calculate cancellation metrics grouped by entity on-demand
|
|
180
|
+
*/
|
|
181
|
+
async calculateCancellations(
|
|
182
|
+
groupBy: EntityType,
|
|
183
|
+
dateRange?: AnalyticsDateRange,
|
|
184
|
+
options?: { storeInCache?: boolean; clinicBranchId?: string },
|
|
185
|
+
) {
|
|
186
|
+
return this.calculateOnDemand({
|
|
187
|
+
analyticsType: 'cancellation',
|
|
188
|
+
groupBy,
|
|
189
|
+
filters: options?.clinicBranchId ? { clinicBranchId: options.clinicBranchId } : undefined,
|
|
190
|
+
dateRange: dateRange
|
|
191
|
+
? {
|
|
192
|
+
start: dateRange.start.toISOString(),
|
|
193
|
+
end: dateRange.end.toISOString(),
|
|
194
|
+
}
|
|
195
|
+
: undefined,
|
|
196
|
+
options,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Calculate no-show metrics grouped by entity on-demand
|
|
202
|
+
*/
|
|
203
|
+
async calculateNoShows(
|
|
204
|
+
groupBy: EntityType,
|
|
205
|
+
dateRange?: AnalyticsDateRange,
|
|
206
|
+
options?: { storeInCache?: boolean; clinicBranchId?: string },
|
|
207
|
+
) {
|
|
208
|
+
return this.calculateOnDemand({
|
|
209
|
+
analyticsType: 'noShow',
|
|
210
|
+
groupBy,
|
|
211
|
+
filters: options?.clinicBranchId ? { clinicBranchId: options.clinicBranchId } : undefined,
|
|
212
|
+
dateRange: dateRange
|
|
213
|
+
? {
|
|
214
|
+
start: dateRange.start.toISOString(),
|
|
215
|
+
end: dateRange.end.toISOString(),
|
|
216
|
+
}
|
|
217
|
+
: undefined,
|
|
218
|
+
options,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|