@tiangong-lca/cli 0.0.23 → 0.0.24
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/README.md +14 -6
- package/dist/src/cli.js +20 -9
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-apply.js +269 -4
- package/dist/src/lib/dataset-maintenance-apply.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-contract.js +118 -16
- package/dist/src/lib/dataset-maintenance-contract.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-derivatives.js +265 -0
- package/dist/src/lib/dataset-maintenance-derivatives.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-plan.js +38 -6
- package/dist/src/lib/dataset-maintenance-plan.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-remote.js +25 -0
- package/dist/src/lib/dataset-maintenance-remote.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-verify.js +309 -3
- package/dist/src/lib/dataset-maintenance-verify.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { CliError } from './errors.js';
|
|
2
|
+
import { DERIVATIVE_REBUILD_COMPONENTS, isJsonObject, } from './dataset-maintenance-contract.js';
|
|
3
|
+
const SHA256 = /^[a-f0-9]{64}$/u;
|
|
4
|
+
const POSITIVE_INTEGER_TEXT = /^[1-9]\d*$/u;
|
|
5
|
+
function requiredToken(value, label) {
|
|
6
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
7
|
+
throw new CliError(`${label} must be a non-empty string.`, {
|
|
8
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
9
|
+
exitCode: 1,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
return value.trim();
|
|
13
|
+
}
|
|
14
|
+
function requiredSha256(value, label) {
|
|
15
|
+
const normalized = requiredToken(value, label);
|
|
16
|
+
if (!SHA256.test(normalized)) {
|
|
17
|
+
throw new CliError(`${label} must be a lowercase SHA-256 digest.`, {
|
|
18
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
19
|
+
exitCode: 1,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return normalized;
|
|
23
|
+
}
|
|
24
|
+
function nullableSha256(value, label) {
|
|
25
|
+
return value === null ? null : requiredSha256(value, label);
|
|
26
|
+
}
|
|
27
|
+
function nullableTimestamp(value, label) {
|
|
28
|
+
if (value === null)
|
|
29
|
+
return null;
|
|
30
|
+
const normalized = requiredToken(value, label);
|
|
31
|
+
if (!Number.isFinite(Date.parse(normalized))) {
|
|
32
|
+
throw new CliError(`${label} must be an ISO timestamp or null.`, {
|
|
33
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
34
|
+
exitCode: 1,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return normalized;
|
|
38
|
+
}
|
|
39
|
+
function requestStatus(value, label) {
|
|
40
|
+
const normalized = requiredToken(value, label);
|
|
41
|
+
const statuses = [
|
|
42
|
+
'queued',
|
|
43
|
+
'dispatching',
|
|
44
|
+
'markdown_pending',
|
|
45
|
+
'embedding_pending',
|
|
46
|
+
'completed',
|
|
47
|
+
'stale',
|
|
48
|
+
'failed',
|
|
49
|
+
];
|
|
50
|
+
if (!statuses.includes(normalized)) {
|
|
51
|
+
throw new CliError(`${label} is not a supported derivative rebuild status.`, {
|
|
52
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
53
|
+
exitCode: 1,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return normalized;
|
|
57
|
+
}
|
|
58
|
+
function responseBody(value, command) {
|
|
59
|
+
if (!isJsonObject(value) || value.ok !== true || value.command !== command) {
|
|
60
|
+
throw new CliError(`${command} returned an invalid response envelope.`, {
|
|
61
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
62
|
+
exitCode: 1,
|
|
63
|
+
details: value,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
export function parseDerivativeSnapshotResponse(value, expected) {
|
|
69
|
+
const body = responseBody(value, 'cmd_dataset_derivative_rebuild_snapshot');
|
|
70
|
+
if (body.schema_version !== 'dataset-derivative-snapshot.v1' ||
|
|
71
|
+
body.table !== 'processes' ||
|
|
72
|
+
body.id !== expected.id ||
|
|
73
|
+
body.version !== expected.version ||
|
|
74
|
+
body.user_id !== expected.userId ||
|
|
75
|
+
body.state_code !== 0) {
|
|
76
|
+
throw new CliError('Derivative snapshot identity, owner, state, or schema is invalid.', {
|
|
77
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
78
|
+
exitCode: 1,
|
|
79
|
+
details: body,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const modifiedAt = nullableTimestamp(body.modified_at, 'Derivative snapshot modified_at');
|
|
83
|
+
if (!modifiedAt) {
|
|
84
|
+
throw new CliError('Derivative snapshot modified_at must be non-null.', {
|
|
85
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
86
|
+
exitCode: 1,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const jsonSha256 = requiredSha256(body.json_sha256, 'Derivative snapshot json_sha256');
|
|
90
|
+
const jsonOrderedSha256 = requiredSha256(body.json_ordered_sha256, 'Derivative snapshot json_ordered_sha256');
|
|
91
|
+
if (jsonSha256 !== jsonOrderedSha256) {
|
|
92
|
+
throw new CliError('Derivative snapshot json and json_ordered hashes must match.', {
|
|
93
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PRIMARY_MISMATCH',
|
|
94
|
+
exitCode: 1,
|
|
95
|
+
details: { json_sha256: jsonSha256, json_ordered_sha256: jsonOrderedSha256 },
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
schema_version: 'dataset-derivative-snapshot.v1',
|
|
100
|
+
table: 'processes',
|
|
101
|
+
id: expected.id,
|
|
102
|
+
version: expected.version,
|
|
103
|
+
user_id: expected.userId,
|
|
104
|
+
state_code: 0,
|
|
105
|
+
modified_at: modifiedAt,
|
|
106
|
+
json_sha256: jsonSha256,
|
|
107
|
+
json_ordered_sha256: jsonOrderedSha256,
|
|
108
|
+
extracted_text_sha256: requiredSha256(body.extracted_text_sha256, 'Derivative snapshot extracted_text_sha256'),
|
|
109
|
+
extracted_md_sha256: nullableSha256(body.extracted_md_sha256, 'Derivative snapshot extracted_md_sha256'),
|
|
110
|
+
embedding_ft_sha256: nullableSha256(body.embedding_ft_sha256, 'Derivative snapshot embedding_ft_sha256'),
|
|
111
|
+
embedding_ft_at: nullableTimestamp(body.embedding_ft_at, 'Derivative snapshot embedding_ft_at'),
|
|
112
|
+
snapshot_sha256: requiredSha256(body.snapshot_sha256, 'Derivative snapshot snapshot_sha256'),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export function isDerivativeRebuildPlan(plan) {
|
|
116
|
+
return plan.operation === 'rebuild-derivatives';
|
|
117
|
+
}
|
|
118
|
+
export function derivativePlanAction(plan) {
|
|
119
|
+
const action = plan.actions[0];
|
|
120
|
+
if (!isDerivativeRebuildPlan(plan) ||
|
|
121
|
+
plan.target_mode !== 'owner_draft' ||
|
|
122
|
+
plan.actions.length !== 1 ||
|
|
123
|
+
!action ||
|
|
124
|
+
action.action !== 'rebuild_derivatives' ||
|
|
125
|
+
action.table !== 'processes' ||
|
|
126
|
+
!action.derivative_before) {
|
|
127
|
+
throw new CliError('Derivative rebuild plan does not match the fixed V1 contract.', {
|
|
128
|
+
code: 'DATASET_MAINTENANCE_PLAN_INVALID',
|
|
129
|
+
exitCode: 2,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return action;
|
|
133
|
+
}
|
|
134
|
+
export function buildDerivativePlanRequest(plan) {
|
|
135
|
+
const action = derivativePlanAction(plan);
|
|
136
|
+
const derivativeBefore = action.derivative_before;
|
|
137
|
+
return {
|
|
138
|
+
schema_version: 'dataset-derivative-rebuild-plan.v1',
|
|
139
|
+
plan_sha256: plan.plan_sha256,
|
|
140
|
+
operation_id: plan.operation_id,
|
|
141
|
+
target_visibility: 'owner_draft',
|
|
142
|
+
actions: [
|
|
143
|
+
{
|
|
144
|
+
action_id: action.action_id,
|
|
145
|
+
action: 'rebuild_derivatives',
|
|
146
|
+
table: 'processes',
|
|
147
|
+
id: action.id,
|
|
148
|
+
version: action.version,
|
|
149
|
+
expected_state_code: 0,
|
|
150
|
+
expected_snapshot_sha256: derivativeBefore.snapshot_sha256,
|
|
151
|
+
components: [...DERIVATIVE_REBUILD_COMPONENTS],
|
|
152
|
+
reason_code: action.reason_code,
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
export function parseDerivativeSubmitResponse(value, plan) {
|
|
158
|
+
const body = responseBody(value, 'cmd_dataset_derivative_rebuild_plan_guarded');
|
|
159
|
+
const status = requestStatus(body.status, 'Derivative submit status');
|
|
160
|
+
if (body.schema_version !== 'dataset-derivative-rebuild-plan.v1' ||
|
|
161
|
+
body.plan_sha256 !== plan.plan_sha256 ||
|
|
162
|
+
body.operation_id !== plan.operation_id ||
|
|
163
|
+
body.target_visibility !== 'owner_draft' ||
|
|
164
|
+
body.action_count !== 1 ||
|
|
165
|
+
body.accepted_count !== 1 ||
|
|
166
|
+
typeof body.idempotent_replay !== 'boolean' ||
|
|
167
|
+
status !== 'queued') {
|
|
168
|
+
throw new CliError('Derivative submit response does not match the approved plan.', {
|
|
169
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
170
|
+
exitCode: 1,
|
|
171
|
+
details: body,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const summaryAuditId = requiredToken(body.summary_audit_id, 'Derivative summary_audit_id');
|
|
175
|
+
const databaseAuditId = requiredToken(body.database_audit_id, 'Derivative database_audit_id');
|
|
176
|
+
if (!POSITIVE_INTEGER_TEXT.test(summaryAuditId) || !POSITIVE_INTEGER_TEXT.test(databaseAuditId)) {
|
|
177
|
+
throw new CliError('Derivative audit ids must be numeric strings safe from JSON precision loss.', {
|
|
178
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
179
|
+
exitCode: 1,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
schema_version: 'dataset-derivative-rebuild-plan.v1',
|
|
184
|
+
plan_sha256: plan.plan_sha256,
|
|
185
|
+
operation_id: plan.operation_id,
|
|
186
|
+
target_visibility: 'owner_draft',
|
|
187
|
+
plan_request_sha256: requiredSha256(body.plan_request_sha256, 'Derivative plan_request_sha256'),
|
|
188
|
+
idempotent_replay: body.idempotent_replay,
|
|
189
|
+
action_count: 1,
|
|
190
|
+
accepted_count: 1,
|
|
191
|
+
summary_audit_id: summaryAuditId,
|
|
192
|
+
request_id: requiredToken(body.request_id, 'Derivative request_id'),
|
|
193
|
+
status,
|
|
194
|
+
action_request_sha256: requiredSha256(body.action_request_sha256, 'Derivative action_request_sha256'),
|
|
195
|
+
database_audit_id: databaseAuditId,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
export function parseDerivativeStatusResponse(value, plan, submit) {
|
|
199
|
+
const action = derivativePlanAction(plan);
|
|
200
|
+
const body = responseBody(value, 'cmd_dataset_derivative_rebuild_read');
|
|
201
|
+
const status = requestStatus(body.status, 'Derivative read status');
|
|
202
|
+
const phase = requiredToken(body.phase, 'Derivative read phase');
|
|
203
|
+
if (body.schema_version !== 'dataset-derivative-rebuild-status.v1' ||
|
|
204
|
+
body.request_id !== submit.request_id ||
|
|
205
|
+
body.plan_sha256 !== plan.plan_sha256 ||
|
|
206
|
+
body.operation_id !== plan.operation_id ||
|
|
207
|
+
body.action_id !== action.action_id ||
|
|
208
|
+
body.table !== 'processes' ||
|
|
209
|
+
body.id !== action.id ||
|
|
210
|
+
body.version !== action.version ||
|
|
211
|
+
body.plan_request_sha256 !== submit.plan_request_sha256 ||
|
|
212
|
+
body.action_request_sha256 !== submit.action_request_sha256 ||
|
|
213
|
+
body.database_audit_id !== submit.database_audit_id ||
|
|
214
|
+
body.summary_audit_id !== submit.summary_audit_id) {
|
|
215
|
+
throw new CliError('Derivative status response does not match the accepted request proof.', {
|
|
216
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
217
|
+
exitCode: 1,
|
|
218
|
+
details: body,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
const completedSnapshotSha256 = body.completed_snapshot_sha256 === null
|
|
222
|
+
? null
|
|
223
|
+
: requiredSha256(body.completed_snapshot_sha256, 'Derivative completed_snapshot_sha256');
|
|
224
|
+
const completedAt = nullableTimestamp(body.completed_at, 'Derivative completed_at');
|
|
225
|
+
const error = body.error === null ? null : isJsonObject(body.error) ? body.error : undefined;
|
|
226
|
+
if (typeof body.fence_active !== 'boolean' ||
|
|
227
|
+
error === undefined ||
|
|
228
|
+
(status === 'completed' &&
|
|
229
|
+
(!completedSnapshotSha256 || !completedAt || error !== null || body.fence_active)) ||
|
|
230
|
+
(status !== 'completed' && (completedSnapshotSha256 !== null || completedAt !== null))) {
|
|
231
|
+
throw new CliError('Derivative status terminal proof is invalid.', {
|
|
232
|
+
code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',
|
|
233
|
+
exitCode: 1,
|
|
234
|
+
details: body,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
schema_version: 'dataset-derivative-rebuild-status.v1',
|
|
239
|
+
request_id: submit.request_id,
|
|
240
|
+
plan_sha256: plan.plan_sha256,
|
|
241
|
+
operation_id: plan.operation_id,
|
|
242
|
+
action_id: action.action_id,
|
|
243
|
+
table: 'processes',
|
|
244
|
+
id: action.id,
|
|
245
|
+
version: action.version,
|
|
246
|
+
status,
|
|
247
|
+
phase,
|
|
248
|
+
fence_active: body.fence_active,
|
|
249
|
+
plan_request_sha256: submit.plan_request_sha256,
|
|
250
|
+
action_request_sha256: submit.action_request_sha256,
|
|
251
|
+
database_audit_id: submit.database_audit_id,
|
|
252
|
+
summary_audit_id: submit.summary_audit_id,
|
|
253
|
+
completed_snapshot_sha256: completedSnapshotSha256,
|
|
254
|
+
completed_at: completedAt,
|
|
255
|
+
error,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
export function derivativeStatusCategory(status) {
|
|
259
|
+
if (status === 'completed')
|
|
260
|
+
return 'passed';
|
|
261
|
+
if (['stale', 'failed'].includes(status))
|
|
262
|
+
return 'failed';
|
|
263
|
+
return 'pending';
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=dataset-maintenance-derivatives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset-maintenance-derivatives.js","sourceRoot":"","sources":["../../../src/lib/dataset-maintenance-derivatives.ts"],"names":[],"mappings":"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","sourcesContent":["import { CliError } from './errors.js';\nimport {\n DERIVATIVE_REBUILD_COMPONENTS,\n isJsonObject,\n type DatasetMaintenanceDerivativeSnapshot,\n type DatasetMaintenancePlan,\n type DatasetMaintenancePlanAction,\n type JsonObject,\n} from './dataset-maintenance-contract.js';\n\nexport type DatasetMaintenanceDerivativeRequestStatus =\n | 'queued'\n | 'dispatching'\n | 'markdown_pending'\n | 'embedding_pending'\n | 'completed'\n | 'stale'\n | 'failed';\n\nexport type DatasetMaintenanceDerivativeSubmitProof = {\n schema_version: 'dataset-derivative-rebuild-plan.v1';\n plan_sha256: string;\n operation_id: string;\n target_visibility: 'owner_draft';\n plan_request_sha256: string;\n idempotent_replay: boolean;\n action_count: 1;\n accepted_count: 1;\n summary_audit_id: string;\n request_id: string;\n status: DatasetMaintenanceDerivativeRequestStatus;\n action_request_sha256: string;\n database_audit_id: string;\n};\n\nexport type DatasetMaintenanceDerivativeStatusProof = {\n schema_version: 'dataset-derivative-rebuild-status.v1';\n request_id: string;\n plan_sha256: string;\n operation_id: string;\n action_id: string;\n table: 'processes';\n id: string;\n version: string;\n status: DatasetMaintenanceDerivativeRequestStatus;\n phase: string;\n fence_active: boolean;\n plan_request_sha256: string;\n action_request_sha256: string;\n database_audit_id: string;\n summary_audit_id: string;\n completed_snapshot_sha256: string | null;\n completed_at: string | null;\n error: JsonObject | null;\n};\n\nconst SHA256 = /^[a-f0-9]{64}$/u;\nconst POSITIVE_INTEGER_TEXT = /^[1-9]\\d*$/u;\n\nfunction requiredToken(value: unknown, label: string): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new CliError(`${label} must be a non-empty string.`, {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n });\n }\n return value.trim();\n}\n\nfunction requiredSha256(value: unknown, label: string): string {\n const normalized = requiredToken(value, label);\n if (!SHA256.test(normalized)) {\n throw new CliError(`${label} must be a lowercase SHA-256 digest.`, {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n });\n }\n return normalized;\n}\n\nfunction nullableSha256(value: unknown, label: string): string | null {\n return value === null ? null : requiredSha256(value, label);\n}\n\nfunction nullableTimestamp(value: unknown, label: string): string | null {\n if (value === null) return null;\n const normalized = requiredToken(value, label);\n if (!Number.isFinite(Date.parse(normalized))) {\n throw new CliError(`${label} must be an ISO timestamp or null.`, {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n });\n }\n return normalized;\n}\n\nfunction requestStatus(value: unknown, label: string): DatasetMaintenanceDerivativeRequestStatus {\n const normalized = requiredToken(value, label);\n const statuses: DatasetMaintenanceDerivativeRequestStatus[] = [\n 'queued',\n 'dispatching',\n 'markdown_pending',\n 'embedding_pending',\n 'completed',\n 'stale',\n 'failed',\n ];\n if (!statuses.includes(normalized as DatasetMaintenanceDerivativeRequestStatus)) {\n throw new CliError(`${label} is not a supported derivative rebuild status.`, {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n });\n }\n return normalized as DatasetMaintenanceDerivativeRequestStatus;\n}\n\nfunction responseBody(value: unknown, command: string): JsonObject {\n if (!isJsonObject(value) || value.ok !== true || value.command !== command) {\n throw new CliError(`${command} returned an invalid response envelope.`, {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n details: value,\n });\n }\n return value;\n}\n\nexport function parseDerivativeSnapshotResponse(\n value: unknown,\n expected: { id: string; version: string; userId: string },\n): DatasetMaintenanceDerivativeSnapshot {\n const body = responseBody(value, 'cmd_dataset_derivative_rebuild_snapshot');\n if (\n body.schema_version !== 'dataset-derivative-snapshot.v1' ||\n body.table !== 'processes' ||\n body.id !== expected.id ||\n body.version !== expected.version ||\n body.user_id !== expected.userId ||\n body.state_code !== 0\n ) {\n throw new CliError('Derivative snapshot identity, owner, state, or schema is invalid.', {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n details: body,\n });\n }\n const modifiedAt = nullableTimestamp(body.modified_at, 'Derivative snapshot modified_at');\n if (!modifiedAt) {\n throw new CliError('Derivative snapshot modified_at must be non-null.', {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n });\n }\n const jsonSha256 = requiredSha256(body.json_sha256, 'Derivative snapshot json_sha256');\n const jsonOrderedSha256 = requiredSha256(\n body.json_ordered_sha256,\n 'Derivative snapshot json_ordered_sha256',\n );\n if (jsonSha256 !== jsonOrderedSha256) {\n throw new CliError('Derivative snapshot json and json_ordered hashes must match.', {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PRIMARY_MISMATCH',\n exitCode: 1,\n details: { json_sha256: jsonSha256, json_ordered_sha256: jsonOrderedSha256 },\n });\n }\n return {\n schema_version: 'dataset-derivative-snapshot.v1',\n table: 'processes',\n id: expected.id,\n version: expected.version,\n user_id: expected.userId,\n state_code: 0,\n modified_at: modifiedAt,\n json_sha256: jsonSha256,\n json_ordered_sha256: jsonOrderedSha256,\n extracted_text_sha256: requiredSha256(\n body.extracted_text_sha256,\n 'Derivative snapshot extracted_text_sha256',\n ),\n extracted_md_sha256: nullableSha256(\n body.extracted_md_sha256,\n 'Derivative snapshot extracted_md_sha256',\n ),\n embedding_ft_sha256: nullableSha256(\n body.embedding_ft_sha256,\n 'Derivative snapshot embedding_ft_sha256',\n ),\n embedding_ft_at: nullableTimestamp(body.embedding_ft_at, 'Derivative snapshot embedding_ft_at'),\n snapshot_sha256: requiredSha256(body.snapshot_sha256, 'Derivative snapshot snapshot_sha256'),\n };\n}\n\nexport function isDerivativeRebuildPlan(plan: DatasetMaintenancePlan): boolean {\n return plan.operation === 'rebuild-derivatives';\n}\n\nexport function derivativePlanAction(plan: DatasetMaintenancePlan): DatasetMaintenancePlanAction {\n const action = plan.actions[0];\n if (\n !isDerivativeRebuildPlan(plan) ||\n plan.target_mode !== 'owner_draft' ||\n plan.actions.length !== 1 ||\n !action ||\n action.action !== 'rebuild_derivatives' ||\n action.table !== 'processes' ||\n !action.derivative_before\n ) {\n throw new CliError('Derivative rebuild plan does not match the fixed V1 contract.', {\n code: 'DATASET_MAINTENANCE_PLAN_INVALID',\n exitCode: 2,\n });\n }\n return action;\n}\n\nexport function buildDerivativePlanRequest(plan: DatasetMaintenancePlan): JsonObject {\n const action = derivativePlanAction(plan);\n const derivativeBefore = action.derivative_before!;\n return {\n schema_version: 'dataset-derivative-rebuild-plan.v1',\n plan_sha256: plan.plan_sha256,\n operation_id: plan.operation_id,\n target_visibility: 'owner_draft',\n actions: [\n {\n action_id: action.action_id,\n action: 'rebuild_derivatives',\n table: 'processes',\n id: action.id,\n version: action.version,\n expected_state_code: 0,\n expected_snapshot_sha256: derivativeBefore.snapshot_sha256,\n components: [...DERIVATIVE_REBUILD_COMPONENTS],\n reason_code: action.reason_code,\n },\n ],\n };\n}\n\nexport function parseDerivativeSubmitResponse(\n value: unknown,\n plan: DatasetMaintenancePlan,\n): DatasetMaintenanceDerivativeSubmitProof {\n const body = responseBody(value, 'cmd_dataset_derivative_rebuild_plan_guarded');\n const status = requestStatus(body.status, 'Derivative submit status');\n if (\n body.schema_version !== 'dataset-derivative-rebuild-plan.v1' ||\n body.plan_sha256 !== plan.plan_sha256 ||\n body.operation_id !== plan.operation_id ||\n body.target_visibility !== 'owner_draft' ||\n body.action_count !== 1 ||\n body.accepted_count !== 1 ||\n typeof body.idempotent_replay !== 'boolean' ||\n status !== 'queued'\n ) {\n throw new CliError('Derivative submit response does not match the approved plan.', {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n details: body,\n });\n }\n const summaryAuditId = requiredToken(body.summary_audit_id, 'Derivative summary_audit_id');\n const databaseAuditId = requiredToken(body.database_audit_id, 'Derivative database_audit_id');\n if (!POSITIVE_INTEGER_TEXT.test(summaryAuditId) || !POSITIVE_INTEGER_TEXT.test(databaseAuditId)) {\n throw new CliError(\n 'Derivative audit ids must be numeric strings safe from JSON precision loss.',\n {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n },\n );\n }\n return {\n schema_version: 'dataset-derivative-rebuild-plan.v1',\n plan_sha256: plan.plan_sha256,\n operation_id: plan.operation_id,\n target_visibility: 'owner_draft',\n plan_request_sha256: requiredSha256(body.plan_request_sha256, 'Derivative plan_request_sha256'),\n idempotent_replay: body.idempotent_replay as boolean,\n action_count: 1,\n accepted_count: 1,\n summary_audit_id: summaryAuditId,\n request_id: requiredToken(body.request_id, 'Derivative request_id'),\n status,\n action_request_sha256: requiredSha256(\n body.action_request_sha256,\n 'Derivative action_request_sha256',\n ),\n database_audit_id: databaseAuditId,\n };\n}\n\nexport function parseDerivativeStatusResponse(\n value: unknown,\n plan: DatasetMaintenancePlan,\n submit: DatasetMaintenanceDerivativeSubmitProof,\n): DatasetMaintenanceDerivativeStatusProof {\n const action = derivativePlanAction(plan);\n const body = responseBody(value, 'cmd_dataset_derivative_rebuild_read');\n const status = requestStatus(body.status, 'Derivative read status');\n const phase = requiredToken(body.phase, 'Derivative read phase');\n if (\n body.schema_version !== 'dataset-derivative-rebuild-status.v1' ||\n body.request_id !== submit.request_id ||\n body.plan_sha256 !== plan.plan_sha256 ||\n body.operation_id !== plan.operation_id ||\n body.action_id !== action.action_id ||\n body.table !== 'processes' ||\n body.id !== action.id ||\n body.version !== action.version ||\n body.plan_request_sha256 !== submit.plan_request_sha256 ||\n body.action_request_sha256 !== submit.action_request_sha256 ||\n body.database_audit_id !== submit.database_audit_id ||\n body.summary_audit_id !== submit.summary_audit_id\n ) {\n throw new CliError('Derivative status response does not match the accepted request proof.', {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n details: body,\n });\n }\n const completedSnapshotSha256 =\n body.completed_snapshot_sha256 === null\n ? null\n : requiredSha256(body.completed_snapshot_sha256, 'Derivative completed_snapshot_sha256');\n const completedAt = nullableTimestamp(body.completed_at, 'Derivative completed_at');\n const error = body.error === null ? null : isJsonObject(body.error) ? body.error : undefined;\n if (\n typeof body.fence_active !== 'boolean' ||\n error === undefined ||\n (status === 'completed' &&\n (!completedSnapshotSha256 || !completedAt || error !== null || body.fence_active)) ||\n (status !== 'completed' && (completedSnapshotSha256 !== null || completedAt !== null))\n ) {\n throw new CliError('Derivative status terminal proof is invalid.', {\n code: 'DATASET_MAINTENANCE_DERIVATIVE_PROOF_INVALID',\n exitCode: 1,\n details: body,\n });\n }\n return {\n schema_version: 'dataset-derivative-rebuild-status.v1',\n request_id: submit.request_id,\n plan_sha256: plan.plan_sha256,\n operation_id: plan.operation_id,\n action_id: action.action_id,\n table: 'processes',\n id: action.id,\n version: action.version,\n status,\n phase,\n fence_active: body.fence_active as boolean,\n plan_request_sha256: submit.plan_request_sha256,\n action_request_sha256: submit.action_request_sha256,\n database_audit_id: submit.database_audit_id,\n summary_audit_id: submit.summary_audit_id,\n completed_snapshot_sha256: completedSnapshotSha256,\n completed_at: completedAt,\n error,\n };\n}\n\nexport function derivativeStatusCategory(\n status: DatasetMaintenanceDerivativeRequestStatus,\n): 'pending' | 'passed' | 'failed' {\n if (status === 'completed') return 'passed';\n if (['stale', 'failed'].includes(status)) return 'failed';\n return 'pending';\n}\n"]}
|
|
@@ -3,8 +3,9 @@ import { collectRemoteReferences } from './dataset-remote-verify.js';
|
|
|
3
3
|
import { buildAliasRewritePlan, } from './dataset-maintenance-alias-rewrite.js';
|
|
4
4
|
import { CliError } from './errors.js';
|
|
5
5
|
import { computePlanSha256, isJsonObject, maintenanceRowKey, parseMaintenanceScope, readJsonFile, safeActionFileName, sha256Json, snapshotRemoteRow, writeImmutableJson, writeImmutableJsonLines, } from './dataset-maintenance-contract.js';
|
|
6
|
+
import { parseDerivativeSnapshotResponse } from './dataset-maintenance-derivatives.js';
|
|
6
7
|
import { inspectMaintenanceSupportPayload, maintenancePayloadIdentity, } from './dataset-maintenance-support-validation.js';
|
|
7
|
-
import { fetchMaintenanceAccountRows, fetchMaintenanceExactRows, normalizeMaintenancePageSize, resolveMaintenanceRemoteContext, } from './dataset-maintenance-remote.js';
|
|
8
|
+
import { fetchMaintenanceAccountRows, fetchMaintenanceDerivativeSnapshot, fetchMaintenanceExactRows, normalizeMaintenancePageSize, resolveMaintenanceRemoteContext, } from './dataset-maintenance-remote.js';
|
|
8
9
|
function normalizeEmail(value) {
|
|
9
10
|
return value.trim().toLowerCase();
|
|
10
11
|
}
|
|
@@ -285,6 +286,25 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
285
286
|
actionBlockers.push(blocker(action, 'DESIRED_PAYLOAD_IDENTITY_MISMATCH', 'Desired payload root id/version does not match the target row.', identity));
|
|
286
287
|
}
|
|
287
288
|
}
|
|
289
|
+
let derivativeBefore;
|
|
290
|
+
if (action.action === 'rebuild_derivatives' && before && actionBlockers.length === 0) {
|
|
291
|
+
const rawSnapshot = await fetchMaintenanceDerivativeSnapshot({
|
|
292
|
+
context,
|
|
293
|
+
id: action.id,
|
|
294
|
+
version: action.version,
|
|
295
|
+
});
|
|
296
|
+
derivativeBefore = parseDerivativeSnapshotResponse(rawSnapshot, {
|
|
297
|
+
id: action.id,
|
|
298
|
+
version: action.version,
|
|
299
|
+
userId: action.expected_user_id,
|
|
300
|
+
});
|
|
301
|
+
if (derivativeBefore.modified_at !== before.modified_at) {
|
|
302
|
+
actionBlockers.push(blocker(action, 'DERIVATIVE_PRIMARY_SNAPSHOT_DRIFT', 'Derivative snapshot modified_at differs from the lean account snapshot.', {
|
|
303
|
+
account_snapshot_modified_at: before.modified_at,
|
|
304
|
+
derivative_snapshot_modified_at: derivativeBefore.modified_at,
|
|
305
|
+
}));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
288
308
|
actionPlans.push({
|
|
289
309
|
...action,
|
|
290
310
|
ordinal,
|
|
@@ -292,16 +312,19 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
292
312
|
before,
|
|
293
313
|
desired_payload: desiredPayload,
|
|
294
314
|
blockers: actionBlockers,
|
|
315
|
+
...(derivativeBefore ? { derivative_before: derivativeBefore } : {}),
|
|
295
316
|
rollback: {
|
|
296
317
|
strategy: action.action === 'save_draft'
|
|
297
318
|
? 'save_before_snapshot'
|
|
298
319
|
: action.action === 'delete'
|
|
299
320
|
? 'restore_deleted_before_snapshot'
|
|
300
|
-
: '
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
321
|
+
: action.action === 'update_json_ordered'
|
|
322
|
+
? 'restore_atomic_alias_before_snapshot'
|
|
323
|
+
: 'none_derivative_only',
|
|
324
|
+
before_payload_sha256: action.action === 'rebuild_derivatives' ? null : (before?.payload_sha256 ?? null),
|
|
325
|
+
before_payload: action.action === 'rebuild_derivatives' ? null : (before?.json_ordered ?? null),
|
|
326
|
+
model_id: action.action === 'rebuild_derivatives' ? null : (before?.model_id ?? null),
|
|
327
|
+
rule_verification: action.action === 'rebuild_derivatives' ? null : (before?.rule_verification ?? null),
|
|
305
328
|
},
|
|
306
329
|
});
|
|
307
330
|
}
|
|
@@ -384,6 +407,8 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
384
407
|
delete: actionPlans.filter((action) => action.action === 'delete').length,
|
|
385
408
|
update_json_ordered: actionPlans.filter((action) => action.action === 'update_json_ordered')
|
|
386
409
|
.length,
|
|
410
|
+
rebuild_derivatives: actionPlans.filter((action) => action.action === 'rebuild_derivatives')
|
|
411
|
+
.length,
|
|
387
412
|
atomic_batches: aliasBatches?.length ?? 0,
|
|
388
413
|
scaled_exchanges: aliasBatches?.reduce((sum, batch) => sum + batch.summary.exchanges, 0) ?? 0,
|
|
389
414
|
scaled_amount_fields: aliasBatches?.reduce((sum, batch) => sum + batch.summary.amount_fields, 0) ?? 0,
|
|
@@ -402,6 +427,9 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
402
427
|
dry_run_report: 'dry-run-report.json',
|
|
403
428
|
payload_dir: 'payloads',
|
|
404
429
|
...(aliasBatches ? { exchange_rewrite_plan: 'exchange-rewrite-plan.jsonl' } : {}),
|
|
430
|
+
...(scope.operation === 'rebuild-derivatives'
|
|
431
|
+
? { derivative_baseline: 'derivative-baseline.json' }
|
|
432
|
+
: {}),
|
|
405
433
|
},
|
|
406
434
|
actions: actionPlans,
|
|
407
435
|
...(aliasBatches ? { alias_batches: aliasBatches } : {}),
|
|
@@ -426,6 +454,9 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
426
454
|
rows: snapshotRows,
|
|
427
455
|
});
|
|
428
456
|
writeImmutableJsonLines(path.join(outDir, plan.artifacts.protected_rows), protectedRowList);
|
|
457
|
+
if (plan.artifacts.derivative_baseline) {
|
|
458
|
+
writeImmutableJson(path.join(outDir, plan.artifacts.derivative_baseline), plan.actions[0].derivative_before ?? null);
|
|
459
|
+
}
|
|
429
460
|
if (plan.artifacts.exchange_rewrite_plan) {
|
|
430
461
|
writeImmutableJsonLines(path.join(outDir, plan.artifacts.exchange_rewrite_plan), plan.alias_batches.flatMap((batch) => batch.exchange_rewrites.map((rewrite) => ({
|
|
431
462
|
schema_version: 1,
|
|
@@ -464,6 +495,7 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
464
495
|
version: action.version,
|
|
465
496
|
status: action.status,
|
|
466
497
|
blockers: action.blockers,
|
|
498
|
+
...(action.derivative_before ? { derivative_before: action.derivative_before } : {}),
|
|
467
499
|
})),
|
|
468
500
|
alias_batches: plan.alias_batches?.map((batch) => ({
|
|
469
501
|
batch_id: batch.batch_id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset-maintenance-plan.js","sourceRoot":"","sources":["../../../src/lib/dataset-maintenance-plan.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { collectRemoteReferences } from './dataset-remote-verify.js';\nimport {\n buildAliasRewritePlan,\n type DatasetMaintenanceAliasSchemas,\n} from './dataset-maintenance-alias-rewrite.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n computePlanSha256,\n isJsonObject,\n maintenanceRowKey,\n parseMaintenanceScope,\n readJsonFile,\n safeActionFileName,\n sha256Json,\n snapshotRemoteRow,\n writeImmutableJson,\n writeImmutableJsonLines,\n type DatasetMaintenanceBlocker,\n type DatasetMaintenanceAliasBatchPlan,\n type DatasetMaintenanceOperation,\n type DatasetMaintenancePlan,\n type DatasetMaintenancePlanAction,\n type DatasetMaintenanceProtectedRow,\n type DatasetMaintenanceReferenceImpact,\n type DatasetMaintenanceRemoteRow,\n type DatasetMaintenanceRowSnapshot,\n type DatasetMaintenanceScopeAction,\n type JsonObject,\n} from './dataset-maintenance-contract.js';\nimport {\n inspectMaintenanceSupportPayload,\n maintenancePayloadIdentity,\n type DatasetMaintenanceSupportSchemas,\n} from './dataset-maintenance-support-validation.js';\nimport {\n fetchMaintenanceAccountRows,\n fetchMaintenanceExactRows,\n normalizeMaintenancePageSize,\n resolveMaintenanceRemoteContext,\n} from './dataset-maintenance-remote.js';\n\nexport type RunDatasetMaintenancePlanOptions = {\n scopePath: string;\n operation: DatasetMaintenanceOperation;\n outDir: string;\n pageSize?: number;\n timeoutMs?: number;\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n now?: Date;\n supportSchemas?: DatasetMaintenanceSupportSchemas;\n aliasSchemas?: DatasetMaintenanceAliasSchemas;\n};\n\nfunction normalizeEmail(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction blocker(\n action: DatasetMaintenanceScopeAction,\n code: string,\n message: string,\n details?: unknown,\n): DatasetMaintenanceBlocker {\n return {\n code,\n message,\n action_id: action.action_id,\n table: action.table,\n id: action.id,\n version: action.version,\n ...(details === undefined ? {} : { details }),\n };\n}\n\nfunction referenceImpacts(options: {\n rows: DatasetMaintenanceRemoteRow[];\n deletes: DatasetMaintenanceScopeAction[];\n phase: DatasetMaintenanceReferenceImpact['phase'];\n}): DatasetMaintenanceReferenceImpact[] {\n const payloadRows = options.rows\n .filter((row) => row.json_ordered !== null)\n .map((row) => ({\n table: row.table,\n id: row.id,\n version: row.version,\n json_ordered: row.json_ordered as JsonObject,\n }));\n const references = collectRemoteReferences(payloadRows).filter(\n (reference) => reference.role === 'reference',\n );\n const impacts: DatasetMaintenanceReferenceImpact[] = [];\n for (const reference of references) {\n const source = payloadRows[reference.row_index];\n if (!reference.table || !reference.id) {\n continue;\n }\n for (const target of options.deletes) {\n const sameTarget =\n reference.table === target.table &&\n reference.id === target.id &&\n (!reference.version || reference.version === target.version);\n if (sameTarget) {\n impacts.push({\n target_action_id: target.action_id,\n target_table: target.table,\n target_id: target.id,\n target_version: target.version,\n phase: options.phase,\n source_table: source!.table,\n source_id: source!.id,\n source_version: source!.version,\n reference_path: reference.path,\n reference_version: reference.version,\n });\n }\n }\n }\n return impacts.sort((left, right) =>\n [\n left.target_action_id,\n left.source_table,\n left.source_id,\n left.source_version,\n left.reference_path,\n ]\n .join('\\u0000')\n .localeCompare(\n [\n right.target_action_id,\n right.source_table,\n right.source_id,\n right.source_version,\n right.reference_path,\n ].join('\\u0000'),\n ),\n );\n}\n\nfunction projectedRows(options: {\n current: DatasetMaintenanceRemoteRow[];\n actions: DatasetMaintenancePlanAction[];\n desiredPayloads: Map<string, JsonObject>;\n}): DatasetMaintenanceRemoteRow[] {\n const projected = new Map(options.current.map((row) => [maintenanceRowKey(row), { ...row }]));\n for (const action of options.actions.filter((entry) =>\n ['save_draft', 'update_json_ordered'].includes(entry.action),\n )) {\n const key = maintenanceRowKey(action);\n const row = projected.get(key);\n const payload = options.desiredPayloads.get(action.action_id);\n if (row && payload) {\n projected.set(key, { ...row, json_ordered: payload });\n }\n }\n for (const action of options.actions.filter((entry) => entry.action === 'delete')) {\n projected.delete(maintenanceRowKey(action));\n }\n return [...projected.values()].sort((left, right) =>\n maintenanceRowKey(left).localeCompare(maintenanceRowKey(right)),\n );\n}\n\nexport function maintenanceProjectedReferenceFingerprint(\n rows: DatasetMaintenanceRemoteRow[],\n): unknown[] {\n const payloadRows = rows\n .filter((row) => row.json_ordered !== null)\n .map((row) => ({\n table: row.table,\n id: row.id,\n version: row.version,\n json_ordered: row.json_ordered as JsonObject,\n }));\n return collectRemoteReferences(payloadRows)\n .filter((reference) => reference.role === 'reference')\n .map((reference) => ({\n source: maintenanceRowKey(payloadRows[reference.row_index]!),\n table: reference.table,\n id: reference.id,\n version: reference.version,\n path: reference.path,\n }))\n .sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));\n}\n\nfunction protectedRows(options: {\n snapshot: DatasetMaintenanceRowSnapshot[];\n actions: DatasetMaintenancePlanAction[];\n}): DatasetMaintenanceProtectedRow[] {\n const readyActionKeys = new Set(\n options.actions\n .filter((action) => action.before && action.status === 'ready')\n .map(maintenanceRowKey),\n );\n const blockedActionKeys = new Set(\n options.actions\n .filter((action) => action.before && action.status === 'blocked')\n .map(maintenanceRowKey),\n );\n return options.snapshot\n .filter((row) => !readyActionKeys.has(maintenanceRowKey(row)))\n .map((row) => ({\n table: row.table,\n id: row.id,\n version: row.version,\n modified_at: row.modified_at,\n row_sha256: row.row_sha256,\n payload_sha256: row.payload_sha256,\n reason: blockedActionKeys.has(maintenanceRowKey(row))\n ? ('blocked_action_row' as const)\n : ('non_action_visible_row' as const),\n }));\n}\n\nexport async function runDatasetMaintenancePlan(\n options: RunDatasetMaintenancePlanOptions,\n): Promise<DatasetMaintenancePlan> {\n const scopePath = path.resolve(options.scopePath);\n const outDir = path.resolve(options.outDir);\n const pageSize = normalizeMaintenancePageSize(options.pageSize);\n const generatedAtUtc = (options.now ?? new Date()).toISOString();\n const scope = parseMaintenanceScope(\n readJsonFile(scopePath, 'Maintenance scope'),\n options.operation,\n );\n const context = await resolveMaintenanceRemoteContext({\n env: options.env,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n });\n if (context.account.user_id !== scope.account.user_id) {\n throw new CliError('Current authenticated user does not match maintenance scope account.', {\n code: 'DATASET_MAINTENANCE_ACCOUNT_MISMATCH',\n exitCode: 1,\n details: {\n expected_user_id: scope.account.user_id,\n current_user_id: context.account.user_id,\n },\n });\n }\n if (\n scope.account.email &&\n normalizeEmail(scope.account.email) !== normalizeEmail(context.account.email)\n ) {\n throw new CliError('Current authenticated email does not match maintenance scope account.', {\n code: 'DATASET_MAINTENANCE_ACCOUNT_EMAIL_MISMATCH',\n exitCode: 1,\n details: {\n expected_email: scope.account.email,\n current_email: context.account.email,\n },\n });\n }\n\n const accountSnapshot = await fetchMaintenanceAccountRows({\n context,\n userId: scope.account.user_id,\n pageSize,\n });\n const snapshotRows = accountSnapshot.rows\n .map(snapshotRemoteRow)\n .sort((left, right) => maintenanceRowKey(left).localeCompare(maintenanceRowKey(right)));\n const snapshotByKey = new Map(snapshotRows.map((row) => [maintenanceRowKey(row), row]));\n const desiredPayloads = new Map<string, JsonObject>();\n const actionPlans: DatasetMaintenancePlanAction[] = [];\n const aliasTargetSnapshots = new Map<\n string,\n DatasetMaintenanceAliasBatchPlan['target_snapshots']\n >();\n for (const batch of scope.alias_batches ?? []) {\n const targetRows = await Promise.all(\n (['unitgroup', 'flowproperty'] as const).map(async (kind) => {\n const target = batch.target[kind];\n const table = kind === 'unitgroup' ? 'unitgroups' : 'flowproperties';\n const exact = await fetchMaintenanceExactRows({\n context,\n table,\n id: target.id,\n version: target.version,\n });\n const row = exact.rows.length === 1 ? exact.rows[0] : null;\n if (!row?.json_ordered) return null;\n const inspection = inspectMaintenanceSupportPayload({\n table,\n payload: row.json_ordered,\n schemas: options.supportSchemas,\n });\n return inspection.identity.id === target.id &&\n inspection.identity.version === target.version &&\n inspection.schemaResult.success\n ? snapshotRemoteRow(row)\n : null;\n }),\n );\n const sourceUnitGroupSnapshot = snapshotByKey.get(\n maintenanceRowKey({\n table: 'unitgroups',\n id: batch.source.unitgroup.id,\n version: batch.source.unitgroup.version,\n }),\n );\n const sourceUnitGroupInspection = sourceUnitGroupSnapshot?.json_ordered\n ? inspectMaintenanceSupportPayload({\n table: 'unitgroups',\n payload: sourceUnitGroupSnapshot.json_ordered,\n schemas: options.supportSchemas,\n })\n : null;\n aliasTargetSnapshots.set(batch.batch_id, {\n unitgroup: targetRows[0],\n flowproperty: targetRows[1],\n source_unitgroup:\n sourceUnitGroupSnapshot &&\n sourceUnitGroupInspection?.identity.id === batch.source.unitgroup.id &&\n sourceUnitGroupInspection.identity.version === batch.source.unitgroup.version &&\n sourceUnitGroupInspection.schemaResult.success\n ? sourceUnitGroupSnapshot\n : null,\n });\n }\n\n for (const [ordinal, action] of scope.actions.entries()) {\n const actionBlockers: DatasetMaintenanceBlocker[] = [];\n const exact = await fetchMaintenanceExactRows({\n context,\n table: action.table,\n id: action.id,\n version: action.version,\n });\n const remote = exact.rows[0] ?? null;\n if (exact.rows.length === 0) {\n actionBlockers.push(\n blocker(\n action,\n 'TARGET_NOT_VISIBLE',\n 'Exact target row is not visible under the current authenticated RLS session.',\n ),\n );\n }\n if (exact.rows.length > 1) {\n actionBlockers.push(\n blocker(action, 'TARGET_NOT_UNIQUE', 'Exact target lookup returned multiple rows.'),\n );\n }\n const before = remote ? snapshotRemoteRow(remote) : null;\n if (before && before.user_id !== action.expected_user_id) {\n actionBlockers.push(\n blocker(action, 'TARGET_OWNER_MISMATCH', 'Target row is not owned by the expected user.', {\n visible_user_id: before.user_id,\n }),\n );\n }\n if (before && before.state_code !== 0) {\n actionBlockers.push(\n blocker(action, 'TARGET_NOT_DRAFT', 'Target row is not a draft with state_code=0.', {\n visible_state_code: before.state_code,\n }),\n );\n }\n if (before && !before.json_ordered) {\n actionBlockers.push(\n blocker(action, 'TARGET_PAYLOAD_MISSING', 'Target row has no object json_ordered payload.'),\n );\n }\n if (action.action === 'update_json_ordered' && before && !before.modified_at) {\n actionBlockers.push(\n blocker(\n action,\n 'ALIAS_EXPECTED_MODIFIED_AT_MISSING',\n `${action.action} target requires a non-null modified_at optimistic-lock value.`,\n ),\n );\n }\n if (\n before &&\n action.expected_before_sha256 &&\n action.expected_before_sha256 !== before.row_sha256\n ) {\n actionBlockers.push(\n blocker(action, 'EXPECTED_BEFORE_HASH_MISMATCH', 'Target row hash differs from scope.', {\n expected: action.expected_before_sha256,\n actual: before.row_sha256,\n }),\n );\n }\n const snapshotRow = snapshotByKey.get(maintenanceRowKey(action));\n if (before && (!snapshotRow || snapshotRow.row_sha256 !== before.row_sha256)) {\n actionBlockers.push(\n blocker(\n action,\n 'SNAPSHOT_DRIFT',\n 'Exact target row differs from the same-account visible snapshot.',\n ),\n );\n }\n\n let desiredPayload: DatasetMaintenancePlanAction['desired_payload'] = null;\n if (action.action === 'save_draft' && action.desired_payload_path) {\n const sourcePayloadPath = path.resolve(path.dirname(scopePath), action.desired_payload_path);\n const rawPayload = readJsonFile(sourcePayloadPath, 'Maintenance desired payload');\n if (!isJsonObject(rawPayload)) {\n throw new CliError(`Desired payload must be a JSON object: ${sourcePayloadPath}`, {\n code: 'DATASET_MAINTENANCE_DESIRED_PAYLOAD_INVALID',\n exitCode: 2,\n });\n }\n const payloadPath = path.join(\n outDir,\n 'payloads',\n `${safeActionFileName(action.action_id)}.json`,\n );\n writeImmutableJson(payloadPath, rawPayload);\n desiredPayloads.set(action.action_id, rawPayload);\n desiredPayload = {\n path: path.relative(outDir, payloadPath),\n sha256: sha256Json(rawPayload),\n };\n const identity = maintenancePayloadIdentity(rawPayload);\n if (identity.id !== action.id || identity.version !== action.version) {\n actionBlockers.push(\n blocker(\n action,\n 'DESIRED_PAYLOAD_IDENTITY_MISMATCH',\n 'Desired payload root id/version does not match the target row.',\n identity,\n ),\n );\n }\n }\n actionPlans.push({\n ...action,\n ordinal,\n status: actionBlockers.length ? 'blocked' : 'ready',\n before,\n desired_payload: desiredPayload,\n blockers: actionBlockers,\n rollback: {\n strategy:\n action.action === 'save_draft'\n ? 'save_before_snapshot'\n : action.action === 'delete'\n ? 'restore_deleted_before_snapshot'\n : 'restore_atomic_alias_before_snapshot',\n before_payload_sha256: before?.payload_sha256 ?? null,\n before_payload: before?.json_ordered ?? null,\n model_id: before?.model_id ?? null,\n rule_verification: before?.rule_verification ?? null,\n },\n });\n }\n\n let aliasBatches: DatasetMaintenanceAliasBatchPlan[] | undefined;\n if (scope.operation === 'merge-support-aliases') {\n const aliasPlan = buildAliasRewritePlan({\n scope,\n actions: actionPlans,\n accountRows: accountSnapshot.rows,\n targetSnapshots: aliasTargetSnapshots,\n schemas: options.aliasSchemas,\n });\n aliasBatches = aliasPlan.batches;\n for (const action of actionPlans) {\n const rawPayload = aliasPlan.desired_payloads.get(action.action_id);\n if (!rawPayload) continue;\n const payloadPath = path.join(\n outDir,\n 'payloads',\n `${safeActionFileName(action.action_id)}.json`,\n );\n writeImmutableJson(payloadPath, rawPayload);\n desiredPayloads.set(action.action_id, rawPayload);\n action.desired_payload = {\n path: path.relative(outDir, payloadPath),\n sha256: sha256Json(rawPayload),\n };\n const identity = maintenancePayloadIdentity(rawPayload);\n if (identity.id !== action.id || identity.version !== action.version) {\n action.blockers.push(\n blocker(\n action,\n 'DESIRED_PAYLOAD_IDENTITY_MISMATCH',\n 'Generated alias payload root id/version does not match the target row.',\n identity,\n ),\n );\n action.status = 'blocked';\n }\n }\n }\n\n const intendedRows = projectedRows({\n current: accountSnapshot.rows,\n actions: actionPlans,\n desiredPayloads,\n });\n const deleteActions = scope.actions.filter((action) => action.action === 'delete');\n const currentImpacts = referenceImpacts({\n rows: accountSnapshot.rows,\n deletes: deleteActions,\n phase: 'current',\n });\n const projectedImpacts = referenceImpacts({\n rows: intendedRows,\n deletes: deleteActions,\n phase: 'projected',\n });\n for (const action of actionPlans.filter((entry) => entry.action === 'delete')) {\n const impacts = projectedImpacts.filter(\n (impact) => impact.target_action_id === action.action_id,\n );\n if (impacts.length) {\n action.blockers.push(\n blocker(\n action,\n 'PROJECTED_INBOUND_REFERENCES',\n `Projected state still contains ${impacts.length} inbound reference(s) to this delete target.`,\n impacts,\n ),\n );\n action.status = 'blocked';\n }\n }\n const allBlockers = actionPlans.flatMap((action) => action.blockers);\n const protectedRowList = protectedRows({ snapshot: snapshotRows, actions: actionPlans });\n const scopeSha256 = sha256Json(scope);\n const plan: DatasetMaintenancePlan = {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n task_id: scope.task_id,\n operation: scope.operation,\n operation_id: `maintenance-${scopeSha256.slice(0, 20)}`,\n account: {\n user_id: scope.account.user_id,\n email: context.account.email,\n },\n source_import_run_id: scope.source_import_run_id ?? null,\n source_lineage: scope.source_lineage ?? null,\n target_mode: scope.target_mode ?? null,\n status: allBlockers.length ? 'blocked' : 'ready',\n scope_sha256: scopeSha256,\n visible_snapshot_sha256: sha256Json(snapshotRows),\n snapshot_completeness: accountSnapshot.completeness,\n projected_reference_sha256: sha256Json(maintenanceProjectedReferenceFingerprint(intendedRows)),\n plan_sha256: '',\n summary: {\n actions: actionPlans.length,\n save_draft: actionPlans.filter((action) => action.action === 'save_draft').length,\n delete: actionPlans.filter((action) => action.action === 'delete').length,\n update_json_ordered: actionPlans.filter((action) => action.action === 'update_json_ordered')\n .length,\n atomic_batches: aliasBatches?.length ?? 0,\n scaled_exchanges: aliasBatches?.reduce((sum, batch) => sum + batch.summary.exchanges, 0) ?? 0,\n scaled_amount_fields:\n aliasBatches?.reduce((sum, batch) => sum + batch.summary.amount_fields, 0) ?? 0,\n unrelated_exchanges_preserved:\n aliasBatches?.reduce((sum, batch) => sum + batch.summary.unrelated_exchanges, 0) ?? 0,\n protected_rows: protectedRowList.length,\n blockers: allBlockers.length,\n current_reference_impacts: currentImpacts.length,\n projected_reference_impacts: projectedImpacts.length,\n },\n artifacts: {\n maintenance_scope: 'maintenance-scope.json',\n rls_visible_snapshot: 'rls-visible-snapshot.json',\n protected_rows: 'protected-rows.jsonl',\n reference_impact_report: 'reference-impact-report.json',\n maintenance_plan: 'maintenance-plan.json',\n dry_run_report: 'dry-run-report.json',\n payload_dir: 'payloads',\n ...(aliasBatches ? { exchange_rewrite_plan: 'exchange-rewrite-plan.jsonl' } : {}),\n },\n actions: actionPlans,\n ...(aliasBatches ? { alias_batches: aliasBatches } : {}),\n protected_rows: protectedRowList,\n blockers: allBlockers,\n };\n plan.plan_sha256 = computePlanSha256(plan);\n\n writeImmutableJson(path.join(outDir, plan.artifacts.maintenance_scope), scope);\n writeImmutableJson(path.join(outDir, plan.artifacts.rls_visible_snapshot), {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n account: {\n user_id: scope.account.user_id,\n email: context.account.email,\n session_source: context.account.session_source,\n },\n page_size: pageSize,\n completeness: accountSnapshot.completeness,\n source_urls: accountSnapshot.source_urls,\n row_count: snapshotRows.length,\n snapshot_sha256: plan.visible_snapshot_sha256,\n rows: snapshotRows,\n });\n writeImmutableJsonLines(path.join(outDir, plan.artifacts.protected_rows), protectedRowList);\n if (plan.artifacts.exchange_rewrite_plan) {\n writeImmutableJsonLines(\n path.join(outDir, plan.artifacts.exchange_rewrite_plan),\n plan.alias_batches!.flatMap((batch) =>\n batch.exchange_rewrites.map((rewrite) => ({\n schema_version: 1,\n plan_sha256: plan.plan_sha256,\n operation_id: plan.operation_id,\n batch_id: batch.batch_id,\n factor: batch.factor,\n ...rewrite,\n })),\n ),\n );\n }\n writeImmutableJson(path.join(outDir, plan.artifacts.reference_impact_report), {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n plan_sha256: plan.plan_sha256,\n status: plan.status,\n current: currentImpacts,\n projected: projectedImpacts,\n projected_reference_sha256: plan.projected_reference_sha256,\n });\n writeImmutableJson(path.join(outDir, plan.artifacts.dry_run_report), {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n status: plan.status,\n operation: plan.operation,\n target_mode: plan.target_mode,\n task_id: plan.task_id,\n plan_sha256: plan.plan_sha256,\n account: plan.account,\n snapshot_completeness: accountSnapshot.completeness,\n summary: plan.summary,\n actions: plan.actions.map((action) => ({\n action_id: action.action_id,\n action: action.action,\n table: action.table,\n id: action.id,\n version: action.version,\n status: action.status,\n blockers: action.blockers,\n })),\n alias_batches: plan.alias_batches?.map((batch) => ({\n batch_id: batch.batch_id,\n dimension: batch.dimension,\n factor: batch.factor,\n summary: batch.summary,\n postconditions: batch.postconditions,\n target_snapshots: batch.target_snapshots,\n })),\n blockers: plan.blockers,\n });\n writeImmutableJson(path.join(outDir, plan.artifacts.maintenance_plan), plan);\n return plan;\n}\n\nexport const __testInternals = {\n desiredPayloadIdentity: maintenancePayloadIdentity,\n maintenanceProjectedReferenceFingerprint,\n projectedRows,\n protectedRows,\n referenceImpacts,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"dataset-maintenance-plan.js","sourceRoot":"","sources":["../../../src/lib/dataset-maintenance-plan.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { collectRemoteReferences } from './dataset-remote-verify.js';\nimport {\n buildAliasRewritePlan,\n type DatasetMaintenanceAliasSchemas,\n} from './dataset-maintenance-alias-rewrite.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n computePlanSha256,\n isJsonObject,\n maintenanceRowKey,\n parseMaintenanceScope,\n readJsonFile,\n safeActionFileName,\n sha256Json,\n snapshotRemoteRow,\n writeImmutableJson,\n writeImmutableJsonLines,\n type DatasetMaintenanceBlocker,\n type DatasetMaintenanceAliasBatchPlan,\n type DatasetMaintenanceOperation,\n type DatasetMaintenancePlan,\n type DatasetMaintenancePlanAction,\n type DatasetMaintenanceProtectedRow,\n type DatasetMaintenanceReferenceImpact,\n type DatasetMaintenanceRemoteRow,\n type DatasetMaintenanceRowSnapshot,\n type DatasetMaintenanceScopeAction,\n type JsonObject,\n} from './dataset-maintenance-contract.js';\nimport { parseDerivativeSnapshotResponse } from './dataset-maintenance-derivatives.js';\nimport {\n inspectMaintenanceSupportPayload,\n maintenancePayloadIdentity,\n type DatasetMaintenanceSupportSchemas,\n} from './dataset-maintenance-support-validation.js';\nimport {\n fetchMaintenanceAccountRows,\n fetchMaintenanceDerivativeSnapshot,\n fetchMaintenanceExactRows,\n normalizeMaintenancePageSize,\n resolveMaintenanceRemoteContext,\n} from './dataset-maintenance-remote.js';\n\nexport type RunDatasetMaintenancePlanOptions = {\n scopePath: string;\n operation: DatasetMaintenanceOperation;\n outDir: string;\n pageSize?: number;\n timeoutMs?: number;\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n now?: Date;\n supportSchemas?: DatasetMaintenanceSupportSchemas;\n aliasSchemas?: DatasetMaintenanceAliasSchemas;\n};\n\nfunction normalizeEmail(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction blocker(\n action: DatasetMaintenanceScopeAction,\n code: string,\n message: string,\n details?: unknown,\n): DatasetMaintenanceBlocker {\n return {\n code,\n message,\n action_id: action.action_id,\n table: action.table,\n id: action.id,\n version: action.version,\n ...(details === undefined ? {} : { details }),\n };\n}\n\nfunction referenceImpacts(options: {\n rows: DatasetMaintenanceRemoteRow[];\n deletes: DatasetMaintenanceScopeAction[];\n phase: DatasetMaintenanceReferenceImpact['phase'];\n}): DatasetMaintenanceReferenceImpact[] {\n const payloadRows = options.rows\n .filter((row) => row.json_ordered !== null)\n .map((row) => ({\n table: row.table,\n id: row.id,\n version: row.version,\n json_ordered: row.json_ordered as JsonObject,\n }));\n const references = collectRemoteReferences(payloadRows).filter(\n (reference) => reference.role === 'reference',\n );\n const impacts: DatasetMaintenanceReferenceImpact[] = [];\n for (const reference of references) {\n const source = payloadRows[reference.row_index];\n if (!reference.table || !reference.id) {\n continue;\n }\n for (const target of options.deletes) {\n const sameTarget =\n reference.table === target.table &&\n reference.id === target.id &&\n (!reference.version || reference.version === target.version);\n if (sameTarget) {\n impacts.push({\n target_action_id: target.action_id,\n target_table: target.table,\n target_id: target.id,\n target_version: target.version,\n phase: options.phase,\n source_table: source!.table,\n source_id: source!.id,\n source_version: source!.version,\n reference_path: reference.path,\n reference_version: reference.version,\n });\n }\n }\n }\n return impacts.sort((left, right) =>\n [\n left.target_action_id,\n left.source_table,\n left.source_id,\n left.source_version,\n left.reference_path,\n ]\n .join('\\u0000')\n .localeCompare(\n [\n right.target_action_id,\n right.source_table,\n right.source_id,\n right.source_version,\n right.reference_path,\n ].join('\\u0000'),\n ),\n );\n}\n\nfunction projectedRows(options: {\n current: DatasetMaintenanceRemoteRow[];\n actions: DatasetMaintenancePlanAction[];\n desiredPayloads: Map<string, JsonObject>;\n}): DatasetMaintenanceRemoteRow[] {\n const projected = new Map(options.current.map((row) => [maintenanceRowKey(row), { ...row }]));\n for (const action of options.actions.filter((entry) =>\n ['save_draft', 'update_json_ordered'].includes(entry.action),\n )) {\n const key = maintenanceRowKey(action);\n const row = projected.get(key);\n const payload = options.desiredPayloads.get(action.action_id);\n if (row && payload) {\n projected.set(key, { ...row, json_ordered: payload });\n }\n }\n for (const action of options.actions.filter((entry) => entry.action === 'delete')) {\n projected.delete(maintenanceRowKey(action));\n }\n return [...projected.values()].sort((left, right) =>\n maintenanceRowKey(left).localeCompare(maintenanceRowKey(right)),\n );\n}\n\nexport function maintenanceProjectedReferenceFingerprint(\n rows: DatasetMaintenanceRemoteRow[],\n): unknown[] {\n const payloadRows = rows\n .filter((row) => row.json_ordered !== null)\n .map((row) => ({\n table: row.table,\n id: row.id,\n version: row.version,\n json_ordered: row.json_ordered as JsonObject,\n }));\n return collectRemoteReferences(payloadRows)\n .filter((reference) => reference.role === 'reference')\n .map((reference) => ({\n source: maintenanceRowKey(payloadRows[reference.row_index]!),\n table: reference.table,\n id: reference.id,\n version: reference.version,\n path: reference.path,\n }))\n .sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));\n}\n\nfunction protectedRows(options: {\n snapshot: DatasetMaintenanceRowSnapshot[];\n actions: DatasetMaintenancePlanAction[];\n}): DatasetMaintenanceProtectedRow[] {\n const readyActionKeys = new Set(\n options.actions\n .filter((action) => action.before && action.status === 'ready')\n .map(maintenanceRowKey),\n );\n const blockedActionKeys = new Set(\n options.actions\n .filter((action) => action.before && action.status === 'blocked')\n .map(maintenanceRowKey),\n );\n return options.snapshot\n .filter((row) => !readyActionKeys.has(maintenanceRowKey(row)))\n .map((row) => ({\n table: row.table,\n id: row.id,\n version: row.version,\n modified_at: row.modified_at,\n row_sha256: row.row_sha256,\n payload_sha256: row.payload_sha256,\n reason: blockedActionKeys.has(maintenanceRowKey(row))\n ? ('blocked_action_row' as const)\n : ('non_action_visible_row' as const),\n }));\n}\n\nexport async function runDatasetMaintenancePlan(\n options: RunDatasetMaintenancePlanOptions,\n): Promise<DatasetMaintenancePlan> {\n const scopePath = path.resolve(options.scopePath);\n const outDir = path.resolve(options.outDir);\n const pageSize = normalizeMaintenancePageSize(options.pageSize);\n const generatedAtUtc = (options.now ?? new Date()).toISOString();\n const scope = parseMaintenanceScope(\n readJsonFile(scopePath, 'Maintenance scope'),\n options.operation,\n );\n const context = await resolveMaintenanceRemoteContext({\n env: options.env,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n });\n if (context.account.user_id !== scope.account.user_id) {\n throw new CliError('Current authenticated user does not match maintenance scope account.', {\n code: 'DATASET_MAINTENANCE_ACCOUNT_MISMATCH',\n exitCode: 1,\n details: {\n expected_user_id: scope.account.user_id,\n current_user_id: context.account.user_id,\n },\n });\n }\n if (\n scope.account.email &&\n normalizeEmail(scope.account.email) !== normalizeEmail(context.account.email)\n ) {\n throw new CliError('Current authenticated email does not match maintenance scope account.', {\n code: 'DATASET_MAINTENANCE_ACCOUNT_EMAIL_MISMATCH',\n exitCode: 1,\n details: {\n expected_email: scope.account.email,\n current_email: context.account.email,\n },\n });\n }\n\n const accountSnapshot = await fetchMaintenanceAccountRows({\n context,\n userId: scope.account.user_id,\n pageSize,\n });\n const snapshotRows = accountSnapshot.rows\n .map(snapshotRemoteRow)\n .sort((left, right) => maintenanceRowKey(left).localeCompare(maintenanceRowKey(right)));\n const snapshotByKey = new Map(snapshotRows.map((row) => [maintenanceRowKey(row), row]));\n const desiredPayloads = new Map<string, JsonObject>();\n const actionPlans: DatasetMaintenancePlanAction[] = [];\n const aliasTargetSnapshots = new Map<\n string,\n DatasetMaintenanceAliasBatchPlan['target_snapshots']\n >();\n for (const batch of scope.alias_batches ?? []) {\n const targetRows = await Promise.all(\n (['unitgroup', 'flowproperty'] as const).map(async (kind) => {\n const target = batch.target[kind];\n const table = kind === 'unitgroup' ? 'unitgroups' : 'flowproperties';\n const exact = await fetchMaintenanceExactRows({\n context,\n table,\n id: target.id,\n version: target.version,\n });\n const row = exact.rows.length === 1 ? exact.rows[0] : null;\n if (!row?.json_ordered) return null;\n const inspection = inspectMaintenanceSupportPayload({\n table,\n payload: row.json_ordered,\n schemas: options.supportSchemas,\n });\n return inspection.identity.id === target.id &&\n inspection.identity.version === target.version &&\n inspection.schemaResult.success\n ? snapshotRemoteRow(row)\n : null;\n }),\n );\n const sourceUnitGroupSnapshot = snapshotByKey.get(\n maintenanceRowKey({\n table: 'unitgroups',\n id: batch.source.unitgroup.id,\n version: batch.source.unitgroup.version,\n }),\n );\n const sourceUnitGroupInspection = sourceUnitGroupSnapshot?.json_ordered\n ? inspectMaintenanceSupportPayload({\n table: 'unitgroups',\n payload: sourceUnitGroupSnapshot.json_ordered,\n schemas: options.supportSchemas,\n })\n : null;\n aliasTargetSnapshots.set(batch.batch_id, {\n unitgroup: targetRows[0],\n flowproperty: targetRows[1],\n source_unitgroup:\n sourceUnitGroupSnapshot &&\n sourceUnitGroupInspection?.identity.id === batch.source.unitgroup.id &&\n sourceUnitGroupInspection.identity.version === batch.source.unitgroup.version &&\n sourceUnitGroupInspection.schemaResult.success\n ? sourceUnitGroupSnapshot\n : null,\n });\n }\n\n for (const [ordinal, action] of scope.actions.entries()) {\n const actionBlockers: DatasetMaintenanceBlocker[] = [];\n const exact = await fetchMaintenanceExactRows({\n context,\n table: action.table,\n id: action.id,\n version: action.version,\n });\n const remote = exact.rows[0] ?? null;\n if (exact.rows.length === 0) {\n actionBlockers.push(\n blocker(\n action,\n 'TARGET_NOT_VISIBLE',\n 'Exact target row is not visible under the current authenticated RLS session.',\n ),\n );\n }\n if (exact.rows.length > 1) {\n actionBlockers.push(\n blocker(action, 'TARGET_NOT_UNIQUE', 'Exact target lookup returned multiple rows.'),\n );\n }\n const before = remote ? snapshotRemoteRow(remote) : null;\n if (before && before.user_id !== action.expected_user_id) {\n actionBlockers.push(\n blocker(action, 'TARGET_OWNER_MISMATCH', 'Target row is not owned by the expected user.', {\n visible_user_id: before.user_id,\n }),\n );\n }\n if (before && before.state_code !== 0) {\n actionBlockers.push(\n blocker(action, 'TARGET_NOT_DRAFT', 'Target row is not a draft with state_code=0.', {\n visible_state_code: before.state_code,\n }),\n );\n }\n if (before && !before.json_ordered) {\n actionBlockers.push(\n blocker(action, 'TARGET_PAYLOAD_MISSING', 'Target row has no object json_ordered payload.'),\n );\n }\n if (action.action === 'update_json_ordered' && before && !before.modified_at) {\n actionBlockers.push(\n blocker(\n action,\n 'ALIAS_EXPECTED_MODIFIED_AT_MISSING',\n `${action.action} target requires a non-null modified_at optimistic-lock value.`,\n ),\n );\n }\n if (\n before &&\n action.expected_before_sha256 &&\n action.expected_before_sha256 !== before.row_sha256\n ) {\n actionBlockers.push(\n blocker(action, 'EXPECTED_BEFORE_HASH_MISMATCH', 'Target row hash differs from scope.', {\n expected: action.expected_before_sha256,\n actual: before.row_sha256,\n }),\n );\n }\n const snapshotRow = snapshotByKey.get(maintenanceRowKey(action));\n if (before && (!snapshotRow || snapshotRow.row_sha256 !== before.row_sha256)) {\n actionBlockers.push(\n blocker(\n action,\n 'SNAPSHOT_DRIFT',\n 'Exact target row differs from the same-account visible snapshot.',\n ),\n );\n }\n\n let desiredPayload: DatasetMaintenancePlanAction['desired_payload'] = null;\n if (action.action === 'save_draft' && action.desired_payload_path) {\n const sourcePayloadPath = path.resolve(path.dirname(scopePath), action.desired_payload_path);\n const rawPayload = readJsonFile(sourcePayloadPath, 'Maintenance desired payload');\n if (!isJsonObject(rawPayload)) {\n throw new CliError(`Desired payload must be a JSON object: ${sourcePayloadPath}`, {\n code: 'DATASET_MAINTENANCE_DESIRED_PAYLOAD_INVALID',\n exitCode: 2,\n });\n }\n const payloadPath = path.join(\n outDir,\n 'payloads',\n `${safeActionFileName(action.action_id)}.json`,\n );\n writeImmutableJson(payloadPath, rawPayload);\n desiredPayloads.set(action.action_id, rawPayload);\n desiredPayload = {\n path: path.relative(outDir, payloadPath),\n sha256: sha256Json(rawPayload),\n };\n const identity = maintenancePayloadIdentity(rawPayload);\n if (identity.id !== action.id || identity.version !== action.version) {\n actionBlockers.push(\n blocker(\n action,\n 'DESIRED_PAYLOAD_IDENTITY_MISMATCH',\n 'Desired payload root id/version does not match the target row.',\n identity,\n ),\n );\n }\n }\n let derivativeBefore: DatasetMaintenancePlanAction['derivative_before'];\n if (action.action === 'rebuild_derivatives' && before && actionBlockers.length === 0) {\n const rawSnapshot = await fetchMaintenanceDerivativeSnapshot({\n context,\n id: action.id,\n version: action.version,\n });\n derivativeBefore = parseDerivativeSnapshotResponse(rawSnapshot, {\n id: action.id,\n version: action.version,\n userId: action.expected_user_id,\n });\n if (derivativeBefore.modified_at !== before.modified_at) {\n actionBlockers.push(\n blocker(\n action,\n 'DERIVATIVE_PRIMARY_SNAPSHOT_DRIFT',\n 'Derivative snapshot modified_at differs from the lean account snapshot.',\n {\n account_snapshot_modified_at: before.modified_at,\n derivative_snapshot_modified_at: derivativeBefore.modified_at,\n },\n ),\n );\n }\n }\n actionPlans.push({\n ...action,\n ordinal,\n status: actionBlockers.length ? 'blocked' : 'ready',\n before,\n desired_payload: desiredPayload,\n blockers: actionBlockers,\n ...(derivativeBefore ? { derivative_before: derivativeBefore } : {}),\n rollback: {\n strategy:\n action.action === 'save_draft'\n ? 'save_before_snapshot'\n : action.action === 'delete'\n ? 'restore_deleted_before_snapshot'\n : action.action === 'update_json_ordered'\n ? 'restore_atomic_alias_before_snapshot'\n : 'none_derivative_only',\n before_payload_sha256:\n action.action === 'rebuild_derivatives' ? null : (before?.payload_sha256 ?? null),\n before_payload:\n action.action === 'rebuild_derivatives' ? null : (before?.json_ordered ?? null),\n model_id: action.action === 'rebuild_derivatives' ? null : (before?.model_id ?? null),\n rule_verification:\n action.action === 'rebuild_derivatives' ? null : (before?.rule_verification ?? null),\n },\n });\n }\n\n let aliasBatches: DatasetMaintenanceAliasBatchPlan[] | undefined;\n if (scope.operation === 'merge-support-aliases') {\n const aliasPlan = buildAliasRewritePlan({\n scope,\n actions: actionPlans,\n accountRows: accountSnapshot.rows,\n targetSnapshots: aliasTargetSnapshots,\n schemas: options.aliasSchemas,\n });\n aliasBatches = aliasPlan.batches;\n for (const action of actionPlans) {\n const rawPayload = aliasPlan.desired_payloads.get(action.action_id);\n if (!rawPayload) continue;\n const payloadPath = path.join(\n outDir,\n 'payloads',\n `${safeActionFileName(action.action_id)}.json`,\n );\n writeImmutableJson(payloadPath, rawPayload);\n desiredPayloads.set(action.action_id, rawPayload);\n action.desired_payload = {\n path: path.relative(outDir, payloadPath),\n sha256: sha256Json(rawPayload),\n };\n const identity = maintenancePayloadIdentity(rawPayload);\n if (identity.id !== action.id || identity.version !== action.version) {\n action.blockers.push(\n blocker(\n action,\n 'DESIRED_PAYLOAD_IDENTITY_MISMATCH',\n 'Generated alias payload root id/version does not match the target row.',\n identity,\n ),\n );\n action.status = 'blocked';\n }\n }\n }\n\n const intendedRows = projectedRows({\n current: accountSnapshot.rows,\n actions: actionPlans,\n desiredPayloads,\n });\n const deleteActions = scope.actions.filter((action) => action.action === 'delete');\n const currentImpacts = referenceImpacts({\n rows: accountSnapshot.rows,\n deletes: deleteActions,\n phase: 'current',\n });\n const projectedImpacts = referenceImpacts({\n rows: intendedRows,\n deletes: deleteActions,\n phase: 'projected',\n });\n for (const action of actionPlans.filter((entry) => entry.action === 'delete')) {\n const impacts = projectedImpacts.filter(\n (impact) => impact.target_action_id === action.action_id,\n );\n if (impacts.length) {\n action.blockers.push(\n blocker(\n action,\n 'PROJECTED_INBOUND_REFERENCES',\n `Projected state still contains ${impacts.length} inbound reference(s) to this delete target.`,\n impacts,\n ),\n );\n action.status = 'blocked';\n }\n }\n const allBlockers = actionPlans.flatMap((action) => action.blockers);\n const protectedRowList = protectedRows({ snapshot: snapshotRows, actions: actionPlans });\n const scopeSha256 = sha256Json(scope);\n const plan: DatasetMaintenancePlan = {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n task_id: scope.task_id,\n operation: scope.operation,\n operation_id: `maintenance-${scopeSha256.slice(0, 20)}`,\n account: {\n user_id: scope.account.user_id,\n email: context.account.email,\n },\n source_import_run_id: scope.source_import_run_id ?? null,\n source_lineage: scope.source_lineage ?? null,\n target_mode: scope.target_mode ?? null,\n status: allBlockers.length ? 'blocked' : 'ready',\n scope_sha256: scopeSha256,\n visible_snapshot_sha256: sha256Json(snapshotRows),\n snapshot_completeness: accountSnapshot.completeness,\n projected_reference_sha256: sha256Json(maintenanceProjectedReferenceFingerprint(intendedRows)),\n plan_sha256: '',\n summary: {\n actions: actionPlans.length,\n save_draft: actionPlans.filter((action) => action.action === 'save_draft').length,\n delete: actionPlans.filter((action) => action.action === 'delete').length,\n update_json_ordered: actionPlans.filter((action) => action.action === 'update_json_ordered')\n .length,\n rebuild_derivatives: actionPlans.filter((action) => action.action === 'rebuild_derivatives')\n .length,\n atomic_batches: aliasBatches?.length ?? 0,\n scaled_exchanges: aliasBatches?.reduce((sum, batch) => sum + batch.summary.exchanges, 0) ?? 0,\n scaled_amount_fields:\n aliasBatches?.reduce((sum, batch) => sum + batch.summary.amount_fields, 0) ?? 0,\n unrelated_exchanges_preserved:\n aliasBatches?.reduce((sum, batch) => sum + batch.summary.unrelated_exchanges, 0) ?? 0,\n protected_rows: protectedRowList.length,\n blockers: allBlockers.length,\n current_reference_impacts: currentImpacts.length,\n projected_reference_impacts: projectedImpacts.length,\n },\n artifacts: {\n maintenance_scope: 'maintenance-scope.json',\n rls_visible_snapshot: 'rls-visible-snapshot.json',\n protected_rows: 'protected-rows.jsonl',\n reference_impact_report: 'reference-impact-report.json',\n maintenance_plan: 'maintenance-plan.json',\n dry_run_report: 'dry-run-report.json',\n payload_dir: 'payloads',\n ...(aliasBatches ? { exchange_rewrite_plan: 'exchange-rewrite-plan.jsonl' } : {}),\n ...(scope.operation === 'rebuild-derivatives'\n ? { derivative_baseline: 'derivative-baseline.json' }\n : {}),\n },\n actions: actionPlans,\n ...(aliasBatches ? { alias_batches: aliasBatches } : {}),\n protected_rows: protectedRowList,\n blockers: allBlockers,\n };\n plan.plan_sha256 = computePlanSha256(plan);\n\n writeImmutableJson(path.join(outDir, plan.artifacts.maintenance_scope), scope);\n writeImmutableJson(path.join(outDir, plan.artifacts.rls_visible_snapshot), {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n account: {\n user_id: scope.account.user_id,\n email: context.account.email,\n session_source: context.account.session_source,\n },\n page_size: pageSize,\n completeness: accountSnapshot.completeness,\n source_urls: accountSnapshot.source_urls,\n row_count: snapshotRows.length,\n snapshot_sha256: plan.visible_snapshot_sha256,\n rows: snapshotRows,\n });\n writeImmutableJsonLines(path.join(outDir, plan.artifacts.protected_rows), protectedRowList);\n if (plan.artifacts.derivative_baseline) {\n writeImmutableJson(\n path.join(outDir, plan.artifacts.derivative_baseline),\n plan.actions[0]!.derivative_before ?? null,\n );\n }\n if (plan.artifacts.exchange_rewrite_plan) {\n writeImmutableJsonLines(\n path.join(outDir, plan.artifacts.exchange_rewrite_plan),\n plan.alias_batches!.flatMap((batch) =>\n batch.exchange_rewrites.map((rewrite) => ({\n schema_version: 1,\n plan_sha256: plan.plan_sha256,\n operation_id: plan.operation_id,\n batch_id: batch.batch_id,\n factor: batch.factor,\n ...rewrite,\n })),\n ),\n );\n }\n writeImmutableJson(path.join(outDir, plan.artifacts.reference_impact_report), {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n plan_sha256: plan.plan_sha256,\n status: plan.status,\n current: currentImpacts,\n projected: projectedImpacts,\n projected_reference_sha256: plan.projected_reference_sha256,\n });\n writeImmutableJson(path.join(outDir, plan.artifacts.dry_run_report), {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n status: plan.status,\n operation: plan.operation,\n target_mode: plan.target_mode,\n task_id: plan.task_id,\n plan_sha256: plan.plan_sha256,\n account: plan.account,\n snapshot_completeness: accountSnapshot.completeness,\n summary: plan.summary,\n actions: plan.actions.map((action) => ({\n action_id: action.action_id,\n action: action.action,\n table: action.table,\n id: action.id,\n version: action.version,\n status: action.status,\n blockers: action.blockers,\n ...(action.derivative_before ? { derivative_before: action.derivative_before } : {}),\n })),\n alias_batches: plan.alias_batches?.map((batch) => ({\n batch_id: batch.batch_id,\n dimension: batch.dimension,\n factor: batch.factor,\n summary: batch.summary,\n postconditions: batch.postconditions,\n target_snapshots: batch.target_snapshots,\n })),\n blockers: plan.blockers,\n });\n writeImmutableJson(path.join(outDir, plan.artifacts.maintenance_plan), plan);\n return plan;\n}\n\nexport const __testInternals = {\n desiredPayloadIdentity: maintenancePayloadIdentity,\n maintenanceProjectedReferenceFingerprint,\n projectedRows,\n protectedRows,\n referenceImpacts,\n};\n"]}
|