@checkstack/healthcheck-common 0.5.0 → 0.7.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,67 @@
1
1
  # @checkstack/healthcheck-common
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1f81b60: ### Clickable Run History with Deep Linking
8
+
9
+ **Backend (`healthcheck-backend`):**
10
+
11
+ - Added `getRunById` service method to fetch a single health check run by ID
12
+
13
+ **Schema (`healthcheck-common`):**
14
+
15
+ - Added `getRunById` RPC procedure for fetching individual runs
16
+ - Added `historyRun` route for deep linking to specific runs (`/history/:systemId/:configurationId/:runId`)
17
+
18
+ **Frontend (`healthcheck-frontend`):**
19
+
20
+ - Table rows in Recent Runs and Run History now navigate to detailed view instead of expanding inline
21
+ - Added "Selected Run" card that displays when navigating to a specific run
22
+ - Extracted `ExpandedResultView` into reusable component
23
+ - Fixed layout shift during table pagination by preserving previous data while loading
24
+ - Removed accordion expansion in favor of consistent navigation UX
25
+
26
+ ### Patch Changes
27
+
28
+ - 090143b: ### Health Check Aggregation & UI Fixes
29
+
30
+ **Backend (`healthcheck-backend`):**
31
+
32
+ - Fixed tail-end bucket truncation where the last aggregated bucket was cut off at the interval boundary instead of extending to the query end date
33
+ - Added `rangeEnd` parameter to `reaggregateBuckets()` to properly extend the last bucket
34
+ - Fixed cross-tier merge logic (`mergeTieredBuckets`) to prevent hourly aggregates from blocking fresh raw data
35
+
36
+ **Schema (`healthcheck-common`):**
37
+
38
+ - Added `bucketEnd` field to `AggregatedBucketBaseSchema` so frontends know the actual end time of each bucket
39
+
40
+ **Frontend (`healthcheck-frontend`):**
41
+
42
+ - Updated all components to use `bucket.bucketEnd` instead of calculating from `bucketIntervalSeconds`
43
+ - Fixed aggregation mode detection: changed `>` to `>=` so 7-day queries use aggregated data when `rawRetentionDays` is 7
44
+ - Added ref-based memoization in `useHealthCheckData` to prevent layout shift during signal-triggered refetches
45
+ - Exposed `isFetching` state to show loading spinner during background refetches
46
+ - Added debounced custom date range with Apply button to prevent fetching on every field change
47
+ - Added validation preventing start date >= end date in custom ranges
48
+ - Added sparkline downsampling: when there are 60+ data points, they are aggregated into buckets with informative tooltips
49
+
50
+ **UI (`ui`):**
51
+
52
+ - Fixed `DateRangeFilter` presets to use true sliding windows (removed `startOfDay` from 7-day and 30-day ranges)
53
+ - Added `disabled` prop to `DateRangeFilter` and `DateTimePicker` components
54
+ - Added `onCustomChange` prop to `DateRangeFilter` for debounced custom date handling
55
+ - Improved layout: custom date pickers now inline with preset buttons on desktop
56
+ - Added responsive mobile layout: date pickers stack vertically with down arrow
57
+ - Added validation error display for invalid date ranges
58
+
59
+ ## 0.6.0
60
+
61
+ ### Minor Changes
62
+
63
+ - 11d2679: Add ability to pause health check configurations globally. When paused, health checks continue to be scheduled but execution is skipped for all systems using that configuration. Users with manage access can pause/resume from the Health Checks config page.
64
+
3
65
  ## 0.5.0
4
66
 
5
67
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/healthcheck-common",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
package/src/index.ts CHANGED
@@ -28,6 +28,7 @@ export interface HealthCheckConfiguration {
28
28
  config: Record<string, unknown>;
29
29
  intervalSeconds: number;
30
30
  collectors?: CollectorConfigEntry[];
31
+ paused: boolean;
31
32
  createdAt: Date;
32
33
  updatedAt: Date;
33
34
  }
