URS-034 · Export Order and Inventory History for Audits
Title: Export Order and Inventory History for Audits Date: 2026-08-03T23:03:34.983Z Duration: 59.7s Overall Status: ✅ PASS
User Requirement
Section titled “User Requirement”The system shall support exporting order and inventory history for audits.
Source: User_Requirement_Specifications_Vantis_DeviceFlow.xlsx — the run below proves the system meets this requirement.
Environment
Section titled “Environment”- Inbox URL: http://localhost:40997
- Database: localhost:32801/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: Exports page overview — ✅ PASS
Section titled “1. Step 1: Exports page overview — ✅ PASS”What this step proves:
Logs in as an admin user (Dan Distributor) and navigates to the /exports page, confirming that export options for Orders and Inventory are visible to authorized users.
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:03:41Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:03:51Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:04:07Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:04:19Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:04:27Z | user_log | user:login | rana.reyes@corvetasurgical.com | Corveta Surgical Group | — |
Screenshots:


Video recording:
2. Step 2: Export order history — ✅ PASS
Section titled “2. Step 2: Export order history — ✅ PASS”What this step proves:
Downloads the Orders CSV export, verifying that order history can be exported for audits and that the file contains the expected audit columns including order numbers, status, and creation dates. The download itself is audited: the endpoint writes an export:orders audit event capturing the acting user, timestamp, and the number of rows exported, so the act of exporting compliance data is itself traceable.
Audit events generated by this step:
(Evidence scoped to step execution window: 2026-08-03T23:03:56.791Z → 2026-08-03T23:04:00.703Z)
| Time | Type | Action | User | Org | Performed |
|---|---|---|---|---|---|
| 2026-08-03 23:03:57Z | export | export:orders | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
Screenshots:


Video recording:
3. Step 3: Order export verification — ✅ PASS
Section titled “3. Step 3: Order export verification — ✅ PASS”What this step proves:
Verifies the downloaded order CSV contains all required audit fields with non-empty values, confirming the export provides complete audit-ready data.
Screenshots:

Video recording:
4. Step 4: Export inventory — ✅ PASS
Section titled “4. Step 4: Export inventory — ✅ PASS”What this step proves:
Downloads the Inventory CSV export, verifying that inventory history is exportable for audits with the expected columns including location and quantity data. The download is audited: the endpoint writes an export:inventory audit event capturing the acting user, timestamp, and exported row count.
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:04:13Z | export | export:inventory | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
Screenshots:


Video recording:
5. Step 5: Date range filtering — ✅ PASS
Section titled “5. Step 5: Date range filtering — ✅ PASS”What this step proves:
Confirms that the date range filter on the orders export works correctly: a narrow historical range returns zero results while a wide range spanning the test data returns the expected records. Each filtered download writes its own export:orders audit event, and the applied from/to range is recorded in the event payload (dateFrom/dateTo) — proving that not only the export but the exact date window queried is captured for audit.
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:03:57Z | export | export:orders | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:04:20Z | export | export:orders | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:04:20Z | export | export:orders | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
Screenshots:

