# Validation Report: URS-016

**Title:** Auto-decrement Inventory After Order Submission
**Date:** 2026-04-23T03:36:41.370Z
**Duration:** 119.5s
**Overall Status:** ✅ PASS

## User Requirement

> The system shall automatically decrement inventory after a bill-only order is submitted.

*Source: `User_Requirement_Specifications_ZuriMED_DeviceFlow.xlsx` — the run below proves the system meets this requirement.*

## Environment

- **Inbox URL:** http://localhost:62754
- **Database:** localhost:62755/cc_repinbox_dev

## Setup

Status: ✅ PASS

## Test Steps

Each step below corresponds to one Playwright test that ran sequentially. Screenshots and video recordings provide visual evidence of the UI behaviour.

### 1. Step 1: Initial inventory — ✅ PASS

**What this step proves:**

Logs in as a sales rep (Bob Kauffman) and navigates to TRUNK-36 to record the starting quantities for SpeedPatch and FiberLocker. This establishes the known baseline so subsequent steps can prove the correct delta was applied after each order.

**Audit events generated by this step:**

*(Evidence matched by declared name — step timing not available or no events fell in window)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-04-23 03:36:43Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:36:54Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:37:26Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:37:34Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:38:07Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |

**Screenshots:**

![step 01 logged in](screenshots/step-01-logged-in.png)

![step 01 initial inventory](screenshots/step-01-initial-inventory.png)

**Video recording:**

[▶ Watch step recording](videos/step-01-initial-inventory.webm)

---

### 2. Step 2: First order — ✅ PASS

**What this step proves:**

Creates and submits a bill-only order for 3 SpeedPatch and 2 FiberLocker devices from trunk inventory. This exercises the full order-submission flow that should trigger an automatic inventory decrement in the database.

**Audit events generated by this step:**

*(Evidence scoped to step execution window: 2026-04-23T03:37:03.656Z → 2026-04-23T03:37:22.747Z)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-04-23 03:37:20Z | decision | bill_only_order.enqueue_upload_classification | bob.kauffman@stellartech.com | ZuriMED | no |
| 2026-04-23 03:37:21Z | transactional_email | new_bill_only | — | StellarTech Medical Solutions | — |

**Emails triggered by this step:**

*(Evidence matched by declared name — step timing not available or no events fell in window)*

**Email 1: New Bill-Only Order - 4/22/2026 - ZuriMED BO-1**

Template: `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-1`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-1](screenshots/emails/2026-04-23T03-37-21-740Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-1.png)

**Email 2: New Bill-Only Order - 4/22/2026 - ZuriMED BO-2**

Template: `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-2`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-2](screenshots/emails/2026-04-23T03-37-58-333Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-2.png)

**Email 3: New Bill-Only Order - 4/22/2026 - ZuriMED BO-3**

Template: `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-3`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-3](screenshots/emails/2026-04-23T03-38-30-934Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-3.png)

**Screenshots:**

![step 02 account selected](screenshots/step-02-account-selected.png)

![step 02 devices selected](screenshots/step-02-devices-selected.png)

![step 02 documents](screenshots/step-02-documents.png)

![step 02 review](screenshots/step-02-review.png)

![step 02 order submitted](screenshots/step-02-order-submitted.png)

**Video recording:**

[▶ Watch step recording](videos/step-02-first-order.webm)

---

### 3. Step 3: Verify first decrement — ✅ PASS

**What this step proves:**

Navigates to TRUNK-36 immediately after the first order and confirms that SpeedPatch and FiberLocker quantities have each decreased by the ordered amount. This proves the inventory auto-decrement fires on order submission.

**Screenshots:**

![step 03 inventory after first order](screenshots/step-03-inventory-after-first-order.png)

**Video recording:**

[▶ Watch step recording](videos/step-03-verify-decrement.webm)

---

### 4. Step 4: Second order — ✅ PASS

**What this step proves:**

