# Delivery notification sent on state transition to delivered

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

## Why it matters

Delivery confirmation from the carrier is a natural trigger for re-engagement — a 'your order arrived' email is the highest-open-rate message in ecommerce. Without it, the customer only knows their order arrived because they were home when it showed up. The platform misses the opportunity to prompt a review, confirm customer satisfaction, or detect a non-delivery claim early. This is an iso-25010:2011 reliability issue: the system receives or computes a delivery event and fails to act on it. The delivery email also serves as the customer's receipt of physical delivery, which matters if they later dispute receiving the item.

## Severity rationale

Medium because missing delivery notification skips the highest-engagement touchpoint in the order lifecycle and leaves the platform blind to delivery disputes until the customer contacts support.

## Remediation

Add a delivery email trigger in the handler or job that transitions orders to 'delivered' — typically `src/jobs/delivery-check.ts` for carrier-webhook polling or a webhook handler for real-time updates.

```ts
// In your delivery handler or job:
await transitionOrder(orderId, 'delivered', 'system', 'Carrier confirmed delivery')

await sendDeliveryConfirmationEmail({
  to: order.user.email,
  orderNumber: order.id,
  deliveredAt: new Date(),
  reviewUrl: `https://yoursite.com/orders/${order.id}/review`,
})
```

Add `sendDeliveryConfirmationEmail` to `lib/email/order-emails.ts` alongside the other order email functions.

## Detection

- **ID:** `delivery-email`
- **Severity:** `medium`
- **What to look for:** Find the code path that transitions orders to `delivered` status. This is commonly triggered by a carrier webhook, a polling job, or a manual admin action. Count the email or notification calls in this transition path (at least 1 required). Enumerate which data fields are passed to the delivery email template — at minimum the order number and delivery date. Also check whether the email content includes a review request link or satisfaction survey.
- **Pass criteria:** When an order transitions to `delivered` status, at least 1 delivery confirmation email is sent to the customer. The email passes at least 2 data fields (order number and delivery confirmation date). A delivery handler that updates status but makes 0 email calls does not count as pass.
- **Fail criteria:** No email is sent when an order is marked delivered (0 email calls in the delivery path). The customer's only indication that their order was delivered is through third-party carrier tracking, not from the e-commerce platform directly.
- **Skip (N/A) when:** The project does not track the `delivered` state internally — delivery status is managed entirely by the carrier and the application does not receive or process delivery events. No `delivered` status transition exists in application code.
- **Detail on fail:** `"No delivered-status email trigger found. The polling job that marks orders as delivered (src/jobs/delivery-check.ts) updates order status but makes 0 email service calls. Customers are not notified when delivery is confirmed."`
- **Remediation:** Add delivery notification alongside the delivery transition in your delivery handler or job:

  ```ts
  // In your delivery handler or job (e.g., src/jobs/delivery-check.ts):
  await transitionOrder(orderId, 'delivered', 'system', 'Carrier confirmed delivery')

  await sendDeliveryConfirmationEmail({
    to: order.user.email,
    orderNumber: order.id,
    deliveredAt: new Date(),
    reviewUrl: `https://yoursite.com/orders/${order.id}/review`,
  })
  ```

  If delivery status comes from carrier webhooks, handle it in the webhook processor and enqueue the email notification as a job to avoid blocking the webhook response.

## External references

- iso-25010 reliability

Taxons: error-resilience

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