A user‑experience walkthrough of the asynchronous ingestion pipeline — every state, every step, and every action a user can take. Written for the UI/UX & frontend design session. No backend detail — only what the user can see and do.
A user uploads a raw delivery file. The system turns it into a real Inbound Delivery by running it through a pipeline of 10 steps. The whole thing is asynchronous and live: the user submits and then watches progress update on its own — one upload is shown as one card.
Along the way the user can pause at any point, resume from where it paused, and if a step finds a problem with the data, fix it and retry. Near the end there is a grace period — a safety countdown where the user can stop the upload if they spot a mistake — before the delivery is actually created. When it finishes, a Delivery (and, when there is leftover stock, a generated Order) is created and the user gets direct links to open them.
One mental model for the designer: a card = one upload; the card shows where it is (a row of step bubbles + a status), and offers the actions that make sense for that status.
The card always shows exactly one status. It drives the colour, the headline, and which buttons appear.
Submitted and waiting to start. Nothing has run yet.
Actively working through the steps. Progress and the current step update live.
All preparation is done and a countdown is running before the delivery is created — the user's chance to stop a mistaken upload before it's committed.
Paused by the user. It stays exactly where it was and waits. The headline shows where: e.g. “paused before Create delivery”.
A step found a problem with the data (e.g. an unknown product, a duplicate key). The card shows the exact items that failed.
The delivery was created, but it produced an Order that still needs to be filled in. The ingestion waits here and finishes on its own (→ Succeeded) once that order is completed — no action needed to push it along.
The delivery was created (and any generated Order is now completed). The card carries links to the created Delivery and that Order.
A restart does not create a separate record — the same card simply bumps to a new attempt and keeps the previous run in a collapsible “Previous attempts” block.
Ten steps, left to right. Each one shows as a bubble that fills in as it completes — ✓ done (with how long it took), ✗ failed, a highlighted bubble while running, or a grey number for a step not yet reached. The three outcomes the UI needs to render:
Plain language: what each step is for, exactly what the user sees on the card as it runs, and where a step can fail.
Reads the uploaded file and pulls out the partner and the list of items with their keys.
When the upload contains archives, the individual files inside are extracted so the rest of the pipeline works on real files. Archives can be password‑protected — the user attaches the archive’s password to that line and the step decrypts it on the way in.
Confirms the partner on the upload is a real, valid delivery partner.
Matches every line on the upload to a real, available product in the catalogue, and checks the lines are within limits.
Reads the actual keys out of the upload — the typed keys and the contents of each file — and checks every one is usable and free to load.
Claims every key in the load so that no other upload running at the same time can grab the same ones.
Checks the upload for the same key appearing more than once.
Sends the uploaded files to storage so they’re ready for the delivery.
A countdown before the delivery is actually created. It exists so the user can stop the ingestion if they spot a mistake — a wrong upload never gets committed once they pause here.
Creates the Inbound Delivery and — when the upload has leftover stock — a generated Inbound Order, then loads the keys onto PickTower.
Everything the user reads on a single ingestion, top to bottom.
Which buttons appear, when, and what they do for the user. Only the relevant ones show for a given status.
| Action | Appears when… | What it does |
|---|---|---|
| ⏸ Stop / ⏸ Pause | Queued · Running · Grace | Pauses it. The step that’s already running finishes (no wasted work); it halts before the next step. In the grace window the button reads Pause. |
| ⏸ Stopping… | pause pending | Disabled placeholder shown for the brief moment between clicking pause and the pipeline actually halting. |
| ▶ Resume | Stopped / Failed (mid‑pipeline) | Continues from the step where it was paused — already‑completed steps are not re‑run, and the upload isn’t re‑sent. |
| ▶ Resume | paused in the Grace window | Re‑arms the grace countdown; the delivery is created when it elapses again. |
| ✎ Load into form | Stopped · Failed | Loads the upload back into the editor, highlighting the items that failed, so the user can correct them. |
| ↺ Restart | Stopped · Failed | Re‑runs from step 1 using the corrected form, on the same card. The earlier run is kept as a collapsible “Previous attempts” entry. |
| ⬇ Download payload | always | Downloads the stored upload exactly as it was submitted (audit / re‑use). |
| 🗑 Delete | Failed · Stopped | Permanently removes the ingestion and its stored upload. |
| IBD‑… IBO‑… | Succeeded · IBO generated | Deep links that open the created Delivery and the generated Order in the main app. The IBO‑… link already appears in IBO generated — that’s the order the user goes to fill in. |
The three flows worth designing for.
Cards update on their own as steps progress — the user never has to refresh. New uploads appear at the top.
A pause never throws away the step in progress — it finishes, then the pipeline halts before the next one. The card shows which step it’s paused before.
The grace countdown is the deliberate window for the user to stop a wrong upload before it’s created. It deserves a clear, prominent timer and an unmissable Pause — this is where a mistake gets caught.
Failures name the specific lines / keys (title · message · explanation), so the UI should make them scannable and tie them to “fix & retry”.
An uploaded .zip can be encrypted. The user supplies its password alongside the line; the pipeline decrypts it during Unpack archives. A wrong or missing password fails that step with a clear message — fix the password and retry.
Success can produce a Delivery and a generated Order. Surface both links; the Order may be absent (no overflow) — design for one‑or‑two. When an Order is generated, the card pauses in IBO generated until that order is completed, then becomes Succeeded on its own.
Before anything runs: “No ingestions yet”. The list also needs a signed‑out / loading state.
Restarting keeps the prior attempt as a collapsible “Previous attempts” block with its own timeline and errors.