Submits a second bill-only order and then re-checks the inventory to verify that quantities reflect both orders cumulatively. This proves the decrement is applied consistently across multiple successive submissions.

**Audit events generated by this step:**

*(Evidence matched by declared name — step timing not available or no events fell in window)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-04-23 03:37:20Z | decision | bill_only_order.enqueue_upload_classification | bob.kauffman@stellartech.com | ZuriMED | no |
| 2026-04-23 03:37:56Z | decision | bill_only_order.enqueue_upload_classification | bob.kauffman@stellartech.com | ZuriMED | no |
| 2026-04-23 03:38:29Z | decision | bill_only_order.enqueue_upload_classification | bob.kauffman@stellartech.com | ZuriMED | no |

**Emails triggered by this step:**

*(Evidence matched by declared name — step timing not available or no events fell in window)*

**Email 1: New Bill-Only Order - 4/22/2026 - ZuriMED BO-1**

Template: `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-1`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-1](screenshots/emails/2026-04-23T03-37-21-740Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-1.png)

**Email 2: New Bill-Only Order - 4/22/2026 - ZuriMED BO-2**

Template: `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-2`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-2](screenshots/emails/2026-04-23T03-37-58-333Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-2.png)

**Email 3: New Bill-Only Order - 4/22/2026 - ZuriMED BO-3**

Template: `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-3`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-3](screenshots/emails/2026-04-23T03-38-30-934Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-3.png)

**Screenshots:**

![step 04 second order submitted](screenshots/step-04-second-order-submitted.png)

![step 04 inventory after second order](screenshots/step-04-inventory-after-second-order.png)

**Video recording:**

[▶ Watch step recording](videos/step-04-second-order.webm)

---

### 5. Step 5: Shortage edge case — ✅ PASS

**What this step proves:**

Orders more SpeedPatch units than are available in trunk stock. The system permits submission in best-effort mode and consumes all remaining units, bringing the count to zero. This proves the system handles inventory shortages without blocking the order while still tracking the discrepancy.

**Audit events generated by this step:**

*(Evidence scoped to step execution window: 2026-04-23T03:38:25.208Z → 2026-04-23T03:38:35.299Z)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-04-23 03:38:29Z | decision | bill_only_order.enqueue_upload_classification | bob.kauffman@stellartech.com | ZuriMED | no |
| 2026-04-23 03:38:30Z | transactional_email | new_bill_only | — | StellarTech Medical Solutions | — |

**Emails triggered by this step:**

*(Evidence matched by declared name — step timing not available or no events fell in window)*

**Email 1: New Bill-Only Order - 4/22/2026 - ZuriMED BO-1**

Template: `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-1`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-1](screenshots/emails/2026-04-23T03-37-21-740Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-1.png)

**Email 2: New Bill-Only Order - 4/22/2026 - ZuriMED BO-2**

Template: `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-2`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-2](screenshots/emails/2026-04-23T03-37-58-333Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-2.png)

**Email 3: New Bill-Only Order - 4/22/2026 - ZuriMED BO-3**

Template: `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-3`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-3](screenshots/emails/2026-04-23T03-38-30-934Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-3.png)

**Screenshots:**

![step 05 shortage warning](screenshots/step-05-shortage-warning.png)

![step 05 review with shortage](screenshots/step-05-review-with-shortage.png)

![step 05 shortage result](screenshots/step-05-shortage-result.png)

![step 05 final inventory](screenshots/step-05-final-inventory.png)

**Video recording:**

[▶ Watch step recording](videos/step-05-shortage-edge-case.webm)

---

## Database Validations

The following SQL queries ran against the application database after the Playwright scenarios completed. Each query asserts a specific condition that proves the feature under test persisted its data correctly.

### Inventory items exist at trunk — ✅ PASS

**Assertion:** Both test inventory items (SpeedPatch and FiberLocker) should exist at TRUNK-36

