@checkstack/integration-backend 0.1.30 → 0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,89 @@
1
1
  # @checkstack/integration-backend
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 41c77f4: feat(automation): one-time migration of webhook subscriptions + remove legacy integration backend
8
+
9
+ **BREAKING CHANGES** (platform is in BETA — no major bump):
10
+
11
+ - `IntegrationProvider` no longer carries `config` (subscription
12
+ config) or `deliver`. The interface now models a connection provider
13
+ only: connection schema + `getConnectionOptions` + `testConnection`.
14
+ - The legacy subscription / delivery-log / event endpoints
15
+ (`listSubscriptions`, `createSubscription`, `getDeliveryLogs`,
16
+ `listEventTypes`, …) are removed from `integrationContract`.
17
+ - `delivery-coordinator`, `hook-subscriber`, `event-registry`, and the
18
+ `integrationEventExtensionPoint` are deleted. Plugins that
19
+ previously called `integrationEvents.registerEvent(...)` now
20
+ register their hooks as automation triggers via
21
+ `automationTriggerExtensionPoint.registerTrigger(...)`.
22
+ - Frontend pages `IntegrationsPage` and `DeliveryLogsPage` are gone;
23
+ the integration plugin's only remaining UI is connection
24
+ management. Subscription management lives under `/automation/...`.
25
+ - `webhook_subscriptions` and `delivery_logs` tables stay in the
26
+ database for one release as a safety net (no code reads or writes
27
+ them), and will be dropped in a follow-up migration.
28
+
29
+ **New**:
30
+
31
+ - `jira.create_issue`, `teams.post_message`, `webex.post_message`,
32
+ `webhook.send`, `integration-script.run_shell`, and
33
+ `integration-script.run_script` actions registered against the
34
+ Automation Platform with matching `*.message`, `*.delivery`,
35
+ `shell.result`, and `script.result` artifact types. The script
36
+ plugin exposes **two** actions — `run_shell` runs bash via the
37
+ shared `ShellScriptRunner` (Monaco `shell` editor), `run_script`
38
+ runs an ESM module in a Bun subprocess via `EsmScriptRunner`
39
+ (Monaco `typescript` editor + `defineIntegration` helper) — to
40
+ preserve the legacy provider split. `jira.create_issue` keeps the
41
+ dynamic field-mapping dropdown (driven by
42
+ `JIRA_RESOLVERS.FIELD_OPTIONS`).
43
+ - One-time data migration runs on boot in
44
+ `automation-backend.afterPluginsReady`. It reads
45
+ `webhook_subscriptions` via a new service RPC
46
+ `IntegrationApi.listLegacySubscriptions`, translates each row into
47
+ a single-trigger / single-action automation (marked with
48
+ `managed_by = "migrated-subscription:<id>"`), and is idempotent
49
+ across restarts.
50
+ - Failed translations are recorded in a new
51
+ `automation_migration_failures` table and surfaced via
52
+ `AutomationApi.listMigrationFailures` /
53
+ `acknowledgeMigrationFailure` so admins can review and re-create
54
+ failed entries by hand.
55
+
56
+ ### Patch Changes
57
+
58
+ - 41c77f4: feat(jira): register Jira automation actions + `jira.issue` artifact type
59
+
60
+ Adds three Jira actions to the Automation platform:
61
+
62
+ - `jira.create_issue` — produces the new `jira.issue` artifact type
63
+ (`issueKey`, `projectKey`, `issueUrl`, `id`, `status?`)
64
+ - `jira.transition_issue` — consumes `jira.issue` (or accepts an
65
+ explicit `issueKey`), idempotent against already-applied transitions
66
+ - `jira.add_comment` — consumes `jira.issue` (or accepts an explicit
67
+ `issueKey`)
68
+
69
+ Extends the Jira client with `getTransitions`, `getIssueStatus`,
70
+ `transitionIssue` (handles 204 No Content, comment in ADF for Cloud /
71
+ plain text for Data Center), and `addComment`. Adds a new
72
+ `JIRA_RESOLVERS.TRANSITION_OPTIONS` cascading dropdown driven by
73
+ `connectionId` + `issueKey`. `@checkstack/integration-backend` now
74
+ re-exports the `ConnectionStore` interface so action plugins can take
75
+ it as a typed dep.
76
+
77
+ - Updated dependencies [41c77f4]
78
+ - Updated dependencies [6d52276]
79
+ - Updated dependencies [35bc682]
80
+ - @checkstack/integration-common@0.6.0
81
+ - @checkstack/common@0.12.0
82
+ - @checkstack/backend-api@0.18.0
83
+ - @checkstack/command-backend@0.1.31
84
+ - @checkstack/signal-common@0.2.5
85
+ - @checkstack/queue-api@0.3.6
86
+
3
87
  ## 0.1.30
