@opengeni/db 0.28.9 → 0.36.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 (225) hide show
  1. package/dist/attached-browser-devices.d.ts +42 -0
  2. package/dist/attempt-tool-catalogs.d.ts +16 -0
  3. package/dist/browser-auth.d.ts +299 -0
  4. package/dist/browser-downloads.d.ts +51 -0
  5. package/dist/browser-identities.d.ts +137 -0
  6. package/dist/browser-sessions.d.ts +354 -0
  7. package/dist/browser-state-artifacts.d.ts +91 -0
  8. package/dist/canonical-human-identities.d.ts +48 -0
  9. package/dist/canonical-human-identities.js +28 -0
  10. package/dist/canonical-human-identities.js.map +1 -0
  11. package/dist/capability-components.d.ts +37 -0
  12. package/dist/capability-integrations.d.ts +194 -0
  13. package/dist/chunk-5KTIEDX7.js +13200 -0
  14. package/dist/chunk-5KTIEDX7.js.map +1 -0
  15. package/dist/chunk-CQZ4QSP5.js +995 -0
  16. package/dist/chunk-CQZ4QSP5.js.map +1 -0
  17. package/dist/chunk-F32YT7MP.js +117 -0
  18. package/dist/chunk-F32YT7MP.js.map +1 -0
  19. package/dist/chunk-JC5QPLUM.js +666 -0
  20. package/dist/chunk-JC5QPLUM.js.map +1 -0
  21. package/dist/chunk-P3RE4D2B.js +3535 -0
  22. package/dist/chunk-P3RE4D2B.js.map +1 -0
  23. package/dist/chunk-TAUTWOS5.js +259 -0
  24. package/dist/chunk-TAUTWOS5.js.map +1 -0
  25. package/dist/chunk-VKLB2ZGI.js +2389 -0
  26. package/dist/chunk-VKLB2ZGI.js.map +1 -0
  27. package/dist/codemode-operations.d.ts +117 -0
  28. package/dist/codex-token-resolver.d.ts +2 -2
  29. package/dist/company-profile-schema.d.ts +798 -0
  30. package/dist/company-profile.d.ts +268 -0
  31. package/dist/computer-sessions.d.ts +109 -0
  32. package/dist/connection-token-resolver.d.ts +9 -4
  33. package/dist/database.d.ts +57 -3
  34. package/dist/editable-artifact-durable-export.d.ts +153 -0
  35. package/dist/editable-artifact-durable-export.js +788 -0
  36. package/dist/editable-artifact-durable-export.js.map +1 -0
  37. package/dist/editable-artifact-materialization.d.ts +123 -0
  38. package/dist/editable-artifacts-schema.d.ts +4152 -0
  39. package/dist/editable-artifacts.d.ts +610 -0
  40. package/dist/editable-artifacts.js +26 -0
  41. package/dist/editable-artifacts.js.map +1 -0
  42. package/dist/generated-images.d.ts +139 -0
  43. package/dist/index.d.ts +1122 -126
  44. package/dist/index.js +42329 -18407
  45. package/dist/index.js.map +1 -1
  46. package/dist/insights.d.ts +73 -10
  47. package/dist/integration-bindings.d.ts +70 -0
  48. package/dist/integration-facets.d.ts +99 -0
  49. package/dist/interaction-revisions.d.ts +14 -0
  50. package/dist/interaction-schema.d.ts +6036 -0
  51. package/dist/knowledge-source-sync-schema.d.ts +1679 -0
  52. package/dist/knowledge-source-sync.d.ts +274 -0
  53. package/dist/memory-governance.d.ts +2 -2
  54. package/dist/memory-slack-delivery.d.ts +101 -0
  55. package/dist/new-session-drafts.d.ts +2 -2
  56. package/dist/pack-components.d.ts +76 -0
  57. package/dist/pack-installations.d.ts +86 -0
  58. package/dist/persistence-errors.d.ts +3 -3
  59. package/dist/plugin-packages.d.ts +126 -0
  60. package/dist/preference-registry.d.ts +1 -1
  61. package/dist/provision-roles.d.ts +9 -1
  62. package/dist/provision-roles.js +1 -1
  63. package/dist/runtime-posture.d.ts +19 -6
  64. package/dist/schema.d.ts +22654 -9359
  65. package/dist/schema.js +209 -3
  66. package/dist/scoped-knowledge.d.ts +97 -1
  67. package/dist/session-control.d.ts +33 -7
  68. package/dist/session-queue-commands.d.ts +19 -11
  69. package/dist/session-realtime-context.d.ts +2 -2
  70. package/dist/session-realtime-ledger.d.ts +4 -4
  71. package/dist/session-realtime-mirror.d.ts +2 -2
  72. package/dist/session-realtime-state.d.ts +1 -1
  73. package/dist/session-realtime-terminal.d.ts +1 -1
  74. package/dist/session-realtime.d.ts +7 -7
  75. package/dist/session-tenancy.d.ts +44 -0
  76. package/dist/session-tenancy.js +16 -0
  77. package/dist/session-tenancy.js.map +1 -0
  78. package/dist/session-tool-call-settlement.d.ts +1 -1
  79. package/dist/slack-task-policy-schema.d.ts +847 -0
  80. package/dist/slack-task-policy.d.ts +65 -0
  81. package/dist/slack-user-link-access.d.ts +54 -0
  82. package/dist/task-notes-schema.d.ts +924 -0
  83. package/dist/task-notes.d.ts +85 -0
  84. package/dist/transcription-recordings.d.ts +2 -2
  85. package/dist/turn-initiator.d.ts +2 -2
  86. package/dist/video-generation.d.ts +225 -0
  87. package/dist/video-generation.js +68 -0
  88. package/dist/video-generation.js.map +1 -0
  89. package/dist/workspace-artifacts.d.ts +1 -1
  90. package/dist/workspace-instruction-policies.d.ts +1 -1
  91. package/dist/workspace-learning-policy-schema.d.ts +932 -0
  92. package/dist/workspace-learning-policy.d.ts +161 -0
  93. package/dist/xai-subscription.d.ts +326 -0
  94. package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
  95. package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
  96. package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
  97. package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
  98. package/drizzle/0187_generated_image_artifacts.sql +173 -0
  99. package/drizzle/0188_image_generation_retention_failure.sql +25 -0
  100. package/drizzle/0189_retained_session_image_formats.sql +13 -0
  101. package/drizzle/0190_timeline_annotations.sql +31 -0
  102. package/drizzle/0191_editable_artifact_engine.sql +3853 -0
  103. package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
  104. package/drizzle/0193_editable_artifact_authorization.sql +190 -0
  105. package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
  106. package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
  107. package/drizzle/0196_rig_provider_images.sql +152 -0
  108. package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
  109. package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
  110. package/drizzle/0199_workspace_learning_policy.sql +980 -0
  111. package/drizzle/0201_company_profile_authority.sql +849 -0
  112. package/drizzle/0202_document_index_checkpoints.sql +85 -0
  113. package/drizzle/0203_durable_video_generation.sql +353 -0
  114. package/drizzle/0204_video_generation_funding.sql +44 -0
  115. package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
  116. package/drizzle/0206_browser_sessions.sql +646 -0
  117. package/drizzle/0207_browser_identities.sql +379 -0
  118. package/drizzle/0208_attached_browser_devices.sql +165 -0
  119. package/drizzle/0209_computer_sessions.sql +575 -0
  120. package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
  121. package/drizzle/0211_editable_artifact_session_links.sql +58 -0
  122. package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
  123. package/drizzle/0212_slack_installation_bindings.sql +348 -0
  124. package/drizzle/0213_browser_interaction_authority.sql +67 -0
  125. package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
  126. package/drizzle/0214_browser_download_saves.sql +34 -0
  127. package/drizzle/0214_session_activity_commit_gate.sql +262 -0
  128. package/drizzle/0215_browser_controller_host.sql +385 -0
  129. package/drizzle/0215_capabilities_platform.sql +980 -0
  130. package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
  131. package/drizzle/0216_pack_component_ownership.sql +235 -0
  132. package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
  133. package/drizzle/0217_external_browser_auth_operations.sql +22 -0
  134. package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
  135. package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
  136. package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
  137. package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
  138. package/drizzle/0220_session_channels.sql +54 -0
  139. package/drizzle/0221_sessions_channel_index.sql +5 -0
  140. package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
  141. package/drizzle/0222_sessions_channel_fk.sql +89 -0
  142. package/drizzle/0223_pending_tool_event_output.sql +55 -0
  143. package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
  144. package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
  145. package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
  146. package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
  147. package/drizzle/0227_slack_native_actions.sql +145 -0
  148. package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
  149. package/drizzle/0228_slack_task_policy.sql +400 -0
  150. package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
  151. package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
  152. package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
  153. package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
  154. package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
  155. package/drizzle/0234_xai_subscription_authority.sql +1139 -0
  156. package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
  157. package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
  158. package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
  159. package/drizzle/0237_interaction_transition_reaper.sql +263 -0
  160. package/drizzle/0238_goal_persistence_policy.sql +471 -0
  161. package/drizzle/0238_supergrok_realtime_model.sql +29 -0
  162. package/drizzle/0239_supergrok_video_funding.sql +50 -0
  163. package/drizzle/0239_task_tree_notes.sql +990 -0
  164. package/package.json +26 -5
  165. package/src/attached-browser-devices.ts +371 -0
  166. package/src/attempt-tool-catalogs.ts +131 -0
  167. package/src/browser-auth.ts +4373 -0
  168. package/src/browser-downloads.ts +517 -0
  169. package/src/browser-identities.ts +1385 -0
  170. package/src/browser-sessions.ts +2294 -0
  171. package/src/browser-state-artifacts.ts +449 -0
  172. package/src/canonical-human-identities.ts +317 -0
  173. package/src/capability-components.ts +166 -0
  174. package/src/capability-integrations.ts +1571 -0
  175. package/src/codemode-operations.ts +674 -0
  176. package/src/company-profile-schema.ts +143 -0
  177. package/src/company-profile.ts +968 -0
  178. package/src/computer-sessions.ts +1130 -0
  179. package/src/connection-token-resolver.ts +270 -25
  180. package/src/database.ts +468 -24
  181. package/src/editable-artifact-durable-export.ts +1201 -0
  182. package/src/editable-artifact-materialization.ts +893 -0
  183. package/src/editable-artifacts-schema.ts +879 -0
  184. package/src/editable-artifacts.ts +5404 -0
  185. package/src/generated-images.ts +740 -0
  186. package/src/index.ts +9963 -1465
  187. package/src/insights.ts +251 -23
  188. package/src/integration-bindings.ts +455 -0
  189. package/src/integration-facets.ts +862 -0
  190. package/src/interaction-revisions.ts +70 -0
  191. package/src/interaction-schema.ts +1606 -0
  192. package/src/knowledge-source-sync-schema.ts +192 -0
  193. package/src/knowledge-source-sync.ts +1922 -0
  194. package/src/memory-slack-delivery.ts +801 -0
  195. package/src/pack-components.ts +954 -0
  196. package/src/pack-installations.ts +886 -0
  197. package/src/persistence-errors.ts +4 -7
  198. package/src/plugin-packages.ts +1186 -0
  199. package/src/provision-roles.ts +534 -1
  200. package/src/runtime-posture-cli.ts +9 -0
  201. package/src/runtime-posture.ts +721 -5
  202. package/src/schema.ts +6270 -3159
  203. package/src/scoped-knowledge-schema.ts +1 -1
  204. package/src/scoped-knowledge.ts +655 -3
  205. package/src/session-control.ts +130 -42
  206. package/src/session-queue-commands.ts +265 -15
  207. package/src/session-realtime-context.ts +2 -2
  208. package/src/session-realtime-ledger.ts +3 -3
  209. package/src/session-realtime.ts +7 -7
  210. package/src/session-tenancy.ts +188 -0
  211. package/src/session-tool-call-settlement.ts +18 -3
  212. package/src/slack-task-policy-schema.ts +130 -0
  213. package/src/slack-task-policy.ts +341 -0
  214. package/src/slack-user-link-access.ts +702 -0
  215. package/src/task-notes-schema.ts +135 -0
  216. package/src/task-notes.ts +178 -0
  217. package/src/video-generation.ts +1530 -0
  218. package/src/workspace-artifacts.ts +1 -1
  219. package/src/workspace-learning-policy-schema.ts +139 -0
  220. package/src/workspace-learning-policy.ts +595 -0
  221. package/src/xai-subscription.ts +1887 -0
  222. package/dist/chunk-P6CUHXQZ.js +0 -7248
  223. package/dist/chunk-P6CUHXQZ.js.map +0 -1
  224. package/dist/chunk-VHBFHMPC.js +0 -1219
  225. package/dist/chunk-VHBFHMPC.js.map +0 -1
