Skip to content

URS-077 · Representative certification gating per manufacturer

Title: Representative certification gating per manufacturer Date: 2026-09-29T02:30:59.420Z Duration: 79.8s Overall Status: ✅ PASS

The system shall block representatives who have not completed a manufacturer’s required certification from restricted actions for that manufacturer (bill-only and order-request creation), enforcing the block server-side against crafted submissions, providing help text linking to the certification checklist, lifting the block immediately upon certification completion (timestamped document acknowledgment, fully correct knowledge check with unlimited retries, and signature), keeping other manufacturers unaffected, and exporting completion records that match the stored certification data.

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.

1. Step 1a: Uncertified rep blocked — ✅ PASS

Section titled “1. Step 1a: Uncertified rep blocked — ✅ PASS”

What this step proves:

An approved representative who has not completed the manufacturer’s required certification opens bill-only and order-request creation. The manufacturer is absent from both manufacturer pickers, and a ‘Certification required’ notice links the representative to the certification checklist. A second manufacturer without a certification requirement remains selectable.

Screenshots:

step 01 billing blocked

step 01 billing picker

Video recording:


2. Step 1b: Trunk order requests allowed while pending — ✅ PASS

Section titled “2. Step 1b: Trunk order requests allowed while pending — ✅ PASS”

Screenshots:

step 01 orders trunk allowed


3. Step 2: Direct-post defense — ✅ PASS

Section titled “3. Step 2: Direct-post defense — ✅ PASS”

What this step proves:

A crafted submission naming the certification-gated manufacturer is sent directly to the server, bypassing the picker. The server rejects it with a certification-required error and records the gate decision; no order or billing rows are created.

Screenshots:

step 02 crafted rejected

Video recording:


4. Step 3: Certification completion — ✅ PASS

Section titled “4. Step 3: Certification completion — ✅ PASS”

What this step proves:

The representative completes the certification behind the Part 11 signing re-authentication gate: the training flow stays hidden until a one-time signing code — issued on request and read back out of the email the system sent — is verified. The representative then opens and acknowledges the training document (timestamped server-side), fails the knowledge check once (server-side grading records the attempt and allows unlimited retries), passes at 100%, signs, and receives a certificate. The completion consumes the one-time code: replaying the identical completion request — with and without the verified code — is refused with a re-authentication demand and creates no second record. The manufacturer immediately reappears in the pickers.

Audit events generated by this step:

(Evidence scoped to step execution window: 2026-09-29T02:31:35.302Z → 2026-09-29T02:32:01.758Z)

TimeTypeActionUserOrgPerformed
2026-09-29 02:31:37Zcertificationsigning_code_issuedmarco.silva@corvetasurgical.comVantis—
2026-09-29 02:31:37Zdecisioncertifications.signing_challenge.send_smsmarco.silva@corvetasurgical.comVantisno
2026-09-29 02:31:38Ztransactional_emailcertification_signing_code—Vantis—
2026-09-29 02:31:40Zcertificationsigning_code_verifiedmarco.silva@corvetasurgical.comVantis—
2026-09-29 02:31:50Zdecisionforms.grade_submissionmarco.silva@corvetasurgical.comVantisyes
2026-09-29 02:31:54Zcertificationcompletedmarco.silva@corvetasurgical.comVantis—
2026-09-29 02:31:54Zdecisioncertifications.complete_certification.issue_certificatemarco.silva@corvetasurgical.comVantisyes
2026-09-29 02:31:54Zdecisioncertifications.complete_certification.mark_relationship_certifiedmarco.silva@corvetasurgical.comVantisyes
2026-09-29 02:31:54Zorganization_representationstatus_changemarco.silva@corvetasurgical.comVantis—
2026-09-29 02:31:54Zcertificationsigning_code_consumedmarco.silva@corvetasurgical.comVantis—
2026-09-29 02:31:54Zuser_logrep_relationship_certifiedmarco.silva@corvetasurgical.comVantis—
2026-09-29 02:31:56Zcertificationsigning_reauth_failedmarco.silva@corvetasurgical.comVantis—
2026-09-29 02:31:56Zcertificationsigning_reauth_failedmarco.silva@corvetasurgical.comVantis—
2026-09-29 02:31:57Zcertification_certificateissuedmarco.silva@corvetasurgical.comVantis—
2026-09-29 02:31:57Zcertification_completion_recordissuedmarco.silva@corvetasurgical.comVantis—

Emails triggered by this step:

