Project flow considerations for bigger teams
My thesis today is that in many distributed teams siloing is the unfortunate side effect of poor work organisation. Backend oriented folks working on the services without ever considering or talking to the Froenenders who are building the consumer application for the services just a few desks away. Testers not adjusting their workflow to the situation they are in. PO going mad over the worsening speed of project delivery and everyone being pretty frustrated and overwhelmed with the amount of guessing, follow ups and ad hoc calls they have to take to "clarify a few things" and the amount of things being pulled back because of working in isolation.
It's my strong belief that there are tools which help alleviate most of those symptoms significantly, but admittedly most of them are based on open and regular communication. No I am not calling for more meetings, communication doesn't mean in person presence, at times merely giving people easy tools to request what they need is enough.
Below are some tools / techniques which have helped me tremendously on some of the projects in the past.
- Collaboration is the root of speed, eradicator of misunderstandings and one of the best requirement clarification techniques. Comparing approaches by all the parties involved in development opens a new door for simplicity - instead of asking for a new endpoint you may reuse an old one, instead of creating an entirely new screen you may be better off tweaking the existing one. It calls for the sacrifice of the Ivory Tower architect, trying to figure out the low level details from the heights of his position.
- Contract driven development - I am not talking of the choice of language - contract is after all just an agreement between the parties of what is the common thing they strive to achieve. If you start with collaboration and establish what you want already, in web context contract can mean an openapi specification that you can already use for mocking. The beauty of this approach is that you can build the consumer <-> service implementation from the get go, and make mocking way easier. Some of the tools I use regularly are nest.js (because if you decorate it properly it will spit out a fully functional openapi spec, watch out though as some of the return types might prove problematic), go-swagger - but admittedly I feel like the comment based approach is a little clunky. Most recently we've been giving airtasker/spot a go, as we wanted to avoid using nest.js this time. The way it works is the following: looking at what you're trying to build, you arrive at a transport that satisfies both parties (as it will suffice for the display layer and be achievable by the service), you code it in the form of interfaces, along with the accompanying router. You ignore the implementation for now, this is just about the structure. Next you generate the openApi spec and use a tool like stoplightio/prism to quickly spin up mock servers instead of running full implementations of the code by the consumers and BAM, you have a local environment that is not dependant on the speed of delivery, will be easy to keep up to date (as it is generate from the actual interfaces used in code) and can accept PR / suggestion for change via Pull Requests.
- Split up work. In a team of 5 + or if there is mentoring happening within the general rule is: the smaller the work unit the better. It's faster to finish, easier to check, eliminates most of the merge conflicts (because nothing easy to check keeps hanging in the PR limbo and diverging further) and most importantly - it's less taxing mentally. You will feel less inclined to think that being thrown off focus is something uniquely frustrating to your profession if you structure work in a way that will let you get back to it relatively quickly. Smaller unit = less context = less lost in interruptions (not that I support them, but they are inevitable).
- Document decisions - every so often I gaze stupidly at something I've conjured to life thinking "WTF, why on Earth would anyone want it this way" - keeping a decision log quickly sets me straight especially when it comes to corners I've deliberately chosen to cut. ADR to the rescue - there are a bunch of great tools for that, but most of them are merely spawning .md files with some naming convention in a given folder - I have been using adr-tools for a while, and they work despite the repo claiming the build is failing.
- Document everything that has proven problematic - basically any time you had an issue with something - drop it into the repo in one of the .md files (or anywhere else you keep your docs) - quick tips from the context that is familiar for you and your team members are way more valuable than more general ones.
- TRIAGE bugs / tickets that are being sent back by the QA team. It takes a little coordination but I am always suggesting a flow of QA reach out to a person from Development team (either base it on rotation or just throw it out there during the daily and stay over), try to find out what the issue can be - a lot of the times you will find it pretty quickly, otherwise just leave it as it is for further investigation (make sure to jot down anything you have crossed out as a possible problem source) This makes a tremendous difference in my opinion especially when the work is split between stack oriented teams - you limit the chance of the ticket going into the wrong pipeline - eg. something requiring a FE change going to the BE team and the other way around.
This should be plenty already. Last is my favourite tool for planning - Event Storming, but it calls for a dedicated post! Hope this may help someone in the future.