01 — User Roles

The system ships with eleven roles out of the box: one administrative super-role plus ten workflow roles modelled after real-world responsibilities. Each role bundles a set of permissions; the permissions matrix lists exactly which actions each role grants.

This doc is people-first: who each role represents, what their day looks like, what they want to accomplish, and where in the UI they spend time.

Roles are additive. A user can hold multiple roles at once. A real-life "ops manager" might be assigned Transfer Approver + Audit Planner + Audit Reviewer + Checkout Issuer. The system unions every permission across the roles a user holds, so wearing more hats only ever expands what they can do.

Index

  1. Super Admin (admin user)
  2. Transfer Requester
  3. Transfer Approver
  4. Transfer Receiver
  5. Audit Planner
  6. Auditor (desktop)
  7. Audit Reviewer
  8. Mobile Auditor
  9. Checkout Issuer
  10. Checkout Returner
  11. Asset Custodian
  12. Combining roles in real life
  13. Demo accounts (development only)

Super Admin

The single account that ships with every fresh install. Holds every permission in the system.

Persona. Sara is the IT operations lead. She owns the Asset Tracking deployment end-to-end: master data, user provisioning, role design, system settings, troubleshooting.

Goals.

  • Set the system up correctly the first time (organizations, locations, classifications, vendors, manufacturers, statuses).
  • Onboard new users, give them the right roles, deactivate them when they leave.
  • Tune notifications (templates, email provider, languages).
  • Step in to fix data when a user files a ticket.

User stories.

  • As a Super Admin, I want to import our existing org chart and locations from Excel so I don't re-key 200 rows by hand.
  • As a Super Admin, I want to create a new role for "Branch Manager" that combines Transfer Approver + Checkout Issuer permissions, so I don't grant each permission user-by-user.
  • As a Super Admin, I want to set Arabic as the secondary language so every bilingual field captures both English and Arabic and our staff see Arabic in the UI when they pick it.
  • As a Super Admin, I want to edit a notification template to add our company logo and a "View transfer" link, so emails look on-brand.
  • As a Super Admin, I want to view the audit log to find out who changed an asset's location at 2 AM last Friday.

Day in the life.

Sara starts at the Dashboard to scan tile counts (open audit results, in-progress work orders, pending transfers). Most days she's in Settings → Hierarchy verifying nothing has been added at the wrong level, or in Users processing a help-desk ticket — usually a permission re-issue or password reset. Once a quarter she imports refreshed master data from Excel and reviews the Audit log for sensitive changes.

Where she spends time.

  • /users, /users/:id — onboarding, role assignment, session revocation
  • /roles, /roles/:id — role design (the redesigned permissions editor with vertical-stacked module cards)
  • /permissions — read-only catalog browser, useful when designing roles
  • /organizations, /locations, /classifications, /vendors, /manufacturers — master data CRUD
  • /settings/hierarchy, /settings/languages, /settings/translations, /settings/notification-templates, /settings/email
  • /audit-log, /login-audit — forensics

What she doesn't do (typically). Doesn't run audits in the field. Doesn't issue check-outs. The role can but in practice she delegates these.


Transfer Requester

A field user who needs to move assets between organizations or locations.

Persona. Omar is an office manager. His team got a new lead, and the lead's old laptop, monitor, and chair need to move from the old desk in Building A Floor 2 to a new desk in Building C Floor 5. Across organizations sometimes too — when an employee transfers between departments their assets follow.

Goals.

  • Capture a transfer request quickly while standing at the old desk with the assets in front of him.
  • See the request progress through approval and receipt without chasing people on chat.
  • Cancel if plans change.

