Standard users and HRM employees live in the same list but follow different rules: different editable fields, sync constraints, and a different system of record. The design makes the boundary legible instead of surprising.
Shipped and now used to set up access for new customers: who can see and do what, across a brand, its franchises and every location beneath them.
Almost every action in the platform runs through one question: is this person allowed? User Manager is where it gets answered. My job was to take a permission model that had grown tangled and make the correct access the obvious next step, not an extra one, the form only ever asking for what actually applied. It shipped, and it's now how the implementation team sets up access for new customers.
At a glanceLevel first, then a flow that branches to match it, so nobody sees a field that doesn't apply to them.
Read → 04 Made a three way rule legibleHierarchy, role and security level all have to pass, designed to be predictable instead of discovered.
Read → 05 Resolved duplicate emailsEmail uniqueness switched on against a live database full of clashes, without breaking a single user.
Read →When I took this on, a user's level was never actually stored: the system guessed it from their home location, and there was no explicit hierarchy sitting behind it.
I mapped this before I designed a single screen: every path a user takes through the system, created, assigned locations, moved between levels, deactivated and reactivated, worked out on paper and on a board until the flow made sense on its own.
The platform now stored hierarchy explicitly instead of inferring it from a home location, so I built five levels onto it: four paired a full and a restricted version, Location stood alone at the base, tied to a single home location. Moving someone between levels never meant touching it.
Mapped directly onto how the business is actually structured: Brand, HQ and brand-owned locations, Franchise, Location.
The full vs restricted split was deliberate: full means all locations, now and future; restricted means an explicit list that never quietly grows when a new location opens, because access should never expand without someone choosing it. A small distinction, but it matters a lot for a growing brand.
I also made management rights granular inside an assignment (franchise by franchise, you decide whether a restricted user can only access it or also manage it), so "restricted" never had to mean all or nothing.
The old create form asked for everything at once. I turned it around: ask for level first, then branch the rest of the flow to match it. A Restricted Brand user assigns whole franchises, full access to everything in them, now and future, then adds individual locations from elsewhere if needed; a Location user skips assignment entirely, since their one location already is their access. The tradeoff I chose was a longer, staged flow in exchange for never showing anyone a field that doesn't apply to them.
For the location picker I gave people three interchangeable views: Business Units, Hierarchy and a flat list, because a brand admin and a franchise manager picture their estate differently, and I didn't want to force either into the other's mental model. The messy cases are where the real decisions were: HQ selectable, pre active locations permission gated, discontinued ones view only behind a toggle only full access users ever see.
Access here is three separate checks that all have to pass at once. The logic wasn't mine to invent, but making it predictable to a human was, so I designed the flow around the rule rather than leaving people to discover it:
You must sit at an equal or higher level than the person you're acting on: a location user can't edit a franchise user, even on a shared location.
Your role must rank equal or higher. You can only assign roles at or below your own level, so permissions can't leak upward.
A numeric level shared with HRM. Equal levels can't view each other; higher can edit lower, never the reverse.
Small choices carry the rule: I had roles auto sort by rank and pinned the default role so it can never be removed; even "Remove All" leaves it. And I finally addressed the failure that started this whole section: instead of an empty modal, the person now gets a clear, specific reason why an action isn't theirs to take.
This was the last thing I designed on the feature, and my favourite problem on it: turning on email uniqueness against a live database already full of duplicates. We couldn't block everyone with a clash, and we couldn't ignore it either, so we went with a third option: tolerate, but quarantine.
Moving someone between levels can quietly break their access, so I gave it its own guarded flow (repick franchises, locations and a valid home location) and designed in who is allowed to move whom: only a brand user moves a brand user, a cross franchise move needs access to both, an employee never moves up to brand. Getting those rules to feel like guardrails instead of dead ends was the hard part.
Two more edge cases needed their own rules:
Standard users and HRM employees live in the same list but follow different rules: different editable fields, sync constraints, and a different system of record. The design makes the boundary legible instead of surprising.
Loaned access moved out of the permanent permission table and flipped to the destination location, surfaced with a badge, so a short term loan can never silently become permanent access — and if permanent access is later revoked while the loan is still live, the badge reverts rather than vanishing.
The design was mine end to end, though the product decisions and research were shared with a product manager, and I worked closely with the implementation team who use this tool to set up access for new customers. The through line was taming complexity: a genuinely combinatorial permission matrix, shaped into a short series of plain choices. If I point to one piece, it's the duplicate emails resolution: a data integrity problem the redesign itself created, solved without breaking a single existing user.
Delivered by a team across product, engineering and QA; I owned the design. Focuses on the design problem, model and decisions; adoption is described qualitatively and the design reached implementation; hard metrics weren't tracked.