diff --git a/web/src/padelnomics/admin/pipeline_routes.py b/web/src/padelnomics/admin/pipeline_routes.py index 62260f4..b95f95d 100644 --- a/web/src/padelnomics/admin/pipeline_routes.py +++ b/web/src/padelnomics/admin/pipeline_routes.py @@ -372,11 +372,22 @@ def _is_stale(run: dict) -> bool: @role_required("admin") async def pipeline_dashboard(): """Main page: health stat cards + tab container.""" - summary = await asyncio.to_thread(_fetch_extraction_summary_sync) - serving_meta = await asyncio.to_thread(_load_serving_meta) + from .analytics import fetch_analytics # noqa: PLC0415 - total_serving_tables = len(serving_meta["tables"]) if serving_meta else 0 - last_export = serving_meta.get("exported_at_utc", "")[:19].replace("T", " ") if serving_meta else "—" + summary, serving_meta = await asyncio.gather( + asyncio.to_thread(_fetch_extraction_summary_sync), + asyncio.to_thread(_load_serving_meta), + ) + + if serving_meta: + total_serving_tables = len(serving_meta.get("tables", {})) + last_export = serving_meta.get("exported_at_utc", "")[:19].replace("T", " ") or "—" + else: + schema_rows = await fetch_analytics( + "SELECT COUNT(*) AS n FROM information_schema.tables WHERE table_schema = 'serving'" + ) + total_serving_tables = schema_rows[0]["n"] if schema_rows else 0 + last_export = "—" success_rate = 0 if summary["total"] > 0: @@ -422,12 +433,30 @@ async def pipeline_overview(): # Compute landing zone totals total_landing_bytes = sum(s["total_bytes"] for s in landing_stats) + # Build serving tables list: prefer _serving_meta.json (has counts + timestamp), + # fall back to information_schema when file doesn't exist yet. + if serving_meta: + serving_tables = [ + {"name": name, "row_count": meta.get("row_count")} + for name, meta in sorted(serving_meta.get("tables", {}).items()) + ] + last_export = serving_meta.get("exported_at_utc", "")[:19].replace("T", " ") or None + else: + from .analytics import fetch_analytics # noqa: PLC0415 + schema_rows = await fetch_analytics( + "SELECT table_name FROM information_schema.tables " + "WHERE table_schema = 'serving' ORDER BY table_name" + ) + serving_tables = [{"name": r["table_name"], "row_count": None} for r in schema_rows] + last_export = None + return await render_template( "admin/partials/pipeline_overview.html", workflow_rows=workflow_rows, landing_stats=landing_stats, total_landing_bytes=total_landing_bytes, - serving_meta=serving_meta, + serving_tables=serving_tables, + last_export=last_export, format_bytes=_format_bytes, ) diff --git a/web/src/padelnomics/admin/templates/admin/partials/pipeline_overview.html b/web/src/padelnomics/admin/templates/admin/partials/pipeline_overview.html index 7015fc5..6d5b0d0 100644 --- a/web/src/padelnomics/admin/templates/admin/partials/pipeline_overview.html +++ b/web/src/padelnomics/admin/templates/admin/partials/pipeline_overview.html @@ -56,10 +56,12 @@
Serving Tables
- {% if serving_meta %} + {% if last_export %}- Last export: {{ serving_meta.exported_at_utc[:19].replace('T', ' ') }} + Last export: {{ last_export }}
+ {% endif %} + {% if serving_tables %}| serving.{{ tname }} | -{{ "{:,}".format(tmeta.row_count) }} | +serving.{{ t.name }} | ++ {% if t.row_count is not none %}{{ "{:,}".format(t.row_count) }}{% else %}—{% endif %} + |
- _serving_meta.json not found — run the pipeline to generate it.
-
No serving tables found — run the pipeline first.
{% endif %}