E2EFS — Software

DevelopmentFreight

What it does, and what it refuses to do.

Software that runs a working day: what arrives at a warehouse, what leaves for a shop, and what the books say at the end of the month. 52 things built for people at work, across 12 areas — built so the expensive mistakes are impossible rather than discouraged.

Three things this software will not let us do

  • A release that has not been installed over the previous version cannot be uploaded.
  • A month whose totals disagree cannot be handed to an accountant.
  • A deposit whose ticked payments do not match the bank line cannot be confirmed.

None of these is a warning somebody can click past.

01

Warehouse

Goods in, goods on a shelf, goods on a truck — with a ledger underneath that cannot be talked out of the number it holds.

Receiving against what was promised

A delivery is booked line by line against the supplier's invoice, and the screen says where the two disagree.

Two mistakes can cancel. Two cases short of one product and two cases over on another is a receipt with two wrong lines and a money difference of exactly zero, and a check that compares two money totals passes it. The comparison counts lines and quantities before it looks at money, so a short, an over and a wrong unit price are three separate findings instead of one silence.

Lots, shelf life and FEFO picking

Stock is held as lots with expiry dates, and a pick list is assembled first-expiry-first without anybody choosing.

  • expiry report
  • intake and throughput reports

A stock ledger that cannot go negative

Every movement is appended; nothing is edited in place.

Pressing a button twice used to conjure inventory. The floor of the ledger is now enforced in the database, so the second press is refused there rather than guarded for in each screen that might write.

Lot labels on a thermal printer

One sticker per case: Code 128, lot, expiry, and a batch colour so a pallet can be read from across the room.

Barcodes that will actually scan

Each barcode is checked against its GS1 check digit when it is imported, and the ones that would never come off a scanner are flagged instead of silently stored.

Loading and quality sign-off

Built, checked, loaded — each a separate state, with the signature recorded against the person who gave it.

A sign-off used to survive the thing it signed off. Reopening a built order to change it left the previous check in place, so the paperwork certified a pallet that no longer existed. The signature is now bound to the build it was given for, and reopening voids it.

Cycle counts

A count sheet that writes its difference into the ledger as a movement, so the correction has a history too.

02

Order to cash

From a rep typing an order to money confirmed against a bank line — and the parts of that chain where a small mistake becomes somebody's bill.

Orders, picking, loading, delivery

One order moves through submitted, approved, picking, picked, loaded, out for delivery and delivered, and each screen only shows the work its own role can do.

"Being built" and "on tomorrow's truck" are different days, and one dashboard number used to cover both while its link opened only one of them. They are two numbers now, because an order sitting on a truck overnight is a state the office needs to see as itself.

Prices per store, per purchase unit

A product can be sold by the each, the pack and the case at prices that are not multiples of each other, and a store can be on a tier or on its own number.

Deriving the unit price by dividing the case price was measured wrong and dropped: for many items the cheapest way to buy is a ten-pack, not a single. Every purchase unit carries its own price.

Invoices, credit notes and opening balances

Invoices are cut from what was picked; a return at the door produces a credit note against the invoice it belongs to.

A credit reduces what is owed, not what has been paid. Writing it as a payment would have let a store earn credit terms by sending goods back, because the rule that grants terms reads payments as evidence.

Payments and deposit batches

Cash and cheques are recorded as collected, then confirmed against a single line on the bank statement.

The batch total is typed, not computed. A computed total agrees with itself and therefore checks nothing. The database refuses to confirm a batch whose ticked payments do not add up to the figure on the statement, and it refuses at commit — so two tabs cannot each read a set that balances and commit a pair that does not.

COD, credit terms and credit limits

New customers pay on delivery; terms are granted only after a fully paid order and an explicit approval, and the limit is a number the business sets.

There is no default credit limit anywhere in the code, and a gate proves it — including the spellings that are easy to miss, like a local variable initialised to a number inside the very function the rule lives in. Blank means no ceiling, which is what the system did before anybody typed one.

Store status at a glance

Six states — new, in good standing, owing, at risk, blacklisted, out today — resolved once per page for hundreds of stores.

Blacklisted has to win, and it did not. An order already picked passed the credit hold because the blacklist was only checked where orders are created, and an existing order never goes through that door again. It is refused at the loading bay now, and that refusal was watched happening.

Receivables

Aging by how long a debt has been late, with no date range, because the question is what is still outstanding.

03

Books

Statements in, a month closed, and a file an accountant can take — with the arithmetic checked by something that is not a person reading columns.

Statement to ledger

Bank and card statement PDFs are read, transactions classified, accounts reconciled, and the month handed over.

