#!/usr/bin/env node import { readFile } from 'node:fs/promises' import { resolve } from 'node:path' import { pathToFileURL } from 'node:url' import { describeAcceptanceScope } from './admin-test-env-acceptance.mjs' /** 首页八个业务入口的脚本审计;登记范围不是运行证据。 */ export function describeHomepageBusinessCoverage() { const scope = describeAcceptanceScope() return [ { title: '头程下单', route: '/orders/first-leg/create', modules: ['orders', 'phase5-overseas-fulfillment'], additionalModules: ['phase5-root-fulfillment', 'dropship-pallet-matrix'], covered: '默认头程至海外履约主链;拆分根单、一件代发矩阵为可选专项', remaining: '各订单类型、税制及根/余量分支未由默认链全部执行' }, { title: '退货换标', route: '/overseas-warehouse/return-relabel/create', modules: ['phase4-overseas-return-receipt', 'phase4-overseas-return-followups'], covered: '退货预报、审核、签收、合箱、换标、客户确认及换标后出库', remaining: '换标、客户确认及换标后出库已接入默认后续模块;固定客户跨客户边界仍缺资源,真实HTTP待验' }, { title: '美国本土卡', route: '/cross-border/domestic-trucking/create', modules: ['phase4-overseas-business'], covered: '创建、编辑、审核及原单实收、两托部分至全部分配、派车、运输完成,逐步幂等重放', remaining: '独立本土卡车正常及部分分配链已接入;超托审核与真实HTTP待验,不能替代车队签收证据' }, { title: '美本土散板', route: '/cross-border/pallet-shipping/create', modules: ['phase4-overseas-business', 'phase5-overseas-fulfillment'], covered: '原单创建、需求池接车、PDA实收、原车加货及共享装车签收,核对原单终态与数量', remaining: '正常链已接入默认编排;异常履约、完整费用边界及真实HTTP待验' }, { title: '海外采购', route: '/cross-border/procurement/create', modules: ['phase4-overseas-business', 'phase4-overseas-wallet-and-pallet-cost'], covered: '创建、备注编辑、审核驳回;固定客户正常样品采购至寄客户及资金核对已接入默认链', remaining: '固定客户已接入正常样品采购、收货、核费及寄客户;异常、退款及其他采购类型未全覆盖,真实HTTP待验' }, { title: '贴标申请', route: '/overseas-warehouse/labeling/create', modules: ['phase4-overseas-client-services', 'phase4-overseas-dispatch', 'phase5-overseas-fulfillment'], covered: '客户原申请审核、PDA换标、客户确认、同单新箱唛出库签收、车次释放及原费用结算回查', remaining: '异常边界与真实HTTP仍待验' }, { title: '仓储转运', route: '/overseas-warehouse/storage-transfer/create', modules: ['phase4-overseas-client-services'], covered: '客户申请、提交、审核与拒绝、取消边界;已有库存原单分配、关联换标、出库、异仓收货及唯一库存流水与结算终态核验', remaining: '在途转运入库计量、多来源及部分收货异常矩阵仍待补;真实HTTP待验' }, { title: '货物废弃', route: '/overseas-warehouse/cargo-disposal/create', modules: ['phase4-overseas-client-services'], covered: '申请、拒绝释放、批准锁箱、PDA照片与实际扣库、客户确认及终态重放', remaining: '已接入同一申请公共库存总账核对;独立箱/SKU流水证据、多来源边界及真实HTTP仍待验' }, ].map(business => ({ ...business, defaultModules: business.modules.filter(name => scope.defaultModules.includes(name)), additionalModules: (business.additionalModules || []).map(name => ({ name, defaultSelected: scope.defaultModules.includes(name), skippedWithFixedResources: scope.fixedResourceSkippedModules.includes(name) })), endToEndCoverage: 'INCOMPLETE', currentVersionVerified: false, })) } /** 只输出白名单统计和模块名,不转抄报告中的账号、地址、凭据或业务载荷。 */ export function summarizeReport(report) { if (!report || !Array.isArray(report.steps) || report.steps.length === 0 || report.steps.some((step) => typeof step.passed !== 'boolean')) { throw new Error('报告缺少有效 steps,不能认定验收结果') } const steps = report.steps const failed = steps.filter((step) => !step.passed && !step.skipped) const skipped = steps.filter((step) => step.skipped) const skippedModules = Array.isArray(report.modules) ? report.modules.filter((module) => module.skipped).length : 0 const gaps = Array.isArray(report.coverageGaps) ? report.coverageGaps : [] const blockers = gaps.filter((gap) => gap.blocking || gap.deploymentBlocker) const scope = report.executionScope // 历史报告不包含计划信息,不能从断言数量或模块名字推定完整执行。 const scopeKnown = Array.isArray(scope?.plannedModules) && scope.plannedModules.length > 0 && Array.isArray(scope.defaultModules) && scope.defaultModules.length > 0 const observedModules = new Set(steps.map((step) => step.module)) const missingModules = scopeKnown ? scope.plannedModules.filter((name) => !observedModules.has(name)) : [] const limited = Boolean(scope?.preparationOnly || scope?.returnMainChainOnly || report.fullAcceptance === false) const failedResult = Boolean(report.fatal) || report.success === false || failed.length > 0 || blockers.length > 0 return { result: failedResult ? 'FAILED' : skipped.length || skippedModules || gaps.length || missingModules.length || limited ? 'INCOMPLETE' : 'RECORDED_CHECKS_PASSED', passed: steps.filter((step) => step.passed && !step.skipped).length, failed: failed.length, skipped: skipped.length, skippedModules, blockingGaps: blockers.length, nonBlockingGaps: gaps.length - blockers.length, failedModules: [...new Set(failed.map((step) => step.module).filter(Boolean))], // 无请求的失败包含前置不足和模块退出,不能计作独立接口缺陷。 failuresWithRequest: failed.filter((step) => step.request).length, failuresWithoutRequest: failed.filter((step) => !step.request).length, scope: !scopeKnown ? 'UNKNOWN_LEGACY_REPORT' : limited ? 'LIMITED_SCOPE' : scope.defaultModules.every((name) => scope.plannedModules.includes(name)) ? 'DEFAULT_ADMIN_PLAN' : 'SELECTED_MODULES', missingPlannedModules: missingModules, currentVersionVerified: false, pageAcceptance: 'NOT_VERIFIED_BY_HTTP', } } /** 默认仅展示范围;显式报告只读分析,不发现历史目录、不联网、不执行验收。 */ async function main(argv) { if (argv.length && !(argv.length === 2 && argv[0] === '--report')) { throw new Error('用法:node scripts/acceptance-overview.mjs [--report <明确JSON路径>]') } const scope = describeAcceptanceScope() const result = { purpose: '离线验收范围总览,不执行HTTP,不证明当前部署通过', admin: { entry: 'scripts/admin-test-env-acceptance.mjs', ...scope }, homepageBusinesses: describeHomepageBusinessCoverage(), otherEntries: [ { entry: 'scripts/client-test-env-acceptance.mjs', scope: 'Client全量HTTP,独立执行' }, { entry: 'scripts/client-phase2-test-env-acceptance.mjs', scope: '测量计费专项,不替代Client全量' }, { entry: 'scripts/fleet-test-env-acceptance.mjs', scope: '车辆专项,不计入Admin默认全量' }, ], boundaries: ['可选模块不等于默认执行;其他专项入口详见scripts/README.md', '本地合同、HTTP、页面与真机验收分别报告', '报告通过只代表该次记录;需另核对源码、配置与实际部署版本', '环境与凭据前置仍由实际入口校验;本工具不读取环境文件'], } if (argv.length) result.report = summarizeReport(JSON.parse(await readFile(resolve(argv[1]), 'utf8'))) console.log(JSON.stringify(result, null, 2)) } if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) { main(process.argv.slice(2)).catch((error) => { console.error(error.message); process.exitCode = 1 }) }