Short write‑ups of problems we hit running a real commerce operation and what we changed in the code because of them. No product announcements; just the reasoning.
A dashboard that makes ordering easy invites dumping. What stops the purchaser ticking everything red and calling it someone else's problem - a hard cap built from measured deliveries, a shared warehouse split fairly, and a rule about never letting anyone edit the number that judges them.
Data can only predict the past. Our stock forecaster leans into that - measure the past honestly (including the days the shelf was empty), then say how wrong you might be.
Almost every piece of paper the business touches is a PDF we generated — invoices, delivery notes, picking sheets, pallet returns, timesheets, barcode labels in five widths, carrier labels from three APIs. How one rule decides between mpdf and headless Chrome, how a single invoice template serves shops in different countries, languages and tax regimes without forking, and the gotchas: a bakery called "& Fils" that broke shipping, labels that must scale from 55 mm to 125 mm, and why we merge PDFs with a renderer that never renders them.
One morning every page in the back office threw errors for about two seconds, and the trail led somewhere strange — a queue that had been renamed in June and never given a worker, quietly growing to 6.9 million jobs and 18 GB inside Redis until the box was living in swap and one routine Lua script stalled past the busy threshold. How we traced a frontend error bucket to a key nobody was reading, why deleting it had to happen before fixing it, the eager-loading bug hiding behind the first fix, and the one-hour check that would have caught the whole thing in week one.
The new system's name wasn't invented for a rebrand — and it wasn't even the first name. In October 2020, years before aiku served its first request, a file called trait.Aiku.php appeared inside Aurora, pushing entity changes to a system that barely existed. The app that eventually caught those changes was born as "Pika" — an experiment to extract warehouse picking into a micro-service, started on a warehouse visit in Eastern Europe — and only became aiku by a rename ticket in March 2023. This is the archaeology of a name.
Every codebase has a birthday; Aurora — the system aiku replaced — has a timestamp, a timezone and a table by the window. The header at the top of its entry point reads "Created: 27 August 2015 12:49:03 GMT+8, Singapore", and the commit from that day says "thought experiments to a full SPA". This is the origin story — the 2008 system that came before it, the habit of writing the city into every file header, and how "aiku" was a trait inside Aurora years before it was a product.
14,880 commits from 2008 to today, read not as a changelog but as a diary. The ticket prefixes that name the eras (KAKTUS, CSER, PIKA), the hour histogram with its 3am tail, a New Year's Day spent chasing a search bug with the typos getting worse by the hour, "brexit nightmare", "leap year hack", and the honest admission a commit message almost never makes: "Stock Levels don't add up..we think".
The next thing we are building — an MCP server for customers, so a trade buyer or a dropshipper can connect their own AI assistant to their account and ask, browse and eventually order without an integration project. What it will do first, what it will not do until someone accountable says so, and the groundwork already in place.
Every file in Aurora starts with a header recording the exact time — and the city — where it was created. Nobody asked for it, and for seven years it recorded nothing but a company name. Then, from October 2015, the headers start naming places, and read end to end they become a travel diary — Spain, Sheffield, Macau, Penang, a factory city in China, Bali, Bangkok, Mexico City, Tokyo, Kuala Lumpur — including three files created mid-flight. The typos are the proof it was all typed live.
Aurora has no framework, because in 2008 there was nothing worth adopting — so it grew its own. A 5,864-line router, an active-record ORM with a built-in audit trail, a process-forking job runner years before queues were a composer require, translations in sixteen languages with a homemade string extractor, and a Content-Security-Policy assembled by string concatenation. A tour of what one developer hand-rolls in fourteen years, what each piece is called today, and why the answer to "was it bad?" is more interesting than yes or no.
We did not embed the business into a vector store and hope the right chunk came back. We gave the model forty‑five tools — the same actions the staff app runs, under the same permissions — and a guide on how to use them. The result is a report that used to take three people a day, or a ticket to engineering, arriving in thirty seconds with real figures. The reactions, in order: disbelief, checking whether the numbers were random, and then a very quiet "oh".
Nobody on the team is an SEO specialist, and dozens of storefronts on one codebase rank anyway. That is because almost everything that matters is plumbing that a storefront engine either does for every shop or does for none — a computed canonical URL nobody types by hand, a 301 that follows a discontinued product to its family, a sitemap index regenerated nightly with a real lastmod, structured data that obeys the same price rules as the page. What we built, what we skipped on purpose, and the three things that bit us anyway.
We built an internal messenger into the ERP instead of sending the warehouse to a third-party app. Why it had to be separate from customer chat, why the first users were pickers on tablets, transparent translation between languages, chats that start from an order, and the rule that staff chat is work — so HR may read it.
We log every call an assistant makes to our MCP server — who, which tool, how long, did it fail and why — and put it on a sysadmin dashboard. Two weeks of data found a user whose assistant had made 454 calls with a 100% error rate, and fixed the server's instructions instead of the user.
A warehouse cannot stop for a deploy, and neither can we. How a nineteen-person team ships a monolith with six thousand actions to production seventeen times a week — the pipeline, the tests that gate it, the deploy that never cuts the branch it sits on, and why AI agents made the cadence faster without making it looser.
Trade discounts are not "10% off with code". They are forty trigger types — quantity of a family, amount across a department, every nth order, first order, cartons, gifts, vouchers, customer‑exclusive deals — stacked, metered, re‑evaluated on every basket change, and written to every invoice line as an allowance you can audit. How aiku's discount engine works, why buy‑X‑get‑cheapest‑free counts the way it does, and the penny that float arithmetic tried to steal.
The engineers are in Southeast Asia — a big city and an island people go to on holiday; the warehouses, the sales floor and most of the staff are in Europe. That is six to seven hours of offset, every day, for four years. It shaped almost everything in how we work — the quiet morning deploys, the ticket that has to carry the whole conversation, the boring release, the hand-off note — and it is the honest reason some of our best habits exist. The advantages, the costs, and what we would tell a team considering it.
A warehouse note that is "blocked" with nothing blocking it is the worst kind of bug — invisible until a picker is standing there with no button. We replaced four cached flags and six readers with two generated columns, one predicate and an alarm.
How support requests flow from a picker, an accountant or a customer‑service agent into a Jira project, how they come back out as commits, and the rules we hold when we answer — plain words, what we did, why it happened, what you do next. And a tease: we may build our own ticket system, because we can, and because we would do it our way.
In 2022 we picked Laravel because it was the easiest way to find programmers for a system that would take years to build. In 2026 we would pick it again, for a reason that did not exist then — the models know it better than any hire ever would. What the choice bought us, what it cost, and what "is Laravel still worth it" actually asks.