This living & breathing document is a collective agreement about what great engineering looks like at House Rx.

Purpose

Tenets of our process

🫂 We design together

Though one person can take ownership in writing a design document, we circulate it in the team and give people time to sprinkle it with feedback and alternative ideas. We make better decisions together.

♻️ We respect our lifecycle

We branch off of the fusion branch when starting work, and always merge against it. Our features make their way through our remote environments in sequence and go through a suite of manual and automated tests before they make their way to production. The flow goes from local, to fusion, to staging, and finally to production.

➕ Code reviews make us better engineers

We value feedback and we honor it by making sure all of our code reviews (Pull Requests, or PRs) get code reviewed and approved by someone else before merging it in. Code reviews make the reader better as well; we all benefit from being aware of others' changes, perspectives and approaches. A few guidelines: assume competence and goodwill, ask for the why & mention the positives.

🌀 We continuously validate our technology

Both through automated and manual means, our team is consistently validating that the technology is working as expected. We yearn to find out about problems before anyone else does.

💨 We move fast and fail fast

We prototype quickly and iterate furiously. We are not afraid to pivot if we realize the prototype/framework is not doing what it’s meant to. We give ourselves the luxury of changing our minds. 

💔 We try our best to not break things

Once projects have reached clients' hands, we do everything within our power to not break things. Speed cannot come at the expense of quality and reliability.

💡 We understand what we are building

We ask for context from our product managers and make sure we understand the purpose of what we are building. We ask clarifying questions about the vocabulary used. If you don’t have context/confidence in reviewing others’ work, ask questions and recruit for backup. 

📣 We shout our assumptions
from the rooftops

We do that in public channels so that others can validate them. We make better assumptions together. 

✌️ We’re committed to
improving the process

All of our agreements are fluid and we are open to changing them together. If we see an opportunity for improvement, we bring it to the team. 

🤲🏽 Let’s stay humble
to make better decisions

Our understanding will always be partial and often biased. We know that we make better decisions together. We’re excited to grow and learn from each other. 

Tenets of our design

🌵 DRY and fly

Don’t Repeat Yourself; Feel Light, Yo. When possible, generalize a piece of code to be used elsewhere.

🗂️ We separate our concerns

The kitchen is for cooking and the bedroom is for sleeping. We abstract away complexity into narrow functional layers, enabling code/software users to see only what they need. We write modular code that’s highly cohesive, striving for the functional single responsibility principle (SRP) whenever possible. Every function, class, module, or service should have a single clearly defined responsibility.

💋 KISS, we are not remiss

Keep It Simple, Silly. Don’t make things complex when they can be simple and “minimal”. It’s just good zen practice.

🍬 We don’t add extra

Don’t add things because you think they’ll be needed in the future. Let’s hold off on adding that column, variable, on function until it's backed up by a user/system need.

💞 Interconnected but Loosely Coupled

We have a deeply interconnected system that is loosely coupled. We believe in the dependency inversion principle (DIP), and our modules are unaware of the particularities needed for implementation in its dependencies. We strive for this both in software through separation of concerns but also through our testing and infrastructure.

🔥 We don't reinvent the wheel:
Open source is fuego

We use reliable open source when available. We check how other systems utilize a given piece of open source code and do temporal npm evaluations before suggesting integrations.

🆕 We’re flexible to extensions

We write narrow functional code that is open to extensions. As the product grows and needs change, we want the code to be adaptable. All things equal, we prefer extensions of existing code over broad modifications. As software engineers we are skeptical of modifications that require broad sweeping changes of code.

⏩ We are responsibly progressive

We value experimentation and the freedom to figure out the right path. We recognize we don’t always create a good thing the first time around. If it’s impacting business deliverables or the developer lifecycle, we are willing to throw our own code down the drain. We are open to writing some code for the sake of proposing a design even if the PR gets closed and bites the dust.

🔒 Security at all levels

It’s imperative that we keep in mind that we are building a multi-tenant software for clinical workflows, creating, processing and aggregating information about people’s health and wellness. We must bake security into every step of our building: from design to user-interface implementation, from API gating logic to database hardening, from strict networking rules to secret rotations. We must ensure that our open source dependencies are secure. We must ensure that our authorization & authentication are foolproof. People will make the mistakes that are available to them. We develop conservatively.

📦 Our inheritance makes sense

A penguin is a bird, but let's remember that not all birds can fly. We follow the Liskov Substitution Principle, meaning that every child/derived class should be substitutable for their parent/base class without breaking functionality. In other words, the objects of our subclass should behave in the same way as the objects of our superclass.

📝 We give the gift of learning: we document

We document our systems in a way that’s succinct, informative, and informational. We train our own replacement so we can expand our work as engineers; we document systems and processes so someone else can try building it next time.

☑️ We’re consistent

Once we agree to a pattern, we are consistent with it. From naming choices to coding frameworks, once we agree to it we apply it everywhere.

👣 We Develop Incrementally

We help our product managers and tech leads break up work into testable functional bite-sizes.

💭 We anticipate change

We know today’s truth might not be tomorrows. We know data types can change and things can come in looking different. We write code that is defensive, and we anticipate the change of tomorrow by writing code that will kindly deal with it.

🧪 Our development is test driven

We know that developing complex features requires thinking through the entire user and data workflow. We codify experience expectations into tests to ensure our code meets requirements. We know that in an interconnected, complex system, changes here can break things there.