Sun, 03 Apr 2022
When I used to work for ZipRecruiter I would fly cross-country a few times a year to visit the offices. A couple of those times I spent the week hanging around with a business team to learn what what they did and if there was anything I could do to help. There were always inspiring problems to tackle. Some problems I could fix right away. Others turned into bigger projects. It was fun. I like learning about other people's jobs. I like picking low-hanging fruits. And I like fixing things for people I can see and talk to.
One important project that came out of one of those visits was: whenever we took on a new customer or partner, an account manager would have to fill out a giant form that included all the business information that our system would need to know to handle the account.
But often, the same customer would have multiple “accounts” to represent different segments of their business. The account manager would create an account that was almost exactly like the one that already existed. They'd carefully fill out the giant form, setting all the values for the new account to whatever they were for the account that already existed. It was time-consuming and tedious, and also error-prone.
The product managers hadn't wanted to solve this. In their minds, this giant form was going to go away, so time spent on it would be wasted. They had grand plans.
“Okay suppose,” I said, talking to the Account Management people who actually had to fill out this form, “on the page for an existing account, there was a button you could click that said “make another account just like this one”, and it wouldn't actually make the account, it would just take you to the same form as always, but the form would be already filled in with the current values for the account you just came from? Then you'd only need to change the few items that you wanted to change.”
The account managers were in favor of this idea. It would save time and prevent errors.
Doing this was straightforward and fairly quick. The form was generated by a method in the application. I gave the method an extra optional parameter, and account ID, that told the method to pre-fill the form with the data for the specified account. The method would do a single extra database lookup, and pass the resulting data to the page. I had to make a large number of changes to the giant form to default its fields to the existing-account data if that was provided, but they were completely routine. I added a link on the already-existing account information pages, to call up the form and supply the account ID for the correct pre-filling. I don't remember there being anything tricky. It took me a couple of days, and probably saved the AM team hundreds of hours of toil and error.
Product's prediction that the giant form would soon go away did not come to pass for any reasonable interpretation of “soon”. (What a surprise!)
This is the kind of magic that sometimes happens when an engineer gets to talk directly to the users to find out what they are doing. When it works, it works really well. ZipRecruiter was willing to let me do this kind of work and then would reward me for it.
But that wasn't my favorite project from that visit. My favorite was the new menu item I added for an account manager named Olaf.
Every month, Olaf had to produce a report that included how many “conversion transitions” had occurred in the previous month. I don't remember what the “conversion transitions” were or what they were actually called. It was probably some sort of business event, maybe something like a potential customer moving from one phase of the sales process to another. All I needed to know then, and all you need to know now is: they were some sort of events, each with an associated date, and a few hundred were added to a database every each month.
There was a web app that provided Account Management with information about the conversion transitions. Olaf would navigate to the page about conversion transitions and there would be a form for filtering conversion transitions in various ways: by customer name, and also a menu with common date filtering choices: select all the conversion transitions from the current month, select the conversion transitions of the last thirty days, or whatever. Somewhere on the back end this would turn into a database query, and then the app would display “317 conversion transitions selected” and the first pageful of events.
Around the beginning of a new month, say August, Olaf would need to write his July report. He would visit the web app and it would immediately tell him that there had been 9 events so far in August. But Olaf needed the number for July. But there was no menu item for July. There was a menu item for “last 30 days”, but that wasn't what he wanted, since it omitted part of July and included part of August,
What Olaf would do, every month, was select “last 60 days”, page forward until he got to the page with the first conversion transition from July, and hand-count the events on that page. Then he would advance through the pages one by one, counting events, until he got to the last one from July. Then he would write the count into his report.
I felt a cold fury. The machine's job is to collate information for reports. It was not doing its job, and to pick up the slack, Olaf, a sentient being, was having to pretend to be a machine. Also, since my job is to make sure the machine is doing its job, this felt to me like an embarrassing professional failure.
“Olaf,” I said, “I am going to fix this for you.”
Fixing it was not as simple as I had expected. But it wasn't anything out of the ordinary and I did it. I added the new menu item, and then had to plumb the desired functionality through three or four levels of software, maybe through some ad-hoc network API, into whatever was actually querying the database, so that alongside the “last 30 days” and “current month” queries, the app also knew how to query for “previous month”.
Once this was done, Olaf would just select “previous month” from the menu, and the first page of July conversion transitions would appear, with a display “332 conversion transitions selected”. Then he could copy the number 332 into his report without having to look at anything else.
From a purely business perspective, this project probably cost the company money. The programming, which was in a part of the system I had never looked at before, took something like a full day of my time including the code changes, testing, and deployment. Olaf couldn't have been spending more than an hour a month on his hand count of conversion transitions. So the cost-benefit break-even point was at least several months out, possibly many years depending on how much Olaf's time was worth.
But the moral calculus was in everyone's favor. What is money, after all, compared with good and evil? If ZipRecruiter could stop trampling on Olaf's soul every month, and the only cost was a few hours of my time, that was time and money well-spent making the world a better place. And one reason I liked working for ZipRecruiter and stayed there so long was that I believed the founders would agree.