Groups Recover Together

thoughtbot · 2021

A phone number is not a person.

React Native · one system across a clinician portal and both mobile apps

Industry: Healthcare & Recovery Role: Product Designer and Front-End Developer, thoughtbot Duration: 13 months Tools Used: Ruby on Rails, React Native, Figma, HTML, CSS (TailwindCSS) Website: joingroups.com

Project Brief

Groups Recover Together delivers medication-assisted treatment and group therapy for opioid use disorder. I worked on it through thoughtbot, which supplied most of the tech team, starting with a product design sprint and staying on afterward.

A designer came out of that sprint with me. She set the visual language, and I carried it into the design system I was coding in Tailwind. Groups had a site with colors, typefaces, and some marketing copy, and very few guidelines, so we both worked from what was there. Over time, the design work on the project narrowed to me.

It was the first React Native feature work I had ever done, and the first design system I had built for mobile: two applications, two runtimes, one person holding the system. The system was not craftsmanship; it was arithmetic: the only way that arrangement ships anything is if a decision made once holds everywhere.

The work itself was consolidation. A set of tools assembled quickly during the pandemic had to become one platform, for a service moving to fully remote care, integrating with the electronic medical record the organization already ran on. Most of the early judgment was deciding which parts of that to build, which to buy, and which to leave exactly where they were.

A phone number is not a person

Staff trained on the software while we built it, which kept the client’s team reachable for feedback week after week. We interviewed members during the first sprint. It took a lot of empathy, grace, and respect, and we designed almost nothing on this project without someone who used it in the room.

The finding that rewrote the architecture was about phones. Some members did not have a device of their own. Some shared both a device and the number attached to it. An authentication model that treats a phone number as an identity works fine until it silently excludes the people the service exists for.

So identity moved to usernames, with a migration path off phone sign-in, a recovery flow, and biometrics designed on the assumption that the device is shared. The same assumption runs through the invitation specs: an invitation that cannot arrive — the number unreachable, or a landline — is an ordinary case with a retry path, not an error state to be logged and forgotten.

A phone number is not a person

A single failed assumption resolving into five capabilities. On the left, a phone number assumed to be a person. Correcting that moves identity onto a name somebody claims, and that one move requires five things that did not previously exist: a way to claim an identity one person owns, a way to migrate an account off phone sign-in, a way to recover the name when the number is gone, a way to be invited without an existing account, and a way to unlock privately, because the device may be shared.

Identity movesto a name somebody claimsClaim an identitya name one person ownsMigrate an accountoff phone sign-inRecover the namewhen the number is goneBe invitedwithout an existing accountUnlock privatelythe device may be sharedA phone numberassumed to be a person

Treating a phone number as an identity is a mobile default. For this population it could not be one, so identity moved onto a name somebody claims — and the five capabilities on the right are what that single move required.

Collage of mobile member app screens and the web admin dashboard with group schedule and intake views

Where the platform stops

Staff research set the other boundary: the existing electronic medical record.

We covered the part the care team needed day to day, kept the record itself authoritative, and named the edge where the two met. Somebody adding a member still finished the job in the medical record.

That was a decision, not a gap. A system of record you must not replace and should not duplicate is one you integrate with deliberately and then stop at: a second surface editing the same patient data is not a convenience; it is two sources of truth waiting to disagree. Deciding what not to build kept two systems from disagreeing about the same patient, and none of it is visible in the interface.

The sprint set the shape: essential features defined, the integration mapped, then a pilot with real members whose feedback drove the iterations. Interviews sorted what was essential to recovery from what merely stood in the way, and settled the three the product would be organized around. Progress tracking, community, and needs and interventions.

One system, two runtimes

A single Pattern Library ran across the clinician’s console and the member’s phone. One shared Tailwind configuration ran across web and React Native, so a color or spacing step carried the same name in both places, with an abstraction layer for things that don’t map between them.

Those differences are not cosmetic. In HTML, text can run free in a container; in React Native, every string has to live inside a Text component. A shared system either absorbs that kind of difference or leaks it, and a leak means two implementations drifting from the same intent.

Care Plans were specified as Member and Admin pairs in every version: two sides of one feature designed together, not one first and the other later. That is the habit the whole system runs on: a feature is not the screen the patient sees; it is the screen the patient sees and the screen the clinician sees, and they are one decision.

Three mobile screens: onboarding video event, urine drug screening submission, and care plan milestone goal selection
Clinician web admin showing a member’s care plan history with Dashboard and Members navigation

Impact and Results

By January 2022, the platform had launched nationwide as web, iOS, and Android. We handed it over to an in-house team, which meant the design system had to be legible to people who had never met us: the real test of whether the naming and pairs were doing their job, and why we had been strict about both.

Figma design spec sheet showing annotated Registration Flow and Lapsed Registration Flow mobile screens

Outcome

Self-scheduling, outreach, forms, payment, treatment planning, and group therapy all moved onto one platform, integrated with the electronic health record Groups already used. The same system carried a web portal for care teams and both mobile apps.

Groups went on to more than double its membership over the period it expanded into remote-first treatment: a shift the platform was built to support, alongside a great deal of work that had nothing to do with software. Thirty per cent of those members live in a county where Groups has no physical office.

What I would change

Not a decision — a cadence. We did a lot of research, and it was episodic: it arrived at milestones, in campaigns, when a phase called for it. I would run standing interviews every two weeks with a fixed group instead, so that insight arrives continuously rather than being commissioned.

And there is a question I never had access to, which I have come to think is the real one. An organization like this sits between government grants, regulation, and its own financing, and the design problem underneath it all is how you ethically scale something like this: how to grow enough to support as many people as need help, without exploiting a single one of them.

The project opens with a finding about one person’s phone and ends on a question about an entire business. It is the same instinct at two scales, and I only got to act on the first one.