As a project manager, I managed to wreck a project over the past four months (post-launch, it was riddled with issues, and users couldn't use it). Over the past few days, I’ve been reflecting on myself and asking these questions:
What did I do wrong?
How much of the failure was my responsibility?
The following will answer these questions, and I’ll share my remedies at the end.
Project and Team Background
First, let me provide some context to help clarify the project:
This was a secondary development project. The first version (a declaration printing system) was also led by me.
The system needed to integrate with a national system, involving three main workflows.
The requirements changed frequently, as the client was unclear about their needs due to the integration with the national system. In May alone, there were over eight major changes to the workflows.
Based on the initial requirements, the project size was estimated at around 100 man-days.
Two of the primary workflows couldn’t be tested as they relied on external U-Key devices, which we didn’t have during development.
On-site U-Key debugging and development lasted around 20 days.
At that time, I was responsible for managing four projects of varying sizes and did not directly participate in development, only overseeing progress.
The team had three members, two of whom were familiar with the project as they had worked on the original version.
The project required multiple rounds of on-site testing and debugging, carried out by two engineers from the team.
What I Did Wrong
Managing Quality is as Important as Monitoring Progress
At the start of development, I created a detailed project plan to guide the process. This plan was handed over to the client, and I was determined to follow through on my commitments. Throughout the project, I strictly controlled the timeline, regularly checking if tasks were completed and reporting progress to the client. As a result, development proceeded on schedule, but this also planted the seeds for disaster. I was so focused on ensuring tasks were completed that I neglected to pay attention to the quality of the work.
Quality issues became evident post-launch. For example:
One of the main workflows couldn’t be completed by the client.
The declaration function falsely showed success, but the declaration could not be found in the national system.
The printing function had multiple errors, such as incorrect data.
The data synchronization function either failed or produced incorrect data.
Some functions took too long to execute, causing database disconnections.
Reflections:
While progress and speed are important, sacrificing quality for speed is unacceptable.
If there’s a conflict between time and quality, prioritize quality—because you’ll eventually pay the price for shortcuts.
Even in difficult situations, ensure basic testing is done.
If time is extremely tight, at least ensure the core features work smoothly.
Trust is Important, but Don’t Let Your Guard Down
The team consisted of three competent developers who were familiar with the framework. Two of them had even worked on the original version. Because I trusted them, and with my attention spread across other projects, I didn’t give this one the focus it needed.
I trusted them to handle everything, but I failed to provide guidance at critical moments. I didn’t help solve challenges or even offer direction. My role in the project was essentially just liaising with the client and pushing for progress.
Reflections:
Regardless of the circumstances, always check in on your team’s status.
Trust is essential, but also maintain some vigilance—developers can overlook issues due to inexperience.
Along with trust, provide guidance. Don’t use a lack of time as an excuse to avoid helping or advising your team. Otherwise, you’ll end up spending more time fixing things later.
If You Can’t Manage the Whole Project, Assign Someone to Take Charge
This was my biggest mistake in the project.
Due to various reasons, I couldn’t grasp every detail of the project. There were three developers, but I didn’t designate one person to be in charge. Everything was left for them to figure out. I communicated issues directly with the responsible developer, but no one had a comprehensive understanding of the entire project.
Reflections:
Holding management power but failing to manage is my biggest issue in this project.
Delegate! If you can’t manage a project directly, delegate management authority to a team member.
Managing one person is easier and more efficient than managing several.
Control Both Requirements and the Process
This was a secondary development project, with a familiar team, a manageable workload, and a tight schedule.
Given these factors, I was complacent. I didn’t plan or design the project at the beginning, nor did I establish any development standards. I simply told the developers to reuse as much code as possible and didn’t check if they actually did so.
When requirements changed or the client provided feedback, I simply passed the information along to the developers without detailed planning. Everything was communicated verbally, and all changes were left to memory.
Reflections:
Don’t start development without proper design.
Use management tools to guide development, and document all changes and feedback.
Control requirement changes and reject unreasonable requests.
Standardize requirement changes instead of burdening developers directly.
Always Conduct Code Reviews
Over the nearly four months of this project, I only spent about two hours reviewing the code, without pointing out any issues. This led to a massive increase in time spent on code review later, and by that point, fixing issues in the established code was much more difficult.
There were also no peer reviews between developers, and no code review meetings were held.
In the end, I found many problems with the code, such as inconsistent naming conventions, poor code reuse, and unnecessarily complicated logic. Most of these issues could have been avoided with early guidance, proper delegation, and code reviews.
Reflections:
Code quality is crucial; the cleaner the code, the fewer bugs.
Peer reviews help developers focus more on code quality.
Early code reviews can significantly reduce time spent on issues later.
How Much of This Was My Responsibility?
100%.
How I Fixed the Issues
After the project went live and issues emerged, we spent eight days fixing it. Fortunately, the project wasn’t too large, and I was able to handle the situation myself.
Here’s what I did:
I reviewed every requirement detail with the developers working on the main workflows.
Based on my understanding of the requirements, I spent three days analyzing all the code for the main workflows, implementing necessary changes, and deploying them for production testing (this was essentially like changing the engine of a plane mid-flight).
I spent over 12 hours a day reviewing and modifying the code, often working until 2 a.m. (focusing only on major issues that affected a small scope).
During work hours, I had the developers sit with me while I made changes, ensuring they could supervise and prevent mistakes.
I optimized functions and fixed problems I encountered, aiming to improve the user experience and restore user confidence.
Lessons Learned
Design before development.
Delegate management authority; someone must be fully responsible for the project.
Always conduct code reviews.
Never sacrifice quality for progress; never promise an unreasonable development schedule to clients.