@checkstack/healthcheck-common 0.3.0 → 0.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,65 @@
1
1
  # @checkstack/healthcheck-common
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7a23261: ## TanStack Query Integration
8
+
9
+ Migrated all frontend components to use `usePluginClient` hook with TanStack Query integration, replacing the legacy `forPlugin()` pattern.
10
+
11
+ ### New Features
12
+
13
+ - **`usePluginClient` hook**: Provides type-safe access to plugin APIs with `.useQuery()` and `.useMutation()` methods
14
+ - **Automatic request deduplication**: Multiple components requesting the same data share a single network request
15
+ - **Built-in caching**: Configurable stale time and cache duration per query
16
+ - **Loading/error states**: TanStack Query provides `isLoading`, `error`, `isRefetching` states automatically
17
+ - **Background refetching**: Stale data is automatically refreshed when components mount
18
+
19
+ ### Contract Changes
20
+
21
+ All RPC contracts now require `operationType: "query"` or `operationType: "mutation"` metadata:
22
+
23
+ ```typescript
24
+ const getItems = proc()
25
+ .meta({ operationType: "query", access: [access.read] })
26
+ .output(z.array(itemSchema))
27
+ .query();
28
+
29
+ const createItem = proc()
30
+ .meta({ operationType: "mutation", access: [access.manage] })
31
+ .input(createItemSchema)
32
+ .output(itemSchema)
33
+ .mutation();
34
+ ```
35
+
36
+ ### Migration
37
+
38
+ ```typescript
39
+ // Before (forPlugin pattern)
40
+ const api = useApi(myPluginApiRef);
41
+ const [items, setItems] = useState<Item[]>([]);
42
+ useEffect(() => {
43
+ api.getItems().then(setItems);
44
+ }, [api]);
45
+
46
+ // After (usePluginClient pattern)
47
+ const client = usePluginClient(MyPluginApi);
48
+ const { data: items, isLoading } = client.getItems.useQuery({});
49
+ ```
50
+
51
+ ### Bug Fixes
52
+
53
+ - Fixed `rpc.test.ts` test setup for middleware type inference
54
+ - Fixed `SearchDialog` to use `setQuery` instead of deprecated `search` method
55
+ - Fixed null→undefined warnings in notification and queue frontends
56
+
57
+ ### Patch Changes
58
+
59
+ - Updated dependencies [7a23261]
60
+ - @checkstack/common@0.3.0
61
+ - @checkstack/signal-common@0.1.1
62
+
3
63
  ## 0.3.0
4
64
 
