Skip to content

URS-055 · Restrict uncertified reps from actions until approved

Title: Restrict uncertified reps from actions until approved Date: 2026-08-03T23:04:28.021Z Duration: 132.3s Overall Status: ✅ PASS

The system shall restrict regulated sales actions to authorized and approved rep users only

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

Status: ✅ PASS

Each step below corresponds to one Playwright test that ran sequentially. Screenshots and video recordings provide visual evidence of the UI behaviour.

What this step proves:

An uncertified sales rep attempts to create a bill-only order. The system blocks access to the bill-only form, confirming that the certification requirement is enforced before any order can be submitted.

Screenshots:

step 01 ryan dashboard

step 01 billing blocked

Video recording:


2. Step 2: Order request blocked — ✅ PASS

Section titled “2. Step 2: Order request blocked — ✅ PASS”

What this step proves:

The same uncertified rep attempts to submit a standard order request. The system again blocks access, demonstrating that both order types are restricted until the rep obtains manufacturer certification.

Screenshots:

step 02 order request blocked

Video recording:


3. Step 3: Certified rep control — ✅ PASS

Section titled “3. Step 3: Certified rep control — ✅ PASS”

What this step proves:

A certified sales rep navigates through the bill-only form without being blocked. The form heading and step indicator both render, and the “Manufacturer Approval Required” warning is absent — confirming the restriction is applied only to uncertified reps.

Blair’s relationship row has active = true in the fixtures, which is the column the gating logic (getAvailableFulfillingOrganizations) consults. The status column in the demo data may read proposed_pending_onboarding rather than active because the seed set preserves the original onboarding history — but the boolean active flag is authoritative for whether the rep may place orders, which is why the DB assertion in this run checks active = true for the control case rather than the status string.

Screenshots:

step 03 bob billing form

Video recording:


4. Step 4: Manufacturer approval — ✅ PASS

Section titled “4. Step 4: Manufacturer approval — ✅ PASS”

What this step proves:

A manufacturer user reviews the pending rep certification request and approves it, changing the relationship status from pending to active. This step generates the approval notification that certifies the previously blocked rep.

Audit events generated by this step:

(Evidence scoped to step execution window: 2026-08-03T23:05:33.387Z → 2026-08-03T23:05:40.371Z)

TimeTypeActionUserOrgPerformed
2026-08-03 23:05:37Zuser_logrep_onboarding_request_approvedmark.manufacturer@vantismedical.comVantis
2026-08-03 23:05:37Ztransactional_emailrep_createdCorveta Surgical Group

Screenshots:

step 04 ryan pending

step 04 approval dialog

step 04 ryan active

Video recording:


5. Step 5: Bill-only after certification — ✅ PASS

Section titled “5. Step 5: Bill-only after certification — ✅ PASS”

What this step proves:

The newly certified rep navigates to the bill-only form and is no longer blocked. The form is accessible and the order is submitted successfully, confirming that certification takes immediate effect.

Audit events generated by this step:

(Evidence scoped to step execution window: 2026-08-03T23:05:48.196Z → 2026-08-03T23:06:11.294Z)

TimeTypeActionUserOrgPerformed
2026-08-03 23:06:08Zdecisionbill_only.link_purchase_orderrana.reyes@corvetasurgical.comCorveta Surgical Groupno
2026-08-03 23:06:08Zdecisionbill_only_order.inventory_items_decrementrana.reyes@corvetasurgical.comVantisyes
2026-08-03 23:06:08Zdecisionbill_only_order.direct_po_import_on_createrana.reyes@corvetasurgical.comVantisno
2026-08-03 23:06:08Zbilling_orderstatus_changerana.reyes@corvetasurgical.comVantis
2026-08-03 23:06:10Ztransactional_emailnew_bill_onlyCorveta Surgical Group

Screenshots:

step 05 billing form accessible

step 05 devices selected

step 05 review

step 05 order submitted

Video recording:


6. Step 6: Order request after certification — ✅ PASS

Section titled “6. Step 6: Order request after certification — ✅ PASS”

What this step proves:

The certified rep navigates to the standard order request form without the approval warning, then submits a consignment order end-to-end. A DB assertion subsequently confirms that a row was persisted to the order_requests table — proving the post-certification path is unlocked at the database level, not just the UI level.

Audit events generated by this step:

