50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
import { REVIEW_CONSTANTS, isBuildRelatedDim } from './review-constants';
|
||
|
||
export interface HardRuleContext {
|
||
buildFailed: boolean;
|
||
testStepFailed: boolean;
|
||
duplicateRatio: number;
|
||
hasAnyReadme: boolean;
|
||
hasRootReadme: boolean;
|
||
}
|
||
|
||
export interface HardRuleDim {
|
||
name: string;
|
||
score: number;
|
||
maxScore: number;
|
||
}
|
||
|
||
export interface HardRuleResult {
|
||
dimensions: HardRuleDim[];
|
||
log: string[];
|
||
}
|
||
|
||
/**
|
||
* 评审 Phase 3c:确定性硬规则封顶(校准后执行)。
|
||
* 纯函数、不修改入参;封顶只降不升。
|
||
*/
|
||
export function applyHardRules(
|
||
dims: HardRuleDim[],
|
||
ctx: HardRuleContext
|
||
): HardRuleResult {
|
||
const log: string[] = [];
|
||
const dimensions = dims.map(d => {
|
||
const name = d.name;
|
||
let cap = d.maxScore;
|
||
const isBuildCapDim = isBuildRelatedDim(name);
|
||
if (ctx.buildFailed && isBuildCapDim) cap = Math.min(cap, Math.floor(d.maxScore * REVIEW_CONSTANTS.BUILD_FAIL_CAP_RATIO));
|
||
if (ctx.buildFailed && name.includes('效果与数据')) cap = Math.min(cap, Math.floor(d.maxScore * REVIEW_CONSTANTS.EFFECT_DATA_BUILD_FAIL_RATIO));
|
||
if (ctx.testStepFailed && (name.includes('效果与数据') || isBuildCapDim)) cap = Math.min(cap, Math.floor(d.maxScore * REVIEW_CONSTANTS.TEST_FAIL_CAP_RATIO));
|
||
if (ctx.duplicateRatio > REVIEW_CONSTANTS.DUP_RATIO_CAP_TRIGGER && name.includes('代码规范')) cap = Math.min(cap, REVIEW_CONSTANTS.DUP_CAP_SCORE);
|
||
if (!ctx.hasAnyReadme && name.includes('演示与文档')) cap = Math.min(cap, REVIEW_CONSTANTS.NO_README_CAP);
|
||
else if (!ctx.hasRootReadme && name.includes('演示与文档')) cap = Math.min(cap, REVIEW_CONSTANTS.NO_ROOT_README_CAP);
|
||
let score = d.score;
|
||
if (score > cap) {
|
||
log.push(`${name} ${score}→${cap}(超上限${cap})`);
|
||
score = cap;
|
||
}
|
||
return { name, score, maxScore: d.maxScore };
|
||
});
|
||
return { dimensions, log };
|
||
}
|