Cancellation updates order status and creates history entry
Why it matters
A cancellation that only flips the status field leaves no durable record of who cancelled, when, or why. This is a CWE-778 gap and a GDPR Art. 5(1)(f) issue: processing activities must be accountable, and 'the order is cancelled' with no supporting event log is not accountable. Without a history entry, support staff cannot determine whether the cancellation was customer-initiated or admin-initiated, and refund disputes have no audit anchor. Both writes — status update and history entry — must be atomic in a transaction; a non-transactional write creates a race condition where one operation can succeed and the other fail.
Severity rationale
High because a cancellation with no history entry eliminates the audit trail needed for refund disputes, compliance checks, and post-incident support investigations.
Remediation
Route all cancellations through the shared transitionOrder function in lib/orders/state-machine.ts, which handles both the status update and history entry atomically. Remove any direct db.orders.update() calls in cancellation handlers.
// Replace in app/api/orders/[id]/cancel/route.ts:
// WRONG:
await db.orders.update({ where: { id: orderId }, data: { status: 'cancelled' } })
// CORRECT:
await transitionOrder(orderId, 'cancelled', actorId, 'Customer requested cancellation')
// transitionOrder wraps both writes in a db.$transaction
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Order Management Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-778 — Insufficient Logging
- iso-25010:2011 · functional-correctness — Functional Correctness
- gdpr · Art. 5(1)(f) — Integrity and confidentiality of personal data processing records
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ecommerce-order-management·automated