(Evidence matched by declared name — step timing not available or no events fell in window)

Email 1: Your signing code for LiraLock Implant System Certification

Template: Your_signing_code_for_LiraLock_Implant_System_Certification

Your signing code for LiraLock Implant System Certification

Screenshots:

step 03 verify identity gate

step 03 signing code sent

step 03 document page

step 03 doc acknowledged

step 03 quiz failed attempt

step 03 quiz passed

step 03 signature

step 03 replay refused

step 03 completed

step 03 certificate status

step 03 gate lifted

Video recording:


5. Step 4: Per-manufacturer isolation — ✅ PASS

Section titled “5. Step 4: Per-manufacturer isolation — ✅ PASS”

What this step proves:

The certification gate is scoped to the requiring manufacturer. The same representative could act for the second manufacturer before, during, and after certification; both manufacturers are selectable at the end of the run.

Screenshots:

step 04 both manufacturers

Video recording:


6. Step 5: Completion-record export — ✅ PASS

Section titled “6. Step 5: Completion-record export — ✅ PASS”

What this step proves:

The manufacturer exports certification completion records. The CSV download contains one row per completion record — including the newly certified representative — with version, completion date, and signature integrity hash, matching the database. A background PDF bundle job is requested and completes with a downloadable ZIP.

Audit events generated by this step:

(Evidence scoped to step execution window: 2026-09-29T02:32:14.013Z → 2026-09-29T02:32:16.870Z)

TimeTypeActionUserOrgPerformed
2026-09-29 02:32:14Zexportexport:certification-completion-recordsmark.manufacturer@vantismedical.comVantis—
2026-09-29 02:32:16Zbulk_exportrequestedmark.manufacturer@vantismedical.comVantis—

Screenshots:

step 05 export card

step 05 zip requested

step 05 zip status

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.

Certification block existed before it was lifted this run — ✅ PASS

Section titled “Certification block existed before it was lifted this run — ✅ PASS”

Assertion: A pending_certification hold is recorded earlier in the run than the active completion transition

SELECT to_status, reason_code, created_at
FROM organization_representation_request_status_changes
WHERE relationship_id = $1 AND created_at > NOW() - INTERVAL '2 hours'
ORDER BY created_at
to_statusreason_codecreated_at
activecertification_completed2026-09-29T02:31:54.918Z

Gate actively evaluated the representative during the run — ✅ PASS

Section titled “Gate actively evaluated the representative during the run — ✅ PASS”

Assertion: The per-manufacturer action gate recorded decisions for the representative while ordering flows were exercised

SELECT action, payload->>'reason' AS reason
FROM audit_events
WHERE action = 'representatives.gate_rep_action'
AND user_id = $1
AND created_at > NOW() - INTERVAL '2 hours'
ORDER BY created_at DESC LIMIT 10
actionreason
representatives.gate_rep_actionno_blocking_relationship

No order or billing rows were created while the representative was gated — ✅ PASS

Section titled “No order or billing rows were created while the representative was gated — ✅ PASS”

Assertion: Zero order requests and zero billing orders exist for the gated representative

SELECT
(SELECT COUNT(*) FROM order_requests
WHERE requested_by_user_id = $1
AND created_at > NOW() - INTERVAL '2 hours') AS order_count,
(SELECT COUNT(*) FROM billing_orders
WHERE created_by_user_id = $1
AND created_at > NOW() - INTERVAL '2 hours') AS billing_count
order_countbilling_count
00

Immutable certification record created on completion — ✅ PASS

Section titled “Immutable certification record created on completion — ✅ PASS”

Assertion: Exactly one record exists for the rep, on version 2, with a completion timestamp, signature reference, and form submission

SELECT r.rep_user_id, r.certification_id, r.certification_version_id,
r.completed_at, r.expires_at, r.signature_ref, r.form_submission_id
FROM certification_records r
WHERE r.rep_user_id = $1 AND r.certification_id = $2
rep_user_idcertification_idcertification_version_idcompleted_atexpires_atsignature_refform_submission_id
ce000001-0000-4000-8000-000000000002ce000100-0000-4000-8000-000000000001ce000200-0000-4000-8000-0000000000022026-09-29T02:31:54.929Z2028-09-29T00:00:00.000Z01a0eb01-2132-7b31-877d-f31ae2c707f801a0eb01-1109-70a8-a813-f763c4b01bfa

Status change recorded: pending_certification to active on completion — ✅ PASS

Section titled “Status change recorded: pending_certification to active on completion — ✅ PASS”

