TL;DR
- Context: Lead UX at a B2B packaging e-commerce scaleup.
- Problem: Requests (a lost parcel, a refund, an invoice correction) circulated in messages. The person reporting wrote to one colleague after another until someone picked it up.
- What I did: I designed a workflow layer in the platform that sends a task to the right team based on the type of problem.
- Result: More than 10 workflows in production and ~300 tasks a month.
Diagnosis
When I took over the project, the platform already had a task module in progress. But it was missing the most important part: getting requests to the right people. Someone reporting a lost parcel doesn’t know who will handle it, and doesn’t need to. It’s enough for them to say what happened. Writing to people one by one works poorly, because the more requests there are, the more time slips away on them. So we didn’t need a nicer task list. We needed a layer that takes a request by problem type and hands it to the team that deals with it. I put it inside the platform where the order already was, so nobody had to switch to another tool.
flowchart TD
subgraph Before["Before"]
A1["Reporter writes to person 1"] --> A2{"Reply?"}
A2 -->|"no"| A3["Writes to person 2, 3..."]
A3 --> A2
A2 -->|"yes"| A4["Someone finally picks it up"]
end
subgraph After["After"]
B1["Request: problem type"] --> B2["Automatic handoff to the team"]
B2 --> B3["The right team takes the task"]
end
classDef good fill:#e6f2ea,stroke:none,color:#1f4d33,rx:14,ry:14
classDef bad fill:#faeaea,stroke:none,color:#5f2626,rx:14,ry:14
classDef accent fill:#27272a,stroke:#3f3f46,stroke-width:1px,color:#fafafa,rx:14,ry:14
class A1,A2,A3,A4 bad
class B1,B2 good
class B3 accent
style Before fill:#fdf5f5,stroke:#e0c3c3,stroke-width:1px,color:#5f2626,rx:14,ry:14
style After fill:#f2f8f3,stroke:#c2dcc8,stroke-width:1px,color:#1f4d33,rx:14,ry:14
linkStyle default stroke:#a8a8b3,stroke-width:1.5px
What I did
- I expanded the task module left behind by a designer who had left the company. I added a workflow layer that routes tasks to teams.
- I designed task creation from an order or a specific line item. The task has context from the start, and nobody has to fill in an empty form.
- I designed views for two roles. A manager sees tasks by person, plus a separate “unassigned” group. An employee sees their own tasks grouped by workflow. I took inspiration from Notion databases and Jira and Asana boards.
- I fit it all into the existing platform, with no separate ticketing system.
Results
- More than 10 workflows in production (including lost parcel, invoice correction, refund).
| # | Workflow | Status |
|---|---|---|
| 1 | Lost parcel | in production |
| 2 | Invoice correction | in production |
| 3 | Refund | in production |
| 4 | Shipping status | in production |
| 5–10+ | other request types | in production |
- ~300 tasks a month in the first three months.
- Handling time measured for each process. With messages, this couldn’t be measured.
- Teams said they could easily see open cases and easily hand tasks over when someone suddenly went on sick leave. A request has its type, so it doesn’t get stuck in someone’s inbox.
The problem
Why were internal requests so slow?
The company made packaging to order. Every order goes through specification, quoting, production, shipping and billing, and something can go wrong at every stage. When a parcel got lost or an invoice had an error, the person who noticed (often from customer service) wrote to one colleague after another until someone took it on. They didn’t know who to go to, because there was no system. The more requests there were, the more time this took, and nobody could see what was open and who was working on it.
Why not buy an off-the-shelf ticketing system?
Because all the work already happens in the order-handling platform. A separate tool means another login, another place to check and more data to keep in sync. The system had to be simple and work where the order is.
My role / scope
- I was Lead UX and responsible for designing the task system and the workflow layer.
- Another designer sketched the basic task module before leaving, but without workflows. I was the one who added routing requests to teams, because I judged that’s where the most value was.
- I left the company before the next planned phase (a command palette and automatic assignment).
Process
- I started from a simple assumption: the person reporting doesn’t care who handles the case. They only care about what happened. I based the whole workflow model on that.
- I listed the request types that keep coming back: lost parcel, invoice correction, refund, shipping status. Each got its own workflow with a list of the information it needs.
- I designed task creation from an order, the role views and notifications. I kept checking them with the teams who were going to use them.
Key decisions & trade-offs
- Requests by problem type. The reporter picks “lost parcel” and doesn’t have to look for anyone in logistics. They don’t need to know people to report something, and that works no matter how many requests there are. In my view, this is what finally made the task module make sense.
- A system inside the platform. I skipped an external tool. We had to build and maintain it ourselves, but it works where the order is. Nobody switches between tools and nothing gets out of sync.
flowchart LR
O["Order view<br/>existing platform"] --> T["Task system<br/>built in"]
Alt["Separate ticketing system"] -->|"another login, switching tools"| O
classDef good fill:#e6f2ea,stroke:none,color:#1f4d33,rx:14,ry:14
classDef bad fill:#faeaea,stroke:none,color:#5f2626,rx:14,ry:14
classDef accent fill:#27272a,stroke:#3f3f46,stroke-width:1px,color:#fafafa,rx:14,ry:14
class O good
class T accent
class Alt bad
linkStyle default stroke:#a8a8b3,stroke-width:1.5px
- Tasks created from the order. A task is created where the problem is and already has the order data. Nobody has to retype it.
- Separate views for managers and employees. A manager distributes work and has the “unassigned” group at the top. An employee sees their own tasks grouped by workflow. The filters and dense layout are for people who work in this system all day.
- A simple MVP with fields in the description. To avoid burning the budget at the start, the information each workflow required (amount, account number etc.) was pasted as text into the task description. I have to admit it’s not an elegant solution. It was enough for the first version. I decided separate fields were worth adding only once we saw what people really needed.
A reconstructed sketch. The same pool of tasks in two views, for a manager and for an employee (inspired by Notion databases and Jira and Asana boards).
How it turned out
We rolled the system out quickly, and teams started using it quickly. In the first three months there were more than 10 workflows running and ~300 tasks a month. For the first time it was also possible to measure the handling time of each process. I left before the command palette and automatic assignment were rolled out, so I only write about what we shipped while I was there.
What I took away
- A task list isn’t enough. The module became useful only when requests started reaching teams on their own, without a person distributing them.
- Reporting shouldn’t require knowing people. The question “what happened?” works at any number of requests. The question “who should I write to?” stops working very quickly.
- It’s worth building a tool where people already work. In my view, an internal tool that makes you switch to another system eventually stops being used.
- The first version can be simple. Fields pasted as text were enough to see what people really needed, and only then build more.