@opengeni/db 0.26.0 → 0.27.3
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/{chunk-7WTDI7Y3.js → chunk-EX7CDSGH.js} +88 -1
- package/dist/{chunk-7WTDI7Y3.js.map → chunk-EX7CDSGH.js.map} +1 -1
- package/dist/{chunk-KW6U54V2.js → chunk-IHPCI4GV.js} +3 -1
- package/dist/chunk-IHPCI4GV.js.map +1 -0
- package/dist/index.js +291 -4
- package/dist/index.js.map +1 -1
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +2 -2
- package/dist/schema.js +3 -1
- package/dist/workspace-instruction-policies-schema.d.ts +381 -0
- package/dist/workspace-instruction-policies.d.ts +35 -1
- package/drizzle/0169_workspace_instruction_policy_onboarding_proposals.sql +202 -0
- package/package.json +4 -4
- package/src/runtime-posture.ts +2 -0
- package/src/workspace-instruction-policies-schema.ts +86 -0
- package/src/workspace-instruction-policies.ts +381 -1
- package/dist/chunk-KW6U54V2.js.map +0 -1
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
|
|
3
|
+
-- Onboarding inputs create immutable proposal receipts plus ordinary inactive
|
|
4
|
+
-- instruction-policy revisions. This table is provenance/audit evidence only:
|
|
5
|
+
-- it never writes or owns an active policy head.
|
|
6
|
+
CREATE TABLE "workspace_instruction_policy_onboarding_proposals" (
|
|
7
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
8
|
+
"operation_id" uuid NOT NULL,
|
|
9
|
+
"request_fingerprint" text NOT NULL,
|
|
10
|
+
"account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
|
|
11
|
+
"workspace_id" uuid NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
|
|
12
|
+
"kind" text NOT NULL,
|
|
13
|
+
"scope" text NOT NULL,
|
|
14
|
+
"role_key" text,
|
|
15
|
+
"source_id" text NOT NULL,
|
|
16
|
+
"source_version" text NOT NULL,
|
|
17
|
+
"confidence_bps" integer NOT NULL,
|
|
18
|
+
"baseline_revision_id" uuid REFERENCES "workspace_instruction_policy_revisions"("id")
|
|
19
|
+
ON DELETE RESTRICT,
|
|
20
|
+
"baseline_revision" bigint,
|
|
21
|
+
"baseline_content_hash" text,
|
|
22
|
+
"baseline_activation_version" bigint NOT NULL,
|
|
23
|
+
"baseline_activated_at" timestamptz,
|
|
24
|
+
"draft_revision_id" uuid NOT NULL REFERENCES "workspace_instruction_policy_revisions"("id")
|
|
25
|
+
ON DELETE RESTRICT,
|
|
26
|
+
"draft_revision" bigint NOT NULL,
|
|
27
|
+
"draft_content_hash" text NOT NULL,
|
|
28
|
+
"status" text NOT NULL DEFAULT 'proposed',
|
|
29
|
+
"created_by_subject_id" text NOT NULL,
|
|
30
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
31
|
+
CONSTRAINT "workspace_instruction_policy_onboarding_proposals_operation_receipt_chk" CHECK (
|
|
32
|
+
"request_fingerprint" ~ '^[0-9a-f]{64}$'
|
|
33
|
+
),
|
|
34
|
+
CONSTRAINT "workspace_instruction_policy_onboarding_proposals_target_chk" CHECK (
|
|
35
|
+
("kind" = 'charter' AND "scope" = 'global' AND "role_key" IS NULL)
|
|
36
|
+
OR ("kind" = 'policy' AND "scope" = 'global' AND "role_key" IS NULL)
|
|
37
|
+
OR ("kind" = 'policy' AND "scope" = 'role' AND "role_key" IS NOT NULL)
|
|
38
|
+
),
|
|
39
|
+
CONSTRAINT "workspace_instruction_policy_onboarding_proposals_role_key_chk" CHECK (
|
|
40
|
+
"role_key" IS NULL
|
|
41
|
+
OR (
|
|
42
|
+
"role_key" = lower(btrim("role_key"))
|
|
43
|
+
AND length("role_key") BETWEEN 1 AND 64
|
|
44
|
+
AND "role_key" ~ '^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$'
|
|
45
|
+
AND "role_key" !~ '--'
|
|
46
|
+
)
|
|
47
|
+
),
|
|
48
|
+
CONSTRAINT "workspace_instruction_policy_onboarding_proposals_source_chk" CHECK (
|
|
49
|
+
length(btrim("source_id")) BETWEEN 1 AND 512
|
|
50
|
+
AND length(btrim("source_version")) BETWEEN 1 AND 256
|
|
51
|
+
AND "confidence_bps" BETWEEN 0 AND 10000
|
|
52
|
+
),
|
|
53
|
+
CONSTRAINT "workspace_instruction_policy_onboarding_proposals_baseline_chk" CHECK (
|
|
54
|
+
(
|
|
55
|
+
"baseline_revision_id" IS NULL
|
|
56
|
+
AND "baseline_revision" IS NULL
|
|
57
|
+
AND "baseline_content_hash" IS NULL
|
|
58
|
+
AND "baseline_activation_version" = 0
|
|
59
|
+
AND "baseline_activated_at" IS NULL
|
|
60
|
+
) OR (
|
|
61
|
+
"baseline_revision_id" IS NOT NULL
|
|
62
|
+
AND "baseline_revision" > 0
|
|
63
|
+
AND "baseline_content_hash" ~ '^[0-9a-f]{64}$'
|
|
64
|
+
AND "baseline_activation_version" > 0
|
|
65
|
+
AND "baseline_activated_at" IS NOT NULL
|
|
66
|
+
)
|
|
67
|
+
),
|
|
68
|
+
CONSTRAINT "workspace_instruction_policy_onboarding_proposals_draft_chk" CHECK (
|
|
69
|
+
"draft_revision" > 0
|
|
70
|
+
AND "draft_content_hash" ~ '^[0-9a-f]{64}$'
|
|
71
|
+
AND "status" = 'proposed'
|
|
72
|
+
),
|
|
73
|
+
CONSTRAINT "workspace_instruction_policy_onboarding_proposals_actor_chk" CHECK (
|
|
74
|
+
length(btrim("created_by_subject_id")) BETWEEN 1 AND 1024
|
|
75
|
+
),
|
|
76
|
+
CONSTRAINT "workspace_instruction_policy_onboarding_proposals_workspace_operation_uq"
|
|
77
|
+
UNIQUE ("workspace_id", "operation_id")
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
CREATE UNIQUE INDEX "workspace_instruction_policy_onboarding_proposals_source_version_target_uq"
|
|
81
|
+
ON "workspace_instruction_policy_onboarding_proposals"
|
|
82
|
+
(
|
|
83
|
+
"workspace_id",
|
|
84
|
+
"kind",
|
|
85
|
+
"scope",
|
|
86
|
+
coalesce("role_key", ''),
|
|
87
|
+
"source_id",
|
|
88
|
+
"source_version"
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
CREATE INDEX "workspace_instruction_policy_onboarding_proposals_workspace_time_idx"
|
|
92
|
+
ON "workspace_instruction_policy_onboarding_proposals"
|
|
93
|
+
("workspace_id", "created_at" DESC, "id" DESC);
|
|
94
|
+
|
|
95
|
+
CREATE OR REPLACE FUNCTION workspace_instruction_policy_validate_onboarding_proposal()
|
|
96
|
+
RETURNS trigger
|
|
97
|
+
LANGUAGE plpgsql
|
|
98
|
+
AS $$
|
|
99
|
+
BEGIN
|
|
100
|
+
IF NEW."baseline_revision_id" IS NULL THEN
|
|
101
|
+
IF EXISTS (
|
|
102
|
+
SELECT 1
|
|
103
|
+
FROM "workspace_instruction_policy_heads" head
|
|
104
|
+
WHERE head."account_id" = NEW."account_id"
|
|
105
|
+
AND head."workspace_id" = NEW."workspace_id"
|
|
106
|
+
AND head."kind" = NEW."kind"
|
|
107
|
+
AND head."scope" = NEW."scope"
|
|
108
|
+
AND head."role_key" IS NOT DISTINCT FROM NEW."role_key"
|
|
109
|
+
) THEN
|
|
110
|
+
RAISE EXCEPTION 'instruction-policy onboarding proposal must capture the exact active head baseline'
|
|
111
|
+
USING ERRCODE = '23514';
|
|
112
|
+
END IF;
|
|
113
|
+
ELSIF NOT EXISTS (
|
|
114
|
+
SELECT 1
|
|
115
|
+
FROM "workspace_instruction_policy_heads" head
|
|
116
|
+
WHERE head."account_id" = NEW."account_id"
|
|
117
|
+
AND head."workspace_id" = NEW."workspace_id"
|
|
118
|
+
AND head."kind" = NEW."kind"
|
|
119
|
+
AND head."scope" = NEW."scope"
|
|
120
|
+
AND head."role_key" IS NOT DISTINCT FROM NEW."role_key"
|
|
121
|
+
AND head."revision_id" = NEW."baseline_revision_id"
|
|
122
|
+
AND head."revision" = NEW."baseline_revision"
|
|
123
|
+
AND head."content_hash" = NEW."baseline_content_hash"
|
|
124
|
+
AND head."activation_version" = NEW."baseline_activation_version"
|
|
125
|
+
AND head."activated_at" = NEW."baseline_activated_at"
|
|
126
|
+
) THEN
|
|
127
|
+
RAISE EXCEPTION 'instruction-policy onboarding proposal must capture the exact active head baseline'
|
|
128
|
+
USING ERRCODE = '23514';
|
|
129
|
+
END IF;
|
|
130
|
+
|
|
131
|
+
IF NEW."baseline_revision_id" IS NOT NULL AND NOT EXISTS (
|
|
132
|
+
SELECT 1
|
|
133
|
+
FROM "workspace_instruction_policy_revisions" revision
|
|
134
|
+
WHERE revision."id" = NEW."baseline_revision_id"
|
|
135
|
+
AND revision."account_id" = NEW."account_id"
|
|
136
|
+
AND revision."workspace_id" = NEW."workspace_id"
|
|
137
|
+
AND revision."kind" = NEW."kind"
|
|
138
|
+
AND revision."scope" = NEW."scope"
|
|
139
|
+
AND revision."role_key" IS NOT DISTINCT FROM NEW."role_key"
|
|
140
|
+
AND revision."revision" = NEW."baseline_revision"
|
|
141
|
+
AND revision."content_hash" = NEW."baseline_content_hash"
|
|
142
|
+
) THEN
|
|
143
|
+
RAISE EXCEPTION 'instruction-policy onboarding proposal has an invalid baseline revision'
|
|
144
|
+
USING ERRCODE = '23514';
|
|
145
|
+
END IF;
|
|
146
|
+
|
|
147
|
+
IF NOT EXISTS (
|
|
148
|
+
SELECT 1
|
|
149
|
+
FROM "workspace_instruction_policy_revisions" revision
|
|
150
|
+
WHERE revision."id" = NEW."draft_revision_id"
|
|
151
|
+
AND revision."operation_id" = NEW."operation_id"
|
|
152
|
+
AND revision."request_fingerprint" = NEW."request_fingerprint"
|
|
153
|
+
AND revision."account_id" = NEW."account_id"
|
|
154
|
+
AND revision."workspace_id" = NEW."workspace_id"
|
|
155
|
+
AND revision."kind" = NEW."kind"
|
|
156
|
+
AND revision."scope" = NEW."scope"
|
|
157
|
+
AND revision."role_key" IS NOT DISTINCT FROM NEW."role_key"
|
|
158
|
+
AND revision."revision" = NEW."draft_revision"
|
|
159
|
+
AND revision."content_hash" = NEW."draft_content_hash"
|
|
160
|
+
AND revision."provenance_source" = 'onboarding'
|
|
161
|
+
AND revision."provenance_source_id" = NEW."id"::text
|
|
162
|
+
AND revision."supersedes_revision_id" IS NOT DISTINCT FROM NEW."baseline_revision_id"
|
|
163
|
+
AND revision."created_by_subject_id" = NEW."created_by_subject_id"
|
|
164
|
+
) THEN
|
|
165
|
+
RAISE EXCEPTION 'instruction-policy onboarding proposal must identify its exact inactive draft'
|
|
166
|
+
USING ERRCODE = '23514';
|
|
167
|
+
END IF;
|
|
168
|
+
|
|
169
|
+
IF EXISTS (
|
|
170
|
+
SELECT 1
|
|
171
|
+
FROM "workspace_instruction_policy_heads" head
|
|
172
|
+
WHERE head."account_id" = NEW."account_id"
|
|
173
|
+
AND head."workspace_id" = NEW."workspace_id"
|
|
174
|
+
AND head."revision_id" = NEW."draft_revision_id"
|
|
175
|
+
) OR EXISTS (
|
|
176
|
+
SELECT 1
|
|
177
|
+
FROM "workspace_instruction_policy_activation_events" event
|
|
178
|
+
WHERE event."account_id" = NEW."account_id"
|
|
179
|
+
AND event."workspace_id" = NEW."workspace_id"
|
|
180
|
+
AND event."new_revision_id" = NEW."draft_revision_id"
|
|
181
|
+
) THEN
|
|
182
|
+
RAISE EXCEPTION 'instruction-policy onboarding proposal must identify a never-activated inactive draft'
|
|
183
|
+
USING ERRCODE = '23514';
|
|
184
|
+
END IF;
|
|
185
|
+
RETURN NEW;
|
|
186
|
+
END;
|
|
187
|
+
$$;
|
|
188
|
+
|
|
189
|
+
CREATE TRIGGER workspace_instruction_policy_onboarding_proposals_validate_draft
|
|
190
|
+
BEFORE INSERT OR UPDATE ON "workspace_instruction_policy_onboarding_proposals"
|
|
191
|
+
FOR EACH ROW EXECUTE FUNCTION workspace_instruction_policy_validate_onboarding_proposal();
|
|
192
|
+
|
|
193
|
+
CREATE TRIGGER workspace_instruction_policy_onboarding_proposals_immutable
|
|
194
|
+
BEFORE UPDATE OR DELETE ON "workspace_instruction_policy_onboarding_proposals"
|
|
195
|
+
FOR EACH ROW EXECUTE FUNCTION workspace_instruction_policy_reject_mutation();
|
|
196
|
+
|
|
197
|
+
ALTER TABLE "workspace_instruction_policy_onboarding_proposals" ENABLE ROW LEVEL SECURITY;
|
|
198
|
+
ALTER TABLE "workspace_instruction_policy_onboarding_proposals" FORCE ROW LEVEL SECURITY;
|
|
199
|
+
|
|
200
|
+
CREATE POLICY workspace_isolation ON "workspace_instruction_policy_onboarding_proposals"
|
|
201
|
+
USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
|
|
202
|
+
WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/db",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.3",
|
|
4
4
|
"description": "OpenGeni persistence: Drizzle schema, RLS-scoped query layer, the SQL migration runner, and role provisioning.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@opengeni/codex": "^0.2.10",
|
|
54
|
-
"@opengeni/config": "^0.10.
|
|
55
|
-
"@opengeni/contracts": "^0.
|
|
56
|
-
"@opengeni/network": "^0.1.
|
|
54
|
+
"@opengeni/config": "^0.10.9",
|
|
55
|
+
"@opengeni/contracts": "^0.37.0",
|
|
56
|
+
"@opengeni/network": "^0.1.2",
|
|
57
57
|
"drizzle-orm": "^0.45.2",
|
|
58
58
|
"postgres": "^3.4.7"
|
|
59
59
|
},
|
package/src/runtime-posture.ts
CHANGED
|
@@ -126,6 +126,7 @@ export const FORCE_RLS_TABLES = [
|
|
|
126
126
|
"workspace_inference_controls",
|
|
127
127
|
"workspace_instruction_policy_activation_events",
|
|
128
128
|
"workspace_instruction_policy_heads",
|
|
129
|
+
"workspace_instruction_policy_onboarding_proposals",
|
|
129
130
|
"workspace_instruction_policy_revisions",
|
|
130
131
|
"workspace_instruction_policy_snapshots",
|
|
131
132
|
"workspace_model_policies",
|
|
@@ -294,6 +295,7 @@ export const RUNTIME_READ_INSERT_TABLES = [
|
|
|
294
295
|
"workspace_artifact_events",
|
|
295
296
|
"workspace_artifact_versions",
|
|
296
297
|
"workspace_instruction_policy_activation_events",
|
|
298
|
+
"workspace_instruction_policy_onboarding_proposals",
|
|
297
299
|
"workspace_instruction_policy_revisions",
|
|
298
300
|
] as const;
|
|
299
301
|
|
|
@@ -172,6 +172,92 @@ export const workspaceInstructionPolicyActivationEvents = pgTable(
|
|
|
172
172
|
}),
|
|
173
173
|
);
|
|
174
174
|
|
|
175
|
+
export const workspaceInstructionPolicyOnboardingProposals = pgTable(
|
|
176
|
+
"workspace_instruction_policy_onboarding_proposals",
|
|
177
|
+
{
|
|
178
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
179
|
+
operationId: uuid("operation_id").notNull(),
|
|
180
|
+
requestFingerprint: text("request_fingerprint").notNull(),
|
|
181
|
+
accountId: uuid("account_id").notNull(),
|
|
182
|
+
workspaceId: uuid("workspace_id").notNull(),
|
|
183
|
+
kind: text("kind").notNull(),
|
|
184
|
+
scope: text("scope").notNull(),
|
|
185
|
+
roleKey: text("role_key"),
|
|
186
|
+
sourceId: text("source_id").notNull(),
|
|
187
|
+
sourceVersion: text("source_version").notNull(),
|
|
188
|
+
confidenceBps: integer("confidence_bps").notNull(),
|
|
189
|
+
baselineRevisionId: uuid("baseline_revision_id"),
|
|
190
|
+
baselineRevision: bigint("baseline_revision", { mode: "number" }),
|
|
191
|
+
baselineContentHash: text("baseline_content_hash"),
|
|
192
|
+
baselineActivationVersion: bigint("baseline_activation_version", { mode: "number" }).notNull(),
|
|
193
|
+
baselineActivatedAt: timestamp("baseline_activated_at", { withTimezone: true }),
|
|
194
|
+
draftRevisionId: uuid("draft_revision_id").notNull(),
|
|
195
|
+
draftRevision: bigint("draft_revision", { mode: "number" }).notNull(),
|
|
196
|
+
draftContentHash: text("draft_content_hash").notNull(),
|
|
197
|
+
status: text("status").notNull().default("proposed"),
|
|
198
|
+
createdBySubjectId: text("created_by_subject_id").notNull(),
|
|
199
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
200
|
+
},
|
|
201
|
+
(table) => ({
|
|
202
|
+
workspaceOperation: uniqueIndex(
|
|
203
|
+
"workspace_instruction_policy_onboarding_proposals_workspace_operation_uq",
|
|
204
|
+
).on(table.workspaceId, table.operationId),
|
|
205
|
+
sourceVersionTarget: uniqueIndex(
|
|
206
|
+
"workspace_instruction_policy_onboarding_proposals_source_version_target_uq",
|
|
207
|
+
).on(
|
|
208
|
+
table.workspaceId,
|
|
209
|
+
table.kind,
|
|
210
|
+
table.scope,
|
|
211
|
+
sql`coalesce(${table.roleKey}, '')`,
|
|
212
|
+
table.sourceId,
|
|
213
|
+
table.sourceVersion,
|
|
214
|
+
),
|
|
215
|
+
workspaceTimeline: index(
|
|
216
|
+
"workspace_instruction_policy_onboarding_proposals_workspace_time_idx",
|
|
217
|
+
).on(table.workspaceId, table.createdAt, table.id),
|
|
218
|
+
operationReceipt: check(
|
|
219
|
+
"workspace_instruction_policy_onboarding_proposals_operation_receipt_chk",
|
|
220
|
+
sql`${table.requestFingerprint} ~ '^[0-9a-f]{64}$'`,
|
|
221
|
+
),
|
|
222
|
+
target: check(
|
|
223
|
+
"workspace_instruction_policy_onboarding_proposals_target_chk",
|
|
224
|
+
sql`(
|
|
225
|
+
(${table.kind} = 'charter' and ${table.scope} = 'global' and ${table.roleKey} is null)
|
|
226
|
+
or (${table.kind} = 'policy' and ${table.scope} = 'global' and ${table.roleKey} is null)
|
|
227
|
+
or (${table.kind} = 'policy' and ${table.scope} = 'role' and ${table.roleKey} is not null)
|
|
228
|
+
)`,
|
|
229
|
+
),
|
|
230
|
+
source: check(
|
|
231
|
+
"workspace_instruction_policy_onboarding_proposals_source_chk",
|
|
232
|
+
sql`length(btrim(${table.sourceId})) between 1 and 512
|
|
233
|
+
and length(btrim(${table.sourceVersion})) between 1 and 256
|
|
234
|
+
and ${table.confidenceBps} between 0 and 10000`,
|
|
235
|
+
),
|
|
236
|
+
baseline: check(
|
|
237
|
+
"workspace_instruction_policy_onboarding_proposals_baseline_chk",
|
|
238
|
+
sql`(
|
|
239
|
+
${table.baselineRevisionId} is null
|
|
240
|
+
and ${table.baselineRevision} is null
|
|
241
|
+
and ${table.baselineContentHash} is null
|
|
242
|
+
and ${table.baselineActivationVersion} = 0
|
|
243
|
+
and ${table.baselineActivatedAt} is null
|
|
244
|
+
) or (
|
|
245
|
+
${table.baselineRevisionId} is not null
|
|
246
|
+
and ${table.baselineRevision} > 0
|
|
247
|
+
and ${table.baselineContentHash} ~ '^[0-9a-f]{64}$'
|
|
248
|
+
and ${table.baselineActivationVersion} > 0
|
|
249
|
+
and ${table.baselineActivatedAt} is not null
|
|
250
|
+
)`,
|
|
251
|
+
),
|
|
252
|
+
draft: check(
|
|
253
|
+
"workspace_instruction_policy_onboarding_proposals_draft_chk",
|
|
254
|
+
sql`${table.draftRevision} > 0
|
|
255
|
+
and ${table.draftContentHash} ~ '^[0-9a-f]{64}$'
|
|
256
|
+
and ${table.status} = 'proposed'`,
|
|
257
|
+
),
|
|
258
|
+
}),
|
|
259
|
+
);
|
|
260
|
+
|
|
175
261
|
export const workspaceInstructionPolicySnapshots = pgTable(
|
|
176
262
|
"workspace_instruction_policy_snapshots",
|
|
177
263
|
{
|