@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,194 @@
|
|
|
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
|
+
* Promotion — a discount rule applied to a Cart snapshot (T129 / FR-052).
|
|
15
|
+
*
|
|
16
|
+
* Three kinds of effect:
|
|
17
|
+
* - `percentage_off` — `value` 0..100, applied to either the cart subtotal
|
|
18
|
+
* or the lines matching the optional category/product
|
|
19
|
+
* scope.
|
|
20
|
+
* - `amount_off` — `value` is money in `currency`.
|
|
21
|
+
* - `free_delivery` — zero out the cart's delivery cost.
|
|
22
|
+
*
|
|
23
|
+
* Eligibility filters: `code`, `minCartSubtotal`, `validFrom`/`validUntil`,
|
|
24
|
+
* `organizationId` / `customerGroupId`, `categoryId` / `productId`.
|
|
25
|
+
*
|
|
26
|
+
* Inactive (`isActive=false`) promotions are skipped without being deleted —
|
|
27
|
+
* useful for re-enabling seasonally.
|
|
28
|
+
*/
|
|
29
|
+
let Promotion = class Promotion {
|
|
30
|
+
[OptionalProps];
|
|
31
|
+
id = randomUUID();
|
|
32
|
+
code;
|
|
33
|
+
name;
|
|
34
|
+
/** Legacy effect kind — nullable on feature-045 action-based promotions. */
|
|
35
|
+
kind;
|
|
36
|
+
/** Legacy effect value — nullable on feature-045 action-based promotions. */
|
|
37
|
+
value;
|
|
38
|
+
currency;
|
|
39
|
+
minCartSubtotal;
|
|
40
|
+
validFrom;
|
|
41
|
+
validUntil;
|
|
42
|
+
organizationId;
|
|
43
|
+
customerGroupId;
|
|
44
|
+
categoryId;
|
|
45
|
+
productId;
|
|
46
|
+
/**
|
|
47
|
+
* Feature 012 / US8 — line-level discriminated criteria. ANDed with
|
|
48
|
+
* the flat `categoryId` / `productId` scope. JSONB column with default
|
|
49
|
+
* `'[]'::jsonb` so existing rows behave exactly as before until the
|
|
50
|
+
* operator authors a criterion.
|
|
51
|
+
*/
|
|
52
|
+
criteria = [];
|
|
53
|
+
isActive = true;
|
|
54
|
+
// --- Feature 045 — engine fields -----------------------------------------
|
|
55
|
+
description;
|
|
56
|
+
/** Application order across a cart's matching promotions (DESC). */
|
|
57
|
+
priority = 0;
|
|
58
|
+
/** When true, no lower-priority promotion applies once this one does. */
|
|
59
|
+
stopFurther = false;
|
|
60
|
+
/** Registered action key (null on legacy kind/value promotions). */
|
|
61
|
+
actionType;
|
|
62
|
+
/** Action parameters, validated against the registered action's schema. */
|
|
63
|
+
actionConfig = {};
|
|
64
|
+
/** Named-rule reference (mutually exclusive with `ruleDefinition`). */
|
|
65
|
+
ruleId;
|
|
66
|
+
/** Inline rule AST (mutually exclusive with `ruleId`). */
|
|
67
|
+
ruleDefinition;
|
|
68
|
+
usageLimitGlobal;
|
|
69
|
+
usageLimitPerOrganization;
|
|
70
|
+
usageLimitPerCustomer;
|
|
71
|
+
createdAt = new Date();
|
|
72
|
+
updatedAt = new Date();
|
|
73
|
+
};
|
|
74
|
+
__decorate([
|
|
75
|
+
PrimaryKey({ type: 'uuid' }),
|
|
76
|
+
__metadata("design:type", String)
|
|
77
|
+
], Promotion.prototype, "id", void 0);
|
|
78
|
+
__decorate([
|
|
79
|
+
Property({ type: 'string', length: 64, nullable: true }),
|
|
80
|
+
Unique(),
|
|
81
|
+
__metadata("design:type", Object)
|
|
82
|
+
], Promotion.prototype, "code", void 0);
|
|
83
|
+
__decorate([
|
|
84
|
+
Property({ type: 'string', length: 160 }),
|
|
85
|
+
__metadata("design:type", String)
|
|
86
|
+
], Promotion.prototype, "name", void 0);
|
|
87
|
+
__decorate([
|
|
88
|
+
Property({ type: 'string', length: 24, nullable: true }),
|
|
89
|
+
Index(),
|
|
90
|
+
__metadata("design:type", Object)
|
|
91
|
+
], Promotion.prototype, "kind", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
Property({ type: 'decimal', precision: 14, scale: 4, nullable: true }),
|
|
94
|
+
__metadata("design:type", Object)
|
|
95
|
+
], Promotion.prototype, "value", void 0);
|
|
96
|
+
__decorate([
|
|
97
|
+
Property({ type: 'string', length: 3, nullable: true }),
|
|
98
|
+
__metadata("design:type", Object)
|
|
99
|
+
], Promotion.prototype, "currency", void 0);
|
|
100
|
+
__decorate([
|
|
101
|
+
Property({ type: 'decimal', precision: 14, scale: 2, nullable: true }),
|
|
102
|
+
__metadata("design:type", Object)
|
|
103
|
+
], Promotion.prototype, "minCartSubtotal", void 0);
|
|
104
|
+
__decorate([
|
|
105
|
+
Property({ type: 'datetime', nullable: true }),
|
|
106
|
+
__metadata("design:type", Object)
|
|
107
|
+
], Promotion.prototype, "validFrom", void 0);
|
|
108
|
+
__decorate([
|
|
109
|
+
Property({ type: 'datetime', nullable: true }),
|
|
110
|
+
__metadata("design:type", Object)
|
|
111
|
+
], Promotion.prototype, "validUntil", void 0);
|
|
112
|
+
__decorate([
|
|
113
|
+
Property({ type: 'uuid', nullable: true }),
|
|
114
|
+
Index(),
|
|
115
|
+
__metadata("design:type", Object)
|
|
116
|
+
], Promotion.prototype, "organizationId", void 0);
|
|
117
|
+
__decorate([
|
|
118
|
+
Property({ type: 'uuid', nullable: true }),
|
|
119
|
+
Index(),
|
|
120
|
+
__metadata("design:type", Object)
|
|
121
|
+
], Promotion.prototype, "customerGroupId", void 0);
|
|
122
|
+
__decorate([
|
|
123
|
+
Property({ type: 'uuid', nullable: true }),
|
|
124
|
+
__metadata("design:type", Object)
|
|
125
|
+
], Promotion.prototype, "categoryId", void 0);
|
|
126
|
+
__decorate([
|
|
127
|
+
Property({ type: 'uuid', nullable: true }),
|
|
128
|
+
__metadata("design:type", Object)
|
|
129
|
+
], Promotion.prototype, "productId", void 0);
|
|
130
|
+
__decorate([
|
|
131
|
+
Property({ type: 'json', columnType: 'jsonb', default: "'[]'" }),
|
|
132
|
+
__metadata("design:type", Array)
|
|
133
|
+
], Promotion.prototype, "criteria", void 0);
|
|
134
|
+
__decorate([
|
|
135
|
+
Property({ type: 'boolean' }),
|
|
136
|
+
Index(),
|
|
137
|
+
__metadata("design:type", Boolean)
|
|
138
|
+
], Promotion.prototype, "isActive", void 0);
|
|
139
|
+
__decorate([
|
|
140
|
+
Property({ type: 'text', nullable: true }),
|
|
141
|
+
__metadata("design:type", Object)
|
|
142
|
+
], Promotion.prototype, "description", void 0);
|
|
143
|
+
__decorate([
|
|
144
|
+
Property({ type: 'integer', default: 0 }),
|
|
145
|
+
Index(),
|
|
146
|
+
__metadata("design:type", Number)
|
|
147
|
+
], Promotion.prototype, "priority", void 0);
|
|
148
|
+
__decorate([
|
|
149
|
+
Property({ type: 'boolean', default: false }),
|
|
150
|
+
__metadata("design:type", Boolean)
|
|
151
|
+
], Promotion.prototype, "stopFurther", void 0);
|
|
152
|
+
__decorate([
|
|
153
|
+
Property({ type: 'string', length: 64, nullable: true }),
|
|
154
|
+
__metadata("design:type", Object)
|
|
155
|
+
], Promotion.prototype, "actionType", void 0);
|
|
156
|
+
__decorate([
|
|
157
|
+
Property({ type: 'json', columnType: 'jsonb', default: "'{}'" }),
|
|
158
|
+
__metadata("design:type", Object)
|
|
159
|
+
], Promotion.prototype, "actionConfig", void 0);
|
|
160
|
+
__decorate([
|
|
161
|
+
Property({ type: 'uuid', nullable: true }),
|
|
162
|
+
Index(),
|
|
163
|
+
__metadata("design:type", Object)
|
|
164
|
+
], Promotion.prototype, "ruleId", void 0);
|
|
165
|
+
__decorate([
|
|
166
|
+
Property({ type: 'json', columnType: 'jsonb', nullable: true }),
|
|
167
|
+
__metadata("design:type", Object)
|
|
168
|
+
], Promotion.prototype, "ruleDefinition", void 0);
|
|
169
|
+
__decorate([
|
|
170
|
+
Property({ type: 'integer', nullable: true }),
|
|
171
|
+
__metadata("design:type", Object)
|
|
172
|
+
], Promotion.prototype, "usageLimitGlobal", void 0);
|
|
173
|
+
__decorate([
|
|
174
|
+
Property({ type: 'integer', nullable: true }),
|
|
175
|
+
__metadata("design:type", Object)
|
|
176
|
+
], Promotion.prototype, "usageLimitPerOrganization", void 0);
|
|
177
|
+
__decorate([
|
|
178
|
+
Property({ type: 'integer', nullable: true }),
|
|
179
|
+
__metadata("design:type", Object)
|
|
180
|
+
], Promotion.prototype, "usageLimitPerCustomer", void 0);
|
|
181
|
+
__decorate([
|
|
182
|
+
Property({ type: 'datetime', onCreate: () => new Date() }),
|
|
183
|
+
__metadata("design:type", Date)
|
|
184
|
+
], Promotion.prototype, "createdAt", void 0);
|
|
185
|
+
__decorate([
|
|
186
|
+
Property({ type: 'datetime', onUpdate: () => new Date() }),
|
|
187
|
+
__metadata("design:type", Date)
|
|
188
|
+
], Promotion.prototype, "updatedAt", void 0);
|
|
189
|
+
Promotion = __decorate([
|
|
190
|
+
GlobalEntity(),
|
|
191
|
+
Entity({ tableName: 'promotions' })
|
|
192
|
+
], Promotion);
|
|
193
|
+
export { Promotion };
|
|
194
|
+
//# sourceMappingURL=promotion.entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promotion.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/promotion.entity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql';
|
|
2
|
+
import type { ChannelMemberEntityType } from '@endora-commerce/contracts';
|
|
3
|
+
import type { CatalogProductReadPort, CatalogPromoAttributePort, DictionaryValidator } from '@endora-commerce/contracts';
|
|
4
|
+
import type { AuditPort, ModuleContext, OrganizationReadPort, RequireAdminFactory, SalesChannelMembershipPort } from '@endora-commerce/platform/kernel';
|
|
5
|
+
import { PromotionService } from './services/promotion-service.js';
|
|
6
|
+
import { Promotion } from './entities/promotion.entity.js';
|
|
7
|
+
import { PromotionRuleEntity } from './entities/promotion-rule.entity.js';
|
|
8
|
+
import { PromotionCoupon } from './entities/promotion-coupon.entity.js';
|
|
9
|
+
import { CouponBatch } from './entities/coupon-batch.entity.js';
|
|
10
|
+
import { PromotionUsage } from './entities/promotion-usage.entity.js';
|
|
11
|
+
import { PromotionUsageCounter } from './entities/promotion-usage-counter.entity.js';
|
|
12
|
+
import { CouponService } from './services/coupon-service.js';
|
|
13
|
+
import { PromotionRuleStore } from './services/promotion-rule-store.js';
|
|
14
|
+
import { PromotionStatsService } from './services/promotion-stats-service.js';
|
|
15
|
+
import type { PromotionRuleTargetPorts } from './routes.js';
|
|
16
|
+
/**
|
|
17
|
+
* `promotions` — six optional arguments, four of which were gates (feature 072,
|
|
18
|
+
* wave 2, T115; closed by issue #251).
|
|
19
|
+
*
|
|
20
|
+
* The one worth naming was `resolveOrganizationStatus`, documented as
|
|
21
|
+
* *"Defaults to 'skip' the gate when omitted (legacy composition)"*. Feature 026
|
|
22
|
+
* US5 exists so an org-targeted promotion only fires for an **active**
|
|
23
|
+
* Organization — a blocked or moderated customer should not keep receiving
|
|
24
|
+
* negotiated discounts. Omitting the resolver skipped that check entirely, so
|
|
25
|
+
* the promotion applied to every organization regardless of status.
|
|
26
|
+
*
|
|
27
|
+
* `salesChannelMembership`, `dictionaryValidator` and `auditLog` were the same
|
|
28
|
+
* story in quieter registers: without the first a new promotion bound to no
|
|
29
|
+
* channel and `applyToCart` did no channel filtering at all, without the second
|
|
30
|
+
* an unknown currency code was stored, without the third the write was
|
|
31
|
+
* unrecorded.
|
|
32
|
+
*
|
|
33
|
+
* All four are required arguments now. Both roots always passed them, so
|
|
34
|
+
* nothing was live — but `test/helpers/promotion-service.ts` passed none of
|
|
35
|
+
* them, so ten suites asserted against a service four gates quieter than the
|
|
36
|
+
* composed one. That is what an optional dependency production always supplies
|
|
37
|
+
* costs: the absent branch is untested by construction and only tests ever run
|
|
38
|
+
* it.
|
|
39
|
+
*
|
|
40
|
+
* **One bundle stays in the root**, for the reason `megamenu`'s did.
|
|
41
|
+
* `ruleTargets` reads `organizations`, `categories`, `payment_methods` and
|
|
42
|
+
* `delivery_methods` tables directly; it belongs to modules that have not
|
|
43
|
+
* converted, and pulling it in would give this module reads of storage it does
|
|
44
|
+
* not own.
|
|
45
|
+
*
|
|
46
|
+
* `catalogQueryPort` used to be the second, and this comment used to say the
|
|
47
|
+
* honest end state was for the two methods this module reached on
|
|
48
|
+
* `CatalogQueryService` to move behind a narrower port. Feature 075's Phase P
|
|
49
|
+
* did exactly that: `catalogPromoAttributePort` is those two questions, and
|
|
50
|
+
* `catalogProductReadPort` is the per-line attribute hydration that used to be
|
|
51
|
+
* an `em.find(Product, …)`. Both are resolved by contract type here.
|
|
52
|
+
*/
|
|
53
|
+
export interface PromotionsCradle {
|
|
54
|
+
/**
|
|
55
|
+
* Feature 120 (FR-015) — the platform's channel-bridge registry, resolved by
|
|
56
|
+
* **container name** rather than imported. The shape is the narrow one this
|
|
57
|
+
* module needs, which is what `ctx.cradle<C>()` asks an author to declare;
|
|
58
|
+
* the registry itself is the kernel's and is published on no barrel.
|
|
59
|
+
*/
|
|
60
|
+
readonly salesChannelBridgeRegistry: {
|
|
61
|
+
register(bridge: {
|
|
62
|
+
entityType: ChannelMemberEntityType;
|
|
63
|
+
table: string;
|
|
64
|
+
entityIdColumn: string;
|
|
65
|
+
}): void;
|
|
66
|
+
};
|
|
67
|
+
readonly emFactory: () => EntityManager;
|
|
68
|
+
readonly auditLogService: AuditPort;
|
|
69
|
+
readonly requireAdmin: RequireAdminFactory;
|
|
70
|
+
readonly salesChannelMembershipPort: SalesChannelMembershipPort;
|
|
71
|
+
readonly dictionaryValidator: DictionaryValidator;
|
|
72
|
+
/** Owned by `catalog`: the two promo-attribute questions the Rule Builder asks. */
|
|
73
|
+
readonly catalogPromoAttributePort: CatalogPromoAttributePort;
|
|
74
|
+
/** Owned by `catalog`: the product rows a cart line's attribute values come from. */
|
|
75
|
+
readonly catalogProductReadPort: CatalogProductReadPort;
|
|
76
|
+
/**
|
|
77
|
+
* The tenancy read port — the gate that keeps a suspended org out (T138).
|
|
78
|
+
* Was `organizationStatusResolver`, a raw `select "status" from
|
|
79
|
+
* "organizations"` each root spelled by hand against another module's table.
|
|
80
|
+
*/
|
|
81
|
+
readonly organizationReadPort: OrganizationReadPort;
|
|
82
|
+
/** Rule Builder picker sources; root-shaped, reads four other modules' tables. */
|
|
83
|
+
readonly promotionRuleTargets: PromotionRuleTargetPorts;
|
|
84
|
+
readonly promotionService: PromotionService;
|
|
85
|
+
readonly promotionCouponService: CouponService;
|
|
86
|
+
readonly promotionRuleStore: PromotionRuleStore;
|
|
87
|
+
readonly promotionStatsService: PromotionStatsService;
|
|
88
|
+
}
|
|
89
|
+
export declare function registerModule(ctx: ModuleContext): void;
|
|
90
|
+
/**
|
|
91
|
+
* The module's persisted entity classes, on the `./backend` subpath, as one
|
|
92
|
+
* array and **no named class export** (D-168).
|
|
93
|
+
*
|
|
94
|
+
* This is the shape the platform reads when the package is *installed*: the
|
|
95
|
+
* boot-time loader (`src/packages/package-runtime.ts`, `exported['entities']`)
|
|
96
|
+
* and the static declaration reader (`scripts/lib/package-declarations.ts`),
|
|
97
|
+
* which is the third source of `check:module-boundary`'s `table→owner` map and
|
|
98
|
+
* the package pass of `check-entity-tenant-classification`. A missing array is
|
|
99
|
+
* answered with `[]` — zero entities registered, no error anywhere.
|
|
100
|
+
*
|
|
101
|
+
* Six classes, and `promotion_usages` is the one that had to be shown to keep a
|
|
102
|
+
* foreign key without a named export (D-169): `promotion_usages_order_fk` runs
|
|
103
|
+
* into `orders.id`, and a constraint is between two column names — it needs the
|
|
104
|
+
* **table**, never the class. Nothing another module can legitimately do with
|
|
105
|
+
* `PromotionUsage` is lost. D-32 forbids an ORM relation into it; what `orders`
|
|
106
|
+
* actually needs is the *method* placement calls, which leaves this package as
|
|
107
|
+
* `PromotionUsageFinalizer` on the type-only `./ports` subpath.
|
|
108
|
+
*/
|
|
109
|
+
export declare const entities: (typeof Promotion | typeof PromotionRuleEntity | typeof PromotionCoupon | typeof CouponBatch | typeof PromotionUsage | typeof PromotionUsageCounter)[];
|
|
110
|
+
/**
|
|
111
|
+
* The sales-channel membership bridge this module owns (feature 120, FR-015).
|
|
112
|
+
*
|
|
113
|
+
* Exported as well as registered because the owning module is the only honest
|
|
114
|
+
* source for it: a caller that composes no platform — the bare-database test
|
|
115
|
+
* harness, which constructs the kernel's membership service directly — declares
|
|
116
|
+
* these from here rather than from a list of nine it keeps itself, which is
|
|
117
|
+
* exactly the total map this feature deleted.
|
|
118
|
+
*/
|
|
119
|
+
export declare const salesChannelBridges: ReadonlyArray<{
|
|
120
|
+
readonly entityType: ChannelMemberEntityType;
|
|
121
|
+
readonly table: string;
|
|
122
|
+
readonly entityIdColumn: string;
|
|
123
|
+
}>;
|
|
124
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EAGzB,mBAAmB,EAEpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,EAC3B,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AAErF,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAG5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,0BAA0B,EAAE;QACnC,QAAQ,CAAC,MAAM,EAAE;YACf,UAAU,EAAE,uBAAuB,CAAC;YACpC,KAAK,EAAE,MAAM,CAAC;YACd,cAAc,EAAE,MAAM,CAAC;SACxB,GAAG,IAAI,CAAC;KACV,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE,MAAM,aAAa,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,QAAQ,CAAC,0BAA0B,EAAE,0BAA0B,CAAC;IAChE,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAClD,mFAAmF;IACnF,QAAQ,CAAC,yBAAyB,EAAE,yBAAyB,CAAC;IAC9D,qFAAqF;IACrF,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;IACxD;;;;OAIG;IACH,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,kFAAkF;IAClF,QAAQ,CAAC,oBAAoB,EAAE,wBAAwB,CAAC;IACxD,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,sBAAsB,EAAE,aAAa,CAAC;IAC/C,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IAChD,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;CACvD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA+KvD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,QAAQ,wJAOpB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,uBAAuB,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC,CAEA,CAAC"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { lazyPort } from '@endora-commerce/platform/kernel';
|
|
2
|
+
import { PromotionService } from './services/promotion-service.js';
|
|
3
|
+
import { Promotion } from './entities/promotion.entity.js';
|
|
4
|
+
import { PromotionRuleEntity } from './entities/promotion-rule.entity.js';
|
|
5
|
+
import { PromotionCoupon } from './entities/promotion-coupon.entity.js';
|
|
6
|
+
import { CouponBatch } from './entities/coupon-batch.entity.js';
|
|
7
|
+
import { PromotionUsage } from './entities/promotion-usage.entity.js';
|
|
8
|
+
import { PromotionUsageCounter } from './entities/promotion-usage-counter.entity.js';
|
|
9
|
+
import { PromotionCodeService } from './services/promotion-code-port.js';
|
|
10
|
+
import { CouponService } from './services/coupon-service.js';
|
|
11
|
+
import { PromotionRuleStore } from './services/promotion-rule-store.js';
|
|
12
|
+
import { PromotionStatsService } from './services/promotion-stats-service.js';
|
|
13
|
+
import { registerPromotionRoutes } from './routes.js';
|
|
14
|
+
import { registerPromotionCurrencyReferences } from './services/promotion-currency-reference.js';
|
|
15
|
+
export function registerModule(ctx) {
|
|
16
|
+
/**
|
|
17
|
+
* Feature 120 (FR-015) — the sales-channel membership bridge this module owns.
|
|
18
|
+
*
|
|
19
|
+
* The platform used to hold a map **total** over
|
|
20
|
+
* `ChannelMemberEntityTypeSchema`, naming this module's bridge table from
|
|
21
|
+
* inside the kernel. That is D-52/D-53's prohibition expressed in a contract
|
|
22
|
+
* instead of an import, and it meant a membership call for 'promotion' on an
|
|
23
|
+
* instance that never installed this module executed SQL against a relation
|
|
24
|
+
* that is not there (D-226). The module whose migration creates the table is
|
|
25
|
+
* the one that says where it is; a member nothing registers now refuses at
|
|
26
|
+
* the call instead.
|
|
27
|
+
*
|
|
28
|
+
* A **contribution** hook and deliberately **unprobed** (D-62/D-68): a
|
|
29
|
+
* registration is an inert statement about the schema rather than a
|
|
30
|
+
* capability, the rows outlive an operator switching this module off, and
|
|
31
|
+
* probing would make a runtime activation flip require a restart. It is
|
|
32
|
+
* declared first in this module so any later hook of its own that binds a
|
|
33
|
+
* membership finds the bridge already there.
|
|
34
|
+
*/
|
|
35
|
+
ctx.onBoot(() => {
|
|
36
|
+
const { salesChannelBridgeRegistry } = ctx.cradle();
|
|
37
|
+
for (const bridge of salesChannelBridges)
|
|
38
|
+
salesChannelBridgeRegistry.register(bridge);
|
|
39
|
+
});
|
|
40
|
+
ctx.di.register({
|
|
41
|
+
// Contribution point: a composition with no picker sources gets empty
|
|
42
|
+
// pickers, not a broken Rule Builder.
|
|
43
|
+
promotionRuleTargets: ctx
|
|
44
|
+
.asFunction(() => ({}))
|
|
45
|
+
.singleton(),
|
|
46
|
+
promotionCouponService: ctx
|
|
47
|
+
.asFunction(({ emFactory, auditLogService }) => new CouponService(emFactory, auditLogService))
|
|
48
|
+
.singleton(),
|
|
49
|
+
promotionRuleStore: ctx
|
|
50
|
+
.asFunction(({ emFactory, auditLogService }) => new PromotionRuleStore(emFactory, auditLogService))
|
|
51
|
+
.singleton(),
|
|
52
|
+
promotionStatsService: ctx
|
|
53
|
+
.asFunction(({ emFactory }) => new PromotionStatsService(emFactory))
|
|
54
|
+
.singleton(),
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* Feature 075, Phase P — the coupon-resolution port.
|
|
58
|
+
*
|
|
59
|
+
* `carts` reaches both promotion entities for one question: is this code
|
|
60
|
+
* live, and which promotion is it? The three-step lookup behind it — the
|
|
61
|
+
* legacy inline code, then the coupon table, then the promotion behind the
|
|
62
|
+
* coupon, each filtered on `isActive` — is this module's, and reproducing it
|
|
63
|
+
* in `carts` meant reproducing it correctly.
|
|
64
|
+
*/
|
|
65
|
+
ctx.di.providePort('promotionCodePort', ctx
|
|
66
|
+
.asFunction(({ emFactory }) => new PromotionCodeService(emFactory))
|
|
67
|
+
.singleton());
|
|
68
|
+
/**
|
|
69
|
+
* D-94.5 — the co-transactional half of the promotion seam, as its own
|
|
70
|
+
* gated port.
|
|
71
|
+
*
|
|
72
|
+
* `orders` used to reach `finalizeUsage` through `promotionService`, typed
|
|
73
|
+
* by an interface `orders` wrote itself: `lazyPort<T>` is an unchecked cast,
|
|
74
|
+
* so with `T` on the consumer's side nothing verified that this module still
|
|
75
|
+
* satisfied it. The interface is `PromotionUsageFinalizer` and it is this
|
|
76
|
+
* module's to declare — `../ports/index.ts`, published on the type-only
|
|
77
|
+
* `./ports` subpath (R8), because the signature carries the caller's
|
|
78
|
+
* `EntityManager` and FR-034 keeps a MikroORM type out of
|
|
79
|
+
* `@endora-commerce/contracts`.
|
|
80
|
+
*
|
|
81
|
+
* It was declared beside the implementation until this module became a
|
|
82
|
+
* package, and `orders` reached it by a relative path — a `permanent: true`
|
|
83
|
+
* cross-module ledger entry naming `promotion_usages_order_fk`. D-171 retires
|
|
84
|
+
* that entry rather than the seam: a subpath the owner declared is contract
|
|
85
|
+
* surface, so the import is a package dependency and not a reach into
|
|
86
|
+
* internals. The foreign key, the transaction and the `EntityManager`
|
|
87
|
+
* parameter are all exactly where they were.
|
|
88
|
+
*/
|
|
89
|
+
ctx.di.providePort('promotionUsageFinalizer', ctx
|
|
90
|
+
.asFunction(() => {
|
|
91
|
+
// Lazily, even though this module owns the name: `providePort` gates
|
|
92
|
+
// on the effective state, and a singleton that captured its own gate
|
|
93
|
+
// would answer after an operator switched this module off.
|
|
94
|
+
const service = lazyPort(ctx, 'promotionService');
|
|
95
|
+
return {
|
|
96
|
+
finalizeUsage: (em, input) => service.finalizeUsage(em, input),
|
|
97
|
+
};
|
|
98
|
+
})
|
|
99
|
+
.singleton());
|
|
100
|
+
ctx.di.providePort('promotionService', ctx
|
|
101
|
+
.asFunction(({ emFactory, auditLogService }) => new PromotionService(emFactory,
|
|
102
|
+
// Every argument up to and including `auditLog` is required
|
|
103
|
+
// (issues #164 and #251): each is resolved for every composition,
|
|
104
|
+
// so the type no longer says otherwise. `auditLogger` and
|
|
105
|
+
// `actionRegistry` follow, and are the only two with a default —
|
|
106
|
+
// both are genuine defaults (a console sink, the built-in action
|
|
107
|
+
// catalogue), not gates an omission opens.
|
|
108
|
+
lazyPort(ctx, 'catalogPromoAttributePort'), lazyPort(ctx, 'catalogProductReadPort'), lazyPort(ctx, 'salesChannelMembershipPort'), lazyPort(ctx, 'dictionaryValidator'), async (orgId) => (await ctx
|
|
109
|
+
.cradle()
|
|
110
|
+
.organizationReadPort.loadEffectiveOrganization(orgId))?.status ?? null, auditLogService))
|
|
111
|
+
.singleton());
|
|
112
|
+
ctx.routes(async (app) => {
|
|
113
|
+
const { promotionCouponService, promotionRuleStore, promotionStatsService, requireAdmin, promotionRuleTargets, } = ctx.cradle();
|
|
114
|
+
await registerPromotionRoutes(app, {
|
|
115
|
+
// Lazily, even though the module owns this port: route *registration* runs
|
|
116
|
+
// inside `buildServer` whatever the module's effective state is, so
|
|
117
|
+
// destructuring the gate here would stop the next start instead of
|
|
118
|
+
// stopping the routes (D-40).
|
|
119
|
+
promotionService: lazyPort(ctx, 'promotionService'),
|
|
120
|
+
couponService: promotionCouponService,
|
|
121
|
+
ruleStore: promotionRuleStore,
|
|
122
|
+
statsService: promotionStatsService,
|
|
123
|
+
requireAdmin,
|
|
124
|
+
catalogPromoAttributes: lazyPort(ctx, 'catalogPromoAttributePort'),
|
|
125
|
+
ruleTargets: promotionRuleTargets,
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
/**
|
|
129
|
+
* This module's rows carry a currency code, so it answers "who still points at
|
|
130
|
+
* this currency?" about its own tables (feature 077, D-87), where the owner used
|
|
131
|
+
* to count them with SQL naming this module's tables.
|
|
132
|
+
*
|
|
133
|
+
* A **contribution** hook: it pushes an inert descriptor into `currencyReferenceRegistry`,
|
|
134
|
+
* an ungated registry, and carries no presence probe (D-62/D-68). Probing
|
|
135
|
+
* would be wrong in the dangerous direction — a switched-off module still owns
|
|
136
|
+
* the rows, so its currency must still refuse the delete, which is the
|
|
137
|
+
* enumeration policy the registry states.
|
|
138
|
+
*/
|
|
139
|
+
ctx.onBoot(() => {
|
|
140
|
+
registerPromotionCurrencyReferences(lazyPort(ctx, 'currencyReferenceRegistry'), ctx.cradle().emFactory);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The module's persisted entity classes, on the `./backend` subpath, as one
|
|
145
|
+
* array and **no named class export** (D-168).
|
|
146
|
+
*
|
|
147
|
+
* This is the shape the platform reads when the package is *installed*: the
|
|
148
|
+
* boot-time loader (`src/packages/package-runtime.ts`, `exported['entities']`)
|
|
149
|
+
* and the static declaration reader (`scripts/lib/package-declarations.ts`),
|
|
150
|
+
* which is the third source of `check:module-boundary`'s `table→owner` map and
|
|
151
|
+
* the package pass of `check-entity-tenant-classification`. A missing array is
|
|
152
|
+
* answered with `[]` — zero entities registered, no error anywhere.
|
|
153
|
+
*
|
|
154
|
+
* Six classes, and `promotion_usages` is the one that had to be shown to keep a
|
|
155
|
+
* foreign key without a named export (D-169): `promotion_usages_order_fk` runs
|
|
156
|
+
* into `orders.id`, and a constraint is between two column names — it needs the
|
|
157
|
+
* **table**, never the class. Nothing another module can legitimately do with
|
|
158
|
+
* `PromotionUsage` is lost. D-32 forbids an ORM relation into it; what `orders`
|
|
159
|
+
* actually needs is the *method* placement calls, which leaves this package as
|
|
160
|
+
* `PromotionUsageFinalizer` on the type-only `./ports` subpath.
|
|
161
|
+
*/
|
|
162
|
+
export const entities = [
|
|
163
|
+
Promotion,
|
|
164
|
+
PromotionRuleEntity,
|
|
165
|
+
PromotionCoupon,
|
|
166
|
+
CouponBatch,
|
|
167
|
+
PromotionUsage,
|
|
168
|
+
PromotionUsageCounter,
|
|
169
|
+
];
|
|
170
|
+
/**
|
|
171
|
+
* The sales-channel membership bridge this module owns (feature 120, FR-015).
|
|
172
|
+
*
|
|
173
|
+
* Exported as well as registered because the owning module is the only honest
|
|
174
|
+
* source for it: a caller that composes no platform — the bare-database test
|
|
175
|
+
* harness, which constructs the kernel's membership service directly — declares
|
|
176
|
+
* these from here rather than from a list of nine it keeps itself, which is
|
|
177
|
+
* exactly the total map this feature deleted.
|
|
178
|
+
*/
|
|
179
|
+
export const salesChannelBridges = [
|
|
180
|
+
{ entityType: 'promotion', table: 'sales_channel_promotions', entityIdColumn: 'promotion_id' },
|
|
181
|
+
];
|
|
182
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import type { PromotionService } from './services/promotion-service.js';
|
|
3
|
+
import type { CouponService } from './services/coupon-service.js';
|
|
4
|
+
import type { PromotionRuleStore } from './services/promotion-rule-store.js';
|
|
5
|
+
import type { PromotionStatsService } from './services/promotion-stats-service.js';
|
|
6
|
+
/**
|
|
7
|
+
* List ports feeding the Rule Builder pickers (feature 045, US1/T033).
|
|
8
|
+
*
|
|
9
|
+
* Declared here rather than in a module factory since feature 072 (T115): the
|
|
10
|
+
* factory is gone, and these are the routes' own option shape. Every member is
|
|
11
|
+
* optional because a composition may know how to list some target kinds and not
|
|
12
|
+
* others — an absent one yields an empty picker rather than a broken screen.
|
|
13
|
+
*/
|
|
14
|
+
export interface PromotionRuleTargetPorts {
|
|
15
|
+
salesChannels?: () => Promise<Array<{
|
|
16
|
+
id: string;
|
|
17
|
+
code: string;
|
|
18
|
+
name: string;
|
|
19
|
+
}>>;
|
|
20
|
+
customerGroups?: () => Promise<Array<{
|
|
21
|
+
id: string;
|
|
22
|
+
code: string;
|
|
23
|
+
name: string;
|
|
24
|
+
}>>;
|
|
25
|
+
organizations?: () => Promise<Array<{
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
taxId: string | null;
|
|
29
|
+
}>>;
|
|
30
|
+
categories?: () => Promise<Array<{
|
|
31
|
+
id: string;
|
|
32
|
+
slug: string;
|
|
33
|
+
name: string;
|
|
34
|
+
parentCategoryId: string | null;
|
|
35
|
+
}>>;
|
|
36
|
+
paymentMethods?: () => Promise<Array<{
|
|
37
|
+
id: string;
|
|
38
|
+
code: string;
|
|
39
|
+
name: string;
|
|
40
|
+
}>>;
|
|
41
|
+
deliveryMethods?: () => Promise<Array<{
|
|
42
|
+
id: string;
|
|
43
|
+
code: string;
|
|
44
|
+
name: string;
|
|
45
|
+
}>>;
|
|
46
|
+
}
|
|
47
|
+
import type { CatalogPromoAttributePort } from '@endora-commerce/contracts';
|
|
48
|
+
import type { RequireAdminFactory } from '@endora-commerce/platform/kernel';
|
|
49
|
+
export interface PromotionRoutesDeps {
|
|
50
|
+
promotionService: PromotionService;
|
|
51
|
+
couponService: CouponService;
|
|
52
|
+
ruleStore: PromotionRuleStore;
|
|
53
|
+
statsService: PromotionStatsService;
|
|
54
|
+
requireAdmin: RequireAdminFactory;
|
|
55
|
+
/**
|
|
56
|
+
* Feature 012 / US8 — feeds the rule-target picker endpoint. Since feature
|
|
57
|
+
* 075's Phase C this is `catalogPromoAttributePort`, the two questions this
|
|
58
|
+
* picker asks, rather than `catalog`'s 1400-line storefront query service.
|
|
59
|
+
*
|
|
60
|
+
* **Required** (issue #164), for the reason the two ports on
|
|
61
|
+
* `PromotionService` are. It was optional and the one call site there is —
|
|
62
|
+
* `backend.ts`, through `lazyPort('catalogPromoAttributePort')` — always
|
|
63
|
+
* supplied it, so the absent branch had never run; what it would have run
|
|
64
|
+
* was `503 { code: 'service_unavailable' }`, a code written nowhere else in
|
|
65
|
+
* the repository, in no `ERROR_CODES`, with no translation and no admin
|
|
66
|
+
* handler. That made it a second spelling of one absence, and the platform
|
|
67
|
+
* already spells that absence once: `lazyPort` resolves inside the forwarded
|
|
68
|
+
* call, so an owner that is not there throws `ModuleDisabledError` and the
|
|
69
|
+
* envelope answers 503 `MODULE_DISABLED` naming the module. Here even that
|
|
70
|
+
* cannot happen — `catalog` declares `activation.nonDeactivatable`, so the
|
|
71
|
+
* gate on this port has no closed state — which leaves exactly one absence
|
|
72
|
+
* this route can see, and it is the one `getAttributeWithOptions` already
|
|
73
|
+
* says in its return type: `null`, no such attribute.
|
|
74
|
+
*/
|
|
75
|
+
catalogPromoAttributes: CatalogPromoAttributePort;
|
|
76
|
+
/**
|
|
77
|
+
* Feature 045 (T033) — list ports for the remaining rule-target pickers.
|
|
78
|
+
*
|
|
79
|
+
* The bundle is required and its **members** are not: the container
|
|
80
|
+
* registers `promotionRuleTargets` with a `{}` default that a composition
|
|
81
|
+
* root contributes over, so the routes always receive one, while which
|
|
82
|
+
* picker kinds it knows how to list stays the composition's business
|
|
83
|
+
* (issue #164 again — the outer `?.` guarded nothing).
|
|
84
|
+
*/
|
|
85
|
+
ruleTargets: PromotionRuleTargetPorts;
|
|
86
|
+
}
|
|
87
|
+
export declare function registerPromotionRoutes(app: FastifyInstance, deps: PromotionRoutesDeps): Promise<void>;
|
|
88
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/backend/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAS/C,OAAO,KAAK,EAAE,gBAAgB,EAAwB,MAAM,iCAAiC,CAAC;AAC9F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,qBAAqB,EAAc,MAAM,uCAAuC,CAAC;AAE/F;;;;;;;GAOG;AACH,MAAM,WAAW,wBAAwB;IACvC,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACjF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAClF,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC,CAAC;IACzF,UAAU,CAAC,EAAE,MAAM,OAAO,CACxB,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CACnF,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAClF,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CACpF;AAMD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,kBAAkB,CAAC;IAC9B,YAAY,EAAE,qBAAqB,CAAC;IACpC,YAAY,EAAE,mBAAmB,CAAC;IAClC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,sBAAsB,EAAE,yBAAyB,CAAC;IAClD;;;;;;;;OAQG;IACH,WAAW,EAAE,wBAAwB,CAAC;CACvC;AAED,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,IAAI,CAAC,CAwQf"}
|