@opengeni/db 0.28.1 → 0.31.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 (187) 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 +91 -0
  4. package/dist/browser-identities.d.ts +128 -0
  5. package/dist/browser-sessions.d.ts +272 -0
  6. package/dist/browser-state-artifacts.d.ts +17 -0
  7. package/dist/capability-components.d.ts +37 -0
  8. package/dist/capability-integrations.d.ts +192 -0
  9. package/dist/chunk-F5FT7BEZ.js +3535 -0
  10. package/dist/chunk-F5FT7BEZ.js.map +1 -0
  11. package/dist/chunk-ISI2TIUG.js +639 -0
  12. package/dist/chunk-ISI2TIUG.js.map +1 -0
  13. package/dist/chunk-MWDVXQOL.js +11639 -0
  14. package/dist/chunk-MWDVXQOL.js.map +1 -0
  15. package/dist/chunk-NBE6CHRI.js +955 -0
  16. package/dist/chunk-NBE6CHRI.js.map +1 -0
  17. package/dist/{chunk-DBS5HPEW.js → chunk-YHZXQ7HP.js} +760 -11
  18. package/dist/chunk-YHZXQ7HP.js.map +1 -0
  19. package/dist/codemode-operations.d.ts +117 -0
  20. package/dist/codex-token-resolver.d.ts +2 -2
  21. package/dist/company-profile-schema.d.ts +798 -0
  22. package/dist/company-profile.d.ts +268 -0
  23. package/dist/computer-sessions.d.ts +109 -0
  24. package/dist/connection-token-resolver.d.ts +9 -4
  25. package/dist/database.d.ts +52 -3
  26. package/dist/editable-artifact-durable-export.d.ts +153 -0
  27. package/dist/editable-artifact-durable-export.js +788 -0
  28. package/dist/editable-artifact-durable-export.js.map +1 -0
  29. package/dist/editable-artifact-materialization.d.ts +123 -0
  30. package/dist/editable-artifacts-schema.d.ts +4152 -0
  31. package/dist/editable-artifacts.d.ts +610 -0
  32. package/dist/editable-artifacts.js +26 -0
  33. package/dist/editable-artifacts.js.map +1 -0
  34. package/dist/environment-crypto.d.ts +8 -4
  35. package/dist/generated-images.d.ts +139 -0
  36. package/dist/index.d.ts +958 -126
  37. package/dist/index.js +31204 -12172
  38. package/dist/index.js.map +1 -1
  39. package/dist/insights.d.ts +51 -4
  40. package/dist/integration-bindings.d.ts +70 -0
  41. package/dist/integration-features.d.ts +99 -0
  42. package/dist/interaction-revisions.d.ts +3 -0
  43. package/dist/interaction-schema.d.ts +5372 -0
  44. package/dist/knowledge-source-sync-schema.d.ts +1679 -0
  45. package/dist/knowledge-source-sync.d.ts +274 -0
  46. package/dist/lossless-columns.d.ts +58 -0
  47. package/dist/lossless-json.d.ts +39 -0
  48. package/dist/memory-domain.d.ts +3 -6
  49. package/dist/memory-governance.d.ts +2 -2
  50. package/dist/memory-slack-delivery.d.ts +101 -0
  51. package/dist/new-session-drafts.d.ts +2 -2
  52. package/dist/pack-components.d.ts +76 -0
  53. package/dist/pack-installations.d.ts +86 -0
  54. package/dist/persistence-errors.d.ts +7 -14
  55. package/dist/plugin-packages.d.ts +126 -0
  56. package/dist/preference-registry.d.ts +1 -1
  57. package/dist/provision-roles.d.ts +9 -1
  58. package/dist/provision-roles.js +1 -1
  59. package/dist/runtime-posture.d.ts +18 -6
  60. package/dist/schema.d.ts +19122 -8731
  61. package/dist/schema.js +173 -1
  62. package/dist/scoped-knowledge.d.ts +97 -1
  63. package/dist/session-control.d.ts +4 -4
  64. package/dist/session-queue-commands.d.ts +19 -11
  65. package/dist/session-realtime-context.d.ts +2 -2
  66. package/dist/session-realtime-ledger.d.ts +4 -4
  67. package/dist/session-realtime-mirror.d.ts +2 -2
  68. package/dist/session-realtime-state.d.ts +1 -1
  69. package/dist/session-realtime-terminal.d.ts +8 -1
  70. package/dist/session-realtime.d.ts +7 -7
  71. package/dist/session-tool-call-settlement.d.ts +1 -1
  72. package/dist/slack-user-link-access.d.ts +54 -0
  73. package/dist/transcription-recordings-schema.d.ts +44 -6
  74. package/dist/transcription-recordings.d.ts +3 -3
  75. package/dist/turn-initiator.d.ts +2 -2
  76. package/dist/video-generation.d.ts +216 -0
  77. package/dist/video-generation.js +66 -0
  78. package/dist/video-generation.js.map +1 -0
  79. package/dist/workspace-artifacts.d.ts +1 -1
  80. package/dist/workspace-instruction-policies.d.ts +1 -1
  81. package/dist/workspace-learning-policy-schema.d.ts +932 -0
  82. package/dist/workspace-learning-policy.d.ts +161 -0
  83. package/drizzle/0065_enrollment_credential_generation.sql +10 -0
  84. package/drizzle/0140_retained_screenshot_artifacts.sql +192 -0
  85. package/drizzle/0176_lossless_canonical_json.sql +975 -0
  86. package/drizzle/0177_session_events_workspace_turn_type_index.sql +5 -0
  87. package/drizzle/0178_permissioned_secret_reads.sql +14 -0
  88. package/drizzle/0179_slack_private_shortcut_delivery_gate.sql +85 -0
  89. package/drizzle/0180_retained_screenshot_lifecycle_fences.sql +273 -0
  90. package/drizzle/0181_connected_machine_removal.sql +52 -0
  91. package/drizzle/0182_connected_machine_remove_session_default.sql +77 -0
  92. package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
  93. package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
  94. package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
  95. package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
  96. package/drizzle/0187_generated_image_artifacts.sql +173 -0
  97. package/drizzle/0188_image_generation_retention_failure.sql +25 -0
  98. package/drizzle/0189_retained_session_image_formats.sql +13 -0
  99. package/drizzle/0190_timeline_annotations.sql +31 -0
  100. package/drizzle/0191_editable_artifact_engine.sql +3853 -0
  101. package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
  102. package/drizzle/0193_editable_artifact_authorization.sql +190 -0
  103. package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
  104. package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
  105. package/drizzle/0196_rig_provider_images.sql +152 -0
  106. package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
  107. package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
  108. package/drizzle/0199_workspace_learning_policy.sql +980 -0
  109. package/drizzle/0201_company_profile_authority.sql +849 -0
  110. package/drizzle/0202_document_index_checkpoints.sql +85 -0
  111. package/drizzle/0203_durable_video_generation.sql +353 -0
  112. package/drizzle/0204_video_generation_funding.sql +44 -0
  113. package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
  114. package/drizzle/0206_browser_sessions.sql +646 -0
  115. package/drizzle/0207_browser_identities.sql +379 -0
  116. package/drizzle/0208_attached_browser_devices.sql +165 -0
  117. package/drizzle/0209_computer_sessions.sql +575 -0
  118. package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
  119. package/drizzle/0211_editable_artifact_session_links.sql +58 -0
  120. package/drizzle/0212_slack_installation_bindings.sql +348 -0
  121. package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
  122. package/drizzle/0214_session_activity_commit_gate.sql +262 -0
  123. package/drizzle/0215_capabilities_platform.sql +980 -0
  124. package/drizzle/0216_pack_component_ownership.sql +235 -0
  125. package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
  126. package/package.json +18 -5
  127. package/src/attached-browser-devices.ts +371 -0
  128. package/src/attempt-tool-catalogs.ts +131 -0
  129. package/src/browser-auth.ts +1896 -0
  130. package/src/browser-identities.ts +1168 -0
  131. package/src/browser-sessions.ts +2005 -0
  132. package/src/browser-state-artifacts.ts +59 -0
  133. package/src/capability-components.ts +166 -0
  134. package/src/capability-integrations.ts +1663 -0
  135. package/src/codemode-operations.ts +674 -0
  136. package/src/company-profile-schema.ts +143 -0
  137. package/src/company-profile.ts +968 -0
  138. package/src/computer-sessions.ts +1130 -0
  139. package/src/connection-token-resolver.ts +270 -25
  140. package/src/database.ts +434 -24
  141. package/src/editable-artifact-durable-export.ts +1201 -0
  142. package/src/editable-artifact-materialization.ts +893 -0
  143. package/src/editable-artifacts-schema.ts +879 -0
  144. package/src/editable-artifacts.ts +5404 -0
  145. package/src/environment-crypto.ts +22 -9
  146. package/src/generated-images.ts +740 -0
  147. package/src/index.ts +10117 -2730
  148. package/src/insights.ts +160 -13
  149. package/src/integration-bindings.ts +455 -0
  150. package/src/integration-features.ts +859 -0
  151. package/src/interaction-revisions.ts +40 -0
  152. package/src/interaction-schema.ts +1303 -0
  153. package/src/knowledge-source-sync-schema.ts +192 -0
  154. package/src/knowledge-source-sync.ts +1922 -0
  155. package/src/lossless-columns.ts +35 -0
  156. package/src/lossless-json.ts +322 -0
  157. package/src/memory-domain.ts +5 -44
  158. package/src/memory-slack-delivery.ts +801 -0
  159. package/src/pack-components.ts +954 -0
  160. package/src/pack-installations.ts +929 -0
  161. package/src/persistence-errors.ts +26 -34
  162. package/src/plugin-packages.ts +1186 -0
  163. package/src/provision-roles.ts +302 -1
  164. package/src/runtime-posture-cli.ts +9 -0
  165. package/src/runtime-posture.ts +514 -5
  166. package/src/schema.ts +5177 -2957
  167. package/src/scoped-knowledge-schema.ts +1 -1
  168. package/src/scoped-knowledge.ts +655 -3
  169. package/src/session-control.ts +133 -81
  170. package/src/session-queue-commands.ts +511 -247
  171. package/src/session-realtime-context.ts +20 -7
  172. package/src/session-realtime-ledger.ts +32 -10
  173. package/src/session-realtime-mirror.ts +4 -2
  174. package/src/session-realtime-terminal.ts +89 -21
  175. package/src/session-realtime.ts +10 -9
  176. package/src/session-tool-call-settlement.ts +38 -15
  177. package/src/slack-user-link-access.ts +702 -0
  178. package/src/transcription-recordings-schema.ts +5 -2
  179. package/src/transcription-recordings.ts +70 -40
  180. package/src/video-generation.ts +1452 -0
  181. package/src/workspace-learning-policy-schema.ts +139 -0
  182. package/src/workspace-learning-policy.ts +595 -0
  183. package/dist/chunk-DBS5HPEW.js.map +0 -1
  184. package/dist/chunk-HT5T62CC.js +0 -6803
  185. package/dist/chunk-HT5T62CC.js.map +0 -1
  186. package/dist/event-payload-sanitizer.d.ts +0 -32
  187. package/src/event-payload-sanitizer.ts +0 -377
