From 70188b508c1904bf12ab7d0c82a2925e772bb5c6 Mon Sep 17 00:00:00 2001 From: toto Date: Thu, 9 Apr 2026 13:54:38 +0200 Subject: [PATCH] fix(dashboard): eliminate @apply CSS, fix status column, fix click propagation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Playwright testing revealed 3 critical bugs: 1. Tailwind CDN @apply with custom brand-* colors produces empty CSS rules, breaking ALL design components (kpi-card, data-table, badges, filter-btn, section-card, nav-item). Fix: replace all @apply directives with equivalent raw CSS values. 2. Traffic API and IP detail API reference non-existent 'status' column in http_logs table → HTTP 500 on /traffic and /ip/{ip}. Fix: remove status from SELECT, sort whitelist, filters, and templates. 3. Nested links (fmtJA4, fmtASN, fmtCountry, fmtBotName) inside clickable capture clicks, preventing row navigation to /ip/ detail. Fix: add event.stopPropagation() to all formatter links. Verified with Playwright: 10 pages × 0 JS errors, all tooltips hidden by default, sidebar toggle works, keyboard shortcuts (Alt+1-9, Alt+B), classification form saves to DB, campaign detail panel opens on click. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- services/dashboard/backend/routes/api.py | 12 ++-- .../dashboard/backend/templates/base.html | 58 ++++++++++--------- .../backend/templates/ip_detail.html | 5 +- .../dashboard/backend/templates/traffic.html | 9 +-- 4 files changed, 39 insertions(+), 45 deletions(-) diff --git a/services/dashboard/backend/routes/api.py b/services/dashboard/backend/routes/api.py index 6ebb03a..0e05f53 100644 --- a/services/dashboard/backend/routes/api.py +++ b/services/dashboard/backend/routes/api.py @@ -35,7 +35,7 @@ _SCORE_SORT_COLS = { "asn_org", "country_code", "browser_family", } _TRAFFIC_SORT_COLS = { - "time", "src_ip", "method", "status", "host", "path", "http_version", + "time", "src_ip", "method", "host", "path", "http_version", "header_user_agent", "ja4", "src_country_code", } _ORDER_VALUES = {"ASC", "DESC"} @@ -315,7 +315,7 @@ async def traffic( method: str | None = Query(None), host: str | None = Query(None), http_version: str | None = Query(None), - status: int | None = Query(None), + status: int | None = Query(None, description="Not implemented — reserved"), search: str | None = Query(None), ) -> dict[str, Any]: sort = _validate_sort(sort, _TRAFFIC_SORT_COLS, "time") @@ -337,10 +337,6 @@ async def traffic( where_clauses.append("http_version = {http_version:String}") params["http_version"] = http_version - if status is not None: - where_clauses.append("status = {status:UInt16}") - params["status"] = status - if search: where_clauses.append( "(toString(src_ip) LIKE {search:String} " @@ -358,7 +354,7 @@ async def traffic( ) rows = query( - f"SELECT time, toString(src_ip) AS src_ip, method, status, host, path, " + f"SELECT time, toString(src_ip) AS src_ip, method, host, path, " f"http_version, header_user_agent, ja4, src_country_code " f"FROM {_DB_LOGS}.http_logs " f"WHERE {where} ORDER BY {sort} {order} " @@ -406,7 +402,7 @@ async def ip_detail(ip: str) -> dict[str, Any]: ) http_logs = query( - f"SELECT time, method, status, host, path, http_version, header_user_agent, ja4 " + f"SELECT time, method, host, path, http_version, header_user_agent, ja4 " f"FROM {_DB_LOGS}.http_logs " "WHERE src_ip = toIPv4OrZero({ip:String}) " "AND time >= now() - INTERVAL 1 DAY " diff --git a/services/dashboard/backend/templates/base.html b/services/dashboard/backend/templates/base.html index 6983e76..3385fd6 100644 --- a/services/dashboard/backend/templates/base.html +++ b/services/dashboard/backend/templates/base.html @@ -23,7 +23,7 @@ } } -