Skip to content

PRD: User identifiers & configuration management

ModuleUser ManagementPRD IDPRD-USR-002
StatusReady to devFEATUSR
EpicPlaneBANA-1525
Date2026-06-15Versionv1.0
Packages@nx/identityURDUSR
SurfaceClient · Owner/Mgr
OwnerPhát Nguyễn

What identifiers & configuration management is

PRD-USR-001 established the account: a user can hold several login identifiers, and a default set of configurations is seeded at registration. That PRD defined what those records are - this PRD defines how a user manages them afterwards as standalone, permission-gated resources: list, add, remove identifiers; read and write user configuration.

Every identifier carries a scheme that types it - username, email, phone, plus system-issued schemes - drawn from a fixed set. Adding an identifier always binds it to the caller and always starts unverified, whatever the request claims. Configurations are grouped under system or table, uniquely keyed by code per user, and readable right after sign-in - before a merchant or organizer is even chosen - so the app can hydrate preferences from the first screen.

Why a dedicated management surface is needed

Without a managed surface a signed-in user cannot add a second phone, list the identifiers they already hold, or save their own table layout - and nothing guards the two ways an identifier-create goes wrong: attaching it to another user, or attaching one pre-marked verified to skip the one-time code. Removing an identifier is missing a similar guard: nothing stops a user from removing their own last verified email, or - at the Owner role or below - their own last verified phone, losing a trustworthy way to sign back in.

Configurations have a subtler gap: they must be readable before a merchant or organizer is chosen - the very first thing the client needs to render preferences - yet the standard resource pattern gates reads behind a merchant scope. This increment closes these gaps, and adds a per-user custom table view, built by cloning a base table layout.

One identifier, from add to removal

On the Profile screen in Account Settings (specified in PRD-AUTH-001), a user adds a new phone number. It is stored under their own account and marked unverified, awaiting a one-time code - regardless of any user reference or verified flag the request sends along. That same user tries to remove their last verified phone → the removal is refused, keeping at least one trustworthy way to sign back in. Separately, the app loads the user's configurations the moment they sign in - before an organizer or merchant is chosen - and the user saves a custom "Products" table view; the system clones the base product table layout into a new per-user view, refusing a second view that reuses the same code.

The easiest thing to get wrong

The last-verified-identifier rule applies to EVERY removal path, not just the profile screen

It is easy to assume that blocking the removal of the last verified email or phone is just a form validation on the profile screen. It is not - the rule applies to every identifier-removal path, including inside the verification flow.

Enforce it in only one place, and a user can still lock themselves out of signing back in through a different removal path the profile-screen validation never covers.

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.