Router.Africa — Dashboard Scope
Backlog item #3 (product half — stack half is resolved in the Tech Stack doc). What the dashboard actually needs: screens, data, and actions. Each ties back to something already decided elsewhere in the architecture, noted per section.
- Sign up / log in — email+password and social login (Better Auth, per the Dashboard Auth decision). Social login is a stated hard requirement, not optional.
- Session management — logout, and logout-everywhere if a session-revocation need comes up later.
No org/team/multi-user screens for now — the architecture assumes single-account-per-API-key (noted as a premature feature if built now, per the tech stack doc’s “explicitly not adopted” list). Revisit if that assumption changes.
Overview / Home
Section titled “Overview / Home”First thing a logged-in user sees. Pulls from the areas below rather than owning new data itself:
- Current credit balance
- Quick usage snapshot (e.g. last 24h requests, spend)
- Any account-level alerts (e.g. low balance)
Usage Analytics
Section titled “Usage Analytics”- Requests/spend over time, filterable by model and date range
- Cost breakdown by model/provider
- This is read data from the async analytics pipeline (Cloudflare Queues →
apps/dashboard-api→ analytics store) — inherently near-real-time, not instant, given the pipeline is deliberately async. Worth the UI reflecting that (e.g. “as of a few minutes ago”) rather than implying live data.
Request Logs
Section titled “Request Logs”- Per-request detail: timestamp, model, status, latency, tokens, cost
- This is the same logged metadata decided under Request Logging in the architecture — the dashboard is simply the read view onto it.
- Filterable by API key, model, date range, status.
API Keys
Section titled “API Keys”- List, create, revoke, rotate keys.
- Per-key spend cap — already decided as part of API key security (bounds blast radius on a leak).
- Rate limit (set per org) — admin-only, not customer-facing. Not a field on this screen; Router.Africa sets and manages it internally, invisible to the account holder. Stored in Postgres and enforced by Bifrost via the key’s 1:1 virtual key.
- Model availability per key — a customer chooses which models are enabled for each key (scoped per key, decided). Starts at signup for the first key (see Onboarding below), but is editable here too, not just a one-time onboarding step.
- Key display follows the security decision already made: raw key shown once on creation, never again (only the stored hash exists after).
Billing / Credits
Section titled “Billing / Credits”- Current balance, including any active holds (so a customer isn’t confused why available balance is lower than expected mid-request).
- Published rate visibility — the daily per-model, per-token-type rate, shown as the final rate only — no breakdown of base cost, FX, or markup. A single clean number per the Pricing Model doc’s transparency requirement (“customers see THAT as the cost… at any time”), not a cost-composition view.
- Top-up flow — via Niobi payments, routed through
apps/niobi-proxy. This is the one flow that talks to a real external payment provider — needs the usual careful UX around pending/failed/succeeded states, not just happy path. The customer enters the credits they want, sees the transaction fee and total to pay (e.g. 1,000 credits + 40 fee = 1,040) before confirming, and only the credits are added to their balance. Fee values are managed in the admin app. - Transaction history — settlements, top-ups, holds released.
Account Settings
Section titled “Account Settings”- Basic profile/email management
- Prompt/response retention opt-out — on by default; a customer can opt out of Router.Africa saving their prompts and data (see the Decisions Log, Audit trail & prompt/response retention)
- Password/social login management (whatever Better Auth’s own UI primitives support — worth checking what it provides out of the box before custom-building this)
Onboarding
Section titled “Onboarding”Signup → first API key must be fast — this is the stated priority, not a nice-to-have. Minimize steps between account creation and having a working key in hand; every screen between signup and “here’s your key” is a drop-off risk.
Model selection is part of this flow — the customer chooses which models are enabled for their account/key during onboarding (and can revisit this later under API Keys, per above). This is more than a UI step: it implies an allowed-models list needs enforcing on the backend, not just displayed on the frontend — apps/api needs to check the requested model against the account’s/key’s allowed list before routing to Bifrost, and reject or fall back appropriately if a model outside the selection is requested. This is a new item for backend scope (#4) and schema (#6) — an allowed_models field (per key, decided) needs to exist and be checked in the request path, alongside the hold/idempotency/rate-limit transaction already decided.
Concrete flow, subject to refinement once backend scope is drafted:
- Sign up (email or social)
- Select models to enable (sensible defaults pre-checked, so this isn’t a blocking decision — a customer can accept defaults and move on immediately)
- Key generated automatically, shown once
- Land on Overview/quickstart
Open Questions for This Scope
Section titled “Open Questions for This Scope”- None currently. Model selection: per-account or per-key? was resolved — per key (see the Decisions Log).
Cross-reference the Decisions Log for the backend behavior each screen surfaces, and the Pricing Model doc for the billing screen’s rate display requirement.