Wholesale · Deliveries

Inbound Delivery Ingestion

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.

7 lifecycle states 10 pipeline steps Live, no refresh needed Pause · Resume · Fix · Retry Password‑protected ZIPs

The big picture

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.

1 · Lifecycle states

The card always shows exactly one status. It drives the colour, the headline, and which buttons appear.

Queued

Submitted and waiting to start. Nothing has run yet.

Can: Pause
Running

Actively working through the steps. Progress and the current step update live.

Can: Pause
Grace

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.

Can: Pause
Stopped

Paused by the user. It stays exactly where it was and waits. The headline shows where: e.g. “paused before Create delivery”.

Can: Resume · Fix & Restart · Delete · Download
Failed

A step found a problem with the data (e.g. an unknown product, a duplicate key). The card shows the exact items that failed.

Can: Fix & Restart · Delete · Download
IBO generated

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.

Can: Open Delivery / Order · Download
Succeeded

The delivery was created (and any generated Order is now completed). The card carries links to the created Delivery and that Order.

Can: Open Delivery / Order · Download

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.

2 · The pipeline at a glance

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:

Successful run every step completes — the delivery is created.
Parse
6.2s
Unpack
5.9s
Partner
6.2s
Products
6.3s
Keys
6.1s
Reserve
6.2s
Dupes
6.2s
Upload
6.0s
Grace
30s
Create
0.4s
Failed run a check rejects the data — the pipeline stops at that step and shows the error; later steps never run.
Parse
6.2s
Unpack
5.9s
Partner
6.2s
Products
failed
5
Keys
6
Reserve
7
Dupes
8
Upload
9
Grace
10
Create
Stopped run the user paused mid‑pipeline — the running step finished, then it halted before the next one (here: paused before Dupes).
Parse
6.2s
Unpack
5.9s
Partner
6.2s
Products
6.3s
Keys
6.1s
Reserve
6.2s
7
Dupes
⏸ paused
8
Upload
9
Grace
10
Create

3 · Every step — what the user sees

Plain language: what each step is for, exactly what the user sees on the card as it runs, and where a step can fail.

1
Read the upload

Parse raw payload

Reads the uploaded file and pulls out the partner and the list of items with their keys.

Sees: while it runs, the header reads “step 1/10 · Parse raw payload” and the progress bar starts to fill. On success the bubble turns green ✓ with its duration, and the partner and item count it found appear in the card’s details. If the file can’t be read, or a line carries no keys at all, the bubble turns red ✗, the status flips to Failed, and the error explains what was wrong.
can fail · empty / unreadable upload
2
Prepare · check

Unpack archives

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.

Sees: the bubble shows as running, then turns green ✓ with a duration; from this point on the timeline operates on the extracted files. If an archive is encrypted and the password is wrong or missing, the bubble turns red ✗, the status flips to Failed, and the card says which it was — a “Wrong archive password” or a “Password‑protected archive” (none provided) — and tells the user to fix this line’s ZIP password and re‑upload. A corrupt or unreadable .zip — or one with no usable files at the expected levels — fails here in the same way. Hovering the bubble reveals when it started, finished and how long it took.
can fail · bad / locked archive skipped when no archive
3
Check

Validate partner

Confirms the partner on the upload is a real, valid delivery partner.

Sees: a quick green ✓ on success, and the partner’s name is shown on the card. If the partner is unknown or missing, the bubble turns red ✗, the status flips to Failed, and the error panel names the partner problem.
can fail · unknown partner
4
Check

Resolve & validate products

Matches every line on the upload to a real, available product in the catalogue, and checks the lines are within limits.

Sees: a green ✓ once every line passes. On failure the bubble turns red ✗Failed and the error panel names each problem line — an unknown product, one that’s disabled or on hold, a dependent item with no name, an over‑long note, or simply too many lines — so the user knows exactly what to correct.
can fail · unknown / unavailable product
5
Prepare · check

Generate keys

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.

Sees: for a large load a live count of keys checked ticks up; on success the bubble turns green ✓. It turns red ✗Failed if a key is already in stock, already loaded on an earlier delivery, or still downloading, if a file can’t be read, or if the load breaks a limit (too many keys, too many dependents, or a dependent that doesn’t line up with its base) — the error panel names each offending key or line to fix and retry.
can fail · duplicate / unusable keys live progress
6
Prepare · check

Reserve keys

