Client: International Salon Supplies
Role: Senior Software Engineer
Period: Apr 2023 – Present
Status: Overview
Tech stack: Retail Express REST & SOAP, WooCommerce, WordPress, Next.js, NestJS, RabbitMQ, PostgreSQL, Elasticsearch, Typesense, Tyro, PayPal, Afterpay, Zip, Stripe, MachShip, Cario, Omnisend, Maropost, Monday.com, Cloudflare, DigitalOcean, Google Workspace, MCP
An overview of the systems I've designed and connected at International Salon Supplies since 2023: roughly 30 third-party and in-house APIs across ERP, e-commerce, payments, freight, marketing, search and AI, organised around a single event stream from the ERP. Start here, then follow the links into each project.
The shape of the business
International Salon Supplies (ISS) supplies salons, barbers and beauty professionals in Western Australia through a wholesale website, retail stores, a skincare brand (Tuel) and a network of dropshippers. The single source of truth is Retail Express (REX), an ERP with a modern REST API and an older SOAP web service.
Since 2023 I've built the systems around that ERP. This post is the map.
One event stream, many consumers
Retail Express ERP
(REST v2 / v2.1 · SOAP)
│
Sync engine (NestJS + PostgreSQL)
delta polling → outbox → RabbitMQ
│
┌──────────────┬──────────────┼───────────────┬──────────────┬─────────────┐
▼ ▼ ▼ ▼ ▼ ▼
Wholesale Tuel store CMS / Ops Dropshipper Monday.com Mobile app
website (headless) platform API PO sync (warehouse)
Every system on the right is fed by that same stream, either directly or through the PostgreSQL mirror it keeps up to date, instead of polling the ERP itself. That one decision made each later project faster to build and easier to reason about.
The projects
Commerce
- ISSWA 2.0: headless wholesale platform
- Tuel Skincare: headless re-platform
- Dropshipper B2B product-feed API
Operations
- ISSWA CMS: from product CMS to operations platform
- ISSWA Shop Assistant mobile app
- MachShip scan-to-consignment
- Monday.com ↔︎ Retail Express PO sync
- Price list reconciler (Excel + Access)
- Reporting automation toolkit
Data & AI
Infrastructure & tooling
- Website migration toolkit
- Email migration to Google Workspace
- Self-hosted company wiki
- IE-in-Chrome via Native Messaging
- GTM dataLayer tracker
- PDF size tools
- Odoo 19 exploration
APIs in the mix
| Area | Systems |
|---|---|
| ERP | Retail Express REST 2.0 & 2.1, Retail Express SOAP web store |
| E-commerce | WooCommerce REST, CoCart, WPGraphQL, custom WordPress endpoints |
| Payments | Tyro, PayPal, Afterpay, Zip, Stripe, Simplify |
| Freight | MachShip, Cario |
| Marketing | Omnisend, Maropost, Meta Conversions API, GA4, Google Merchant Center |
| Search | Elasticsearch, Typesense, semantic-search experiments |
| Work management | Monday.com GraphQL |
| Infrastructure | RabbitMQ, Cloudflare (KV, Workers, Turnstile, cache), DigitalOcean (Spaces, CDN, managed databases) |
| AI | Gemini, Claude, OpenAI, Model Context Protocol |
| In-house services | Sync engine, storefront BFF, dropshipper API, PDF service, image processor, 404 catcher, MachShip relay, error handler |
Recurring patterns
- Mirror the ERP once. A PostgreSQL copy of ERP data takes load off a rate-limited API and becomes the read model for everything else.
- Buffer before you ack. Consumers write to a local store before acknowledging the broker, so a slow downstream never loses a message.
- Idempotent everything. Upserts keyed on ERP IDs, message IDs with attempt counters, and re-runnable migrations.
- Embrace the REST/SOAP split. Read over REST, write over SOAP where the ERP requires it, and hide that behind a clean interface.
- Let the business change rules safely. Sandboxed filters, editable templates and admin screens, not redeploys.
- Give LLMs read-only, least-privilege access. Dedicated roles, curated views, sandboxes and tests that prove the boundaries hold.