Expecting end users to customize the experience is madness

 Don’t do it to yourselves

Don’t do it to customers 

Do the work to make a good product

Enterprise software sucks. Its not bought by the people using it, but by a guy wearing a suite on the 37th floor the day after eating a fabulous steak dinner paid for by Oracle sales guys.  By the time you start using it, it is bought and paid for. Suck it up and learn how this pile of code works. 

Internal enterprise software is another beast. Constantly underfunded, built by interns that just learned object oriented programming, and designed by the CEOs cousin, it is not the greatest. 

Know what will ensure that your internal software is never improved in a meaningful way? Make customizing it the default workflow. Just have every engineer at the company load up a GreaseMonkey script that adds in the features that PAAS should have by now. 

The problem is fixed for the graybeards. Sure, every new employee will spend six months realizing that all the people who are getting anything done have customized the UI so extensively its not recognizable as the same product. 

When they said go use ‘deployment ladder’, they meant use ‘deployment ladder’ with 12 GreaseMonkey scripts installed. Where are those scripts? You might ask, the answer is always ‘in the wiki’. Searching for the name of the thing in the wiki does not result in finding the thing, like it would in google for an open source project.

Having everyone customize the software does not result in a good product. It papers over a shitty UI by fragmenting it even more. After a while no one with any power in your organization realizes there is a problem because they have 50 GreaseMonkey scripts installed, and haven’t looked at the actual ‘base’ UI in 5 years. 

Save yourself millions in on-boarding. Invest in good tools. Put the work into offering a great default workflow. Don’t end up in a situation where the graybeards can’t even understand the workflows the new hires are dealing with. 

Business Intelligence what is it?

Business Intelligence is the process of exposing the results of customer workflows in an easy to consume fashion for Business Analysts, Accountants and Executives. 

When your product is software that your customers’ use, it can be hard to know how customers are using it in the large. For BI you log whatever the customer did in a format that is easy to query via SQL. For purchasing flow you log.

{
    "customerId": "ABC",
    "itemId": 1234,
    "time": "12:34 AM",
    "price": "$13.87",
    ……
    "sessionId": 987
}

Then analysts can figure out usage patterns, discover and fix bad customer experiences and generally figure out what customers are doing. 

How is this different from normal logging? 

Programmers care about exceptions, lines of code and values of variables. The business cares where the customer was in the workflow, what did the customer click on, what happened after that. If there was a silent retry that the customer didn’t notice the business analysts don’t care. 

They care about what customers are doing and how the software responds more so than what the software is doing. 

BI logging is typically preserved durably over at least months and needs to adhere to a schema that makes aggregating data together easy later on. This can be achieved with normal structured logging or by adding a separate code flow just for ‘Business’ logs. 

If you like my writing, please buy my book on Amazon.
The Sledgeworx Guide to Getting into Software


Designing your development environment

What should your development environment look like? People talk about how its hard to setup development environments, this or that component are tricky etc. 

But what components should you actually have? For a backend API server in a major language you will probably have an application that serves requests while writing to a database, logging and emitting metrics. 

If you follow best practices you will have unit tests, a deployment pipeline, integration and end-to-end tests. All that stuff is great, but what about the development environment. 

You should have a best in class IDE. Whether that is Visual Studio, IntelliJ or Emacs make sure you have the core features syntax highlighting, go-to-definition, safe renaming, and a debugger. 

You want some way to run integration tests on a local developer’s machine. In my workplace we ssh into VMs which we can run the entire development stack on. If you can manage that without the VM, do it, its 10x better. 

You want to be able to run a remote debugger against a fully running version of your application. Ideally, you should be able to test manually end-to-end against a version of your application running on your local machine. 

If you have only one service this is easy. If your Microservice is 1 of a 100, making that happen is tricker but worth it. 


Code coverage should be verified during your build. 

Code style linters should automatically apply stying fixes. The build should never break over styling issues. 

Builds should be FAST. Every minute of build time can safely be assumed to result in wasted developer time. The ideal build time is under 15 seconds, including unit tests. 

The longer your build time the more distractions will edge into your workflow. If builds take a minute or two devs will click to look at Slack or their browser. If builds take over 5 minutes devs will be talking to their coworkers and getting distracted. If builds take 15+ minutes its bad. That means less than 4 code changes can be verified per hour. 

If you like my writing, please buy my book on Amazon.
The Sledgeworx Guide to Getting into Software

Why do we have unit tests for things that can never happen

So you finally have established good development practices for your team. Linters enforce code coverage of 90% and everyone is adding tests. Month over month test count increases and obviously code quality is increasing as well…

Until a partner contributing code to your project notices a test that validates something that can never happen. This test in particular validates the behavior of an endpoint when a particular input is null. The issue is that our platform ensures this input is never null, any requests to our service without that input will be a platform error, and never make a request to our API. 

Our slack chat room had a lengthy discussion on why we have that unit test, but the answer is code coverage. Someone added it because code coverage declared that code path to be untested. 

Can we delete this test? Probably not without writing new tests for other functionality or reducing our coverage requirement. 

One option here is to add a Spring MethodValidationInterceptor which validates ‘base’ inputs to our service and then write tests for that. This approach moves responsibility for ‘things that can never happen’ to a centralized class which can be tested. Then we know what is prevented from happening within the domain of our unit tests. 

But at the platform level this really will never happen. Do we really need every service in our dependency tree to validate this particular case and throw an exception? 

Never get in the way of people with the momentum to get things done

Most of us have productivity swings. Some weeks you are energized and getting things done. Then the next project just seems to drag on and on. Slumps and burnout happen. But usually at least one person on the team still has some momentum going. 

Don’t slow them down. Do what you can to assist in their effort. Don’t think you have to operate as effectively as they are this week. It can be intimidating to see another person delivering more value than you. Don’t hit yourself thinking “If only I was more motivated I could outperform Jack.” 

Software engineering is not a coding competition. Success or failure is evaluated at the product level by our customers. Which member of your team delivered the most story points this sprint is complete irrelevant to customers. They don’t know and wouldn’t even care if they did. 

Customers care about what your engineering organization does as a whole. Which features are shipped, how stable is the service, how good is the user onboarding, these things matter to customers. You aren’t signing each line of code for customers to look at. They don’t have a favorite programmer on the product. 

Your goal is to enhance your team’s efforts as much as possible. That is achieved by following the momentum and supporting it, to get things done .