5
65
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/healthcheck-common",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
package/src/access.ts CHANGED
@@ -7,8 +7,20 @@ export const healthCheckAccess = {
7
7
  /**
8
8
  * Status-only access for viewing health check status.
9
9
  * Enabled by default for anonymous and authenticated users.
10
+ * Uses system-level instance access for team-based filtering.
10
11
  */
11
12
  status: access("healthcheck.status", "read", "View Health Check Status", {
13
+ idParam: "systemId",
14
+ isDefault: true,
15
+ isPublic: true,
16
+ }),
17
+
18
+ /**
19
+ * Bulk status access for viewing health check status for multiple systems.
20
+ * Uses recordKey for filtering the output record by accessible system IDs.
21
+ */
22
+ bulkStatus: access("healthcheck.status", "read", "View Health Check Status", {
23
+ recordKey: "statuses",
12
24
  isDefault: true,
13
25
  isPublic: true,
14
26
  }),
@@ -1,8 +1,4 @@
1
- import { oc } from "@orpc/contract";
2
- import {
3
- createClientDefinition,
4
- type ProcedureMetadata,
5
- } from "@checkstack/common";
1
+ import { createClientDefinition, proc } from "@checkstack/common";
6
2
  import { pluginMetadata } from "./plugin-metadata";
7
3
  import { z } from "zod";
8
4
  import { healthCheckAccess } from "./access";
@@ -22,9 +18,6 @@ import {
22
18
  AggregatedBucketSchema,
23
19
  } from "./schemas";
24
20
 
25
- // Base builder with full metadata support
26
- const _base = oc.$meta<ProcedureMetadata>({});
27
-
28
21
  // --- Response Schemas for Evaluated Status ---
29
22
 
30
23
  const SystemCheckStatusSchema = z.object({
@@ -41,28 +34,27 @@ const SystemHealthStatusResponseSchema = z.object({
41
34
  checkStatuses: z.array(SystemCheckStatusSchema),
42
35
  });
43
36
 
37
+ export type SystemHealthStatusResponse = z.infer<
38
+ typeof SystemHealthStatusResponseSchema
39
+ >;
40
+
44
41
  // Health Check RPC Contract using oRPC's contract-first pattern
45
42
  export const healthCheckContract = {
46
43
  // ==========================================================================
47
44
  // STRATEGY MANAGEMENT (userType: "authenticated" with read access)
48
45
  // ==========================================================================
49
46
 
50
- getStrategies: _base
51
- .meta({
52
- userType: "authenticated",
53
- access: [healthCheckAccess.configuration.read],
54
- })
55
- .output(z.array(HealthCheckStrategyDtoSchema)),
47
+ getStrategies: proc({
48
+ operationType: "query",
49
+ userType: "authenticated",
50
+ access: [healthCheckAccess.configuration.read],
51
+ }).output(z.array(HealthCheckStrategyDtoSchema)),
56
52
 
57
- /**
58
- * Get available collectors for a specific strategy.
59
- * Returns collectors that support the given strategy's transport.
60
- */
61
- getCollectors: _base
62
- .meta({
63
- userType: "authenticated",
64
- access: [healthCheckAccess.configuration.read],
65
- })
53
+ getCollectors: proc({
54
+ operationType: "query",
55
+ userType: "authenticated",
56
+ access: [healthCheckAccess.configuration.read],
57
+ })
66
58
  .input(z.object({ strategyId: z.string() }))
67
59
  .output(z.array(CollectorDtoSchema)),
68
60
 
@@ -70,28 +62,27 @@ export const healthCheckContract = {
70
62
  // CONFIGURATION MANAGEMENT (userType: "authenticated")
71
63
  // ==========================================================================
72
64
 
73
- getConfigurations: _base
74
- .meta({
75
- userType: "authenticated",
76
- access: [healthCheckAccess.configuration.read],
77
- })
78
- .output(
79
- z.object({ configurations: z.array(HealthCheckConfigurationSchema) })
80
- ),
65
+ getConfigurations: proc({
66
+ operationType: "query",
67
+ userType: "authenticated",
68
+ access: [healthCheckAccess.configuration.read],
69
+ }).output(
70
+ z.object({ configurations: z.array(HealthCheckConfigurationSchema) })
71
+ ),
81
72
 
82
- createConfiguration: _base
83
- .meta({
84
- userType: "authenticated",
85
- access: [healthCheckAccess.configuration.manage],
86
- })
73
+ createConfiguration: proc({
74
+ operationType: "mutation",
75
+ userType: "authenticated",
76
+ access: [healthCheckAccess.configuration.manage],
77
+ })
87
78
  .input(CreateHealthCheckConfigurationSchema)
88
79
  .output(HealthCheckConfigurationSchema),
89
80
 
90
- updateConfiguration: _base
91
- .meta({
92
- userType: "authenticated",
93
- access: [healthCheckAccess.configuration.manage],
94
- })
81
+ updateConfiguration: proc({
82
+ operationType: "mutation",
83
+ userType: "authenticated",
84
+ access: [healthCheckAccess.configuration.manage],
85
+ })
95
86
  .input(
96
87
  z.object({
97
88
  id: z.string(),
@@ -100,11 +91,11 @@ export const healthCheckContract = {
100
91
  )
101
92
  .output(HealthCheckConfigurationSchema),
102
93
 
103
- deleteConfiguration: _base
104
- .meta({
105
- userType: "authenticated",
106
- access: [healthCheckAccess.configuration.manage],
107
- })
94
+ deleteConfiguration: proc({
95
+ operationType: "mutation",
96
+ userType: "authenticated",
97
+ access: [healthCheckAccess.configuration.manage],
98
+ })
108
99
  .input(z.string())
109
100
  .output(z.void()),
110
101
 
@@ -112,23 +103,19 @@ export const healthCheckContract = {
112
103
  // SYSTEM ASSOCIATION (userType: "authenticated")
113
104
  // ==========================================================================
114
105
 
115
- getSystemConfigurations: _base
116
- .meta({
117
- userType: "authenticated",
118
- access: [healthCheckAccess.configuration.read],
119
- })
106
+ getSystemConfigurations: proc({
107
+ operationType: "query",
108
+ userType: "authenticated",
109
+ access: [healthCheckAccess.configuration.read],
110
+ })
120
111
  .input(z.string())
121
112
  .output(z.array(HealthCheckConfigurationSchema)),
122
113
 
123
- /**
124
- * Get system associations with their threshold configurations.
125
- * Returns full association data including enabled state and thresholds.
126
- */
127
- getSystemAssociations: _base
128
- .meta({
129
- userType: "authenticated",
130
- access: [healthCheckAccess.configuration.read],
131
- })
114
+ getSystemAssociations: proc({
115
+ operationType: "query",
116
+ userType: "authenticated",
117
+ access: [healthCheckAccess.configuration.read],
118
+ })
132
119
  .input(z.object({ systemId: z.string() }))
133
120
  .output(
134
121
  z.array(
@@ -141,11 +128,11 @@ export const healthCheckContract = {
141
128
  )
142
129
  ),
143
130
 
144
- associateSystem: _base
145
- .meta({
146
- userType: "authenticated",
147
- access: [healthCheckAccess.configuration.manage],
148
- })
131
+ associateSystem: proc({
132
+ operationType: "mutation",
133
+ userType: "authenticated",
134
+ access: [healthCheckAccess.configuration.manage],
135
+ })
149
136
  .input(
150
137
  z.object({
151
138
  systemId: z.string(),
@@ -154,11 +141,11 @@ export const healthCheckContract = {
154
141
  )
155
142
  .output(z.void()),
156
143
 
157
- disassociateSystem: _base
158
- .meta({
159
- userType: "authenticated",
160
- access: [healthCheckAccess.configuration.manage],
161
- })
144
+ disassociateSystem: proc({
145
+ operationType: "mutation",
146
+ userType: "authenticated",
147
+ access: [healthCheckAccess.configuration.manage],
148
+ })
162
149
  .input(
163
150
  z.object({
164
151
  systemId: z.string(),
@@ -171,11 +158,11 @@ export const healthCheckContract = {
171
158
  // RETENTION CONFIGURATION (userType: "authenticated" with manage access)
172
159
  // ==========================================================================
173
160
 
174
- getRetentionConfig: _base
175
- .meta({
176
- userType: "authenticated",
177
- access: [healthCheckAccess.configuration.read],
178
- })
161
+ getRetentionConfig: proc({
162
+ operationType: "query",
163
+ userType: "authenticated",
164
+ access: [healthCheckAccess.configuration.read],
165
+ })
179
166
  .input(
180
167
  z.object({
181
168
  systemId: z.string(),
@@ -188,11 +175,11 @@ export const healthCheckContract = {
188
175
  })
189
176
  ),
190
177
 
191
- updateRetentionConfig: _base
192
- .meta({
193
- userType: "authenticated",
194
- access: [healthCheckAccess.configuration.manage],
195
- })
178
+ updateRetentionConfig: proc({
179
+ operationType: "mutation",
180
+ userType: "authenticated",
181
+ access: [healthCheckAccess.configuration.manage],
182
+ })
196
183
  .input(
197
184
  z.object({
198
185
  systemId: z.string(),
@@ -203,14 +190,14 @@ export const healthCheckContract = {
203
190
  .output(z.void()),
204
191
 
205
192
  // ==========================================================================
206
- // HISTORY & STATUS (userType: "user" with read access)
193
+ // HISTORY & STATUS (userType: "public" with read access)
207
194
  // ==========================================================================
208
195
 
209
- getHistory: _base
210
- .meta({
211
- userType: "public",
212
- access: [healthCheckAccess.status],
213
- })
196
+ getHistory: proc({
197
+ operationType: "query",
198
+ userType: "public",
199
+ access: [healthCheckAccess.status],
200
+ })
214
201
  .input(
215
202
  z.object({
216
203
  systemId: z.string().optional(),
@@ -228,15 +215,11 @@ export const healthCheckContract = {
228
215
  })
229
216
  ),
230
217
 
231
- /**
232
- * Get detailed health check run history with full result data.
233
- * Requires access to view detailed run data including metadata.
234
- */
235
- getDetailedHistory: _base
236
- .meta({
237
- userType: "authenticated",
238
- access: [healthCheckAccess.details],
239
- })
218
+ getDetailedHistory: proc({
219
+ operationType: "query",
220
+ userType: "authenticated",
221
+ access: [healthCheckAccess.details],
222
+ })
240
223
  .input(
241
224
  z.object({
242
225
  systemId: z.string().optional(),
@@ -254,16 +237,11 @@ export const healthCheckContract = {
254
237
  })
255
238
  ),
256
239
 
257
- /**
258
- * Get aggregated health check history for long-term analysis.
259
- * Returns pre-computed buckets with core metrics only (no strategy-specific data).
260
- * For strategy-specific aggregated results, use getDetailedAggregatedHistory.
261
- */
262
- getAggregatedHistory: _base
263
- .meta({
264
- userType: "public",
265
- access: [healthCheckAccess.status],
266
- })
240
+ getAggregatedHistory: proc({
241
+ operationType: "query",
242
+ userType: "public",
243
+ access: [healthCheckAccess.status],
244
+ })
267
245
  .input(
268
246
  z.object({
269
247
  systemId: z.string(),
@@ -279,16 +257,11 @@ export const healthCheckContract = {
279
257
  })
280
258
  ),
281
259
 
282
- /**
283
- * Get detailed aggregated health check history including strategy-specific data.
284
- * Returns buckets with core metrics AND aggregatedResult from strategy.
285
- * Requires healthCheckDetailsRead access rule.
286
- */
287
- getDetailedAggregatedHistory: _base
288
- .meta({
289
- userType: "public",
290
- access: [healthCheckAccess.details],
291
- })
260
+ getDetailedAggregatedHistory: proc({
261
+ operationType: "query",
262
+ userType: "public",
263
+ access: [healthCheckAccess.details],
264
+ })
292
265
  .input(
293
266
  z.object({
294
267
  systemId: z.string(),
@@ -304,27 +277,31 @@ export const healthCheckContract = {
304
277
  })
305
278
  ),
306
279
 
307
- /**
308
- * Get evaluateted health status for a system based on configured thresholds.
309
- * Aggregates all health check statuses for the system.
310
- */
311
- getSystemHealthStatus: _base
312
- .meta({
313
- userType: "public",
314
- access: [healthCheckAccess.status],
315
- })
280
+ getSystemHealthStatus: proc({
281
+ operationType: "query",
282
+ userType: "public",
283
+ access: [healthCheckAccess.status],
284
+ })
316
285
  .input(z.object({ systemId: z.string() }))
317
286
  .output(SystemHealthStatusResponseSchema),
318
287
 
319
- /**
320
- * Get comprehensive health overview for a system.
321
- * Returns all health checks with their last 25 runs for sparkline visualization.
322
- */
323
- getSystemHealthOverview: _base
324
- .meta({
325
- userType: "public",
326
- access: [healthCheckAccess.status],
327
- })
288
+ getBulkSystemHealthStatus: proc({
289
+ operationType: "query",
290
+ userType: "public",
291
+ access: [healthCheckAccess.bulkStatus],
292
+ })
293
+ .input(z.object({ systemIds: z.array(z.string()) }))
294
+ .output(
295
+ z.object({
296
+ statuses: z.record(z.string(), SystemHealthStatusResponseSchema),
297
+ })
298
+ ),
299
+
300
+ getSystemHealthOverview: proc({
301
+ operationType: "query",
302
+ userType: "public",
303
+ access: [healthCheckAccess.status],
304
+ })
328
305
  .input(z.object({ systemId: z.string() }))
329
306
  .output(
330
307
  z.object({