From 7c0044de3753e57f7edd4ee6a92ea38382eea7eb Mon Sep 17 00:00:00 2001 From: Petru Rares Sincraian Date: Sat, 10 Jan 2026 20:54:57 +0100 Subject: [PATCH] feat: add packages admin view showing tracked packages with analytics Add a new admin view at /backoffice/packages that displays all tracked packages with aggregated statistics including package name, number of events, and last ingested timestamp. The view includes stats cards for total packages and total events, a sortable table ordered by event count, and navigation links in both mobile and desktop menus. Co-Authored-By: Claude Haiku 4.5 --- app/src/api/backoffice.py | 34 +++++++++++++ app/src/templates/backoffice/layout.html | 4 ++ app/src/templates/backoffice/packages.html | 57 ++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 app/src/templates/backoffice/packages.html diff --git a/app/src/api/backoffice.py b/app/src/api/backoffice.py index d7f0dba..4980f58 100644 --- a/app/src/api/backoffice.py +++ b/app/src/api/backoffice.py @@ -235,3 +235,37 @@ async def backoffice_events( "unique_packages_from_events": unique_packages_from_events or 0, }, ) + + +@router.get("/packages", response_class=HTMLResponse) +async def backoffice_packages( + request: Request, + db: AsyncSession = Depends(get_db), + admin_user_id: int = Depends(require_admin), +): + """List all tracked packages with statistics.""" + + # Query packages with aggregated stats + packages_result = await db.execute( + select( + AnalyticsEvent.package_name, + func.count(AnalyticsEvent.id).label("nr_events"), + func.max(AnalyticsEvent.received_at).label("last_ingested"), + ) + .group_by(AnalyticsEvent.package_name) + .order_by(func.count(AnalyticsEvent.id).desc()) + ) + packages = packages_result.all() + + total_packages = len(packages) + total_events = sum(p.nr_events for p in packages) + + return templates.TemplateResponse( + "backoffice/packages.html", + { + "request": request, + "packages": packages, + "total_packages": total_packages, + "total_events": total_events, + }, + ) diff --git a/app/src/templates/backoffice/layout.html b/app/src/templates/backoffice/layout.html index ffd417d..b0552bf 100644 --- a/app/src/templates/backoffice/layout.html +++ b/app/src/templates/backoffice/layout.html @@ -22,6 +22,9 @@
  • API Keys
  • +
  • + Packages +
  • Events
  • @@ -47,6 +50,7 @@
  • Dashboard
  • Users
  • API Keys
  • +
  • Packages
  • Events
  • diff --git a/app/src/templates/backoffice/packages.html b/app/src/templates/backoffice/packages.html new file mode 100644 index 0000000..04195b6 --- /dev/null +++ b/app/src/templates/backoffice/packages.html @@ -0,0 +1,57 @@ +{% extends "backoffice/layout.html" %} + +{% block page_title %}Packages{% endblock %} + +{% block backoffice_content %} +
    +

    Packages

    +

    All tracked packages with analytics

    +
    + +
    +
    +
    Total Packages
    +
    {{ total_packages }}
    +
    + +
    +
    +
    +
    Total Events
    +
    {{ total_events }}
    +
    + +
    +
    +
    + +
    + + + + + + + + + + {% for package in packages %} + + + + + + {% endfor %} + +
    Package NameNr EventsLast Ingested
    + {{ package.package_name }} + {{ package.nr_events }}{{ package.last_ingested.strftime('%Y-%m-%d %H:%M') if package.last_ingested else '-' }}
    +
    + +{% if not packages %} +
    + +

    No packages tracked yet.

    +
    +{% endif %} +{% endblock %}