CASE STUDY 02Health-tech2025
Series B health-tech dashboard.
This is a care-coordinator dashboard at a Series B remote-patient-monitoring company — an internal ops tool for the team that triages device-generated alerts between patient-worn devices and the clinicians who own the care plans. The inherited v1 was structurally working and operationally drowning. We rebuilt the queue end-to-end across six two-week cycles; twelve weeks to GA.
§01Index
Project facts.
- YEAR
- 2025
- SECTOR
- Health-tech · remote patient monitoring
- SCOPE
- Operator-dashboard redesign — alert triage queue, patient-envelope grouping, inline row actions, operator design system
- DURATION
- 12 weeks to GA · six two-week cycles
- TEAM
- One designer (us), two engineers, one care lead consulting weekly, eight coordinators interviewed
- ROLE
- Product design lead · design-system authorship · engineering partnership on the row-level commit model
- OUTCOME
- 12 weeks to GA. 60% drop in support tickets in the first month after GA.
§02Brief
What we walked into.
We picked up a dashboard that worked the way a v1 built by an engineering squad with no designer works: alerts arrived in it, alerts could be acted on, and the work felt nothing like the screen. Coordinators triaged eighty to a hundred and twenty alerts a shift against panels of two hundred and fifty to four hundred patients, with a sixty-second decision tree on each alert. The alert table was the binding constraint — it took roughly 40% of the coordinator’s screen and roughly 0% of their attention.
Alerts rendered as a flat, arrival-sorted table with no priority signal at the row level; the three primary actions lived three clicks deep inside a row-detail drawer; and the row’s visual state did not change after the drawer closed, so coordinators couldn’t tell whether the commit had landed. One coordinator’s phrase in discovery was “the screen is thinking” — in a job where the human has to be the one thinking. We set out to make the dashboard render the work the way coordinators were already mentally organizing it: by patient, by severity, with action under the cursor, in a row that confirms.
§03Decisions
What we changed, and why.
Four named decisions, in the order we made them. Each names the design change, the engineering reasoning that made it viable, and the tradeoff we accepted.
DECISION 01
Replace the flat alert table with a severity-banded alert ladder
The flat, arrival-sorted table became a vertically-stacked ladder: four bands — critical, high, routine, informational — each a contiguous region with its own subtle color anchor and a live count in the band header. Within a band, alerts sort by time-since-arrival; across bands, severity wins. The point is information scent at row zero. A glance at “3 critical · 17 high · 41 routine · 64 informational” tells a coordinator where the shift is before they read a single row, and the critical band’s hue is tuned to diverge sharply enough that a critical alert reads as different even at the edge of vision.
The ladder only works if the band assignment is already correct by the time the row paints, so severity scoring moved off the request hot path entirely: a background worker recomputes the score on each device event and writes a denormalized band assignment back to the row, and the queue renders server-side from the precomputed column under 200ms cold on a 1,500-alert queue.
The tradeoff was honest. A vocal cohort of coordinators who took pride in catching low-priority drift felt the informational band was buried below the fold, and they were right. We held the call anyway, because priority signal was the binding problem and saved views (cycle 4) would address informational drift. Every band is collapsible but starts expanded on first session, and the band header always shows live counts so nothing is invisible.
DECISION 02
Replace the inherited 16-column grid with an 8-column reading grid for the queue
The v1 used a 16-column layout grid borrowed wholesale from the company’s marketing and operations tooling, which made the queue feel dense and wire-framey — too many columns, too many vertical rules, too much chrome between the row’s payload and the coordinator’s eye. We rebuilt the queue on an 8-column reading grid sized to a single-monitor reading width, with the row payload centered and action affordances aligned to the right edge of the content column.
Fewer columns meant each row reads as one chunk instead of seven cells; coordinators reported the queue stopped feeling like a spreadsheet, which is the chunking effect speaking. The engineering side was less dramatic — the queue is a server component reading from the same denormalized row that drives the ladder, so the grid swap was a render-time change without a data-model change — which is why we could land it in a single cycle.
We lost density on the device-inventory page, a secondary admin view care leads visit roughly once a week. They asked for an opt-in dense view; we deferred it to post-GA. Worth it because queue volume was binding and inventory was not.
DECISION 03
Hoist primary actions into the row; demote the detail drawer
v1 buried Call, Escalate, and Dismiss inside the row-detail drawer — three clicks deep from the row, with no in-row confirmation that the commit had landed. We pulled those three actions to the right edge of every row as labeled buttons with C / E / D keyboard shortcuts; a single overflow menu carries everything else. The drawer survives as optional context, not as the action surface.
The engineering shape is React Server Actions with optimistic UI behind idempotent endpoints keyed by a client-generated ULID: the row paints the post-action state — severity strip dim, status pip flipped, last-action chip set — within roughly 80 milliseconds of the click, and replays of the same action id are no-ops at the database level, so v1’s double-click pattern is structurally a single commit. A five-second undo toast confirms. The “did that save?” question stops being a thing a coordinator has reason to ask.
The tradeoff was real: we deprecated the keyboard-power-user shape (Tab into drawer, Enter to act) the most senior coordinators had built around, and asked the team to learn the new shortcuts. We shipped a one-time tooltip and the team adopted C / E / D inside the first cycle.
DECISION 04
Group same-patient alerts inside a patient envelope
Device bursts produced the same-patient-three-alerts case constantly, and v1 rendered each as a discrete row. Coordinators opened the same chart twice, sometimes called the patient twice, sometimes escalated three things that were one thing. We collapsed same-patient alerts into a patient envelope — a common region, a thin left rule, the patient’s identity in a named accent slot, and the alerts themselves as a nested mini-ladder. The unit of attention became “this patient, these alerts,” not “this alert, who is it about?”
Bulk actions at the envelope shipped in cycle 5; what made them viable was a chunked server action that splits the envelope’s alert ids into chunks of eight and paints per-chunk progress, so a 50-alert bulk dismiss is sub-150ms to first row paint instead of v1’s 1.2-second blocking pattern.
The tradeoff: for the majority case where a patient has exactly one open alert, the envelope’s header costs one extra row of vertical height versus v1’s flat row. Cycle 3 shipped a no-header compact rendering for single-alert envelopes that recovered most of that density, and the alert-frequent cohort was producing most of the cognitive load anyway.
§04System
The operator design system.
The operator system is a distinct grammar from the studio’s marketing system — denser, cooler, built for an eight-hour shift on the dim external monitors care leads actually use. The load-bearing tokens are the four-step severity ramp anchored by a critical hue tuned to diverge sharply from the rest of the page; the 32-pixel density unit that the alert ladder, the patient envelope, and the inline action row all align to; the type ladder that puts patient name and severity on the F-pattern’s two horizontal strokes; and the component chip set — severity strip, last-action chip, status pip — that makes those three pieces a coherent family rather than three custom one-offs.

