@checkstack/healthcheck-backend 0.0.2

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 ADDED
@@ -0,0 +1,181 @@
1
+ # @checkstack/healthcheck-backend
2
+
3
+ ## 0.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - d20d274: Initial release of all @checkstack packages. Rebranded from Checkmate to Checkstack with new npm organization @checkstack and domain checkstack.dev.
8
+ - Updated dependencies [d20d274]
9
+ - @checkstack/backend-api@0.0.2
10
+ - @checkstack/catalog-backend@0.0.2
11
+ - @checkstack/catalog-common@0.0.2
12
+ - @checkstack/command-backend@0.0.2
13
+ - @checkstack/common@0.0.2
14
+ - @checkstack/healthcheck-common@0.0.2
15
+ - @checkstack/integration-backend@0.0.2
16
+ - @checkstack/queue-api@0.0.2
17
+ - @checkstack/signal-common@0.0.2
18
+
19
+ ## 0.2.0
20
+
21
+ ### Minor Changes
22
+
23
+ - a65e002: Add command palette commands and deep-linking support
24
+
25
+ **Backend Changes:**
26
+
27
+ - `healthcheck-backend`: Add "Manage Health Checks" (⇧⌘H) and "Create Health Check" commands
28
+ - `catalog-backend`: Add "Manage Systems" (⇧⌘S) and "Create System" commands
29
+ - `integration-backend`: Add "Manage Integrations" (⇧⌘G), "Create Integration Subscription", and "View Integration Logs" commands
30
+ - `auth-backend`: Add "Manage Users" (⇧⌘U), "Create User", "Manage Roles", and "Manage Applications" commands
31
+ - `command-backend`: Auto-cleanup command registrations when plugins are deregistered
32
+
33
+ **Frontend Changes:**
34
+
35
+ - `HealthCheckConfigPage`: Handle `?action=create` URL parameter
36
+ - `CatalogConfigPage`: Handle `?action=create` URL parameter
37
+ - `IntegrationsPage`: Handle `?action=create` URL parameter
38
+ - `AuthSettingsPage`: Handle `?tab=` and `?action=create` URL parameters
39
+
40
+ ### Patch Changes
41
+
42
+ - Updated dependencies [4c5aa9e]
43
+ - Updated dependencies [b4eb432]
44
+ - Updated dependencies [a65e002]
45
+ - Updated dependencies [a65e002]
46
+ - @checkstack/integration-backend@0.1.0
47
+ - @checkstack/backend-api@1.1.0
48
+ - @checkstack/common@0.2.0
49
+ - @checkstack/command-backend@0.1.0
50
+ - @checkstack/catalog-backend@0.1.0
51
+ - @checkstack/queue-api@1.0.1
52
+ - @checkstack/catalog-common@0.1.2
53
+ - @checkstack/healthcheck-common@0.1.1
54
+ - @checkstack/signal-common@0.1.1
55
+
56
+ ## 0.1.1
57
+
58
+ ### Patch Changes
59
+
60
+ - @checkstack/catalog-common@0.1.1
61
+ - @checkstack/catalog-backend@0.0.3
62
+
63
+ ## 0.1.0
64
+
65
+ ### Minor Changes
66
+
67
+ - ae19ff6: Add configurable state thresholds for health check evaluation
68
+
69
+ **@checkstack/backend-api:**
70
+
71
+ - Added `VersionedData<T>` generic interface as base for all versioned data structures
72
+ - `VersionedConfig<T>` now extends `VersionedData<T>` and adds `pluginId`
73
+ - Added `migrateVersionedData()` utility function for running migrations on any `VersionedData` subtype
74
+
75
+ **@checkstack/backend:**
76
+
77
+ - Refactored `ConfigMigrationRunner` to use the new `migrateVersionedData` utility
78
+
79
+ **@checkstack/healthcheck-common:**
80
+
81
+ - Added state threshold schemas with two evaluation modes (consecutive, window)
82
+ - Added `stateThresholds` field to `AssociateHealthCheckSchema`
83
+ - Added `getSystemHealthStatus` RPC endpoint contract
84
+
85
+ **@checkstack/healthcheck-backend:**
86
+
87
+ - Added `stateThresholds` column to `system_health_checks` table
88
+ - Added `state-evaluator.ts` with health status evaluation logic
89
+ - Added `state-thresholds-migrations.ts` with migration infrastructure
90
+ - Added `getSystemHealthStatus` RPC handler
91
+
92
+ **@checkstack/healthcheck-frontend:**
93
+
94
+ - Updated `SystemHealthBadge` to use new backend endpoint
95
+
96
+ - 0babb9c: Add public health status access and detailed history for admins
97
+
98
+ **Permission changes:**
99
+
100
+ - Added `healthcheck.status.read` permission with `isPublicDefault: true` for anonymous access
101
+ - `getSystemHealthStatus`, `getSystemHealthOverview`, and `getHistory` now public
102
+ - `getHistory` no longer returns `result` field (security)
103
+
104
+ **New features:**
105
+
106
+ - Added `getDetailedHistory` endpoint with `healthcheck.manage` permission
107
+ - New `/healthcheck/history` page showing paginated run history with expandable result JSON
108
+
109
+ ### Patch Changes
110
+
111
+ - e4d83fc: Add BullMQ queue plugin with orphaned job cleanup
112
+
113
+ - **queue-api**: Added `listRecurringJobs()` method to Queue interface for detecting orphaned jobs
114
+ - **queue-bullmq-backend**: New plugin implementing BullMQ (Redis) queue backend with job schedulers, consumer groups, and distributed job persistence
115
+ - **queue-bullmq-common**: New common package with queue permissions
116
+ - **queue-memory-backend**: Implemented `listRecurringJobs()` for in-memory queue
117
+ - **healthcheck-backend**: Enhanced `bootstrapHealthChecks` to clean up orphaned job schedulers using `listRecurringJobs()`
118
+ - **test-utils-backend**: Added `listRecurringJobs()` to mock queue factory
119
+
120
+ This enables production-ready distributed queue processing with Redis persistence and automatic cleanup of orphaned jobs when health checks are deleted.
121
+
122
+ - 81f3f85: ## Breaking: Unified Versioned<T> Architecture
123
+
124
+ Refactored the versioning system to use a unified `Versioned<T>` class instead of separate `VersionedSchema`, `VersionedData`, and `VersionedConfig` types.
125
+
126
+ ### Breaking Changes
127
+
128
+ - **`VersionedSchema<T>`** is replaced by `Versioned<T>` class
129
+ - **`VersionedData<T>`** is replaced by `VersionedRecord<T>` interface
130
+ - **`VersionedConfig<T>`** is replaced by `VersionedPluginRecord<T>` interface
131
+ - **`ConfigMigration<F, T>`** is replaced by `Migration<F, T>` interface
132
+ - **`MigrationChain<T>`** is removed (use `Migration<unknown, unknown>[]`)
133
+ - **`migrateVersionedData()`** is removed (use `versioned.parse()`)
134
+ - **`ConfigMigrationRunner`** is removed (migrations are internal to Versioned)
135
+
136
+ ### Migration Guide
137
+
138
+ Before:
139
+
140
+ ```typescript
141
+ const strategy: HealthCheckStrategy = {
142
+ config: {
143
+ version: 1,
144
+ schema: mySchema,
145
+ migrations: [],
146
+ },
147
+ };
148
+ const data = await migrateVersionedData(stored, 1, migrations);
149
+ ```
150
+
151
+ After:
152
+
153
+ ```typescript
154
+ const strategy: HealthCheckStrategy = {
155
+ config: new Versioned({
156
+ version: 1,
157
+ schema: mySchema,
158
+ migrations: [],
159
+ }),
160
+ };
161
+ const data = await strategy.config.parse(stored);
162
+ ```
163
+
164
+ - Updated dependencies [ffc28f6]
165
+ - Updated dependencies [e4d83fc]
166
+ - Updated dependencies [4dd644d]
167
+ - Updated dependencies [71275dd]
168
+ - Updated dependencies [ae19ff6]
169
+ - Updated dependencies [0babb9c]
170
+ - Updated dependencies [b55fae6]
171
+ - Updated dependencies [b354ab3]
172
+ - Updated dependencies [8e889b4]
173
+ - Updated dependencies [81f3f85]
174
+ - @checkstack/common@0.1.0
175
+ - @checkstack/backend-api@1.0.0
176
+ - @checkstack/catalog-common@0.1.0
177
+ - @checkstack/queue-api@1.0.0
178
+ - @checkstack/healthcheck-common@0.1.0
179
+ - @checkstack/signal-common@0.1.0
180
+ - @checkstack/catalog-backend@0.0.2
181
+ - @checkstack/integration-backend@0.0.2
@@ -0,0 +1,33 @@
1
+ CREATE TYPE "health_check_status" AS ENUM('healthy', 'unhealthy', 'degraded');--> statement-breakpoint
2
+ CREATE TABLE "health_check_configurations" (
3
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
4
+ "name" text NOT NULL,
5
+ "strategy_id" text NOT NULL,
6
+ "config" jsonb NOT NULL,
7
+ "interval_seconds" integer NOT NULL,
8
+ "is_template" boolean DEFAULT false,
9
+ "created_at" timestamp DEFAULT now() NOT NULL,
10
+ "updated_at" timestamp DEFAULT now() NOT NULL
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE TABLE "health_check_runs" (
14
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
15
+ "configuration_id" uuid NOT NULL,
16
+ "system_id" text NOT NULL,
17
+ "status" "health_check_status" NOT NULL,
18
+ "result" jsonb,
19
+ "timestamp" timestamp DEFAULT now() NOT NULL
20
+ );
21
+ --> statement-breakpoint
22
+ CREATE TABLE "system_health_checks" (
23
+ "system_id" text NOT NULL,
24
+ "configuration_id" uuid NOT NULL,
25
+ "enabled" boolean DEFAULT true NOT NULL,
26
+ "state_thresholds" jsonb,
27
+ "created_at" timestamp DEFAULT now() NOT NULL,
28
+ "updated_at" timestamp DEFAULT now() NOT NULL,
29
+ CONSTRAINT "system_health_checks_system_id_configuration_id_pk" PRIMARY KEY("system_id","configuration_id")
30
+ );
31
+ --> statement-breakpoint
32
+ ALTER TABLE "health_check_runs" ADD CONSTRAINT "health_check_runs_configuration_id_health_check_configurations_id_fk" FOREIGN KEY ("configuration_id") REFERENCES "health_check_configurations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
33
+ ALTER TABLE "system_health_checks" ADD CONSTRAINT "system_health_checks_configuration_id_health_check_configurations_id_fk" FOREIGN KEY ("configuration_id") REFERENCES "health_check_configurations"("id") ON DELETE cascade ON UPDATE no action;
@@ -0,0 +1 @@
1
+ ALTER TABLE "health_check_runs" ADD COLUMN "latency_ms" integer;
@@ -0,0 +1,19 @@
1
+ CREATE TYPE "bucket_size" AS ENUM('hourly', 'daily');--> statement-breakpoint
2
+ CREATE TABLE "health_check_aggregates" (
3
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
4
+ "configuration_id" uuid NOT NULL,
5
+ "system_id" text NOT NULL,
6
+ "bucket_start" timestamp NOT NULL,
7
+ "bucket_size" "bucket_size" NOT NULL,
8
+ "run_count" integer NOT NULL,
9
+ "healthy_count" integer NOT NULL,
10
+ "degraded_count" integer NOT NULL,
11
+ "unhealthy_count" integer NOT NULL,
12
+ "avg_latency_ms" integer,
13
+ "min_latency_ms" integer,
14
+ "max_latency_ms" integer,
15
+ "p95_latency_ms" integer,
16
+ "aggregated_metadata" jsonb
17
+ );
18
+ --> statement-breakpoint
19
+ ALTER TABLE "health_check_aggregates" ADD CONSTRAINT "health_check_aggregates_configuration_id_health_check_configurations_id_fk" FOREIGN KEY ("configuration_id") REFERENCES "health_check_configurations"("id") ON DELETE cascade ON UPDATE no action;
@@ -0,0 +1 @@
1
+ ALTER TABLE "system_health_checks" ADD COLUMN "retention_config" jsonb;
@@ -0,0 +1 @@
1
+ CREATE UNIQUE INDEX "health_check_aggregates_bucket_unique" ON "health_check_aggregates" USING btree ("configuration_id","system_id","bucket_start","bucket_size");
@@ -0,0 +1 @@
1
+ ALTER TABLE "health_check_aggregates" RENAME COLUMN "aggregated_metadata" TO "aggregated_result";
@@ -0,0 +1,234 @@
1
+ {
2
+ "id": "74a6fab2-e8df-4d0f-a2af-669d072ecdf5",
3
+ "prevId": "00000000-0000-0000-0000-000000000000",
4
+ "version": "7",
5
+ "dialect": "postgresql",
6
+ "tables": {
7
+ "public.health_check_configurations": {
8
+ "name": "health_check_configurations",
9
+ "schema": "",
10
+ "columns": {
11
+ "id": {
12
+ "name": "id",
13
+ "type": "uuid",
14
+ "primaryKey": true,
15
+ "notNull": true,
16
+ "default": "gen_random_uuid()"
17
+ },
18
+ "name": {
19
+ "name": "name",
20
+ "type": "text",
21
+ "primaryKey": false,
22
+ "notNull": true
23
+ },
24
+ "strategy_id": {
25
+ "name": "strategy_id",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": true
29
+ },
30
+ "config": {
31
+ "name": "config",
32
+ "type": "jsonb",
33
+ "primaryKey": false,
34
+ "notNull": true
35
+ },
36
+ "interval_seconds": {
37
+ "name": "interval_seconds",
38
+ "type": "integer",
39
+ "primaryKey": false,
40
+ "notNull": true
41
+ },
42
+ "is_template": {
43
+ "name": "is_template",
44
+ "type": "boolean",
45
+ "primaryKey": false,
46
+ "notNull": false,
47
+ "default": false
48
+ },
49
+ "created_at": {
50
+ "name": "created_at",
51
+ "type": "timestamp",
52
+ "primaryKey": false,
53
+ "notNull": true,
54
+ "default": "now()"
55
+ },
56
+ "updated_at": {
57
+ "name": "updated_at",
58
+ "type": "timestamp",
59
+ "primaryKey": false,
60
+ "notNull": true,
61
+ "default": "now()"
62
+ }
63
+ },
64
+ "indexes": {},
65
+ "foreignKeys": {},
66
+ "compositePrimaryKeys": {},
67
+ "uniqueConstraints": {},
68
+ "policies": {},
69
+ "checkConstraints": {},
70
+ "isRLSEnabled": false
71
+ },
72
+ "public.health_check_runs": {
73
+ "name": "health_check_runs",
74
+ "schema": "",
75
+ "columns": {
76
+ "id": {
77
+ "name": "id",
78
+ "type": "uuid",
79
+ "primaryKey": true,
80
+ "notNull": true,
81
+ "default": "gen_random_uuid()"
82
+ },
83
+ "configuration_id": {
84
+ "name": "configuration_id",
85
+ "type": "uuid",
86
+ "primaryKey": false,
87
+ "notNull": true
88
+ },
89
+ "system_id": {
90
+ "name": "system_id",
91
+ "type": "text",
92
+ "primaryKey": false,
93
+ "notNull": true
94
+ },
95
+ "status": {
96
+ "name": "status",
97
+ "type": "health_check_status",
98
+ "typeSchema": "public",
99
+ "primaryKey": false,
100
+ "notNull": true
101
+ },
102
+ "result": {
103
+ "name": "result",
104
+ "type": "jsonb",
105
+ "primaryKey": false,
106
+ "notNull": false
107
+ },
108
+ "timestamp": {
109
+ "name": "timestamp",
110
+ "type": "timestamp",
111
+ "primaryKey": false,
112
+ "notNull": true,
113
+ "default": "now()"
114
+ }
115
+ },
116
+ "indexes": {},
117
+ "foreignKeys": {
118
+ "health_check_runs_configuration_id_health_check_configurations_id_fk": {
119
+ "name": "health_check_runs_configuration_id_health_check_configurations_id_fk",
120
+ "tableFrom": "health_check_runs",
121
+ "tableTo": "health_check_configurations",
122
+ "columnsFrom": [
123
+ "configuration_id"
124
+ ],
125
+ "columnsTo": [
126
+ "id"
127
+ ],
128
+ "onDelete": "cascade",
129
+ "onUpdate": "no action"
130
+ }
131
+ },
132
+ "compositePrimaryKeys": {},
133
+ "uniqueConstraints": {},
134
+ "policies": {},
135
+ "checkConstraints": {},
136
+ "isRLSEnabled": false
137
+ },
138
+ "public.system_health_checks": {
139
+ "name": "system_health_checks",
140
+ "schema": "",
141
+ "columns": {
142
+ "system_id": {
143
+ "name": "system_id",
144
+ "type": "text",
145
+ "primaryKey": false,
146
+ "notNull": true
147
+ },
148
+ "configuration_id": {
149
+ "name": "configuration_id",
150
+ "type": "uuid",
151
+ "primaryKey": false,
152
+ "notNull": true
153
+ },
154
+ "enabled": {
155
+ "name": "enabled",
156
+ "type": "boolean",
157
+ "primaryKey": false,
158
+ "notNull": true,
159
+ "default": true
160
+ },
161
+ "state_thresholds": {
162
+ "name": "state_thresholds",
163
+ "type": "jsonb",
164
+ "primaryKey": false,
165
+ "notNull": false
166
+ },
167
+ "created_at": {
168
+ "name": "created_at",
169
+ "type": "timestamp",
170
+ "primaryKey": false,
171
+ "notNull": true,
172
+ "default": "now()"
173
+ },
174
+ "updated_at": {
175
+ "name": "updated_at",
176
+ "type": "timestamp",
177
+ "primaryKey": false,
178
+ "notNull": true,
179
+ "default": "now()"
180
+ }
181
+ },
182
+ "indexes": {},
183
+ "foreignKeys": {
184
+ "system_health_checks_configuration_id_health_check_configurations_id_fk": {
185
+ "name": "system_health_checks_configuration_id_health_check_configurations_id_fk",
186
+ "tableFrom": "system_health_checks",
187
+ "tableTo": "health_check_configurations",
188
+ "columnsFrom": [
189
+ "configuration_id"
190
+ ],
191
+ "columnsTo": [
192
+ "id"
193
+ ],
194
+ "onDelete": "cascade",
195
+ "onUpdate": "no action"
196
+ }
197
+ },
198
+ "compositePrimaryKeys": {
199
+ "system_health_checks_system_id_configuration_id_pk": {
200
+ "name": "system_health_checks_system_id_configuration_id_pk",
201
+ "columns": [
202
+ "system_id",
203
+ "configuration_id"
204
+ ]
205
+ }
206
+ },
207
+ "uniqueConstraints": {},
208
+ "policies": {},
209
+ "checkConstraints": {},
210
+ "isRLSEnabled": false
211
+ }
212
+ },
213
+ "enums": {
214
+ "public.health_check_status": {
215
+ "name": "health_check_status",
216
+ "schema": "public",
217
+ "values": [
218
+ "healthy",
219
+ "unhealthy",
220
+ "degraded"
221
+ ]
222
+ }
223
+ },
224
+ "schemas": {},
225
+ "sequences": {},
226
+ "roles": {},
227
+ "policies": {},
228
+ "views": {},
229
+ "_meta": {
230
+ "columns": {},
231
+ "schemas": {},
232
+ "tables": {}
233
+ }
234
+ }