@tiangong-lca/cli 0.0.22 → 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 +23 -7
- package/dist/src/cli.js +25 -12
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-apply.js +274 -6
- package/dist/src/lib/dataset-maintenance-apply.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-clear-account.js +121 -58
- package/dist/src/lib/dataset-maintenance-clear-account.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-contract.js +126 -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-pagination.js +270 -0
- package/dist/src/lib/dataset-maintenance-pagination.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-plan.js +41 -6
- package/dist/src/lib/dataset-maintenance-plan.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-remote.js +76 -28
- package/dist/src/lib/dataset-maintenance-remote.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-verify.js +314 -5
- package/dist/src/lib/dataset-maintenance-verify.js.map +1 -1
- package/package.json +1 -1
|
@@ -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
|
}
|
|
@@ -375,6 +398,7 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
375
398
|
status: allBlockers.length ? 'blocked' : 'ready',
|
|
376
399
|
scope_sha256: scopeSha256,
|
|
377
400
|
visible_snapshot_sha256: sha256Json(snapshotRows),
|
|
401
|
+
snapshot_completeness: accountSnapshot.completeness,
|
|
378
402
|
projected_reference_sha256: sha256Json(maintenanceProjectedReferenceFingerprint(intendedRows)),
|
|
379
403
|
plan_sha256: '',
|
|
380
404
|
summary: {
|
|
@@ -383,6 +407,8 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
383
407
|
delete: actionPlans.filter((action) => action.action === 'delete').length,
|
|
384
408
|
update_json_ordered: actionPlans.filter((action) => action.action === 'update_json_ordered')
|
|
385
409
|
.length,
|
|
410
|
+
rebuild_derivatives: actionPlans.filter((action) => action.action === 'rebuild_derivatives')
|
|
411
|
+
.length,
|
|
386
412
|
atomic_batches: aliasBatches?.length ?? 0,
|
|
387
413
|
scaled_exchanges: aliasBatches?.reduce((sum, batch) => sum + batch.summary.exchanges, 0) ?? 0,
|
|
388
414
|
scaled_amount_fields: aliasBatches?.reduce((sum, batch) => sum + batch.summary.amount_fields, 0) ?? 0,
|
|
@@ -401,6 +427,9 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
401
427
|
dry_run_report: 'dry-run-report.json',
|
|
402
428
|
payload_dir: 'payloads',
|
|
403
429
|
...(aliasBatches ? { exchange_rewrite_plan: 'exchange-rewrite-plan.jsonl' } : {}),
|
|
430
|
+
...(scope.operation === 'rebuild-derivatives'
|
|
431
|
+
? { derivative_baseline: 'derivative-baseline.json' }
|
|
432
|
+
: {}),
|
|
404
433
|
},
|
|
405
434
|
actions: actionPlans,
|
|
406
435
|
...(aliasBatches ? { alias_batches: aliasBatches } : {}),
|
|
@@ -418,12 +447,16 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
418
447
|
session_source: context.account.session_source,
|
|
419
448
|
},
|
|
420
449
|
page_size: pageSize,
|
|
450
|
+
completeness: accountSnapshot.completeness,
|
|
421
451
|
source_urls: accountSnapshot.source_urls,
|
|
422
452
|
row_count: snapshotRows.length,
|
|
423
453
|
snapshot_sha256: plan.visible_snapshot_sha256,
|
|
424
454
|
rows: snapshotRows,
|
|
425
455
|
});
|
|
426
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
|
+
}
|
|
427
460
|
if (plan.artifacts.exchange_rewrite_plan) {
|
|
428
461
|
writeImmutableJsonLines(path.join(outDir, plan.artifacts.exchange_rewrite_plan), plan.alias_batches.flatMap((batch) => batch.exchange_rewrites.map((rewrite) => ({
|
|
429
462
|
schema_version: 1,
|
|
@@ -452,6 +485,7 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
452
485
|
task_id: plan.task_id,
|
|
453
486
|
plan_sha256: plan.plan_sha256,
|
|
454
487
|
account: plan.account,
|
|
488
|
+
snapshot_completeness: accountSnapshot.completeness,
|
|
455
489
|
summary: plan.summary,
|
|
456
490
|
actions: plan.actions.map((action) => ({
|
|
457
491
|
action_id: action.action_id,
|
|
@@ -461,6 +495,7 @@ export async function runDatasetMaintenancePlan(options) {
|
|
|
461
495
|
version: action.version,
|
|
462
496
|
status: action.status,
|
|
463
497
|
blockers: action.blockers,
|
|
498
|
+
...(action.derivative_before ? { derivative_before: action.derivative_before } : {}),
|
|
464
499
|
})),
|
|
465
500
|
alias_batches: plan.alias_batches?.map((batch) => ({
|
|
466
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 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 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 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"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliError } from './errors.js';
|
|
2
|
+
import { buildSnapshotCompleteness, fetchCompletePostgrestPages, } from './dataset-maintenance-pagination.js';
|
|
2
3
|
import { buildSupabaseAuthHeaders, deriveSupabaseProjectBaseUrl, requireSupabaseRestRuntime, } from './supabase-client.js';
|
|
3
4
|
import { resolveSupabaseUserSession } from './supabase-session.js';
|
|
4
5
|
import { isJsonObject, MAINTENANCE_SCAN_TABLES, } from './dataset-maintenance-contract.js';
|
|
@@ -41,7 +42,7 @@ export function normalizeMaintenanceTimeout(value) {
|
|
|
41
42
|
}
|
|
42
43
|
return normalized;
|
|
43
44
|
}
|
|
44
|
-
async function
|
|
45
|
+
async function fetchJsonResponse(options) {
|
|
45
46
|
const response = await options.context.fetch_impl(options.url, {
|
|
46
47
|
...options.init,
|
|
47
48
|
headers: {
|
|
@@ -59,10 +60,10 @@ async function fetchJson(options) {
|
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
if (!text.trim()) {
|
|
62
|
-
return null;
|
|
63
|
+
return { body: null, headers: response.headers };
|
|
63
64
|
}
|
|
64
65
|
try {
|
|
65
|
-
return JSON.parse(text);
|
|
66
|
+
return { body: JSON.parse(text), headers: response.headers };
|
|
66
67
|
}
|
|
67
68
|
catch (error) {
|
|
68
69
|
throw new CliError(`Remote response was not valid JSON for ${options.label}`, {
|
|
@@ -75,6 +76,9 @@ async function fetchJson(options) {
|
|
|
75
76
|
});
|
|
76
77
|
}
|
|
77
78
|
}
|
|
79
|
+
async function fetchJson(options) {
|
|
80
|
+
return (await fetchJsonResponse(options)).body;
|
|
81
|
+
}
|
|
78
82
|
function selectForTable(table) {
|
|
79
83
|
const common = 'id,version,user_id,state_code,modified_at,json_ordered,rule_verification';
|
|
80
84
|
return table === 'processes' ? `${common},model_id` : common;
|
|
@@ -180,33 +184,51 @@ export async function fetchMaintenanceExactRows(options) {
|
|
|
180
184
|
}
|
|
181
185
|
export async function fetchMaintenanceAccountRows(options) {
|
|
182
186
|
const pageSize = normalizeMaintenancePageSize(options.pageSize);
|
|
183
|
-
const
|
|
184
|
-
const sourceUrls = [];
|
|
187
|
+
const tableResults = [];
|
|
185
188
|
for (const table of MAINTENANCE_SCAN_TABLES) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
189
|
+
const result = await fetchCompletePostgrestPages({
|
|
190
|
+
table,
|
|
191
|
+
requestedPageSize: pageSize,
|
|
192
|
+
rowIdentity: (row) => `${row.id}\u0000${row.version}`,
|
|
193
|
+
fetchPage: async (offset) => {
|
|
194
|
+
const url = new URL(`${options.context.rest_base_url}/${table}`);
|
|
195
|
+
url.searchParams.set('select', selectForTable(table));
|
|
196
|
+
url.searchParams.set('user_id', `eq.${options.userId}`);
|
|
197
|
+
url.searchParams.set('order', 'id.asc,version.asc');
|
|
198
|
+
url.searchParams.set('limit', String(pageSize));
|
|
199
|
+
url.searchParams.set('offset', String(offset));
|
|
200
|
+
const sourceUrl = url.toString();
|
|
201
|
+
const response = await fetchJsonResponse({
|
|
202
|
+
context: options.context,
|
|
203
|
+
url: sourceUrl,
|
|
204
|
+
init: { headers: { Prefer: 'count=exact' } },
|
|
205
|
+
label: `${table} account maintenance snapshot`,
|
|
206
|
+
});
|
|
207
|
+
const rows = normalizeRemoteRows(table, response.body, sourceUrl);
|
|
208
|
+
if (rows.some((row) => row.user_id !== options.userId)) {
|
|
209
|
+
throw new CliError(`Remote ${table} snapshot contained a foreign account row.`, {
|
|
210
|
+
code: 'DATASET_MAINTENANCE_REMOTE_ROW_INVALID',
|
|
211
|
+
exitCode: 1,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
rows,
|
|
216
|
+
source_url: sourceUrl,
|
|
217
|
+
content_range: response.headers.get('content-range'),
|
|
218
|
+
};
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
tableResults.push({ table, ...result });
|
|
208
222
|
}
|
|
209
|
-
return {
|
|
223
|
+
return {
|
|
224
|
+
rows: tableResults.flatMap((result) => result.rows),
|
|
225
|
+
source_urls: tableResults.flatMap((result) => result.source_urls),
|
|
226
|
+
completeness: buildSnapshotCompleteness({
|
|
227
|
+
tables: MAINTENANCE_SCAN_TABLES,
|
|
228
|
+
requestedPageSize: pageSize,
|
|
229
|
+
results: tableResults,
|
|
230
|
+
}),
|
|
231
|
+
};
|
|
210
232
|
}
|
|
211
233
|
async function invokeMaintenanceRpc(options) {
|
|
212
234
|
const url = `${options.context.rest_base_url}/rpc/${options.rpc}`;
|
|
@@ -229,6 +251,31 @@ async function invokeMaintenanceRpc(options) {
|
|
|
229
251
|
}
|
|
230
252
|
return body;
|
|
231
253
|
}
|
|
254
|
+
export async function fetchMaintenanceDerivativeSnapshot(options) {
|
|
255
|
+
return invokeMaintenanceRpc({
|
|
256
|
+
context: options.context,
|
|
257
|
+
rpc: 'cmd_dataset_derivative_rebuild_snapshot',
|
|
258
|
+
body: {
|
|
259
|
+
p_table: 'processes',
|
|
260
|
+
p_id: options.id,
|
|
261
|
+
p_version: options.version,
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
export async function applyMaintenanceDerivativeRebuild(options) {
|
|
266
|
+
return invokeMaintenanceRpc({
|
|
267
|
+
context: options.context,
|
|
268
|
+
rpc: 'cmd_dataset_derivative_rebuild_plan_guarded',
|
|
269
|
+
body: { p_plan: options.plan },
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
export async function readMaintenanceDerivativeRebuild(options) {
|
|
273
|
+
return invokeMaintenanceRpc({
|
|
274
|
+
context: options.context,
|
|
275
|
+
rpc: 'cmd_dataset_derivative_rebuild_read',
|
|
276
|
+
body: { p_request_id: options.requestId },
|
|
277
|
+
});
|
|
278
|
+
}
|
|
232
279
|
export async function applyMaintenanceAliasPlan(options) {
|
|
233
280
|
return invokeMaintenanceRpc({
|
|
234
281
|
context: options.context,
|
|
@@ -265,6 +312,7 @@ export async function deleteMaintenanceRow(options) {
|
|
|
265
312
|
}
|
|
266
313
|
export const __testInternals = {
|
|
267
314
|
fetchJson,
|
|
315
|
+
fetchJsonResponse,
|
|
268
316
|
normalizeRemoteRow,
|
|
269
317
|
normalizeRemoteRows,
|
|
270
318
|
selectForTable,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset-maintenance-remote.js","sourceRoot":"","sources":["../../../src/lib/dataset-maintenance-remote.ts"],"names":[],"mappings":"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","sourcesContent":["import { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseProjectBaseUrl,\n requireSupabaseRestRuntime,\n} from './supabase-client.js';\nimport { resolveSupabaseUserSession } from './supabase-session.js';\nimport {\n isJsonObject,\n MAINTENANCE_SCAN_TABLES,\n type DatasetMaintenanceMutableTable,\n type DatasetMaintenanceRemoteRow,\n type DatasetMaintenanceScanTable,\n type JsonObject,\n} from './dataset-maintenance-contract.js';\n\nconst DEFAULT_PAGE_SIZE = 1_000;\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport type DatasetMaintenanceRemoteContext = {\n rest_base_url: string;\n publishable_key: string;\n access_token: string;\n account: {\n user_id: string;\n email: string;\n session_source: string;\n };\n fetch_impl: FetchLike;\n timeout_ms: number;\n};\n\nfunction trimToken(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const trimmed = value.trim();\n return trimmed || null;\n}\n\nfunction normalizeStateCode(value: unknown): number | null {\n if (typeof value === 'number' && Number.isInteger(value)) {\n return value;\n }\n return typeof value === 'string' && /^-?\\d+$/u.test(value.trim())\n ? Number.parseInt(value.trim(), 10)\n : null;\n}\n\nexport function normalizeMaintenancePageSize(value?: number): number {\n const normalized = value ?? DEFAULT_PAGE_SIZE;\n if (!Number.isInteger(normalized) || normalized < 1 || normalized > 5_000) {\n throw new CliError('Maintenance page size must be an integer between 1 and 5000.', {\n code: 'DATASET_MAINTENANCE_PAGE_SIZE_INVALID',\n exitCode: 2,\n details: value,\n });\n }\n return normalized;\n}\n\nexport function normalizeMaintenanceTimeout(value?: number): number {\n const normalized = value ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isInteger(normalized) || normalized < 1) {\n throw new CliError('Maintenance timeout must be a positive integer.', {\n code: 'DATASET_MAINTENANCE_TIMEOUT_INVALID',\n exitCode: 2,\n details: value,\n });\n }\n return normalized;\n}\n\nasync function fetchJson(options: {\n context: Pick<\n DatasetMaintenanceRemoteContext,\n 'publishable_key' | 'access_token' | 'fetch_impl' | 'timeout_ms'\n >;\n url: string;\n init?: RequestInit;\n label: string;\n}): Promise<unknown> {\n const response = await options.context.fetch_impl(options.url, {\n ...options.init,\n headers: {\n ...buildSupabaseAuthHeaders(options.context.publishable_key, options.context.access_token),\n ...(options.init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(options.context.timeout_ms),\n });\n const text = await response.text();\n if (!response.ok) {\n throw new CliError(`HTTP ${response.status} returned from ${options.label}`, {\n code: 'DATASET_MAINTENANCE_REMOTE_REQUEST_FAILED',\n exitCode: 1,\n details: { url: options.url, response: text },\n });\n }\n if (!text.trim()) {\n return null;\n }\n try {\n return JSON.parse(text);\n } catch (error) {\n throw new CliError(`Remote response was not valid JSON for ${options.label}`, {\n code: 'DATASET_MAINTENANCE_REMOTE_INVALID_JSON',\n exitCode: 1,\n details: {\n url: options.url,\n error: String(error),\n },\n });\n }\n}\n\nfunction selectForTable(table: DatasetMaintenanceScanTable): string {\n const common = 'id,version,user_id,state_code,modified_at,json_ordered,rule_verification';\n return table === 'processes' ? `${common},model_id` : common;\n}\n\nfunction normalizeRemoteRow(\n table: DatasetMaintenanceScanTable,\n value: unknown,\n): DatasetMaintenanceRemoteRow | null {\n if (!isJsonObject(value)) {\n return null;\n }\n const id = trimToken(value.id);\n const version = trimToken(value.version);\n if (!id || !version) {\n return null;\n }\n return {\n table,\n id,\n version,\n user_id: trimToken(value.user_id),\n state_code: normalizeStateCode(value.state_code),\n modified_at: trimToken(value.modified_at),\n json_ordered: isJsonObject(value.json_ordered) ? value.json_ordered : null,\n model_id: trimToken(value.model_id),\n rule_verification:\n typeof value.rule_verification === 'boolean' ? value.rule_verification : null,\n };\n}\n\nfunction normalizeRemoteRows(\n table: DatasetMaintenanceScanTable,\n value: unknown,\n label: string,\n): DatasetMaintenanceRemoteRow[] {\n if (!Array.isArray(value)) {\n throw new CliError(`Remote response was not an array for ${label}.`, {\n code: 'DATASET_MAINTENANCE_REMOTE_ROWS_INVALID',\n exitCode: 1,\n details: value,\n });\n }\n const rows = value.map((entry) => normalizeRemoteRow(table, entry));\n if (rows.some((row) => row === null)) {\n throw new CliError(`Remote response contained an invalid row for ${label}.`, {\n code: 'DATASET_MAINTENANCE_REMOTE_ROW_INVALID',\n exitCode: 1,\n });\n }\n return rows as DatasetMaintenanceRemoteRow[];\n}\n\nexport async function resolveMaintenanceRemoteContext(options: {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n}): Promise<DatasetMaintenanceRemoteContext> {\n const timeoutMs = normalizeMaintenanceTimeout(options.timeoutMs);\n const runtime = requireSupabaseRestRuntime(options.env);\n const session = await resolveSupabaseUserSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now: options.now,\n });\n const projectBaseUrl = deriveSupabaseProjectBaseUrl(runtime.apiBaseUrl);\n const partialContext = {\n publishable_key: runtime.publishableKey,\n access_token: session.accessToken,\n fetch_impl: options.fetchImpl,\n timeout_ms: timeoutMs,\n };\n const currentUser = await fetchJson({\n context: partialContext,\n url: `${projectBaseUrl}/auth/v1/user`,\n label: 'supabase current-user lookup',\n });\n const userId = isJsonObject(currentUser) ? trimToken(currentUser.id) : null;\n const email = isJsonObject(currentUser)\n ? (trimToken(currentUser.email) ?? trimToken(session.userEmail))\n : trimToken(session.userEmail);\n if (!userId || !email) {\n throw new CliError('Supabase current-user lookup did not return id and email.', {\n code: 'DATASET_MAINTENANCE_CURRENT_USER_INVALID',\n exitCode: 1,\n });\n }\n return {\n rest_base_url: `${projectBaseUrl}/rest/v1`,\n publishable_key: runtime.publishableKey,\n access_token: session.accessToken,\n account: {\n user_id: userId,\n email,\n session_source: session.source,\n },\n fetch_impl: options.fetchImpl,\n timeout_ms: timeoutMs,\n };\n}\n\nexport async function fetchMaintenanceExactRows(options: {\n context: DatasetMaintenanceRemoteContext;\n table: DatasetMaintenanceScanTable;\n id: string;\n version: string;\n}): Promise<{ rows: DatasetMaintenanceRemoteRow[]; source_url: string }> {\n const url = new URL(`${options.context.rest_base_url}/${options.table}`);\n url.searchParams.set('select', selectForTable(options.table));\n url.searchParams.set('id', `eq.${options.id}`);\n url.searchParams.set('version', `eq.${options.version}`);\n url.searchParams.set('limit', '2');\n const sourceUrl = url.toString();\n const body = await fetchJson({\n context: options.context,\n url: sourceUrl,\n label: `${options.table} exact maintenance lookup`,\n });\n return {\n rows: normalizeRemoteRows(options.table, body, sourceUrl),\n source_url: sourceUrl,\n };\n}\n\nexport async function fetchMaintenanceAccountRows(options: {\n context: DatasetMaintenanceRemoteContext;\n userId: string;\n pageSize?: number;\n}): Promise<{ rows: DatasetMaintenanceRemoteRow[]; source_urls: string[] }> {\n const pageSize = normalizeMaintenancePageSize(options.pageSize);\n const rows: DatasetMaintenanceRemoteRow[] = [];\n const sourceUrls: string[] = [];\n for (const table of MAINTENANCE_SCAN_TABLES) {\n let offset = 0;\n while (true) {\n const url = new URL(`${options.context.rest_base_url}/${table}`);\n url.searchParams.set('select', selectForTable(table));\n url.searchParams.set('user_id', `eq.${options.userId}`);\n url.searchParams.set('order', 'id.asc,version.asc');\n url.searchParams.set('limit', String(pageSize));\n url.searchParams.set('offset', String(offset));\n const sourceUrl = url.toString();\n const body = await fetchJson({\n context: options.context,\n url: sourceUrl,\n label: `${table} account maintenance snapshot`,\n });\n const page = normalizeRemoteRows(table, body, sourceUrl);\n rows.push(...page);\n sourceUrls.push(sourceUrl);\n if (page.length < pageSize) {\n break;\n }\n offset += pageSize;\n }\n }\n return { rows, source_urls: sourceUrls };\n}\n\nasync function invokeMaintenanceRpc(options: {\n context: DatasetMaintenanceRemoteContext;\n rpc: 'cmd_dataset_save_draft' | 'cmd_dataset_delete' | 'cmd_dataset_alias_plan_guarded';\n body: JsonObject;\n}): Promise<JsonObject> {\n const url = `${options.context.rest_base_url}/rpc/${options.rpc}`;\n const body = await fetchJson({\n context: options.context,\n url,\n init: {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(options.body),\n },\n label: options.rpc,\n });\n if (!isJsonObject(body) || body.ok !== true) {\n throw new CliError(`${options.rpc} returned an unexpected response.`, {\n code: 'DATASET_MAINTENANCE_RPC_FAILED',\n exitCode: 1,\n details: body,\n });\n }\n return body;\n}\n\nexport async function applyMaintenanceAliasPlan(options: {\n context: DatasetMaintenanceRemoteContext;\n plan: JsonObject;\n}): Promise<JsonObject> {\n return invokeMaintenanceRpc({\n context: options.context,\n rpc: 'cmd_dataset_alias_plan_guarded',\n body: { p_plan: options.plan },\n });\n}\n\nexport async function saveDraftMaintenanceRow(options: {\n context: DatasetMaintenanceRemoteContext;\n table: DatasetMaintenanceMutableTable;\n id: string;\n version: string;\n payload: JsonObject;\n modelId: string | null;\n ruleVerification: boolean | null;\n audit: JsonObject;\n}): Promise<JsonObject> {\n return invokeMaintenanceRpc({\n context: options.context,\n rpc: 'cmd_dataset_save_draft',\n body: {\n p_table: options.table,\n p_id: options.id,\n p_version: options.version,\n p_json_ordered: options.payload,\n p_model_id: options.modelId,\n p_rule_verification: options.ruleVerification,\n p_audit: options.audit,\n },\n });\n}\n\nexport async function deleteMaintenanceRow(options: {\n context: DatasetMaintenanceRemoteContext;\n table: DatasetMaintenanceMutableTable;\n id: string;\n version: string;\n audit: JsonObject;\n}): Promise<JsonObject> {\n return invokeMaintenanceRpc({\n context: options.context,\n rpc: 'cmd_dataset_delete',\n body: {\n p_table: options.table,\n p_id: options.id,\n p_version: options.version,\n p_audit: options.audit,\n },\n });\n}\n\nexport const __testInternals = {\n fetchJson,\n normalizeRemoteRow,\n normalizeRemoteRows,\n selectForTable,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"dataset-maintenance-remote.js","sourceRoot":"","sources":["../../../src/lib/dataset-maintenance-remote.ts"],"names":[],"mappings":"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","sourcesContent":["import { CliError } from './errors.js';\nimport type { FetchLike, ResponseLike } from './http.js';\nimport {\n buildSnapshotCompleteness,\n fetchCompletePostgrestPages,\n type DatasetMaintenanceSnapshotCompleteness,\n} from './dataset-maintenance-pagination.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseProjectBaseUrl,\n requireSupabaseRestRuntime,\n} from './supabase-client.js';\nimport { resolveSupabaseUserSession } from './supabase-session.js';\nimport {\n isJsonObject,\n MAINTENANCE_SCAN_TABLES,\n type DatasetMaintenanceMutableTable,\n type DatasetMaintenanceRemoteRow,\n type DatasetMaintenanceScanTable,\n type JsonObject,\n} from './dataset-maintenance-contract.js';\n\nconst DEFAULT_PAGE_SIZE = 1_000;\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport type DatasetMaintenanceRemoteContext = {\n rest_base_url: string;\n publishable_key: string;\n access_token: string;\n account: {\n user_id: string;\n email: string;\n session_source: string;\n };\n fetch_impl: FetchLike;\n timeout_ms: number;\n};\n\nfunction trimToken(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const trimmed = value.trim();\n return trimmed || null;\n}\n\nfunction normalizeStateCode(value: unknown): number | null {\n if (typeof value === 'number' && Number.isInteger(value)) {\n return value;\n }\n return typeof value === 'string' && /^-?\\d+$/u.test(value.trim())\n ? Number.parseInt(value.trim(), 10)\n : null;\n}\n\nexport function normalizeMaintenancePageSize(value?: number): number {\n const normalized = value ?? DEFAULT_PAGE_SIZE;\n if (!Number.isInteger(normalized) || normalized < 1 || normalized > 5_000) {\n throw new CliError('Maintenance page size must be an integer between 1 and 5000.', {\n code: 'DATASET_MAINTENANCE_PAGE_SIZE_INVALID',\n exitCode: 2,\n details: value,\n });\n }\n return normalized;\n}\n\nexport function normalizeMaintenanceTimeout(value?: number): number {\n const normalized = value ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isInteger(normalized) || normalized < 1) {\n throw new CliError('Maintenance timeout must be a positive integer.', {\n code: 'DATASET_MAINTENANCE_TIMEOUT_INVALID',\n exitCode: 2,\n details: value,\n });\n }\n return normalized;\n}\n\nasync function fetchJsonResponse(options: {\n context: Pick<\n DatasetMaintenanceRemoteContext,\n 'publishable_key' | 'access_token' | 'fetch_impl' | 'timeout_ms'\n >;\n url: string;\n init?: RequestInit;\n label: string;\n}): Promise<{ body: unknown; headers: ResponseLike['headers'] }> {\n const response = await options.context.fetch_impl(options.url, {\n ...options.init,\n headers: {\n ...buildSupabaseAuthHeaders(options.context.publishable_key, options.context.access_token),\n ...(options.init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(options.context.timeout_ms),\n });\n const text = await response.text();\n if (!response.ok) {\n throw new CliError(`HTTP ${response.status} returned from ${options.label}`, {\n code: 'DATASET_MAINTENANCE_REMOTE_REQUEST_FAILED',\n exitCode: 1,\n details: { url: options.url, response: text },\n });\n }\n if (!text.trim()) {\n return { body: null, headers: response.headers };\n }\n try {\n return { body: JSON.parse(text), headers: response.headers };\n } catch (error) {\n throw new CliError(`Remote response was not valid JSON for ${options.label}`, {\n code: 'DATASET_MAINTENANCE_REMOTE_INVALID_JSON',\n exitCode: 1,\n details: {\n url: options.url,\n error: String(error),\n },\n });\n }\n}\n\nasync function fetchJson(options: {\n context: Pick<\n DatasetMaintenanceRemoteContext,\n 'publishable_key' | 'access_token' | 'fetch_impl' | 'timeout_ms'\n >;\n url: string;\n init?: RequestInit;\n label: string;\n}): Promise<unknown> {\n return (await fetchJsonResponse(options)).body;\n}\n\nfunction selectForTable(table: DatasetMaintenanceScanTable): string {\n const common = 'id,version,user_id,state_code,modified_at,json_ordered,rule_verification';\n return table === 'processes' ? `${common},model_id` : common;\n}\n\nfunction normalizeRemoteRow(\n table: DatasetMaintenanceScanTable,\n value: unknown,\n): DatasetMaintenanceRemoteRow | null {\n if (!isJsonObject(value)) {\n return null;\n }\n const id = trimToken(value.id);\n const version = trimToken(value.version);\n if (!id || !version) {\n return null;\n }\n return {\n table,\n id,\n version,\n user_id: trimToken(value.user_id),\n state_code: normalizeStateCode(value.state_code),\n modified_at: trimToken(value.modified_at),\n json_ordered: isJsonObject(value.json_ordered) ? value.json_ordered : null,\n model_id: trimToken(value.model_id),\n rule_verification:\n typeof value.rule_verification === 'boolean' ? value.rule_verification : null,\n };\n}\n\nfunction normalizeRemoteRows(\n table: DatasetMaintenanceScanTable,\n value: unknown,\n label: string,\n): DatasetMaintenanceRemoteRow[] {\n if (!Array.isArray(value)) {\n throw new CliError(`Remote response was not an array for ${label}.`, {\n code: 'DATASET_MAINTENANCE_REMOTE_ROWS_INVALID',\n exitCode: 1,\n details: value,\n });\n }\n const rows = value.map((entry) => normalizeRemoteRow(table, entry));\n if (rows.some((row) => row === null)) {\n throw new CliError(`Remote response contained an invalid row for ${label}.`, {\n code: 'DATASET_MAINTENANCE_REMOTE_ROW_INVALID',\n exitCode: 1,\n });\n }\n return rows as DatasetMaintenanceRemoteRow[];\n}\n\nexport async function resolveMaintenanceRemoteContext(options: {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n}): Promise<DatasetMaintenanceRemoteContext> {\n const timeoutMs = normalizeMaintenanceTimeout(options.timeoutMs);\n const runtime = requireSupabaseRestRuntime(options.env);\n const session = await resolveSupabaseUserSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now: options.now,\n });\n const projectBaseUrl = deriveSupabaseProjectBaseUrl(runtime.apiBaseUrl);\n const partialContext = {\n publishable_key: runtime.publishableKey,\n access_token: session.accessToken,\n fetch_impl: options.fetchImpl,\n timeout_ms: timeoutMs,\n };\n const currentUser = await fetchJson({\n context: partialContext,\n url: `${projectBaseUrl}/auth/v1/user`,\n label: 'supabase current-user lookup',\n });\n const userId = isJsonObject(currentUser) ? trimToken(currentUser.id) : null;\n const email = isJsonObject(currentUser)\n ? (trimToken(currentUser.email) ?? trimToken(session.userEmail))\n : trimToken(session.userEmail);\n if (!userId || !email) {\n throw new CliError('Supabase current-user lookup did not return id and email.', {\n code: 'DATASET_MAINTENANCE_CURRENT_USER_INVALID',\n exitCode: 1,\n });\n }\n return {\n rest_base_url: `${projectBaseUrl}/rest/v1`,\n publishable_key: runtime.publishableKey,\n access_token: session.accessToken,\n account: {\n user_id: userId,\n email,\n session_source: session.source,\n },\n fetch_impl: options.fetchImpl,\n timeout_ms: timeoutMs,\n };\n}\n\nexport async function fetchMaintenanceExactRows(options: {\n context: DatasetMaintenanceRemoteContext;\n table: DatasetMaintenanceScanTable;\n id: string;\n version: string;\n}): Promise<{ rows: DatasetMaintenanceRemoteRow[]; source_url: string }> {\n const url = new URL(`${options.context.rest_base_url}/${options.table}`);\n url.searchParams.set('select', selectForTable(options.table));\n url.searchParams.set('id', `eq.${options.id}`);\n url.searchParams.set('version', `eq.${options.version}`);\n url.searchParams.set('limit', '2');\n const sourceUrl = url.toString();\n const body = await fetchJson({\n context: options.context,\n url: sourceUrl,\n label: `${options.table} exact maintenance lookup`,\n });\n return {\n rows: normalizeRemoteRows(options.table, body, sourceUrl),\n source_url: sourceUrl,\n };\n}\n\nexport async function fetchMaintenanceAccountRows(options: {\n context: DatasetMaintenanceRemoteContext;\n userId: string;\n pageSize?: number;\n}): Promise<{\n rows: DatasetMaintenanceRemoteRow[];\n source_urls: string[];\n completeness: DatasetMaintenanceSnapshotCompleteness<DatasetMaintenanceScanTable>;\n}> {\n const pageSize = normalizeMaintenancePageSize(options.pageSize);\n const tableResults: Array<{\n table: DatasetMaintenanceScanTable;\n rows: DatasetMaintenanceRemoteRow[];\n source_urls: string[];\n completeness: Awaited<ReturnType<typeof fetchCompletePostgrestPages>>['completeness'];\n }> = [];\n for (const table of MAINTENANCE_SCAN_TABLES) {\n const result = await fetchCompletePostgrestPages({\n table,\n requestedPageSize: pageSize,\n rowIdentity: (row: DatasetMaintenanceRemoteRow) => `${row.id}\\u0000${row.version}`,\n fetchPage: async (offset) => {\n const url = new URL(`${options.context.rest_base_url}/${table}`);\n url.searchParams.set('select', selectForTable(table));\n url.searchParams.set('user_id', `eq.${options.userId}`);\n url.searchParams.set('order', 'id.asc,version.asc');\n url.searchParams.set('limit', String(pageSize));\n url.searchParams.set('offset', String(offset));\n const sourceUrl = url.toString();\n const response = await fetchJsonResponse({\n context: options.context,\n url: sourceUrl,\n init: { headers: { Prefer: 'count=exact' } },\n label: `${table} account maintenance snapshot`,\n });\n const rows = normalizeRemoteRows(table, response.body, sourceUrl);\n if (rows.some((row) => row.user_id !== options.userId)) {\n throw new CliError(`Remote ${table} snapshot contained a foreign account row.`, {\n code: 'DATASET_MAINTENANCE_REMOTE_ROW_INVALID',\n exitCode: 1,\n });\n }\n return {\n rows,\n source_url: sourceUrl,\n content_range: response.headers.get('content-range'),\n };\n },\n });\n tableResults.push({ table, ...result });\n }\n return {\n rows: tableResults.flatMap((result) => result.rows),\n source_urls: tableResults.flatMap((result) => result.source_urls),\n completeness: buildSnapshotCompleteness({\n tables: MAINTENANCE_SCAN_TABLES,\n requestedPageSize: pageSize,\n results: tableResults,\n }),\n };\n}\n\nasync function invokeMaintenanceRpc(options: {\n context: DatasetMaintenanceRemoteContext;\n rpc:\n | 'cmd_dataset_save_draft'\n | 'cmd_dataset_delete'\n | 'cmd_dataset_alias_plan_guarded'\n | 'cmd_dataset_derivative_rebuild_snapshot'\n | 'cmd_dataset_derivative_rebuild_plan_guarded'\n | 'cmd_dataset_derivative_rebuild_read';\n body: JsonObject;\n}): Promise<JsonObject> {\n const url = `${options.context.rest_base_url}/rpc/${options.rpc}`;\n const body = await fetchJson({\n context: options.context,\n url,\n init: {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(options.body),\n },\n label: options.rpc,\n });\n if (!isJsonObject(body) || body.ok !== true) {\n throw new CliError(`${options.rpc} returned an unexpected response.`, {\n code: 'DATASET_MAINTENANCE_RPC_FAILED',\n exitCode: 1,\n details: body,\n });\n }\n return body;\n}\n\nexport async function fetchMaintenanceDerivativeSnapshot(options: {\n context: DatasetMaintenanceRemoteContext;\n id: string;\n version: string;\n}): Promise<JsonObject> {\n return invokeMaintenanceRpc({\n context: options.context,\n rpc: 'cmd_dataset_derivative_rebuild_snapshot',\n body: {\n p_table: 'processes',\n p_id: options.id,\n p_version: options.version,\n },\n });\n}\n\nexport async function applyMaintenanceDerivativeRebuild(options: {\n context: DatasetMaintenanceRemoteContext;\n plan: JsonObject;\n}): Promise<JsonObject> {\n return invokeMaintenanceRpc({\n context: options.context,\n rpc: 'cmd_dataset_derivative_rebuild_plan_guarded',\n body: { p_plan: options.plan },\n });\n}\n\nexport async function readMaintenanceDerivativeRebuild(options: {\n context: DatasetMaintenanceRemoteContext;\n requestId: string;\n}): Promise<JsonObject> {\n return invokeMaintenanceRpc({\n context: options.context,\n rpc: 'cmd_dataset_derivative_rebuild_read',\n body: { p_request_id: options.requestId },\n });\n}\n\nexport async function applyMaintenanceAliasPlan(options: {\n context: DatasetMaintenanceRemoteContext;\n plan: JsonObject;\n}): Promise<JsonObject> {\n return invokeMaintenanceRpc({\n context: options.context,\n rpc: 'cmd_dataset_alias_plan_guarded',\n body: { p_plan: options.plan },\n });\n}\n\nexport async function saveDraftMaintenanceRow(options: {\n context: DatasetMaintenanceRemoteContext;\n table: DatasetMaintenanceMutableTable;\n id: string;\n version: string;\n payload: JsonObject;\n modelId: string | null;\n ruleVerification: boolean | null;\n audit: JsonObject;\n}): Promise<JsonObject> {\n return invokeMaintenanceRpc({\n context: options.context,\n rpc: 'cmd_dataset_save_draft',\n body: {\n p_table: options.table,\n p_id: options.id,\n p_version: options.version,\n p_json_ordered: options.payload,\n p_model_id: options.modelId,\n p_rule_verification: options.ruleVerification,\n p_audit: options.audit,\n },\n });\n}\n\nexport async function deleteMaintenanceRow(options: {\n context: DatasetMaintenanceRemoteContext;\n table: DatasetMaintenanceMutableTable;\n id: string;\n version: string;\n audit: JsonObject;\n}): Promise<JsonObject> {\n return invokeMaintenanceRpc({\n context: options.context,\n rpc: 'cmd_dataset_delete',\n body: {\n p_table: options.table,\n p_id: options.id,\n p_version: options.version,\n p_audit: options.audit,\n },\n });\n}\n\nexport const __testInternals = {\n fetchJson,\n fetchJsonResponse,\n normalizeRemoteRow,\n normalizeRemoteRows,\n selectForTable,\n};\n"]}
|