Procurement Express
From customer request to code reality to measured outcome, without losing the thread.
Case Study auf Englisch
I came in as a product designer. The work pulled in discovery, analytics and design engineering, because the boundaries between them kept getting in the way of answering the real question.
What the backlog was actually saying
A portal holding 661 feature requests is not a list of things to build. I reconciled it against the codebase, against itself and against what had already shipped — duplicates collapsed, votes consolidated, and each surviving request sized against what the system would really take to deliver.
Some of what came out changed the question instead of answering it. The portal’s highest-voted request turned out to be built and merged already, sitting behind a switch. That moved the decision from whether to build it to whether it was safe to turn on — a different conversation, with a different owner and a much shorter path.
Recurring POs had been in the portal for six years, carrying 71 votes and about two sentences of definition. I built it into a product model from production behaviour, the constraints already in the codebase, earlier design work, the way the accounting systems it would have to meet actually behave, and what customers had described wanting.
The production data did not show one recurring-purchase behaviour. It showed several, which is the likeliest reason the request stayed ambiguous for six years: roughly one in ten active companies showed strong repeat-supplier patterns, and 49 had already built annual POs by hand, using month-based line structures in place of a feature that did not exist yet.
- Reconcile against realityVotes, duplicates and requests checked against the codebase and against what had already shipped.
- Find the question under the requestA feature ask is a symptom. The model underneath it is the work.
- Size it honestlyScope defined against what the system will actually take, not against the mock.
Define value before measuring it
I defined mobile activation around participation in a real purchase workflow rather than installs: identify an approver, create a purchase request, or approve one. That gave the measurement work a product question worth answering instead of a generic onboarding funnel.
Three systems each held part of the answer and none of them agreed, so the first job was to trace the data through the stack until one number held. I rebuilt the event model around that definition of activation rather than around onboarding completion, which is a far easier thing to record and a far weaker thing to know.
The loop runs Firebase to GA4 to BigQuery, and I wrote and ran the queries myself. Tightening the event contracts came before any of it was used to make a decision: a funnel number is only worth optimising once it means what you think it means.
- Activation is a product definitionNot a tracking one. What counts as value has to be decided before it can be counted.
- One source of truth firstThe measurement chain was made trustworthy before any funnel number informed a decision.
- Contracts before optimisationEvent definitions specified and verified end to end, Firebase through to BigQuery.
Two problems the signup numbers were hiding
Once activation was measurable, the acquisition picture separated. Organic mobile users reached activation at 12.70% within seven days. Paid users reached it at 4.23% — about a third of the rate. Signup volume had been answering a question about cost; activation answered a different one about whether the users being paid for ever reached the product’s value at all.
The onboarding phone capture had the same gap between present and useful. Only 48.4% of captured values passed a strict validity test, so a field that looked populated was around half unusable downstream. That evidence set the Android-first capture work, which was designed around what the data showed rather than around the form.
Neither of those is a shipped screen. Both changed what was worth optimising next, across acquisition spend, onboarding, CRM usefulness and the mobile roadmap — and on this product, at this point, that was the more valuable output.
- Separate quality from volumeAcquisition judged on whether users reach product value, not on how many signed up.
- Collected is not usableA validity test on captured data, not a completeness check.
- Evidence before designThe Android-first recovery path followed the finding; it did not precede it.
The design went into the product
The mobile work went into the React and Capacitor application. I specified event contracts and guardrails, scoped implementation tickets and followed the changes into the codebase.
The same is true on the web product. ProcurementExpress is an established Rails application with years of behaviour underneath it, so apparently small changes can cross controllers, models, policies, query objects and JavaScript. I trace that complexity early and let it shape the design, which is usually cheaper than discovering it during build.
I stay with the work through tickets, implementation, automated tests, review-app QA and production follow-up, alongside the engineering team. There is much less handoff when the person defining the behaviour can also inspect and change the product.
AI-assisted development helps me move through a large codebase faster. What matters more is that it shortens the trip from product question to code evidence to a tightly contained PR, without losing the reason the change exists along the way.
- Scope against the codebaseWhat should change is defined from customer evidence, product precedent and what the code actually does.
- Build where it makes senseDirectly in the React/Capacitor app and the Rails product, alongside the engineering team.
- Verify before calling it donePR review, regression coverage and manual QA, through to production.
A verdict set before the result
Success criteria go in before launch — cohort defined, threshold named — and then the 14- and 28-day readouts come from the actual data. The point was never to make the work look successful. It was to decide what the evidence supported next.
Invite Approver moved the invite rate from a 0.8% baseline to 9.75% at Day 28, more than twelve times what it had been, and still did not clear the 10% floor I had committed to beforehand. It is recorded as not validated, because the floor was set before the number was known. 84.09% of the users who chose to invite an approver went on to send the invite, so the form was never the blocker — the decision point sat earlier than the screen did.
Auth Recovery returned a 2.6pp lift over fourteen days, too small to claim as activation. Both of those are the system working rather than the work failing. A threshold that only holds when the result is flattering is not a threshold, and the readouts are how I keep hindsight out of the decision.
- Decide before readingCriteria set before launch, so the result cannot be reinterpreted afterwards.
- A big lift under its bar is still under its barTwelve times the baseline, held to the floor it was measured against.
- Ship, read, decideThe work continues through production measurement, not just implementation.
3×activation gap found between organic and paid mobile users — 12.70% against 4.23% in seven days, which changed how acquisition is judged
48.4%of captured phone values passed strict validation — a populated field was not usable data, and that set the Android-first capture work
661 requestsreconciled against the codebase, duplicates and already-shipped work, turning portal demand into product evidence
71 votesand six years of ambiguity turned into a researched product model for Recurring POs, grounded in production behaviour
- I came in as a product designer. The role expanded into discovery, analytics and design engineering because those boundaries kept getting in the way of answering the real question.
- The value is not that I can design and also code. It is that a customer request can travel all the way to a product question, to what the code actually does, to evidence, to shipped behaviour, to a measured outcome — without the thread breaking anywhere along the way.