Claims every key in the load so that no other upload running at the same time can grab the same ones.

Sees: a green ✓ when the claim succeeds. If another upload is already using one of these keys, the bubble turns red ✗Failed and the error panel names the clashing keys (being ingested elsewhere right now) — wait and retry, or change them. The prepared keys are saved, so a later Resume picks up exactly where it left off.
can fail · key in use elsewhere
7
Check

Detect duplicates

Checks the upload for the same key appearing more than once.

Sees: a green ✓ when the load is clean. If it finds repeats, the bubble turns red ✗, the status flips to Failed, and the error panel lists each duplicated item — ready to fix and retry. Failing here also frees the keys it had reserved, so a parallel upload isn’t blocked while the user fixes this one.
can fail · duplicates
8
Prepare

Upload keys

Sends the uploaded files to storage so they’re ready for the delivery.

Sees: for a load with many files a live count ticks up as batches upload, then the bubble turns green ✓ and the progress bar moves into the final stretch. A text‑only upload has no files to send, so this step is skipped. A storage hiccup here isn’t a user error — it simply retries on its own.
skipped for text‑only live progress
9
Safety window — stop a mistake

Await grace period

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.

Sees: the status shows Grace and the card displays a live ⏳ grace countdown with a shrinking bar and a “delivery in 12s” timer, while the Pause button sits front‑and‑centre. Pausing halts it before anything is created (the card then reads “paused before Create delivery”); letting the timer reach zero moves straight on to Create.
user can pause & resume here
10
The result

Create delivery

Creates the Inbound Delivery and — when the upload has leftover stock — a generated Inbound Order, then loads the keys onto PickTower.

Sees: the last bubble fills and the bar reaches 100%. The card’s details now show clickable IBD‑… (the delivery) and, when one was generated, IBO‑… (the order) — opening them in the main app. If no order was generated the status flips straight to Succeeded; if one was, the card first shows IBO generated while that order waits to be filled in, then flips to Succeeded on its own once the order is completed.

4 · Anatomy of a card

Everything the user reads on a single ingestion, top to bottom.

08ded02d Stopped paused before Create delivery 1m 55s  90%
Grace period — delivery is created when it elapses (pause to halt first) delivery in 12s
  • Header line — short id · status chip · where it is now (“step 6/10 · Reserve keys”, “paused before Create delivery”, “done”) · attempt number if it was retried · elapsed time · progress %.
  • Progress bar — coloured by status (blue running, green done, amber stopped, red failed).
  • Step bubbles — the 10‑step rail with each step’s state & duration.
  • Live “…working” line — for longer steps, a one‑line detail of what’s happening right now.
  • Grace countdown — the timer + shrinking bar shown above, while in the grace window.
  • IBO‑generated notice — a violet line shown when the created delivery generated an order: “🧾 Delivery created — the generated order still needs to be filled in & completed. Finishes automatically once it is.”
  • Stop notice — “⏸ Stop requested — the pipeline will halt before the next step”, shown while a pause is pending.
  • Details (expand) — who created it & when, the partner name, source, and — once created — links to the Delivery and Order. Plus per‑item error details and a previous‑attempts history.

5 · Actions reference

Which buttons appear, when, and what they do for the user. Only the relevant ones show for a given status.

ActionAppears 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.

6 · Key user journeys

The three flows worth designing for.

① Happy path

Submit upload Watch steps tick green Grace countdown Delivery created Open IBD‑… / IBO‑…

② Pause & resume

Running Pause (current step finishes) Stopped — “paused before X” Resume Continues from X (no re‑run)

③ Fix & retry

Step fails See per‑item errors Load into form & fix Restart Runs again (old attempt kept as history)

④ Generated order to complete

Delivery created IBO generated — order awaits User opens & completes the Order Succeeded (automatic)

7 · Notes for the design

Live by default

Cards update on their own as steps progress — the user never has to refresh. New uploads appear at the top.

No wasted work on pause

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.

Grace is the safety net

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.

Errors are item‑level

Failures name the specific lines / keys (title · message · explanation), so the UI should make them scannable and tie them to “fix & retry”.

Password‑protected archives

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.

Two outputs

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.

Empty & auth states

Before anything runs: “No ingestions yet”. The list also needs a signed‑out / loading state.

History stays

Restarting keeps the prior attempt as a collapsible “Previous attempts” block with its own timeline and errors.