Video recording:
6. Step 6: Permission restriction — ✅ PASS
Section titled “6. Step 6: Permission restriction — ✅ PASS”What this step proves:
Logs in as Rana Reyes (Sales Rep without export permissions) and verifies that the /exports page and the direct CSV endpoint deny access, enforcing role-based export access control.
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:03:41Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:03:51Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:04:07Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:04:19Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — |
| 2026-08-03 23:04:27Z | user_log | user:login | rana.reyes@corvetasurgical.com | Corveta Surgical Group | — |
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.
Exports feature flag enabled — ✅ PASS
Section titled “Exports feature flag enabled — ✅ PASS”Assertion: The “exports” feature flag should be enabled for Corveta
SELECT id, value FROM feature_flags WHERE id = 'exports' AND organization_id = $1| id | value |
|---|---|
| exports | true |
Admin role has exports:access — ✅ PASS
Section titled “Admin role has exports:access — ✅ PASS”Assertion: The Corveta Admin role should have exports:access permission
SELECT p.permission FROM permissions p WHERE p.actor_id = $1 AND p.permission = 'exports:access'| permission |
|---|
| exports:access |
Sales rep role lacks exports:access — ✅ PASS
Section titled “Sales rep role lacks exports:access — ✅ PASS”Assertion: The Sales Rep role should NOT have exports:access permission
SELECT p.permission FROM permissions p WHERE p.actor_id = $1 AND p.permission = 'exports:access'No rows returned
Order requests exist for organization — ✅ PASS
Section titled “Order requests exist for organization — ✅ PASS”Assertion: At least one order request should exist for Corveta
SELECT COUNT(*) as count, MIN(created_at) as oldest_order, MAX(created_at) as newest_order FROM order_requests WHERE requesting_organization_id = $1 OR fulfilling_organization_id = $1| count | oldest_order | newest_order |
|---|---|---|
| 3 | 2026-07-04T23:03:35.017Z | 2026-07-29T23:03:35.017Z |
Inventory items exist for organization — ✅ PASS
Section titled “Inventory items exist for organization — ✅ PASS”Assertion: At least one inventory item with positive quantity should exist for Corveta
SELECT COUNT(*) as count FROM inventory_items WHERE organization_id = $1 AND (quantity_ready > 0 OR quantity_backordered > 0 OR quantity_in_transit > 0)| count |
|---|
| 13 |
Admin user has Admin role — ✅ PASS
Section titled “Admin user has Admin role — ✅ PASS”Assertion: Dan Distributor should have the Admin role for Corveta
SELECT u.email, u.name, r.name as role_name, r.id as role_id FROM users u JOIN user_roles ur ON ur.user_id = u.id JOIN roles r ON r.id = ur.role_id WHERE u.id = $1 AND ur.organization_id = $2| name | role_name | role_id | |
|---|---|---|---|
| dan.distributor@corvetasurgical.com | Dan Distributor | Corveta Admin | 40e1f2a3-b4c5-6789-4567-890123456789 |
Orders export download is audited — ✅ PASS
Section titled “Orders export download is audited — ✅ PASS”Assertion: Downloading the orders CSV should write an “export:orders” audit event capturing the acting user, row count, and any date range applied
SELECT ae.created_at, ae.action, u.email AS user_email, ae.payload->>'exportType' AS export_type, ae.payload->>'rowCount' AS row_count, ae.payload->>'dateFrom' AS date_from, ae.payload->>'dateTo' AS date_to FROM audit_events ae LEFT JOIN users u ON u.id = ae.user_id WHERE ae.organization_id = $1 AND ae.event_type = 'export' AND ae.action = 'export:orders' AND ae.created_at >= NOW() - INTERVAL '30 minutes' ORDER BY ae.created_at DESC LIMIT 10| created_at | action | user_email | export_type | row_count | date_from | date_to |
|---|---|---|---|---|---|---|
| 2026-08-03T23:04:20.713Z | export:orders | dan.distributor@corvetasurgical.com | orders | 4 | 2024-08-03 | 2026-08-03 |
| 2026-08-03T23:04:20.681Z | export:orders | dan.distributor@corvetasurgical.com | orders | 0 | 2020-01-01 | 2020-01-02 |
| 2026-08-03T23:03:57.403Z | export:orders | dan.distributor@corvetasurgical.com | orders | 4 | 2026-05-03 | 2026-08-03 |
Inventory export download is audited — ✅ PASS
Section titled “Inventory export download is audited — ✅ PASS”Assertion: Downloading the inventory CSV should write an “export:inventory” audit event capturing the acting user and row count
SELECT ae.created_at, ae.action, u.email AS user_email, ae.payload->>'exportType' AS export_type, ae.payload->>'rowCount' AS row_count FROM audit_events ae LEFT JOIN users u ON u.id = ae.user_id WHERE ae.organization_id = $1 AND ae.event_type = 'export' AND ae.action = 'export:inventory' AND ae.created_at >= NOW() - INTERVAL '30 minutes' ORDER BY ae.created_at DESC LIMIT 10| created_at | action | user_email | export_type | row_count |
|---|---|---|---|---|
| 2026-08-03T23:04:13.400Z | export:inventory | dan.distributor@corvetasurgical.com | inventory | 13 |
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: Exports page overview | user_log:user:login | ✅ |
| Step 2: Export order history | export:export:orders | ✅ |
| Step 4: Export inventory | export:export:inventory | ✅ |
| Step 5: Date range filtering | export:export:orders | ✅ |
| Step 6: Permission restriction | 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-08-03T23:03:33.098Z
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 ASC9 event(s) captured:
| Time | Type | Action | User | Org | Object ID | Performed | Reason |
|---|---|---|---|---|---|---|---|
| 2026-08-03 23:03:41Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — | — | |
| 2026-08-03 23:03:51Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — | — | |
| 2026-08-03 23:03:57Z | export | export:orders | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — | — | |
| 2026-08-03 23:04:07Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — | — | |
| 2026-08-03 23:04:13Z | export | export:inventory | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — | — | |
| 2026-08-03 23:04:19Z | user_log | user:login | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — | — | |
| 2026-08-03 23:04:20Z | export | export:orders | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — | — | |
| 2026-08-03 23:04:20Z | export | export:orders | dan.distributor@corvetasurgical.com | Corveta Surgical Group | — | — | |
| 2026-08-03 23:04:27Z | user_log | user:login | rana.reyes@corvetasurgical.com | Corveta Surgical Group | — | — |