डिजिटल वस्तुओं का थोक मंच

Order State Machine Design 2026: Digital Goods में order lifecycle modelling

B2B order FSM का production design: 6 core states, transition invariants, audit log, और TypeScript implementation।

Order State Machine Design 2026: Digital Goods में order lifecycle modelling

Order state machine किसी भी B2B fulfilment का heart है। सही design system को observable, debuggable, और audit-friendly बनाता है। Bad design impossible states और race conditions पैदा करता है जिन्हें महीनों तक chase करना पड़ता है। यह article digital-goods order के लिए FSM design करने की detailed guide है।

1. छह core states

enum OrderState {
  PENDING = 'pending',         // created, payment + reservation का wait
  RESERVED = 'reserved',       // इस order के लिए inventory locked
  PROCESSING = 'processing',   // supplier API called, webhook का wait
  DELIVERED = 'delivered',     // success, customer को code release
  FAILED = 'failed',           // terminal — supplier rejected या timeout
  REFUNDED = 'refunded',       // terminal — funds customer को return
}

Allowed transitions (graph):

pending     → reserved | failed
reserved    → processing | failed
processing  → delivered | failed
delivered   → refunded
failed      → (terminal)
refunded    → (terminal)

कोई और transition (जैसे delivered → processing) invalid है और throw करना चाहिए।

2. Invariants

Invariant = वह property जो state के बावजूद हमेशा true है। Order के लिए:

  1. total_amount > 0
  2. reserved_at IS NULLstate ∈ {pending, failed}
  3. delivered_at IS NULLstate ≠ delivered
  4. refund_amount <= total_amount
  5. state = refundeddelivered_at IS NOT NULL

Invariants FSM transition handler के अंदर और DB में CHECK constraints के through दोनों जगह check करें:

ALTER TABLE orders ADD CONSTRAINT chk_refund_amount
  CHECK (refund_amount <= total_amount);
ALTER TABLE orders ADD CONSTRAINT chk_refunded_delivered
  CHECK (state != 'refunded' OR delivered_at IS NOT NULL);

3. XState या enum+switch?

Small/medium projects के लिए enum + switch काफी है:

async function transition(order: Order, event: OrderEvent): Promise<Order> {
  const next = nextState(order.state, event.type);
  if (!next) throw new Error(`invalid transition ${order.state} + ${event.type}`);
  return db.tx(async (tx) => {
    const updated = await tx.orders.update(order.id, {
      state: next,
      version: order.version + 1, // optimistic lock
    }, { where: { version: order.version } });
    await tx.audit.insert({
      event_id: randomUUID(),
      order_id: order.id,
      from_state: order.state,
      to_state: next,
      actor: event.actor,
      timestamp: new Date(),
    });
    return updated;
  });
}

Complex flows (multi-supplier, partial-delivery, fraud-hold) के लिए XState visual diagram और hierarchical states देता है।

4. Implementation comparison

Approach LoC Visualisable Type-safe Performance
Boolean flags 50 No No Best
Enum + switch 150 No Strong Best
XState 200+ Yes (Inspector) Strong Good
Temporal workflow 500+ Yes Strong Good (async)

FoxReload का internal core enum+switch use करता है (p95 transition latency 8ms suit करता है)। Partners को UI में order lifecycle visualise करने के लिए XState recommend करते हैं।

CTA

FoxReload API GET /v1/orders/{id}/events के through current state और audit log expose करता है — webhook event stream internal FSM से mirror करती है। Access पाएं

अक्सर पूछे जाने वाले प्रश्न

Order FSM में कितनी states होनी चाहिए?
Digital goods के लिए कम से कम 5–6: pending → reserved → processing → delivered → (refunded), failed absorbing terminal state के तौर पर। awaiting_payment या partial_fulfillment जैसी slack states सिर्फ business logic demand करे तब add करें — हर extra state ~5% bugs बढ़ाती है।
क्या state machine की जगह boolean flags use कर सकते हैं?
नहीं। is_paid, is_shipped, is_refunded जैसे flags impossible states create करते हैं (जैसे refunded=true जबकि is_shipped=false)। Enum-based FSM guarantee देता है कि हर order exactly एक valid state में है। यह 30%+ state-related bugs eliminate करता है।
Error पर order को कैसे roll back करें?
FSM roll back नहीं करता। Processing से supplier error पर failed (terminal) transition करें; फिर separate failed → refunded transition refund run करता है। कोई backward edges नहीं — वो audit trail तोड़ती हैं।
हर transition के लिए audit log में क्या होना चाहिए?
event_id (UUIDv4), order_id, from_state, to_state, timestamp, actor (user_id या 'system'), reason, source_ip, metadata (जैसे processing→delivered पर supplier_id)। Append-only; existing rows पर कोई updates नहीं।
FoxReload API एक्सेस पाएं

संबंधित लेख