forked from wangziqi/ruoyi-vue-pro
3.3 KiB
3.3 KiB
EDU-028 — Activate native checkout Promotion activities
- Status: done — tenant-owned discount/reward persistence, native APIs/UI, RBAC, and PostgreSQL evidence delivered
- Type: native module takeover / checkout dependency / tenant isolation
- Phase: 5 / commercialization foundation
- Blockers: EDU-025, EDU-026, EDU-027, PostgreSQL Flyway
Problem
Every normal RuoYi Trade price calculation invokes the native limited-time discount and reward calculators. Those calculators call DiscountActivityApi and RewardActivityApi even when no activity is configured, so V4390's order core still failed with missing Promotion tables before it could return an empty promotion result. Replacing these APIs inside Education would duplicate Promotion ownership and bypass the native administration UI.
Delivered contract
DiscountActivityDO,DiscountProductDO, andRewardActivityDOextendTenantBaseDO; their existing services, mappers, controllers, and public APIs remain authoritative.- V4400 creates tenant-scoped
promotion_discount_activity,promotion_discount_product, andpromotion_reward_activitytables with explicit PostgreSQL sequences and(tenant_id,id)ownership keys. - Discount Product → Activity/SPU/SKU references are tenant-qualified. Active SKU uniqueness, status/time, discount type/value, reward condition/scope, and JSON reward-rule checks fail closed in PostgreSQL.
- The native cross-database
MyBatisUtils.findInSetWithParamIndexalready renders PostgreSQLPOSITION(...)against the comma-separatedLongListTypeHandlervalue; no mapper fork or Education shadow interface is introduced. - Menu IDs 6970–6982 mount the existing
mall/promotion/discountActivity/indexandmall/promotion/rewardActivity/indexVben pages with the exact ten native controller permissions.
Legacy data decision
V4400 starts both activity families empty. Legacy coupon/code campaigns are not equivalent to time-boxed SKU discounts or structured full-reduction/gift rules, and no activity, product scope, time range, or reward rule is inferred.
Verification
- The Promotion tenant contract proves all three activated records participate in framework tenant isolation.
- The focused V4400 scenario proves cross-tenant identifier reuse, composite reference rejection, active-SKU uniqueness, PostgreSQL scope membership semantics, reward-rule/scope rejection, three explicit sequences, exact routes/permissions, and fail-closed global-table adoption.
- A Spring/MyBatis integration test invokes the real
DiscountActivityApiImplandRewardActivityApiImplagainst migrated PostgreSQL tables and proves empty normal-checkout lookups return empty lists rather than missing-table errors. - The full PostgreSQL Flyway suite passes 47 scenarios through V4400.
Explicitly open
- This slice removes the normal price pipeline's discount/reward missing-table blocker; it does not claim end-to-end order creation. Delivery express/template/pick-up persistence and configured Pay App/Channel runtime data remain prerequisites for applicable checkout modes.
- Seckill, bargain, combination, point, and other special-order Promotion tables remain separate tenant-safe activations.
- Legacy Product/campaign/order import, purchase-driven Education entitlement fulfillment, refund-driven revocation, and production API/browser smoke evidence remain separate work.