Delivering my first software application

Jensen Seah Ee Song
7 min readNov 20, 2021

3 months ago I graduated from Singapore University of Technology & Design (SUTD). As part of my capstone project, my team worked with a liaison from a courier company in South East Asia. Our mission (should we choose to accept it) was to manifest a cloud-based software application that would help delivery drivers across the 5 countries manage how petty cash was invested, spent and optimized. A more detailed account can be found on a feature on SUTD’s website.

Photo by KOBU Agency on Unsplash

Touted as one of the few capstone projects that not only delivered against the stated requirements but also validated relentlessly with real users with multiple rounds of user acceptance testing (UAT), I’d say I feel pretty good with what we’ve accomplished. Yet behind the scenes it was less than sunshine and rainbows. After all, one could only expect so much from 7 undergraduates on part-time capacity tasked to design, develop, test, tweak and deploy a fully functioning software application at scale. The truth was, we struggled and made many trade-offs we had trouble finding peace with.

Looking back, there were many things I wished I’d done differently. Unfortunately, the best I can do at this point is to reflect on them and hopefully I’ll remember these things the next time I have the privilege to lead a team.

Discovery: Don’t discount team learning

After 4 years as students, many of us are excited to prove ourselves. Not just to peers, professors, industry mentors but also to ourselves. We want to show that the years we spent in bent over books, assignments & examinations wasn’t for nothing. We want to put our names proudly next to a product of value, a product that works and a product we can be proud of. What better chance than a real-world industry project right before we leave school?

What we didn’t expect of course, was that a real life project brings with it real life complications that school projects are blissfully ignorant of. Legacy implementation, unfamiliar technology, organizational constraints, conflicting agendas and shifting targets.

Things change. We need to change along with them.

To do so, we need to dedicate time and energy to the team’s cumulative knowledge.

For SUTD’s engineering capstone, the first few months is traditionally reserved for problem discovery & research in line with the design thinking methodology. Like many teams out there (especially those with project requirements already clearly defined by their company mentor), our team simply went through the motions instead of actively trying to expand the boundaries of our thinking through team learning. State-of-the-art research, user interviews, usability studies were executed and documented but the core solution seldom budged.

Photo by Jason Goodman on Unsplash

I recently took a few online courses and was pleasantly impressed with the quality and how much I could pick within a span of a few hours. In the realms of scrum, technical architecture, cloud computing, so many of issues we struggled with already had prescribed best practices published on the internet for anyone to peruse. How much easier our lives would have been and how the quality of our final solution could be improved if we had chanced upon the right piece of knowledge at the right time.

Hold team learning sessions: Taking turns, each member to research a topic that the team was unfamiliar with or something that could be improved. Findings are then shared with the team in an unstructured and informal setting. Sharings are meant to inspire ideas, facilitate discussion, strengthen relationships and allow the team grow together.

Understandably, most of these sessions would be a hit and miss but there are multiple other intangible benefits to be reaped. Additionally, in the nascent stage of a project where many important (potentially irreversible) decisions are made, uncovering the right knowledge could save the team a lot of hassle down the line.

Scoping: Respect the triangle

Few weeks back, I took the Certified Scrum Master course over the weekend. Yes, I’ll admit it — I played the role of scrum master in my capstone project without even knowing what a scrum master does. But older and wiser now, the iron triangle concept that could have saved my team a year ago from scope creep will be one I’ll never forget.

The agile iron triangle mandate I wish I knew then dictates: Of project scope, resources and schedule, only 2 of these can fixed — lest quality be compromised.

“That’s great, Captain Obvious.”

Agreed. But what’s less obvious here, is how this underpins any scope negotiations, requirement changes or additional requests. In a project with a fixed resources and schedule, similar to my engineering capstone, scope must remain flexible. Take our project as a case study for what NOT to do (at least not while working under an agile development framework).

  • We agreed to a project scope we weren’t confident of delivering
  • We agreed to fundamental requirement changes in the midst of development i.e. changes to the tech stack
  • We agreed to casual additional requests from our client

While we did please our company mentor at every turn, giving them what they desired, we unwittingly put the final deliverable at risk. Either the full functionalities would not be realized at project end, or the quality of the solution would take a hit — both of which wouldn’t be something that the team nor our client would have preferred.

Don’t be afraid to say no: Create a common understanding of the triangle and which vertices are fixed/flexible. When proposed with change requests, ask “would you be willing to pay more/push the release date/trade out a feature”?

Developing: Define standards & keep to them

I’ve been a developer in a professional setting before. I know what a properly organized development teams feels like. You’re tasked with a feature, you do it and you mark it as done. Step 1,2,3. No ambiguity, no dependencies, minimal further communication outside the daily stand-up necessary for you to get it done. Everything aligned for you to focus on developing the feature to the best of your ability. We did not achieve this level of organization.

A little context: Our solution featured a webapp with 4 supporting microservices built on various PAAS products from GCP. Every 2-week sprint was kickstarted by with the prioritized features ordered from the product backlog. The development team was broken into the classic front-end/back-end developers. The desired user flow is then described using wireframes and the business logic of back-end services was described with pseudo-code. The development team then discusses salient issues and updates each other during biweekly stand ups. As mentioned before, scope was fixed so each sprint had to be contained in a strict, unforgiving timebox. Technical debt would always be swept under the rug and we focused on mechanically churning features.

Every release for UAT, it was a mad scramble to piece everything together and for the last few sprints, tension and emotions ran alarmingly high within the development team. Despite employing re-useable components & layered microservice architectures, a great deal of cleaning & re-factoring was still in order for the code to be readable & maintainable.

What happened?

Photo by John Schnobrich on Unsplash

From where I was standing, different expectations with regards to development was generating heat between the developers. I believe prescriptive directives on collaborative software development could have reduced friction within the team. Mostly basic tenets but every team may operate differently:

From where I was standing, different expectations with regards to development was generating heat between the developers. I believe prescriptive directives on collaborative software development could have reduced friction within the team. Mostly basic tenets but every team may operate differently:

  • Best practices and accepted standards for code quality, code integration, definition of done
  • Agile paradigms (TDD, BDD, DDD) could also streamline the communication of requirements between business analysts and developers.
  • Thoughtful decomposition of features to minimize inter-dependencies and the need for constant communication between members

These directives aren’t overheads to be glossed over once and forgotten. Take time to flesh these out and gather the commitment to adhere to them. This will prevent countless instances of unintentional toe-stepping and pent-up frustration that can quickly degrade team morale and performance. Further, they keep us accountable to each other from taking the easy way out when under pressure.

Build these directives early: Each developer to share their experience & what works best for them. Come to a consensus on what directives will optimize collaboration & team performance.

Don’t skip sprint retros: Every sprint should end in a honest conversation on team performance. Members should be open-minded & constructive.

--

--