{"slug":"ga4-dashboard","total":4,"limit":100,"offset":0,"since":null,"commits":[{"hash":"3942604","date":"2026-08-04 15:48:21 -0700","author":"Steve Abrams","subject":"chore: lint (drop unused import), v1.0.1 (session close)","body":""},{"hash":"80a2fa1","date":"2026-08-04 14:04:05 -0700","author":"Steve Abrams","subject":"auto-save: 2026-08-04T14:04:01 (1 files) — etl.py","body":""},{"hash":"464db7f","date":"2026-08-04 14:02:51 -0700","author":"Steve","subject":"Fix A: duplicate-domain dedup; Fix B: wire table column sort","body":"Fix A (etl.py): after building the results list, normalize each property's\ndomain (lowercase, strip scheme/www./trailing-slash) and group by normalized\nkey. For any domain shared by >1 property, pick the canonical as the one with\nthe highest sessions_7d (tie-break: newest create_time) and set\nduplicate_domain=True/canonical=False on the rest. Every entry now carries\nboth fields. ETL run confirmed 10 duplicates flagged across 126 properties.\n\nFix A (server.js): active-site headline count now excludes non-canonical\nduplicates (54 real active vs. inflated 64). filterData() respects a\n\"Hide duplicates\" checkbox (default checked, persisted to localStorage).\nDuplicate cards and table rows get an opacity-0.6 \"is-dup\" class and a\nmuted \"dup\" badge.\n\nFix B (server.js): table <th> headers wired with onclick=\"tableSort(key)\".\nAdded colValue(), NUMERIC_COLS, sortByState(), and tableSort() — numeric\ncols sort descending by default, text cols A-Z. Active sort header gets\n.sorted class + directional arrow. render() uses sortByState() when a\ncolumn sort is active in table mode.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"},{"hash":"f917b8b","date":"2026-08-04 13:49:53 -0700","author":"Steve Abrams","subject":"Add GA4 fleet traffic dashboard (local, port 9710)","body":"ETL script (etl.py) auto-discovers all accounts + properties via GA4 Admin API,\npulls 7d + 30d traffic metrics, writes cache/data.json. Server (server.js) serves\nthe cache instantly with basic-auth, sort, density slider, grid/table toggle, and\ndrill-down links to GA4 reports. 126 properties across 2 accounts, 0 errors, $0 cost.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n"}]}