Do Not Make Up Your Own Requirements – a Short Story of Our “Howler”
Even if you start working with a large corporate client from small functionalities or MVP, sooner or later, you will have to face something bigger. Eventually, you’ll get the entire module of a huge system on your plate, or the key, most-used view in their product. In such a situation, it is worth avoiding some simple mistakes we usually introduce ourselves. Here is one of these mistakes from our own history that we want to tell you today.
The Goal of the Project, or What Was To Be Done
One of our clients asked us to implement the functionality that would enable the presentation of data on tiles. What immediately came to our mind was: ” a classic dashboard.” But! In addition, the user could choose from several types of tiles: adding, removing, and changing their order. The functionality is also meant to support the management of many such dashboards – layout manager. The requirements include:
- Such things as several predefined tile sizes.
- Sharing dashboards.
- Adding them to favorites or managing their visibility depending on the role/context.
Dashboards were to be Data Driven and offer the client’s developers the ability to add new tile types in a few simple steps.
We also used two suggested libraries for implementing layouts. These were not “irrefutable” proposals, but it was strongly emphasized that we certainly do not want to write our solution from scratch.
How We Approached the Topic
We approached the task comprehensively. We had two small, cooperating teams of programmers at our disposal with an analyst, designer, and tester on board. After collecting the requirements, creating mockups, and initial assigning tasks in the backlog, we moved to the first stage of activities – preparation for implementation
We started with standardizing knowledge and defining the scope of work, using Event Storming method. The client was not present at the workshop, as the representative of a domain expert in the person of our analyst was sufficient for us. We also found “hotspots,” i.e., points that still need to be checked or clarified with the client.
The results developed during the workshop served as input for the next stage. The Discovery Phase has been divided into two independent parts. One of the teams started investigating the existing backend code (the current page in .NET) and got acquainted with the database structure. At the same time, we delegated the analysis of libraries available on the market to the second team, along with the preparation of the Proof-of-Concept (PoC) and the final recommendation. As a result of the Discovery Phase, which lasted around a week, we implemented several such PoCs and chose the library (Muuri), which was responsible for the tiles’ layout.
From the beginning, we considered the functionality’s relatively high complexity and the need to address the customer’s flexibility requirements. That is why we decided to create the framework of the target solution as soon as possible. The Angular architecture was based on dynamically created components based on metadata returned from the database.
The investigation of the results, the created PoC, the planned architecture, and the selected library allowed for the provision of relatively precise valuations. Based on this, the client finally confirmed the scope of work with us, and we could sit down to implement it…
If you want more details about the course of each stage of preparation for implementation, please visit our webinar at the end of September!
Let’s Start the Implementation
Thanks to the previously developed architecture, the beginning of the implementation went very smoothly. Component skeletons appeared quickly in the target application, and the effects on the views were more than satisfactory. Technology also helped us with this – Angular provides, for example, dependency injection (which we used a lot) and well-worn implementation patterns for many things. After a few sprints, it’s time for the first demo with a client.
The perception of the effects of our work was positive. There were, however, a few comments, and quite significant ones, regarding the basic functionality – layout. The most important was the possibility of leaving empty spaces in the tile layout. It was possible, and it turned out that it shouldn’t!
It sounds like a serious problem, after all, we knew the limitations of the library we chose. We had to come up with something quickly. We organized an internal workshop on layout functionality to answer the question: what are we doing next? At the beginning of the meeting, we realized that we could come up with requirements for maintaining the library, such as drag & drop tiles from the palette on the canvas or freely arranging them, allowing us to leave empty spaces. We also had to admit to ourselves that we made the final choice of the library somewhat under these possibilities.
Changing the Library
We have come to the only correct answer to the question posed as the workshop’s aim – the library needs to be changed. The Muuri chosen by us provided the possibility of creating any layout. It also had a great performance and offered drag & drop – which we thought was vital! However, when we give up the possibility of putting tiles on the canvas and block the freedom of layout, the library we chose loses to the second option, i.e., Packery.
We had to make a change. It’s a pity we didn’t get there until the second half of the deadline. We knew that the change would not be trivial. Some mechanisms developed in the preparation phase were, to some extent, connected with the selected library. We took up the challenge and managed to deliver everything. The customer is satisfied with the final result, minimal slippage compared to the original term forgiven, and great success.
After closing the topic, we immediately sat down to learn from it. We looked for points on the project timeline where we made wrong decisions or used inappropriate processes or tools. Going from the beginning – no client at the Event Storming. Even the best analyst cannot read the client’s mind, so it would be good to have someone on hand at the beginning of the analysis to make the final decisions.
Then we have a more procedural thing, i.e., delegating the library selection to one of the two teams without the correct process. Team 2 prepared a PoC for each library, analyzed the requirements provided by Team 1, giving them the decision, and started the work. The fact of using a ready-made solution lulled our vigilance a bit. We subconsciously assumed that the requirements would adapt to the library’s capabilities, and we were not looking for a library that would meet the previously set requirements. It lacked both the current validation of PoC requirements and the state of the PoC between teams and, above all, bouncing the idea from the client. Instead of the “fail fast” approach, we stumbled into constipation without ensuring we were going in the right direction. We did not show the customer a demo of the produced PoCs, but only conveyed the choice.
And the thing that was definitely the easiest thing to avoid. Coming up with our own requirements. Drag & Drop was an obvious necessity for us that never fell from the client’s mouth. Similarly, with the empty spaces between the tiles. It was enough to ask about it anytime, and everything would be clear.
At first, if the story does not include many details, it may seem that the customer has failed. He did not give full requirements, then changed something else after the demo. What a bad customer! The truth is, however, that it is on our side as service providers, and preferably even partners, to ensure that we know everything needed to deliver precisely what the customer needs.
It is on our side to proactively extract knowledge from the client and validate the requirements and the results of our work with him daily. We must prepare the architecture as flexibly as possible, deferring all decisions until the “last responsible moment.” We cannot build basic mechanisms for a specific library or use workarounds for implementation.
This approach will be perfect for quick MVP creation, but it is worth avoiding the abovementioned mistakes regarding long-term cooperation.
If you want to know more about our bugs and conclusions, we invite you to our webinar at the end of September!
About the Authors
Principal Developer at Synergy Codes
He often worked with Angular but also carried out projects using React and Electron. In addition to writing code, he manages the Software Delivery Guild, where corporate processes related to software development are tested and improved. Initiator who likes working with people, willingly shares knowledge, whether inside or outside the company. Recently, he has been developing strongly in modeling and software architecture.
Principal Developer at Synergy Codes
Piotr started as a backend developer, but for five years, mainly associated with the frontend. He is involved in many corporate initiatives supporting process improvement. He manages the “Software Stack Diversity” Guild, which aims to recognize new technologies that enable the company’s development in new areas. Piotr specializes in frontend architecture and the broadly understood software development process. Privately, he is passionate about photography, science, and his beloved wife and two kids.