@opengeni/db 0.31.1 → 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.
- package/dist/browser-auth.d.ts +209 -1
- package/dist/browser-downloads.d.ts +51 -0
- package/dist/browser-identities.d.ts +11 -2
- package/dist/browser-sessions.d.ts +83 -1
- package/dist/browser-state-artifacts.d.ts +75 -1
- package/dist/canonical-human-identities.d.ts +48 -0
- package/dist/canonical-human-identities.js +28 -0
- package/dist/canonical-human-identities.js.map +1 -0
- package/dist/capability-integrations.d.ts +8 -6
- package/dist/{chunk-MWDVXQOL.js → chunk-5KTIEDX7.js} +5773 -4212
- package/dist/chunk-5KTIEDX7.js.map +1 -0
- package/dist/{chunk-NBE6CHRI.js → chunk-CQZ4QSP5.js} +49 -9
- package/dist/chunk-CQZ4QSP5.js.map +1 -0
- package/dist/chunk-F32YT7MP.js +117 -0
- package/dist/chunk-F32YT7MP.js.map +1 -0
- package/dist/{chunk-ISI2TIUG.js → chunk-JC5QPLUM.js} +30 -3
- package/dist/chunk-JC5QPLUM.js.map +1 -0
- package/dist/{chunk-F5FT7BEZ.js → chunk-P3RE4D2B.js} +2 -2
- package/dist/chunk-TAUTWOS5.js +259 -0
- package/dist/chunk-TAUTWOS5.js.map +1 -0
- package/dist/{chunk-YHZXQ7HP.js → chunk-VKLB2ZGI.js} +446 -19
- package/dist/chunk-VKLB2ZGI.js.map +1 -0
- package/dist/database.d.ts +5 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +438 -29
- package/dist/index.js +35640 -28969
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +23 -7
- package/dist/integration-bindings.d.ts +24 -24
- package/dist/integration-facets.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +11 -0
- package/dist/interaction-schema.d.ts +698 -34
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +8 -7
- package/dist/schema.d.ts +9464 -5412
- package/dist/schema.js +51 -9
- package/dist/session-control.d.ts +29 -3
- package/dist/session-tenancy.d.ts +44 -0
- package/dist/session-tenancy.js +16 -0
- package/dist/session-tenancy.js.map +1 -0
- package/dist/slack-task-policy-schema.d.ts +847 -0
- package/dist/slack-task-policy.d.ts +65 -0
- package/dist/task-notes-schema.d.ts +924 -0
- package/dist/task-notes.d.ts +85 -0
- package/dist/video-generation.d.ts +9 -0
- package/dist/video-generation.js +5 -3
- package/dist/xai-subscription.d.ts +326 -0
- package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
- package/drizzle/0213_browser_interaction_authority.sql +67 -0
- package/drizzle/0214_browser_download_saves.sql +34 -0
- package/drizzle/0215_browser_controller_host.sql +385 -0
- package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
- package/drizzle/0217_external_browser_auth_operations.sql +22 -0
- package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
- package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
- package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
- package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
- package/drizzle/0220_session_channels.sql +54 -0
- package/drizzle/0221_sessions_channel_index.sql +5 -0
- package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
- package/drizzle/0222_sessions_channel_fk.sql +89 -0
- package/drizzle/0223_pending_tool_event_output.sql +55 -0
- package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
- package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
- package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
- package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
- package/drizzle/0227_slack_native_actions.sql +145 -0
- package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
- package/drizzle/0228_slack_task_policy.sql +400 -0
- package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
- package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
- package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
- package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
- package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
- package/drizzle/0234_xai_subscription_authority.sql +1139 -0
- package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
- package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
- package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
- package/drizzle/0237_interaction_transition_reaper.sql +263 -0
- package/drizzle/0238_goal_persistence_policy.sql +471 -0
- package/drizzle/0238_supergrok_realtime_model.sql +29 -0
- package/drizzle/0239_supergrok_video_funding.sql +50 -0
- package/drizzle/0239_task_tree_notes.sql +990 -0
- package/package.json +13 -5
- package/src/browser-auth.ts +2600 -123
- package/src/browser-downloads.ts +517 -0
- package/src/browser-identities.ts +220 -3
- package/src/browser-sessions.ts +334 -45
- package/src/browser-state-artifacts.ts +402 -12
- package/src/canonical-human-identities.ts +317 -0
- package/src/capability-integrations.ts +121 -213
- package/src/database.ts +41 -1
- package/src/index.ts +4157 -394
- package/src/insights.ts +109 -28
- package/src/integration-bindings.ts +101 -101
- package/src/{integration-features.ts → integration-facets.ts} +187 -184
- package/src/interaction-revisions.ts +33 -3
- package/src/interaction-schema.ts +311 -8
- package/src/pack-components.ts +43 -43
- package/src/pack-installations.ts +0 -43
- package/src/plugin-packages.ts +9 -9
- package/src/provision-roles.ts +232 -0
- package/src/runtime-posture.ts +227 -14
- package/src/schema.ts +1188 -75
- package/src/session-control.ts +122 -37
- package/src/session-queue-commands.ts +78 -1
- package/src/session-tenancy.ts +188 -0
- package/src/session-tool-call-settlement.ts +9 -3
- package/src/slack-task-policy-schema.ts +130 -0
- package/src/slack-task-policy.ts +341 -0
- package/src/task-notes-schema.ts +135 -0
- package/src/task-notes.ts +178 -0
- package/src/video-generation.ts +90 -12
- package/src/workspace-artifacts.ts +1 -1
- package/src/xai-subscription.ts +1887 -0
- package/dist/chunk-ISI2TIUG.js.map +0 -1
- package/dist/chunk-MWDVXQOL.js.map +0 -1
- package/dist/chunk-NBE6CHRI.js.map +0 -1
- package/dist/chunk-YHZXQ7HP.js.map +0 -1
- package/dist/integration-features.d.ts +0 -99
- /package/dist/{chunk-F5FT7BEZ.js.map → chunk-P3RE4D2B.js.map} +0 -0
|
@@ -0,0 +1,610 @@
|
|
|
1
|
+
-- deployment-mode: maintenance
|
|
2
|
+
-- Replace the Integration Feature submodel with authoritative Integration
|
|
3
|
+
-- Facet definitions and bindings across physical storage, Pack manifests,
|
|
4
|
+
-- ownership, and operation results. This is a one-way protocol cutover: all
|
|
5
|
+
-- opengeni_app sessions must be stopped and in-flight Pack/Facet operations
|
|
6
|
+
-- must be settled before activation.
|
|
7
|
+
|
|
8
|
+
SET LOCAL lock_timeout = '5s';
|
|
9
|
+
SET LOCAL statement_timeout = '30min';
|
|
10
|
+
|
|
11
|
+
DO $maintenance_preflight_guard$
|
|
12
|
+
BEGIN
|
|
13
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app')
|
|
14
|
+
AND EXISTS (
|
|
15
|
+
SELECT 1
|
|
16
|
+
FROM pg_stat_activity
|
|
17
|
+
WHERE datname = current_database()
|
|
18
|
+
AND usename = 'opengeni_app'
|
|
19
|
+
AND pid <> pg_backend_pid()
|
|
20
|
+
)
|
|
21
|
+
THEN
|
|
22
|
+
RAISE EXCEPTION
|
|
23
|
+
'Integration Facet activation requires all opengeni_app sessions to be stopped'
|
|
24
|
+
USING ERRCODE = '55000';
|
|
25
|
+
END IF;
|
|
26
|
+
|
|
27
|
+
IF EXISTS (
|
|
28
|
+
SELECT 1
|
|
29
|
+
FROM capability_operations
|
|
30
|
+
WHERE target_kind IN ('pack', 'facet_binding')
|
|
31
|
+
AND status IN ('pending', 'running')
|
|
32
|
+
) THEN
|
|
33
|
+
RAISE EXCEPTION
|
|
34
|
+
'Integration Facet activation requires Pack and Facet operations to be settled'
|
|
35
|
+
USING ERRCODE = '55000';
|
|
36
|
+
END IF;
|
|
37
|
+
END
|
|
38
|
+
$maintenance_preflight_guard$;
|
|
39
|
+
|
|
40
|
+
DO $lock_authority$
|
|
41
|
+
DECLARE
|
|
42
|
+
relation_name text;
|
|
43
|
+
BEGIN
|
|
44
|
+
FOREACH relation_name IN ARRAY ARRAY[
|
|
45
|
+
'integration_feature_binding_owners',
|
|
46
|
+
'integration_facet_binding_owners',
|
|
47
|
+
'integration_feature_bindings',
|
|
48
|
+
'integration_facet_bindings',
|
|
49
|
+
'integration_feature_facets',
|
|
50
|
+
'integration_facet_definitions',
|
|
51
|
+
'pack_installation_components',
|
|
52
|
+
'pack_installations',
|
|
53
|
+
'workspace_packs',
|
|
54
|
+
'capability_installations',
|
|
55
|
+
'capability_operations'
|
|
56
|
+
]
|
|
57
|
+
LOOP
|
|
58
|
+
IF to_regclass(relation_name) IS NOT NULL THEN
|
|
59
|
+
EXECUTE format('LOCK TABLE %I IN ACCESS EXCLUSIVE MODE', relation_name);
|
|
60
|
+
END IF;
|
|
61
|
+
END LOOP;
|
|
62
|
+
END
|
|
63
|
+
$lock_authority$;
|
|
64
|
+
|
|
65
|
+
DO $facet_precondition$
|
|
66
|
+
BEGIN
|
|
67
|
+
IF EXISTS (
|
|
68
|
+
SELECT 1
|
|
69
|
+
FROM workspace_packs pack
|
|
70
|
+
WHERE pack.manifest ? 'components'
|
|
71
|
+
AND jsonb_typeof(pack.manifest -> 'components') <> 'array'
|
|
72
|
+
) OR EXISTS (
|
|
73
|
+
SELECT 1
|
|
74
|
+
FROM pack_installations installation
|
|
75
|
+
WHERE installation.manifest_snapshot IS NOT NULL
|
|
76
|
+
AND installation.manifest_snapshot ? 'components'
|
|
77
|
+
AND jsonb_typeof(installation.manifest_snapshot -> 'components') <> 'array'
|
|
78
|
+
) THEN
|
|
79
|
+
RAISE EXCEPTION 'a persisted Pack has a non-array components manifest'
|
|
80
|
+
USING ERRCODE = '23514';
|
|
81
|
+
END IF;
|
|
82
|
+
|
|
83
|
+
IF EXISTS (
|
|
84
|
+
SELECT 1
|
|
85
|
+
FROM workspace_packs pack,
|
|
86
|
+
LATERAL jsonb_array_elements(COALESCE(pack.manifest -> 'components', '[]'::jsonb)) component
|
|
87
|
+
WHERE (
|
|
88
|
+
component ->> 'kind' = 'feature'
|
|
89
|
+
AND (
|
|
90
|
+
NULLIF(component ->> 'featureKey', '') IS NULL
|
|
91
|
+
OR component ? 'facetKey'
|
|
92
|
+
)
|
|
93
|
+
) OR (
|
|
94
|
+
component ? 'featureKey'
|
|
95
|
+
AND component ->> 'kind' <> 'feature'
|
|
96
|
+
)
|
|
97
|
+
) OR EXISTS (
|
|
98
|
+
SELECT 1
|
|
99
|
+
FROM pack_installations installation,
|
|
100
|
+
LATERAL jsonb_array_elements(COALESCE(installation.manifest_snapshot -> 'components', '[]'::jsonb)) component
|
|
101
|
+
WHERE installation.manifest_snapshot IS NOT NULL
|
|
102
|
+
AND (
|
|
103
|
+
(
|
|
104
|
+
component ->> 'kind' = 'feature'
|
|
105
|
+
AND (
|
|
106
|
+
NULLIF(component ->> 'featureKey', '') IS NULL
|
|
107
|
+
OR component ? 'facetKey'
|
|
108
|
+
)
|
|
109
|
+
) OR (
|
|
110
|
+
component ? 'featureKey'
|
|
111
|
+
AND component ->> 'kind' <> 'feature'
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
) THEN
|
|
115
|
+
RAISE EXCEPTION 'a persisted Pack Facet component has ambiguous identity'
|
|
116
|
+
USING ERRCODE = '23514';
|
|
117
|
+
END IF;
|
|
118
|
+
END
|
|
119
|
+
$facet_precondition$;
|
|
120
|
+
|
|
121
|
+
CREATE OR REPLACE FUNCTION opengeni_private.integration_facet_rewrite_pack(value jsonb)
|
|
122
|
+
RETURNS jsonb
|
|
123
|
+
LANGUAGE plpgsql
|
|
124
|
+
IMMUTABLE
|
|
125
|
+
STRICT
|
|
126
|
+
PARALLEL SAFE
|
|
127
|
+
AS $rewrite_pack$
|
|
128
|
+
DECLARE
|
|
129
|
+
components jsonb;
|
|
130
|
+
BEGIN
|
|
131
|
+
IF NOT (value ? 'components') THEN
|
|
132
|
+
RETURN value;
|
|
133
|
+
END IF;
|
|
134
|
+
IF jsonb_typeof(value -> 'components') <> 'array' THEN
|
|
135
|
+
RAISE EXCEPTION 'Pack components must be an array' USING ERRCODE = '23514';
|
|
136
|
+
END IF;
|
|
137
|
+
|
|
138
|
+
SELECT COALESCE(
|
|
139
|
+
jsonb_agg(
|
|
140
|
+
CASE
|
|
141
|
+
WHEN component.value ->> 'kind' = 'feature' THEN
|
|
142
|
+
(component.value - 'kind' - 'featureKey') || jsonb_build_object(
|
|
143
|
+
'kind', 'facet',
|
|
144
|
+
'facetKey', component.value -> 'featureKey'
|
|
145
|
+
)
|
|
146
|
+
ELSE component.value
|
|
147
|
+
END
|
|
148
|
+
ORDER BY component.ordinality
|
|
149
|
+
),
|
|
150
|
+
'[]'::jsonb
|
|
151
|
+
)
|
|
152
|
+
INTO components
|
|
153
|
+
FROM jsonb_array_elements(value -> 'components') WITH ORDINALITY AS component(value, ordinality);
|
|
154
|
+
|
|
155
|
+
RETURN jsonb_set(value, '{components}', components, false);
|
|
156
|
+
END
|
|
157
|
+
$rewrite_pack$;
|
|
158
|
+
|
|
159
|
+
CREATE OR REPLACE FUNCTION opengeni_private.integration_facet_canonical_json(value jsonb)
|
|
160
|
+
RETURNS text
|
|
161
|
+
LANGUAGE plpgsql
|
|
162
|
+
IMMUTABLE
|
|
163
|
+
STRICT
|
|
164
|
+
PARALLEL SAFE
|
|
165
|
+
AS $canonical_json$
|
|
166
|
+
DECLARE
|
|
167
|
+
rendered text;
|
|
168
|
+
BEGIN
|
|
169
|
+
CASE jsonb_typeof(value)
|
|
170
|
+
WHEN 'object' THEN
|
|
171
|
+
SELECT COALESCE(
|
|
172
|
+
'{' || string_agg(
|
|
173
|
+
to_jsonb(entry.key)::text || ':' ||
|
|
174
|
+
opengeni_private.integration_facet_canonical_json(entry.value),
|
|
175
|
+
',' ORDER BY entry.key COLLATE "C"
|
|
176
|
+
) || '}',
|
|
177
|
+
'{}'
|
|
178
|
+
)
|
|
179
|
+
INTO rendered
|
|
180
|
+
FROM jsonb_each(value) AS entry(key, value);
|
|
181
|
+
RETURN rendered;
|
|
182
|
+
WHEN 'array' THEN
|
|
183
|
+
SELECT COALESCE(
|
|
184
|
+
'[' || string_agg(
|
|
185
|
+
opengeni_private.integration_facet_canonical_json(entry.value),
|
|
186
|
+
',' ORDER BY entry.ordinality
|
|
187
|
+
) || ']',
|
|
188
|
+
'[]'
|
|
189
|
+
)
|
|
190
|
+
INTO rendered
|
|
191
|
+
FROM jsonb_array_elements(value) WITH ORDINALITY AS entry(value, ordinality);
|
|
192
|
+
RETURN rendered;
|
|
193
|
+
ELSE
|
|
194
|
+
RETURN value::text;
|
|
195
|
+
END CASE;
|
|
196
|
+
END
|
|
197
|
+
$canonical_json$;
|
|
198
|
+
|
|
199
|
+
UPDATE workspace_packs
|
|
200
|
+
SET manifest = opengeni_private.integration_facet_rewrite_pack(manifest)
|
|
201
|
+
WHERE manifest ? 'components'
|
|
202
|
+
AND manifest IS DISTINCT FROM opengeni_private.integration_facet_rewrite_pack(manifest);
|
|
203
|
+
|
|
204
|
+
CREATE TEMP TABLE integration_facet_pack_cutover ON COMMIT DROP AS
|
|
205
|
+
SELECT
|
|
206
|
+
id,
|
|
207
|
+
workspace_id,
|
|
208
|
+
pack_id,
|
|
209
|
+
opengeni_private.integration_facet_rewrite_pack(manifest_snapshot) AS manifest_snapshot
|
|
210
|
+
FROM pack_installations
|
|
211
|
+
WHERE manifest_snapshot IS NOT NULL
|
|
212
|
+
AND manifest_snapshot IS DISTINCT FROM
|
|
213
|
+
opengeni_private.integration_facet_rewrite_pack(manifest_snapshot);
|
|
214
|
+
|
|
215
|
+
UPDATE pack_installations installation
|
|
216
|
+
SET manifest_snapshot = migrated.manifest_snapshot,
|
|
217
|
+
manifest_digest = encode(
|
|
218
|
+
digest(
|
|
219
|
+
convert_to(
|
|
220
|
+
opengeni_private.integration_facet_canonical_json(migrated.manifest_snapshot),
|
|
221
|
+
'UTF8'
|
|
222
|
+
),
|
|
223
|
+
'sha256'
|
|
224
|
+
),
|
|
225
|
+
'hex'
|
|
226
|
+
)
|
|
227
|
+
FROM integration_facet_pack_cutover migrated
|
|
228
|
+
WHERE installation.id = migrated.id;
|
|
229
|
+
|
|
230
|
+
UPDATE capability_installations capability
|
|
231
|
+
SET metadata = jsonb_set(
|
|
232
|
+
capability.metadata,
|
|
233
|
+
'{manifestDigest}',
|
|
234
|
+
to_jsonb(installation.manifest_digest),
|
|
235
|
+
true
|
|
236
|
+
)
|
|
237
|
+
FROM pack_installations installation
|
|
238
|
+
JOIN integration_facet_pack_cutover migrated ON migrated.id = installation.id
|
|
239
|
+
WHERE capability.workspace_id = migrated.workspace_id
|
|
240
|
+
AND capability.capability_id = 'pack:' || migrated.pack_id
|
|
241
|
+
AND capability.metadata ->> 'platformVersion' = '2';
|
|
242
|
+
|
|
243
|
+
DELETE FROM capability_operations operation
|
|
244
|
+
USING integration_facet_pack_cutover migrated
|
|
245
|
+
WHERE operation.workspace_id = migrated.workspace_id
|
|
246
|
+
AND operation.target_kind = 'pack'
|
|
247
|
+
AND operation.target_id = migrated.pack_id;
|
|
248
|
+
|
|
249
|
+
ALTER TABLE pack_installation_components
|
|
250
|
+
DROP CONSTRAINT IF EXISTS pack_installation_components_kind_chk;
|
|
251
|
+
|
|
252
|
+
UPDATE pack_installation_components
|
|
253
|
+
SET kind = CASE WHEN kind = 'feature' THEN 'facet' ELSE kind END,
|
|
254
|
+
metadata = CASE
|
|
255
|
+
WHEN metadata ? 'featureKey' THEN
|
|
256
|
+
(metadata - 'featureKey') || jsonb_build_object('facetKey', metadata -> 'featureKey')
|
|
257
|
+
ELSE metadata
|
|
258
|
+
END
|
|
259
|
+
WHERE kind = 'feature' OR metadata ? 'featureKey';
|
|
260
|
+
|
|
261
|
+
ALTER TABLE pack_installation_components
|
|
262
|
+
ADD CONSTRAINT pack_installation_components_kind_chk CHECK (
|
|
263
|
+
kind IN ('plugin', 'skill', 'integration', 'facet', 'inline_skill')
|
|
264
|
+
) NOT VALID;
|
|
265
|
+
ALTER TABLE pack_installation_components
|
|
266
|
+
VALIDATE CONSTRAINT pack_installation_components_kind_chk;
|
|
267
|
+
|
|
268
|
+
DELETE FROM capability_operations
|
|
269
|
+
WHERE target_kind = 'facet_binding'
|
|
270
|
+
AND result IS NOT NULL
|
|
271
|
+
AND (
|
|
272
|
+
result ? 'featureKey'
|
|
273
|
+
OR (jsonb_typeof(result -> 'binding') = 'object' AND result -> 'binding' ? 'featureKey')
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
DO $drop_legacy_triggers$
|
|
277
|
+
BEGIN
|
|
278
|
+
IF to_regclass('integration_feature_bindings') IS NOT NULL THEN
|
|
279
|
+
EXECUTE 'DROP TRIGGER IF EXISTS integration_feature_bindings_validate ON integration_feature_bindings';
|
|
280
|
+
END IF;
|
|
281
|
+
IF to_regclass('integration_facet_bindings') IS NOT NULL THEN
|
|
282
|
+
EXECUTE 'DROP TRIGGER IF EXISTS integration_feature_bindings_validate ON integration_facet_bindings';
|
|
283
|
+
EXECUTE 'DROP TRIGGER IF EXISTS integration_facet_bindings_validate ON integration_facet_bindings';
|
|
284
|
+
END IF;
|
|
285
|
+
IF to_regclass('integration_feature_binding_owners') IS NOT NULL THEN
|
|
286
|
+
EXECUTE 'DROP TRIGGER IF EXISTS integration_feature_binding_owners_validate ON integration_feature_binding_owners';
|
|
287
|
+
END IF;
|
|
288
|
+
IF to_regclass('integration_facet_binding_owners') IS NOT NULL THEN
|
|
289
|
+
EXECUTE 'DROP TRIGGER IF EXISTS integration_feature_binding_owners_validate ON integration_facet_binding_owners';
|
|
290
|
+
EXECUTE 'DROP TRIGGER IF EXISTS integration_facet_binding_owners_validate ON integration_facet_binding_owners';
|
|
291
|
+
END IF;
|
|
292
|
+
END
|
|
293
|
+
$drop_legacy_triggers$;
|
|
294
|
+
|
|
295
|
+
DROP FUNCTION IF EXISTS capability_v2_validate_feature_binding();
|
|
296
|
+
DROP FUNCTION IF EXISTS capability_v2_validate_feature_binding_owner();
|
|
297
|
+
|
|
298
|
+
DO $rename_relations$
|
|
299
|
+
BEGIN
|
|
300
|
+
IF to_regclass('integration_feature_facets') IS NOT NULL
|
|
301
|
+
AND to_regclass('integration_facet_definitions') IS NULL
|
|
302
|
+
THEN
|
|
303
|
+
ALTER TABLE integration_feature_facets RENAME TO integration_facet_definitions;
|
|
304
|
+
END IF;
|
|
305
|
+
IF to_regclass('integration_feature_bindings') IS NOT NULL
|
|
306
|
+
AND to_regclass('integration_facet_bindings') IS NULL
|
|
307
|
+
THEN
|
|
308
|
+
ALTER TABLE integration_feature_bindings RENAME TO integration_facet_bindings;
|
|
309
|
+
END IF;
|
|
310
|
+
IF to_regclass('integration_feature_binding_owners') IS NOT NULL
|
|
311
|
+
AND to_regclass('integration_facet_binding_owners') IS NULL
|
|
312
|
+
THEN
|
|
313
|
+
ALTER TABLE integration_feature_binding_owners RENAME TO integration_facet_binding_owners;
|
|
314
|
+
END IF;
|
|
315
|
+
END
|
|
316
|
+
$rename_relations$;
|
|
317
|
+
|
|
318
|
+
DO $rename_columns$
|
|
319
|
+
BEGIN
|
|
320
|
+
IF EXISTS (
|
|
321
|
+
SELECT 1 FROM information_schema.columns
|
|
322
|
+
WHERE table_schema = current_schema()
|
|
323
|
+
AND table_name = 'integration_facet_definitions'
|
|
324
|
+
AND column_name = 'feature_key'
|
|
325
|
+
) THEN
|
|
326
|
+
ALTER TABLE integration_facet_definitions RENAME COLUMN feature_key TO facet_key;
|
|
327
|
+
END IF;
|
|
328
|
+
IF EXISTS (
|
|
329
|
+
SELECT 1 FROM information_schema.columns
|
|
330
|
+
WHERE table_schema = current_schema()
|
|
331
|
+
AND table_name = 'integration_facet_bindings'
|
|
332
|
+
AND column_name = 'feature_facet_id'
|
|
333
|
+
) THEN
|
|
334
|
+
ALTER TABLE integration_facet_bindings RENAME COLUMN feature_facet_id TO facet_definition_id;
|
|
335
|
+
END IF;
|
|
336
|
+
END
|
|
337
|
+
$rename_columns$;
|
|
338
|
+
|
|
339
|
+
DO $rename_constraints$
|
|
340
|
+
DECLARE
|
|
341
|
+
target_table text;
|
|
342
|
+
old_name text;
|
|
343
|
+
new_name text;
|
|
344
|
+
constraint_row record;
|
|
345
|
+
BEGIN
|
|
346
|
+
FOREACH target_table IN ARRAY ARRAY[
|
|
347
|
+
'integration_facet_definitions',
|
|
348
|
+
'integration_facet_bindings',
|
|
349
|
+
'integration_facet_binding_owners'
|
|
350
|
+
]
|
|
351
|
+
LOOP
|
|
352
|
+
FOR constraint_row IN
|
|
353
|
+
SELECT conname
|
|
354
|
+
FROM pg_constraint
|
|
355
|
+
WHERE conrelid = to_regclass(target_table)
|
|
356
|
+
AND conname LIKE '%feature%'
|
|
357
|
+
ORDER BY conname
|
|
358
|
+
LOOP
|
|
359
|
+
old_name := constraint_row.conname;
|
|
360
|
+
new_name := replace(old_name, 'integration_feature_facets', 'integration_facet_definitions');
|
|
361
|
+
new_name := replace(new_name, 'integration_feature_bindings', 'integration_facet_bindings');
|
|
362
|
+
new_name := replace(new_name, 'integration_feature_binding_owners', 'integration_facet_binding_owners');
|
|
363
|
+
new_name := replace(new_name, 'feature_facet', 'facet_definition');
|
|
364
|
+
new_name := replace(new_name, 'feature_key', 'facet_key');
|
|
365
|
+
new_name := replace(new_name, 'integration_feature', 'integration_facet');
|
|
366
|
+
new_name := replace(new_name, 'feature', 'facet');
|
|
367
|
+
IF old_name <> new_name THEN
|
|
368
|
+
EXECUTE format('ALTER TABLE %I RENAME CONSTRAINT %I TO %I', target_table, old_name, new_name);
|
|
369
|
+
END IF;
|
|
370
|
+
END LOOP;
|
|
371
|
+
END LOOP;
|
|
372
|
+
END
|
|
373
|
+
$rename_constraints$;
|
|
374
|
+
|
|
375
|
+
DO $rename_indexes$
|
|
376
|
+
DECLARE
|
|
377
|
+
index_row record;
|
|
378
|
+
new_name text;
|
|
379
|
+
BEGIN
|
|
380
|
+
FOR index_row IN
|
|
381
|
+
SELECT indexname
|
|
382
|
+
FROM pg_indexes
|
|
383
|
+
WHERE schemaname = current_schema()
|
|
384
|
+
AND tablename IN (
|
|
385
|
+
'integration_facet_definitions',
|
|
386
|
+
'integration_facet_bindings',
|
|
387
|
+
'integration_facet_binding_owners'
|
|
388
|
+
)
|
|
389
|
+
AND indexname LIKE '%feature%'
|
|
390
|
+
ORDER BY indexname
|
|
391
|
+
LOOP
|
|
392
|
+
new_name := replace(index_row.indexname, 'integration_feature_facets', 'integration_facet_definitions');
|
|
393
|
+
new_name := replace(new_name, 'integration_feature_bindings', 'integration_facet_bindings');
|
|
394
|
+
new_name := replace(new_name, 'integration_feature_binding_owners', 'integration_facet_binding_owners');
|
|
395
|
+
new_name := replace(new_name, 'feature_facet', 'facet_definition');
|
|
396
|
+
new_name := replace(new_name, 'feature_key', 'facet_key');
|
|
397
|
+
new_name := replace(new_name, 'integration_feature', 'integration_facet');
|
|
398
|
+
new_name := replace(new_name, 'feature', 'facet');
|
|
399
|
+
IF index_row.indexname <> new_name THEN
|
|
400
|
+
EXECUTE format('ALTER INDEX %I RENAME TO %I', index_row.indexname, new_name);
|
|
401
|
+
END IF;
|
|
402
|
+
END LOOP;
|
|
403
|
+
END
|
|
404
|
+
$rename_indexes$;
|
|
405
|
+
|
|
406
|
+
UPDATE integration_facet_binding_owners
|
|
407
|
+
SET owner_id = 'facet:' || substr(owner_id, length('feature:') + 1)
|
|
408
|
+
WHERE owner_kind = 'direct'
|
|
409
|
+
AND owner_id LIKE 'feature:%';
|
|
410
|
+
|
|
411
|
+
CREATE OR REPLACE FUNCTION capability_v2_validate_facet_binding()
|
|
412
|
+
RETURNS trigger
|
|
413
|
+
LANGUAGE plpgsql
|
|
414
|
+
AS $$
|
|
415
|
+
BEGIN
|
|
416
|
+
IF NOT EXISTS (
|
|
417
|
+
SELECT 1
|
|
418
|
+
FROM integration_facet_definitions definition
|
|
419
|
+
JOIN capability_facet_installations installation
|
|
420
|
+
ON installation.id = NEW.integration_facet_installation_id
|
|
421
|
+
AND installation.facet_id = definition.integration_facet_id
|
|
422
|
+
WHERE definition.id = NEW.facet_definition_id
|
|
423
|
+
AND installation.account_id = NEW.account_id
|
|
424
|
+
AND installation.workspace_id = NEW.workspace_id
|
|
425
|
+
) THEN
|
|
426
|
+
RAISE EXCEPTION 'Facet binding does not match its Integration installation or tenant'
|
|
427
|
+
USING ERRCODE = '23514';
|
|
428
|
+
END IF;
|
|
429
|
+
IF NEW.connection_id IS NOT NULL AND NOT EXISTS (
|
|
430
|
+
SELECT 1 FROM connections connection
|
|
431
|
+
WHERE connection.id = NEW.connection_id
|
|
432
|
+
AND connection.account_id = NEW.account_id
|
|
433
|
+
AND connection.workspace_id = NEW.workspace_id
|
|
434
|
+
) THEN
|
|
435
|
+
RAISE EXCEPTION 'Facet binding Connection belongs to another tenant'
|
|
436
|
+
USING ERRCODE = '23514';
|
|
437
|
+
END IF;
|
|
438
|
+
RETURN NEW;
|
|
439
|
+
END;
|
|
440
|
+
$$;
|
|
441
|
+
|
|
442
|
+
CREATE TRIGGER integration_facet_bindings_validate
|
|
443
|
+
BEFORE INSERT OR UPDATE ON integration_facet_bindings
|
|
444
|
+
FOR EACH ROW EXECUTE FUNCTION capability_v2_validate_facet_binding();
|
|
445
|
+
|
|
446
|
+
CREATE OR REPLACE FUNCTION capability_v2_validate_facet_binding_owner()
|
|
447
|
+
RETURNS trigger
|
|
448
|
+
LANGUAGE plpgsql
|
|
449
|
+
AS $$
|
|
450
|
+
BEGIN
|
|
451
|
+
IF NOT EXISTS (
|
|
452
|
+
SELECT 1 FROM integration_facet_bindings binding
|
|
453
|
+
WHERE binding.id = NEW.binding_id
|
|
454
|
+
AND binding.account_id = NEW.account_id
|
|
455
|
+
AND binding.workspace_id = NEW.workspace_id
|
|
456
|
+
) THEN
|
|
457
|
+
RAISE EXCEPTION 'Facet binding owner does not match its binding tenant'
|
|
458
|
+
USING ERRCODE = '23514';
|
|
459
|
+
END IF;
|
|
460
|
+
IF NEW.owner_kind = 'plugin' THEN
|
|
461
|
+
IF NEW.owner_id !~* '^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$' THEN
|
|
462
|
+
RAISE EXCEPTION 'Plugin Facet binding owner belongs to another tenant or does not exist'
|
|
463
|
+
USING ERRCODE = '23514';
|
|
464
|
+
ELSIF NOT EXISTS (
|
|
465
|
+
SELECT 1 FROM capability_plugin_installations plugin
|
|
466
|
+
WHERE plugin.id = NEW.owner_id::uuid
|
|
467
|
+
AND plugin.account_id = NEW.account_id
|
|
468
|
+
AND plugin.workspace_id = NEW.workspace_id
|
|
469
|
+
) THEN
|
|
470
|
+
RAISE EXCEPTION 'Plugin Facet binding owner belongs to another tenant or does not exist'
|
|
471
|
+
USING ERRCODE = '23514';
|
|
472
|
+
END IF;
|
|
473
|
+
ELSIF NEW.owner_kind = 'pack'
|
|
474
|
+
AND NEW.owner_id ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$'
|
|
475
|
+
THEN
|
|
476
|
+
IF NOT EXISTS (
|
|
477
|
+
SELECT 1 FROM pack_installations pack
|
|
478
|
+
WHERE pack.id = NEW.owner_id::uuid
|
|
479
|
+
AND pack.account_id = NEW.account_id
|
|
480
|
+
AND pack.workspace_id = NEW.workspace_id
|
|
481
|
+
) THEN
|
|
482
|
+
RAISE EXCEPTION 'Pack Facet binding owner belongs to another tenant or does not exist'
|
|
483
|
+
USING ERRCODE = '23514';
|
|
484
|
+
END IF;
|
|
485
|
+
END IF;
|
|
486
|
+
RETURN NEW;
|
|
487
|
+
END;
|
|
488
|
+
$$;
|
|
489
|
+
|
|
490
|
+
CREATE TRIGGER integration_facet_binding_owners_validate
|
|
491
|
+
BEFORE INSERT OR UPDATE ON integration_facet_binding_owners
|
|
492
|
+
FOR EACH ROW EXECUTE FUNCTION capability_v2_validate_facet_binding_owner();
|
|
493
|
+
|
|
494
|
+
DO $facet_postcondition$
|
|
495
|
+
BEGIN
|
|
496
|
+
IF to_regclass('integration_feature_facets') IS NOT NULL
|
|
497
|
+
OR to_regclass('integration_feature_bindings') IS NOT NULL
|
|
498
|
+
OR to_regclass('integration_feature_binding_owners') IS NOT NULL
|
|
499
|
+
OR to_regclass('integration_facet_definitions') IS NULL
|
|
500
|
+
OR to_regclass('integration_facet_bindings') IS NULL
|
|
501
|
+
OR to_regclass('integration_facet_binding_owners') IS NULL
|
|
502
|
+
THEN
|
|
503
|
+
RAISE EXCEPTION 'Integration Facet physical authority migration did not converge'
|
|
504
|
+
USING ERRCODE = '23514';
|
|
505
|
+
END IF;
|
|
506
|
+
|
|
507
|
+
IF EXISTS (
|
|
508
|
+
SELECT 1
|
|
509
|
+
FROM information_schema.columns
|
|
510
|
+
WHERE table_schema = current_schema()
|
|
511
|
+
AND table_name IN (
|
|
512
|
+
'integration_facet_definitions',
|
|
513
|
+
'integration_facet_bindings',
|
|
514
|
+
'integration_facet_binding_owners'
|
|
515
|
+
)
|
|
516
|
+
AND column_name LIKE '%feature%'
|
|
517
|
+
) OR EXISTS (
|
|
518
|
+
SELECT 1
|
|
519
|
+
FROM pg_constraint
|
|
520
|
+
WHERE conrelid IN (
|
|
521
|
+
to_regclass('integration_facet_definitions'),
|
|
522
|
+
to_regclass('integration_facet_bindings'),
|
|
523
|
+
to_regclass('integration_facet_binding_owners')
|
|
524
|
+
)
|
|
525
|
+
AND conname LIKE '%feature%'
|
|
526
|
+
) OR EXISTS (
|
|
527
|
+
SELECT 1
|
|
528
|
+
FROM pg_indexes
|
|
529
|
+
WHERE schemaname = current_schema()
|
|
530
|
+
AND tablename IN (
|
|
531
|
+
'integration_facet_definitions',
|
|
532
|
+
'integration_facet_bindings',
|
|
533
|
+
'integration_facet_binding_owners'
|
|
534
|
+
)
|
|
535
|
+
AND indexname LIKE '%feature%'
|
|
536
|
+
) OR EXISTS (
|
|
537
|
+
SELECT 1
|
|
538
|
+
FROM information_schema.triggers
|
|
539
|
+
WHERE trigger_schema = current_schema()
|
|
540
|
+
AND event_object_table IN (
|
|
541
|
+
'integration_facet_definitions',
|
|
542
|
+
'integration_facet_bindings',
|
|
543
|
+
'integration_facet_binding_owners'
|
|
544
|
+
)
|
|
545
|
+
AND trigger_name LIKE '%feature%'
|
|
546
|
+
) OR EXISTS (
|
|
547
|
+
SELECT 1
|
|
548
|
+
FROM pg_proc procedure
|
|
549
|
+
JOIN pg_namespace namespace ON namespace.oid = procedure.pronamespace
|
|
550
|
+
WHERE namespace.nspname = current_schema()
|
|
551
|
+
AND procedure.proname LIKE '%feature_binding%'
|
|
552
|
+
) THEN
|
|
553
|
+
RAISE EXCEPTION 'Integration Facet catalog names retain legacy Feature identity'
|
|
554
|
+
USING ERRCODE = '23514';
|
|
555
|
+
END IF;
|
|
556
|
+
|
|
557
|
+
IF EXISTS (
|
|
558
|
+
SELECT 1
|
|
559
|
+
FROM workspace_packs pack,
|
|
560
|
+
LATERAL jsonb_array_elements(COALESCE(pack.manifest -> 'components', '[]'::jsonb)) component
|
|
561
|
+
WHERE component ->> 'kind' = 'feature'
|
|
562
|
+
OR component ? 'featureKey'
|
|
563
|
+
) OR EXISTS (
|
|
564
|
+
SELECT 1
|
|
565
|
+
FROM pack_installations installation,
|
|
566
|
+
LATERAL jsonb_array_elements(COALESCE(installation.manifest_snapshot -> 'components', '[]'::jsonb)) component
|
|
567
|
+
WHERE installation.manifest_snapshot IS NOT NULL
|
|
568
|
+
AND (component ->> 'kind' = 'feature' OR component ? 'featureKey')
|
|
569
|
+
) OR EXISTS (
|
|
570
|
+
SELECT 1 FROM pack_installation_components
|
|
571
|
+
WHERE kind = 'feature' OR metadata ? 'featureKey'
|
|
572
|
+
) OR EXISTS (
|
|
573
|
+
SELECT 1 FROM integration_facet_binding_owners
|
|
574
|
+
WHERE owner_kind = 'direct' AND owner_id LIKE 'feature:%'
|
|
575
|
+
) OR EXISTS (
|
|
576
|
+
SELECT 1 FROM capability_operations
|
|
577
|
+
WHERE target_kind = 'facet_binding'
|
|
578
|
+
AND result IS NOT NULL
|
|
579
|
+
AND (
|
|
580
|
+
result ? 'featureKey'
|
|
581
|
+
OR (jsonb_typeof(result -> 'binding') = 'object' AND result -> 'binding' ? 'featureKey')
|
|
582
|
+
)
|
|
583
|
+
) THEN
|
|
584
|
+
RAISE EXCEPTION 'Integration Facet persisted identity migration did not converge'
|
|
585
|
+
USING ERRCODE = '23514';
|
|
586
|
+
END IF;
|
|
587
|
+
|
|
588
|
+
IF EXISTS (
|
|
589
|
+
SELECT 1
|
|
590
|
+
FROM pack_installations
|
|
591
|
+
WHERE manifest_snapshot IS NOT NULL
|
|
592
|
+
AND manifest_digest <> encode(
|
|
593
|
+
digest(
|
|
594
|
+
convert_to(
|
|
595
|
+
opengeni_private.integration_facet_canonical_json(manifest_snapshot),
|
|
596
|
+
'UTF8'
|
|
597
|
+
),
|
|
598
|
+
'sha256'
|
|
599
|
+
),
|
|
600
|
+
'hex'
|
|
601
|
+
)
|
|
602
|
+
) THEN
|
|
603
|
+
RAISE EXCEPTION 'Integration Facet Pack digest migration did not converge'
|
|
604
|
+
USING ERRCODE = '23514';
|
|
605
|
+
END IF;
|
|
606
|
+
END
|
|
607
|
+
$facet_postcondition$;
|
|
608
|
+
|
|
609
|
+
DROP FUNCTION opengeni_private.integration_facet_rewrite_pack(jsonb);
|
|
610
|
+
DROP FUNCTION opengeni_private.integration_facet_canonical_json(jsonb);
|