@opengeni/db 0.31.1 → 0.36.1

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 (125) hide show
  1. package/dist/browser-auth.d.ts +209 -1
  2. package/dist/browser-downloads.d.ts +51 -0
  3. package/dist/browser-identities.d.ts +11 -2
  4. package/dist/browser-sessions.d.ts +83 -1
  5. package/dist/browser-state-artifacts.d.ts +75 -1
  6. package/dist/canonical-human-identities.d.ts +48 -0
  7. package/dist/canonical-human-identities.js +28 -0
  8. package/dist/canonical-human-identities.js.map +1 -0
  9. package/dist/capability-integrations.d.ts +8 -6
  10. package/dist/{chunk-MWDVXQOL.js → chunk-5KTIEDX7.js} +5773 -4212
  11. package/dist/chunk-5KTIEDX7.js.map +1 -0
  12. package/dist/chunk-FPVAD4CO.js +117 -0
  13. package/dist/chunk-FPVAD4CO.js.map +1 -0
  14. package/dist/chunk-GYO7ED2Q.js +259 -0
  15. package/dist/chunk-GYO7ED2Q.js.map +1 -0
  16. package/dist/{chunk-F5FT7BEZ.js → chunk-HSOWSYOX.js} +2 -2
  17. package/dist/{chunk-YHZXQ7HP.js → chunk-VKLB2ZGI.js} +446 -19
  18. package/dist/chunk-VKLB2ZGI.js.map +1 -0
  19. package/dist/{chunk-NBE6CHRI.js → chunk-VTPRIXKG.js} +49 -9
  20. package/dist/chunk-VTPRIXKG.js.map +1 -0
  21. package/dist/{chunk-ISI2TIUG.js → chunk-Z7VYMNPZ.js} +76 -4
  22. package/dist/chunk-Z7VYMNPZ.js.map +1 -0
  23. package/dist/database.d.ts +5 -0
  24. package/dist/editable-artifact-durable-export.js +2 -2
  25. package/dist/editable-artifacts.js +3 -3
  26. package/dist/index.d.ts +467 -29
  27. package/dist/index.js +23247 -16232
  28. package/dist/index.js.map +1 -1
  29. package/dist/insights.d.ts +23 -7
  30. package/dist/integration-bindings.d.ts +24 -24
  31. package/dist/integration-facets.d.ts +99 -0
  32. package/dist/interaction-revisions.d.ts +11 -0
  33. package/dist/interaction-schema.d.ts +698 -34
  34. package/dist/persistence-errors.d.ts +8 -0
  35. package/dist/provision-roles.js +1 -1
  36. package/dist/runtime-posture.d.ts +8 -7
  37. package/dist/schema.d.ts +9464 -5412
  38. package/dist/schema.js +51 -9
  39. package/dist/session-control.d.ts +29 -3
  40. package/dist/session-tenancy.d.ts +44 -0
  41. package/dist/session-tenancy.js +16 -0
  42. package/dist/session-tenancy.js.map +1 -0
  43. package/dist/slack-task-policy-schema.d.ts +847 -0
  44. package/dist/slack-task-policy.d.ts +65 -0
  45. package/dist/task-notes-schema.d.ts +924 -0
  46. package/dist/task-notes.d.ts +85 -0
  47. package/dist/video-generation.d.ts +9 -0
  48. package/dist/video-generation.js +5 -3
  49. package/dist/xai-subscription.d.ts +326 -0
  50. package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
  51. package/drizzle/0213_browser_interaction_authority.sql +67 -0
  52. package/drizzle/0214_browser_download_saves.sql +34 -0
  53. package/drizzle/0215_browser_controller_host.sql +385 -0
  54. package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
  55. package/drizzle/0217_external_browser_auth_operations.sql +22 -0
  56. package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
  57. package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
  58. package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
  59. package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
  60. package/drizzle/0220_session_channels.sql +54 -0
  61. package/drizzle/0221_sessions_channel_index.sql +5 -0
  62. package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
  63. package/drizzle/0222_sessions_channel_fk.sql +89 -0
  64. package/drizzle/0223_pending_tool_event_output.sql +55 -0
  65. package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
  66. package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
  67. package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
  68. package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
  69. package/drizzle/0227_slack_native_actions.sql +145 -0
  70. package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
  71. package/drizzle/0228_slack_task_policy.sql +400 -0
  72. package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
  73. package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
  74. package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
  75. package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
  76. package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
  77. package/drizzle/0234_xai_subscription_authority.sql +1139 -0
  78. package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
  79. package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
  80. package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
  81. package/drizzle/0237_interaction_transition_reaper.sql +263 -0
  82. package/drizzle/0238_goal_persistence_policy.sql +471 -0
  83. package/drizzle/0238_recover_unclaimed_session_turns.sql +307 -0
  84. package/drizzle/0238_supergrok_realtime_model.sql +29 -0
  85. package/drizzle/0239_supergrok_video_funding.sql +50 -0
  86. package/drizzle/0239_task_tree_notes.sql +990 -0
  87. package/package.json +13 -5
  88. package/src/browser-auth.ts +2600 -123
  89. package/src/browser-downloads.ts +517 -0
  90. package/src/browser-identities.ts +220 -3
  91. package/src/browser-sessions.ts +334 -45
  92. package/src/browser-state-artifacts.ts +402 -12
  93. package/src/canonical-human-identities.ts +317 -0
  94. package/src/capability-integrations.ts +121 -213
  95. package/src/database.ts +41 -1
  96. package/src/index.ts +4625 -411
  97. package/src/insights.ts +109 -28
  98. package/src/integration-bindings.ts +101 -101
  99. package/src/{integration-features.ts → integration-facets.ts} +187 -184
  100. package/src/interaction-revisions.ts +33 -3
  101. package/src/interaction-schema.ts +311 -8
  102. package/src/pack-components.ts +43 -43
  103. package/src/pack-installations.ts +0 -43
  104. package/src/persistence-errors.ts +60 -1
  105. package/src/plugin-packages.ts +9 -9
  106. package/src/provision-roles.ts +232 -0
  107. package/src/runtime-posture.ts +227 -14
  108. package/src/schema.ts +1188 -75
  109. package/src/session-control.ts +122 -37
  110. package/src/session-queue-commands.ts +78 -1
  111. package/src/session-tenancy.ts +188 -0
  112. package/src/session-tool-call-settlement.ts +9 -3
  113. package/src/slack-task-policy-schema.ts +130 -0
  114. package/src/slack-task-policy.ts +341 -0
  115. package/src/task-notes-schema.ts +135 -0
  116. package/src/task-notes.ts +178 -0
  117. package/src/video-generation.ts +90 -12
  118. package/src/workspace-artifacts.ts +1 -1
  119. package/src/xai-subscription.ts +1887 -0
  120. package/dist/chunk-ISI2TIUG.js.map +0 -1
  121. package/dist/chunk-MWDVXQOL.js.map +0 -1
  122. package/dist/chunk-NBE6CHRI.js.map +0 -1
  123. package/dist/chunk-YHZXQ7HP.js.map +0 -1
  124. package/dist/integration-features.d.ts +0 -99
  125. /package/dist/{chunk-F5FT7BEZ.js.map → chunk-HSOWSYOX.js.map} +0 -0
