Airports run hundreds of vendors: restaurants, shops, and services. Every menu, price, and availability update eventually appears on a passenger facing website. When that data is wrong, passengers notice. A price that doesn’t match the till. A shop showing open three hours after it closed. An item that’s been on the menu for weeks after it was removed.
This project was about redesigning the internal system that manages all of that data. It’s the kind of system nobody thinks about until something goes wrong.
I led the design end to end, from the overall system architecture to vendor workflows, Ops workflows, and manager governance. The biggest design decision, though, happened before I opened Figma. The client had asked for a faster data entry tool, but after looking at how the operation worked, it became clear that improving the interface wouldn’t solve the real problem. The workflow itself needed to change.


Background
GrayMatter provides airport vendor management software across multiple airports in India. Every restaurant, duty free shop, coffee kiosk, and retail outlet shown on the passenger website is managed through this system.
At the time, a team of around ten Ops members handled updates for more than one hundred vendors. Vendors emailed their changes. Support converted those emails into tickets. Ops entered the changes into the backend. Managers reviewed them before they reached the website.
Each handoff added time and another opportunity for mistakes.
More importantly, the workflow wasn’t going to scale as more airports came on board. The Ops tool was essentially a ticketing system. Changes arrived by email, were verified through email threads, and were entered into the backend by hand.
One ticket. One change. One form at a time.

Problem
The original brief was to build a better data entry tool for the Ops team. At first, that seemed reasonable. The existing workflow was slow, and almost every vendor update passed through Ops before reaching the passenger website. Improving the interface felt like the obvious next step.
But after mapping the workflow, it became clear that data entry wasn’t the real constraint.
Every change, whether it was a new product, a price update, or correcting a typo, still depended on the same Ops team. A faster interface might reduce the time spent entering each request, but it wouldn’t reduce the number of requests they had to process.
The question became: How do we reduce the amount of work that depends on Ops in the first place?
That changed the direction of the project. Instead of making Ops faster, we started looking at how the workflow itself could change.

What I did
Over 3 months, I designed the end to end experience covering every step between a vendor requesting a change and that change appearing on the passenger website.
My role wasn’t just designing workflows. It was understanding whether the requested solution addressed the underlying problem and deciding what the system needed to support.
I worked closely with the PM and domain expert throughout the project. They regularly met with the Ops team, brought back feedback, and validated new ideas through working sessions.
That created a tight feedback loop where each iteration was shaped by operational realities rather than assumptions. As the scope expanded, a junior designer supported the Figma execution while I focused on the overall system design and product decisions.
The resulting system had three clear roles: vendors owned data entry, Ops verified submissions, and managers governed the approval rules.
The faster-horse trap
GrayMatter approached us with a clear ask: “Build a faster data entry tool for our internal Ops team.”
They provided a dev server prototype that mirrored their existing workflow. It was essentially a ticketing system for everything. Whether it was a new shop launch or a typo fix, an Ops member had to enter the update.
The assumption was straightforward: if we made the interface faster, Ops could process more requests.
But the numbers suggested otherwise. Even at a conservative 2 to 3 updates per vendor per week, that’s 200 to 300 updates every week for a 10 person team. A better interface might reduce the time spent on each entry, but it wouldn’t change the fact that internal labour was the constraint.
I raised this with the PM, who brought in the domain expert. We worked through the workflow together and confirmed that we were solving the problem at the wrong level.

The pivot
I proposed reframing the project around vendor self service rather than internal data entry. The idea was straightforward: move data entry closer to the source, introduce controlled approval before anything goes live, and separate who provides the data from who verifies and governs it.
The proposal moved operational responsibility from the airport’s internal team to the vendors themselves. That made the governance questions unavoidable from the start. The PM and domain expert took the proposal to the Ops team, worked through their concerns over a few days, and came back with approval to proceed.

