You need to build a reliable order system where the frontend must handle duplicate submissions gracefully, the backend processes orders asynchronously via a message queue, and the system remains consistent across services.
DEV prompt for Event-Driven Order Processing with Idempotent APIs & Background Jobs
AI prompt created by PromptsRadar
Instructions
PromptsRadar
2026-05-11
Claude
"Act as a full-stack architect for a distributed system. Build an order processing pipeline where users submit orders, but order validation and inventory deduction happen in a background worker to avoid blocking the UI. Use React + TypeScript frontend, Node.js + BullMQ + Redis for queuing, and two separate Node.js services (API Gateway and Worker). Data persistence is PostgreSQL with Prisma ORM.
Requirements:
Backend (API Gateway - Express)
Endpoint POST /api/orders accepts { productId, quantity, userId }. Before enqueuing, it checks for an Idempotency-Key header. Store the key with status PENDING in an idempotency table. If the same key is seen within 24 hours, return the previous result (200/409/500) without reprocessing.
Enqueue a processOrder job into BullMQ with options: attempts: 3, backoff: 2s. Return 202 Accepted + { jobId, status: 'processing' } immediately.
Expose GET /api/orders/:orderId to poll for status (PENDING, CONFIRMED, FAILED).
Backend (Worker Service)
Process the job: start a Prisma transaction – deduct inventory, create order record, update idempotency key status to CONFIRMED (or FAILED). If inventory insufficient or any step fails, rollback the transaction and mark idempotency as FAILED.
After 3 failures, move job to a dead-letter queue and log reason.
Emit a WebSocket event (using Socket.IO via Redis adapter) back to the API Gateway to notify the specific user’s frontend of completion – this avoids polling.
Frontend (React + Zustand + Socket.IO)
When user clicks 'Place Order', generate a UUID as Idempotency-Key and send it in the header. Immediately show an optimistic 'Order received – processing' state.
Subscribe to a private room WebSocket channel user:{userId}:orders. On receiving order:confirmed or order:failed, update Zustand store and show a toast.
Also implement a fallback: if no WebSocket message after 5 seconds, start polling GET /api/orders/:orderId every 2 seconds until resolution.
Prevent duplicate form submission during network retries by tracking pending idempotency keys in local storage.
Provide:
gateway/src/routes/orders.ts (idempotency middleware + BullMQ producer)
worker/src/processors/orderProcessor.ts (BullMQ consumer + Prisma transaction)
shared/prisma/schema.prisma (Order, Inventory, IdempotencyKey models)
frontend/src/stores/orderStore.ts (Zustand + Socket.IO + polling fallback)
frontend/src/components/OrderForm.tsx (with idempotency key generation)
docker-compose.yml (Postgres, Redis, Gateway, Worker, and optional Nginx)
Share on Socials




