Multiple
Rates of Pay
One employee, more than one rate — without the manual overrides.
The canonical case: an employee who washes dishes at $10 and also hosts at $12. Running payroll at two rates was time-consuming and required many overrides — the only way to do it on the platform. Multiple Rates of Pay replaced that with something native.
A single rate touched the whole product. So did this.
Because a single rate of pay already reached across job costing, the user detail page, payroll, and printed checks, adding multiplerates rippled everywhere too. It was a direct request from one of TriNet’s largest customers — and I’ll be honest about how it reached me: I joined mid-way through the specification, so some decisions were already made without design input, and it moved forward on a single client’s use case without external user validation.
Find every place a rate lives — then extend it naturally.
Working alongside the product owner, we did a page-by-page audit, determining all the places in the current UI where changes were needed — job costing, the user detail page, payroll, printed payroll checks. The individual’s detail page already showed a single rate, so the interesting question was where multiple rates should live so it felt like a natural extension rather than a bolt-on.
I designed the “Add Rate of Pay” pattern to sit right inside the familiar Employee Change Request flow — a primary rate, then additional rates, each with its own job code, work location, and department — built to hold an essentially unlimited number of rates, since we couldn’t predict how customers would use it.
Fine one at a time. Catastrophic for setup.
Job-costing codes had to be added one at a time, each carrying a full profile — title, short title, description, regular/temporary, EEO-1 category, FLSA status, tipped, project ID. Fine for a tweak; catastrophic for initial setup, which could mean hundreds of codes.
So I added a Bulk Upload entry point and designed the upload as a guided wizard — Attach File → Match Headings → Review File → Import File— with drag-and-drop CSV, a heading-matching step, and a Verify Upload review table before anything commits. I didn’t reinvent the interaction: another designer had a bulk-upload model elsewhere in the app, and I reworked her patterns for our case — which is exactly what a design system is for.
Merge by SSN. Fail loudly, not silently.
The genuinely hard part was error handling — especially because a single employee could carry multiple rates across multiple lines. Working with the dev team, we gave each rate its own line and merged lines back to one person by SSN, then mapped the whole upload against what was already in the system and threw clear errors on any no-match — so users could fix problems instead of silently importing bad data.
Bulk upload saves users a lot of time if done correctly — so guide them to do it while introducing as few errors to the system as possible.
Align the teams before kickoff, not halfway through.
MRoP was fully specified across all its touchpoints — job costing, user detail, payroll, printed checks — with a bulk-upload path that solved the SSN-merge and error-handling problems. I’ll also name the soft spot, because it’s a real lesson: it moved forward on a singlelarge customer’s request, without testing beyond that one client. A reasonable bet given their scale — but a bet. With that many cooks in the kitchen, I’d align everyone before kickoff next time.
Honest ending: I left before implementation, so there are no measured adoption or efficiency numbers to quote here.