If the totals do not agree, the hand-off is refused. Eight months of reconciliations closed at a difference of exactly 0.00 — not because somebody was careful, but because there is no path that closes a month while the difference is anything else.

  • four legal entities

Pushing documents to an accounting system

Invoices and payments become one document shape before any accounting adapter sees them, so the adapter never learns which of the two it came from.

A push that dies halfway used to mark documents sent against a file it had thrown away. The log row is written before the send, a crash leaves the document pending rather than sent, and the batch that went out is kept — so "it was sent" can be checked by opening the file it was sent in.

Knowing when a sent document changed

Each document carries a fingerprint of the bytes that were sent, so an edit afterwards is visible as an update rather than a duplicate.

The rule is the file, not a list of fields. A fingerprint repaired by naming the three fields somebody had forgotten still could not see two more; it now covers everything the export writes, and the check renders the file twice and fails if the bytes move while the fingerprint does not.

One set of books

An organisation keeps its books inside the portal or pushes them to an outside accounting system — never both.

Enforced in the database, not in a form. Two transactions could otherwise walk through one check each and commit a state where both were on at once; the constraint is deferred to commit, and it was measured refusing exactly that.

04

Who can do what

One codebase serving several businesses, where the wrong row appearing on the wrong screen is the whole risk.

Roles, capabilities and organisation kinds

What a screen shows comes from the role a person holds and the kind of business they hold it in, resolved in one place rather than asked page by page.

A gate reads every page and every server action and refuses the build when one guards nothing, or guards the wrong capability. It has been made to go red on purpose — moving a guard below the write it protects, or removing the negation, is caught.

One person, several jobs

In a small business one person runs the warehouse and the office, so access is a set of pools a person holds rather than a single word.

Handing out the pools was the easy half. The hard half was that six decisions still asked for the one role somebody was hired into — including whether they clock in, which would have meant a rep who also works the warehouse never having a shift recorded.

An audit trail that only grows

Decisions that move stock or money write who, what and when, and the table refuses deletion.

An audit line is only worth the write underneath it. A conditional update that matched no rows still came back successful — nothing changed, nobody was told, and the audit line written on top of it would have recorded a decision that never happened. The write now reports how many rows it touched, and zero is a failure rather than a success with nothing in it.

Attendance

Shifts that clamp, so a forgotten clock-out does not become a recorded 72-hour day, and a night shift crossing midnight is one shift.

05

Ordering for customers

The other side of the same warehouse: a store owner on a phone, seeing their own prices and their own history.

Invited logins, scoped to one store

A customer account belongs to one store and can see nothing else, enforced in the schema rather than by filtering.

A cart that behaves

One open cart per store, one line per product, and an order that stops changing the moment it is sent.

"Stops changing" is a database rule, not a disabled button — including the case where an order number would pass ninety-nine thousand, which is refused in the same statement that would have issued it.

Tracking, typed or imported

Carrier numbers arrive as a file from the warehouse or typed one at a time, match to orders, and appear on the customer's own order.

An import with no size limit took away the screen you would need to undo it. Measured through the form: 20,001 rows accepted in 215 seconds, then every unmatched row rendered with a dropdown of the whole queue — 820,000 options on one page, which no browser finishes. The rows stay until somebody resolves them on the screen they can no longer open. The same file is now refused in 0.6 seconds with nothing written, and the exception list is bounded.

Notifications that do not go out by accident

A shipped-email path exists and is switched off; with no key it stops at the door and says so in the log rather than failing quietly.

Sending twice is prevented by a unique constraint on the parcel, not by a flag somebody has to remember to check. The same parcel attached four different ways produces one email.

06

Freight

The business this started as: quoting a shipment, booking it, and billing it without the paperwork disagreeing with itself.

Quotes across legs and vendors

A shipment is quoted leg by leg with several vendors side by side, and the quotation goes out as a PDF generated from the same rows.

Shipments, milestones and equipment

Containers, vessels, carriers and dated milestones on one record, with the forms a freight file needs produced from it.

Vendor bills against customer invoices

What a carrier charged and what the customer was billed sit against each other on the same shipment.

A carrier bill was being joined to whether the customer had been invoiced, so three real bills worth six thousand dollars were missing from the export while the screen showed zero owing.

Ports, facilities and postcodes

Airport, seaport, facility and postcode reference data behind the search boxes that use it.