```sql
SELECT ii.id, ii.di, ii.lot, ii.quantity_ready, ii.quantity_backordered, ii.quantity_in_transit
      FROM inventory_items ii
      WHERE ii.real_world_location_id = $1
        AND ii.lot IN ($2, $3)
      ORDER BY ii.lot
```

| id | di | lot | quantity_ready | quantity_backordered | quantity_in_transit |
| --- | --- | --- | --- | --- | --- |
| 37d34f0e-71d0-44e4-a8c2-6051d9f00083 | 07649988202247 | URS016-FL-001 | 12 | 0 | 0 |
| 183cc218-e60c-4186-b10f-5ae0ef359f2e | 07649988202230 | URS016-SP-001 | 0 | 0 | 0 |

### Inventory quantities decremented — ✅ PASS

**Assertion:** Both inventory items should have quantity_ready less than their initial values

```sql
SELECT ii.lot, ii.quantity_ready,
        CASE
          WHEN ii.lot = $2 THEN 20
          WHEN ii.lot = $3 THEN 15
        END as initial_quantity,
        CASE
          WHEN ii.lot = $2 THEN 20 - ii.quantity_ready
          WHEN ii.lot = $3 THEN 15 - ii.quantity_ready
        END as total_decremented
      FROM inventory_items ii
      WHERE ii.real_world_location_id = $1
        AND ii.lot IN ($2, $3)
      ORDER BY ii.lot
```

| lot | quantity_ready | initial_quantity | total_decremented |
| --- | --- | --- | --- |
| URS016-FL-001 | 12 | 15 | 3 |
| URS016-SP-001 | 0 | 20 | 20 |

### Recent billing orders created — ✅ PASS

**Assertion:** At least one billing order should have been created by Bob Kauffman in the last 30 minutes

```sql
SELECT bo.id, bo.order_number, bo.status, bo.procedure_date,
        bo.created_at, bo.created_by_user_id
      FROM billing_orders bo
      WHERE bo.created_by_user_id = $1
        AND bo.created_at > NOW() - INTERVAL '30 minutes'
      ORDER BY bo.created_at DESC
      LIMIT 5
```

| id | order_number | status | procedure_date | created_at | created_by_user_id |
| --- | --- | --- | --- | --- | --- |
| 019db86a-f2a5-7c88-a8c2-356185cd1b6b | BO-3 | submitted | 2026-04-22T05:00:00.000Z | 2026-04-23T03:38:29.898Z | 17b8c9d0-e1f2-3456-1234-567890123456 |
| 019db86a-720a-76e7-a399-383a55663c73 | BO-2 | submitted | 2026-04-22T05:00:00.000Z | 2026-04-23T03:37:56.964Z | 17b8c9d0-e1f2-3456-1234-567890123456 |
| 019db869-e30c-7d88-8414-53d7a9be656b | BO-1 | submitted | 2026-04-22T05:00:00.000Z | 2026-04-23T03:37:20.366Z | 17b8c9d0-e1f2-3456-1234-567890123456 |

### Billing order items reference correct products — ✅ PASS

**Assertion:** Billing order items should reference SpeedPatch and/or FiberLocker products

```sql
SELECT boi.id, boi.billing_order_id, op.title as product_name,
        boi.lot_number, boi.serial_number, boi.location_id,
        boi.inventory_discrepancy
      FROM billing_order_items boi
      JOIN org_products op ON boi.product_id = op.id
      JOIN billing_orders bo ON boi.billing_order_id = bo.id
      WHERE bo.created_by_user_id = $1
        AND bo.created_at > NOW() - INTERVAL '30 minutes'
      ORDER BY bo.created_at DESC, op.title
```

