Release notes

What's new in EMS.

Every shipped change, in chronological order. Subscribe to our newsletter or follow to be notified of major releases.

v3.5.5.041 Latest 29 May 2026

Bulk-import overhaul, variant-aware production, customer-confirmed delivery, and a 5× capacity boost

Receiving & Inventory

  • One unified Bulk Import — a single CSV now lands a migration shipment, products, real per-box records, and optional skid placements in one upload. No more running Inventory then Storage as a two-step. Idempotent on re-runs.
  • Bulk-imported boxes are auto-received on landing, so units appear as Available immediately instead of being stranded as "Expected".
  • Bulk-imported skids now flow into Receiving → Put-Aways for manual placement verification, grouped by AWB — same model as live receiving.
  • Brand filter on the box scanner now hides off-brand lines on a mixed box, with a clear "N other line(s) hidden — clear the filter to scan them" notice. Lines stay intact in the box until you switch filters.

Production & Stamps

  • Variant-aware everywhere. Nicotine (mg) and volume (mL) now show as first-class columns on the Customer Requests inbox, the PO review screen, the Production Run allocation cards, the box-scan flavour picker, and the customer portal request form. No more guessing whether "Grape Ice" means 10mg or 20mg.
  • The flavour picker now distinguishes "Variant mismatch" (same flavour, different nic/mL on the PO) from a genuine "Not on PO" — with a line explaining exactly which variant the customer ordered.
  • Complete Skid → Add to existing or Create new. Operators with a small remainder can now top up an existing skid instead of wasting a slot. Damage / stamp accounting roll up correctly across the merge.
  • Multi-select box transfer on the skid detail modal. Tick boxes, pick a destination + reason once, transfer the batch.
  • Deleted skid numbers are reused — delete SK-XX-02 out of 1/2/3 and the next skid completes as 02, not 04.
  • Box scan auto-pre-selects the last stamp region you used on this PO — production lines typically stamp one region at a time, this saves a click per box.
  • Inline damage photo capture restored on the production scan form. Snap a photo while scanning instead of opening a separate modal for a common case.
  • New Found Damaged column on the Verify PO screen, distinct from Damaged (during production) and Missing. Pre-existing damage no longer counts against the production line's variance.

Customer Portal

  • Server-confirmed PO submission. The submit handler now waits for the server to confirm before showing success or generating the receipt PDF. No more "submitted!" toasts on writes that never reached the server.
  • Customers can now specify a Requested Delivery Date and delivery details when submitting a PO. Surfaces on the admin Customer Requests inbox and the PO review screen so you no longer chase customers for delivery info.
  • Production Orders page restructured into three sections — Shipments Awaiting PO · My Submitted Requests · Production History (a collapsible month-by-month accordion that combines completed requests + admin POs).
  • Skid Breakdown export now embeds a full Damage Report with affected boxes, units by damage type, notes, and a photo gallery.

Compliance & Reporting

  • Nova Scotia + custom stamp regions propagate everywhere — Stamp Orders, B600, customer portal request form — the moment you add them in Settings.
  • Admin-defined product categories. Add "Nicotine Pouches", "Vape Juice", anything you need. Custom categories flow into every dropdown the moment they're saved; stampable / non-stampable flags carry through to inventory rollups.
  • Total Litres calc fixed: case- and plural-insensitive category matching so "Disposable" and "Disposables" both count, and custom stampable categories are litre-bearing by default.
  • Stamping Summary PDF column widths reworked so the flavour column no longer overlaps the stamp type.
  • Customer-facing surfaces no longer leak admin / warehouse staff names — four leak points patched across PO updates, request history, timelines, and damage records.

