From aed0cd5d7f4438d447be143b18db88a81202de78 Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 4 Jul 2026 16:06:39 +0200 Subject: [PATCH] Analytika: /auth sa uz nesleduje -- 1:1 duplicita landing eventu Na /auth sa da dostat len plnym loadom stranky (vsetky interne redirecty nan su REPLACE a beacon ich skipuje) a kazdy plny load uz posiela event landing. Kazdy riadok /auth by tak mal dvojicku z toho isteho loadu. Skip na frontende aj v _SKIPPED_PATHS (pokryje aj stare cache-ovane verzie frontendu). Stare /auth riadky v DB ostavaju. Co-Authored-By: Claude Fable 5 --- api/stats.py | 9 ++++++--- frontend/src/App.tsx | 4 ++++ tests/test_stats.py | 5 +++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/api/stats.py b/api/stats.py index e3ff3c9..2afd276 100644 --- a/api/stats.py +++ b/api/stats.py @@ -44,9 +44,12 @@ def _country_for_ip(ip: str) -> str: _DYNAMIC_PATH_PREFIXES = ("/lobby", "/game") # Tieto (po normalizacii) sa vobec nezaznamenavaju -- vysoka frekvencia (kazda -# akcia v hre) bez analytickej hodnoty. Ostava len /auth, /history a pomenovane -# eventy (napr. "rules_view", "login"), ktore sem nespadaju. -_SKIPPED_PATHS = frozenset({"/", "/lobby", "/game"}) +# akcia v hre) bez analytickej hodnoty. "/auth" je zas 1:1 duplicita eventu +# "landing": dostat sa nan da len plnym loadom stranky (interne redirecty nan +# su REPLACE a beacon ich skipuje), a kazdy plny load uz posiela "landing" +# (main.tsx). Ostava len /history a pomenovane eventy (napr. "landing", +# "rules_view", "login"), ktore sem nespadaju. +_SKIPPED_PATHS = frozenset({"/", "/auth", "/lobby", "/game"}) def _normalize_path(path: str) -> str: diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ef9ec3e..4e42db6 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -78,11 +78,15 @@ function AppInner() { // analytical value; the backend drops these anyway (api/stats.py _SKIPPED_PATHS). // The visitor's first touch (incl. landings on "/", which both skips would // otherwise swallow) is captured by trackLanding() in main.tsx instead. + // Skip /auth too: it's only ever reached by a full page load (every in-app + // redirect to it is REPLACE), so each /auth row would be a 1:1 duplicate of + // the landing event fired by that same load. useEffect(() => { if (navigationType === 'REPLACE') return; if (location.pathname.startsWith('/admin')) return; if ( location.pathname === '/' || + location.pathname === '/auth' || location.pathname.startsWith('/lobby') || location.pathname.startsWith('/game') ) { diff --git a/tests/test_stats.py b/tests/test_stats.py index fa25af8..e5e326e 100644 --- a/tests/test_stats.py +++ b/tests/test_stats.py @@ -112,7 +112,8 @@ class StatsCase(unittest.TestCase): def test_skipped_paths_not_recorded(self): # "/", "/lobby" a "/game" (aj s dynamickym ID) sa vobec nezapisuju -- - # vysoka frekvencia bez analytickej hodnoty (api/stats.py _SKIPPED_PATHS). + # vysoka frekvencia bez analytickej hodnoty; "/auth" zas preto, ze je + # to vzdy 1:1 duplicita eventu "landing" (api/stats.py _SKIPPED_PATHS). async def _count(): from sqlalchemy import func, select as sa_select @@ -125,7 +126,7 @@ class StatsCase(unittest.TestCase): ).scalar() before = run(_count()) - for path in ("/", "/lobby", "/lobby/abc-123", "/game", "/game/xyz-789"): + for path in ("/", "/auth", "/lobby", "/lobby/abc-123", "/game", "/game/xyz-789"): run(stats.record_pageview(path=path, referrer="", user_agent=CHROME_UA)) after = run(_count()) self.assertEqual(after, before)