@@ -0,0 +1,1606 @@
1
+ import type {
2
+ AttachedBrowserDeviceCapabilities,
3
+ AuthRunChoice,
4
+ AuthRunExternalAction,
5
+ AuthRunPendingField,
6
+ BrowserRevisionMaterialization,
7
+ BrowserSessionCapabilities,
8
+ ComputerSessionCapabilities,
9
+ InteractionPlacement,
10
+ NetworkRouteConfiguration,
11
+ NetworkRouteConsistency,
12
+ SiteAuthAuthority,
13
+ SiteAuthHealthPolicy,
14
+ SiteAuthMethod,
15
+ } from "@opengeni/contracts";
16
+ import { sql } from "drizzle-orm";
17
+ import {
18
+ bigint,
19
+ boolean,
20
+ check,
21
+ index,
22
+ integer,
23
+ jsonb,
24
+ pgTable,
25
+ primaryKey,
26
+ text,
27
+ timestamp,
28
+ uniqueIndex,
29
+ uuid,
30
+ } from "drizzle-orm/pg-core";
31
+
32
+ // Foreign keys into the older workspace/session/sandbox tables live in the SQL
33
+ // migration. Keeping this schema leaf independent avoids a cycle into schema.ts.
34
+
35
+ export const interactionLifecycleValues = [
36
+ "starting",
37
+ "active",
38
+ "suspending",
39
+ "suspended",
40
+ "restoring",
41
+ "repair_required",
42
+ "lost",
43
+ "ending",
44
+ "ended",
45
+ "failed",
46
+ ] as const;
47
+
48
+ export const interactionOperationStateValues = [
49
+ "prepared",
50
+ "dispatched",
51
+ "completed",
52
+ "failed",
53
+ "outcome_unknown",
54
+ ] as const;
55
+
56
+ export const interactionOperationKindValues = [
57
+ "create",
58
+ "resume",
59
+ "suspend",
60
+ "end",
61
+ "publish",
62
+ ] as const;
63
+
64
+ export const workspaceInteractionRevisions = pgTable(
65
+ "workspace_interaction_revisions",
66
+ {
67
+ workspaceId: uuid("workspace_id").primaryKey(),
68
+ accountId: uuid("account_id").notNull(),
69
+ revision: bigint("revision", { mode: "number" }).notNull().default(0),
70
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
71
+ },
72
+ (table) => ({
73
+ revisionValid: check(
74
+ "workspace_interaction_revisions_revision_check",
75
+ sql`${table.revision} >= 0`,
76
+ ),
77
+ }),
78
+ );
79
+
80
+ export const browserIdentities = pgTable(
81
+ "browser_identities",
82
+ {
83
+ id: uuid("id").primaryKey(),
84
+ accountId: uuid("account_id").notNull(),
85
+ workspaceId: uuid("workspace_id").notNull(),
86
+ name: text("name").notNull(),
87
+ status: text("status", { enum: ["active", "archived"] })
88
+ .notNull()
89
+ .default("active"),
90
+ version: bigint("version", { mode: "number" }).notNull().default(1),
91
+ defaultRevisionId: uuid("default_revision_id"),
92
+ headGeneration: bigint("head_generation", { mode: "number" }).notNull().default(0),
93
+ revisionCount: bigint("revision_count", { mode: "number" }).notNull().default(0),
94
+ createOperationId: uuid("create_operation_id").notNull(),
95
+ createdBySubjectId: text("created_by_subject_id").notNull(),
96
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
97
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
98
+ },
99
+ (table) => ({
100
+ workspaceIdentity: uniqueIndex("browser_identities_workspace_id_uq").on(
101
+ table.workspaceId,
102
+ table.id,
103
+ ),
104
+ createOperation: uniqueIndex("browser_identities_workspace_create_operation_uq").on(
105
+ table.workspaceId,
106
+ table.createOperationId,
107
+ ),
108
+ activeName: uniqueIndex("browser_identities_workspace_active_name_uq")
109
+ .on(table.workspaceId, sql`lower(${table.name})`)
110
+ .where(sql`${table.status} = 'active'`),
111
+ discovery: index("browser_identities_workspace_status_updated_idx").on(
112
+ table.workspaceId,
113
+ table.status,
114
+ table.updatedAt,
115
+ table.id,
116
+ ),
117
+ valuesValid: check(
118
+ "browser_identities_values_check",
119
+ sql`octet_length(${table.name}) between 1 and 200
120
+ and ${table.name} = btrim(${table.name})
121
+ and octet_length(${table.createdBySubjectId}) between 1 and 1024
122
+ and ${table.version} > 0
123
+ and ${table.headGeneration} >= 0
124
+ and ${table.revisionCount} >= 0
125
+ and (
126
+ (${table.headGeneration} = 0 and ${table.defaultRevisionId} is null)
127
+ or (${table.headGeneration} > 0 and ${table.defaultRevisionId} is not null)
128
+ )`,
129
+ ),
130
+ }),
131
+ );
132
+
133
+ export const browserRevisions = pgTable(
134
+ "browser_revisions",
135
+ {
136
+ id: uuid("id").primaryKey(),
137
+ accountId: uuid("account_id").notNull(),
138
+ workspaceId: uuid("workspace_id").notNull(),
139
+ identityId: uuid("identity_id").notNull(),
140
+ parentRevisionId: uuid("parent_revision_id"),
141
+ ordinal: bigint("ordinal", { mode: "number" }).notNull(),
142
+ sourceBrowserSessionId: uuid("source_browser_session_id").notNull(),
143
+ publicationOperationId: uuid("publication_operation_id").notNull(),
144
+ expectedHeadGeneration: bigint("expected_head_generation", {
145
+ mode: "number",
146
+ }).notNull(),
147
+ advanceDefaultRequested: boolean("advance_default_requested").notNull(),
148
+ defaultAdvanced: boolean("default_advanced").notNull(),
149
+ resultHeadGeneration: bigint("result_head_generation", {
150
+ mode: "number",
151
+ }).notNull(),
152
+ manifestDigest: text("manifest_digest").notNull(),
153
+ createdBySubjectId: text("created_by_subject_id").notNull(),
154
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
155
+ },
156
+ (table) => ({
157
+ workspaceRevision: uniqueIndex("browser_revisions_workspace_id_uq").on(
158
+ table.workspaceId,
159
+ table.id,
160
+ ),
161
+ identityRevision: uniqueIndex("browser_revisions_identity_id_uq").on(
162
+ table.identityId,
163
+ table.id,
164
+ ),
165
+ workspaceIdentityRevision: uniqueIndex("browser_revisions_workspace_identity_id_uq").on(
166
+ table.workspaceId,
167
+ table.identityId,
168
+ table.id,
169
+ ),
170
+ identityOrdinal: uniqueIndex("browser_revisions_identity_ordinal_uq").on(
171
+ table.identityId,
172
+ table.ordinal,
173
+ ),
174
+ publicationOperation: uniqueIndex("browser_revisions_workspace_publication_operation_uq").on(
175
+ table.workspaceId,
176
+ table.publicationOperationId,
177
+ ),
178
+ identityHistory: index("browser_revisions_identity_history_idx").on(
179
+ table.workspaceId,
180
+ table.identityId,
181
+ table.ordinal,
182
+ ),
183
+ valuesValid: check(
184
+ "browser_revisions_values_check",
185
+ sql`${table.ordinal} > 0
186
+ and ${table.expectedHeadGeneration} >= 0
187
+ and ${table.resultHeadGeneration} >= 0
188
+ and (not ${table.defaultAdvanced} or ${table.advanceDefaultRequested})
189
+ and (
190
+ not ${table.defaultAdvanced}
191
+ or ${table.resultHeadGeneration} = ${table.expectedHeadGeneration} + 1
192
+ )
193
+ and ${table.manifestDigest} ~ '^[0-9a-f]{64}$'
194
+ and octet_length(${table.createdBySubjectId}) between 1 and 1024
195
+ and ${table.parentRevisionId} is distinct from ${table.id}`,
196
+ ),
197
+ }),
198
+ );
199
+
200
+ /** Internal encrypted object metadata. Public mappers expose only bounded
201
+ * integrity/compatibility fields through BrowserRevisionComponent. */
202
+ export const browserStateArtifacts = pgTable(
203
+ "browser_state_artifacts",
204
+ {
205
+ id: uuid("id").primaryKey(),
206
+ accountId: uuid("account_id").notNull(),
207
+ workspaceId: uuid("workspace_id").notNull(),
208
+ sourceBrowserSessionId: uuid("source_browser_session_id").notNull(),
209
+ purpose: text("purpose", {
210
+ enum: ["revision_component", "private_checkpoint"],
211
+ }).notNull(),
212
+ kind: text("kind", {
213
+ enum: ["chromium_profile", "normalized_web_state", "provider_snapshot"],
214
+ }).notNull(),
215
+ format: text("format").notNull(),
216
+ artifactDigest: text("artifact_digest").notNull(),
217
+ contentDigest: text("content_digest").notNull(),
218
+ manifestDigest: text("manifest_digest").notNull(),
219
+ objectKey: text("object_key").notNull(),
220
+ encryptedDataKey: text("encrypted_data_key"),
221
+ sizeBytes: bigint("size_bytes", { mode: "number" }).notNull(),
222
+ materialization: jsonb("materialization").$type<BrowserRevisionMaterialization>().notNull(),
223
+ state: text("state", {
224
+ enum: ["available", "delete_pending", "deleting", "deleted"],
225
+ })
226
+ .notNull()
227
+ .default("available"),
228
+ retainedUntil: timestamp("retained_until", { withTimezone: true }),
229
+ deleteClaimId: uuid("delete_claim_id"),
230
+ deleteClaimedAt: timestamp("delete_claimed_at", { withTimezone: true }),
231
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
232
+ deletedAt: timestamp("deleted_at", { withTimezone: true }),
233
+ },
234
+ (table) => ({
235
+ workspaceArtifact: uniqueIndex("browser_state_artifacts_workspace_id_uq").on(
236
+ table.workspaceId,
237
+ table.id,
238
+ ),
239
+ commitAuthority: uniqueIndex("browser_state_artifacts_commit_authority_uq").on(
240
+ table.workspaceId,
241
+ table.id,
242
+ table.purpose,
243
+ table.sourceBrowserSessionId,
244
+ ),
245
+ objectKey: uniqueIndex("browser_state_artifacts_object_key_uq").on(table.objectKey),
246
+ source: index("browser_state_artifacts_source_idx").on(
247
+ table.workspaceId,
248
+ table.sourceBrowserSessionId,
249
+ table.createdAt,
250
+ ),
251
+ gc: index("browser_state_artifacts_gc_idx").on(
252
+ table.state,
253
+ table.retainedUntil,
254
+ table.deleteClaimedAt,
255
+ table.createdAt,
256
+ ),
257
+ valuesValid: check(
258
+ "browser_state_artifacts_values_check",
259
+ sql`octet_length(${table.format}) between 1 and 512
260
+ and ${table.format} = btrim(${table.format})
261
+ and ${table.artifactDigest} ~ '^[0-9a-f]{64}$'
262
+ and ${table.contentDigest} ~ '^[0-9a-f]{64}$'
263
+ and ${table.manifestDigest} ~ '^[0-9a-f]{64}$'
264
+ and octet_length(${table.objectKey}) between 1 and 2048
265
+ and ${table.objectKey} ~ ('^workspaces/' || ${table.workspaceId}::text || '/browser-state/[A-Za-z0-9._=-]+(/[A-Za-z0-9._=-]+)*$')
266
+ and (
267
+ ${table.encryptedDataKey} is null
268
+ or octet_length(${table.encryptedDataKey}) between 16 and 8192
269
+ )
270
+ and ${table.sizeBytes} > 0
271
+ and jsonb_typeof(${table.materialization}) = 'object'
272
+ and octet_length(${table.materialization}::text) between 2 and 65536
273
+ and (
274
+ ${table.purpose} <> 'revision_component'
275
+ or (
276
+ ${table.state} = 'available'
277
+ and ${table.retainedUntil} is null
278
+ and ${table.deletedAt} is null
279
+ and ${table.deleteClaimId} is null
280
+ and ${table.deleteClaimedAt} is null
281
+ and ${table.encryptedDataKey} is not null
282
+ )
283
+ )`,
284
+ ),
285
+ lifecycleValid: check(
286
+ "browser_state_artifacts_lifecycle_check",
287
+ sql`(
288
+ ${table.state} = 'available'
289
+ and ${table.retainedUntil} is null
290
+ and ${table.deleteClaimId} is null
291
+ and ${table.deleteClaimedAt} is null
292
+ and ${table.deletedAt} is null
293
+ and ${table.encryptedDataKey} is not null
294
+ ) or (
295
+ ${table.state} = 'delete_pending'
296
+ and ${table.retainedUntil} is not null
297
+ and ${table.deleteClaimId} is null
298
+ and ${table.deleteClaimedAt} is null
299
+ and ${table.deletedAt} is null
300
+ and ${table.encryptedDataKey} is not null
301
+ ) or (
302
+ ${table.state} = 'deleting'
303
+ and ${table.retainedUntil} is not null
304
+ and ${table.deleteClaimId} is not null
305
+ and ${table.deleteClaimedAt} is not null
306
+ and ${table.deletedAt} is null
307
+ and ${table.encryptedDataKey} is not null
308
+ ) or (
309
+ ${table.state} = 'deleted'
310
+ and ${table.retainedUntil} is not null
311
+ and ${table.deleteClaimId} is null
312
+ and ${table.deleteClaimedAt} is null
313
+ and ${table.deletedAt} is not null
314
+ and ${table.encryptedDataKey} is null
315
+ )`,
316
+ ),
317
+ }),
318
+ );
319
+
320
+ /** Pre-publication object authority. This row exists before a controller can
321
+ * upload bytes, then becomes either a committed artifact root or reclaimable
322
+ * cleanup authority. It never carries encryption keys or signed URLs. */
323
+ export const browserStateUploads = pgTable(
324
+ "browser_state_uploads",
325
+ {
326
+ id: uuid("id").primaryKey(),
327
+ accountId: uuid("account_id").notNull(),
328
+ workspaceId: uuid("workspace_id").notNull(),
329
+ operationId: uuid("operation_id").notNull(),
330
+ sourceBrowserSessionId: uuid("source_browser_session_id").notNull(),
331
+ purpose: text("purpose", {
332
+ enum: ["revision_component", "private_checkpoint"],
333
+ }).notNull(),
334
+ objectKey: text("object_key").notNull(),
335
+ state: text("state", {
336
+ enum: ["prepared", "delete_pending", "deleting", "committed", "deleted"],
337
+ })
338
+ .notNull()
339
+ .default("prepared"),
340
+ cleanupAfter: timestamp("cleanup_after", { withTimezone: true }),
341
+ committedArtifactId: uuid("committed_artifact_id"),
342
+ deleteClaimId: uuid("delete_claim_id"),
343
+ deleteClaimedAt: timestamp("delete_claimed_at", { withTimezone: true }),
344
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
345
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
346
+ deletedAt: timestamp("deleted_at", { withTimezone: true }),
347
+ },
348
+ (table) => ({
349
+ workspaceUpload: uniqueIndex("browser_state_uploads_workspace_id_uq").on(
350
+ table.workspaceId,
351
+ table.id,
352
+ ),
353
+ operationObject: uniqueIndex("browser_state_uploads_operation_object_uq").on(
354
+ table.workspaceId,
355
+ table.operationId,
356
+ table.objectKey,
357
+ ),
358
+ objectKey: uniqueIndex("browser_state_uploads_object_key_uq").on(table.objectKey),
359
+ gc: index("browser_state_uploads_gc_idx").on(
360
+ table.state,
361
+ table.cleanupAfter,
362
+ table.deleteClaimedAt,
363
+ table.createdAt,
364
+ ),
365
+ valuesValid: check(
366
+ "browser_state_uploads_values_check",
367
+ sql`octet_length(${table.objectKey}) between 1 and 2048
368
+ and ${table.objectKey} ~ ('^workspaces/' || ${table.workspaceId}::text || '/browser-state/[A-Za-z0-9._=-]+(/[A-Za-z0-9._=-]+)*$')
369
+ and ${table.updatedAt} >= ${table.createdAt}`,
370
+ ),
371
+ lifecycleValid: check(
372
+ "browser_state_uploads_lifecycle_check",
373
+ sql`(
374
+ ${table.state} = 'prepared'
375
+ and ${table.cleanupAfter} is not null
376
+ and ${table.committedArtifactId} is null
377
+ and ${table.deleteClaimId} is null
378
+ and ${table.deleteClaimedAt} is null
379
+ and ${table.deletedAt} is null
380
+ ) or (
381
+ ${table.state} = 'delete_pending'
382
+ and ${table.cleanupAfter} is not null
383
+ and ${table.committedArtifactId} is null
384
+ and ${table.deleteClaimId} is null
385
+ and ${table.deleteClaimedAt} is null
386
+ and ${table.deletedAt} is null
387
+ ) or (
388
+ ${table.state} = 'deleting'
389
+ and ${table.cleanupAfter} is not null
390
+ and ${table.committedArtifactId} is null
391
+ and ${table.deleteClaimId} is not null
392
+ and ${table.deleteClaimedAt} is not null
393
+ and ${table.deletedAt} is null
394
+ ) or (
395
+ ${table.state} = 'committed'
396
+ and ${table.cleanupAfter} is null
397
+ and ${table.committedArtifactId} is not null
398
+ and ${table.deleteClaimId} is null
399
+ and ${table.deleteClaimedAt} is null
400
+ and ${table.deletedAt} is null
401
+ ) or (
402
+ ${table.state} = 'deleted'
403
+ and ${table.cleanupAfter} is not null
404
+ and ${table.committedArtifactId} is null
405
+ and ${table.deleteClaimId} is null
406
+ and ${table.deleteClaimedAt} is null
407
+ and ${table.deletedAt} is not null
408
+ )`,
409
+ ),
410
+ }),
411
+ );
412
+
413
+ export const browserRevisionComponents = pgTable(
414
+ "browser_revision_components",
415
+ {
416
+ id: uuid("id").primaryKey(),
417
+ accountId: uuid("account_id").notNull(),
418
+ workspaceId: uuid("workspace_id").notNull(),
419
+ identityId: uuid("identity_id").notNull(),
420
+ revisionId: uuid("revision_id").notNull(),
421
+ artifactId: uuid("artifact_id").notNull(),
422
+ sourceBrowserSessionId: uuid("source_browser_session_id").notNull(),
423
+ artifactPurpose: text("artifact_purpose", { enum: ["revision_component"] })
424
+ .notNull()
425
+ .default("revision_component"),
426
+ kind: text("kind", {
427
+ enum: ["chromium_profile", "normalized_web_state", "provider_snapshot"],
428
+ }).notNull(),
429
+ position: integer("position").notNull(),
430
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
431
+ },
432
+ (table) => ({
433
+ workspaceComponent: uniqueIndex("browser_revision_components_workspace_id_uq").on(
434
+ table.workspaceId,
435
+ table.id,
436
+ ),
437
+ revisionPosition: uniqueIndex("browser_revision_components_revision_position_uq").on(
438
+ table.revisionId,
439
+ table.position,
440
+ ),
441
+ artifact: uniqueIndex("browser_revision_components_artifact_uq").on(table.artifactId),
442
+ revisionKind: uniqueIndex("browser_revision_components_revision_kind_uq").on(
443
+ table.revisionId,
444
+ table.kind,
445
+ ),
446
+ revision: index("browser_revision_components_revision_idx").on(
447
+ table.workspaceId,
448
+ table.revisionId,
449
+ table.position,
450
+ ),
451
+ valuesValid: check(
452
+ "browser_revision_components_values_check",
453
+ sql`${table.position} between 0 and 15
454
+ and ${table.artifactPurpose} = 'revision_component'`,
455
+ ),
456
+ }),
457
+ );
458
+
459
+ export const attachedBrowserDevices = pgTable(
460
+ "attached_browser_devices",
461
+ {
462
+ id: uuid("id").notNull(),
463
+ accountId: uuid("account_id").notNull(),
464
+ workspaceId: uuid("workspace_id").notNull(),
465
+ enrollmentId: uuid("enrollment_id").notNull(),
466
+ name: text("name").notNull(),
467
+ profileLabel: text("profile_label"),
468
+ browserName: text("browser_name").notNull(),
469
+ browserVersion: text("browser_version").notNull(),
470
+ extensionVersion: text("extension_version").notNull(),
471
+ platform: text("platform", {
472
+ enum: ["linux", "macos", "windows"],
473
+ }).notNull(),
474
+ architecture: text("architecture", { enum: ["x64", "arm64"] }).notNull(),
475
+ connectionGeneration: text("connection_generation").notNull(),
476
+ inventoryRevision: bigint("inventory_revision", {
477
+ mode: "number",
478
+ }).notNull(),
479
+ tabCount: integer("tab_count").notNull(),
480
+ capabilities: jsonb("capabilities").$type<AttachedBrowserDeviceCapabilities>().notNull(),
481
+ lastSeenAt: timestamp("last_seen_at", { withTimezone: true }).notNull(),
482
+ disconnectedAt: timestamp("disconnected_at", { withTimezone: true }),
483
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
484
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
485
+ },
486
+ (table) => ({
487
+ identity: primaryKey({
488
+ name: "attached_browser_devices_workspace_id_pk",
489
+ columns: [table.workspaceId, table.id],
490
+ }),
491
+ enrollment: index("attached_browser_devices_enrollment_idx").on(
492
+ table.workspaceId,
493
+ table.enrollmentId,
494
+ table.disconnectedAt,
495
+ table.updatedAt,
496
+ ),
497
+ discovery: index("attached_browser_devices_discovery_idx").on(
498
+ table.workspaceId,
499
+ table.disconnectedAt,
500
+ table.updatedAt,
501
+ table.id,
502
+ ),
503
+ valuesValid: check(
504
+ "attached_browser_devices_values_check",
505
+ sql`octet_length(${table.name}) between 1 and 200
506
+ and ${table.name} = btrim(${table.name})
507
+ and (${table.profileLabel} is null or (
508
+ octet_length(${table.profileLabel}) between 1 and 200
509
+ and ${table.profileLabel} = btrim(${table.profileLabel})
510
+ ))
511
+ and octet_length(${table.browserName}) between 1 and 100
512
+ and ${table.browserName} = btrim(${table.browserName})
513
+ and octet_length(${table.browserVersion}) between 1 and 256
514
+ and ${table.browserVersion} = btrim(${table.browserVersion})
515
+ and octet_length(${table.extensionVersion}) between 1 and 256
516
+ and ${table.extensionVersion} = btrim(${table.extensionVersion})
517
+ and octet_length(${table.connectionGeneration}) between 1 and 256
518
+ and ${table.connectionGeneration} ~ '^[A-Za-z0-9][A-Za-z0-9._:-]*$'
519
+ and ${table.inventoryRevision} >= 0
520
+ and ${table.tabCount} between 0 and 100000
521
+ and jsonb_typeof(${table.capabilities}) = 'object'
522
+ and octet_length(${table.capabilities}::text) between 2 and 65536`,
523
+ ),
524
+ }),
525
+ );
526
+
527
+ /** Accepted full-snapshot cursor for one connected agent's local browser bridge.
528
+ * This lets heartbeat replay refresh liveness without allowing an older
529
+ * inventory to disconnect a newly announced profile. */
530
+ export const attachedBrowserInventories = pgTable(
531
+ "attached_browser_inventories",
532
+ {
533
+ accountId: uuid("account_id").notNull(),
534
+ workspaceId: uuid("workspace_id").notNull(),
535
+ enrollmentId: uuid("enrollment_id").notNull(),
536
+ bridgeGeneration: text("bridge_generation").notNull(),
537
+ revision: bigint("revision", { mode: "number" }).notNull(),
538
+ observedAt: timestamp("observed_at", { withTimezone: true }).notNull(),
539
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
540
+ },
541
+ (table) => ({
542
+ identity: primaryKey({
543
+ name: "attached_browser_inventories_workspace_enrollment_pk",
544
+ columns: [table.workspaceId, table.enrollmentId],
545
+ }),
546
+ valuesValid: check(
547
+ "attached_browser_inventories_values_check",
548
+ sql`octet_length(${table.bridgeGeneration}) between 1 and 256
549
+ and ${table.bridgeGeneration} ~ '^[A-Za-z0-9][A-Za-z0-9._:-]*$'
550
+ and ${table.revision} >= 0`,
551
+ ),
552
+ }),
553
+ );
554
+
555
+ export const browserSessions = pgTable(
556
+ "browser_sessions",
557
+ {
558
+ id: uuid("id").primaryKey(),
559
+ accountId: uuid("account_id").notNull(),
560
+ workspaceId: uuid("workspace_id").notNull(),
561
+ name: text("name").notNull(),
562
+ lifecycle: text("lifecycle", { enum: interactionLifecycleValues })
563
+ .notNull()
564
+ .default("starting"),
565
+ placementKind: text("placement_kind", {
566
+ enum: ["sandbox_group", "connected_machine", "attached_device", "external_provider"],
567
+ }).notNull(),
568
+ sandboxGroupId: uuid("sandbox_group_id"),
569
+ connectedSandboxId: uuid("connected_sandbox_id"),
570
+ deviceId: uuid("device_id"),
571
+ externalProviderId: text("external_provider_id"),
572
+ externalPlacementId: text("external_placement_id"),
573
+ /** Sandbox group hosting browserd when the logical browser itself lives
574
+ * on a remote provider. This is deliberately separate from placement. */
575
+ controllerHostSandboxGroupId: uuid("controller_host_sandbox_group_id"),
576
+ controllerId: text("controller_id"),
577
+ controllerGeneration: text("controller_generation"),
578
+ placementInstanceId: text("placement_instance_id"),
579
+ tokenGeneration: integer("token_generation").notNull().default(1),
580
+ driverId: text("driver_id").notNull(),
581
+ engine: text("engine", {
582
+ enum: ["chromium", "chrome", "firefox", "webkit", "lightpanda", "external"],
583
+ }).notNull(),
584
+ engineVersion: text("engine_version"),
585
+ headless: boolean("headless").notNull(),
586
+ identityId: uuid("identity_id"),
587
+ baseRevisionId: uuid("base_revision_id"),
588
+ linkedComputerSessionId: uuid("linked_computer_session_id"),
589
+ networkRouteId: uuid("network_route_id"),
590
+ networkRouteVersion: bigint("network_route_version", { mode: "number" }),
591
+ networkRouteConfiguration: jsonb("network_route_configuration"),
592
+ networkRouteConsistency: jsonb("network_route_consistency"),
593
+ networkRouteCredentialVersion: bigint("network_route_credential_version", {
594
+ mode: "number",
595
+ }),
596
+ networkRouteAuthorityDigest: text("network_route_authority_digest"),
597
+ privateCheckpointArtifactId: uuid("private_checkpoint_artifact_id"),
598
+ capabilities: jsonb("capabilities").$type<BrowserSessionCapabilities>().notNull(),
599
+ createOperationId: uuid("create_operation_id").notNull(),
600
+ createdBySubjectId: text("created_by_subject_id").notNull(),
601
+ failureCode: text("failure_code"),
602
+ controllerHeartbeatAt: timestamp("controller_heartbeat_at", {
603
+ withTimezone: true,
604
+ }),
605
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
606
+ lastUsedAt: timestamp("last_used_at", { withTimezone: true }).notNull().defaultNow(),
607
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
608
+ },
609
+ (table) => ({
610
+ workspaceIdentity: uniqueIndex("browser_sessions_workspace_id_uq").on(
611
+ table.workspaceId,
612
+ table.id,
613
+ ),
614
+ createOperation: uniqueIndex("browser_sessions_workspace_create_operation_uq").on(
615
+ table.workspaceId,
616
+ table.createOperationId,
617
+ ),
618
+ workspaceLifecycle: index("browser_sessions_workspace_lifecycle_idx").on(
619
+ table.workspaceId,
620
+ table.lifecycle,
621
+ table.lastUsedAt,
622
+ table.id,
623
+ ),
624
+ sandboxGroup: index("browser_sessions_sandbox_group_idx").on(
625
+ table.workspaceId,
626
+ table.sandboxGroupId,
627
+ table.lifecycle,
628
+ ),
629
+ controllerHostSandboxGroup: index("browser_sessions_controller_host_sandbox_group_idx").on(
630
+ table.workspaceId,
631
+ table.controllerHostSandboxGroupId,
632
+ table.lifecycle,
633
+ ),
634
+ networkRoute: index("browser_sessions_workspace_network_route_idx").on(
635
+ table.workspaceId,
636
+ table.networkRouteId,
637
+ table.lifecycle,
638
+ ),
639
+ valuesValid: check(
640
+ "browser_sessions_values_check",
641
+ sql`octet_length(${table.name}) between 1 and 200
642
+ and octet_length(${table.driverId}) between 1 and 512
643
+ and octet_length(${table.createdBySubjectId}) between 1 and 1024
644
+ and ${table.tokenGeneration} > 0
645
+ and octet_length(${table.capabilities}::text) between 2 and 65536
646
+ and (
647
+ (${table.networkRouteId} is null
648
+ and ${table.networkRouteVersion} is null
649
+ and ${table.networkRouteConfiguration} is null
650
+ and ${table.networkRouteConsistency} is null
651
+ and ${table.networkRouteCredentialVersion} is null
652
+ and ${table.networkRouteAuthorityDigest} is null)
653
+ or
654
+ (${table.networkRouteId} is not null
655
+ and ${table.networkRouteVersion} > 0
656
+ and jsonb_typeof(${table.networkRouteConfiguration}) = 'object'
657
+ and octet_length(${table.networkRouteConfiguration}::text) between 2 and 65536
658
+ and jsonb_typeof(${table.networkRouteConsistency}) = 'object'
659
+ and octet_length(${table.networkRouteConsistency}::text) between 2 and 65536
660
+ and (${table.networkRouteCredentialVersion} is null or ${table.networkRouteCredentialVersion} > 0)
661
+ and (${table.networkRouteAuthorityDigest} is not null or ${table.networkRouteCredentialVersion} is null)
662
+ and (${table.networkRouteAuthorityDigest} is null or (
663
+ octet_length(${table.networkRouteAuthorityDigest}) between 16 and 256
664
+ and ${table.networkRouteAuthorityDigest} ~ '^[A-Za-z0-9._~-]+$'
665
+ )))
666
+ )
667
+ and (${table.engineVersion} is null or octet_length(${table.engineVersion}) between 1 and 256)
668
+ and (${table.failureCode} is null or octet_length(${table.failureCode}) between 1 and 512)`,
669
+ ),
670
+ placementValid: check(
671
+ "browser_sessions_placement_check",
672
+ sql`(
673
+ ${table.placementKind} = 'sandbox_group'
674
+ and ${table.sandboxGroupId} is not null
675
+ and ${table.connectedSandboxId} is null
676
+ and ${table.deviceId} is null
677
+ and ${table.externalProviderId} is null
678
+ and ${table.externalPlacementId} is null
679
+ ) or (
680
+ ${table.placementKind} = 'connected_machine'
681
+ and ${table.sandboxGroupId} is null
682
+ and ${table.connectedSandboxId} is not null
683
+ and ${table.deviceId} is null
684
+ and ${table.externalProviderId} is null
685
+ and ${table.externalPlacementId} is null
686
+ ) or (
687
+ ${table.placementKind} = 'attached_device'
688
+ and ${table.sandboxGroupId} is null
689
+ and ${table.connectedSandboxId} is null
690
+ and ${table.deviceId} is not null
691
+ and ${table.externalProviderId} is null
692
+ and ${table.externalPlacementId} is null
693
+ ) or (
694
+ ${table.placementKind} = 'external_provider'
695
+ and ${table.sandboxGroupId} is null
696
+ and ${table.connectedSandboxId} is null
697
+ and ${table.deviceId} is null
698
+ and ${table.externalProviderId} is not null
699
+ and ${table.externalPlacementId} is not null
700
+ and octet_length(${table.externalProviderId}) between 1 and 512
701
+ and octet_length(${table.externalPlacementId}) between 1 and 512
702
+ )`,
703
+ ),
704
+ controllerValid: check(
705
+ "browser_sessions_controller_check",
706
+ sql`(
707
+ ${table.controllerId} is null
708
+ and ${table.controllerGeneration} is null
709
+ and ${table.placementInstanceId} is null
710
+ and ${table.controllerHeartbeatAt} is null
711
+ ) or (
712
+ ${table.controllerId} is not null
713
+ and octet_length(${table.controllerId}) between 1 and 512
714
+ and ${table.controllerGeneration} is not null
715
+ and octet_length(${table.controllerGeneration}) between 1 and 256
716
+ and ${table.placementInstanceId} is not null
717
+ and octet_length(${table.placementInstanceId}) between 1 and 512
718
+ and ${table.controllerHeartbeatAt} is not null
719
+ )`,
720
+ ),
721
+ controllerHostValid: check(
722
+ "browser_sessions_controller_host_check",
723
+ sql`(
724
+ ${table.placementKind} = 'sandbox_group'
725
+ and ${table.controllerHostSandboxGroupId} = ${table.sandboxGroupId}
726
+ ) or (
727
+ ${table.placementKind} = 'external_provider'
728
+ and ${table.controllerHostSandboxGroupId} is not null
729
+ ) or (
730
+ ${table.placementKind} in ('connected_machine', 'attached_device')
731
+ and ${table.controllerHostSandboxGroupId} is null
732
+ )`,
733
+ ),
734
+ identityRevisionValid: check(
735
+ "browser_sessions_identity_revision_check",
736
+ sql`${table.baseRevisionId} is null or ${table.identityId} is not null`,
737
+ ),
738
+ failureValid: check(
739
+ "browser_sessions_failure_check",
740
+ sql`(
741
+ ${table.lifecycle} in ('repair_required', 'lost', 'failed')
742
+ and ${table.failureCode} is not null
743
+ ) or (
744
+ ${table.lifecycle} not in ('repair_required', 'lost', 'failed')
745
+ and ${table.failureCode} is null
746
+ )`,
747
+ ),
748
+ }),
749
+ );
750
+
751
+ export const browserSessionAssociations = pgTable(
752
+ "browser_session_associations",
753
+ {
754
+ id: uuid("id").primaryKey().defaultRandom(),
755
+ accountId: uuid("account_id").notNull(),
756
+ workspaceId: uuid("workspace_id").notNull(),
757
+ browserSessionId: uuid("browser_session_id").notNull(),
758
+ sessionId: uuid("session_id").notNull(),
759
+ turnId: uuid("turn_id"),
760
+ attemptId: uuid("attempt_id"),
761
+ relationship: text("relationship", {
762
+ enum: ["created", "using", "observing", "related"],
763
+ }).notNull(),
764
+ actorSubjectId: text("actor_subject_id").notNull(),
765
+ lastUsedAt: timestamp("last_used_at", { withTimezone: true }).notNull().defaultNow(),
766
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
767
+ },
768
+ (table) => ({
769
+ resourceSessionRelationship: uniqueIndex(
770
+ "browser_session_associations_resource_session_relationship_uq",
771
+ ).on(table.browserSessionId, table.sessionId, table.relationship),
772
+ workspaceSession: index("browser_session_associations_workspace_session_idx").on(
773
+ table.workspaceId,
774
+ table.sessionId,
775
+ table.lastUsedAt,
776
+ ),
777
+ resource: index("browser_session_associations_resource_idx").on(
778
+ table.workspaceId,
779
+ table.browserSessionId,
780
+ table.lastUsedAt,
781
+ ),
782
+ valuesValid: check(
783
+ "browser_session_associations_values_check",
784
+ sql`octet_length(${table.actorSubjectId}) between 1 and 1024
785
+ and (${table.attemptId} is null or ${table.turnId} is not null)`,
786
+ ),
787
+ }),
788
+ );
789
+
790
+ export const computerSessions = pgTable(
791
+ "computer_sessions",
792
+ {
793
+ id: uuid("id").primaryKey(),
794
+ accountId: uuid("account_id").notNull(),
795
+ workspaceId: uuid("workspace_id").notNull(),
796
+ name: text("name").notNull(),
797
+ lifecycle: text("lifecycle", { enum: interactionLifecycleValues })
798
+ .notNull()
799
+ .default("starting"),
800
+ placementKind: text("placement_kind", {
801
+ enum: ["sandbox_group", "connected_machine", "attached_device", "external_provider"],
802
+ }).notNull(),
803
+ sandboxGroupId: uuid("sandbox_group_id"),
804
+ connectedSandboxId: uuid("connected_sandbox_id"),
805
+ deviceId: uuid("device_id"),
806
+ externalProviderId: text("external_provider_id"),
807
+ externalPlacementId: text("external_placement_id"),
808
+ controllerId: text("controller_id"),
809
+ controllerGeneration: text("controller_generation"),
810
+ placementInstanceId: text("placement_instance_id"),
811
+ tokenGeneration: integer("token_generation").notNull().default(1),
812
+ platform: text("platform", { enum: ["linux", "macos", "windows"] }),
813
+ adapter: text("adapter"),
814
+ seatId: text("seat_id"),
815
+ displayId: text("display_id"),
816
+ capabilities: jsonb("capabilities").$type<ComputerSessionCapabilities>(),
817
+ createOperationId: uuid("create_operation_id").notNull(),
818
+ createdBySubjectId: text("created_by_subject_id").notNull(),
819
+ failureCode: text("failure_code"),
820
+ controllerHeartbeatAt: timestamp("controller_heartbeat_at", {
821
+ withTimezone: true,
822
+ }),
823
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
824
+ lastUsedAt: timestamp("last_used_at", { withTimezone: true }).notNull().defaultNow(),
825
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
826
+ },
827
+ (table) => ({
828
+ workspaceIdentity: uniqueIndex("computer_sessions_workspace_id_uq").on(
829
+ table.workspaceId,
830
+ table.id,
831
+ ),
832
+ createOperation: uniqueIndex("computer_sessions_workspace_create_operation_uq").on(
833
+ table.workspaceId,
834
+ table.createOperationId,
835
+ ),
836
+ workspaceLifecycle: index("computer_sessions_workspace_lifecycle_idx").on(
837
+ table.workspaceId,
838
+ table.lifecycle,
839
+ table.lastUsedAt,
840
+ table.id,
841
+ ),
842
+ sandboxGroup: index("computer_sessions_sandbox_group_idx").on(
843
+ table.workspaceId,
844
+ table.sandboxGroupId,
845
+ table.lifecycle,
846
+ ),
847
+ valuesValid: check(
848
+ "computer_sessions_values_check",
849
+ sql`octet_length(${table.name}) between 1 and 200
850
+ and ${table.name} = btrim(${table.name})
851
+ and octet_length(${table.createdBySubjectId}) between 1 and 1024
852
+ and ${table.tokenGeneration} > 0
853
+ and (${table.adapter} is null or octet_length(${table.adapter}) between 1 and 512)
854
+ and (${table.seatId} is null or octet_length(${table.seatId}) between 1 and 512)
855
+ and (${table.displayId} is null or octet_length(${table.displayId}) between 1 and 512)
856
+ and (${table.capabilities} is null or (
857
+ jsonb_typeof(${table.capabilities}) = 'object'
858
+ and octet_length(${table.capabilities}::text) between 2 and 65536
859
+ ))
860
+ and (${table.failureCode} is null or octet_length(${table.failureCode}) between 1 and 512)`,
861
+ ),
862
+ placementValid: check(
863
+ "computer_sessions_placement_check",
864
+ sql`(
865
+ ${table.placementKind} = 'sandbox_group'
866
+ and ${table.sandboxGroupId} is not null
867
+ and ${table.connectedSandboxId} is null
868
+ and ${table.deviceId} is null
869
+ and ${table.externalProviderId} is null
870
+ and ${table.externalPlacementId} is null
871
+ ) or (
872
+ ${table.placementKind} = 'connected_machine'
873
+ and ${table.sandboxGroupId} is null
874
+ and ${table.connectedSandboxId} is not null
875
+ and ${table.deviceId} is null
876
+ and ${table.externalProviderId} is null
877
+ and ${table.externalPlacementId} is null
878
+ ) or (
879
+ ${table.placementKind} = 'attached_device'
880
+ and ${table.sandboxGroupId} is null
881
+ and ${table.connectedSandboxId} is null
882
+ and ${table.deviceId} is not null
883
+ and ${table.externalProviderId} is null
884
+ and ${table.externalPlacementId} is null
885
+ ) or (
886
+ ${table.placementKind} = 'external_provider'
887
+ and ${table.sandboxGroupId} is null
888
+ and ${table.connectedSandboxId} is null
889
+ and ${table.deviceId} is null
890
+ and ${table.externalProviderId} is not null
891
+ and ${table.externalPlacementId} is not null
892
+ and octet_length(${table.externalProviderId}) between 1 and 512
893
+ and octet_length(${table.externalPlacementId}) between 1 and 512
894
+ )`,
895
+ ),
896
+ controllerValid: check(
897
+ "computer_sessions_controller_check",
898
+ sql`(
899
+ ${table.controllerId} is null
900
+ and ${table.controllerGeneration} is null
901
+ and ${table.placementInstanceId} is null
902
+ and ${table.controllerHeartbeatAt} is null
903
+ ) or (
904
+ ${table.controllerId} is not null
905
+ and octet_length(${table.controllerId}) between 1 and 512
906
+ and ${table.controllerGeneration} is not null
907
+ and octet_length(${table.controllerGeneration}) between 1 and 256
908
+ and ${table.placementInstanceId} is not null
909
+ and octet_length(${table.placementInstanceId}) between 1 and 512
910
+ and ${table.controllerHeartbeatAt} is not null
911
+ )`,
912
+ ),
913
+ nativeBindingValid: check(
914
+ "computer_sessions_native_binding_check",
915
+ sql`(
916
+ ${table.platform} is null
917
+ and ${table.adapter} is null
918
+ and ${table.seatId} is null
919
+ and ${table.displayId} is null
920
+ and ${table.capabilities} is null
921
+ ) or (
922
+ ${table.platform} is not null
923
+ and ${table.adapter} is not null
924
+ and ${table.seatId} is not null
925
+ and ${table.displayId} is not null
926
+ and ${table.capabilities} is not null
927
+ )`,
928
+ ),
929
+ activeValid: check(
930
+ "computer_sessions_active_binding_check",
931
+ sql`${table.lifecycle} <> 'active' or (
932
+ ${table.controllerId} is not null
933
+ and ${table.platform} is not null
934
+ and ${table.capabilities} is not null
935
+ )`,
936
+ ),
937
+ failureValid: check(
938
+ "computer_sessions_failure_check",
939
+ sql`(
940
+ ${table.lifecycle} in ('repair_required', 'lost', 'failed')
941
+ and ${table.failureCode} is not null
942
+ ) or (
943
+ ${table.lifecycle} not in ('repair_required', 'lost', 'failed')
944
+ and ${table.failureCode} is null
945
+ )`,
946
+ ),
947
+ }),
948
+ );
949
+
950
+ export const computerSessionAssociations = pgTable(
951
+ "computer_session_associations",
952
+ {
953
+ id: uuid("id").primaryKey().defaultRandom(),
954
+ accountId: uuid("account_id").notNull(),
955
+ workspaceId: uuid("workspace_id").notNull(),
956
+ computerSessionId: uuid("computer_session_id").notNull(),
957
+ sessionId: uuid("session_id").notNull(),
958
+ turnId: uuid("turn_id"),
959
+ attemptId: uuid("attempt_id"),
960
+ relationship: text("relationship", {
961
+ enum: ["created", "using", "observing", "related"],
962
+ }).notNull(),
963
+ actorSubjectId: text("actor_subject_id").notNull(),
964
+ lastUsedAt: timestamp("last_used_at", { withTimezone: true }).notNull().defaultNow(),
965
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
966
+ },
967
+ (table) => ({
968
+ resourceSessionRelationship: uniqueIndex(
969
+ "computer_session_associations_resource_session_relationship_uq",
970
+ ).on(table.computerSessionId, table.sessionId, table.relationship),
971
+ workspaceSession: index("computer_session_associations_workspace_session_idx").on(
972
+ table.workspaceId,
973
+ table.sessionId,
974
+ table.lastUsedAt,
975
+ ),
976
+ resource: index("computer_session_associations_resource_idx").on(
977
+ table.workspaceId,
978
+ table.computerSessionId,
979
+ table.lastUsedAt,
980
+ ),
981
+ valuesValid: check(
982
+ "computer_session_associations_values_check",
983
+ sql`octet_length(${table.actorSubjectId}) between 1 and 1024
984
+ and (${table.attemptId} is null or ${table.turnId} is not null)`,
985
+ ),
986
+ }),
987
+ );
988
+
989
+ export const networkRoutes = pgTable(
990
+ "network_routes",
991
+ {
992
+ id: uuid("id").primaryKey().defaultRandom(),
993
+ accountId: uuid("account_id").notNull(),
994
+ workspaceId: uuid("workspace_id").notNull(),
995
+ name: text("name").notNull(),
996
+ status: text("status", { enum: ["active", "archived"] })
997
+ .notNull()
998
+ .default("active"),
999
+ configuration: jsonb("configuration").$type<NetworkRouteConfiguration>().notNull(),
1000
+ consistency: jsonb("consistency").$type<NetworkRouteConsistency>().notNull(),
1001
+ version: bigint("version", { mode: "number" }).notNull().default(1),
1002
+ createOperationId: uuid("create_operation_id").notNull(),
1003
+ createdBySubjectId: text("created_by_subject_id").notNull(),
1004
+ updatedBySubjectId: text("updated_by_subject_id").notNull(),
1005
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1006
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1007
+ },
1008
+ (table) => ({
1009
+ workspaceIdentity: uniqueIndex("network_routes_workspace_id_uq").on(
1010
+ table.workspaceId,
1011
+ table.id,
1012
+ ),
1013
+ createOperation: uniqueIndex("network_routes_workspace_create_operation_uq").on(
1014
+ table.workspaceId,
1015
+ table.createOperationId,
1016
+ ),
1017
+ activeName: uniqueIndex("network_routes_workspace_active_name_uq")
1018
+ .on(table.workspaceId, sql`lower(${table.name})`)
1019
+ .where(sql`${table.status} = 'active'`),
1020
+ discovery: index("network_routes_workspace_status_updated_idx").on(
1021
+ table.workspaceId,
1022
+ table.status,
1023
+ table.updatedAt,
1024
+ table.id,
1025
+ ),
1026
+ valuesValid: check(
1027
+ "network_routes_values_check",
1028
+ sql`octet_length(${table.name}) between 1 and 200
1029
+ and ${table.name} = btrim(${table.name})
1030
+ and jsonb_typeof(${table.configuration}) = 'object'
1031
+ and octet_length(${table.configuration}::text) between 2 and 65536
1032
+ and jsonb_typeof(${table.consistency}) = 'object'
1033
+ and octet_length(${table.consistency}::text) between 2 and 65536
1034
+ and ${table.version} > 0
1035
+ and octet_length(${table.createdBySubjectId}) between 1 and 1024
1036
+ and octet_length(${table.updatedBySubjectId}) between 1 and 1024`,
1037
+ ),
1038
+ }),
1039
+ );
1040
+
1041
+ export const siteAuthConnections = pgTable(
1042
+ "site_auth_connections",
1043
+ {
1044
+ id: uuid("id").primaryKey().defaultRandom(),
1045
+ accountId: uuid("account_id").notNull(),
1046
+ workspaceId: uuid("workspace_id").notNull(),
1047
+ name: text("name").notNull(),
1048
+ accountLabel: text("account_label").notNull(),
1049
+ status: text("status", { enum: ["active", "archived"] })
1050
+ .notNull()
1051
+ .default("active"),
1052
+ origins: jsonb("origins").$type<string[]>().notNull(),
1053
+ loginUrl: text("login_url"),
1054
+ verificationUrlPrefixes: jsonb("verification_url_prefixes").$type<string[]>().notNull(),
1055
+ authorities: jsonb("authorities").$type<SiteAuthAuthority[]>().notNull(),
1056
+ methods: jsonb("methods").$type<SiteAuthMethod[]>().notNull(),
1057
+ preferredIdentityId: uuid("preferred_identity_id"),
1058
+ preferredPlacement: jsonb("preferred_placement").$type<InteractionPlacement>(),
1059
+ preferredNetworkRouteId: uuid("preferred_network_route_id"),
1060
+ healthPolicy: jsonb("health_policy").$type<SiteAuthHealthPolicy>().notNull(),
1061
+ verificationState: text("verification_state", {
1062
+ enum: ["unknown", "verified", "needs_repair", "failed"],
1063
+ })
1064
+ .notNull()
1065
+ .default("unknown"),
1066
+ lastVerifiedAt: timestamp("last_verified_at", { withTimezone: true }),
1067
+ lastVerifiedUrl: text("last_verified_url"),
1068
+ lastCheckedAt: timestamp("last_checked_at", { withTimezone: true }),
1069
+ nextCheckAt: timestamp("next_check_at", { withTimezone: true }),
1070
+ maintenanceOperationId: uuid("maintenance_operation_id"),
1071
+ maintenanceAction: text("maintenance_action", { enum: ["health_check", "repair"] }),
1072
+ maintenanceDueAt: timestamp("maintenance_due_at", { withTimezone: true }),
1073
+ maintenanceClaimedAt: timestamp("maintenance_claimed_at", { withTimezone: true }),
1074
+ maintenanceSessionId: uuid("maintenance_session_id"),
1075
+ maintenanceStartedAt: timestamp("maintenance_started_at", { withTimezone: true }),
1076
+ healthSequence: bigint("health_sequence", { mode: "number" }).notNull().default(0),
1077
+ repairCode: text("repair_code"),
1078
+ version: bigint("version", { mode: "number" }).notNull().default(1),
1079
+ createOperationId: uuid("create_operation_id").notNull(),
1080
+ createdBySubjectId: text("created_by_subject_id").notNull(),
1081
+ updatedBySubjectId: text("updated_by_subject_id").notNull(),
1082
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1083
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1084
+ },
1085
+ (table) => ({
1086
+ workspaceIdentity: uniqueIndex("site_auth_connections_workspace_id_uq").on(
1087
+ table.workspaceId,
1088
+ table.id,
1089
+ ),
1090
+ createOperation: uniqueIndex("site_auth_connections_workspace_create_operation_uq").on(
1091
+ table.workspaceId,
1092
+ table.createOperationId,
1093
+ ),
1094
+ activeName: uniqueIndex("site_auth_connections_workspace_active_name_uq")
1095
+ .on(table.workspaceId, sql`lower(${table.name})`)
1096
+ .where(sql`${table.status} = 'active'`),
1097
+ discovery: index("site_auth_connections_workspace_status_updated_idx").on(
1098
+ table.workspaceId,
1099
+ table.status,
1100
+ table.updatedAt,
1101
+ table.id,
1102
+ ),
1103
+ maintenance: index("site_auth_connections_health_maintenance_idx").on(
1104
+ table.nextCheckAt,
1105
+ table.maintenanceClaimedAt,
1106
+ table.id,
1107
+ ),
1108
+ valuesValid: check(
1109
+ "site_auth_connections_values_check",
1110
+ sql`octet_length(${table.name}) between 1 and 200
1111
+ and ${table.name} = btrim(${table.name})
1112
+ and octet_length(${table.accountLabel}) between 1 and 200
1113
+ and ${table.accountLabel} = btrim(${table.accountLabel})
1114
+ and jsonb_typeof(${table.origins}) = 'array'
1115
+ and octet_length(${table.origins}::text) between 3 and 65536
1116
+ and (${table.loginUrl} is null or octet_length(${table.loginUrl}) between 1 and 16384)
1117
+ and jsonb_typeof(${table.verificationUrlPrefixes}) = 'array'
1118
+ and octet_length(${table.verificationUrlPrefixes}::text) between 2 and 65536
1119
+ and jsonb_typeof(${table.authorities}) = 'array'
1120
+ and octet_length(${table.authorities}::text) between 3 and 65536
1121
+ and jsonb_typeof(${table.methods}) = 'array'
1122
+ and octet_length(${table.methods}::text) between 3 and 65536
1123
+ and (${table.preferredPlacement} is null or (
1124
+ jsonb_typeof(${table.preferredPlacement}) = 'object'
1125
+ and octet_length(${table.preferredPlacement}::text) between 2 and 65536
1126
+ ))
1127
+ and jsonb_typeof(${table.healthPolicy}) = 'object'
1128
+ and octet_length(${table.healthPolicy}::text) between 2 and 65536
1129
+ and (${table.lastVerifiedUrl} is null or octet_length(${table.lastVerifiedUrl}) between 1 and 16384)
1130
+ and (${table.repairCode} is null or octet_length(${table.repairCode}) between 1 and 512)
1131
+ and ${table.version} > 0
1132
+ and octet_length(${table.createdBySubjectId}) between 1 and 1024
1133
+ and octet_length(${table.updatedBySubjectId}) between 1 and 1024`,
1134
+ ),
1135
+ verificationValid: check(
1136
+ "site_auth_connections_verification_check",
1137
+ sql`(
1138
+ ${table.verificationState} = 'verified'
1139
+ and ${table.lastVerifiedAt} is not null
1140
+ and ${table.lastVerifiedUrl} is not null
1141
+ and ${table.repairCode} is null
1142
+ ) or (
1143
+ ${table.verificationState} = 'unknown'
1144
+ and ${table.lastVerifiedAt} is null
1145
+ and ${table.lastVerifiedUrl} is null
1146
+ and ${table.repairCode} is null
1147
+ ) or (
1148
+ ${table.verificationState} in ('needs_repair', 'failed')
1149
+ and ${table.repairCode} is not null
1150
+ )`,
1151
+ ),
1152
+ healthValid: check(
1153
+ "site_auth_connections_health_check",
1154
+ sql`(
1155
+ (
1156
+ ${table.healthSequence} = 0
1157
+ and ${table.lastCheckedAt} is null
1158
+ ) or (
1159
+ ${table.healthSequence} > 0
1160
+ and ${table.lastCheckedAt} is not null
1161
+ )
1162
+ ) and (
1163
+ (
1164
+ ${table.status} = 'active'
1165
+ and ${table.healthPolicy}->>'mode' = 'maintained'
1166
+ and ${table.nextCheckAt} is not null
1167
+ ) or (
1168
+ not (${table.status} = 'active' and ${table.healthPolicy}->>'mode' = 'maintained')
1169
+ and ${table.nextCheckAt} is null
1170
+ )
1171
+ )`,
1172
+ ),
1173
+ maintenanceValid: check(
1174
+ "site_auth_connections_maintenance_check",
1175
+ sql`(
1176
+ ${table.maintenanceOperationId} is null
1177
+ and ${table.maintenanceAction} is null
1178
+ and ${table.maintenanceDueAt} is null
1179
+ and ${table.maintenanceClaimedAt} is null
1180
+ and ${table.maintenanceSessionId} is null
1181
+ and ${table.maintenanceStartedAt} is null
1182
+ ) or (
1183
+ ${table.status} = 'active'
1184
+ and ${table.healthPolicy}->>'mode' = 'maintained'
1185
+ and ${table.maintenanceOperationId} is not null
1186
+ and ${table.maintenanceAction} in ('health_check', 'repair')
1187
+ and ${table.maintenanceDueAt} is not null
1188
+ and ${table.maintenanceClaimedAt} is not null
1189
+ and ${table.maintenanceSessionId} is not null
1190
+ and (
1191
+ ${table.maintenanceStartedAt} is null
1192
+ or ${table.maintenanceStartedAt} >= ${table.maintenanceDueAt}
1193
+ )
1194
+ )`,
1195
+ ),
1196
+ }),
1197
+ );
1198
+
1199
+ export const authRuns = pgTable(
1200
+ "auth_runs",
1201
+ {
1202
+ id: uuid("id").primaryKey().defaultRandom(),
1203
+ accountId: uuid("account_id").notNull(),
1204
+ workspaceId: uuid("workspace_id").notNull(),
1205
+ siteAuthConnectionId: uuid("site_auth_connection_id").notNull(),
1206
+ browserSessionId: uuid("browser_session_id").notNull(),
1207
+ targetId: text("target_id").notNull(),
1208
+ controllerGeneration: text("controller_generation").notNull(),
1209
+ targetGeneration: text("target_generation").notNull(),
1210
+ documentGeneration: text("document_generation"),
1211
+ purpose: text("purpose", { enum: ["authenticate", "health_check", "repair"] })
1212
+ .notNull()
1213
+ .default("authenticate"),
1214
+ healthSequence: bigint("health_sequence", { mode: "number" })
1215
+ .notNull()
1216
+ .default(sql`nextval('auth_runs_health_sequence_seq'::regclass)`),
1217
+ maintenanceOperationId: uuid("maintenance_operation_id"),
1218
+ methodId: text("method_id"),
1219
+ authorityId: text("authority_id"),
1220
+ state: text("state", {
1221
+ enum: [
1222
+ "discovering",
1223
+ "awaiting_choice",
1224
+ "awaiting_secret",
1225
+ "awaiting_external_action",
1226
+ "working",
1227
+ "verified",
1228
+ "failed",
1229
+ "cancelled",
1230
+ ],
1231
+ })
1232
+ .notNull()
1233
+ .default("discovering"),
1234
+ choices: jsonb("choices").$type<AuthRunChoice[]>().notNull().default([]),
1235
+ pendingFields: jsonb("pending_fields").$type<AuthRunPendingField[]>().notNull().default([]),
1236
+ externalAction: jsonb("external_action").$type<AuthRunExternalAction>(),
1237
+ interventionId: uuid("intervention_id"),
1238
+ verifiedUrl: text("verified_url"),
1239
+ failureCode: text("failure_code"),
1240
+ version: bigint("version", { mode: "number" }).notNull().default(1),
1241
+ operationId: uuid("operation_id").notNull(),
1242
+ createdBySubjectId: text("created_by_subject_id").notNull(),
1243
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1244
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1245
+ settledAt: timestamp("settled_at", { withTimezone: true }),
1246
+ },
1247
+ (table) => ({
1248
+ workspaceIdentity: uniqueIndex("auth_runs_workspace_id_uq").on(table.workspaceId, table.id),
1249
+ operation: uniqueIndex("auth_runs_workspace_operation_uq").on(
1250
+ table.workspaceId,
1251
+ table.operationId,
1252
+ ),
1253
+ activeTarget: uniqueIndex("auth_runs_active_browser_target_uq")
1254
+ .on(table.workspaceId, table.browserSessionId, table.targetId)
1255
+ .where(sql`${table.settledAt} is null`),
1256
+ browserHistory: index("auth_runs_browser_history_idx").on(
1257
+ table.workspaceId,
1258
+ table.browserSessionId,
1259
+ table.createdAt,
1260
+ ),
1261
+ siteHistory: index("auth_runs_site_history_idx").on(
1262
+ table.workspaceId,
1263
+ table.siteAuthConnectionId,
1264
+ table.createdAt,
1265
+ ),
1266
+ maintenanceOperation: uniqueIndex("auth_runs_workspace_maintenance_operation_uq")
1267
+ .on(table.workspaceId, table.maintenanceOperationId)
1268
+ .where(sql`${table.maintenanceOperationId} is not null`),
1269
+ valuesValid: check(
1270
+ "auth_runs_values_check",
1271
+ sql`octet_length(${table.targetId}) between 1 and 512
1272
+ and octet_length(${table.controllerGeneration}) between 1 and 256
1273
+ and octet_length(${table.targetGeneration}) between 1 and 256
1274
+ and (${table.documentGeneration} is null or octet_length(${table.documentGeneration}) between 1 and 256)
1275
+ and (${table.methodId} is null or octet_length(${table.methodId}) between 1 and 512)
1276
+ and (${table.authorityId} is null or octet_length(${table.authorityId}) between 1 and 512)
1277
+ and jsonb_typeof(${table.choices}) = 'array'
1278
+ and octet_length(${table.choices}::text) between 2 and 65536
1279
+ and jsonb_typeof(${table.pendingFields}) = 'array'
1280
+ and octet_length(${table.pendingFields}::text) between 2 and 65536
1281
+ and (${table.externalAction} is null or (
1282
+ jsonb_typeof(${table.externalAction}) = 'object'
1283
+ and octet_length(${table.externalAction}::text) between 2 and 65536
1284
+ ))
1285
+ and (${table.verifiedUrl} is null or octet_length(${table.verifiedUrl}) between 1 and 16384)
1286
+ and (${table.failureCode} is null or octet_length(${table.failureCode}) between 1 and 512)
1287
+ and ${table.version} > 0
1288
+ and octet_length(${table.createdBySubjectId}) between 1 and 1024`,
1289
+ ),
1290
+ healthEvidenceValid: check(
1291
+ "auth_runs_health_evidence_check",
1292
+ sql`${table.purpose} in ('authenticate', 'health_check', 'repair')
1293
+ and ${table.healthSequence} > 0`,
1294
+ ),
1295
+ maintenanceValid: check(
1296
+ "auth_runs_maintenance_check",
1297
+ sql`${table.maintenanceOperationId} is null
1298
+ or ${table.purpose} in ('health_check', 'repair')`,
1299
+ ),
1300
+ lifecycleValid: check(
1301
+ "auth_runs_lifecycle_check",
1302
+ sql`(
1303
+ ${table.state} = 'verified'
1304
+ and ${table.verifiedUrl} is not null
1305
+ and ${table.failureCode} is null
1306
+ and ${table.settledAt} is not null
1307
+ ) or (
1308
+ ${table.state} = 'failed'
1309
+ and ${table.verifiedUrl} is null
1310
+ and ${table.failureCode} is not null
1311
+ and ${table.settledAt} is not null
1312
+ ) or (
1313
+ ${table.state} = 'cancelled'
1314
+ and ${table.verifiedUrl} is null
1315
+ and ${table.settledAt} is not null
1316
+ ) or (
1317
+ ${table.state} not in ('verified', 'failed', 'cancelled')
1318
+ and ${table.verifiedUrl} is null
1319
+ and ${table.failureCode} is null
1320
+ and ${table.settledAt} is null
1321
+ )`,
1322
+ ),
1323
+ projectionValid: check(
1324
+ "auth_runs_projection_check",
1325
+ sql`(${table.state} = 'awaiting_choice') = (jsonb_array_length(${table.choices}) > 0)
1326
+ and (${table.state} = 'awaiting_secret') = (jsonb_array_length(${table.pendingFields}) > 0)
1327
+ and (${table.state} = 'awaiting_external_action') = (${table.externalAction} is not null)
1328
+ and (${table.state} = 'failed') = (${table.failureCode} is not null)`,
1329
+ ),
1330
+ }),
1331
+ );
1332
+
1333
+ export const interactionInterventions = pgTable(
1334
+ "interaction_interventions",
1335
+ {
1336
+ id: uuid("id").primaryKey().defaultRandom(),
1337
+ accountId: uuid("account_id").notNull(),
1338
+ workspaceId: uuid("workspace_id").notNull(),
1339
+ resourceKind: text("resource_kind", {
1340
+ enum: ["browser_session", "computer_session"],
1341
+ }).notNull(),
1342
+ resourceId: uuid("resource_id").notNull(),
1343
+ targetId: text("target_id").notNull(),
1344
+ controllerGeneration: text("controller_generation").notNull(),
1345
+ targetGeneration: text("target_generation").notNull(),
1346
+ documentGeneration: text("document_generation"),
1347
+ kind: text("kind", {
1348
+ enum: ["manual_login", "mfa", "external_action", "confirmation", "other"],
1349
+ }).notNull(),
1350
+ reason: text("reason").notNull(),
1351
+ status: text("status", {
1352
+ enum: ["open", "completed", "dismissed", "expired", "cancelled"],
1353
+ })
1354
+ .notNull()
1355
+ .default("open"),
1356
+ authRunId: uuid("auth_run_id"),
1357
+ originatingSessionId: uuid("originating_session_id").notNull(),
1358
+ originatingTurnId: uuid("originating_turn_id"),
1359
+ originatingAttemptId: uuid("originating_attempt_id"),
1360
+ originatingToolOperationId: uuid("originating_tool_operation_id"),
1361
+ originatingToolCallId: text("originating_tool_call_id"),
1362
+ responseActorSubjectId: text("response_actor_subject_id"),
1363
+ version: bigint("version", { mode: "number" }).notNull().default(1),
1364
+ operationId: uuid("operation_id").notNull(),
1365
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
1366
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1367
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1368
+ settledAt: timestamp("settled_at", { withTimezone: true }),
1369
+ },
1370
+ (table) => ({
1371
+ workspaceIdentity: uniqueIndex("interaction_interventions_workspace_id_uq").on(
1372
+ table.workspaceId,
1373
+ table.id,
1374
+ ),
1375
+ operation: uniqueIndex("interaction_interventions_workspace_operation_uq").on(
1376
+ table.workspaceId,
1377
+ table.operationId,
1378
+ ),
1379
+ originatingToolCall: uniqueIndex("interaction_interventions_originating_tool_call_uq")
1380
+ .on(
1381
+ table.workspaceId,
1382
+ table.originatingSessionId,
1383
+ table.originatingTurnId,
1384
+ table.originatingToolCallId,
1385
+ )
1386
+ .where(sql`${table.originatingToolCallId} is not null`),
1387
+ openResource: index("interaction_interventions_open_resource_idx").on(
1388
+ table.workspaceId,
1389
+ table.resourceKind,
1390
+ table.resourceId,
1391
+ table.status,
1392
+ table.createdAt,
1393
+ ),
1394
+ openTargetKind: uniqueIndex("interaction_interventions_open_target_kind_uq")
1395
+ .on(table.workspaceId, table.resourceKind, table.resourceId, table.targetId, table.kind)
1396
+ .where(sql`${table.status} = 'open'`),
1397
+ openAuthRun: uniqueIndex("interaction_interventions_open_auth_run_uq")
1398
+ .on(table.workspaceId, table.authRunId)
1399
+ .where(sql`${table.status} = 'open' and ${table.authRunId} is not null`),
1400
+ valuesValid: check(
1401
+ "interaction_interventions_values_check",
1402
+ sql`octet_length(${table.targetId}) between 1 and 512
1403
+ and octet_length(${table.controllerGeneration}) between 1 and 256
1404
+ and octet_length(${table.targetGeneration}) between 1 and 256
1405
+ and (${table.documentGeneration} is null or octet_length(${table.documentGeneration}) between 1 and 256)
1406
+ and octet_length(${table.reason}) between 1 and 2048
1407
+ and ${table.reason} = btrim(${table.reason})
1408
+ and (${table.originatingAttemptId} is null or ${table.originatingTurnId} is not null)
1409
+ and (${table.originatingToolOperationId} is null or ${table.originatingAttemptId} is not null)
1410
+ and (${table.originatingToolCallId} is null or (
1411
+ ${table.originatingAttemptId} is not null
1412
+ and octet_length(${table.originatingToolCallId}) between 1 and 1024
1413
+ ))
1414
+ and (${table.responseActorSubjectId} is null or octet_length(${table.responseActorSubjectId}) between 1 and 1024)
1415
+ and ${table.version} > 0`,
1416
+ ),
1417
+ lifecycleValid: check(
1418
+ "interaction_interventions_lifecycle_check",
1419
+ sql`(
1420
+ ${table.status} = 'open'
1421
+ and ${table.responseActorSubjectId} is null
1422
+ and ${table.settledAt} is null
1423
+ ) or (
1424
+ ${table.status} <> 'open'
1425
+ and ${table.settledAt} is not null
1426
+ )`,
1427
+ ),
1428
+ }),
1429
+ );
1430
+
1431
+ export const interactionResourceOperations = pgTable(
1432
+ "interaction_resource_operations",
1433
+ {
1434
+ operationId: uuid("operation_id").primaryKey(),
1435
+ accountId: uuid("account_id").notNull(),
1436
+ workspaceId: uuid("workspace_id").notNull(),
1437
+ resourceKind: text("resource_kind", {
1438
+ enum: [
1439
+ "browser_identity",
1440
+ "network_route",
1441
+ "site_auth_connection",
1442
+ "auth_run",
1443
+ "intervention",
1444
+ "browser_download",
1445
+ ],
1446
+ }).notNull(),
1447
+ resourceId: uuid("resource_id").notNull(),
1448
+ kind: text("kind", {
1449
+ enum: [
1450
+ "create",
1451
+ "update",
1452
+ "start",
1453
+ "report",
1454
+ "protected_fill",
1455
+ "external_auth",
1456
+ "verify",
1457
+ "resolve",
1458
+ "save",
1459
+ ],
1460
+ }).notNull(),
1461
+ requestDigest: text("request_digest").notNull(),
1462
+ metadata: jsonb("metadata").$type<Record<string, unknown>>().notNull().default({}),
1463
+ state: text("state", {
1464
+ enum: ["prepared", "dispatched", "completed", "failed", "outcome_unknown"],
1465
+ })
1466
+ .notNull()
1467
+ .default("completed"),
1468
+ resultVersion: bigint("result_version", { mode: "number" }),
1469
+ result: jsonb("result").$type<Record<string, unknown>>(),
1470
+ errorCode: text("error_code"),
1471
+ actorSubjectId: text("actor_subject_id").notNull(),
1472
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1473
+ settledAt: timestamp("settled_at", { withTimezone: true }),
1474
+ },
1475
+ (table) => ({
1476
+ workspaceOperation: uniqueIndex("interaction_resource_operations_workspace_operation_uq").on(
1477
+ table.workspaceId,
1478
+ table.operationId,
1479
+ ),
1480
+ resourceHistory: index("interaction_resource_operations_resource_history_idx").on(
1481
+ table.workspaceId,
1482
+ table.resourceKind,
1483
+ table.resourceId,
1484
+ table.createdAt,
1485
+ ),
1486
+ valuesValid: check(
1487
+ "interaction_resource_operations_values_check",
1488
+ sql`${table.requestDigest} ~ '^[0-9a-f]{64}$'
1489
+ and jsonb_typeof(${table.metadata}) = 'object'
1490
+ and octet_length(${table.metadata}::text) between 2 and 65536
1491
+ and (${table.resultVersion} is null or ${table.resultVersion} > 0)
1492
+ and (${table.result} is null or (
1493
+ jsonb_typeof(${table.result}) = 'object'
1494
+ and octet_length(${table.result}::text) between 2 and 262144
1495
+ ))
1496
+ and (${table.errorCode} is null or octet_length(${table.errorCode}) between 1 and 512)
1497
+ and octet_length(${table.actorSubjectId}) between 1 and 1024`,
1498
+ ),
1499
+ lifecycleValid: check(
1500
+ "interaction_resource_operations_lifecycle_check",
1501
+ sql`(
1502
+ ${table.state} = 'completed'
1503
+ and ${table.resultVersion} is not null
1504
+ and ${table.result} is not null
1505
+ and ${table.errorCode} is null
1506
+ and ${table.settledAt} is not null
1507
+ ) or (
1508
+ ${table.state} in ('failed', 'outcome_unknown')
1509
+ and ${table.resultVersion} is null
1510
+ and ${table.result} is null
1511
+ and ${table.errorCode} is not null
1512
+ and ${table.settledAt} is not null
1513
+ ) or (
1514
+ ${table.state} in ('prepared', 'dispatched')
1515
+ and ${table.resultVersion} is null
1516
+ and ${table.result} is null
1517
+ and ${table.errorCode} is null
1518
+ and ${table.settledAt} is null
1519
+ )`,
1520
+ ),
1521
+ }),
1522
+ );
1523
+
1524
+ export const interactionOperations = pgTable(
1525
+ "interaction_operations",
1526
+ {
1527
+ operationId: uuid("operation_id").primaryKey(),
1528
+ accountId: uuid("account_id").notNull(),
1529
+ workspaceId: uuid("workspace_id").notNull(),
1530
+ resourceKind: text("resource_kind", {
1531
+ enum: ["browser_session", "computer_session"],
1532
+ }).notNull(),
1533
+ resourceId: uuid("resource_id").notNull(),
1534
+ kind: text("kind", { enum: interactionOperationKindValues }).notNull(),
1535
+ requestDigest: text("request_digest").notNull(),
1536
+ state: text("state", { enum: interactionOperationStateValues }).notNull().default("prepared"),
1537
+ controllerGeneration: text("controller_generation"),
1538
+ errorCode: text("error_code"),
1539
+ errorMessage: text("error_message"),
1540
+ errorRetryable: boolean("error_retryable"),
1541
+ errorDetails: jsonb("error_details").$type<Record<string, unknown>>(),
1542
+ actorSubjectId: text("actor_subject_id").notNull(),
1543
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
1544
+ dispatchedAt: timestamp("dispatched_at", { withTimezone: true }),
1545
+ settledAt: timestamp("settled_at", { withTimezone: true }),
1546
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
1547
+ },
1548
+ (table) => ({
1549
+ workspaceOperation: uniqueIndex("interaction_operations_workspace_operation_uq").on(
1550
+ table.workspaceId,
1551
+ table.operationId,
1552
+ ),
1553
+ resourceHistory: index("interaction_operations_resource_history_idx").on(
1554
+ table.workspaceId,
1555
+ table.resourceKind,
1556
+ table.resourceId,
1557
+ table.createdAt,
1558
+ ),
1559
+ activeResource: uniqueIndex("interaction_operations_active_resource_uq")
1560
+ .on(table.workspaceId, table.resourceKind, table.resourceId)
1561
+ .where(sql`${table.state} in ('prepared', 'dispatched')`),
1562
+ valuesValid: check(
1563
+ "interaction_operations_values_check",
1564
+ sql`${table.requestDigest} ~ '^[0-9a-f]{64}$'
1565
+ and octet_length(${table.actorSubjectId}) between 1 and 1024
1566
+ and (${table.controllerGeneration} is null or octet_length(${table.controllerGeneration}) between 1 and 256)
1567
+ and (${table.errorCode} is null or octet_length(${table.errorCode}) between 1 and 512)
1568
+ and (${table.errorMessage} is null or octet_length(${table.errorMessage}) between 1 and 8192)
1569
+ and (${table.errorDetails} is null or octet_length(${table.errorDetails}::text) between 2 and 65536)`,
1570
+ ),
1571
+ lifecycleValid: check(
1572
+ "interaction_operations_lifecycle_check",
1573
+ sql`(
1574
+ ${table.state} = 'prepared'
1575
+ and ${table.dispatchedAt} is null
1576
+ and ${table.settledAt} is null
1577
+ and ${table.errorCode} is null
1578
+ and ${table.errorMessage} is null
1579
+ and ${table.errorRetryable} is null
1580
+ and ${table.errorDetails} is null
1581
+ ) or (
1582
+ ${table.state} = 'dispatched'
1583
+ and ${table.dispatchedAt} is not null
1584
+ and ${table.settledAt} is null
1585
+ and ${table.errorCode} is null
1586
+ and ${table.errorMessage} is null
1587
+ and ${table.errorRetryable} is null
1588
+ and ${table.errorDetails} is null
1589
+ ) or (
1590
+ ${table.state} = 'completed'
1591
+ and ${table.dispatchedAt} is not null
1592
+ and ${table.settledAt} is not null
1593
+ and ${table.errorCode} is null
1594
+ and ${table.errorMessage} is null
1595
+ and ${table.errorRetryable} is null
1596
+ and ${table.errorDetails} is null
1597
+ ) or (
1598
+ ${table.state} in ('failed', 'outcome_unknown')
1599
+ and ${table.settledAt} is not null
1600
+ and ${table.errorCode} is not null
1601
+ and ${table.errorMessage} is not null
1602
+ and ${table.errorRetryable} is not null
1603
+ )`,
1604
+ ),
1605
+ }),
1606
+ );