@opengeni/api-router 0.30.3 → 2.2.0-canary.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.
Files changed (165) hide show
  1. package/dist/api-websocket.d.ts +18 -0
  2. package/dist/app.js +1 -1
  3. package/dist/auth/managed-auth.d.ts +6 -0
  4. package/dist/{chunk-WCXHI3FF.js → chunk-3TP54PPX.js} +26692 -15389
  5. package/dist/chunk-3TP54PPX.js.map +1 -0
  6. package/dist/codemode.d.ts +8 -1
  7. package/dist/company-brain-okf.d.ts +24 -0
  8. package/dist/connected-machine-computer-access.d.ts +11 -0
  9. package/dist/connection-authority-owner.d.ts +59 -0
  10. package/dist/connection-ownership.d.ts +47 -0
  11. package/dist/controller-data-plane.d.ts +16 -0
  12. package/dist/editable-artifact-websocket.d.ts +5 -15
  13. package/dist/editable-artifact-workspace-files.d.ts +1 -1
  14. package/dist/http/api-error.d.ts +10 -0
  15. package/dist/http/cors.d.ts +5 -0
  16. package/dist/http/interaction-control-error.d.ts +13 -0
  17. package/dist/http/sse.d.ts +2 -3
  18. package/dist/index.d.ts +5 -2
  19. package/dist/index.js +326 -82
  20. package/dist/index.js.map +1 -1
  21. package/dist/integrations/atlassian.d.ts +17 -0
  22. package/dist/integrations/fiken.d.ts +7 -2
  23. package/dist/integrations/google-drive.d.ts +18 -0
  24. package/dist/integrations/oauth-client.d.ts +22 -3
  25. package/dist/integrations/oauth-profiles.d.ts +195 -0
  26. package/dist/integrations/personal-github-repositories.d.ts +45 -0
  27. package/dist/integrations/personal-github.d.ts +40 -0
  28. package/dist/integrations/pr-review-provider.d.ts +22 -0
  29. package/dist/integrations/provider-oauth.d.ts +8 -0
  30. package/dist/integrations/slack-app-home.d.ts +24 -0
  31. package/dist/integrations/slack-bot.d.ts +157 -9
  32. package/dist/integrations/slack-interactions.d.ts +39 -5
  33. package/dist/integrations/slack-routing.d.ts +120 -0
  34. package/dist/integrations/social-oauth.d.ts +5 -0
  35. package/dist/interaction-frame-proxy.d.ts +68 -0
  36. package/dist/mcp/company-brain-governed-writes.d.ts +26 -0
  37. package/dist/mcp/company-profile-agent-admin.d.ts +44 -0
  38. package/dist/mcp/documents.d.ts +1 -0
  39. package/dist/mcp/remember.d.ts +28 -0
  40. package/dist/mcp/request-abort.d.ts +19 -0
  41. package/dist/mcp/scheduled-task-view.d.ts +4 -4
  42. package/dist/mcp/server.d.ts +15 -2
  43. package/dist/mcp/session-view.d.ts +4 -0
  44. package/dist/mcp/session-wait.d.ts +137 -0
  45. package/dist/routes/automations.d.ts +4 -0
  46. package/dist/routes/billing.d.ts +5 -0
  47. package/dist/routes/browser-sessions.d.ts +4 -1
  48. package/dist/routes/company-brain.d.ts +3 -0
  49. package/dist/routes/company-profile.d.ts +2 -1
  50. package/dist/routes/connection-authorities.d.ts +3 -0
  51. package/dist/routes/personal-github-git-broker.d.ts +29 -0
  52. package/dist/routes/personal-github.d.ts +3 -0
  53. package/dist/routes/pr-review.d.ts +3 -0
  54. package/dist/routes/sessions.d.ts +1 -0
  55. package/dist/routes/user-resource-authorities.d.ts +3 -0
  56. package/dist/routes/workspace-capture.d.ts +10 -2
  57. package/dist/routes/workspace-learning.d.ts +3 -0
  58. package/dist/routes/workspaces.d.ts +19 -0
  59. package/dist/sandbox/channel-a.d.ts +11 -1
  60. package/dist/sandbox/connection-authority.d.ts +3 -0
  61. package/dist/sandbox/enrollment.d.ts +2 -0
  62. package/dist/sandbox/machines.d.ts +2 -2
  63. package/dist/sandbox/metrics-ingestion.d.ts +10 -20
  64. package/dist/sandbox/viewer.d.ts +24 -1
  65. package/dist/sandbox-file-artifacts.d.ts +11 -0
  66. package/dist/scheduled-task-deletion.d.ts +14 -0
  67. package/dist/slack-reaction-files.d.ts +1 -1
  68. package/dist/temporal-schedule-cleanup.d.ts +1 -0
  69. package/package.json +20 -18
  70. package/src/api-websocket.ts +23 -0
  71. package/src/app.ts +161 -23
  72. package/src/auth/managed-auth.ts +25 -3
  73. package/src/codemode.ts +53 -23
  74. package/src/codex-realtime.ts +8 -2
  75. package/src/company-brain-okf.ts +340 -0
  76. package/src/connected-machine-computer-access.ts +33 -0
  77. package/src/connection-authority-owner.ts +61 -0
  78. package/src/connection-ownership.ts +180 -0
  79. package/src/controller-data-plane.ts +47 -0
  80. package/src/editable-artifact-native-kernel.ts +26 -15
  81. package/src/editable-artifact-office-import.ts +28 -3
  82. package/src/editable-artifact-production.ts +13 -7
  83. package/src/editable-artifact-websocket.ts +11 -18
  84. package/src/editable-artifact-workspace-files.ts +31 -6
  85. package/src/http/api-error.ts +28 -0
  86. package/src/http/auth.ts +4 -0
  87. package/src/http/cors.ts +35 -0
  88. package/src/http/interaction-control-error.ts +164 -0
  89. package/src/http/sse.ts +112 -66
  90. package/src/index.ts +46 -6
  91. package/src/integrations/atlassian.ts +146 -35
  92. package/src/integrations/fiken.ts +102 -22
  93. package/src/integrations/google-drive.ts +301 -92
  94. package/src/integrations/oauth-client.ts +272 -143
  95. package/src/integrations/oauth-profiles.ts +477 -0
  96. package/src/integrations/personal-github-repositories.ts +445 -0
  97. package/src/integrations/personal-github.ts +705 -0
  98. package/src/integrations/pr-review-provider.ts +246 -0
  99. package/src/integrations/provider-oauth.ts +121 -5
  100. package/src/integrations/slack-app-home.ts +300 -0
  101. package/src/integrations/slack-bot.ts +342 -57
  102. package/src/integrations/slack-interactions.ts +1898 -259
  103. package/src/integrations/slack-routing.ts +337 -0
  104. package/src/integrations/social-oauth.ts +25 -0
  105. package/src/interaction-frame-proxy.ts +409 -0
  106. package/src/mcp/company-brain-governed-writes.ts +262 -0
  107. package/src/mcp/company-profile-agent-admin.ts +205 -0
  108. package/src/mcp/documents.ts +37 -6
  109. package/src/mcp/files.ts +16 -1
  110. package/src/mcp/remember.ts +181 -0
  111. package/src/mcp/request-abort.ts +44 -0
  112. package/src/mcp/scheduled-task-view.ts +1 -0
  113. package/src/mcp/server.ts +719 -369
  114. package/src/mcp/session-view.ts +54 -0
  115. package/src/mcp/session-wait.ts +554 -0
  116. package/src/model-catalog.ts +20 -12
  117. package/src/routes/api-integrations.ts +4 -0
  118. package/src/routes/api-keys.ts +1 -0
  119. package/src/routes/automations.ts +534 -0
  120. package/src/routes/billing.ts +57 -1
  121. package/src/routes/browser-sessions.ts +329 -79
  122. package/src/routes/channels.ts +17 -1
  123. package/src/routes/codex.ts +50 -0
  124. package/src/routes/company-brain.ts +367 -0
  125. package/src/routes/company-profile.ts +1 -1
  126. package/src/routes/computer-sessions.ts +320 -93
  127. package/src/routes/connection-authorities.ts +139 -0
  128. package/src/routes/connections.ts +144 -34
  129. package/src/routes/documents.ts +353 -4
  130. package/src/routes/editable-artifacts.ts +11 -3
  131. package/src/routes/enrollments.ts +116 -26
  132. package/src/routes/environments.ts +127 -55
  133. package/src/routes/files.ts +72 -11
  134. package/src/routes/install.ts +82 -28
  135. package/src/routes/integration-facets.ts +29 -0
  136. package/src/routes/interaction-resources.ts +20 -2
  137. package/src/routes/machines.ts +275 -13
  138. package/src/routes/organization-memberships.ts +717 -28
  139. package/src/routes/packs.ts +4 -3
  140. package/src/routes/personal-github-git-broker.ts +785 -0
  141. package/src/routes/personal-github.ts +319 -0
  142. package/src/routes/pr-review.ts +531 -0
  143. package/src/routes/rigs.ts +104 -39
  144. package/src/routes/scheduled-tasks.ts +19 -21
  145. package/src/routes/sessions.ts +775 -38
  146. package/src/routes/social.ts +14 -2
  147. package/src/routes/supergrok.ts +23 -4
  148. package/src/routes/transcription-recordings.ts +8 -2
  149. package/src/routes/user-resource-authorities.ts +138 -0
  150. package/src/routes/workspace-artifacts.ts +4 -1
  151. package/src/routes/workspace-capture.ts +21 -0
  152. package/src/routes/workspace-learning.ts +228 -0
  153. package/src/routes/workspaces.ts +59 -6
  154. package/src/sandbox/auth-callout.ts +38 -12
  155. package/src/sandbox/channel-a.ts +242 -19
  156. package/src/sandbox/connection-authority.ts +3 -0
  157. package/src/sandbox/enrollment.ts +15 -3
  158. package/src/sandbox/machines.ts +186 -64
  159. package/src/sandbox/metrics-ingestion.ts +220 -58
  160. package/src/sandbox/viewer.ts +243 -19
  161. package/src/sandbox-file-artifacts.ts +329 -0
  162. package/src/scheduled-task-deletion.ts +127 -0
  163. package/src/slack-reaction-files.ts +16 -5
  164. package/src/temporal-schedule-cleanup.ts +13 -0
  165. package/dist/chunk-WCXHI3FF.js.map +0 -1
