overview
Swap Support — Product Overview
Section titled “Swap Support — Product Overview”Audience: Rechaj leadership · CTO · Ops & Support leads Status: Design complete · awaiting backend buy-off Author: Ridwan Egbeyemi (PM, Swap) Last updated: 18 May 2026
Battery-swap stations in the field hit operational issues every hour — wallets that won’t load, payments that don’t reflect, batteries that aren’t where the system thinks they are, riders crossing stations, VCUs that won’t unlock. Today, none of this is captured in the swap-app. Managers WhatsApp the Ops team, who chase it ad hoc, then a tired manager scribbles it in a notebook.
We’ve designed an end-to-end fix on two surfaces:
- Swap App (mobile) — every operational issue surfaces inline during a swap, with structured capture (photo, voice, picker chips) and an in-app “Park” mechanism so the manager handles the next rider while the issue is resolved.
- Atlas Backoffice (desktop) — a dedicated Swap Support queue for the support team, with an embedded Resolve flow per issue type (no leaving the page to fix things), click-to-call between stations, photo evidence review, and a full audit trail visible to the PM.
Across both surfaces we cover the full taxonomy of operational pain points we’ve seen this quarter. The battery group now has four distinct scenarios — all rooted in the same underlying bug (field-support staff doing a swap without recording it in the app, which leaves both batteries with the wrong digital position). Three of the four are single-click record mutations in Atlas (release-and-reassign an old battery, station-claim a new one, attribute an old battery to a rider whose keke has none on record); only the fourth — a scanned new-battery serial that returns no data — keeps the print-and-relabel mechanic, with support pushing back the closest serial match for the manager to reprint and stick.
Live prototypes:
- 📱 Swap App support cases (v3): https://design.rechaj.com/flows → Support Cases (v3)
- 🖥️ Atlas Swap Support Resolution: https://design.rechaj.com/flows → Swap Support Resolution
Why this matters
Section titled “Why this matters”Today, each support issue takes 30–90 minutes end-to-end:
- Manager calls or WhatsApps Ops with partial information.
- Ops calls a second manager or the rider for context.
- Someone manually moves money in a backend tool that wasn’t built for this.
- No single record exists of what happened or who decided what.
This shows up in two places we care about:
- Rider trust. A rider who paid ₦12,000 for a swap and got told “wallet is loading, come back later” doesn’t come back. Daily-active riders drop after every funding glitch.
- PM visibility. Right now I can’t tell you how many swap issues we had yesterday, what kind, who resolved them, or how long they took. We’re flying blind on a core part of the business.
After this ships, every issue is:
- Captured at the moment it happens, with rider/manager/station context auto-attached.
- Routed to a support specialist’s queue in Atlas (round-robin, severity-weighted).
- Resolved in a single embedded flow — call, verify, move funds, close.
- Logged in an immutable audit trail that the PM can slice by issue type, station, manager, or rider.
Why this approach (and not the obvious one)
Section titled “Why this approach (and not the obvious one)”The obvious thing would have been to bolt a generic “Report an issue” form into the swap app: a button on the top bar, a dropdown for issue type, a free-text field, an attach-photo button, submit to backoffice. We deliberately didn’t do that. Here’s why.
What the form-based approach gets wrong
Section titled “What the form-based approach gets wrong”A generic ticketing layer disconnected from the swap steps fails operators in four predictable ways:
-
It breaks flow. The manager is mid-swap with a rider standing in front of them. They hit an issue. Now they have to abandon the swap context, navigate to a separate Support area, fill out a form that doesn’t know anything about the swap they were in, then somehow get back to where they were. In practice they don’t — they call Ops on WhatsApp instead, and we lose the entire interaction.
-
It loses context at the moment of value. The instant the issue manifests is when we have all the data: rider ID, tricycle, current battery, wallet state, fee due, station, manager, exact timestamp, what step they were on, what they just tried. A generic form throws all that away and asks the manager to re-describe it in free text. Ops then receives a “wallet not loading for rider Adekunle” ticket with no error code, no station, no swap context — and has to call the manager back to recover the data we already had in memory.
-
It can’t be parked. A swap can’t sit idle for 20 minutes while support resolves. We need the manager to serve the next rider and resume the parked one when resolution lands. A form-and-ticket flow has no concept of “resume this swap from where it broke” — the rider goes home unhappy and the manager loses the thread.
-
It produces unstructured data the PM can’t act on. Free-text tickets are unsearchable, untaggable, untrendable. After 3 months you have 4,000 tickets and no way to answer “what’s the most common issue at Yaba?” or “which bank settles slowest?” or “is VCU-LTE-2891 a repeat offender?”. You’re back to spreadsheets.
What inline/embedded does instead
Section titled “What inline/embedded does instead”We made three architectural choices that flow from the same principle: support is part of the swap, not separate from it.
| Form-based | What we built |
|---|---|
| One generic ticket form for everything | Issue-specific capture surfaces at the step where it manifests. Wallet-not-loading appears on the rider profile, battery-not-here appears on scan-new-battery. The manager never picks “type of issue” from a dropdown — the system already knows. |
| Free-text “describe what happened” | Structured fields the support team actually uses to resolve. For funding-not-reflecting: virtual account picker + source bank picker + receipt photo (single or multi-payment). For cross-station disputes: which manager + payment evidence + amount. The manager only fills the human-judgment fields; everything else is auto-attached. |
| Submit → wait → maybe-resolved → ??? | Park + push-resume. The swap goes into a parked queue with a live timer. When support resolves it, the manager gets a tap-to-resume push and lands back in the exact step they left, with the resolution already applied. The rider’s wait is filled with the next rider’s swap, not idle anxiety. |
The Atlas side mirrors this: instead of “view ticket → click external link → open finance tool → move money → come back and update ticket”, the support specialist resolves the issue inside the issue page. Call both managers from the page. Move ₦12,000 from one station wallet to another in the page. Close. The audit trail captures all of it automatically.
What this unlocks
Section titled “What this unlocks”- Resolution time drops from 30–90 min to under 10 min for the common cases. Most of today’s time is “calls to gather context” — we already have the context.
- Support team scales sub-linearly with riders. Structured capture + embedded resolution means a specialist resolves 3–4x more cases per shift than they could with free-text tickets and tab-switching.
- The PM finally gets to see the system. Every issue is tagged by type, station, manager, rider, severity, time-to-resolve, who-resolved-it, what-was-the-action. The PM dashboard slices it any way we want, and anomalies (e.g. a station spike or a problematic VCU) get auto-flagged.
- Riders don’t churn after one bad swap. They get a resolution while still at the station, not a vague “we’re looking into it”.
The form-based approach optimizes for capturing problems. Our approach optimizes for resolving them — with the operator still in the room.
In scope
Section titled “In scope”- Mobile swap-app journey for the station manager persona (the operator who actually does the swap)
- Backoffice journey for the swap support specialist and the swap PM
- 16 operational scenarios (see catalog below)
- Wallet & swap-fee model: rider wallet, daily fee deduction, station wallet, virtual accounts for top-up (Opay / Paystack / Monnify)
- VCU bluetooth pairing for the swap (manual-unlock fallback is out of scope — TBD)
- Cross-station fund-release disputes (rider paid station A, swapping at station B)
- Primary station change requests (initiated from support page, approved by Ops)
- Inline issue parking + push notification when resolution arrives
Out of scope (for this round)
Section titled “Out of scope (for this round)”- Rider-facing app (riders interact only with the station manager + their bank)
- Charge-hub operator interface (separate persona, separate product)
- VCU manual-unlock fallback (deferred — resolution path being redesigned to live entirely in-app)
- Finance/accounting reconciliation tools (we’ll trigger them; we don’t replace them)
- KaaG telemetry dashboards (already shipped in Atlas)
Pending clarification
Section titled “Pending clarification”| Item | Question | Owner |
|---|---|---|
| Station wallet top-up policy | Today stations self-fund their wallet (often the on-duty manager fronts the cash) — do we want to centralise that in Atlas v2? | Ridwan + Finance |
| Overdraft accounting | Where do unmatched overdrafts live in our books while waiting for bank settlement? | Finance |
The two surfaces
Section titled “The two surfaces”Swap App (mobile · 390 × 844)
Section titled “Swap App (mobile · 390 × 844)”The station manager’s tool. Used hundreds of times a day per station. Designed so the manager can stay in flow — every issue surfaces inline with the rider standing right there, never breaks the swap into a separate “support” mode.
Key UX patterns:
- Wallet hero card — wallet balance + daily swap fee side-by-side, with a single status footer line (“Wallet covers today’s fee” / “Can’t cover today’s fee” / state-coloured). The dominant visual element on the rider profile.
- Daily-fee deduction step — explicit deduct action before VCU connect. On success the wallet visibly depletes; on failure the rider’s wallet is intact (idempotency-safe) and a “Couldn’t draw daily fee” alert opens.
- VCU lock/unlock toggle — a fixed-position pill right under the keke illustration. Position doesn’t shift between locked/unlocked states; “I’ve taken out the battery” is disabled until unlocked.
- Parked-swap queue — when an issue blocks the swap, the manager parks it and serves the next rider. When the issue resolves, a push notification with a rider name brings them back into the parked flow.
- Quick requests on support page — outside of an active swap, the manager can still raise a primary-station change, payment reconciliation, battery transfer request, or any “other” issue, all with the same structured capture.
Atlas Backoffice (desktop · 1440 × 900)
Section titled “Atlas Backoffice (desktop · 1440 × 900)”The swap support specialist’s workspace. Designed for embedded resolution — the user never leaves the issue page to fix it.
Key UX patterns:
- Issue detail = split view. Full context on the left (rider, manager, station, evidence, case history). Sticky Resolution panel on the right with a stepwise checklist, decision dropdown, internal note field, and primary action buttons.
- Click-to-call everyone in the issue. Every party — rider, station manager, “the other” manager, charge-hub lead — has a phone & message button. Calls route through the Atlas dialler (audit-logged automatically).
- One-click money movement. For cross-station disputes, the support specialist approves and money moves from station A’s wallet into the rider’s wallet at station B — without leaving the issue page.
- Audit trail — every action (approval, denial, transfer, call placed, note added) gets a typed entry with target, delta, and timestamp. Visible to the specialist and to the PM.
- PM overview — Ridwan’s view aggregates team-level KPIs, issue-type distribution (where is the team spending time?), an hour-by-hour heatmap, team scoreboard, and auto-detected anomalies (“Asbestos spike: +63% issues this week”).
Scenario catalog
Section titled “Scenario catalog”13 scenarios. Each one has a corresponding detection / capture flow in the swap app and a resolution flow in Atlas. Severity reflects how often it blocks a rider mid-swap.
Station
Section titled “Station”| # | Scenario | What happens | App capture | Atlas resolution | Severity |
|---|---|---|---|---|---|
| 1 | Temporary swap (away from primary station) | Rider’s primary station is somewhere else; they need a one-time swap here | Inline alert on rider profile · request authorization · park while support decides | Three decisions: allow + ₦500 fee · allow + waive fee · deny (rider returns to primary) · pattern flag if 3+/week | Med |
| 2 | Primary station change | Manager wants to formally reassign the rider | Initiated from the support page · scan/license lookup → 2-step form → status screen (pending → approved push) | Approve/deny · both stations & rider notified · effective immediately or scheduled | Low |
Wallet & payments
Section titled “Wallet & payments”Scenarios 4, 6, 7, 8 share one rider-profile entry point: the “How is the rider paying?” alert with four actions (pay from station wallet · show funding accounts · log rider’s receipt · funds at another station). The manager picks the right one; the backend paths remain distinct.
| # | Scenario | What happens | App capture | Atlas resolution | Severity |
|---|---|---|---|---|---|
| 3 | Wallet not loading | Rider record fails to fetch | Inline alert · retry · or park while support rebuilds | Force rebuild from ledger · push notif to manager when ready | Med |
| 4 | Insufficient balance | Wallet ₦0; rider needs to fund | Consolidated alert · “Show funding accounts” (Opay / Paystack / Monnify) or “Pay from station wallet” (station pays subscription, manager collects cash) | n/a — resolves itself when funds arrive | Med |
| 5 | Daily-fee deduction fails | Manager taps “Draw daily fee”, wallet svc rejects | Inline danger alert · retry · or send to support | Linked engineering ticket · safe to retry (idempotent) | Med |
| 6 | Funding not reflecting | Rider claims paid; wallet still ₦0 | Capture rider’s receipt · single OR multiple payments · pick virtual account + source bank | Live settlement-feed tail · overdraft / wait / deny | High |
| 7 | Station-wallet payment failed | Station’s “pay from station wallet” rejected | Alert · retry · escalate to support | Confirm fix landed · retry transfer for station | Med |
| 8 | Funds at another station | Rider claims paid manager A; swapping at station B | Photo evidence + manager picker · sent for backend resolution | Call both managers (click-to-call) · move ₦12k from station A’s wallet → rider wallet · resolve | High |
| 8a | Funding account number invalid | The Opay / Paystack / Monnify account number shown to the rider for top-up is rejected by their bank — provider-generated value doesn’t match what the rider sees | Consolidated alert · “Funding account invalid” opens capture sheet (provider + account shown + rider’s bank error) · park until support fixes | Support escalates internally to engineering · audit captures provider + VA · rider re-tries funding once corrected | Med |
| 15 | Outstanding overdraft blocks new swap | Prior #6 overdraft never reconciled; rider returns next day for a new swap | Inline danger alert on rider profile · single CTA opens the originating case · no manager override | Atlas Ops must reconcile against late settlement, or write off, before another swap is allowed | High |
Battery
Section titled “Battery”Every battery scenario has a single upstream cause: a field-support staff member performed a swap in the field without recording it in the app. That single off-app swap leaves the old battery physically moved to a station but digitally still attached to the keke, AND the new battery physically at the station but digitally with a different keke — so the same off-app swap can resurface as up to three different problems on three different future swaps, plus a fourth standalone scenario when a new-battery scan returns nothing because the printed serial was a typo. Three of the four resolutions are single-click record mutations in Atlas (no relabel). Only scenario 16 keeps the print-and-stick mechanic.
| # | Scenario | What happens | App capture | Atlas resolution | Severity |
|---|---|---|---|---|---|
| 9 | Release-and-reassign (old battery) | The previously-depleted battery has been recharged and the manager is about to issue it to a new rider, but the system still has it attached to the previous keke (because of an off-app swap) | Inline alert on scan-new-battery · “Send to support” → captured-context sheet · waiting card · resume push when released | Support reviews · calls manager to confirm · one click releases from previous rider and reassigns to this station | Med |
| 10 | Station claim (new battery) | A previously-charged battery comes back depleted, gets recharged, possibly moves between stations. Manager scans to give it out — system says it’s at another station or with a keke | Inline alert on scan-new-battery · “Send to support” → captured-context sheet · waiting card · resume push when claimed | Support reviews · calls manager (and the other station’s manager if needed) · one click claims it for the calling station | Med |
| 11 | Old-battery attribution (rider) | The rider whose battery was un-recorded arrives for a swap. Post-VCU-pair, the “Current battery in keke” card has nothing to show — the keke’s old battery is missing from inventory | Empty-state on the VCU “Current battery in keke” card · “Send to support” → captured-context sheet · waiting card · resume push when attributed | Support reviews keke history + calls manager · one click attributes a candidate old-battery serial to the keke; swap-app then displays it so the manager can advance | Med |
| 16 | Serial mismatch (new battery) | Manager scans a new battery and the serial returns no data — typo / worn label / off-by-one print | Inline alert on scan-new-battery · “Send to support” → captured-context sheet · waiting card · ready card with corrected serial · manager copies, prints, sticks, rescans (validated against corrected serial) | Support finds the closest match in inventory and pushes the corrected serial back; audit trail records the relabel and any rescan mismatch | Low |
VCU connection
Section titled “VCU connection”Scenarios 12 / 13 / 14 (unlock fails, BT-failed-internet-recovers, full ladder → manual unlock) are deferred. The bluetooth connection itself stays in the swap app; the manual-unlock back-and-forth with a 6-digit code is being redesigned to live entirely in the app — no human in the loop. Until that design lands, these scenarios are not surfaced in the support backoffice.
(Scenario numbers are sticky to historical IDs; the battery group expanded from 2 → 4 by reusing 9/10/11 for the three location/attribution scenarios and adding 16 for the standalone serial-mismatch path. 15 remains the next-day consequence of an unreconciled #6.)
Key UX moments (worth a click)
Section titled “Key UX moments (worth a click)”If leadership is short on time, the five flows that best showcase the system:
- Happy path (swap app) — scan → rider profile with wallet hero + virtual accounts → draw daily fee → VCU connect → lock/unlock toggle → scan new battery → 3-field mileage calc → swap complete → “Start another swap”
- Funds with another station (swap app + atlas) — the cross-station dispute flow. Rider in front of you claims to have paid Tunde at Yaba. Photo evidence, manager picker, parked-swap, then call both managers from Atlas and resolve in one click.
- Funding not reflecting (swap app) — single vs multiple payments toggle, per-slot receipt photo, virtual account picker, source bank picker (so we can finally answer “which banks settle slowest?”).
- PM dashboard (Atlas) — Ridwan’s view. Issue mix distribution, hour-by-hour heatmap, team scoreboard, anomaly flags.
Patterns introduced
Section titled “Patterns introduced”These are reusable across other Rechaj products. Now living in patterns/ alongside the earlier ones we built (parked-queue, notification-banner, inline-alert, status-card, captured-context, timer-band, prototype-scenarios):
| Pattern | Where it shows up |
|---|---|
| Wallet hero | Rider profile (mobile) · 2-column wallet + fee with state-driven footer |
| VCU lock toggle | Fixed position under illustration · stable tap target across lock states |
| Other-specify | Reason chips with “Other” expand to textarea + voice-note record |
| Photo evidence dropzone | Funding receipts, dispute photos, support tickets |
| Manager picker | Cross-station disputes · search + radio-select |
| Scenarios drawer | /flows page · vertical “Scenarios” tab opens a slide-in drawer (replaces previous side panel that didn’t fit on desktop iframes) |
| Issue resolution split view | Atlas · context left, sticky resolution panel right |
| Click-to-call contact card | Atlas · avatar + role + phone with call/message buttons |
| Audit trail timeline | Atlas · typed action badges with deltas |
What’s needed from engineering
Section titled “What’s needed from engineering”Workstream 3 (the backend PRD) is the next deliverable I’m putting together. At a high level, the systems that need to exist to support these flows:
- Rider wallet service — current balance, transaction history, idempotent debit/credit, with overdraft support
- Station wallet wallet service — per-station wallet, station-to-rider subscription payment + cross-station transfers + reimbursement settlement
- Virtual account ingest — Opay/Paystack/Sterling settlement matching against rider phone numbers
- Inventory service — battery serial → station mapping, with multi-unit support for serial conflicts
- VCU command bus — Bluetooth + internet routes, manual code generation (HMAC w/ 90s TTL)
- Support case service — case state machine, routing, SLA tracking, audit trail
- Station-manager registry — who runs what, contact details, current station-wallet balance
- Notification service — push to manager phone, in-app banner, audit-trail entries
I’ll have a full agent-friendly PRD with API surfaces, state machines, event flows, idempotency keys, and edge cases ready for CTO review this week.
Decisions made along the way
Section titled “Decisions made along the way”A few non-obvious calls worth flagging:
- Daily fee is drawn before VCU connect, not after. A rider with zero wallet shouldn’t be able to half-swap. Deduction first; if it fails, the keke never opens. Saves us from “I unlocked the battery but the rider’s wallet won’t deduct” partial states.
- The wallet hero owns hierarchy on the profile page. Riders don’t care about the tricycle model — they care whether their money is here and whether it covers today’s swap. Everything else on the profile is metadata under it.
- No CSAT KPI on the support specialist dashboard. I can’t justify measuring it yet — surveys are 1-of-50 and noisy. We measure resolved/open/avg-time. Re-add when we have signal.
- Funds-with-other-station is a manual backend flow. Rider disputes are too contextual for automation. Support specialist calls both managers, verifies, moves money. The app captures the evidence so the specialist can do that fast.
- Battery problems are inventory-position bugs, not label bugs. The original framing collapsed everything into “mint a fresh serial”. After clarifying the underlying off-app-swap cause we now have four distinct resolutions, three of which never touch a printer.
- No emojis in the UI; no battery percentages anywhere. We don’t have electronic connection to the batteries yet, so showing 98%/12% is invented data. Removed across the board.
Cross-references
Section titled “Cross-references”| Doc | Where |
|---|---|
| Swap app design system | products/rechaj-swap-app/DESIGN.md |
| Atlas design system | products/atlas/DESIGN.md |
| Mobile swap support v3 prototype | products/rechaj-swap-app/prototypes/support-cases-v3.html |
| Atlas backoffice resolution prototype | products/atlas/prototypes/swap-support-resolution.html |
| Patterns library | patterns/ |
| Backend PRD (next deliverable) | coming this week |
Open questions for leadership
Section titled “Open questions for leadership”A short list of things I’d love a steer on before we hand to engineering:
- Station wallet top-up policy. Today stations self-fund their wallet (often the on-duty manager fronts the cash) and reconcile against ops at week-end. Should Atlas v2 own this directly? Affects scope of the wallet service.
- Overdraft ceiling. When the bank is slow on a funding-not-reflecting case, support overdrafts up to ₦X per rider per day. What’s X? Need a number from finance.
- Issue SLA targets. I’ve assumed 15-min target for in-swap-blocking issues and 24-hour for primary station changes. Worth a quick alignment.
- Primary station change cooldown. Should we prevent the same rider from changing primary station more than once a month? Prevents wallet-arbitrage gaming.