DEV Community

Cover image for Three Post-Mortem Lessons From a Failed Software Project
Cesar Aguirre
Cesar Aguirre

Posted on • Originally published at canro91.github.io

Three Post-Mortem Lessons From a Failed Software Project

I originally posted this post on my blog a long time ago in a galaxy far, far away.


Software projects don't fail because of the tech stack, programming languages, or frameworks.

Sure, choosing the right tech stack is critical for the success of a software project. But software projects fail due to unclear expectations and communication issues. Even unclear expectations are a communication issue too.

This is a failed software project that was killed by unclear expectations and poor communication.

This was a one-month project to integrate a Property Management System (PMS) with a third-party Guest Messaging System. The idea was to sync reservations and guest data to this third-party system, so hotels could send their guests reminders and Welcome messages.

Even though our team delivered the project, we made some mistakes and I learned a lesson or two.

1. Minimize Moving Parts

Before starting the project, we worked with an N-tier architecture: Controllers call Services that use Repositories to talk to a database.

There's nothing wrong with that. But, the new guideline was to "start doing DDD." That's not a bad thing per se. The thing was: we didn't know what the upper management wanted with "start doing DDD."

With this decision, a one-month project ended up being behind schedule.

After reading posts and sneaking into GitHub template projects, two or three weeks later, we agreed on the project structure, aggregate and entity names, and an overall approach. We were already late.

For such a small project with a tight schedule, there was no room for experimentation.

"The best tool for a job is the tool you already know." At that time, the best tool for my team was N-tier architecture.

Lesson: For tight-schedule projects, reduce the moving parts and play with the cards you have.

2. Define a Clear Path

We agreed on reading the "guests" and "reservations" tables inside a background processor to call the third-party APIs. And we stared working on it.

But another team member was analyzing how to implement an Event-Driven solution with a message queue.

Our team member didn't realize that his solution required "touching" some parts of the Reservation lifecycle, with all the Development and Testing effort implied.

Although his idea could be the right solution, in theory, we already chose the low-risk solution. He wasted some time we could have used on something else.

Lesson: Define a clear plan and make sure everybody understand it.

3. Don't Get Distracted. Cross the Finish Line

With a defined solution and everybody working on it, the team lead decided to put the project back on track with more meetings and ceremonies.

We started to estimate with poker planning.

During some of the planning sessions, we joked about putting "in one month" as the completion date for all tickets and stopped doing those meetings.

Why should everyone in the team vote for an estimation on a task somebody else was already working on? We all knew what we needed and what everybody else was doing.

It was time to focus on the goal and not get distracted by unproductive ceremonies or meetings. I don't mean stop writing unit tests or doing code reviews. Those were the minimum safety procedures for the team.

Lesson: Establish minimum standards and focus on crossing the finish line.

Voilà! Although tech choice plays a role in the success of a project, "people and interactions" are way more important than choosing the right libraries and frameworks.

We can find failed projects using the most state-of-the-art technology or programming languages.

Like marriages, software projects fail because of unclear expectations and poor communication. This was one of them.


Starting out or already on the software engineering journey? Join my free 7-day email course to refactor your coding career and save years and thousands of dollars' worth of career mistakes.

Top comments (5)

Collapse
 
uzair004 profile image
Muhammad Uzair

Completely agree with the points even though its my very nature to get into all 3 of them.
Remind me of one of my personal project where I sit down to complete next task but think of edge cases in existing processes and endup re-writting code using classes and some complex hierarchy.

Even though its side project, However I have natural urge to keep things flexible i.e inserting new services or replace existing ones on the go.

Collapse
 
canro91 profile image
Cesar Aguirre

Keeping things flexible is important...and knowing when to stop too. Thanks for your comment, Muhammad.

Collapse
 
aaronre16397861 profile image
Aaron Reese

Make it work
Make it fast and secure
Make it easy to maintain

In that order

Collapse
 
aaronre16397861 profile image
Aaron Reese

I would add, especially for 'small' projects keep picking at the specification until you get absolutely minimum viable product. You also need to get management to understand that this is a quick and dirty, will likely have LOTS of technical debt and missing performance optimisation (tell them expensive cloud bills!) and future enhancements will require time and budgets for refactoring.

Collapse
 
canro91 profile image
Cesar Aguirre

That's a great addition Aaron. For the project I wrote about, another team in the future had to jump in to clean the messoptimize things :\ Thanks for your comment.