| id | billing_order_id | product_name | lot_number | serial_number | location_id | inventory_discrepancy |
| --- | --- | --- | --- | --- | --- | --- |
| 019db86a-f2a2-7f49-ba3e-926aaef035e6 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 019db86a-f2a3-7305-aab3-9bd1fc3e7524 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a3-7305-aab3-9bd2365978df | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a3-7305-aab3-9bd3706f8a3b | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a3-7305-aab3-9bd43eb43ed7 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a3-7305-aab3-9bd5e45aad7a | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a3-7305-aab3-9bd66dc51b49 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a3-7305-aab3-9bd706fa1217 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a3-7305-aab3-9bd87c53e9a2 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a2-7f49-ba3e-9266117baeef | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 019db86a-f2a2-7f49-ba3e-9267642d2b79 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 019db86a-f2a2-7f49-ba3e-9268212d8c68 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 019db86a-f2a2-7f49-ba3e-9269db68297e | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 019db86a-f2a2-7f49-ba3e-926b0ac3c3a5 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a2-7f49-ba3e-926c195da876 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a2-7f49-ba3e-926d8c01c2f6 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a2-7f49-ba3e-926e51b11599 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a2-7f49-ba3e-926f5ea087b2 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a2-7f49-ba3e-9270554ec455 | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-f2a3-7305-aab3-9bd0621055bb | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-7202-7755-a209-ce9e86ed2b83 | 019db86a-720a-76e7-a399-383a55663c73 | FiberLocker® Instrument SN | URS016-FL-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-7204-7747-8006-8271cf47d7f9 | 019db86a-720a-76e7-a399-383a55663c73 | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db86a-7204-7747-8006-82705004712d | 019db86a-720a-76e7-a399-383a55663c73 | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db869-e307-79cb-bac6-efc13347e404 | 019db869-e30c-7d88-8414-53d7a9be656b | FiberLocker® Instrument SN | URS016-FL-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db869-e308-77a6-80c6-88c1913bdeb2 | 019db869-e30c-7d88-8414-53d7a9be656b | FiberLocker® Instrument SN | URS016-FL-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db869-e309-7d5c-b749-9a338a7ae71b | 019db869-e30c-7d88-8414-53d7a9be656b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db869-e309-7d5c-b749-9a32cad23a1c | 019db869-e30c-7d88-8414-53d7a9be656b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 019db869-e309-7d5c-b749-9a3492c78d6d | 019db869-e30c-7d88-8414-53d7a9be656b | SpeedPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |

### Inventory history records bill_only_order removals — ✅ PASS

**Assertion:** Inventory history should contain records with action=removed and reason=bill_only_order

```sql
SELECT ih.id, ih.item_id, ih.quantity, ih.status, ih.info,
        ih.created_at, ih.inventory_id
      FROM inventory_history ih
      WHERE ih.item_id IN (
        SELECT id FROM inventory_items
        WHERE real_world_location_id = $1
          AND lot IN ($2, $3)
      )
      AND ih.created_at > NOW() - INTERVAL '30 minutes'
      AND ih.info->>'action' = 'removed'
      AND ih.info->>'reason' = 'bill_only_order'
      ORDER BY ih.created_at DESC
      LIMIT 20
```

