Test Cases: User Management
| Module | CORE-01 | URD | User Management URD |
|---|
1. Coverage Summary
| Area | URD reqs | Test cases | Covered |
|---|---|---|---|
Authentication (AUTH) | 14 | 13 | ⚠️ |
User Account (USR) | 11 | 12 | ✅ |
Roles & Scoping (ROLE) | 8 | 8 | ✅ |
Employee Management (EMP) | 8 | 8 | ✅ |
Customer Management (CUS) | 6 | 6 | ✅ |
User Configuration (CFG) | 3 | 3 | ✅ |
Priority = P1 (critical) / P2 (major) / P3 (minor). Steps use Given / When / Then.
2. Test Cases
2.1 Authentication
| TC ID | URD ref | Scenario | Steps | Expected | P |
|---|---|---|---|---|---|
| TC-AUTH-001 | URD-AUTH-001 | Sign-up with valid username + password | Given a new user; When they sign up | Account created; Owner role assigned | P1 |
| TC-AUTH-002 | URD-AUTH-001 | Sign-up with a taken username | Given a username already registered; When a new user signs up with it | Rejected; identifier already in use | P1 |
| TC-AUTH-003 | URD-AUTH-002, URD-CFG-001 | Sign-up creates everything together | Given a valid sign-up; When it completes | Account, profile, identifiers, and default settings all exist | P1 |
| TC-AUTH-004 | URD-AUTH-003 | Atomic sign-up rollback | Given a sign-up where one step fails; When the transaction runs | Nothing is created — full rollback | P1 |
| TC-AUTH-005 | URD-AUTH-004 | Sign-in with valid credentials | Given a verified user; When they sign in with identifier + password | Authentication succeeds | P1 |
| TC-AUTH-006 | URD-AUTH-004 | Sign-in with wrong password | Given a registered user; When they sign in with a wrong password | Rejected; error does not reveal whether the account exists | P1 |
| TC-AUTH-007 | URD-AUTH-005 | Token carries scope | Given a successful sign-in; When the token is inspected | Token contains user ID, roles, organization IDs, merchant IDs | P1 |
| TC-AUTH-008 | URD-AUTH-006 | Passwords are hashed | Given a created account; When credential storage is inspected | Password is stored hashed, never in plain text | P1 |
| TC-AUTH-009 | URD-AUTH-007 | Change password — correct current | Given an authenticated user; When they change password with the correct current one | Updated; user signs in with the new password | P1 |
| TC-AUTH-010 | URD-AUTH-007 | Change password — wrong current | Given an authenticated user; When they supply a wrong current password | Rejected; current password incorrect | P1 |
| TC-AUTH-011 | URD-AUTH-008, URD-USR-005 | Verify email via OTP | Given an unverified email; When the user requests and submits the correct OTP | Email identifier marked verified | P1 |
| TC-AUTH-012 | URD-AUTH-010 | Forgot-password reset | Given a user who forgot their password; When they request, verify the code, and set a new one | Password reset; user signs in with the new password | P1 |
| TC-AUTH-013 | URD-AUTH-012 | Last sign-in recorded | Given a successful sign-in; When user details are viewed | Last sign-in timestamp is updated and visible | P2 |
Known gap — email verification on sign-up
Email verification is currently disabled on sign-up in code, while sign-in requires a verified identifier. A user who signs up and then tries to sign in by email may be blocked until the email is verified through a separate flow. TC-AUTH-011 covers the verification flow itself; the sign-up→sign-in-by-email path is a known defect, not a passing case. See developer docs.
2.2 User Account
| TC ID | URD ref | Scenario | Steps | Expected | P |
|---|---|---|---|---|---|
| TC-USR-001 | URD-USR-001 | Unique system ID | Given an account is created; When it is inspected | A unique, immutable, never-reused ID is assigned | P1 |
| TC-USR-002 | URD-USR-002 | Multiple identifiers | Given a user with an email; When a phone is added | Both identifiers stored; user can be looked up by either | P1 |
| TC-USR-003 | URD-USR-003 | Email uniqueness | Given user A owns an email; When user B registers with the same email | Rejected; email already in use | P1 |
| TC-USR-004 | URD-USR-003 | Phone uniqueness | Given user A owns a phone; When user B adds the same phone | Rejected; identifier unique per type | P2 |
| TC-USR-005 | URD-USR-004 | Username auto-verified | Given a new account; When the username identifier is inspected | Username is verified immediately | P1 |
| TC-USR-006 | URD-USR-005 | Email starts unverified | Given a newly added email; When inspected before verification | Status is unverified until OTP is completed | P1 |
| TC-USR-007 | URD-USR-006 | View / update profile | Given an authenticated user; When they update first name and locale | Profile updated; changes reflected on next read | P1 |
| TC-USR-008 | URD-USR-007 | Deactivate then reactivate | Given an ACTIVATED account; When an admin deactivates then reactivates it | Status moves ACTIVATED → DEACTIVATED → ACTIVATED; sign-in restored | P1 |
| TC-USR-009 | URD-USR-007 | Block for security | Given an ACTIVATED account; When an admin blocks it | Status becomes BLOCKED; user cannot sign in | P1 |
| TC-USR-010 | URD-USR-008 | Deactivated cannot sign in | Given a DEACTIVATED account; When the user signs in | Rejected; account deactivated | P1 |
| TC-USR-011 | URD-USR-009 | Soft-delete preserves data | Given a user with data is removed; When records are checked | Data preserved; no physical deletion | P1 |
| TC-USR-012 | URD-USR-011 | Archived is terminal | Given an ARCHIVED account; When an admin attempts to reactivate it | Rejected; ARCHIVED cannot be reactivated | P2 |
QE finding — identifier uniqueness on update
The identifier-uniqueness check on update has inverted logic — it can allow a duplicate email / phone across users during an update. TC-USR-003 / TC-USR-004 cover the create path; the update path is a known defect.
2.3 Roles & Scoping
| TC ID | URD ref | Scenario | Steps | Expected | P |
|---|---|---|---|---|---|
| TC-ROLE-001 | URD-ROLE-001 | Eight fixed roles exist | Given an initialized system; When roles are listed | Super Admin, Admin, Operator, Owner, Cashier, Employee, Customer, Guest exist | P1 |
| TC-ROLE-002 | URD-ROLE-002 | Internal account creation respects hierarchy | Given an Admin; When they create an Operator | Operator created; an Operator cannot create another Operator | P1 |
| TC-ROLE-003 | URD-ROLE-003 | Internal users bypass filters | Given a Super Admin; When they query data | All data returned system-wide; no scope filtering applied | P1 |
| TC-ROLE-004 | URD-ROLE-004 | Owner scoped to own org | Given Owner of Org X; When they query Org Y data | Access denied; Owner limited to own org and its merchants | P1 |
| TC-ROLE-005 | URD-ROLE-005 | Employee scoped to merchants | Given an employee assigned to Merchant A; When they list orders across A and B | Only Merchant A orders returned | P1 |
| TC-ROLE-006 | URD-ROLE-006 | Counts are scope-filtered | Given an employee on Merchant A only; When they request a product count | Count includes only Merchant A products | P1 |
| TC-ROLE-007 | URD-ROLE-007 | No self-escalation | Given an Employee; When they try to grant themselves Owner | Rejected; cannot manage a role at or above own priority | P1 |
| TC-ROLE-008 | URD-ROLE-008 | Owner auto-assigned at sign-up | Given a completed sign-up; When the user's roles are inspected | Owner role is assigned automatically | P1 |
2.4 Employee Management
| TC ID | URD ref | Scenario | Steps | Expected | P |
|---|---|---|---|---|---|
| TC-EMP-001 | URD-EMP-001 | Owner creates employee | Given an Owner; When they create an employee | Account created with Employee role, linked to the organization | P1 |
| TC-EMP-002 | URD-EMP-002 | Employee linked to merchants | Given an employee assigned to A and B; When the mapping is inspected | Employee mapped to org and to Merchants A and B | P1 |
| TC-EMP-003 | URD-EMP-003 | Cross-merchant access denied | Given an employee on Merchant A only; When they access Merchant B data | Access denied | P1 |
| TC-EMP-004 | URD-EMP-004 | Employee sign-in | Given an employee with valid credentials; When they sign in | Authenticated with access scoped to assigned merchants | P1 |
| TC-EMP-005 | URD-EMP-005 | Query filtered by assignment | Given an employee on Merchant A; When they query orders | Only Merchant A orders returned; B not visible | P1 |
| TC-EMP-006 | URD-EMP-006 | Reassign merchants | Given an employee on Merchant A; When the Owner updates to A + B | Previous assignments replaced; employee now sees A and B; no new account | P2 |
| TC-EMP-007 | URD-EMP-007 | Deactivate / remove employee | Given an active employee; When the Owner deactivates then removes them | Employee can no longer sign in; record soft-deleted; data preserved | P1 |
| TC-EMP-008 | URD-EMP-008 | Ownership validation | Given an Owner; When they create an employee for a merchant they do not own | Rejected; org / merchant ownership validated | P1 |
2.5 Customer Management
| TC ID | URD ref | Scenario | Steps | Expected | P |
|---|---|---|---|---|---|
| TC-CUS-001 | URD-CUS-001 | Owner creates customer | Given an Owner; When they create a customer | Customer account created and linked to the organization | P1 |
| TC-CUS-002 | URD-CUS-002 | Customer role auto-assigned | Given a created customer; When the account is inspected | Customer role assigned; linked to the organization | P1 |
| TC-CUS-003 | URD-CUS-003 | Customer profile | Given a customer; When the profile is inspected | Profile includes name and contact details | P2 |
| TC-CUS-004 | URD-CUS-004 | Update / soft-delete customer | Given a customer; When the Owner updates contact info then removes them | Changes saved; customer soft-deleted, data preserved | P1 |
| TC-CUS-005 | URD-CUS-005 | Promote sale customer | Given a sale-level customer; When promotion is triggered | Full user created with Customer role | P2 |
| TC-CUS-006 | URD-CUS-006 | Promotion conflict check | Given a sale customer whose email is already taken; When promotion runs | Blocked with a conflict error | P2 |
Known gap — customers cannot sign in
Customer accounts are created without credentials or login identifiers, so they cannot currently authenticate. TC-CUS-001..004 verify customer-record management by the Owner; customer self-service sign-in is not yet supported. See developer docs.
2.6 User Configuration
| TC ID | URD ref | Scenario | Steps | Expected | P |
|---|---|---|---|---|---|
| TC-CFG-001 | URD-CFG-001 | Defaults created on registration | Given a new sign-up; When the account is created | A default set of user configurations exists | P1 |
| TC-CFG-002 | URD-CFG-002 | Config uniqueness per user | Given a user with configs; When a duplicate code is added | Rejected; codes are unique per user | P2 |
| TC-CFG-003 | URD-CFG-003 | View / update configs | Given an authenticated user; When they read and update a setting | Setting is returned and the update persists | P2 |
3. Traceability
Every Must requirement must map to ≥1 test case. Gaps are flagged explicitly.
| URD requirement | Test case(s) | Status |
|---|---|---|
| URD-AUTH-001 | TC-AUTH-001, TC-AUTH-002 | ✅ Covered |
| URD-AUTH-002 | TC-AUTH-003 | ✅ Covered |
| URD-AUTH-003 | TC-AUTH-004 | ✅ Covered |
| URD-AUTH-004 | TC-AUTH-005, TC-AUTH-006 | ✅ Covered |
| URD-AUTH-005 | TC-AUTH-007 | ✅ Covered |
| URD-AUTH-006 | TC-AUTH-008 | ✅ Covered |
| URD-AUTH-007 | TC-AUTH-009, TC-AUTH-010 | ✅ Covered |
| URD-AUTH-008 | TC-AUTH-011 | ✅ Covered |
| URD-AUTH-009 | — | ⚠️ Uncovered — phone OTP verification (mirror of TC-AUTH-011) |
| URD-AUTH-010 | TC-AUTH-012 | ✅ Covered |
| URD-AUTH-011 | — | ⚠️ Uncovered (Should) — link account |
| URD-AUTH-012 | TC-AUTH-013 | ✅ Covered |
| URD-AUTH-013 | — | ⚠️ Planned — 2FA enforcement not built |
| URD-AUTH-014 | — | ⚠️ Planned — OAuth login not built |
| URD-USR-001 | TC-USR-001 | ✅ Covered |
| URD-USR-002 | TC-USR-002 | ✅ Covered |
| URD-USR-003 | TC-USR-003, TC-USR-004 | ✅ Covered |
| URD-USR-004 | TC-USR-005 | ✅ Covered |
| URD-USR-005 | TC-USR-006, TC-AUTH-011 | ✅ Covered |
| URD-USR-006 | TC-USR-007 | ✅ Covered |
| URD-USR-007 | TC-USR-008, TC-USR-009, TC-USR-012 | ✅ Covered |
| URD-USR-008 | TC-USR-010 | ✅ Covered |
| URD-USR-009 | TC-USR-011 | ✅ Covered |
| URD-USR-010 | TC-USR-007 | ✅ Covered |
| URD-USR-011 | TC-USR-012 | ✅ Covered |
| URD-ROLE-001 | TC-ROLE-001 | ✅ Covered |
| URD-ROLE-002 | TC-ROLE-002 | ✅ Covered |
| URD-ROLE-003 | TC-ROLE-003 | ✅ Covered |
| URD-ROLE-004 | TC-ROLE-004 | ✅ Covered |
| URD-ROLE-005 | TC-ROLE-005 | ✅ Covered |
| URD-ROLE-006 | TC-ROLE-006 | ✅ Covered |
| URD-ROLE-007 | TC-ROLE-007 | ✅ Covered |
| URD-ROLE-008 | TC-ROLE-008 | ✅ Covered |
| URD-EMP-001 | TC-EMP-001 | ✅ Covered |
| URD-EMP-002 | TC-EMP-002 | ✅ Covered |
| URD-EMP-003 | TC-EMP-003 | ✅ Covered |
| URD-EMP-004 | TC-EMP-004 | ✅ Covered |
| URD-EMP-005 | TC-EMP-005 | ✅ Covered |
| URD-EMP-006 | TC-EMP-006 | ✅ Covered |
| URD-EMP-007 | TC-EMP-007 | ✅ Covered |
| URD-EMP-008 | TC-EMP-008 | ✅ Covered |
| URD-CUS-001 | TC-CUS-001 | ✅ Covered |
| URD-CUS-002 | TC-CUS-002 | ✅ Covered |
| URD-CUS-003 | TC-CUS-003 | ✅ Covered |
| URD-CUS-004 | TC-CUS-004 | ✅ Covered |
| URD-CUS-005 | TC-CUS-005 | ✅ Covered |
| URD-CUS-006 | TC-CUS-006 | ✅ Covered |
| URD-CFG-001 | TC-CFG-001 | ✅ Covered |
| URD-CFG-002 | TC-CFG-002 | ✅ Covered |
| URD-CFG-003 | TC-CFG-003 | ✅ Covered |
Open gaps: one Must requirement (URD-AUTH-009, phone OTP) lacks a dedicated test case — add a TC mirroring TC-AUTH-011. URD-AUTH-011 (link account, Should) is also uncovered. URD-AUTH-013/014 are Planned and intentionally untested.