Add self-hosted usage analytics: pageview tracking + admin stats dashboard

Records pageviews (path, referrer, browser/OS/device, IP, GeoIP country) via
a POST /api/track beacon into a new PageView table, and exposes aggregated
daily/breakdown stats behind a token-gated GET /api/admin/stats endpoint with
brute-force lockout. Frontend gets a /admin dashboard (charts + breakdown
tables) built on recharts, with a switchable per-day pageviews chart.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
tim
2026-07-01 19:43:10 +02:00
co-authored by Claude Sonnet 5
parent c59dca754f
commit 0845562a21
17 changed files with 1386 additions and 18 deletions
+7
View File
@@ -20,6 +20,13 @@ services:
environment:
# Async SQLAlchemy URL -> the Postgres service above (asyncpg driver).
DATABASE_URL: postgresql+asyncpg://bridzik:bridzik@db:5432/bridzik
# Shared secret for the self-hosted /api/admin/* stats endpoints.
ADMIN_TOKEN: tajneheslo
# Optional: IP -> country for /api/track. Drop a .mmdb file (GeoLite2 or
# a DB-IP/IP2Location Lite equivalent) at ./geoip/ -- it's already inside
# the ./:/app bind mount below, no extra volume entry needed. Missing
# file -> country is just recorded as "" (see api/stats.py:_country_for_ip).
GEOIP_DB_PATH: /app/geoip/GeoLite2-Country.mmdb
ports:
- "5000:5000"
volumes: