Warehouse mobile app
The warehouse app is a touch-friendly Vue 3 SPA opened in the browser of a barcode-scanner-equipped tablet or fixed workstation on the floor. It covers four operational flows — Incoming (receipts), Transfer (position-to-position moves), Shipment (outgoing picks and packing), and Inventory (count sessions and on-the-fly checks) — plus a login screen.
Camera-based barcode reading runs through
@zxing/browser'sBrowserMultiFormatReaderagainst the device'sMediaDevicesAPI; label printing goes throughbrowserprint-esto a directly-addressable network printer. The warehouse app is a pure web application — no app-store installation is required.
Key screens
Login
How to reach: open the warehouse SPA URL in the browser (Traefik routes it; see Deployment). The root path / redirects to /login.
What you can do here:
- Enter username and password, then submit Inizia sessione (
session_start) to authenticate. - If the backend returns
action: reset_password, set and confirm a new password before the session starts. - After verification, the welcome screen names the operator and redirects to the operator's home — by default
IncomingRoot, or theredirect_toquery parameter if one was set.
Expected business logic:
- Authentication posts to
/authand stores the returned JWT in a cookie namedAuthorization; the same JWT mechanism backs the main webapp (API reference). - A successful auth issues a follow-up
POST /sessioncall which the store treats as the start-of-session signal.
Incoming
How to reach: login → Incoming home (route: /warehouse/incoming/, name IncomingHome). Open a planned list at /warehouse/incoming/list/{listKey} or start a free-form receipt at /warehouse/incoming/manual (IncomingManual).
What you can do here:
- Browse incoming lists grouped by date and supplier; each card shows the list code and a
completed / plannedrow counter. - Tap Nuovo (
incoming_new) to start a manual receipt that walks through the stages product → quantity → serials → position → confirm (thestageComponentMapinIncomingManual.vue). - Scan or search a product, set the received quantity, capture serial codes if the product is serialised, and assign the receipt to a destination position.
Expected business logic:
- Confirming a receipt creates inventory movements into the chosen destination position; the resulting domain event is MovementCompletedEvent .
- Lists flagged
due(today) andoverdue(pastdue_by) are highlighted on the home view so the operator can prioritise.
Transfer
How to reach: login → Transfer home (route: /warehouse/transfer/, name TransferRoot). Manual transfers run at /warehouse/transfer/manual (TransferManual).
What you can do here:
- Tap Nuovo trasferimento (
transfer_new) and choose the starting axis — Prodotto (product), Seriali (serial), or Posizione (position). - For a product-led transfer, search the product, pick inventory rows from the available positions (
TransferManualProductInventory), then choose a destination position (TransferManualDestination). - For a position-led transfer, scan the source position, pick contents to move (
TransferManualPositionContents), then scan the destination. - For a serial-led transfer, scan or enter the serial codes (
TransferManualSerials) before selecting a destination. - Final stage is
confirm(TransferManualConfirm) — review and commit.
Expected business logic:
- A confirmed transfer records an inventory movement from the source position to the destination position; serials carry through unchanged.
- Cross-link: MovementCompletedEvent .
Shipment
How to reach: login → Shipment home (route: /warehouse/shipment/, name ShipmentHome). Open a planned shipping list at /warehouse/shipment/list/{listKey} or a manual outbound at /warehouse/shipment/manual (ShipmentManual).
What you can do here:
- Browse outbound lists grouped by date and customer; the same
completed / plannedcounter anddue/overduehighlighting as Incoming. - Open a list to pick its rows; the item card walks through inventory selection (
ShipmentItemInventorySelection) and confirmation (ShipmentItemConfirmation). - Tap Stampa etichetta (
print_label) on the selected item to print a product label viaprintProductLabel(...)— this is thebrowserprint-esdirect-printer path. - Tap Avanti (
next) once a quantity is selected, choose source positions, then Conferma (confirm) to commit.
Expected business logic:
- Confirming an item dispatches one or more
MOVEMENT_UPDATEDevents viasendEventsBulk(...), marking planned movements ascompletedwith the picked positions and quantities. - Serial-bearing rows match each scanned inventory line back to the planned movement that already names that serial; non-traceable rows split the planned quantity across the picked positions via
split_into.
Inventory (count scanning)
How to reach: login → Inventory home (route: /warehouse/inventory/, name InventoryHome). Open an assigned count session at /warehouse/inventory/count-session/{countSessionKey}. Ad-hoc checks live at /warehouse/inventory/product, /warehouse/inventory/serial, and /warehouse/inventory/position.
What you can do here:
- See the list of
startedcount sessions assigned to this warehouse, each card showing the session code, description, type, anddue_bydate. - Open a session — product-typed sessions render
CountingProductBrowser; position-typed sessions renderCountingPositionBrowser— and scan positions, products, or serials to record actual on-hand quantities. - For inventory checks outside a session, jump into Prodotto (
product), Seriali (serial), or Posizione (position) browsers to inspect current inventory and search by code.
Expected business logic:
- The session is created and assigned from the main app's Counting module; scanning takes place here. The warehouse app loads the session via
loadCountSessionData(...)and submits scan data back to the API. - Submitted counts feed into the count session and, on session apply, generate CountSessionAppliedEvent .
Related
- Counting (main app) — count sessions are created and assigned here; scanning runs in the warehouse app
- Deployment — how the warehouse SPA is served and which URL to use
- Events: inventory
- Coverage philosophy