@classytic/promo 0.2.5 → 0.4.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/CHANGELOG.md +127 -0
- package/README.md +68 -8
- package/dist/{constants-BB5O8zlN.mjs → constants-BE886vJk.mjs} +52 -34
- package/dist/events/promo-event-catalog.d.mts +233 -0
- package/dist/events/promo-event-catalog.mjs +2 -0
- package/dist/index.d.mts +260 -362
- package/dist/index.mjs +232 -363
- package/dist/promo-event-catalog-Dyh0xQ6w.mjs +250 -0
- package/dist/schemas/index.d.mts +4 -4
- package/dist/schemas/index.mjs +1 -1
- package/package.json +10 -6
- /package/dist/{constants-CrbSSQG5.d.mts → constants-hcMTDJml.d.mts} +0 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,163 +1,191 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EvaluationCommitted, EvaluationCommittedPayloadSchema, EvaluationCompleted, EvaluationCompletedPayloadSchema, EvaluationRolledBack, EvaluationRolledBackPayloadSchema, GiftCardExhausted, GiftCardSpent, GiftCardSpentPayloadSchema, GiftCardToppedUp, GiftCardToppedUpPayloadSchema, ProgramActivated, ProgramArchived, ProgramCreated, ProgramLifecyclePayloadSchema, ProgramPaused, PromoEventDefinition, PromoEventPayloadOf, PromoEventSchema, RewardAdded, RewardPayloadSchema, RewardRemoved, RewardUpdated, RuleAdded, RulePayloadSchema, RuleRemoved, RuleUpdated, VoucherCancelled, VoucherExpired, VoucherGenerated, VoucherGeneratedPayloadSchema, VoucherLifecyclePayloadSchema, VoucherRedeemed, VoucherRedeemedPayloadSchema, promoEventDefinitions } from "./events/promo-event-catalog.mjs";
|
|
2
|
+
import { c as ProgramType, f as StackingMode, g as VoucherStatus, i as DiscountScope, m as TriggerMode, r as DiscountMode, s as ProgramStatus, u as RewardType } from "./constants-hcMTDJml.mjs";
|
|
2
3
|
import { PluginType as PluginType$1, Repository } from "@classytic/mongokit";
|
|
3
4
|
import { ResolvedTenantConfig, TenantConfig, TenantFieldType } from "@classytic/repo-core/tenant";
|
|
4
5
|
import { DomainEvent, DomainEvent as DomainEvent$1, EventHandler, EventTransport, EventTransport as EventTransport$1 } from "@classytic/primitives/events";
|
|
5
6
|
import { ClientSession, Connection, Model } from "mongoose";
|
|
6
|
-
import {
|
|
7
|
+
import { RetryPolicy } from "@classytic/repo-core/repository";
|
|
7
8
|
import { OutboxStore } from "@classytic/primitives/outbox";
|
|
8
9
|
import { OperationContext } from "@classytic/primitives/context";
|
|
10
|
+
import { HttpError } from "@classytic/repo-core/errors";
|
|
9
11
|
|
|
10
12
|
//#region src/types/inputs.d.ts
|
|
11
13
|
/**
|
|
12
14
|
* Extends `@classytic/primitives`' {@link OperationContext}. The
|
|
13
15
|
* `[key: string]: unknown` fall-through lets hosts pass dynamic tenant keys
|
|
14
16
|
* when they've configured a custom `contextKey` on `TenantConfig`.
|
|
17
|
+
*
|
|
18
|
+
* Primitives' `actorId` is replaced by `actorRef` — the commerce-wide
|
|
19
|
+
* convention (cart/order/flow) for "stable user id OR guest session id".
|
|
20
|
+
*
|
|
21
|
+
* **Option threading.** Promo deliberately spreads the WHOLE context into
|
|
22
|
+
* mongokit option bags (`{ lean: true, ...ctx }`) instead of using a
|
|
23
|
+
* fixed-key options extractor — the index-signature fall-through means a
|
|
24
|
+
* host's custom `contextKey` value reaches `multiTenantPlugin` without
|
|
25
|
+
* promo knowing its name. The typed fields below (`session`, `signal`,
|
|
26
|
+
* `retryPolicy`, `organizationId`) ride the same spread: mongokit 3.16
|
|
27
|
+
* reads them straight off the options bag (cancellation at every op
|
|
28
|
+
* boundary, `withRetry` around driver round-trips).
|
|
15
29
|
*/
|
|
16
|
-
interface PromoContext extends OperationContext {
|
|
17
|
-
/**
|
|
18
|
-
|
|
30
|
+
interface PromoContext extends Omit<OperationContext, 'actorId' | 'organizationId'> {
|
|
31
|
+
/**
|
|
32
|
+
* Actor identity — a stable user ID (authenticated) or a session ID
|
|
33
|
+
* (guest). Matches the `actorRef` convention used by `@classytic/cart`,
|
|
34
|
+
* `@classytic/order`, and `@classytic/flow`.
|
|
35
|
+
*/
|
|
36
|
+
actorRef?: string | undefined;
|
|
19
37
|
/** Narrowed from primitives' `IdLike` to string. */
|
|
20
|
-
organizationId?: string;
|
|
38
|
+
organizationId?: string | undefined;
|
|
21
39
|
/** Narrows primitives' `session: unknown` to the concrete Mongoose type so
|
|
22
40
|
* this context flows directly into mongokit repository calls. */
|
|
23
|
-
session?: ClientSession;
|
|
41
|
+
session?: ClientSession | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Cooperative cancellation. Mongokit checks the signal at every op
|
|
44
|
+
* boundary; promo additionally checks it between iterations of its own
|
|
45
|
+
* batch loops (`expireByDate`, the per-program evaluation loop, the
|
|
46
|
+
* commit usage loops). Aborting never rolls back a committed write.
|
|
47
|
+
*/
|
|
48
|
+
signal?: AbortSignal | undefined;
|
|
49
|
+
/** Per-call retry policy — mongokit wraps driver round-trips in
|
|
50
|
+
* `withRetry` (never hooks; hooks run exactly once). */
|
|
51
|
+
retryPolicy?: RetryPolicy | undefined;
|
|
24
52
|
[key: string]: unknown;
|
|
25
53
|
}
|
|
26
54
|
interface CreateProgramInput {
|
|
27
55
|
name: string;
|
|
28
|
-
description?: string;
|
|
56
|
+
description?: string | undefined;
|
|
29
57
|
programType: ProgramType;
|
|
30
58
|
triggerMode: TriggerMode;
|
|
31
|
-
stackingMode?: StackingMode;
|
|
32
|
-
priority?: number;
|
|
33
|
-
startsAt?: Date;
|
|
34
|
-
endsAt?: Date;
|
|
35
|
-
maxUsageTotal?: number;
|
|
36
|
-
maxUsagePerCustomer?: number;
|
|
37
|
-
applicableCustomerIds?: string[];
|
|
38
|
-
applicableCustomerTags?: string[];
|
|
39
|
-
metadata?: Record<string, unknown
|
|
59
|
+
stackingMode?: StackingMode | undefined;
|
|
60
|
+
priority?: number | undefined;
|
|
61
|
+
startsAt?: Date | undefined;
|
|
62
|
+
endsAt?: Date | undefined;
|
|
63
|
+
maxUsageTotal?: number | undefined;
|
|
64
|
+
maxUsagePerCustomer?: number | undefined;
|
|
65
|
+
applicableCustomerIds?: string[] | undefined;
|
|
66
|
+
applicableCustomerTags?: string[] | undefined;
|
|
67
|
+
metadata?: Record<string, unknown> | undefined;
|
|
40
68
|
}
|
|
41
69
|
interface UpdateProgramInput {
|
|
42
|
-
name?: string;
|
|
43
|
-
description?: string;
|
|
44
|
-
stackingMode?: StackingMode;
|
|
45
|
-
priority?: number;
|
|
46
|
-
startsAt?: Date;
|
|
47
|
-
endsAt?: Date;
|
|
48
|
-
maxUsageTotal?: number;
|
|
49
|
-
maxUsagePerCustomer?: number;
|
|
50
|
-
applicableCustomerIds?: string[];
|
|
51
|
-
applicableCustomerTags?: string[];
|
|
52
|
-
metadata?: Record<string, unknown
|
|
70
|
+
name?: string | undefined;
|
|
71
|
+
description?: string | undefined;
|
|
72
|
+
stackingMode?: StackingMode | undefined;
|
|
73
|
+
priority?: number | undefined;
|
|
74
|
+
startsAt?: Date | undefined;
|
|
75
|
+
endsAt?: Date | undefined;
|
|
76
|
+
maxUsageTotal?: number | undefined;
|
|
77
|
+
maxUsagePerCustomer?: number | undefined;
|
|
78
|
+
applicableCustomerIds?: string[] | undefined;
|
|
79
|
+
applicableCustomerTags?: string[] | undefined;
|
|
80
|
+
metadata?: Record<string, unknown> | undefined;
|
|
53
81
|
}
|
|
54
82
|
interface CreateRuleInput {
|
|
55
|
-
name?: string;
|
|
56
|
-
minimumAmount?: number;
|
|
57
|
-
minimumQuantity?: number;
|
|
58
|
-
applicableProductIds?: string[];
|
|
59
|
-
applicableCategories?: string[];
|
|
60
|
-
applicableSkus?: string[];
|
|
61
|
-
buyQuantity?: number;
|
|
62
|
-
code?: string;
|
|
63
|
-
startsAt?: Date;
|
|
64
|
-
endsAt?: Date;
|
|
65
|
-
metadata?: Record<string, unknown
|
|
83
|
+
name?: string | undefined;
|
|
84
|
+
minimumAmount?: number | undefined;
|
|
85
|
+
minimumQuantity?: number | undefined;
|
|
86
|
+
applicableProductIds?: string[] | undefined;
|
|
87
|
+
applicableCategories?: string[] | undefined;
|
|
88
|
+
applicableSkus?: string[] | undefined;
|
|
89
|
+
buyQuantity?: number | undefined;
|
|
90
|
+
code?: string | undefined;
|
|
91
|
+
startsAt?: Date | undefined;
|
|
92
|
+
endsAt?: Date | undefined;
|
|
93
|
+
metadata?: Record<string, unknown> | undefined;
|
|
66
94
|
}
|
|
67
95
|
interface UpdateRuleInput {
|
|
68
|
-
name?: string;
|
|
69
|
-
minimumAmount?: number;
|
|
70
|
-
minimumQuantity?: number;
|
|
71
|
-
applicableProductIds?: string[];
|
|
72
|
-
applicableCategories?: string[];
|
|
73
|
-
applicableSkus?: string[];
|
|
74
|
-
buyQuantity?: number;
|
|
75
|
-
code?: string;
|
|
76
|
-
startsAt?: Date;
|
|
77
|
-
endsAt?: Date;
|
|
78
|
-
metadata?: Record<string, unknown
|
|
96
|
+
name?: string | undefined;
|
|
97
|
+
minimumAmount?: number | undefined;
|
|
98
|
+
minimumQuantity?: number | undefined;
|
|
99
|
+
applicableProductIds?: string[] | undefined;
|
|
100
|
+
applicableCategories?: string[] | undefined;
|
|
101
|
+
applicableSkus?: string[] | undefined;
|
|
102
|
+
buyQuantity?: number | undefined;
|
|
103
|
+
code?: string | undefined;
|
|
104
|
+
startsAt?: Date | undefined;
|
|
105
|
+
endsAt?: Date | undefined;
|
|
106
|
+
metadata?: Record<string, unknown> | undefined;
|
|
79
107
|
}
|
|
80
108
|
interface CreateRewardInput {
|
|
81
|
-
ruleId?: string;
|
|
109
|
+
ruleId?: string | undefined;
|
|
82
110
|
rewardType: RewardType;
|
|
83
|
-
discountMode?: DiscountMode;
|
|
84
|
-
discountAmount?: number;
|
|
85
|
-
maxDiscountAmount?: number;
|
|
86
|
-
discountScope?: DiscountScope;
|
|
87
|
-
applicableProductIds?: string[];
|
|
88
|
-
freeProductId?: string;
|
|
89
|
-
freeProductSku?: string;
|
|
90
|
-
freeQuantity?: number;
|
|
91
|
-
giftCardAmount?: number;
|
|
92
|
-
metadata?: Record<string, unknown
|
|
111
|
+
discountMode?: DiscountMode | undefined;
|
|
112
|
+
discountAmount?: number | undefined;
|
|
113
|
+
maxDiscountAmount?: number | undefined;
|
|
114
|
+
discountScope?: DiscountScope | undefined;
|
|
115
|
+
applicableProductIds?: string[] | undefined;
|
|
116
|
+
freeProductId?: string | undefined;
|
|
117
|
+
freeProductSku?: string | undefined;
|
|
118
|
+
freeQuantity?: number | undefined;
|
|
119
|
+
giftCardAmount?: number | undefined;
|
|
120
|
+
metadata?: Record<string, unknown> | undefined;
|
|
93
121
|
}
|
|
94
122
|
interface UpdateRewardInput {
|
|
95
|
-
discountMode?: DiscountMode;
|
|
96
|
-
discountAmount?: number;
|
|
97
|
-
maxDiscountAmount?: number;
|
|
98
|
-
discountScope?: DiscountScope;
|
|
99
|
-
applicableProductIds?: string[];
|
|
100
|
-
freeProductId?: string;
|
|
101
|
-
freeProductSku?: string;
|
|
102
|
-
freeQuantity?: number;
|
|
103
|
-
giftCardAmount?: number;
|
|
104
|
-
metadata?: Record<string, unknown
|
|
123
|
+
discountMode?: DiscountMode | undefined;
|
|
124
|
+
discountAmount?: number | undefined;
|
|
125
|
+
maxDiscountAmount?: number | undefined;
|
|
126
|
+
discountScope?: DiscountScope | undefined;
|
|
127
|
+
applicableProductIds?: string[] | undefined;
|
|
128
|
+
freeProductId?: string | undefined;
|
|
129
|
+
freeProductSku?: string | undefined;
|
|
130
|
+
freeQuantity?: number | undefined;
|
|
131
|
+
giftCardAmount?: number | undefined;
|
|
132
|
+
metadata?: Record<string, unknown> | undefined;
|
|
105
133
|
}
|
|
106
134
|
interface GenerateCodesInput {
|
|
107
135
|
programId: string;
|
|
108
136
|
count: number;
|
|
109
|
-
customerId?: string;
|
|
110
|
-
expiresAt?: Date;
|
|
111
|
-
metadata?: Record<string, unknown
|
|
137
|
+
customerId?: string | undefined;
|
|
138
|
+
expiresAt?: Date | undefined;
|
|
139
|
+
metadata?: Record<string, unknown> | undefined;
|
|
112
140
|
}
|
|
113
141
|
interface GenerateSingleCodeInput {
|
|
114
142
|
programId: string;
|
|
115
|
-
code?: string;
|
|
116
|
-
customerId?: string;
|
|
117
|
-
expiresAt?: Date;
|
|
118
|
-
initialBalance?: number;
|
|
119
|
-
metadata?: Record<string, unknown
|
|
143
|
+
code?: string | undefined;
|
|
144
|
+
customerId?: string | undefined;
|
|
145
|
+
expiresAt?: Date | undefined;
|
|
146
|
+
initialBalance?: number | undefined;
|
|
147
|
+
metadata?: Record<string, unknown> | undefined;
|
|
120
148
|
}
|
|
121
149
|
interface RedeemVoucherInput {
|
|
122
150
|
code: string;
|
|
123
151
|
orderId: string;
|
|
124
|
-
customerId?: string;
|
|
152
|
+
customerId?: string | undefined;
|
|
125
153
|
discountAmount: number;
|
|
126
|
-
idempotencyKey?: string;
|
|
154
|
+
idempotencyKey?: string | undefined;
|
|
127
155
|
}
|
|
128
156
|
interface GiftCardSpendInput {
|
|
129
157
|
code: string;
|
|
130
158
|
amount: number;
|
|
131
159
|
orderId: string;
|
|
132
|
-
description?: string;
|
|
133
|
-
idempotencyKey?: string;
|
|
160
|
+
description?: string | undefined;
|
|
161
|
+
idempotencyKey?: string | undefined;
|
|
134
162
|
}
|
|
135
163
|
interface GiftCardTopUpInput {
|
|
136
164
|
code: string;
|
|
137
165
|
amount: number;
|
|
138
|
-
description?: string;
|
|
139
|
-
idempotencyKey?: string;
|
|
166
|
+
description?: string | undefined;
|
|
167
|
+
idempotencyKey?: string | undefined;
|
|
140
168
|
}
|
|
141
169
|
interface CartItem {
|
|
142
170
|
productId: string;
|
|
143
|
-
sku?: string;
|
|
144
|
-
categoryId?: string;
|
|
171
|
+
sku?: string | undefined;
|
|
172
|
+
categoryId?: string | undefined;
|
|
145
173
|
quantity: number;
|
|
146
174
|
unitPrice: number;
|
|
147
|
-
lineTotal?: number;
|
|
175
|
+
lineTotal?: number | undefined;
|
|
148
176
|
}
|
|
149
177
|
interface EvaluateInput {
|
|
150
178
|
items: CartItem[];
|
|
151
179
|
subtotal: number;
|
|
152
|
-
codes?: string[];
|
|
153
|
-
customerId?: string;
|
|
154
|
-
customerTags?: string[];
|
|
180
|
+
codes?: string[] | undefined;
|
|
181
|
+
customerId?: string | undefined;
|
|
182
|
+
customerTags?: string[] | undefined;
|
|
155
183
|
}
|
|
156
184
|
interface ListQuery {
|
|
157
|
-
page?: number;
|
|
158
|
-
limit?: number;
|
|
159
|
-
sort?: string;
|
|
160
|
-
filters?: Record<string, unknown
|
|
185
|
+
page?: number | undefined;
|
|
186
|
+
limit?: number | undefined;
|
|
187
|
+
sort?: string | undefined;
|
|
188
|
+
filters?: Record<string, unknown> | undefined;
|
|
161
189
|
}
|
|
162
190
|
//#endregion
|
|
163
191
|
//#region src/types/results.d.ts
|
|
@@ -169,14 +197,14 @@ interface DiscountLine {
|
|
|
169
197
|
scope: 'order' | 'cheapest' | 'specific_products';
|
|
170
198
|
amount: number;
|
|
171
199
|
description: string;
|
|
172
|
-
voucherCode?: string;
|
|
200
|
+
voucherCode?: string | undefined;
|
|
173
201
|
}
|
|
174
202
|
interface FreeProductLine {
|
|
175
203
|
programId: string;
|
|
176
204
|
programName: string;
|
|
177
205
|
rewardId: string;
|
|
178
|
-
productId?: string;
|
|
179
|
-
productSku?: string;
|
|
206
|
+
productId?: string | undefined;
|
|
207
|
+
productSku?: string | undefined;
|
|
180
208
|
quantity: number;
|
|
181
209
|
description: string;
|
|
182
210
|
}
|
|
@@ -220,10 +248,10 @@ interface VoucherValidation {
|
|
|
220
248
|
programType: string;
|
|
221
249
|
status: string;
|
|
222
250
|
remainingUses: number;
|
|
223
|
-
currentBalance?: number;
|
|
224
|
-
expiresAt?: Date;
|
|
251
|
+
currentBalance?: number | undefined;
|
|
252
|
+
expiresAt?: Date | undefined;
|
|
225
253
|
};
|
|
226
|
-
error?: string;
|
|
254
|
+
error?: string | undefined;
|
|
227
255
|
}
|
|
228
256
|
interface GiftCardBalance {
|
|
229
257
|
code: string;
|
|
@@ -255,7 +283,7 @@ interface PaginatedResult<T> {
|
|
|
255
283
|
interface StoredEvaluationSnapshot {
|
|
256
284
|
readonly result: EvaluationResult;
|
|
257
285
|
readonly ctx: PromoContext;
|
|
258
|
-
readonly customerId?: string;
|
|
286
|
+
readonly customerId?: string | undefined;
|
|
259
287
|
readonly programUsages: ReadonlyArray<{
|
|
260
288
|
programId: string;
|
|
261
289
|
}>;
|
|
@@ -284,7 +312,7 @@ interface StoredEvaluationSnapshot {
|
|
|
284
312
|
* have to translate between context shapes at the call site.
|
|
285
313
|
*/
|
|
286
314
|
interface EvaluationStoreContext {
|
|
287
|
-
readonly tenantValue?: string;
|
|
315
|
+
readonly tenantValue?: string | undefined;
|
|
288
316
|
readonly session?: unknown;
|
|
289
317
|
}
|
|
290
318
|
/**
|
|
@@ -387,6 +415,34 @@ interface PromoConfig {
|
|
|
387
415
|
} | undefined;
|
|
388
416
|
indexes?: Partial<Record<ModelName, IndexDefinition[]>> | undefined;
|
|
389
417
|
autoIndex?: boolean | Partial<Record<ModelName, boolean>> | undefined;
|
|
418
|
+
/**
|
|
419
|
+
* Optional namespace prepended to every physical collection promo
|
|
420
|
+
* creates (PACKAGE_RULES §20.1) — e.g. `'commerce_'` →
|
|
421
|
+
* `commerce_promoprograms`. Model names are never prefixed, so `ref:`
|
|
422
|
+
* populate keeps working. Unset → the historical default names
|
|
423
|
+
* (`promoprograms`, `promorules`, `promorewards`, `promovouchers`,
|
|
424
|
+
* `promopendingevaluations`).
|
|
425
|
+
*/
|
|
426
|
+
collectionPrefix?: string | undefined;
|
|
427
|
+
/**
|
|
428
|
+
* When true, existing Mongoose models with promo's names on the
|
|
429
|
+
* connection are deleted and re-registered — hot-reload / test fixtures
|
|
430
|
+
* only. Default `false`: a name collision throws
|
|
431
|
+
* `PromoModelCollisionError` (rule 21). Two promo engines in one
|
|
432
|
+
* process need two Mongoose connections.
|
|
433
|
+
*/
|
|
434
|
+
forceRecreate?: boolean | undefined;
|
|
435
|
+
/**
|
|
436
|
+
* Escape hatch for the boot-time capability gate. Promo's commit /
|
|
437
|
+
* redeem / spend / topUp paths are transactional; by default
|
|
438
|
+
* `createPromoEngine` asserts the backend's `capabilities.transactions`
|
|
439
|
+
* flag at boot (fail loud at boot, not with a cryptic error 263 on the
|
|
440
|
+
* first checkout). `allowNonTransactional: true` skips the gate AND lets
|
|
441
|
+
* the internal unit-of-work fall back to non-transactional execution on
|
|
442
|
+
* standalone MongoDB (dev / CI without a replica set) — atomicity across
|
|
443
|
+
* documents is then best-effort.
|
|
444
|
+
*/
|
|
445
|
+
allowNonTransactional?: boolean | undefined;
|
|
390
446
|
events?: {
|
|
391
447
|
transport?: EventTransport$1 | undefined;
|
|
392
448
|
} | undefined;
|
|
@@ -448,6 +504,21 @@ interface PromoModels {
|
|
|
448
504
|
Voucher: Model<unknown>;
|
|
449
505
|
PendingEvaluation: Model<unknown>;
|
|
450
506
|
}
|
|
507
|
+
/**
|
|
508
|
+
* Explicit physical collection names (PACKAGE_RULES §20.1) — the values
|
|
509
|
+
* Mongoose's pluralizer produced before they were pinned, so existing
|
|
510
|
+
* deployments keep their data with zero migration. Passed as the third
|
|
511
|
+
* arg of `connection.model()` so a host that disables/changes the
|
|
512
|
+
* pluralizer can't silently rename collections. Changing any entry is a
|
|
513
|
+
* BREAKING change (renames the physical collection — ship a migration).
|
|
514
|
+
*/
|
|
515
|
+
declare const DEFAULT_COLLECTIONS: {
|
|
516
|
+
readonly PromoProgram: "promoprograms";
|
|
517
|
+
readonly PromoRule: "promorules";
|
|
518
|
+
readonly PromoReward: "promorewards";
|
|
519
|
+
readonly PromoVoucher: "promovouchers";
|
|
520
|
+
readonly PromoPendingEvaluation: "promopendingevaluations";
|
|
521
|
+
};
|
|
451
522
|
//#endregion
|
|
452
523
|
//#region src/events/dispatch.d.ts
|
|
453
524
|
interface DispatchLogger {
|
|
@@ -458,6 +529,23 @@ interface DispatchDeps {
|
|
|
458
529
|
outbox?: OutboxStore | undefined;
|
|
459
530
|
logger?: DispatchLogger | undefined;
|
|
460
531
|
}
|
|
532
|
+
/**
|
|
533
|
+
* Context key for the post-commit publish queue. Promo's transactional
|
|
534
|
+
* verbs attach it automatically when they own the transaction; hosts that
|
|
535
|
+
* own the outer transaction (`ctx.session`) MAY attach their own array and
|
|
536
|
+
* drain it with {@link flushPendingPromoEvents} after commit for strict
|
|
537
|
+
* no-ghost-event semantics. Symbol-keyed so it survives `{ ...ctx }`
|
|
538
|
+
* spreads but never collides with host context fields.
|
|
539
|
+
*/
|
|
540
|
+
declare const PENDING_PROMO_EVENTS: unique symbol;
|
|
541
|
+
/**
|
|
542
|
+
* Drain a pending-events queue through the transport, swallowing per-event
|
|
543
|
+
* publish errors (durable delivery is the outbox's job). Promo's
|
|
544
|
+
* transactional verbs call this after commit; hosts that attached their own
|
|
545
|
+
* `[PENDING_PROMO_EVENTS]` queue call it after their outer transaction
|
|
546
|
+
* commits. The queue is emptied in place.
|
|
547
|
+
*/
|
|
548
|
+
declare function flushPendingPromoEvents(deps: DispatchDeps, events: DomainEvent$1[]): Promise<void>;
|
|
461
549
|
//#endregion
|
|
462
550
|
//#region src/repositories/pending-evaluation.repository.d.ts
|
|
463
551
|
/**
|
|
@@ -525,16 +613,16 @@ declare class PendingEvaluationRepository extends Repository<PendingEvaluationDo
|
|
|
525
613
|
* keep cross-tenant isolation on the cache layer too.
|
|
526
614
|
*/
|
|
527
615
|
takeByEvaluationId(evaluationId: string, ctx?: {
|
|
528
|
-
tenantValue?: string;
|
|
529
|
-
session?: ClientSession;
|
|
616
|
+
tenantValue?: string | undefined;
|
|
617
|
+
session?: ClientSession | undefined;
|
|
530
618
|
}): Promise<PendingEvaluationDocument | null>;
|
|
531
619
|
/**
|
|
532
620
|
* Idempotent delete. Returns whether anything was actually removed,
|
|
533
621
|
* so callers can distinguish "we cleaned it" from "already gone".
|
|
534
622
|
*/
|
|
535
623
|
deleteByEvaluationId(evaluationId: string, ctx?: {
|
|
536
|
-
tenantValue?: string;
|
|
537
|
-
session?: ClientSession;
|
|
624
|
+
tenantValue?: string | undefined;
|
|
625
|
+
session?: ClientSession | undefined;
|
|
538
626
|
}): Promise<boolean>;
|
|
539
627
|
/**
|
|
540
628
|
* Build a query filter with the configured tenant scope appended,
|
|
@@ -766,11 +854,11 @@ interface PromoRepositories {
|
|
|
766
854
|
pendingEvaluation: PendingEvaluationRepository;
|
|
767
855
|
}
|
|
768
856
|
interface RepositoryPluginsMap {
|
|
769
|
-
program?: PluginType$1[];
|
|
770
|
-
rule?: PluginType$1[];
|
|
771
|
-
reward?: PluginType$1[];
|
|
772
|
-
voucher?: PluginType$1[];
|
|
773
|
-
pendingEvaluation?: PluginType$1[];
|
|
857
|
+
program?: PluginType$1[] | undefined;
|
|
858
|
+
rule?: PluginType$1[] | undefined;
|
|
859
|
+
reward?: PluginType$1[] | undefined;
|
|
860
|
+
voucher?: PluginType$1[] | undefined;
|
|
861
|
+
pendingEvaluation?: PluginType$1[] | undefined;
|
|
774
862
|
}
|
|
775
863
|
interface RepositoryDispatchDeps {
|
|
776
864
|
events?: EventTransport$1 | undefined;
|
|
@@ -840,6 +928,28 @@ declare class VoucherService {
|
|
|
840
928
|
private dispatchDeps;
|
|
841
929
|
private config;
|
|
842
930
|
constructor(voucherRepo: VoucherRepository, programRepo: ProgramRepository, unitOfWork: UnitOfWork, dispatchDeps: DispatchDeps, config: ResolvedConfig);
|
|
931
|
+
/**
|
|
932
|
+
* Session threading — checkout-chain participation. When the host
|
|
933
|
+
* already owns a transaction (e.g. the cart → order → flow → promo →
|
|
934
|
+
* invoice chain runs as ONE atomic unit), it passes `ctx.session` and
|
|
935
|
+
* the transactional body JOINS that session: every write commits or
|
|
936
|
+
* aborts with the host's order. MongoDB has no nested transactions, so
|
|
937
|
+
* we must NOT open our own in that case — the host owns commit/abort/
|
|
938
|
+
* retry. Without a host session we own the transaction via the
|
|
939
|
+
* UnitOfWork (mongokit retry semantics included).
|
|
940
|
+
*
|
|
941
|
+
* **Post-commit publish (§P8 phased variant).** When promo owns the
|
|
942
|
+
* transaction, a pending queue is attached to the tx context so every
|
|
943
|
+
* `dispatchPromoEvent` inside the body defers its transport publish; the
|
|
944
|
+
* queue flushes only after the transaction commits — a rollback (or a
|
|
945
|
+
* transient retry of the body) can't leak ghost events to in-process
|
|
946
|
+
* subscribers. The queue resets at the start of each retry attempt.
|
|
947
|
+
* When the HOST owns the session, promo can't know when the host
|
|
948
|
+
* commits: with a host-attached `[PENDING_PROMO_EVENTS]` queue the
|
|
949
|
+
* deferral still applies (host flushes); without one, publish happens
|
|
950
|
+
* in-scope as the documented best effort (see events/dispatch.ts).
|
|
951
|
+
*/
|
|
952
|
+
private runTransactional;
|
|
843
953
|
generateCodes(input: GenerateCodesInput, ctx: PromoContext): Promise<Voucher[]>;
|
|
844
954
|
generateSingleCode(input: GenerateSingleCodeInput, ctx: PromoContext): Promise<Voucher>;
|
|
845
955
|
validateCode(code: string, ctx: PromoContext): Promise<VoucherValidation>;
|
|
@@ -897,17 +1007,17 @@ declare class InMemoryEvaluationStore implements EvaluationStore {
|
|
|
897
1007
|
}
|
|
898
1008
|
//#endregion
|
|
899
1009
|
//#region src/domain/errors/base.d.ts
|
|
900
|
-
declare
|
|
901
|
-
|
|
902
|
-
|
|
1010
|
+
declare class PromoError extends Error implements HttpError {
|
|
1011
|
+
readonly code: string;
|
|
1012
|
+
readonly status: number;
|
|
1013
|
+
constructor(message: string, code: string, status: number);
|
|
903
1014
|
}
|
|
904
1015
|
//#endregion
|
|
905
1016
|
//#region src/domain/errors/domain-errors.d.ts
|
|
906
1017
|
declare class ValidationError extends PromoError {
|
|
907
|
-
|
|
1018
|
+
constructor(message: string);
|
|
908
1019
|
}
|
|
909
1020
|
declare class ProgramNotFoundError extends PromoError {
|
|
910
|
-
readonly code = "PROGRAM_NOT_FOUND";
|
|
911
1021
|
constructor(id?: string);
|
|
912
1022
|
}
|
|
913
1023
|
/**
|
|
@@ -920,31 +1030,24 @@ declare class ProgramNotFoundError extends PromoError {
|
|
|
920
1030
|
declare class ProgramUsageCapExceededError extends PromoError {
|
|
921
1031
|
readonly programId: string;
|
|
922
1032
|
readonly maxUsageTotal: number;
|
|
923
|
-
readonly code = "PROGRAM_USAGE_CAP_EXCEEDED";
|
|
924
1033
|
constructor(programId: string, maxUsageTotal: number);
|
|
925
1034
|
}
|
|
926
1035
|
declare class RuleNotFoundError extends PromoError {
|
|
927
|
-
readonly code = "RULE_NOT_FOUND";
|
|
928
1036
|
constructor(id?: string);
|
|
929
1037
|
}
|
|
930
1038
|
declare class RewardNotFoundError extends PromoError {
|
|
931
|
-
readonly code = "REWARD_NOT_FOUND";
|
|
932
1039
|
constructor(id?: string);
|
|
933
1040
|
}
|
|
934
1041
|
declare class VoucherNotFoundError extends PromoError {
|
|
935
|
-
readonly code = "VOUCHER_NOT_FOUND";
|
|
936
1042
|
constructor(codeOrId?: string);
|
|
937
1043
|
}
|
|
938
1044
|
declare class InvalidTransitionError extends PromoError {
|
|
939
|
-
readonly code = "INVALID_TRANSITION";
|
|
940
1045
|
constructor(from: string, to: string);
|
|
941
1046
|
}
|
|
942
1047
|
declare class VoucherExpiredError extends PromoError {
|
|
943
|
-
readonly code = "VOUCHER_EXPIRED";
|
|
944
1048
|
constructor(code: string);
|
|
945
1049
|
}
|
|
946
1050
|
declare class VoucherExhaustedError extends PromoError {
|
|
947
|
-
readonly code = "VOUCHER_EXHAUSTED";
|
|
948
1051
|
constructor(code: string);
|
|
949
1052
|
}
|
|
950
1053
|
/**
|
|
@@ -954,7 +1057,6 @@ declare class VoucherExhaustedError extends PromoError {
|
|
|
954
1057
|
* later" messaging.
|
|
955
1058
|
*/
|
|
956
1059
|
declare class GiftCardExhaustedError extends PromoError {
|
|
957
|
-
readonly code = "GIFT_CARD_EXHAUSTED";
|
|
958
1060
|
constructor(code: string);
|
|
959
1061
|
}
|
|
960
1062
|
/**
|
|
@@ -967,24 +1069,28 @@ declare class ConcurrencyConflictError extends PromoError {
|
|
|
967
1069
|
readonly resource: 'voucher' | 'program' | 'rule' | 'reward';
|
|
968
1070
|
readonly resourceId: string;
|
|
969
1071
|
readonly cause?: unknown | undefined;
|
|
970
|
-
readonly code = "CONCURRENCY_CONFLICT";
|
|
971
|
-
readonly status = 409;
|
|
972
1072
|
constructor(resource: 'voucher' | 'program' | 'rule' | 'reward', resourceId: string, cause?: unknown | undefined);
|
|
973
1073
|
}
|
|
974
1074
|
declare class InsufficientBalanceError extends PromoError {
|
|
975
|
-
readonly code = "INSUFFICIENT_BALANCE";
|
|
976
1075
|
constructor(code: string, available: number, requested: number);
|
|
977
1076
|
}
|
|
978
1077
|
declare class TenantIsolationError extends PromoError {
|
|
979
|
-
readonly code = "TENANT_ISOLATION";
|
|
980
1078
|
constructor();
|
|
981
1079
|
}
|
|
982
1080
|
declare class DuplicateRedemptionError extends PromoError {
|
|
983
|
-
readonly code = "DUPLICATE_REDEMPTION";
|
|
984
1081
|
constructor(key: string);
|
|
985
1082
|
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Residual E11000 on the voucher `code` unique index, classified via
|
|
1085
|
+
* mongokit's `isDuplicateKeyError` and re-thrown as this typed shape
|
|
1086
|
+
* (Concurrency House Rules: "typed collision errors are the contract;
|
|
1087
|
+
* the unique index is the authoritative guard"). Realistic path:
|
|
1088
|
+
* `generateSingleCode` with a caller-supplied code that already exists.
|
|
1089
|
+
*/
|
|
1090
|
+
declare class DuplicateVoucherCodeError extends PromoError {
|
|
1091
|
+
constructor(code?: string);
|
|
1092
|
+
}
|
|
986
1093
|
declare class EvaluationNotFoundError extends PromoError {
|
|
987
|
-
readonly code = "EVALUATION_NOT_FOUND";
|
|
988
1094
|
constructor(id: string);
|
|
989
1095
|
}
|
|
990
1096
|
/**
|
|
@@ -995,9 +1101,18 @@ declare class EvaluationNotFoundError extends PromoError {
|
|
|
995
1101
|
* tries to apply the stale discount to the altered order.
|
|
996
1102
|
*/
|
|
997
1103
|
declare class CartHashMismatchError extends PromoError {
|
|
998
|
-
readonly code = "CART_HASH_MISMATCH";
|
|
999
1104
|
constructor(evaluationId: string);
|
|
1000
1105
|
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Thrown by `createModels` when a Mongoose model with one of promo's names
|
|
1108
|
+
* is already registered on the connection (rule 21). Silent `deleteModel`
|
|
1109
|
+
* would clobber another engine's models; the throw makes the collision
|
|
1110
|
+
* loud. Hot-reload / test fixtures opt in via `forceRecreate: true`; two
|
|
1111
|
+
* promo engines in one process need two Mongoose connections.
|
|
1112
|
+
*/
|
|
1113
|
+
declare class PromoModelCollisionError extends PromoError {
|
|
1114
|
+
constructor(modelName: string);
|
|
1115
|
+
}
|
|
1001
1116
|
//#endregion
|
|
1002
1117
|
//#region src/events/event-constants.d.ts
|
|
1003
1118
|
declare const PromoEvents: {
|
|
@@ -1031,237 +1146,20 @@ interface InProcessPromoBusOptions {
|
|
|
1031
1146
|
};
|
|
1032
1147
|
}
|
|
1033
1148
|
//#endregion
|
|
1034
|
-
//#region src/events/promo-event-catalog.d.ts
|
|
1035
|
-
interface PromoEventSchema {
|
|
1036
|
-
type: 'object';
|
|
1037
|
-
properties?: Record<string, {
|
|
1038
|
-
type?: string;
|
|
1039
|
-
format?: string;
|
|
1040
|
-
[key: string]: unknown;
|
|
1041
|
-
}>;
|
|
1042
|
-
required?: string[];
|
|
1043
|
-
[key: string]: unknown;
|
|
1044
|
-
}
|
|
1045
|
-
interface PromoEventDefinition<TSchema extends z.ZodType = z.ZodType> {
|
|
1046
|
-
readonly name: string;
|
|
1047
|
-
readonly version: number;
|
|
1048
|
-
readonly description?: string;
|
|
1049
|
-
readonly schema: PromoEventSchema;
|
|
1050
|
-
readonly zodSchema: TSchema;
|
|
1051
|
-
create(payload: z.infer<TSchema>, meta?: Partial<DomainEvent$1['meta']>): DomainEvent$1<z.infer<TSchema>>;
|
|
1052
|
-
readonly __payload?: z.infer<TSchema>;
|
|
1053
|
-
}
|
|
1054
|
-
type PromoEventPayloadOf<D> = D extends PromoEventDefinition<infer S> ? z.infer<S> : never;
|
|
1055
|
-
/** Mirrors `ProgramLifecyclePayload`. */
|
|
1056
|
-
declare const programLifecycleSchema: z.ZodObject<{
|
|
1057
|
-
programId: z.ZodString;
|
|
1058
|
-
programType: z.ZodString;
|
|
1059
|
-
status: z.ZodString;
|
|
1060
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1061
|
-
}, z.core.$strip>;
|
|
1062
|
-
/** Mirrors `RulePayload`. */
|
|
1063
|
-
declare const ruleSchema: z.ZodObject<{
|
|
1064
|
-
programId: z.ZodString;
|
|
1065
|
-
ruleId: z.ZodString;
|
|
1066
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1067
|
-
}, z.core.$strip>;
|
|
1068
|
-
/** Mirrors `RewardPayload`. */
|
|
1069
|
-
declare const rewardSchema: z.ZodObject<{
|
|
1070
|
-
programId: z.ZodString;
|
|
1071
|
-
rewardId: z.ZodString;
|
|
1072
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1073
|
-
}, z.core.$strip>;
|
|
1074
|
-
/** Mirrors `VoucherGeneratedPayload`. */
|
|
1075
|
-
declare const voucherGeneratedSchema: z.ZodObject<{
|
|
1076
|
-
programId: z.ZodString;
|
|
1077
|
-
voucherIds: z.ZodArray<z.ZodString>;
|
|
1078
|
-
codes: z.ZodArray<z.ZodString>;
|
|
1079
|
-
count: z.ZodNumber;
|
|
1080
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1081
|
-
}, z.core.$strip>;
|
|
1082
|
-
/** Mirrors `VoucherRedeemedPayload`. */
|
|
1083
|
-
declare const voucherRedeemedSchema: z.ZodObject<{
|
|
1084
|
-
voucherId: z.ZodString;
|
|
1085
|
-
code: z.ZodString;
|
|
1086
|
-
orderId: z.ZodString;
|
|
1087
|
-
discountAmount: z.ZodNumber;
|
|
1088
|
-
customerId: z.ZodOptional<z.ZodString>;
|
|
1089
|
-
}, z.core.$strip>;
|
|
1090
|
-
/**
|
|
1091
|
-
* Mirrors `VoucherLifecyclePayload` — shared by VOUCHER_CANCELLED,
|
|
1092
|
-
* VOUCHER_EXPIRED, and GIFT_CARD_EXHAUSTED (repo emits `status: 'cancelled'`
|
|
1093
|
-
* / `'used'` / host-supplied terminal value).
|
|
1094
|
-
*/
|
|
1095
|
-
declare const voucherLifecycleSchema: z.ZodObject<{
|
|
1096
|
-
voucherId: z.ZodString;
|
|
1097
|
-
code: z.ZodString;
|
|
1098
|
-
status: z.ZodString;
|
|
1099
|
-
}, z.core.$strip>;
|
|
1100
|
-
/** Mirrors `GiftCardSpentPayload`. */
|
|
1101
|
-
declare const giftCardSpentSchema: z.ZodObject<{
|
|
1102
|
-
voucherId: z.ZodString;
|
|
1103
|
-
code: z.ZodString;
|
|
1104
|
-
amount: z.ZodNumber;
|
|
1105
|
-
remainingBalance: z.ZodNumber;
|
|
1106
|
-
orderId: z.ZodString;
|
|
1107
|
-
}, z.core.$strip>;
|
|
1108
|
-
/** Mirrors `GiftCardToppedUpPayload`. */
|
|
1109
|
-
declare const giftCardToppedUpSchema: z.ZodObject<{
|
|
1110
|
-
voucherId: z.ZodString;
|
|
1111
|
-
code: z.ZodString;
|
|
1112
|
-
amount: z.ZodNumber;
|
|
1113
|
-
newBalance: z.ZodNumber;
|
|
1114
|
-
}, z.core.$strip>;
|
|
1115
|
-
/** Mirrors `EvaluationCompletedPayload`. */
|
|
1116
|
-
declare const evaluationCompletedSchema: z.ZodObject<{
|
|
1117
|
-
evaluationId: z.ZodString;
|
|
1118
|
-
totalDiscount: z.ZodNumber;
|
|
1119
|
-
programsApplied: z.ZodNumber;
|
|
1120
|
-
codesUsed: z.ZodArray<z.ZodString>;
|
|
1121
|
-
isPreview: z.ZodBoolean;
|
|
1122
|
-
}, z.core.$strip>;
|
|
1123
|
-
/** Mirrors `EvaluationCommittedPayload`. */
|
|
1124
|
-
declare const evaluationCommittedSchema: z.ZodObject<{
|
|
1125
|
-
evaluationId: z.ZodString;
|
|
1126
|
-
orderId: z.ZodString;
|
|
1127
|
-
totalDiscount: z.ZodNumber;
|
|
1128
|
-
}, z.core.$strip>;
|
|
1129
|
-
/** Single-field rollback payload — emitted by `evaluation.service.ts`. */
|
|
1130
|
-
declare const evaluationRolledBackSchema: z.ZodObject<{
|
|
1131
|
-
evaluationId: z.ZodString;
|
|
1132
|
-
}, z.core.$strip>;
|
|
1133
|
-
type ProgramLifecyclePayloadSchema = z.infer<typeof programLifecycleSchema>;
|
|
1134
|
-
type RulePayloadSchema = z.infer<typeof ruleSchema>;
|
|
1135
|
-
type RewardPayloadSchema = z.infer<typeof rewardSchema>;
|
|
1136
|
-
type VoucherGeneratedPayloadSchema = z.infer<typeof voucherGeneratedSchema>;
|
|
1137
|
-
type VoucherRedeemedPayloadSchema = z.infer<typeof voucherRedeemedSchema>;
|
|
1138
|
-
type VoucherLifecyclePayloadSchema = z.infer<typeof voucherLifecycleSchema>;
|
|
1139
|
-
type GiftCardSpentPayloadSchema = z.infer<typeof giftCardSpentSchema>;
|
|
1140
|
-
type GiftCardToppedUpPayloadSchema = z.infer<typeof giftCardToppedUpSchema>;
|
|
1141
|
-
type EvaluationCompletedPayloadSchema = z.infer<typeof evaluationCompletedSchema>;
|
|
1142
|
-
type EvaluationCommittedPayloadSchema = z.infer<typeof evaluationCommittedSchema>;
|
|
1143
|
-
type EvaluationRolledBackPayloadSchema = z.infer<typeof evaluationRolledBackSchema>;
|
|
1144
|
-
declare const ProgramCreated: PromoEventDefinition<z.ZodObject<{
|
|
1145
|
-
programId: z.ZodString;
|
|
1146
|
-
programType: z.ZodString;
|
|
1147
|
-
status: z.ZodString;
|
|
1148
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1149
|
-
}, z.core.$strip>>;
|
|
1150
|
-
declare const ProgramActivated: PromoEventDefinition<z.ZodObject<{
|
|
1151
|
-
programId: z.ZodString;
|
|
1152
|
-
programType: z.ZodString;
|
|
1153
|
-
status: z.ZodString;
|
|
1154
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1155
|
-
}, z.core.$strip>>;
|
|
1156
|
-
declare const ProgramPaused: PromoEventDefinition<z.ZodObject<{
|
|
1157
|
-
programId: z.ZodString;
|
|
1158
|
-
programType: z.ZodString;
|
|
1159
|
-
status: z.ZodString;
|
|
1160
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1161
|
-
}, z.core.$strip>>;
|
|
1162
|
-
declare const ProgramArchived: PromoEventDefinition<z.ZodObject<{
|
|
1163
|
-
programId: z.ZodString;
|
|
1164
|
-
programType: z.ZodString;
|
|
1165
|
-
status: z.ZodString;
|
|
1166
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1167
|
-
}, z.core.$strip>>;
|
|
1168
|
-
declare const RuleAdded: PromoEventDefinition<z.ZodObject<{
|
|
1169
|
-
programId: z.ZodString;
|
|
1170
|
-
ruleId: z.ZodString;
|
|
1171
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1172
|
-
}, z.core.$strip>>;
|
|
1173
|
-
declare const RuleUpdated: PromoEventDefinition<z.ZodObject<{
|
|
1174
|
-
programId: z.ZodString;
|
|
1175
|
-
ruleId: z.ZodString;
|
|
1176
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1177
|
-
}, z.core.$strip>>;
|
|
1178
|
-
declare const RuleRemoved: PromoEventDefinition<z.ZodObject<{
|
|
1179
|
-
programId: z.ZodString;
|
|
1180
|
-
ruleId: z.ZodString;
|
|
1181
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1182
|
-
}, z.core.$strip>>;
|
|
1183
|
-
declare const RewardAdded: PromoEventDefinition<z.ZodObject<{
|
|
1184
|
-
programId: z.ZodString;
|
|
1185
|
-
rewardId: z.ZodString;
|
|
1186
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1187
|
-
}, z.core.$strip>>;
|
|
1188
|
-
declare const RewardUpdated: PromoEventDefinition<z.ZodObject<{
|
|
1189
|
-
programId: z.ZodString;
|
|
1190
|
-
rewardId: z.ZodString;
|
|
1191
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1192
|
-
}, z.core.$strip>>;
|
|
1193
|
-
declare const RewardRemoved: PromoEventDefinition<z.ZodObject<{
|
|
1194
|
-
programId: z.ZodString;
|
|
1195
|
-
rewardId: z.ZodString;
|
|
1196
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1197
|
-
}, z.core.$strip>>;
|
|
1198
|
-
declare const VoucherGenerated: PromoEventDefinition<z.ZodObject<{
|
|
1199
|
-
programId: z.ZodString;
|
|
1200
|
-
voucherIds: z.ZodArray<z.ZodString>;
|
|
1201
|
-
codes: z.ZodArray<z.ZodString>;
|
|
1202
|
-
count: z.ZodNumber;
|
|
1203
|
-
actorId: z.ZodOptional<z.ZodString>;
|
|
1204
|
-
}, z.core.$strip>>;
|
|
1205
|
-
declare const VoucherRedeemed: PromoEventDefinition<z.ZodObject<{
|
|
1206
|
-
voucherId: z.ZodString;
|
|
1207
|
-
code: z.ZodString;
|
|
1208
|
-
orderId: z.ZodString;
|
|
1209
|
-
discountAmount: z.ZodNumber;
|
|
1210
|
-
customerId: z.ZodOptional<z.ZodString>;
|
|
1211
|
-
}, z.core.$strip>>;
|
|
1212
|
-
declare const VoucherCancelled: PromoEventDefinition<z.ZodObject<{
|
|
1213
|
-
voucherId: z.ZodString;
|
|
1214
|
-
code: z.ZodString;
|
|
1215
|
-
status: z.ZodString;
|
|
1216
|
-
}, z.core.$strip>>;
|
|
1217
|
-
declare const VoucherExpired: PromoEventDefinition<z.ZodObject<{
|
|
1218
|
-
voucherId: z.ZodString;
|
|
1219
|
-
code: z.ZodString;
|
|
1220
|
-
status: z.ZodString;
|
|
1221
|
-
}, z.core.$strip>>;
|
|
1222
|
-
declare const GiftCardSpent: PromoEventDefinition<z.ZodObject<{
|
|
1223
|
-
voucherId: z.ZodString;
|
|
1224
|
-
code: z.ZodString;
|
|
1225
|
-
amount: z.ZodNumber;
|
|
1226
|
-
remainingBalance: z.ZodNumber;
|
|
1227
|
-
orderId: z.ZodString;
|
|
1228
|
-
}, z.core.$strip>>;
|
|
1229
|
-
declare const GiftCardToppedUp: PromoEventDefinition<z.ZodObject<{
|
|
1230
|
-
voucherId: z.ZodString;
|
|
1231
|
-
code: z.ZodString;
|
|
1232
|
-
amount: z.ZodNumber;
|
|
1233
|
-
newBalance: z.ZodNumber;
|
|
1234
|
-
}, z.core.$strip>>;
|
|
1235
|
-
declare const GiftCardExhausted: PromoEventDefinition<z.ZodObject<{
|
|
1236
|
-
voucherId: z.ZodString;
|
|
1237
|
-
code: z.ZodString;
|
|
1238
|
-
status: z.ZodString;
|
|
1239
|
-
}, z.core.$strip>>;
|
|
1240
|
-
declare const EvaluationCompleted: PromoEventDefinition<z.ZodObject<{
|
|
1241
|
-
evaluationId: z.ZodString;
|
|
1242
|
-
totalDiscount: z.ZodNumber;
|
|
1243
|
-
programsApplied: z.ZodNumber;
|
|
1244
|
-
codesUsed: z.ZodArray<z.ZodString>;
|
|
1245
|
-
isPreview: z.ZodBoolean;
|
|
1246
|
-
}, z.core.$strip>>;
|
|
1247
|
-
declare const EvaluationCommitted: PromoEventDefinition<z.ZodObject<{
|
|
1248
|
-
evaluationId: z.ZodString;
|
|
1249
|
-
orderId: z.ZodString;
|
|
1250
|
-
totalDiscount: z.ZodNumber;
|
|
1251
|
-
}, z.core.$strip>>;
|
|
1252
|
-
declare const EvaluationRolledBack: PromoEventDefinition<z.ZodObject<{
|
|
1253
|
-
evaluationId: z.ZodString;
|
|
1254
|
-
}, z.core.$strip>>;
|
|
1255
|
-
/**
|
|
1256
|
-
* Every promo event defined in the package — pass to Arc's
|
|
1257
|
-
* `EventRegistry`. Hosts wire ONE array; the whole `promo.*` namespace
|
|
1258
|
-
* becomes introspectable via OpenAPI and auto-validated at publish time
|
|
1259
|
-
* when `eventPlugin({ validateMode: 'reject' })` is set.
|
|
1260
|
-
*/
|
|
1261
|
-
declare const promoEventDefinitions: ReadonlyArray<PromoEventDefinition>;
|
|
1262
|
-
//#endregion
|
|
1263
1149
|
//#region src/index.d.ts
|
|
1264
1150
|
declare function resolveConfig(config: PromoConfig): ResolvedConfig;
|
|
1151
|
+
/**
|
|
1152
|
+
* Boot-time capability gate (PACKAGE_RULES "Runtime capabilities").
|
|
1153
|
+
* commit / redeem / spend / topUp are transactional — assert the backend
|
|
1154
|
+
* declares `transactions` at engine creation so misconfigured deployments
|
|
1155
|
+
* fail loud at boot instead of with a cryptic error on the first checkout.
|
|
1156
|
+
* `allowNonTransactional: true` is the explicit opt-out for standalone
|
|
1157
|
+
* MongoDB (dev / CI) — the unit-of-work then falls back to
|
|
1158
|
+
* non-transactional execution.
|
|
1159
|
+
*
|
|
1160
|
+
* Exported for unit testing; hosts never call it directly.
|
|
1161
|
+
*/
|
|
1162
|
+
declare function assertPromoCapabilities(capabilities: Record<string, unknown> | undefined): void;
|
|
1265
1163
|
interface PromoEngine {
|
|
1266
1164
|
models: PromoModels;
|
|
1267
1165
|
repositories: PromoRepositories;
|
|
@@ -1308,4 +1206,4 @@ interface PromoEngine {
|
|
|
1308
1206
|
*/
|
|
1309
1207
|
declare function createPromoEngine(config: PromoConfig): PromoEngine;
|
|
1310
1208
|
//#endregion
|
|
1311
|
-
export { type BalanceLedgerEntry, CartHashMismatchError, type CartItem, type CommitOptions, type CommitResult, ConcurrencyConflictError, type CreateProgramInput, type CreateRewardInput, type CreateRuleInput, type DiscountLine, type DomainEvent, DuplicateRedemptionError, type EvaluateInput, EvaluationCommitted, type EvaluationCommittedPayloadSchema, EvaluationCompleted, type EvaluationCompletedPayloadSchema, EvaluationNotFoundError, type EvaluationResult, EvaluationRolledBack, type EvaluationRolledBackPayloadSchema, type EvaluationStore, type EvaluationStoreContext, type EventHandler, type EventTransport, type FreeProductLine, type GenerateCodesInput, type GenerateSingleCodeInput, type GiftCardBalance, GiftCardExhausted, GiftCardExhaustedError, type GiftCardSpendInput, GiftCardSpent, type GiftCardSpentPayloadSchema, type GiftCardTopUpInput, GiftCardToppedUp, type GiftCardToppedUpPayloadSchema, InMemoryEvaluationStore, type InProcessPromoBusOptions, InsufficientBalanceError, InvalidTransitionError, type ListQuery, MongoEvaluationStore, type PaginatedResult, type PendingEvaluationDocument, PendingEvaluationRepository, type PluginType, type Program, ProgramActivated, ProgramArchived, ProgramCreated, type ProgramLifecyclePayloadSchema, ProgramNotFoundError, ProgramPaused, ProgramRepository, ProgramUsageCapExceededError, type PromoConfig, type PromoContext, PromoEngine, PromoError, type PromoEventDefinition, type PromoEventName, type PromoEventPayloadOf, type PromoEventSchema, PromoEvents, type PromoModels, type PromoRepositories, type PromoServices, type RedeemVoucherInput, type RejectedCode, type RepositoryDispatchDeps, type RepositoryPluginsMap, type ResolvedConfig, type ResolvedTenant, type Reward, RewardAdded, RewardNotFoundError, type RewardPayloadSchema, RewardRemoved, RewardRepository, RewardUpdated, type Rule, RuleAdded, RuleNotFoundError, type RulePayloadSchema, RuleRemoved, RuleRepository, RuleUpdated, type StoredEvaluationSnapshot, type TenantFieldType, TenantIsolationError, type UpdateProgramInput, type UpdateRewardInput, type UpdateRuleInput, ValidationError, type Voucher, VoucherCancelled, VoucherExhaustedError, VoucherExpired, VoucherExpiredError, VoucherGenerated, type VoucherGeneratedPayloadSchema, type VoucherLifecyclePayloadSchema, VoucherNotFoundError, VoucherRedeemed, type VoucherRedeemedPayloadSchema, type VoucherRedemption, VoucherRepository, type VoucherValidation, createPromoEngine, promoEventDefinitions, resolveConfig };
|
|
1209
|
+
export { type BalanceLedgerEntry, CartHashMismatchError, type CartItem, type CommitOptions, type CommitResult, ConcurrencyConflictError, type CreateProgramInput, type CreateRewardInput, type CreateRuleInput, DEFAULT_COLLECTIONS, type DiscountLine, type DispatchDeps, type DispatchLogger, type DomainEvent, DuplicateRedemptionError, DuplicateVoucherCodeError, type EvaluateInput, EvaluationCommitted, type EvaluationCommittedPayloadSchema, EvaluationCompleted, type EvaluationCompletedPayloadSchema, EvaluationNotFoundError, type EvaluationResult, EvaluationRolledBack, type EvaluationRolledBackPayloadSchema, type EvaluationStore, type EvaluationStoreContext, type EventHandler, type EventTransport, type FreeProductLine, type GenerateCodesInput, type GenerateSingleCodeInput, type GiftCardBalance, GiftCardExhausted, GiftCardExhaustedError, type GiftCardSpendInput, GiftCardSpent, type GiftCardSpentPayloadSchema, type GiftCardTopUpInput, GiftCardToppedUp, type GiftCardToppedUpPayloadSchema, InMemoryEvaluationStore, type InProcessPromoBusOptions, InsufficientBalanceError, InvalidTransitionError, type ListQuery, MongoEvaluationStore, PENDING_PROMO_EVENTS, type PaginatedResult, type PendingEvaluationDocument, PendingEvaluationRepository, type PluginType, type Program, ProgramActivated, ProgramArchived, ProgramCreated, type ProgramLifecyclePayloadSchema, ProgramNotFoundError, ProgramPaused, ProgramRepository, ProgramUsageCapExceededError, type PromoConfig, type PromoContext, PromoEngine, PromoError, type PromoEventDefinition, type PromoEventName, type PromoEventPayloadOf, type PromoEventSchema, PromoEvents, PromoModelCollisionError, type PromoModels, type PromoRepositories, type PromoServices, type RedeemVoucherInput, type RejectedCode, type RepositoryDispatchDeps, type RepositoryPluginsMap, type ResolvedConfig, type ResolvedTenant, type Reward, RewardAdded, RewardNotFoundError, type RewardPayloadSchema, RewardRemoved, RewardRepository, RewardUpdated, type Rule, RuleAdded, RuleNotFoundError, type RulePayloadSchema, RuleRemoved, RuleRepository, RuleUpdated, type StoredEvaluationSnapshot, type TenantFieldType, TenantIsolationError, type UpdateProgramInput, type UpdateRewardInput, type UpdateRuleInput, ValidationError, type Voucher, VoucherCancelled, VoucherExhaustedError, VoucherExpired, VoucherExpiredError, VoucherGenerated, type VoucherGeneratedPayloadSchema, type VoucherLifecyclePayloadSchema, VoucherNotFoundError, VoucherRedeemed, type VoucherRedeemedPayloadSchema, type VoucherRedemption, VoucherRepository, type VoucherValidation, assertPromoCapabilities, createPromoEngine, flushPendingPromoEvents, promoEventDefinitions, resolveConfig };
|