feat(coverage): 覆盖图节点用 lucide 图标 + 精简 label + 抽屉展示关联意图/事实
- 节点图标 emoji → 平台一致的 lucide 图标(白色 SVG data URI,iconSrc)
- 图内 label:服务显示 端口·标题·状态码(不再完整 URL),端点只显示 path
- 点节点抽屉新增「关联意图/关联事实/关联发现」:按 exploration_anchors
反查本任务锚定该资产的节点
- db AssetRefs(assetID);server GET /api/tasks/{id}/asset-refs?asset_id=X
- types/api taskAssetRefs;抽屉按 node.asset_id 拉取渲染
Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
9c1591ad8e
commit
e35c766e6a
5 files changed
+218
-14
No files matched your search
@@ -484,6 +484,7 @@ func (s *Server) Handler() http.Handler {
|
||||
mux.HandleFunc("GET /api/tasks/{id}", s.getTask)
|
||||
mux.HandleFunc("GET /api/tasks/{id}/coverage", s.taskCoverage)
|
||||
mux.HandleFunc("GET /api/tasks/{id}/coverage-graph", s.taskCoverageGraph)
|
||||
mux.HandleFunc("GET /api/tasks/{id}/asset-refs", s.taskAssetRefs)
|
||||
mux.HandleFunc("GET /api/tasks/{id}/scope", s.taskScopeList)
|
||||
mux.HandleFunc("POST /api/tasks/{id}/control", s.control)
|
||||
mux.HandleFunc("POST /api/active", s.setActive)
|
||||
@@ -1130,6 +1131,40 @@ func (s *Server) taskCoverageGraph(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, 200, g)
|
||||
}
|
||||
|
||||
// taskAssetRefs returns the intents / facts / findings in this task anchored to a
|
||||
// given asset id — powers the coverage-graph node drawer's「关联意图 / 关联事实」。
|
||||
func (s *Server) taskAssetRefs(w http.ResponseWriter, r *http.Request) {
|
||||
t, ok := s.m.Task(r.PathValue("id"))
|
||||
if !ok {
|
||||
writeErr(w, 404, "task not found")
|
||||
return
|
||||
}
|
||||
assetID, _ := strconv.ParseInt(r.URL.Query().Get("asset_id"), 10, 64)
|
||||
if assetID <= 0 {
|
||||
writeErr(w, 400, "需要 asset_id")
|
||||
return
|
||||
}
|
||||
refs, err := t.Store.AssetRefs(assetID)
|
||||
if err != nil {
|
||||
writeErr(w, 500, err.Error())
|
||||
return
|
||||
}
|
||||
intents := []db.AssetRef{}
|
||||
facts := []db.AssetRef{}
|
||||
findings := []db.AssetRef{}
|
||||
for _, ref := range refs {
|
||||
switch ref.Kind {
|
||||
case "intent":
|
||||
intents = append(intents, ref)
|
||||
case "fact":
|
||||
facts = append(facts, ref)
|
||||
case "finding":
|
||||
findings = append(findings, ref)
|
||||
}
|
||||
}
|
||||
writeJSON(w, 200, map[string]any{"intents": intents, "facts": facts, "findings": findings})
|
||||
}
|
||||
|
||||
// taskScopeList returns a task's scope rows (coverage denominator sources).
|
||||
func (s *Server) taskScopeList(w http.ResponseWriter, r *http.Request) {
|
||||
t, ok := s.m.Task(r.PathValue("id"))
|
||||
|
||||
Reference in new issue
Block a user