Pack Lifecycle States
Every pack in Levy Swap is always in exactly one lifecycle state. The state machine is enforced server-side — illegal transitions are blocked at the database level, not just the UI, so a misbehaving client can't corrupt the history.
The State Machine
ordered → received → deployed → in_use → returned → recycled
↓ ↑
swap_in swap_out
↓ ↑
in-station ← → charging → charged
↓
maintenance
Primary Lifecycle States
| State | What It Means | Set By |
|---|---|---|
| ordered | Pack record exists, QR minted, but pack not in hand yet | Mint dialog |
| received | Pack physically received at a warehouse or station; not yet installed | Receive flow |
| deployed | Pack assigned to a vehicle and currently the installed pack | Swap-complete (install side) |
| in_use | Synonymous with deployed in some views — pack is the active pack on a vehicle | System |
| returned | Pack removed from a vehicle and pending decision (recharge, recycle, warranty) | Swap-complete (remove side) |
| recycled | Pack retired permanently and sent for disposal | Manual / forced retirement |
Station / Charging States
| State | What It Means |
|---|---|
| charging | Pack is in a station slot, plugged in, not yet at full charge |
| charged | Pack is in a station slot at ≥95% and ready to install |
| maintenance | Pack is held back from inventory — defect, warranty claim, awaiting inspection |
A pack can move between charging, charged, and maintenance freely while sitting in a station. It can only re-enter deployed from charged (you cannot install a pack that's still charging or flagged for maintenance).
Legal Transitions
The CHECK trigger on battery_packs allows only these transitions:
ordered → receivedreceived → deployed(first install)received → chargingorreceived → charged(load into station first)deployed → returned(swap out)returned → chargingorreturned → maintenance(post-swap routing)charging → chargedcharged → deployed(install on a vehicle)maintenance → charging,maintenance → returned,maintenance → recycledreturned → recycled(forced retirement)charged → maintenance(post-charge defect found)
Terminal state: recycled. Once a pack is in recycled, no further transitions are allowed and the row is preserved forever for warranty / audit traceability.
Forced Retirement
When SoH drops below 40, the next swap automatically routes the pack to returned and then recycled instead of putting it back into station inventory. This is intentional — sub-40 packs should not be re-deployed.
The Audit Log
Every state change writes a row to battery_pack_history. The trigger captures:
from_statusandto_statusactor_type—system,team_member, orjuiceractor_id— the user UUIDswap_event_id— when the transition was part of a swapstation_id— when the transition was a station slot move- Timestamp
This log is append-only and retained forever. It's what makes warranty claims possible — when you file a defect with OKAI or Segway, the export includes the pack's full state history with timestamps.
What "in_use" Means in Practice
in_use and deployed are very close. Both mean the pack is installed on a vehicle. The distinction matters in two places:
- Concurrency check on swap-out — we read the pack's current
in_useflag to make sure we're not double-swapping. If two techs scan the same pack from two vehicles, one of them gets a rejection. - Juicer eligibility — a bounty engine cannot create a bounty for a vehicle whose installed pack is flagged
maintenance. The check happens at the pack level, not the vehicle level.
For most dashboard views, treat the two as equivalent.
Reading the History
From any pack's detail page, the History tab shows the full transition log. You'll see:
- Initial mint event (
ordered) - The receive scan (
received) - Every install / uninstall (
deployed/returned) - Every charge cycle (
charging/charged) - Any maintenance or warranty events
- Terminal recycling event
For high-volume packs that have been swapped 100+ times, the history paginates by month.
Common State-Related Issues
- "Pack is in use" error during a swap — the pack you just scanned is already installed on another vehicle. Re-check which physical pack you have in your hand.
- Pack stuck in
receivedfor weeks — the pack was minted and received but never installed. Either install it on a vehicle or move it into a station slot (received → charging). - Pack you expected to see is missing from station inventory — check the audit log; it may have transitioned to
maintenancefrom a slot defect, or toreturnedif someone scanned it out by mistake.
See Troubleshooting for the full list.