# Backend Migration Journey Catalog

Audience: AI coding agents first. Each row derives exactly one Playwright spec. Seed durable state through APIs only.

| ID | Title | Family | Priority | Layer |
|---|---|---|---|---|
| UJ-001 | Onboard, connect, and provision API key | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-002 | Display character estimate before translation | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-003 | Queue and apply one post translation | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-004 | Queue bulk translations and apply callbacks | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-005 | View credits and usage | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-006 | Surface translation service errors | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-007 | Activate license | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-008 | Deactivate license | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-009 | Save API key in settings | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-010 | Test backend connection | A — WP plugin admin | MUST-HAVE | L2 |
| UJ-101 | Staff login with brute-force backoff | B — staff dashboard | MUST-HAVE | L3 |
| UJ-102 | Look up customer account | B — staff dashboard | MUST-HAVE | L3 |
| UJ-103 | View subscription, usage, and invoices | B — staff dashboard | MUST-HAVE | L3 |
| UJ-104 | Refund PayPal payment and issue credit note | B — staff dashboard | MUST-HAVE | L3 |
| UJ-105 | Grant manual credits through ledger | B — staff dashboard | MUST-HAVE | L3 |
| UJ-106 | Suspend customer account | B — staff dashboard | MUST-HAVE | L3 |
| UJ-107 | Verify audit trail for staff actions | B — staff dashboard | MUST-HAVE | L3 |
| UJ-108 | Inspect translation job | B — staff dashboard | MUST-HAVE | L3 |
| UJ-109 | Manage issued license | B — staff dashboard | MUST-HAVE | L3 |
| UJ-110 | Manage subscription tiers | B — staff dashboard | MUST-HAVE | L3 |
| UJ-111 | Inspect webhook delivery | B — staff dashboard | MUST-HAVE | L3 |
| UJ-112 | View analytics and churn | B — staff dashboard | MUST-HAVE | L3 |
| UJ-113 | Filter and export payments | B — staff dashboard | MUST-HAVE | L3 |
| UJ-114 | Manage platform settings | B — staff dashboard | MUST-HAVE | L3 |
| UJ-115 | Inspect credit transaction | B — staff dashboard | MUST-HAVE | L3 |
| UJ-116 | Reset customer password (staff-initiated) | B — staff dashboard | MUST-HAVE | L3 |
| UJ-117 | Manage customer translation exceptions | B — staff dashboard | MUST-HAVE | L3 |

## Old-panel coverage

| Old page | Journey |
|---|---|
| `LoginPage.tsx` | UJ-101 |
| `UsersPage.tsx`, `UserDetailPage.tsx` | UJ-102, UJ-103, UJ-105, UJ-106 |
| `PaymentsPage.tsx` | UJ-104, UJ-113 |
| `JobsPage.tsx`, `JobDetailPage.tsx` | UJ-108 |
| `LicensesPage.tsx`, `LicenseDetailPage.tsx` | UJ-109 |
| `SubscriptionTiersPage.tsx` | UJ-110 |
| `WebhookEventsPage.tsx`, `WebhookEventDetailPage.tsx` | UJ-111 |
| `MetaDashboardPage.tsx`, `TranslateDashboardPage.tsx`, `MultilingualDashboardPage.tsx`, `AnalyticsPage.tsx`, `ChurnPage.tsx` | UJ-112 |
| `SettingsPage.tsx` | UJ-114 |
| `TransactionsPage.tsx`, `TransactionDetailPage.tsx` | UJ-115 |

All 19 `admin-panel/src/pages/*.tsx` files map above. Grouping follows actor goal, not page count.

## Locked decisions (user, 2026-07-20)

