Product ownership0→1Safety-sensitive workflowInteraction design

Beauty Client Card

Turning a safety-sensitive practitioner workflow into a working product.

A practitioner was running a safety-sensitive workflow on paper. I identified the problem, defined the product, decided what not to build, designed the workflow and the interface, set the rules the software would enforce, directed the implementation, audited it before anyone relied on it, and took it into real use.

TL;DR

The design problem wasn't digitising the workflow. It was deciding where software should take control, and where practitioner judgement should remain.

The product in use

Beauty Client Card is a mobile-first operational product used on a phone between clients and on a tablet in front of them. The practitioner opens a client, sees the one thing that needs attention, resolves it, and records the treatment.

Everything that follows is a decision about that sequence.

Three phone screens. The client list with a search field, show and sort filters and one summary line per client. A client profile headed “Ready for next visit”, with quick access to services, forms, attention flags and last visit. The add-treatment sheet with visit date, treatment area, service type, volume, style and notes.
The working sequence: find the client, resolve what needs attention, record the treatment.

The problem was not paper. It was the decision.

A paper client card is a competent filing system. It stores what a client declared, what was tested and what was done. What it cannot do is answer the question that opens every appointment: can this treatment go ahead right now, and what should I look at first?

That answer lived in the practitioner's memory and in the physical act of reconstructing it from a folder: which patch test covered which service, whether anything had been declared since, which of last visit's details should carry forward. Every one of those is a place where a busy day quietly degrades a safety decision. Digitising the forms would have preserved that exactly: the same information, faster to file, with the decision still unmodelled.

I deliberately did not build a CRM.

The first product decision was subtraction. One practitioner did not need booking, payments, deposits, marketing automation, a client portal or a configurable form builder. Each is defensible alone and fatal together: they turn a workflow that has to be fast between clients into software that needs administering, and every one of them competes for attention at exactly the wrong moment.

NOT BUILTBookingPaymentsDepositsMarketing automationClient portalConfigurable form builder

Scope stayed on client evidence, eligibility, treatment records and repeat visits, and stayed there under pressure, because a product like this attracts adjacent features continuously.

Where should software take control?

Every rule had to be sorted into one of three categories, and getting that sorting wrong in either direction breaks the product. Too little control and the software is a filing cabinet with a login. Too much and it starts overruling a trained professional on questions it has no basis to judge, which does not make anyone safer, it teaches the practitioner to work around the system.

I drew the line between a procedural requirement and a professional judgement.

An early practitioner session settled this. The earlier model produced false blocks: situations where software stopped progression based on a signal that was meant to inform practitioner judgement, not replace it. The evidence was unambiguous: a system that blocks on those signals is not stricter, it is worked around. Acknowledgement recorded against a specific signed submission gives the practitioner the prompt without taking the decision.

Two phone screens side by side. On the left a client profile carrying “No patch test” and “No General Client Record” badges, with the status “Needs consultation and patch test” and a “Complete documentation” action. On the right a submitted, signed consultation listing two attention items, with a checkbox confirming they have been reviewed with the client before treatment.
The same product, two kinds of decision: one the system settles, one it hands to the practitioner.

The interface should never claim more than the evidence supports

Two decisions came out of the same principle.

Eligibility belongs to a service, not a client

The first model held one patch-test verdict per client: valid, expired or missing. Simple, visible on every screen, and false. Coverage is not a property of a person, it is a property of a person and a service. A test for one product family says nothing about another, and one service in the range needs no patch test at all. That single status generated errors in both directions: it could make a client look eligible for a service they had never been tested for, and it could block a service that requires no patch test on the grounds of data that was never required.

I rebuilt eligibility around the question it should always have asked: does this client have valid coverage for the service in front of me? Requirement became a property of the service definition. Coverage became evidence produced by a specific passing test for a specific service. Unknown services fail closed, so a gap in configuration can never present as permission. Blocker messages name the affected service, because “patch test expired” is not actionable and naming the service is.

Then I removed the global status from the interface. Not relabelled. Removed. A client can hold a valid, an expired, a missing and an exempt service at the same time, so any client-level verdict is a claim the product cannot support. Deleting a summary people found convenient is harder than qualifying it.

An interface that states something false with confidence is worse than one that says less.

Every surface answers one question

Once eligibility was truthful, the interface had to be too. Each surface got exactly one question to answer, and was not allowed to answer any other.

Client list
Which client do I open, and is there one thing that needs attention?
Today
What should I do next with this client?
Forms
What is the documentation state, and what action does it need?
Flags
What needs review before treatment?
History
What was done, and when?

The client list carries one operational summary per row, chosen by a deterministic priority: unresolved review, then documentation awaiting completion, then expired documentation for a service the client actually uses, then last visit. One badge carries the category and one line carries the specific reason.

There is no global “Ready” state. A quiet row is the normal case, because “Ready” would be a per-service claim the list has no way to make. Services a client has never had stay silent rather than generating warnings about documentation that was never needed. Otherwise, every profile fills with theoretical gaps and real signals stop being read. And every surface consumes the same resolved state instead of inventing its own, so the list, the profile and the treatment workflow cannot disagree about the same client.

