diff --git a/backend/database.py b/backend/database.py index 4db82be..a522b83 100644 --- a/backend/database.py +++ b/backend/database.py @@ -1422,3 +1422,14 @@ def _migrate(conn_factory): ); """) logger.info("Migration: route_suggest_usage Tabelle bereit.") + + # ORS tägliche Gesamtaufrufe (für Admin-Dashboard) + existing_ors = conn.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='ors_daily_total'").fetchone() + if not existing_ors: + conn.executescript(""" + CREATE TABLE ors_daily_total ( + date TEXT PRIMARY KEY, + count INTEGER NOT NULL DEFAULT 0 + ); + """) + logger.info("Migration: ors_daily_total erstellt.") diff --git a/backend/routes/admin.py b/backend/routes/admin.py index 43e944a..ae379a8 100644 --- a/backend/routes/admin.py +++ b/backend/routes/admin.py @@ -853,6 +853,54 @@ async def admin_delete_zuchter(zuchter_id: int, user=Depends(require_mod)): # ------------------------------------------------------------------ # POST /api/admin/media/generate-previews — Previews für Bestandsmedien # ------------------------------------------------------------------ +@router.get("/ors/stats") +async def ors_stats(user=Depends(require_mod)): + """ORS-Routenvorschlag Statistiken für Admin-Panel.""" + with db() as conn: + # Heute + today = __import__('datetime').date.today().isoformat() + today_row = conn.execute( + "SELECT COALESCE(count,0) as count FROM ors_daily_total WHERE date=?", (today,) + ).fetchone() + today_count = today_row["count"] if today_row else 0 + + # Letzte 30 Tage (Verlauf) + daily_history = conn.execute(""" + SELECT date, count FROM ors_daily_total + WHERE date >= DATE('now', '-29 days') + ORDER BY date ASC + """).fetchall() + + # Letzte 8 Wochen (Wochensummen aus route_suggest_usage) + weekly_totals = conn.execute(""" + SELECT week, SUM(count) as count + FROM route_suggest_usage + WHERE week >= DATE('now', '-56 days') + GROUP BY week ORDER BY week ASC + """).fetchall() + + # Top-Nutzer (alle Zeiten) + top_users = conn.execute(""" + SELECT u.name, u.email, + SUM(r.count) as total, + MAX(r.week) as last_week + FROM route_suggest_usage r + JOIN users u ON u.id = r.user_id + GROUP BY r.user_id + ORDER BY total DESC + LIMIT 15 + """).fetchall() + + return { + "today_count": today_count, + "today_limit": 2000, + "daily_history": [{"date": r["date"], "count": r["count"]} for r in daily_history], + "weekly_totals": [{"week": r["week"], "count": r["count"]} for r in weekly_totals], + "top_users": [{"name": r["name"], "email": r["email"], + "total": r["total"], "last_week": r["last_week"]} for r in top_users], + } + + @router.post("/media/generate-previews") async def generate_media_previews(user=Depends(require_admin)): """Generiert fehlende _preview.jpg für alle Bilder in /data/media.""" diff --git a/backend/routes/routen.py b/backend/routes/routen.py index f812284..6755ccc 100644 --- a/backend/routes/routen.py +++ b/backend/routes/routen.py @@ -283,6 +283,14 @@ async def suggest_route(data: SuggestRequest, user=Depends(get_current_user)): """, (user["id"], week_start)) current_count += 1 + # Täglichen Gesamtzähler hochzählen (für Admin-Stats) + today_str = _dt.date.today().isoformat() + with db() as conn: + conn.execute(""" + INSERT INTO ors_daily_total (date, count) VALUES (?, 1) + ON CONFLICT(date) DO UPDATE SET count = count + 1 + """, (today_str,)) + weekly_remaining = None if is_privileged else max(0, WEEKLY_LIMIT - current_count) return { diff --git a/backend/static/js/app.js b/backend/static/js/app.js index c7159df..210e83a 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '461'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '462'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const App = (() => { diff --git a/backend/static/js/pages/admin.js b/backend/static/js/pages/admin.js index 8ba1363..f54865d 100644 --- a/backend/static/js/pages/admin.js +++ b/backend/static/js/pages/admin.js @@ -903,6 +903,7 @@ window.Page_admin = (() => { ${UI.icon('arrows-clockwise')} Aktualisieren +
| Name | +Gesamt | +Letzte Woche | +
|---|