forked from wangziqi/ruoyi-vue-pro
35 lines
2.8 KiB
Markdown
35 lines
2.8 KiB
Markdown
# EDU-019 — Secure learning activation codes
|
|
|
|
## Status
|
|
|
|
Done for the bounded V4310 contract. Legacy activation-code import and coupons remain separate.
|
|
|
|
## Decision
|
|
|
|
Activation codes are Education learning-access credentials, not Mall Promotion coupons. They reference a Mall-owned SPU through the existing tenant-scoped `education_resource_product_binding`, authenticate redemption with the existing Member principal, and grant access through the existing idempotent `EducationEntitlementService` event pipeline. No product, member, coupon, or second entitlement ledger is introduced.
|
|
|
|
## Delivered contract
|
|
|
|
- Tenant-owned activation-code batches and codes with database constraints, tenant-composite foreign keys, optimistic versions, and separate query/manage/generate permissions.
|
|
- Admin batch page/create/update/generate and masked code page/disable endpoints.
|
|
- Member-only app check/redeem endpoints; administrator and anonymous principals fail closed.
|
|
- Cryptographically random codes normalized for redemption. Plaintext is returned only by the successful generation response; persistence stores SHA-256 digest and a mask.
|
|
- `SELECT ... FOR UPDATE` serializes redemption. A successful grant writes the existing entitlement event/aggregate, marks the code redeemed, and increments the batch count in one transaction.
|
|
- Same-member retry returns the existing entitlement idempotently; another member receives an already-used conflict.
|
|
- Batch SPU, duration, and prefix become immutable after generation. Disabled batches, codes, or resource bindings cannot be redeemed. `durationDays=0` intentionally means no expiry.
|
|
- Vben page `education/activation-code/index` provides batch and masked-code tables, create/edit/generate flows, copy/download, unsaved-plaintext dismissal warning, and disable confirmation. Closing the generation modal clears plaintext.
|
|
|
|
## Verification
|
|
|
|
- PostgreSQL Flyway verifies both tables, constraints, cross-tenant batch references, four menu rows, and migration history through V4310.
|
|
- Controller contracts verify independent admin permissions and Member-only app access.
|
|
- Unit tests verify digest/mask persistence, entitlement composition, replay/conflict, target validation, and generated-batch immutability.
|
|
- Real PostgreSQL service tests verify digest-only persistence, tenant isolation, entitlement/event creation, same/different-member behavior, disabled dependencies, and one winner under concurrent redemption.
|
|
- Vben formatting, lint, Vue typecheck, and production build cover the fifteenth custom Education page.
|
|
|
|
## Explicit non-goals
|
|
|
|
- Importing or preserving plaintext from legacy activation-code rows.
|
|
- Coupon templates, claims, discounts, stacking, or redemption; those remain Mall Promotion-owned.
|
|
- Payment/order/refund fulfillment, legacy payment mode/provider mapping, tenant PNVS, or generic encrypted secret rotation.
|