Operations & Reliability

  • 5× capacity boost. Large shipments — hundreds or thousands of boxes — now fit comfortably. Transparent gzip compression of large records in the storage layer raised the effective per-shipment ceiling from ~400 KB to several megabytes of raw data, with zero changes required in the app.
  • Cold-boot resilience: a stuck write can no longer hang login. Permanently-failing writes are now parked to a dead-letter queue after a few retries, server-side size violations return a clear 413 (drop, don't retry), and the boot drain is hard-bounded so Auth always resolves.
  • Queue persistence: writes made just before a refresh or tab close survive in localStorage and replay on next load — no lost POs from a closed tab.
  • New 4 × 2 landscape option on the skid allocation label printer, alongside the existing portrait + square sizes.

Fixes

  • Nav alert badges populate on first login instead of waiting for a manual refresh.
  • Build Skid no longer needs a page reload after a fast double-action — saves now await durably before re-render.
  • Brand truncation on the box-scan flavour dropdown — long brand names no longer clip the flavour.
  • Reupload Documents on a re-parsed shipment no longer 500s on the blob path.
  • "Shipment not found" when saving a damage report from production scan is replaced with a box-number recovery + clearer error including the shipmentId for support.
  • iPad portrait UI: sidebar collapses to a drawer at <1024px and tables scroll cleanly inside their cards. AWB cards no longer disappear behind the sidebar.
v2.5.0 28 April 2026

Granular damage capture, scrollytelling marketing, and a global portal search

Receiving

  • Edit form on a Current Skid box now matches the initial scan UI: granular Damaged / Missing / Good unit inputs per line, with auto-recalculating totals on every keystroke.
  • Skid row visibly reflects damage: alert-red card background and per-line "N good / M" chips when a box has any damage or missing units.
  • Inbound tab ETA now uses the most up-to-date date available — pickup completion → scheduled pickup → estimated arrival → flight + 8 days — instead of always reading the stale wizard-time estimate.
  • Variant dropdown in the edit row stays inside the container even with long product names.

Production & Stamps

  • Production allocation (getShipmentAvailable, getShipmentTotalRemaining, getShipmentStampableRemaining) now respects per-box goodQty instead of raw packing-list quantity. Damaged and missing units no longer over-allocate stamps.
  • Customer portal inventory mirrors the same calculation — customers can no longer request a PO for damaged units.
  • Truck capacity capped at 12 skids (down from 13) per pickup trip — the warning toast and capacity calculator follow.

Customer Portal

  • New global search bar in the topbar — searches the customer's own shipments by AWB / supplier / status and production orders by PO number / linked AWB. Click a result to open it.
  • Portal sidebar carries a build-version chip so you can verify exactly what build is running.

Compliance & Reporting

  • NOA upload modal auto-fills the Schedule Pickup Date as Arrival + 1 day, and updates live if you change the arrival date.
  • All calendar tiles and event pills are now read-only across Dashboard, Shipping, Logistics, Production and Outbound — the calendar shows what's happening, dedicated module pages do the navigation.

Fixes

  • Damage report save no longer leaves the Logistics inbound view stale — re-renders whichever host container is currently mounted.
  • Receiving edit form clobbered the "Good units" display on row 0 when launching the edit (brittle div:last-child selector replaced with an explicit id).
  • Section render errors no longer take down the whole app — the Router now renders an inline error placeholder per section (admin + portal).
  • Cache-busted all <script src> and <link href> tags in index.html and portal.html so a Cmd-Shift-R always reaches your users.
v2.4.0 21 April 2026

Damage report split + alert-red flagging across the warehouse pipeline

Receiving / Logistics

  • Damage report on inbound shipments now offers three independent actions — Tag Box, Photo, Upload — instead of bundling box-tagging into the photo upload flow.
  • New "Tagged boxes" list above the photo gallery, with per-row Untag and a Confirm-all button.

Design

  • Sidebar version chip introduced — at-a-glance way to identify exactly which build a tester is running.
  • All red circular warning badges (sidebar nav, top-bar bell, stamp-orders pending) now use flexbox centering — text sits visually centered regardless of font.
v2.3.2 Patch 14 April 2026

Phase logic consolidated, error boundaries on render

Fixes

  • Shipment phase definitions consolidated in helpers.js as SHIPMENT_PHASES, eliminating drift between the admin and portal phase-bar implementations.
  • Router now wraps section-render handlers in try/catch — a single bad shipment can no longer take the whole app down. Portal inherits the same protection.
v2.3.0 02 April 2026

Customer Portal — production order request flow

Customer Portal

  • Customers can now submit production order requests directly from the portal — pick a shipment, allocate quantities by region (Federal, Ontario, Quebec, Alberta, Manitoba), and choose a production date with a calendar slot picker.
  • Drag-and-drop sequencing for stamping order across regions inside a single PO request.
  • "Urgent" toggle promotes the PO to the top of the next available production day, with admin notification.

Sub-accounts

  • Primary consignee account holders can now create sub-accounts for their team with granular per-section permissions (shipments, inventory, orders, reports, settings).
v2.2.0 17 March 2026

Outbound & Logistics module split

Outbound

  • Auto-generated outbounds from completed production orders, grouped by consignee.
  • Loading checklist with per-skid verification, BOL and packing-list PDF generation in one click.
  • Multi-stop dispatch support for routes hitting multiple retailers in one truck.

Logistics

  • Unified Logistics module with three tabs: Inbound (delegates to Shipping's pickup view), In-Transit, Outbound. Single calendar covering both sides of the warehouse.
v2.1.0 24 February 2026

Production scheduling, stamp ledger, batch IDs

Production

  • Drag-and-drop production sequencing across weekday slots with daily capacity caps.
  • Auto-overflow handling — if a PO exceeds a single day's cap, EMS splits it across consecutive days automatically.
  • Verification step before completion — actual scanned count vs estimate, with a stamp-count adjustment.

Stamp Orders

  • New module: incoming stamp inventory by region (any region you add), with approval workflow and request submission.

Batch IDs (optional module)

  • Per-PO + flavour + region batch IDs for unit-level traceability. Toggle on in Settings.
v2.0.0 06 January 2026

Multi-tenant rewrite — receiving, storage, customer portal

Highlights

  • Complete rewrite around a multi-tenant data model — every box carries its consignee from intake.
  • Six-zone warehouse layout (A–D, F, H) with auto-suggested slot assignments and a colour-coded occupancy grid.
  • Customer self-service portal launched: real-time shipment tracking, inventory view, dispatch view, scoped per consignee.
  • Cross-tab live sync — admin and portal stay in lockstep through the browser storage event.
  • IndexedDB-backed blob store for PDF and image attachments (NOA, damage photos), with metadata in localStorage.

Want notified of major releases?

Subscribe to the changelog newsletter — only major releases, never marketing fluff.