Implement statistics pages for orderees, order managers and site admins

Per-user pages get fact rows from /api/stats/me and /api/stats/managed and
aggregate client-side; the site overview is aggregated by /api/admin/stats.
Items that need new data are tracked as TODOs in docs/statistics.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Simon GruberandClaude Sonnet 5.5 committed 2026-11-05 17:18:05 +01:00
1 parent 70bd7642d4
commit c812921a2b
13 files changed
+914 -47

No files matched your search

+50
View File
@@ -0,0 +1,50 @@
# Statistics
Statistics pages live under `/stats/*` (`src/frontend/src/views/StatisticsView.tsx`). Status: ✅ done, 🔲 TODO (needs backend changes, listed under each item).
## Architecture
- Backend (`services/stats_service.py`) returns compact **fact rows**, not aggregates, for the per-user pages. Aggregation (months, weekdays, hours) happens in the frontend (`lib/stats.ts`) so buckets use the viewer's timezone.
- The site overview is aggregated in the backend (`GET /api/admin/stats`) because it spans all users and needs files on disk.
- Item names/prices come from the per-order config files (`data/configs/<admin_token>.json`), resolved in the backend.
- Estimated totals only exist for orders whose menu items have prices.
| Endpoint | Auth | Used by |
|---|---|---|
| `GET /api/stats/me` | any user | My Orders |
| `GET /api/stats/managed` | any user (own orders only) | Order Management |
| `GET /api/admin/stats` | site admin | Site Overview |
## My Orders (orderees)
- ✅ Participation over time (orders joined per month) and current streak (consecutive weeks)
- ✅ Favourite items and categories, items repeated most
- ✅ Total and average spend per order (priced menus only)
- ✅ Usual order day / hour
- ✅ Most frequent organizers
- ✅ Open payments (accepted, unpaid) and payment history
- 🔲 How early you submit before the deadline — orders have no deadline. Backend: add `group_orders.deadline` (nullable ISO text) + create/update API + UI field; expose it in `/api/stats/me`.
## Order Management
- ✅ Orders created over time; open vs. closed (closed = ordering done)
- ✅ Participants per order (average, trend); repeat vs. new participants
- ✅ Submission timeline: time from order creation to submission
- ✅ Popular items and categories across own orders
- ✅ Order volume: items and value per order
- ✅ Payment status: paid / accepted-unpaid / pending
- 🔲 Average time to payment — only the current `paid` flag is stored. Backend: add `submissions.paid_at` (and `accepted_at`), set on status updates, backfill NULL.
- 🔲 Participants who are invited but rarely submit — there is no invite/participant list. Backend: `order_invites` table (order, email) or a per-owner contact list.
- 🔲 Submission timeline relative to the deadline — needs the deadline (see above).
## Site Overview (admins)
- ✅ Active contributors per week (users who created an order or submission), new registrations per week
- ✅ Users with recent activity (7 / 30 days, from last known activity — approximation)
- ✅ Unconfirmed accounts, pending email / user-id changes, open registration links
- ✅ Orders per week and share of orders with ≥1 submission
- ✅ Top order managers, most active participants
- ✅ Most ordered items site-wide
- ✅ Storage usage per data folder and orphaned files
- 🔲 Real daily/weekly/monthly active users — only creation timestamps are recorded. Backend: `user_profiles.last_seen_at` updated (throttled) in `get_existing_user_id`, or an `activity_log` table.
- 🔲 Email volume and failures — `email_service` does not log sends. Backend: `email_log` table (kind, recipient hash, status, error, created_at) written by `email_service`.