§05Screens
In situ.
Three screens, in the order a coordinator meets them. The first is the queue at rest — start of shift, band-header counts already telling the coordinator where to begin. The second is the queue under load: roughly two hundred open alerts, the ladder doing the visual lifting that v1’s flat table refused to do. The third is the moment that pays for everything else — a coordinator inside a patient envelope, the inline actions a keystroke away, the audit-log peek showing the alert’s prior history without a route change.



§06Cycle
Two-week shipping cadence.
Twelve weeks. Six two-week cycles. No calendar slippage. Cycle 1 was discovery and a clickable prototype of the alert ladder built against a thin replay of real device-event data; cycle 6 was GA with a chunked-action fix and an accessibility verification pass. Between them, the dashboard rebuilt itself in public, two weeks at a time.
- Cycle 01Discovery — eight coordinator interviews, two care lead interviews, clickable ladder prototype against replayed device data.
- Cycle 02Alert ladder into production behind a feature flag; inline row actions replace the drawer for two pilot coordinators.
- Cycle 03Patient-envelope grouping ships. Severity scoring moves off the request hot path; ladder renders server-side under 200ms cold.
- Cycle 04Saved views, C / E / D keyboard shortcuts, and the discoverable shortcut sheet.
- Cycle 05Bulk actions at the envelope, five-second undo on dismiss-with-note, audit-log peek. One regression: 1.2s UI block on 50-alert bulk dismiss.
- Cycle 06GA — chunked-action fix, full rollout, accessibility verification pass. No calendar slippage.
§07Outcome
What changed for the operator.
Support tickets dropped 60% in the first month after GA, driven primarily by the alert-ladder redesign and the row-level commit model: coordinators stopped escalating tickets they could now resolve in place, and they stopped filing “did that save?” tickets because the row paints the post-action state within 80 milliseconds and the audit-log peek made post-hoc verification one keypress away.
The pre-redesign ticket volume was concentrated in four patterns — action-commit doubt, wrong-patient escalation, undifferentiated urgency, and lost filtered views — and the redesign retired all four structurally, in roughly that order of share. The team also measured a convergence in escalation rate toward the protocol-expected band inside the first two weeks post-GA; coordinators stopped escalating routine alerts to clinicians as a hedge against an absent priority signal.
§08Notes
What we’d revise.
- Note 01
Saved-view sharing across coordinators got cut from the GA scope. The workaround that appeared inside the first week — coordinators emailing each other queue URLs — was a clear signal we’d cut the wrong corner. v1.1 ships it; in hindsight we should have held the line and landed it in cycle 6.
- Note 02
The audit-log peek shipped without a strong opinion about how coordinators should read prior clinician decisions. A clinician flagged the obvious risk after we shipped — coordinators second-guessing triage they were never meant to second-guess — and that conversation should have been part of the peek’s design spec, not an afterthought we caught in post-GA review.
- Note 03
The dense-view escape hatch for the device-inventory page shipped as “opt-in, post-GA,” which in practice meant care leads kept tab-pinning the old layout. Naming an explicit migration path inside the GA cycle would have closed it; “we’ll get to it” is a deferral, not a decision.
Want yours to be the next case study?
Tell us what you’re building. We reply within one business day.