# Validation Report: URS-029

**Title:** Collect Return Information per Individual Item
**Date:** 2026-08-03T23:09:29.894Z
**Duration:** 60.6s
**Overall Status:** ✅ PASS

## User Requirement

> The system shall collect return information for each individual item.

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

## Environment

- **Inbox URL:** http://localhost:38465
- **Database:** localhost:46031/cc_repinbox_dev

## Setup

Status: ✅ PASS

## Run Recording

This validation was captured as a single end-to-end screencast covering every step below.

[▶ Watch full run recording](videos/step-01-full-run.webm)

## 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. Login — ✅ PASS

**What this step proves:**

Authenticates as Blair Bennett (Corveta sales rep) to establish the user identity that will be associated with the return submission.

**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-08-03 23:09:35Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — |

**Screenshots:**

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

---

### 2. New Return opened — ✅ PASS

**What this step proves:**

Navigates to the new return form, confirming the multi-step return workflow is accessible.

**Screenshots:**

![02 new return form](screenshots/02-new-return-form.png)

---

### 3. Account selected — ✅ PASS

**What this step proves:**

Selects the sales account to associate with the return, establishing the account-level context for per-item traceability.

**Screenshots:**

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

---

### 4. Event details — ✅ PASS

**What this step proves:**

Records the reporting user, event date, and a unique run marker in the notes field so the database validation step can locate this specific return.

**Screenshots:**

![04 event details](screenshots/04-event-details.png)

---

### 5. Quantities filled — ✅ PASS

**What this step proves:**

Sets return quantities for three products (2 NovaPatch, 3 LiraLock, 1 Medical Gelatin = 6 total units), enabling per-unit item card generation.

**Screenshots:**

![05 product quantities set](screenshots/05-product-quantities-set.png)

---

### 6. Lots filled — ✅ PASS

**What this step proves:**

Assigns distinct lot numbers to each individual unit, demonstrating that the form supports per-unit lot tracking rather than a single shared lot.

**Screenshots:**

![06 product lots filled](screenshots/06-product-lots-filled.png)

---

### 7. All 6 item cards rendered — ✅ PASS

**What this step proves:**

Verifies that the form renders one item card per unit (6 total), each with product-specific question fields — the prerequisite for per-item data capture.

**Screenshots:**

![07 per item cards rendered](screenshots/07-per-item-cards-rendered.png)

---

### 8. All per-item questions filled — ✅ PASS

**What this step proves:**

Fills distinct answers for every unit's product-specific questions, proving that each unit's response is captured independently rather than shared across units.

**Screenshots:**

![08 per item questions filled](screenshots/08-per-item-questions-filled.png)

---

### 9. Locations selected — ✅ PASS

**What this step proves:**

Selects return and replacement shipping locations to complete the return request before the review step.

**Screenshots:**

![09 locations selected](screenshots/09-locations-selected.png)

---

### 10. Review summary — ✅ PASS

**What this step proves:**

Displays the full summary of all 6 units with their individual lot numbers and answers, confirming per-item data is preserved through to the review step.

**Screenshots:**

![10 review summary](screenshots/10-review-summary.png)

---

### 11. Submission success — ✅ PASS

**What this step proves:**

Confirms the return was submitted successfully, triggering back-end persistence of return_items and per-item question responses for each unit.

**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-08-03 23:10:28Z | return_request | created | blair.bennett@corvetasurgical.com | Vantis | — |

**Screenshots:**

![11 submission success](screenshots/11-submission-success.png)

---

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

### Return created for Corveta → Vantis — ✅ PASS

**Assertion:** Exactly one return with status=submitted should exist, created in the last 2 hours.

```sql
SELECT id, return_number, status, date_of_event, notes, created_at
    FROM returns
    WHERE sales_organization_id = $1
      AND manufacturer_organization_id = $2
      AND notes LIKE 'URS-029%'
      AND created_at > NOW() - INTERVAL '2 hours'
    ORDER BY created_at DESC
```

| id | return_number | status | date_of_event | notes | created_at |
| --- | --- | --- | --- | --- | --- |
| 019fc9e4-938a-74a3-bc58-89808805c221 | RET-1 | submitted | 2026-08-03T00:00:00.000Z | URS-029 validation run 2026-08-03T23:09:31.011Z | 2026-08-03T23:10:28.206Z |

### Per-item return_items rows — ✅ PASS

**Assertion:** Each individual unit should have its own return_items row. Expected 6.

```sql
SELECT ri.id, ri.product_id, op.sku, op.title, ri.lot_number,
      ri.return_item_number, ri.created_at
    FROM return_items ri
    JOIN org_products op ON op.id = ri.product_id
    WHERE ri.return_id = $1
    ORDER BY op.sku, ri.lot_number
```