Assertion: A status-change row with reason_code certification_completed moved the relationship to active

SELECT from_status, to_status, reason_code
FROM organization_representation_request_status_changes
WHERE relationship_id = $1
AND to_status = 'active' AND reason_code = 'certification_completed'
AND created_at > NOW() - INTERVAL '2 hours'
from_statusto_statusreason_code
pending_certificationactivecertification_completed

Document acknowledgment timestamps recorded with the document ID — ✅ PASS

Section titled “Document acknowledgment timestamps recorded with the document ID — ✅ PASS”

Assertion: A document view row exists for the acknowledged training document with a first-seen timestamp

SELECT upload_id, first_viewed_at, last_viewed_at
FROM form_document_views
WHERE user_id = $1 AND form_definition_id = $2
upload_idfirst_viewed_atlast_viewed_at
ce000400-0000-4000-8000-0000000000022026-09-29T02:31:41.593Z2026-09-29T02:31:41.722Z

Quiz graded server-side: one failed attempt then a passing attempt — ✅ PASS

Section titled “Quiz graded server-side: one failed attempt then a passing attempt — ✅ PASS”

Assertion: At least one failed attempt (incorrect answers, no submission) precedes a passing attempt linked to the stored submission

SELECT passed, incorrect_count, form_submission_id
FROM form_quiz_attempts
WHERE user_id = $1 AND form_definition_id = $2
ORDER BY created_at
passedincorrect_countform_submission_id
false101a0eb01-1109-70a8-a813-f763c4b01bfa
true001a0eb01-1109-70a8-a813-f763c4b01bfa
true001a0eb01-1109-70a8-a813-f763c4b01bfa

Part 11 signing challenge verified, consumed, and linked to the signature — ✅ PASS

Section titled “Part 11 signing challenge verified, consumed, and linked to the signature — ✅ PASS”

Assertion: Exactly one consumed signing challenge exists: emailed, verified (window opened), consumed by the completion, linked to the completion signature, and storing only a sha256 hash — never the raw code

SELECT ch.code_hash, ch.email_sent_at, ch.verified_at, ch.signing_window_expires_at,
ch.consumed_at, ch.consumed_signature_id, r.signature_ref
FROM certification_signing_challenges ch
JOIN certification_records r
ON r.rep_user_id = ch.user_id AND r.certification_id = ch.certification_id
WHERE ch.user_id = $1 AND ch.certification_id = $2
AND ch.consumed_at IS NOT NULL
code_hashemail_sent_atverified_atsigning_window_expires_atconsumed_atconsumed_signature_idsignature_ref
5f882cd4b24abd65c4d931c40b216400a8527c425bc0eb3471097bc30a457f742026-09-29T02:31:37.429Z2026-09-29T02:31:40.853Z2026-09-29T06:31:40.853Z2026-09-29T02:31:54.932Z01a0eb01-2132-7b31-877d-f31ae2c707f801a0eb01-2132-7b31-877d-f31ae2c707f8

Signature captured with integrity hash — ✅ PASS

Section titled “Signature captured with integrity hash — ✅ PASS”

Assertion: The completion signature has meaning ‘Certification completion’, a signer name, an execution timestamp, and a SHA-256 hash

SELECT s.meaning, s.signer_name, s.sha256_hash, s.executed_at
FROM signatures s
JOIN certification_records r ON r.signature_ref = s.id::text
WHERE r.rep_user_id = $1 AND r.certification_id = $2
meaningsigner_namesha256_hashexecuted_at
Certification completionMarco Silva9b34dc26b713e354e6833fbd8da8717422eb648b95c34c07f4308755197cdbf22026-09-29T02:31:54.929Z

Signed-payload hash recomputes from the stored completion record and signature — ✅ PASS

Section titled “Signed-payload hash recomputes from the stored completion record and signature — ✅ PASS”

Assertion: signatures.signed_payload_sha256 equals the sha256 of the canonical signed payload (record id, certification, version, submission, signer, meaning, execution time, SVG hash) rebuilt from the stored rows, and the record completed_at equals the signature executed_at the hash binds (11.70)

