PRD: Merchant User Administration (Back Office)
| Module | User Management | PRD ID | PRD-EMP-002 |
| Status | Ready to dev | FEAT | EMP · BANA-1435 |
| Epic | BANA-1336 | Plane | BANA-1737 |
| Date | 2026-06-30 | Version | v1.0 |
| Packages | @nx/identity | URD | EMP |
| Surface | BO · Ops | ||
| Owner | Phát Nguyễn | ||
What Merchant User Administration (Back Office) is
A merchant owner can manage their own employees from the Client app (Employee management). But the operations team also needs to manage merchant users across all merchants from the Back Office - to provision staff for a client during onboarding, fix an assignment, reset access, or lock someone out - without being the owner and without a database edit.
This increment is that operator surface: a cross-merchant merchant-user admin that does what an owner does for their own staff, but for the operations team, scoped by the operator's role. It sits beside internal operations-staff administration (which manages our own internal staff); this screen manages merchants' users.
One merchant user, from creation to lock
| Step | What happens |
|---|---|
| 1. Find | An operator opens the cross-merchant list, searches or filters by organizer/merchant/role/status |
| 2. Create | Create a merchant user with their own sign-in credentials |
| 3. Assign | Assign the user to an organizer and one merchant, with one or more roles |
| 4. Operate | Edit the profile; lock or unlock the account when needed |
| 5. Moving toward | Assigning one user to multiple merchants, full-set reassignment, and removal outright (🚧, see §5) |
Where it's easy to get wrong
Creating a user is not yet one complete transaction
Creating a user currently happens in several sequential steps - create the account, then grant the organizer/merchant. If a step fails mid-way and the operator changes the merchant before retrying, the user can end up in both merchants; leaving the page mid-way and re-submitting can create a duplicate user.
1. Goals & Non-Goals
Goals
- A cross-merchant list of merchant users an operator can search and filter.
- Create a merchant user account.
- Assign a merchant user to an organizer and merchant, with one or more roles; moving toward assigning multiple merchants per user.
- Edit and reassign - replacing a user's merchant assignments (🚧).
- Lock/unlock; moving toward removing a merchant user (🚧).
Non-Goals
- A merchant owner managing their own employees in the Client app (Employee management) - same capability, different surface.
- Our own internal staff accounts (Operations staff administration).
- Defining roles and permissions themselves (Permissions).
2. Success Metrics
| Metric | Target / signal |
|---|---|
| Operator self-service | An operator provisions or fixes a merchant's user without a database edit |
| Correct scoping | A merchant user sees only the merchants they are assigned to |
| Cross-merchant reach | An operator manages users for any merchant within their role's scope |
3. Personas & Use Cases
| Persona | Goal in this feature |
|---|---|
| Operations team | Provision and maintain merchant staff accounts across the platform |
| Onboarding / support staff | Set up a new merchant's first users, or fix an access problem |
Core scenario: an operator opens the merchant-user list, creates a user for a merchant, assigns them to that merchant with roles; later locks the user when they leave. Next target: editing the assignment to add a second merchant or move the user to another merchant entirely (🚧). Every action is validated so the operator only manages merchants within their scope.
4. User Stories
| # | As a | I want | So that |
|---|---|---|---|
| 01 | operator | a cross-merchant list of merchant users | I can find and manage any merchant's staff |
| 02 | operator | to create a merchant user and assign them to a merchant with roles | a new staff member can sign in scoped correctly |
| 03 | operator | to reassign a user's merchants | their access reflects where they actually work |
| 04 | operator | to lock a merchant user | a departed staff member loses access |
| 05 | operator | assignment validated against my scope | I never touch merchants I don't manage |
5. Functional Requirements
| # | Requirement | Status | URD ref |
|---|---|---|---|
FR-001 | A cross-merchant merchant-user list, searchable and filterable, kept separate from our internal operations accounts. • 9 columns: First name · Last name · Phone number · Username · Email · Organizer · Merchant · Role · Status; Organizer/Merchant/Role render as labels, at most 3 per cell, the rest collapse into a "+n" label - hover to see them all. • Role labels distinguish system roles from custom roles with different colors and icons. • A global search box, plus 4 filters: Organizer (pick one), Merchant (pick one, narrowed by the selected Organizer - changing the Organizer clears the Merchant selection), Role (pick one), Status (pick many - Activated / Deactivated / Blocked, this screen has no Archived). • Default pagination 50 rows/page (options 25 / 50 / 75 / 100). | ✅ | URD-EMP-002 · URD-EMP-005 |
FR-002 | The create form has 9 fields: personal info, login, status, and permissions. • First name, Last name: required, free text. • Username: required at creation, 4-32 characters; lowercase letters and digits, with dots / underscores / hyphens allowed between character groups; uppercase auto-lowercased, whitespace stripped. • Email: optional, valid email format when provided. • Phone numbers: optional, multiple numbers, add/remove, no verification required at creation. • Password: required at creation, 8-80 characters, at least 1 uppercase letter, 1 lowercase letter, and 1 digit, the field starts empty and must be typed. • Status: required, defaults to Activated, value set Activated / Deactivated / Blocked. • Organizer: required, pick one. • Merchant: required, pick one, narrowed by the selected Organizer. • Roles: required ≥ 1, multiple roles selectable at once from the selected merchant; no merchant selected locks the Roles field; changing the Merchant clears every selected role and they must be re-picked; roles not in Activated status are shown but not selectable; a merchant with no roles yet shows a clear message; a live preview card mirrors the selections in real time. | ✅ | URD-EMP-001 · URD-EMP-004 |
FR-003 | Assign a merchant user to exactly one organizer and one merchant, with one or more roles within that merchant. • On create, the organizer-merchant pair is consistent by construction, because the merchant list is narrowed by the selected organizer. • Moving toward: assigning one user to multiple merchants of the same organizer, each with its own role set - add/remove merchants directly on the form, roles are always picked per merchant, and the list shows every merchant a user belongs to. | 🔶 | URD-EMP-002 · URD-ROLE-001 |
FR-004 | Reassign a user's merchant set - the new set replaces the ENTIRE previous set in one operation. • On the edit screen, ops can change a user's assignment set: move to another merchant, add merchants, remove merchants; a user is never left "stuck" in an old merchant unintentionally. • The UI states clearly before saving that the previous assignments will be replaced. • Today, on the edit screen, the Organizer and Merchant fields are shown but locked - only the profile, status, and role set within the current merchant are editable. | 🚧 | URD-EMP-006 |
FR-005 | Lock/unlock a merchant user according to their current status; removal outright is the next target. • A row action on the list: an Activated user → a Lock button; a Blocked user → an Unlock button; any other status (Deactivated) → no button. • Both directions go through a confirmation dialog before executing; a locked user cannot sign in until unlocked. • Remove (next target): an action to remove a merchant user outright, with a confirmation naming the account about to be removed. | 🔶 | URD-EMP-007 |
FR-006 | Every action is validated against the operator's scope and gated to operator roles. • Today, the screen is only reachable with an internal operations account in the Back Office. • Next target: each assign/edit action is validated against the merchant scope of the operator's role - an operator cannot assign a user to a merchant outside their scope, even by sending the request directly. | 🔶 | URD-EMP-008 |
FR-007 | Show each merchant user's identifier verification state; a manual toggle never sends SMS or email. • A phone number entered at creation needs no verification - the account is usable right away. • The list and the edit screen clearly show whether each email / phone number is verified. • Authorized operations staff can toggle the verification state right in Back Office - no SMS or email is ever sent. | 🚧 | URD-USR-023 |
5.1 Acceptance Criteria
- Creating a merchant user with all valid fields → the user appears in the list with the correct organizer, merchant, and role labels.
- On the create form, no merchant selected → the roles field is locked; after picking a merchant and then switching to another → all selected roles are cleared.
- Leaving organizer or merchant empty, or selecting no role on create → the save is blocked and the offending fields are highlighted.
- Password
abcdefgh(no uppercase, no digit) is rejected with a message. - Opening the edit screen → username and password do not appear; organizer and merchant are shown but cannot be changed.
- Pressing Lock on an Activated user → confirmation dialog → the status becomes Blocked and the button switches to Unlock; that user can no longer sign in.
- A Deactivated user → no lock/unlock button is shown.
- Filtering by Organizer A → the list shows only users of A; the Merchant filter then lists only A's merchants.
- Reassign: change a user's merchant set and save → the user belongs only to the new set, with no trace of the old one.
- An operator with a limited scope assigns a user to an out-of-scope merchant → rejected with a message.
- Open the edit screen of a user with an email / phone number → each identifier clearly shows whether it is verified.
- An authorized operator marks a phone number as verified → the state flips to verified right away, and no SMS or email is sent.
6. Non-Functional Requirements
| Area | Requirement |
|---|---|
| Tenancy & authz | Cross-merchant within the operator's scope; gated to operator roles |
| Access scoping | A merchant user's data access is filtered to their assigned merchants |
| Create & assign integrity | Creating a user and assigning their organizer/merchant is one complete business transaction: no half-done state may ever exist - a user without a membership, or belonging to an unintended merchant (see the FAQ tab's Risks section) |
| Reassignment integrity | Updating assignments replaces the entire previous set, leaving no stale assignment behind |
| Validation | The operator may only assign merchants within their scope |
| i18n | Labels are bilingual (EN/VI) |
7. UX & Flows
How an operator manages a merchant user:
What the screen lets an operator do:
The screen lives in the Back Office "Access Control" section, beside internal user and role management.
8. Data & Domain
| Concept | Role in this screen |
|---|---|
| Merchant user | A staff account that belongs to a merchant and signs in with its own credentials (target: belonging to multiple merchants) |
| Assignment | The link between a merchant user and the organizer + merchant they may access |
| Role | What the user may do within their assigned merchant; roles belong to a merchant |
Conceptual only - a merchant user is a user linked to merchants; the data model lives in the identity domain model.
9. Dependencies & Assumptions
Depends on
| # | Feature | What it depends on |
|---|---|---|
| 01 | Merchants (Commerce) | the units a merchant user is assigned to. |
| 02 | Roles & scoping (URD-ROLE - Permissions) | the roles assigned to a merchant user, per merchant. |
| 03 | User accounts | identities and credentials a merchant user signs in with. |
Assumptions
| # | Assumption | What breaks if wrong |
|---|---|---|
| 01 | The operator is authenticated with a role that scopes which merchants they manage. | There is no basis to limit the operator to the merchants they manage - FR-006 loses the ground it needs to enforce scope. |
| 02 | The selected merchant already has roles to assign. | The Roles field shows an empty list, and the operator cannot create a merchant user for that merchant until a role exists. |
10. Release Plan & Launch Criteria
| Aspect | Plan |
|---|---|
| Phase | P1 - the core (list, create, single-merchant assignment, lock/unlock) is available to operators in the Back Office |
| Rollout | Operator users; no feature flag |
| Migration | None - it manages existing merchant users |
| Launch criteria (core, ✅) | An operator creates a merchant user, assigns them to a merchant with roles, and locks/unlocks them - per the §5.1 acceptance criteria |
| Next-increment criteria (🚧) | Multi-merchant assignment (FR-003), full-set reassignment (FR-004), removal (FR-005), operator-scope validation (FR-006), identifier verification state (FR-007) |
| Monitoring | Merchant-user create/edit volume; lock rate |
References
- URD: User Management -
EMP(Employee Management) ·ROLE- Permissions ·USR - Related: PRD-OPS-001 - Operations staff & access administration · Permissions
- Module: User Management - URD · Roadmap: Phase 2 - By Month
- Developer: @nx/identity
Risks & Open Questions
| # | Risk / question | Mitigation / status |
|---|---|---|
| 01 | Multi-step, non-transactional create: creating a user currently happens in several sequential steps (create the account, then grant the organizer/merchant); if a step fails mid-way and the operator changes the merchant before retrying, the user can end up in both merchants; leaving the page mid-way and re-submitting can create a duplicate user | Relates to the "one complete transaction" NFR (§6); the UI currently warns when leaving with unsaved work |
| 02 | An operator managing a merchant outside their scope | FR-006 (🚧): every assignment is validated against the operator's scope |
| 03 | Reassignment replacing all assignments | FR-004: the new set replaces the entire old set; the UI states this clearly before saving |
| 04 | A user already in multiple merchants (from a failed create) opened on the edit screen | The edit screen currently shows only the first assignment - showing all of them is part of FR-003/FR-004 |
| 05 | Overlap with owner-managed employees | Same underlying capability; this is the operator (BO) surface, owners use the Client app |
FAQ
| # | Question | Answer |
|---|---|---|
| 01 | How is this different from an owner managing their employees? | Same capability - but this is the operator (back-office) surface across merchants; owners manage their own staff in the Client app. |
| 02 | How is this different from operations-staff admin? | That manages our own internal staff; this manages merchants' users. |
| 03 | What happens when I reassign merchants? | (FR-004) The new merchant set replaces the user's entire previous assignments - no old merchant is ever left behind. Organizer/merchant are currently locked on the edit screen. |
| 04 | How many merchants can one user belong to? | Today: exactly one, assigned at creation. Target (FR-003): one or more merchants of the same organizer, with per-merchant roles. |
| 05 | Can an operator manage any merchant? | The target is only merchants within their role's scope (FR-006); today the screen is open to internal operations accounts. |