4
88
 
5
89
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/integration-backend",
3
- "version": "0.1.30",
3
+ "version": "0.2.0",
4
4
  "license": "Elastic-2.0",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -16,11 +16,11 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@checkstack/integration-common": "0.5.0",
19
- "@checkstack/backend-api": "0.17.0",
19
+ "@checkstack/backend-api": "0.17.1",
20
20
  "@checkstack/signal-common": "0.2.4",
21
- "@checkstack/queue-api": "0.3.4",
21
+ "@checkstack/queue-api": "0.3.5",
22
22
  "@checkstack/common": "0.11.0",
23
- "@checkstack/command-backend": "0.1.29",
23
+ "@checkstack/command-backend": "0.1.30",
24
24
  "drizzle-orm": "^0.45.0",
25
25
  "zod": "^4.2.1",
26
26
  "@orpc/server": "^1.13.2"
@@ -29,7 +29,7 @@
29
29
  "@checkstack/drizzle-helper": "0.0.5",
30
30
  "@checkstack/scripts": "0.3.3",
31
31
  "@checkstack/tsconfig": "0.0.7",
32
- "@checkstack/test-utils-backend": "0.1.29",
32
+ "@checkstack/test-utils-backend": "0.1.30",
33
33
  "@types/node": "^20.0.0",
34
34
  "drizzle-kit": "^0.31.10",
35
35
  "typescript": "^5.0.0"
package/src/index.ts CHANGED
@@ -13,26 +13,14 @@ import {
13
13
  } from "@checkstack/integration-common";
14
14
  import { resolveRoute } from "@checkstack/common";
15
15
  import type { PluginMetadata } from "@checkstack/common";
16
- import type {
17
- IntegrationEventDefinition,
18
- IntegrationProvider,
19
- } from "./provider-types";
16
+ import type { IntegrationProvider } from "./provider-types";
20
17
 
21
18
  import * as schema from "./schema";
22
- import {
23
- createIntegrationEventRegistry,
24
- type IntegrationEventRegistry,
25
- } from "./event-registry";
26
- import {
27
- createIntegrationProviderRegistry,
28
- type IntegrationProviderRegistry,
29
- } from "./provider-registry";
30
- import { createDeliveryCoordinator } from "./delivery-coordinator";
19
+ import { createIntegrationProviderRegistry } from "./provider-registry";
31
20
  import {
32
21
  createConnectionStore,
33
22
  type ConnectionStore,
34
23
  } from "./connection-store";
35
- import { subscribeToRegisteredEvents } from "./hook-subscriber";
36
24
  import { createIntegrationRouter } from "./router";
37
25
  import { registerSearchProvider } from "@checkstack/command-backend";
38
26
 
@@ -41,11 +29,11 @@ import { registerSearchProvider } from "@checkstack/command-backend";
41
29
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
42
30
 
43
31
  /**
44
- * Service reference for the connection store.
45
- * Provider plugins can inject this to access connection credentials.
32
+ * Service reference for the connection store. Provider plugins inject
33
+ * this to look up credentials when an automation action runs.
46
34
  */
47
35
  export const connectionStoreRef = createServiceRef<ConnectionStore>(
48
- "integration.connectionStore"
36
+ "integration.connectionStore",
49
37
  );
50
38
 
