You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
chajia/scripts/export-priority1-canonical-...

120 lines
3.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/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("");
}