URS-002 · Role-Based Access Control (Rep, Principal, Admin)
Title: Role-Based Access Control (Rep, Principal, Admin) Date: 2026-04-23T03:33:42.056Z Duration: 110.0s Overall Status: ✅ PASS
User Requirement
Section titled “User Requirement”The system shall enforce role‑based access control (such as, rep, principal, admin).
Source: User_Requirement_Specifications_ZuriMED_DeviceFlow.xlsx — the run below proves the system meets this requirement.
Environment
Section titled “Environment”- Inbox URL: http://localhost:61668
- Database: localhost:61669/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: Sales Rep login and navigation menu — ✅ PASS
Section titled “1. Step 1: Sales Rep login and navigation menu — ✅ PASS”What this step proves:
The Sales Representative role logs in and the sidebar navigation is inspected. Only items the role has permission to access are visible; administrative items such as Settings and Billing are hidden. This confirms that the application enforces role-based navigation visibility server-side.
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:33:49Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:33:56Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:04Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:12Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:21Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:28Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:36Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:43Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:51Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:59Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:35:12Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:35:26Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
Screenshots:

Video recording:
2. Step 2: Sales Rep can view orders — ✅ PASS
Section titled “2. Step 2: Sales Rep can view orders — ✅ PASS”What this step proves:
The Sales Rep navigates to the Orders page and it loads successfully without an error page. This confirms that the Sales Representative role includes the order-viewing permission and that permitted routes are accessible.
Screenshots:

Video recording:
3. Step 3: Sales Rep denied access to Role Management — ✅ PASS
Section titled “3. Step 3: Sales Rep denied access to Role Management — ✅ PASS”What this step proves:
The Sales Rep attempts to navigate directly to /settings/roles by URL, bypassing the hidden navigation link. The test captures the HTTP response status from the initial navigation and accepts either of the two legitimate server-side denial mechanisms: (a) the route loader renders an “Error Encountered” page because the org:manage_roles permission check failed, or (b) the request is redirected to /login because the auth guard invalidated the session. The screencast chapter for this step records which mechanism fired (and the observed HTTP status). Either response proves server-side enforcement, not just link hiding.
Screenshots:

Video recording:
4. Step 4: Sales Rep denied access to Billing — ✅ PASS
Section titled “4. Step 4: Sales Rep denied access to Billing — ✅ PASS”What this step proves:
The Sales Rep attempts to navigate directly to /billing by URL. The test captures the HTTP response status and accepts either the error-page or login-redirect denial mechanism. The screencast chapter records the observed mechanism and status. This confirms that billing permissions are enforced at the route level for non-admin roles regardless of how the user constructs the request.
Screenshots:

Video recording:
5. Step 5: Employee login and navigation menu — ✅ PASS
Section titled “5. Step 5: Employee login and navigation menu — ✅ PASS”What this step proves:
The Employee role logs in and the sidebar navigation is inspected. The Employee’s visible navigation items differ from the Sales Rep’s, confirming that each role has an independently configured permission set and that the navigation reflects that configuration accurately.
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:33:49Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:33:56Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:04Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:12Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:21Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:28Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:36Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:43Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:51Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:59Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:35:12Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:35:26Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
Screenshots:

Video recording:
6. Step 6: Employee can view orders — ✅ PASS
Section titled “6. Step 6: Employee can view orders — ✅ PASS”What this step proves:
The Employee navigates to the Orders page and it loads successfully, confirming that the Employee role includes the order-viewing permission and that access to shared features is properly granted across multiple roles.
Screenshots:

Video recording:
7. Step 7: Employee denied access to Role Management — ✅ PASS
Section titled “7. Step 7: Employee denied access to Role Management — ✅ PASS”What this step proves:
The Employee attempts to navigate directly to /settings/roles by URL. The test captures the HTTP response status and accepts either denial mechanism (error page or login redirect). The screencast chapter records which mechanism fired. This confirms that org:manage_roles is admin-only and the same server-side check applies regardless of which non-admin role makes the request.
Screenshots:

Video recording:
8. Step 8: Admin login and navigation menu — ✅ PASS
Section titled “8. Step 8: Admin login and navigation menu — ✅ PASS”What this step proves:
The Admin role logs in and the full sidebar navigation is inspected. All expected admin-level navigation items are present, confirming that the admin role is assigned the complete set of permissions needed to manage the organization.
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:33:49Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:33:56Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:04Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:12Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:21Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:28Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:36Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:43Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:51Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:59Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:35:12Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:35:26Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — |
Screenshots:

