fix(小宝预警): 接入静默风险证据

This commit is contained in:
Script Generator
2026-06-29 17:49:52 +08:00
parent ffe7001b42
commit 585316d1cf
2 changed files with 66 additions and 3 deletions

View File

@@ -128,3 +128,55 @@ test('calcXiaobaoVersionRisk preserves daily evidence on the returned risk objec
assert.equal(risk.dailyEvidence, dailyEvidence);
});
test('calcXiaobaoVersionRisk uses silent risks from daily evidence', () => {
const silentRisk = {
key: 'no_progress_today',
title: '今日无进展',
detail: '进行中的任务今天没有动态。',
itemId: 'dev-1',
itemType: 'dev_task' as const,
};
const dailyEvidence: VersionDailyEvidence = {
todayDeliveries: [],
todayProgress: [],
todayRisks: [],
progressNotes: [],
needsProgressItems: [],
recentActivityCount: 0,
silentRisks: [silentRisk],
};
const risk = calcXiaobaoVersionRisk({
version: version(),
devTasks: [],
testCases: [],
bugs: [],
dailyEvidence,
now: new Date('2026-07-02T01:00:00.000Z'),
});
assert.deepEqual(risk.silentRisks, [silentRisk]);
assert.equal(risk.signals.silentRiskCount, 1);
assert.ok(risk.riskScore > 0);
assert.ok(risk.reasons.some((reason: { key: string }) => reason.key === 'silent_risk'));
});
test('calcXiaobaoVersionRisk preserves null expected release date as a compatible output value', () => {
const versionWithNullRelease = {
id: 'ver-null-release',
name: 'V1.1',
expectedReleaseDate: null,
members: [],
};
const risk = calcXiaobaoVersionRisk({
version: versionWithNullRelease,
devTasks: [],
testCases: [],
bugs: [],
now: new Date('2026-07-02T01:00:00.000Z'),
});
assert.equal(risk.expectedReleaseDate, null);
});

View File

@@ -15,7 +15,7 @@ export interface XiaobaoVersionRef {
status?: string;
productName?: string;
projectName?: string;
expectedReleaseDate?: string;
expectedReleaseDate?: string | null;
members?: Array<{ id?: string; name: string; role?: string }>;
}
@@ -49,6 +49,7 @@ export interface XiaobaoVersionRisk {
versionId: string;
riskScore: number;
riskLevel: XiaobaoRiskLevel;
expectedReleaseDate: string | null;
confidence: number;
confidenceLevel: XiaobaoConfidenceLevel;
forecastReleaseDate?: string;
@@ -86,7 +87,7 @@ export function calcXiaobaoVersionRisk(input: CalcXiaobaoVersionRiskInput): Xiao
const devTasks = input.devTasks ?? [];
const testCases = input.testCases ?? [];
const bugs = input.bugs ?? [];
const silentRisks = input.silentRisks ?? [];
const silentRisks = input.dailyEvidence?.silentRisks ?? [];
const remainingDevHours = devTasks.reduce((sum, task) => {
const estimate = getEstimateHours(task);
@@ -164,6 +165,15 @@ export function calcXiaobaoVersionRisk(input: CalcXiaobaoVersionRiskInput): Xiao
count: failedTestCount,
});
}
if (silentRisks.length > 0) {
reasons.push({
key: 'silent_risk',
title: '静默风险',
detail: `发现 ${silentRisks.length} 个今日缺少进展或证据的风险项。`,
severity: 'warning',
count: silentRisks.length,
});
}
const signals: XiaobaoRiskSignals = {
unfinishedCount,
@@ -193,6 +203,7 @@ export function calcXiaobaoVersionRisk(input: CalcXiaobaoVersionRiskInput): Xiao
versionId: input.version.id,
riskScore,
riskLevel,
expectedReleaseDate: input.version.expectedReleaseDate ?? null,
confidence,
confidenceLevel: getConfidenceLevel(confidence),
forecastReleaseDate,
@@ -297,7 +308,7 @@ function getConfidenceLevel(confidence: number): XiaobaoConfidenceLevel {
return 'low';
}
function parseDate(iso?: string): Date | undefined {
function parseDate(iso?: string | null): Date | undefined {
if (!iso) return undefined;
const date = new Date(iso);
return Number.isNaN(date.getTime()) ? undefined : date;