---
title: Roles & Personas
tags: [overview, roles, personas, permissions, rbac]
created: 2026-05-23
---

# Roles & Personas

> [!info] Where roles live in code
> The hard role enum is defined in `backend/src/models/User.ts:94` as `"admin" | "buyer" | "seller" | "resolver"`. The `resolver` role was added to the backend in commit `fce8a19` and is now a first-class enum value in `User.ts`, `UserRole` enum in `shared/types/index.ts`, and the dispute routes. Support is implemented as an admin variant (a dedicated `support@amn.gg` user is created at bootstrap — see `backend/TODO.md`) rather than as its own enum value. Permission checks live in route middleware and in service guards.

Amn has five user personas. Four are first-class roles in the data model; the fifth (Support) is a special-cased admin with reduced privileges.

```mermaid
flowchart LR
    Visitor["Anonymous visitor<br/>(blog, public shops)"]
    Buyer["Buyer<br/>(User)"]
    Seller["Seller<br/>(Owner)"]
    Support["Support<br/>(admin variant)"]
    Admin["Admin"]
    Resolver["Resolver<br/>(dispute specialist)"]

    Visitor -->|signs up| Buyer
    Buyer -->|requests seller mode<br/>+ admin approval| Seller
    Buyer & Seller -->|opens ticket| Support
    Support -->|escalates| Admin
    Admin -->|assigns role| Resolver
```

---

## Buyer (User)

> [!example] Who they are
> Default new user. Anyone who signs up is a buyer until they request seller status. The persona name in the UI is **"User"** but the model role is `buyer`.

### Primary workflows

- **Browse and search** the public marketplace and request templates.
- **Create a [[Purchase Request]]** describing what they want — product type (physical / digital / service / consultation), budget, urgency, delivery info, attachments. See `backend/src/models/PurchaseRequest.ts`.
- **Review incoming [[Seller Offer]]s**, negotiate over chat, accept the best one.
- **Pay** via the Request Network in-house checkout, using a supported EVM wallet through Wagmi/WalletConnect and the platform's payment request metadata.
- **Track the order** through `processing → delivery → delivered → confirming → completed` states.
- **Confirm receipt** (or let the SLA auto-confirm), leave a review, accrue points.
- **Open a [[Dispute]]** if delivery never lands, item is wrong, or quality is poor.
- **Refer friends** via their personal referral code; earn points per signup that converts.
- **Manage profile**: avatar, addresses, wallet address, passkeys, notification preferences, language.

### Key permissions

- Create, edit, cancel **own** purchase requests.
- Accept / reject offers on **own** requests.
- Initiate payments on **own** requests.
- Open disputes on **own** orders.
- Chat with sellers on **own** open requests and disputes.
- Read public sellers, public requests, public blog.
- **Cannot**: see other users' private data, moderate content, issue payouts, change another user's role.

### Dashboard sections (frontend routes)

The buyer dashboard lives under `/dashboard` (`frontend/src/app/dashboard/`). Notable areas:

- `/dashboard` — overview (recent requests, recent offers received, points balance)
- `/dashboard/request` — list, detail, and create flow for purchase requests
- `/dashboard/request-template` — saved templates and the catalogue of admin templates
- `/dashboard/chat` — all conversations
- `/dashboard/payment` — payment history (in + out) and active invoices
- `/dashboard/disputes` — open and resolved disputes
- `/dashboard/points` — points, levels, referrals
- `/dashboard/account` — profile, security (passkeys), addresses, language
- `/dashboard/post` — read-only blog reader (also public)

> [!tip] See also
> Full buyer playbook in [[User Guide]]. Auth specifics in [[Authentication Flow]].

---

## Seller (Owner)

> [!example] Who they are
> A buyer who has been promoted to `role: "seller"`. The UI sometimes calls them **"Owner"** because they own a shop. Sellers retain all buyer capabilities — they can still post requests of their own.

### Primary workflows

