# Validation Report: URS-074

**Title:** Virtual kit pricing modes (fixed and component-sum)
**Date:** 2026-08-03T23:05:39.857Z
**Duration:** 139.8s
**Overall Status:** ✅ PASS

## User Requirement

> The system shall support fixed and component-sum pricing modes for virtual kits, where fixed mode bills the kit at its stored per-account approved price and component-sum mode computes the kit price at billing time as the sum of each component's effective approved price multiplied by its BOM quantity, blocking billing when any component lacks active pricing.

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

## Environment

- **Inbox URL:** http://localhost:43843
- **Database:** localhost:45457/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: Fixed-price kit billing — ✅ PASS

**What this step proves:**

Documents that IK2025LL (LiraLock® Implant Kit) is configured with pricing_mode='fixed' on the ROSS account, and that a bill-only order charges the kit at the stored per-account approved price — not a computed sum. The billing order item unit_price is frozen at submission time.

**Audit events generated by this step:**

*(Evidence scoped to step execution window: 2026-08-03T23:05:46.438Z → 2026-08-03T23:06:15.555Z)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-08-03 23:05:51Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:06:13Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | yes |
| 2026-08-03 23:06:13Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | no |
| 2026-08-03 23:06:13Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-08-03 23:06:13Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-08-03 23:06:13Z | transactional_email | new_bill_only | — | Corveta Surgical Group | — |

**Screenshots:**

![step 01 fixed kit product](screenshots/step-01-fixed-kit-product.png)

![step 01 fixed kit account pricing](screenshots/step-01-fixed-kit-account-pricing.png)

![step 01 fixed kit selected](screenshots/step-01-fixed-kit-selected.png)

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

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

**Video recording:**

[▶ Watch step recording](videos/step-01-fixed-price-kit-billing.webm)

---

### 2. Step 2: Component-sum pricing — ✅ PASS

**What this step proves:**

Documents that IK2025CS (LiraLock® Surgical System CS) is configured with pricing_mode='component_sum' on the ROSS account. The account pricing page displays a read-only computed price equal to the sum of its component approved prices (LL516SNA $3,000 + NP019N1A $1,500 = $4,500). No stored price input is available. The bill-only order captures this computed sum as the kit unit_price.

**Audit events generated by this step:**

*(Evidence scoped to step execution window: 2026-08-03T23:06:21.196Z → 2026-08-03T23:06:50.071Z)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-08-03 23:06:25Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:06:47Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | yes |
| 2026-08-03 23:06:47Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | no |
| 2026-08-03 23:06:47Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-08-03 23:06:47Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-08-03 23:06:48Z | transactional_email | new_bill_only | — | Corveta Surgical Group | — |

**Screenshots:**

![step 02 cs kit product](screenshots/step-02-cs-kit-product.png)

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

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

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

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

**Video recording:**

[▶ Watch step recording](videos/step-02-component-sum-billing.webm)

---

### 3. Step 3: Automatic recalculation — ✅ PASS

**What this step proves:**

Shows that updating the LL516SNA component price on ROSS from $3,000 to $2,750 immediately changes the kit effective price from $4,500 to $4,250. A new bill-only order billed after the update captures $4,250. The original bill-only snapshot from Step 2 is unaffected — each billing order freezes the component-sum price at the moment of submission.

**Audit events generated by this step:**

*(Evidence scoped to step execution window: 2026-08-03T23:06:56.156Z → 2026-08-03T23:07:24.989Z)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-08-03 23:07:00Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:07:22Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | no |
| 2026-08-03 23:07:22Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | yes |
| 2026-08-03 23:07:22Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | no |
| 2026-08-03 23:07:22Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | — |
| 2026-08-03 23:07:23Z | transactional_email | new_bill_only | — | Corveta Surgical Group | — |

**Screenshots:**

![step 03 price before](screenshots/step-03-price-before.png)

![step 03 price after](screenshots/step-03-price-after.png)

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

![step 03 updated submitted](screenshots/step-03-updated-submitted.png)

**Video recording:**

[▶ Watch step recording](videos/step-03-recalculated-billing.webm)

---

### 4. Step 4: Missing component price blocks billing — ✅ PASS

**What this step proves:**

Deactivating the NP019N1A approved pricing row on ROSS causes the kit pricing widget to display "Missing component prices" instead of a dollar amount. IK2025CS is absent from the bill-only product picker (or shown as unavailable) while a component lacks active pricing. Restoring the pricing row re-enables billing.

**Audit events generated by this step:**

*(Evidence scoped to step execution window: 2026-08-03T23:07:31.042Z → 2026-08-03T23:07:47.918Z)*

| Time | Type | Action | User | Org | Performed |
|------|------|--------|------|-----|-----------|
| 2026-08-03 23:07:33Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |

**Screenshots:**

![step 04 missing component price warning](screenshots/step-04-missing-component-price-warning.png)

![step 04 billing no cs kit](screenshots/step-04-billing-no-cs-kit.png)

**Video recording:**

[▶ Watch step recording](videos/step-04-billing-blocked.webm)

---

### 5. Step 5: Derived price not proposable — ✅ PASS

**What this step proves:**

The pricing proposal form for IK2025CS on the ROSS account shows no price-entry field — the kit price is derived from its components and cannot be stored. Only an enabled/disabled toggle is available. The product settings page confirms pricing_mode='component_sum'.

**Screenshots:**

![step 05 account pricing before](screenshots/step-05-account-pricing-before.png)

![step 05 proposal form no price input](screenshots/step-05-proposal-form-no-price-input.png)

![step 05 product settings component sum](screenshots/step-05-product-settings-component-sum.png)

**Video recording:**

[▶ Watch step recording](videos/step-05-no-price-proposal.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.

### IK2025LL has pricing_mode=fixed and an effective, enabled pricing row on ROSS — ✅ PASS

**Assertion:** IK2025LL has pricing_mode='fixed', active pricing with status='effective' and enabled=true

```sql
SELECT p.sku, p.pricing_mode,
            ap.price, ap.status, ap.active AS pricing_active, ap.enabled
     FROM org_products p
     JOIN sales_account_approved_pricing ap
       ON ap.org_product_id = p.id
      AND ap.sales_account_id = $2
      AND ap.active = true
     WHERE p.id = $1
```

| sku | pricing_mode | price | status | pricing_active | enabled |
| --- | --- | --- | --- | --- | --- |
| IK2025LL | fixed | 4750.00 | effective | true | true |

### Bill-only for IK2025LL records the stored approved price as unit_price — ✅ PASS

**Assertion:** IK2025LL billing order item unit_price matches the stored per-account approved price

```sql
SELECT boi.unit_price, bo.status
     FROM billing_orders bo
     JOIN billing_order_items boi ON boi.billing_order_id = bo.id
     WHERE boi.product_id = $1
       AND bo.notes LIKE $2
```

| unit_price | status |
| --- | --- |
| 4750.00 | submitted |

### IK2025CS has pricing_mode=component_sum and a two-component BOM — ✅ PASS

**Assertion:** IK2025CS is a virtual_kit with pricing_mode='component_sum' and LL516SNA + NP019N1A in the BOM

```sql
SELECT p.sku, p.pricing_mode, cp.sku AS component_sku, pc.quantity
     FROM org_products p
     JOIN product_components pc ON pc.composite_product_id = p.id
     JOIN org_products cp ON cp.id = pc.component_product_id
     WHERE p.id = $1
     ORDER BY pc.sort_order
```

| sku | pricing_mode | component_sku | quantity |
| --- | --- | --- | --- |
| IK2025CS | component_sum | LL516SNA | 1 |
| IK2025CS | component_sum | NP019N1A | 1 |

### First IK2025CS bill-only has unit_price = $4500 (= $3,000 + $1,500) — ✅ PASS

**Assertion:** IK2025CS bill-only unit_price = 4500 (sum of component approved prices)

```sql
SELECT boi.unit_price, bo.status
     FROM billing_orders bo
     JOIN billing_order_items boi ON boi.billing_order_id = bo.id
     WHERE boi.product_id = $1
       AND bo.notes LIKE $2
```

| unit_price | status |
| --- | --- |
| 4500.00 | submitted |

### Second IK2025CS bill-only has unit_price = $4250 after LL516SNA price update — ✅ PASS

**Assertion:** IK2025CS second bill-only unit_price = 4250 (computed from $2,750 + $1,500)

```sql
SELECT boi.unit_price, bo.status
     FROM billing_orders bo
     JOIN billing_order_items boi ON boi.billing_order_id = bo.id
     WHERE boi.product_id = $1
       AND bo.notes LIKE $2
```

| unit_price | status |
| --- | --- |
| 4250.00 | submitted |

### Original IK2025CS bill-only snapshot still shows $4500 after component price change — ✅ PASS

**Assertion:** Unit price = 4500 (frozen at billing time, not recalculated after component update)

```sql
SELECT boi.unit_price
     FROM billing_orders bo
     JOIN billing_order_items boi ON boi.billing_order_id = bo.id
     WHERE boi.product_id = $1
       AND bo.notes LIKE $2
```

| unit_price |
| --- |
| 4500.00 |

### Attempting to bill IK2025CS with a missing component price creates no billing order line — ✅ PASS

**Assertion:** No billing order line created for IK2025CS when a component price is missing (billing blocked)

```sql
SELECT boi.id, bo.notes
     FROM billing_orders bo
     JOIN billing_order_items boi ON boi.billing_order_id = bo.id
     WHERE boi.product_id = $1
       AND bo.notes LIKE $2
```

*No rows returned*

### LL516SNA pricing row on ROSS shows the recalculation price ($2750.00) — ✅ PASS

**Assertion:** price = 2750.00 (set by scenario 3's component price update)

```sql
SELECT price, active FROM sales_account_approved_pricing
     WHERE id = $1
```

| price | active |
| --- | --- |
| 2750.00 | true |

## 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-08-03T23:05:37.901Z

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

24 event(s) captured:

| Time | Type | Action | User | Org | Object ID | Performed | Reason |
|------|------|--------|------|-----|-----------|-----------|--------|
| 2026-08-03 23:05:43Z | user_log | user:login | alex.admin@vantismedical.com | Vantis | — | — |  |
| 2026-08-03 23:05:51Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-08-03 23:06:13Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | 019fc9e0-af2e-764a-847d-eb5541624026 | yes | inventory_items_decremented |
| 2026-08-03 23:06:13Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | 019fc9e0-af2e-764a-847d-eb5541624026 | no | no_purchase_order_selected |
| 2026-08-03 23:06:13Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | 019fc9e0-af2e-764a-847d-eb5541624026 | no | No uploaded PO documents |
| 2026-08-03 23:06:13Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | 019fc9e0-af2e-764a-847d-eb5541624026 | — |  |
| 2026-08-03 23:06:13Z | transactional_email | new_bill_only | — | Corveta Surgical Group | 019fc9e0-af2e-764a-847d-eb5541624026 | — |  |
| 2026-08-03 23:06:18Z | user_log | user:login | alex.admin@vantismedical.com | Vantis | — | — |  |
| 2026-08-03 23:06:25Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-08-03 23:06:47Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | 019fc9e1-366e-75d6-850b-cf8e5c7ba8ab | yes | inventory_items_decremented |
| 2026-08-03 23:06:47Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | 019fc9e1-366e-75d6-850b-cf8e5c7ba8ab | no | no_purchase_order_selected |
| 2026-08-03 23:06:47Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | 019fc9e1-366e-75d6-850b-cf8e5c7ba8ab | no | No uploaded PO documents |
| 2026-08-03 23:06:47Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | 019fc9e1-366e-75d6-850b-cf8e5c7ba8ab | — |  |
| 2026-08-03 23:06:48Z | transactional_email | new_bill_only | — | Corveta Surgical Group | 019fc9e1-366e-75d6-850b-cf8e5c7ba8ab | — |  |
| 2026-08-03 23:06:52Z | user_log | user:login | alex.admin@vantismedical.com | Vantis | — | — |  |
| 2026-08-03 23:07:00Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-08-03 23:07:22Z | decision | bill_only.link_purchase_order | blair.bennett@corvetasurgical.com | Corveta Surgical Group | 019fc9e1-be4a-7bfd-9ca2-e70517827075 | no | no_purchase_order_selected |
| 2026-08-03 23:07:22Z | decision | bill_only_order.inventory_items_decrement | blair.bennett@corvetasurgical.com | Vantis | 019fc9e1-be4a-7bfd-9ca2-e70517827075 | yes | inventory_items_decremented |
| 2026-08-03 23:07:22Z | decision | bill_only_order.direct_po_import_on_create | blair.bennett@corvetasurgical.com | Vantis | 019fc9e1-be4a-7bfd-9ca2-e70517827075 | no | No uploaded PO documents |
| 2026-08-03 23:07:22Z | billing_order | status_change | blair.bennett@corvetasurgical.com | Vantis | 019fc9e1-be4a-7bfd-9ca2-e70517827075 | — |  |
| 2026-08-03 23:07:23Z | transactional_email | new_bill_only | — | Corveta Surgical Group | 019fc9e1-be4a-7bfd-9ca2-e70517827075 | — |  |
| 2026-08-03 23:07:27Z | user_log | user:login | alex.admin@vantismedical.com | Vantis | — | — |  |
| 2026-08-03 23:07:33Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-08-03 23:07:50Z | user_log | user:login | alex.admin@vantismedical.com | Vantis | — | — |  |

## Additional Video Evidence

The following screencast recordings were captured but could not be matched to a specific test step. Step-matched recordings appear inline in their respective step sections above.

- [videos/step-01-fixed-price-kit-config.webm](videos/step-01-fixed-price-kit-config.webm)
- [videos/step-02-component-sum-pricing.webm](videos/step-02-component-sum-pricing.webm)
- [videos/step-03-recalculation.webm](videos/step-03-recalculation.webm)
- [videos/step-04-missing-component-price.webm](videos/step-04-missing-component-price.webm)