Video recording:
9. Step 9: Admin can access Settings — ✅ PASS
Section titled “9. Step 9: Admin can access Settings — ✅ PASS”What this step proves:
The Admin navigates to the Settings page and it loads without error. This confirms that the settings access permission is correctly assigned to the admin role and that the route loader grants access as expected.
Screenshots:

Video recording:
10. Step 10: Admin can access role management — ✅ PASS
Section titled “10. Step 10: Admin can access role management — ✅ PASS”What this step proves:
The Admin navigates to /settings/roles. The test asserts both the HTTP layer (the navigation returns a 2xx status from the route loader, proving the org:manage_roles permission check passed server-side) and the UI layer (the page renders its specific “Roles” heading, a “Create Role” action link, and either the roles table or the documented empty-state message). A broken page that merely contained the word “role” somewhere would fail these assertions. Together with Step 3 (same route denied for Sales Rep) this proves the permission is correctly gated both ways.
Screenshots:

Video recording:
11. Step 11: Anonymous user redirected to login — ✅ PASS
Section titled “11. Step 11: Anonymous user redirected to login — ✅ PASS”What this step proves:
An unauthenticated browser navigates directly to /orders/requests without a session cookie. The server-side route loader detects the missing authentication and redirects to /login. This confirms that authentication is required for all application routes and cannot be bypassed.
Screenshots:

Video recording:
12. Step 12: Sales Rep blocked from multiple restricted URLs — ✅ PASS
Section titled “12. Step 12: Sales Rep blocked from multiple restricted URLs — ✅ PASS”What this step proves:
The Sales Rep attempts to access four restricted URLs in sequence: /settings/roles, /settings/members, /billing, and /settings/products. Each request is blocked by the server-side permission check, and the test captures a separate screenshot for every URL so the compliance report has independent visual evidence per denial. Each screencast chapter also records which denial mechanism fired (error page vs. login redirect) along with the observed HTTP status. This confirms that RBAC enforcement is comprehensive across administrative routes, not limited to the pages tested individually in earlier steps.
Screenshots:




