--- 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
(blog, public shops)"] Buyer["Buyer
(User)"] Seller["Seller
(Owner)"] Support["Support
(admin variant)"] Admin["Admin"] Resolver["Resolver
(dispute specialist)"] Visitor -->|signs up| Buyer Buyer -->|requests seller mode
+ 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-` 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.