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.
Selling through a wholesale marketplace means the order is not yours: the buyer edits it after you have picked it, the marketplace sets the discount and the commission, the items can change after dispatch, and the only truth is their payload. The shops we run on such a marketplace taught us more about ownership than any other integration — six rules, each with the afternoon behind it.
The factory still runs on paper: a tally per worker per task, totted up on Friday. The manufacture module that replaces it is built, tested, imported from the old system locally, and not yet on the floor. Part I is the model — artefacts, recipes as ordered tasks with raw materials per step, job orders that expand into a work queue, and a "task session" that is the single payable fact, with the pay rate frozen at the moment it closes — and the decision to make every product a trade unit first so a candle made on Tuesday can be sold online on Wednesday.
3,300 tests against a real PostgreSQL with 800 tables, restored from a dump before every file, run in parallel on ten processes in CI and by a dozen people and their AI agents at once locally — without stepping on each other. No mocks of the schema, no synthetic repositories. How the TEST_TOKEN trick makes that possible, and the four ways such a suite goes flaky.
Twenty‑nine steps between "push to production" and "the warehouse is on the new code", and not one of them makes a picker wait. A walk through one deploy as it actually runs — releases and symlinks, caches, migrations on one host only, a front‑end build that is skipped when nothing changed, checksums that decide what to flush, queues told to finish, workers reloaded from an anchor, SSR restarted only if it must, a broadcast that tells open tabs to refresh, and a few chores at the end.
Four sales hubs in Europe buy most of their stock from suppliers in Asia through agents — commission‑based intermediaries who consolidate everyone's purchase orders, pay deposits, and ship one container. The procurement module that models that is built and being migrated, not yet live. Part I is the design: suppliers as group master data, the agent's "mini kingdom", a purchase order that splits per supplier, a stock delivery that is a delivery note in reverse, a cross‑organisation shopping list with MOQ bars, deposits as "money in the air", and a command‑and‑control board built for the fights.
A million invoices and fifty thousand credit notes, and the rule that governs all of them: an invoice is a frozen picture of an order at the moment it was billed, and nothing that happens later — a price change, a tax change, a product rename — can move it. How invoices are minted from orders, how credit notes reference the lines they return, how a paid status is derived rather than set, how invoices are categorised for the accountants, and how a PDF, an e‑invoice and an export all read from the same rows.
Coming soon in the manufacture module — a production reward scheme that pays people by the hour at a band earned by their pace, never below the legal wage, with targets derived so that faster work costs the business the same per unit. Why we did not build piecework, how the spreadsheet became rows with dates, and the live ladder on the shop‑floor screen.
Four years, 1,659 migrations, 793 tables, twenty thousand columns, five thousand indexes. How the aiku schema got this big without getting lost — the group/organisation/shop spine on every row, a stats table beside every entity, slugs as public identity, jsonb where the business is still deciding, and the bridge columns that let us migrate off a twenty‑year‑old system one table at a time.
We did not rewrite the twenty‑year‑old system and flip a switch. We built the new one beside it, pulled the data across entity by entity with 106 fetchers, ran both for years, and moved one company at a time — 588,000 customers, 1.08 million invoices, eventually 88 million rows of history. The "source id" on every row, the fetchers that could not be allowed to overwrite what people had edited in the new system, the guard that froze the catalogue, the import of two decades of audit trail, and the rule that a closed shop must rest in peace.
Eight years of sent email — 245 million rows, 217 GB, never pruned — was slowing down a daily rollup and bloating every developer's copy of the database. How we moved it to an archive server in verified batches, why the retention window is 90 days and not 60, and the one trick that keeps historical stats correct after the rows are gone.
After a flush, the first visitor to each storefront page pays for the render. We have written the thing that pre‑pays three times: a link‑following crawler from a package, a two‑pass seeder‑then‑deep crawl with concurrency rules, and — the one we kept — a list of the pages people actually visit, fetched in order of traffic, at a concurrency that can never outbid a live shopper. Why each version was wrong for the next stage, and the surge‑protection bug that made the warmer most aggressive exactly when it should have been gentlest.
Our pickers and packers work on cheap tablets with a Bluetooth scanner, on the same web application the office uses — same URL, same codebase, no app store. How a browser tells a barcode from a person typing, what the server does with a scan (match → location → pick, in one round‑trip), and why "it feels like an app" is a design discipline, not a framework.
Stock in aiku is never a number you set; it is the sum of movements you record — purchase, pick, return, transfer, production, found, write‑off, audit. How 88,000 stock items across 45,000 locations stay honest: a location‑stock row per bay, a picking location per item, audits as movements with a delta and a reason, a lock that stops a low count being audited mid‑pick, and the "error" naming rule that keeps a retired SKU from ever being picked again.
One warehouse wanted a fingerprint reader, another wanted to scan a QR with their own phone, the office wanted a PIN on a tablet, and a visiting colleague wanted to clock in wherever they happened to be. How the clocking system grew eight machine types by listening to managers, and the two quiet rules — order the timestamps, find the right employment — that keep the timesheets honest underneath all of them.
Weighted average cost and FIFO computed in one pass over the movement history, a group-level switch that decides which one is "official", and why LIFO is deliberately missing.
No Kubernetes, no managed database, no serverless. aiku runs a multi‑country commerce operation on a handful of rented bare‑metal machines behind Cloudflare — a primary, a replica and a staging box — and we would choose it again. Why metal beats "cloud" for a workload like ours, what the boxes actually do, and the two incidents that are the honest cost of owning the iron.
Shopify first, in 2024; then WooCommerce, TikTok Shop, Magento, Amazon, eBay, Allegro, Wix, and a wholesale marketplace with its own rules. Two years of connecting other people's platforms to our warehouse — the model that survived all of them (platform, channel, portfolio), the lesson about who owns the truth, and the small ugly things that each platform taught us.
We had an attribution feature for years and it had credited 0.08% of customers. Here is what was wrong, what we rebuilt — twenty channels, three email channels, ROAS and CAC with real costs, a per-customer journey — and the one invariant we now check after every change.
Every storefront page sends one small request to our own endpoint — not to a third party. From it: visitors, sessions, page views, country, device, referrer, the traffic source that becomes attribution, registration and add‑to‑basket conversions, "who is on the site right now", product interest per customer, and the list of most‑visited pages that decides what the cache warmer warms. Why a beacon that fires on cached pages was the only design that could work, how bots are filtered, and what we deliberately do not collect.
We replaced a third-party storefront search with our own — Typesense, typo tuning measured against real queries, synonyms shared across fourteen languages, merchandising boosts for staff, a hybrid semantic arm tuned with a harness instead of a hunch — and then turned the queries that found nothing into a shopping list for the buyers. Total AI spend for the whole programme: about six cents.