feat(iit): harden QC pipeline consistency and release artifacts
Implement IIT quality workflow hardening across eQuery deduplication, guard metadata validation, timeline/readability improvements, and chat evidence fallbacks, then synchronize release and development documentation for deployment handoff. Includes migration/scripts for open eQuery dedupe guards, orchestration/status semantics, report/tool readability fixes, and updated module status plus deployment checklist. Made-with: Cursor
This commit is contained in:
114
backend/scripts/regression_hardrule_guards.ts
Normal file
114
backend/scripts/regression_hardrule_guards.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* 引擎级 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<string, any>, 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);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user