Box CLILive upgrades

Live Box upgrades

Publishing a package makes it available to Boxes. It does not change a running Box, restart a service, migrate a database, or replace an Android app. Each deployed Box must update its source checkout, build the new package graph, and deploy that build. Android Till apps follow a separate release channel.

What updates what

ActionUpdatesDoes not update
box upgradeThe Box CLI binary on the operator’s machine or build host.A Box’s installed packages, database, running containers, or Android apps.
box updateThe entitled @withpotter/* engine and dashboard package graph in the current Box checkout, its lockfile, generated routes, and validated production build.A running deployment or installed Android APK.
Rebuild and deployThe running Box engine and dashboard. Engine startup applies pending package migrations.Android apps already installed on Till hardware.
Android app releaseEmbedded ARR libraries and optional Till UI inside the host app, or the demo APK.The Box engine and dashboard.
⚠️

Run box update from the Box repository you intend to deploy. Updating a developer checkout does not update a different checkout used by CI, Railway, a VPS, or another customer Box.

Production rollout

Record the current state

Before changing the checkout, record the deployed commit, package lockfile, database backup, and service health. Commit or stash intentional local changes.

git status --short
git rev-parse HEAD
box --version
box status
box update --check

Take a database backup using the deployment provider’s normal backup process. Do not rely on an application rollback to reverse a database migration.

Upgrade the CLI

Use a current Box CLI before updating package state:

box upgrade --check
box upgrade
box --version

box upgrade changes the CLI binary only. It is safe to check or perform before touching the Box checkout.

Update the Box checkout

Run the package update from the Box root:

box update --check
box update
git diff -- package.json package-lock.json

box update resolves the entitled package graph as one compatible closure, refreshes stale lockfile entries, regenerates dashboard route stubs, detects logical App Router collisions, and runs a production build. It reports success only after that build passes.

Commit the package and lockfile changes so the deployment uses the exact graph you tested:

git add package.json package-lock.json console/scripts
git commit -m "chore: update Box packages"
git push

Rebuild and deploy

Use the Box’s normal deployment pipeline. For a Docker Compose deployment:

docker compose up -d --build

For Railway or another managed provider, deploy the commit produced in the previous step. Do not restart an old image and call it an upgrade; the image must be rebuilt from the updated lockfile.

Let the engine migrate

The engine applies pending package migrations during startup. Keep only one migration owner running while the new release starts, and inspect its startup logs before increasing traffic.

For bounded operator shifts, the additive migration:

  • keeps existing operator PIN verifiers unchanged;
  • assigns existing operators a default shift duration of 360 minutes;
  • adds session expiry and closure metadata;
  • reconciles historical duplicate open sessions; and
  • enforces one open session per tenant and operator.

No plaintext PIN migration is required. Merchants do not need to reset existing PINs. They can change an operator’s limit later from POS Operations → Operators → Edit operator.

Verify the Box

At minimum, verify:

curl --fail https://api.your-box.example/health

Then sign in to the merchant dashboard and check:

  • Products shows Import CSV beside Export and Add Product;
  • POS Operations shows each operator’s shift limit;
  • editing an operator persists a value between 15 and 720 minutes;
  • opening a Till shift produces the configured server expiry; and
  • signing the same operator into another device closes the earlier session.

Upgrade Android Tills

Upgrade Android only after the engine and dashboard are healthy. A host app that embeds ARR updates its Maven dependencies, rebuilds, tests, and distributes the new app through its normal device-management channel:

app/build.gradle.kts
dependencies {
  implementation("com.withpotter.box:box-commerce:0.1.0-alpha.4")
  implementation("com.withpotter.box:box-arr-ui:0.1.0-alpha.4")
}

Demo Till users install the matching APK:

adb install -r box-demo-0.1.0-alpha.4.apk

The -r install preserves the app’s linked-device data. Verify a 60-minute idle lock, wrong PIN rejection, correct active-operator PIN resume, continued heartbeats while locked, and an unchanged server session ID.

Rollback

If verification fails:

  1. Stop the rollout before updating more Boxes or Tills.
  2. Capture engine, dashboard, migration, and device logs.
  3. Redeploy the previously tested Box commit and lockfile.
  4. Restore the database backup only when the release notes or migration owner require it. Do not run ad hoc SQL against a partially migrated database.
  5. Roll Android devices back through the host’s normal app-distribution process.

Android and Box versions do not have to share the same version number. They do have to satisfy the release’s documented API contract. Roll out the engine and dashboard first so the new client never reaches an older API contract.

For several live Boxes, update one canary Box first. Complete engine, dashboard, migration, and Till verification there before rolling the same committed lockfile and Android build to the rest of the fleet. Record the deployed commit, package versions, migration result, and APK version per Box.

See also