# Validation Report: URS-016

**Title:** Auto-decrement Inventory After Order Submission
**Date:** 2026-09-29T02:24:46.612Z
**Duration:** 193.9s
**Overall Status:** ✅ PASS

## User Requirement

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

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

## Environment

- **Inbox URL:** http://localhost:36065
- **Database:** localhost:41649/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 (Blair Bennett) and navigates to TRUNK-36 to record the starting quantities for NovaPatch and LiraLock. 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-09-29 02:25:17Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-09-29 02:25:29Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-09-29 02:26:44Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-09-29 02:26:49Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-09-29 02:27:25Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |

**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 NovaPatch and 2 LiraLock 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-09-29T02:25:39.810Z → 2026-09-29T02:26:40.688Z)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-09-29 02:25:41Z | decision | bill_only_order.duplicate_submission_block | blair.bennett@corvetasurgical.com | Corveta Surgical Group | no |
| 2026-09-29 02:26:37Z | decision | bill_only_order.duplicate_submission_block | blair.bennett@corvetasurgical.com | Corveta Surgical Group | no |
| 2026-09-29 02:26:37Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | no |
| 2026-09-29 02:26:37Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-09-29 02:26:37Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-09-29 02:26:37Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-09-29 02:26:37Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-09-29 02:26:37Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-09-29 02:26:37Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | yes |
| 2026-09-29 02:26:37Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-09-29 02:26:37Z | decision | basicErp.deriveSalesOrder | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-09-29 02:26:37Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-09-29 02:26:39Z | decision | bill_only.notifications.cc_incident_recipients | — | Vantis | no |
| 2026-09-29 02:26:40Z | transactional_email | new_bill_only | — | Corveta Surgical Group | — |

**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 - 9/29/2026 - Vantis BO-1**

Template: `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-1`

![New Bill-Only Order - 9/29/2026 - Vantis BO-1](screenshots/emails/2026-09-29T02-26-40-372Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-1.png)

**Email 2: New Bill-Only Order - 9/29/2026 - Vantis BO-2**

Template: `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-2`

![New Bill-Only Order - 9/29/2026 - Vantis BO-2](screenshots/emails/2026-09-29T02-27-19-489Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-2.png)

**Email 3: New Bill-Only Order - 9/29/2026 - Vantis BO-3**

Template: `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-3`

