Faulty by Design was originally published on December 4th, 2007.
After 18 long months, it was finally time to celebrate. David M. and his fellow dev team members received word that their latest build had passed QA testing and was ready for delivery.
The software that David created was a point-of-sale system, designed to replace the antiquated cash registers used by a midsized retail chain. While the retailer was growing, the cash register vendor was going in the opposite direction. The company had just filed for Chapter 11, leaving all of its customers -- including David's client -- with an inventory of cash registers that no one else could sell or maintain.
David's company believed this to be the perfect opportunity for an upgrade to PC-based cash registers with modern point-of-sale software. They could utilize things like UPC bar codes, customer loyalty programs and gift certificates in the new system to streamline company operations and boost profits.
The Customer Wants What?
The retailer agreed, but only to a point: They would buy new hardware and software, but it had to look and function exactly like the old systems. No touch-screens, no graphics and no cashier-friendly reminders; just a plain old text-based interface with obscure keyboard commands for navigation. After all, they had spent a lot of money developing training programs for these registers and had no intention of simply throwing them out.
The retailer had also invested in a whole host of back-office management and reporting applications. Some were PC-based and some relied on proprietary hardware, but they all interfaced with the old cash registers' proprietary database. And though many of those applications were antiquated as well, the retailer had no desire to retire them. The new software would just have to interface with them. On top of that, the retailer didn't want a "flash cutover" deployment. They wanted a seamless, phased deployment that would allow them to switch over one register at a time, and have it all look the same on the back-end. So, with the latest and greatest technology at their disposal, Dave's team built outdated and mediocre software that functioned and communicated exactly like the old software. It did everything it was supposed to do and it did it right. And therein lay the problem.
Strive for Imperfection
Shortly after they delivered the software, the retailer rejected the QA testers' build and sent David's company a list of bugs. But it wasn't a list of bugs that their software had -- it was a list of bugs that it didn't have. When the retailer said they wanted the same functions, they apparently meant the same bugs as well.
The first bug on the list was related to receipt taxation. While the proper way to apply sales tax to a purchase is to simply multiply the taxable total by the tax rate, the old software applied a tax to each line item, rounded it, and then added the total. What this meant was that, with enough items purchased, the sales tax collected would be slightly higher than it should be.
Another bug was related to coupons. Because the old registers couldn't handle coupons, cashiers would simply apply a discount to the sale. This presented yet another problem with the sales tax calculation: Uncle Sam didn't get his cut when manufacturer coupons were used.
The most critical bug, however, was the end-of-day report that detailed what taxable and non-taxable purchases were made in each department. Because of the aforementioned and similar tax-related calculation problems, the old registers had much different "interpretations" of the day's sales.
All these non-implemented bugs added up to one unhappy customer. In their eyes, the software was far too "unbroken" for them to use. So, after spending a year and a half developing outdated and mediocre software, David's team put on the final touches: a slew of bugs that made it look and function like the original.