@checkstack/slo-backend 0.4.6 → 0.5.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 +124 -0
- package/package.json +12 -13
- package/src/hooks.ts +2 -1
- package/src/index.ts +29 -17
- package/tsconfig.json +3 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,129 @@
|
|
|
1
1
|
# @checkstack/slo-backend
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 41c77f4: feat(automation): type enum-able trigger/artifact fields as enums for editor value autocompletion
|
|
8
|
+
|
|
9
|
+
The automation editor's staged completion offers concrete values after a
|
|
10
|
+
comparator (`{{ trigger.payload.severity == "high" }}`) only when the
|
|
11
|
+
field's JSON Schema carries an `enum`. Several trigger payload + artifact
|
|
12
|
+
schemas declared closed-set fields as loose `z.string()`, so no values
|
|
13
|
+
were suggested. Tightened them to the canonical enums that already
|
|
14
|
+
existed in each plugin's `-common` package (and matched the hook payload
|
|
15
|
+
types in lockstep so the trigger's `payloadSchema` and `hook` keep the
|
|
16
|
+
same `TPayload`):
|
|
17
|
+
|
|
18
|
+
- **incident** — trigger payloads: `severity` → `IncidentSeverityEnum`,
|
|
19
|
+
`status` / `statusChange` → `IncidentStatusEnum`.
|
|
20
|
+
- **healthcheck** — trigger payloads: `previousStatus` / `newStatus` /
|
|
21
|
+
`status` → `HealthCheckStatusSchema` (across systemDegraded,
|
|
22
|
+
systemHealthy, systemHealthChanged, checkFailed; plus checkCompleted's
|
|
23
|
+
hook type).
|
|
24
|
+
- **dependency** — trigger + artifact: `impactType` → `ImpactTypeSchema`;
|
|
25
|
+
impactPropagated `previousState` / `newState` → `DerivedStateSchema`.
|
|
26
|
+
Also deduped the inline `impactTypeSchema` action-config enum to reuse
|
|
27
|
+
the canonical `ImpactTypeSchema`.
|
|
28
|
+
- **maintenance** — trigger + artifact: `status` →
|
|
29
|
+
`MaintenanceStatusEnum`; deduped the inline `maintenanceStatusEnum`
|
|
30
|
+
(used by `add_update.statusChange`) to the canonical one.
|
|
31
|
+
- **slo** — `achievement.unlocked` trigger + hook: `achievement` →
|
|
32
|
+
`AchievementTypeSchema`.
|
|
33
|
+
|
|
34
|
+
Runtime behaviour is unchanged — these fields always carried valid enum
|
|
35
|
+
values (the underlying records are enum-constrained); only the schema
|
|
36
|
+
types were loose. The hook payload generics are now precise too, which
|
|
37
|
+
caught one stale test fixture asserting an invalid `impactType: "soft"`.
|
|
38
|
+
|
|
39
|
+
Fields that look enum-ish but are genuinely free-form were intentionally
|
|
40
|
+
left as `z.string()`: satellite `region` (user-entered), Jira issue
|
|
41
|
+
`status` (per-instance workflow name), notification `strategyQualifiedId`
|
|
42
|
+
/ `errorMessage`, healthcheck collector `result`, and script
|
|
43
|
+
`stdout` / `stderr`.
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- 41c77f4: feat(automation): one-time migration of webhook subscriptions + remove legacy integration backend
|
|
48
|
+
|
|
49
|
+
**BREAKING CHANGES** (platform is in BETA — no major bump):
|
|
50
|
+
|
|
51
|
+
- `IntegrationProvider` no longer carries `config` (subscription
|
|
52
|
+
config) or `deliver`. The interface now models a connection provider
|
|
53
|
+
only: connection schema + `getConnectionOptions` + `testConnection`.
|
|
54
|
+
- The legacy subscription / delivery-log / event endpoints
|
|
55
|
+
(`listSubscriptions`, `createSubscription`, `getDeliveryLogs`,
|
|
56
|
+
`listEventTypes`, …) are removed from `integrationContract`.
|
|
57
|
+
- `delivery-coordinator`, `hook-subscriber`, `event-registry`, and the
|
|
58
|
+
`integrationEventExtensionPoint` are deleted. Plugins that
|
|
59
|
+
previously called `integrationEvents.registerEvent(...)` now
|
|
60
|
+
register their hooks as automation triggers via
|
|
61
|
+
`automationTriggerExtensionPoint.registerTrigger(...)`.
|
|
62
|
+
- Frontend pages `IntegrationsPage` and `DeliveryLogsPage` are gone;
|
|
63
|
+
the integration plugin's only remaining UI is connection
|
|
64
|
+
management. Subscription management lives under `/automation/...`.
|
|
65
|
+
- `webhook_subscriptions` and `delivery_logs` tables stay in the
|
|
66
|
+
database for one release as a safety net (no code reads or writes
|
|
67
|
+
them), and will be dropped in a follow-up migration.
|
|
68
|
+
|
|
69
|
+
**New**:
|
|
70
|
+
|
|
71
|
+
- `jira.create_issue`, `teams.post_message`, `webex.post_message`,
|
|
72
|
+
`webhook.send`, `integration-script.run_shell`, and
|
|
73
|
+
`integration-script.run_script` actions registered against the
|
|
74
|
+
Automation Platform with matching `*.message`, `*.delivery`,
|
|
75
|
+
`shell.result`, and `script.result` artifact types. The script
|
|
76
|
+
plugin exposes **two** actions — `run_shell` runs bash via the
|
|
77
|
+
shared `ShellScriptRunner` (Monaco `shell` editor), `run_script`
|
|
78
|
+
runs an ESM module in a Bun subprocess via `EsmScriptRunner`
|
|
79
|
+
(Monaco `typescript` editor + `defineIntegration` helper) — to
|
|
80
|
+
preserve the legacy provider split. `jira.create_issue` keeps the
|
|
81
|
+
dynamic field-mapping dropdown (driven by
|
|
82
|
+
`JIRA_RESOLVERS.FIELD_OPTIONS`).
|
|
83
|
+
- One-time data migration runs on boot in
|
|
84
|
+
`automation-backend.afterPluginsReady`. It reads
|
|
85
|
+
`webhook_subscriptions` via a new service RPC
|
|
86
|
+
`IntegrationApi.listLegacySubscriptions`, translates each row into
|
|
87
|
+
a single-trigger / single-action automation (marked with
|
|
88
|
+
`managed_by = "migrated-subscription:<id>"`), and is idempotent
|
|
89
|
+
across restarts.
|
|
90
|
+
- Failed translations are recorded in a new
|
|
91
|
+
`automation_migration_failures` table and surfaced via
|
|
92
|
+
`AutomationApi.listMigrationFailures` /
|
|
93
|
+
`acknowledgeMigrationFailure` so admins can review and re-create
|
|
94
|
+
failed entries by hand.
|
|
95
|
+
|
|
96
|
+
- Updated dependencies [e2d6f25]
|
|
97
|
+
- Updated dependencies [41c77f4]
|
|
98
|
+
- Updated dependencies [41c77f4]
|
|
99
|
+
- Updated dependencies [e1a2077]
|
|
100
|
+
- Updated dependencies [41c77f4]
|
|
101
|
+
- Updated dependencies [41c77f4]
|
|
102
|
+
- Updated dependencies [41c77f4]
|
|
103
|
+
- Updated dependencies [41c77f4]
|
|
104
|
+
- Updated dependencies [41c77f4]
|
|
105
|
+
- Updated dependencies [41c77f4]
|
|
106
|
+
- Updated dependencies [41c77f4]
|
|
107
|
+
- Updated dependencies [6d52276]
|
|
108
|
+
- Updated dependencies [6d52276]
|
|
109
|
+
- Updated dependencies [35bc682]
|
|
110
|
+
- @checkstack/automation-backend@0.2.0
|
|
111
|
+
- @checkstack/healthcheck-backend@1.3.0
|
|
112
|
+
- @checkstack/catalog-backend@1.2.0
|
|
113
|
+
- @checkstack/common@0.12.0
|
|
114
|
+
- @checkstack/backend-api@0.18.0
|
|
115
|
+
- @checkstack/healthcheck-common@1.3.0
|
|
116
|
+
- @checkstack/catalog-common@2.2.3
|
|
117
|
+
- @checkstack/dependency-common@1.1.3
|
|
118
|
+
- @checkstack/slo-common@0.4.2
|
|
119
|
+
- @checkstack/command-backend@0.1.31
|
|
120
|
+
- @checkstack/gitops-backend@0.3.7
|
|
121
|
+
- @checkstack/gitops-common@0.4.2
|
|
122
|
+
- @checkstack/signal-common@0.2.5
|
|
123
|
+
- @checkstack/cache-api@0.3.6
|
|
124
|
+
- @checkstack/queue-api@0.3.6
|
|
125
|
+
- @checkstack/cache-utils@0.2.11
|
|
126
|
+
|
|
3
127
|
## 0.4.6
|
|
4
128
|
|
|
5
129
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/slo-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"license": "Elastic-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -14,23 +14,22 @@
|
|
|
14
14
|
"lint:code": "eslint . --max-warnings 0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@checkstack/backend-api": "0.17.
|
|
18
|
-
"@checkstack/cache-api": "0.3.
|
|
19
|
-
"@checkstack/cache-utils": "0.2.
|
|
17
|
+
"@checkstack/backend-api": "0.17.1",
|
|
18
|
+
"@checkstack/cache-api": "0.3.5",
|
|
19
|
+
"@checkstack/cache-utils": "0.2.10",
|
|
20
20
|
"@checkstack/slo-common": "0.4.1",
|
|
21
|
-
"@checkstack/healthcheck-common": "1.
|
|
22
|
-
"@checkstack/healthcheck-backend": "1.
|
|
21
|
+
"@checkstack/healthcheck-common": "1.2.0",
|
|
22
|
+
"@checkstack/healthcheck-backend": "1.2.0",
|
|
23
23
|
"@checkstack/dependency-common": "1.1.2",
|
|
24
24
|
"@checkstack/catalog-common": "2.2.2",
|
|
25
|
-
"@checkstack/catalog-backend": "1.1.
|
|
26
|
-
"@checkstack/command-backend": "0.1.
|
|
25
|
+
"@checkstack/catalog-backend": "1.1.6",
|
|
26
|
+
"@checkstack/command-backend": "0.1.30",
|
|
27
27
|
"@checkstack/signal-common": "0.2.4",
|
|
28
|
-
"@checkstack/
|
|
29
|
-
"@checkstack/
|
|
30
|
-
"@checkstack/gitops-backend": "0.3.5",
|
|
28
|
+
"@checkstack/automation-backend": "0.1.0",
|
|
29
|
+
"@checkstack/gitops-backend": "0.3.6",
|
|
31
30
|
"@checkstack/gitops-common": "0.4.1",
|
|
32
31
|
"@checkstack/common": "0.11.0",
|
|
33
|
-
"@checkstack/queue-api": "0.3.
|
|
32
|
+
"@checkstack/queue-api": "0.3.5",
|
|
34
33
|
"drizzle-orm": "^0.45.0",
|
|
35
34
|
"zod": "^4.2.1",
|
|
36
35
|
"@orpc/server": "^1.13.2"
|
|
@@ -38,7 +37,7 @@
|
|
|
38
37
|
"devDependencies": {
|
|
39
38
|
"@checkstack/drizzle-helper": "0.0.5",
|
|
40
39
|
"@checkstack/scripts": "0.3.3",
|
|
41
|
-
"@checkstack/test-utils-backend": "0.1.
|
|
40
|
+
"@checkstack/test-utils-backend": "0.1.30",
|
|
42
41
|
"@checkstack/tsconfig": "0.0.7",
|
|
43
42
|
"@types/bun": "^1.0.0",
|
|
44
43
|
"drizzle-kit": "^0.31.10",
|
package/src/hooks.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHook } from "@checkstack/backend-api";
|
|
2
|
+
import type { AchievementType } from "@checkstack/slo-common";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* SLO hooks for cross-plugin communication.
|
|
@@ -50,7 +51,7 @@ export const sloHooks = {
|
|
|
50
51
|
*/
|
|
51
52
|
sloAchievementUnlocked: createHook<{
|
|
52
53
|
systemId: string;
|
|
53
|
-
achievement:
|
|
54
|
+
achievement: AchievementType;
|
|
54
55
|
}>("slo.achievement.unlocked"),
|
|
55
56
|
|
|
56
57
|
/**
|
package/src/index.ts
CHANGED
|
@@ -7,9 +7,10 @@ import {
|
|
|
7
7
|
pluginMetadata,
|
|
8
8
|
sloContract,
|
|
9
9
|
sloRoutes,
|
|
10
|
+
AchievementTypeSchema,
|
|
10
11
|
} from "@checkstack/slo-common";
|
|
11
12
|
import { createBackendPlugin, coreServices } from "@checkstack/backend-api";
|
|
12
|
-
import {
|
|
13
|
+
import { automationTriggerExtensionPoint } from "@checkstack/automation-backend";
|
|
13
14
|
import { SloService } from "./service";
|
|
14
15
|
import { SloEngine } from "./slo-engine";
|
|
15
16
|
import { createRouter } from "./router";
|
|
@@ -60,7 +61,7 @@ const sloStreakBrokenPayloadSchema = z.object({
|
|
|
60
61
|
|
|
61
62
|
const sloAchievementUnlockedPayloadSchema = z.object({
|
|
62
63
|
systemId: z.string(),
|
|
63
|
-
achievement:
|
|
64
|
+
achievement: AchievementTypeSchema,
|
|
64
65
|
});
|
|
65
66
|
|
|
66
67
|
const sloWeeklyDigestPayloadSchema = z.object({
|
|
@@ -93,77 +94,88 @@ export default createBackendPlugin({
|
|
|
93
94
|
register(env) {
|
|
94
95
|
env.registerAccessRules(sloAccessRules);
|
|
95
96
|
|
|
96
|
-
// Register hooks as
|
|
97
|
-
const
|
|
98
|
-
|
|
97
|
+
// Register hooks as automation triggers
|
|
98
|
+
const automationTriggers = env.getExtensionPoint(
|
|
99
|
+
automationTriggerExtensionPoint,
|
|
99
100
|
);
|
|
100
101
|
|
|
101
|
-
|
|
102
|
+
automationTriggers.registerTrigger(
|
|
102
103
|
{
|
|
103
|
-
|
|
104
|
+
id: "budget.warning",
|
|
104
105
|
displayName: "SLO Budget Warning",
|
|
105
106
|
description:
|
|
106
107
|
"Fired when an SLO error budget consumption exceeds the warning threshold",
|
|
107
108
|
category: "SLO",
|
|
108
109
|
payloadSchema: sloBudgetWarningPayloadSchema,
|
|
110
|
+
hook: sloHooks.sloBudgetWarning,
|
|
111
|
+
contextKey: (p) => p.systemId,
|
|
109
112
|
},
|
|
110
113
|
pluginMetadata,
|
|
111
114
|
);
|
|
112
115
|
|
|
113
|
-
|
|
116
|
+
automationTriggers.registerTrigger(
|
|
114
117
|
{
|
|
115
|
-
|
|
118
|
+
id: "budget.critical",
|
|
116
119
|
displayName: "SLO Budget Critical",
|
|
117
120
|
description:
|
|
118
121
|
"Fired when an SLO error budget consumption exceeds the critical threshold",
|
|
119
122
|
category: "SLO",
|
|
120
123
|
payloadSchema: sloBudgetCriticalPayloadSchema,
|
|
124
|
+
hook: sloHooks.sloBudgetCritical,
|
|
125
|
+
contextKey: (p) => p.systemId,
|
|
121
126
|
},
|
|
122
127
|
pluginMetadata,
|
|
123
128
|
);
|
|
124
129
|
|
|
125
|
-
|
|
130
|
+
automationTriggers.registerTrigger(
|
|
126
131
|
{
|
|
127
|
-
|
|
132
|
+
id: "budget.exhausted",
|
|
128
133
|
displayName: "SLO Budget Exhausted",
|
|
129
134
|
description: "Fired when an SLO error budget is fully consumed",
|
|
130
135
|
category: "SLO",
|
|
131
136
|
payloadSchema: sloBudgetExhaustedPayloadSchema,
|
|
137
|
+
hook: sloHooks.sloBudgetExhausted,
|
|
138
|
+
contextKey: (p) => p.systemId,
|
|
132
139
|
},
|
|
133
140
|
pluginMetadata,
|
|
134
141
|
);
|
|
135
142
|
|
|
136
|
-
|
|
143
|
+
automationTriggers.registerTrigger(
|
|
137
144
|
{
|
|
138
|
-
|
|
145
|
+
id: "streak.broken",
|
|
139
146
|
displayName: "SLO Streak Broken",
|
|
140
147
|
description: "Fired when a reliability streak is broken",
|
|
141
148
|
category: "SLO",
|
|
142
149
|
payloadSchema: sloStreakBrokenPayloadSchema,
|
|
150
|
+
hook: sloHooks.sloStreakBroken,
|
|
151
|
+
contextKey: (p) => p.systemId,
|
|
143
152
|
},
|
|
144
153
|
pluginMetadata,
|
|
145
154
|
);
|
|
146
155
|
|
|
147
|
-
|
|
156
|
+
automationTriggers.registerTrigger(
|
|
148
157
|
{
|
|
149
|
-
|
|
158
|
+
id: "achievement.unlocked",
|
|
150
159
|
displayName: "SLO Achievement Unlocked",
|
|
151
160
|
description:
|
|
152
161
|
"Fired when a system unlocks a new reliability achievement",
|
|
153
162
|
category: "SLO",
|
|
154
163
|
payloadSchema: sloAchievementUnlockedPayloadSchema,
|
|
164
|
+
hook: sloHooks.sloAchievementUnlocked,
|
|
165
|
+
contextKey: (p) => p.systemId,
|
|
155
166
|
},
|
|
156
167
|
pluginMetadata,
|
|
157
168
|
);
|
|
158
169
|
|
|
159
|
-
|
|
170
|
+
automationTriggers.registerTrigger(
|
|
160
171
|
{
|
|
161
|
-
|
|
172
|
+
id: "weekly.digest",
|
|
162
173
|
displayName: "SLO Weekly Digest",
|
|
163
174
|
description:
|
|
164
175
|
"Weekly summary of SLO performance across all systems (Monday 09:00 UTC)",
|
|
165
176
|
category: "SLO",
|
|
166
177
|
payloadSchema: sloWeeklyDigestPayloadSchema,
|
|
178
|
+
hook: sloHooks.sloWeeklyDigest,
|
|
167
179
|
},
|
|
168
180
|
pluginMetadata,
|
|
169
181
|
);
|
package/tsconfig.json
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
"src"
|
|
5
5
|
],
|
|
6
6
|
"references": [
|
|
7
|
+
{
|
|
8
|
+
"path": "../automation-backend"
|
|
9
|
+
},
|
|
7
10
|
{
|
|
8
11
|
"path": "../backend-api"
|
|
9
12
|
},
|
|
@@ -43,12 +46,6 @@
|
|
|
43
46
|
{
|
|
44
47
|
"path": "../healthcheck-common"
|
|
45
48
|
},
|
|
46
|
-
{
|
|
47
|
-
"path": "../integration-backend"
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
"path": "../integration-common"
|
|
51
|
-
},
|
|
52
49
|
{
|
|
53
50
|
"path": "../queue-api"
|
|
54
51
|
},
|