![New Bill-Only Order - 9/29/2026 - Vantis BO-3](screenshots/emails/2026-09-29T02-27-52-579Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_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 NovaPatch and LiraLock 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-09-29 02:26:37Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | yes |
| 2026-09-29 02:27:18Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | yes |
| 2026-09-29 02:27:51Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | yes |

**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 - 9/29/2026 - Vantis BO-1**

Template: `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-1`

![New Bill-Only Order - 9/29/2026 - Vantis BO-1](screenshots/emails/2026-09-29T02-26-40-372Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-1.png)

**Email 2: New Bill-Only Order - 9/29/2026 - Vantis BO-2**

Template: `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-2`

![New Bill-Only Order - 9/29/2026 - Vantis BO-2](screenshots/emails/2026-09-29T02-27-19-489Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-2.png)

**Email 3: New Bill-Only Order - 9/29/2026 - Vantis BO-3**

Template: `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-3`

![New Bill-Only Order - 9/29/2026 - Vantis BO-3](screenshots/emails/2026-09-29T02-27-52-579Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_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 NovaPatch 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-09-29T02:27:47.145Z → 2026-09-29T02:27:57.031Z)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-09-29 02:27:51Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | yes |
| 2026-09-29 02:27:51Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-09-29 02:27:51Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-09-29 02:27:51Z | decision | basicErp.deriveSalesOrder | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-09-29 02:27:51Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-09-29 02:27:51Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | no |
| 2026-09-29 02:27:51Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-09-29 02:27:51Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-09-29 02:27:51Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-09-29 02:27:51Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-09-29 02:27:51Z | decision | bill_only_order.duplicate_submission_block | blair.bennett@corvetasurgical.com | Corveta Surgical Group | no |
| 2026-09-29 02:27:52Z | decision | bill_only.notifications.cc_incident_recipients | — | Vantis | no |
| 2026-09-29 02:27:52Z | transactional_email | new_bill_only | — | Corveta Surgical Group | — |

**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 - 9/29/2026 - Vantis BO-1**

Template: `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-1`

![New Bill-Only Order - 9/29/2026 - Vantis BO-1](screenshots/emails/2026-09-29T02-26-40-372Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-1.png)

**Email 2: New Bill-Only Order - 9/29/2026 - Vantis BO-2**

Template: `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-2`

![New Bill-Only Order - 9/29/2026 - Vantis BO-2](screenshots/emails/2026-09-29T02-27-19-489Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-2.png)

**Email 3: New Bill-Only Order - 9/29/2026 - Vantis BO-3**

Template: `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-3`

![New Bill-Only Order - 9/29/2026 - Vantis BO-3](screenshots/emails/2026-09-29T02-27-52-579Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_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 (NovaPatch and LiraLock) 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 |
| --- | --- | --- | --- | --- | --- |
| 349f34d2-a717-4429-9fa1-fd4762591b7a | 07649988202247 | URS016-FL-001 | 12 | 0 | 0 |
| 4f8551d2-ec58-4abf-b6df-b50b8d725a06 | 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 Blair Bennett 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 |
| --- | --- | --- | --- | --- | --- |
| 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | BO-3 | submitted | 2026-09-29T00:00:00.000Z | 2026-09-29T02:27:51.885Z | 17b8c9d0-e1f2-3456-1234-567890123456 |
| 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | BO-2 | submitted | 2026-09-29T00:00:00.000Z | 2026-09-29T02:27:18.004Z | 17b8c9d0-e1f2-3456-1234-567890123456 |
| 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | BO-1 | submitted | 2026-09-29T00:00:00.000Z | 2026-09-29T02:26:37.635Z | 17b8c9d0-e1f2-3456-1234-567890123456 |

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

**Assertion:** Billing order items should reference NovaPatch and/or LiraLock 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 |
| --- | --- | --- | --- | --- | --- | --- |
| 01a0eafd-6bf0-7c93-92b8-6003ff7cea06 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 01a0eafd-6bf0-7c93-92b8-600bc12ec781 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-600c929a63e9 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-600dd7ddb0b5 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-600ec9a598dd | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-600f779ac300 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-6010bf50e1ff | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-601125a798da | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-6012c405f007 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-5fff1d8217b6 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 01a0eafd-6bf0-7c93-92b8-6000a91854d3 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 01a0eafd-6bf0-7c93-92b8-600125bfe73d | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 01a0eafd-6bf0-7c93-92b8-600217913008 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | true |
| 01a0eafd-6bf0-7c93-92b8-60040f8e3ef2 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-6005d2368e4d | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-6006f52e284c | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-6007296f35d6 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-60080c7cdad6 | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-600958151dfa | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafd-6bf0-7c93-92b8-600a4f15770c | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafc-e79b-7e67-ae30-bab8884dbea5 | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | LiraLock® Instrument SN | URS016-FL-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafc-e79c-7641-8b24-c61c79a06b8a | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafc-e79c-7641-8b24-c61bb33179cf | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafc-4a80-78c6-bfbe-db79a662c6e7 | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | LiraLock® Instrument SN | URS016-FL-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafc-4a80-78c6-bfbe-db7a0909a1af | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | LiraLock® Instrument SN | URS016-FL-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafc-4a80-78c6-bfbe-db7cde6799cf | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafc-4a80-78c6-bfbe-db7b346fe7d0 | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | NovaPatch® PET | URS016-SP-001 | NULL | a6e7f8a9-b0c1-2345-0123-456789012345 | false |
| 01a0eafc-4a80-78c6-bfbe-db7d12d256d2 | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | NovaPatch® 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 |
| --- | --- | --- | --- | --- | --- | --- |
| 01a0eafd-6c0b-7f6c-b64b-4d1943751c04 | 4f8551d2-ec58-4abf-b6df-b50b8d725a06 | 15 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3","shortageQuantity":0,"requestedQuantity":15}` | 2026-09-29T02:27:51.885Z | fa000001-0000-4000-8000-000000000001 |
| 01a0eafd-6c0b-7f6c-b64b-4d1ae89ee166 | 4f8551d2-ec58-4abf-b6df-b50b8d725a06 | 5 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3","shortageQuantity":5,"requestedQuantity":20}` | 2026-09-29T02:27:51.885Z | fa000001-0000-4000-8000-000000000001 |
| 01a0eafc-e7b0-74f6-b3ef-9fbf886fed15 | 349f34d2-a717-4429-9fa1-fd4762591b7a | 1 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"01a0eafc-e7a6-7dfc-9006-bd7f89526d60","shortageQuantity":0,"requestedQuantity":1}` | 2026-09-29T02:27:18.004Z | fa000001-0000-4000-8000-000000000001 |
| 01a0eafc-e7b0-74f6-b3ef-9fc0d26f4dd6 | 4f8551d2-ec58-4abf-b6df-b50b8d725a06 | 2 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"01a0eafc-e7a6-7dfc-9006-bd7f89526d60","shortageQuantity":0,"requestedQuantity":2}` | 2026-09-29T02:27:18.004Z | fa000001-0000-4000-8000-000000000001 |
| 01a0eafc-4b08-74c7-9836-20aa5ae0667f | 349f34d2-a717-4429-9fa1-fd4762591b7a | 2 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"01a0eafc-4aa0-7a25-96a2-7afa2738f1db","shortageQuantity":0,"requestedQuantity":2}` | 2026-09-29T02:26:37.635Z | fa000001-0000-4000-8000-000000000001 |
| 01a0eafc-4b08-74c7-9836-20ab75e07aa7 | 4f8551d2-ec58-4abf-b6df-b50b8d725a06 | 3 | ready | `{"action":"removed","reason":"bill_only_order","bestEffort":true,"billingOrderId":"01a0eafc-4aa0-7a25-96a2-7afa2738f1db","shortageQuantity":0,"requestedQuantity":3}` | 2026-09-29T02:26:37.635Z | fa000001-0000-4000-8000-000000000001 |

### 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 |
| --- | --- | --- | --- | --- | --- |
| 01a0eafd-6c07-72cb-acbe-55e5f0bd758a | bill_only_order | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | 2026-09-29T02:27:51.885Z | b2c3d4e5-f6a7-8901-bcde-f12345678901 | NULL |
| 01a0eafc-e7ac-75cb-ad8b-c0e37c52ce38 | bill_only_order | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | 2026-09-29T02:27:18.004Z | b2c3d4e5-f6a7-8901-bcde-f12345678901 | NULL |
| 01a0eafc-4ac2-751e-a62e-b930ac680819 | bill_only_order | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | 2026-09-29T02:26:37.635Z | 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.inventory_items_decrement` | ✅ |
| Step 4: Second order | `decision:bill_only_order.inventory_items_decrement` | ✅ |

