docs+fix: 4份核心文档 + 项目模块版本记录数据全联动

文档:
- architecture.md - 整体架构、心智模型、关键设计原则
- decisions.md - 16条关键决策记录(含为什么)
- workflow.md - 工作流程和协作偏好
- roadmap.md - V1/V2/V3 路线图和已完成清单

修复项目详情版本记录:
1. 状态胶囊数据联动(开发中分支也补传 stageProgress)
2. 日期数据联动:
   - 实际开始 = 取所有阶段最早 actualStartAt/startDate/startedAt
   - 实际截止 = 取所有阶段最晚 completedAt/closedAt
   - 数据完全和版本详情一致

VersionCard 的 versionData useMemo 增加 actualStart/actualEnd 派生字段,
两种状态分支(developing/released)都使用派生值,不再用静态 version.startDate

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Script Generator
2026-06-16 12:40:10 +08:00
parent 4b05e09dab
commit 6d2f6d8b9f
5 changed files with 534 additions and 4 deletions

View File

@@ -77,6 +77,15 @@ function VersionCard({ version, progress, plans, devTasks, testCases, bugs, requ
vTCs.forEach((c) => { if (c.startedAt) startDates.push(c.startedAt); });
const earliestStart = startDates.length > 0 ? startDates.sort()[0] : version.startDate;
const actualStartDisplay = startDates.length > 0 ? startDates.sort()[0].slice(0, 10) : (version.startDate ?? null);
// 实际截止:取所有阶段最晚完成
const endDates: string[] = [];
vPlans.forEach((p) => { if (p.completedAt) endDates.push(p.completedAt); });
vDevTasks.forEach((t) => { if (t.completedAt) endDates.push(t.completedAt); });
vTCs.forEach((c) => { if (c.completedAt) endDates.push(c.completedAt); });
vBugs.forEach((b) => { if (b.closedAt) endDates.push(b.closedAt); });
const actualEndDisplay = endDates.length > 0 ? endDates.sort().reverse()[0].slice(0, 10) : null;
let totalDays = 0;
if (earliestStart) {
@@ -87,7 +96,7 @@ function VersionCard({ version, progress, plans, devTasks, testCases, bugs, requ
totalDays = Math.max(0, Math.floor((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)));
}
return { vPlans, vDevTasks, vTCs, vBugs, totalDays };
return { vPlans, vDevTasks, vTCs, vBugs, totalDays, actualStart: actualStartDisplay, actualEnd: actualEndDisplay };
}, [version, plans, devTasks, testCases, bugs, requirements]);
// 状态胶囊数据 — 与版本详情一致
@@ -185,7 +194,9 @@ function VersionCard({ version, progress, plans, devTasks, testCases, bugs, requ
<span className={`text-[11px] px-2 py-0.5 rounded-full ${displayBg}`}>{displayStatus}</span>
<span className="flex-1 text-[11px] text-[var(--ink-muted)] flex items-center gap-1">
<Calendar className="h-3 w-3" />
{version.startDate ?? '-'} {version.releaseDate ?? '-'}
{versionData.actualStart ?? version.startDate ?? '-'}
<span className="mx-1"></span>
{versionData.actualEnd ?? version.releaseDate ?? '-'}
<span className="ml-1"> {totalDays} </span>
</span>
<ChevronDown className={`h-3.5 w-3.5 text-[var(--ink-muted)] transition-transform ${expanded ? 'rotate-180' : ''}`} />
@@ -212,11 +223,19 @@ function VersionCard({ version, progress, plans, devTasks, testCases, bugs, requ
<span className="text-[11px] tabular-nums text-[var(--ink-muted)]">{progress}%</span>
</div>
</div>
<div className="mb-3"><CapsuleStages /></div>
<div className="mb-3"><CapsuleStages stageProgress={stageProgress} /></div>
<div className="flex items-center justify-between text-[11px] text-[var(--ink-muted)] mb-3 pb-3 border-b border-[var(--line-soft)]">
<span className="flex items-center gap-1">
<Calendar className="h-3 w-3" />
{version.startDate ?? '-'} {version.expectedReleaseDate ?? '-'}
{versionData.actualStart ?? version.startDate ?? '-'}
<span className="mx-1"></span>
{version.expectedReleaseDate ?? '-'}
{versionData.actualEnd && (
<>
<span className="mx-1">|</span>
{versionData.actualEnd}
</>
)}
</span>
<span className="flex items-center gap-1">
<Clock className="h-3 w-3" /> {totalDays}