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 के लिए:
total_amount > 0reserved_at IS NULL⇔state ∈ {pending, failed}delivered_at IS NULL⇔state ≠ deliveredrefund_amount <= total_amountstate = refunded⇒delivered_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 पाएं।
