@endora-commerce/mod-promotions 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/admin/api/promotions-client.d.ts +98 -0
  4. package/dist/admin/api/promotions-client.d.ts.map +1 -0
  5. package/dist/admin/api/promotions-client.js +40 -0
  6. package/dist/admin/api/promotions-client.js.map +1 -0
  7. package/dist/admin/components/CouponGeneratorForm.d.ts +10 -0
  8. package/dist/admin/components/CouponGeneratorForm.d.ts.map +1 -0
  9. package/dist/admin/components/CouponGeneratorForm.js +56 -0
  10. package/dist/admin/components/CouponGeneratorForm.js.map +1 -0
  11. package/dist/admin/index.d.ts +43 -0
  12. package/dist/admin/index.d.ts.map +1 -0
  13. package/dist/admin/index.js +69 -0
  14. package/dist/admin/index.js.map +1 -0
  15. package/dist/admin/pages/PromotionEditPage.d.ts +9 -0
  16. package/dist/admin/pages/PromotionEditPage.d.ts.map +1 -0
  17. package/dist/admin/pages/PromotionEditPage.js +333 -0
  18. package/dist/admin/pages/PromotionEditPage.js.map +1 -0
  19. package/dist/admin/pages/PromotionRulesPage.d.ts +14 -0
  20. package/dist/admin/pages/PromotionRulesPage.d.ts.map +1 -0
  21. package/dist/admin/pages/PromotionRulesPage.js +86 -0
  22. package/dist/admin/pages/PromotionRulesPage.js.map +1 -0
  23. package/dist/admin/pages/PromotionStatsPage.d.ts +13 -0
  24. package/dist/admin/pages/PromotionStatsPage.d.ts.map +1 -0
  25. package/dist/admin/pages/PromotionStatsPage.js +44 -0
  26. package/dist/admin/pages/PromotionStatsPage.js.map +1 -0
  27. package/dist/admin/pages/PromotionsPage.d.ts +9 -0
  28. package/dist/admin/pages/PromotionsPage.d.ts.map +1 -0
  29. package/dist/admin/pages/PromotionsPage.js +79 -0
  30. package/dist/admin/pages/PromotionsPage.js.map +1 -0
  31. package/dist/backend/actions/amount-off-cart.d.ts +4 -0
  32. package/dist/backend/actions/amount-off-cart.d.ts.map +1 -0
  33. package/dist/backend/actions/amount-off-cart.js +16 -0
  34. package/dist/backend/actions/amount-off-cart.js.map +1 -0
  35. package/dist/backend/actions/buy-x-get-y-free.d.ts +8 -0
  36. package/dist/backend/actions/buy-x-get-y-free.d.ts.map +1 -0
  37. package/dist/backend/actions/buy-x-get-y-free.js +20 -0
  38. package/dist/backend/actions/buy-x-get-y-free.js.map +1 -0
  39. package/dist/backend/actions/buy-x-units-amount-off.d.ts +4 -0
  40. package/dist/backend/actions/buy-x-units-amount-off.d.ts.map +1 -0
  41. package/dist/backend/actions/buy-x-units-amount-off.js +19 -0
  42. package/dist/backend/actions/buy-x-units-amount-off.js.map +1 -0
  43. package/dist/backend/actions/buy-x-units-percent-off.d.ts +4 -0
  44. package/dist/backend/actions/buy-x-units-percent-off.d.ts.map +1 -0
  45. package/dist/backend/actions/buy-x-units-percent-off.js +15 -0
  46. package/dist/backend/actions/buy-x-units-percent-off.js.map +1 -0
  47. package/dist/backend/actions/buy-x-units-y-free.d.ts +7 -0
  48. package/dist/backend/actions/buy-x-units-y-free.d.ts.map +1 -0
  49. package/dist/backend/actions/buy-x-units-y-free.js +21 -0
  50. package/dist/backend/actions/buy-x-units-y-free.js.map +1 -0
  51. package/dist/backend/actions/every-nth-product-percent-off.d.ts +7 -0
  52. package/dist/backend/actions/every-nth-product-percent-off.d.ts.map +1 -0
  53. package/dist/backend/actions/every-nth-product-percent-off.js +17 -0
  54. package/dist/backend/actions/every-nth-product-percent-off.js.map +1 -0
  55. package/dist/backend/actions/free-delivery.d.ts +4 -0
  56. package/dist/backend/actions/free-delivery.d.ts.map +1 -0
  57. package/dist/backend/actions/free-delivery.js +11 -0
  58. package/dist/backend/actions/free-delivery.js.map +1 -0
  59. package/dist/backend/actions/percentage-off-cart.d.ts +4 -0
  60. package/dist/backend/actions/percentage-off-cart.d.ts.map +1 -0
  61. package/dist/backend/actions/percentage-off-cart.js +11 -0
  62. package/dist/backend/actions/percentage-off-cart.js.map +1 -0
  63. package/dist/backend/actions/spend-x-amount-off.d.ts +4 -0
  64. package/dist/backend/actions/spend-x-amount-off.d.ts.map +1 -0
  65. package/dist/backend/actions/spend-x-amount-off.js +17 -0
  66. package/dist/backend/actions/spend-x-amount-off.js.map +1 -0
  67. package/dist/backend/actions/spend-x-percent-off.d.ts +4 -0
  68. package/dist/backend/actions/spend-x-percent-off.d.ts.map +1 -0
  69. package/dist/backend/actions/spend-x-percent-off.js +18 -0
  70. package/dist/backend/actions/spend-x-percent-off.js.map +1 -0
  71. package/dist/backend/actions/types.d.ts +37 -0
  72. package/dist/backend/actions/types.d.ts.map +1 -0
  73. package/dist/backend/actions/types.js +2 -0
  74. package/dist/backend/actions/types.js.map +1 -0
  75. package/dist/backend/actions/util.d.ts +13 -0
  76. package/dist/backend/actions/util.d.ts.map +1 -0
  77. package/dist/backend/actions/util.js +18 -0
  78. package/dist/backend/actions/util.js.map +1 -0
  79. package/dist/backend/entities/coupon-batch.entity.d.ts +21 -0
  80. package/dist/backend/entities/coupon-batch.entity.d.ts.map +1 -0
  81. package/dist/backend/entities/coupon-batch.entity.js +78 -0
  82. package/dist/backend/entities/coupon-batch.entity.js.map +1 -0
  83. package/dist/backend/entities/promotion-coupon.entity.d.ts +17 -0
  84. package/dist/backend/entities/promotion-coupon.entity.d.ts.map +1 -0
  85. package/dist/backend/entities/promotion-coupon.entity.js +64 -0
  86. package/dist/backend/entities/promotion-coupon.entity.js.map +1 -0
  87. package/dist/backend/entities/promotion-rule.entity.d.ts +16 -0
  88. package/dist/backend/entities/promotion-rule.entity.d.ts.map +1 -0
  89. package/dist/backend/entities/promotion-rule.entity.js +57 -0
  90. package/dist/backend/entities/promotion-rule.entity.js.map +1 -0
  91. package/dist/backend/entities/promotion-usage-counter.entity.d.ts +15 -0
  92. package/dist/backend/entities/promotion-usage-counter.entity.d.ts.map +1 -0
  93. package/dist/backend/entities/promotion-usage-counter.entity.js +48 -0
  94. package/dist/backend/entities/promotion-usage-counter.entity.js.map +1 -0
  95. package/dist/backend/entities/promotion-usage.entity.d.ts +21 -0
  96. package/dist/backend/entities/promotion-usage.entity.d.ts.map +1 -0
  97. package/dist/backend/entities/promotion-usage.entity.js +89 -0
  98. package/dist/backend/entities/promotion-usage.entity.js.map +1 -0
  99. package/dist/backend/entities/promotion.entity.d.ts +63 -0
  100. package/dist/backend/entities/promotion.entity.d.ts.map +1 -0
  101. package/dist/backend/entities/promotion.entity.js +194 -0
  102. package/dist/backend/entities/promotion.entity.js.map +1 -0
  103. package/dist/backend/index.d.ts +124 -0
  104. package/dist/backend/index.d.ts.map +1 -0
  105. package/dist/backend/index.js +182 -0
  106. package/dist/backend/index.js.map +1 -0
  107. package/dist/backend/routes.d.ts +88 -0
  108. package/dist/backend/routes.d.ts.map +1 -0
  109. package/dist/backend/routes.js +256 -0
  110. package/dist/backend/routes.js.map +1 -0
  111. package/dist/backend/services/coupon-service.d.ts +40 -0
  112. package/dist/backend/services/coupon-service.d.ts.map +1 -0
  113. package/dist/backend/services/coupon-service.js +178 -0
  114. package/dist/backend/services/coupon-service.js.map +1 -0
  115. package/dist/backend/services/promotion-action-registry.d.ts +20 -0
  116. package/dist/backend/services/promotion-action-registry.d.ts.map +1 -0
  117. package/dist/backend/services/promotion-action-registry.js +57 -0
  118. package/dist/backend/services/promotion-action-registry.js.map +1 -0
  119. package/dist/backend/services/promotion-code-port.d.ts +24 -0
  120. package/dist/backend/services/promotion-code-port.d.ts.map +1 -0
  121. package/dist/backend/services/promotion-code-port.js +53 -0
  122. package/dist/backend/services/promotion-code-port.js.map +1 -0
  123. package/dist/backend/services/promotion-currency-reference.d.ts +13 -0
  124. package/dist/backend/services/promotion-currency-reference.d.ts.map +1 -0
  125. package/dist/backend/services/promotion-currency-reference.js +25 -0
  126. package/dist/backend/services/promotion-currency-reference.js.map +1 -0
  127. package/dist/backend/services/promotion-rule-evaluator.d.ts +32 -0
  128. package/dist/backend/services/promotion-rule-evaluator.d.ts.map +1 -0
  129. package/dist/backend/services/promotion-rule-evaluator.js +131 -0
  130. package/dist/backend/services/promotion-rule-evaluator.js.map +1 -0
  131. package/dist/backend/services/promotion-rule-service.d.ts +62 -0
  132. package/dist/backend/services/promotion-rule-service.d.ts.map +1 -0
  133. package/dist/backend/services/promotion-rule-service.js +95 -0
  134. package/dist/backend/services/promotion-rule-service.js.map +1 -0
  135. package/dist/backend/services/promotion-rule-store.d.ts +33 -0
  136. package/dist/backend/services/promotion-rule-store.d.ts.map +1 -0
  137. package/dist/backend/services/promotion-rule-store.js +88 -0
  138. package/dist/backend/services/promotion-rule-store.js.map +1 -0
  139. package/dist/backend/services/promotion-service.d.ts +312 -0
  140. package/dist/backend/services/promotion-service.d.ts.map +1 -0
  141. package/dist/backend/services/promotion-service.js +762 -0
  142. package/dist/backend/services/promotion-service.js.map +1 -0
  143. package/dist/backend/services/promotion-stats-service.d.ts +15 -0
  144. package/dist/backend/services/promotion-stats-service.d.ts.map +1 -0
  145. package/dist/backend/services/promotion-stats-service.js +66 -0
  146. package/dist/backend/services/promotion-stats-service.js.map +1 -0
  147. package/dist/backend/services/promotion-usage-service.d.ts +46 -0
  148. package/dist/backend/services/promotion-usage-service.d.ts.map +1 -0
  149. package/dist/backend/services/promotion-usage-service.js +168 -0
  150. package/dist/backend/services/promotion-usage-service.js.map +1 -0
  151. package/dist/manifest.d.ts +172 -0
  152. package/dist/manifest.d.ts.map +1 -0
  153. package/dist/manifest.js +140 -0
  154. package/dist/manifest.js.map +1 -0
  155. package/dist/migrations/20260505T074605_promotions_criteria.d.ts +19 -0
  156. package/dist/migrations/20260505T074605_promotions_criteria.d.ts.map +1 -0
  157. package/dist/migrations/20260505T074605_promotions_criteria.js +23 -0
  158. package/dist/migrations/20260505T074605_promotions_criteria.js.map +1 -0
  159. package/dist/migrations/20260618T100727_promotions_engine.d.ts +19 -0
  160. package/dist/migrations/20260618T100727_promotions_engine.d.ts.map +1 -0
  161. package/dist/migrations/20260618T100727_promotions_engine.js +148 -0
  162. package/dist/migrations/20260618T100727_promotions_engine.js.map +1 -0
  163. package/dist/migrations/20260818T081251_promotions_promotion_usage_order_fk.d.ts +42 -0
  164. package/dist/migrations/20260818T081251_promotions_promotion_usage_order_fk.d.ts.map +1 -0
  165. package/dist/migrations/20260818T081251_promotions_promotion_usage_order_fk.js +76 -0
  166. package/dist/migrations/20260818T081251_promotions_promotion_usage_order_fk.js.map +1 -0
  167. package/dist/migrations/20260912T094715_promotions_sales_channel_promotions.d.ts +27 -0
  168. package/dist/migrations/20260912T094715_promotions_sales_channel_promotions.d.ts.map +1 -0
  169. package/dist/migrations/20260912T094715_promotions_sales_channel_promotions.js +44 -0
  170. package/dist/migrations/20260912T094715_promotions_sales_channel_promotions.js.map +1 -0
  171. package/dist/migrations/index.d.ts +39 -0
  172. package/dist/migrations/index.d.ts.map +1 -0
  173. package/dist/migrations/index.js +44 -0
  174. package/dist/migrations/index.js.map +1 -0
  175. package/dist/ports/index.d.ts +106 -0
  176. package/dist/ports/index.d.ts.map +1 -0
  177. package/dist/ports/index.js +2 -0
  178. package/dist/ports/index.js.map +1 -0
  179. package/docs/promotions.md +96 -0
  180. package/i18n/en.json +34 -0
  181. package/i18n/pl.json +34 -0
  182. package/package.json +101 -0
  183. package/tailwind.css +14 -0