User stories.

  • As a Transfer Requester, I want to create a draft transfer with a list of assets, a destination, and a reason so the right approver can act on it.
  • As a Transfer Requester, I want to add or remove asset lines while the transfer is still a draft so I can fix mistakes without starting over.
  • As a Transfer Requester, I want to submit the transfer for approval when I'm ready, so the approver gets notified.
  • As a Transfer Requester, I want to see the current status of my transfers — submitted, approved, in-transit, completed, rejected — so I know whether I can move on.
  • As a Transfer Requester, I want to cancel a draft or submitted transfer if I realize the request was a mistake.

Day in the life.

Omar opens Transfers, clicks "New transfer", picks the from/to organization and location, types a reason (rich-text, so he can paste a screenshot of the email asking for the move), then adds the affected assets one by one (or with a multi-select). He saves as draft, double-checks, then clicks Submit. The approver gets an email and an in-app notification. Omar sees the transfer flip to "Submitted" in his list.

Where he spends time.

  • /transfers — list, filtered to "Mine only" by default
  • /transfers/:id — detail, where he edits lines or submits

What he doesn't see. No Approve/Reject buttons. No Receive buttons. He sees status changes but doesn't drive them.


Transfer Approver

A manager who decides whether a proposed transfer should happen.

Persona. Nadia is the asset-control supervisor. She owns asset placement decisions for her cost center. When someone wants to move assets out of (or into) her area, she signs off.

Goals.

  • See submitted transfers waiting on her approval at a glance.
  • Read the requester's reason and the affected asset list.
  • Approve or reject with a note.

User stories.

  • As a Transfer Approver, I want to be notified by email and in-app when a transfer needs my approval so I don't have to poll the page.
  • As a Transfer Approver, I want to see the requester, reason, source/destination, and full asset line list before deciding so I'm not approving blindly.
  • As a Transfer Approver, I want to approve a transfer in one click — assuming I'm satisfied — so it can move into transit.
  • As a Transfer Approver, I want to reject a transfer with a written reason that the requester sees, so they understand why and can correct.
  • As a Transfer Approver, I want to filter the transfer list by status = Submitted so my review queue is one click away.

Day in the life.

Nadia gets the email "Transfer XFER-000043 awaiting your approval". She opens the link, lands on the transfer detail, scans the from/to + reason + line list, and either clicks Approve (system auto-advances to InTransit) or Reject with a typed reason. The requester gets notified.

Where she spends time.

  • /transfers?status=Submitted — her queue
  • /transfers/:id — review + decision

What she doesn't do. Doesn't create transfers (someone else's job). Doesn't receive at the destination. Doesn't complete the transfer.


Transfer Receiver

Someone at the destination who confirms the assets actually arrived.

Persona. Khalid runs the receiving side. When approved transfers land at his location, he physically inspects each asset, marks lines as Ok / Damaged / Missing, then completes the transfer once every line is accounted for.

Goals.

  • See approved transfers heading his way.
  • Mark each line received with a status and optional notes.
  • Mark the whole transfer complete when done — which writes the new location/organization back to each asset's record.

User stories.

  • As a Transfer Receiver, I want to see only approved / in-transit transfers heading to my location so my inbox isn't clogged with unrelated traffic.
  • As a Transfer Receiver, I want to receive a single line as Ok/Damaged/Missing with notes so the audit trail is precise even when one item arrived broken.
  • As a Transfer Receiver, I want to bulk-receive every line as Ok when everything looks fine, so I don't click through 30 items.
  • As a Transfer Receiver, I want to complete the transfer so the asset's location and organization update everywhere in the system and the original requester is notified.

Day in the life.

A delivery arrives. Khalid opens Transfers, finds the one in InTransit for his location, opens it, walks through the line list with the truck driver, marks each line, then clicks Complete. The system writes location/organization changes to every asset and emits a notification to the original requester.

Where he spends time.

  • /transfers?status=InTransit — his inbound queue
  • /transfers/:id — line-by-line receive + complete

What he doesn't do. Doesn't approve. Doesn't reject (a damaged-line note isn't a rejection). Doesn't change the transfer's destination.


Audit Planner

Plans physical inventory audits and assigns them to field staff.

