It was supposed to be a demo.
We built it in a week to show a potential customer what the product could look like. Hardcoded values, no error handling, a database schema that would make anyone wince. The kind of code you write when you know it's going to be thrown away.
The customer loved it. They signed. They wanted it live by the end of the month.
We said we'd rebuild it properly. We didn't.
Instead, we fixed the most embarrassing parts and shipped it. Then we fixed a few more things. Then a few more. The prototype became the product, one patch at a time.
This felt wrong. We kept apologising for the code. We kept promising a rewrite that never came. Every time something broke, someone would say, "Well, it was only supposed to be a prototype."
But here's the thing: it worked.
Not elegantly. Not in a way that would impress anyone reviewing the architecture. But it solved the customer's problem. They paid us. They renewed. They referred other customers.
The "proper" version we'd imagined would have taken months. It would have been cleaner, more extensible, better tested. It also would have been late, and by the time it shipped, we might have learned that half our assumptions were wrong.
The prototype taught us what mattered. The parts that broke were the parts that needed attention. The parts that didn't break were, apparently, fine.
I used to think there was a clear line between prototype and production. Prototypes were experiments. Production was serious. You didn't ship prototypes.
Now I think the line is blurrier than we admit. A prototype that solves a real problem is already production, whether you call it that or not. And a "production" system that nobody uses is just a prototype that got too much funding.
The question isn't whether the code is good enough. It's whether the code is good enough for what it needs to do right now. And "right now" is the only time that matters, because by the time you've built the perfect version, the requirements have changed.
We eventually did rewrite parts of that system. Not all at once, and not because we'd planned to. We rewrote the parts that hurt, when they hurt, and left the rest alone.
Some of the original prototype code is still running. It's been years. Nobody complains.
Maybe it was production all along.