SELECT r.id AS record_id, r.certification_id, r.certification_version_id,
r.form_submission_id, r.rep_user_id, r.completed_at,
s.meaning, s.executed_at, s.sha256_hash, s.signed_payload_sha256
FROM certification_records r
JOIN signatures s ON r.signature_ref = s.id::text
WHERE r.rep_user_id = $1 AND r.certification_id = $2
record_idcertification_idcertification_version_idform_submission_idrep_user_idcompleted_atmeaningexecuted_atsha256_hashsigned_payload_sha256
01a0eb01-2131-737b-95f7-636028f0aaadce000100-0000-4000-8000-000000000001ce000200-0000-4000-8000-00000000000201a0eb01-1109-70a8-a813-f763c4b01bface000001-0000-4000-8000-0000000000022026-09-29T02:31:54.929ZCertification completion2026-09-29T02:31:54.929Z9b34dc26b713e354e6833fbd8da8717422eb648b95c34c07f4308755197cdbf28db42d4e7b2c524d03ddac135cf729b83211019ad0184ca4b76cbaf76e87d87e

Refused signing re-authentication attempts audited with machine-readable reasons — ✅ PASS

Section titled “Refused signing re-authentication attempts audited with machine-readable reasons — ✅ PASS”

Assertion: The suite’s two refused completion replays are audited (11.300(d)): the replay without the signing cookie as ‘missing_code_cookie’, and the tampered replay with the resurrected (already-consumed) code as ‘no_challenge’

SELECT payload->>'reason' AS reason, created_at
FROM audit_events
WHERE event_type = 'certification' AND action = 'signing_reauth_failed'
AND user_id = $1 AND object_id = $2
AND created_at > NOW() - INTERVAL '2 hours'
ORDER BY created_at
reasoncreated_at
missing_code_cookie2026-09-29T02:31:56.327Z
no_challenge2026-09-29T02:31:56.360Z

Certificate and completion-record documents issued — ✅ PASS

Section titled “Certificate and completion-record documents issued — ✅ PASS”

Assertion: Both a certificate and a completion_record document were generated

SELECT document_type, status
FROM certification_documents
WHERE user_id = $1 AND organization_id = $2
AND created_at > NOW() - INTERVAL '2 hours'
document_typestatus
certificatecreated
completion_recordcreated

Second-manufacturer relationship untouched throughout — ✅ PASS

Section titled “Second-manufacturer relationship untouched throughout — ✅ PASS”

Assertion: The relationship with the second manufacturer remained active for the whole run

SELECT status, active FROM organization_representation_relationships WHERE id = $1
statusactive
activetrue

Completion-record export audited and a background bundle job was created — ✅ PASS

Section titled “Completion-record export audited and a background bundle job was created — ✅ PASS”

Assertion: The CSV export was audited and a certification-completion-records bulk export job was created

SELECT
(SELECT COUNT(*) FROM audit_events
WHERE event_type = 'export' AND action = 'export:certification-completion-records'
AND organization_id = $1 AND created_at > NOW() - INTERVAL '2 hours') AS csv_exports,
(SELECT COUNT(*) FROM bulk_exports
WHERE organization_id = $1 AND export_type = 'certification_completion_records'
AND created_at > NOW() - INTERVAL '2 hours') AS bundle_jobs
csv_exportsbundle_jobs
11

Export rows match certification records — ✅ PASS

Section titled “Export rows match certification records — ✅ PASS”

Assertion: The certification records the CSV was compared against (rep, version, completion date) are present

SELECT r.id, u.name AS rep_name, v.version_number, r.completed_at
FROM certification_records r
JOIN users u ON u.id = r.rep_user_id
JOIN certification_versions v ON v.id = r.certification_version_id
WHERE r.certification_id = $1
ORDER BY r.completed_at
idrep_nameversion_numbercompleted_at
ce000700-0000-4000-8000-000000000004Theo Larsen12025-12-03T02:23:22.269Z
ce000700-0000-4000-8000-000000000005Dana Whitfield22026-08-15T02:23:22.269Z
ce000700-0000-4000-8000-000000000003Elena Novak22026-08-30T02:23:22.269Z
01a0eb01-2131-737b-95f7-636028f0aaadMarco Silva22026-09-29T02:31:54.929Z

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 3: Certification completioncertification:signing_code_issued✅
Step 3: Certification completioncertification:signing_code_verified✅
Step 3: Certification completioncertification:signing_code_consumed✅
Step 3: Certification completioncertification:completed✅
Step 3: Certification completioncertification:signing_reauth_failed✅
Step 5: Completion-record exportexport:export:certification-completion-records✅

Each row asserts that a declared expectedEmailTemplates entry was matched (case-insensitive substring) by a captured email subject or template. A ❌ flips overall status to FAIL.

