Skip to content

PRD: Gói, giấy phép & quyền sử dụng lúc chạy

ModuleGói & giấy phép (CORE-15)PRD IDPRD-PLN-001
StatusShippedOwnerLicensing squad
Date2026-06-05Versionv1.0
Packages@nx/licensing · @nx/coreURDPLN · LIC · VAL

TL;DR

Cho phép người vận hành nền tảng bán KICKO dưới dạng các gói đóng gói feature flag có kiểu và hạn mức thiết bị, phát hành một giấy phép từ một gói cho một merchant, và đưa giấy phép đó qua một vòng đời có theo dõi. Lúc chạy, bất kỳ service nào cũng kiểm tra một license key và nhận về một chứng chỉ đã ký mà nó tin cậy ngoại tuyến - nhờ đó việc giới hạn tính năng nhất quán và kiểm toán được mà không cần gọi licensing trực tiếp trên mỗi request. Kết quả: một định nghĩa chung, đáng tin cậy về "merchant này đã trả tiền cho những gì", với khả năng merchant tự cấp một gói dùng thử miễn phí duy nhất.

1. Bối cảnh & Vấn đề

KICKO được bán dưới dạng các gói đóng gói những bộ tính năng và hạn mức ghế (seat) khác nhau, và sản phẩm cần một cách duy nhất, đáng tin cậy để quyết định mỗi merchant được phép chạy những gì. Không có nó, mỗi module lại tự chế ra cách giới hạn tạm bợ riêng và không có định nghĩa chung về "merchant này đã trả tiền cho những gì" - khiến quyền sử dụng trở nên thiếu nhất quán, không kiểm toán được, và không thể suy luận xuyên suốt các service.

Increment này thiết lập trục cấp phép lõi: các gói tái sử dụng mang feature flag có kiểu, các giấy phép phát hành từ những gói đó với một vòng đời được theo dõi, và một lời gọi kiểm tra hiệu lực lúc chạy trả về một chứng chỉ đã ký mà các service khác kiểm chứng ngoại tuyến - nhờ đó một consumer không bao giờ cần gọi licensing trực tiếp trên mỗi request. Thanh toán và tính tiền cố ý nằm ngoài phạm vi; increment này nói về quyền sử dụng, không phải tiền.

2. Mục tiêu & Không phải mục tiêu

Mục tiêu

  • Người vận hành định nghĩa các gói tái sử dụng (dùng thử / thuê bao / vĩnh viễn) với thời hạn, thời gian ân hạn, hạn mức ghế, và các feature flag có kiểu.
  • Phát hành một giấy phép từ một gói, ràng buộc vào một merchant hoặc người dùng, và đưa nó qua renew / suspend / reinstate / revoke với một dấu vết kiểm toán đầy đủ.
  • Kiểm tra hiệu lực một license key lúc chạy và trả về trạng thái, bộ tính năng đã phân giải, và một chứng chỉ đã ký mà các consumer kiểm chứng ngoại tuyến.
  • Phơi bày một danh mục gói công khai cho các bề mặt đăng ký và nâng cấp.
  • Cho phép một merchant tự cấp đúng một gói dùng thử miễn phí mà không cần người vận hành can thiệp.

Không phải mục tiêu

  • Tính tiền, xuất hóa đơn, đòi nợ, hay tích hợp tính phí thanh toán.
  • Đo lường mức sử dụng, heartbeat, hay quét hết hạn chủ động/theo lịch.
  • Thực thi tính năng lúc chạy bên trong các module tiêu thụ - mỗi module tự giới hạn dựa trên chứng chỉ.
  • Một giao diện quản lý giấy phép (thuộc về frontend).

3. Success Metrics

