Files
nick-doc/00 - Overview/Roles & Personas.md
Siavash Sameni 4cf5c49274 docs(audit): align documentation with post-remediation backend reality
- Update data model enums to match backend models
- Update API reference auth requirements
- Add dispute module references and warning blocks
- Add 2026-05-24 audit remediation callout to Overview
- Generate task breakdowns and audit artifacts
- Add doc alignment report (.taskmaster/reports/)
2026-05-24 11:16:29 +04:00

12 KiB

title, tags, created
title tags created
Roles & Personas
overview
roles
personas
permissions
rbac
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". 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 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 SHKeeper (custodial crypto invoice) or Web3 wallet (DePay + MetaMask through Wagmi).
  • 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, 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 automatically via SHKeeper to the configured wallet once the order is finalised (admin-triggered batch or per-order based on shop policy).
  • 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", 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 (planned, not yet implemented).
  • Operate payments: trigger payouts, fetch on-chain transactions, manually confirm stuck payments (the manual transaction-hash flow described in backend/TODO.md), audit the SHKeeper webhook history (services/payment/shkeeper/webhookStats.ts).
  • 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: SHKeeper status (background health monitor in app.ts:433), Redis, 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, payout dispatch, webhook 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)

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:

  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 guardsfrontend/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