by Serguey Shinder
We built our trade ordering system in 2019, and in the second week of it somebody drew a box on a whiteboard labelled account and wrote under it one company, one billing address, one price list, one set of logins. Nobody argued. It described every customer we had. The conversation lasted about two minutes and I could not now tell you who was in the room.
In March a regional group bought four of our merchant customers in one transaction, and rang us the following week to ask for a single login that could see all four, one invoice, and the best of the four price lists applied across the lot. Commercially it was the easiest yes we have ever given. In the code it meant that a user belonged to exactly one account, as a column on the users table, joined on in twenty seven queries, checked in nine separate permission routines and written into every row of our audit trail.
What we did, because the date was fixed and the alternative was a quarter's work, was add a linked accounts table and a switcher in the header. You pick which of your four you are currently acting as. It shipped in a fortnight and it has cost us ever since. A scheduled report picks up whichever account the user happened to be in when they saved it. A permission check passes because you are allowed to do that thing somewhere, just not here. Our audit trail records the account the person was in rather than the one their action actually changed, which we discovered during a dispute, eighteen months after the fact, when the record we needed turned out to describe the wrong company.
Four of the six worst defects we shipped last year come back to that switcher. None of them look related in the ticket queue.
The thing I keep turning over is that nothing about the original decision was wrong. One company, one account was accurate for every customer we had and for every customer we expected. It did not fail. That is precisely why nobody ever revisited it, because a modelling decision of that kind never produces an error. It produces workarounds, somewhere else, years later, in code written by people who have no idea they are paying for a whiteboard in 2019.
So there are two questions I now ask about every relationship in a design, at the point where it is still free to answer them. How many of these can there be, honestly, not today but in the worst plausible version of our success. And can this one move to a different owner while the system is running. Nullability and size we argue about constantly. Those two we settle in a minute and live with for a decade.
– Serguey Asael Shinder
Leave a Reply