Skip to content

Domain Model

Cả năm bảng nằm trong schema PostgreSQL licensing và được định nghĩa trong @nx/core tại packages/core/src/models/schemas/licensing/. @nx/licensing chỉ re-export repository.

1. ERD đầy đủ

2. Entities

Policy

Thuộc tínhGiá trị
Tablelicensing.Policy
Sourcepackages/core/src/models/schemas/licensing/policy/schema.ts
Soft-deletecó (generateCommonColumnDefs)
Owner ID column— (template cấp hệ thống)

Trường:

TrườngKiểuBắt buộcMặc địnhMô tả
idtextSnowflakePrimary key
namejsonb (i18n)Tên hiển thị { default, en, vi }
descriptionjsonb (i18n)Tuỳ chọn
producttextĐịnh danh product (có index)
typetextPolicyTypes (xem enum)
statustextACTIVATEDPolicyStatuses
sequenceinteger0Thứ tự hiển thị
durationjsonb (IDuration){ unit, value }; null = vĩnh viễn
activationjsonb (IActivationConfig){ limit }; null = không giới hạn thiết bị
gracePeriodjsonb (IDuration)Mở rộng cửa sổ xác thực sau khi hết hạn

Enum type (PolicyTypes):

Giá trịMô tả
000_TRIALGói dùng thử (free trial seed dùng cái này)
100_SUBSCRIPTIONSubscription có giới hạn thời gian
200_PERPETUALKhông hết hạn (đặt duration: null)

Enum status (PolicyStatuses): ACTIVATED · DEACTIVATED · ARCHIVED.

Index: IDX trên product, type, status.

PolicyFeature

Thuộc tínhGiá trị
Tablelicensing.PolicyFeature
Sourcepackages/core/src/models/schemas/licensing/policy-feature/schema.ts
Soft-deletekhông (generateTzColumnDefs({ deleted: { enable: false } }))
Owner ID columnpolicyId

Trường:

TrườngKiểuBắt buộcMặc địnhMô tả
idtextSnowflakePrimary key
policyIdtextFK → Policy.id (cascade delete)
codetextKhoá feature (vd MAX_ALLOCATION_LAYOUTS)
dataTypetextboolean / number / text / json (từ generateDataTypeColumnDefs)
boValuebooleanGiá trị khi dataType=boolean
nValuenumericGiá trị khi dataType=number
tValuetextGiá trị khi dataType=text
jValuejsonbGiá trị khi dataType=json
namejsonb (i18n)Tên hiển thị
descriptionjsonb (i18n)Tuỳ chọn
sequenceinteger0Thứ tự hiển thị
statustextACTIVATEDPolicyFeatureStatuses (ACTIVATED/DEACTIVATED)

Giá trị đa hình: LicensingBaseService.DATA_TYPE_RESOLVERS đọc cột khớp với dataType. Một feature DEACTIVATED giải về mặc định theo từng kiểu (false/0/''/null).

Index & ràng buộc: UQ trên (policyId, code); IDX trên policyId, status; FK cascade khi delete.

License

Thuộc tínhGiá trị
Tablelicensing.License
Sourcepackages/core/src/models/schemas/licensing/license/schema.ts
Soft-delete
Owner ID columnentityType + entityId (principal đa hình)

Trường:

TrườngKiểuBắt buộcMặc địnhMô tả
idtextSnowflakePrimary key
policyIdtextFK → Policy.id
keytextLicense key (PREFIX-XXXX-XXXX-XXXX-XXXX)
namejsonb (i18n)Tên hiển thị
statustextACTIVATEDLicenseStatuses (xem enum)
entityTypetextLicensePrincipalTypes: Merchant / User
entityIdtextId principal
certificatetextEnvelope cert đã ký mới nhất (base64)
overridejsonb{ activation, features } — ghi đè mặc định Policy
issuedAttimestamptznow()
startsAttimestamptznow()Bắt đầu hiệu lực
expiresAttimestamptznull = vĩnh viễn
graceExpiresAttimestamptzHết cửa sổ grace sau hết hạn
lastValidatedAttimestamptzCập nhật (fire-and-forget) mỗi lần validate thành công

Enum status (LicenseStatuses):

Giá trịMô tả
ACTIVATEDĐang hoạt động và dùng được
SUSPENDEDTạm vô hiệu (có thể reinstate)
EXPIREDQua expiresAt + grace (đặt lazy khi validate)
REVOKEDChấm dứt vĩnh viễn

isActive = chỉ ACTIVATED; isInactive = {SUSPENDED, REVOKED, EXPIRED}.

Index & ràng buộc: UQ partial-unique trên key (where deletedAt IS NULL); IDX trên policyId, status, (entityType, entityId), entityId, expiresAt; FK → Policy.id.

Activation

Thuộc tínhGiá trị
Tablelicensing.Activation
Sourcepackages/core/src/models/schemas/licensing/activation/schema.ts
Soft-delete
Owner ID columnlicenseId

Trường:

TrườngKiểuBắt buộcMặc địnhMô tả
idtextSnowflakePrimary key
licenseIdtextFK → License.id (cascade delete)
fingerprinttextFingerprint thiết bị
labeltextTên thiết bị thân thiện
platformtextOS / platform
hostnametextHostname thiết bị
iptextIP thấy gần nhất

Index & ràng buộc: UQ partial-unique trên (licenseId, fingerprint) (where deletedAt IS NULL) — một activation mỗi thiết bị mỗi license; IDX trên licenseId; FK cascade.

LicenseEvent

Thuộc tínhGiá trị
Tablelicensing.LicenseEvent
Sourcepackages/core/src/models/schemas/licensing/license-event/schema.ts
Soft-deletekhông (audit chỉ-thêm)
Owner ID columnlicenseId (nullable)

Trường:

TrườngKiểuBắt buộcMặc địnhMô tả
idtextSnowflakePrimary key
licenseIdtextFK → License.id (ON DELETE SET NULL)
eventtextLicenseEventTypes (created/activated/deactivated/suspended/reinstated/renewed/expired/revoked)
iptext
userAgenttext
datajsonb{}Payload theo sự kiện
metadatajsonb

Index: IDX trên licenseId, event; FK ON DELETE SET NULL (event sống sót qua việc xoá license).

3. Bất biến xuyên entity

Bất biếnCách thực thi
Số activation ≤ activation.limitActivationService.activate / ValidationService.tryCreateActivation: SELECT License FOR UPDATE → re-COUNT trong tx → rollback nếu >= limit
Một activation mỗi (licenseId, fingerprint)Partial-unique index + fast path find-before-create
License key duy nhất trong các hàng còn sốngPartial-unique index trên key WHERE deletedAt IS NULL
Giá trị feature khớp dataTypeDATA_TYPE_RESOLVERS đọc cột có kiểu; DEACTIVATED → mặc định theo kiểu
renew yêu cầu Policy có durationLỗi RENEW_PERPETUAL nếu duration là null
Chứng chỉ phản ánh trạng thái license hiện tạiRe-publish sau mỗi mutation vòng đời (issue/suspend/reinstate/renew/revoke) và khi lazy expiry

4. Hành vi Soft-delete

EntitySoft-deleteHard-deleteGhi chú
Policycó (deletedAt)qua repoPolicyController xoá theo status (không hard delete trong app)
Licensequa repoMặc định đọc deletedAt IS NULL
Activationcascade từ License (FK)Deactivate dùng deleteById
PolicyFeaturekhôngcascade từ Policy (FK)Cột deleted bị tắt
LicenseEventkhôngFK SET NULL khi xoá licenseAudit chỉ-thêm

5. Trang liên quan

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