| id | product_id | sku | title | lot_number | return_item_number | created_at |
| --- | --- | --- | --- | --- | --- | --- |
| 019fc9e4-938d-7af4-9b34-05547272d311 | 66a80423-2315-4d10-8ecf-238b3058528b | DB2025G | Medical gelatin (For demonstration purpose) | URS029-MG-001 | RET-1-DB2025G-1 | 2026-08-03T23:10:28.206Z |
| 019fc9e4-938d-7af4-9b34-0551baf4429f | 01989ca1-f2f8-7ab7-8269-7179342797cc | LL516SNA | LiraLock® Instrument SN | URS029-FL-001 | RET-1-LL516SNA-1 | 2026-08-03T23:10:28.206Z |
| 019fc9e4-938d-7af4-9b34-055230f35bc4 | 01989ca1-f2f8-7ab7-8269-7179342797cc | LL516SNA | LiraLock® Instrument SN | URS029-FL-002 | RET-1-LL516SNA-2 | 2026-08-03T23:10:28.206Z |
| 019fc9e4-938d-7af4-9b34-0553780fc602 | 01989ca1-f2f8-7ab7-8269-7179342797cc | LL516SNA | LiraLock® Instrument SN | URS029-FL-003 | RET-1-LL516SNA-3 | 2026-08-03T23:10:28.206Z |
| 019fc9e4-938d-7af4-9b34-054fb39b9905 | 01989ca2-6a54-7834-8376-06a0251bacd8 | NP019N1A | NovaPatch® PET | URS029-SP-001 | RET-1-NP019N1A-1 | 2026-08-03T23:10:28.206Z |
| 019fc9e4-938d-7af4-9b34-0550b4359457 | 01989ca2-6a54-7834-8376-06a0251bacd8 | NP019N1A | NovaPatch® PET | URS029-SP-002 | RET-1-NP019N1A-2 | 2026-08-03T23:10:28.206Z |

### Each unit has its own distinct lot number — ✅ PASS

**Assertion:** All expected per-unit lot numbers should appear exactly once, proving per-item data was stored.

```sql
-- Expected lot numbers: URS029-SP-001, URS029-SP-002, URS029-FL-001, URS029-FL-002, URS029-FL-003, URS029-MG-001
```

| lot_number | sku |
| --- | --- |
| URS029-MG-001 | DB2025G |
| URS029-FL-001 | LL516SNA |
| URS029-FL-002 | LL516SNA |
| URS029-FL-003 | LL516SNA |
| URS029-SP-001 | NP019N1A |
| URS029-SP-002 | NP019N1A |

### Each returned unit has per-item question responses — ✅ PASS

**Assertion:** Every return_item should have at least one associated return_item_question_response row.

```sql
SELECT riqr.id, riqr.return_item_id, riqr.question_version_id,
      riqr.response_text, riqr.response_values::text AS response_values_json,
      ri.lot_number, rpqv.question_type, rpqv.is_required, rpqv.question_text
    FROM return_item_question_responses riqr
    JOIN return_items ri ON ri.id = riqr.return_item_id
    JOIN return_product_question_versions rpqv ON rpqv.id = riqr.question_version_id
    JOIN return_product_questions rpq ON rpq.id = rpqv.question_id
    WHERE ri.return_id = $1
    ORDER BY ri.lot_number, rpq.display_order NULLS LAST, rpqv.version_number
```

