@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.
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/admin/api/promotions-client.d.ts +98 -0
- package/dist/admin/api/promotions-client.d.ts.map +1 -0
- package/dist/admin/api/promotions-client.js +40 -0
- package/dist/admin/api/promotions-client.js.map +1 -0
- package/dist/admin/components/CouponGeneratorForm.d.ts +10 -0
- package/dist/admin/components/CouponGeneratorForm.d.ts.map +1 -0
- package/dist/admin/components/CouponGeneratorForm.js +56 -0
- package/dist/admin/components/CouponGeneratorForm.js.map +1 -0
- package/dist/admin/index.d.ts +43 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +69 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/PromotionEditPage.d.ts +9 -0
- package/dist/admin/pages/PromotionEditPage.d.ts.map +1 -0
- package/dist/admin/pages/PromotionEditPage.js +333 -0
- package/dist/admin/pages/PromotionEditPage.js.map +1 -0
- package/dist/admin/pages/PromotionRulesPage.d.ts +14 -0
- package/dist/admin/pages/PromotionRulesPage.d.ts.map +1 -0
- package/dist/admin/pages/PromotionRulesPage.js +86 -0
- package/dist/admin/pages/PromotionRulesPage.js.map +1 -0
- package/dist/admin/pages/PromotionStatsPage.d.ts +13 -0
- package/dist/admin/pages/PromotionStatsPage.d.ts.map +1 -0
- package/dist/admin/pages/PromotionStatsPage.js +44 -0
- package/dist/admin/pages/PromotionStatsPage.js.map +1 -0
- package/dist/admin/pages/PromotionsPage.d.ts +9 -0
- package/dist/admin/pages/PromotionsPage.d.ts.map +1 -0
- package/dist/admin/pages/PromotionsPage.js +79 -0
- package/dist/admin/pages/PromotionsPage.js.map +1 -0
- package/dist/backend/actions/amount-off-cart.d.ts +4 -0
- package/dist/backend/actions/amount-off-cart.d.ts.map +1 -0
- package/dist/backend/actions/amount-off-cart.js +16 -0
- package/dist/backend/actions/amount-off-cart.js.map +1 -0
- package/dist/backend/actions/buy-x-get-y-free.d.ts +8 -0
- package/dist/backend/actions/buy-x-get-y-free.d.ts.map +1 -0
- package/dist/backend/actions/buy-x-get-y-free.js +20 -0
- package/dist/backend/actions/buy-x-get-y-free.js.map +1 -0
- package/dist/backend/actions/buy-x-units-amount-off.d.ts +4 -0
- package/dist/backend/actions/buy-x-units-amount-off.d.ts.map +1 -0
- package/dist/backend/actions/buy-x-units-amount-off.js +19 -0
- package/dist/backend/actions/buy-x-units-amount-off.js.map +1 -0
- package/dist/backend/actions/buy-x-units-percent-off.d.ts +4 -0
- package/dist/backend/actions/buy-x-units-percent-off.d.ts.map +1 -0
- package/dist/backend/actions/buy-x-units-percent-off.js +15 -0
- package/dist/backend/actions/buy-x-units-percent-off.js.map +1 -0
- package/dist/backend/actions/buy-x-units-y-free.d.ts +7 -0
- package/dist/backend/actions/buy-x-units-y-free.d.ts.map +1 -0
- package/dist/backend/actions/buy-x-units-y-free.js +21 -0
- package/dist/backend/actions/buy-x-units-y-free.js.map +1 -0
- package/dist/backend/actions/every-nth-product-percent-off.d.ts +7 -0
- package/dist/backend/actions/every-nth-product-percent-off.d.ts.map +1 -0
- package/dist/backend/actions/every-nth-product-percent-off.js +17 -0
- package/dist/backend/actions/every-nth-product-percent-off.js.map +1 -0
- package/dist/backend/actions/free-delivery.d.ts +4 -0
- package/dist/backend/actions/free-delivery.d.ts.map +1 -0
- package/dist/backend/actions/free-delivery.js +11 -0
- package/dist/backend/actions/free-delivery.js.map +1 -0
- package/dist/backend/actions/percentage-off-cart.d.ts +4 -0
- package/dist/backend/actions/percentage-off-cart.d.ts.map +1 -0
- package/dist/backend/actions/percentage-off-cart.js +11 -0
- package/dist/backend/actions/percentage-off-cart.js.map +1 -0
- package/dist/backend/actions/spend-x-amount-off.d.ts +4 -0
- package/dist/backend/actions/spend-x-amount-off.d.ts.map +1 -0
- package/dist/backend/actions/spend-x-amount-off.js +17 -0
- package/dist/backend/actions/spend-x-amount-off.js.map +1 -0
- package/dist/backend/actions/spend-x-percent-off.d.ts +4 -0
- package/dist/backend/actions/spend-x-percent-off.d.ts.map +1 -0
- package/dist/backend/actions/spend-x-percent-off.js +18 -0
- package/dist/backend/actions/spend-x-percent-off.js.map +1 -0
- package/dist/backend/actions/types.d.ts +37 -0
- package/dist/backend/actions/types.d.ts.map +1 -0
- package/dist/backend/actions/types.js +2 -0
- package/dist/backend/actions/types.js.map +1 -0
- package/dist/backend/actions/util.d.ts +13 -0
- package/dist/backend/actions/util.d.ts.map +1 -0
- package/dist/backend/actions/util.js +18 -0
- package/dist/backend/actions/util.js.map +1 -0
- package/dist/backend/entities/coupon-batch.entity.d.ts +21 -0
- package/dist/backend/entities/coupon-batch.entity.d.ts.map +1 -0
- package/dist/backend/entities/coupon-batch.entity.js +78 -0
- package/dist/backend/entities/coupon-batch.entity.js.map +1 -0
- package/dist/backend/entities/promotion-coupon.entity.d.ts +17 -0
- package/dist/backend/entities/promotion-coupon.entity.d.ts.map +1 -0
- package/dist/backend/entities/promotion-coupon.entity.js +64 -0
- package/dist/backend/entities/promotion-coupon.entity.js.map +1 -0
- package/dist/backend/entities/promotion-rule.entity.d.ts +16 -0
- package/dist/backend/entities/promotion-rule.entity.d.ts.map +1 -0
- package/dist/backend/entities/promotion-rule.entity.js +57 -0
- package/dist/backend/entities/promotion-rule.entity.js.map +1 -0
- package/dist/backend/entities/promotion-usage-counter.entity.d.ts +15 -0
- package/dist/backend/entities/promotion-usage-counter.entity.d.ts.map +1 -0
- package/dist/backend/entities/promotion-usage-counter.entity.js +48 -0
- package/dist/backend/entities/promotion-usage-counter.entity.js.map +1 -0
- package/dist/backend/entities/promotion-usage.entity.d.ts +21 -0
- package/dist/backend/entities/promotion-usage.entity.d.ts.map +1 -0
- package/dist/backend/entities/promotion-usage.entity.js +89 -0
- package/dist/backend/entities/promotion-usage.entity.js.map +1 -0
- package/dist/backend/entities/promotion.entity.d.ts +63 -0
- package/dist/backend/entities/promotion.entity.d.ts.map +1 -0
- package/dist/backend/entities/promotion.entity.js +194 -0
- package/dist/backend/entities/promotion.entity.js.map +1 -0
- package/dist/backend/index.d.ts +124 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +182 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/routes.d.ts +88 -0
- package/dist/backend/routes.d.ts.map +1 -0
- package/dist/backend/routes.js +256 -0
- package/dist/backend/routes.js.map +1 -0
- package/dist/backend/services/coupon-service.d.ts +40 -0
- package/dist/backend/services/coupon-service.d.ts.map +1 -0
- package/dist/backend/services/coupon-service.js +178 -0
- package/dist/backend/services/coupon-service.js.map +1 -0
- package/dist/backend/services/promotion-action-registry.d.ts +20 -0
- package/dist/backend/services/promotion-action-registry.d.ts.map +1 -0
- package/dist/backend/services/promotion-action-registry.js +57 -0
- package/dist/backend/services/promotion-action-registry.js.map +1 -0
- package/dist/backend/services/promotion-code-port.d.ts +24 -0
- package/dist/backend/services/promotion-code-port.d.ts.map +1 -0
- package/dist/backend/services/promotion-code-port.js +53 -0
- package/dist/backend/services/promotion-code-port.js.map +1 -0
- package/dist/backend/services/promotion-currency-reference.d.ts +13 -0
- package/dist/backend/services/promotion-currency-reference.d.ts.map +1 -0
- package/dist/backend/services/promotion-currency-reference.js +25 -0
- package/dist/backend/services/promotion-currency-reference.js.map +1 -0
- package/dist/backend/services/promotion-rule-evaluator.d.ts +32 -0
- package/dist/backend/services/promotion-rule-evaluator.d.ts.map +1 -0
- package/dist/backend/services/promotion-rule-evaluator.js +131 -0
- package/dist/backend/services/promotion-rule-evaluator.js.map +1 -0
- package/dist/backend/services/promotion-rule-service.d.ts +62 -0
- package/dist/backend/services/promotion-rule-service.d.ts.map +1 -0
- package/dist/backend/services/promotion-rule-service.js +95 -0
- package/dist/backend/services/promotion-rule-service.js.map +1 -0
- package/dist/backend/services/promotion-rule-store.d.ts +33 -0
- package/dist/backend/services/promotion-rule-store.d.ts.map +1 -0
- package/dist/backend/services/promotion-rule-store.js +88 -0
- package/dist/backend/services/promotion-rule-store.js.map +1 -0
- package/dist/backend/services/promotion-service.d.ts +312 -0
- package/dist/backend/services/promotion-service.d.ts.map +1 -0
- package/dist/backend/services/promotion-service.js +762 -0
- package/dist/backend/services/promotion-service.js.map +1 -0
- package/dist/backend/services/promotion-stats-service.d.ts +15 -0
- package/dist/backend/services/promotion-stats-service.d.ts.map +1 -0
- package/dist/backend/services/promotion-stats-service.js +66 -0
- package/dist/backend/services/promotion-stats-service.js.map +1 -0
- package/dist/backend/services/promotion-usage-service.d.ts +46 -0
- package/dist/backend/services/promotion-usage-service.d.ts.map +1 -0
- package/dist/backend/services/promotion-usage-service.js +168 -0
- package/dist/backend/services/promotion-usage-service.js.map +1 -0
- package/dist/manifest.d.ts +172 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +140 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260505T074605_promotions_criteria.d.ts +19 -0
- package/dist/migrations/20260505T074605_promotions_criteria.d.ts.map +1 -0
- package/dist/migrations/20260505T074605_promotions_criteria.js +23 -0
- package/dist/migrations/20260505T074605_promotions_criteria.js.map +1 -0
- package/dist/migrations/20260618T100727_promotions_engine.d.ts +19 -0
- package/dist/migrations/20260618T100727_promotions_engine.d.ts.map +1 -0
- package/dist/migrations/20260618T100727_promotions_engine.js +148 -0
- package/dist/migrations/20260618T100727_promotions_engine.js.map +1 -0
- package/dist/migrations/20260818T081251_promotions_promotion_usage_order_fk.d.ts +42 -0
- package/dist/migrations/20260818T081251_promotions_promotion_usage_order_fk.d.ts.map +1 -0
- package/dist/migrations/20260818T081251_promotions_promotion_usage_order_fk.js +76 -0
- package/dist/migrations/20260818T081251_promotions_promotion_usage_order_fk.js.map +1 -0
- package/dist/migrations/20260912T094715_promotions_sales_channel_promotions.d.ts +27 -0
- package/dist/migrations/20260912T094715_promotions_sales_channel_promotions.d.ts.map +1 -0
- package/dist/migrations/20260912T094715_promotions_sales_channel_promotions.js +44 -0
- package/dist/migrations/20260912T094715_promotions_sales_channel_promotions.js.map +1 -0
- package/dist/migrations/index.d.ts +39 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +44 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/ports/index.d.ts +106 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +2 -0
- package/dist/ports/index.js.map +1 -0
- package/docs/promotions.md +96 -0
- package/i18n/en.json +34 -0
- package/i18n/pl.json +34 -0
- package/package.json +101 -0
- 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"}
|