@@ -10,8 +10,13 @@ import {
10
10
  RigChangeTransitionError,
11
11
  } from "@opengeni/db";
12
12
  import type { Hono } from "hono";
13
+ import type { Context } from "hono";
13
14
  import { HTTPException } from "hono/http-exception";
14
- import { requireAccessGrant } from "@opengeni/core";
15
+ import {
16
+ requireAccessGrant,
17
+ requireAccessGrantAuthorization,
18
+ requirePermission,
19
+ } from "@opengeni/core";
15
20
  import type { ApiRouteDeps } from "@opengeni/core";
16
21
  import {
17
22
  activateRigVersionForApi,
@@ -31,6 +36,28 @@ import { boundedLimit } from "../http/common";
31
36
  export function registerRigRoutes(app: Hono, deps: ApiRouteDeps): void {
32
37
  const { db, workflowClient } = deps;
33
38
 
39
+ async function requireRigMutation(
40
+ c: Context,
41
+ workspaceId: string,
42
+ permission: "rigs:manage" | "rigs:use",
43
+ ) {
44
+ const authorization = await requireAccessGrantAuthorization(c, deps, workspaceId, permission);
45
+ const rigId = c.req.param("rigId");
46
+ if (!rigId) {
47
+ throw new HTTPException(400, { message: "rig id is required" });
48
+ }
49
+ const rig = await requireRigForApi(db, authorization.grant, rigId);
50
+ if (
51
+ rig.scope === "organization" &&
52
+ authorization.accountGrant?.permissions.includes("account:admin") !== true
53
+ ) {
54
+ throw new HTTPException(403, {
55
+ message: "missing permission: account:admin",
56
+ });
57
+ }
58
+ return { authorization, grant: authorization.grant, rig };
59
+ }
60
+
34
61
  async function startChangeVerification(
35
62
  workspaceId: string,
36
63
  changeId: string,
@@ -114,15 +141,27 @@ export function registerRigRoutes(app: Hono, deps: ApiRouteDeps): void {
114
141
 
115
142
  app.get("/v1/workspaces/:workspaceId/rigs", async (c) => {
116
143
  const workspaceId = c.req.param("workspaceId");
117
- await requireAccessGrant(c, deps, workspaceId, "rigs:use");
118
- return c.json(await listRigs(db, workspaceId));
144
+ const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:use");
145
+ return c.json(await listRigs(db, grant));
119
146
  });
120
147
 
121
148
  app.post("/v1/workspaces/:workspaceId/rigs", async (c) => {
122
149
  const workspaceId = c.req.param("workspaceId");
123
- const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:manage");
150
+ const authorization = await requireAccessGrantAuthorization(c, deps, workspaceId);
151
+ const grant = authorization.grant;
152
+ requirePermission(grant, "rigs:manage");
124
153
  const payload = CreateRigRequest.parse(await c.req.json());
125
- const rig = await createRigForApi({ db }, grant, payload);
154
+ const allowOrganization =
155
+ payload.scope === "organization" &&
156
+ authorization.accountGrant?.permissions.includes("account:admin") === true;
157
+ if (payload.scope === "organization" && !allowOrganization) {
158
+ throw new HTTPException(403, {
159
+ message: "missing permission: account:admin",
160
+ });
161
+ }
162
+ const rig = await createRigForApi({ db }, grant, payload, {
163
+ allowOrganization,
164
+ });
126
165
  if (rig.activeVersion) {
127
166
  const started = await tryStartInitialVersionVerification(workspaceId, rig.activeVersion.id);
128
167
  if (!started) c.header("OpenGeni-Rig-Verification", "deferred");
@@ -132,40 +171,59 @@ export function registerRigRoutes(app: Hono, deps: ApiRouteDeps): void {
132
171
 
133
172
  app.get("/v1/workspaces/:workspaceId/rigs/:rigId", async (c) => {
134
173
  const workspaceId = c.req.param("workspaceId");
135
- await requireAccessGrant(c, deps, workspaceId, "rigs:use");
136
- return c.json(await requireRigForApi(db, workspaceId, c.req.param("rigId")));
174
+ const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:use");
175
+ return c.json(await requireRigForApi(db, grant, c.req.param("rigId")));
137
176
  });
138
177
 
139
178
  app.patch("/v1/workspaces/:workspaceId/rigs/:rigId", async (c) => {
140
179
  const workspaceId = c.req.param("workspaceId");
141
- const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:manage");
142
- const rig = await requireRigForApi(db, workspaceId, c.req.param("rigId"));
180
+ const authorization = await requireAccessGrantAuthorization(c, deps, workspaceId);
181
+ const grant = authorization.grant;
182
+ requirePermission(grant, "rigs:manage");
183
+ const rig = await requireRigForApi(db, grant, c.req.param("rigId"));
184
+ const allowOrganization =
185
+ rig.scope === "organization" &&
186
+ authorization.accountGrant?.permissions.includes("account:admin") === true;
187
+ if (rig.scope === "organization" && !allowOrganization) {
188
+ throw new HTTPException(403, {
189
+ message: "missing permission: account:admin",
190
+ });
191
+ }
143
192
  const payload = UpdateRigRequest.parse(await c.req.json());
144
- return c.json(await updateRigForApi({ db }, grant, rig, payload));
193
+ return c.json(await updateRigForApi({ db }, grant, rig, payload, { allowOrganization }));
145
194
  });
146
195
 
147
196
  app.delete("/v1/workspaces/:workspaceId/rigs/:rigId", async (c) => {
148
197
  const workspaceId = c.req.param("workspaceId");
149
- const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:manage");
150
- const rig = await requireRigForApi(db, workspaceId, c.req.param("rigId"));
151
- await deleteRigForApi({ db }, grant, rig);
198
+ const authorization = await requireAccessGrantAuthorization(c, deps, workspaceId);
199
+ const grant = authorization.grant;
200
+ requirePermission(grant, "rigs:manage");
201
+ const rig = await requireRigForApi(db, grant, c.req.param("rigId"));
202
+ const allowOrganization =
203
+ rig.scope === "organization" &&
204
+ authorization.accountGrant?.permissions.includes("account:admin") === true;
205
+ if (rig.scope === "organization" && !allowOrganization) {
206
+ throw new HTTPException(403, {
207
+ message: "missing permission: account:admin",
208
+ });
209
+ }
210
+ await deleteRigForApi({ db }, grant, rig, { allowOrganization });
152
211
  return c.json({ ok: true });
153
212
  });
154
213
 
155
214
  app.get("/v1/workspaces/:workspaceId/rigs/:rigId/versions", async (c) => {
156
215
  const workspaceId = c.req.param("workspaceId");
157
- await requireAccessGrant(c, deps, workspaceId, "rigs:use");
158
- const rig = await requireRigForApi(db, workspaceId, c.req.param("rigId"));
159
- return c.json(await listRigVersionsForApi({ db }, workspaceId, rig.id));
216
+ const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:use");
217
+ const rig = await requireRigForApi(db, grant, c.req.param("rigId"));
218
+ return c.json(await listRigVersionsForApi({ db }, rig.workspaceId, rig.id));
160
219
  });
161
220
 
162
221
  app.post("/v1/workspaces/:workspaceId/rigs/:rigId/versions", async (c) => {
163
222
  const workspaceId = c.req.param("workspaceId");
164
- const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:manage");
165
- const rig = await requireRigForApi(db, workspaceId, c.req.param("rigId"));
223
+ const { grant, rig } = await requireRigMutation(c, workspaceId, "rigs:manage");
166
224
  const payload = RigDefinitionEditPayload.parse(await c.req.json());
167
225
  const version = await createRigVersionForApi({ db }, grant, rig, payload);
168
- const started = await tryStartInitialVersionVerification(workspaceId, version.id);
226
+ const started = await tryStartInitialVersionVerification(rig.workspaceId, version.id);
169
227
  if (!started) c.header("OpenGeni-Rig-Verification", "deferred");
170
228
  return c.json(version, 201);
171
229
  });
@@ -173,18 +231,22 @@ export function registerRigRoutes(app: Hono, deps: ApiRouteDeps): void {
173
231
  // Rollback / promote-activate: flips which existing version is active.
174
232
  app.post("/v1/workspaces/:workspaceId/rigs/:rigId/versions/:versionId/activate", async (c) => {
175
233
  const workspaceId = c.req.param("workspaceId");
176
- const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:manage");
177
- const rig = await requireRigForApi(db, workspaceId, c.req.param("rigId"));
234
+ const { grant, rig } = await requireRigMutation(c, workspaceId, "rigs:manage");
178
235
  const version = await activateRigVersionForApi({ db }, grant, rig, c.req.param("versionId"));
179
236
  return c.json(version);
180
237
  });
181
238
 
182
239
  app.get("/v1/workspaces/:workspaceId/rigs/:rigId/changes", async (c) => {
183
240
  const workspaceId = c.req.param("workspaceId");
184
- await requireAccessGrant(c, deps, workspaceId, "rigs:use");
185
- const rig = await requireRigForApi(db, workspaceId, c.req.param("rigId"));
241
+ const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:use");
242
+ const rig = await requireRigForApi(db, grant, c.req.param("rigId"));
186
243
  return c.json(
187
- await listRigChangesForApi({ db }, workspaceId, rig.id, boundedLimit(c.req.query("limit"))),
244
+ await listRigChangesForApi(
245
+ { db },
246
+ rig.workspaceId,
247
+ rig.id,
248
+ boundedLimit(c.req.query("limit")),
249
+ ),
188
250
  );
189
251
  });
190
252
 
@@ -193,54 +255,57 @@ export function registerRigRoutes(app: Hono, deps: ApiRouteDeps): void {
193
255
  // promote gate (definition_edit) land in M4.
194
256
  app.post("/v1/workspaces/:workspaceId/rigs/:rigId/changes", async (c) => {
195
257
  const workspaceId = c.req.param("workspaceId");
196
- const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:use");
197
- const rig = await requireRigForApi(db, workspaceId, c.req.param("rigId"));
258
+ const { grant, rig } = await requireRigMutation(c, workspaceId, "rigs:use");
198
259
  const request = ProposeRigChangeRequest.parse(await c.req.json());
199
260
  const change = await proposeRigChangeForApi({ db }, grant, rig, request);
200
- const verification = await startChangeVerification(workspaceId, change.id);
261
+ const verification = await startChangeVerification(rig.workspaceId, change.id);
201
262
  if (!verification.started) c.header("OpenGeni-Rig-Verification", "deferred");
202
263
  return c.json(verification.change, 201);
203
264
  });
204
265
 
205
266
  app.get("/v1/workspaces/:workspaceId/rigs/:rigId/changes/:changeId", async (c) => {
206
267
  const workspaceId = c.req.param("workspaceId");
207
- await requireAccessGrant(c, deps, workspaceId, "rigs:use");
268
+ const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:use");
269
+ const rig = await requireRigForApi(db, grant, c.req.param("rigId"));
208
270
  return c.json(
209
- await requireRigChangeForApi(db, workspaceId, c.req.param("rigId"), c.req.param("changeId")),
271
+ await requireRigChangeForApi(db, rig.workspaceId, rig.id, c.req.param("changeId")),
210
272
  );
211
273
  });
212
274
 
213
275
  app.post("/v1/workspaces/:workspaceId/rigs/:rigId/changes/:changeId/verify", async (c) => {
214
276
  const workspaceId = c.req.param("workspaceId");
215
- await requireAccessGrant(c, deps, workspaceId, "rigs:use");
277
+ const { rig } = await requireRigMutation(c, workspaceId, "rigs:use");
216
278
  const change = await requireRigChangeForApi(
217
279
  db,
218
- workspaceId,
219
- c.req.param("rigId"),
280
+ rig.workspaceId,
281
+ rig.id,
220
282
  c.req.param("changeId"),
221
283
  );
222
- const verification = await startChangeVerification(workspaceId, change.id);
284
+ const verification = await startChangeVerification(rig.workspaceId, change.id);
223
285
  if (!verification.started) c.header("OpenGeni-Rig-Verification", "deferred");
224
286
  return c.json(verification.change, 202);
225
287
  });
226
288
 
227
289
  app.post("/v1/workspaces/:workspaceId/rigs/:rigId/changes/:changeId/promote", async (c) => {
228
290
  const workspaceId = c.req.param("workspaceId");
229
- const grant = await requireAccessGrant(c, deps, workspaceId, "rigs:manage");
230
- const rig = await requireRigForApi(db, workspaceId, c.req.param("rigId"));
231
- const change = await requireRigChangeForApi(db, workspaceId, rig.id, c.req.param("changeId"));
291
+ const { grant, rig } = await requireRigMutation(c, workspaceId, "rigs:manage");
292
+ const change = await requireRigChangeForApi(
293
+ db,
294
+ rig.workspaceId,
295
+ rig.id,
296
+ c.req.param("changeId"),
297
+ );
232
298
  const promoted = await promoteVerifiedDefinitionEditChangeForApi({ db }, grant, rig, change);
233
299
  return c.json(promoted.version, 201);
234
300
  });
235
301
 
236
302
  app.post("/v1/workspaces/:workspaceId/rigs/:rigId/verify", async (c) => {
237
303
  const workspaceId = c.req.param("workspaceId");
238
- await requireAccessGrant(c, deps, workspaceId, "rigs:use");
239
- const rig = await requireRigForApi(db, workspaceId, c.req.param("rigId"));
304
+ const { rig } = await requireRigMutation(c, workspaceId, "rigs:use");
240
305
  if (!rig.activeVersion) {
241
306
  return c.json({ error: "rig has no active version" }, 422);
242
307
  }
243
- await startVersionVerification(workspaceId, rig.activeVersion.id);
308
+ await startVersionVerification(rig.workspaceId, rig.activeVersion.id);
244
309
  return c.json({ ok: true, versionId: rig.activeVersion.id }, 202);
245
310
  });
246
311
  }
@@ -3,12 +3,7 @@ import {
3
3
  TriggerScheduledTaskRequest,
4
4
  UpdateScheduledTaskRequest,
5
5
  } from "@opengeni/contracts";
6
- import {
7
- deleteScheduledTask,
8
- listScheduledTaskRuns,
9
- listScheduledTasks,
10
- updateScheduledTask,
11
- } from "@opengeni/db";
6
+ import { listScheduledTaskRuns, listScheduledTasks } from "@opengeni/db";
12
7
  import type { Hono } from "hono";
13
8
  import { HTTPException } from "hono/http-exception";
14
9
  import { requireAccessGrant } from "@opengeni/core";
@@ -26,12 +21,12 @@ import {
26
21
  requireScheduledTaskForApi,
27
22
  syncCreatedScheduledTask,
28
23
  syncUpdatedScheduledTask,
24
+ updateScheduledTaskForApi,
29
25
  validateScheduledTaskTarget,
30
26
  validatedScheduledTaskUpdate,
31
27
  } from "@opengeni/core";
32
28
  import { boundedLimit } from "../http/common";
33
- import { revokeKnowledgeSourceScheduleAuthorization } from "../integrations/google-drive";
34
- import { revokeAtlassianScheduleAuthorization } from "../integrations/atlassian";
29
+ import { deleteScheduledTaskWithDurableCleanup } from "../scheduled-task-deletion";
35
30
 
36
31
  export function registerScheduledTaskRoutes(app: Hono, deps: ApiRouteDeps): void {
37
32
  const { settings, db, workflowClient, objectStorage } = deps;
@@ -106,7 +101,7 @@ export function registerScheduledTaskRoutes(app: Hono, deps: ApiRouteDeps): void
106
101
  sessionAuthorization: deps.sessionAuthorization,
107
102
  authorizationSurface: "http",
108
103
  });
109
- const task = await updateScheduledTask(db, workspaceId, taskId, update);
104
+ const task = await updateScheduledTaskForApi(db, workspaceId, taskId, update);
110
105
  await syncUpdatedScheduledTask({ db, workflowClient, previous, task });
111
106
  return c.json(scheduledTaskForGrant(task, grant));
112
107
  });
@@ -116,7 +111,7 @@ export function registerScheduledTaskRoutes(app: Hono, deps: ApiRouteDeps): void
116
111
  const grant = await requireAccessGrant(c, deps, workspaceId, "scheduled_tasks:manage");
117
112
  const existing = await requireScheduledTaskForApi(db, workspaceId, c.req.param("taskId"));
118
113
  const previous = await captureScheduledTaskRestoreState(db, existing);
119
- const task = await updateScheduledTask(db, workspaceId, existing.id, {
114
+ const task = await updateScheduledTaskForApi(db, workspaceId, existing.id, {
120
115
  status: "paused",
121
116
  });
122
117
  await syncUpdatedScheduledTask({ db, workflowClient, previous, task });
@@ -128,9 +123,17 @@ export function registerScheduledTaskRoutes(app: Hono, deps: ApiRouteDeps): void
128
123
  const grant = await requireAccessGrant(c, deps, workspaceId, "scheduled_tasks:manage");
129
124
  const existing = await requireScheduledTaskForApi(db, workspaceId, c.req.param("taskId"));
130
125
  const previous = await captureScheduledTaskRestoreState(db, existing);
131
- const task = await updateScheduledTask(db, workspaceId, existing.id, {
132
- status: "active",
126
+ const update = await validatedScheduledTaskUpdate({
127
+ settings,
128
+ db,
129
+ objectStorage,
130
+ grant,
131
+ existing,
132
+ payload: { status: "active" },
133
+ sessionAuthorization: deps.sessionAuthorization,
134
+ authorizationSurface: "http",
133
135
  });
136
+ const task = await updateScheduledTaskForApi(db, workspaceId, existing.id, update);
134
137
  await syncUpdatedScheduledTask({ db, workflowClient, previous, task });
135
138
  return c.json(scheduledTaskForGrant(task, grant));
136
139
  });
@@ -197,16 +200,11 @@ export function registerScheduledTaskRoutes(app: Hono, deps: ApiRouteDeps): void
197
200
  app.delete("/v1/workspaces/:workspaceId/scheduled-tasks/:taskId", async (c) => {
198
201
  const workspaceId = c.req.param("workspaceId");
199
202
  const grant = await requireAccessGrant(c, deps, workspaceId, "scheduled_tasks:manage");
200
- const task = await requireScheduledTaskForApi(db, workspaceId, c.req.param("taskId"));
201
- if (task.metadata.connectorKind === "atlassian") {
202
- await revokeAtlassianScheduleAuthorization(deps, { task, subjectId: grant.subjectId });
203
- } else {
204
- await revokeKnowledgeSourceScheduleAuthorization(deps, { task, subjectId: grant.subjectId });
205
- }
206
- await workflowClient.deleteScheduledTaskSchedule({
207
- temporalScheduleId: task.temporalScheduleId,
203
+ await deleteScheduledTaskWithDurableCleanup(deps, {
204
+ workspaceId,
205
+ taskId: c.req.param("taskId"),
206
+ subjectId: grant.subjectId,
208
207
  });
209
- await deleteScheduledTask(db, workspaceId, task.id);
210
208
  return c.json({ ok: true });
211
209
  });
212
210