URS-028 · Initiate Return Requests for Products
Title: Initiate Return Requests for Products Date: 2026-04-23T03:39:16.900Z Duration: 125.8s Overall Status: ✅ PASS
User Requirement
Section titled “User Requirement”The system shall support initiating return requests for products.
Source: User_Requirement_Specifications_ZuriMED_DeviceFlow.xlsx — the run below proves the system meets this requirement.
Environment
Section titled “Environment”- Inbox URL: http://localhost:63629
- Database: localhost:63630/cc_repinbox_dev
Status: ✅ PASS
Test Steps
Section titled “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: Navigate to returns — ✅ PASS
Section titled “1. Step 1: Navigate to returns — ✅ PASS”What this step proves:
A sales rep navigates to the returns section of the application. This verifies the returns feature is accessible and that the navigation flow works correctly.
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:39:19Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:39:28Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:40:23Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:41:11Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
Screenshots:


Video recording:
2. Step 2: Fill return form — ✅ PASS
Section titled “2. Step 2: Fill return form — ✅ PASS”What this step proves:
The sales rep fills out the multi-step return request form with product and return reason details. This verifies all required fields are present and that form data can be entered correctly.
Screenshots:







Video recording:
3. Step 3: Submit return — ✅ PASS
Section titled “3. Step 3: Submit return — ✅ PASS”What this step proves:
The completed return form is submitted. This verifies the system accepts the return request and processes the submission through the multi-step form flow.
Screenshots:


Video recording:
4. Step 4: Verify return recorded — ✅ PASS
Section titled “4. Step 4: Verify return recorded — ✅ PASS”What this step proves:
The submitted return request is confirmed to appear in the returns list. This verifies the return data was persisted correctly and is visible to the requesting user, satisfying the requirement that return requests can be initiated and tracked.
Screenshots:


