# meowtrace — User Portal Plan (PORTAL-PLAN.md)

> ↩ **Back to canonical entry:** [SPEC.md](./SPEC.md)
> Full living spec for the **User Portal** surface — current state + planned work.
> The Admin surface has its own doc: [ADMIN-PLAN.md](./ADMIN-PLAN.md).

**Status:** Built (Phase 5 ✅), on staging — living spec for ongoing feature work
**Surface:** `https://app.staging.meowtrace.com` (hostname-selected from the shared portal SPA)
**Last updated:** 2026-07-27

---

## 1. What this is

The **User Portal** is the public/authenticated developer-facing app. It is one half
of a single role-gated React/Vite SPA ([`src/portal/`](../src/portal/)); hostname
`app.*` selects the User surface, `admin.*` selects the Admin surface
([ADMIN-PLAN.md](./ADMIN-PLAN.md)). Auth is a **bearer token** held in `localStorage`
(`mt_token`); the client calls the live API via `VITE_API_BASE`
(see [DEVOPS.md §API / Frontend](./DEVOPS.md)).

Target audience: **developers** (API-first) — see [SPEC.md §3](./SPEC.md). Non-technical
web-UI users are a secondary convenience, not the design center.

## 2. Surfaces & routes (current)

| Route | Page | Purpose |
|---|---|---|
| `/login` | Login / signup | Bearer-session login; signup requires **confirm-password** match |
| `/` | Dashboard | Credit balance + usage rollup |
| `/lookup` | Lookup | Type an IP → location result (auto-detect caller IP as convenience) |
| `/keys` | API Keys | Create/list/revoke keys (SHA-256 hashed, shown once) |
| `/members` | Members | Org members + invites (org switching) |
| `/billing` | Billing | Plan, balance, Stripe Checkout/Customer Portal |

> **Wireframe (lo-fi):** [wireframes/dashboard.html](./wireframes/dashboard.html) — greyscale
> structure for the Dashboard (sidenav + summary cards + usage trend + recent lookups +
> top keys). Not final visual design.

## 3. Feature detail

### 3.1 Core app surface
- **Sign-up / login** — bearer session. Signup form requires a **confirm-password**
  field that must match the password before submit (client + server validation).
- **Navigation** — **side navigation (sidenav)**, not a topbar. (Applies to both
  surfaces; the Admin sidenav is tracked in [ADMIN-PLAN.md](./ADMIN-PLAN.md).)
- **IP lookup UI** — **single-IP** lookup: type an IP, see the result; auto-detect the
  caller's own IP as a convenience. **Bulk is API-only** (not a portal UI feature —
  use `POST /v1/lookup`). Country/region/city only (no lat/long in v1 — [SPEC.md §6](./SPEC.md)).
  Renders the canonical result body (see [API.md](./API.md)):
  ```json
  { "result": { "ip": "143.130.141.229",
      "country": { "code": "AT", "name": "Austria" },
      "region": "Wien", "city": "Vienna" } }
  ```
- **Dashboard** — credit balance + usage (see §5, usage data model in
  [SPEC.md §9.1](./SPEC.md)).
- **API-key management** — per-account keys, multiple keys, revocable
  ([SPEC.md §4.3](./SPEC.md)).
- **Billing / invoices** — see §3.2.
- **Pricing page** — the three tiers ([SPEC.md §8](./SPEC.md)).
- **Organizations** — orgs own credits/keys/billing; member invites (auto-join),
  org switching (re-tokens to the new org).
- **Org details management** — view/edit the current org's details (e.g. name, and
  other org-level settings); scoped to members with the right role. See §4 backlog.

### 3.2 Billing features (User Portal)
- Current plan + credit balance and reset/refill date.
- Usage this period (with history / trend).
- Upgrade / downgrade / cancel plan.
- Payment method management (via Stripe — [SPEC.md §10](./SPEC.md)).
- Invoice history + downloadable receipts (Stripe-hosted or synced).

### 3.3 HTTP request/response log view (User)
- The developer sees a **searchable/filterable log of their own requests** — recent
  calls, status, latency, credits, errors — to debug integrations.
- Per-account scoped; a user sees only their own traffic.
- Backed by the request-log data model in [SPEC.md §9.1](./SPEC.md) (shared with Admin
  oversight — see [ADMIN-PLAN.md](./ADMIN-PLAN.md)); the credit **debit** record is the
  billing source of truth, the HTTP log is the richer per-call diagnostic trail, sharing
  a request ID for correlation.
- _(TBD)_ Export/stream of logs (CSV/JSON download).

## 4. Planned / backlog

- [ ] **Confirm-password on signup** — add a confirm-password field to the signup form;
  validate match client-side and server-side before account creation (§3.1).
- [ ] **Sidenav navigation** — replace the topbar nav with a side navigation across the
  portal (applies to both User and Admin surfaces; Admin side in [ADMIN-PLAN.md](./ADMIN-PLAN.md)).
- [ ] **Org details management** — UI + API to view/edit the current org's details
  (name, org-level settings), role-gated to authorized members (§3.1).
- [ ] **Inner pages on canon palette** — dashboard/keys/billing still lean on the earlier
  theme; bring fully onto the canon palette (STATUS §9).
- [ ] Own-request log export (CSV/JSON) — §3.3.
- [ ] Response-format options / SDK snippets surfaced in the portal ([SPEC.md §4.3](./SPEC.md) TBD).
- [ ] **Lookup view: render the result envelope** — `{ result: {...} }` with nested
  `country: { code, name }` + `region` + `city`. **Backend contract is live/shipped**
  (`routes.ts`; see [API.md](./API.md)) — wire the portal lookup view to it.

## 5. Data & API dependencies

- **Usage tracking data model** — the shared contract lives in [SPEC.md §9.1](./SPEC.md)
  (credit ledger, usage records, aggregates, real-time counters, exports). This doc
  describes the **User-facing views** of that data, not the model itself.
- **API** — endpoints in [API.md](./API.md); base URL via `VITE_API_BASE`
  ([DEVOPS.md](./DEVOPS.md)). Login preflight requires API CORS (DEVOPS §API).

## Changelog
- **2026-07-20** — **Backlog rulings:** #4 canon-palette kept; **#5 billing alerts removed**;
  #6 own-request log export kept; #7 lookup UI kept but **single-IP only** (bulk is API-only);
  #8 lookup **result body** set to nested `country: { code, name }` + `region` + `city`
  (dropped redundant `_name` suffix; null-country = `{ null, null }`) under a
  `{ result }` / `{ results:[] }` envelope (canonical contract in [API.md](./API.md);
  **shipped in `src/backend` — no longer pending**).
- **2026-07-20** — **Feature decisions recorded:** (1) signup gains a **confirm-password**
  field (match-validated); (2) dropped the "signup always starts on Free tier" wording;
  (3) navigation moves to a **sidenav** (both surfaces — Admin side in ADMIN-PLAN); (4) new
  **org details management** function (view/edit org name + settings, role-gated). Added to
  §2/§3.1/§4.
- **2026-07-20** — Created. Migrated User-Portal feature detail out of SPEC (§5.1 surface,
  §9.2 billing features, §9.4 user log view) into this full living spec. Usage-tracking
  **data model** stays in [SPEC.md §9.1](./SPEC.md) (shared contract).