(Evidence scoped to step execution window: 2026-08-03T23:06:18.876Z → 2026-08-03T23:06:37.555Z)

TimeTypeActionUserOrgPerformed
2026-08-03 23:06:35Zchecklistchecklists.createrana.reyes@corvetasurgical.comVantis
2026-08-03 23:06:35Zdecisionorder_request_createdrana.reyes@corvetasurgical.comVantisyes

Screenshots:

step 06 order request form accessible

step 06 order request product

step 06 order request review

step 06 order request submitted

Video recording:


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.

Assertion: Rana’s representation relationship should be active after manufacturer approval

SELECT id, status, active, responded_at, responded_by_user_id
FROM organization_representation_relationships
WHERE id = $1
idstatusactiveresponded_atresponded_by_user_id
95d6e7f8-a9b0-1234-9012-345678901234activetrue2026-08-03T23:05:37.206Zd4e5f6a7-b8c9-0123-def1-234567890123

Blair relationship still active (control) — ✅ PASS

Section titled “Blair relationship still active (control) — ✅ PASS”

Assertion: Blair’s relationship should remain active = true (the column the certification gate actually reads) and be unaffected by Rana’s approval. The status string in this row is informational only and may read proposed_pending_onboarding from the seed data.

SELECT id, status, active
FROM organization_representation_relationships
WHERE id = $1
idstatusactive
84c5d6e7-f8a9-0123-8901-234567890123proposed_pending_onboardingtrue

Status change history recorded — ✅ PASS

Section titled “Status change history recorded — ✅ PASS”

Assertion: Status change to “active” should be recorded in history table

SELECT id, to_status, from_status, changed_by_user_id, created_at
FROM organization_representation_request_status_changes
WHERE relationship_id = $1
AND created_at > NOW() - INTERVAL '30 minutes'
ORDER BY created_at DESC
LIMIT 5
idto_statusfrom_statuschanged_by_user_idcreated_at
019fc9e0-22b8-7fa6-a69a-54db8c536310activeproposedd4e5f6a7-b8c9-0123-def1-2345678901232026-08-03T23:05:37.134Z

Bill-only order created by Rana after certification — ✅ PASS

Section titled “Bill-only order created by Rana after certification — ✅ PASS”

Assertion: At least one bill-only order should have been created by Rana after being certified

SELECT bo.id, bo.order_number, bo.status, 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
idorder_numberstatuscreated_atcreated_by_user_id
019fc9e0-9e8d-74c0-ac03-e3c56f488193BO-1submitted2026-08-03T23:06:08.866Z28c9d0e1-f2a3-4567-2345-678901234567

Order request created by Rana after certification — ✅ PASS

Section titled “Order request created by Rana after certification — ✅ PASS”

Assertion: A standard order request should have been persisted by Rana after certification (Step 6) — tagged with the URS-055 notes marker

SELECT id, request_number, order_type, status, sales_account_id, notes, created_at
FROM order_requests
WHERE requested_by_user_id = $1
AND notes LIKE $2
AND created_at > NOW() - INTERVAL '30 minutes'
ORDER BY created_at DESC
LIMIT 5
idrequest_numberorder_typestatussales_account_idnotescreated_at
019fc9e1-0606-7575-9423-41ff783b30ebOR-2dropshipsubmittedfea7b8c9-d0e1-2345-0123-456789012345URS-055: post-certification order request2026-08-03T23:06:35.380Z

Audit trail for representative approval — ✅ PASS

Section titled “Audit trail for representative approval — ✅ PASS”

Assertion: Audit/decision events should exist referencing Rana after the approval action

