@tiangong-lca/cli 0.0.33 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -13
  3. package/assets/import-smoke/simapro.csv +20 -0
  4. package/bin/tiangong-lca.js +1 -1
  5. package/dist/src/cli.js +213 -64
  6. package/dist/src/cli.js.map +1 -1
  7. package/dist/src/lib/auth-identity-receipt.js +634 -0
  8. package/dist/src/lib/auth-identity-receipt.js.map +1 -0
  9. package/dist/src/lib/dataset-bilingual.js.map +1 -1
  10. package/dist/src/lib/dataset-classification.js.map +1 -1
  11. package/dist/src/lib/dataset-contract.js.map +1 -1
  12. package/dist/src/lib/dataset-evidence-search.js.map +1 -1
  13. package/dist/src/lib/dataset-import-lca.js +302 -131
  14. package/dist/src/lib/dataset-import-lca.js.map +1 -1
  15. package/dist/src/lib/dataset-maintenance-apply.js +213 -46
  16. package/dist/src/lib/dataset-maintenance-apply.js.map +1 -1
  17. package/dist/src/lib/dataset-maintenance-clear-account.js +10 -4
  18. package/dist/src/lib/dataset-maintenance-clear-account.js.map +1 -1
  19. package/dist/src/lib/dataset-maintenance-contract.js +1 -6
  20. package/dist/src/lib/dataset-maintenance-contract.js.map +1 -1
  21. package/dist/src/lib/dataset-maintenance-derivatives.js +0 -1
  22. package/dist/src/lib/dataset-maintenance-derivatives.js.map +1 -1
  23. package/dist/src/lib/dataset-maintenance-flow-identity-capture.js +1 -0
  24. package/dist/src/lib/dataset-maintenance-flow-identity-capture.js.map +1 -1
  25. package/dist/src/lib/dataset-maintenance-pagination.js.map +1 -1
  26. package/dist/src/lib/dataset-maintenance-protected-before.js.map +1 -1
  27. package/dist/src/lib/dataset-maintenance-protected-contract.js +0 -1
  28. package/dist/src/lib/dataset-maintenance-protected-contract.js.map +1 -1
  29. package/dist/src/lib/dataset-maintenance-protected-freeze.js.map +1 -1
  30. package/dist/src/lib/dataset-maintenance-protected-preparation.js +0 -2
  31. package/dist/src/lib/dataset-maintenance-protected-preparation.js.map +1 -1
  32. package/dist/src/lib/dataset-maintenance-protected-seal.js.map +1 -1
  33. package/dist/src/lib/dataset-maintenance-protected-verify.js +0 -3
  34. package/dist/src/lib/dataset-maintenance-protected-verify.js.map +1 -1
  35. package/dist/src/lib/dataset-maintenance-remote.js +36 -14
  36. package/dist/src/lib/dataset-maintenance-remote.js.map +1 -1
  37. package/dist/src/lib/dataset-maintenance-verify.js +1 -2
  38. package/dist/src/lib/dataset-maintenance-verify.js.map +1 -1
  39. package/dist/src/lib/dataset-remote-refresh.js.map +1 -1
  40. package/dist/src/lib/dataset-remote-verify.js +2 -0
  41. package/dist/src/lib/dataset-remote-verify.js.map +1 -1
  42. package/dist/src/lib/dataset-save-draft-run.js +2 -0
  43. package/dist/src/lib/dataset-save-draft-run.js.map +1 -1
  44. package/dist/src/lib/flow-build-alias-map.js.map +1 -1
  45. package/dist/src/lib/flow-fetch-rows.js.map +1 -1
  46. package/dist/src/lib/flow-get.js.map +1 -1
  47. package/dist/src/lib/flow-governance.js.map +1 -1
  48. package/dist/src/lib/flow-list.js +1 -0
  49. package/dist/src/lib/flow-list.js.map +1 -1
  50. package/dist/src/lib/flow-payload-validation.js.map +1 -1
  51. package/dist/src/lib/flow-publish-version.js +1 -0
  52. package/dist/src/lib/flow-publish-version.js.map +1 -1
  53. package/dist/src/lib/flow-read.js +1 -0
  54. package/dist/src/lib/flow-read.js.map +1 -1
  55. package/dist/src/lib/flow-regen-product.js.map +1 -1
  56. package/dist/src/lib/flow-remediate.js.map +1 -1
  57. package/dist/src/lib/http.js.map +1 -1
  58. package/dist/src/lib/identity-preflight.js +4 -10
  59. package/dist/src/lib/identity-preflight.js.map +1 -1
  60. package/dist/src/lib/lifecyclemodel-bundle-save.js +1 -0
  61. package/dist/src/lib/lifecyclemodel-bundle-save.js.map +1 -1
  62. package/dist/src/lib/lifecyclemodel-orchestrate.js.map +1 -1
  63. package/dist/src/lib/lifecyclemodel-publish-resulting-process.js.map +1 -1
  64. package/dist/src/lib/lifecyclemodel-resulting-process.js.map +1 -1
  65. package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -1
  66. package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
  67. package/dist/src/lib/package-version.js.map +1 -1
  68. package/dist/src/lib/process-auto-build.js.map +1 -1
  69. package/dist/src/lib/process-dedup-review.js +14 -7
  70. package/dist/src/lib/process-dedup-review.js.map +1 -1
  71. package/dist/src/lib/process-flow-build-plan.js +111 -30
  72. package/dist/src/lib/process-flow-build-plan.js.map +1 -1
  73. package/dist/src/lib/process-get.js +1 -0
  74. package/dist/src/lib/process-get.js.map +1 -1
  75. package/dist/src/lib/process-list.js +1 -0
  76. package/dist/src/lib/process-list.js.map +1 -1
  77. package/dist/src/lib/process-payload-validation.js.map +1 -1
  78. package/dist/src/lib/process-qa.js.map +1 -1
  79. package/dist/src/lib/process-refresh-references.js +15 -10
  80. package/dist/src/lib/process-refresh-references.js.map +1 -1
  81. package/dist/src/lib/process-save-draft.js +9 -3
  82. package/dist/src/lib/process-save-draft.js.map +1 -1
  83. package/dist/src/lib/process-scope-statistics.js +11 -4
  84. package/dist/src/lib/process-scope-statistics.js.map +1 -1
  85. package/dist/src/lib/process-verify-rows.js.map +1 -1
  86. package/dist/src/lib/publish.js.map +1 -1
  87. package/dist/src/lib/run.js.map +1 -1
  88. package/dist/src/lib/supabase-client.js +13 -1
  89. package/dist/src/lib/supabase-client.js.map +1 -1
  90. package/dist/src/lib/supabase-data-api-contract.js +328 -0
  91. package/dist/src/lib/supabase-data-api-contract.js.map +1 -0
  92. package/dist/src/lib/supabase-data-api-replay.js +69 -0
  93. package/dist/src/lib/supabase-data-api-replay.js.map +1 -0
  94. package/dist/src/lib/supabase-json-ordered-write.js +2 -0
  95. package/dist/src/lib/supabase-json-ordered-write.js.map +1 -1
  96. package/dist/src/lib/supabase-rest.js +1 -0
  97. package/dist/src/lib/supabase-rest.js.map +1 -1
  98. package/dist/src/lib/tidas-sdk-package-validator.js +5 -5
  99. package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
  100. package/dist/src/lib/validation.js.map +1 -1
  101. package/dist/src/main.js.map +1 -1
  102. package/package.json +43 -40
  103. package/dist/scripts/assert-full-coverage.js +0 -77
  104. package/dist/scripts/assert-full-coverage.js.map +0 -1
@@ -1,9 +1,11 @@
1
+ // data-api-relations: lifecyclemodels, processes
1
2
  import path from 'node:path';
2
3
  import { writeJsonArtifact } from './artifacts.js';
3
4
  import { CliError } from './errors.js';
4
5
  import { readJsonInput } from './io.js';
5
6
  import { getRuntimeRuleset, resolveRuntimeRuleId } from './runtime-rulesets.js';
6
- import { deriveSupabaseProjectBaseUrl, requireSupabaseRestRuntime } from './supabase-client.js';
7
+ import { deriveSupabaseProjectBaseUrl, deriveSupabaseRestBaseUrl, requireSupabaseRestRuntime, } from './supabase-client.js';
8
+ import { applyDataApiProfileHeaders, buildDataApiUrl, resolveDataApiCapability, } from './supabase-data-api-contract.js';
7
9
  import { resolveSupabaseUserSession } from './supabase-session.js';
8
10
  const DEFAULT_TIMEOUT_MS = 30_000;
9
11
  const DEFAULT_MAX_RETRIES = 4;