Video recording:
13. Step 13: Sales Rep blocked at HTTP layer by direct API calls — ✅ PASS
Section titled “13. Step 13: Sales Rep blocked at HTTP layer by direct API calls — ✅ PASS”What this step proves:
The Sales Rep issues direct HTTP GET requests to restricted SvelteKit routes using page.request.get (which bypasses client-side navigation and UI redirects). Each response is asserted to be a 401, 403, or a 3xx redirect to /login — any 2xx would indicate the backend permitted the request, which is the failure mode this step is designed to catch. The exact status code and Location header for each URL are written to step-13-api-enforcement.json alongside the report so a reviewer can cite the wire-level response. This proves that permission enforcement is server-side and cannot be bypassed by a user who avoids the UI.
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.
User-role assignments match test configuration — ✅ PASS
Section titled “User-role assignments match test configuration — ✅ PASS”Assertion: Bob=Sales Rep, Ryan=Employee, Dan=StellarTech Admin
SELECT u.email, u.name, r.name as role_name, r.id as role_id FROM user_roles ur JOIN users u ON u.id = ur.user_id JOIN roles r ON r.id = ur.role_id WHERE ur.user_id IN ($1, $2, $3) AND ur.organization_id = $4 ORDER BY u.email| name | role_name | role_id | |
|---|---|---|---|
| bob.kauffman@stellartech.com | Bob Kauffman | Sales Representative | d2e3f4a5-b6c7-8901-def0-123456789abc |
| dan.distributor@stellartech.com | Dan Distributor | StellarTech Admin | 40e1f2a3-b4c5-6789-4567-890123456789 |
| ryan.delauintana@stellartech.com | Ryan Delauintana | Employee | f4a5b6c7-d8e9-0123-f012-3456789abcde |
Permission counts follow role hierarchy — ✅ PASS
Section titled “Permission counts follow role hierarchy — ✅ PASS”Assertion: Sales Rep (9) < Employee (16) < Admin (96)
SELECT r.name as role_name, r.id as role_id, COUNT(p.permission) as permission_count FROM roles r LEFT JOIN permissions p ON p.actor_id = r.id WHERE r.id IN ($1, $2, $3) GROUP BY r.name, r.id ORDER BY permission_count ASC| role_name | role_id | permission_count |
|---|---|---|
| Sales Representative | d2e3f4a5-b6c7-8901-def0-123456789abc | 9 |
| Employee | f4a5b6c7-d8e9-0123-f012-3456789abcde | 16 |
| StellarTech Admin | 40e1f2a3-b4c5-6789-4567-890123456789 | 96 |
Admin has settings/billing permissions that Sales Rep lacks — ✅ PASS
Section titled “Admin has settings/billing permissions that Sales Rep lacks — ✅ PASS”Assertion: Admin should have org:manage_roles, billing:view, etc. while Sales Rep should not
SELECT r.name as role_name, r.id as role_id, p.permission FROM roles r JOIN permissions p ON p.actor_id = r.id WHERE r.id IN ($1, $2) AND p.permission IN ( 'org:manage_roles', 'org:manage_users', 'org:manage_organization_settings', 'billing:view', 'billing:create', 'forms:manage' ) ORDER BY r.name, p.permission| role_name | role_id | permission |
|---|---|---|
| StellarTech Admin | 40e1f2a3-b4c5-6789-4567-890123456789 | billing:create |
| StellarTech Admin | 40e1f2a3-b4c5-6789-4567-890123456789 | billing:view |
| StellarTech Admin | 40e1f2a3-b4c5-6789-4567-890123456789 | forms:manage |
| StellarTech Admin | 40e1f2a3-b4c5-6789-4567-890123456789 | org:manage_organization_settings |
| StellarTech Admin | 40e1f2a3-b4c5-6789-4567-890123456789 | org:manage_roles |
| StellarTech Admin | 40e1f2a3-b4c5-6789-4567-890123456789 | org:manage_users |
All test users scoped to same organization — ✅ PASS
Section titled “All test users scoped to same organization — ✅ PASS”Assertion: All three test users should belong to StellarTech Medical Solutions
SELECT u.email, o.name as org_name, ur.organization_id FROM user_roles ur JOIN users u ON u.id = ur.user_id JOIN organizations o ON ur.organization_id = o.id WHERE ur.user_id IN ($1, $2, $3) AND ur.organization_id = $4 ORDER BY u.email| org_name | organization_id | |
|---|---|---|
| bob.kauffman@stellartech.com | StellarTech Medical Solutions | b2c3d4e5-f6a7-8901-bcde-f12345678901 |
| dan.distributor@stellartech.com | StellarTech Medical Solutions | b2c3d4e5-f6a7-8901-bcde-f12345678901 |
| ryan.delauintana@stellartech.com | StellarTech Medical Solutions | b2c3d4e5-f6a7-8901-bcde-f12345678901 |
No orphaned permissions in StellarTech org — ✅ PASS
Section titled “No orphaned permissions in StellarTech org — ✅ PASS”Assertion: All permissions should reference valid roles
SELECT p.actor_id, p.permission, p.organization_id FROM permissions p WHERE p.organization_id = $1 AND NOT EXISTS ( SELECT 1 FROM roles r WHERE r.id = p.actor_id ) LIMIT 10No rows returned
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: Sales Rep login and navigation menu | user_log:user:login | ✅ |
| Step 5: Employee login and navigation menu | user_log:user:login | ✅ |
| Step 8: Admin login and navigation menu | 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:33:40.173Z
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 ASC12 event(s) captured:
| Time | Type | Action | User | Org | Object ID | Performed | Reason |
|---|---|---|---|---|---|---|---|
| 2026-04-23 03:33:49Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:33:56Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:34:04Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:34:12Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:34:21Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:34:28Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:34:36Z | user_log | user:login | ryan.delauintana@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:34:43Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:34:51Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:34:59Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:35:12Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:35:26Z | user_log | user:login | bob.kauffman@stellartech.com | StellarTech Medical Solutions | — | — |
Downloads
Section titled “Downloads”- audit-events.json
- report.md
- result.json
- screenshots-index.json
- step-13-api-enforcement.json
- step-timings.json