An internal care platform for a value-based cardiology company — replacing a clunky EMR, a stack of spreadsheets, and half a dozen third-party tools with a task engine built around what the care team should do next.

Karoo's care team was running enrollment out of five disconnected systems, and the only way to serve more patients was to hire more people. I led product design and product management on the replacement: a platform that models every piece of care team work as tasks within workflows, so the system always knows what the next step is and who should take it.
We shipped an MVP targeted to one team first — the Patient Engagement Specialists (PES) who handle enrollment. It's in beta now with a small cohort of real patients, and so far a PES can run an enrollment start to finish without leaving the platform.
Karoo Health is a value-based care company in the cardiovascular space. It sits as an enablement layer between health plans — Zing Health and Humana — and the provider groups whose cardiologists see patients. It also employs its own clinical team of nurses, dietitians and social workers who hold appointments with patients directly.
The goal is to reduce the total cost of care while holding health outcomes flat or better, through targeted interventions on both patient and provider behavior. It's been done in oncology and nephrology. Cardiology is next.
I joined Karoo as Director of Product Design in 2025 and lead both product design and product management for Flow.
Wireframes to get ideas on paper early, iterated into pixel-perfect mockups in Figma on a design system built for this project, linked into interactive prototypes that were used for user testing and winning stakeholder support.
PRDs specifying how every workflow in the platform should function — engineering requirements, data and reporting requirements, and the rationale for why we were building it that way.
Co-defined the platform's hierarchy and taxonomy with the CTO, COO, VP of Engineering, and the clinical operations team across onsites and remote working sessions.
Five systems, and none of them talked to each other. ThoroughCare, an EMR-adjacent care management platform, held the patient record. Then a separate tool for calling, another for texting campaigns, a pile of spreadsheets where the work was actually organized and tracked, and a calendar that knew nothing about any of it. This created a disjointed workflow for every single patient interaction.
None of it standardized how we wanted people working, and none of it would scale as patient attribution grew. The only way to serve more patients was to scale linearly by hiring more care team members. We wanted the opposite: tools that let the team we already had become more effective and absorb far more patient load, so headcount stopped tracking patient growth one for one.
The single most useful thing I did was shadow the PES team during actual enrollment calls. It's what produced the decision that ended up shaping the whole task model: a real enrollment call is not a script. It's a free-flowing conversation, and depending on where it goes, a PES will do things in a different order than any workflow diagram would suggest.
Structured sessions with PES, clinical, and operations staff formed the backbone of requirements gathering, alongside PES managers on both the Humana and Zing sides and members of the data and analytics team, who shaped how we'd process data and what reporting had to support.
Roughly five PES carried the deep-dive feedback sessions, user testing, and prototype acceptance. I ran sessions with their managers separately since they were a genuinely different user group with different needs. The PES do the work; their managers need visibility into the work.
The case for buying was strong on paper: faster, cheaper up front, and it didn't put a six-month platform build in front of a company that needed to be serving patients now. So we ran a real evaluation, and our "buy" options slotted into three buckets:
Innovaccer and everything in that category do similar things, and in doing similar things they fail in similar ways: a repository of patient data that never gives you an obvious next step. Buying one meant buying the exact problem we were trying to solve.
Zendesk, Salesforce. Genuinely task-oriented, but a patient enrollment call is not a support ticket. Close enough to be tempting, wrong enough to be a trap.
We'd already built a Chrome extension on it. Every new feature added another seam between two data models, and no amount of extension changes how the underlying platform thinks about the work.
Every platform has a way it wants you to work, and you pay twice to switch to something that works okay, but never quite right. What tipped the decision toward "build" was that building had gotten cheaper. Eighteen months earlier, "just buy something" would have been correct. With AI-assisted development, three people could build something designed specifically for our care team's needs.
The repository model is fine in some practices: a holistic view of a patient that enables customized care for the infinite variety of potential health issues a person may be dealing with. It is the wrong model for a value-based care company in cardiology, where the entire game is delivering very specific interventions to specific patients at the right time. Not handling every problem a patient may have, but solving the subset of problems that we can both have an impact on and that drive down total cost of care.
So instead of reinventing a care management platform, we built something aggressively task-oriented: identify the exact patients who need a specific thing done at a specific time, and put that thing in front of the right person. Everything the care team does, even the genuinely complex multi-step work that spans patients, providers, and internal coordination across nurses, social workers, and dietitians, can be modeled as a workflow or a series of workflows. Inside any workflow are individual tasks that move it along.
Today's AI and LLM tools aren't good at owning a full end-to-end clinical workflow, and in a lot of cases we wouldn't want them to. Certain interactions with patients are better done by a human with real cardiovascular expertise, someone who can listen and be empathetic to that patient's situation. But plenty of other work could be handled by a system: sending reminders, rescheduling appointments, the self-encapsulated administrative pieces.
For example, a five-task workflow might have two tasks a system can drive and three where our care team should stay firmly in the loop. Modeling the work as individual tasks is what makes AI-automated integration possible later.
The other half of the bet was absorbing the third-party tools. In a startup it's normal to accumulate a pile of them, and each one makes you build your workflow around someone else's product. Pulling texting and calling into the platform meant we could design them the way the care team actually needs them to work, cancel a set of subscriptions, and stop paying the tax of working around external constraints.
What came out of my research process were a handful of common themes that I heard over and over again. These were codified into a set of guiding principles that served as a north star as the team moved through the MVP.
The system can recommend, prioritize, and route work — but humans remain the decision-makers, especially in clinical contexts.
Where it showed up: Workflows guide but never dictate. A PES can work tasks out of order mid-call.
There's no single comprehensive journey, only next steps and transitions. We build tools flexible enough for the full range of patients we encounter.
Where it showed up: Override capability during scheduling that allows the booking of a social worker instead of a nurse when SDOH needs surface on a call.
Every interaction should have a clear purpose. We give the team a focused toolkit and clarity on what to do next, not an open-ended set of options.
Where it showed up: The whole task-engine bet — a next step instead of a data repository.
The platform needed one model that could hold everything the care team does, not just enrollment. Getting there took several onsites and a lot of remote sessions with the engineering team, clinical operations team, and the leadership group. This taxonomy not only gave structure to the product we were building, but also served as a "shared vocabulary" between the different teams as we iterated.
Where we landed: a patient is the top-level object. A patient can be assigned to one or more pathways, each a high-level block of work that could span months or years. Examples of pathways might be health condition specific (like Heart Failure or Diabetes), intervention specific (like GDMT, guideline-directed medical therapy, which covers getting a patient onto the right medications and every touchpoint with them and their providers along the way), or more business objective oriented (like Patient Enrollment).
Inside a pathway are workflows, each a discrete set of tasks organized into stages. For example, within the Enrollment pathway, you would have 2 workflows: an Outreach workflow (getting in touch with the person and enrolling them in the Karoo Program), and then an Onboarding workflow (sending them a welcome kit, getting the patient app downloaded, etc).
Inside a workflow are tasks - the individual units of work that move the workflow along. For example, a workflow for patient lab work, might have individual tasks for coordinating the blood draw, reminding the patient of their lab appointment, reviewing the lab results, discussing the lab results with the patient, and sending a note to their doctor if anything abnormal pops up.
The model is deliberately bigger than anything we planned to build for an MVP. We had a vision for what we were building toward longterm, but the next decision was which slice of it to ship first.
The Patient Engagement Specialists are a small team doing a narrow, repeatable set of work, and most of their time goes to one thing: getting attributed patients enrolled. That work is a workflow in the truest sense — the same sequence, in roughly the same order, for nearly every patient. It's also self-contained. Enrollment starts and finishes with the PES, and a patient enrolled is a patient we can actually go do something for. Nothing downstream has to exist for it to be worth doing.
Nurse and care-team workflows are the opposite. What a nurse does next depends on that patient's diagnosis, its severity, their medications, what happened on the last call. Serving them meaningfully would have meant building most of the taxonomy at once — multiple clinical pathways, most of the task types, the coordination surfaces between roles. Months of work before anyone could do their actual job in the platform.
So we covered roughly 80% of one team's core workflow instead of 10% of the full team's. Enrollment is about 80% of the PES job, so building the enrollment process in full covers it. The other 20% is everything adjacent to enrollment but not part of it — a patient calling in to reschedule, assorted administrative work.
To cover that 80%, we built: a dashboard that answers what am I supposed to be doing, a task action view where the work gets completed, a patient profile every task reads from and writes back to, and search, because sometimes a patient calls you.
Scope discipline is most of what an MVP actually is. Three things we designed and then didn't build:
A focused view for tasks that stand alone — a reminder doesn't need a whole workflow around it. We cut it because every MVP task can be completed from the workflow view, and the extra context isn't harmful when it isn't needed. The reverse isn't true: strip the context out and a PES loses the ability to move between tasks mid-call, which is exactly what enrollment requires.
We'd integrated Nylas for scheduling, and Nylas syncs to Google Calendar, where the team could already see everything. So we built the scheduling UI constraint system and no calendar to look at.
Enrollment campaigns come from an operations spreadsheet built on criteria that shift from campaign to campaign - these campaigns dictated which patients the PES team would reach out to. The obvious move was to have the system generate those lists itself.
Working with the operations team made clear their process wasn't defined tightly enough to fully automate, so we initially designed a middle path that would allow cohorts to be built within the platform manually. Cool feature, but ultimately I felt like this was scope creep - this functionality wasn't necessary to satisfy the underlying goal of the MVP: get the PES team what they need to complete enrollments. So we cut that too, in favor of simply ingesting the spreadsheet.
The core workflow that we built for the PES team was the Enrollment workflow. It's made up of four stages that serve as checkpoints - each stage should be completed before the next one makes sense - and tasks are the units of work that get you there.
Early in a call, while the PES is still establishing who Karoo is, patients routinely start volunteering information about their cardiologist and their other doctors. That's Collect, a stage three task. The PES is nominally still in stage one or two — the patient hasn't consented, the education isn't finished — but the information is being offered right now, and the only sensible thing to do is write it down. It happens again a few minutes later. The PES explains how Karoo will interact with them, and the patient answers with when they want to be called. Also Collect. Also out of order.
The system's job is to keep up rather than object, so a task sitting outside the current stage never locks it.
A task type determines what the platform renders. Consent is send-and-track. Collect is a set of structured fields. Schedule has a constraint picker. We defined 20+ so the model could support the whole care organization, and built the six PES enrollment needs for the MVP.
The problem is that those six aren't encountered one at a time. A PES moves through five of them in a single phone call, while the patient is talking. So each type has to be shaped for its own job, and none of them can feel like a different application.
One rigid template that every type fills in fits none of them well. Six customized screens fit perfectly, but cost you as the user has to readjust to where things are located at exactly the moment they can least afford to go looking — during the call with a patient. And the types we hadn't built yet would each be a from-scratch design later.
What we built is one task shell with a variable body. The base structure never changes — who the patient is, where you are in the stage, the Complete Task action, the call widget docked in the same corner. The body is the only thing a task type defines. That's what keeps the fifth task in a call as legible as the first, and what makes the next task type an addition rather than a redesign.
We started with a single Engage task per patient that would accumulate attempts as the PES made them — the PES would continue outreach until actually successful, at which point the task would be complete. At some point, we pivoted to having multiple Engage tasks - one for each communication channel (one task for calls, one for emails, one for postal mail, etc). Three problems killed both approaches.
The story got lost. Outreach is multi-channel by design. We want to send an email about the program, follow with postal mail a couple of days later, then a series of calls after that. Split across per-channel tasks, nobody could see the full story of what had already been done.
Engineering pushed back on the data model. A cleaner model treats each Engage task as one discrete action — a single outreach attempt.
And the one nobody saw coming, which surfaced in testing with the PES managers: it broke the metrics. A task that accumulates attempts never completes. Under the old model, a PES could reach out to a patient six times and if productivity was measured against tasks completed versus tasks assigned, it looks like they'd done nothing at all. Their managers needed visibility into work actually performed.
One Engage task equals one discrete outreach attempt. The PES picks the channel, which changes the UI rendered for that task, then logs the outcome. If the attempt was unsuccessful, the system prompts them to create the next one at a later date, which surfaces on their dashboard that day. There's always a next step.
The full story is preserved by aggregation instead of by one big task. Every attempt in the same workflow stage renders as a log inside each individual Engage task. Email on this date. Postal mail on this date. A call that went to voicemail. Another attempt, no answer. Now you're making this third call — what was the outcome?
That resolved all three problems at once. The PES sees complete history, engineering gets the discrete model they wanted, and reporting reflects real effort. People get credit for the work they're doing even when we haven't gotten the outcome we want.
Scheduling had been causing problems for over a year, and fixing it was an explicit goal of the MVP. The old scheduling system was calendar-based: find an open block, pick a time, hope. That produced double bookings, time zone errors, and a lot of manual cross-referencing to find out what time of day a patient actually preferred.
The reframe was asking why a person was doing constraint satisfaction at all. Our nurses are spread across the country on different hours, some work four days a week, state licensure limits which nurses can see which patients, and each region has a primary nurse with secondaries behind them. Nobody was going to hold all of that in their head reliably.
So the system does those calculations instead. It reconciles time zones, licensure, working hours, patient preference, existing bookings and nurse priority, then surfaces suggested slots the PES can confirm and book while the patient is still on the phone. Constraints act as defaults, not walls — overrides are always available, including booking a social worker instead of a nurse when SDOH needs surface mid-call.
We built the design system before we built the product for the same reason building was viable at all — the economics had changed. A few years ago that would have been overengineering, and the reason it isn't anymore is one of my most valuable takeaways from this project.
The team was three full-stack engineers who leaned backend, and me as the only product designer. Nobody to hand a redline to, nobody to absorb UI churn. By the old math, a full design system before an MVP is premature investment. You don't know what you need yet, half the components get thrown away, and a small team burns runway on polish before it has proof anyone wants the thing. That's the whole reason "ship the ugly version first" became default advice.
What changed is the cost of quality. With coding agents implementing against a defined system, a well-specified component is close to as fast to ship as an improvised one. The expensive part stopped being the building and became the deciding: what the component is, how it behaves, what it's called, what it does in every state. That's the part a model can't do for you, and it's exactly where a designer is already strong. And the reverse holds too: without a system to point at, an LLM will cheerfully generate a slightly different button forty times, every screen locally reasonable while the whole product is disjointed. A design system isn't overhead on top of AI-assisted development, it's what makes the output coherent.
So we built it first in Figma, using Figma MCP to connect Claude Code directly into the library, with Code Connect providing the mapping layer, so a component defined once is what the engineers actually get in code. The team spent far less time on frontend UI and could focus on backend and business logic, which is what they wanted to be doing anyway.
The path from there was conventional even if the tooling wasn't. Wireframes first, to iterate early with the clinical and operations teams on what they actually needed. Then pixel-perfect mockups built on the system, with interactive prototypes covering real use cases end-to-end for user testing.
Polish isn't vanity in healthcare. There's an enormous amount of information in a clinical model, it's easy to hit information overload, and a poorly designed platform is exhausting to work in even when the workflows underneath it are right.
Karoo Flow is in beta. A small cohort of real patients is being enrolled through the platform, running alongside the existing process rather than replacing it — the PES team still has the old stack underneath them while we find out what the system gets wrong with real people on the phone. Broader rollout is planned for later this year.
One enrollment used to touch five systems: ThoroughCare for the patient record, one tool for calling, another for texting, a spreadsheet where the work was actually tracked, and a calendar that knew nothing about any of it. Scheduling errors weren't edge cases either — double bookings and time zone mistakes were regular enough that the team had habits built around catching them.
A beta this size won't truly answer any of them. It answers the narrower question the MVP was scoped around: can a PES run an enrollment end to end inside a task system, with a real patient on the phone, without reaching for anything else. So far, yes.
Close the remaining 20% of PES coverage, and in parallel start bringing the clinical team in.
The second one is where the interesting problem is. "No patient is average" means that to truly serve one patient you need the functionality to serve all of them — you never know what a given patient will need — which makes "get the care team into the platform" a boil-the-ocean problem taken head-on.
We chose to focus on one pathway instead: GDMT, guideline-directed medication therapy. GDMT escapes the trap because it's self-encapsulated: a defined intervention, a defined patient subset, and only a handful of nurses involved today. Small enough to bite off, and it still gets real clinical workflows running in the platform so we can see how the model responds.
From there, fill out the rest of the care team workflows until everyone is in one platform and the third-party stack can genuinely be retired.
For an MVP scoped to PES enrollment you barely need any taxonomy — one workflow, four stages, six tasks, shippable with almost no hierarchy at all. But care team workflows branch in a hundred directions depending on a patient's diagnosis, its severity, their medications, and what happened last time, and retrofitting structure into a system that never had it is expensive. So the question was whether to build slim and risk not surviving contact with clinical work, or build hierarchy up front that looks like overengineering today and might turn out to be the wrong hierarchy anyway. We went back and forth for months, across multiple onsites. It was the most contentious thing on the project.
We landed in the middle. Pathways exist in the model even though only one is live today — enough structure that adding the next one is an addition rather than a rebuild, not so much that we were designing for workflows nobody had specified yet.
I still don't know if that was right. It's possible that supporting genuinely complex care team workflows means refactoring more than I'd like. That question doesn't get answered by reasoning about it, it gets answered by building the next pathway.
Get something in front of people much earlier.
What shipped as the MVP was really version five or six. By the time engineering started, the design had been through several rounds of definition — all best guesses rather than a working thing. What I'd change is fighting harder for the capacity to stand up a scrappy proof of concept early, even a thin one covering a couple of tasks.
Not because the design would have come out better, but because it's the only thing that would have answered the taxonomy question while it was still cheap to change. Point a rough prototype at a care team workflow — the ones most likely to break the model — and you find out. Instead, we reasoned about it for months.
The economics of this project changed underneath it: building was viable for a team this size because AI-assisted development made it viable, and the design system came first for the same reason. What I didn't do is apply that shift to how we learned. If building the real thing got that much cheaper, building a throwaway version to find out what we had wrong should have been close to free.