Admin analytics (#33 phase 2): overview, accounts, timeline + Paddle checkout funnel #36
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/admin-analytics-33"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 2 of the staff console: the real analytics endpoints, all staff-gated and all derived from state the server already holds plus a small funnel-events table.
Endpoints
GET /v1/admin/overview— MRR / ARR / seats licensed / median seats (unlimited-key sentinel excluded), expiring-in-90-days (count/seats/value), churn (scheduled cancellations / rate), plus a guarded signup→checkout→paid funnel snapshot.freeOver40andfailedPaymentsreturn 0 (not observable without, respectively, free-tier check-ins and a Paddle payment-failed feed).GET /v1/admin/accounts— roster with derived state (paid / cancelled / abandoned / free), seats, MRR, license count, created, last-seen.GET /v1/admin/accounts/{id}— one account.GET /v1/admin/accounts/{id}/timeline— account creation + license issuance + checkout events for that email.Funnel events
recordPaddleEventis called once from the webhook (spliced in):transaction.created→checkout_open,transaction.completed→checkout_paid, human-checkout origins only (subscription renewals excluded). It captures the transaction id, total seat cap, and buyer email; distinct transaction ids give opened / paid / abandoned and a recoverable-value estimate.Privacy (ADR-0002)
The
eventstable stores an email + seat count only, is pruned to 180 days, and never leaves the Swiss VPS.admin.gostill owns all its tables directly; no change to the storesave()/load()path or theaccountstruct.Deliberately still on fixtures
The dedicated Funnel and Geography tabs keep admin.html's client-side fixtures:
vFunneldivides by raw counts (showsNaN%on sparse real data — needs a small frontend guard first), and geo needs an offline GeoIP source (a genuine dependency decision). overview's own funnel block is division-safe, so the main dashboard is fully real. Those two remain as a documented follow-up.Tests
analytics_test.go: overview rollups (seats 200, MRR $300, ARR $3600, median 100, expiring-90 {1,80}); funnel event capture (2 opened / 1 paid / 1 abandoned, renewal ignored); accounts view (paid state, seats, org) + timeline (issued + created) + 404 on unknown id.