We share with the client the responsibility for the success of the product we develop. Therefore, we need to understand all stakeholders' real goals and motivations, to adjust our vision, and to plan together with the client at each step. We document these goals and keep them in mind when we make each significant work block. When it seems that something has changed and our vision has become less precise, we always clarify the situation with the client. That's why, our mutual product vision remains consistently clear and harmonious.
As in any other process, we are against unnecessary bureaucracy. When there are enough inputs to make high-quality decisions, we do our work quickly. At the start of a huge project, we usually document the results of our product planning in a convenient form. This document contains the goals of the product, their reasons, the general approach to achieving it, and product risks. We develop the agreement and finalize it with the client to the necessary level. We update this document every time we make a significant change in the business model if the goals have changed.
The "Approach to Achieving Product Goals" section of the agreement describes how we move from negotiation to the development stage. In this section we offer the client our vision for the overall product architecture, team design, technology stack, and communication processes. This part helps quickly identify potential disagreements in the product vision and explains our action plan. We work through all ambiguities and differences with the client, laying a solid foundation for work on the product.
The agreement declares product risks, which we strive to mitigate whenever possible. Therefore, it helps us to make better decisions and save time. If we know that there will be many product hypotheses, we will choose the fastest and most reasonable ways to test each of them. If we implement a product functionality using a 3rd-party, we develop a plan to eliminate that dependency. So, the users will not suffer significantly from the long-term inoperability if the 3rd-party stops solving its problem.
This set of measures makes the result more predictable, the product more reliable, and all team members — much more confident in their actions.
[ The carpenter's saying, “Measure twice, cut once” is highly relevant to the construction part of software development, which can account for as much as 65 percent of the total project costs. ]
— Steve McConnell, Code Complete
A young project's most significant technical difficulty is the constantly changing requirements. An entrepreneur is just starting to build a business model, so this is normal. At the same time, this often becomes a Pandora's Box for product developers. Sometimes changing the minor aspect of functionality from a business perspective can lead to big problems in product development. Usually, the right solution is not just to redesign a feature but also to align other dependent product modules. Proper technical and architectural planning of the product makes these problems predictable, the threats manageable, and the costs of product changes optimal. It also makes programmers happier.
We know how to appropriately use technology to evaluate the most probable threats and prevent most of them in the earliest stages of product development. Before we move on to technical details, here are a couple of words about how we interact with the customer.
We have clients with a high level of technical expertise and clients who have no IT specialists at all. Regardless of the client's technical expertise level, we always follow the principle: the client must clearly and distinctly understand all the significant consequences of our architectural solutions for their business. And achieving this clarity is our duty. We create conditions for the client to understand the causes and consequences of our decisions as deeply as possible.
The main task is to define the overall system design and basic architectural principles. When the client's vision is clear enough, and the inputs are consistent, we can quickly make these decisions. Based on expected development scenarios, we determine the optimal starting constraints for the system. Architectural principles should answer the most critical questions of the product. For example, "how do we keep the most important subsystems operational?", "how do we optimize the cost of any future increment?", "how do we prepare for pivots?" This is how we determine the primary vector of product development and prepare for changes of any level.
Then we plan initial format of works including technical goals, processes on the product and the strategy for changing this framework. Also we prioritize parts of the product by businesses importance and expected changing, determine level of attention and technical quality. Decide, in what way we organize critic of technical requirement, code review, how to test a product, how to release and how to control bus factor. Also, we prioritize the parts of the product by importance for the business and determine the required level of technical quality. We define technical limits that the product must fit into, for example, "a page must load in 90% of cases in no more than 200ms" or "the main API in production must operate at 50 RPS". Continuous support of such constraints helps to guarantee stable operation of the product and simplifies local decision-making.
Then we need to choose project technologies. Usually, the main technologies, such as the primary programming language and framework, DBMS, and main 3rd-parties, are determined at the "Gathering Input" stage. Here we decide on specific technical questions, maximizing the cost-effectiveness and comfort of the development process. They are the CI/CD tools, 3rd-party secondary importance, policy on adding third-party dependencies, logging, monitoring, and alerting systems. Our client's choice is to understand this down to the smallest detail or learn what is essential to their business only.
The technical leader usually makes these decisions in a short time. A high-quality result requires a polarity of views, so we offer the client our solution only after an internal discussion. Then we implement taken decisions. With this approach, we feel confident with the constantly changing requirements.
[ They talked, chatted — sat down and cried ]
— Ukrainian folklore. Not about us.
High team performance requires strong project management, which consists of the competent organization of communications between all participants and a flawless reaction to force majeure. Standard solutions cover most of the questions entirely, so they do not require significant time.
The main task is not just to make the communication comfortable but also to document it's results as much as possible with a reasonable effort. The conversation can be highly productive, so we should not lose the details and reasons over time. Also, some tasks need research, which can lead to unpredictable results, so it is essential to document the process and mention all the significant facts.
Therefore, we produce artifacts after every communication. What did we discuss and why? What have we decided? What are the next steps? All team members must know the answers to these questions to make the right technical decisions. We don't like "meetings that could have been an email" and prefer to save our colleagues' time for more productive activities. Therefore we communicate in three places: Gitlab, Slack, and Notion.
We keep in Notion client agreements as well as strategic, architectural, and other documents. We like Notion for the excellent UX, the convenient system of user rights, and the tree-like structure of documents. All team members have access to project documents for the duration of their work. We also share working ideas there and maintain product documentation.
We have technology-oriented teams, so we use Gitlab as our main task tracker. It allows us to keep requirements, requests, bugs, and related discussions close to the code. It's easy to understand the reason behind any decision in the code because each commit links to a Gitlab task that contains the goal and technical requirements. We can quickly find all of the work done in each direction with the task search. Moreover, Gitlab has all the necessary project management tools, like the kanban board and milestones.
We use Slack for text communication with the client because of its UX and comfort notification system, what are better on the market in our opinion. It also has a pretty cool search, so we have no problem finding every discussion of an important subject here as well. We also use Slack for internal discussions. We schedule meetings in Google Calendar. In addition to Slack, we often use Google Meet to make calls.
We have typical communication processes lined up for each role. When launching communications on a project, we only choose how detailed text artifacts would be produced. The rest is the task of the product manager, who can focus on his art without spending too much time on routine.
Each element of the development process illustration is a link to an article. Click on it to learn more.