intermediate
battery
lifecycle
states

Pack Lifecycle States

Every state a battery pack moves through in Levy Swap, the legal transitions between them, and how the audit log works

Levy Fleets TeamMay 18, 20266 min read

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

StateWhat It MeansSet By
orderedPack record exists, QR minted, but pack not in hand yetMint dialog
receivedPack physically received at a warehouse or station; not yet installedReceive flow
deployedPack assigned to a vehicle and currently the installed packSwap-complete (install side)
in_useSynonymous with deployed in some views — pack is the active pack on a vehicleSystem
returnedPack removed from a vehicle and pending decision (recharge, recycle, warranty)Swap-complete (remove side)
recycledPack retired permanently and sent for disposalManual / forced retirement

Station / Charging States

StateWhat It Means
chargingPack is in a station slot, plugged in, not yet at full charge
chargedPack is in a station slot at ≥95% and ready to install
maintenancePack 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).

The CHECK trigger on battery_packs allows only these transitions:

  • ordered → received
  • received → deployed (first install)
  • received → charging or received → charged (load into station first)
  • deployed → returned (swap out)
  • returned → charging or returned → maintenance (post-swap routing)
  • charging → charged
  • charged → deployed (install on a vehicle)
  • maintenance → charging, maintenance → returned, maintenance → recycled
  • returned → 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_status and to_status
  • actor_typesystem, team_member, or juicer
  • actor_id — the user UUID
  • swap_event_id — when the transition was part of a swap
  • station_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:

  1. Concurrency check on swap-out — we read the pack's current in_use flag to make sure we're not double-swapping. If two techs scan the same pack from two vehicles, one of them gets a rejection.
  2. 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.

  • "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 received for 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 maintenance from a slot defect, or to returned if someone scanned it out by mistake.

See Troubleshooting for the full list.