ESC

Minplan: Mobile App APIs for a Digital Safety Planning Tool

minplan

Minplan: Mobile App APIs for a Digital Safety Planning Tool

Minplan is a digital safety planning tool designed to support individuals at risk of severe mental health crises, offering personalized crisis plans, coping strategies, and emergency contacts, while also serving clinicians and caregivers as a practical resource in mental health care. In 2023, as part of his role as Senior Fullstack Developer at Techscale, Faisal worked with Minplan to build and strengthen the backend APIs powering the app’s mobile experience. This Minplan case study covers that work in detail.

A safety planning tool occupies an unusual position for a piece of software: it’s designed to be used precisely at the moments when a person is least able to tolerate the app behaving unpredictably. A crisis plan that fails to load, an emergency contact list that shows stale information, or an endpoint that silently times out isn’t a minor inconvenience in this context, it’s a gap in a support system at exactly the point someone is relying on it most.

That context shaped the engineering priorities on this engagement from the outset: predictable API behavior and thorough test coverage weren’t treated as nice-to-haves layered on top of feature work, they were treated as core requirements of the product itself.

What We Built

The core of the engagement involved building multiple mobile app APIs for Minplan using ASP.NET Core. These APIs served as the connective layer between the mobile client and the underlying application logic, enabling the features clinicians, caregivers, and end users rely on within the app. Work centered on designing endpoints that were consistent, predictable, and straightforward for the mobile team to integrate against, as well as extending existing functionality to support new capabilities as the product evolved. That scope is the core of this Minplan case study.

Minplan case study - mobile API reliability and testing flow diagram

Because the API layer was shared infrastructure feeding a live mobile app, changes had to be made carefully. New endpoints needed to slot into the existing ASP.NET Core architecture without disrupting functionality that was already in use, which meant paying close attention to how requests, data models, and business logic were structured so that the API surface stayed maintainable as it grew. This kind of incremental, backward-compatible extension work is often less visible than building a system from scratch, but it is where a large share of the effort in an established codebase actually goes.

Extending an existing API surface without breaking mobile clients already in the field is a specific discipline. Unlike a web frontend, which can be redeployed the moment a backend change ships, a mobile app’s installed base updates gradually, and some users may run an older version of the app for weeks or months after a new one is released.

That means backend changes generally need to remain backward-compatible with older client versions for a meaningful window, adding new fields and endpoints additively rather than changing the shape or meaning of existing ones out from under clients that haven’t updated yet. Getting this wrong doesn’t just cause a bug report, it can mean a subset of real users hitting broken functionality with no way to fix it on their end except updating the app.

Beyond feature delivery, a significant part of the work was dedicated to writing comprehensive unit and integration tests across the API surface. This meant validating individual components in isolation as well as verifying that services, data layers, and endpoints behaved correctly when working together as a full system. The goal was not just to confirm that new functionality worked as intended, but to build a regression safety net that would catch problems early as the codebase continued to grow, giving the wider team a clearer signal about the health of the system with every change.

Why Reliability and Testing Mattered Here

Any application that handles personal and sensitive user data warrants a higher bar for engineering rigor than the average consumer product, and that principle guided the approach to this work, a theme that runs throughout this Minplan case study. When an API sits behind a mobile app that people depend on to function correctly, untested edge cases and silent regressions carry more weight than they would in a lower-stakes context. Comprehensive test coverage reduces the likelihood that a change made for one feature quietly breaks another, and it gives the development team confidence to ship updates without reintroducing old bugs.

Integration tests in particular matter for systems like this because real-world behavior depends on how multiple components interact, not just how each one performs in isolation. A method that passes its unit tests can still fail once it is wired into the full request pipeline, so validating that pipeline end-to-end is essential to catching issues before they reach production. For an application built around dependable, real-time access to information, treating reliability and test coverage as first-class engineering concerns, rather than an afterthought, is simply the responsible way to build.

This standard also shapes how ongoing changes are handled. In a codebase with strong test coverage, a developer can modify or extend an API with a reasonable degree of confidence, because the test suite will surface unintended side effects rather than letting them slip through unnoticed. That confidence compounds over time: it allows a team to keep improving the product at a steady pace instead of slowing to a crawl out of fear of breaking something that already works. For a product whose users are, by design, trusting it to behave correctly, that discipline is not optional.

API Design for a Long-Lived Mobile Backend

Diagram of the Minplan mobile API architecture: mobile app, REST API, auth layer, database

Designing endpoints that stay “consistent and predictable” for a mobile team isn’t just a matter of good intentions, it comes from specific practices. Using dedicated request and response models, rather than exposing internal database entities directly through the API, means the mobile app’s contract with the backend doesn’t have to change every time an internal data structure changes for unrelated reasons. This principle shows up repeatedly across this Minplan case study.

Versioning strategy matters too: when a breaking change is genuinely unavoidable, introducing it as a new version of an endpoint, rather than altering the existing one in place, lets older app versions keep working against the version they were built for while newer clients adopt the updated behavior. Consistent naming, predictable error response shapes, and clear status codes across the whole API surface also reduce the amount of special-casing a mobile team has to write client-side, since a single set of conventions can be relied on everywhere rather than re-learned endpoint by endpoint. These are the conventions this Minplan case study leans on most heavily.