Persona. Reem is the internal-audit lead. Quarterly she runs a count of every laptop in the building. Twice a year she audits a specific organization. Her job is to define the scope of each audit and assign it to one of her field auditors.

Goals.

  • Define a clear scope (a building, a department, a list of asset codes, or "every asset of classification X within organization Y").
  • See how many assets the scope resolves to before committing to it.
  • Assign the audit to the right auditor.
  • Track which audits are still open vs. completed.

User stories.

  • As an Audit Planner, I want to create a plan with a name, priority, and one or more scope rules so the right assets get audited.
  • As an Audit Planner, I want to preview how many assets a scope will resolve to before saving — so I don't accidentally assign a 5,000-asset audit to one person.
  • As an Audit Planner, I want to add a Combined scope intersecting Organization + Location when I want to audit "every asset of organization X at location Y" instead of separately.
  • As an Audit Planner, I want to assign a plan to a specific auditor (one active assignment per plan) so two auditors don't race each other.
  • As an Audit Planner, I want to cancel an assignment if the auditor goes on leave, so I can re-assign without confusion.
  • As an Audit Planner, I want to see which plans are in progress vs. completed to track team workload.

Day in the life.

Reem opens Audit Plans → New, fills in name + priority, adds a Location scope (Building B, include children = true), clicks Preview scope to confirm "412 assets in scope", saves the plan. From the plan detail, she clicks Assign and picks Layla (a Mobile Auditor). Layla gets notified. Reem checks back over the week to see assignments flip to Submitted, then In Review, then Completed.

Where she spends time.

  • /audit-plans — list, filtered by status
  • /audit-plans/new — multi-step plan creation with scope preview
  • /audit-plans/:id — assignments tab
  • /users (read-only) — to look up auditors when assigning