- **Staff dashboard go-live scope = FULL old-panel parity.** All 19 old `admin-panel/src/pages/*.tsx` capabilities ship at cutover. No CARRY-OVER-CANDIDATE rows remain. Resolves UNC-003, UNC-004, UNC-005.
- **UJ-116 staff-initiated password reset = MUST-HAVE** (support + test enablement).
- **UJ-117 staff exception management = view + edit.** Backend exception surface (`/exceptions` sync/pull) ships regardless — it is in the plugin contract (CAP-04).
- **Entitlement + metering MUST be plugin-generic, NEVER translation-specific.** Forum (and later plugins) meter different units under different limits. Design one entitlement model — per-plugin meter definitions over a shared ledger — at Spec 2 time; build only translation meters now. Reject any schema, route, or UI that hardcodes characters/translation as THE metered unit. Enforced by MR-21.

## Uncertainties — human decision required

Resolved rows kept for provenance; `RESOLVED` = no longer a test-generation blocker.

| ID | Conflict or missing locked decision | Impact |
|---|---|---|
| UNC-001 | OPEN — not a user decision. New staff route contract + UI literals are a Phase 2 deliverable (Spec 2 staff surface); L3 specs generate only after it lands. | Blocks L3 test generation until Spec 2 staff routes are written. |
| UNC-002 | RESOLVED 2026-07-20 (design): every staff mutation MUST render an explicit success or error state; silent catch is a defect and is NEVER replicated. Exact copy fixed in Spec 2 alongside routes. | Rolled into UNC-001 deliverable. |
| UNC-003 | RESOLVED 2026-07-20 — both carried over. Password reset → UJ-116. Exception management → UJ-117 (view + edit). | Journeys authored; routes defined in Spec 2. |
| UNC-004 | RESOLVED 2026-07-20 — staff license administration IS in go-live scope. | UJ-109 promoted to MUST-HAVE. |
| UNC-005 | RESOLVED 2026-07-20 — full old-panel parity locked. | UJ-108–UJ-115 promoted to MUST-HAVE. |
| UNC-006 | RESOLVED 2026-07-20 (design): refund = PayPal refund (money) THEN Morning credit note (legal doc), one staff action, client `Idempotency-Key` required, both external IDs persisted + shown, audit row written. Partial failure surfaces explicitly and is retry-safe — NEVER silently half-applied. | Spec 2 defines route + copy. |
| UNC-007 | RESOLVED 2026-07-20 (design, no user fork — one robust answer): manual grant = integer units on a named meter, `reason` MANDATORY, client-supplied `Idempotency-Key` required, audit row records actor, account, meter, delta, reason, resulting balance. Silent catch is a defect, never replicated. | Spec 2 defines route + copy. |
| UNC-008 | RESOLVED 2026-07-20 (design): `account` is the aggregate; users are members of an account. Suspension targets the account and cascades to every credential and plugin entitlement under it. Old `/users/{id}/suspend` is legacy shape, not a parity target. | Spec 2 models account aggregate. |
| UNC-009 | RESOLVED 2026-07-20 (design): deactivation that fails backend-side MUST surface as local-only removal with explicit UI copy + a retry path. Silent divergence between local and backend seat state is a defect. | Phase 3 plugin fix. |
| UNC-010 | RESOLVED 2026-07-20 (design): new backend emits exactly ONE envelope (`{data}` / `{error:{code,message}}`). Plugin callers are normalized in Phase 3 — the backend NEVER ships dual envelopes for caller convenience. | Phase 3 plugin fix, blocks UJ-003/UJ-006 until done. |
| UNC-011 | RESOLVED 2026-07-20 (design): UJ-005 asserts a real balance label sourced from the account ledger, generic over meters (not "characters"). Plugin UI gains the label in Phase 3. | Phase 3 plugin fix; depends on MR-21 meter model. |

## Test-generation gate

- Resolve relevant `UNC-*` before deriving blocked selectors/routes.
- Seed through public/plugin/staff APIs only. Never direct DB.
- Fault-inject `401`, `402`, `429`, and transport failures at HTTP boundary.
- Assert callback signature/timestamp handling and fresh reload persistence for async translations.
