Skip to Content

ISSWA Shop Assistant App

ISSWA Shop Assistant: A Warehouse App Staff Actually Use
25 September 2026 by

Client: International Salon Supplies

Role: Full-Stack & Mobile Engineer

Period: Jan 2026 – Present

Status: Production (Google Play & App Store)

Tech stack: React Native, Expo SDK 54, Expo Router, NativeWind, TypeScript, Express 5, PostgreSQL, Drizzle ORM, Clerk, Expo Push, EAS Build, Retail Express SOAP API, Docker

An internal iOS and Android app for warehouse and store staff: barcode product lookup, shelf-refill and discrepancy lists, bin-location updates written back to the ERP, line-by-line order picking with barcode verification, and push notifications for new web orders. Shipped to both app stores and maintained continuously.

The problem

Warehouse and store staff at International Salon Supplies were juggling paper lists, a desktop ERP screen and memory. Which shelves need refilling? Where does this product live? Has this web order been fully picked? Every question needed a trip back to a computer.

ISSWA Shop Assistant puts those answers in their hands. Staff scan a barcode with the phone camera and get to work.

What it does

  • Product lookup by barcode scan (with torch support) or search
  • Shelf refill and discrepancy lists that staff build as they walk the floor
  • Recommended shelf refill: a prioritised worklist driven by stock coming back in and incoming purchase orders
  • Bin-location updates written straight back to Retail Express
  • Order fulfilment: pick web orders line by line with barcode verification, put orders on hold, add private comments
  • Customer stock alerts and in-store customer registration
  • Push notifications when a new web order arrives

Architecture

Retail Express ERP ──(existing sync)──► PostgreSQL (shared ERP mirror)
   ▲  SOAP write-back                      22 tables + 4 views
   │  (bin locations, order comments)            ▲
   │                                              │
Express 5 API ── Clerk JWT middleware ── Drizzle / SQL
   │  ~30 endpoints: stock-keeping, products, orders, customers, notifications, app-version
   │  new-order webhook ──► Expo Push (chunked, token-validated)
   ▼
Expo / React Native app (iOS + Android): 11 screens, camera scanning, OTA updates

The app reads from the same PostgreSQL mirror of the ERP that powers the company's CMS. Reads are fast and never touch the rate-limited ERP. Writes that must land in the ERP (bin locations, order comments) go through hand-built SOAP envelopes against the ERP's web services.

Engineering highlights

A shelf-refill list that thinks ahead

The most useful screen is driven by a single SQL query built from CTEs:

  1. Unnest purchase-order line items stored as JSON (json_array_elements).
  2. Keep only POs that are on order or being received and not held in customs.
  3. Aggregate expected arrival dates per product and outlet.
  4. Join "back in stock" events against available inventory.
  5. Exclude anything already on a staff member's fill list.

The result tells staff what to put on the shelf now and what's about to arrive, so they don't restock a bay that a pallet is about to fill.

Server-driven app updates

App Store review times vary, and you can't force people to update. An /app-version endpoint returns the latest and minimum supported version for each platform:

  • Builds below the minimum are hard-blocked with an update screen.
  • Builds between minimum and latest get a dismissible prompt.

Combined with Expo's over-the-air updates, most fixes ship in minutes. Breaking API changes can still be enforced without waiting for a store release.

Authentication done properly

Every endpoint moved to Clerk session-token authentication verified on the server, with a documented migration from raw fetch to an authenticated apiFetch wrapper and proper session-expiry handling. Every stock action is audit-logged with who, what and when, in Perth time.

Order picking as data

Each order's pick state is stored as JSONB per line (fulfilled, unfulfilled, completed), and a barcode-verification modal confirms the right item is in hand before a line can be ticked off.

By the numbers

  • ~17k lines of TypeScript (~12.5k mobile, ~4.6k server)
  • 11 screens, ~30 API endpoints, 22 tables and 4 views
  • 118 commits from Jan to Sep 2026, releases 1.0.1 (Jul 2026) and 1.0.2 (Sep 2026)
  • Published on Google Play and the Apple App Store

Lessons

  • Build on a shared read model. The app was quick to build because the ERP data already lived in PostgreSQL, synced by an event-driven worker.
  • Legacy SOAP is fine behind a clean API. The phone never knows the ERP speaks XML.
  • Design for the store queue. A version policy endpoint is a tiny piece of code that saves a lot of pain.