PRD: Tài khoản & cấu hình người dùng
| Module | Quản lý Người dùng (CORE-01) | PRD ID | PRD-USR-001 |
| Status | Shipped | Owner | Identity squad |
| Date | 2026-05-27 | Version | v1.0 |
| Packages | @nx/identity · @nx/core | URD | USR · CFG |
TL;DR
Cấp cho mỗi người dùng trên KICKO một tài khoản bền vững, có thể xóa mềm: một ID do hệ thống sinh ra, có thể giữ nhiều identifier (username, email, số điện thoại), một profile có thể chỉnh sửa kèm tùy chọn locale, một vòng đời trạng thái được kiểm soát, và một bộ thiết lập cá nhân mặc định được tạo tự động khi đăng ký. Kết quả: một bản ghi tài khoản đáng tin cậy duy nhất để mọi module khác gắn role, nhân viên và khách hàng lên trên - và để chính người dùng đọc và tinh chỉnh.
1. Context & Problem
Mọi module khác đều tin cậy danh tính và scope do Quản lý Người dùng cấp, nên bản thân tài khoản - bản ghi bền vững mà một người sở hữu, cùng các identifier, profile, trạng thái và thiết lập cá nhân - phải tồn tại trước khi có thể gắn role, nhân viên hay khách hàng lên trên. Nếu không có một tài khoản hạng nhất, sẽ không có subject ổn định để gắn role, không có cách xác minh email hay số điện thoại nào thực sự thuộc về user, không có nơi lưu tùy chọn theo từng user như ngôn ngữ, và không có đảm bảo rằng dữ liệu tài khoản sống sót sau một thao tác "xóa". Đây là điều kiện tiên quyết bắt buộc cho phần còn lại của nền tảng.
Phần này xây dựng các phần tính năng USR (Tài khoản người dùng) và CFG (Cấu hình người dùng) trên nền identity, đặt cạnh xác thực và cung cấp đầu vào cho việc phân giải role và scope.
2. Goals & Non-Goals
Goals
- Một tài khoản người dùng với ID do hệ thống sinh ra duy nhất, có thể xóa mềm và không bao giờ bị xóa vật lý.
- Nhiều identifier cho mỗi user (username, email, số điện thoại): username bắt buộc và được coi là đã xác minh; email/số điện thoại bắt đầu ở trạng thái chưa xác minh và cần OTP.
- Một profile có thể chỉnh sửa (tên, ngày sinh, locale, thông tin liên hệ) kèm tùy chọn ngôn ngữ / locale.
- Một vòng đời trạng thái (kích hoạt, vô hiệu hóa, chặn, lưu trữ) được kiểm soát theo điều kiện đăng nhập, với
ARCHIVEDlà trạng thái kết thúc. - Một bộ cấu hình mặc định cho mỗi user được tạo tự động khi đăng ký, được nhóm và đánh khóa duy nhất theo code cho từng user.
- User có thể đọc và cập nhật cấu hình của chính mình (gồm một đường đọc và một cờ launchpad-tour đã lưu).
Non-Goals
- Bản thân xác thực, gửi OTP và các luồng mật khẩu → phần
AUTH/ Authentication. - Tạo role tùy biến và quản lý permission động → Permissions.
- Mời người dùng, quản lý session / thu hồi từ xa, lịch sử đăng nhập / audit.
- Truy cập đa tổ chức cho một user; bắt buộc MFA.
3. Success Metrics
| Metric | Mục tiêu / tín hiệu |
|---|---|
| Độ bền tài khoản | Không có xóa vật lý; mọi tài khoản bị gỡ vẫn còn dưới dạng dòng đã xóa mềm |
| Tính toàn vẹn identifier | 100% identifier duy nhất trong cùng loại; không có bản trùng đã xác minh |
| Tính đúng đắn xác minh | Email/số điện thoại chỉ dùng được sau khi xác minh OTP; user bị vô hiệu hóa/chặn không thể đăng nhập |
| Khởi tạo cấu hình | 100% lượt đăng ký tạo ra bộ cấu hình mặc định, được nhóm và đánh khóa theo code |
| Tự phục vụ | User có thể đọc và cập nhật profile và cấu hình của mình mà không cần operator hỗ trợ |
4. Personas & Use Cases
| Persona | Mục tiêu |
|---|---|
| Chủ sở hữu / người dùng cuối | Sở hữu một tài khoản, chỉnh sửa profile và locale, quản lý email/số điện thoại, tinh chỉnh thiết lập cá nhân |
| Operator được ủy quyền | Thay đổi trạng thái của user (kích hoạt, vô hiệu hóa, chặn, lưu trữ) trong phạm vi của mình |
| Các module khác | Dựa vào một subject tài khoản ổn định, có scope cho role, nhân viên và khách hàng |
Core scenarios: một user đăng ký → một tài khoản, profile, các identifier và bộ cấu hình mặc định được tạo → user chỉnh sửa profile/locale, thêm và xác minh OTP cho email hoặc số điện thoại, và đọc/cập nhật thiết lập → một operator được ủy quyền thay đổi trạng thái của user, điều này kiểm soát đăng nhập; dữ liệu tài khoản luôn được giữ lại qua xóa mềm.
5. User Stories
- Là một user, tôi muốn một tài khoản duy nhất có thể giữ một username cùng nhiều email và số điện thoại, để tôi đăng nhập bằng identifier nào tôi có.
- Là một user, tôi muốn thêm một email hoặc số điện thoại và xác minh qua OTP, để liên hệ đó trở thành đăng nhập đáng tin.
- Là một user, tôi muốn chỉnh sửa profile và đặt ngôn ngữ / locale của mình, để sản phẩm hiển thị đúng với tôi.
- Là một operator được ủy quyền, tôi muốn kích hoạt, vô hiệu hóa, chặn hoặc lưu trữ một user, để truy cập phản ánh đúng tình trạng tài khoản.
- Là một user, tôi muốn tài khoản được giữ lại ngay cả khi "xóa", để dữ liệu không bao giờ bị mất âm thầm.
- Là một user, tôi muốn thiết lập mặc định được tạo tự động và do tôi chỉnh sửa, để các tùy chọn của tôi (gồm cả launchpad tour) được lưu lại.
6. Functional Requirements
| # | Requirement | URD ref |
|---|---|---|
| FR-1 | Mỗi user có một ID do hệ thống sinh ra duy nhất; dữ liệu tài khoản có thể xóa mềm và không bao giờ bị xóa vật lý | URD-USR-001 · URD-USR-009 |
| FR-2 | Một user có thể giữ nhiều identifier (username, email, số điện thoại), mỗi cái duy nhất trong cùng loại | URD-USR-002..003 |
| FR-3 | Username bắt buộc và được coi là đã xác minh; identifier email/số điện thoại bắt đầu chưa xác minh và cần OTP | URD-USR-004..005 |
| FR-4 | User có thể xem và cập nhật profile của chính mình (tên, ngày sinh, locale, liên hệ) | URD-USR-006 |
| FR-5 | User có thể đặt tùy chọn ngôn ngữ / locale | URD-USR-010 |
| FR-6 | Người dùng được ủy quyền có thể thay đổi trạng thái của user (kích hoạt, vô hiệu hóa, chặn, lưu trữ); user bị vô hiệu hóa/chặn không thể đăng nhập | URD-USR-007..008 |
| FR-7 | ARCHIVED là trạng thái kết thúc và không thể kích hoạt lại | URD-USR-011 |
| FR-8 | Một bộ cấu hình mặc định được tạo tự động khi một user đăng ký | URD-CFG-001 |
| FR-9 | Cấu hình được nhóm và đánh khóa duy nhất theo code cho từng user | URD-CFG-002 |
| FR-10 | User có thể xem và cập nhật cấu hình của chính mình (đường đọc + cờ launchpad-tour đã lưu) | URD-CFG-003 |
Toàn văn requirement và tiêu chí chấp nhận nằm trong URD Quản lý Người dùng. PRD này tham chiếu thay vì lặp lại chúng.
7. Non-Functional Requirements
| Area | Requirement |
|---|---|
| Tính toàn vẹn dữ liệu | Tính duy nhất của identifier có nhận biết xác minh (chỉ ràng buộc duy nhất trên identifier đã xác minh); xóa mềm giữ lại mọi dòng tài khoản |
| Tenancy & authz | Scope tài khoản (organizer/merchant) được phân giải theo từng user; thao tác trạng thái/profile/cấu hình đều được gác permission |
| Quyền riêng tư | Yêu cầu OTP lại cho một identifier đã tồn tại sẽ gửi âm thầm - không rò rỉ thông tin liệt kê tài khoản |
| Tính nhất quán | Đăng ký tạo tài khoản, profile, các identifier và cấu hình mặc định cùng nhau; không cho phép tạo một phần |
| i18n | Nhãn/trạng thái hướng người dùng song ngữ ({ en, vi }); tùy chọn locale chi phối cách hiển thị |
8. UX & Flows
Các màn hình chính (trong apps/client): chỉnh sửa profile người dùng, chọn locale, quản lý identifier, và danger zone của thiết lập merchant; cờ launchpad-tour được lưu dưới dạng một cấu hình người dùng.
9. Data & Domain
| Entity | Vai trò |
|---|---|
User | Tài khoản bền vững - ID do hệ thống sinh ra, trạng thái, xóa mềm, scope organizer/merchant |
UserIdentifier | Một giá trị đăng nhập (username / email / số điện thoại) kèm cờ xác minh; tính duy nhất có nhận biết xác minh |
UserProfile | Thông tin cá nhân một-cho-mỗi-user - tên, ngày sinh, locale, liên hệ |
UserConfiguration | Một thiết lập key-value theo từng user, được nhóm và đánh khóa duy nhất theo code |
Chỉ mang tính khái niệm - schema và bất biến đầy đủ nằm trong domain model của identity.
10. Dependencies & Assumptions
Phụ thuộc vào
- Authentication (URD-AUTH) - đăng ký, gửi OTP và việc kiểm soát đăng nhập nằm trong phần
AUTH. - Roles & Scoping (URD-ROLE) - tài khoản là subject mà role và scope organizer/merchant gắn vào.
@nx/core- model dùng chung, scope và phần kết nối cấu hình.
Giả định
- Một user đăng ký qua luồng sign-up, kích hoạt việc tạo tài khoản, profile, identifier và cấu hình mặc định.
- Kênh OTP (email/SMS) tồn tại để xác minh identifier email và số điện thoại.
11. Risks & Open Questions
| Rủi ro / câu hỏi | Giảm thiểu / trạng thái |
|---|---|
| Identifier trùng lặp giữa các user | Ràng buộc duy nhất theo loại trên identifier đã xác minh; constraint mức bảng được làm lại thành kiểm tra có nhận biết xác minh |
| Liệt kê tài khoản qua yêu cầu OTP | Yêu cầu OTP lại cho một identifier đã tồn tại gửi âm thầm |
| Tài khoản tạo dở khi đăng ký thất bại | Tài khoản + profile + identifier + cấu hình mặc định được tạo cùng nhau; từ chối tạo một phần |
| Kích hoạt lại một tài khoản đã lưu trữ | ARCHIVED là trạng thái kết thúc theo thiết kế; không có đường kích hoạt lại |
12. Release Plan & Launch Criteria
| Aspect | Plan |
|---|---|
| Phase | P1 (nền tảng) - xem catalog tính năng URD |
| Rollout | Mọi user; không có feature flag |
| Migration | Không cần cho tài khoản mới; cấu hình mặc định được seed cho từng user khi đăng ký |
| Launch criteria | Đăng ký → kiểm chứng tài khoản/profile/identifier/cấu hình mặc định; xác minh OTP đổi trạng thái identifier; chuyển trạng thái kiểm soát đăng nhập; xóa mềm giữ lại dữ liệu |
| Monitoring | Tỷ lệ đăng ký thành công, tỷ lệ xác minh OTP, vi phạm tính duy nhất identifier, độ phủ khởi tạo cấu hình |
13. FAQ
Một user có thể có nhiều hơn một email hoặc số điện thoại không? Có - một user giữ nhiều identifier (username, email, số điện thoại). Username bắt buộc và đã xác minh; email và số điện thoại bắt đầu chưa xác minh và cần OTP.
Điều gì xảy ra khi một tài khoản bị "xóa"? Nó bị xóa mềm - dòng dữ liệu được giữ lại và không bao giờ bị xóa vật lý.
Vì sao user bị vô hiệu hóa hoặc bị chặn không thể đăng nhập? Trạng thái kiểm soát đăng nhập: chỉ tài khoản đang hoạt động mới xác thực; user bị vô hiệu hóa và bị chặn bị từ chối.
ARCHIVED có đảo ngược được không? Không - ARCHIVED là trạng thái kết thúc và không thể kích hoạt lại.
Thiết lập mặc định đến từ đâu? Một bộ cấu hình mặc định được tạo tự động khi đăng ký, được nhóm và đánh khóa duy nhất theo code; user có thể đọc và cập nhật cấu hình của chính mình.
Yêu cầu OTP cho một email đã tồn tại có để lộ rằng tài khoản tồn tại không? Không - yêu cầu lại cho một identifier đã tồn tại gửi âm thầm để tránh rò rỉ liệt kê.
References
- URD: Quản lý Người dùng - Tài khoản người dùng · Cấu hình người dùng
- Xây trên: Authentication · Roles & Scoping
- Module: Quản lý Người dùng - tổng quan + traceability
- Developer: @nx/identity · domain model · @nx/core