AppleSmart
Nine WordPress installations for a post-harvest treatment supplier: eight client portals and one central service that works out the dose for each cold store, splits it across the pack sizes in stock, and numbers every transport document without ever repeating one.
- Type
- Production system
- Area
- Operations & tools
- Main stack
- WordPress · PHP · MySQL · Gravity Forms
Key features
- • Dose worked out from the volume of the cold store and the coefficient of the variety, along a curve interpolated over historical reference points
- • The total split across the pack sizes in stock, always rounding down
- • Document numbers allocated atomically: transaction, row lock, named lock, idempotency key
- • Two independent series shared between clients; a number freed by a deleted order goes back into use
- • A retry returns the number already assigned; the same key for a different order is refused
- • Editing an issued document reverses the old stock movement before applying the new one
- • Warehouse load and unload with an availability check that blocks the save
- • Cold-store watch that mails each responsible operator
- • Eight client sites gathered into one operator dashboard through sandboxed frames
- • Scripted deployment: read-only by default, writes behind an explicit switch
About the project
AppleSmart, a management platform for post-harvest fruit treatment, built as an application layer on top of WordPress and spread across nine installations: eight client portals, one for each cooperative, and a central service that coordinates them.
A cooperative files the treatment requests for its cold stores from its own portal; the platform works out the dose; the supplier's operators work the order, issue the transport document and unload the product from the warehouse. The central service keeps the inventory by lot, numbers the documents and gives the operators one dashboard over every client.
Two problems in it are harder than they look, and neither is the paperwork.
The first is the dose: the product a cold store needs comes from its volume and the coefficient of the variety in it, turned into a dose by a curve interpolated over historical reference points, and that total then has to be split across the pack sizes actually in stock - 8.5 g and 2.5 g sachets, 1000 and 250 tins - always rounding down, because a treatment that rounds up is product nobody paid for. The quantities stay editable by the operator, and editing an already issued document settles the warehouse by the difference rather than by writing the new figure over the old.
The second is concurrency: every transport document needs a number that is never duplicated and never burned, while several devices submit orders at the same time across separate sites. The allocator runs inside an explicit MySQL transaction, locks the sequence row for update, takes a named lock as a second barrier, and matches an idempotency key the browser generates and keeps across retries: a reload or a dropped connection replays the number already assigned instead of taking a new one, and the same key arriving for a different order is refused outright. It runs over two independent series shared between clients, and a number left free by a deleted order goes back into use rather than staying a hole in the sequence.
Around that sit tenancy on shared hosting - shared databases separated by table prefix, with the central service exposing REST endpoints to the client portals - traceability by lot, with stock and a load-and-unload history per pack size, so issuing a document unloads from the lot it was drawn from; visibility by role, where a client sees only its own orders and an operator sees them all; warehouse load and unload with an availability check, editing an already issued document by reversing the old stock movement before applying the new one, server-side drafts validated against the stock they were written from, a cold-store watch that mails each responsible operator, and an operator dashboard that gathers every client panel into sandboxed frames.
Deployment is scripted rather than manual: read-only by default, writes behind an explicit switch, and the remote password read from the Windows credential store instead of a file.
Technologies used
WordPress
PHP
MySQL
Gravity Forms
GravityView
Elementor Pro
REST API
WP-CLI
PowerShell