@uptimizr/collector-server 2.0.1 → 2.2.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 (139) hide show
  1. package/AGENTS.md +187 -11
  2. package/README.md +91 -7
  3. package/dist/__tests__/support/registryRequests.d.ts +2 -1
  4. package/dist/__tests__/support/registryRequests.d.ts.map +1 -1
  5. package/dist/__tests__/support/registryRequests.js +17 -1
  6. package/dist/__tests__/support/registryRequests.js.map +1 -1
  7. package/dist/__tests__/support/subscriptionFixtures.d.ts +63 -0
  8. package/dist/__tests__/support/subscriptionFixtures.d.ts.map +1 -0
  9. package/dist/__tests__/support/subscriptionFixtures.js +17 -0
  10. package/dist/__tests__/support/subscriptionFixtures.js.map +1 -0
  11. package/dist/agentReport.d.ts +256 -0
  12. package/dist/agentReport.d.ts.map +1 -0
  13. package/dist/agentReport.js +861 -0
  14. package/dist/agentReport.js.map +1 -0
  15. package/dist/app.d.ts +13 -0
  16. package/dist/app.d.ts.map +1 -1
  17. package/dist/app.js +112 -5
  18. package/dist/app.js.map +1 -1
  19. package/dist/audit.d.ts +5 -1
  20. package/dist/audit.d.ts.map +1 -1
  21. package/dist/audit.js +24 -4
  22. package/dist/audit.js.map +1 -1
  23. package/dist/auth.d.ts +41 -1
  24. package/dist/auth.d.ts.map +1 -1
  25. package/dist/auth.js +47 -0
  26. package/dist/auth.js.map +1 -1
  27. package/dist/cli.js +133 -13
  28. package/dist/cli.js.map +1 -1
  29. package/dist/cliStore.d.ts +31 -2
  30. package/dist/cliStore.d.ts.map +1 -1
  31. package/dist/cliStore.js +34 -0
  32. package/dist/cliStore.js.map +1 -1
  33. package/dist/clickhouseStore.d.ts.map +1 -1
  34. package/dist/clickhouseStore.js +44 -2
  35. package/dist/clickhouseStore.js.map +1 -1
  36. package/dist/config.d.ts +49 -0
  37. package/dist/config.d.ts.map +1 -1
  38. package/dist/config.js +21 -0
  39. package/dist/config.js.map +1 -1
  40. package/dist/connectionLimiter.d.ts +23 -0
  41. package/dist/connectionLimiter.d.ts.map +1 -0
  42. package/dist/connectionLimiter.js +24 -0
  43. package/dist/connectionLimiter.js.map +1 -0
  44. package/dist/duckdbStore.d.ts.map +1 -1
  45. package/dist/duckdbStore.js +44 -1
  46. package/dist/duckdbStore.js.map +1 -1
  47. package/dist/internalDispatch.d.ts +36 -0
  48. package/dist/internalDispatch.d.ts.map +1 -0
  49. package/dist/internalDispatch.js +50 -0
  50. package/dist/internalDispatch.js.map +1 -0
  51. package/dist/memoryStore.d.ts.map +1 -1
  52. package/dist/memoryStore.js +314 -1
  53. package/dist/memoryStore.js.map +1 -1
  54. package/dist/mssqlStore.d.ts.map +1 -1
  55. package/dist/mssqlStore.js +44 -2
  56. package/dist/mssqlStore.js.map +1 -1
  57. package/dist/postgresStore.d.ts.map +1 -1
  58. package/dist/postgresStore.js +44 -2
  59. package/dist/postgresStore.js.map +1 -1
  60. package/dist/projectMetadata.d.ts +82 -0
  61. package/dist/projectMetadata.d.ts.map +1 -0
  62. package/dist/projectMetadata.js +50 -0
  63. package/dist/projectMetadata.js.map +1 -0
  64. package/dist/routes/context.d.ts +135 -0
  65. package/dist/routes/context.d.ts.map +1 -0
  66. package/dist/routes/context.js +306 -0
  67. package/dist/routes/context.js.map +1 -0
  68. package/dist/routes/insights.d.ts +36 -0
  69. package/dist/routes/insights.d.ts.map +1 -0
  70. package/dist/routes/insights.js +810 -0
  71. package/dist/routes/insights.js.map +1 -0
  72. package/dist/routes/live.d.ts +8 -0
  73. package/dist/routes/live.d.ts.map +1 -1
  74. package/dist/routes/live.js +8 -7
  75. package/dist/routes/live.js.map +1 -1
  76. package/dist/routes/mcp.d.ts +36 -0
  77. package/dist/routes/mcp.d.ts.map +1 -0
  78. package/dist/routes/mcp.js +262 -0
  79. package/dist/routes/mcp.js.map +1 -0
  80. package/dist/routes/meta.d.ts +16 -2
  81. package/dist/routes/meta.d.ts.map +1 -1
  82. package/dist/routes/meta.js +699 -10
  83. package/dist/routes/meta.js.map +1 -1
  84. package/dist/routes/metadata.d.ts +31 -0
  85. package/dist/routes/metadata.d.ts.map +1 -0
  86. package/dist/routes/metadata.js +163 -0
  87. package/dist/routes/metadata.js.map +1 -0
  88. package/dist/routes/narrative.d.ts +36 -0
  89. package/dist/routes/narrative.d.ts.map +1 -0
  90. package/dist/routes/narrative.js +95 -0
  91. package/dist/routes/narrative.js.map +1 -0
  92. package/dist/routes/panels.d.ts +44 -0
  93. package/dist/routes/panels.d.ts.map +1 -0
  94. package/dist/routes/panels.js +108 -0
  95. package/dist/routes/panels.js.map +1 -0
  96. package/dist/routes/query-dsl.d.ts +50 -0
  97. package/dist/routes/query-dsl.d.ts.map +1 -0
  98. package/dist/routes/query-dsl.js +359 -0
  99. package/dist/routes/query-dsl.js.map +1 -0
  100. package/dist/routes/query.d.ts +36 -0
  101. package/dist/routes/query.d.ts.map +1 -1
  102. package/dist/routes/query.js +101 -13
  103. package/dist/routes/query.js.map +1 -1
  104. package/dist/routes/subscriptions.d.ts +52 -0
  105. package/dist/routes/subscriptions.d.ts.map +1 -0
  106. package/dist/routes/subscriptions.js +290 -0
  107. package/dist/routes/subscriptions.js.map +1 -0
  108. package/dist/store.d.ts +113 -2
  109. package/dist/store.d.ts.map +1 -1
  110. package/dist/subscriptions/cli.d.ts +36 -0
  111. package/dist/subscriptions/cli.d.ts.map +1 -0
  112. package/dist/subscriptions/cli.js +143 -0
  113. package/dist/subscriptions/cli.js.map +1 -0
  114. package/dist/subscriptions/delivery.d.ts +101 -0
  115. package/dist/subscriptions/delivery.d.ts.map +1 -0
  116. package/dist/subscriptions/delivery.js +165 -0
  117. package/dist/subscriptions/delivery.js.map +1 -0
  118. package/dist/subscriptions/evaluate.d.ts +119 -0
  119. package/dist/subscriptions/evaluate.d.ts.map +1 -0
  120. package/dist/subscriptions/evaluate.js +326 -0
  121. package/dist/subscriptions/evaluate.js.map +1 -0
  122. package/dist/subscriptions/scheduler.d.ts +97 -0
  123. package/dist/subscriptions/scheduler.d.ts.map +1 -0
  124. package/dist/subscriptions/scheduler.js +332 -0
  125. package/dist/subscriptions/scheduler.js.map +1 -0
  126. package/dist/subscriptions/stream.d.ts +40 -0
  127. package/dist/subscriptions/stream.d.ts.map +1 -0
  128. package/dist/subscriptions/stream.js +38 -0
  129. package/dist/subscriptions/stream.js.map +1 -0
  130. package/dist/version.d.ts +3 -0
  131. package/dist/version.d.ts.map +1 -0
  132. package/dist/version.js +25 -0
  133. package/dist/version.js.map +1 -0
  134. package/dist/webhookSignature.d.ts +64 -0
  135. package/dist/webhookSignature.d.ts.map +1 -0
  136. package/dist/webhookSignature.js +91 -0
  137. package/dist/webhookSignature.js.map +1 -0
  138. package/llms.txt +39 -2
  139. package/package.json +17 -14