| id | item_id | quantity | status | info | created_at | inventory_id |
| --- | --- | --- | --- | --- | --- | --- |
| 019db86a-f2ad-7075-b4b7-8748724e42b4 | 183cc218-e60c-4186-b10f-5ae0ef359f2e | 15 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"019db86a-f2a5-7c88-a8c2-356185cd1b6b","shortageQuantity":0,"requestedQuantity":15}` | 2026-04-23T03:38:29.898Z | 019db869-3d3a-7a42-826f-ae2aff8e5d04 |
| 019db86a-f2ad-7075-b4b7-8749a4191cf2 | 183cc218-e60c-4186-b10f-5ae0ef359f2e | 5 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"019db86a-f2a5-7c88-a8c2-356185cd1b6b","shortageQuantity":5,"requestedQuantity":20}` | 2026-04-23T03:38:29.898Z | 019db869-3d3a-7a42-826f-ae2aff8e5d04 |
| 019db86a-7219-76f1-9ca2-a5fb6ec37e5c | 37d34f0e-71d0-44e4-a8c2-6051d9f00083 | 1 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"019db86a-720a-76e7-a399-383a55663c73","shortageQuantity":0,"requestedQuantity":1}` | 2026-04-23T03:37:56.964Z | 019db869-3d3a-7a42-826f-ae2aff8e5d04 |
| 019db86a-7219-76f1-9ca2-a5fca831f0b8 | 183cc218-e60c-4186-b10f-5ae0ef359f2e | 2 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"019db86a-720a-76e7-a399-383a55663c73","shortageQuantity":0,"requestedQuantity":2}` | 2026-04-23T03:37:56.964Z | 019db869-3d3a-7a42-826f-ae2aff8e5d04 |
| 019db869-e316-7af4-8978-6fab781d7633 | 37d34f0e-71d0-44e4-a8c2-6051d9f00083 | 2 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"019db869-e30c-7d88-8414-53d7a9be656b","shortageQuantity":0,"requestedQuantity":2}` | 2026-04-23T03:37:20.366Z | 019db869-3d3a-7a42-826f-ae2aff8e5d04 |
| 019db869-e316-7af4-8978-6fac8f0b2dec | 183cc218-e60c-4186-b10f-5ae0ef359f2e | 3 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"019db869-e30c-7d88-8414-53d7a9be656b","shortageQuantity":0,"requestedQuantity":3}` | 2026-04-23T03:37:20.366Z | 019db869-3d3a-7a42-826f-ae2aff8e5d04 |

### Inventory transactions created — ✅ PASS

**Assertion:** Inventory transactions should exist with source_type = bill_only_order

```sql
SELECT it.id, it.source_type, it.source_id, it.created_at,
        it.distributor_organization_id, it.manufacturer_organization_id
      FROM inventory_transactions it
      WHERE it.source_type = 'bill_only_order'
        AND it.created_at > NOW() - INTERVAL '30 minutes'
        AND (it.distributor_organization_id = $1 OR it.manufacturer_organization_id = $1)
      ORDER BY it.created_at DESC
      LIMIT 10
```

| id | source_type | source_id | created_at | distributor_organization_id | manufacturer_organization_id |
| --- | --- | --- | --- | --- | --- |
| 019db86a-f2ab-7f73-9352-8512a51e4928 | bill_only_order | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | 2026-04-23T03:38:29.898Z | b2c3d4e5-f6a7-8901-bcde-f12345678901 | NULL |
| 019db86a-7215-7390-bfa6-6e2f5f4c1083 | bill_only_order | 019db86a-720a-76e7-a399-383a55663c73 | 2026-04-23T03:37:56.964Z | b2c3d4e5-f6a7-8901-bcde-f12345678901 | NULL |
| 019db869-e312-7587-8bc2-3583d0b33178 | bill_only_order | 019db869-e30c-7d88-8414-53d7a9be656b | 2026-04-23T03:37:20.366Z | b2c3d4e5-f6a7-8901-bcde-f12345678901 | NULL |

### No negative inventory quantities — ✅ PASS

**Assertion:** Inventory quantities should never go below zero (CHECK constraint enforced)

```sql
SELECT ii.id, ii.lot, ii.quantity_ready
      FROM inventory_items ii
      WHERE ii.real_world_location_id = $1
        AND ii.lot IN ($2, $3)
        AND ii.quantity_ready < 0
```

*No rows returned*

## Audit & Email Assertion Ledger

Per-declaration outcome of every `expectedAuditActions` and `expectedEmailTemplates` entry written into the orchestrator. Missing evidence here is a real test failure, not a soft warning.

### Audit Action Assertions

Each row asserts that a declared `expectedAuditActions` entry produced a matching row in `audit_events`. A ❌ flips overall status to FAIL — the declaration is real proof, not just an annotation.

| Step | Expected Audit Action | Found |
|------|-----------------------|-------|
| Step 1: Initial inventory | `user_log:user:login` | ✅ |
| Step 2: First order | `decision:bill_only_order.enqueue_upload_classification` | ✅ |
| Step 4: Second order | `decision:bill_only_order.enqueue_upload_classification` | ✅ |

