fix(小宝预警): 稳定风险证据与建议更新
关键改动: - 优化风险证据的日报工时与静默风险计算 - 稳定 AI 触发签名,避免证据细节变化造成重复请求 - 调整预警建议更新状态与相关测试 Co-Authored-By: Codex GPT-5 <codex@openai.com>
This commit is contained in:
@@ -148,6 +148,134 @@ test('buildVersionDailyEvidence groups version activity and detects no activity/
|
||||
assert.ok(evidence.silentRisks?.some((risk) => risk.key === 'no_activity' && risk.itemId === 'plan-1'));
|
||||
});
|
||||
|
||||
test('buildVersionDailyEvidence uses plan record work start time for daily hours', () => {
|
||||
const workItems = buildXiaobaoWorkItems({
|
||||
plans: [
|
||||
plan({
|
||||
id: 'plan-cross-day',
|
||||
title: 'Product plan',
|
||||
actualStartAt: '2026-06-30T01:00:00.000Z',
|
||||
createdAt: '2026-06-30T01:00:00.000Z',
|
||||
}),
|
||||
],
|
||||
versions: [{ id: 'ver-1', name: 'V1.0', productName: 'FTB', projectName: 'PM' }],
|
||||
requirementVersionMap: new Map(),
|
||||
});
|
||||
const activities: WorkActivity[] = [
|
||||
{
|
||||
id: 'act-plan-record',
|
||||
actorId: 'pm-1',
|
||||
date: '2026-07-01',
|
||||
occurredAt: '2026-07-01T04:00:00.000Z',
|
||||
sourceType: 'version_plan',
|
||||
sourceId: 'plan-cross-day',
|
||||
action: 'version_plan_requirement_progress',
|
||||
category: 'progress',
|
||||
title: 'Product plan',
|
||||
summary: 'Updated product plan requirement progress',
|
||||
metadata: {
|
||||
requirementId: 'req-1',
|
||||
workStartedAt: '2026-07-01T02:00:00.000Z',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const evidence = buildVersionDailyEvidence({
|
||||
versionId: 'ver-1',
|
||||
workItems,
|
||||
activities,
|
||||
worklogs: [],
|
||||
now: new Date('2026-07-01T08:00:00.000Z'),
|
||||
});
|
||||
|
||||
assert.equal(evidence.todayActualHours, 2);
|
||||
});
|
||||
|
||||
test('buildVersionDailyEvidence uses previous progress next start time for dev task daily hours', () => {
|
||||
const workItems = buildXiaobaoWorkItems({
|
||||
devTasks: [
|
||||
devTask({
|
||||
id: 'dev-cross-day-progress',
|
||||
title: 'Cross-day development',
|
||||
actualStartAt: '2026-07-01T01:30:00.000Z',
|
||||
updatedAt: '2026-07-02T10:00:00.000Z',
|
||||
}),
|
||||
],
|
||||
versions: [{ id: 'ver-1', name: 'V1.0', productName: 'FTB', projectName: 'PM' }],
|
||||
requirementVersionMap: new Map([['req-1', 'ver-1']]),
|
||||
});
|
||||
const activities: WorkActivity[] = [
|
||||
{
|
||||
id: 'act-dev-progress-day-1',
|
||||
actorId: 'dev-1',
|
||||
date: '2026-07-01',
|
||||
occurredAt: '2026-07-01T10:00:00.000Z',
|
||||
sourceType: 'dev_task',
|
||||
sourceId: 'dev-cross-day-progress',
|
||||
action: 'progress_note_added',
|
||||
category: 'note',
|
||||
title: 'Cross-day development',
|
||||
summary: 'Updated today progress',
|
||||
metadata: {
|
||||
note: 'Finished the first part',
|
||||
nextStartAt: '2026-07-02T01:30:00.000Z',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'act-dev-progress-day-2',
|
||||
actorId: 'dev-1',
|
||||
date: '2026-07-02',
|
||||
occurredAt: '2026-07-02T10:00:00.000Z',
|
||||
sourceType: 'dev_task',
|
||||
sourceId: 'dev-cross-day-progress',
|
||||
action: 'progress_note_added',
|
||||
category: 'note',
|
||||
title: 'Cross-day development',
|
||||
summary: 'Updated today progress',
|
||||
metadata: {
|
||||
note: 'Finished the second part',
|
||||
nextStartAt: '2026-07-03T01:30:00.000Z',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const evidence = buildVersionDailyEvidence({
|
||||
versionId: 'ver-1',
|
||||
workItems,
|
||||
activities,
|
||||
worklogs: [],
|
||||
now: new Date('2026-07-02T10:00:00.000Z'),
|
||||
});
|
||||
|
||||
assert.equal(evidence.todayActualHours, 7.5);
|
||||
});
|
||||
|
||||
test('buildVersionDailyEvidence does not emit Infinity-day silent risk details', () => {
|
||||
const workItems = buildXiaobaoWorkItems({
|
||||
plans: [
|
||||
plan({
|
||||
id: 'plan-no-evidence',
|
||||
title: 'Plan without evidence',
|
||||
createdAt: '2026-06-20T01:00:00.000Z',
|
||||
actualStartAt: '2026-06-20T01:00:00.000Z',
|
||||
}),
|
||||
],
|
||||
versions: [{ id: 'ver-1', name: 'V1.0', productName: 'FTB', projectName: 'PM' }],
|
||||
requirementVersionMap: new Map(),
|
||||
});
|
||||
|
||||
const evidence = buildVersionDailyEvidence({
|
||||
versionId: 'ver-1',
|
||||
workItems,
|
||||
activities: [],
|
||||
worklogs: [],
|
||||
now: new Date('2026-06-29T08:00:00.000Z'),
|
||||
});
|
||||
|
||||
assert.ok((evidence.silentRisks ?? []).length > 0);
|
||||
assert.equal((evidence.silentRisks ?? []).some((risk) => risk.detail.includes('Infinity')), false);
|
||||
});
|
||||
|
||||
test('buildVersionDailyEvidence mirrors daily report timestamp fallback evidence', () => {
|
||||
const workItems = buildXiaobaoWorkItems({
|
||||
plans: [
|
||||
|
||||
Reference in New Issue
Block a user