@creezio/observability 0.22.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.
Files changed (209) hide show
  1. package/README.md +328 -0
  2. package/dist/.creezio-src-hash.json +4 -0
  3. package/dist/api-endpoints/http-routes.d.ts +11 -0
  4. package/dist/api-endpoints/http-routes.d.ts.map +1 -0
  5. package/dist/api-endpoints/http-routes.js +11 -0
  6. package/dist/api-endpoints/http-routes.js.map +1 -0
  7. package/dist/api-endpoints/index.d.ts +4 -0
  8. package/dist/api-endpoints/index.d.ts.map +1 -0
  9. package/dist/api-endpoints/index.js +3 -0
  10. package/dist/api-endpoints/index.js.map +1 -0
  11. package/dist/api-endpoints/registry.d.ts +66 -0
  12. package/dist/api-endpoints/registry.d.ts.map +1 -0
  13. package/dist/api-endpoints/registry.js +102 -0
  14. package/dist/api-endpoints/registry.js.map +1 -0
  15. package/dist/api-mount.d.ts +7 -0
  16. package/dist/api-mount.d.ts.map +1 -0
  17. package/dist/api-mount.js +114 -0
  18. package/dist/api-mount.js.map +1 -0
  19. package/dist/helpers.d.ts +23 -0
  20. package/dist/helpers.d.ts.map +1 -0
  21. package/dist/helpers.js +36 -0
  22. package/dist/helpers.js.map +1 -0
  23. package/dist/index.d.ts +35 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +24 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/memory-store.d.ts +3 -0
  28. package/dist/memory-store.d.ts.map +1 -0
  29. package/dist/memory-store.js +113 -0
  30. package/dist/memory-store.js.map +1 -0
  31. package/dist/ops/emit.d.ts +8 -0
  32. package/dist/ops/emit.d.ts.map +1 -0
  33. package/dist/ops/emit.js +15 -0
  34. package/dist/ops/emit.js.map +1 -0
  35. package/dist/ops/fleet-activity.d.ts +50 -0
  36. package/dist/ops/fleet-activity.d.ts.map +1 -0
  37. package/dist/ops/fleet-activity.js +123 -0
  38. package/dist/ops/fleet-activity.js.map +1 -0
  39. package/dist/ops/fleet-agent.d.ts +102 -0
  40. package/dist/ops/fleet-agent.d.ts.map +1 -0
  41. package/dist/ops/fleet-agent.js +352 -0
  42. package/dist/ops/fleet-agent.js.map +1 -0
  43. package/dist/ops/fleet-samples.d.ts +33 -0
  44. package/dist/ops/fleet-samples.d.ts.map +1 -0
  45. package/dist/ops/fleet-samples.js +223 -0
  46. package/dist/ops/fleet-samples.js.map +1 -0
  47. package/dist/ops/journal.d.ts +56 -0
  48. package/dist/ops/journal.d.ts.map +1 -0
  49. package/dist/ops/journal.js +307 -0
  50. package/dist/ops/journal.js.map +1 -0
  51. package/dist/ops/rules.d.ts +16 -0
  52. package/dist/ops/rules.d.ts.map +1 -0
  53. package/dist/ops/rules.js +98 -0
  54. package/dist/ops/rules.js.map +1 -0
  55. package/dist/ops/types.d.ts +69 -0
  56. package/dist/ops/types.d.ts.map +1 -0
  57. package/dist/ops/types.js +119 -0
  58. package/dist/ops/types.js.map +1 -0
  59. package/dist/request-logs/config.d.ts +19 -0
  60. package/dist/request-logs/config.d.ts.map +1 -0
  61. package/dist/request-logs/config.js +36 -0
  62. package/dist/request-logs/config.js.map +1 -0
  63. package/dist/request-logs/http-routes.d.ts +8 -0
  64. package/dist/request-logs/http-routes.d.ts.map +1 -0
  65. package/dist/request-logs/http-routes.js +29 -0
  66. package/dist/request-logs/http-routes.js.map +1 -0
  67. package/dist/request-logs/index.d.ts +6 -0
  68. package/dist/request-logs/index.d.ts.map +1 -0
  69. package/dist/request-logs/index.js +5 -0
  70. package/dist/request-logs/index.js.map +1 -0
  71. package/dist/request-logs/middleware.d.ts +11 -0
  72. package/dist/request-logs/middleware.d.ts.map +1 -0
  73. package/dist/request-logs/middleware.js +198 -0
  74. package/dist/request-logs/middleware.js.map +1 -0
  75. package/dist/request-logs/request-logs.d.ts +60 -0
  76. package/dist/request-logs/request-logs.d.ts.map +1 -0
  77. package/dist/request-logs/request-logs.js +260 -0
  78. package/dist/request-logs/request-logs.js.map +1 -0
  79. package/dist/schema.d.ts +3 -0
  80. package/dist/schema.d.ts.map +1 -0
  81. package/dist/schema.js +21 -0
  82. package/dist/schema.js.map +1 -0
  83. package/dist/sqlite-driver.d.ts +16 -0
  84. package/dist/sqlite-driver.d.ts.map +1 -0
  85. package/dist/sqlite-driver.js +15 -0
  86. package/dist/sqlite-driver.js.map +1 -0
  87. package/dist/sqlite-store.d.ts +12 -0
  88. package/dist/sqlite-store.d.ts.map +1 -0
  89. package/dist/sqlite-store.js +176 -0
  90. package/dist/sqlite-store.js.map +1 -0
  91. package/dist/types.d.ts +67 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +9 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/usage/adapters.d.ts +31 -0
  96. package/dist/usage/adapters.d.ts.map +1 -0
  97. package/dist/usage/adapters.js +37 -0
  98. package/dist/usage/adapters.js.map +1 -0
  99. package/dist/usage/http-routes.d.ts +23 -0
  100. package/dist/usage/http-routes.d.ts.map +1 -0
  101. package/dist/usage/http-routes.js +150 -0
  102. package/dist/usage/http-routes.js.map +1 -0
  103. package/dist/usage/index.d.ts +11 -0
  104. package/dist/usage/index.d.ts.map +1 -0
  105. package/dist/usage/index.js +7 -0
  106. package/dist/usage/index.js.map +1 -0
  107. package/dist/usage/ui-brand.d.ts +23 -0
  108. package/dist/usage/ui-brand.d.ts.map +1 -0
  109. package/dist/usage/ui-brand.js +18 -0
  110. package/dist/usage/ui-brand.js.map +1 -0
  111. package/dist/usage/usage-analytics-productivity.d.ts +73 -0
  112. package/dist/usage/usage-analytics-productivity.d.ts.map +1 -0
  113. package/dist/usage/usage-analytics-productivity.js +317 -0
  114. package/dist/usage/usage-analytics-productivity.js.map +1 -0
  115. package/dist/usage/usage-analytics-shared.d.ts +5 -0
  116. package/dist/usage/usage-analytics-shared.d.ts.map +1 -0
  117. package/dist/usage/usage-analytics-shared.js +20 -0
  118. package/dist/usage/usage-analytics-shared.js.map +1 -0
  119. package/dist/usage/usage-analytics.d.ts +127 -0
  120. package/dist/usage/usage-analytics.d.ts.map +1 -0
  121. package/dist/usage/usage-analytics.js +338 -0
  122. package/dist/usage/usage-analytics.js.map +1 -0
  123. package/dist-cjs/api-endpoints/http-routes.js +14 -0
  124. package/dist-cjs/api-endpoints/http-routes.js.map +1 -0
  125. package/dist-cjs/api-endpoints/index.js +10 -0
  126. package/dist-cjs/api-endpoints/index.js.map +1 -0
  127. package/dist-cjs/api-endpoints/registry.js +107 -0
  128. package/dist-cjs/api-endpoints/registry.js.map +1 -0
  129. package/dist-cjs/api-mount.js +117 -0
  130. package/dist-cjs/api-mount.js.map +1 -0
  131. package/dist-cjs/helpers.js +41 -0
  132. package/dist-cjs/helpers.js.map +1 -0
  133. package/dist-cjs/index.js +118 -0
  134. package/dist-cjs/index.js.map +1 -0
  135. package/dist-cjs/memory-store.js +119 -0
  136. package/dist-cjs/memory-store.js.map +1 -0
  137. package/dist-cjs/ops/emit.js +18 -0
  138. package/dist-cjs/ops/emit.js.map +1 -0
  139. package/dist-cjs/ops/fleet-activity.js +131 -0
  140. package/dist-cjs/ops/fleet-activity.js.map +1 -0
  141. package/dist-cjs/ops/fleet-agent.js +358 -0
  142. package/dist-cjs/ops/fleet-agent.js.map +1 -0
  143. package/dist-cjs/ops/fleet-samples.js +229 -0
  144. package/dist-cjs/ops/fleet-samples.js.map +1 -0
  145. package/dist-cjs/ops/journal.js +326 -0
  146. package/dist-cjs/ops/journal.js.map +1 -0
  147. package/dist-cjs/ops/rules.js +102 -0
  148. package/dist-cjs/ops/rules.js.map +1 -0
  149. package/dist-cjs/ops/types.js +126 -0
  150. package/dist-cjs/ops/types.js.map +1 -0
  151. package/dist-cjs/package.json +3 -0
  152. package/dist-cjs/request-logs/config.js +42 -0
  153. package/dist-cjs/request-logs/config.js.map +1 -0
  154. package/dist-cjs/request-logs/http-routes.js +32 -0
  155. package/dist-cjs/request-logs/http-routes.js.map +1 -0
  156. package/dist-cjs/request-logs/index.js +27 -0
  157. package/dist-cjs/request-logs/index.js.map +1 -0
  158. package/dist-cjs/request-logs/middleware.js +203 -0
  159. package/dist-cjs/request-logs/middleware.js.map +1 -0
  160. package/dist-cjs/request-logs/request-logs.js +277 -0
  161. package/dist-cjs/request-logs/request-logs.js.map +1 -0
  162. package/dist-cjs/schema.js +24 -0
  163. package/dist-cjs/schema.js.map +1 -0
  164. package/dist-cjs/sqlite-driver.js +18 -0
  165. package/dist-cjs/sqlite-driver.js.map +1 -0
  166. package/dist-cjs/sqlite-store.js +182 -0
  167. package/dist-cjs/sqlite-store.js.map +1 -0
  168. package/dist-cjs/types.js +12 -0
  169. package/dist-cjs/types.js.map +1 -0
  170. package/dist-cjs/usage/adapters.js +47 -0
  171. package/dist-cjs/usage/adapters.js.map +1 -0
  172. package/dist-cjs/usage/http-routes.js +154 -0
  173. package/dist-cjs/usage/http-routes.js.map +1 -0
  174. package/dist-cjs/usage/index.js +34 -0
  175. package/dist-cjs/usage/index.js.map +1 -0
  176. package/dist-cjs/usage/ui-brand.js +23 -0
  177. package/dist-cjs/usage/ui-brand.js.map +1 -0
  178. package/dist-cjs/usage/usage-analytics-productivity.js +321 -0
  179. package/dist-cjs/usage/usage-analytics-productivity.js.map +1 -0
  180. package/dist-cjs/usage/usage-analytics-shared.js +23 -0
  181. package/dist-cjs/usage/usage-analytics-shared.js.map +1 -0
  182. package/dist-cjs/usage/usage-analytics.js +353 -0
  183. package/dist-cjs/usage/usage-analytics.js.map +1 -0
  184. package/fleet-collector/AGENTS.md +7 -0
  185. package/fleet-collector/README.md +83 -0
  186. package/fleet-collector/configure-fleet-npm.sh +108 -0
  187. package/fleet-collector/env.mjs +174 -0
  188. package/fleet-collector/ops-api.mjs +455 -0
  189. package/fleet-collector/public/admin.html +696 -0
  190. package/fleet-collector/public/index.html +941 -0
  191. package/fleet-collector/server.mjs +564 -0
  192. package/fleet-collector/test-fleet-collector.mjs +413 -0
  193. package/fleet-collector/test-server-admin.mjs +475 -0
  194. package/package.json +109 -0
  195. package/scripts/test-api-endpoints-registry.mjs +60 -0
  196. package/ui/analytics-client.tsx +834 -0
  197. package/ui/analytics-productivity-panel.tsx +513 -0
  198. package/ui/api-endpoints-client.tsx +228 -0
  199. package/ui/index.ts +39 -0
  200. package/ui/primitives/badge.tsx +37 -0
  201. package/ui/primitives/button.tsx +44 -0
  202. package/ui/primitives/card.tsx +44 -0
  203. package/ui/primitives/cn.ts +6 -0
  204. package/ui/primitives/input.tsx +19 -0
  205. package/ui/primitives/tabs.tsx +51 -0
  206. package/ui/request-logs-client.tsx +327 -0
  207. package/ui/session-usage-analytics-provider.tsx +28 -0
  208. package/ui/usage-analytics-client.ts +479 -0
  209. package/ui/usage-analytics-provider.tsx +84 -0