@@ -0,0 +1,306 @@
1
+ /**
2
+ * The project **context document** — `GET /api/v1/context` (ADR 0051 §5, design
3
+ * sketch §E.1).
4
+ *
5
+ * Agents start blind. They know the *shape* of the read surface from the metric
6
+ * registry, but nothing about the project in front of them: what its scenes are
7
+ * called, which regions have names, which capture channels are even on, what the
8
+ * application calls its own events, whether raw retention is enabled, or how
9
+ * fresh the data is. Every one of those is a guess an agent would otherwise make
10
+ * badly — asking for `scene=lobby` when the scene is `main-hall`, reporting a
11
+ * zero from a disabled channel as a finding, filtering on a custom event name
12
+ * that does not exist.
13
+ *
14
+ * This route answers all of it in one read, assembled entirely from aggregates
15
+ * and registry rows the collector already serves. It is:
16
+ *
17
+ * - **bounded** — every list is capped (see the `MAX_*` constants), so the whole
18
+ * document stays comfortably inside the budget a small local model can carry
19
+ * in its system prompt; `context.test.ts` asserts the fixture project's
20
+ * document is under 16 KB;
21
+ * - **cached** — briefly, per project ({@link CONTEXT_CACHE_TTL_MS}), because an
22
+ * assistant re-reads it on every session start and it costs half a dozen
23
+ * aggregate queries to build;
24
+ * - **read-only and aggregate-only** — no raw event, no session id, no prop
25
+ * value, nothing a caller could not already read through the query API
26
+ * (ADR 0003).
27
+ *
28
+ * It is deliberately **not** a registry metric: it is not an aggregation over
29
+ * the event stream with a row grain, it is a description of the project. It is
30
+ * described in the OpenAPI document by hand, alongside the other non-metric
31
+ * routes (`routes/meta.ts`).
32
+ */
33
+ import { z } from "zod";
34
+ import { EVENT_TYPES, SCHEMA_VERSION } from "@uptimizr/schema";
35
+ import { allMetrics } from "@uptimizr/metrics";
36
+ import { requireCapability } from "../auth.js";
37
+ import { COLLECTOR_VERSION } from "../version.js";
38
+ import { EMPTY_PROJECT_METADATA } from "../projectMetadata.js";
39
+ /** How long a built document is reused for the same project. */
40
+ export const CONTEXT_CACHE_TTL_MS = 30_000;
41
+ /** The activity window the vocabulary, scenes and channels are computed over. */
42
+ const CONTEXT_WINDOW_MS = 28 * 24 * 60 * 60 * 1000;
43
+ /** The freshness window `dataQuality` reports. */
44
+ const RECENT_WINDOW_MS = 24 * 60 * 60 * 1000;
45
+ /** Caps that keep the document bounded whatever the project contains. */
46
+ const MAX_SCENES = 40;
47
+ const MAX_REGIONS_PER_SCENE = 20;
48
+ const MAX_CUSTOM_EVENTS = 25;
49
+ const MAX_TOP_MESHES = 10;
50
+ /** Distinct meshes counted before `vocabulary.meshes.count` saturates. */
51
+ const MAX_COUNTED_MESHES = 200;
52
+ const MAX_INPUT_ACTIONS = 25;
53
+ const MAX_ANNOTATIONS = 10;
54
+ const MAX_GLOSSARY = 50;
55
+ /** One named region of a scene: the vocabulary a `region=` filter resolves against. */
56
+ const regionSchema = z.object({
57
+ id: z.string(),
58
+ label: z.string(),
59
+ });
60
+ const sceneSchema = z.object({
61
+ /** Developer-assigned scene id (ADR 0010) — the value of the `scene` filter. */
62
+ id: z.string(),
63
+ /** Display label from the scene registry, when one was registered. */
64
+ label: z.string().nullable(),
65
+ /** Named regions declared for this scene (ADR 0051 §2). */
66
+ regions: z.array(regionSchema),
67
+ /** Whether proxy geometry is registered, so spatial results can be labelled. */
68
+ proxy: z.boolean(),
69
+ /**
70
+ * Events recorded in this scene over the context window.
71
+ *
72
+ * The design sketch asks for `sessions28d`; no aggregation reports distinct
73
+ * sessions per scene, and inventing one is outside this change. Event volume
74
+ * is the honest, already-served stand-in and is named for what it is.
75
+ */
76
+ events28d: z.number().int(),
77
+ });
78
+ const captureChannelSchema = z.object({
79
+ /** Whether any event of this type was recorded over the context window. */
80
+ seen: z.boolean(),
81
+ /** Events of this type over the context window. Omitted when none were seen. */
82
+ events28d: z.number().int().optional(),
83
+ });
84
+ const customEventSchema = z.object({
85
+ name: z.string(),
86
+ count28d: z.number().int(),
87
+ sessions28d: z.number().int(),
88
+ /** Observed `props` keys mapped to a coarse type. Never prop *values*. */
89
+ props: z.record(z.string(), z.string()),
90
+ });
91
+ const glossarySchema = z.object({ term: z.string(), meaning: z.string() });
92
+ const annotationSchema = z.object({
93
+ id: z.string(),
94
+ target: z.object({ kind: z.string(), id: z.string().nullable() }),
95
+ text: z.string(),
96
+ at: z.number().int(),
97
+ });
98
+ /**
99
+ * The context document. Declared as Zod so it validates on the way out like
100
+ * every other response, and so the OpenAPI description in `meta.ts` and this
101
+ * shape cannot drift apart silently.
102
+ */
103
+ export const projectContextSchema = z.object({
104
+ /** Identity of the project and of the software serving it. */
105
+ project: z.object({
106
+ id: z.string(),
107
+ /** Storage engine behind this collector (`duckdb`, `clickhouse`, …). */
108
+ store: z.string(),
109
+ /** Event wire-format version (`@uptimizr/schema`). */
110
+ schemaVersion: z.string(),
111
+ /** Version of the running collector, or `unknown`. */
112
+ collectorVersion: z.string(),
113
+ }),
114
+ /** How fresh and how busy the project is — read this before quoting a zero. */
115
+ dataQuality: z.object({
116
+ /** Most recent event, epoch ms, or `null` when the project has no data. */
117
+ lastEventAt: z.number().int().nullable(),
118
+ sessions24h: z.number().int(),
119
+ events24h: z.number().int(),
120
+ retention: z.object({
121
+ /**
122
+ * Whether raw per-session event retention is enabled (ADR 0003). When
123
+ * `false` the session timeline / replay endpoint returns nothing — that is
124
+ * configuration, not missing data.
125
+ */
126
+ rawSessions: z.boolean(),
127
+ }),
128
+ }),
129
+ /** Which capture channels (ADR 0012) this project actually produces. */
130
+ capture: z.object({
131
+ channels: z.record(z.string(), captureChannelSchema),
132
+ }),
133
+ scenes: z.array(sceneSchema),
134
+ vocabulary: z.object({
135
+ customEvents: z.array(customEventSchema),
136
+ meshes: z.object({
137
+ /** Distinct interacted meshes observed, saturating at 200. */
138
+ count: z.number().int(),
139
+ /** The busiest mesh names, most-interacted first. */
140
+ top: z.array(z.string()),
141
+ }),
142
+ /** Developer-bound input action labels (#75, ADR 0023). */
143
+ inputActions: z.array(z.string()),
144
+ }),
145
+ definitions: z.object({
146
+ /** Saved funnel definitions. Always empty: funnels are caller-authored (ADR 0038). */
147
+ funnels: z.array(z.unknown()),
148
+ /** Saved segment definitions. Always empty until the metadata write path exists. */
149
+ segments: z.array(z.unknown()),
150
+ glossary: z.array(glossarySchema),
151
+ }),
152
+ annotations: z.object({
153
+ recent: z.array(annotationSchema),
154
+ }),
155
+ metrics: z.object({
156
+ /** Registry ids this collector serves. */
157
+ available: z.array(z.string()),
158
+ /**
159
+ * Metrics whose every capture channel was unseen over the window — they will
160
+ * return empty, and that is a capture setting rather than a finding.
161
+ */
162
+ disabledByCapture: z.array(z.string()),
163
+ }),
164
+ /** The window the 28-day figures were computed over, epoch ms. */
165
+ window: z.object({ since: z.number().int(), until: z.number().int() }),
166
+ /** When this document was built, epoch ms. Respect the cache TTL. */
167
+ generatedAt: z.number().int(),
168
+ });
169
+ /** Parse an engine-formatted timestamp into epoch ms, or `null`. */
170
+ function toEpochMs(value) {
171
+ if (value == null)
172
+ return null;
173
+ const parsed = Date.parse(value.includes("T") ? value : value.replace(" ", "T") + "Z");
174
+ return Number.isFinite(parsed) ? parsed : null;
175
+ }
176
+ /**
177
+ * Build the document for one project. Pure orchestration over the store: every
178
+ * figure comes from an aggregate the collector already serves, so there is no
179
+ * new SQL here beyond the custom-event vocabulary.
180
+ */
181
+ async function buildContext(store, config, metadata, projectId, now) {
182
+ const since = now - CONTEXT_WINDOW_MS;
183
+ const window = { since, until: now };
184
+ const recent = { since: now - RECENT_WINDOW_MS, until: now };
185
+ const [channelCounts, recentChannelCounts, recentSessions, sceneRows, representations, regionRows, customEvents, meshRows, inputActionRows, glossary, annotations,] = await Promise.all([
186
+ store.eventTypeCounts(projectId, window),
187
+ store.eventTypeCounts(projectId, recent),
188
+ store.listSessions(projectId, { ...recent, limit: 1000 }),
189
+ store.scenes(projectId, { ...window, limit: MAX_SCENES }),
190
+ store.listSceneRepresentations(projectId),
191
+ store.listSceneRegions(projectId),
192
+ store.customEventVocabulary(projectId, { ...window, limit: MAX_CUSTOM_EVENTS }),
193
+ store.topMeshes(projectId, { ...window, limit: MAX_COUNTED_MESHES }),
194
+ store.topInputActions(projectId, { ...window, limit: MAX_INPUT_ACTIONS }),
195
+ metadata.glossary(projectId),
196
+ metadata.recentAnnotations(projectId, MAX_ANNOTATIONS),
197
+ ]);
198
+ const countByType = new Map(channelCounts.map((row) => [row.event_type, row.count]));
199
+ const channels = {};
200
+ for (const type of EVENT_TYPES) {
201
+ const events = countByType.get(type) ?? 0;
202
+ channels[type] = events > 0 ? { seen: true, events28d: events } : { seen: false };
203
+ }
204
+ const labelByScene = new Map(representations.map((rep) => [rep.sceneId, rep.label]));
205
+ const proxyScenes = new Set(representations.map((rep) => rep.sceneId));
206
+ const regionsByScene = new Map();
207
+ for (const region of regionRows) {
208
+ const list = regionsByScene.get(region.sceneId) ?? [];
209
+ if (list.length >= MAX_REGIONS_PER_SCENE)
210
+ continue;
211
+ list.push({ id: region.regionId, label: region.label });
212
+ regionsByScene.set(region.sceneId, list);
213
+ }
214
+ const scenes = sceneRows.map((row) => ({
215
+ id: row.scene_id,
216
+ label: labelByScene.get(row.scene_id) ?? null,
217
+ regions: regionsByScene.get(row.scene_id) ?? [],
218
+ proxy: proxyScenes.has(row.scene_id),
219
+ events28d: row.events,
220
+ }));
221
+ const lastEventAt = sceneRows.reduce((latest, row) => {
222
+ const seen = toEpochMs(row.last_seen);
223
+ return seen != null && (latest == null || seen > latest) ? seen : latest;
224
+ }, null);
225
+ // A metric is "disabled by capture" when it declares source channels and NONE
226
+ // of them produced an event over the window. Derived rollups declare no
227
+ // channels and are never reported as disabled.
228
+ const served = allMetrics().filter((metric) => metric.endpoint != null);
229
+ const seen = (type) => (countByType.get(type) ?? 0) > 0;
230
+ const disabledByCapture = served
231
+ .filter((metric) => metric.sourceChannels.length > 0 && !metric.sourceChannels.some((c) => seen(c)))
232
+ .map((metric) => metric.id);
233
+ return {
234
+ project: {
235
+ id: projectId,
236
+ store: store.engine,
237
+ schemaVersion: SCHEMA_VERSION,
238
+ collectorVersion: COLLECTOR_VERSION,
239
+ },
240
+ dataQuality: {
241
+ lastEventAt,
242
+ sessions24h: recentSessions.length,
243
+ events24h: recentChannelCounts.reduce((total, row) => total + row.count, 0),
244
+ retention: { rawSessions: config.enableRawSessionRetention },
245
+ },
246
+ capture: { channels },
247
+ scenes,
248
+ vocabulary: {
249
+ customEvents: customEvents.map((row) => ({
250
+ name: row.name,
251
+ count28d: row.count,
252
+ sessions28d: row.sessions,
253
+ props: row.props,
254
+ })),
255
+ meshes: {
256
+ count: meshRows.length,
257
+ top: meshRows.slice(0, MAX_TOP_MESHES).map((row) => row.mesh),
258
+ },
259
+ inputActions: [...new Set(inputActionRows.map((row) => row.action))].slice(0, MAX_INPUT_ACTIONS),
260
+ },
261
+ definitions: {
262
+ funnels: [],
263
+ segments: [],
264
+ glossary: glossary.slice(0, MAX_GLOSSARY).map((entry) => ({ ...entry })),
265
+ },
266
+ annotations: {
267
+ recent: annotations.slice(0, MAX_ANNOTATIONS).map((entry) => ({
268
+ id: entry.id,
269
+ target: { kind: entry.target.kind, id: entry.target.id },
270
+ text: entry.text,
271
+ at: entry.at,
272
+ })),
273
+ },
274
+ metrics: {
275
+ available: served.map((metric) => metric.id),
276
+ disabledByCapture,
277
+ },
278
+ window,
279
+ generatedAt: now,
280
+ };
281
+ }
282
+ /**
283
+ * The project context route. Registered as its own plugin so the query plugin —
284
+ * which is the registry-metric surface, and is asserted against the registry
285
+ * route by route — stays exactly that.
286
+ */
287
+ export const contextRoutes = async (app, { store, config, metadata = EMPTY_PROJECT_METADATA }) => {
288
+ const r = app.withTypeProvider();
289
+ /** Per-project document cache, cleared with the instance. */
290
+ const cache = new Map();
291
+ app.addHook("onClose", async () => cache.clear());
292
+ r.get("/api/v1/context", { schema: { response: { 200: projectContextSchema } } }, async (req, reply) => {
293
+ const resolved = await requireCapability(req, reply, store, "query");
294
+ if (!resolved)
295
+ return reply;
296
+ const projectId = resolved.projectId;
297
+ const now = Date.now();
298
+ const cached = cache.get(projectId);
299
+ if (cached && cached.expiresAt > now)
300
+ return cached.document;
301
+ const document = await buildContext(store, config, metadata, projectId, now);
302
+ cache.set(projectId, { expiresAt: now + CONTEXT_CACHE_TTL_MS, document });
303
+ return document;
304
+ });
305
+ };
306
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/routes/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * **Insight primitives** — `GET /api/v1/insights/*` (ADR 0051 §4, sketch §D).
3
+ *
4
+ * Two registry metrics that answer the questions an agent otherwise re-derives
5
+ * from raw rows on every turn:
6
+ *
7
+ * - `insight_baseline` — what is normal for one metric in one scene;
8
+ * - `insight_movers` — what changed, ranked by how unusual the change is;
9
+ * - `insight_anomalies` — which buckets of one metric do not belong, and what
10
+ * inside the metric accounts for them (#306).
11
+ *
12
+ * The plugin is deliberately thin (ADR 0005). Everything that decides an answer
13
+ * lives in `@uptimizr/db`'s pure `src/insights/`: which metrics have a portable
14
+ * bucket series, how the window resolves, and every statistic. This file does
15
+ * three things — validate at the boundary, fan the bucket reads out under a
16
+ * declared cap, and shape the envelope.
17
+ *
18
+ * It is a separate plugin rather than more routes in `query.ts` because it is a
19
+ * separate *kind* of read: a derived metric composed of other metrics' series,
20
+ * which needs its own error vocabulary (a metric can be unknown, not comparable,
21
+ * or comparable but not bucketable — three different 400s) and its own bounded
22
+ * fan-out. One registration line in `app.ts` is the whole coupling.
23
+ */
24
+ import type { FastifyPluginAsync } from "fastify";
25
+ import type { CollectorStore } from "../store.js";
26
+ interface Options {
27
+ store: CollectorStore;
28
+ }
29
+ /**
30
+ * Insight API. Every route is scoped to the authenticated project and needs the
31
+ * ordinary `query` capability — an insight is a read of the project's own
32
+ * telemetry, nothing more.
33
+ */
34
+ export declare const insightRoutes: FastifyPluginAsync<Options>;
35
+ export {};
36
+ //# sourceMappingURL=insights.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insights.d.ts","sourceRoot":"","sources":["../../src/routes/insights.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,SAAS,CAAC;AAmDlE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,UAAU,OAAO;IACf,KAAK,EAAE,cAAc,CAAC;CACvB;AAuaD;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,kBAAkB,CAAC,OAAO,CAubrD,CAAC"}