PRD: Customer profiles
| Module | Customer (CORE-09) | PRD ID | PRD-CUS-001 |
| Status | Shipped | Owner | Customer squad |
| Date | 2026-03-15 | Version | v1.0 |
| Packages | @nx/identity · @nx/sale · @nx/core | URD | CUS |
TL;DR
Gives a merchant a directory of customers under its brand and lets staff attach a known customer to a sale order at checkout - so every order can be tied back to a person, not an anonymous ticket. A captured customer can later be promoted into a full sign-in user account, turning a walk-in into an addressable, returning customer.
1. Context & Problem
Sale orders have no concept of a customer: a checkout cannot be attributed to a known person, and there is no directory of customers under a brand. Without a customer record, a merchant cannot recognise repeat buyers, reconcile orders against a person, or build any of the engagement features (loyalty, segmentation, campaigns) that follow. This is the foundational increment of the Customer module - it introduces the Customer record, the management surface around it, and the link from a customer to a sale order, so later phases (loyalty points, outreach, analytics) have a person to attach to.
2. Goals & Non-Goals
Goals
- Introduce a
Customerentity (name, phone, email,userId,merchantId) with a repository and a customer-management service. - Let staff create and manage customers, and attach a customer to a sale order at checkout.
- Scope every customer to the brand (merchant/Organization), with soft-delete preserving history.
- Promote a captured customer into a full sign-in user account (customer registration + OTP plumbing).
Non-Goals
- Customer segmentation and targeting (Planned).
- Email / SMS campaign engine (Planned).
- Loyalty points, point redemption, and loyalty tiers - owned by Loyalty Points.
- Customer lifetime-value analytics (Planned).
3. Success Metrics
| Metric | Target / signal |
|---|---|
| Order attribution | Share of sale orders that carry a customer trends up |
| Brand isolation | Zero cross-brand customer reads (staff see only their own brand) |
| History preservation | Soft-deleted customers retain linked orders; no hard deletes |
| Promotion | Captured customers promoted to a sign-in account (where chosen) |
4. Personas & Use Cases
| Persona | Goal in this feature |
|---|---|
| Owner | Keep a brand-scoped directory of customers; manage and soft-delete profiles |
| Cashier | Create a customer on the fly and attach it to an order at checkout |
| Customer | Be promoted into a sign-in account to access their own history later |
Core scenarios: a cashier creates a customer (name + phone + email) at checkout → the customer is scoped to the brand and attached to the sale order → staff manage the profile within their brand → a captured customer is optionally promoted into a full sign-in user account.
5. User Stories
- As a cashier, I want to create a customer with name, phone, and email in one step, so I can attach a known person to the order at checkout.
- As a cashier, I want to attach an existing customer to a sale order, so the order is tied to that person.
- As an owner, I want customers scoped to my brand, so staff see and manage only our own customers.
- As an owner, I want to update a customer's profile and soft-delete it, so the directory stays clean while history is preserved.
- As an owner, I want to promote a captured customer into a sign-in user account, so a walk-in can become a returning, addressable customer.
6. Functional Requirements
| # | Requirement | URD ref |
|---|---|---|
| FR-1 | Create a customer with name, at least one email and one phone | URD-CUS-001 |
| FR-2 | Scope every customer to the brand (Organization/merchant) | URD-CUS-002 |
| FR-3 | Update a customer's profile (name, emails, phones, birthday, locale) | URD-CUS-003 |
| FR-4 | Soft-delete a customer, preserving record and linked orders | URD-CUS-004 |
| FR-5 | Staff see and manage only customers within their own brand | URD-CUS-005 |
| FR-6 | Attach a customer to a sale order at checkout; customer returned on order change | URD-CUS-006 |
| FR-7 | Promote a captured customer into a full sign-in user account (OTP-based registration) | URD-CUS-007 |
Full requirement text and acceptance criteria live in the Customer URD. This PRD references them rather than restating them.
7. Non-Functional Requirements
| Area | Requirement |
|---|---|
| Data integrity | Soft-delete via the common column defs; deleting a customer never removes linked orders |
| Tenancy & authz | Every customer is scoped per merchant/brand; staff cannot read or manage another brand's customers |
| Performance / scale | Customer lookup and attach during checkout add no perceptible latency to the sale flow |
| Identity model | A customer is a User with the fixed customer role and no sign-in credentials by default |
| i18n | User-facing labels are bilingual ({ en, vi }); profile carries a locale |
8. UX & Flows
Key screens (in apps/client): the checkout customer picker/create, and the brand-scoped customer management surface. Customer management is served by @nx/identity; sale-order attachment and the promote endpoint live on the sale customer controller.
9. Data & Domain
| Entity | Role |
|---|---|
Customer | The customer record - name, phone, email, userId, merchantId; common column defs (soft-delete) |
User | A customer is a User with the fixed customer role; promotion adds sign-in credentials |
SaleOrder | Carries an attached customer; the customer is returned on order change |
CustomerRegistrationService | Promotes a captured customer into a full sign-in user account via OTP |
Conceptual only - full schema and invariants in the identity domain model.
10. Dependencies & Assumptions
Depends on
- User Management (User Management) - a customer is a User; promotion turns a customer into a sign-in account.
- Commerce (Commerce) - customers are scoped to the Organization/merchant.
- Sale (
@nx/sale) - the sale order attaches and returns the customer at checkout.
Assumptions
- A merchant/brand (Organization) exists to scope the customer to.
- OTP delivery plumbing is available for the promote-to-user path.
11. Risks & Open Questions
| Risk / question | Mitigation / status |
|---|---|
| Cross-brand customer leakage | All reads/writes scoped per merchant; staff limited to their own brand |
| Customer-management ownership split across packages | Entity in @nx/core, controllers across @nx/sale and @nx/identity; the URD names @nx/identity as the CUS dev owner - consolidation tracked separately |
| Promote-to-user duplicates an existing account | OTP-based registration guards account creation; define the merge path if a phone/email already exists |
| Soft-delete vs. orders referencing the customer | Soft-delete preserves the record and its linked orders |
12. Release Plan & Launch Criteria
| Aspect | Plan |
|---|---|
| Phase | P1 (foundation) - see URD feature catalog |
| Rollout | All merchants; no feature flag |
| Migration | None (new Customer entity) |
| Launch criteria | Create→attach→order-carries-customer verified end-to-end; brand isolation verified; promote-to-user verified with OTP registration |
| Monitoring | Customer creation volume per brand, order-attachment rate, promotion success rate |
13. FAQ
Is a customer a sign-in account? Not by default - a customer is a User with the fixed customer role and no credentials. Promotion adds sign-in via OTP-based registration.
Can a customer be attached to an order after checkout starts? Yes - staff attach a customer to the sale order; the customer is returned on the order change.
What happens to orders when a customer is soft-deleted? Nothing - the customer leaves the active list, but the record and its linked orders are preserved.
Does this PRD cover loyalty points? No - points are a separate increment (Loyalty Points); this increment only introduces the customer record and its attachment to orders.
Are customers shared across brands? No - every customer is scoped to its brand (Organization); staff see only their own brand's customers.
References
- URD: Customer - Customer Profiles
- Related: Loyalty Points · Newsletter Subscribers · Sales Inquiries
- Module: Customer - overview + traceability
- Developer: @nx/identity · @nx/sale · domain model