# Delivered status records delivery date/time

- **Pattern:** `ab-001137` (`ecommerce-order-management.order-lifecycle.delivery-timestamp`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001137
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001137)

## Why it matters

Without a `deliveredAt` timestamp, any query for fulfillment metrics — average time from ship to delivery, on-time delivery rate, SLA compliance — becomes impossible or relies on `updatedAt`, which gets overwritten by post-delivery events like refund requests. If the customer contacts support asking when their package arrived, the platform has no answer beyond 'the carrier said so'. Capturing delivery time at the moment the status transitions is a one-line write that prevents a permanent data gap — a gap that can never be filled after the fact.

## Severity rationale

Low because delivery timestamp absence only affects reporting and display quality; the order flow itself continues correctly without it.

## Remediation

Add a nullable `deliveredAt` column to your order model in `prisma/schema.prisma` and populate it in `lib/orders/state-machine.ts` alongside other lifecycle timestamps.

```ts
// prisma/schema.prisma addition:
// deliveredAt DateTime?

// In transitionOrder (lib/orders/state-machine.ts):
const timestampFields: Record<string, Date> = {}
if (newStatus === 'delivered') timestampFields.deliveredAt = new Date()
if (newStatus === 'shipped')   timestampFields.shippedAt   = new Date()
if (newStatus === 'confirmed') timestampFields.confirmedAt = new Date()
if (newStatus === 'cancelled') timestampFields.cancelledAt = new Date()

await db.orders.update({ where: { id: orderId }, data: { status: newStatus, ...timestampFields } })
```

## Detection

- **ID:** `delivery-timestamp`
- **Severity:** `low`
- **What to look for:** When an order transitions to `delivered` status, enumerate all fields written alongside the status change. Check whether a delivery timestamp is captured. Look for a `deliveredAt` column on the orders table or in the order schema (`prisma/schema.prisma` or equivalent). Find the code path that marks orders as delivered — count whether it is a carrier webhook, a manual admin action, or a customer confirmation flow — and verify that at least 1 timestamp field is written alongside the status change.
- **Pass criteria:** When an order reaches `delivered` status, a `deliveredAt` timestamp is recorded on the order record. The field exists in the database schema and is populated during the delivery transition. At least 1 delivery-specific field is written beyond just `status`.
- **Fail criteria:** Order status changes to `delivered` but no delivery timestamp is captured (0 delivery-specific fields written). The `updatedAt` field is the only approximation of when delivery occurred, and it gets overwritten if any future updates happen to the order (e.g., a refund request).
- **Skip (N/A) when:** Delivery status is not tracked by this application — the project delegates tracking entirely to a shipping carrier platform or third-party logistics provider and does not record a `delivered` state internally. No `delivered` status value exists in the codebase.
- **Detail on fail:** `"Orders marked as delivered update only the status field. No deliveredAt timestamp is written. 0 delivery-specific fields captured. The only way to determine when an order was delivered would be to query the order_history table, if it exists."`
- **Remediation:** Add a `deliveredAt` field to your order model (in `prisma/schema.prisma`) and populate it during the delivered transition in `lib/orders/state-machine.ts`:

  ```ts
  // Prisma schema addition (prisma/schema.prisma):
  // deliveredAt DateTime?

  // In transitionOrder (lib/orders/state-machine.ts):
  const timestampFields: Partial<Order> = { status: newStatus, updatedAt: new Date() }
  if (newStatus === 'delivered') timestampFields.deliveredAt = new Date()
  if (newStatus === 'confirmed') timestampFields.confirmedAt = new Date()
  if (newStatus === 'shipped')   timestampFields.shippedAt = new Date()
  if (newStatus === 'cancelled') timestampFields.cancelledAt = new Date()

  await db.orders.update({ where: { id: orderId }, data: timestampFields })
  ```

  Capturing all lifecycle timestamps makes it straightforward to display a delivery timeline to customers and to calculate fulfillment metrics (e.g., average time from confirmed to shipped).

## External references

- iso-25010 functional-correctness

Taxons: data-integrity

HTML version: https://auditbuffet.com/patterns/ab-001137