None of these practices are unique to Minplan specifically, they’re general good practice for any API serving a mobile client with an installed base that updates on its own schedule. What made them worth emphasizing here is the cost of getting them wrong: a breaking change that slips through in a product like this doesn’t just produce an error toast, it can mean a safety plan failing to load for someone in the middle of a crisis, which is a fundamentally different severity of failure than a typical consumer app bug.

Testing Strategy in Practice

Diagram of the Minplan testing strategy: unit tests, integration tests, regression suite

A typical ASP.NET Core test suite for this kind of API layer splits into a few distinct layers. Unit tests target individual classes and methods in isolation, mocking out dependencies like the data layer so that a test failure points precisely at the piece of logic that broke. That discipline anchors the testing side of this Minplan case study.

Integration tests, by contrast, exercise a more complete slice of the system, often spinning up the actual request pipeline against a test database, to verify that components which pass their individual unit tests also behave correctly once wired together. This layered approach catches two different classes of bugs: unit tests catch logic errors within a single component, while integration tests catch the more subtle failures that only appear from how components interact, such as a data access layer returning a shape that a service method doesn’t handle correctly, or an authorization check that behaves differently once real middleware is involved.

For an API supporting a mental-health-focused product, this layered testing approach also functions as a form of risk management. A crisis-planning feature that silently fails to save a safety plan, or that shows a caregiver stale emergency contact information, isn’t just a typical software bug, it’s a failure with real consequences for someone in a vulnerable moment. Building the test suite to catch these classes of failure before they reach production is a direct, practical expression of taking that responsibility seriously.

Test data management is its own consideration in this kind of suite. Integration tests that touch a database need a way to set up known, isolated test data and tear it down cleanly afterward, so tests don’t leak state into one another or depend on the order they happen to run in. A flaky test suite, one that occasionally fails for reasons unrelated to an actual bug, tends to erode a team’s trust in testing altogether, so investing in reliable, isolated test setup is as much a part of “comprehensive testing” as writing the assertions themselves.

Key Outcomes of the Minplan Case Study

As this Minplan case study shows, this engagement gave Minplan a set of mobile app APIs built to extend safely over time without breaking existing clients, and a comprehensive unit and integration test suite that functions as an ongoing regression safety net as the product continues to evolve. Together, these gave the wider team the confidence to keep shipping changes to a mobile application that clinicians, caregivers, and at-risk individuals depend on functioning correctly.

Tech Stack

  • ASP.NET Core — the framework used to build and extend Minplan’s mobile app API layer — a central technology in this Minplan case study. See our Hire an ASP.NET Core Developer page for related backend engineering work.

This work was carried out as part of Faisal’s role as Senior Fullstack Developer at Techscale, an agency serving clients including Minplan — the same engagement covered throughout this Minplan case study. For related backend API work in a different domain, see the Specsavers case study.

Book a Free 30-Minute Call

Frequently Asked Questions

Why is backward compatibility especially important for mobile app APIs?
Unlike a website, which updates instantly for every visitor the moment new code ships, a mobile app’s user base updates gradually, and some users may run an older app version for weeks after a new one releases. Backend APIs generally need to keep supporting those older clients during that transition window, which means extending functionality additively rather than changing the meaning or shape of existing endpoints out from under apps that haven’t updated yet. This is one of the patterns this Minplan case study returns to repeatedly.

What’s the difference between unit tests and integration tests?
Unit tests check a single piece of code in isolation, typically with its dependencies mocked out, so a failure points precisely at the broken component. Integration tests exercise multiple components together, often through something close to the real request pipeline, to verify that pieces which each pass their individual tests also work correctly when combined. Both matter: unit tests catch logic errors quickly, while integration tests catch the failures that only appear from how components interact.

Why does test coverage matter more for an application handling sensitive personal data?
When an application handles sensitive information, like mental-health-related data, as in this Minplan case study, an untested edge case or silent regression isn’t just an inconvenience, it can mean a real user hitting broken functionality at a moment when they’re depending on the app to work correctly. Comprehensive testing reduces that risk and gives the team confidence to keep improving the product without reintroducing problems that were already fixed once.

What does it mean to design an API “contract-first” with request and response models?
Rather than exposing a database table’s exact structure directly to API consumers, a contract-first approach defines dedicated request and response models that represent exactly what the mobile client needs to send and receive. This decouples the API’s public contract from internal implementation details, so the underlying data model can evolve for reasons unrelated to the mobile app, such as adding an internal tracking field, without forcing every client integration to change in lockstep.

Why does test data isolation matter in an integration test suite?
Integration tests that share state, or that depend on running in a specific order, tend to become unreliable over time, failing intermittently for reasons that have nothing to do with an actual bug in the code being tested. Setting up known, isolated data for each test and tearing it down afterward keeps the suite deterministic, which matters because a test suite that produces false failures eventually gets ignored, defeating the purpose of having it in the first place. That discipline is a recurring thread in this Minplan case study.

Join the Engineering Newsletter

Get deep dives into system design and scalability delivered to your inbox.

We respect your privacy. Unsubscribe at any time.