From 422137efa824691ee4d43042bcff41e505167272 Mon Sep 17 00:00:00 2001 From: OoO Date: Tue, 5 May 2026 21:46:28 +0800 Subject: [PATCH] test(observability): validate sidebar route coverage --- docs/guides/observability_ui_governance.md | 1 + scripts/check_observability_ui.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/docs/guides/observability_ui_governance.md b/docs/guides/observability_ui_governance.md index eab8575..7e5827f 100644 --- a/docs/guides/observability_ui_governance.md +++ b/docs/guides/observability_ui_governance.md @@ -67,6 +67,7 @@ Guard 會檢查: - 側欄是否維持暖深咖啡背景與第二/三層足夠對比。 - Topbar 是否仍載入觀測台 CSS 與健康 indicator。 - 10 個觀測頁的 `active_page`、側欄 URL、側欄 label、`momo-observability-mode` 掛載清單是否一一對齊。 +- 10 個側欄 URL 是否都在 `routes/admin_observability_routes.py` 有對應 Flask route。 ### 2. Production 10 頁 HTTP 巡檢 diff --git a/scripts/check_observability_ui.py b/scripts/check_observability_ui.py index a8e1da9..9381326 100644 --- a/scripts/check_observability_ui.py +++ b/scripts/check_observability_ui.py @@ -246,6 +246,15 @@ def scan_nav_contract() -> list[str]: if active_page not in base_text: findings.append(f"{BASE_PATH}: momo-observability-mode list missing `{active_page}`") + route_suffix = url.replace("/observability", "", 1) or "/" + route_pattern = re.compile( + r"@admin_observability_bp\.route\(\s*['\"]" + + re.escape(route_suffix) + + r"['\"]" + ) + if route_text and not route_pattern.search(route_text): + findings.append(f"{ROUTE_PATH}: missing route `{route_suffix}` for `{label}`") + sidebar_observability_links = set(re.findall(r'href="(/observability/[^"]+)"', shell_text)) expected_links = {url for _, _, url, _ in OBSERVABILITY_NAV_ITEMS} extra_links = sorted(sidebar_observability_links - expected_links)