@opengeni/db 0.28.9 → 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.
- package/dist/attached-browser-devices.d.ts +42 -0
- package/dist/attempt-tool-catalogs.d.ts +16 -0
- package/dist/browser-auth.d.ts +91 -0
- package/dist/browser-identities.d.ts +128 -0
- package/dist/browser-sessions.d.ts +272 -0
- package/dist/browser-state-artifacts.d.ts +17 -0
- package/dist/capability-components.d.ts +37 -0
- package/dist/capability-integrations.d.ts +192 -0
- package/dist/chunk-F5FT7BEZ.js +3535 -0
- package/dist/chunk-F5FT7BEZ.js.map +1 -0
- package/dist/chunk-ISI2TIUG.js +639 -0
- package/dist/chunk-ISI2TIUG.js.map +1 -0
- package/dist/chunk-MWDVXQOL.js +11639 -0
- package/dist/chunk-MWDVXQOL.js.map +1 -0
- package/dist/chunk-NBE6CHRI.js +955 -0
- package/dist/chunk-NBE6CHRI.js.map +1 -0
- package/dist/{chunk-VHBFHMPC.js → chunk-YHZXQ7HP.js} +754 -11
- package/dist/chunk-YHZXQ7HP.js.map +1 -0
- package/dist/codemode-operations.d.ts +117 -0
- package/dist/codex-token-resolver.d.ts +2 -2
- package/dist/company-profile-schema.d.ts +798 -0
- package/dist/company-profile.d.ts +268 -0
- package/dist/computer-sessions.d.ts +109 -0
- package/dist/connection-token-resolver.d.ts +9 -4
- package/dist/database.d.ts +52 -3
- package/dist/editable-artifact-durable-export.d.ts +153 -0
- package/dist/editable-artifact-durable-export.js +788 -0
- package/dist/editable-artifact-durable-export.js.map +1 -0
- package/dist/editable-artifact-materialization.d.ts +123 -0
- package/dist/editable-artifacts-schema.d.ts +4152 -0
- package/dist/editable-artifacts.d.ts +610 -0
- package/dist/editable-artifacts.js +26 -0
- package/dist/editable-artifacts.js.map +1 -0
- package/dist/generated-images.d.ts +139 -0
- package/dist/index.d.ts +698 -111
- package/dist/index.js +27573 -10322
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +51 -4
- package/dist/integration-bindings.d.ts +70 -0
- package/dist/integration-features.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +3 -0
- package/dist/interaction-schema.d.ts +5372 -0
- package/dist/knowledge-source-sync-schema.d.ts +1679 -0
- package/dist/knowledge-source-sync.d.ts +274 -0
- package/dist/memory-governance.d.ts +2 -2
- package/dist/memory-slack-delivery.d.ts +101 -0
- package/dist/new-session-drafts.d.ts +2 -2
- package/dist/pack-components.d.ts +76 -0
- package/dist/pack-installations.d.ts +86 -0
- package/dist/persistence-errors.d.ts +3 -3
- package/dist/plugin-packages.d.ts +126 -0
- package/dist/preference-registry.d.ts +1 -1
- package/dist/provision-roles.d.ts +9 -1
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +18 -6
- package/dist/schema.d.ts +18342 -9099
- package/dist/schema.js +165 -1
- package/dist/scoped-knowledge.d.ts +97 -1
- package/dist/session-control.d.ts +4 -4
- package/dist/session-queue-commands.d.ts +19 -11
- package/dist/session-realtime-context.d.ts +2 -2
- package/dist/session-realtime-ledger.d.ts +4 -4
- package/dist/session-realtime-mirror.d.ts +2 -2
- package/dist/session-realtime-state.d.ts +1 -1
- package/dist/session-realtime-terminal.d.ts +1 -1
- package/dist/session-realtime.d.ts +7 -7
- package/dist/session-tool-call-settlement.d.ts +1 -1
- package/dist/slack-user-link-access.d.ts +54 -0
- package/dist/transcription-recordings.d.ts +2 -2
- package/dist/turn-initiator.d.ts +2 -2
- package/dist/video-generation.d.ts +216 -0
- package/dist/video-generation.js +66 -0
- package/dist/video-generation.js.map +1 -0
- package/dist/workspace-artifacts.d.ts +1 -1
- package/dist/workspace-instruction-policies.d.ts +1 -1
- package/dist/workspace-learning-policy-schema.d.ts +932 -0
- package/dist/workspace-learning-policy.d.ts +161 -0
- package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
- package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
- package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
- package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
- package/drizzle/0187_generated_image_artifacts.sql +173 -0
- package/drizzle/0188_image_generation_retention_failure.sql +25 -0
- package/drizzle/0189_retained_session_image_formats.sql +13 -0
- package/drizzle/0190_timeline_annotations.sql +31 -0
- package/drizzle/0191_editable_artifact_engine.sql +3853 -0
- package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
- package/drizzle/0193_editable_artifact_authorization.sql +190 -0
- package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
- package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
- package/drizzle/0196_rig_provider_images.sql +152 -0
- package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
- package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
- package/drizzle/0199_workspace_learning_policy.sql +980 -0
- package/drizzle/0201_company_profile_authority.sql +849 -0
- package/drizzle/0202_document_index_checkpoints.sql +85 -0
- package/drizzle/0203_durable_video_generation.sql +353 -0
- package/drizzle/0204_video_generation_funding.sql +44 -0
- package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
- package/drizzle/0206_browser_sessions.sql +646 -0
- package/drizzle/0207_browser_identities.sql +379 -0
- package/drizzle/0208_attached_browser_devices.sql +165 -0
- package/drizzle/0209_computer_sessions.sql +575 -0
- package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
- package/drizzle/0211_editable_artifact_session_links.sql +58 -0
- package/drizzle/0212_slack_installation_bindings.sql +348 -0
- package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
- package/drizzle/0214_session_activity_commit_gate.sql +262 -0
- package/drizzle/0215_capabilities_platform.sql +980 -0
- package/drizzle/0216_pack_component_ownership.sql +235 -0
- package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
- package/package.json +18 -5
- package/src/attached-browser-devices.ts +371 -0
- package/src/attempt-tool-catalogs.ts +131 -0
- package/src/browser-auth.ts +1896 -0
- package/src/browser-identities.ts +1168 -0
- package/src/browser-sessions.ts +2005 -0
- package/src/browser-state-artifacts.ts +59 -0
- package/src/capability-components.ts +166 -0
- package/src/capability-integrations.ts +1663 -0
- package/src/codemode-operations.ts +674 -0
- package/src/company-profile-schema.ts +143 -0
- package/src/company-profile.ts +968 -0
- package/src/computer-sessions.ts +1130 -0
- package/src/connection-token-resolver.ts +270 -25
- package/src/database.ts +427 -23
- package/src/editable-artifact-durable-export.ts +1201 -0
- package/src/editable-artifact-materialization.ts +893 -0
- package/src/editable-artifacts-schema.ts +879 -0
- package/src/editable-artifacts.ts +5404 -0
- package/src/generated-images.ts +740 -0
- package/src/index.ts +5917 -1182
- package/src/insights.ts +160 -13
- package/src/integration-bindings.ts +455 -0
- package/src/integration-features.ts +859 -0
- package/src/interaction-revisions.ts +40 -0
- package/src/interaction-schema.ts +1303 -0
- package/src/knowledge-source-sync-schema.ts +192 -0
- package/src/knowledge-source-sync.ts +1922 -0
- package/src/memory-slack-delivery.ts +801 -0
- package/src/pack-components.ts +954 -0
- package/src/pack-installations.ts +929 -0
- package/src/persistence-errors.ts +4 -7
- package/src/plugin-packages.ts +1186 -0
- package/src/provision-roles.ts +302 -1
- package/src/runtime-posture-cli.ts +9 -0
- package/src/runtime-posture.ts +508 -5
- package/src/schema.ts +5117 -3119
- package/src/scoped-knowledge-schema.ts +1 -1
- package/src/scoped-knowledge.ts +655 -3
- package/src/session-control.ts +8 -5
- package/src/session-queue-commands.ts +187 -14
- package/src/session-realtime-context.ts +2 -2
- package/src/session-realtime-ledger.ts +3 -3
- package/src/session-realtime.ts +7 -7
- package/src/session-tool-call-settlement.ts +9 -0
- package/src/slack-user-link-access.ts +702 -0
- package/src/video-generation.ts +1452 -0
- package/src/workspace-learning-policy-schema.ts +139 -0
- package/src/workspace-learning-policy.ts +595 -0
- package/dist/chunk-P6CUHXQZ.js +0 -7248
- package/dist/chunk-P6CUHXQZ.js.map +0 -1
- package/dist/chunk-VHBFHMPC.js.map +0 -1
|
@@ -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$;
|