- **Configure shop**: shop name, banner, description, response time SLA, accepted payment methods, payout wallet address. See `backend/src/models/ShopSettings.ts` and `frontend/src/sections/shop-settings/`.
- **Discover requests** through the seller feed (filtered by category and preferred-seller status). Receive live notifications when a relevant request is posted via the `sellers` / `seller-<id>` Socket.IO rooms (`backend/src/app.ts:101-112`).
- **Submit offers** with price in **USDT** (the only supported currency for the escrow MVP — USD/EUR/IRR removed in commit 3aaa2fe), delivery time, optional attachments and notes.
- **Negotiate** in the per-request chat — bilateral with the buyer until an offer is accepted.
- **Fulfil** the order: ship physical goods (with optional tracking number), or upload/email digital deliverables.
- **Use the [[delivery code]]** for physical handoffs: a six-digit one-time code the buyer reads to the courier to confirm receipt.
- **Receive payout** to the configured wallet after ledger-gated release. Today this is an admin/custody-signer operation; the target path is Safe/hardware-backed approvals as described in [[PRD - Decentralized Custody and Smart-Contract Escrow Roadmap]].
- **Manage [[Request Templates]]** scoped to their shop — publish "off-the-shelf" offerings buyers can purchase in one click.
- **Engage with reviews and disputes**: respond to reviews, contest disputes, provide evidence.

### Key permissions

- All buyer permissions.
- Create / edit / withdraw **own** seller offers.
- Read all public purchase requests + read-only access to requests where they have an active offer.
- Manage **own** shop settings, payout wallet, business hours.
- Publish [[Request Templates]] scoped to their shop.
- Mark orders as shipped, upload digital deliverables, request delivery codes.
- Respond in disputes they are a party to.
- **Cannot**: see another seller's analytics, edit another seller's shop, moderate the platform.

### Dashboard sections

Seller dashboard reuses the same `/dashboard` shell with extra modules:

- `/dashboard/shops` — public-facing shop browser (also visible to buyers)
- `/dashboard/shop-settings` — edit own shop, payout wallet, working hours
- `/dashboard/request-template` — create / edit shop-scoped templates
- `/dashboard/payment` — receivables, payout history, pending releases
- `/dashboard/disputes` — disputes where the seller is the respondent
- `/dashboard/seller/marketplace/offers` — **Offer Management** (tabbed view of all own offers filtered by status: pending / accepted / rejected / withdrawn; inline withdraw action; commit 9cf1686)

> [!tip] See also
> [[Seller Guide]] walks through onboarding, first listing, and payout setup end-to-end. [[Payments Overview]] explains the escrow + payout state machine.

---

## Admin

> [!example] Who they are
> Platform operators with full read/write access. Admins are seeded at startup via `backend/src/infrastructure/database/init-admin.ts`. There is typically one root admin (`admin@amn.gg`) and additional admins promoted through database operations or a dedicated admin-creation endpoint.

### Primary workflows

- **Moderate users**: suspend / unsuspend accounts (`User.status: "active" | "suspended" | "deleted"`, see `backend/src/models/User.ts`), promote buyers to sellers, ban repeat offenders.
- **Moderate marketplace content**: categories (`Category` model), request templates (the canonical platform-wide ones), blog posts.
- **Resolve disputes**: get assigned to disputes, drive them to resolution, choose an outcome (`refund | replacement | compensation | warning_seller | ban_seller | no_action`). See `backend/src/services/dispute/DisputeService.ts` and [[Dispute Flow]].
- **Operate payments**: trigger ledger-gated releases/refunds, review Request Network webhooks, inspect derived destination wallets, fetch on-chain transactions, and manually confirm stuck payments only after Transaction Safety Provider checks.
- **Configure the platform**: levels (`LevelConfig`), points multipliers, blog seed content, default templates.
- **Run data cleanup**: `/api/admin/cleanup` exposes destructive maintenance utilities (`services/admin/`).
- **Author blog posts** via the TipTap rich-text editor.
- **Monitor health**: Request Network webhook/reconciliation status, ledger enforcement, custody signer/Safe readiness, Redis, and MongoDB.

### Key permissions

- **All** read and write across the platform — no row-level scoping.
- Promote users, change roles, suspend accounts.
- Approve / reject seller applications.
- Resolve any dispute, override any payment state.
- Trigger payouts and refunds.
- Edit / delete any blog post, template, or category.
- Run admin cleanup endpoints (irreversible — use with care).
- Access the full Sentry stream and webhook logs.

### Dashboard sections

Admins see the buyer/seller surfaces plus dedicated admin modules (typically under `/dashboard` with admin-only guards, growing into a dedicated `/admin` area in later versions):

- User management (search, suspend, role change)
- Dispute queue with assignment and resolution
- Payment console (manual confirmation, release/refund dispatch, Request Network webhook and ledger log)
- Category and template management
- Blog editor (publish / unpublish / featured)
- Platform analytics (TODO — see `backend/TODO.md`)
- Data cleanup utilities

> [!warning] Destructive operations
> `/api/admin/cleanup/*` and direct role mutations are not undoable. Admin actions should be logged to an audit trail. Audit logging is on the roadmap (`backend/TODO.md` → Security Enhancements → Audit Logging).