Four phone screens for the same client, one per tab. Today, showing current status and quick access. Forms, listing client documentation and per-service states such as “Patch test valid” and “Awaiting completion”. Flags, listing attention items per service. History, listing past treatments with dates and service types.
One summary per row, one question per surface, and silence as the normal state.

Evidence moves through the workflow

A safety decision is only as good as the evidence attached to it, and re-typed evidence is not evidence. Submitted consultations are immutable: a correction creates new evidence rather than rewriting history, because the question a year later is not what a client says now but what she declared at the time of that treatment. The current profile is derived from the applicable evidence rather than kept as a second editable copy that can drift away from what was signed.

Confirmation is proportionate to the change. Before a treatment the client is asked whether anything has changed; a “no” records a lightweight confirmation and a “yes” creates new signed evidence. Making every visit a full re-completion would have been safer on paper and abandoned in practice. Each treatment then retains the exact evidence it relied on, so history is operational evidence rather than an archive of what happened.

Repeat visits start from the previous record rather than a blank form. Copy Previous carries forward the setup that legitimately repeats, and clears the information that belonged to a specific appointment instead of copying it blindly. Where a service has nothing meaningful to carry forward, the action does not appear at all.

Three phone screens in sequence. Treatment history for a client. A past treatment record showing date, service type, style, curl, products used and notes, with actions to view the submitted consultation, edit the treatment or copy it to a new treatment. A new treatment form carrying forward the service setup with the visit date advanced and the previous notes cleared.
What repeats is carried forward. What belonged to one appointment is cleared.

The audit changed the system, not just the bug

Before anyone relied on this product, I put it through a readiness audit against its own safety promises. It returned twenty findings, two of them blocking. The serious one was exactly the class of failure the audit existed to find.

20

findings

2

blockers

8 / 8

services covered after the correction

  1. FINDING

    Four services accepted a declared previous adverse reaction and stored it correctly. Nothing in the interface indicated that the answer required review.

  2. ROOT CAUSE

    The safety surface recognised question keys from an explicit list, and those four services used names that were never added to it. Two mechanisms shared no vocabulary, so a question could raise a rule and reach no surface anyone looks at.

  3. CORRECTION

    Adding four missing names would have fixed the symptom. I treated the disconnection itself as the defect, and made recognition a property the whole model has to satisfy.

  4. PROTECTION

    Per-service regression coverage, plus a guard that reads the configured safety rules and fails the build when a rule exists whose answer the flag model would not recognise. The failure class could no longer be reintroduced without the guard detecting it.

A second blocker exposed an unsafe environment boundary, so I separated development and production workflows before real data entered the product.

Evidence contradicted the product model, so I changed the model rather than the screen.

Two phone screens of consultation records. On the left, two attention items including a declared previous reaction to beauty products, with an unchecked confirmation that they have been reviewed with the client before treatment. On the right, the same kind of record after review, reading “1 attention item reviewed” above the same declared reaction.
The answer was always stored. After the correction, it reaches the surface the practitioner relies on.

A coherent interface needed a small system behind it

I also built the UI system behind the product: reusable Figma components, design tokens and a corresponding implementation layer covering the states, controls and patterns the workflow needed. The goal was not to create another design-system project. It was to make a product I was evolving quickly remain visually and behaviourally coherent.

Three panels. A colour token table naming ink, surface, accent, success, warning and error values. A component sheet showing input, search and filter, badge, toggle, checkbox, radio, section row and tab bar variants and states. The product screen those components assemble into.
Enough UI infrastructure to keep the product coherent as it changed.

I took it into real use

Done did not mean merged. Production releases passed explicit database, access-control and authenticated workflow checks before practitioner acceptance, because the cost of a mistake in an operational tool is not a rollback.

The product moved from validation into controlled practitioner use, on the devices and inside the workflow it was designed for, and it kept evolving after that. New capability has been staged into production deliberately, one piece at a time, with anything whose rules were not yet settled left unavailable rather than shipped and hidden. Recognising a treatment did not mean the product was ready to offer it safely.

Two phone screens showing the everyday treatment path: a client profile in the “Ready for next visit” state with the treatment action available, and the add-treatment sheet part-completed with visit date, treatment area, service options and notes.
The product in the hands it was designed for.

AI accelerated delivery. It did not define the product.

AI agents executed much of the implementation inside product boundaries I had already defined: the scope, the rules, the interaction model and the acceptance criteria existed before any agent wrote code. Work was handed over in bounded units, validated against intended behaviour and reviewed before release.

Nothing in that arrangement could redefine a product rule, bypass eligibility, alter signed evidence or make the final treatment decision. The same boundary is built into the product itself: a dictated visit can only become a record marked as needing approval, and the practitioner approves or discards it. Product and release authority stayed human.

AI proposes. The system validates. The practitioner decides.

Interface evidence shown in this case study uses fictional data from the test environment. No production client data is shown.

Working on a complex product, platform or design system?

I'm interested in Staff and Principal Product Designer roles where complex product decisions, systems thinking and technical depth need to work together.