@@ -0,0 +1,317 @@
1
+ /**
2
+ * Agrégations productivité : heatmap, heures actives, pauses, score.
3
+ * Basé sur les événements usage_events (heartbeats, clics, pages, idle…).
4
+ */
5
+ import { uaQueryAll as queryAll } from "./adapters.js";
6
+ import { ensureUsageAnalyticsSchema, } from "./usage-analytics.js";
7
+ /** Seuil pause courte (gap activité). */
8
+ export const BREAK_MIN_MS = 5 * 60_000;
9
+ /** Au-delà → coupure de journée / session, pas une pause. */
10
+ export const BREAK_MAX_MS = 4 * 60 * 60_000;
11
+ /** Granularité activité (fallback sans heartbeat). */
12
+ const BUCKET_MS = 5 * 60_000;
13
+ function buildWhere(filters) {
14
+ const parts = ["1=1"];
15
+ const params = [];
16
+ if (filters.from) {
17
+ parts.push("created_at >= ?");
18
+ params.push(filters.from);
19
+ }
20
+ if (filters.to) {
21
+ parts.push("created_at <= ?");
22
+ params.push(filters.to);
23
+ }
24
+ if (filters.userId) {
25
+ parts.push("user_id = ?");
26
+ params.push(filters.userId);
27
+ }
28
+ if (filters.kind && filters.kind !== "all") {
29
+ parts.push("user_kind = ?");
30
+ params.push(filters.kind);
31
+ }
32
+ return { sql: parts.join(" AND "), params };
33
+ }
34
+ function dayKey(d) {
35
+ return d.toISOString().slice(0, 10);
36
+ }
37
+ function scoreProductivity(input) {
38
+ const activeHours = input.activeMs / 3_600_000;
39
+ const expectedPerDay = 6.5; // journée type CRM
40
+ const coverage = input.daysActive > 0
41
+ ? Math.min(1, activeHours / (expectedPerDay * input.daysActive))
42
+ : 0;
43
+ const focus = input.activeMs + input.idleMs > 0
44
+ ? input.activeMs / (input.activeMs + input.idleMs)
45
+ : 0;
46
+ const density = activeHours > 0 ? Math.min(1, (input.clicks + input.events * 0.15) / (activeHours * 40)) : 0;
47
+ const raw = coverage * 0.45 + focus * 0.35 + density * 0.2;
48
+ return Math.round(Math.max(0, Math.min(100, raw * 100)));
49
+ }
50
+ function analyzeUserEvents(userId, username, kind, events, period) {
51
+ const sorted = [...events].sort((a, b) => a.created_at.localeCompare(b.created_at));
52
+ const heatmapMap = new Map();
53
+ const dailyMap = new Map();
54
+ const ensureDay = (date) => {
55
+ let d = dailyMap.get(date);
56
+ if (!d) {
57
+ d = {
58
+ activeBuckets: new Set(),
59
+ heartbeatMs: 0,
60
+ idleMs: 0,
61
+ events: 0,
62
+ clicks: 0,
63
+ pageViews: 0,
64
+ heartbeats: 0,
65
+ firstSeen: null,
66
+ lastSeen: null,
67
+ times: [],
68
+ };
69
+ dailyMap.set(date, d);
70
+ }
71
+ return d;
72
+ };
73
+ for (const e of sorted) {
74
+ const t = new Date(e.created_at);
75
+ if (Number.isNaN(t.getTime()))
76
+ continue;
77
+ const date = dayKey(t);
78
+ const day = ensureDay(date);
79
+ day.events += 1;
80
+ day.times.push(t.getTime());
81
+ if (!day.firstSeen)
82
+ day.firstSeen = e.created_at;
83
+ day.lastSeen = e.created_at;
84
+ if (e.event_type === "ui.click")
85
+ day.clicks += 1;
86
+ if (e.event_type === "page.view")
87
+ day.pageViews += 1;
88
+ if (e.event_type === "presence.heartbeat") {
89
+ day.heartbeats += 1;
90
+ day.heartbeatMs += Math.min(e.duration_ms || 60_000, 120_000);
91
+ }
92
+ if (e.event_type === "presence.idle" && e.duration_ms) {
93
+ day.idleMs += e.duration_ms;
94
+ }
95
+ // Bucket activité 5 min
96
+ const bucket = Math.floor(t.getTime() / BUCKET_MS);
97
+ day.activeBuckets.add(bucket);
98
+ const weekday = t.getUTCDay();
99
+ const hour = t.getUTCHours();
100
+ const hk = `${weekday}:${hour}`;
101
+ let cell = heatmapMap.get(hk);
102
+ if (!cell) {
103
+ cell = { weekday, hour, events: 0, activeMs: 0 };
104
+ heatmapMap.set(hk, cell);
105
+ }
106
+ cell.events += 1;
107
+ if (e.event_type === "presence.heartbeat") {
108
+ cell.activeMs += Math.min(e.duration_ms || 60_000, 120_000);
109
+ }
110
+ }
111
+ // Pauses + focus blocks depuis timestamps
112
+ const allTimes = sorted
113
+ .map((e) => new Date(e.created_at).getTime())
114
+ .filter((n) => !Number.isNaN(n));
115
+ const breaks = [];
116
+ const focusBlocks = [];
117
+ let blockStart = allTimes[0] ?? 0;
118
+ let blockEvents = 0;
119
+ let last = allTimes[0] ?? 0;
120
+ for (let i = 0; i < allTimes.length; i++) {
121
+ const cur = allTimes[i];
122
+ if (i === 0) {
123
+ blockStart = cur;
124
+ blockEvents = 1;
125
+ last = cur;
126
+ continue;
127
+ }
128
+ const gap = cur - last;
129
+ if (gap >= BREAK_MIN_MS && gap <= BREAK_MAX_MS) {
130
+ // clôturer focus block
131
+ if (last > blockStart) {
132
+ focusBlocks.push({
133
+ startedAt: new Date(blockStart).toISOString(),
134
+ endedAt: new Date(last).toISOString(),
135
+ durationMs: last - blockStart,
136
+ events: blockEvents,
137
+ });
138
+ }
139
+ breaks.push({
140
+ startedAt: new Date(last).toISOString(),
141
+ endedAt: new Date(cur).toISOString(),
142
+ durationMs: gap,
143
+ day: dayKey(new Date(last)),
144
+ });
145
+ blockStart = cur;
146
+ blockEvents = 1;
147
+ }
148
+ else if (gap > BREAK_MAX_MS) {
149
+ if (last > blockStart) {
150
+ focusBlocks.push({
151
+ startedAt: new Date(blockStart).toISOString(),
152
+ endedAt: new Date(last).toISOString(),
153
+ durationMs: last - blockStart,
154
+ events: blockEvents,
155
+ });
156
+ }
157
+ blockStart = cur;
158
+ blockEvents = 1;
159
+ }
160
+ else {
161
+ blockEvents += 1;
162
+ }
163
+ last = cur;
164
+ }
165
+ if (allTimes.length && last > blockStart) {
166
+ focusBlocks.push({
167
+ startedAt: new Date(blockStart).toISOString(),
168
+ endedAt: new Date(last).toISOString(),
169
+ durationMs: last - blockStart,
170
+ events: blockEvents,
171
+ });
172
+ }
173
+ const breakMsByDay = new Map();
174
+ for (const b of breaks) {
175
+ const cur = breakMsByDay.get(b.day) || { ms: 0, n: 0 };
176
+ cur.ms += b.durationMs;
177
+ cur.n += 1;
178
+ breakMsByDay.set(b.day, cur);
179
+ }
180
+ const daily = Array.from(dailyMap.entries())
181
+ .sort(([a], [b]) => a.localeCompare(b))
182
+ .map(([date, d]) => {
183
+ const bucketActive = d.activeBuckets.size * BUCKET_MS;
184
+ const activeMs = d.heartbeatMs > 0 ? d.heartbeatMs : bucketActive;
185
+ const br = breakMsByDay.get(date) || { ms: 0, n: 0 };
186
+ return {
187
+ date,
188
+ activeMs,
189
+ idleMs: d.idleMs,
190
+ breakMs: br.ms,
191
+ breaksCount: br.n,
192
+ events: d.events,
193
+ clicks: d.clicks,
194
+ pageViews: d.pageViews,
195
+ heartbeats: d.heartbeats,
196
+ firstSeen: d.firstSeen,
197
+ lastSeen: d.lastSeen,
198
+ productivityScore: scoreProductivity({
199
+ activeMs,
200
+ idleMs: d.idleMs,
201
+ events: d.events,
202
+ clicks: d.clicks,
203
+ daysActive: 1,
204
+ }),
205
+ };
206
+ });
207
+ const activeMs = daily.reduce((s, d) => s + d.activeMs, 0);
208
+ const idleMs = daily.reduce((s, d) => s + d.idleMs, 0);
209
+ const breakMs = breaks.reduce((s, b) => s + b.durationMs, 0);
210
+ const clicks = daily.reduce((s, d) => s + d.clicks, 0);
211
+ const pageViews = daily.reduce((s, d) => s + d.pageViews, 0);
212
+ const eventsCount = daily.reduce((s, d) => s + d.events, 0);
213
+ const daysActive = daily.filter((d) => d.activeMs > 0 || d.events > 0).length;
214
+ const heatmap = Array.from(heatmapMap.values()).sort((a, b) => a.weekday - b.weekday || a.hour - b.hour);
215
+ let peakHour = null;
216
+ let peakWeekday = null;
217
+ let peakVal = -1;
218
+ for (const c of heatmap) {
219
+ const v = c.activeMs + c.events * 1000;
220
+ if (v > peakVal) {
221
+ peakVal = v;
222
+ peakHour = c.hour;
223
+ peakWeekday = c.weekday;
224
+ }
225
+ }
226
+ const activeHours = activeMs / 3_600_000;
227
+ const summary = {
228
+ userId,
229
+ username,
230
+ kind,
231
+ activeMs,
232
+ idleMs,
233
+ breakMs,
234
+ avgActivePerDayMs: daysActive > 0 ? Math.round(activeMs / daysActive) : 0,
235
+ avgBreakMs: breaks.length ? Math.round(breakMs / breaks.length) : 0,
236
+ breaksCount: breaks.length,
237
+ focusBlocksCount: focusBlocks.length,
238
+ avgFocusBlockMs: focusBlocks.length
239
+ ? Math.round(focusBlocks.reduce((s, f) => s + f.durationMs, 0) / focusBlocks.length)
240
+ : 0,
241
+ peakHour,
242
+ peakWeekday,
243
+ eventsPerActiveHour: activeHours > 0 ? Math.round((eventsCount / activeHours) * 10) / 10 : 0,
244
+ focusRatio: activeMs + idleMs > 0
245
+ ? Math.round((activeMs / (activeMs + idleMs)) * 1000) / 1000
246
+ : 0,
247
+ productivityScore: scoreProductivity({
248
+ activeMs,
249
+ idleMs,
250
+ events: eventsCount,
251
+ clicks,
252
+ daysActive: Math.max(daysActive, 1),
253
+ }),
254
+ daysActive,
255
+ events: eventsCount,
256
+ clicks,
257
+ pageViews,
258
+ };
259
+ // Cap listes pour l'API
260
+ const recentBreaks = breaks.slice(-40).reverse();
261
+ const topFocus = [...focusBlocks].sort((a, b) => b.durationMs - a.durationMs).slice(0, 20);
262
+ return {
263
+ summary,
264
+ heatmap,
265
+ daily,
266
+ breaks: recentBreaks,
267
+ focusBlocks: topFocus,
268
+ };
269
+ }
270
+ export function getProductivityReport(filters) {
271
+ ensureUsageAnalyticsSchema();
272
+ const { sql, params } = buildWhere(filters);
273
+ const rows = queryAll(`SELECT created_at, event_type, duration_ms, user_id, username, user_kind
274
+ FROM usage_events
275
+ WHERE ${sql}
276
+ AND user_id IS NOT NULL
277
+ AND event_type NOT IN ('session.context')
278
+ ORDER BY created_at ASC
279
+ LIMIT 50000`, params);
280
+ const period = { from: filters.from || "", to: filters.to || "" };
281
+ const byUser = new Map();
282
+ for (const r of rows) {
283
+ if (!r.user_id)
284
+ continue;
285
+ const list = byUser.get(r.user_id) || [];
286
+ list.push(r);
287
+ byUser.set(r.user_id, list);
288
+ }
289
+ const leaderboard = [];
290
+ let detail = null;
291
+ for (const [uid, evs] of Array.from(byUser.entries())) {
292
+ const username = evs.find((e) => e.username)?.username || uid;
293
+ const kind = evs.find((e) => e.user_kind)?.user_kind || "human";
294
+ const analyzed = analyzeUserEvents(uid, username, kind, evs, period);
295
+ if (analyzed.summary)
296
+ leaderboard.push(analyzed.summary);
297
+ if (filters.userId && uid === filters.userId)
298
+ detail = analyzed;
299
+ }
300
+ leaderboard.sort((a, b) => b.productivityScore - a.productivityScore || b.activeMs - a.activeMs);
301
+ // Sans userId : rapport du top user pour la heatmap, + leaderboard
302
+ if (!detail && leaderboard[0]) {
303
+ const topId = leaderboard[0].userId;
304
+ const evs = byUser.get(topId) || [];
305
+ detail = analyzeUserEvents(topId, leaderboard[0].username, leaderboard[0].kind, evs, period);
306
+ }
307
+ return {
308
+ period,
309
+ summary: detail?.summary || null,
310
+ heatmap: detail?.heatmap || [],
311
+ daily: detail?.daily || [],
312
+ breaks: detail?.breaks || [],
313
+ focusBlocks: detail?.focusBlocks || [],
314
+ leaderboard,
315
+ };
316
+ }
317
+ //# sourceMappingURL=usage-analytics-productivity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-analytics-productivity.js","sourceRoot":"","sources":["../../src/usage/usage-analytics-productivity.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,UAAU,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EACL,0BAA0B,GAE3B,MAAM,sBAAsB,CAAC;AAE9B,yCAAyC;AACzC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC;AACvC,6DAA6D;AAC7D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;AAC5C,sDAAsD;AACtD,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC;AAgF7B,SAAS,UAAU,CAAC,OAAqB;IACvC,MAAM,KAAK,GAAa,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;AAC9C,CAAC;AAED,SAAS,MAAM,CAAC,CAAO;IACrB,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,iBAAiB,CAAC,KAM1B;IACC,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC/C,MAAM,cAAc,GAAG,GAAG,CAAC,CAAC,mBAAmB;IAC/C,MAAM,QAAQ,GACZ,KAAK,CAAC,UAAU,GAAG,CAAC;QAClB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,cAAc,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,KAAK,GACT,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC;QAC/B,CAAC,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;QAClD,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,OAAO,GACX,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,MAAM,GAAG,GAAG,QAAQ,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,GAAG,GAAG,CAAC;IAC3D,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,iBAAiB,CACxB,MAAc,EACd,QAAgB,EAChB,IAAY,EACZ,MAAkB,EAClB,MAAoC;IAEpC,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IAEpF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAuB,CAAC;IAClD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAcrB,CAAC;IAEJ,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;QACjC,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,GAAG;gBACF,aAAa,EAAE,IAAI,GAAG,EAAE;gBACxB,WAAW,EAAE,CAAC;gBACd,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,CAAC;gBACT,SAAS,EAAE,CAAC;gBACZ,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,IAAI;gBACf,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,EAAE;aACV,CAAC;YACF,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAAE,SAAS;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5B,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;QAChB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,SAAS;YAAE,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,UAAU,CAAC;QACjD,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,UAAU,CAAC;QAE5B,IAAI,CAAC,CAAC,UAAU,KAAK,UAAU;YAAE,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,UAAU,KAAK,WAAW;YAAE,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,CAAC,UAAU,KAAK,oBAAoB,EAAE,CAAC;YAC1C,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC;YACpB,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,MAAM,EAAE,OAAO,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,CAAC,UAAU,KAAK,eAAe,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YACtD,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,WAAW,CAAC;QAC9B,CAAC;QAED,wBAAwB;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC;QACnD,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE9B,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC;QAChC,IAAI,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YACjD,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC,CAAC,UAAU,KAAK,oBAAoB,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,0CAA0C;IAC1C,MAAM,QAAQ,GAAG,MAAM;SACpB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;SAC5C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,IAAI,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACZ,UAAU,GAAG,GAAG,CAAC;YACjB,WAAW,GAAG,CAAC,CAAC;YAChB,IAAI,GAAG,GAAG,CAAC;YACX,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;QACvB,IAAI,GAAG,IAAI,YAAY,IAAI,GAAG,IAAI,YAAY,EAAE,CAAC;YAC/C,uBAAuB;YACvB,IAAI,IAAI,GAAG,UAAU,EAAE,CAAC;gBACtB,WAAW,CAAC,IAAI,CAAC;oBACf,SAAS,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE;oBAC7C,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;oBACrC,UAAU,EAAE,IAAI,GAAG,UAAU;oBAC7B,MAAM,EAAE,WAAW;iBACpB,CAAC,CAAC;YACL,CAAC;YACD,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;gBACvC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;gBACpC,UAAU,EAAE,GAAG;gBACf,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;aAC5B,CAAC,CAAC;YACH,UAAU,GAAG,GAAG,CAAC;YACjB,WAAW,GAAG,CAAC,CAAC;QAClB,CAAC;aAAM,IAAI,GAAG,GAAG,YAAY,EAAE,CAAC;YAC9B,IAAI,IAAI,GAAG,UAAU,EAAE,CAAC;gBACtB,WAAW,CAAC,IAAI,CAAC;oBACf,SAAS,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE;oBAC7C,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;oBACrC,UAAU,EAAE,IAAI,GAAG,UAAU;oBAC7B,MAAM,EAAE,WAAW;iBACpB,CAAC,CAAC;YACL,CAAC;YACD,UAAU,GAAG,GAAG,CAAC;YACjB,WAAW,GAAG,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,WAAW,IAAI,CAAC,CAAC;QACnB,CAAC;QACD,IAAI,GAAG,GAAG,CAAC;IACb,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,IAAI,IAAI,GAAG,UAAU,EAAE,CAAC;QACzC,WAAW,CAAC,IAAI,CAAC;YACf,SAAS,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE;YAC7C,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;YACrC,UAAU,EAAE,IAAI,GAAG,UAAU;YAC7B,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,GAAG,EAAqC,CAAC;IAClE,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,UAAU,CAAC;QACvB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QACX,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,KAAK,GAAwB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;SAC9D,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACjB,MAAM,YAAY,GAAG,CAAC,CAAC,aAAa,CAAC,IAAI,GAAG,SAAS,CAAC;QACtD,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;QAClE,MAAM,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACrD,OAAO;YACL,IAAI;YACJ,QAAQ;YACR,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,EAAE,CAAC,EAAE;YACd,WAAW,EAAE,EAAE,CAAC,CAAC;YACjB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,iBAAiB,EAAE,iBAAiB,CAAC;gBACnC,QAAQ;gBACR,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,UAAU,EAAE,CAAC;aACd,CAAC;SACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAE9E,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAClD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CACnD,CAAC;IACF,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;QACvC,IAAI,CAAC,GAAG,OAAO,EAAE,CAAC;YAChB,OAAO,GAAG,CAAC,CAAC;YACZ,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC;YAClB,WAAW,GAAG,CAAC,CAAC,OAAO,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,MAAM,OAAO,GAAwB;QACnC,MAAM;QACN,QAAQ;QACR,IAAI;QACJ,QAAQ;QACR,MAAM;QACN,OAAO;QACP,iBAAiB,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACzE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,WAAW,EAAE,MAAM,CAAC,MAAM;QAC1B,gBAAgB,EAAE,WAAW,CAAC,MAAM;QACpC,eAAe,EAAE,WAAW,CAAC,MAAM;YACjC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC;YACpF,CAAC,CAAC,CAAC;QACL,QAAQ;QACR,WAAW;QACX,mBAAmB,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5F,UAAU,EACR,QAAQ,GAAG,MAAM,GAAG,CAAC;YACnB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI;YAC5D,CAAC,CAAC,CAAC;QACP,iBAAiB,EAAE,iBAAiB,CAAC;YACnC,QAAQ;YACR,MAAM;YACN,MAAM,EAAE,WAAW;YACnB,MAAM;YACN,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;SACpC,CAAC;QACF,UAAU;QACV,MAAM,EAAE,WAAW;QACnB,MAAM;QACN,SAAS;KACV,CAAC;IAEF,wBAAwB;IACxB,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE3F,OAAO;QACL,OAAO;QACP,OAAO;QACP,KAAK;QACL,MAAM,EAAE,YAAY;QACpB,WAAW,EAAE,QAAQ;KACtB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAqB;IACzD,0BAA0B,EAAE,CAAC;IAC7B,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,QAAQ,CACnB;;aAES,GAAG;;;;iBAIC,EACb,MAAM,CACP,CAAC;IAEF,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,CAAC,OAAO;YAAE,SAAS;QACzB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACb,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,WAAW,GAA0B,EAAE,CAAC;IAC9C,IAAI,MAAM,GAA8D,IAAI,CAAC;IAE7E,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAW,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,QAAQ,IAAI,GAAG,CAAC;QACxE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAW,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,SAAS,IAAI,OAAO,CAAC;QAC1E,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QACrE,IAAI,QAAQ,CAAC,OAAO;YAAE,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG,KAAK,OAAO,CAAC,MAAM;YAAE,MAAM,GAAG,QAAQ,CAAC;IAClE,CAAC;IAED,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEjG,mEAAmE;IACnE,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,GAAG,iBAAiB,CACxB,KAAK,EACL,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,EACvB,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EACnB,GAAG,EACH,MAAM,CACP,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM;QACN,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI;QAChC,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE;QAC9B,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE;QAC1B,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE;QAC5B,WAAW,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE;QACtC,WAAW;KACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** Types / helpers partagés client + serveur (sans dépendance SQLite). */
2
+ export type UsageUserKind = "human" | "ai" | "system" | "unknown";
3
+ export type UsagePeriod = "day" | "week" | "month" | "year";
4
+ export declare function formatDuration(ms: number): string;
5
+ //# sourceMappingURL=usage-analytics-shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-analytics-shared.d.ts","sourceRoot":"","sources":["../../src/usage/usage-analytics-shared.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAC;AAClE,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5D,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAajD"}
@@ -0,0 +1,20 @@
1
+ /** Types / helpers partagés client + serveur (sans dépendance SQLite). */
2
+ export function formatDuration(ms) {
3
+ if (!ms || ms < 0)
4
+ return "0s";
5
+ const s = Math.round(ms / 1000);
6
+ if (s < 60)
7
+ return `${s}s`;
8
+ const m = Math.floor(s / 60);
9
+ const rs = s % 60;
10
+ if (m < 60)
11
+ return rs ? `${m}m ${rs}s` : `${m}m`;
12
+ const h = Math.floor(m / 60);
13
+ const rm = m % 60;
14
+ if (h < 48)
15
+ return rm ? `${h}h ${rm}m` : `${h}h`;
16
+ const d = Math.floor(h / 24);
17
+ const rh = h % 24;
18
+ return rh ? `${d}j ${rh}h` : `${d}j`;
19
+ }
20
+ //# sourceMappingURL=usage-analytics-shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-analytics-shared.js","sourceRoot":"","sources":["../../src/usage/usage-analytics-shared.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAK1E,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC;IAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvC,CAAC"}
@@ -0,0 +1,127 @@
1
+ import { formatDuration, type UsagePeriod, type UsageUserKind } from "./usage-analytics-shared.js";
2
+ export type { UsagePeriod, UsageUserKind };
3
+ export { formatDuration };
4
+ export type UsageEventInput = {
5
+ eventType: string;
6
+ category?: string;
7
+ label?: string | null;
8
+ path?: string | null;
9
+ referrerPath?: string | null;
10
+ userId?: string | null;
11
+ username?: string | null;
12
+ userKind?: UsageUserKind | string | null;
13
+ userRole?: string | null;
14
+ sessionId?: string | null;
15
+ durationMs?: number | null;
16
+ meta?: Record<string, unknown> | null;
17
+ userAgent?: string | null;
18
+ surface?: string | null;
19
+ createdAt?: string | null;
20
+ };
21
+ export type UsageEventRow = {
22
+ id: number;
23
+ created_at: string;
24
+ event_type: string;
25
+ category: string;
26
+ label: string | null;
27
+ path: string | null;
28
+ referrer_path: string | null;
29
+ user_id: string | null;
30
+ username: string | null;
31
+ user_kind: string;
32
+ user_role: string | null;
33
+ session_id: string | null;
34
+ duration_ms: number | null;
35
+ meta_json: string | null;
36
+ user_agent: string | null;
37
+ surface: string;
38
+ };
39
+ export type UsageFilters = {
40
+ from?: string;
41
+ to?: string;
42
+ userId?: string;
43
+ kind?: UsageUserKind | "all";
44
+ eventType?: string;
45
+ path?: string;
46
+ q?: string;
47
+ };
48
+ export declare function usageAnalyticsReady(): boolean;
49
+ /** Crée la table si absente (dev / avant migration Electron). */
50
+ export declare function ensureUsageAnalyticsSchema(): void;
51
+ export declare function insertUsageEvents(events: UsageEventInput[]): number;
52
+ export declare function recordUsageEvent(event: UsageEventInput): void;
53
+ export declare function resolvePeriodFilters(period: UsagePeriod | string | undefined, from?: string, to?: string): UsageFilters;
54
+ export type UsageOverview = {
55
+ period: {
56
+ from: string;
57
+ to: string;
58
+ };
59
+ totals: {
60
+ events: number;
61
+ pageViews: number;
62
+ clicks: number;
63
+ sessions: number;
64
+ activeUsers: number;
65
+ activeHumans: number;
66
+ activeAi: number;
67
+ totalTimeMs: number;
68
+ avgSessionTimeMs: number;
69
+ };
70
+ byKind: Array<{
71
+ kind: string;
72
+ events: number;
73
+ users: number;
74
+ timeMs: number;
75
+ }>;
76
+ };
77
+ export declare function getUsageOverview(filters: UsageFilters): UsageOverview;
78
+ export type TimelineBucket = {
79
+ bucket: string;
80
+ events: number;
81
+ pageViews: number;
82
+ clicks: number;
83
+ humans: number;
84
+ ai: number;
85
+ timeMs: number;
86
+ };
87
+ export declare function getUsageTimeline(filters: UsageFilters, period?: UsagePeriod): TimelineBucket[];
88
+ export type PageStat = {
89
+ path: string;
90
+ views: number;
91
+ uniqueUsers: number;
92
+ avgTimeMs: number;
93
+ totalTimeMs: number;
94
+ };
95
+ export declare function getTopPages(filters: UsageFilters, limit?: number): PageStat[];
96
+ export type ClickStat = {
97
+ label: string;
98
+ clicks: number;
99
+ uniqueUsers: number;
100
+ paths: number;
101
+ };
102
+ export declare function getTopClicks(filters: UsageFilters, limit?: number): ClickStat[];
103
+ export type UserStat = {
104
+ userId: string;
105
+ username: string;
106
+ kind: string;
107
+ role: string | null;
108
+ events: number;
109
+ pageViews: number;
110
+ clicks: number;
111
+ sessions: number;
112
+ timeMs: number;
113
+ lastSeen: string | null;
114
+ };
115
+ export declare function getUserStats(filters: UsageFilters, limit?: number): UserStat[];
116
+ export declare function listUsageEvents(filters: UsageFilters & {
117
+ limit?: number;
118
+ offset?: number;
119
+ }): {
120
+ events: UsageEventRow[];
121
+ total: number;
122
+ };
123
+ export declare function purgeUsageEvents(opts?: {
124
+ before?: string;
125
+ all?: boolean;
126
+ }): number;
127
+ //# sourceMappingURL=usage-analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-analytics.d.ts","sourceRoot":"","sources":["../../src/usage/usage-analytics.ts"],"names":[],"mappings":"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"}