@@ -58,5 +59,5 @@ export const HEALTH_CHECK_RUN_COMPLETED = createSignal(
58
59
  configurationName: z.string(),
59
60
  status: z.enum(["healthy", "degraded", "unhealthy"]),
60
61
  latencyMs: z.number().optional(),
61
- })
62
+ }),
62
63
  );
package/src/routes.ts CHANGED
@@ -7,4 +7,5 @@ export const healthcheckRoutes = createRoutes("healthcheck", {
7
7
  config: "/config",
8
8
  history: "/history",
9
9
  historyDetail: "/history/:systemId/:configurationId",
10
+ historyRun: "/history/:systemId/:configurationId/:runId",
10
11
  });
@@ -99,6 +99,22 @@ export const healthCheckContract = {
99
99
  .input(z.string())
100
100
  .output(z.void()),
101
101
 
102
+ pauseConfiguration: proc({
103
+ operationType: "mutation",
104
+ userType: "authenticated",
105
+ access: [healthCheckAccess.configuration.manage],
106
+ })
107
+ .input(z.string())
108
+ .output(z.void()),
109
+
110
+ resumeConfiguration: proc({
111
+ operationType: "mutation",
112
+ userType: "authenticated",
113
+ access: [healthCheckAccess.configuration.manage],
114
+ })
115
+ .input(z.string())
116
+ .output(z.void()),
117
+
102
118
  // ==========================================================================
103
119
  // SYSTEM ASSOCIATION (userType: "authenticated")
104
120
  // ==========================================================================
@@ -206,6 +222,7 @@ export const healthCheckContract = {
206
222
  endDate: z.date().optional(),
207
223
  limit: z.number().optional().default(10),
208
224
  offset: z.number().optional().default(0),
225
+ sortOrder: z.enum(["asc", "desc"]),
209
226
  }),
210
227
  )
211
228
  .output(
@@ -228,6 +245,7 @@ export const healthCheckContract = {
228
245
  endDate: z.date().optional(),
229
246
  limit: z.number().optional().default(10),
230
247
  offset: z.number().optional().default(0),
248
+ sortOrder: z.enum(["asc", "desc"]),
231
249
  }),
232
250
  )
233
251
  .output(
@@ -237,6 +255,18 @@ export const healthCheckContract = {
237
255
  }),
238
256
  ),
239
257
 
258
+ getRunById: proc({
259
+ operationType: "query",
260
+ userType: "authenticated",
261
+ access: [healthCheckAccess.details],
262
+ })
263
+ .input(
264
+ z.object({
265
+ runId: z.string(),
266
+ }),
267
+ )
268
+ .output(HealthCheckRunSchema.optional()),
269
+
240
270
  getAggregatedHistory: proc({
241
271
  operationType: "query",
242
272
  userType: "public",
package/src/schemas.ts CHANGED
@@ -81,6 +81,8 @@ export const HealthCheckConfigurationSchema = z.object({
81
81
  intervalSeconds: z.number(),
82
82
  /** Optional collector configurations */
83
83
  collectors: z.array(CollectorConfigEntrySchema).optional(),
84
+ /** Whether this configuration is paused (execution skipped for all systems) */
85
+ paused: z.boolean(),
84
86
  createdAt: z.date(),
85
87
  updatedAt: z.date(),
86
88
  });
@@ -278,6 +280,8 @@ export const DEFAULT_RETENTION_CONFIG: RetentionConfig = {
278
280
  */
279
281
  export const AggregatedBucketBaseSchema = z.object({
280
282
  bucketStart: z.date(),
283
+ /** Actual end time of this bucket (may differ from start + interval for the last bucket) */
284
+ bucketEnd: z.date(),
281
285
  /** @deprecated Use bucketIntervalSeconds instead. Kept for backward compatibility. */
282
286
  bucketSize: z.enum(["hourly", "daily"]).optional(),
283
287
  /** Bucket interval in seconds (e.g., 7 for 7-second buckets) */