SELECT ae.id, ae.event_type, ae.action, ae.created_at, ae.user_id, ae.object_id,
substring(ae.payload::text, 1, 500) as payload_preview
FROM audit_events ae
WHERE ae.created_at > NOW() - INTERVAL '30 minutes'
AND (ae.object_id = $1 OR ae.object_id = $2)
ORDER BY ae.created_at DESC
LIMIT 10
idevent_typeactioncreated_atuser_idobject_idpayload_preview
019fc9e0-253c-75a5-9011-a7f7608119d4transactional_emailrep_created2026-08-03T23:05:37.876ZNULL95d6e7f8-a9b0-1234-9012-345678901234{“to”: [“rana.reyes@corvetasurgical.com”], “s3Path”: “email-audit/b2c3d4e5-f6a7-8901-bcde-f12345678901/019fc9e0-253c-75a5-9011-a7f7608119d4/”, “subject”: “Representative Account Approved - Vantis”, “messageId”: “dev-console-log”, “relatedEntityType”: “organization_representation_relationship”}
019fc9e0-22ba-7ead-918b-ba2071669cf6user_logrep_onboarding_request_approved2026-08-03T23:05:37.232Zd4e5f6a7-b8c9-0123-def1-23456789012395d6e7f8-a9b0-1234-9012-345678901234{“userId”: “28c9d0e1-f2a3-4567-2345-678901234567”, “userName”: “Rana Reyes”, “userEmail”: “rana.reyes@corvetasurgical.com”, “distributorOrganizationId”: “b2c3d4e5-f6a7-8901-bcde-f12345678901”, “manufacturerOrganizationId”: “a1b2c3d4-e5f6-7890-abcd-ef1234567890”}

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.

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.

StepExpected Audit ActionFound
Step 4: Manufacturer approvaluser_log:rep_onboarding_request_approved

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:04:26.122Z

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

15 event(s) captured:

TimeTypeActionUserOrgObject IDPerformedReason
2026-08-03 23:05:02Zuser_loguser:loginrana.reyes@corvetasurgical.comCorveta Surgical Group
2026-08-03 23:05:11Zuser_loguser:loginrana.reyes@corvetasurgical.comCorveta Surgical Group
2026-08-03 23:05:19Zuser_loguser:loginblair.bennett@corvetasurgical.comCorveta Surgical Group
2026-08-03 23:05:27Zuser_loguser:loginmark.manufacturer@vantismedical.comVantis
2026-08-03 23:05:37Zuser_logrep_onboarding_request_approvedmark.manufacturer@vantismedical.comVantis95d6e7f8-a9b0-1234-9012-345678901234
2026-08-03 23:05:37Ztransactional_emailrep_createdCorveta Surgical Group95d6e7f8-a9b0-1234-9012-345678901234
2026-08-03 23:05:43Zuser_loguser:loginrana.reyes@corvetasurgical.comCorveta Surgical Group
2026-08-03 23:06:08Zdecisionbill_only.link_purchase_orderrana.reyes@corvetasurgical.comCorveta Surgical Group019fc9e0-9e8d-74c0-ac03-e3c56f488193nono_purchase_order_selected
2026-08-03 23:06:08Zdecisionbill_only_order.inventory_items_decrementrana.reyes@corvetasurgical.comVantis019fc9e0-9e8d-74c0-ac03-e3c56f488193yesinventory_items_decremented
2026-08-03 23:06:08Zdecisionbill_only_order.direct_po_import_on_createrana.reyes@corvetasurgical.comVantis019fc9e0-9e8d-74c0-ac03-e3c56f488193noNo uploaded PO documents
2026-08-03 23:06:08Zbilling_orderstatus_changerana.reyes@corvetasurgical.comVantis019fc9e0-9e8d-74c0-ac03-e3c56f488193
2026-08-03 23:06:10Ztransactional_emailnew_bill_onlyCorveta Surgical Group019fc9e0-9e8d-74c0-ac03-e3c56f488193
2026-08-03 23:06:14Zuser_loguser:loginrana.reyes@corvetasurgical.comCorveta Surgical Group
2026-08-03 23:06:35Zchecklistchecklists.createrana.reyes@corvetasurgical.comVantis019fc9e1-0613-7673-975e-ca9df9800062
2026-08-03 23:06:35Zdecisionorder_request_createdrana.reyes@corvetasurgical.comVantis019fc9e1-0606-7575-9423-41ff783b30ebyesOrder request OR-2 created (importSource=manual)

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

1. Representative Account Approved - Vantis

Section titled “1. Representative Account Approved - Vantis”

Template: Representative_Account_Approved_-_Vantis

Representative Account Approved - Vantis

2. New Bill-Only Order - 8/3/2026 - Vantis BO-1

Section titled “2. New Bill-Only Order - 8/3/2026 - Vantis BO-1”

Template: New_Bill-Only_Order_-_8_3_2026_-_Vantis_BO-1

New Bill-Only Order - 8/3/2026 - Vantis BO-1