A table this size is where a quiet defect lives. The database layer returns at most a thousand rows and sets no error, so asking for all 40,979 postcodes comes back as 1,000 rows and a clean result — indistinguishable from a complete answer, and it never raises anything. A check now reads every query against a table that grows and refuses the build when one is unpaged. It was written after that exact read was measured returning 1,000 of 40,979.

  • 8,802 airports
  • 17,520 seaports
  • 40,979 postcodes

07

Software on the floor

A Windows application on tablets in food-retail stores. It prints the labels on the packages customers pick up, so when it stops, the counter stops.

Labels from a spreadsheet the client keeps

Staff pick an item on a tablet and a label prints. The catalogue behind it is the client's own workbook, so a price change is an edit they already know how to make.

  • 107 items
  • bilingual labels

Updates that verify themselves

A new version is staged, installed, and checked against the version the registry actually reports afterwards.

Stores were updating and coming back on the old version. The installer was remembering the first folder it had ever been given. A release now cannot be uploaded without a record of that file having been installed over the previous version and the version re-read afterwards — and the record is tied to the installer's hash, so rebuilding invalidates it.

Printers, watched

Print readiness, queue state and faults are reported from each tablet, so a jam in one store is visible without a phone call.

  • 23 tablets
  • release 0.14.36

Tablet health and power

Sleep and hibernate states, security state and disk are reported by each tablet on its own.

Reading the client's wall chart

The PLU chart on the wall is cropped out of PDFs the client exports, and compared against the catalogue so a name that has drifted is caught.

One item has four different names across the label, the wall chart and the workbook. The catalogue was set to match the printed label — the one already in a customer's hand — and the test comparing it to the chart was left red on purpose, with the reason written next to it. It turns green when the client re-exports the chart. That is the red one in the count above.

08

Field apps

Two tablet apps for work that happens away from a desk, in buildings where the wifi is a rumour.

Inspections and compliance logs

Paper checklists and temperature logs on a tablet, with signatures drawn on the screen.

Offline first, and honest about it

Entries queue locally and upload when there is a connection; the queue is visible and survives a restart.

The whole upload path was proved without touching the real account: the server taken down mid-send, the browser put offline, and the case where the reply is lost after the row was already written — where naive code sends it twice. Sixty records in one batch, and the record count was read from the endpoint rather than from the screen that reports success.

09

Appointments

Booking, calendar and checkout for a business that takes appointments, running on its own domain instead of a per-seat subscription product.

Calendar, waitlist and checkout

Bookings with per-provider prices, service levels, recurrence and deposits; tips and payment method at checkout.

Booking on the customer's own domain

Each tenant's booking pages answer on its own hostname.

Which tenant a request belongs to used to be inferred from the hostname it arrived on, which means an unfamiliar hostname had to be guessed about. The application's own hosts are a declared list now, and a name that is not on it resolves to no tenant at all. Found by an adversarial review before it shipped.

Text messages, consented

Reminders by SMS with consent captured and shown, because the carrier registration is reviewed against that screen.

Live data, handled as such

The customer's real book is the only copy there is — no staging duplicate — so screen tests run against a disposable tenant created for the run and deleted after it.

The tool that creates those tenants could delete a live customer's book: its guard passed on "belongs to the probe organisation", and the rows it was asked about were selected by that same condition, so the guard could never refuse. An adversarial review demonstrated it on a stand-in and it is now refused three different ways.

10

Support

Where a customer's complaint goes, and the number this is judged on: the share of tickets that still need a person.

One store, two doors

A report button on every portal screen, and a paste box for what arrives by text or email. Both write the same row.

The button carries the screen, the tenant, the login and the browser with no typing. The paste box cannot know those, and leaves them as "not known" in words rather than guessing — the guess is what makes a ticket unusable six weeks later.

A number that cannot be gamed

The share of tickets needing approval is shown from month zero, so a later claim that it fell can be checked.

Marking a ticket as handled automatically requires a recorded reason, so the figure cannot be improved by relabelling. Back-dating a ticket out of the window was possible and is now clamped.

11

One system, several customers

The same running system serves more than one customer without a copy of it being forked for each. Three things differ between them — what it looks like, which parts are switched on, and the records they arrive with — and each of the three is a setting read at runtime rather than a branch of the code.

The look belongs to the tenant

Seven themes, two densities and a light or dark shell. The organisation sets the house style; a person can override it for their own account without moving anyone else.

Seven themes only cost what one costs while no component can tell which theme it is in. A screen that names a colour directly is wrong in six of them and right in one — and it type-checks, lints, builds and renders, so nothing would ever say so. One check refuses a palette colour named anywhere in the source; a second opens each screen in a browser and asks what it was actually painted in, theme by theme, because the source and the screen have disagreed here before.

