Skip to content

v1.31.0 -- Returns void, fulfillment fixes, audit gate

Choose a tag to compare

@mhightower932 mhightower932 released this 18 Aug 22:10
· 53 commits to main since this release
ed921e3

Returns handling, transfer-order and shipping fixes, and a dependency-audit gate that can accept a single advisory without dropping the whole check.

Added

ADMIN void (soft-delete) for return orders (#430). Operators occasionally create a return SO (order_type='return', the <orig>-RMA goods-in record) by mistake, and there was no order-level delete. The generic cancel unwinds outbound allocation and picking, which is wrong for a goods-in return. POST /admin/sales-orders/<id>/void-return stamps voided_at / voided_by (migration 076) and writes a RETURN_VOID audit entry; the row and its audit trail persist while the sales-order list hides it, so the RMA drops off the page. Gated to return orders that are OPEN, un-received, and carry no linked refund. ADMIN-only, stricter than the cancel route, because the action is destructive from the operator's point of view. Re-voiding is idempotent.

Per-advisory npm audit allowlist (#429). npm audit has no --ignore-vuln, so accepting one unreachable advisory previously meant dropping the gate entirely. .github/scripts/npm_audit_gate.py wraps npm audit --json and applies an AUDIT_ALLOW list of GHSA ids, where an entry suppresses only its own id. A new advisory on an allowlisted package still blocks the merge, and an allowlisted id that stops being reported is warned about as stale, so the list cannot quietly rot into a blanket bypass.

Changed

RMA disposition bin is a searchable field (#431). The receive screen preloaded up to 500 bins into a dropdown and auto-selected whichever sorted first, so returned goods could land in the wrong bin unnoticed and a large warehouse was silently truncated to its first page. It now uses the same debounced server-side bin search as Adjustments, scoped to the chosen disposition warehouse. The bin starts empty and must be picked, and clears when the warehouse changes so one from the prior warehouse cannot carry over.

Dependency advisories cleared across all three trees (#429). cryptography 48.0.1 to 50.0.0; admin react-router 7.17.0 to 7.18.2, undici 7.28.0 to 7.29.0, plus js-yaml, nanoid, brace-expansion and postcss inside their existing ranges. The admin tree reports zero vulnerabilities. image-size is allowlisted on the two mobile jobs: both parser advisories name a vulnerable range of <= 2.0.2 and 2.0.2 is the latest published release, so there is nothing to move to, and it is reached only through Expo's bundler at build time, never on device.

Fixed

Transfer order auto-submits when its pick batch completes (#432). complete_batch only ever flipped sales orders to PICKED, so finishing a transfer-order pick batch left the TO at PARTIALLY_PICKED with no approval row. With the batch then COMPLETED, the handheld's pick guard found no open batch and admin start-picking refused because no lines remained, deadlocking the TO. The picker submit logic moves into transfer_order_service.submit_picks and complete_batch calls it for each transfer order the batch picked, so a hand submit and a batch completion take the same path.

Actual ship method persisted on the SO header (#433). record_ship wrote carrier and tracking number to the header but left ship_method at its ingestion value, so an order shipped on a different carrier kept a stale method above a contradicting tracking number. ship_method joins the header UPDATE, COALESCE-guarded so methodless local-pickup ships keep their value. This is the stored-value complement to the display-only fix in v1.29.1.

Admin version display was stuck at 1.29.1 on the Settings page, and the docs Current Version list skipped v1.30.0. Both are corrected.

Migrations

076 sales_orders_void_return: adds voided_at TIMESTAMPTZ and voided_by VARCHAR(255) to sales_orders. NULL voided_at means live. Only return SOs ever carry it, so normal sales orders are unaffected.

Mobile

No mobile source diffs. The build stays at version 1.29.0 / versionCode 10 and no new APK is cut for this release. The mobile dependency tree does move (js-yaml, tar, nanoid updated; postcss / nanoid pinned through overrides), all build-tooling only.

Verification

Merged-main suites: api 2869 passed / 9 skipped, admin 101 passed, mobile 44 passed.