@@ -0,0 +1,379 @@
1
+ -- deployment-mode: maintenance
2
+ -- Canonical immutable BrowserIdentity revisions and encrypted browser-state artifacts.
3
+ -- The application and controller cut over together; there is no mutable-profile
4
+ -- compatibility path.
5
+ SET LOCAL lock_timeout = '5s';
6
+ SET LOCAL statement_timeout = '30s';
7
+
8
+ CREATE TABLE "browser_identities" (
9
+ "id" uuid PRIMARY KEY,
10
+ "account_id" uuid NOT NULL,
11
+ "workspace_id" uuid NOT NULL,
12
+ "name" text NOT NULL,
13
+ "status" text NOT NULL DEFAULT 'active',
14
+ "default_revision_id" uuid,
15
+ "head_generation" bigint NOT NULL DEFAULT 0,
16
+ "revision_count" bigint NOT NULL DEFAULT 0,
17
+ "create_operation_id" uuid NOT NULL,
18
+ "created_by_subject_id" text NOT NULL,
19
+ "created_at" timestamptz NOT NULL DEFAULT now(),
20
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
21
+ CONSTRAINT "browser_identities_workspace_account_fk"
22
+ FOREIGN KEY ("workspace_id", "account_id")
23
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
24
+ CONSTRAINT "browser_identities_status_check"
25
+ CHECK ("status" IN ('active', 'archived')),
26
+ CONSTRAINT "browser_identities_values_check" CHECK (
27
+ octet_length("name") BETWEEN 1 AND 200
28
+ AND "name" = btrim("name")
29
+ AND octet_length("created_by_subject_id") BETWEEN 1 AND 1024
30
+ AND "head_generation" >= 0
31
+ AND "revision_count" >= 0
32
+ AND "head_generation" <= "revision_count"
33
+ AND (
34
+ ("head_generation" = 0 AND "default_revision_id" IS NULL)
35
+ OR ("head_generation" > 0 AND "default_revision_id" IS NOT NULL)
36
+ )
37
+ ),
38
+ CONSTRAINT "browser_identities_workspace_id_uq" UNIQUE ("workspace_id", "id"),
39
+ CONSTRAINT "browser_identities_workspace_create_operation_uq"
40
+ UNIQUE ("workspace_id", "create_operation_id")
41
+ );
42
+
43
+ CREATE UNIQUE INDEX "browser_identities_workspace_active_name_uq"
44
+ ON "browser_identities" ("workspace_id", lower("name"))
45
+ WHERE "status" = 'active';
46
+ CREATE INDEX "browser_identities_workspace_status_updated_idx"
47
+ ON "browser_identities" ("workspace_id", "status", "updated_at", "id");
48
+
49
+ CREATE TABLE "browser_revisions" (
50
+ "id" uuid PRIMARY KEY,
51
+ "account_id" uuid NOT NULL,
52
+ "workspace_id" uuid NOT NULL,
53
+ "identity_id" uuid NOT NULL,
54
+ "parent_revision_id" uuid,
55
+ "ordinal" bigint NOT NULL,
56
+ "source_browser_session_id" uuid NOT NULL,
57
+ "publication_operation_id" uuid NOT NULL,
58
+ "expected_head_generation" bigint NOT NULL,
59
+ "advance_default_requested" boolean NOT NULL,
60
+ "default_advanced" boolean NOT NULL,
61
+ "result_head_generation" bigint NOT NULL,
62
+ "manifest_digest" text NOT NULL,
63
+ "created_by_subject_id" text NOT NULL,
64
+ "created_at" timestamptz NOT NULL DEFAULT now(),
65
+ CONSTRAINT "browser_revisions_workspace_account_fk"
66
+ FOREIGN KEY ("workspace_id", "account_id")
67
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
68
+ CONSTRAINT "browser_revisions_identity_fk"
69
+ FOREIGN KEY ("workspace_id", "identity_id")
70
+ REFERENCES "browser_identities"("workspace_id", "id") ON DELETE RESTRICT,
71
+ CONSTRAINT "browser_revisions_source_session_fk"
72
+ FOREIGN KEY ("workspace_id", "source_browser_session_id")
73
+ REFERENCES "browser_sessions"("workspace_id", "id") ON DELETE RESTRICT,
74
+ CONSTRAINT "browser_revisions_publication_operation_fk"
75
+ FOREIGN KEY ("workspace_id", "publication_operation_id")
76
+ REFERENCES "interaction_operations"("workspace_id", "operation_id") ON DELETE RESTRICT,
77
+ CONSTRAINT "browser_revisions_values_check" CHECK (
78
+ "ordinal" > 0
79
+ AND "expected_head_generation" >= 0
80
+ AND "result_head_generation" >= 0
81
+ AND (NOT "default_advanced" OR "advance_default_requested")
82
+ AND (NOT "default_advanced" OR "result_head_generation" = "expected_head_generation" + 1)
83
+ AND "manifest_digest" ~ '^[0-9a-f]{64}$'
84
+ AND octet_length("created_by_subject_id") BETWEEN 1 AND 1024
85
+ AND "parent_revision_id" IS DISTINCT FROM "id"
86
+ ),
87
+ CONSTRAINT "browser_revisions_workspace_id_uq" UNIQUE ("workspace_id", "id"),
88
+ CONSTRAINT "browser_revisions_identity_id_uq" UNIQUE ("identity_id", "id"),
89
+ CONSTRAINT "browser_revisions_workspace_identity_id_uq"
90
+ UNIQUE ("workspace_id", "identity_id", "id"),
91
+ CONSTRAINT "browser_revisions_workspace_identity_source_id_uq"
92
+ UNIQUE ("workspace_id", "identity_id", "id", "source_browser_session_id"),
93
+ CONSTRAINT "browser_revisions_identity_ordinal_uq" UNIQUE ("identity_id", "ordinal"),
94
+ CONSTRAINT "browser_revisions_workspace_publication_operation_uq"
95
+ UNIQUE ("workspace_id", "publication_operation_id"),
96
+ CONSTRAINT "browser_revisions_parent_fk"
97
+ FOREIGN KEY ("identity_id", "parent_revision_id")
98
+ REFERENCES "browser_revisions"("identity_id", "id") ON DELETE RESTRICT
99
+ );
100
+
101
+ CREATE INDEX "browser_revisions_identity_history_idx"
102
+ ON "browser_revisions" ("workspace_id", "identity_id", "ordinal");
103
+
104
+ ALTER TABLE "browser_identities"
105
+ ADD CONSTRAINT "browser_identities_default_revision_fk"
106
+ FOREIGN KEY ("id", "default_revision_id")
107
+ REFERENCES "browser_revisions"("identity_id", "id") ON DELETE RESTRICT;
108
+
109
+ CREATE TABLE "browser_state_artifacts" (
110
+ "id" uuid PRIMARY KEY,
111
+ "account_id" uuid NOT NULL,
112
+ "workspace_id" uuid NOT NULL,
113
+ "source_browser_session_id" uuid NOT NULL,
114
+ "purpose" text NOT NULL,
115
+ "kind" text NOT NULL,
116
+ "format" text NOT NULL,
117
+ "artifact_digest" text NOT NULL,
118
+ "content_digest" text NOT NULL,
119
+ "manifest_digest" text NOT NULL,
120
+ "object_key" text NOT NULL,
121
+ "encrypted_data_key" text NOT NULL,
122
+ "size_bytes" bigint NOT NULL,
123
+ "materialization" jsonb NOT NULL,
124
+ "state" text NOT NULL DEFAULT 'available',
125
+ "retained_until" timestamptz,
126
+ "created_at" timestamptz NOT NULL DEFAULT now(),
127
+ "deleted_at" timestamptz,
128
+ CONSTRAINT "browser_state_artifacts_workspace_account_fk"
129
+ FOREIGN KEY ("workspace_id", "account_id")
130
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
131
+ CONSTRAINT "browser_state_artifacts_source_session_fk"
132
+ FOREIGN KEY ("workspace_id", "source_browser_session_id")
133
+ REFERENCES "browser_sessions"("workspace_id", "id") ON DELETE RESTRICT,
134
+ CONSTRAINT "browser_state_artifacts_purpose_check"
135
+ CHECK ("purpose" IN ('revision_component', 'private_checkpoint')),
136
+ CONSTRAINT "browser_state_artifacts_kind_check"
137
+ CHECK ("kind" IN ('chromium_profile', 'normalized_web_state', 'provider_snapshot')),
138
+ CONSTRAINT "browser_state_artifacts_state_check"
139
+ CHECK ("state" IN ('available', 'delete_pending', 'deleted')),
140
+ CONSTRAINT "browser_state_artifacts_values_check" CHECK (
141
+ octet_length("format") BETWEEN 1 AND 512
142
+ AND "format" = btrim("format")
143
+ AND "artifact_digest" ~ '^[0-9a-f]{64}$'
144
+ AND "content_digest" ~ '^[0-9a-f]{64}$'
145
+ AND "manifest_digest" ~ '^[0-9a-f]{64}$'
146
+ AND octet_length("object_key") BETWEEN 1 AND 2048
147
+ AND "object_key" ~ (
148
+ '^workspaces/' || "workspace_id"::text ||
149
+ '/browser-state/[A-Za-z0-9._=-]+(/[A-Za-z0-9._=-]+)*$'
150
+ )
151
+ AND octet_length("encrypted_data_key") BETWEEN 16 AND 8192
152
+ AND "size_bytes" > 0
153
+ AND jsonb_typeof("materialization") = 'object'
154
+ AND octet_length("materialization"::text) BETWEEN 2 AND 65536
155
+ AND (
156
+ "purpose" <> 'revision_component'
157
+ OR (
158
+ "state" = 'available'
159
+ AND "retained_until" IS NULL
160
+ AND "deleted_at" IS NULL
161
+ )
162
+ )
163
+ ),
164
+ CONSTRAINT "browser_state_artifacts_lifecycle_check" CHECK (
165
+ ("state" = 'deleted' AND "deleted_at" IS NOT NULL)
166
+ OR ("state" <> 'deleted' AND "deleted_at" IS NULL)
167
+ ),
168
+ CONSTRAINT "browser_state_artifacts_workspace_id_uq" UNIQUE ("workspace_id", "id"),
169
+ CONSTRAINT "browser_state_artifacts_component_authority_uq"
170
+ UNIQUE ("workspace_id", "id", "purpose", "source_browser_session_id", "kind"),
171
+ CONSTRAINT "browser_state_artifacts_object_key_uq" UNIQUE ("object_key")
172
+ );
173
+
174
+ CREATE INDEX "browser_state_artifacts_source_idx"
175
+ ON "browser_state_artifacts" ("workspace_id", "source_browser_session_id", "created_at");
176
+ CREATE INDEX "browser_state_artifacts_gc_idx"
177
+ ON "browser_state_artifacts" ("state", "retained_until", "created_at");
178
+
179
+ CREATE TABLE "browser_revision_components" (
180
+ "id" uuid PRIMARY KEY,
181
+ "account_id" uuid NOT NULL,
182
+ "workspace_id" uuid NOT NULL,
183
+ "identity_id" uuid NOT NULL,
184
+ "revision_id" uuid NOT NULL,
185
+ "artifact_id" uuid NOT NULL,
186
+ "source_browser_session_id" uuid NOT NULL,
187
+ "artifact_purpose" text NOT NULL DEFAULT 'revision_component',
188
+ "kind" text NOT NULL,
189
+ "position" integer NOT NULL,
190
+ "created_at" timestamptz NOT NULL DEFAULT now(),
191
+ CONSTRAINT "browser_revision_components_workspace_account_fk"
192
+ FOREIGN KEY ("workspace_id", "account_id")
193
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
194
+ CONSTRAINT "browser_revision_components_revision_fk"
195
+ FOREIGN KEY (
196
+ "workspace_id", "identity_id", "revision_id", "source_browser_session_id"
197
+ )
198
+ REFERENCES "browser_revisions"(
199
+ "workspace_id", "identity_id", "id", "source_browser_session_id"
200
+ ) ON DELETE CASCADE,
201
+ CONSTRAINT "browser_revision_components_artifact_fk"
202
+ FOREIGN KEY (
203
+ "workspace_id", "artifact_id", "artifact_purpose", "source_browser_session_id", "kind"
204
+ )
205
+ REFERENCES "browser_state_artifacts"(
206
+ "workspace_id", "id", "purpose", "source_browser_session_id", "kind"
207
+ ) ON DELETE RESTRICT,
208
+ CONSTRAINT "browser_revision_components_values_check" CHECK (
209
+ "position" BETWEEN 0 AND 15
210
+ AND "artifact_purpose" = 'revision_component'
211
+ AND "kind" IN ('chromium_profile', 'normalized_web_state', 'provider_snapshot')
212
+ ),
213
+ CONSTRAINT "browser_revision_components_workspace_id_uq"
214
+ UNIQUE ("workspace_id", "id"),
215
+ CONSTRAINT "browser_revision_components_revision_position_uq"
216
+ UNIQUE ("revision_id", "position"),
217
+ CONSTRAINT "browser_revision_components_revision_kind_uq"
218
+ UNIQUE ("revision_id", "kind"),
219
+ CONSTRAINT "browser_revision_components_artifact_uq" UNIQUE ("artifact_id")
220
+ );
221
+
222
+ CREATE INDEX "browser_revision_components_revision_idx"
223
+ ON "browser_revision_components" ("workspace_id", "revision_id", "position");
224
+
225
+ CREATE FUNCTION opengeni_private.browser_identities_update_guard()
226
+ RETURNS trigger
227
+ LANGUAGE plpgsql
228
+ SET search_path = pg_catalog
229
+ AS $guard$
230
+ BEGIN
231
+ IF ROW(
232
+ NEW.id, NEW.account_id, NEW.workspace_id, NEW.create_operation_id,
233
+ NEW.created_by_subject_id, NEW.created_at
234
+ ) IS DISTINCT FROM ROW(
235
+ OLD.id, OLD.account_id, OLD.workspace_id, OLD.create_operation_id,
236
+ OLD.created_by_subject_id, OLD.created_at
237
+ ) THEN
238
+ RAISE EXCEPTION 'BrowserIdentity immutable authority cannot change'
239
+ USING ERRCODE = '23514';
240
+ END IF;
241
+ IF NEW.revision_count < OLD.revision_count
242
+ OR NEW.revision_count > OLD.revision_count + 1 THEN
243
+ RAISE EXCEPTION 'BrowserIdentity revision count must advance monotonically by one'
244
+ USING ERRCODE = '23514';
245
+ END IF;
246
+ IF NEW.default_revision_id IS DISTINCT FROM OLD.default_revision_id THEN
247
+ IF NEW.head_generation <> OLD.head_generation + 1 THEN
248
+ RAISE EXCEPTION 'BrowserIdentity default change must advance its head generation'
249
+ USING ERRCODE = '23514';
250
+ END IF;
251
+ ELSIF NEW.head_generation <> OLD.head_generation THEN
252
+ RAISE EXCEPTION 'BrowserIdentity head generation requires a default change'
253
+ USING ERRCODE = '23514';
254
+ END IF;
255
+ IF NEW.updated_at < OLD.updated_at THEN
256
+ RAISE EXCEPTION 'BrowserIdentity updated time cannot move backwards'
257
+ USING ERRCODE = '23514';
258
+ END IF;
259
+ RETURN NEW;
260
+ END
261
+ $guard$;
262
+
263
+ CREATE TRIGGER "browser_identities_update_guard_trg"
264
+ BEFORE UPDATE ON "browser_identities"
265
+ FOR EACH ROW EXECUTE FUNCTION opengeni_private.browser_identities_update_guard();
266
+
267
+ CREATE FUNCTION opengeni_private.browser_state_artifacts_update_guard()
268
+ RETURNS trigger
269
+ LANGUAGE plpgsql
270
+ SET search_path = pg_catalog
271
+ AS $guard$
272
+ BEGIN
273
+ IF ROW(
274
+ NEW.id, NEW.account_id, NEW.workspace_id, NEW.source_browser_session_id,
275
+ NEW.purpose, NEW.kind, NEW.format, NEW.artifact_digest, NEW.content_digest,
276
+ NEW.manifest_digest, NEW.object_key, NEW.encrypted_data_key, NEW.size_bytes, NEW.materialization,
277
+ NEW.created_at
278
+ ) IS DISTINCT FROM ROW(
279
+ OLD.id, OLD.account_id, OLD.workspace_id, OLD.source_browser_session_id,
280
+ OLD.purpose, OLD.kind, OLD.format, OLD.artifact_digest, OLD.content_digest,
281
+ OLD.manifest_digest, OLD.object_key, OLD.encrypted_data_key, OLD.size_bytes, OLD.materialization,
282
+ OLD.created_at
283
+ ) THEN
284
+ RAISE EXCEPTION 'Browser state artifact immutable authority cannot change'
285
+ USING ERRCODE = '23514';
286
+ END IF;
287
+ IF OLD.purpose = 'revision_component'
288
+ AND ROW(NEW.state, NEW.retained_until, NEW.deleted_at)
289
+ IS DISTINCT FROM ROW(OLD.state, OLD.retained_until, OLD.deleted_at) THEN
290
+ RAISE EXCEPTION 'Published BrowserRevision artifacts are immutable'
291
+ USING ERRCODE = '23514';
292
+ END IF;
293
+ IF NEW.state IS DISTINCT FROM OLD.state
294
+ AND NOT (
295
+ (OLD.state = 'available' AND NEW.state = 'delete_pending')
296
+ OR (OLD.state = 'delete_pending' AND NEW.state = 'deleted')
297
+ ) THEN
298
+ RAISE EXCEPTION 'Browser state artifact lifecycle cannot move backwards or skip a phase'
299
+ USING ERRCODE = '23514';
300
+ END IF;
301
+ RETURN NEW;
302
+ END
303
+ $guard$;
304
+
305
+ CREATE TRIGGER "browser_state_artifacts_update_guard_trg"
306
+ BEFORE UPDATE ON "browser_state_artifacts"
307
+ FOR EACH ROW EXECUTE FUNCTION opengeni_private.browser_state_artifacts_update_guard();
308
+
309
+ REVOKE ALL ON FUNCTION opengeni_private.browser_identities_update_guard() FROM PUBLIC;
310
+ REVOKE ALL ON FUNCTION opengeni_private.browser_state_artifacts_update_guard() FROM PUBLIC;
311
+
312
+ ALTER TABLE "browser_sessions"
313
+ ADD CONSTRAINT "browser_sessions_identity_fk"
314
+ FOREIGN KEY ("workspace_id", "identity_id")
315
+ REFERENCES "browser_identities"("workspace_id", "id") ON DELETE RESTRICT,
316
+ ADD CONSTRAINT "browser_sessions_base_revision_fk"
317
+ FOREIGN KEY ("identity_id", "base_revision_id")
318
+ REFERENCES "browser_revisions"("identity_id", "id") ON DELETE RESTRICT,
319
+ ADD CONSTRAINT "browser_sessions_private_checkpoint_fk"
320
+ FOREIGN KEY ("workspace_id", "private_checkpoint_artifact_id")
321
+ REFERENCES "browser_state_artifacts"("workspace_id", "id") ON DELETE RESTRICT;
322
+
323
+ ALTER TABLE "interaction_operations"
324
+ DROP CONSTRAINT "interaction_operations_kind_check";
325
+ ALTER TABLE "interaction_operations"
326
+ ADD CONSTRAINT "interaction_operations_kind_check"
327
+ CHECK ("kind" IN ('create', 'resume', 'suspend', 'end', 'publish'));
328
+
329
+ ALTER TABLE "browser_identities" ENABLE ROW LEVEL SECURITY;
330
+ ALTER TABLE "browser_identities" FORCE ROW LEVEL SECURITY;
331
+ CREATE POLICY workspace_isolation ON "browser_identities"
332
+ USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
333
+ WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
334
+
335
+ ALTER TABLE "browser_revisions" ENABLE ROW LEVEL SECURITY;
336
+ ALTER TABLE "browser_revisions" FORCE ROW LEVEL SECURITY;
337
+ CREATE POLICY workspace_isolation ON "browser_revisions"
338
+ USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
339
+ WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
340
+
341
+ ALTER TABLE "browser_state_artifacts" ENABLE ROW LEVEL SECURITY;
342
+ ALTER TABLE "browser_state_artifacts" FORCE ROW LEVEL SECURITY;
343
+ CREATE POLICY workspace_isolation ON "browser_state_artifacts"
344
+ USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
345
+ WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
346
+
347
+ ALTER TABLE "browser_revision_components" ENABLE ROW LEVEL SECURITY;
348
+ ALTER TABLE "browser_revision_components" FORCE ROW LEVEL SECURITY;
349
+ CREATE POLICY workspace_isolation ON "browser_revision_components"
350
+ USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
351
+ WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
352
+
353
+ DO $grants$
354
+ DECLARE target_schema text := current_schema();
355
+ BEGIN
356
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
357
+ EXECUTE format(
358
+ 'REVOKE ALL ON TABLE %I.browser_identities, %I.browser_revisions, %I.browser_state_artifacts, %I.browser_revision_components FROM opengeni_app',
359
+ target_schema, target_schema, target_schema, target_schema
360
+ );
361
+ EXECUTE format(
362
+ 'GRANT SELECT, INSERT, UPDATE ON TABLE %I.browser_identities TO opengeni_app',
363
+ target_schema
364
+ );
365
+ EXECUTE format(
366
+ 'GRANT SELECT, INSERT ON TABLE %I.browser_revisions TO opengeni_app',
367
+ target_schema
368
+ );
369
+ EXECUTE format(
370
+ 'GRANT SELECT, INSERT, UPDATE ON TABLE %I.browser_state_artifacts TO opengeni_app',
371
+ target_schema
372
+ );
373
+ EXECUTE format(
374
+ 'GRANT SELECT, INSERT ON TABLE %I.browser_revision_components TO opengeni_app',
375
+ target_schema
376
+ );
377
+ END IF;
378
+ END
379
+ $grants$;
@@ -0,0 +1,165 @@
1
+ -- deployment-mode: maintenance
2
+ -- Canonical live attached-Chrome endpoints. A row names one extension installation in one
3
+ -- Chrome profile; immutable BrowserIdentity revisions remain a separate resource.
4
+ SET LOCAL lock_timeout = '5s';
5
+ SET LOCAL statement_timeout = '30s';
6
+
7
+ ALTER TABLE "enrollments"
8
+ ADD CONSTRAINT "enrollments_workspace_id_uq" UNIQUE ("workspace_id", "id");
9
+
10
+ CREATE TABLE "attached_browser_devices" (
11
+ "id" uuid NOT NULL,
12
+ "account_id" uuid NOT NULL,
13
+ "workspace_id" uuid NOT NULL,
14
+ "enrollment_id" uuid NOT NULL,
15
+ "name" text NOT NULL,
16
+ "profile_label" text,
17
+ "browser_name" text NOT NULL,
18
+ "browser_version" text NOT NULL,
19
+ "extension_version" text NOT NULL,
20
+ "platform" text NOT NULL,
21
+ "architecture" text NOT NULL,
22
+ "connection_generation" text NOT NULL,
23
+ "inventory_revision" bigint NOT NULL,
24
+ "tab_count" integer NOT NULL,
25
+ "capabilities" jsonb NOT NULL,
26
+ "last_seen_at" timestamptz NOT NULL,
27
+ "disconnected_at" timestamptz,
28
+ "created_at" timestamptz NOT NULL DEFAULT now(),
29
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
30
+ CONSTRAINT "attached_browser_devices_workspace_id_pk"
31
+ PRIMARY KEY ("workspace_id", "id"),
32
+ CONSTRAINT "attached_browser_devices_workspace_account_fk"
33
+ FOREIGN KEY ("workspace_id", "account_id")
34
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
35
+ CONSTRAINT "attached_browser_devices_enrollment_fk"
36
+ FOREIGN KEY ("workspace_id", "enrollment_id")
37
+ REFERENCES "enrollments"("workspace_id", "id") ON DELETE RESTRICT,
38
+ CONSTRAINT "attached_browser_devices_platform_check"
39
+ CHECK ("platform" IN ('linux', 'macos', 'windows')),
40
+ CONSTRAINT "attached_browser_devices_architecture_check"
41
+ CHECK ("architecture" IN ('x64', 'arm64')),
42
+ CONSTRAINT "attached_browser_devices_values_check" CHECK (
43
+ octet_length("name") BETWEEN 1 AND 200
44
+ AND "name" = btrim("name")
45
+ AND ("profile_label" IS NULL OR (
46
+ octet_length("profile_label") BETWEEN 1 AND 200
47
+ AND "profile_label" = btrim("profile_label")
48
+ ))
49
+ AND octet_length("browser_name") BETWEEN 1 AND 100
50
+ AND "browser_name" = btrim("browser_name")
51
+ AND octet_length("browser_version") BETWEEN 1 AND 256
52
+ AND "browser_version" = btrim("browser_version")
53
+ AND octet_length("extension_version") BETWEEN 1 AND 256
54
+ AND "extension_version" = btrim("extension_version")
55
+ AND octet_length("connection_generation") BETWEEN 1 AND 256
56
+ AND "connection_generation" ~ '^[A-Za-z0-9][A-Za-z0-9._:-]*$'
57
+ AND "inventory_revision" >= 0
58
+ AND "tab_count" BETWEEN 0 AND 100000
59
+ AND jsonb_typeof("capabilities") = 'object'
60
+ AND octet_length("capabilities"::text) BETWEEN 2 AND 65536
61
+ )
62
+ );
63
+
64
+ CREATE INDEX "attached_browser_devices_enrollment_idx"
65
+ ON "attached_browser_devices" (
66
+ "workspace_id", "enrollment_id", "disconnected_at", "updated_at"
67
+ );
68
+ CREATE INDEX "attached_browser_devices_discovery_idx"
69
+ ON "attached_browser_devices" (
70
+ "workspace_id", "disconnected_at", "updated_at", "id"
71
+ );
72
+
73
+ CREATE TABLE "attached_browser_inventories" (
74
+ "account_id" uuid NOT NULL,
75
+ "workspace_id" uuid NOT NULL,
76
+ "enrollment_id" uuid NOT NULL,
77
+ "bridge_generation" text NOT NULL,
78
+ "revision" bigint NOT NULL,
79
+ "observed_at" timestamptz NOT NULL,
80
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
81
+ CONSTRAINT "attached_browser_inventories_workspace_enrollment_pk"
82
+ PRIMARY KEY ("workspace_id", "enrollment_id"),
83
+ CONSTRAINT "attached_browser_inventories_workspace_account_fk"
84
+ FOREIGN KEY ("workspace_id", "account_id")
85
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
86
+ CONSTRAINT "attached_browser_inventories_enrollment_fk"
87
+ FOREIGN KEY ("workspace_id", "enrollment_id")
88
+ REFERENCES "enrollments"("workspace_id", "id") ON DELETE RESTRICT,
89
+ CONSTRAINT "attached_browser_inventories_values_check" CHECK (
90
+ octet_length("bridge_generation") BETWEEN 1 AND 256
91
+ AND "bridge_generation" ~ '^[A-Za-z0-9][A-Za-z0-9._:-]*$'
92
+ AND "revision" >= 0
93
+ )
94
+ );
95
+
96
+ CREATE FUNCTION opengeni_private.attached_browser_devices_update_guard()
97
+ RETURNS trigger
98
+ LANGUAGE plpgsql
99
+ SET search_path = pg_catalog
100
+ AS $guard$
101
+ BEGIN
102
+ IF ROW(
103
+ NEW.id, NEW.account_id, NEW.workspace_id, NEW.enrollment_id, NEW.created_at
104
+ ) IS DISTINCT FROM ROW(
105
+ OLD.id, OLD.account_id, OLD.workspace_id, OLD.enrollment_id, OLD.created_at
106
+ ) THEN
107
+ RAISE EXCEPTION 'Attached browser endpoint identity cannot change'
108
+ USING ERRCODE = '23514';
109
+ END IF;
110
+ IF NEW.last_seen_at < OLD.last_seen_at OR NEW.updated_at < OLD.updated_at THEN
111
+ RAISE EXCEPTION 'Attached browser endpoint time cannot move backwards'
112
+ USING ERRCODE = '23514';
113
+ END IF;
114
+ IF NEW.connection_generation = OLD.connection_generation
115
+ AND NEW.inventory_revision < OLD.inventory_revision THEN
116
+ RAISE EXCEPTION 'Attached browser inventory revision cannot move backwards'
117
+ USING ERRCODE = '23514';
118
+ END IF;
119
+ RETURN NEW;
120
+ END
121
+ $guard$;
122
+
123
+ CREATE TRIGGER "attached_browser_devices_update_guard_trg"
124
+ BEFORE UPDATE ON "attached_browser_devices"
125
+ FOR EACH ROW EXECUTE FUNCTION opengeni_private.attached_browser_devices_update_guard();
126
+
127
+ REVOKE ALL ON FUNCTION opengeni_private.attached_browser_devices_update_guard() FROM PUBLIC;
128
+
129
+ ALTER TABLE "browser_sessions"
130
+ ADD CONSTRAINT "browser_sessions_attached_device_fk"
131
+ FOREIGN KEY ("workspace_id", "device_id")
132
+ REFERENCES "attached_browser_devices"("workspace_id", "id") ON DELETE RESTRICT;
133
+
134
+ ALTER TABLE "attached_browser_devices" ENABLE ROW LEVEL SECURITY;
135
+ ALTER TABLE "attached_browser_devices" FORCE ROW LEVEL SECURITY;
136
+ CREATE POLICY workspace_isolation ON "attached_browser_devices"
137
+ USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
138
+ WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
139
+
140
+ ALTER TABLE "attached_browser_inventories" ENABLE ROW LEVEL SECURITY;
141
+ ALTER TABLE "attached_browser_inventories" FORCE ROW LEVEL SECURITY;
142
+ CREATE POLICY workspace_isolation ON "attached_browser_inventories"
143
+ USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
144
+ WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
145
+
146
+ DO $grants$
147
+ DECLARE target_schema text := current_schema();
148
+ BEGIN
149
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
150
+ EXECUTE format(
151
+ 'REVOKE ALL ON TABLE %I.attached_browser_devices, %I.attached_browser_inventories FROM opengeni_app',
152
+ target_schema,
153
+ target_schema
154
+ );
155
+ EXECUTE format(
156
+ 'GRANT SELECT, INSERT, UPDATE ON TABLE %I.attached_browser_devices TO opengeni_app',
157
+ target_schema
158
+ );
159
+ EXECUTE format(
160
+ 'GRANT SELECT, INSERT, UPDATE ON TABLE %I.attached_browser_inventories TO opengeni_app',
161
+ target_schema
162
+ );
163
+ END IF;
164
+ END
165
+ $grants$;