12 KiB
title, tags, created
| title | tags | created | |||||
|---|---|---|---|---|---|---|---|
| Roles & Personas |
|
2026-05-23 |
Roles & Personas
[!info] Where roles live in code The hard role enum is defined in
backend/src/models/User.ts:94as"admin" | "buyer" | "seller". Support is implemented as an admin variant (a dedicatedsupport@amn.gguser is created at bootstrap — seebackend/TODO.md) rather than as its own enum value. Permission checks live in route middleware and in service guards.
Amn has four user personas. Three are first-class roles in the data model; the fourth (Support) is a special-cased admin with reduced privileges.
flowchart LR
Visitor["Anonymous visitor<br/>(blog, public shops)"]
Buyer["Buyer<br/>(User)"]
Seller["Seller<br/>(Owner)"]
Support["Support<br/>(admin variant)"]
Admin["Admin"]
Visitor -->|signs up| Buyer
Buyer -->|requests seller mode<br/>+ admin approval| Seller
Buyer & Seller -->|opens ticket| Support
Support -->|escalates| Admin
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 Offers, 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 → completedstates. - 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.tsandfrontend/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, currency (USDT default, USDC, USD, EUR, IRR supported), 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
[!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", seebackend/src/models/User.ts), promote buyers to sellers, ban repeat offenders. - Moderate marketplace content: categories (
Categorymodel), 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). Seebackend/src/services/dispute/DisputeService.tsand 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/cleanupexposes 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.ggaccount — that exists to handle user tickets and triage disputes without granting full destructive access. Implemented as anadminrole with a restricted permission profile applied in middleware (seebackend/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)
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 |
| Admin | Support | Permission profile applied at middleware | Role stays admin |
Permission model
Permissions are enforced at three layers:
- Route middleware (e.g.
requireAuth,requireRole('admin')) — coarse gating on the HTTP layer. - Service guards — finer ownership checks (e.g. "you can only edit a request whose
buyerIdmatches youruserId"). - 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.