MetricMục tiêu / tín hiệu
Giới hạn ngoại tuyếnMọi service tiêu thụ đều giới hạn tính năng dựa trên chứng chỉ - không có lời gọi licensing trực tiếp nào trên mỗi request
Tính toàn vẹn dùng thửPhát hành gói dùng thử thành công một cách idempotent; một merchant không bao giờ kết thúc với hai gói dùng thử
Đầy đủ kiểm toán100% các thao tác vòng đời tạo ra một event chỉ-thêm và một chứng chỉ được ký lại
Đúng đắn kiểm traCác kết quả kiểm tra (hợp lệ / ân hạn / hết hạn / tạm ngưng / thu hồi) khớp với trạng thái giấy phép

4. Personas & Tình huống sử dụng

PersonaMục tiêu trong tính năng này
Người vận hành nền tảngĐịnh nghĩa gói & feature flag; phát hành, renew, suspend, reinstate, revoke giấy phép
Chủ merchantDuyệt danh mục gói, tự cấp một gói dùng thử miễn phí, chạy trên một giấy phép hợp lệ
Service tiêu thụKiểm tra một license key và giới hạn tính năng & ghế ngoại tuyến dựa trên chứng chỉ

Tình huống cốt lõi: người vận hành định nghĩa một gói với feature flag → một merchant được phát hành (hoặc tự cấp) một giấy phép → một service kiểm tra key và nhận về trạng thái + tính năng đã phân giải + một chứng chỉ đã ký → nó giới hạn tính năng và ghế ngoại tuyến → người vận hành renew / suspend / reinstate / revoke, ký lại chứng chỉ mỗi lần.

5. User Stories

  • Là một người vận hành nền tảng, tôi muốn định nghĩa các gói tái sử dụng với feature flag có kiểu và một hạn mức ghế, để tôi đóng gói những gì mỗi tầng merchant được phép chạy.
  • Là một người vận hành nền tảng, tôi muốn phát hành một giấy phép từ một gói ràng buộc vào một merchant hoặc người dùng, để quyền sử dụng gắn với một principal đã biết kèm một key duy nhất.
  • Là một người vận hành nền tảng, tôi muốn renew, suspend, reinstate, và revoke một giấy phép, để tôi quản lý vòng đời của nó với một dấu vết kiểm toán đầy đủ.
  • Là một chủ merchant, tôi muốn tự cấp một gói dùng thử miễn phí duy nhất, để tôi đánh giá sản phẩm mà không cần người vận hành can thiệp và không kết thúc với các gói dùng thử trùng lặp.
  • Là một chủ merchant, tôi muốn một danh mục công khai các gói đang hoạt động, để tôi chọn hoặc nâng cấp gói của mình.
  • Là một service tiêu thụ, tôi muốn kiểm tra một license key và nhận về một chứng chỉ đã ký, để tôi giới hạn tính năng và ghế ngoại tuyến mà không cần gọi licensing trên mỗi request.

6. Functional Requirements

#Yêu cầuURD ref
FR-1Tạo một gói loại dùng thử / thuê bao / vĩnh viễn, với một thời hạn (hoặc null vĩnh viễn) và một thời gian ân hạn tùy chọnURD-PLN-001..002
FR-2Một gói tùy chọn giới hạn số thiết bị (hạn mức ghế); null = không giới hạnURD-PLN-003
FR-3Gắn các feature flag có kiểu (boolean / number / text / json); một flag đã vô hiệu hóa phân giải về giá trị rỗng/tắt mặc định theo kiểu của nóURD-PLN-004..005
FR-4Phơi bày một danh mục công khai các gói đang hoạt động kèm các tính năng đang hoạt động của chúng, theo thứ tự hiển thịURD-PLN-008
FR-5Phát hành một giấy phép từ một gói, ràng buộc vào một merchant hoặc người dùng, với một key được sinh duy nhất; tính ngày hết hạn từ thời hạn + ân hạnURD-LIC-001..002
FR-6Suspend rồi reinstate; renew (gia hạn hiệu lực, khôi phục một giấy phép hết hạn); revoke (kết thúc, không đảo ngược)URD-LIC-004..005 · URD-LIC-007
FR-7Một merchant tự cấp một giấy phép dùng thử miễn phí duy nhất; một gói dùng thử sẵn có được trả về, không bao giờ nhân bảnURD-LIC-008
FR-8Mọi thao tác vòng đời được ghi vào một event log chỉ-thêmURD-LIC-009
FR-9Mỗi thay đổi vòng đời ký lại và phát hành lại chứng chỉ giấy phépURD-LIC-010
FR-10Kiểm tra một key và trả về việc nó có hợp lệ hay không kèm một mã kết quảURD-VAL-001
FR-11Kiểm tra trả về bộ tính năng đã phân giải với các override theo từng giấy phép được áp dụngURD-VAL-006
FR-12Một lần kiểm tra thành công trả về một chứng chỉ đã ký mà các service khác kiểm chứng ngoại tuyếnURD-VAL-008