@@ -364,7 +366,8 @@ async function fetchRemoteMetadata(options) {
364
366
  if (options.processIds.length === 0) {
365
367
  return {};
366
368
  }
367
- const url = new URL(`${options.auth.projectBaseUrl}/rest/v1/processes`);
369
+ const capability = resolveDataApiCapability({ kind: 'relation', name: 'processes' });
370
+ const url = new URL(buildDataApiUrl(deriveSupabaseRestBaseUrl(options.auth.projectBaseUrl), capability));
368
371
  url.searchParams.set('select', 'id,version,state_code,created_at,modified_at,user_id,team_id,model_id,json');
369
372
  url.searchParams.set('id', `in.(${options.processIds.join(',')})`);
370
373
  url.searchParams.set('order', 'id.asc');
@@ -372,11 +375,11 @@ async function fetchRemoteMetadata(options) {
372
375
  url: url.toString(),
373
376
  init: {
374
377
  method: 'GET',
375
- headers: {
378
+ headers: applyDataApiProfileHeaders({
376
379
  apikey: options.auth.publishableKey,
377
380
  Authorization: `Bearer ${options.auth.accessToken}`,
378
381
  Accept: 'application/json',
379
- },
382
+ }, capability),
380
383
  },
381
384
  label: 'process dedup remote metadata fetch',
382
385
  fetchImpl: options.fetchImpl,
@@ -423,7 +426,11 @@ async function fetchCurrentUserRows(options) {
423
426
  let offset = 0;
424
427
  let total = null;
425
428
  while (total === null || offset < total) {
426
- const url = new URL(`${options.auth.projectBaseUrl}/rest/v1/${options.tableName}`);
429
+ const capability = resolveDataApiCapability({
430
+ kind: 'relation',
431
+ name: options.tableName,
432
+ });
433
+ const url = new URL(buildDataApiUrl(deriveSupabaseRestBaseUrl(options.auth.projectBaseUrl), capability));
427
434
  url.searchParams.set('select', options.select);
428
435
  url.searchParams.set('user_id', `eq.${options.userId}`);
429
436
  url.searchParams.set('order', 'id.asc');
@@ -433,12 +440,12 @@ async function fetchCurrentUserRows(options) {
433
440
  url: url.toString(),
434
441
  init: {
435
442
  method: 'GET',
436
- headers: {
443
+ headers: applyDataApiProfileHeaders({
437
444
  apikey: options.auth.publishableKey,
438
445
  Authorization: `Bearer ${options.auth.accessToken}`,
439
446
  Accept: 'application/json',
440
447
  Prefer: total === null ? 'count=exact' : 'count=planned',
441
- },
448
+ }, capability),
442
449
  },
443
450
  label: `${options.tableName} current-user reference scan`,
444
451
  fetchImpl: options.fetchImpl,
@@ -1 +1 @@
1
- {"version":3,"file":"process-dedup-review.js","sourceRoot":"","sources":["../../../src/lib/process-dedup-review.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { writeJsonArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike, ResponseLike } from './http.js';\nimport { readJsonInput } from './io.js';\nimport { getRuntimeRuleset, resolveRuntimeRuleId } from './runtime-rulesets.js';\nimport { deriveSupabaseProjectBaseUrl, requireSupabaseRestRuntime } from './supabase-client.js';\nimport { resolveSupabaseUserSession } from './supabase-session.js';\n\ntype JsonRecord = Record<string, unknown>;\ntype ProcessGroupId = string | number;\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_RETRIES = 4;\nconst DEFAULT_PAGE_SIZE = 100;\n\ntype ExchangeSummaryRow = {\n exchange_internal_id: string;\n flow_id: string;\n flow_version: string;\n direction: string;\n mean_amount: string;\n resulting_amount: string;\n flow_short_description_en: string;\n flow_short_description_zh: string;\n};\n\ntype DedupInputProcess = {\n process_id: string;\n version: string;\n name_en: string;\n name_zh: string;\n exchange_count: number | null;\n overview_fingerprint: string;\n sheet_exchange_rows: ExchangeSummaryRow[];\n};\n\ntype DedupInputGroup = {\n group_id: ProcessGroupId;\n processes: DedupInputProcess[];\n};\n\ntype RemoteMetadataRecord = {\n process_id: string;\n version: string;\n state_code: number | null;\n created_at: string | null;\n modified_at: string | null;\n user_id: string | null;\n team_id: string | null;\n model_id: string | null;\n remote_name_en: string;\n remote_name_zh: string;\n remote_exchanges: ExchangeSummaryRow[];\n};\n\ntype ReferenceHitRecord = {\n id: string;\n version: string;\n state_code: number | null;\n model_id?: string | null;\n};\n\ntype ReferenceHits = {\n processes: Record<string, ReferenceHitRecord[]>;\n lifecyclemodels: Record<string, ReferenceHitRecord[]>;\n};\n\ntype RemoteStatus = {\n enabled: boolean;\n loaded: number;\n error: string | null;\n reference_scan:\n | 'not_run'\n | 'skipped_by_flag'\n | 'skipped_missing_user_id'\n | 'current_user_completed'\n | 'failed';\n};\n\ntype ProcessDedupGate = {\n status: 'passed' | 'blocked';\n ruleset_id: 'process-dedup/default';\n ruleset_version: '1';\n ruleset_source_version: string;\n ruleset_rule_ids: string[];\n counts: {\n duplicate_groups: number;\n blocker_groups: number;\n };\n blockers: Array<{\n group_id: ProcessGroupId;\n code: 'process_exact_duplicate_fingerprint';\n methodology_rule_id: string | null;\n severity: 'blocker';\n message: string;\n }>;\n next_action: 'continue' | 'resolve_duplicate_processes';\n};\n\ntype DedupAnalyzedProcess = DedupInputProcess &\n Partial<RemoteMetadataRecord> & {\n analysis_exchanges: ExchangeSummaryRow[];\n normalized_exchange_signature: Array<[string, string, string, string]>;\n name_score: number;\n name_score_reasons: string[];\n };\n\nexport type ProcessDedupReviewGroup = {\n group_id: ProcessGroupId;\n group_pattern: string;\n exact_duplicate: boolean;\n rule_id?: 'process_exact_duplicate_fingerprint';\n methodology_rule_id?: string | null;\n severity?: 'blocker';\n blocker?: boolean;\n processes: DedupAnalyzedProcess[];\n};\n\ntype DeletePlanGroup = {\n group_id: ProcessGroupId;\n status: 'priority_delete_candidates';\n confidence: 'high' | 'medium' | 'low';\n current_user_reference_hits: {\n keep_process_refs: number;\n keep_lifecyclemodel_refs: number;\n delete_refs: Record<\n string,\n {\n process_refs: number;\n lifecyclemodel_refs: number;\n }\n >;\n };\n keep: {\n process_id: string;\n name_en: string;\n name_zh: string;\n score: number;\n reasons: string[];\n };\n delete: Array<{\n process_id: string;\n name_en: string;\n name_zh: string;\n score: number;\n reasons: string[];\n }>;\n notes: string[];\n};\n\ntype RemoteAuthContext = {\n projectBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n userId: string | null;\n};\n\nexport type RunProcessDedupReviewOptions = {\n inputPath: string;\n outDir: string;\n skipRemote?: boolean;\n env?: NodeJS.ProcessEnv;\n fetchImpl?: FetchLike;\n timeoutMs?: number;\n maxRetries?: number;\n now?: Date;\n};\n\nexport type ProcessDedupReviewReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'completed_process_dedup_review';\n input_file: string;\n out_dir: string;\n source_label: string;\n group_count: number;\n exact_duplicate_group_count: number;\n ruleset_id?: 'process-dedup/default';\n ruleset_version?: '1';\n ruleset_source_version?: string;\n ruleset_rule_ids?: string[];\n gate?: ProcessDedupGate;\n remote_status: RemoteStatus;\n files: {\n input_manifest: string;\n remote_metadata: string | null;\n duplicate_groups: string;\n delete_plan: string;\n current_user_reference_scan: string | null;\n };\n};\n\nfunction isRecord(value: unknown): value is JsonRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction trimText(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction nowIso(now: Date = new Date()): string {\n return now.toISOString();\n}\n\nfunction requiredNonEmpty(value: string, label: string, code: string): string {\n const normalized = value.trim();\n if (!normalized) {\n throw new CliError(`Missing required ${label}.`, {\n code,\n exitCode: 2,\n });\n }\n return normalized;\n}\n\nfunction toPositiveInteger(value: number | undefined, label: string, code: string): number {\n if (!Number.isInteger(value) || (value as number) <= 0) {\n throw new CliError(`Expected ${label} to be a positive integer.`, {\n code,\n exitCode: 2,\n });\n }\n return value as number;\n}\n\nfunction normalizeOptionalToken(value: unknown): string | null {\n const normalized = trimText(value);\n return normalized ? normalized : null;\n}\n\nfunction asArray(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value;\n }\n if (value === null || value === undefined || value === '') {\n return [];\n }\n return [value];\n}\n\nfunction toGroupId(value: unknown, fallback: string): ProcessGroupId {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n const normalized = trimText(value);\n if (!normalized) {\n return fallback;\n }\n if (/^\\d+$/u.test(normalized)) {\n return Number.parseInt(normalized, 10);\n }\n return normalized;\n}\n\nfunction normalizeExchangeCount(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n const normalized = trimText(value);\n if (!normalized) {\n return null;\n }\n const parsed = Number.parseInt(normalized, 10);\n return Number.isInteger(parsed) ? parsed : null;\n}\n\nfunction normalizeAmount(value: unknown): string {\n const normalized = trimText(value);\n if (!normalized) {\n return '';\n }\n if (/^[+-]?\\d+(?:\\.\\d+)?$/u.test(normalized)) {\n let result = normalized.replace(/^\\+/u, '');\n result = result.replace(/^(-?)0+(?=\\d)/u, '$1');\n if (result.includes('.')) {\n result = result.replace(/0+$/u, '').replace(/\\.$/u, '');\n }\n if (result === '' || result === '-' || result === '-0') {\n return '0';\n }\n return result;\n }\n const parsed = Number(normalized);\n if (Number.isFinite(parsed)) {\n return parsed.toString();\n }\n return normalized;\n}\n\nfunction getLangList(value: unknown): JsonRecord[] {\n if (value === null || value === undefined || value === '') {\n return [];\n }\n if (Array.isArray(value)) {\n return value.filter((entry): entry is JsonRecord => isRecord(entry));\n }\n if (isRecord(value)) {\n const langString = value['common:langString'];\n if (Array.isArray(langString)) {\n return langString.filter((entry): entry is JsonRecord => isRecord(entry));\n }\n if (isRecord(langString)) {\n return [langString];\n }\n if (value['#text'] !== undefined || value['@xml:lang'] !== undefined) {\n return [value];\n }\n }\n if (typeof value === 'string') {\n return [{ '@xml:lang': 'en', '#text': value }];\n }\n return [];\n}\n\nfunction getLangText(value: unknown, lang: string): string {\n const entries = getLangList(value);\n for (const entry of entries) {\n if (\n trimText(entry['@xml:lang']).toLowerCase() === lang.toLowerCase() &&\n trimText(entry['#text'])\n ) {\n return trimText(entry['#text']);\n }\n }\n for (const entry of entries) {\n if (trimText(entry['#text'])) {\n return trimText(entry['#text']);\n }\n }\n return '';\n}\n\nfunction normalizeExchangeSummaryRow(value: unknown): ExchangeSummaryRow | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const flowRef = isRecord(value.referenceToFlowDataSet) ? value.referenceToFlowDataSet : {};\n const flowShortDescription = value.flow_short_description ?? flowRef['common:shortDescription'];\n\n const normalized: ExchangeSummaryRow = {\n exchange_internal_id: trimText(value.exchange_internal_id ?? value['@dataSetInternalID']),\n flow_id: trimText(value.flow_id ?? flowRef['@refObjectId']),\n flow_version: trimText(value.flow_version ?? flowRef['@version']),\n direction: trimText(value.direction ?? value.exchangeDirection),\n mean_amount: trimText(value.mean_amount ?? value.meanAmount),\n resulting_amount: trimText(value.resulting_amount ?? value.resultingAmount),\n flow_short_description_en:\n trimText(value.flow_short_description_en) || getLangText(flowShortDescription, 'en'),\n flow_short_description_zh:\n trimText(value.flow_short_description_zh) || getLangText(flowShortDescription, 'zh'),\n };\n\n if (\n !normalized.exchange_internal_id &&\n !normalized.flow_id &&\n !normalized.direction &&\n !normalized.mean_amount &&\n !normalized.resulting_amount\n ) {\n return null;\n }\n\n return normalized;\n}\n\nfunction normalizeExchangeRows(value: unknown): ExchangeSummaryRow[] {\n return asArray(value)\n .map((entry) => normalizeExchangeSummaryRow(entry))\n .filter((entry): entry is ExchangeSummaryRow => entry !== null);\n}\n\nfunction normalizeInputProcess(value: unknown): DedupInputProcess {\n if (!isRecord(value)) {\n throw new CliError('Each process dedup candidate must be a JSON object.', {\n code: 'PROCESS_DEDUP_INPUT_INVALID_PROCESS',\n exitCode: 2,\n });\n }\n\n const processId = requiredNonEmpty(\n trimText(value.process_id ?? value.id),\n 'process_id',\n 'PROCESS_DEDUP_PROCESS_ID_REQUIRED',\n );\n\n return {\n process_id: processId,\n version: trimText(value.version),\n name_en: trimText(value.name_en ?? value.remote_name_en),\n name_zh: trimText(value.name_zh ?? value.remote_name_zh),\n exchange_count: normalizeExchangeCount(value.exchange_count),\n overview_fingerprint: trimText(value.overview_fingerprint),\n sheet_exchange_rows: normalizeExchangeRows(\n value.sheet_exchange_rows ??\n value.analysis_exchanges ??\n value.remote_exchanges ??\n value.exchanges,\n ),\n };\n}\n\nfunction normalizeInputGroup(\n value: unknown,\n fallbackGroupId: string,\n index: number,\n): DedupInputGroup {\n if (!isRecord(value)) {\n throw new CliError('Each process dedup group must be a JSON object.', {\n code: 'PROCESS_DEDUP_INPUT_INVALID_GROUP',\n exitCode: 2,\n });\n }\n\n const processes = asArray(value.processes).map((entry) => normalizeInputProcess(entry));\n if (processes.length === 0) {\n throw new CliError(`Process dedup group ${index + 1} is missing processes.`, {\n code: 'PROCESS_DEDUP_GROUP_PROCESSES_REQUIRED',\n exitCode: 2,\n });\n }\n\n return {\n group_id: toGroupId(value.group_id, fallbackGroupId),\n processes,\n };\n}\n\nfunction normalizeInputDocument(\n value: unknown,\n resolvedInputPath: string,\n): {\n sourceLabel: string;\n groups: DedupInputGroup[];\n} {\n if (!isRecord(value)) {\n throw new CliError('Process dedup review input must be a JSON object.', {\n code: 'PROCESS_DEDUP_INPUT_INVALID',\n exitCode: 2,\n });\n }\n\n const sourceLabel =\n trimText(value.source_label ?? value.source_workbook ?? value.source_file) ||\n path.basename(resolvedInputPath);\n const rawGroups = value.groups;\n let groups: DedupInputGroup[] = [];\n\n if (Array.isArray(rawGroups)) {\n groups = rawGroups.map((entry, index) => normalizeInputGroup(entry, String(index + 1), index));\n } else if (isRecord(rawGroups)) {\n groups = Object.entries(rawGroups).map(([groupId, entry], index) =>\n normalizeInputGroup(entry, groupId, index),\n );\n }\n\n if (groups.length === 0) {\n throw new CliError('Process dedup review input must contain at least one group.', {\n code: 'PROCESS_DEDUP_GROUPS_REQUIRED',\n exitCode: 2,\n });\n }\n\n return {\n sourceLabel,\n groups,\n };\n}\n\nasync function parseJsonResponse(response: ResponseLike, label: string): Promise<unknown> {\n const text = await response.text();\n const contentType = response.headers.get('content-type') ?? '';\n if (!text.trim()) {\n return null;\n }\n if (!contentType.includes('application/json')) {\n return text;\n }\n try {\n return JSON.parse(text);\n } catch (error) {\n throw new CliError(`${label} returned invalid JSON.`, {\n code: 'PROCESS_DEDUP_REMOTE_INVALID_JSON',\n exitCode: 1,\n details: String(error),\n });\n }\n}\n\nasync function fetchJsonWithRetry(options: {\n url: string;\n init: RequestInit;\n label: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<{ status: number; headers: Headers; body: unknown }> {\n let lastError: unknown = null;\n\n for (let attempt = 1; attempt <= options.maxRetries; attempt += 1) {\n try {\n const response = await options.fetchImpl(options.url, {\n ...options.init,\n signal: AbortSignal.timeout(options.timeoutMs),\n });\n const body = await parseJsonResponse(response, options.label);\n if (!response.ok) {\n throw new CliError(`${options.label} failed with ${response.status}.`, {\n code: 'PROCESS_DEDUP_REMOTE_REQUEST_FAILED',\n exitCode: 1,\n details: {\n status: response.status,\n body,\n url: options.url,\n },\n });\n }\n return {\n status: response.status,\n headers: new Headers({\n 'content-range': response.headers.get('content-range') ?? '',\n 'content-type': response.headers.get('content-type') ?? '',\n }),\n body,\n };\n } catch (error) {\n lastError = error;\n if (attempt >= options.maxRetries) {\n break;\n }\n await new Promise((resolve) => setTimeout(resolve, attempt * 1_500));\n }\n }\n\n if (lastError instanceof CliError) {\n throw lastError;\n }\n\n throw new CliError(`${options.label} failed after ${options.maxRetries} attempt(s).`, {\n code: 'PROCESS_DEDUP_REMOTE_REQUEST_FAILED',\n exitCode: 1,\n details: String(lastError),\n });\n}\n\nasync function fetchCurrentUserId(options: {\n projectBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<string | null> {\n const response = await fetchJsonWithRetry({\n url: `${options.projectBaseUrl}/auth/v1/user`,\n init: {\n method: 'GET',\n headers: {\n apikey: options.publishableKey,\n Authorization: `Bearer ${options.accessToken}`,\n Accept: 'application/json',\n },\n },\n label: 'supabase current-user lookup',\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n if (!isRecord(response.body)) {\n return null;\n }\n return normalizeOptionalToken(response.body.id);\n}\n\nasync function resolveRemoteAuthContext(options: {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n now: Date;\n}): Promise<RemoteAuthContext> {\n const runtime = requireSupabaseRestRuntime(options.env);\n const session = await resolveSupabaseUserSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n });\n const projectBaseUrl = deriveSupabaseProjectBaseUrl(runtime.apiBaseUrl);\n\n let userId: string | null;\n try {\n userId = await fetchCurrentUserId({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n } catch {\n userId = null;\n }\n\n return {\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n userId,\n };\n}\n\nfunction summarizeRemoteExchanges(processJson: unknown): ExchangeSummaryRow[] {\n if (!isRecord(processJson)) {\n return [];\n }\n const processDataSet = isRecord(processJson.processDataSet) ? processJson.processDataSet : {};\n const exchanges = isRecord(processDataSet.exchanges) ? processDataSet.exchanges.exchange : [];\n return normalizeExchangeRows(exchanges);\n}\n\nasync function fetchRemoteMetadata(options: {\n processIds: string[];\n auth: RemoteAuthContext;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<Record<string, RemoteMetadataRecord>> {\n if (options.processIds.length === 0) {\n return {};\n }\n\n const url = new URL(`${options.auth.projectBaseUrl}/rest/v1/processes`);\n url.searchParams.set(\n 'select',\n 'id,version,state_code,created_at,modified_at,user_id,team_id,model_id,json',\n );\n url.searchParams.set('id', `in.(${options.processIds.join(',')})`);\n url.searchParams.set('order', 'id.asc');\n\n const response = await fetchJsonWithRetry({\n url: url.toString(),\n init: {\n method: 'GET',\n headers: {\n apikey: options.auth.publishableKey,\n Authorization: `Bearer ${options.auth.accessToken}`,\n Accept: 'application/json',\n },\n },\n label: 'process dedup remote metadata fetch',\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n const rows = Array.isArray(response.body) ? response.body : [];\n const byId: Record<string, RemoteMetadataRecord> = {};\n\n for (const row of rows) {\n if (!isRecord(row)) {\n continue;\n }\n const processId = trimText(row.id);\n if (!processId) {\n continue;\n }\n const payload = row.json;\n const processDataSet =\n isRecord(payload) && isRecord(payload.processDataSet) ? payload.processDataSet : {};\n const processInformation = isRecord(processDataSet.processInformation)\n ? processDataSet.processInformation\n : {};\n const dataSetInformation = isRecord(processInformation.dataSetInformation)\n ? processInformation.dataSetInformation\n : {};\n const name = isRecord(dataSetInformation.name) ? dataSetInformation.name : {};\n\n byId[processId] = {\n process_id: processId,\n version: trimText(row.version),\n state_code: typeof row.state_code === 'number' ? row.state_code : null,\n created_at: normalizeOptionalToken(row.created_at),\n modified_at: normalizeOptionalToken(row.modified_at),\n user_id: normalizeOptionalToken(row.user_id),\n team_id: normalizeOptionalToken(row.team_id),\n model_id: normalizeOptionalToken(row.model_id),\n remote_name_en: getLangText(name.baseName, 'en'),\n remote_name_zh: getLangText(name.baseName, 'zh'),\n remote_exchanges: summarizeRemoteExchanges(payload),\n };\n }\n\n return byId;\n}\n\nasync function fetchCurrentUserRows(options: {\n auth: RemoteAuthContext;\n tableName: 'processes' | 'lifecyclemodels';\n userId: string;\n select: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<unknown[]> {\n const rows: unknown[] = [];\n let offset = 0;\n let total: number | null = null;\n\n while (total === null || offset < total) {\n const url = new URL(`${options.auth.projectBaseUrl}/rest/v1/${options.tableName}`);\n url.searchParams.set('select', options.select);\n url.searchParams.set('user_id', `eq.${options.userId}`);\n url.searchParams.set('order', 'id.asc');\n url.searchParams.set('limit', String(DEFAULT_PAGE_SIZE));\n url.searchParams.set('offset', String(offset));\n\n const page = await fetchJsonWithRetry({\n url: url.toString(),\n init: {\n method: 'GET',\n headers: {\n apikey: options.auth.publishableKey,\n Authorization: `Bearer ${options.auth.accessToken}`,\n Accept: 'application/json',\n Prefer: total === null ? 'count=exact' : 'count=planned',\n },\n },\n label: `${options.tableName} current-user reference scan`,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n const pageRows = Array.isArray(page.body) ? page.body : [];\n rows.push(...pageRows);\n\n if (total === null) {\n const contentRange = page.headers.get('content-range');\n const match = contentRange ? contentRange.match(/\\/(\\d+)$/u) : null;\n total = match ? Number.parseInt(match[1], 10) : rows.length;\n }\n\n if (pageRows.length === 0) {\n break;\n }\n offset += DEFAULT_PAGE_SIZE;\n }\n\n return rows;\n}\n\nfunction collectReferenceHits(root: unknown, targetIds: Set<string>): string[] {\n const hits: string[] = [];\n const visited = new Set<object>();\n\n const walk = (value: unknown): void => {\n if (value === null || value === undefined) {\n return;\n }\n\n if (Array.isArray(value)) {\n if (visited.has(value)) {\n return;\n }\n visited.add(value);\n value.forEach((entry) => walk(entry));\n return;\n }\n\n if (!isRecord(value)) {\n return;\n }\n\n if (visited.has(value)) {\n return;\n }\n visited.add(value);\n\n const refObjectId = trimText(value['@refObjectId']);\n if (refObjectId && targetIds.has(refObjectId)) {\n hits.push(refObjectId);\n }\n\n Object.values(value).forEach((entry) => walk(entry));\n };\n\n walk(root);\n return hits;\n}\n\nfunction buildEmptyReferenceHits(processIds: string[]): ReferenceHits {\n return {\n processes: Object.fromEntries(processIds.map((processId) => [processId, []])),\n lifecyclemodels: Object.fromEntries(processIds.map((processId) => [processId, []])),\n };\n}\n\nasync function fetchCurrentUserReferenceHits(options: {\n auth: RemoteAuthContext;\n userId: string;\n targetProcessIds: string[];\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<ReferenceHits> {\n const targetIds = new Set(options.targetProcessIds);\n const results = buildEmptyReferenceHits(options.targetProcessIds);\n\n const processRows = await fetchCurrentUserRows({\n auth: options.auth,\n tableName: 'processes',\n userId: options.userId,\n select: 'id,version,state_code,user_id,model_id,json',\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n for (const row of processRows) {\n if (!isRecord(row)) {\n continue;\n }\n const rowId = trimText(row.id);\n const hits = collectReferenceHits(row.json, targetIds);\n for (const hit of hits) {\n if (rowId === hit) {\n continue;\n }\n results.processes[hit]?.push({\n id: rowId,\n version: trimText(row.version),\n state_code: typeof row.state_code === 'number' ? row.state_code : null,\n model_id: normalizeOptionalToken(row.model_id),\n });\n }\n }\n\n const lifecyclemodelRows = await fetchCurrentUserRows({\n auth: options.auth,\n tableName: 'lifecyclemodels',\n userId: options.userId,\n select: 'id,version,state_code,user_id,json',\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n for (const row of lifecyclemodelRows) {\n if (!isRecord(row)) {\n continue;\n }\n const hits = collectReferenceHits(row.json, targetIds);\n for (const hit of hits) {\n results.lifecyclemodels[hit]?.push({\n id: trimText(row.id),\n version: trimText(row.version),\n state_code: typeof row.state_code === 'number' ? row.state_code : null,\n });\n }\n }\n\n return results;\n}\n\nfunction normalizedSignature(\n exchanges: ExchangeSummaryRow[],\n): Array<[string, string, string, string]> {\n return [...exchanges]\n .map(\n (exchange) =>\n [\n trimText(exchange.flow_id),\n trimText(exchange.direction),\n normalizeAmount(exchange.mean_amount),\n normalizeAmount(exchange.resulting_amount),\n ] as [string, string, string, string],\n )\n .sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));\n}\n\nfunction normalizedSignatureKey(exchanges: ExchangeSummaryRow[]): string {\n return JSON.stringify(normalizedSignature(exchanges));\n}\n\nfunction detectGroupPattern(processes: DedupAnalyzedProcess[]): string {\n const sample = processes.find(\n (process) => process.analysis_exchanges.length > 0,\n )?.analysis_exchanges;\n if (!sample || sample.length === 0) {\n return 'unknown';\n }\n\n const inputExchanges = sample.filter(\n (exchange) => trimText(exchange.direction).toLowerCase() === 'input',\n );\n const outputExchanges = sample.filter(\n (exchange) => trimText(exchange.direction).toLowerCase() === 'output',\n );\n const inputFlowIds = new Set(\n inputExchanges.map((exchange) => trimText(exchange.flow_id)).filter(Boolean),\n );\n const outputFlowIds = new Set(\n outputExchanges.map((exchange) => trimText(exchange.flow_id)).filter(Boolean),\n );\n\n const hasTransportInput = inputExchanges.some((exchange) => {\n const en = trimText(exchange.flow_short_description_en).toLowerCase();\n const zh = trimText(exchange.flow_short_description_zh);\n return en.includes('transport;') || zh.includes('运输;');\n });\n\n if (outputFlowIds.size > 0 && [...outputFlowIds].every((flowId) => inputFlowIds.has(flowId))) {\n return hasTransportInput ? 'transport_pass_through' : 'same_flow_pass_through';\n }\n return 'other';\n}\n\nfunction scoreProcessName(\n process: Pick<DedupAnalyzedProcess, 'name_en' | 'name_zh' | 'remote_name_en' | 'remote_name_zh'>,\n groupPattern: string,\n): { score: number; reasons: string[] } {\n const nameEn = trimText(process.remote_name_en ?? process.name_en);\n const nameZh = trimText(process.remote_name_zh ?? process.name_zh);\n const lowerEn = nameEn.toLowerCase();\n const reasons: string[] = [];\n let score = 0;\n\n if (groupPattern === 'transport_pass_through') {\n if (lowerEn.includes('transport') || nameZh.includes('运输')) {\n score += 30;\n reasons.push('name matches explicit transport-service input');\n }\n if (lowerEn.includes('logistics') || nameZh.includes('物流')) {\n score -= 10;\n reasons.push('name is broader than the observed transport-service input');\n }\n }\n\n if (groupPattern === 'same_flow_pass_through') {\n if (lowerEn.includes('processing') || nameZh.includes('加工')) {\n score -= 20;\n reasons.push('same-flow pass-through does not support a processing label');\n }\n if (lowerEn.includes('reception') || nameZh.includes('接收')) {\n score += 20;\n reasons.push('reception matches same-flow intake/output handling');\n }\n }\n\n if (lowerEn.includes('collection') || nameZh.includes('收集')) {\n score += 20;\n reasons.push('collection is semantically consistent with a gather/sort process');\n }\n if (lowerEn.includes('wastepaper')) {\n score -= 5;\n reasons.push(\"compressed English form is less standardized than 'waste paper'\");\n }\n if (lowerEn.includes('waste paper')) {\n score += 3;\n reasons.push('English wording is standardized');\n }\n if (nameEn.includes('/') || nameZh.includes('/')) {\n score += 5;\n reasons.push('name keeps the broader material scope explicit');\n }\n\n return { score, reasons };\n}\n\nfunction createdAtKey(process: Pick<DedupAnalyzedProcess, 'created_at'>): string {\n return trimText(process.created_at) || '9999-12-31T23:59:59+00:00';\n}\n\nfunction compareGroupIds(left: ProcessGroupId, right: ProcessGroupId): number {\n return String(left).localeCompare(String(right), 'en', { numeric: true });\n}\n\nfunction analyzeGroups(\n groups: DedupInputGroup[],\n remoteById: Record<string, RemoteMetadataRecord>,\n referenceHits: ReferenceHits,\n): {\n duplicateGroups: ProcessDedupReviewGroup[];\n deletePlanGroups: DeletePlanGroup[];\n} {\n const duplicateGroups: ProcessDedupReviewGroup[] = [];\n const deletePlanGroups: DeletePlanGroup[] = [];\n\n for (const group of [...groups].sort((left, right) =>\n compareGroupIds(left.group_id, right.group_id),\n )) {\n const processes: DedupAnalyzedProcess[] = group.processes.map((process) => {\n const remote = remoteById[process.process_id];\n const analysisExchanges =\n remote && remote.remote_exchanges.length > 0\n ? remote.remote_exchanges\n : process.sheet_exchange_rows;\n const initialScore = scoreProcessName(\n {\n name_en: process.name_en,\n name_zh: process.name_zh,\n remote_name_en: remote?.remote_name_en,\n remote_name_zh: remote?.remote_name_zh,\n },\n 'unknown',\n );\n\n return {\n ...process,\n ...remote,\n analysis_exchanges: analysisExchanges,\n normalized_exchange_signature: normalizedSignature(analysisExchanges),\n name_score: initialScore.score,\n name_score_reasons: initialScore.reasons,\n };\n });\n\n const exactDuplicate =\n processes.length > 1 &&\n new Set(processes.map((process) => normalizedSignatureKey(process.analysis_exchanges)))\n .size === 1;\n const groupPattern = detectGroupPattern(processes);\n\n for (const process of processes) {\n const rescored = scoreProcessName(process, groupPattern);\n process.name_score = rescored.score;\n process.name_score_reasons = rescored.reasons;\n }\n\n const sortedProcesses = [...processes].sort(\n (left, right) =>\n right.name_score - left.name_score ||\n createdAtKey(left).localeCompare(createdAtKey(right)) ||\n left.process_id.localeCompare(right.process_id),\n );\n\n duplicateGroups.push({\n group_id: group.group_id,\n group_pattern: groupPattern,\n exact_duplicate: exactDuplicate,\n ...(exactDuplicate\n ? {\n rule_id: 'process_exact_duplicate_fingerprint' as const,\n methodology_rule_id: resolveRuntimeRuleId(\n 'process-dedup/default',\n 'process_exact_duplicate_fingerprint',\n ),\n severity: 'blocker' as const,\n blocker: true,\n }\n : {}),\n processes,\n });\n\n if (!exactDuplicate) {\n continue;\n }\n\n const keep = sortedProcesses[0] as DedupAnalyzedProcess;\n const deleteCandidates = sortedProcesses.slice(1);\n const scoreGap = keep.name_score - deleteCandidates[0]!.name_score;\n const confidence: 'high' | 'medium' | 'low' = scoreGap >= 15 ? 'high' : 'medium';\n\n const keepProcessRefs = referenceHits.processes[keep.process_id]!;\n const keepLifecyclemodelRefs = referenceHits.lifecyclemodels[keep.process_id]!;\n const deleteRefs = Object.fromEntries(\n deleteCandidates.map((candidate) => [\n candidate.process_id,\n {\n process_refs: referenceHits.processes[candidate.process_id]!.length,\n lifecyclemodel_refs: referenceHits.lifecyclemodels[candidate.process_id]!.length,\n },\n ]),\n );\n\n const notes = ['exact duplicate confirmed by normalized exchange signature'];\n if (\n Object.values(deleteRefs).every(\n (entry) => entry.process_refs === 0 && entry.lifecyclemodel_refs === 0,\n )\n ) {\n notes.push('current-user reference scan found no downstream hits for delete candidates');\n } else {\n notes.push(\n 'current-user reference scan found downstream hits; delete requires reference cleanup',\n );\n }\n notes.push('global or shared-team reference verification is outside this command');\n\n deletePlanGroups.push({\n group_id: group.group_id,\n status: 'priority_delete_candidates',\n confidence,\n current_user_reference_hits: {\n keep_process_refs: keepProcessRefs.length,\n keep_lifecyclemodel_refs: keepLifecyclemodelRefs.length,\n delete_refs: deleteRefs,\n },\n keep: {\n process_id: keep.process_id,\n name_en: trimText(keep.remote_name_en ?? keep.name_en),\n name_zh: trimText(keep.remote_name_zh ?? keep.name_zh),\n score: keep.name_score,\n reasons: keep.name_score_reasons,\n },\n delete: deleteCandidates.map((candidate) => ({\n process_id: candidate.process_id,\n name_en: trimText(candidate.remote_name_en ?? candidate.name_en),\n name_zh: trimText(candidate.remote_name_zh ?? candidate.name_zh),\n score: candidate.name_score,\n reasons: candidate.name_score_reasons,\n })),\n notes,\n });\n }\n\n return {\n duplicateGroups,\n deletePlanGroups,\n };\n}\n\nfunction buildDedupGate(duplicateGroups: ProcessDedupReviewGroup[]): ProcessDedupGate {\n const ruleset = getRuntimeRuleset('process-dedup/default');\n const blockers = duplicateGroups\n .filter((group) => group.exact_duplicate)\n .map((group) => ({\n group_id: group.group_id,\n code: 'process_exact_duplicate_fingerprint' as const,\n methodology_rule_id: resolveRuntimeRuleId(ruleset.id, 'process_exact_duplicate_fingerprint'),\n severity: 'blocker' as const,\n message:\n 'Process group has an exact duplicate normalized exchange fingerprint and must be resolved before creating or publishing another process.',\n }));\n return {\n status: blockers.length > 0 ? 'blocked' : 'passed',\n ruleset_id: ruleset.id,\n ruleset_version: ruleset.version,\n ruleset_source_version: ruleset.source_version,\n ruleset_rule_ids: ruleset.rule_ids,\n counts: {\n duplicate_groups: duplicateGroups.length,\n blocker_groups: blockers.length,\n },\n blockers,\n next_action: blockers.length > 0 ? 'resolve_duplicate_processes' : 'continue',\n };\n}\n\nexport async function runProcessDedupReview(\n options: RunProcessDedupReviewOptions,\n): Promise<ProcessDedupReviewReport> {\n const inputPath = requiredNonEmpty(options.inputPath, '--input', 'PROCESS_DEDUP_INPUT_REQUIRED');\n const outDir = requiredNonEmpty(options.outDir, '--out-dir', 'PROCESS_DEDUP_OUT_DIR_REQUIRED');\n const resolvedInputPath = path.resolve(inputPath);\n const resolvedOutDir = path.resolve(outDir);\n const timeoutMs = toPositiveInteger(\n options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n '--timeout-ms',\n 'PROCESS_DEDUP_TIMEOUT_INVALID',\n );\n const maxRetries = toPositiveInteger(\n options.maxRetries ?? DEFAULT_MAX_RETRIES,\n '--max-retries',\n 'PROCESS_DEDUP_MAX_RETRIES_INVALID',\n );\n const generatedAtUtc = nowIso(options.now);\n\n const document = normalizeInputDocument(readJsonInput(resolvedInputPath), resolvedInputPath);\n const processIds = [\n ...new Set(\n document.groups.flatMap((group) => group.processes.map((process) => process.process_id)),\n ),\n ];\n\n const inputManifestPath = path.join(resolvedOutDir, 'inputs', 'dedup-input.manifest.json');\n writeJsonArtifact(inputManifestPath, {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n input_file: resolvedInputPath,\n source_label: document.sourceLabel,\n group_count: document.groups.length,\n process_count: processIds.length,\n });\n\n const remoteStatus: RemoteStatus = {\n enabled: false,\n loaded: 0,\n error: null,\n reference_scan: options.skipRemote ? 'skipped_by_flag' : 'not_run',\n };\n\n let remoteMetadataPath: string | null = null;\n let referenceScanPath: string | null = null;\n let remoteById: Record<string, RemoteMetadataRecord> = {};\n let referenceHits = buildEmptyReferenceHits(processIds);\n\n if (!options.skipRemote) {\n try {\n const env = options.env ?? process.env;\n const fetchImpl = options.fetchImpl ?? (fetch as FetchLike);\n const auth = await resolveRemoteAuthContext({\n env,\n fetchImpl,\n timeoutMs,\n maxRetries,\n now: options.now ?? new Date(),\n });\n\n remoteById = await fetchRemoteMetadata({\n processIds,\n auth,\n fetchImpl,\n timeoutMs,\n maxRetries,\n });\n remoteStatus.enabled = true;\n remoteStatus.loaded = Object.keys(remoteById).length;\n remoteMetadataPath = path.join(resolvedOutDir, 'inputs', 'processes.remote-metadata.json');\n writeJsonArtifact(remoteMetadataPath, remoteById);\n\n if (auth.userId) {\n try {\n referenceHits = await fetchCurrentUserReferenceHits({\n auth,\n userId: auth.userId,\n targetProcessIds: processIds,\n fetchImpl,\n timeoutMs,\n maxRetries,\n });\n referenceScanPath = path.join(\n resolvedOutDir,\n 'outputs',\n 'current-user-reference-scan.json',\n );\n writeJsonArtifact(referenceScanPath, referenceHits);\n remoteStatus.reference_scan = 'current_user_completed';\n } catch (error) {\n remoteStatus.reference_scan = 'failed';\n remoteStatus.error = errorMessage(error);\n }\n } else {\n remoteStatus.reference_scan = 'skipped_missing_user_id';\n }\n } catch (error) {\n remoteStatus.error = errorMessage(error);\n }\n }\n\n const analysis = analyzeGroups(document.groups, remoteById, referenceHits);\n const gate = buildDedupGate(analysis.duplicateGroups);\n const duplicateGroupsPath = path.join(resolvedOutDir, 'outputs', 'duplicate-groups.json');\n const deletePlanPath = path.join(resolvedOutDir, 'outputs', 'delete-plan.json');\n\n writeJsonArtifact(duplicateGroupsPath, {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n input_file: resolvedInputPath,\n source_label: document.sourceLabel,\n ruleset_id: gate.ruleset_id,\n ruleset_version: gate.ruleset_version,\n ruleset_source_version: gate.ruleset_source_version,\n ruleset_rule_ids: gate.ruleset_rule_ids,\n gate,\n remote_status: remoteStatus,\n groups: analysis.duplicateGroups,\n });\n writeJsonArtifact(deletePlanPath, {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n input_file: resolvedInputPath,\n source_label: document.sourceLabel,\n ruleset_id: gate.ruleset_id,\n ruleset_version: gate.ruleset_version,\n ruleset_source_version: gate.ruleset_source_version,\n ruleset_rule_ids: gate.ruleset_rule_ids,\n gate,\n remote_status: remoteStatus,\n groups: analysis.deletePlanGroups,\n });\n\n return {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n status: 'completed_process_dedup_review',\n input_file: resolvedInputPath,\n out_dir: resolvedOutDir,\n source_label: document.sourceLabel,\n group_count: analysis.duplicateGroups.length,\n exact_duplicate_group_count: analysis.duplicateGroups.filter((group) => group.exact_duplicate)\n .length,\n ruleset_id: gate.ruleset_id,\n ruleset_version: gate.ruleset_version,\n ruleset_source_version: gate.ruleset_source_version,\n ruleset_rule_ids: gate.ruleset_rule_ids,\n gate,\n remote_status: remoteStatus,\n files: {\n input_manifest: inputManifestPath,\n remote_metadata: remoteMetadataPath,\n duplicate_groups: duplicateGroupsPath,\n delete_plan: deletePlanPath,\n current_user_reference_scan: referenceScanPath,\n },\n };\n}\n\nexport const __testInternals = {\n analyzeGroups,\n buildDedupGate,\n collectReferenceHits,\n detectGroupPattern,\n errorMessage,\n fetchCurrentUserId,\n fetchCurrentUserReferenceHits,\n fetchCurrentUserRows,\n fetchJsonWithRetry,\n fetchRemoteMetadata,\n getLangList,\n getLangText,\n normalizeAmount,\n normalizeExchangeRows,\n normalizeInputDocument,\n normalizedSignature,\n parseJsonResponse,\n resolveRemoteAuthContext,\n scoreProcessName,\n};\n"]}
1
+ {"version":3,"file":"process-dedup-review.js","sourceRoot":"","sources":["../../../src/lib/process-dedup-review.ts"],"names":[],"mappings":"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","sourcesContent":["// data-api-relations: lifecyclemodels, processes\nimport path from 'node:path';\nimport { writeJsonArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike, ResponseLike } from './http.js';\nimport { readJsonInput } from './io.js';\nimport { getRuntimeRuleset, resolveRuntimeRuleId } from './runtime-rulesets.js';\nimport {\n deriveSupabaseProjectBaseUrl,\n deriveSupabaseRestBaseUrl,\n requireSupabaseRestRuntime,\n} from './supabase-client.js';\nimport {\n applyDataApiProfileHeaders,\n buildDataApiUrl,\n resolveDataApiCapability,\n} from './supabase-data-api-contract.js';\nimport { resolveSupabaseUserSession } from './supabase-session.js';\n\ntype JsonRecord = Record<string, unknown>;\ntype ProcessGroupId = string | number;\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_RETRIES = 4;\nconst DEFAULT_PAGE_SIZE = 100;\n\ntype ExchangeSummaryRow = {\n exchange_internal_id: string;\n flow_id: string;\n flow_version: string;\n direction: string;\n mean_amount: string;\n resulting_amount: string;\n flow_short_description_en: string;\n flow_short_description_zh: string;\n};\n\ntype DedupInputProcess = {\n process_id: string;\n version: string;\n name_en: string;\n name_zh: string;\n exchange_count: number | null;\n overview_fingerprint: string;\n sheet_exchange_rows: ExchangeSummaryRow[];\n};\n\ntype DedupInputGroup = {\n group_id: ProcessGroupId;\n processes: DedupInputProcess[];\n};\n\ntype RemoteMetadataRecord = {\n process_id: string;\n version: string;\n state_code: number | null;\n created_at: string | null;\n modified_at: string | null;\n user_id: string | null;\n team_id: string | null;\n model_id: string | null;\n remote_name_en: string;\n remote_name_zh: string;\n remote_exchanges: ExchangeSummaryRow[];\n};\n\ntype ReferenceHitRecord = {\n id: string;\n version: string;\n state_code: number | null;\n model_id?: string | null;\n};\n\ntype ReferenceHits = {\n processes: Record<string, ReferenceHitRecord[]>;\n lifecyclemodels: Record<string, ReferenceHitRecord[]>;\n};\n\ntype RemoteStatus = {\n enabled: boolean;\n loaded: number;\n error: string | null;\n reference_scan:\n | 'not_run'\n | 'skipped_by_flag'\n | 'skipped_missing_user_id'\n | 'current_user_completed'\n | 'failed';\n};\n\ntype ProcessDedupGate = {\n status: 'passed' | 'blocked';\n ruleset_id: 'process-dedup/default';\n ruleset_version: '1';\n ruleset_source_version: string;\n ruleset_rule_ids: string[];\n counts: {\n duplicate_groups: number;\n blocker_groups: number;\n };\n blockers: Array<{\n group_id: ProcessGroupId;\n code: 'process_exact_duplicate_fingerprint';\n methodology_rule_id: string | null;\n severity: 'blocker';\n message: string;\n }>;\n next_action: 'continue' | 'resolve_duplicate_processes';\n};\n\ntype DedupAnalyzedProcess = DedupInputProcess &\n Partial<RemoteMetadataRecord> & {\n analysis_exchanges: ExchangeSummaryRow[];\n normalized_exchange_signature: Array<[string, string, string, string]>;\n name_score: number;\n name_score_reasons: string[];\n };\n\nexport type ProcessDedupReviewGroup = {\n group_id: ProcessGroupId;\n group_pattern: string;\n exact_duplicate: boolean;\n rule_id?: 'process_exact_duplicate_fingerprint';\n methodology_rule_id?: string | null;\n severity?: 'blocker';\n blocker?: boolean;\n processes: DedupAnalyzedProcess[];\n};\n\ntype DeletePlanGroup = {\n group_id: ProcessGroupId;\n status: 'priority_delete_candidates';\n confidence: 'high' | 'medium' | 'low';\n current_user_reference_hits: {\n keep_process_refs: number;\n keep_lifecyclemodel_refs: number;\n delete_refs: Record<\n string,\n {\n process_refs: number;\n lifecyclemodel_refs: number;\n }\n >;\n };\n keep: {\n process_id: string;\n name_en: string;\n name_zh: string;\n score: number;\n reasons: string[];\n };\n delete: Array<{\n process_id: string;\n name_en: string;\n name_zh: string;\n score: number;\n reasons: string[];\n }>;\n notes: string[];\n};\n\ntype RemoteAuthContext = {\n projectBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n userId: string | null;\n};\n\nexport type RunProcessDedupReviewOptions = {\n inputPath: string;\n outDir: string;\n skipRemote?: boolean;\n env?: NodeJS.ProcessEnv;\n fetchImpl?: FetchLike;\n timeoutMs?: number;\n maxRetries?: number;\n now?: Date;\n};\n\nexport type ProcessDedupReviewReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'completed_process_dedup_review';\n input_file: string;\n out_dir: string;\n source_label: string;\n group_count: number;\n exact_duplicate_group_count: number;\n ruleset_id?: 'process-dedup/default';\n ruleset_version?: '1';\n ruleset_source_version?: string;\n ruleset_rule_ids?: string[];\n gate?: ProcessDedupGate;\n remote_status: RemoteStatus;\n files: {\n input_manifest: string;\n remote_metadata: string | null;\n duplicate_groups: string;\n delete_plan: string;\n current_user_reference_scan: string | null;\n };\n};\n\nfunction isRecord(value: unknown): value is JsonRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction trimText(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction nowIso(now: Date = new Date()): string {\n return now.toISOString();\n}\n\nfunction requiredNonEmpty(value: string, label: string, code: string): string {\n const normalized = value.trim();\n if (!normalized) {\n throw new CliError(`Missing required ${label}.`, {\n code,\n exitCode: 2,\n });\n }\n return normalized;\n}\n\nfunction toPositiveInteger(value: number | undefined, label: string, code: string): number {\n if (!Number.isInteger(value) || (value as number) <= 0) {\n throw new CliError(`Expected ${label} to be a positive integer.`, {\n code,\n exitCode: 2,\n });\n }\n return value as number;\n}\n\nfunction normalizeOptionalToken(value: unknown): string | null {\n const normalized = trimText(value);\n return normalized ? normalized : null;\n}\n\nfunction asArray(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value;\n }\n if (value === null || value === undefined || value === '') {\n return [];\n }\n return [value];\n}\n\nfunction toGroupId(value: unknown, fallback: string): ProcessGroupId {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n const normalized = trimText(value);\n if (!normalized) {\n return fallback;\n }\n if (/^\\d+$/u.test(normalized)) {\n return Number.parseInt(normalized, 10);\n }\n return normalized;\n}\n\nfunction normalizeExchangeCount(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n const normalized = trimText(value);\n if (!normalized) {\n return null;\n }\n const parsed = Number.parseInt(normalized, 10);\n return Number.isInteger(parsed) ? parsed : null;\n}\n\nfunction normalizeAmount(value: unknown): string {\n const normalized = trimText(value);\n if (!normalized) {\n return '';\n }\n if (/^[+-]?\\d+(?:\\.\\d+)?$/u.test(normalized)) {\n let result = normalized.replace(/^\\+/u, '');\n result = result.replace(/^(-?)0+(?=\\d)/u, '$1');\n if (result.includes('.')) {\n result = result.replace(/0+$/u, '').replace(/\\.$/u, '');\n }\n if (result === '' || result === '-' || result === '-0') {\n return '0';\n }\n return result;\n }\n const parsed = Number(normalized);\n if (Number.isFinite(parsed)) {\n return parsed.toString();\n }\n return normalized;\n}\n\nfunction getLangList(value: unknown): JsonRecord[] {\n if (value === null || value === undefined || value === '') {\n return [];\n }\n if (Array.isArray(value)) {\n return value.filter((entry): entry is JsonRecord => isRecord(entry));\n }\n if (isRecord(value)) {\n const langString = value['common:langString'];\n if (Array.isArray(langString)) {\n return langString.filter((entry): entry is JsonRecord => isRecord(entry));\n }\n if (isRecord(langString)) {\n return [langString];\n }\n if (value['#text'] !== undefined || value['@xml:lang'] !== undefined) {\n return [value];\n }\n }\n if (typeof value === 'string') {\n return [{ '@xml:lang': 'en', '#text': value }];\n }\n return [];\n}\n\nfunction getLangText(value: unknown, lang: string): string {\n const entries = getLangList(value);\n for (const entry of entries) {\n if (\n trimText(entry['@xml:lang']).toLowerCase() === lang.toLowerCase() &&\n trimText(entry['#text'])\n ) {\n return trimText(entry['#text']);\n }\n }\n for (const entry of entries) {\n if (trimText(entry['#text'])) {\n return trimText(entry['#text']);\n }\n }\n return '';\n}\n\nfunction normalizeExchangeSummaryRow(value: unknown): ExchangeSummaryRow | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const flowRef = isRecord(value.referenceToFlowDataSet) ? value.referenceToFlowDataSet : {};\n const flowShortDescription = value.flow_short_description ?? flowRef['common:shortDescription'];\n\n const normalized: ExchangeSummaryRow = {\n exchange_internal_id: trimText(value.exchange_internal_id ?? value['@dataSetInternalID']),\n flow_id: trimText(value.flow_id ?? flowRef['@refObjectId']),\n flow_version: trimText(value.flow_version ?? flowRef['@version']),\n direction: trimText(value.direction ?? value.exchangeDirection),\n mean_amount: trimText(value.mean_amount ?? value.meanAmount),\n resulting_amount: trimText(value.resulting_amount ?? value.resultingAmount),\n flow_short_description_en:\n trimText(value.flow_short_description_en) || getLangText(flowShortDescription, 'en'),\n flow_short_description_zh:\n trimText(value.flow_short_description_zh) || getLangText(flowShortDescription, 'zh'),\n };\n\n if (\n !normalized.exchange_internal_id &&\n !normalized.flow_id &&\n !normalized.direction &&\n !normalized.mean_amount &&\n !normalized.resulting_amount\n ) {\n return null;\n }\n\n return normalized;\n}\n\nfunction normalizeExchangeRows(value: unknown): ExchangeSummaryRow[] {\n return asArray(value)\n .map((entry) => normalizeExchangeSummaryRow(entry))\n .filter((entry): entry is ExchangeSummaryRow => entry !== null);\n}\n\nfunction normalizeInputProcess(value: unknown): DedupInputProcess {\n if (!isRecord(value)) {\n throw new CliError('Each process dedup candidate must be a JSON object.', {\n code: 'PROCESS_DEDUP_INPUT_INVALID_PROCESS',\n exitCode: 2,\n });\n }\n\n const processId = requiredNonEmpty(\n trimText(value.process_id ?? value.id),\n 'process_id',\n 'PROCESS_DEDUP_PROCESS_ID_REQUIRED',\n );\n\n return {\n process_id: processId,\n version: trimText(value.version),\n name_en: trimText(value.name_en ?? value.remote_name_en),\n name_zh: trimText(value.name_zh ?? value.remote_name_zh),\n exchange_count: normalizeExchangeCount(value.exchange_count),\n overview_fingerprint: trimText(value.overview_fingerprint),\n sheet_exchange_rows: normalizeExchangeRows(\n value.sheet_exchange_rows ??\n value.analysis_exchanges ??\n value.remote_exchanges ??\n value.exchanges,\n ),\n };\n}\n\nfunction normalizeInputGroup(\n value: unknown,\n fallbackGroupId: string,\n index: number,\n): DedupInputGroup {\n if (!isRecord(value)) {\n throw new CliError('Each process dedup group must be a JSON object.', {\n code: 'PROCESS_DEDUP_INPUT_INVALID_GROUP',\n exitCode: 2,\n });\n }\n\n const processes = asArray(value.processes).map((entry) => normalizeInputProcess(entry));\n if (processes.length === 0) {\n throw new CliError(`Process dedup group ${index + 1} is missing processes.`, {\n code: 'PROCESS_DEDUP_GROUP_PROCESSES_REQUIRED',\n exitCode: 2,\n });\n }\n\n return {\n group_id: toGroupId(value.group_id, fallbackGroupId),\n processes,\n };\n}\n\nfunction normalizeInputDocument(\n value: unknown,\n resolvedInputPath: string,\n): {\n sourceLabel: string;\n groups: DedupInputGroup[];\n} {\n if (!isRecord(value)) {\n throw new CliError('Process dedup review input must be a JSON object.', {\n code: 'PROCESS_DEDUP_INPUT_INVALID',\n exitCode: 2,\n });\n }\n\n const sourceLabel =\n trimText(value.source_label ?? value.source_workbook ?? value.source_file) ||\n path.basename(resolvedInputPath);\n const rawGroups = value.groups;\n let groups: DedupInputGroup[] = [];\n\n if (Array.isArray(rawGroups)) {\n groups = rawGroups.map((entry, index) => normalizeInputGroup(entry, String(index + 1), index));\n } else if (isRecord(rawGroups)) {\n groups = Object.entries(rawGroups).map(([groupId, entry], index) =>\n normalizeInputGroup(entry, groupId, index),\n );\n }\n\n if (groups.length === 0) {\n throw new CliError('Process dedup review input must contain at least one group.', {\n code: 'PROCESS_DEDUP_GROUPS_REQUIRED',\n exitCode: 2,\n });\n }\n\n return {\n sourceLabel,\n groups,\n };\n}\n\nasync function parseJsonResponse(response: ResponseLike, label: string): Promise<unknown> {\n const text = await response.text();\n const contentType = response.headers.get('content-type') ?? '';\n if (!text.trim()) {\n return null;\n }\n if (!contentType.includes('application/json')) {\n return text;\n }\n try {\n return JSON.parse(text);\n } catch (error) {\n throw new CliError(`${label} returned invalid JSON.`, {\n code: 'PROCESS_DEDUP_REMOTE_INVALID_JSON',\n exitCode: 1,\n details: String(error),\n });\n }\n}\n\nasync function fetchJsonWithRetry(options: {\n url: string;\n init: RequestInit;\n label: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<{ status: number; headers: Headers; body: unknown }> {\n let lastError: unknown = null;\n\n for (let attempt = 1; attempt <= options.maxRetries; attempt += 1) {\n try {\n const response = await options.fetchImpl(options.url, {\n ...options.init,\n signal: AbortSignal.timeout(options.timeoutMs),\n });\n const body = await parseJsonResponse(response, options.label);\n if (!response.ok) {\n throw new CliError(`${options.label} failed with ${response.status}.`, {\n code: 'PROCESS_DEDUP_REMOTE_REQUEST_FAILED',\n exitCode: 1,\n details: {\n status: response.status,\n body,\n url: options.url,\n },\n });\n }\n return {\n status: response.status,\n headers: new Headers({\n 'content-range': response.headers.get('content-range') ?? '',\n 'content-type': response.headers.get('content-type') ?? '',\n }),\n body,\n };\n } catch (error) {\n lastError = error;\n if (attempt >= options.maxRetries) {\n break;\n }\n await new Promise((resolve) => setTimeout(resolve, attempt * 1_500));\n }\n }\n\n if (lastError instanceof CliError) {\n throw lastError;\n }\n\n throw new CliError(`${options.label} failed after ${options.maxRetries} attempt(s).`, {\n code: 'PROCESS_DEDUP_REMOTE_REQUEST_FAILED',\n exitCode: 1,\n details: String(lastError),\n });\n}\n\nasync function fetchCurrentUserId(options: {\n projectBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<string | null> {\n const response = await fetchJsonWithRetry({\n url: `${options.projectBaseUrl}/auth/v1/user`,\n init: {\n method: 'GET',\n headers: {\n apikey: options.publishableKey,\n Authorization: `Bearer ${options.accessToken}`,\n Accept: 'application/json',\n },\n },\n label: 'supabase current-user lookup',\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n if (!isRecord(response.body)) {\n return null;\n }\n return normalizeOptionalToken(response.body.id);\n}\n\nasync function resolveRemoteAuthContext(options: {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n now: Date;\n}): Promise<RemoteAuthContext> {\n const runtime = requireSupabaseRestRuntime(options.env);\n const session = await resolveSupabaseUserSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n });\n const projectBaseUrl = deriveSupabaseProjectBaseUrl(runtime.apiBaseUrl);\n\n let userId: string | null;\n try {\n userId = await fetchCurrentUserId({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n } catch {\n userId = null;\n }\n\n return {\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n userId,\n };\n}\n\nfunction summarizeRemoteExchanges(processJson: unknown): ExchangeSummaryRow[] {\n if (!isRecord(processJson)) {\n return [];\n }\n const processDataSet = isRecord(processJson.processDataSet) ? processJson.processDataSet : {};\n const exchanges = isRecord(processDataSet.exchanges) ? processDataSet.exchanges.exchange : [];\n return normalizeExchangeRows(exchanges);\n}\n\nasync function fetchRemoteMetadata(options: {\n processIds: string[];\n auth: RemoteAuthContext;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<Record<string, RemoteMetadataRecord>> {\n if (options.processIds.length === 0) {\n return {};\n }\n\n const capability = resolveDataApiCapability({ kind: 'relation', name: 'processes' });\n const url = new URL(\n buildDataApiUrl(deriveSupabaseRestBaseUrl(options.auth.projectBaseUrl), capability),\n );\n url.searchParams.set(\n 'select',\n 'id,version,state_code,created_at,modified_at,user_id,team_id,model_id,json',\n );\n url.searchParams.set('id', `in.(${options.processIds.join(',')})`);\n url.searchParams.set('order', 'id.asc');\n\n const response = await fetchJsonWithRetry({\n url: url.toString(),\n init: {\n method: 'GET',\n headers: applyDataApiProfileHeaders(\n {\n apikey: options.auth.publishableKey,\n Authorization: `Bearer ${options.auth.accessToken}`,\n Accept: 'application/json',\n },\n capability,\n ),\n },\n label: 'process dedup remote metadata fetch',\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n const rows = Array.isArray(response.body) ? response.body : [];\n const byId: Record<string, RemoteMetadataRecord> = {};\n\n for (const row of rows) {\n if (!isRecord(row)) {\n continue;\n }\n const processId = trimText(row.id);\n if (!processId) {\n continue;\n }\n const payload = row.json;\n const processDataSet =\n isRecord(payload) && isRecord(payload.processDataSet) ? payload.processDataSet : {};\n const processInformation = isRecord(processDataSet.processInformation)\n ? processDataSet.processInformation\n : {};\n const dataSetInformation = isRecord(processInformation.dataSetInformation)\n ? processInformation.dataSetInformation\n : {};\n const name = isRecord(dataSetInformation.name) ? dataSetInformation.name : {};\n\n byId[processId] = {\n process_id: processId,\n version: trimText(row.version),\n state_code: typeof row.state_code === 'number' ? row.state_code : null,\n created_at: normalizeOptionalToken(row.created_at),\n modified_at: normalizeOptionalToken(row.modified_at),\n user_id: normalizeOptionalToken(row.user_id),\n team_id: normalizeOptionalToken(row.team_id),\n model_id: normalizeOptionalToken(row.model_id),\n remote_name_en: getLangText(name.baseName, 'en'),\n remote_name_zh: getLangText(name.baseName, 'zh'),\n remote_exchanges: summarizeRemoteExchanges(payload),\n };\n }\n\n return byId;\n}\n\nasync function fetchCurrentUserRows(options: {\n auth: RemoteAuthContext;\n tableName: 'processes' | 'lifecyclemodels';\n userId: string;\n select: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<unknown[]> {\n const rows: unknown[] = [];\n let offset = 0;\n let total: number | null = null;\n\n while (total === null || offset < total) {\n const capability = resolveDataApiCapability({\n kind: 'relation',\n name: options.tableName,\n });\n const url = new URL(\n buildDataApiUrl(deriveSupabaseRestBaseUrl(options.auth.projectBaseUrl), capability),\n );\n url.searchParams.set('select', options.select);\n url.searchParams.set('user_id', `eq.${options.userId}`);\n url.searchParams.set('order', 'id.asc');\n url.searchParams.set('limit', String(DEFAULT_PAGE_SIZE));\n url.searchParams.set('offset', String(offset));\n\n const page = await fetchJsonWithRetry({\n url: url.toString(),\n init: {\n method: 'GET',\n headers: applyDataApiProfileHeaders(\n {\n apikey: options.auth.publishableKey,\n Authorization: `Bearer ${options.auth.accessToken}`,\n Accept: 'application/json',\n Prefer: total === null ? 'count=exact' : 'count=planned',\n },\n capability,\n ),\n },\n label: `${options.tableName} current-user reference scan`,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n const pageRows = Array.isArray(page.body) ? page.body : [];\n rows.push(...pageRows);\n\n if (total === null) {\n const contentRange = page.headers.get('content-range');\n const match = contentRange ? contentRange.match(/\\/(\\d+)$/u) : null;\n total = match ? Number.parseInt(match[1], 10) : rows.length;\n }\n\n if (pageRows.length === 0) {\n break;\n }\n offset += DEFAULT_PAGE_SIZE;\n }\n\n return rows;\n}\n\nfunction collectReferenceHits(root: unknown, targetIds: Set<string>): string[] {\n const hits: string[] = [];\n const visited = new Set<object>();\n\n const walk = (value: unknown): void => {\n if (value === null || value === undefined) {\n return;\n }\n\n if (Array.isArray(value)) {\n if (visited.has(value)) {\n return;\n }\n visited.add(value);\n value.forEach((entry) => walk(entry));\n return;\n }\n\n if (!isRecord(value)) {\n return;\n }\n\n if (visited.has(value)) {\n return;\n }\n visited.add(value);\n\n const refObjectId = trimText(value['@refObjectId']);\n if (refObjectId && targetIds.has(refObjectId)) {\n hits.push(refObjectId);\n }\n\n Object.values(value).forEach((entry) => walk(entry));\n };\n\n walk(root);\n return hits;\n}\n\nfunction buildEmptyReferenceHits(processIds: string[]): ReferenceHits {\n return {\n processes: Object.fromEntries(processIds.map((processId) => [processId, []])),\n lifecyclemodels: Object.fromEntries(processIds.map((processId) => [processId, []])),\n };\n}\n\nasync function fetchCurrentUserReferenceHits(options: {\n auth: RemoteAuthContext;\n userId: string;\n targetProcessIds: string[];\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<ReferenceHits> {\n const targetIds = new Set(options.targetProcessIds);\n const results = buildEmptyReferenceHits(options.targetProcessIds);\n\n const processRows = await fetchCurrentUserRows({\n auth: options.auth,\n tableName: 'processes',\n userId: options.userId,\n select: 'id,version,state_code,user_id,model_id,json',\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n for (const row of processRows) {\n if (!isRecord(row)) {\n continue;\n }\n const rowId = trimText(row.id);\n const hits = collectReferenceHits(row.json, targetIds);\n for (const hit of hits) {\n if (rowId === hit) {\n continue;\n }\n results.processes[hit]?.push({\n id: rowId,\n version: trimText(row.version),\n state_code: typeof row.state_code === 'number' ? row.state_code : null,\n model_id: normalizeOptionalToken(row.model_id),\n });\n }\n }\n\n const lifecyclemodelRows = await fetchCurrentUserRows({\n auth: options.auth,\n tableName: 'lifecyclemodels',\n userId: options.userId,\n select: 'id,version,state_code,user_id,json',\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n for (const row of lifecyclemodelRows) {\n if (!isRecord(row)) {\n continue;\n }\n const hits = collectReferenceHits(row.json, targetIds);\n for (const hit of hits) {\n results.lifecyclemodels[hit]?.push({\n id: trimText(row.id),\n version: trimText(row.version),\n state_code: typeof row.state_code === 'number' ? row.state_code : null,\n });\n }\n }\n\n return results;\n}\n\nfunction normalizedSignature(\n exchanges: ExchangeSummaryRow[],\n): Array<[string, string, string, string]> {\n return [...exchanges]\n .map(\n (exchange) =>\n [\n trimText(exchange.flow_id),\n trimText(exchange.direction),\n normalizeAmount(exchange.mean_amount),\n normalizeAmount(exchange.resulting_amount),\n ] as [string, string, string, string],\n )\n .sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));\n}\n\nfunction normalizedSignatureKey(exchanges: ExchangeSummaryRow[]): string {\n return JSON.stringify(normalizedSignature(exchanges));\n}\n\nfunction detectGroupPattern(processes: DedupAnalyzedProcess[]): string {\n const sample = processes.find(\n (process) => process.analysis_exchanges.length > 0,\n )?.analysis_exchanges;\n if (!sample || sample.length === 0) {\n return 'unknown';\n }\n\n const inputExchanges = sample.filter(\n (exchange) => trimText(exchange.direction).toLowerCase() === 'input',\n );\n const outputExchanges = sample.filter(\n (exchange) => trimText(exchange.direction).toLowerCase() === 'output',\n );\n const inputFlowIds = new Set(\n inputExchanges.map((exchange) => trimText(exchange.flow_id)).filter(Boolean),\n );\n const outputFlowIds = new Set(\n outputExchanges.map((exchange) => trimText(exchange.flow_id)).filter(Boolean),\n );\n\n const hasTransportInput = inputExchanges.some((exchange) => {\n const en = trimText(exchange.flow_short_description_en).toLowerCase();\n const zh = trimText(exchange.flow_short_description_zh);\n return en.includes('transport;') || zh.includes('运输;');\n });\n\n if (outputFlowIds.size > 0 && [...outputFlowIds].every((flowId) => inputFlowIds.has(flowId))) {\n return hasTransportInput ? 'transport_pass_through' : 'same_flow_pass_through';\n }\n return 'other';\n}\n\nfunction scoreProcessName(\n process: Pick<DedupAnalyzedProcess, 'name_en' | 'name_zh' | 'remote_name_en' | 'remote_name_zh'>,\n groupPattern: string,\n): { score: number; reasons: string[] } {\n const nameEn = trimText(process.remote_name_en ?? process.name_en);\n const nameZh = trimText(process.remote_name_zh ?? process.name_zh);\n const lowerEn = nameEn.toLowerCase();\n const reasons: string[] = [];\n let score = 0;\n\n if (groupPattern === 'transport_pass_through') {\n if (lowerEn.includes('transport') || nameZh.includes('运输')) {\n score += 30;\n reasons.push('name matches explicit transport-service input');\n }\n if (lowerEn.includes('logistics') || nameZh.includes('物流')) {\n score -= 10;\n reasons.push('name is broader than the observed transport-service input');\n }\n }\n\n if (groupPattern === 'same_flow_pass_through') {\n if (lowerEn.includes('processing') || nameZh.includes('加工')) {\n score -= 20;\n reasons.push('same-flow pass-through does not support a processing label');\n }\n if (lowerEn.includes('reception') || nameZh.includes('接收')) {\n score += 20;\n reasons.push('reception matches same-flow intake/output handling');\n }\n }\n\n if (lowerEn.includes('collection') || nameZh.includes('收集')) {\n score += 20;\n reasons.push('collection is semantically consistent with a gather/sort process');\n }\n if (lowerEn.includes('wastepaper')) {\n score -= 5;\n reasons.push(\"compressed English form is less standardized than 'waste paper'\");\n }\n if (lowerEn.includes('waste paper')) {\n score += 3;\n reasons.push('English wording is standardized');\n }\n if (nameEn.includes('/') || nameZh.includes('/')) {\n score += 5;\n reasons.push('name keeps the broader material scope explicit');\n }\n\n return { score, reasons };\n}\n\nfunction createdAtKey(process: Pick<DedupAnalyzedProcess, 'created_at'>): string {\n return trimText(process.created_at) || '9999-12-31T23:59:59+00:00';\n}\n\nfunction compareGroupIds(left: ProcessGroupId, right: ProcessGroupId): number {\n return String(left).localeCompare(String(right), 'en', { numeric: true });\n}\n\nfunction analyzeGroups(\n groups: DedupInputGroup[],\n remoteById: Record<string, RemoteMetadataRecord>,\n referenceHits: ReferenceHits,\n): {\n duplicateGroups: ProcessDedupReviewGroup[];\n deletePlanGroups: DeletePlanGroup[];\n} {\n const duplicateGroups: ProcessDedupReviewGroup[] = [];\n const deletePlanGroups: DeletePlanGroup[] = [];\n\n for (const group of [...groups].sort((left, right) =>\n compareGroupIds(left.group_id, right.group_id),\n )) {\n const processes: DedupAnalyzedProcess[] = group.processes.map((process) => {\n const remote = remoteById[process.process_id];\n const analysisExchanges =\n remote && remote.remote_exchanges.length > 0\n ? remote.remote_exchanges\n : process.sheet_exchange_rows;\n const initialScore = scoreProcessName(\n {\n name_en: process.name_en,\n name_zh: process.name_zh,\n remote_name_en: remote?.remote_name_en,\n remote_name_zh: remote?.remote_name_zh,\n },\n 'unknown',\n );\n\n return {\n ...process,\n ...remote,\n analysis_exchanges: analysisExchanges,\n normalized_exchange_signature: normalizedSignature(analysisExchanges),\n name_score: initialScore.score,\n name_score_reasons: initialScore.reasons,\n };\n });\n\n const exactDuplicate =\n processes.length > 1 &&\n new Set(processes.map((process) => normalizedSignatureKey(process.analysis_exchanges)))\n .size === 1;\n const groupPattern = detectGroupPattern(processes);\n\n for (const process of processes) {\n const rescored = scoreProcessName(process, groupPattern);\n process.name_score = rescored.score;\n process.name_score_reasons = rescored.reasons;\n }\n\n const sortedProcesses = [...processes].sort(\n (left, right) =>\n right.name_score - left.name_score ||\n createdAtKey(left).localeCompare(createdAtKey(right)) ||\n left.process_id.localeCompare(right.process_id),\n );\n\n duplicateGroups.push({\n group_id: group.group_id,\n group_pattern: groupPattern,\n exact_duplicate: exactDuplicate,\n ...(exactDuplicate\n ? {\n rule_id: 'process_exact_duplicate_fingerprint' as const,\n methodology_rule_id: resolveRuntimeRuleId(\n 'process-dedup/default',\n 'process_exact_duplicate_fingerprint',\n ),\n severity: 'blocker' as const,\n blocker: true,\n }\n : {}),\n processes,\n });\n\n if (!exactDuplicate) {\n continue;\n }\n\n const keep = sortedProcesses[0] as DedupAnalyzedProcess;\n const deleteCandidates = sortedProcesses.slice(1);\n const scoreGap = keep.name_score - deleteCandidates[0]!.name_score;\n const confidence: 'high' | 'medium' | 'low' = scoreGap >= 15 ? 'high' : 'medium';\n\n const keepProcessRefs = referenceHits.processes[keep.process_id]!;\n const keepLifecyclemodelRefs = referenceHits.lifecyclemodels[keep.process_id]!;\n const deleteRefs = Object.fromEntries(\n deleteCandidates.map((candidate) => [\n candidate.process_id,\n {\n process_refs: referenceHits.processes[candidate.process_id]!.length,\n lifecyclemodel_refs: referenceHits.lifecyclemodels[candidate.process_id]!.length,\n },\n ]),\n );\n\n const notes = ['exact duplicate confirmed by normalized exchange signature'];\n if (\n Object.values(deleteRefs).every(\n (entry) => entry.process_refs === 0 && entry.lifecyclemodel_refs === 0,\n )\n ) {\n notes.push('current-user reference scan found no downstream hits for delete candidates');\n } else {\n notes.push(\n 'current-user reference scan found downstream hits; delete requires reference cleanup',\n );\n }\n notes.push('global or shared-team reference verification is outside this command');\n\n deletePlanGroups.push({\n group_id: group.group_id,\n status: 'priority_delete_candidates',\n confidence,\n current_user_reference_hits: {\n keep_process_refs: keepProcessRefs.length,\n keep_lifecyclemodel_refs: keepLifecyclemodelRefs.length,\n delete_refs: deleteRefs,\n },\n keep: {\n process_id: keep.process_id,\n name_en: trimText(keep.remote_name_en ?? keep.name_en),\n name_zh: trimText(keep.remote_name_zh ?? keep.name_zh),\n score: keep.name_score,\n reasons: keep.name_score_reasons,\n },\n delete: deleteCandidates.map((candidate) => ({\n process_id: candidate.process_id,\n name_en: trimText(candidate.remote_name_en ?? candidate.name_en),\n name_zh: trimText(candidate.remote_name_zh ?? candidate.name_zh),\n score: candidate.name_score,\n reasons: candidate.name_score_reasons,\n })),\n notes,\n });\n }\n\n return {\n duplicateGroups,\n deletePlanGroups,\n };\n}\n\nfunction buildDedupGate(duplicateGroups: ProcessDedupReviewGroup[]): ProcessDedupGate {\n const ruleset = getRuntimeRuleset('process-dedup/default');\n const blockers = duplicateGroups\n .filter((group) => group.exact_duplicate)\n .map((group) => ({\n group_id: group.group_id,\n code: 'process_exact_duplicate_fingerprint' as const,\n methodology_rule_id: resolveRuntimeRuleId(ruleset.id, 'process_exact_duplicate_fingerprint'),\n severity: 'blocker' as const,\n message:\n 'Process group has an exact duplicate normalized exchange fingerprint and must be resolved before creating or publishing another process.',\n }));\n return {\n status: blockers.length > 0 ? 'blocked' : 'passed',\n ruleset_id: ruleset.id,\n ruleset_version: ruleset.version,\n ruleset_source_version: ruleset.source_version,\n ruleset_rule_ids: ruleset.rule_ids,\n counts: {\n duplicate_groups: duplicateGroups.length,\n blocker_groups: blockers.length,\n },\n blockers,\n next_action: blockers.length > 0 ? 'resolve_duplicate_processes' : 'continue',\n };\n}\n\nexport async function runProcessDedupReview(\n options: RunProcessDedupReviewOptions,\n): Promise<ProcessDedupReviewReport> {\n const inputPath = requiredNonEmpty(options.inputPath, '--input', 'PROCESS_DEDUP_INPUT_REQUIRED');\n const outDir = requiredNonEmpty(options.outDir, '--out-dir', 'PROCESS_DEDUP_OUT_DIR_REQUIRED');\n const resolvedInputPath = path.resolve(inputPath);\n const resolvedOutDir = path.resolve(outDir);\n const timeoutMs = toPositiveInteger(\n options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n '--timeout-ms',\n 'PROCESS_DEDUP_TIMEOUT_INVALID',\n );\n const maxRetries = toPositiveInteger(\n options.maxRetries ?? DEFAULT_MAX_RETRIES,\n '--max-retries',\n 'PROCESS_DEDUP_MAX_RETRIES_INVALID',\n );\n const generatedAtUtc = nowIso(options.now);\n\n const document = normalizeInputDocument(readJsonInput(resolvedInputPath), resolvedInputPath);\n const processIds = [\n ...new Set(\n document.groups.flatMap((group) => group.processes.map((process) => process.process_id)),\n ),\n ];\n\n const inputManifestPath = path.join(resolvedOutDir, 'inputs', 'dedup-input.manifest.json');\n writeJsonArtifact(inputManifestPath, {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n input_file: resolvedInputPath,\n source_label: document.sourceLabel,\n group_count: document.groups.length,\n process_count: processIds.length,\n });\n\n const remoteStatus: RemoteStatus = {\n enabled: false,\n loaded: 0,\n error: null,\n reference_scan: options.skipRemote ? 'skipped_by_flag' : 'not_run',\n };\n\n let remoteMetadataPath: string | null = null;\n let referenceScanPath: string | null = null;\n let remoteById: Record<string, RemoteMetadataRecord> = {};\n let referenceHits = buildEmptyReferenceHits(processIds);\n\n if (!options.skipRemote) {\n try {\n const env = options.env ?? process.env;\n const fetchImpl = options.fetchImpl ?? (fetch as FetchLike);\n const auth = await resolveRemoteAuthContext({\n env,\n fetchImpl,\n timeoutMs,\n maxRetries,\n now: options.now ?? new Date(),\n });\n\n remoteById = await fetchRemoteMetadata({\n processIds,\n auth,\n fetchImpl,\n timeoutMs,\n maxRetries,\n });\n remoteStatus.enabled = true;\n remoteStatus.loaded = Object.keys(remoteById).length;\n remoteMetadataPath = path.join(resolvedOutDir, 'inputs', 'processes.remote-metadata.json');\n writeJsonArtifact(remoteMetadataPath, remoteById);\n\n if (auth.userId) {\n try {\n referenceHits = await fetchCurrentUserReferenceHits({\n auth,\n userId: auth.userId,\n targetProcessIds: processIds,\n fetchImpl,\n timeoutMs,\n maxRetries,\n });\n referenceScanPath = path.join(\n resolvedOutDir,\n 'outputs',\n 'current-user-reference-scan.json',\n );\n writeJsonArtifact(referenceScanPath, referenceHits);\n remoteStatus.reference_scan = 'current_user_completed';\n } catch (error) {\n remoteStatus.reference_scan = 'failed';\n remoteStatus.error = errorMessage(error);\n }\n } else {\n remoteStatus.reference_scan = 'skipped_missing_user_id';\n }\n } catch (error) {\n remoteStatus.error = errorMessage(error);\n }\n }\n\n const analysis = analyzeGroups(document.groups, remoteById, referenceHits);\n const gate = buildDedupGate(analysis.duplicateGroups);\n const duplicateGroupsPath = path.join(resolvedOutDir, 'outputs', 'duplicate-groups.json');\n const deletePlanPath = path.join(resolvedOutDir, 'outputs', 'delete-plan.json');\n\n writeJsonArtifact(duplicateGroupsPath, {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n input_file: resolvedInputPath,\n source_label: document.sourceLabel,\n ruleset_id: gate.ruleset_id,\n ruleset_version: gate.ruleset_version,\n ruleset_source_version: gate.ruleset_source_version,\n ruleset_rule_ids: gate.ruleset_rule_ids,\n gate,\n remote_status: remoteStatus,\n groups: analysis.duplicateGroups,\n });\n writeJsonArtifact(deletePlanPath, {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n input_file: resolvedInputPath,\n source_label: document.sourceLabel,\n ruleset_id: gate.ruleset_id,\n ruleset_version: gate.ruleset_version,\n ruleset_source_version: gate.ruleset_source_version,\n ruleset_rule_ids: gate.ruleset_rule_ids,\n gate,\n remote_status: remoteStatus,\n groups: analysis.deletePlanGroups,\n });\n\n return {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n status: 'completed_process_dedup_review',\n input_file: resolvedInputPath,\n out_dir: resolvedOutDir,\n source_label: document.sourceLabel,\n group_count: analysis.duplicateGroups.length,\n exact_duplicate_group_count: analysis.duplicateGroups.filter((group) => group.exact_duplicate)\n .length,\n ruleset_id: gate.ruleset_id,\n ruleset_version: gate.ruleset_version,\n ruleset_source_version: gate.ruleset_source_version,\n ruleset_rule_ids: gate.ruleset_rule_ids,\n gate,\n remote_status: remoteStatus,\n files: {\n input_manifest: inputManifestPath,\n remote_metadata: remoteMetadataPath,\n duplicate_groups: duplicateGroupsPath,\n delete_plan: deletePlanPath,\n current_user_reference_scan: referenceScanPath,\n },\n };\n}\n\nexport const __testInternals = {\n analyzeGroups,\n buildDedupGate,\n collectReferenceHits,\n detectGroupPattern,\n errorMessage,\n fetchCurrentUserId,\n fetchCurrentUserReferenceHits,\n fetchCurrentUserRows,\n fetchJsonWithRetry,\n fetchRemoteMetadata,\n getLangList,\n getLangText,\n normalizeAmount,\n normalizeExchangeRows,\n normalizeInputDocument,\n normalizedSignature,\n parseJsonResponse,\n resolveRemoteAuthContext,\n scoreProcessName,\n};\n"]}
@@ -6,6 +6,7 @@ import { CliError } from './errors.js';
6
6
  import { cloneJson, detectDatasetKind, isRecord, unwrapDatasetPayload, } from './dataset-local.js';
7
7
  import { readJsonInput } from './io.js';
8
8
  import { normalizeIssuePath, validateSchemaWithDeepFallback, } from './tidas-sdk-validation.js';
9
+ import { collectClassificationIssues, validateElementaryFlowsClassificationHierarchy, validateProcessesClassificationHierarchy, validateProductFlowsClassificationHierarchy, } from './tidas-sdk-package-validator.js';
9
10
  const AUTO_DECISIONS = new Set([
10
11
  'reuse',
11
12
  'update_same_row',
@@ -284,23 +285,103 @@ function dataSetFormatReference(plan) {
284
285
  'TIDAS / ILCD data set format',
285
286
  });
286
287
  }
287
- function classificationClasses(plan, kind) {
288
- const pathValues = valueAsArray(plan, ['target.classification_path', 'target.classificationPath']).length > 0
289
- ? valueAsArray(plan, ['target.classification_path', 'target.classificationPath'])
290
- : valueAsArray(plan, ['classification_path', 'classificationPath']);
291
- const labels = pathValues
292
- .map((entry) => textToken(entry))
293
- .filter((entry) => Boolean(entry));
294
- const fallback = kind === 'process'
295
- ? ['Technosphere', 'Unspecified sector', 'Unspecified activity', 'Unspecified process']
296
- : ['Technosphere flows', 'Product flows', 'Unspecified category', 'Unspecified flow'];
297
- const requiredCount = kind === 'process' ? 4 : Math.max(labels.length, 1);
298
- const values = Array.from({ length: requiredCount }, (_, index) => labels[index] ?? fallback[index]);
299
- return values.map((label, index) => ({
300
- '@level': String(index),
301
- '@classId': deterministicUuid(`${kind}:classification:${index}:${label}`),
302
- '#text': label,
303
- }));
288
+ function classificationPath(plan) {
289
+ return firstValue(plan, [
290
+ 'target.classification_path',
291
+ 'target.classificationPath',
292
+ 'classification_path',
293
+ 'classificationPath',
294
+ ]);
295
+ }
296
+ function canonicalClassificationToken(entry, key, index) {
297
+ const value = entry[key];
298
+ if (typeof value !== 'string' || !value.trim()) {
299
+ throw new CliError(`Build plan classification_path[${index}] must contain a non-empty ${key} string.`, {
300
+ code: 'BUILD_PLAN_CLASSIFICATION_INVALID',
301
+ exitCode: 2,
302
+ });
303
+ }
304
+ return value.trim();
305
+ }
306
+ function canonicalClassificationEntries(plan, idKey) {
307
+ const rawPath = classificationPath(plan);
308
+ if (rawPath === undefined) {
309
+ throw new CliError('Build plan materialization requires classification_path.', {
310
+ code: 'BUILD_PLAN_CLASSIFICATION_REQUIRED',
311
+ exitCode: 2,
312
+ });
313
+ }
314
+ if (!Array.isArray(rawPath)) {
315
+ throw new CliError('Build plan classification_path must be an array.', {
316
+ code: 'BUILD_PLAN_CLASSIFICATION_INVALID',
317
+ exitCode: 2,
318
+ });
319
+ }
320
+ if (rawPath.length === 0) {
321
+ throw new CliError('Build plan classification_path must not be empty when provided.', {
322
+ code: 'BUILD_PLAN_CLASSIFICATION_INVALID',
323
+ exitCode: 2,
324
+ });
325
+ }
326
+ return rawPath.map((entry, index) => {
327
+ if (!isRecord(entry)) {
328
+ throw new CliError(`Build plan classification_path[${index}] must be a canonical object.`, {
329
+ code: 'BUILD_PLAN_CLASSIFICATION_INVALID',
330
+ exitCode: 2,
331
+ });
332
+ }
333
+ const level = canonicalClassificationToken(entry, '@level', index);
334
+ if (level !== String(index)) {
335
+ throw new CliError(`Build plan classification_path[${index}] expected @level ${index}, received ${level}.`, {
336
+ code: 'BUILD_PLAN_CLASSIFICATION_INVALID',
337
+ exitCode: 2,
338
+ });
339
+ }
340
+ return {
341
+ '@level': level,
342
+ [idKey]: canonicalClassificationToken(entry, idKey, index),
343
+ '#text': canonicalClassificationToken(entry, '#text', index),
344
+ };
345
+ });
346
+ }
347
+ function requireClassificationHierarchy(entries, kind) {
348
+ const errors = kind === 'elementary-flow'
349
+ ? validateElementaryFlowsClassificationHierarchy(entries)
350
+ : kind === 'process'
351
+ ? validateProcessesClassificationHierarchy(entries)
352
+ : validateProductFlowsClassificationHierarchy(entries);
353
+ if (errors.length > 0) {
354
+ throw new CliError(`Build plan classification_path is not a valid ${kind} hierarchy.`, {
355
+ code: 'BUILD_PLAN_CLASSIFICATION_HIERARCHY_INVALID',
356
+ exitCode: 2,
357
+ details: { kind, errors },
358
+ });
359
+ }
360
+ return entries;
361
+ }
362
+ function flowClassificationInformation(plan, flowType) {
363
+ if (flowType === 'Elementary flow') {
364
+ const entries = requireClassificationHierarchy(canonicalClassificationEntries(plan, '@catId'), 'elementary-flow');
365
+ return {
366
+ 'common:elementaryFlowCategorization': {
367
+ 'common:category': entries,
368
+ },
369
+ };
370
+ }
371
+ const entries = requireClassificationHierarchy(canonicalClassificationEntries(plan, '@classId'), 'product-flow');
372
+ return {
373
+ 'common:classification': {
374
+ 'common:class': entries,
375
+ },
376
+ };
377
+ }
378
+ function processClassificationInformation(plan) {
379
+ const entries = requireClassificationHierarchy(canonicalClassificationEntries(plan, '@classId'), 'process');
380
+ return {
381
+ 'common:classification': {
382
+ 'common:class': entries,
383
+ },
384
+ };
304
385
  }
305
386
  function normalizeFlowType(value) {
306
387
  const lower = (value ?? '').toLowerCase();
@@ -498,11 +579,7 @@ function buildCanonicalFlowPayload(plan, inputPath) {
498
579
  treatmentStandardsRoutes: firstMultiLang(plan, ['name_plan.treatment_standards_routes', 'namePlan.treatmentStandardsRoutes'], 'Reference flow'),
499
580
  mixAndLocationTypes: firstMultiLang(plan, ['name_plan.mix_and_location_types', 'namePlan.mixAndLocationTypes'], location ?? 'Global'),
500
581
  },
501
- classificationInformation: {
502
- 'common:classification': {
503
- 'common:class': classificationClasses(plan, 'flow'),
504
- },
505
- },
582
+ classificationInformation: flowClassificationInformation(plan, flowType),
506
583
  ...(firstToken(plan, ['target.cas_number', 'target.CASNumber'])
507
584
  ? { CASNumber: firstToken(plan, ['target.cas_number', 'target.CASNumber']) }
508
585
  : {}),
@@ -582,11 +659,7 @@ function buildCanonicalProcessPayload(plan, inputPath) {
582
659
  'quantitativeReferencePlan.referenceUnit',
583
660
  ]) ?? 'reference unit'),
584
661
  },
585
- classificationInformation: {
586
- 'common:classification': {
587
- 'common:class': classificationClasses(plan, 'process'),
588
- },
589
- },
662
+ classificationInformation: processClassificationInformation(plan),
590
663
  'common:generalComment': firstMultiLang(plan, ['target.general_comment', 'target.generalComment', 'evidence_manifest.summary'], `Process materialized from build plan ${inputPath}.`),
591
664
  },
592
665
  quantitativeReference: {
@@ -932,7 +1005,15 @@ function validateMaterializedSchema(artifact, kind, schemas) {
932
1005
  const { validator, schema, createEntity } = schemaForKind(kind, schemas);
933
1006
  const payload = unwrapDatasetPayload(artifact);
934
1007
  const outcome = validateSchemaWithDeepFallback(schema, payload, createEntity);
935
- if (outcome.success) {
1008
+ const issues = [
1009
+ ...outcome.issues.map(normalizeSchemaIssue),
1010
+ ...collectClassificationIssues(payload, kind === 'process' ? 'processes' : 'flows', '<materialized-payload>').map((issue) => ({
1011
+ path: issue.location,
1012
+ message: issue.message,
1013
+ code: issue.issue_code,
1014
+ })),
1015
+ ];
1016
+ if (issues.length === 0) {
936
1017
  return {
937
1018
  status: 'passed',
938
1019
  validator,
@@ -943,8 +1024,8 @@ function validateMaterializedSchema(artifact, kind, schemas) {
943
1024
  return {
944
1025
  status: 'failed',
945
1026
  validator,
946
- issue_count: outcome.issues.length,
947
- issues: outcome.issues.map(normalizeSchemaIssue),
1027
+ issue_count: issues.length,
1028
+ issues,
948
1029
  };
949
1030
  }
950
1031
  function materializePlan(plan, kind, inputPath) {