/** * 引擎级 guard smoke test(与项目配置无关) * * 注意: * - 本脚本只验证 HardRuleEngine 的通用 guard 机制是否生效 * - 不代表任何具体项目规则配置 * - 项目级回归请使用 regression_hardrule_guards_by_project.ts */ import assert from 'node:assert'; import { HardRuleEngine, type QCRule } from '../src/modules/iit-manager/engines/HardRuleEngine.js'; function runCase(name: string, rules: QCRule[], data: Record, expectedStatus: 'PASS' | 'FAIL' | 'WARNING') { const engine = new HardRuleEngine('regression-project'); const result = engine.executeWithRules('R1', data, rules); assert.strictEqual(result.overallStatus, expectedStatus, `${name} 期望 ${expectedStatus},实际 ${result.overallStatus}`); console.log(`✅ ${name}: ${result.overallStatus}`); } async function main() { const rules: QCRule[] = [ { id: 'r1', name: 'date consistency check A', field: ['visiting_date', 'date_of_signature'], logic: { '<': [{ var: 'visiting_date' }, { var: 'date_of_signature' }] }, message: 'date ordering failed', severity: 'error', category: 'D1', metadata: { guardType: 'date_not_before_or_equal' }, }, { id: 'r2', name: 'date consistency check B', field: ['date_of_assessment_sf_mpq_scale', 'visiting_date'], logic: { '!=': [{ var: 'date_of_assessment_sf_mpq_scale' }, { var: 'visiting_date' }] }, message: 'date mismatch', severity: 'warning', category: 'D3', metadata: { guardType: 'skip_if_any_missing' }, }, { id: 'r3', name: 'all inclusion criteria check', field: ['inclusion_criteria1', 'inclusion_criteria2', 'inclusion_criteria3', 'inclusion_criteria4', 'inclusion_criteria5'], logic: { '==': [1, 0] }, // 故意构造为失败,验证 guard 能兜底 message: 'inclusion not all met', severity: 'warning', category: 'D1', metadata: { guardType: 'pass_if_all_ones' }, }, { id: 'r4', name: 'enrollment exclusion conflict check', field: ['enrollment_status', 'exclusion_criteria1', 'exclusion_criteria2'], logic: { '==': [1, 0] }, // 故意构造为失败,验证 guard 能兜底 message: 'enrollment conflict', severity: 'error', category: 'D1', metadata: { guardType: 'pass_if_exclusion_all_zero' }, }, ]; runCase( '同日访视不应误判早于', [rules[0]], { visiting_date: '2024-03-27', date_of_signature: '2024-03-27' }, 'PASS', ); runCase( '评估日期缺失不应判不一致', [rules[1]], { date_of_assessment_sf_mpq_scale: '', visiting_date: '2024-03-27' }, 'PASS', ); runCase( '纳入标准全1应通过', [rules[2]], { inclusion_criteria1: 1, inclusion_criteria2: 1, inclusion_criteria3: 1, inclusion_criteria4: 1, inclusion_criteria5: 1 }, 'PASS', ); runCase( '排除标准全0应通过', [rules[3]], { enrollment_status: 1, exclusion_criteria1: 0, exclusion_criteria2: 0 }, 'PASS', ); runCase( '无guard普通规则失败应保持失败', [ { id: 'r5', name: 'plain range check', field: 'age', logic: { '>=': [{ var: 'age' }, 18] }, message: 'age too small', severity: 'error', category: 'D1', }, ], { age: 10 }, 'FAIL', ); } main().catch((e) => { console.error(e); process.exit(1); });