Files
AIclinicalresearch/backend/scripts/regression_hardrule_guards.ts
HaHafeng a666649fd4 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
2026-03-08 21:54:35 +08:00

115 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 引擎级 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);
});