@@ -7,29 +7,29 @@ import type { Database } from "./database";
7
7
  import { effectiveCapabilityOwnerSql } from "./capability-components";
8
8
  import * as schema from "./schema";
9
9
 
10
- export type IntegrationFeatureBindingOwner = {
10
+ export type IntegrationFacetBindingOwner = {
11
11
  kind: "direct" | "plugin" | "pack" | "migration";
12
12
  id: string;
13
13
  removable: boolean;
14
14
  };
15
15
 
16
- export type UpsertIntegrationFeatureBindingInput = {
16
+ export type UpsertIntegrationFacetBindingInput = {
17
17
  accountId: string;
18
18
  workspaceId: string;
19
19
  integrationFacetInstallationId: string;
20
- featureFacetId: string;
20
+ facetDefinitionId: string;
21
21
  bindingKey: string;
22
22
  displayName: string;
23
23
  runtimeKey?: string | null;
24
24
  connectionId?: string | null;
25
25
  config: Record<string, unknown>;
26
26
  createdBySubjectId: string;
27
- owner: IntegrationFeatureBindingOwner;
27
+ owner: IntegrationFacetBindingOwner;
28
28
  expectedVersion?: number;
29
29
  };
30
30
 
31
- export class IntegrationFeatureBindingVersionConflictError extends Error {
32
- readonly name = "IntegrationFeatureBindingVersionConflictError";
31
+ export class IntegrationFacetBindingVersionConflictError extends Error {
32
+ readonly name = "IntegrationFacetBindingVersionConflictError";
33
33
 
34
34
  constructor(
35
35
  readonly bindingKey: string,
@@ -42,12 +42,12 @@ export class IntegrationFeatureBindingVersionConflictError extends Error {
42
42
  }
43
43
  }
44
44
 
45
- export class IntegrationFeatureBindingVersionRequiredError extends Error {
46
- readonly name = "IntegrationFeatureBindingVersionRequiredError";
45
+ export class IntegrationFacetBindingVersionRequiredError extends Error {
46
+ readonly name = "IntegrationFacetBindingVersionRequiredError";
47
47
  }
48
48
 
49
- export class IntegrationFeatureBindingOwnershipConflictError extends Error {
50
- readonly name = "IntegrationFeatureBindingOwnershipConflictError";
49
+ export class IntegrationFacetBindingOwnershipConflictError extends Error {
50
+ readonly name = "IntegrationFacetBindingOwnershipConflictError";
51
51
  }
52
52
 
53
53
  export function integrationBindingKey(
@@ -74,11 +74,11 @@ export function integrationRuntimeKey(baseServerId: string, bindingKey: string):
74
74
  return runtimeKey;
75
75
  }
76
76
 
77
- export async function ensureIntegrationFeatureFacet(
77
+ export async function ensureIntegrationFacetDefinition(
78
78
  db: Database,
79
79
  input: {
80
80
  integrationFacetId: string;
81
- featureKey: string;
81
+ facetKey: string;
82
82
  kind:
83
83
  | "tools"
84
84
  | "knowledge_source"
@@ -88,14 +88,14 @@ export async function ensureIntegrationFeatureFacet(
88
88
  configSchema?: Record<string, unknown>;
89
89
  capabilities?: Record<string, unknown>;
90
90
  },
91
- ): Promise<typeof schema.integrationFeatureFacets.$inferSelect> {
91
+ ): Promise<typeof schema.integrationFacetDefinitions.$inferSelect> {
92
92
  const [existing] = await db
93
93
  .select()
94
- .from(schema.integrationFeatureFacets)
94
+ .from(schema.integrationFacetDefinitions)
95
95
  .where(
96
96
  and(
97
- eq(schema.integrationFeatureFacets.integrationFacetId, input.integrationFacetId),
98
- eq(schema.integrationFeatureFacets.featureKey, input.featureKey),
97
+ eq(schema.integrationFacetDefinitions.integrationFacetId, input.integrationFacetId),
98
+ eq(schema.integrationFacetDefinitions.facetKey, input.facetKey),
99
99
  ),
100
100
  )
101
101
  .limit(1);
@@ -107,50 +107,50 @@ export async function ensureIntegrationFeatureFacet(
107
107
  stableJson(existing.configSchema) !== stableJson(configSchema) ||
108
108
  stableJson(existing.capabilities) !== stableJson(capabilities)
109
109
  ) {
110
- throw new Error(`Integration feature ${input.featureKey} conflicts with stored definition`);
110
+ throw new Error(`Integration facet ${input.facetKey} conflicts with stored definition`);
111
111
  }
112
112
  return existing;
113
113
  }
114
114
  const [created] = await db
115
- .insert(schema.integrationFeatureFacets)
115
+ .insert(schema.integrationFacetDefinitions)
116
116
  .values({
117
117
  integrationFacetId: input.integrationFacetId,
118
- featureKey: input.featureKey,
118
+ facetKey: input.facetKey,
119
119
  kind: input.kind,
120
120
  configSchema,
121
121
  capabilities,
122
122
  })
123
123
  .returning();
124
- if (!created) throw new Error(`Failed to create Integration feature ${input.featureKey}`);
124
+ if (!created) throw new Error(`Failed to create Integration facet ${input.facetKey}`);
125
125
  return created;
126
126
  }
127
127
 
128
- export async function upsertIntegrationFeatureBinding(
128
+ export async function upsertIntegrationFacetBinding(
129
129
  db: Database,
130
- input: UpsertIntegrationFeatureBindingInput,
131
- ): Promise<{ row: typeof schema.integrationFeatureBindings.$inferSelect; changed: boolean }> {
130
+ input: UpsertIntegrationFacetBindingInput,
131
+ ): Promise<{ row: typeof schema.integrationFacetBindings.$inferSelect; changed: boolean }> {
132
132
  assertBindingKey(input.bindingKey);
133
133
  if (input.displayName.trim().length === 0 || input.displayName.trim().length > 200) {
134
134
  throw new Error("Integration instance display name must contain 1-200 characters");
135
135
  }
136
136
  await db.execute(
137
- sql`select pg_advisory_xact_lock(hashtextextended(${`integration-binding:${input.workspaceId}:${input.runtimeKey ?? `${input.featureFacetId}:${input.bindingKey}`}`}, 0))`,
137
+ sql`select pg_advisory_xact_lock(hashtextextended(${`integration-binding:${input.workspaceId}:${input.runtimeKey ?? `${input.facetDefinitionId}:${input.bindingKey}`}`}, 0))`,
138
138
  );
139
139
  const [existing] = await db
140
140
  .select()
141
- .from(schema.integrationFeatureBindings)
141
+ .from(schema.integrationFacetBindings)
142
142
  .where(
143
143
  and(
144
- eq(schema.integrationFeatureBindings.workspaceId, input.workspaceId),
144
+ eq(schema.integrationFacetBindings.workspaceId, input.workspaceId),
145
145
  input.runtimeKey
146
- ? eq(schema.integrationFeatureBindings.runtimeKey, input.runtimeKey)
146
+ ? eq(schema.integrationFacetBindings.runtimeKey, input.runtimeKey)
147
147
  : and(
148
148
  eq(
149
- schema.integrationFeatureBindings.integrationFacetInstallationId,
149
+ schema.integrationFacetBindings.integrationFacetInstallationId,
150
150
  input.integrationFacetInstallationId,
151
151
  ),
152
- eq(schema.integrationFeatureBindings.featureFacetId, input.featureFacetId),
153
- eq(schema.integrationFeatureBindings.bindingKey, input.bindingKey),
152
+ eq(schema.integrationFacetBindings.facetDefinitionId, input.facetDefinitionId),
153
+ eq(schema.integrationFacetBindings.bindingKey, input.bindingKey),
154
154
  ),
155
155
  ),
156
156
  )
@@ -158,19 +158,19 @@ export async function upsertIntegrationFeatureBinding(
158
158
  .limit(1);
159
159
  if (!existing) {
160
160
  if (input.expectedVersion !== undefined) {
161
- throw new IntegrationFeatureBindingVersionConflictError(
161
+ throw new IntegrationFacetBindingVersionConflictError(
162
162
  input.bindingKey,
163
163
  input.expectedVersion,
164
164
  0,
165
165
  );
166
166
  }
167
167
  const [created] = await db
168
- .insert(schema.integrationFeatureBindings)
168
+ .insert(schema.integrationFacetBindings)
169
169
  .values({
170
170
  accountId: input.accountId,
171
171
  workspaceId: input.workspaceId,
172
172
  integrationFacetInstallationId: input.integrationFacetInstallationId,
173
- featureFacetId: input.featureFacetId,
173
+ facetDefinitionId: input.facetDefinitionId,
174
174
  bindingKey: input.bindingKey,
175
175
  displayName: input.displayName.trim(),
176
176
  runtimeKey: input.runtimeKey ?? null,
@@ -181,17 +181,17 @@ export async function upsertIntegrationFeatureBinding(
181
181
  })
182
182
  .returning();
183
183
  if (!created) throw new Error("Failed to create Integration instance");
184
- await addIntegrationFeatureBindingOwner(db, created.id, input);
184
+ await addIntegrationFacetBindingOwner(db, created.id, input);
185
185
  return { row: created, changed: true };
186
186
  }
187
187
  if (existing.bindingKey !== input.bindingKey) {
188
- throw new IntegrationFeatureBindingOwnershipConflictError(
188
+ throw new IntegrationFacetBindingOwnershipConflictError(
189
189
  "Integration runtime identity is already assigned to another instance",
190
190
  );
191
191
  }
192
192
  const changed =
193
193
  existing.integrationFacetInstallationId !== input.integrationFacetInstallationId ||
194
- existing.featureFacetId !== input.featureFacetId ||
194
+ existing.facetDefinitionId !== input.facetDefinitionId ||
195
195
  existing.displayName !== input.displayName.trim() ||
196
196
  existing.runtimeKey !== (input.runtimeKey ?? null) ||
197
197
  existing.connectionId !== (input.connectionId ?? null) ||
@@ -200,31 +200,31 @@ export async function upsertIntegrationFeatureBinding(
200
200
  let row = existing;
201
201
  if (changed) {
202
202
  if (input.expectedVersion !== undefined && existing.version !== input.expectedVersion) {
203
- throw new IntegrationFeatureBindingVersionConflictError(
203
+ throw new IntegrationFacetBindingVersionConflictError(
204
204
  input.bindingKey,
205
205
  input.expectedVersion,
206
206
  existing.version,
207
207
  );
208
208
  }
209
209
  if (input.owner.kind === "direct" && input.expectedVersion === undefined) {
210
- throw new IntegrationFeatureBindingVersionRequiredError(
210
+ throw new IntegrationFacetBindingVersionRequiredError(
211
211
  "Updating an Integration instance requires its previewed version",
212
212
  );
213
213
  }
214
- const owners = await listIntegrationFeatureBindingOwners(db, existing.id);
214
+ const owners = await listIntegrationFacetBindingOwners(db, existing.id);
215
215
  const otherOwners = owners.filter(
216
216
  (owner) => owner.kind !== input.owner.kind || owner.id !== input.owner.id,
217
217
  );
218
218
  if (otherOwners.length > 0) {
219
- throw new IntegrationFeatureBindingOwnershipConflictError(
219
+ throw new IntegrationFacetBindingOwnershipConflictError(
220
220
  "Integration instance is shared by another owner and cannot be changed in place",
221
221
  );
222
222
  }
223
223
  const [updated] = await db
224
- .update(schema.integrationFeatureBindings)
224
+ .update(schema.integrationFacetBindings)
225
225
  .set({
226
226
  integrationFacetInstallationId: input.integrationFacetInstallationId,
227
- featureFacetId: input.featureFacetId,
227
+ facetDefinitionId: input.facetDefinitionId,
228
228
  displayName: input.displayName.trim(),
229
229
  runtimeKey: input.runtimeKey ?? null,
230
230
  connectionId: input.connectionId ?? null,
@@ -235,48 +235,48 @@ export async function upsertIntegrationFeatureBinding(
235
235
  lastErrorCode: null,
236
236
  updatedAt: new Date(),
237
237
  })
238
- .where(eq(schema.integrationFeatureBindings.id, existing.id))
238
+ .where(eq(schema.integrationFacetBindings.id, existing.id))
239
239
  .returning();
240
240
  if (!updated) throw new Error("Failed to update Integration instance");
241
241
  row = updated;
242
242
  }
243
- await addIntegrationFeatureBindingOwner(db, row.id, input);
243
+ await addIntegrationFacetBindingOwner(db, row.id, input);
244
244
  return { row, changed };
245
245
  }
246
246
 
247
- export async function listIntegrationFeatureBindingOwners(
247
+ export async function listIntegrationFacetBindingOwners(
248
248
  db: Database,
249
249
  bindingId: string,
250
- ): Promise<IntegrationFeatureBindingOwner[]> {
251
- return await loadIntegrationFeatureBindingOwners(db, bindingId, true);
250
+ ): Promise<IntegrationFacetBindingOwner[]> {
251
+ return await loadIntegrationFacetBindingOwners(db, bindingId, true);
252
252
  }
253
253
 
254
- async function loadIntegrationFeatureBindingOwners(
254
+ async function loadIntegrationFacetBindingOwners(
255
255
  db: Database,
256
256
  bindingId: string,
257
257
  effectiveOnly: boolean,
258
- ): Promise<IntegrationFeatureBindingOwner[]> {
258
+ ): Promise<IntegrationFacetBindingOwner[]> {
259
259
  const rows = await db
260
260
  .select({
261
- kind: schema.integrationFeatureBindingOwners.ownerKind,
262
- id: schema.integrationFeatureBindingOwners.ownerId,
263
- removable: schema.integrationFeatureBindingOwners.removable,
261
+ kind: schema.integrationFacetBindingOwners.ownerKind,
262
+ id: schema.integrationFacetBindingOwners.ownerId,
263
+ removable: schema.integrationFacetBindingOwners.removable,
264
264
  })
265
- .from(schema.integrationFeatureBindingOwners)
265
+ .from(schema.integrationFacetBindingOwners)
266
266
  .where(
267
267
  and(
268
- eq(schema.integrationFeatureBindingOwners.bindingId, bindingId),
268
+ eq(schema.integrationFacetBindingOwners.bindingId, bindingId),
269
269
  effectiveOnly
270
270
  ? effectiveCapabilityOwnerSql(
271
- schema.integrationFeatureBindingOwners.ownerKind,
272
- schema.integrationFeatureBindingOwners.ownerId,
271
+ schema.integrationFacetBindingOwners.ownerKind,
272
+ schema.integrationFacetBindingOwners.ownerId,
273
273
  )
274
274
  : sql`true`,
275
275
  ),
276
276
  )
277
277
  .orderBy(
278
- asc(schema.integrationFeatureBindingOwners.ownerKind),
279
- asc(schema.integrationFeatureBindingOwners.ownerId),
278
+ asc(schema.integrationFacetBindingOwners.ownerKind),
279
+ asc(schema.integrationFacetBindingOwners.ownerId),
280
280
  );
281
281
  return rows.map((row) => {
282
282
  if (
@@ -291,95 +291,95 @@ async function loadIntegrationFeatureBindingOwners(
291
291
  });
292
292
  }
293
293
 
294
- export async function removeIntegrationFeatureBindingOwner(
294
+ export async function removeIntegrationFacetBindingOwner(
295
295
  db: Database,
296
296
  input: {
297
297
  workspaceId: string;
298
298
  bindingId: string;
299
- owner: Pick<IntegrationFeatureBindingOwner, "kind" | "id">;
299
+ owner: Pick<IntegrationFacetBindingOwner, "kind" | "id">;
300
300
  expectedVersion?: number;
301
301
  },
302
302
  ): Promise<{
303
- binding: typeof schema.integrationFeatureBindings.$inferSelect | null;
304
- remainingOwners: IntegrationFeatureBindingOwner[];
303
+ binding: typeof schema.integrationFacetBindings.$inferSelect | null;
304
+ remainingOwners: IntegrationFacetBindingOwner[];
305
305
  }> {
306
306
  const [binding] = await db
307
307
  .select()
308
- .from(schema.integrationFeatureBindings)
308
+ .from(schema.integrationFacetBindings)
309
309
  .where(
310
310
  and(
311
- eq(schema.integrationFeatureBindings.workspaceId, input.workspaceId),
312
- eq(schema.integrationFeatureBindings.id, input.bindingId),
311
+ eq(schema.integrationFacetBindings.workspaceId, input.workspaceId),
312
+ eq(schema.integrationFacetBindings.id, input.bindingId),
313
313
  ),
314
314
  )
315
315
  .for("update")
316
316
  .limit(1);
317
317
  if (!binding) return { binding: null, remainingOwners: [] };
318
318
  if (input.expectedVersion !== undefined && binding.version !== input.expectedVersion) {
319
- throw new IntegrationFeatureBindingVersionConflictError(
319
+ throw new IntegrationFacetBindingVersionConflictError(
320
320
  binding.bindingKey,
321
321
  input.expectedVersion,
322
322
  binding.version,
323
323
  );
324
324
  }
325
325
  await db
326
- .delete(schema.integrationFeatureBindingOwners)
326
+ .delete(schema.integrationFacetBindingOwners)
327
327
  .where(
328
328
  and(
329
- eq(schema.integrationFeatureBindingOwners.workspaceId, input.workspaceId),
330
- eq(schema.integrationFeatureBindingOwners.bindingId, binding.id),
331
- eq(schema.integrationFeatureBindingOwners.ownerKind, input.owner.kind),
332
- eq(schema.integrationFeatureBindingOwners.ownerId, input.owner.id),
329
+ eq(schema.integrationFacetBindingOwners.workspaceId, input.workspaceId),
330
+ eq(schema.integrationFacetBindingOwners.bindingId, binding.id),
331
+ eq(schema.integrationFacetBindingOwners.ownerKind, input.owner.kind),
332
+ eq(schema.integrationFacetBindingOwners.ownerId, input.owner.id),
333
333
  ),
334
334
  );
335
335
  // Pending or repairing owners are not runtime-effective yet, but they still
336
336
  // preserve the shared binding so their operation can resume safely.
337
- const remainingOwners = await loadIntegrationFeatureBindingOwners(db, binding.id, false);
337
+ const remainingOwners = await loadIntegrationFacetBindingOwners(db, binding.id, false);
338
338
  if (remainingOwners.length > 0) return { binding, remainingOwners };
339
339
  const [disabled] = await db
340
- .update(schema.integrationFeatureBindings)
340
+ .update(schema.integrationFacetBindings)
341
341
  .set({ status: "disabled", version: binding.version + 1, updatedAt: new Date() })
342
- .where(eq(schema.integrationFeatureBindings.id, binding.id))
342
+ .where(eq(schema.integrationFacetBindings.id, binding.id))
343
343
  .returning();
344
344
  return { binding: disabled ?? binding, remainingOwners: [] };
345
345
  }
346
346
 
347
- export async function removeIntegrationFeatureBindingOwnersForOwner(
347
+ export async function removeIntegrationFacetBindingOwnersForOwner(
348
348
  db: Database,
349
349
  input: {
350
350
  workspaceId: string;
351
- owner: Pick<IntegrationFeatureBindingOwner, "kind" | "id">;
351
+ owner: Pick<IntegrationFacetBindingOwner, "kind" | "id">;
352
352
  },
353
353
  ): Promise<{ disabledBindingIds: string[]; retainedBindingIds: string[] }> {
354
354
  const deleted = await db
355
- .delete(schema.integrationFeatureBindingOwners)
355
+ .delete(schema.integrationFacetBindingOwners)
356
356
  .where(
357
357
  and(
358
- eq(schema.integrationFeatureBindingOwners.workspaceId, input.workspaceId),
359
- eq(schema.integrationFeatureBindingOwners.ownerKind, input.owner.kind),
360
- eq(schema.integrationFeatureBindingOwners.ownerId, input.owner.id),
358
+ eq(schema.integrationFacetBindingOwners.workspaceId, input.workspaceId),
359
+ eq(schema.integrationFacetBindingOwners.ownerKind, input.owner.kind),
360
+ eq(schema.integrationFacetBindingOwners.ownerId, input.owner.id),
361
361
  ),
362
362
  )
363
- .returning({ bindingId: schema.integrationFeatureBindingOwners.bindingId });
363
+ .returning({ bindingId: schema.integrationFacetBindingOwners.bindingId });
364
364
  const disabledBindingIds: string[] = [];
365
365
  const retainedBindingIds: string[] = [];
366
366
  for (const bindingId of [...new Set(deleted.map((row) => row.bindingId))]) {
367
- const owners = await loadIntegrationFeatureBindingOwners(db, bindingId, false);
367
+ const owners = await loadIntegrationFacetBindingOwners(db, bindingId, false);
368
368
  if (owners.length > 0) {
369
369
  retainedBindingIds.push(bindingId);
370
370
  continue;
371
371
  }
372
372
  await db
373
- .update(schema.integrationFeatureBindings)
373
+ .update(schema.integrationFacetBindings)
374
374
  .set({
375
375
  status: "disabled",
376
- version: sql`${schema.integrationFeatureBindings.version} + 1`,
376
+ version: sql`${schema.integrationFacetBindings.version} + 1`,
377
377
  updatedAt: new Date(),
378
378
  })
379
379
  .where(
380
380
  and(
381
- eq(schema.integrationFeatureBindings.workspaceId, input.workspaceId),
382
- eq(schema.integrationFeatureBindings.id, bindingId),
381
+ eq(schema.integrationFacetBindings.workspaceId, input.workspaceId),
382
+ eq(schema.integrationFacetBindings.id, bindingId),
383
383
  ),
384
384
  );
385
385
  disabledBindingIds.push(bindingId);
@@ -392,33 +392,33 @@ export async function integrationDefinitionHasBindingOwner(
392
392
  input: {
393
393
  workspaceId: string;
394
394
  pluginInstallationId: string;
395
- owner: Pick<IntegrationFeatureBindingOwner, "kind" | "id">;
395
+ owner: Pick<IntegrationFacetBindingOwner, "kind" | "id">;
396
396
  },
397
397
  ): Promise<boolean> {
398
398
  const [row] = await db
399
- .select({ id: schema.integrationFeatureBindingOwners.id })
400
- .from(schema.integrationFeatureBindingOwners)
399
+ .select({ id: schema.integrationFacetBindingOwners.id })
400
+ .from(schema.integrationFacetBindingOwners)
401
401
  .innerJoin(
402
- schema.integrationFeatureBindings,
403
- eq(schema.integrationFeatureBindings.id, schema.integrationFeatureBindingOwners.bindingId),
402
+ schema.integrationFacetBindings,
403
+ eq(schema.integrationFacetBindings.id, schema.integrationFacetBindingOwners.bindingId),
404
404
  )
405
405
  .innerJoin(
406
406
  schema.capabilityFacetInstallations,
407
407
  eq(
408
408
  schema.capabilityFacetInstallations.id,
409
- schema.integrationFeatureBindings.integrationFacetInstallationId,
409
+ schema.integrationFacetBindings.integrationFacetInstallationId,
410
410
  ),
411
411
  )
412
412
  .where(
413
413
  and(
414
- eq(schema.integrationFeatureBindingOwners.workspaceId, input.workspaceId),
415
- eq(schema.integrationFeatureBindingOwners.ownerKind, input.owner.kind),
416
- eq(schema.integrationFeatureBindingOwners.ownerId, input.owner.id),
414
+ eq(schema.integrationFacetBindingOwners.workspaceId, input.workspaceId),
415
+ eq(schema.integrationFacetBindingOwners.ownerKind, input.owner.kind),
416
+ eq(schema.integrationFacetBindingOwners.ownerId, input.owner.id),
417
417
  eq(schema.capabilityFacetInstallations.pluginInstallationId, input.pluginInstallationId),
418
418
  or(
419
- eq(schema.integrationFeatureBindings.status, "active"),
420
- eq(schema.integrationFeatureBindings.status, "needs_attention"),
421
- eq(schema.integrationFeatureBindings.status, "paused"),
419
+ eq(schema.integrationFacetBindings.status, "active"),
420
+ eq(schema.integrationFacetBindings.status, "needs_attention"),
421
+ eq(schema.integrationFacetBindings.status, "paused"),
422
422
  ),
423
423
  ),
424
424
  )
@@ -426,13 +426,13 @@ export async function integrationDefinitionHasBindingOwner(
426
426
  return Boolean(row);
427
427
  }
428
428
 
429
- export async function addIntegrationFeatureBindingOwner(
429
+ export async function addIntegrationFacetBindingOwner(
430
430
  db: Database,
431
431
  bindingId: string,
432
- input: Pick<UpsertIntegrationFeatureBindingInput, "accountId" | "workspaceId" | "owner">,
432
+ input: Pick<UpsertIntegrationFacetBindingInput, "accountId" | "workspaceId" | "owner">,
433
433
  ): Promise<void> {
434
434
  await db
435
- .insert(schema.integrationFeatureBindingOwners)
435
+ .insert(schema.integrationFacetBindingOwners)
436
436
  .values({
437
437
  accountId: input.accountId,
438
438
  workspaceId: input.workspaceId,