Toàn văn yêu cầu và tiêu chí chấp nhận nằm trong URD Gói & giấy phép. PRD này tham chiếu chúng thay vì viết lại.

7. Non-Functional Requirements

Lĩnh vựcYêu cầu
Toàn vẹn dữ liệuMỗi thay đổi vòng đời ghi một event kiểm toán và ký lại chứng chỉ cùng lúc - không có thay đổi trạng thái nào mà thiếu một bản ghi kiểm toán tương ứng
Tính bất biếnEvent log của giấy phép là chỉ-thêm và tồn tại lâu hơn cả việc xóa giấy phép
Tenancy & authzMột giấy phép ràng buộc vào đúng một principal (merchant hoặc người dùng); quản lý gói/giấy phép được giới hạn bởi các permission scope licensing
Hiệu năng / quy môCác consumer kiểm chứng chứng chỉ ngoại tuyến; không có lời gọi licensing trực tiếp trên mỗi request. Hết hạn được phát hiện một cách trễ (lazy) lúc kiểm tra - không có sweeper nền
Tin cậyChứng chỉ được ký (Ed25519) và kiểm chứng được ngoại tuyến bởi bất kỳ service nào
i18nTên hiển thị và mô tả của gói là song ngữ ({ en, vi })

8. UX & Luồng

Bề mặt thuần backend trong @nx/licensing (năm controller trên gói, feature flag, giấy phép, activation, kiểm tra). Không có giao diện quản lý giấy phép trong increment này; các bề mặt đăng ký và nâng cấp đọc danh mục gói công khai.

9. Dữ liệu & Miền

EntityVai trò
PolicyTemplate gói - loại, thời hạn, thời gian ân hạn, hạn mức ghế, metadata hiển thị
PolicyFeatureMột feature flag có kiểu trên một gói (boolean / number / text / json), code duy nhất trong mỗi gói
LicenseMột quyền sử dụng đã phát hành, ràng buộc vào một merchant hoặc người dùng, với một key duy nhất, trạng thái, ngày hết hạn, và các override tùy chọn
ActivationMột ràng buộc của một giấy phép vào một thiết bị qua fingerprint, được tính vào hạn mức ghế
LicenseEventMột bản ghi kiểm toán chỉ-thêm cho mọi thao tác vòng đời

Chỉ ở mức khái niệm - schema và bất biến đầy đủ nằm trong domain model của licensing. Cả năm bảng sống trong @nx/core và được @nx/licensing re-export.

10. Phụ thuộc & Giả định

Phụ thuộc vào

  • Commerce (Commerce) - một giấy phép ràng buộc vào một principal merchant (hoặc người dùng) mà danh tính đến từ Commerce.
  • Permissions (Permissions) - các thao tác quản lý gói và giấy phép được giới hạn bởi các permission scope licensing.
  • Một cặp khóa ký (Ed25519) để ký chứng chỉ, với khóa công khai được phân phối tới các consumer để kiểm chứng ngoại tuyến.