What she doesn't do. Doesn't run the audit herself (that's the Auditor / Mobile Auditor). Doesn't review submitted results (that's the Audit Reviewer). Doesn't write back observations to the asset (that's a side effect of Approve in review).


Auditor (desktop)

Runs an assigned audit using the desktop UI rather than the mobile shell.

Persona. Tariq is an asset clerk. He's not in the field much; he handles audits where the assets are right next to his desk — server room equipment, conference-room AV gear. He uses the desktop UI because typing is faster than scanning when he's at a workstation.

Goals.

  • See his assignments and pick one up.
  • For each expected asset, record the outcome (Found, Not found, Location/Org mismatch) plus a condition rating and notes.
  • Add "extra finding" rows for assets he found that weren't in the scope.
  • Submit the result once he's done.

User stories.

  • As an Auditor, I want to see only my own assignments so I don't get distracted by everyone else's work.
  • As an Auditor, I want to see each expected asset with its expected location/org/classification so I know what reality is supposed to look like.
  • As an Auditor, I want to set per-asset Outcome, Condition rating (1-5), and Notes so the reviewer has the full picture.
  • As an Auditor, I want to add extra-finding rows for assets I scanned that aren't in my scope so the asset record can be corrected.
  • As an Auditor, I want to submit the assignment when I'm done and have the system stop me if any extra-finding row is missing the asset id.
  • As an Auditor, I want to see the result page after my submission if I have read access, so I can spot-check before the reviewer opens it.

Day in the life.

Tariq opens My Audits, picks the most recent assignment, reviews the expected asset list, walks the rack, ticks each row with the right outcome and condition, adds two "extra" rows for unexpected assets he spotted. He clicks Submit. The reviewer is notified.

Where he spends time.

  • /my-audits — his queue
  • /audit-assignments/:id — the working surface (expected + extras tables)
  • /audit-results/:id (read) — to confirm what he submitted

What he doesn't do. Doesn't approve his own work. Doesn't see other auditors' assignments. Doesn't see the audit log.


Audit Reviewer

Reviews submitted audit results line by line and decides what gets written back to the asset records.

Persona. Hala is a senior asset analyst. Auditors submit; she scrutinizes. Her decisions are what flips reality on the asset record — approve a "LocationMismatch" line and the asset's LocationId actually changes.

Goals.

  • See her review queue.
  • Per result, walk every line with the auditor's outcome, condition rating, notes, and photos.
  • Approve, Reject, or Modify each line. Modify lets her override the auditor's observed location/org if she has additional info.
  • Bulk-approve obvious lines so she's not clicking 200 buttons.

User stories.

  • As an Audit Reviewer, I want to see all submitted results awaiting review filtered by review status, so I work on the oldest first.
  • As an Audit Reviewer, I want to filter the line list within a result by outcome, identification method, and "decided / not decided" so I can focus on the discrepancies first.
  • As an Audit Reviewer, I want to see the auditor's photos thumbnailed inline so I can assess "Damaged" claims without clicking each line.
  • As an Audit Reviewer, I want to Approve a line with one click when the auditor's call is right.
  • As an Audit Reviewer, I want to Modify a line — overriding the observed location with one I know is correct — when the auditor was close but slightly off.
  • As an Audit Reviewer, I want to bulk-approve every "Found" line in one call so I don't waste time on the obvious cases.
  • As an Audit Reviewer, I want to be notified when an auditor submits so I can pick up the work promptly.

Day in the life.

Hala gets the email "Audit result AR-000007 has been submitted and is ready for your review". She opens the link, walks the lines starting with the discrepancies (filter outcome ≠ Found), approves most, modifies two where she knows better, rejects one as wrong (the auditor mis-read a photo). When all lines are decided, the assignment flips to Completed, the plan rolls up, and the original auditor gets a "your audit was approved" notification.

Where she spends time.

  • /pending-reviews — her queue
  • /audit-results/:id — line-by-line decisions

What she doesn't do. Doesn't write asset history rows manually (the Approve action does it via the audit pipeline). Doesn't create plans. Doesn't run audits.


Mobile Auditor

The same person as Auditor — but their entire UI is the mobile shell.

Persona. Layla is a roving asset auditor. Most days she's in a warehouse or campus, walking aisles with her phone. She has the UserType = Mobile flag, which means the moment she logs in she lands in /mobile and the desktop shell auto-redirects her if she ever tries to navigate there.

Goals.

  • Log in on her phone and see the assignments she has open.
  • Pick one. The location filter narrows the list to "where I am right now".
  • Scan each asset's QR sticker with the camera (or type the code if the sticker is damaged).
  • Capture a photo if the asset is damaged or in the wrong place.
  • Move on, even if connectivity drops — her progress is saved as a draft on the server.
  • Submit when done.

User stories.

  • As a Mobile Auditor, I want my login to land me on /mobile, never the desktop shell, so I don't have to navigate around admin pages I can't use anyway.
  • As a Mobile Auditor, I want to filter the expected-asset list by Building / Floor / Room (the configured location levels) so I only see what's around me right now.
  • As a Mobile Auditor, I want to scan a QR code with the camera and have the system flip the matching expected row from "pending" to "found" automatically.
  • As a Mobile Auditor, I want distinct sound + vibration cues for "found" vs "extra" vs "mismatch" so I know what just happened without looking at the screen.
  • As a Mobile Auditor, I want to type the asset code manually when a sticker is unreadable, so I can still complete the audit.
  • As a Mobile Auditor, I want to attach photos to a row as evidence when something looks wrong.
  • As a Mobile Auditor, I want my scan progress persisted server-side, so I can close the app, take a break, and continue later — possibly from a different device.
  • As a Mobile Auditor, I want to download an Excel template, fill it offline, and upload it when the location has no signal, so I'm never blocked.
  • As a Mobile Auditor, I want to see a confirmation summary of "X scanned, Y missing, Z extra" before I submit, so I don't accidentally finalize an incomplete audit.

Day in the life.

Layla logs in on her phone. The mobile shell shows three open assignments. She picks the warehouse one. The location filter auto-locks to "Warehouse → Section B" because that's the deepest common ancestor of every expected asset. She walks the section, taps each pallet's QR sticker, hears a satisfying single beep on each "Found", a double-beep + buzz when she scans something not in scope. After lunch, an aisle without signal — she keeps scanning, the draft saves later when the signal returns. Done, she taps Submit, sees the summary, confirms. Hala gets the email.

Where she spends time.

  • /mobile — assignment list (mobile-shell home)
  • /mobile/assignment/:id — per-assignment page that embeds the camera scanner
  • /mobile/profile, /mobile/notifications — same screens as desktop, but reachable from the mobile menu

What she doesn't see. No side nav. No master-data pages. No reports. No admin. The mobile shell is one job, one tool.


Checkout Issuer

Issues assets to people. The librarian for the asset pool.

Persona. Yusuf runs the IT help desk. New hires walk in on day one — he hands them their laptop, charger, and ID badge. Each becomes a check-out record with a custodian, expected return date, and purpose.

Goals.

  • Find the right asset quickly (search by code or scan).
  • Pick a custodian (the person taking responsibility).
  • Capture a purpose and an expected return date.
  • See current open check-outs and which are overdue.

User stories.

  • As a Checkout Issuer, I want to create a check-out by selecting an asset and a custodian so the asset's status flips to "On Loan" and the custodian field is set.
  • As a Checkout Issuer, I want to set an expected return date so we can flag overdue items later.
  • As a Checkout Issuer, I want the system to prevent me from checking out an asset that's already on active loan so we don't double-issue.
  • As a Checkout Issuer, I want to cancel a check-out if the custodian changes their mind before they walk away.
  • As a Checkout Issuer, I want to filter the check-out list to only the active ones I created so I see my own outstanding loans.

Day in the life.

A new hire walks up. Yusuf opens Check-outs → New, types the laptop's code, picks the new hire as custodian, types "New hire IT kit" as purpose, sets expected return = "1 year". Saves. The asset's status is now OnLoan, the custodian is set, and a custody-history row is written.

Where he spends time.

  • /checkouts — list with filters
  • New-checkout dialog (no separate detail page)

What he doesn't do. Doesn't accept returns (that's Checkout Returner). Doesn't change condition ratings (those happen on return).


Checkout Returner

Receives assets back from custodians.

Persona. Maya is the help-desk back-office. When someone returns equipment, she checks it in, rates the condition (1-5), and adds notes if anything is damaged.

Goals.

  • Find the relevant active check-out.
  • Mark it returned, capture condition + notes.
  • The asset's status reverts to whatever it was before the loan.

User stories.

  • As a Checkout Returner, I want to find the active check-out for an asset by its code so I'm not paging through history.
  • As a Checkout Returner, I want to rate the asset's condition 1-5 on return so we have a numeric trail of degradation over time.
  • As a Checkout Returner, I want to add notes when an item comes back damaged so the custodian can be charged or the asset can be sent for maintenance.
  • As a Checkout Returner, I want the asset's status to auto-revert to its pre-loan state so I'm not manually setting it.

Day in the life.

Maya scans the returned laptop's QR code, opens the active check-out, rates condition 4 (a small dent), notes "small dent on lid corner; verified working", clicks Check in. The asset goes back to its prior status (e.g., Active).

Where she spends time.

  • /checkouts?status=Active — open loans
  • Check-in dialog

What she doesn't do. Doesn't create new check-outs. Doesn't cancel — she returns.


Asset Custodian

A regular employee who happens to currently hold an asset.

Persona. Layla (yes, the same Layla who is also a Mobile Auditor — roles compose). She's a senior dev, has been issued a laptop, monitor, and dock. She's not an admin, doesn't manage check-outs, but the system tracks that she is currently the custodian of those three assets.

Goals.

  • Know what's currently checked out to her.
  • File a maintenance request if something breaks.
  • Get notified when she's about to be overdue.

User stories.

  • As an Asset Custodian, I want to see the list of check-outs in my name so I know what I have.
  • As an Asset Custodian, I want to see which item is overdue so I can return it before someone reminds me.
  • As an Asset Custodian, I want to view my own profile and notifications without needing admin access.

Day in the life.

Layla rarely opens the system in this capacity — most check-out info reaches her through the Issuer / Returner roles. When the check-out fields a maintenance issue (her monitor is dead), she opens Maintenance Requests → New, picks her monitor, severity = High, summary "monitor not powering on". Reviewer triages. (This presumes she also has maintenance-request.create, which the seeded "Asset Custodian" role doesn't include by default — see 02-permissions-matrix. Custodian-as-reporter is a common ad-hoc grant.)

Where she spends time.

  • /checkouts — read-only, scoped to her custody
  • /profile, /notifications — personal

What she doesn't do. Doesn't audit. Doesn't approve. Doesn't manage anything except her own profile and notifications.


Combining roles in real life

Roles are designed to be composable. The seeded ten roles cover the common job functions; real organizations mix and match:

Real-world person Likely role bundle
Department secretary who orders moves and signs off on them Transfer Requester + Transfer Approver
Floor manager who issues equipment and audits the floor Checkout Issuer + Checkout Returner + Auditor
Branch IT lead Audit Planner + Audit Reviewer + Transfer Approver
Quarterly auditor working remotely Mobile Auditor + Audit Reviewer (so they review their own when permitted)
Asset administrator All roles, OR just Super Admin (they get everything anyway)

Adding a role to a user takes effect immediately — the next request sees the new permission, and any cached data is invalidated.

Custom roles are also fine. The Super Admin can create a "Branch Manager" role at /roles/new and pick whichever permissions match. That's the recommended pattern for any responsibility that doesn't map cleanly to a seeded role.

Demo accounts (development only)

When the seeder option Seeding.DemoUsers = true (true by default in appsettings.json), the system creates one demo account per role with the shared password Demo@123456:

Email Username Bilingual name Role Shell
admin@assettracking.local admin System Administrator / مسؤول النظام Super Admin Desktop
requester@assettracking.local requester Transfer Requester Demo / طالب التحويل (تجريبي) Transfer Requester Desktop
approver@assettracking.local approver Transfer Approver Demo / معتمد التحويل (تجريبي) Transfer Approver Desktop
receiver@assettracking.local receiver Transfer Receiver Demo / مستلم التحويل (تجريبي) Transfer Receiver Desktop
planner@assettracking.local planner Audit Planner Demo / مخطط المراجعة (تجريبي) Audit Planner Desktop
auditor@assettracking.local auditor Auditor Demo / مراجع (تجريبي) Auditor Desktop
reviewer@assettracking.local reviewer Audit Reviewer Demo / مراجع النتائج (تجريبي) Audit Reviewer Desktop
mobile@assettracking.local mobile Mobile Auditor Demo / مراجع تطبيق محمول (تجريبي) Mobile Auditor Mobile
issuer@assettracking.local issuer Checkout Issuer Demo / مسؤول الصرف (تجريبي) Checkout Issuer Desktop
returner@assettracking.local returner Checkout Returner Demo / مسؤول الاستلام (تجريبي) Checkout Returner Desktop
custodian@assettracking.local custodian Asset Custodian Demo / مسؤول الأصل (تجريبي) Asset Custodian Desktop

Use these for training, testing, demos, or screen recordings. Disable demo seeding in production by setting Seeding.DemoUsers = false in appsettings.json before deploying.

Where to go next

To learn… See
The exact permission set each role grants 02 — Permissions Matrix
The end-to-end workflow each role participates in 03 — Business Processes
What each user-facing screen looks like 04 — Features by Module