### Email Template Assertions

Each row asserts that a declared `expectedEmailTemplates` entry was matched (case-insensitive substring) by a captured email subject or template. A ❌ flips overall status to FAIL.

| Step | Expected Template | Found |
|------|-------------------|-------|
| Step 2: First order | `New Bill-Only Order` | ✅ |
| Step 4: Second order | `New Bill-Only Order` | ✅ |
| Step 5: Shortage edge case | `New Bill-Only Order` | ✅ |

## Audit Log Events

Every row written to `audit_events` while this test was running (scoped to the demo organizations). Provides compliance evidence that user actions are traced end-to-end (URS-003).

**Capture window start:** 2026-04-23T03:36:39.451Z

<details><summary>Query used to capture events</summary>

```sql
SELECT
    ae.created_at,
    ae.event_type,
    ae.action,
    ae.user_id,
    u.email AS user_email,
    ae.organization_id,
    o.name AS organization_name,
    ae.object_id,
    ae.secondary_object_id,
    ae.payload,
    ae.route,
    ae.trace_id
  FROM audit_events ae
  LEFT JOIN users u ON u.id = ae.user_id
  LEFT JOIN organizations o ON o.id = ae.organization_id
  WHERE ae.created_at >= $1
    AND ae.organization_id = ANY($2::uuid[])
  ORDER BY ae.created_at ASC
```
</details>

11 event(s) captured:

| Time | Type | Action | User | Org | Object ID | Performed | Reason |
|------|------|--------|------|-----|-----------|-----------|--------|
| 2026-04-23 03:36:43Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — |  |
| 2026-04-23 03:36:54Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — |  |
| 2026-04-23 03:37:20Z | decision | bill_only_order.enqueue_upload_classification | bob.kauffman@stellartech.com | ZuriMED | 019db869-e30c-7d88-8414-53d7a9be656b | no | No uploaded PO documents |
| 2026-04-23 03:37:21Z | transactional_email | new_bill_only | — | StellarTech Medical Solutions | 019db869-e30c-7d88-8414-53d7a9be656b | — |  |
| 2026-04-23 03:37:26Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — |  |
| 2026-04-23 03:37:34Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — |  |
| 2026-04-23 03:37:56Z | decision | bill_only_order.enqueue_upload_classification | bob.kauffman@stellartech.com | ZuriMED | 019db86a-720a-76e7-a399-383a55663c73 | no | No uploaded PO documents |
| 2026-04-23 03:37:58Z | transactional_email | new_bill_only | — | StellarTech Medical Solutions | 019db86a-720a-76e7-a399-383a55663c73 | — |  |
| 2026-04-23 03:38:07Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — |  |
| 2026-04-23 03:38:29Z | decision | bill_only_order.enqueue_upload_classification | bob.kauffman@stellartech.com | ZuriMED | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | no | No uploaded PO documents |
| 2026-04-23 03:38:30Z | transactional_email | new_bill_only | — | StellarTech Medical Solutions | 019db86a-f2a5-7c88-a8c2-356185cd1b6b | — |  |

## Email Evidence

3 notification email(s) were captured during this test run. Each email is rendered as a screenshot for compliance review.

### 1. New Bill-Only Order - 4/22/2026 - ZuriMED BO-1

**Template:** `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-1`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-1](screenshots/emails/2026-04-23T03-37-21-740Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-1.png)

### 2. New Bill-Only Order - 4/22/2026 - ZuriMED BO-2

**Template:** `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-2`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-2](screenshots/emails/2026-04-23T03-37-58-333Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-2.png)

### 3. New Bill-Only Order - 4/22/2026 - ZuriMED BO-3

**Template:** `New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-3`

![New Bill-Only Order - 4/22/2026 - ZuriMED BO-3](screenshots/emails/2026-04-23T03-38-30-934Z-New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-3.png)
