Files
descrybe/docs/analytics-audit.md
greeneclipse 8580c996c3 Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
2026-08-09 22:47:43 +02:00

93 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Analytics & usage audit (Descrybe v2)
Date: 2026-08-04
Scope: company billing usage, admin analytics, meters vs live Postgres.
## Surfaces
| Surface | Path / API | Role |
|---------|------------|------|
| Company billing / usage | `/billing``GET /api/billing/credits`, `GET /api/billing/usage?range=` | Tenant |
| Dashboard meters | `/dashboard``/api/auth/me` credits + product count | Tenant |
| Admin overview | `/admin` → summary from `/api/admin/analytics` | Platform admin |
| Admin analytics | `/admin/analytics``GET /api/admin/analytics?days=` | Platform admin |
| Admin billing | `/admin/billing` | Plans / credits / cycles |
## Bugs found
1. **Stale cycle override on company usage**
`UsageSummary` preferred the latest `billing_cycles` row (`credits_used=22`, `products_processed=12`, JuneJuly window) over live wallet and catalog. Demo wallet was `used_credits=0` with **~4323+** processed products and an **AugSep** `company_plans` cycle.
2. **Misleading empty / range UI on `/billing`**
“Usage history” gated on `credits_used > 0`, so a rich catalog with zero wallet spend looked empty. The 7d/30d selector did not change any numbers.
3. **Admin provider cards at zero on running binary**
Disk already had `ai_provider_mode` rollups; the old `api.exe` still returned stub zeros. After rebuild, internal mode matches DB (`internal` on all products/jobs).
4. **Feeds missing from admin volume**
Input/export feed counts were not exposed on the analytics summary.
## Fixes
### `GET /api/billing/usage?range=7d|30d|cycle|all` (default `30d`)
- **Credits** always from live `credit_balances` (not historical cycle rows).
- **Products / tokens** filtered by range; `products_total` is all-time catalog.
- **Cycle dates** from active `company_plans` (`billing_cycle_start` / `next_billing_date`).
- **Feeds** (`feeds_input`, `feeds_export`) and `jobs_total` from live tables.
- **Series** (products + tokens by UTC day) for 7d / 30d / cycle.
- Notes clarify that credit debits are not daily-ledgered yet.
### Admin analytics
- Summary includes `feeds_input` / `feeds_export`.
- Provider breakdown + detail + per-day class series from `ai_provider_mode`.
- Notes updated; billing-cycle table labeled as historical rollups that may lag the active plan window.
### UI
- `/billing`: catalog card, range metric cards, honest empty states, range-driven chart via `AdminSeriesChart`.
- `/admin/analytics`: feed counts on Volume card; clearer cycle table copy.
## Demo verification (Local Demo Co)
Against `postgres://…@localhost:5433/descrybe` after rebuild, logged in as `demo@descrybe.local`:
| Meter | API | DB |
|-------|-----|-----|
| Wallet used / total | 0 / 1_000_000 | 0 / 1_000_000 |
| Products (all) | 4326 | 4326 |
| Input / export feeds | 12 / 5 | 12 / 5 |
| Plan cycle | 2026-08-04 → 2026-09-04 | `company_plans` |
| Platform products | 7225 | 7225 |
| Platform credits used | 26 | 26 |
| Platform feeds in/out | 35 / 12 | 35 / 12 |
| Provider internal tokens/products | 11_383_374 / 7225 | `ai_provider_mode=internal` |
Previously the usage API returned **22 credits / 12 products** from a stale `billing_cycles` row — fixed.
## Remaining limitations
- No per-day **credit** ledger; range filters apply to products/tokens only.
- `billing_cycles` historical rows can lag or disagree with the active plan window; they remain an admin history table, not the tenant source of truth.
- Token series for migrated catalogs often clumps on import day(s).
## Verification commands
```powershell
cd apps/api
go test ./internal/billing/ -run ParseUsageRange -count=1
go build -o bin/api.exe ./cmd/api
cd ../web
npm run check
```
Demo smoke (after API restart):
```powershell
# login as demo@descrybe.local then:
# GET /api/billing/usage?range=30d
# GET /api/admin/analytics?days=30
```