refactor(coverage): 覆盖度改按类型统计 + 新增 list_untested_assets 工具

- 去掉 backlog(避免把未测清单塞进提示词引导 plan),改由 plan 自行判断。
- Coverage 去 Backlog、加 by_type [{type,total,tested}];TaskCoverage 改 GROUP BY type,
  累加得总分母/总已测。
- 新增 db.ListUntestedAssets(范围内未测资产,可按类型过滤 + 分页)与 list_untested_assets
  工具(type + page/page_size,默认页大小 10),绑 planner、随 BuiltinToolSeeds 播种。
- graph_overview 的 coverage 现为 {denominator,tested,pct,by_type,note};note 提示按需调
  list_untested_assets 自行判断,不再推送 backlog。
- /api/tasks/{id}/coverage 去掉 backlog 参数;前端覆盖度卡改为按类型「已测/总数」徽章。

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
Autumn-27andClaude Opus 5 committed 2026-08-08 11:50:51 -04:00
1 parent aeadd0d48b
commit 4c4f65f40a
6 files changed
+144 -52

No files matched your search

@@ -57,7 +57,7 @@ export function OverviewTab({ taskId }: { taskId: string }) {
denominator: number;
tested: number;
pct: number | null;
backlog_sample: { id: number; type: string; label: string }[];
by_type: { type: string; total: number; tested: number }[];
} | null>(null);
React.useEffect(() => {
@@ -126,16 +126,16 @@ export function OverviewTab({ taskId }: { taskId: string }) {
</span>
</div>
{coverage.pct != null && <Progress value={Math.round(coverage.pct * 100)} />}
{coverage.backlog_sample.length > 0 && (
<div className="text-xs">
<div className="text-muted-foreground mb-1">未测(优先补测):</div>
<div className="flex flex-wrap gap-1">
{coverage.backlog_sample.slice(0, 12).map((a) => (
<span key={a.id} className="bg-muted rounded px-1.5 py-0.5 font-mono">
{a.label || a.type}
{coverage.by_type.length > 0 && (
<div className="flex flex-wrap gap-1.5 text-xs">
{coverage.by_type.map((b) => (
<span key={b.type} className="bg-muted rounded px-1.5 py-0.5">
<span className="text-muted-foreground">{b.type}</span>{" "}
<span className="tabular-nums font-medium">
{b.tested}/{b.total}
</span>
))}
</div>
</span>
))}
</div>
)}
</CardContent>