Video recording:
Database Validations
Section titled “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 record created — ✅ PASS
Section titled “Return record created — ✅ PASS”Assertion: At least one return should have been created by Bob Kauffman in the last 30 minutes
SELECT r.id, r.return_number, r.status, r.date_of_event, r.sales_account_id, r.manufacturer_organization_id, r.sales_organization_id, r.reporting_user_id, r.return_location_id, r.replacement_location_id, r.created_at, r.created_by_user_id FROM returns r WHERE r.created_by_user_id = $1 AND r.created_at > NOW() - INTERVAL '30 minutes' ORDER BY r.created_at DESC LIMIT 5| id | return_number | status | date_of_event | sales_account_id | manufacturer_organization_id | sales_organization_id | reporting_user_id | return_location_id | replacement_location_id | created_at | created_by_user_id |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 019db86d-5647-7f7e-bb24-ffa7f6fee9e0 | RET-1 | submitted | 2026-04-22T05:00:00.000Z | fea7b8c9-d0e1-2345-0123-456789012345 | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | b2c3d4e5-f6a7-8901-bcde-f12345678901 | 17b8c9d0-e1f2-3456-1234-567890123456 | 6ea3b4c5-d6e7-8901-6789-012345678901 | 6ea3b4c5-d6e7-8901-6789-012345678901 | 2026-04-23T03:41:06.484Z | 17b8c9d0-e1f2-3456-1234-567890123456 |
Return number generated — ✅ PASS
Section titled “Return number generated — ✅ PASS”Assertion: Return should have a return number matching /^RET-\d+$/
SELECT r.id, r.return_number FROM returns r WHERE r.created_by_user_id = $1 AND r.created_at > NOW() - INTERVAL '30 minutes' AND r.return_number IS NOT NULL AND r.return_number != '' ORDER BY r.created_at DESC LIMIT 1| id | return_number |
|---|---|
| 019db86d-5647-7f7e-bb24-ffa7f6fee9e0 | RET-1 |
Return status is submitted — ✅ PASS
Section titled “Return status is submitted — ✅ PASS”Assertion: Return status should be “submitted”
SELECT r.id, r.return_number, r.status FROM returns r WHERE r.created_by_user_id = $1 AND r.created_at > NOW() - INTERVAL '30 minutes' ORDER BY r.created_at DESC LIMIT 1| id | return_number | status |
|---|---|---|
| 019db86d-5647-7f7e-bb24-ffa7f6fee9e0 | RET-1 | submitted |
Return items created — ✅ PASS
Section titled “Return items created — ✅ PASS”Assertion: At least one return item should exist for the submitted return
SELECT ri.id, ri.return_id, ri.product_id, ri.lot_number, ri.return_item_number, op.title as product_name FROM return_items ri JOIN returns r ON ri.return_id = r.id JOIN org_products op ON ri.product_id = op.id WHERE r.created_by_user_id = $1 AND r.created_at > NOW() - INTERVAL '30 minutes' ORDER BY r.created_at DESC, ri.created_at DESC| id | return_id | product_id | lot_number | return_item_number | product_name |
|---|---|---|---|---|---|
| 019db86d-5649-72e7-a93c-84c52d27f0ce | 019db86d-5647-7f7e-bb24-ffa7f6fee9e0 | 01989ca2-6a54-7834-8376-06a0251bacd8 | URS028-RETURN-001 | RET-1-SP019N1A-1 | SpeedPatch® PET |
Return item has correct lot number — ✅ PASS
Section titled “Return item has correct lot number — ✅ PASS”Assertion: Return item should have lot number “URS028-RETURN-001”
SELECT ri.id, ri.lot_number, ri.return_item_number FROM return_items ri JOIN returns r ON ri.return_id = r.id WHERE r.created_by_user_id = $1 AND r.created_at > NOW() - INTERVAL '30 minutes' AND ri.lot_number = $2 LIMIT 1| id | lot_number | return_item_number |
|---|---|---|
| 019db86d-5649-72e7-a93c-84c52d27f0ce | URS028-RETURN-001 | RET-1-SP019N1A-1 |
Return linked to correct organizations — ✅ PASS
Section titled “Return linked to correct organizations — ✅ PASS”Assertion: Return should be linked to ZuriMED (manufacturer) and StellarTech (distributor)
SELECT r.id, r.return_number, r.manufacturer_organization_id, mo.name as manufacturer_name, r.sales_organization_id, so.name as sales_org_name FROM returns r JOIN organizations mo ON r.manufacturer_organization_id = mo.id JOIN organizations so ON r.sales_organization_id = so.id WHERE r.created_by_user_id = $1 AND r.created_at > NOW() - INTERVAL '30 minutes' ORDER BY r.created_at DESC LIMIT 1| id | return_number | manufacturer_organization_id | manufacturer_name | sales_organization_id | sales_org_name |
|---|---|---|---|---|---|
| 019db86d-5647-7f7e-bb24-ffa7f6fee9e0 | RET-1 | a1b2c3d4-e5f6-7890-abcd-ef1234567890 | ZuriMED | b2c3d4e5-f6a7-8901-bcde-f12345678901 | StellarTech Medical Solutions |
Return has locations set — ✅ PASS
Section titled “Return has locations set — ✅ PASS”Assertion: Return should have both return and replacement locations set
SELECT r.id, r.return_number, r.return_location_id, rl.name as return_location_name, r.replacement_location_id, repl.name as replacement_location_name FROM returns r JOIN real_world_locations rl ON r.return_location_id = rl.id JOIN real_world_locations repl ON r.replacement_location_id = repl.id WHERE r.created_by_user_id = $1 AND r.created_at > NOW() - INTERVAL '30 minutes' ORDER BY r.created_at DESC LIMIT 1| id | return_number | return_location_id | return_location_name | replacement_location_id | replacement_location_name |
|---|---|---|---|---|---|
| 019db86d-5647-7f7e-bb24-ffa7f6fee9e0 | RET-1 | 6ea3b4c5-d6e7-8901-6789-012345678901 | BOSS - Shipping | 6ea3b4c5-d6e7-8901-6789-012345678901 | BOSS - Shipping |
Return has reporting and created_by users — ✅ PASS
Section titled “Return has reporting and created_by users — ✅ PASS”Assertion: Return should have both reporting_user_id and created_by_user_id set
SELECT r.id, r.return_number, r.reporting_user_id, r.created_by_user_id, u1.name as reporting_user_name, u2.name as created_by_user_name FROM returns r JOIN users u1 ON r.reporting_user_id = u1.id JOIN users u2 ON r.created_by_user_id = u2.id WHERE r.created_by_user_id = $1 AND r.created_at > NOW() - INTERVAL '30 minutes' ORDER BY r.created_at DESC LIMIT 1| id | return_number | reporting_user_id | created_by_user_id | reporting_user_name | created_by_user_name |
|---|---|---|---|---|---|
| 019db86d-5647-7f7e-bb24-ffa7f6fee9e0 | RET-1 | 17b8c9d0-e1f2-3456-1234-567890123456 | 17b8c9d0-e1f2-3456-1234-567890123456 | Bob Kauffman | Bob Kauffman |
Return item question response persisted — ✅ PASS
Section titled “Return item question response persisted — ✅ PASS”Assertion: return_item_question_responses should contain a row for the test question with response_text = “Product packaging was damaged during shipping, device is non-functional”
SELECT riqr.id, riqr.return_item_id, riqr.question_version_id, riqr.response_text, ri.lot_number, rpqv.question_text FROM return_item_question_responses riqr JOIN return_items ri ON ri.id = riqr.return_item_id JOIN returns r ON r.id = ri.return_id JOIN return_product_question_versions rpqv ON rpqv.id = riqr.question_version_id WHERE r.created_by_user_id = $1 AND r.created_at > NOW() - INTERVAL '30 minutes' AND riqr.question_version_id = $2 ORDER BY riqr.created_at DESC| id | return_item_id | question_version_id | response_text | lot_number | question_text |
|---|---|---|---|---|---|
| 019db86d-564b-77bc-9a4d-f3d1123ab29f | 019db86d-5649-72e7-a93c-84c52d27f0ce | 02822222-2222-4222-8222-222222222222 | Product packaging was damaged during shipping, device is non-functional | URS028-RETURN-001 | Describe the issue with this product |
Audit & Email Assertion Ledger
Section titled “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
Section titled “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: Navigate to returns | user_log:user:login | ✅ |
Audit Log Events
Section titled “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:39:15.004Z
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 ASC4 event(s) captured:
| Time | Type | Action | User | Org | Object ID | Performed | Reason |
|---|---|---|---|---|---|---|---|
| 2026-04-23 03:39:19Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:39:28Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:40:23Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:41:11Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — |