Skip to content

URS-055 · Restrict uncertified reps from actions until approved

Title: Restrict uncertified reps from actions until approved Date: 2026-04-23T03:43:31.759Z Duration: 114.9s Overall Status: ✅ PASS

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

Source: User_Requirement_Specifications_ZuriMED_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.

Bob’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-04-23T03:44:11.248Z → 2026-04-23T03:44:18.786Z)

TimeTypeActionUserOrgPerformed
2026-04-23 03:44:15Zuser_logrep_onboarding_request_approvedmark.manufacturer@zurimed.comZuriMED
2026-04-23 03:44:15Ztransactional_emailrep_createdStellarTech Medical Solutions

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-04-23T03:44:28.430Z → 2026-04-23T03:44:51.534Z)

TimeTypeActionUserOrgPerformed
2026-04-23 03:44:49Zdecisionbill_only_order.enqueue_upload_classificationryan.delauintana@stellartech.comZuriMEDno
2026-04-23 03:44:50Ztransactional_emailnew_bill_onlyStellarTech Medical Solutions

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-04-23T03:45:01.340Z → 2026-04-23T03:45:21.755Z)

TimeTypeActionUserOrgPerformed
2026-04-23 03:45:19Zdecisionorder_request_createdryan.delauintana@stellartech.comZuriMEDyes

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: Ryan’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-04-23T03:44:15.773Zd4e5f6a7-b8c9-0123-def1-234567890123

Bob relationship still active (control) — ✅ PASS

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

Assertion: Bob’s relationship should remain active = true (the column the certification gate actually reads) and be unaffected by Ryan’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
019db870-399e-7a4f-84a9-4f518efc6f49activeproposedd4e5f6a7-b8c9-0123-def1-2345678901232026-04-23T03:44:15.744Z

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

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

Assertion: At least one bill-only order should have been created by Ryan 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
019db870-bc20-789f-a38d-55a1432563aeBO-1submitted2026-04-23T03:44:49.158Z28c9d0e1-f2a3-4567-2345-678901234567

Order request created by Ryan after certification — ✅ PASS

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

Assertion: A standard order request should have been persisted by Ryan 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
019db871-3336-7dc9-bd5b-28e6e1bc4387OR-2consignmentsubmittedfea7b8c9-d0e1-2345-0123-456789012345URS-055: post-certification order request2026-04-23T03:45:19.655Z

Audit trail for representative approval — ✅ PASS

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

Assertion: Audit/decision events should exist referencing Ryan 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
019db870-39b0-7bc3-b69d-4076f39563f4transactional_emailrep_created2026-04-23T03:44:15.804ZNULL95d6e7f8-a9b0-1234-9012-345678901234{“to”: [“ryan.delauintana@stellartech.com”], “s3Path”: “email-audit/b2c3d4e5-f6a7-8901-bcde-f12345678901/019db870-39b0-7bc3-b69d-4076f39563f4/”, “subject”: “Representative Account Approved - ZuriMED”, “messageId”: “dev-console-log”, “relatedEntityType”: “organization_representation_relationship”}
019db870-399f-770b-84a3-365054e1902buser_logrep_onboarding_request_approved2026-04-23T03:44:15.781Zd4e5f6a7-b8c9-0123-def1-23456789012395d6e7f8-a9b0-1234-9012-345678901234{“userId”: “28c9d0e1-f2a3-4567-2345-678901234567”, “userName”: “Ryan Delauintana”, “userEmail”: “ryan.delauintana@stellartech.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-04-23T03:43:29.845Z

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

11 event(s) captured:

TimeTypeActionUserOrgObject IDPerformedReason
2026-04-23 03:43:33Zuser_loguser:loginryan.delauintana@stellartech.comStellarTech Medical Solutions
2026-04-23 03:43:46Zuser_loguser:loginryan.delauintana@stellartech.comStellarTech Medical Solutions
2026-04-23 03:43:56Zuser_loguser:loginbob.kauffman@stellartech.comStellarTech Medical Solutions
2026-04-23 03:44:05Zuser_loguser:loginmark.manufacturer@zurimed.comZuriMED
2026-04-23 03:44:15Zuser_logrep_onboarding_request_approvedmark.manufacturer@zurimed.comZuriMED95d6e7f8-a9b0-1234-9012-345678901234
2026-04-23 03:44:15Ztransactional_emailrep_createdStellarTech Medical Solutions95d6e7f8-a9b0-1234-9012-345678901234
2026-04-23 03:44:23Zuser_loguser:loginryan.delauintana@stellartech.comStellarTech Medical Solutions
2026-04-23 03:44:49Zdecisionbill_only_order.enqueue_upload_classificationryan.delauintana@stellartech.comZuriMED019db870-bc20-789f-a38d-55a1432563aenoNo uploaded PO documents
2026-04-23 03:44:50Ztransactional_emailnew_bill_onlyStellarTech Medical Solutions019db870-bc20-789f-a38d-55a1432563ae
2026-04-23 03:44:56Zuser_loguser:loginryan.delauintana@stellartech.comStellarTech Medical Solutions
2026-04-23 03:45:19Zdecisionorder_request_createdryan.delauintana@stellartech.comZuriMED019db871-3336-7dc9-bd5b-28e6e1bc4387yesOrder 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 - ZuriMED

Section titled “1. Representative Account Approved - ZuriMED”

Template: Representative_Account_Approved_-_ZuriMED

Representative Account Approved - ZuriMED

2. New Bill-Only Order - 4/22/2026 - ZuriMED BO-1

Section titled “2. New Bill-Only Order - 4/22/2026 - ZuriMED BO-1”

Template: New_Bill-Only_Order_-_4_22_2026_-_ZuriMED_BO-1

New Bill-Only Order - 4/22/2026 - ZuriMED BO-1