增强系统级实体覆盖摘要与工作台索引
这个提交包含在:
@@ -599,19 +599,55 @@ def build_entity_views(source_map: Dict[str, Any], advisories: List[AdvisoryReco
|
||||
"system_id": entity["root_system_id"],
|
||||
"display_name": systems.get(entity["root_system_id"], {}).get("display_name", entity["root_system_id"]),
|
||||
"cataloged_entity_total": 0,
|
||||
"child_entity_total": 0,
|
||||
"candidate_entity_total": 0,
|
||||
"workflow_complete_count": 0,
|
||||
"version_mapped_count": 0,
|
||||
"official_source_covered_count": 0,
|
||||
"history_full_complete_count": 0,
|
||||
"latest_green_count": 0,
|
||||
"version_gap_entity_count": 0,
|
||||
"workflow_gap_entity_count": 0,
|
||||
"plugin_total": 0,
|
||||
"entity_type_counts": {},
|
||||
"top_entities": [],
|
||||
"backlog_preview": [],
|
||||
},
|
||||
)
|
||||
summary["cataloged_entity_total"] += 1
|
||||
if entity["entity_type"] != "system":
|
||||
summary["child_entity_total"] += 1
|
||||
summary["entity_type_counts"][entity["entity_type"]] = summary["entity_type_counts"].get(entity["entity_type"], 0) + 1
|
||||
summary["workflow_complete_count"] += 1 if entity["advisory_count"] and entity["workflow_complete_advisory_count"] >= entity["advisory_count"] else 0
|
||||
summary["version_mapped_count"] += 1 if entity["advisory_count"] and entity["version_mapped_advisory_count"] >= entity["advisory_count"] else 0
|
||||
summary["official_source_covered_count"] += 1 if entity["official_source_covered"] else 0
|
||||
summary["history_full_complete_count"] += 1 if entity.get("history_backfill_status") == "complete" else 0
|
||||
summary["latest_green_count"] += 1 if entity.get("latest_sync_status") == "green" else 0
|
||||
summary["version_gap_entity_count"] += 1 if entity.get("advisory_count") and entity.get("version_mapped_advisory_count", 0) < entity.get("advisory_count", 0) else 0
|
||||
summary["workflow_gap_entity_count"] += 1 if entity.get("advisory_count") and entity.get("workflow_complete_advisory_count", 0) < entity.get("advisory_count", 0) else 0
|
||||
if entity["entity_type"] in PLUGINISH_ENTITY_TYPES:
|
||||
summary["plugin_total"] += 1
|
||||
|
||||
for system_id, summary in system_summary.items():
|
||||
ranked_entities = sorted(
|
||||
[
|
||||
entity
|
||||
for entity in entities.values()
|
||||
if entity["root_system_id"] == system_id and entity["entity_type"] != "system"
|
||||
],
|
||||
key=lambda item: (-(item.get("advisory_count") or 0), item["entity_type"], item["display_name"].lower()),
|
||||
)
|
||||
summary["top_entities"] = [
|
||||
{
|
||||
"entity_id": entity["entity_id"],
|
||||
"entity_type": entity["entity_type"],
|
||||
"display_name": entity["display_name"],
|
||||
"advisory_count": entity.get("advisory_count", 0),
|
||||
"history_backfill_status": entity.get("history_backfill_status"),
|
||||
"latest_sync_status": entity.get("latest_sync_status"),
|
||||
}
|
||||
for entity in ranked_entities[:5]
|
||||
]
|
||||
for candidate in candidate_backlog:
|
||||
system_summary.setdefault(
|
||||
candidate["root_system_id"],
|
||||
@@ -619,13 +655,31 @@ def build_entity_views(source_map: Dict[str, Any], advisories: List[AdvisoryReco
|
||||
"system_id": candidate["root_system_id"],
|
||||
"display_name": systems.get(candidate["root_system_id"], {}).get("display_name", candidate["root_system_id"]),
|
||||
"cataloged_entity_total": 0,
|
||||
"child_entity_total": 0,
|
||||
"candidate_entity_total": 0,
|
||||
"workflow_complete_count": 0,
|
||||
"version_mapped_count": 0,
|
||||
"official_source_covered_count": 0,
|
||||
"history_full_complete_count": 0,
|
||||
"latest_green_count": 0,
|
||||
"version_gap_entity_count": 0,
|
||||
"workflow_gap_entity_count": 0,
|
||||
"plugin_total": 0,
|
||||
"entity_type_counts": {},
|
||||
"top_entities": [],
|
||||
"backlog_preview": [],
|
||||
},
|
||||
)["candidate_entity_total"] += 1
|
||||
preview = system_summary[candidate["root_system_id"]]["backlog_preview"]
|
||||
if len(preview) < 5:
|
||||
preview.append(
|
||||
{
|
||||
"candidate_id": candidate["candidate_id"],
|
||||
"display_name": candidate["display_name"],
|
||||
"entity_type": candidate["entity_type"],
|
||||
"risk": candidate["risk"],
|
||||
}
|
||||
)
|
||||
|
||||
cataloged_entities = [entity for entity in entities.values() if entity.get("status") == "cataloged"]
|
||||
history_full_complete_count = len(
|
||||
|
||||
@@ -534,6 +534,7 @@ def render_registry(
|
||||
) -> None:
|
||||
run_map = latest_runs_by_advisory()
|
||||
entity_views = build_entity_views(source_map, advisories)
|
||||
entity_summary_map = {item["system_id"]: item for item in entity_views["completeness"]["systems"]}
|
||||
grouped: Dict[str, List[AdvisoryRecord]] = defaultdict(list)
|
||||
advisory_payloads: Dict[str, Dict[str, Any]] = {}
|
||||
for advisory in advisories:
|
||||
@@ -556,6 +557,7 @@ def render_registry(
|
||||
items = grouped.get(system_id, [])
|
||||
merged_items = [_merged_item(item, run_map) for item in items]
|
||||
counts = _status_counts(merged_items)
|
||||
entity_summary = entity_summary_map.get(system_id, {})
|
||||
system_payloads[f"{system_id}.json"] = {
|
||||
"system_id": system_id,
|
||||
"display_name": system["display_name"],
|
||||
@@ -571,6 +573,7 @@ def render_registry(
|
||||
"verified_synthetic": counts["verified_synthetic"],
|
||||
"blocked_count": counts["blocked"],
|
||||
"manual_count": counts["manual"],
|
||||
"entity_summary": entity_summary,
|
||||
"items": [item.canonical_id for item in sorted(items, key=lambda item: item.published_at or "", reverse=True)],
|
||||
}
|
||||
if selected_system_ids:
|
||||
|
||||
@@ -162,6 +162,7 @@ def validate(source_map: Dict[str, Any]) -> List[str]:
|
||||
GENERATED_DIR / "dashboard" / "advisories.json",
|
||||
GENERATED_DIR / "dashboard" / "profiles.json",
|
||||
GENERATED_DIR / "dashboard" / "architecture.json",
|
||||
GENERATED_DIR / "dashboard" / "entities.json",
|
||||
GENERATED_DIR / "dashboard" / "assets" / "app.js",
|
||||
GENERATED_DIR / "dashboard" / "assets" / "styles.css",
|
||||
GENERATED_DIR / "dashboard" / "assets" / "icons.svg",
|
||||
|
||||
在新工单中引用
屏蔽一个用户