| id | return_item_id | question_version_id | response_text | response_values_json | lot_number | question_type | is_required | question_text |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 019fc9e4-9390-7b63-9f78-59ad099ac232 | 019fc9e4-938d-7af4-9b34-0551baf4429f | 0c020902-aaaa-4002-9002-000000000002 | NULL | ["opened"] | URS029-FL-001 | single_select | true | Condition at return |
| 019fc9e4-9390-7b63-9f78-59b15337367f | 019fc9e4-938d-7af4-9b34-0551baf4429f | 0c020902-aaaa-4002-9002-000000000004 | Customer confirmed seal integrity at receipt. | NULL | URS029-FL-001 | text | false | Additional notes (optional) |
| 019fc9e4-9390-7b63-9f78-59ae2591cb71 | 019fc9e4-938d-7af4-9b34-055230f35bc4 | 0c020902-aaaa-4002-9002-000000000002 | NULL | ["unopened"] | URS029-FL-002 | single_select | true | Condition at return |
| 019fc9e4-9390-7b63-9f78-59afaa131095 | 019fc9e4-938d-7af4-9b34-0553780fc602 | 0c020902-aaaa-4002-9002-000000000002 | NULL | ["defective"] | URS029-FL-003 | single_select | true | Condition at return |
| 019fc9e4-9390-7b63-9f78-59b0c2661c0a | 019fc9e4-938d-7af4-9b34-05547272d311 | 0c020903-aaaa-4003-9002-000000000002 | URS029 MG unit 1: hydraulic seal failure observed. | NULL | URS029-MG-001 | text | true | Unit inspection note |
| 019fc9e4-9390-7b63-9f78-59a9dbb1f1ac | 019fc9e4-938d-7af4-9b34-054fb39b9905 | 0c020901-aaaa-4001-9002-000000000002 | NULL | ["damaged"] | URS029-SP-001 | single_select | true | Return reason |
| 019fc9e4-9390-7b63-9f78-59aa05c83fa9 | 019fc9e4-938d-7af4-9b34-054fb39b9905 | 0c020901-aaaa-4001-9002-000000000004 | URS029 unit 1: screen cracked during shipping, non-functional. | NULL | URS029-SP-001 | text | true | Per-unit notes |
| 019fc9e4-9390-7b63-9f78-59abcb7b7306 | 019fc9e4-938d-7af4-9b34-0550b4359457 | 0c020901-aaaa-4001-9002-000000000002 | NULL | ["unused"] | URS029-SP-002 | single_select | true | Return reason |
| 019fc9e4-9390-7b63-9f78-59acbb7f0a4d | 019fc9e4-938d-7af4-9b34-0550b4359457 | 0c020901-aaaa-4001-9002-000000000004 | URS029 unit 2: never opened, preventative return. | NULL | URS029-SP-002 | text | true | Per-unit notes |

### Required per-item question responses present — ✅ PASS

**Assertion:** Expected 8 required-question responses across all items.

```sql
-- Filter to versions: 0c020901-aaaa-4001-9002-000000000002, 0c020901-aaaa-4001-9002-000000000004, 0c020902-aaaa-4002-9002-000000000002, 0c020903-aaaa-4003-9002-000000000002
```

| lot_number | question_text | response_text | response_values |
| --- | --- | --- | --- |
| URS029-FL-001 | Condition at return | NULL | ["opened"] |
| URS029-FL-002 | Condition at return | NULL | ["unopened"] |
| URS029-FL-003 | Condition at return | NULL | ["defective"] |
| URS029-MG-001 | Unit inspection note | URS029 MG unit 1: hydraulic seal failure observed. | NULL |
| URS029-SP-001 | Return reason | NULL | ["damaged"] |
| URS029-SP-001 | Per-unit notes | URS029 unit 1: screen cracked during shipping, non-functional. | NULL |
| URS029-SP-002 | Return reason | NULL | ["unused"] |
| URS029-SP-002 | Per-unit notes | URS029 unit 2: never opened, preventative return. | NULL |

### NovaPatch per-unit free-text answers are distinct — ✅ PASS

**Assertion:** Each NovaPatch unit should have a distinct per-unit note, proving per-item data is collected independently.

```sql
-- Filter to novaPatchNotesVersion = 0c020901-aaaa-4001-9002-000000000004
```

| lot_number | response_text |
| --- | --- |
| URS029-SP-001 | URS029 unit 1: screen cracked during shipping, non-functional. |
| URS029-SP-002 | URS029 unit 2: never opened, preventative return. |

## 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 |
|------|-----------------------|-------|
| Login | `user_log:user:login` | ✅ |
| Submission success | `return_request:created` | ✅ |

## 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:09:27.971Z

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

4 event(s) captured:

| Time | Type | Action | User | Org | Object ID | Performed | Reason |
|------|------|--------|------|-----|-----------|-----------|--------|
| 2026-08-03 23:09:35Z | user_log | user:login | blair.bennett@corvetasurgical.com | Corveta Surgical Group | — | — |  |
| 2026-08-03 23:10:28Z | decision | create_replacement_order_on_return | blair.bennett@corvetasurgical.com | Vantis | 019fc9e4-938a-74a3-bc58-89808805c221 | no | manufacturer_setting_disabled |
| 2026-08-03 23:10:28Z | return_request | created | blair.bennett@corvetasurgical.com | Vantis | 019fc9e4-938a-74a3-bc58-89808805c221 | — |  |
| 2026-08-03 23:10:29Z | transactional_email | return_submitted | — | Corveta Surgical Group | 019fc9e4-938a-74a3-bc58-89808805c221 | — |  |

## Email Evidence

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

### 1. Return Submitted - RET-1

**Template:** `Return_Submitted_-_RET-1`

![Return Submitted - RET-1](screenshots/emails/2026-08-03T23-10-29-477Z-Return_Submitted_-_RET-1.png)