### 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-09-29T02:24:45.485Z

<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>

47 event(s) captured:

| Time | Type | Action | User | Org | Object ID | Performed | Reason |
|------|------|--------|------|-----|-----------|-----------|--------|
| 2026-09-29 02:25:17Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-09-29 02:25:29Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-09-29 02:25:41Z | decision | bill_only_order.duplicate_submission_block | blair.bennett@corvetasurgical.com | Corveta Surgical Group | fea7b8c9-d0e1-2345-0123-456789012345 | no | no_same_day_candidates |
| 2026-09-29 02:26:37Z | decision | bill_only_order.duplicate_submission_block | blair.bennett@corvetasurgical.com | Corveta Surgical Group | fea7b8c9-d0e1-2345-0123-456789012345 | no | no_same_day_candidates |
| 2026-09-29 02:26:37Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | no | no_purchase_order_selected |
| 2026-09-29 02:26:37Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | — |  |
| 2026-09-29 02:26:37Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-4ba5-7d93-837c-0c79ad1fe38d | — |  |
| 2026-09-29 02:26:37Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-4bb3-74ec-b974-a151c24142b8 | — |  |
| 2026-09-29 02:26:37Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | no | no_blocking_relationship |
| 2026-09-29 02:26:37Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | no | no_blocking_relationship |
| 2026-09-29 02:26:37Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | yes | inventory_items_decremented |
| 2026-09-29 02:26:37Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | no | No uploaded PO documents |
| 2026-09-29 02:26:37Z | decision | basicErp.deriveSalesOrder | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | no | flag_disabled |
| 2026-09-29 02:26:37Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-4bb7-78e5-9a71-afb603d670cb | — |  |
| 2026-09-29 02:26:39Z | decision | bill_only.notifications.cc_incident_recipients | — | Vantis | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | no | order has no no-charge item with an incident reason |
| 2026-09-29 02:26:40Z | transactional_email | new_bill_only | — | Corveta Surgical Group | 01a0eafc-4aa0-7a25-96a2-7afa2738f1db | — |  |
| 2026-09-29 02:26:44Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-09-29 02:26:49Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-09-29 02:27:02Z | decision | bill_only_order.duplicate_submission_block | blair.bennett@corvetasurgical.com | Corveta Surgical Group | fea7b8c9-d0e1-2345-0123-456789012345 | no | acknowledged_not_duplicate |
| 2026-09-29 02:27:18Z | decision | basicErp.deriveSalesOrder | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | no | flag_disabled |
| 2026-09-29 02:27:18Z | decision | bill_only_order.duplicate_submission_block | blair.bennett@corvetasurgical.com | Corveta Surgical Group | fea7b8c9-d0e1-2345-0123-456789012345 | no | acknowledged_not_duplicate |
| 2026-09-29 02:27:18Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | no | no_purchase_order_selected |
| 2026-09-29 02:27:18Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | no | no_blocking_relationship |
| 2026-09-29 02:27:18Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | no | no_blocking_relationship |
| 2026-09-29 02:27:18Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | yes | inventory_items_decremented |
| 2026-09-29 02:27:18Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | no | No uploaded PO documents |
| 2026-09-29 02:27:18Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | — |  |
| 2026-09-29 02:27:18Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-e7bb-7233-8b50-6095b6081e53 | — |  |
| 2026-09-29 02:27:18Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-e7bf-7ebb-a7a8-cf808f53ca0a | — |  |
| 2026-09-29 02:27:18Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | 01a0eafc-e7c2-7280-9769-79cfa1b187fb | — |  |
| 2026-09-29 02:27:19Z | decision | bill_only.notifications.cc_incident_recipients | — | Vantis | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | no | order has no no-charge item with an incident reason |
| 2026-09-29 02:27:19Z | transactional_email | new_bill_only | — | Corveta Surgical Group | 01a0eafc-e7a6-7dfc-9006-bd7f89526d60 | — |  |
| 2026-09-29 02:27:25Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-09-29 02:27:38Z | decision | bill_only_order.duplicate_submission_block | blair.bennett@corvetasurgical.com | Corveta Surgical Group | fea7b8c9-d0e1-2345-0123-456789012345 | no | acknowledged_not_duplicate |
| 2026-09-29 02:27:51Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | yes | inventory_items_decremented |
| 2026-09-29 02:27:51Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | no | No uploaded PO documents |
| 2026-09-29 02:27:51Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | — |  |
| 2026-09-29 02:27:51Z | decision | basicErp.deriveSalesOrder | blair.bennett@corvetasurgical.com | Vantis | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | no | flag_disabled |
| 2026-09-29 02:27:51Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | 01a0eafd-6c19-73d9-ab74-aef85e13df88 | — |  |
| 2026-09-29 02:27:51Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | no | no_purchase_order_selected |
| 2026-09-29 02:27:51Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | 01a0eafd-6c1c-705e-971a-2ae5cda57da8 | — |  |
| 2026-09-29 02:27:51Z | scheduled_task | scheduled_task.scheduled | blair.bennett@corvetasurgical.com | Vantis | 01a0eafd-6c1f-75bb-b4e6-68ae36e6ae1e | — |  |
| 2026-09-29 02:27:51Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | no | no_blocking_relationship |
| 2026-09-29 02:27:51Z | decision | representatives.gate_rep_action | blair.bennett@corvetasurgical.com | Vantis | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | no | no_blocking_relationship |
| 2026-09-29 02:27:51Z | decision | bill_only_order.duplicate_submission_block | blair.bennett@corvetasurgical.com | Corveta Surgical Group | fea7b8c9-d0e1-2345-0123-456789012345 | no | acknowledged_not_duplicate |
| 2026-09-29 02:27:52Z | decision | bill_only.notifications.cc_incident_recipients | — | Vantis | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | no | order has no no-charge item with an incident reason |
| 2026-09-29 02:27:52Z | transactional_email | new_bill_only | — | Corveta Surgical Group | 01a0eafd-6bff-7b8d-94bc-e20fd3b6cca3 | — |  |

## 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 - 9/29/2026 - Vantis BO-1

**Template:** `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-1`

![New Bill-Only Order - 9/29/2026 - Vantis BO-1](screenshots/emails/2026-09-29T02-26-40-372Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-1.png)

### 2. New Bill-Only Order - 9/29/2026 - Vantis BO-2

**Template:** `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-2`

![New Bill-Only Order - 9/29/2026 - Vantis BO-2](screenshots/emails/2026-09-29T02-27-19-489Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-2.png)

### 3. New Bill-Only Order - 9/29/2026 - Vantis BO-3

**Template:** `New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-3`

![New Bill-Only Order - 9/29/2026 - Vantis BO-3](screenshots/emails/2026-09-29T02-27-52-579Z-New_Bill-Only_Order_-_9_29_2026_-_Vantis_BO-3.png)