Giả định

  • Các module tiêu thụ tự giới hạn theo từng tính năng dựa trên chứng chỉ; licensing không thực thi tính năng bên trong chúng.
  • Một gói dùng thử miễn phí được seed để merchant có thể tự cấp ngay từ ngày đầu.
  • Việc kiểm tra hết hạn diễn ra một cách trễ (lazy) lúc kiểm tra; báo cáo chấp nhận phát hiện hết hạn theo thời gian (không chủ động).

11. Rủi ro & Câu hỏi mở

Rủi ro / câu hỏiGiảm thiểu / trạng thái
Hết hạn trễ có thể trễ so với độ chính xác báo cáoChấp nhận; hết hạn lật ở lần kiểm tra kế. Mở: bổ sung một sweeper theo lịch nếu báo cáo cần hết hạn chủ động
Chưa có API đọc trên event log của giấy phépLog chỉ-thêm đã tồn tại; câu hỏi mở liệu người vận hành cần một bề mặt REST hay truy cập DB trực tiếp là đủ
Số học thời hạn cố định 30/365 ngàyMở: chuyển sang tháng/năm theo lịch nếu cần
Tin cậy chứng chỉ phụ thuộc vào phân phối khóaKhóa công khai được gửi tới các consumer; đường xoay khóa phải được định nghĩa trước khi đổi khóa

12. Kế hoạch phát hành & Tiêu chí ra mắt

Khía cạnhKế hoạch
PhaseP1 (gói + giấy phép + kiểm tra), P2 (activation + dùng thử miễn phí + phân phối chứng chỉ) - xem catalog tính năng URD
RolloutNền tảng của @nx/licensing; một gói dùng thử miễn phí được seed để merchant tự cấp ngay từ ngày đầu; không feature flag
MigrationKhông (entity mới; các bảng sống trong @nx/core, gói dùng thử miễn phí được seed lúc khởi động)
Tiêu chí ra mắtPhát hành → kiểm tra → chứng chỉ kiểm chứng ngoại tuyến đầu-cuối; các thao tác vòng đời mỗi cái tạo ra một event kiểm toán + chứng chỉ ký lại; phát hành dùng thử miễn phí idempotent
Giám sátPhân bố kết quả kiểm tra, tỷ lệ phát hành dùng thử miễn phí, tính nhất quán giữa event kiểm toán và thao tác vòng đời, lỗi ký chứng chỉ

13. FAQ

Cái này có xử lý tính tiền hay thanh toán không? Không - increment này chỉ về quyền sử dụng. Tính tiền, xuất hóa đơn, đòi nợ, và tích hợp tính phí thanh toán nằm ngoài phạm vi rõ ràng.

Một service có gọi licensing trên mỗi request không? Không - một service kiểm tra key một lần và nhận về một chứng chỉ đã ký mà nó kiểm chứng ngoại tuyến. Việc giới hạn theo từng request diễn ra dựa trên chứng chỉ, không phải một lời gọi licensing trực tiếp.

Điều gì xảy ra khi một giấy phép hết hạn? Hết hạn được phát hiện một cách trễ (lazy) lúc kiểm tra: một giấy phép vượt quá cửa sổ ân hạn của nó bị lật sang hết hạn ở lần kiểm tra kế và trả về không hợp lệ. Không có sweeper nền.

Một merchant có thể nhận hai gói dùng thử miễn phí không? Không - việc phát hành dùng thử miễn phí là idempotent. Một merchant đã có một gói dùng thử sẽ nhận lại gói sẵn có thay vì một bản trùng.

Ai thực thi từng tính năng riêng lẻ? Mỗi module tiêu thụ tự giới hạn dựa trên bộ tính năng đã phân giải trong chứng chỉ. Licensing định nghĩa và ký các quyền sử dụng; nó không thực thi chúng bên trong các module khác.

Tham khảo

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