Paul’s request seems simple enough to implement, but it requires a few risky changes. Since I was very busy at the time I didn’t bother to confront Paul with the risks. After the new feature is deployed to production a bug strikes! Paul calls me: Frederik! The search shows the wrong products, it is costing us a lot of money, I trusted you to implement it without errors! I expect this to be fixed asap!
Bugs in production will keep you up at night!
After a heated discussion with Paul about the risks he accepted initially I ended up correcting the error and only charging half the price it actually cost to fix it to preserve the good relationship. After all it was me that caused the error. Fast forward a few months and Paul wants the feature to be expanded again, this time with many additional categories: Hi Frederik, We are selling more than ever because of the search widget and I need you to expand it with ten additional product categories! I know from last time that the state of the code is bad. I also know that a change of this size is going to introduce even more bugs than last time, so I don’t really want to go that way. The only option I see is to make a complete rewrite of the code, but that is going to be expensive and time-consuming. And Paul will not be happy with either. For me as a programmer it is a lose-lose situation, the customer trusted me to be professional and create a system that would support and grow with his business, and I failed. I have seen similar stories happen more often than I would like to. And it sucks, every time