The Worst Room in the House for Business Logic
Third in the legacy-code series. I went looking for where a pricing rule lived and found it in the database, in a stored procedure named sp_recalc_v2, invisible to the app and tested by no one. On why the database is the worst room for business logic.
I went looking for where a particular pricing rule lived, the actual logic that decided what a thing cost. It wasn't in the application. It was in the database, inside a stored procedure, written in SQL, named something like sp_recalc_v2. Its cousin sp_recalc_final lived two tables over. Neither name told the truth, and between them they ran a real chunk of the business.
The rules the company actually operated on were sitting in the one place almost nobody was looking, written in the one language least suited to expressing them, tested by no one, and named as if the goal were to make them unfindable.
Rules you can't see, can't test, can't name
Three things go wrong at once when business logic lives in stored procedures, and they compound.
It's invisible to the application. The code that appears to run the business calls a procedure by name and trusts whatever comes back, so reading the app tells you nothing about what the rules actually are. The logic is offstage.
It's untestable in any normal way. Your test tools live where your code lives, and this logic lives in the database, reachable only by standing up a real one and poking it. So it doesn't get tested, which means it doesn't get changed with confidence, which means it ossifies.
And it has no single home. Some of the rule is in the procedure, some is in the app that massages the inputs and the outputs, and the real behaviour is the sum of the two, smeared across a boundary. There is no one place you can point to and say the rule is here. Ask "what does this actually do" and the honest answer is you have to read two languages in two systems and hold both in your head at once.
Why SQL is the wrong room
None of this is SQL's fault. SQL is superb at what it's for: set operations over data, close to where the data lives. Business rules are not that. They're conditionals and branches and domain concepts that change as the business changes, and they belong in a place built for expressing and testing exactly that kind of thing, your application code, in a real language, under a real test suite.
Putting business rules in stored procedures is keeping your important papers in the garage. It's not that the garage is bad. It's that it's the wrong room, with none of the tools you need for this particular job, and every time you need those papers you're out there in the cold reading them by flashlight.
Evacuate the logic into a name
The fix is to move the rules into the application as named, testable code, and the naming is not a detail, it's the whole win. sp_recalc_v2 becomes a PricingPolicy: a real thing in the codebase, in your language, that says what it is, that a test can exercise in isolation, that a developer can read and understand without a database connection and a prayer.
This is the move the first two posts made possible. You needed honest data shapes so the inputs and outputs were trustworthy, and you needed seams and tests so that lifting live business logic out of the database wasn't an act of faith. With that net in place, you pull the logic into the light, give it a name that tells the truth, and put it somewhere it can finally be seen, tested, and owned. That's the whole series in one sentence, applied to the highest-stakes room in the house: legacy code hides what should be visible, and every fix is dragging the implicit into the light.