Rebasely Beta: data may be purged

examples/storefront Public

Markdown · 33 lines · 1.8 KiB · at 5c7d155

---id: fulfilmenttype: conceptowner: justincomponent: fulfilmentdescribes:  - workers/fulfilment/src/**  - migrations/0004_shipments.sqlreviewed: 2026-10-07---# FulfilmentThe `storefront-fulfilment` Worker turns paid orders into shipments. It consumes the `order-events` queue ([[order-events]]) and talks to two things: storefront-api's OrdersService over the `ORDERS` service binding, and the warehouse's HTTP API at `WAREHOUSE_URL`.## Handling an eventFor each `order.paid` message:1. `OrdersService.forFulfilment(order)` returns the current order. If it is not `paid` any more (already fulfilled, which means this message is a repeat, or cancelled), the message is acked and nothing else happens.2. `POST {WAREHOUSE_URL}/v1/shipments` with the address and the lines, and `Idempotency-Key: order-<id>`.3. `OrdersService.recordShipment(order, shipment_id)` moves the order to `fulfilled` and stores the shipment id.Every other event type is acked and ignored. The steps are drawn in the order fulfilment flow on the Architecture tab.## FailuresEach message in a batch is acked or retried on its own, so one bad order does not hold back the rest. Any error (the warehouse answering 4xx or 5xx, a timeout, OrdersService failing) retries the message after `backoff(attempts)`: 30 seconds, doubling, at most an hour. After six retries the queue moves the message to `order-events-dlq`. Messages there are orders a person has to look at; the logged error says why each one failed.Why repeating step 2 is safe is in [[0007-at-least-once-with-idempotency-keys]].## Running it locally`npx wrangler dev -c workers/fulfilment/wrangler.jsonc` with `WAREHOUSE_URL` and `WAREHOUSE_TOKEN` in `.dev.vars` next to that config. With storefront-api running in another terminal, wrangler connects the service binding and the local queue.