Mô hình miền
Schema nằm trong
@nx/core/src/models/schemas/identity/(vàpublic/configuration/dùng chung). Cột numeric/text tuân theo quy ước IGNIS.
1. ERD đầy đủ
2. Cột chung
Mỗi entity bổ sung các cột này qua generateCommonColumnDefs():
| Cột | Kiểu |
|---|---|
id | text (PK, Snowflake) |
createdAt / modifiedAt | timestamptz |
createdBy / modifiedBy | text |
deletedAt | timestamptz (soft-delete) |
metadata | jsonb |
status | text (khi dùng …WithStatusDefs) |
3. Entities
3.1 User
| Thuộc tính | Giá trị |
|---|---|
| Bảng | User |
| Soft-delete | có |
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
username | text | Username hiển thị (cũng được lưu như identifier) | |
status | text | ✓ | ACTIVATED / DEACTIVATED / LOCKED |
lastLoginAt | timestamptz | Cập nhật bởi signIn |
3.2 UserIdentifier
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
userId | text | ✓ | FK |
identifier | text | ✓ | Giá trị đăng nhập (email, phone, username, v.v.) |
scheme | text | ✓ | USERNAME / EMAIL / PHONE_NUMBER / USER_NUMBER / NX_AUTH |
verified | boolean | ✓ | Mặc định false; chuyển true sau khi xác nhận OTP |
Ràng buộc unique: partial unique trên (scheme, identifier) WHERE deletedAt IS NULL — một giá trị duy nhất trên mỗi scheme.
3.3 UserCredential
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
userId | text | ✓ | FK |
scheme | text | ✓ | BASIC (mật khẩu) / TWO_FA / OAUTH / OAUTH2 |
credential | text | ✓ | Đã hash qua Bun.password (hoặc token ngoài cho OAUTH) |
3.4 UserProfile
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
userId | text | ✓ | FK (1:1) |
firstName / lastName | text | — | |
birthday | timestamptz | — | |
locale | text | en / vi (quyết định template mail/SMS) |
3.5 UserConfiguration
Feature flags / settings theo từng user dưới dạng cặp kv trong jsonb.
3.6 Role
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
identifier | text | ✓ | Slug duy nhất (SUPER_ADMIN, v.v.) |
name | i18n jsonb | ✓ | Hiển thị |
description | i18n jsonb | — | |
priority | int | ✓ | Khoảng 101–499 cho custom; system role dùng 500–1000 |
type | text | ✓ | SYSTEM / CUSTOM / UNKNOWN |
status | text | ✓ | ACTIVATED / DEACTIVATED |
System roles (bất biến, được seed): SUPER_ADMIN(1000), ADMIN(500), OPERATOR(600), OWNER(500), CASHIER(110), EMPLOYEE(100), CUSTOMER(10), GUEST(1).
3.7 Permission
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
code | text | ✓ | <Resource>.<action> (ví dụ User.create) |
resource | text | ✓ | Đối tượng phân quyền |
action | text | ✓ | find / create / updateById / deleteById / domain action |
name / description | i18n jsonb | — |
3.8 PolicyDefinition (cạnh RBAC)
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
variant | text | ✓ | GROUP (subject ↔ subject) / PERMISSION (role ↔ permission) |
subjectType | text | ✓ | User / Role / Permission |
subjectId | text | ✓ | FK target |
targetType | text | ✓ | Role / Permission / User / Organizer / Merchant |
targetId | text | ✓ | FK target |
scope | text | SYSTEM / ORGANIZER / MERCHANT (PolicyDomains) |
Cạnh thường gặp:
| Loại cạnh | Variant | Subject | Target |
|---|---|---|---|
| User → Role | GROUP | User | Role |
| User → Organizer | GROUP | User | Organizer |
| User → Merchant | GROUP | User | Merchant |
| Role → Permission | PERMISSION | Role | Permission |
3.9 Customer
Mở rộng User với các trường ngữ cảnh sales (quản lý ở identity nhưng được sale đọc).
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
userId | text | FK tuỳ chọn (một số khách là guest, không có User) | |
name | text | ✓ | Hiển thị |
phone / email | text | Liên hệ | |
merchantId | text | ✓ | Owner |
pointBalance | decimal(15,4) | ✓ | Điểm thưởng (mặc định 0; được sale ghi) |
3.10 Employee
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
userId | text | ✓ | FK đến User |
merchantId | text | Nơi làm việc (hoặc organizerId) | |
organizerId | text | Nơi làm việc thay thế | |
position | text | Chức danh | |
status | text | ✓ | ACTIVATED / DEACTIVATED |
3.11 Configuration (dùng chung)
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
code | text | ✓ | Duy nhất theo partial (group, principalId, principalType, environment) |
group | text | ✓ | INTEGRATION / MAIL / SMS / OTP / v.v. |
principalType / principalId | text | Khi theo từng merchant (ví dụ provider SMS theo merchant) | |
environment | text | DEVELOPMENT / PRODUCTION | |
tValue | text | Giá trị JSON (mã hoá cho credential) | |
dataType | text | TEXT / JSON / BOOLEAN | |
credential | text | Đã mã hoá (AES-256-GCM qua CryptoUtility); ẩn khỏi đọc CRUD |
Identity đọc cấu hình mail/SMS/OTP từ bảng này; payment ghi credential provider đã mã hoá.
4. Status Enums
4.1 UserIdentifierSchemes
| Giá trị | Mô tả |
|---|---|
USERNAME | Username hiển thị |
EMAIL | Địa chỉ email |
PHONE_NUMBER | Số điện thoại E.164 |
USER_NUMBER | ID số nội bộ |
NX_AUTH | NX-Auth federation |
4.2 UserCredentialSchemes
| Giá trị | Dùng để |
|---|---|
BASIC | Mật khẩu (Bun.password hash) |
TWO_FA | Token yếu tố thứ hai (placeholder) |
OAUTH | OAuth1 federation (đã khai báo, chưa có provider) |
OAUTH2 | OAuth2 federation (đã khai báo, chưa có provider) |
4.3 RoleTypes
| Giá trị | Mã |
|---|---|
SYSTEM | seed sẵn, bất biến |
CUSTOM | merchant tự định nghĩa |
UNKNOWN | fallback |
4.4 PolicyDomains (trường scope)
| Giá trị | Dùng để |
|---|---|
SYSTEM | cạnh toàn cục |
ORGANIZER | giới hạn theo organizer |
MERCHANT | giới hạn theo merchant |
4.5 OTP namespaces
| Namespace | Dùng để |
|---|---|
verify-email | Đăng ký email |
verify-phone | Đăng ký phone |
forgot-password | Đặt lại mật khẩu |
phone-auth | Đăng nhập chỉ-bằng-phone (khi áp dụng) |
add-phone / add-email | Liên kết với tài khoản đã xác thực |
4.6 OTP defaults
| Setting | Giá trị |
|---|---|
CODE_LENGTH | 6 |
EXPIRY | 5–15 phút tuỳ flow |
MAX_ATTEMPTS | 5 |
LOCKOUT | 10–15 phút |
RESEND_COOLDOWN | 60s |
MAX_RESENDS_PER_DAY | 5 |
5. Invariants liên-entity
| Invariant | Cách đảm bảo |
|---|---|
UserIdentifier(scheme, value) duy nhất toàn hệ thống (theo scheme) | Partial unique index |
UserCredential.scheme=BASIC đã hash (không bao giờ plaintext) | AuthenticationService.signUp + changePassword luôn hash |
Role.priority duy nhất trong cùng type | Validation service trong RoleService |
System role (type=SYSTEM) không thể xoá/sửa trừ qua migration | Service guard |
Cycle PolicyDefinition (User → Role → User) bị cấm | Kiểm tra acyclicity ở mức service |
Hạn ngạch OTP hàng ngày theo (namespace, identifierValue) | Bộ đếm Redis {ns}:daily:{value} |
Payload JWT luôn bao gồm userId, roles, organizers, merchants | AuthenticationService.generateToken |
6. Hành vi Soft-delete
| Entity | Soft-delete | Ghi chú |
|---|---|---|
| Mọi entity của identity | ✓ | Cờ deletedAt; mặc định đọc IS NULL |
Configuration | ✓ | Nhưng các bản ghi seed thường được phục hồi khi chạy lại migration |