Features differ without a fork

What a tenant can reach is decided by the kind of organisation it is, the switches set on it, and the capabilities carried by each role — all read at runtime, from one build.

A tenant whose ledger is this portal has nowhere to push invoices out to, so that capability is withheld from it rather than greyed out in a menu: pushing anyway would record the same invoice twice. Permission is answered by one function that is handed the roles, the organisation kind and the switch together, because a check that reads only the role stays right until the day a switch moves.

Bringing the records they already have

Products, stores and suppliers load from a file the customer already has — 43 fields across the three, 162 header names recognised without being told, and whatever is left mapped column by column on screen. An export from Shopify, from QuickBooks, from Zoho, or a sheet somebody typed. Where a wrong guess would be silent it declines to guess: Shopify writes weight in grams and this field is pounds, so that column is deliberately not recognised, because an automatic match would file 2,381 g as 2,381 lb and every screen would look right.

Matching an upload against what the customer already has read only the first 1,000 records, and a record the list does not contain is not an error — it is a new one. A catalogue of 1,992 would therefore have had 992 duplicates created by re-importing the same file, with no failure anywhere. Reads are paged now and a check re-measures it, because this was invisible to five reviews.

12

Storefront

A consumer shop front for a brand of our own: the pages a shopper sees, the basket, and the routes to the other places the product is sold. It replaced the live theme on a store that was already taking orders, and the work finished before that store closed in September 2026.

A shop the owner re-words without a developer

Every band of the page — headline, countdown, product row, where-to-buy, marketplace logos, the wholesale page — is a setting in the admin, so wording, links, images and deadlines change without anybody deploying.

  • 22 page sections
  • 89 editor settings
  • 12 repeatable block types

A basket that does not leave the page

Adding to the basket posts in the background and slides a panel open with the line, its quantity and the subtotal; the shopper stays on the page they were reading.

It shipped looking correct and was not. The panel's open class was applied, its transform was set, and it still did not move — a transform transition does not run in the same frame an element stops being hidden. Nothing was wrong in the markup and the console was clean, so the only thing that showed it was opening the real page and seeing a nineteen-pixel sliver. The repair was one line; finding it was not available from any test we had.

One shelf, several places to buy it

The same product row tells a shopper where else the item is sold — the brand's own site, or a marketplace — with each badge optional and separately linked, so a channel can be added or dropped from the admin.

A wholesale enquiry that reaches a person

The trade page collects business name, address, whether the buyer holds a sales permit, and contact details, and delivers them to a monitored inbox rather than a form log nobody opens.

Product photographs a script can reproduce

Cut-outs, background removal, logo normalisation and compression are scripts, so a new flavour's images are made the same way as the last one instead of by hand in an editor.

  • 9 scripts
  • 6 product cut-outs
  • 3 supplier logos normalised

Renaming a live catalogue without breaking its addresses

Eighteen product names were rewritten through the API on a store that was selling at the time.

A rename is where a shop quietly loses its traffic. The handle — the part of the address every existing link and every search result depends on — is not the title, and rewriting titles while leaving handles alone is a choice somebody has to make deliberately. Nothing redirected, nothing 404'd, and the only visible change was on the shelf.

13

How

A check that has never failed is not a check

Every gate here has been made to go red on purpose and watched doing it. That is not a formality: gates in this codebase have been found green while blind — one certified a fingerprint over two columns it rendered empty in every case, another read the words in a status badge rather than the colour on the screen, and a third reported zero problems because the list it scanned had gone stale.

Weaknesses are reported first

Requirements that were not met lead the write-up. Numbers that were estimated say so. When something cannot be measured with the tools at hand, the report says it was not measured rather than filling the gap — because a confident wrong answer costs more than an admitted hole.

And the size of it

134screens in productionroute files that render a page
1,643tests in four repositoriescounted against the last count, because a suite that quietly shrinks still passes green — 313 once became 296. One is red on purpose, and the reason is written beside it
57checks that can refuse the worka failing check stops the release; it is not a line in a log
55attack suites against those checkseach case is a way past a check that worked once
138database migrationseach one a rule the database now enforces itself

14

One address

No form, no calendar link, no chat widget. What is useful in a first message is what breaks today and what it costs when it breaks, and that is easier to write in an email than to pick out of a dropdown.

operations@e2efs.com

Figures above were measured on 2026-10-14 from the repositories, by a script that counts only source git is tracking rather than anything remembered. They drift — treat that date as their expiry. Set in Newsreader, Instrument Sans and IBM Plex Mono. Freight forwarding is at e2efs.com.