Two principles drove the work that followed.
Move data entry closer to the source.
Vendors know their own products better than Ops ever will, so they should own the input.
Introduce controlled approval before going live.
Not every change carries the same risk, so approval should match the stakes.
Together, these separated three responsibilities that had been collapsed in the old workflow: origin belonged to vendors, execution to Ops, and authority to managers.
The Constraints
Three constraints shaped the architecture more than any individual design decision.
Compliance was airport specific.
The same field change, such as a price update or category change, could be routine at one airport and subject to additional requirements at another. The system couldn’t assume a single compliance model. Each airport needed to be able to define its own rules.
I was one layer removed from the end user.
We rarely spoke to the Ops team directly. The PM and domain expert ran the working sessions, brought back feedback, and helped validate the designs. That meant each design decision had to be clear enough to survive that translation. If a concept needed me in the room to explain it, it wasn’t ready.
We couldn’t fully automate every change.
Some changes, such as price increases above a threshold or new product creation, had caused live site problems before that only a person had caught through context. Automating those decisions would have meant trusting the system with decisions Ops had previously needed to catch themselves.
So we designed for automation where there was enough confidence, and approval where there wasn’t.
Iteration 1 — The 45/5 problem
A recurring scenario exposed the first real flaw in the new workflow.
A vendor uploads 50 products. 45 are valid. 5 have errors. What should happen to the submission?

The first version kept the vendor and Ops roles separate. Vendors submitted their changes, while Ops reviewed them before anything went live. Ops could verify a submission, but they didn’t edit the vendor’s data.
This made the ownership model clear. Vendors owned the data. Ops verified it. Managers stayed out of row level work.

But the Ops team kept surfacing a deeper question: if vendors could catch their own errors before submitting, why should those errors reach Ops at all?
We didn’t solve that in this iteration. We parked it and moved on. It came back later.
Iteration 2 — Risk-based approval
Self service worked, but it moved the bottleneck rather than removing it. Every submission still landed in an Ops Manager’s queue, whether it was a new product launch or a typo fix.
Not every change carries the same risk, so not every change should require the same approval. A risk based framework, with different routes for different types of changes, became the working hypothesis we took into sessions with the Ops team.
Defining the thresholds was the longest part of the project. Categorizing high risk and low risk changes looked straightforward on paper, but the Ops team had years of experience with which changes had caused problems on the live site. That history shaped where the lines were drawn.

One example changed how we handled price. I’d initially put all price changes in the same bucket. The domain expert pointed out that airport retail in India has specific MRP listing rules. A price change isn’t just commercial. If the displayed price differs from what is filed, it can also become a compliance issue.
That meant price changes needed manager approval regardless of size. It also led to price becoming a first class field in the final Compliance Rules screen, with its own threshold controls.
Managers initially pushed back on the framework. Three concerns came up:
“How do I know what’s going live?”
“What if Ops approves something wrong?”
“A vendor makes a mistake, a passenger complains. Who answers for that?”
The audit log addressed the first. Manager owned thresholds addressed the second. The third was more fundamental. The framework wasn’t changing who was accountable. It was changing who handled routine work.
Managers still set the rules. Ops worked within them.
That got managers out of routine approvals and gave Ops authority that matched their role. But one question kept coming up: whose risk matrix was it?
The thresholds reflected one airport’s vendor relationships and compliance context. The framework was working. The ownership of those rules wasn’t.
Iteration 3 — Transparency at the moment of submission
Even with better workflows, vendors still lacked clarity. Why was something rejected? How long would approval take? Was anyone looking at it?
I designed a transparency banner that appeared before submission, not after. It showed the risk level, what the submission required, and the expected SLA before the vendor submitted the change.

This helped address a different kind of friction. A fast workflow with no visibility can still create support tickets. Giving vendors clear expectations before they submitted reduced the need to chase updates later.
But the banner only answered what would happen next. Vendors still couldn’t see what had happened to past submissions. Ops couldn’t trace who approved a change or when it went live.
The system was becoming more transparent at the point of submission, but there was still no clear record of what happened afterwards.
What got shipped
Across the iterations, three things became clear.
Validation belonged with the vendor, not Ops.
Approval thresholds belonged with the airport, not the product.
Transparency needed to be part of the system, not just a banner at submission.
Those three decisions shaped the architecture of what shipped.
The vendor catches their own errors
In the iterations, bad data reached Ops and Ops dealt with it. In the shipped product, bad data doesn’t reach Ops at all.
Two paths make this possible: one for bulk changes and one for individual products. Both follow the same rule: validate before submit, not after.
For bulk changes, vendors upload a CSV. The system parses every row, surfaces errors inline, and blocks submission until they’re resolved. Vendors can edit in place, add rows, or delete rows they don’t want to send. Error rows are highlighted, but every row remains editable, not just the ones with errors.


For single product changes, vendors select a product, see the current live data in a form, make their changes, and the form validates as they type. Nothing ambiguous waits until after submission.

