更新: 2 个文件 - 2026-03-17 02:15:00
这个提交包含在:
@@ -90,6 +90,12 @@ def validate(source_map: Dict[str, Any]) -> List[str]:
|
||||
GENERATED_DIR / "latest-ingest.md",
|
||||
GENERATED_DIR / "run-summary.json",
|
||||
GENERATED_DIR / "dashboard" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "overview" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "runs" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "systems" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "architecture" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "docs" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "data" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "legacy" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "summary.json",
|
||||
GENERATED_DIR / "dashboard" / "systems.json",
|
||||
@@ -120,6 +126,12 @@ def validate(source_map: Dict[str, Any]) -> List[str]:
|
||||
|
||||
runtime_files = [
|
||||
GENERATED_DIR / "dashboard" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "overview" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "runs" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "systems" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "architecture" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "docs" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "data" / "index.html",
|
||||
GENERATED_DIR / "dashboard" / "assets" / "app.js",
|
||||
GENERATED_DIR / "dashboard" / "assets" / "styles.css",
|
||||
GENERATED_DIR / "dashboard" / "legacy" / "index.html",
|
||||
|
||||
@@ -18,6 +18,7 @@ LEGACY_TEMPLATE_DIR = TEMPLATES_DIR / "legacy"
|
||||
LOVART_VENDOR_MANIFEST = LOVART_TEMPLATE_DIR / "vendor" / "source-manifest.json"
|
||||
ROOT_JSON_FILES = ["summary.json", "runs.json", "systems.json", "advisories.json", "profiles.json"]
|
||||
ROOT_JSON_FILES.append("architecture.json")
|
||||
SECTION_ROUTE_DIRS = ["overview", "runs", "systems", "architecture", "data"]
|
||||
|
||||
CATEGORY_LABELS = {
|
||||
"cms": "CMS / 内容平台",
|
||||
@@ -69,7 +70,7 @@ def _dashboard_ref(run: Dict[str, Any], ref: str) -> str:
|
||||
try:
|
||||
bundle_dir = Path(run["report_refs"]["bundle_dir"]).resolve()
|
||||
relative = Path(ref).resolve().relative_to(bundle_dir)
|
||||
return f"./runs/{run['run_id']}/{relative.as_posix()}"
|
||||
return f"/runs/{run['run_id']}/{relative.as_posix()}"
|
||||
except Exception:
|
||||
return ref
|
||||
|
||||
@@ -215,27 +216,32 @@ def _build_architecture_data(summary: Dict[str, Any], source_map: Dict[str, Any]
|
||||
repro_by_system = {item.get("system_id"): item for item in (repro_map.get("systems", []) or []) if item.get("system_id")}
|
||||
|
||||
route_links = [
|
||||
_link("正式工作台", "./index.html", "本地化主 UI,默认入口。"),
|
||||
_link("旧版工作台", "./legacy/index.html", "保留的 legacy 回退入口。"),
|
||||
_link("项目功能文档", "./docs/project-features.html", "项目能力、目录结构与自动化链路总览。"),
|
||||
_link("前端设计文档", "./docs/frontend-dashboard-design.html", "当前本地工作台的交互与视觉规范。"),
|
||||
_link("安全编码索引", "./docs/secure-code-index.html", "secure-code 修复库本地镜像。"),
|
||||
_link("仓库入口镜像", "./docs/root-readme.html", "仓库根 README 的本地镜像。"),
|
||||
_link("授权模型", "./docs/authorization-model.html", "允许目标范围、全局原则与记录要求。"),
|
||||
_link("source-map 真值", "./docs/source-map.html", "系统覆盖、来源和输出目录真值。"),
|
||||
_link("repro-map 真值", "./docs/repro-map.html", "复现族路由、浏览器要求和日志策略。"),
|
||||
_link("覆盖矩阵", "./docs/coverage-matrix.html", "自动生成覆盖摘要的本地镜像。"),
|
||||
_link("设计来源清单", "./docs/design-source.html", "Lovart 模板本地 vendor manifest。"),
|
||||
_link("架构库镜像", "./docs/architecture-library.html", "当前架构库的结构化镜像页。"),
|
||||
_link("总览首页", "/overview/index.html", "工作台总览、最新运行和全局摘要。"),
|
||||
_link("运行中心", "/runs/index.html", "运行队列、详情、证据和日志入口。"),
|
||||
_link("系统分组", "/systems/index.html", "按系统和分类浏览覆盖情况。"),
|
||||
_link("架构库", "/architecture/index.html", "查看控制面、数据层和授权边界。"),
|
||||
_link("文档中心", "/docs/index.html", "集中查看项目文档、本地镜像和说明。"),
|
||||
_link("数据中心", "/data/index.html", "查看 summary、runs、systems 等 JSON 入口。"),
|
||||
_link("旧版工作台", "/legacy/index.html", "保留的 legacy 回退入口。"),
|
||||
_link("项目功能文档", "/docs/project-features.html", "项目能力、目录结构与自动化链路总览。"),
|
||||
_link("前端设计文档", "/docs/frontend-dashboard-design.html", "当前本地工作台的交互与视觉规范。"),
|
||||
_link("安全编码索引", "/docs/secure-code-index.html", "secure-code 修复库本地镜像。"),
|
||||
_link("仓库入口镜像", "/docs/root-readme.html", "仓库根 README 的本地镜像。"),
|
||||
_link("授权模型", "/docs/authorization-model.html", "允许目标范围、全局原则与记录要求。"),
|
||||
_link("source-map 真值", "/docs/source-map.html", "系统覆盖、来源和输出目录真值。"),
|
||||
_link("repro-map 真值", "/docs/repro-map.html", "复现族路由、浏览器要求和日志策略。"),
|
||||
_link("覆盖矩阵", "/docs/coverage-matrix.html", "自动生成覆盖摘要的本地镜像。"),
|
||||
_link("设计来源清单", "/docs/design-source.html", "Lovart 模板本地 vendor manifest。"),
|
||||
_link("架构库镜像", "/docs/architecture-library.html", "当前架构库的结构化镜像页。"),
|
||||
]
|
||||
|
||||
data_links = [
|
||||
_link("summary.json", "./summary.json", "全局摘要、状态分布和最近失败。"),
|
||||
_link("runs.json", "./runs.json", "最近 run 的结构化详情。"),
|
||||
_link("systems.json", "./systems.json", "系统级覆盖与浏览器证据摘要。"),
|
||||
_link("advisories.json", "./advisories.json", "advisory 元数据与来源。"),
|
||||
_link("profiles.json", "./profiles.json", "repro profile 元数据。"),
|
||||
_link("architecture.json", "./architecture.json", "当前架构库结构化 JSON。"),
|
||||
_link("summary.json", "/summary.json", "全局摘要、状态分布和最近失败。"),
|
||||
_link("runs.json", "/runs.json", "最近 run 的结构化详情。"),
|
||||
_link("systems.json", "/systems.json", "系统级覆盖与浏览器证据摘要。"),
|
||||
_link("advisories.json", "/advisories.json", "漏洞条目元数据与来源。"),
|
||||
_link("profiles.json", "/profiles.json", "复现档案元数据。"),
|
||||
_link("architecture.json", "/architecture.json", "当前架构库结构化 JSON。"),
|
||||
]
|
||||
|
||||
category_items: List[Dict[str, Any]] = []
|
||||
@@ -492,7 +498,13 @@ def _build_architecture_data(summary: Dict[str, Any], source_map: Dict[str, Any]
|
||||
"fields": [
|
||||
_field("工作台根目录", "08-threat-intel/generated/dashboard/"),
|
||||
_field("运行归档根目录", "06-case-studies/generated-runs/<run-id>/"),
|
||||
_field("工作台入口", "/index.html"),
|
||||
_field("默认入口", "/index.html"),
|
||||
_field("总览入口", "/overview/index.html"),
|
||||
_field("运行入口", "/runs/index.html"),
|
||||
_field("系统入口", "/systems/index.html"),
|
||||
_field("架构入口", "/architecture/index.html"),
|
||||
_field("文档入口", "/docs/index.html"),
|
||||
_field("数据入口", "/data/index.html"),
|
||||
_field("旧版入口", "/legacy/index.html"),
|
||||
],
|
||||
},
|
||||
@@ -630,7 +642,7 @@ def _dashboard_doc_page(title: str, body: str, description: str) -> str:
|
||||
<main>
|
||||
<div class="panel">
|
||||
<div class="actions">
|
||||
<a class="chip" href="../index.html">返回工作台</a>
|
||||
<a class="chip" href="/overview/index.html">返回工作台</a>
|
||||
</div>
|
||||
<h1>{html.escape(title)}</h1>
|
||||
<div class="meta">{html.escape(description)}</div>
|
||||
@@ -763,6 +775,18 @@ def _render_root_dashboard_shell() -> None:
|
||||
_copy_tree(LOVART_TEMPLATE_DIR / "assets", assets_dir)
|
||||
|
||||
|
||||
def _render_section_dashboard_shells() -> None:
|
||||
source_index = LOVART_TEMPLATE_DIR / "index.html"
|
||||
for section in SECTION_ROUTE_DIRS:
|
||||
section_dir = DASHBOARD_DIR / section
|
||||
_remove_path(section_dir)
|
||||
ensure_dir(section_dir)
|
||||
shutil.copy2(source_index, section_dir / "index.html")
|
||||
docs_dir = DASHBOARD_DIR / "docs"
|
||||
ensure_dir(docs_dir)
|
||||
shutil.copy2(source_index, docs_dir / "index.html")
|
||||
|
||||
|
||||
def _render_legacy_dashboard_shell() -> None:
|
||||
legacy_dir = DASHBOARD_DIR / "legacy"
|
||||
_remove_path(legacy_dir)
|
||||
@@ -951,6 +975,7 @@ def render_dashboard() -> Dict[str, str]:
|
||||
runs = load_json_dir(RUNS_DIR)
|
||||
source_map = read_yaml(SOURCE_MAP_PATH, default={}) or {}
|
||||
repro_map = read_yaml(REPRO_MAP_PATH, default={}) or {}
|
||||
source_system_map = {item["system_id"]: item for item in source_map.get("systems", []) if item.get("system_id")}
|
||||
advisory_map = {item["canonical_id"]: item for item in advisory_records if item.get("canonical_id")}
|
||||
profile_map = load_profiles()
|
||||
|
||||
@@ -971,6 +996,9 @@ def render_dashboard() -> Dict[str, str]:
|
||||
"browser_required": 0,
|
||||
"browser_present": 0,
|
||||
"latest_update": "",
|
||||
"category": source_system_map.get(advisory["system_id"], {}).get("category", advisory.get("category")),
|
||||
"tier": source_system_map.get(advisory["system_id"], {}).get("tier"),
|
||||
"output_dir": source_system_map.get(advisory["system_id"], {}).get("output_dir"),
|
||||
},
|
||||
)
|
||||
system["total"] += 1
|
||||
@@ -1005,10 +1033,10 @@ def render_dashboard() -> Dict[str, str]:
|
||||
}
|
||||
request_only_refs = [ref for ref in item.get("request_log_refs", []) if ref not in item.get("baseline_refs", [])]
|
||||
cloned["dashboard_refs"] = {
|
||||
"report_html": f"./runs/{item['run_id']}/report.html",
|
||||
"report_md": f"./runs/{item['run_id']}/report.md",
|
||||
"timeline": f"./runs/{item['run_id']}/timeline.mmd",
|
||||
"bundle": f"./runs/{item['run_id']}/run.json",
|
||||
"report_html": f"/runs/{item['run_id']}/report.html",
|
||||
"report_md": f"/runs/{item['run_id']}/report.md",
|
||||
"timeline": f"/runs/{item['run_id']}/timeline.mmd",
|
||||
"bundle": f"/runs/{item['run_id']}/run.json",
|
||||
}
|
||||
cloned["browser_evidence"] = browser_evidence
|
||||
cloned["browser_links"] = [_dashboard_ref(item, ref) for ref in item.get("browser_refs", [])]
|
||||
@@ -1075,11 +1103,14 @@ def render_dashboard() -> Dict[str, str]:
|
||||
_write_dashboard_docs(architecture)
|
||||
_write_design_source_manifest()
|
||||
_render_root_dashboard_shell()
|
||||
_render_section_dashboard_shells()
|
||||
_render_legacy_dashboard_shell()
|
||||
|
||||
return {
|
||||
"dashboard_dir": str(DASHBOARD_DIR),
|
||||
"index": str(DASHBOARD_DIR / "index.html"),
|
||||
"overview_index": str(DASHBOARD_DIR / "overview" / "index.html"),
|
||||
"runs_index": str(DASHBOARD_DIR / "runs" / "index.html"),
|
||||
"legacy_index": str(DASHBOARD_DIR / "legacy" / "index.html"),
|
||||
"summary_json": str(DASHBOARD_DIR / "summary.json"),
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户