fix(findings): 补齐「按资产」视图的 mock,修两处标签重复

demo 模式(NEXT_PUBLIC_MOCK=1)下资产树接口没有实现,点开是空白。

- mock findings 关联到 fixture 里已有的资产:一条挂两个资产(验证父节点不重复
  计数)、一条不挂(演示「未关联资产」桶)
- mock handler 实现 asset-tree,并在平铺/分组两个列表分支接上 asset_scope。
  父子优先级、祖先补齐、去重计数、企业层出现条件都与 db/finding_assets.go
  一致;顺带把三处重复的筛选链抽成 mockFilterFindings
- 没有 URL 的服务(SMB、非 HTTP 端口)标签回退成裸 IP,与宿主那行显示得一模
  一样 —— 后端与 mock 都改为补端口(10.10.10.20:8080)
- 接口挂在 host:port 形式的服务下时没触发简写,仍显示完整 URL。宿主判断统一
  成解析后的 host,现在显示 /script

跑 mock handler 实测:17 个节点逐个对账「树上 total == 该节点子树查出的条数」,
无不一致。
This commit is contained in:
Autumn-27 committed 2026-08-31 11:10:47 -04:00
1 parent 23cfb9ed4e
commit 48e14e8cf2
4 files changed
+352 -33

No files matched your search

+8 -1
View File
@@ -76,8 +76,15 @@ func (a *assetRow) coverageNode() CoverageGraphNode {
}
}
// label 复用覆盖图的标签规则(URL > domain > ip > app_name > root_domain)。
// label 复用覆盖图的标签规则(URL > domain > ip > app_name > root_domain),但没有
// URL 的服务(SMB、非 HTTP 端口等)要补上端口:否则它的标签会和宿主 IP/域名那行
// 一模一样,树上父子两行看起来完全重复。
func (a *assetRow) label() string {
if a.kind == "service" && a.url == "" {
if host, port := a.hostPort(); host != "" && port > 0 {
return host + ":" + strconv.Itoa(port)
}
}
n := a.coverageNode()
n.Key = assetKey(a.id)
return coverageNodeLabel(&n)