|
|
#!/usr/bin/env tsx
|
|
|
/**
|
|
|
* 导出 Priority1 全矩阵 24 条系统联调用例
|
|
|
*
|
|
|
* npm run export:priority1-canonical-test-matrix
|
|
|
*
|
|
|
* 产出: .rpa/priority1-canonical-test-matrix.json
|
|
|
*/
|
|
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
|
import { join } from "node:path";
|
|
|
import {
|
|
|
buildPriority1CanonicalTestCases,
|
|
|
formatPriority1InputSummary,
|
|
|
PRIORITY1_CANONICAL_PATHS,
|
|
|
} from "@/workers/rpa/priority1/demo-input";
|
|
|
import {
|
|
|
formatPriority1ConstraintsMarkdown,
|
|
|
PRIORITY1_MUTEX_RULES,
|
|
|
PRIORITY1_WEIGHT_LIMITS,
|
|
|
validatePriority1FormConstraints,
|
|
|
} from "@/workers/rpa/priority1/form-constraints";
|
|
|
|
|
|
const outDir = join(process.cwd(), ".rpa");
|
|
|
mkdirSync(outDir, { recursive: true });
|
|
|
|
|
|
const customerId = process.env.PRIORITY1_TEST_CUSTOMER_ID?.trim() ?? "CUST_PRIORITY1_TEST";
|
|
|
const cases = buildPriority1CanonicalTestCases({ customerId });
|
|
|
const constraintIssues = cases.flatMap((c) =>
|
|
|
validatePriority1FormConstraints(c.apiPayload.priority1_input).map((v) => ({
|
|
|
caseId: c.id,
|
|
|
...v,
|
|
|
})),
|
|
|
);
|
|
|
const constraintErrors = constraintIssues.filter((v) => v.severity === "error");
|
|
|
|
|
|
const payload = {
|
|
|
generatedAt: new Date().toISOString(),
|
|
|
total: cases.length,
|
|
|
canonicalTotal: PRIORITY1_CANONICAL_PATHS.length,
|
|
|
customerId,
|
|
|
apiEndpoint: "POST /api/priority1/quotes",
|
|
|
rpaBenchmark: "npm run benchmark:priority1-canonical-matrix",
|
|
|
singlePath: "$env:PRIORITY1_MATRIX_FILTER=\"P01\"; npm run benchmark:priority1-canonical-matrix",
|
|
|
outcomeLegend: {
|
|
|
instant_quote: "页面返回即时报价(LTL 卡片或 FTL 日历)",
|
|
|
manual_followup: "表单已提交,站点判定需人工确认细节后报价",
|
|
|
},
|
|
|
mutexRules: PRIORITY1_MUTEX_RULES,
|
|
|
weightLimits: PRIORITY1_WEIGHT_LIMITS,
|
|
|
constraintValidation: {
|
|
|
errorCount: constraintErrors.length,
|
|
|
issues: constraintIssues,
|
|
|
},
|
|
|
cases,
|
|
|
};
|
|
|
|
|
|
const jsonPath = join(outDir, "priority1-canonical-test-matrix.json");
|
|
|
writeFileSync(jsonPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
|
|
|
|
const constraintsPath = join(outDir, "priority1-form-constraints.md");
|
|
|
writeFileSync(constraintsPath, formatPriority1ConstraintsMarkdown(), "utf8");
|
|
|
|
|
|
const mdPath = join(outDir, "priority1-canonical-test-matrix.md");
|
|
|
const lines = [
|
|
|
"# Priority1 全矩阵 24 条 — 系统联调清单",
|
|
|
"",
|
|
|
`- 生成: ${payload.generatedAt}`,
|
|
|
`- API: \`${payload.apiEndpoint}\``,
|
|
|
`- 客户: \`${customerId}\``,
|
|
|
"",
|
|
|
"| # | ID | 类型 | 预期终态 | 标题 |",
|
|
|
"|---|-----|------|----------|------|",
|
|
|
];
|
|
|
for (const c of cases) {
|
|
|
const outcome =
|
|
|
c.expectedOutcome === "instant_quote" ? "即时报价" : "人工跟进";
|
|
|
lines.push(`| ${c.index} | ${c.id} | ${c.category} | ${outcome} | ${c.title} |`);
|
|
|
}
|
|
|
lines.push(
|
|
|
"",
|
|
|
"## 批量 RPA 验收",
|
|
|
"",
|
|
|
"```powershell",
|
|
|
"npm run benchmark:priority1-canonical-matrix",
|
|
|
"```",
|
|
|
"",
|
|
|
"## 单条过滤",
|
|
|
"",
|
|
|
"```powershell",
|
|
|
"$env:PRIORITY1_MATRIX_FILTER=\"F04\"",
|
|
|
"npm run benchmark:priority1-canonical-matrix",
|
|
|
"```",
|
|
|
"",
|
|
|
`JSON: \`${jsonPath}\``,
|
|
|
);
|
|
|
writeFileSync(mdPath, `${lines.join("\n")}\n`, "utf8");
|
|
|
|
|
|
console.log("\n════════ Priority1 全矩阵测试用例 ════════");
|
|
|
console.log(`共 ${cases.length} 条 → ${jsonPath}`);
|
|
|
console.log(`规则说明 → ${constraintsPath}`);
|
|
|
if (constraintErrors.length) {
|
|
|
console.error(`\n[export] ✗ ${constraintErrors.length} 条用例违反硬限制:`);
|
|
|
for (const e of constraintErrors) {
|
|
|
console.error(` - ${e.caseId}: ${e.message}`);
|
|
|
}
|
|
|
process.exit(1);
|
|
|
}
|
|
|
console.log(`清单 MD → ${mdPath}\n`);
|
|
|
for (const c of cases) {
|
|
|
const tag = c.expectedOutcome === "instant_quote" ? "即时报价" : "人工跟进";
|
|
|
console.log(`${String(c.index).padStart(2)}. ${c.id} [${c.category}] ${tag}`);
|
|
|
console.log(` ${c.title}`);
|
|
|
console.log(` request_id: ${c.apiPayload.request_id}`);
|
|
|
console.log(formatPriority1InputSummary(c.apiPayload.priority1_input)
|
|
|
.split("\n")
|
|
|
.map((l) => ` ${l}`)
|
|
|
.join("\n"));
|
|
|
console.log("");
|
|
|
}
|