Skip to content

feat(billing): usage time series, admin usage report, and billing docs - #568

Merged
Ayinkx merged 1 commit into
AyinkxLab:mainfrom
abdulwahabmonilola-ctrl:feat/449-480-487-usage-timeseries-admin-report-billing-docs
Oct 23, 2026
Merged

Ayinkx merged 1 commit into
AyinkxLab:mainfrom
abdulwahabmonilola-ctrl:feat/449-480-487-usage-timeseries-admin-report-billing-docs

Conversation

@abdulwahabmonilola-ctrl

@abdulwahabmonilola-ctrl abdulwahabmonilola-ctrl commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Combines the three Phase 10 billing/observability issues assigned to me, plus the minimal repairs needed to make the billing migration and invoice tests runnable on current main.

#449 — Usage time-series API

  • Adds usage_dashboards.timeseries() with daily and weekly buckets (Monday–Sunday UTC), computed strictly from stored UsageRecord rows.
  • Every bucket intersecting the selected window is returned, including empty buckets. Rows outside [now - days, now], including future-dated rows, are excluded.
  • Adds GET /billing/api/usage/timeseries and GET /billing/api/workspaces/<id>/usage/timeseries with the same days, source, provider, and model filters as the dashboards.
  • Tests cover bucket correctness, empty scopes, partial first buckets, bounded ranges, filters, authorization, and invalid input.

#480 — Admin usage report page

  • Adds GET /admin/usage/report protected by the existing admin guard.
  • Supports a date window, scope filters (all / user / workspace), source/provider/model filters, and bounded pagination.
  • Renders totals plus a detailed table with user, workspace, provider/model, status, tokens, and estimated cost.
  • Adds an admin-only navigation link and tests for access control, filtering, and table bounds.

#487 — Billing documentation

  • Documents quotas, alerts, invoices, and the usage time-series API in docs/billing.md.
  • Records every billing/SMTP setting, including BILLING_ALERT_EMAIL and USAGE_EXPORT_CSV_MAX_ROWS, in both the docs and README.
  • Updates .env.example and the config class.

Supporting fixes required by the gate

  • Repairs the cascading indentation in app/services/invoice_export.py and tests/test_invoice_export.py introduced by Phase 10: Invoice export as CSV and PDF #483.
  • Declares fpdf2 for PDF invoice export; CSV export remains import-free.
  • Resets the process-local marketplace fallback cache between tests so offline failure cases are isolated.
  • Rebased onto current main, which already carries the unique migration revision fix.

Validation

Targeted suites pass:

python -m pytest tests/test_usage_timeseries.py tests/test_admin_usage_report.py \
  tests/test_usage_dashboards.py tests/test_docs_links.py \
  tests/test_invoice_export.py tests/test_migrations.py \
  tests/test_marketplace_catalog_offline.py

ruff check . is clean. The full Python suite should be confirmed by CI.

Closes #449
Closes #480
Closes #487

Closes AyinkxLab#449
Closes AyinkxLab#480
Closes AyinkxLab#487

- Add daily/weekly usage time-series aggregation and user/workspace APIs.
- Add the admin usage report page with date/scope filters and bounded paging.
- Document quotas, alerts, invoices, time series, and every billing setting.
- Repair the merged invoice export module/tests and make PDF export an
  explicit fpdf2 dependency.
- Reset the process-local marketplace fallback cache between tests.
@abdulwahabmonilola-ctrl
abdulwahabmonilola-ctrl force-pushed the feat/449-480-487-usage-timeseries-admin-report-billing-docs branch from 0de7407 to 9cbe7a8 Compare October 23, 2026 14:33
Comment thread app/admin/routes.py
try:
days = usage_dashboards.normalize_days(request.args.get("days"))
except ValueError as exc:
return jsonify({"error": str(exc), "kind": "invalid"}), 400
Comment thread app/billing/routes.py
try:
return usage_dashboards.normalize_bucket(request.args.get("bucket")), None
except ValueError as exc:
return None, (jsonify({"error": str(exc), "kind": "invalid"}), 400)

@Ayinkx Ayinkx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change it

@Ayinkx
Ayinkx merged commit a5f6ce6 into AyinkxLab:main Oct 23, 2026
10 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phase 10: Billing documentation Phase 10: Admin usage report page Phase 10: Usage time-series API

3 participants