51
39
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -53,45 +41,21 @@ export const connectionStoreRef = createServiceRef<ConnectionStore>(
53
41
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
54
42
 
55
43
  /**
56
- * Extension point for registering integration events.
57
- * Plugins use this to expose their hooks for external webhook subscriptions.
58
- */
59
- export interface IntegrationEventExtensionPoint {
60
- /**
61
- * Register a hook as an integration event.
62
- * The event will be namespaced by the plugin's ID automatically.
63
- */
64
- registerEvent<T>(
65
- definition: IntegrationEventDefinition<T>,
66
- pluginMetadata: PluginMetadata
67
- ): void;
68
- }
69
-
70
- export const integrationEventExtensionPoint =
71
- createExtensionPoint<IntegrationEventExtensionPoint>(
72
- "integration.eventExtensionPoint"
73
- );
74
-
75
- /**
76
- * Extension point for registering integration providers.
77
- * Plugins use this to register webhook delivery providers.
44
+ * Extension point for registering integration providers. After the
45
+ * migration to the Automation Platform a provider is just the
46
+ * connection metadata + dropdown resolvers + a test endpoint — the
47
+ * per-event delivery work moved onto automation actions.
78
48
  */
79
49
  export interface IntegrationProviderExtensionPoint {
80
- /**
81
- * Register an integration provider.
82
- * The provider will be namespaced by the plugin's ID automatically.
83
- * @template TConfig - Per-subscription configuration type
84
- * @template TConnection - Site-wide connection configuration type (optional)
85
- */
86
- addProvider<TConfig, TConnection = undefined>(
87
- provider: IntegrationProvider<TConfig, TConnection>,
88
- pluginMetadata: PluginMetadata
50
+ addProvider<TConnection = undefined>(
51
+ provider: IntegrationProvider<TConnection>,
52
+ pluginMetadata: PluginMetadata,
89
53
  ): void;
90
54
  }
91
55
 
92
56
  export const integrationProviderExtensionPoint =
93
57
  createExtensionPoint<IntegrationProviderExtensionPoint>(
94
- "integration.providerExtensionPoint"
58
+ "integration.providerExtensionPoint",
95
59
  );
96
60
 
97
61
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -102,34 +66,15 @@ export default createBackendPlugin({
102
66
  metadata: pluginMetadata,
103
67
 
104
68
  register(env) {
105
- // Create the registries
106
- const eventRegistry = createIntegrationEventRegistry();
107
69
  const providerRegistry = createIntegrationProviderRegistry();
108
70
 
109
- // Register static access rules
110
71
  env.registerAccessRules(integrationAccessRules);
111
72
 
112
- // Register the event extension point
113
- env.registerExtensionPoint(integrationEventExtensionPoint, {
114
- registerEvent: <T>(
115
- definition: IntegrationEventDefinition<T>,
116
- metadata: PluginMetadata
117
- ) => {
118
- // Type erasure: cast to unknown for storage (the registry handles this internally)
119
- eventRegistry.register(
120
- definition as IntegrationEventDefinition<unknown>,
121
- metadata
122
- );
123
- },
124
- });
125
-
126
- // Register the provider extension point
127
73
  env.registerExtensionPoint(integrationProviderExtensionPoint, {
128
74
  addProvider: (provider, metadata) => {
129
- // Type erasure: cast to unknown for storage (the registry handles this internally)
130
75
  providerRegistry.register(
131
76
  provider as IntegrationProvider<unknown>,
132
- metadata
77
+ metadata,
133
78
  );
134
79
  },
135
80
  });
@@ -140,167 +85,59 @@ export default createBackendPlugin({
140
85
  logger: coreServices.logger,
141
86
  rpc: coreServices.rpc,
142
87
  config: coreServices.config,
143
- signalService: coreServices.signalService,
144
- queueManager: coreServices.queueManager,
145
88
  },
146
- init: async ({
147
- logger,
148
- database,
149
- rpc,
150
- config,
151
- signalService,
152
- queueManager,
153
- }) => {
89
+ init: async ({ logger, rpc, config, database }) => {
154
90
  logger.debug("🔌 Initializing Integration Backend...");
155
91
 
156
- const db = database;
157
-
158
- // Create connection store for generic connection management
159
92
  const connectionStore = createConnectionStore({
160
93
  configService: config,
161
94
  providerRegistry,
162
95
  logger,
163
96
  });
164
-
165
- // Publish connection store for provider plugins to inject
166
97
  env.registerService(connectionStoreRef, connectionStore);
167
98
 
168
- // Create delivery coordinator
169
- const deliveryCoordinator = createDeliveryCoordinator({
170
- db,
171
- providerRegistry,
172
- connectionStore,
173
- queueManager,
174
- signalService,
175
- logger,
176
- });
177
-
178
- // Store for afterPluginsReady access
179
- (
180
- env as unknown as {
181
- eventRegistry: IntegrationEventRegistry;
182
- providerRegistry: IntegrationProviderRegistry;
183
- deliveryCoordinator: typeof deliveryCoordinator;
184
- }
185
- ).eventRegistry = eventRegistry;
186
- (
187
- env as unknown as {
188
- eventRegistry: IntegrationEventRegistry;
189
- providerRegistry: IntegrationProviderRegistry;
190
- deliveryCoordinator: typeof deliveryCoordinator;
191
- }
192
- ).providerRegistry = providerRegistry;
193
- (
194
- env as unknown as {
195
- eventRegistry: IntegrationEventRegistry;
196
- providerRegistry: IntegrationProviderRegistry;
197
- deliveryCoordinator: typeof deliveryCoordinator;
198
- }
199
- ).deliveryCoordinator = deliveryCoordinator;
200
-
201
- // Create and register the router
202
99
  const router = createIntegrationRouter({
203
- db,
204
- eventRegistry,
100
+ db: database,
205
101
  providerRegistry,
206
- deliveryCoordinator,
207
102
  connectionStore,
208
- signalService,
209
103
  logger,
210
104
  });
211
105
  rpc.registerRouter(router, integrationContract);
212
106
 
213
- // Register command palette commands
214
107
  registerSearchProvider({
215
108
  pluginMetadata,
216
109
  commands: [
217
110
  {
218
- id: "create",
219
- title: "Create Integration Subscription",
220
- subtitle: "Create a new subscription for integration events",
221
- iconName: "Webhook",
222
- route:
223
- resolveRoute(integrationRoutes.routes.list) + "?action=create",
224
- requiredAccessRules: [integrationAccess.manage],
225
- },
226
- {
227
- id: "manage",
228
- title: "Manage Integrations",
229
- subtitle: "Manage integration subscriptions and connections",
111
+ id: "connections",
112
+ title: "Manage Integration Connections",
113
+ subtitle: "Configure credentials for Jira, Teams, Webex, etc.",
230
114
  iconName: "Webhook",
231
115
  shortcuts: ["meta+shift+g", "ctrl+shift+g"],
232
116
  route: resolveRoute(integrationRoutes.routes.list),
233
117
  requiredAccessRules: [integrationAccess.manage],
234
118
  },
235
- {
236
- id: "logs",
237
- title: "View Integration Logs",
238
- subtitle: "View integration delivery logs",
239
- iconName: "FileText",
240
- route: resolveRoute(integrationRoutes.routes.logs),
241
- requiredAccessRules: [integrationAccess.manage],
242
- },
243
119
  ],
244
120
  });
245
121
 
246
- logger.debug("✅ Integration Backend initialized.");
247
- },
248
- afterPluginsReady: async ({ logger, onHook }) => {
249
- // Get registries from env
250
- const stored = env as unknown as {
251
- eventRegistry: IntegrationEventRegistry;
252
- providerRegistry: IntegrationProviderRegistry;
253
- deliveryCoordinator: ReturnType<typeof createDeliveryCoordinator>;
254
- };
255
-
256
- const events = stored.eventRegistry.getEvents();
257
- const providers = stored.providerRegistry.getProviders();
258
-
259
122
  logger.debug(
260
- `🔌 Registered ${events.length} integration events: ${events
261
- .map((e) => e.eventId)
262
- .join(", ")}`
123
+ `📡 Integration Backend init complete with ${providerRegistry.getProviders().length} providers`,
263
124
  );
264
-
265
- logger.debug(
266
- `📡 Registered ${providers.length} integration providers: ${providers
267
- .map((p) => p.qualifiedId)
268
- .join(", ")}`
269
- );
270
-
271
- // Subscribe to all registered integration events
272
- // Uses work-queue mode to ensure only ONE instance processes each event
273
- subscribeToRegisteredEvents({
274
- onHook,
275
- eventRegistry: stored.eventRegistry,
276
- deliveryCoordinator: stored.deliveryCoordinator,
277
- logger,
278
- });
279
-
280
- // Start the delivery worker
281
- await stored.deliveryCoordinator.startWorker();
282
-
283
- logger.debug("✅ Integration Backend afterPluginsReady complete.");
284
125
  },
285
126
  });
286
127
  },
287
128
  });
288
129
 
289
- // Re-export extension points for consumer plugins
290
- export { integrationEventExtensionPoint as eventExtensionPoint };
130
+ // ─── Re-exports ─────────────────────────────────────────────────────────
131
+
291
132
  export { integrationProviderExtensionPoint as providerExtensionPoint };
292
133
 
293
- // Re-export provider types for consumer plugins
294
- // All backend-only types are defined here (not in integration-common)
295
134
  export type {
296
- IntegrationEventDefinition,
297
- IntegrationDeliveryContext,
298
- IntegrationDeliveryResult,
299
135
  TestConnectionResult,
300
136
  ProviderDocumentation,
301
137
  ConnectionOption,
302
138
  GetConnectionOptionsParams,
303
139
  IntegrationProvider,
304
140
  RegisteredIntegrationProvider,
305
- RegisteredIntegrationEvent,
306
141
  } from "./provider-types";
142
+
143
+ export type { ConnectionStore } from "./connection-store";