The 45/5 problem from Iteration 1 didn’t disappear. The work moved to the right person. The Ops verifier who was previously looking at a 50 row submission with 5 errors became the vendor looking at those same rows before submitting.
The principle stayed the same. What changed was who did the work.
Before you submit, you know what happens
Vendors don’t find out what happens to their changes after submission. The preview shows the outcome and approval path before they commit.
The preview screen shows exactly what will happen to each change: which rows go live immediately and which ones go to Ops for review. The same applies to individual changes: one product, one set of edits, with the same visibility.


The vendor can make an informed decision at the point of submission, rather than finding out what happened only after the change has been submitted.
The airport owns its rules
Managers decide which changes need approval and which don’t. Compliance Rules is where they set those rules.
For price and discount changes, managers can set a threshold using a percentage, an absolute amount, or both. For other changes, such as category changes, new products, and availability, they decide whether the field needs approval at all. Fields like product name go through automated checks instead.

Every airport starts with sensible defaults based on the risk matrix from Iteration 2. An airport that trusts those defaults can keep them. One with stricter requirements can tighten them. One with more vendor autonomy can loosen them.
The risk based framework stayed the same. What changed was who owned the rules.
Ops reviews, vendors fix
Ops can approve or reject. That’s it. There are no fields to edit and no way to fix a vendor’s submission from the review screen. If something is wrong, the only path forward is to reject it with a reason and send it back to the vendor.
Bulk and individual submissions sit in different queues because they require different review behaviors. Bulk reviews are designed for scanning changes across many products. Individual reviews are designed for focused, field level verification.
The bulk queue shows one row per submission. Clicking a submission opens the full table of changes as a diff: what was there before and what the vendor wants to change it to.


The individual queue shows one row per product. Clicking a product opens the current live data alongside the proposed changes, using the same diff pattern but scoped to one product.


When Ops rejects a submission, they select a reason from a dropdown configured by the manager. The reasons are specific enough to be actionable without making Ops think too hard about which one to choose. Optional notes sit below.
The vendor sees why it was rejected, fixes the issue, and resubmits.

Ops verifies the data. The vendor owns the fix.
Atomic approval, made visible
The principle from Iteration 2 carried over. If a submission contains even 1 change that needs approval, the whole submission waits. It’s all or nothing.
The shipped product introduced new field types such as availability toggles, schedule changes, and discount thresholds. Each has its own risk classification, which is visible per row in the review screen.

A vendor submitting a price increase alongside an availability toggle sees both classified individually. The price increase waits for Ops. The availability toggle would normally go live immediately, but because it’s part of the same submission as a gated change, it waits too.
When Ops approves, both go live. If Ops rejects, neither does.
This is why the preview screen flags gated rows before submission. A vendor who can see that one row will hold the batch can split the changes into separate submissions rather than having the entire submission wait behind a single review.
Nothing goes untracked
“What happened to my submission?”
“Who approved that price change?”
“When did this go live?”
These were questions that previously required a meeting to answer. The audit log makes that history self serve.
Every change in the system is logged: who made it, when, what changed, and whether it needed approval. Vendors see their own history. Ops sees everything in their remit. Managers see everything.

The log separates changes that went through Ops from changes that went live automatically. Vendors and Ops can see the full picture, including changes that the system approved automatically rather than just the ones that went through manual review.
Clicking any row opens a detail sheet with the full field level history of that product.
The log didn’t change how the system worked. It changed how much people trusted it.
Results
3 months of design, followed by ~3 weeks of post launch tracking through system logs and Ops interviews.

The numbers showed improvements in turnaround time and the amount of work reaching Ops. The interviews also surfaced a less measurable change: the team had more visibility into what happened to each change. They could trace decisions, see who was responsible, and understand what the system had handled automatically. Tracking ended after 3 weeks as we moved on to another engagement with the same client.
The audit log turned “trust us” into “check for yourself.”
Key Takeaways
The interface isn’t always the bottleneck. The client’s request assumed it was. A quick check of the update volume against the team size showed otherwise, and that observation reframed the entire project.
Edge cases are product decisions. Rejecting a batch, accepting it, or editing it each moves the work to a different person. None of those choices are neutral.
Rules work better when the people accountable can control them. Managers used Compliance Rules because the thresholds were theirs to set, not because we had written a better policy.
Measurable isn’t the same as meaningful. We tracked time savings because they were measurable. What mattered more to the Ops Manager was traceability, and we would have missed that if we hadn’t asked.