StepExpected TemplateFound
Step 3: Certification completionYour signing code✅

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-09-29T02:30:57.495Z

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

24 event(s) captured:

TimeTypeActionUserOrgObject IDPerformedReason
2026-09-29 02:31:04Zuser_loguser:loginmarco.silva@corvetasurgical.comCorveta Surgical Group——
2026-09-29 02:31:21Zuser_loguser:loginmarco.silva@corvetasurgical.comCorveta Surgical Group——
2026-09-29 02:31:31Zuser_loguser:loginmarco.silva@corvetasurgical.comCorveta Surgical Group——
2026-09-29 02:31:37Zcertificationsigning_code_issuedmarco.silva@corvetasurgical.comVantisce000100-0000-4000-8000-000000000001—
2026-09-29 02:31:37Zdecisioncertifications.signing_challenge.send_smsmarco.silva@corvetasurgical.comVantis01a0eb00-dca4-7981-9ba0-4fb9bbb1917bnono_phone_channel
2026-09-29 02:31:38Ztransactional_emailcertification_signing_code—Vantis01a0eb00-dca4-7981-9ba0-4fb9bbb1917b—
2026-09-29 02:31:40Zcertificationsigning_code_verifiedmarco.silva@corvetasurgical.comVantisce000100-0000-4000-8000-000000000001—
2026-09-29 02:31:50Zdecisionforms.grade_submissionmarco.silva@corvetasurgical.comVantisce000300-0000-4000-8000-000000000002yesall_answers_correct
2026-09-29 02:31:54Zcertificationcompletedmarco.silva@corvetasurgical.comVantis01a0eb01-2131-737b-95f7-636028f0aaad—
2026-09-29 02:31:54Zdecisioncertifications.complete_certification.issue_certificatemarco.silva@corvetasurgical.comVantis01a0eb01-2131-737b-95f7-636028f0aaadyesquiz_backed_completion
2026-09-29 02:31:54Zdecisioncertifications.complete_certification.mark_relationship_certifiedmarco.silva@corvetasurgical.comVantisce000002-0000-4000-8000-000000000002yesrelationship_pending_certification
2026-09-29 02:31:54Zorganization_representationstatus_changemarco.silva@corvetasurgical.comVantisce000002-0000-4000-8000-000000000002—Certification completed
2026-09-29 02:31:54Zcertificationsigning_code_consumedmarco.silva@corvetasurgical.comVantisce000100-0000-4000-8000-000000000001—
2026-09-29 02:31:54Zuser_logrep_relationship_certifiedmarco.silva@corvetasurgical.comVantis——Certification completed
2026-09-29 02:31:56Zcertificationsigning_reauth_failedmarco.silva@corvetasurgical.comVantisce000100-0000-4000-8000-000000000001—missing_code_cookie
2026-09-29 02:31:56Zcertificationsigning_reauth_failedmarco.silva@corvetasurgical.comVantisce000100-0000-4000-8000-000000000001—no_challenge
2026-09-29 02:31:57Zcertification_certificateissuedmarco.silva@corvetasurgical.comVantis01a0eb01-2158-7e51-95b1-e785dfaf8208—
2026-09-29 02:31:57Zcertification_completion_recordissuedmarco.silva@corvetasurgical.comVantis01a0eb01-215d-7731-b3c3-e203ac055bfb—
2026-09-29 02:32:03Zuser_loguser:loginmarco.silva@corvetasurgical.comCorveta Surgical Group——
2026-09-29 02:32:09Zuser_loguser:loginmark.manufacturer@vantismedical.comVantis——
2026-09-29 02:32:14Zexportexport:certification-completion-recordsmark.manufacturer@vantismedical.comVantisce000100-0000-4000-8000-000000000001—
2026-09-29 02:32:16Zbulk_exportrequestedmark.manufacturer@vantismedical.comVantis01a0eb01-7581-7128-b7ac-98705c5f998e—
2026-09-29 02:32:17Zbulk_exportstartedmark.manufacturer@vantismedical.comVantis01a0eb01-7581-7128-b7ac-98705c5f998e—
2026-09-29 02:32:17Zdecisionbulk_exports.run_bulk_export.claim_job—Vantis01a0eb01-7581-7128-b7ac-98705c5f998eyesclaimed_requested_job

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

1. Your signing code for LiraLock Implant System Certification

Section titled “1. Your signing code for LiraLock Implant System Certification”

Template: Your_signing_code_for_LiraLock_Implant_System_Certification

Your signing code for LiraLock Implant System Certification