@@ -0,0 +1,78 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Entity, Index, OptionalProps, PrimaryKey, Property } from '@mikro-orm/core';
11
+ import { GlobalEntity } from '@endora-commerce/platform/tenancy';
12
+ import { randomUUID } from 'crypto';
13
+ /**
14
+ * Feature 045 — generator config for a batch of coupon codes (US4).
15
+ */
16
+ let CouponBatch = class CouponBatch {
17
+ [OptionalProps];
18
+ id = randomUUID();
19
+ promotionId;
20
+ count;
21
+ length;
22
+ /** `alnum` | `digits` | `letters`. */
23
+ format;
24
+ prefix;
25
+ suffix;
26
+ /** Insert a dash every N characters; 0 = none. */
27
+ dashEvery = 0;
28
+ /** `per_coupon` | `shared_batch`. */
29
+ limitScope;
30
+ createdAt = new Date();
31
+ };
32
+ __decorate([
33
+ PrimaryKey({ type: 'uuid' }),
34
+ __metadata("design:type", String)
35
+ ], CouponBatch.prototype, "id", void 0);
36
+ __decorate([
37
+ Property({ type: 'uuid' }),
38
+ Index(),
39
+ __metadata("design:type", String)
40
+ ], CouponBatch.prototype, "promotionId", void 0);
41
+ __decorate([
42
+ Property({ type: 'integer' }),
43
+ __metadata("design:type", Number)
44
+ ], CouponBatch.prototype, "count", void 0);
45
+ __decorate([
46
+ Property({ type: 'integer' }),
47
+ __metadata("design:type", Number)
48
+ ], CouponBatch.prototype, "length", void 0);
49
+ __decorate([
50
+ Property({ type: 'string', length: 16 }),
51
+ __metadata("design:type", String)
52
+ ], CouponBatch.prototype, "format", void 0);
53
+ __decorate([
54
+ Property({ type: 'string', length: 32, nullable: true }),
55
+ __metadata("design:type", Object)
56
+ ], CouponBatch.prototype, "prefix", void 0);
57
+ __decorate([
58
+ Property({ type: 'string', length: 32, nullable: true }),
59
+ __metadata("design:type", Object)
60
+ ], CouponBatch.prototype, "suffix", void 0);
61
+ __decorate([
62
+ Property({ type: 'integer', default: 0 }),
63
+ __metadata("design:type", Number)
64
+ ], CouponBatch.prototype, "dashEvery", void 0);
65
+ __decorate([
66
+ Property({ type: 'string', length: 16 }),
67
+ __metadata("design:type", String)
68
+ ], CouponBatch.prototype, "limitScope", void 0);
69
+ __decorate([
70
+ Property({ type: 'datetime', onCreate: () => new Date() }),
71
+ __metadata("design:type", Date)
72
+ ], CouponBatch.prototype, "createdAt", void 0);
73
+ CouponBatch = __decorate([
74
+ GlobalEntity(),
75
+ Entity({ tableName: 'coupon_batches' })
76
+ ], CouponBatch);
77
+ export { CouponBatch };
78
+ //# sourceMappingURL=coupon-batch.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coupon-batch.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/coupon-batch.entity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;GAEG;AAGI,IAAM,WAAW,GAAjB,MAAM,WAAW;IACtB,CAAC,aAAa,CAAC,CAA0D;IAGzE,EAAE,GAAW,UAAU,EAAE,CAAC;IAI1B,WAAW,CAAU;IAGrB,KAAK,CAAU;IAGf,MAAM,CAAU;IAEhB,sCAAsC;IAEtC,MAAM,CAAkC;IAGxC,MAAM,CAAiB;IAGvB,MAAM,CAAiB;IAEvB,kDAAkD;IAElD,SAAS,GAAW,CAAC,CAAC;IAEtB,qCAAqC;IAErC,UAAU,CAAiC;IAG3C,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;CAC9B,CAAA;AAhCC;IADC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;uCACH;AAI1B;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,EAAE;;gDACa;AAGrB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;0CACf;AAGf;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;2CACd;AAIhB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;2CACD;AAGxC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;2CAClC;AAGvB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;2CAClC;AAIvB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;8CACpB;AAItB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;+CACE;AAG3C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BAChD,IAAI;8CAAc;AAnClB,WAAW;IAFvB,YAAY,EAAE;IACd,MAAM,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;GAC3B,WAAW,CAoCvB"}
@@ -0,0 +1,17 @@
1
+ import { OptionalProps } from '@mikro-orm/core';
2
+ /**
3
+ * Feature 045 — an individual coupon code gating a promotion. Either a
4
+ * single specified code (`batchId` null) or one of a generated batch.
5
+ */
6
+ export declare class PromotionCoupon {
7
+ [OptionalProps]?: 'id' | 'createdAt' | 'batchId' | 'isActive';
8
+ id: string;
9
+ promotionId: string;
10
+ batchId?: string | null;
11
+ code: string;
12
+ /** `per_coupon` | `shared_batch` — denormalized from the batch. */
13
+ limitScope: 'per_coupon' | 'shared_batch';
14
+ isActive: boolean;
15
+ createdAt: Date;
16
+ }
17
+ //# sourceMappingURL=promotion-coupon.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-coupon.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/promotion-coupon.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAgC,MAAM,iBAAiB,CAAC;AAI7F;;;GAGG;AACH,qBAEa,eAAe;IAC1B,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;IAG9D,EAAE,EAAE,MAAM,CAAgB;IAI1B,WAAW,EAAG,MAAM,CAAC;IAIrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAIxB,IAAI,EAAG,MAAM,CAAC;IAEd,mEAAmE;IAEnE,UAAU,EAAG,YAAY,GAAG,cAAc,CAAC;IAG3C,QAAQ,EAAE,OAAO,CAAQ;IAGzB,SAAS,EAAE,IAAI,CAAc;CAC9B"}
@@ -0,0 +1,64 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Entity, Index, OptionalProps, PrimaryKey, Property, Unique } from '@mikro-orm/core';
11
+ import { GlobalEntity } from '@endora-commerce/platform/tenancy';
12
+ import { randomUUID } from 'crypto';
13
+ /**
14
+ * Feature 045 — an individual coupon code gating a promotion. Either a
15
+ * single specified code (`batchId` null) or one of a generated batch.
16
+ */
17
+ let PromotionCoupon = class PromotionCoupon {
18
+ [OptionalProps];
19
+ id = randomUUID();
20
+ promotionId;
21
+ batchId;
22
+ code;
23
+ /** `per_coupon` | `shared_batch` — denormalized from the batch. */
24
+ limitScope;
25
+ isActive = true;
26
+ createdAt = new Date();
27
+ };
28
+ __decorate([
29
+ PrimaryKey({ type: 'uuid' }),
30
+ __metadata("design:type", String)
31
+ ], PromotionCoupon.prototype, "id", void 0);
32
+ __decorate([
33
+ Property({ type: 'uuid' }),
34
+ Index(),
35
+ __metadata("design:type", String)
36
+ ], PromotionCoupon.prototype, "promotionId", void 0);
37
+ __decorate([
38
+ Property({ type: 'uuid', nullable: true }),
39
+ Index(),
40
+ __metadata("design:type", Object)
41
+ ], PromotionCoupon.prototype, "batchId", void 0);
42
+ __decorate([
43
+ Property({ type: 'string', length: 80 }),
44
+ Unique(),
45
+ __metadata("design:type", String)
46
+ ], PromotionCoupon.prototype, "code", void 0);
47
+ __decorate([
48
+ Property({ type: 'string', length: 16 }),
49
+ __metadata("design:type", String)
50
+ ], PromotionCoupon.prototype, "limitScope", void 0);
51
+ __decorate([
52
+ Property({ type: 'boolean', default: true }),
53
+ __metadata("design:type", Boolean)
54
+ ], PromotionCoupon.prototype, "isActive", void 0);
55
+ __decorate([
56
+ Property({ type: 'datetime', onCreate: () => new Date() }),
57
+ __metadata("design:type", Date)
58
+ ], PromotionCoupon.prototype, "createdAt", void 0);
59
+ PromotionCoupon = __decorate([
60
+ GlobalEntity(),
61
+ Entity({ tableName: 'promotion_coupons' })
62
+ ], PromotionCoupon);
63
+ export { PromotionCoupon };
64
+ //# sourceMappingURL=promotion-coupon.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-coupon.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/promotion-coupon.entity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;GAGG;AAGI,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,CAAC,aAAa,CAAC,CAA+C;IAG9D,EAAE,GAAW,UAAU,EAAE,CAAC;IAI1B,WAAW,CAAU;IAIrB,OAAO,CAAiB;IAIxB,IAAI,CAAU;IAEd,mEAAmE;IAEnE,UAAU,CAAiC;IAG3C,QAAQ,GAAY,IAAI,CAAC;IAGzB,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;CAC9B,CAAA;AAvBC;IADC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;2CACH;AAI1B;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,EAAE;;oDACa;AAIrB;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,KAAK,EAAE;;gDACgB;AAIxB;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACxC,MAAM,EAAE;;6CACK;AAId;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;mDACE;AAG3C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;iDACpB;AAGzB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BAChD,IAAI;kDAAc;AA1BlB,eAAe;IAF3B,YAAY,EAAE;IACd,MAAM,CAAC,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC;GAC9B,eAAe,CA2B3B"}
@@ -0,0 +1,16 @@
1
+ import { OptionalProps } from '@mikro-orm/core';
2
+ import type { PromotionRule } from '@endora-commerce/contracts';
3
+ /**
4
+ * Feature 045 — a standalone, named promotion rule reusable across
5
+ * promotions. Referenced by `promotions.rule_id`.
6
+ */
7
+ export declare class PromotionRuleEntity {
8
+ [OptionalProps]?: 'id' | 'createdAt' | 'updatedAt' | 'description';
9
+ id: string;
10
+ name: string;
11
+ description?: string | null;
12
+ definition: PromotionRule;
13
+ createdAt: Date;
14
+ updatedAt: Date;
15
+ }
16
+ //# sourceMappingURL=promotion-rule.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-rule.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/promotion-rule.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAgC,MAAM,iBAAiB,CAAC;AAG7F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;GAGG;AACH,qBAEa,mBAAmB;IAC9B,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,GAAG,aAAa,CAAC;IAGnE,EAAE,EAAE,MAAM,CAAgB;IAI1B,IAAI,EAAG,MAAM,CAAC;IAGd,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG5B,UAAU,EAAG,aAAa,CAAC;IAI3B,SAAS,EAAE,IAAI,CAAc;IAG7B,SAAS,EAAE,IAAI,CAAc;CAC9B"}
@@ -0,0 +1,57 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Entity, Index, OptionalProps, PrimaryKey, Property, Unique } from '@mikro-orm/core';
11
+ import { GlobalEntity } from '@endora-commerce/platform/tenancy';
12
+ import { randomUUID } from 'crypto';
13
+ /**
14
+ * Feature 045 — a standalone, named promotion rule reusable across
15
+ * promotions. Referenced by `promotions.rule_id`.
16
+ */
17
+ let PromotionRuleEntity = class PromotionRuleEntity {
18
+ [OptionalProps];
19
+ id = randomUUID();
20
+ name;
21
+ description;
22
+ definition;
23
+ createdAt = new Date();
24
+ updatedAt = new Date();
25
+ };
26
+ __decorate([
27
+ PrimaryKey({ type: 'uuid' }),
28
+ __metadata("design:type", String)
29
+ ], PromotionRuleEntity.prototype, "id", void 0);
30
+ __decorate([
31
+ Property({ type: 'string', length: 160 }),
32
+ Unique(),
33
+ __metadata("design:type", String)
34
+ ], PromotionRuleEntity.prototype, "name", void 0);
35
+ __decorate([
36
+ Property({ type: 'text', nullable: true }),
37
+ __metadata("design:type", Object)
38
+ ], PromotionRuleEntity.prototype, "description", void 0);
39
+ __decorate([
40
+ Property({ type: 'json', columnType: 'jsonb' }),
41
+ __metadata("design:type", Object)
42
+ ], PromotionRuleEntity.prototype, "definition", void 0);
43
+ __decorate([
44
+ Property({ type: 'datetime', onCreate: () => new Date() }),
45
+ Index(),
46
+ __metadata("design:type", Date)
47
+ ], PromotionRuleEntity.prototype, "createdAt", void 0);
48
+ __decorate([
49
+ Property({ type: 'datetime', onUpdate: () => new Date() }),
50
+ __metadata("design:type", Date)
51
+ ], PromotionRuleEntity.prototype, "updatedAt", void 0);
52
+ PromotionRuleEntity = __decorate([
53
+ GlobalEntity(),
54
+ Entity({ tableName: 'promotion_rules' })
55
+ ], PromotionRuleEntity);
56
+ export { PromotionRuleEntity };
57
+ //# sourceMappingURL=promotion-rule.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-rule.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/promotion-rule.entity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGpC;;;GAGG;AAGI,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAC9B,CAAC,aAAa,CAAC,CAAoD;IAGnE,EAAE,GAAW,UAAU,EAAE,CAAC;IAI1B,IAAI,CAAU;IAGd,WAAW,CAAiB;IAG5B,UAAU,CAAiB;IAI3B,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;IAG7B,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;CAC9B,CAAA;AAlBC;IADC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;+CACH;AAI1B;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACzC,MAAM,EAAE;;iDACK;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;wDACf;AAG5B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;;uDACrB;AAI3B;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;IAC1D,KAAK,EAAE;8BACG,IAAI;sDAAc;AAG7B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BAChD,IAAI;sDAAc;AArBlB,mBAAmB;IAF/B,YAAY,EAAE;IACd,MAAM,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;GAC5B,mBAAmB,CAsB/B"}
@@ -0,0 +1,15 @@
1
+ import { OptionalProps } from '@mikro-orm/core';
2
+ /**
3
+ * Feature 045 — authoritative per-scope usage counter for atomic cap
4
+ * enforcement (US5). Incremented inside the order-placement transaction via
5
+ * `UPDATE ... WHERE count < limit` so the last available use is race-safe.
6
+ */
7
+ export declare class PromotionUsageCounter {
8
+ [OptionalProps]?: 'id' | 'count';
9
+ id: string;
10
+ /** `global` | `organization` | `customer` | `coupon` | `batch`. */
11
+ scopeType: 'global' | 'organization' | 'customer' | 'coupon' | 'batch';
12
+ scopeKey: string;
13
+ count: number;
14
+ }
15
+ //# sourceMappingURL=promotion-usage-counter.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-usage-counter.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/promotion-usage-counter.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,aAAa,EAAgC,MAAM,iBAAiB,CAAC;AAItF;;;;GAIG;AACH,qBAGa,qBAAqB;IAChC,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC;IAGjC,EAAE,EAAE,MAAM,CAAgB;IAE1B,mEAAmE;IAEnE,SAAS,EAAG,QAAQ,GAAG,cAAc,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;IAGxE,QAAQ,EAAG,MAAM,CAAC;IAGlB,KAAK,EAAE,MAAM,CAAK;CACnB"}
@@ -0,0 +1,48 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Entity, OptionalProps, PrimaryKey, Property, Unique } from '@mikro-orm/core';
11
+ import { GlobalEntity } from '@endora-commerce/platform/tenancy';
12
+ import { randomUUID } from 'crypto';
13
+ /**
14
+ * Feature 045 — authoritative per-scope usage counter for atomic cap
15
+ * enforcement (US5). Incremented inside the order-placement transaction via
16
+ * `UPDATE ... WHERE count < limit` so the last available use is race-safe.
17
+ */
18
+ let PromotionUsageCounter = class PromotionUsageCounter {
19
+ [OptionalProps];
20
+ id = randomUUID();
21
+ /** `global` | `organization` | `customer` | `coupon` | `batch`. */
22
+ scopeType;
23
+ scopeKey;
24
+ count = 0;
25
+ };
26
+ __decorate([
27
+ PrimaryKey({ type: 'uuid' }),
28
+ __metadata("design:type", String)
29
+ ], PromotionUsageCounter.prototype, "id", void 0);
30
+ __decorate([
31
+ Property({ type: 'string', length: 16 }),
32
+ __metadata("design:type", String)
33
+ ], PromotionUsageCounter.prototype, "scopeType", void 0);
34
+ __decorate([
35
+ Property({ type: 'string', length: 128 }),
36
+ __metadata("design:type", String)
37
+ ], PromotionUsageCounter.prototype, "scopeKey", void 0);
38
+ __decorate([
39
+ Property({ type: 'integer', default: 0 }),
40
+ __metadata("design:type", Number)
41
+ ], PromotionUsageCounter.prototype, "count", void 0);
42
+ PromotionUsageCounter = __decorate([
43
+ GlobalEntity(),
44
+ Entity({ tableName: 'promotion_usage_counters' }),
45
+ Unique({ properties: ['scopeType', 'scopeKey'] })
46
+ ], PromotionUsageCounter);
47
+ export { PromotionUsageCounter };
48
+ //# sourceMappingURL=promotion-usage-counter.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-usage-counter.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/promotion-usage-counter.entity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;;GAIG;AAII,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,CAAC,aAAa,CAAC,CAAkB;IAGjC,EAAE,GAAW,UAAU,EAAE,CAAC;IAE1B,mEAAmE;IAEnE,SAAS,CAA+D;IAGxE,QAAQ,CAAU;IAGlB,KAAK,GAAW,CAAC,CAAC;CACnB,CAAA;AAXC;IADC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;iDACH;AAI1B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;wDAC+B;AAGxE;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;uDACxB;AAGlB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;oDACxB;AAdP,qBAAqB;IAHjC,YAAY,EAAE;IACd,MAAM,CAAC,EAAE,SAAS,EAAE,0BAA0B,EAAE,CAAC;IACjD,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC;GACrC,qBAAqB,CAejC"}
@@ -0,0 +1,21 @@
1
+ import { OptionalProps } from '@mikro-orm/core';
2
+ /**
3
+ * Feature 045 — a finalized redemption of a promotion/coupon, written on
4
+ * order placement (US5). Denormalized dimensions feed the statistics
5
+ * aggregates (US7).
6
+ */
7
+ export declare class PromotionUsage {
8
+ [OptionalProps]?: 'id' | 'createdAt' | 'couponId' | 'customerAccountId' | 'organizationId' | 'customerGroupId';
9
+ id: string;
10
+ promotionId: string;
11
+ couponId?: string | null;
12
+ orderId: string;
13
+ customerAccountId?: string | null;
14
+ organizationId?: string | null;
15
+ customerGroupId?: string | null;
16
+ salesChannelId: string;
17
+ discountAmount: string;
18
+ currency: string;
19
+ createdAt: Date;
20
+ }
21
+ //# sourceMappingURL=promotion-usage.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-usage.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/promotion-usage.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAgC,MAAM,iBAAiB,CAAC;AAI7F;;;;GAIG;AACH,qBAGa,cAAc;IACzB,CAAC,aAAa,CAAC,CAAC,EACZ,IAAI,GACJ,WAAW,GACX,UAAU,GACV,mBAAmB,GACnB,gBAAgB,GAChB,iBAAiB,CAAC;IAGtB,EAAE,EAAE,MAAM,CAAgB;IAI1B,WAAW,EAAG,MAAM,CAAC;IAIrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGzB,OAAO,EAAG,MAAM,CAAC;IAIjB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAIlC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAI/B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAIhC,cAAc,EAAG,MAAM,CAAC;IAGxB,cAAc,EAAG,MAAM,CAAC;IAGxB,QAAQ,EAAG,MAAM,CAAC;IAIlB,SAAS,EAAE,IAAI,CAAc;CAC9B"}
@@ -0,0 +1,89 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Entity, Index, OptionalProps, PrimaryKey, Property, Unique } from '@mikro-orm/core';
11
+ import { GlobalEntity } from '@endora-commerce/platform/tenancy';
12
+ import { randomUUID } from 'crypto';
13
+ /**
14
+ * Feature 045 — a finalized redemption of a promotion/coupon, written on
15
+ * order placement (US5). Denormalized dimensions feed the statistics
16
+ * aggregates (US7).
17
+ */
18
+ let PromotionUsage = class PromotionUsage {
19
+ [OptionalProps];
20
+ id = randomUUID();
21
+ promotionId;
22
+ couponId;
23
+ orderId;
24
+ customerAccountId;
25
+ organizationId;
26
+ customerGroupId;
27
+ salesChannelId;
28
+ discountAmount;
29
+ currency;
30
+ createdAt = new Date();
31
+ };
32
+ __decorate([
33
+ PrimaryKey({ type: 'uuid' }),
34
+ __metadata("design:type", String)
35
+ ], PromotionUsage.prototype, "id", void 0);
36
+ __decorate([
37
+ Property({ type: 'uuid' }),
38
+ Index(),
39
+ __metadata("design:type", String)
40
+ ], PromotionUsage.prototype, "promotionId", void 0);
41
+ __decorate([
42
+ Property({ type: 'uuid', nullable: true }),
43
+ Index(),
44
+ __metadata("design:type", Object)
45
+ ], PromotionUsage.prototype, "couponId", void 0);
46
+ __decorate([
47
+ Property({ type: 'uuid' }),
48
+ __metadata("design:type", String)
49
+ ], PromotionUsage.prototype, "orderId", void 0);
50
+ __decorate([
51
+ Property({ type: 'uuid', nullable: true }),
52
+ Index(),
53
+ __metadata("design:type", Object)
54
+ ], PromotionUsage.prototype, "customerAccountId", void 0);
55
+ __decorate([
56
+ Property({ type: 'uuid', nullable: true }),
57
+ Index(),
58
+ __metadata("design:type", Object)
59
+ ], PromotionUsage.prototype, "organizationId", void 0);
60
+ __decorate([
61
+ Property({ type: 'uuid', nullable: true }),
62
+ Index(),
63
+ __metadata("design:type", Object)
64
+ ], PromotionUsage.prototype, "customerGroupId", void 0);
65
+ __decorate([
66
+ Property({ type: 'uuid' }),
67
+ Index(),
68
+ __metadata("design:type", String)
69
+ ], PromotionUsage.prototype, "salesChannelId", void 0);
70
+ __decorate([
71
+ Property({ type: 'decimal', precision: 14, scale: 2 }),
72
+ __metadata("design:type", String)
73
+ ], PromotionUsage.prototype, "discountAmount", void 0);
74
+ __decorate([
75
+ Property({ type: 'string', length: 3 }),
76
+ __metadata("design:type", String)
77
+ ], PromotionUsage.prototype, "currency", void 0);
78
+ __decorate([
79
+ Property({ type: 'datetime', onCreate: () => new Date() }),
80
+ Index(),
81
+ __metadata("design:type", Date)
82
+ ], PromotionUsage.prototype, "createdAt", void 0);
83
+ PromotionUsage = __decorate([
84
+ GlobalEntity(),
85
+ Entity({ tableName: 'promotion_usages' }),
86
+ Unique({ properties: ['orderId', 'promotionId'] })
87
+ ], PromotionUsage);
88
+ export { PromotionUsage };
89
+ //# sourceMappingURL=promotion-usage.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion-usage.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/promotion-usage.entity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;;GAIG;AAII,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,CAAC,aAAa,CAAC,CAMO;IAGtB,EAAE,GAAW,UAAU,EAAE,CAAC;IAI1B,WAAW,CAAU;IAIrB,QAAQ,CAAiB;IAGzB,OAAO,CAAU;IAIjB,iBAAiB,CAAiB;IAIlC,cAAc,CAAiB;IAI/B,eAAe,CAAiB;IAIhC,cAAc,CAAU;IAGxB,cAAc,CAAU;IAGxB,QAAQ,CAAU;IAIlB,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;CAC9B,CAAA;AAtCC;IADC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;0CACH;AAI1B;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,EAAE;;mDACa;AAIrB;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,KAAK,EAAE;;gDACiB;AAGzB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;+CACV;AAIjB;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,KAAK,EAAE;;yDAC0B;AAIlC;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,KAAK,EAAE;;sDACuB;AAI/B;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,KAAK,EAAE;;uDACwB;AAIhC;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,EAAE;;sDACgB;AAGxB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;;sDAC/B;AAGxB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;;gDACtB;AAIlB;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;IAC1D,KAAK,EAAE;8BACG,IAAI;iDAAc;AA/ClB,cAAc;IAH1B,YAAY,EAAE;IACd,MAAM,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC;IACzC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,CAAC;GACtC,cAAc,CAgD1B"}
@@ -0,0 +1,63 @@
1
+ import { OptionalProps } from '@mikro-orm/core';
2
+ import type { PromotionAction, PromotionCriterion, PromotionRule } from '@endora-commerce/contracts';
3
+ /**
4
+ * Promotion — a discount rule applied to a Cart snapshot (T129 / FR-052).
5
+ *
6
+ * Three kinds of effect:
7
+ * - `percentage_off` — `value` 0..100, applied to either the cart subtotal
8
+ * or the lines matching the optional category/product
9
+ * scope.
10
+ * - `amount_off` — `value` is money in `currency`.
11
+ * - `free_delivery` — zero out the cart's delivery cost.
12
+ *
13
+ * Eligibility filters: `code`, `minCartSubtotal`, `validFrom`/`validUntil`,
14
+ * `organizationId` / `customerGroupId`, `categoryId` / `productId`.
15
+ *
16
+ * Inactive (`isActive=false`) promotions are skipped without being deleted —
17
+ * useful for re-enabling seasonally.
18
+ */
19
+ export declare class Promotion {
20
+ [OptionalProps]?: 'id' | 'createdAt' | 'updatedAt' | 'code' | 'currency' | 'minCartSubtotal' | 'validFrom' | 'validUntil' | 'organizationId' | 'customerGroupId' | 'categoryId' | 'productId' | 'criteria' | 'isActive' | 'description' | 'priority' | 'stopFurther' | 'actionType' | 'actionConfig' | 'ruleId' | 'ruleDefinition' | 'usageLimitGlobal' | 'usageLimitPerOrganization' | 'usageLimitPerCustomer';
21
+ id: string;
22
+ code?: string | null;
23
+ name: string;
24
+ /** Legacy effect kind — nullable on feature-045 action-based promotions. */
25
+ kind?: 'percentage_off' | 'amount_off' | 'free_delivery' | null;
26
+ /** Legacy effect value — nullable on feature-045 action-based promotions. */
27
+ value?: string | null;
28
+ currency?: string | null;
29
+ minCartSubtotal?: string | null;
30
+ validFrom?: Date | null;
31
+ validUntil?: Date | null;
32
+ organizationId?: string | null;
33
+ customerGroupId?: string | null;
34
+ categoryId?: string | null;
35
+ productId?: string | null;
36
+ /**
37
+ * Feature 012 / US8 — line-level discriminated criteria. ANDed with
38
+ * the flat `categoryId` / `productId` scope. JSONB column with default
39
+ * `'[]'::jsonb` so existing rows behave exactly as before until the
40
+ * operator authors a criterion.
41
+ */
42
+ criteria: PromotionCriterion[];
43
+ isActive: boolean;
44
+ description?: string | null;
45
+ /** Application order across a cart's matching promotions (DESC). */
46
+ priority: number;
47
+ /** When true, no lower-priority promotion applies once this one does. */
48
+ stopFurther: boolean;
49
+ /** Registered action key (null on legacy kind/value promotions). */
50
+ actionType?: PromotionAction['type'] | null;
51
+ /** Action parameters, validated against the registered action's schema. */
52
+ actionConfig: Record<string, unknown>;
53
+ /** Named-rule reference (mutually exclusive with `ruleDefinition`). */
54
+ ruleId?: string | null;
55
+ /** Inline rule AST (mutually exclusive with `ruleId`). */
56
+ ruleDefinition?: PromotionRule | null;
57
+ usageLimitGlobal?: number | null;
58
+ usageLimitPerOrganization?: number | null;
59
+ usageLimitPerCustomer?: number | null;
60
+ createdAt: Date;
61
+ updatedAt: Date;
62
+ }
63
+ //# sourceMappingURL=promotion.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/promotion.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAgC,MAAM,iBAAiB,CAAC;AAG7F,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAErG;;;;;;;;;;;;;;;GAeG;AACH,qBAEa,SAAS;IACpB,CAAC,aAAa,CAAC,CAAC,EACZ,IAAI,GACJ,WAAW,GACX,WAAW,GACX,MAAM,GACN,UAAU,GACV,iBAAiB,GACjB,WAAW,GACX,YAAY,GACZ,gBAAgB,GAChB,iBAAiB,GACjB,YAAY,GACZ,WAAW,GACX,UAAU,GACV,UAAU,GACV,aAAa,GACb,UAAU,GACV,aAAa,GACb,YAAY,GACZ,cAAc,GACd,QAAQ,GACR,gBAAgB,GAChB,kBAAkB,GAClB,2BAA2B,GAC3B,uBAAuB,CAAC;IAG5B,EAAE,EAAE,MAAM,CAAgB;IAI1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGrB,IAAI,EAAG,MAAM,CAAC;IAEd,4EAA4E;IAG5E,IAAI,CAAC,EAAE,gBAAgB,GAAG,YAAY,GAAG,eAAe,GAAG,IAAI,CAAC;IAEhE,6EAA6E;IAE7E,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAGxB,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAIzB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAI/B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B;;;;;OAKG;IAEH,QAAQ,EAAE,kBAAkB,EAAE,CAAM;IAIpC,QAAQ,EAAE,OAAO,CAAQ;IAKzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,oEAAoE;IAGpE,QAAQ,EAAE,MAAM,CAAK;IAErB,yEAAyE;IAEzE,WAAW,EAAE,OAAO,CAAS;IAE7B,oEAAoE;IAEpE,UAAU,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAE5C,2EAA2E;IAE3E,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;IAE3C,uEAAuE;IAGvE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB,0DAA0D;IAE1D,cAAc,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAGtC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGjC,yBAAyB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG1C,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGtC,SAAS,EAAE,IAAI,CAAc;IAG7B,SAAS,EAAE,IAAI,CAAc;CAC9B"}