> [!tip] See also
> [[Admin Guide]] gives the step-by-step for moderation, dispute resolution, and payment operations.

---

## Support

> [!example] Who they are
> A dedicated support persona — the seeded `support@amn.gg` account — that exists to handle user tickets and triage disputes without granting full destructive access. Implemented as an `admin` role with a restricted permission profile applied in middleware (see `backend/TODO.md` → "Support user creation").

### Primary workflows

- **Join existing chats** to assist a buyer or seller in real time.
- **Triage disputes**: read incoming disputes, attach notes, assign to the right admin, set priority.
- **Answer user queries** about payments and orders without performing the payment action itself.
- **Escalate** anything that requires destructive action (refunds, bans, manual payouts) to a full admin.

### Key permissions

- Read access to all user accounts (no PII edits).
- Read access to all disputes and chats.
- Comment / reply in disputes and chats (write access scoped to messages, not resolution).
- **Cannot**: change roles, issue payouts, suspend users, delete content, resolve a dispute, edit settings.

### Dashboard sections

Support sees a stripped-down admin view focused on the inbox:

- Support chat queue
- Dispute triage list
- User lookup (read-only)
- Order lookup (read-only)

---

## Resolver

> [!example] Who they are
> A platform-employed dispute resolver (`role: "resolver"`). Added to the backend as a first-class role in commit `fce8a19`. Resolvers have targeted authority to mediate and formally resolve disputes — they can assign disputes, update status, issue final resolutions (including `ban_seller` or `refund`), view statistics, and bypass chat membership checks (commit `766a9a2`) to read/send in any chat.

### Primary workflows

- **Review dispute details**: read buyer and seller evidence, chat history, delivery confirmations.
- **Communicate** directly through any chat — bypasses participant membership guard.
- **Assign, update status, and resolve disputes** with the same actions as admins (`refund | replacement | compensation | warning_seller | ban_seller | no_action`).
- **Monitor dispute health** via `GET /api/disputes/statistics`.

### Key permissions

- Full triage on disputes: `POST /:id/assign`, `PATCH /:id/status`, `POST /:id/resolve`, `GET /statistics`.
- Read and write messages in any chat (bypass membership check in `ChatService`).
- Read any dispute and its evidence.
- **Cannot**: change roles, issue payouts, suspend users, delete content, access non-dispute admin endpoints.

> [!note] Implementation
> The `resolver` role was added as a first-class backend enum in commit `fce8a19` (`User.ts`, `UserRole` in `shared/types/index.ts`, dispute routes). Chat bypass was added in commit `766a9a2`.

---

## Cross-cutting concerns

### Role transitions

| From | To | How | Audit |
|---|---|---|---|
| Anonymous | Buyer | Self-service signup | `User` created |
| Buyer | Seller | Application → admin approval | `User.role` change |
| Buyer / Seller | Admin | Manual DB / boot-time seed | High-risk, manual |
| Buyer / Seller | Resolver | Admin role assignment | `User.role` change |
| Admin | Support | Permission profile applied at middleware | Role stays `admin` |

### Permission model

Permissions are enforced at three layers:

1. **Route middleware** (e.g. `requireAuth`, `requireRole('admin')`) — coarse gating on the HTTP layer.
2. **Service guards** — finer ownership checks (e.g. "you can only edit a request whose `buyerId` matches your `userId`").
3. **Frontend route guards** — `frontend/src/auth/guard/` hides UI from users who would be rejected anyway, preventing dead-ends.

### Identity sources

- **Email + password** — primary, with bcrypt hashing.
- **Passkey (WebAuthn)** — multi-device, stored in `User.passkeys[]`.
- **Google OAuth** — server-verified, links by email.

See [[Authentication Flow]] for the full sequence diagram.

### Internationalisation per persona

All four personas see the same six-language UI (en, fr, vi, cn, ar, fa) with the default fallback being Persian (`fa`) — see `frontend/src/locales/locales-config.ts:39`. Date formatting switches to the Jalali calendar in Persian.

---

## See also

- [[Introduction]] — project mission and target audience framing.
- [[System Overview]] — where each persona fits in the architecture.
- [[Authentication Flow]] — how identity becomes a role.
- [[Admin Guide]] — operational handbook for admins and support.
- [[User Guide]] — buyer journey end-to-end.
- [[Seller Guide]] — seller onboarding and shop ops.
- [[Glossary]] — definitions of every domain term referenced above.
