PRD: Employee management
| Module | User Management | PRD ID | PRD-EMP-001 |
| Status | Ready to dev | FEAT | EMP |
| Epic | — | Plane | BANA-1567 |
| Date | 2026-05-25 | Version | v1.0 |
| Packages | @nx/identity | URD | EMP |
| Surface | Client · Owner/Mgr | ||
| Owner | Phát Nguyễn | ||
What Employee management is
Owners bring a merchant onto the platform and then need staff to run it. The Team section on the Client app is where an owner creates staff accounts, scopes each one to one or more merchants in the organizer, and off-boards them when needed - no more sharing one login or handing out access too broadly.
The staff table and permissions form reuse the existing role-merchant machinery (see Roles & Scoping): each employee gets one or more role-merchant pairs, with roles limited to the range between Customer and the system's highest ceiling.
The Grant login toggle
The Grant login toggle draws a clean line between two kinds of staff - people with their own sign-in account, and people who are only tracked in the system without needing to sign in yet - and that same toggle decides how off-boarding works: an employee with login access can be deactivated, one without it can only be removed.
One employee, from creation to off-boarding
| Step | What happens |
|---|---|
| 1. Create | The owner fills in the Personal info card, adds role-merchant pairs on the Permissions card |
| 2. Grant login (optional) | Turn on Grant login with a username → the employee can sign in right away |
| 3. Grant login later | For an employee without login access, turn on the toggle on the Edit screen → the system auto-sends set-password mail |
| 4. Operate | Update permissions, reset the password from the Security card when the employee forgets it |
| 5. Off-board | An employee with login access → deactivate; an employee without login access → remove from the staff table |
Where it's easy to get wrong
Two guards block off-boarding the wrong person
An owner cannot remove themselves, and cannot remove an employee who currently holds the Owner role at any merchant - even when the action is otherwise validated against organizer and merchant ownership.
1. Goals & Non-Goals
Goals
- Owners create staff in the Team section through a two-card form: Personal info and Permissions.
- Assign one or more role-merchant pairs per employee; roles are chosen per merchant and limited to the Customer - system ceiling range.
- The Grant login toggle controls whether an employee has a sign-in account (username), both at creation and later on the Edit screen.
- Updating permissions replaces the entire previous list of role-merchant pairs with the newly entered list.
- Deactivate an employee who currently has login access, or remove any employee - except yourself and anyone currently holding the Owner role.
- Reset an employee's password directly from the Edit screen, without the employee having to request it themselves.
- Validate that the acting owner truly owns the organizer and every merchant involved before writing any change.
Non-Goals
- Custom role creation / dynamic permission management → Permissions.
- A user invitation system (email or phone invites).
- Audit / login history for employee actions.
2. Success Metrics
| Metric | Target / signal |
|---|---|
| Scoping correctness | Employees can only operate on the merchants listed in their Permissions card; zero cross-merchant leakage |
| Ownership safety | 100% of create/edit/remove calls reject when the acting owner does not own the organizer or a merchant named in the request |
| Self-activation | Rising share of newly login-granted employees who set their own password from the mail sent to them, with no operations-team involvement |
| Clean off-boarding | Deactivated or removed employees can no longer sign in; zero cases slip past the self-removal or remove-Owner guards |
3. Personas & Use Cases
| Persona | Goal in this feature |
|---|---|
| Owner | Create, permission, update, deactivate, or remove staff from the Team section |
| Employee | Sign in with their own username (once granted) and operate only the merchants listed in their Permissions card |
Core scenario: an owner creates an employee with personal info, one or more role-merchant pairs, and turns on Grant login with a username → the employee signs in right away → later the owner updates permissions, grants or revokes login, resets the password, or deactivates/removes the account when off-boarding.
4. User Stories
| # | As a | I want | So that |
|---|---|---|---|
| 01 | owner | to create an employee with personal info and one or more role-merchant pairs | staff operate only the merchants I assign them |
| 02 | owner | to turn on Grant login at creation time | the employee can get into the app right away without me having to grant access separately |
| 03 | owner | to create an employee without granting login access | I can track staff who don't need system access yet |
| 04 | owner | to turn the toggle on later from the Edit screen | I can grant login to a previously created employee without recreating them |
| 05 | owner | to turn the toggle off | I can revoke an employee's login access immediately |
| 06 | owner | to update an employee's permissions | I can move staff between merchants in a single save |
| 07 | owner | to reset an employee's password right from the Edit screen | I can help when they forget it without them having to request it themselves |
| 08 | owner | the system to stop me from removing myself or removing someone who holds the Owner role | I don't accidentally off-board the wrong person or lock myself out of admin access |
| 09 | employee | to sign in with my own username and see only my merchants | my view matches my responsibilities |
5. Functional Requirements
| # | Requirement | Status | URD ref |
|---|---|---|---|
FR-001 | The staff table shows seven columns: username, email, phone, first name, last name, role (a badge showing only the role name), and status. • Status is one of five values: Active / Disabled / Blocked / Archived / Unknown. • Each row has two actions: Edit and Remove. | ✅ | URD-EMP-001 |
FR-002 | The Create-employee form has a Personal info card: first name (required), last name (required), email (required), a phone list (optional, multiple entries), and a hire date (required). | ✅ | URD-EMP-001 |
FR-003 | The form has a Permissions card to assign role - merchant pairs to the employee. • From the headquarters merchant: the card shows a merchant picker and lets the owner add more role-merchant rows. • From a regular merchant: the card locks to exactly one pair bound to the current merchant, with no merchant picker and no way to add a row. • The role picker still lists disabled roles, but they cannot be selected. • The role assigned to a pair must sit between the Customer level and the system's highest ceiling; picking a role outside that range and saving is rejected. | ✅ | URD-EMP-002 |
FR-004 | The form has a Grant login toggle. • On the Create screen, turning it on opens an Authentication card to enter a username (required) and a Status field (default Active); the employee can sign in right away with that username. • Turning it off creates the employee normally, without login access. | ✅ | URD-EMP-004 |
FR-005 | On the Edit screen, for an employee without login access, the owner turns on Grant login and enters a username. The system automatically sends set-password mail so the employee can set their own password for the first time. | ✅ | URD-EMP-004 |
FR-006 | On the Edit screen, for an employee with login access, the owner turns off Grant login. The employee's username and password are removed, revoking sign-in access immediately. | ✅ | URD-EMP-004 |
FR-007 | The Edit screen has a Security card with a Reset password button, sending a password-reset request to an employee who currently has login access. The receive-and-set flow is specified in PRD-AUTH-001. | ✅ | URD-EMP-004 |
FR-008 | Updating permissions on the Permissions card replaces the entire previous list of role-merchant pairs with the newly entered list. After the update, the employee sees only the merchants in the new list. | ✅ | URD-EMP-006 |
FR-009 | Deactivating an employee is only possible when that employee currently has login access. • The owner does this by changing the status field inside the Authentication card on the Edit screen. • A deactivated employee cannot sign in, but their data is preserved. | ✅ | URD-EMP-007 |
FR-010 | An employee without login access has no status field to deactivate. For this group, Remove on the staff table is the only way to off-board them. | ✅ | URD-EMP-007 |
FR-011 | Removing an employee is blocked in two cases. • An owner cannot remove themselves. • An owner cannot remove an employee who currently holds the Owner role at any merchant. | ✅ | URD-EMP-007 |
FR-012 | Every create, edit, or remove call is validated against the acting owner truly owning the organizer and every merchant named in the request, before any change is written. | ✅ | URD-EMP-008 |
FR-013 | Once granted login access, an employee can sign in and operate only on the merchants listed in their own Permissions card. | ✅ | URD-EMP-003 · URD-EMP-005 |
FR-014 | Add someone who already has an account to the organizer right on the Employee screen. • Enter an identifier (username, email or phone number) to find the person, then assign role - merchant pairs like a regular employee. • No new account is created, and their password and profile stay untouched. | 🚧 | URD-MORG-002 |
5.1 Acceptance Criteria
- Open the Team section on the Client app → the staff table shows seven columns (username, email, phone, first name, last name, role, status) and two buttons, Edit/Remove, on each row.
- Click Create employee, fill in first name, last name, email, hire date on the Personal info card, add one role-merchant pair on the Permissions card, leave Grant login off, then save → the employee is created without login access.
- Repeat the same flow but turn on Grant login and enter a username → the employee is created and can sign in right away with that username.
- On the Permissions card from the headquarters merchant, pick a merchant then open the role picker → both active and disabled roles appear, but only active roles between Customer and the system ceiling can be selected; picking a role outside that range and saving is rejected. From a regular merchant, the Permissions card locks to one pair on the current merchant with no merchant picker.
- Open the Edit screen for an employee without login access, turn on Grant login, enter a username, save → the username is added and the system automatically sends set-password mail to the employee.
- Open the Edit screen for an employee with login access, turn off Grant login, save → the employee's username and password are removed and they can no longer sign in.
- On the Edit screen for an employee with login access, click Reset password on the Security card → a password-reset request is sent to that employee.
- On the Permissions card in Edit, clear all previous role-merchant pairs, add new ones, then save → the employee now sees only the merchants in the new list.
- On the Authentication card of an employee with login access, change the status field to Disabled → the employee can no longer sign in, but their row remains intact on the table.
- Open an employee without login access → there is no status field to deactivate; off-boarding them means clicking Remove on the staff table.
- Click Remove on your own row → rejected.
- Click Remove on an employee who currently holds the Owner role at any merchant → rejected.
- Create or edit an employee with a merchant you do not own → rejected, nothing is written.
- An employee with login access signs in and tries to operate on a merchant outside their Permissions card → access denied.
- On the Employee screen, add someone who already has an account using their username, assign a role - merchant pair and hit Save → that person sees this organizer at the launchpad on their next sign-in; their existing account, password and profile stay unchanged.
6. Non-Functional Requirements
| Area | Requirement |
|---|---|
| Data integrity | The account, the role-merchant pairs, and the username (when Grant login is on) are created/updated together - a partial failure writes nothing |
| Tenancy & authz | Every create/edit/remove call is ownership-validated against the acting owner's organizer and merchants; a role outside the Customer - system ceiling range can never be assigned |
| Security | Passwords are stored hashed only, never displayed or returned in plain text |
| Soft-delete | Removing an employee is a soft-delete - data is preserved, never physically deleted |
| Scoping | An employee can only operate on merchants listed in their own Permissions card |
| i18n | Table column labels, form field names, and status labels are bilingual (English / Vietnamese) |
7. UX & Flows
The staff table, the Create/Edit form, and the removal guards all live in the Team section on the Client app. The receive-and-set-password flow triggered after granting login access or clicking Reset password is specified in PRD-AUTH-001 and not restated here.
8. Data & Domain
| Entity | Role |
|---|---|
| Employee account | The employee's identity - profile, status, and soft-delete |
| Personal info | First name, last name, email, phone list, hire date |
| Role-merchant pair | One permissions row binding a role to a specific merchant; the whole list is replaced on update |
| Login identifier (username) and password | Only exists while Grant login is on; the password is stored hashed |
| Status | Active / Disabled / Blocked / Archived / Unknown - only applicable to employees with login access |
| Organizer / Merchant | The ownership source - used to validate the owner owns the organizer and every merchant involved |
Conceptual only - full data model in the developer domain model.
9. Dependencies & Assumptions
Depends on
| # | Feature | What it depends on |
|---|---|---|
| 01 | Roles & scoping (URD-ROLE - Permissions) | the valid role range (Customer - system ceiling) and the scope-filtering machinery the Team section reuses; adding someone who already has an account belongs to MORG. |
| 02 | Authentication (PRD-AUTH-001) | the receive-and-set-password flow triggered when Grant login is turned on or Reset password is clicked. |
| 03 | Commerce | organizer and merchant ownership is the source of truth used for validation on every call. |
Assumptions
| # | Assumption | What breaks if wrong |
|---|---|---|
| 01 | The acting owner already owns an organizer with at least one merchant. | There is nothing to bind a role-merchant pair to; the Permissions card has no valid merchant to pick. |
| 02 | The set-password mail configuration is ready before Grant login is turned on. | The employee is granted a username but never receives the set-password mail, locked out of the app they were just given access to. |
10. Release Plan & Launch Criteria
| Aspect | Plan |
|---|---|
| Phase | P2 of the EMP feature - see URD feature catalog |
| Rollout | All merchants; no feature flag |
| Migration | No destructive data migration |
| Launch criteria | Create → permission → sign-in verified end-to-end for both branches of the Grant login toggle; the self-removal and remove-Owner guards behave correctly; ownership validation rejects every non-owned case |
| Monitoring | Employee create/edit error rate, ownership-rejection rate, set-password mail delivery success rate |
References
- URD: User Management - EMP
- Related: Multi-organizer membership · Roles & scoping - Permissions URD · Authentication & account verification
- Module: User Management - URD
- Developer: @nx/identity · domain model
Risks & Open Questions
| # | Risk / question | Mitigation / status |
|---|---|---|
| 01 | Granting access to a merchant the owner does not own | Ownership is validated before any role-merchant pair is written |
| 02 | Off-boarding the wrong person who currently holds the Owner role | A guard blocks removing an employee who holds the Owner role at any merchant |
| 03 | An owner removing themselves and losing admin access to the organizer | A guard blocks self-removal |
| 04 | An employee without login access cannot be deactivated | Off-board this group with Remove instead of Deactivate |
FAQ
| # | Question | Answer |
|---|---|---|
| 01 | How is turning on Grant login at creation different from doing it on Edit? | At creation, turning it on with a username gets the employee into the app right away. On Edit, turning it on for an employee who never had login access makes the system automatically send set-password mail so they set their own password for the first time. |
| 02 | What happens when the toggle is turned off on the Edit screen? | The employee's username and password are removed, revoking sign-in access immediately. |
| 03 | Why can't some employees be deactivated? | Deactivation only applies to employees who currently have login access. An employee without login access can only be removed from the staff table. |
| 04 | How is Reset password on the Edit screen different from the toggle? | Reset password only sends a new password request to an employee who already has login access (see PRD-AUTH-001). The toggle decides whether the employee has login access at all. |
| 05 | Who can I remove? | Any employee, except yourself and anyone who currently holds the Owner role at any merchant. |
| 06 | Does updating permissions add to the previous list? | No - the new list of role-merchant pairs replaces the entire previous list. |