Omnichannel Commerce & Warehouse Platform
Every sales channel, warehouse and till working from the same stock figures
- Platform
- eCommerce
- ERP
- PWA
- Client
- VNE Tech Solutions
- Sector
- Supply chain & logistics
- Year
- 2026
- Platforms
- Web · Installable PWA
- Stage
- MVP

The project at a glance.
The platform serves retailers who sell through several channels and hold stock across warehouses and shops, and third-party logistics (3PL) providers who run warehouses for other brands. It brings orders, stock, warehouse work, tills, buying, invoicing and reporting into one system, so every team works from the same numbers and every change can be traced to the person who made it.
- Who it serves
- Warehouse teamsGoods-in, putaway, picking with scan checks, packing, dispatch, counts and returns workflows in the API, plus a phone-friendly app that the scan screens will plug into.
- Store and trade-counter staffTill logic for shifts, floats, X and Z reports, split payments with VAT, refunds and manager-override voids, with shop stock updated on every sale.
- Operations, buying and finance managersA back-office console for orders, stock and till sales, with requisitions, forecasts, invoicing, stock valuation and dashboards available through the API.
- 3PL clientsSelf-service API access to their own stock, orders, inbound delivery bookings and support tickets, with no visibility of anyone else's data.
More channels, more places for stock numbers to drift
Retailers and 3PL operators who sell online, on marketplaces, over the phone, to trade customers and in their own shops often run each channel on a different system: a webstore back end, a marketplace tool, a warehouse system, a standalone till and a spreadsheet to reconcile them all.
Every hand-off is a chance for the numbers to disagree. Stock sold in a shop still shows as available online, an order is promised from a site that cannot fulfil it, and when something goes wrong it is hard to tell who moved what, when and why.
A shared stock ledger behind every channel
VNE designed the whole platform before writing feature code, producing 21 design documents that cover requirements, architecture, data model, API, roles and permissions, screens, workflows, security, testing and delivery. It was then built module by module as an API-first, multi-tenant TypeScript platform.
At its core is a single stock ledger. Every receipt, putaway, pick, dispatch, till sale, transfer, return and stock count is recorded there as a permanent movement, and buying, forecasting and finance all work from the same figures. On top sit a back-office web console for managers, an installable warehouse app for the floor, and a documented REST API for channel integrations and 3PL client self-service.
What it does.
Order management across every channel
Webstore, marketplace, B2B, phone and manual orders follow one lifecycle, from validation and allocation through picking, packing and dispatch to completion. Channel orders can be imported through connectors that ignore duplicates and set aside anything they cannot map.
One ledger for every stock change
Every change is a permanent movement between 14 stock states, such as available, allocated, in transit and quarantine. Balances are updated in the same database transaction and can never be taken below zero, so stock cannot be oversold.
Goods-in, quality checks and putaway
Receive against a purchase order or without one, capture batch and expiry, flag over-deliveries and route stock to quality control. Putaway then suggests a bin that consolidates with existing stock or fills the next empty one.
Allocate, pick, pack and dispatch
Allocation reserves stock, taking batch-tracked items by earliest expiry, and backorders any shortfall. Picks can be checked against a scanned location and product barcode, then orders are packed into cartons and dispatched with tracking details.
Point of sale and trade counter
Till shifts with an opening float, X and Z reports and cash drops. Sales take split payments with VAT and change, refunds and voids put stock back on the shelf, and the back office lists every transaction.
Shops and warehouses working as one
Transfers between warehouses and stores are tracked while in transit, click & collect reserves shelf stock, and a routing engine ranks warehouses by whether they can fulfil the whole order, delivery postcode and priority.
Buying and demand planning
Requisitions are approved and converted into purchase orders, and supplier on-time, in-full performance is measured from receipts. Simple and weighted moving-average forecasts sit alongside safety-stock and reorder-point suggestions based on recent demand.
Finance, reporting and client billing
Invoices and credit notes with VAT, stock valuation at latest purchase cost, 3PL client billing for storage and pick-pack, an accounting export, four live dashboards and two exportable reports.
Roles, approvals and a full audit trail
30 roles built from a catalogue of 946 permissions, each assignable to a single warehouse, store, client, country or legal entity. Approval workflows apply value thresholds, alerts can be raised for batches nearing expiry, and an audit log records who did what.
See it in action.
Screens captured from the working application using fictional demo data.
How the operation runs, from purchase order to invoice
- 01
Buy
Requisitions become approved purchase orders, while demand forecasts and reorder-point suggestions show what to buy and when.
- 02
Receive and check
Goods-in records what actually arrived against the order, including batch and expiry. Lines flagged for QC wait for inspection, and failed stock goes to quarantine.
- 03
Store and replenish
Putaway tasks suggest a bin, and replenishment tasks top up pick faces from bulk stock when they drop below their minimum.
- 04
Sell on any channel
Orders arrive from connected channels, B2B and phone teams, or the shop tills. Click & collect reserves stock on the shop shelf.
- 05
Pick, pack and dispatch
Stock is allocated by earliest expiry, picks can be checked by scanning, cartons are packed and shipments are dispatched with tracking.
- 06
Return, invoice and report
Returns are authorised and routed back to stock, quarantine or disposal. Refunds and invoices are raised, and the dashboards draw on the same live data.
How it's built.
Every screen and every integration talks to one secure API, and the API writes every stock change to a single ledger in the database. The back office, the warehouse app, the tills and any connected webstore therefore work from the same numbers.
Technically, it is a pnpm and Turborepo monorepo. A NestJS 10 modular monolith (23 domain modules, 42 controllers) uses Prisma 5 over PostgreSQL 16, alongside a Next.js 14 back-office app and a Vite/React PWA. A shared package supplies typed contracts, enums and the permission catalogue to all three. The tenant and user for each request travel through AsyncLocalStorage, and modules are organised by business domain, following the design's bounded contexts, so they can be split into separate services later if needed.
- Back-office consoleNext.js 14, React 18: 14 pages for orders, stock, locations, tills, team and audit
- Warehouse Ops PWAReact + Vite, installable, Workbox app-shell caching, online/offline detection
- Integrators and 3PL clientsREST /api/v1 with generated OpenAPI docs and a client-portal API
- NestJS APIHelmet, rate limiting, whitelist validation, RFC 7807 error responses
- Identity and accessJWT with rotating refresh tokens, Argon2id, lockout, scope-aware permission guard
- Request contextAsyncLocalStorage tenant and principal, request IDs, audit writer
- Inventory ledger engineSingle oversell-safe, idempotent posting path for every stock change
- Warehouse operationsGoods-in, QC, putaway, replenishment, FEFO allocation, pick, pack, dispatch, returns
- CommerceOrder management, POS shifts and sales, transfers, click & collect, routing
- Planning and financeProcurement, forecasting, invoicing, valuation, 3PL billing, BI, approvals
- Integration frameworkConnector registry, SKU mapping, secret-checked webhooks, dead-letter queue
- PostgreSQL 1688 Prisma models across 17 versioned migrations
- Movement ledger and balancesImmutable stock movements with projected balances by location, state and batch
- Outbox, idempotency and auditTransactional outbox events, unique idempotency keys, audit log
- Row-level security scriptTenant-isolation policies prepared for 81 tables
- Docker imagesSeparate images for the API, web console and PWA
- Railway configurationHealth-checked API service; container entrypoint runs migrations and seed
- GitHub ActionsBuild, typecheck, migrate, unit and end-to-end tests, image builds
Technology
Frontend
- Next.js 14
- React 18
- TypeScript 5
- Vite 5
- vite-plugin-pwa (Workbox)
Backend
- Node.js
- NestJS 10
- class-validator
- @nestjs/throttler
- Helmet
Data
- PostgreSQL 16
- Prisma 5.22
- Row-level security policy script
Integrations & APIs
- REST API with OpenAPI and Swagger UI
- Connector framework (sandbox adapters)
- Secret-checked inbound webhooks
Auth & Security
- JWT access and rotating refresh tokens
- Argon2id password hashing
- Account lockout
- Scoped RBAC: 30 roles, 946 permissions
Hosting & DevOps
- pnpm workspaces
- Turborepo 2
- Docker
- Railway configuration
- GitHub Actions
Testing & Quality
- Jest 29
- Supertest 7
- ts-jest
- 128 end-to-end and 17 unit tests
The hard parts, solved.
- 01
Stock that cannot be oversold
Every operational module changes stock through one ledger function. In a single database transaction it reduces the source balance with one conditional update (which only succeeds if enough stock is there), adds to the destination, writes a permanent movement row and records an outbox event. Two operators or tills competing for the last units get a clean refusal instead of negative stock, and an idempotency key backed by a unique index stops a retried request from being posted twice. End-to-end tests cover both the oversell refusal and the replayed request.
- 02
Tracking stock states, not just quantities
A unit can be awaiting QC, available, allocated, reserved for click & collect, in transit, awaiting dispatch, quarantined or damaged. Balances are keyed by SKU, location, state, batch, serial and client, and allocation moves stock from available to allocated in place, picking batches by earliest expiry. Corrections such as count variances, voids and cancellations are posted as new compensating movements rather than edits, so the history always adds up.
- 03
Access control across tenants, sites and clients
Every request carries its tenant and user context, and a deny-by-default guard checks a resource-and-action permission on each endpoint. Role assignments can be limited to one warehouse, store or client. A warehouse manager, for example, can view sales orders but cannot release them, because that permission belongs to order management. 3PL portal users only ever see their own products and orders, which the test suite checks, and a row-level security script prepares database-enforced tenant policies as a further layer.
- 04
Channels that retry, duplicate and fail
Order imports are keyed on the channel's own order ID, so a webhook delivered twice creates only one order. Orders containing products the platform cannot map are moved to a dead-letter queue with the error recorded, and can be reprocessed once the mapping is fixed. Connector secrets are masked whenever connectors are returned by the API, outbound stock-level updates are generated per SKU, and courier labels come from a sandbox adapter until live carriers are connected.
- 05
Delivering a 30-module design one module at a time
The platform was designed in full first and then built module by module. Each business module was delivered with its own end-to-end suite (19 in all) that drives the real API against PostgreSQL, so every new module was tested alongside the behaviour of the ones before it. GitHub Actions is set up to build and typecheck the API, migrate and seed a database and run all 145 tests on every push, and a second workflow checks that the API, web and PWA Docker images build.
The full operational loop, running through the API
The API already runs the full operational loop: buy, receive, check, put away, sell on any channel, pick, pack, dispatch, return, refund, invoice and report. All 145 automated tests pass against a freshly migrated PostgreSQL 16 database.
The back-office console gives managers live visibility of orders, purchase orders, stock, locations, till sales, the team and the audit trail, and can create warehouses, stores, clients and users and handle user approvals. The till, returns, forecasting, finance, workflow and BI screens are designed and currently run through the API. The warehouse app is an installable, offline-aware shell whose scan-by-scan screens are the next build step, and channel and courier connectors run in sandbox mode, ready for live adapters.
Container images, Railway service configuration and CI are in place, so the platform can be deployed and extended one module at a time.
- Product strategy
- Full-stack development
- Data modelling
- Systems integration
- DevOps