@classytic/loyalty 0.1.0 → 0.2.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 +68 -0
- package/dist/config-JYTMP1F7.d.mts +136 -0
- package/dist/{constants-C75GvizO.mjs → constants-DkQYkOK1.mjs} +3 -2
- package/dist/domain/enums/index.d.mts +1 -1
- package/dist/domain/enums/index.mjs +1 -1
- package/dist/events/index.d.mts +2 -2
- package/dist/events/index.mjs +3 -3
- package/dist/events-BjzHSLBn.mjs +344 -0
- package/dist/index-2izQQext.d.mts +281 -0
- package/dist/index-BmqGuj38.d.mts +400 -0
- package/dist/{index-CaH4GhSF.d.mts → index-DMK8a98J.d.mts} +1 -1
- package/dist/index-qI1WvtNg.d.mts +361 -0
- package/dist/index.d.mts +28 -12
- package/dist/index.mjs +30 -26
- package/dist/loyalty-events-Cyt9TwX6.mjs +50 -0
- package/dist/models/index.d.mts +1225 -2
- package/dist/models/index.mjs +2 -2
- package/dist/{models-CrZPmVxt.mjs → models-uhh9c-7k.mjs} +104 -41
- package/dist/notifications/index.d.mts +1 -1
- package/dist/repositories/index.d.mts +2 -2
- package/dist/repositories/index.mjs +1 -1
- package/dist/repositories-ObGUgcSH.mjs +1917 -0
- package/dist/types/index.d.mts +2 -2
- package/package.json +18 -16
- package/dist/config-aNigy4ec.d.mts +0 -90
- package/dist/domain/index.d.mts +0 -90
- package/dist/domain/index.mjs +0 -4
- package/dist/domain-errors-D7q-2LYD.mjs +0 -120
- package/dist/event-emitter.port-CLYPoMni.d.mts +0 -8
- package/dist/event-types-xQBtYBbX.mjs +0 -24
- package/dist/events-CprEWlN7.mjs +0 -25
- package/dist/index-B6ZstxSP.d.mts +0 -2357
- package/dist/index-BcoGeDco.d.mts +0 -127
- package/dist/index-DqzTjeEB.d.mts +0 -148
- package/dist/index-O7TL4R2P.d.mts +0 -86
- package/dist/index-_pg4J11t.d.mts +0 -191
- package/dist/repositories-qMX7Xh_y.mjs +0 -440
- package/dist/services/index.d.mts +0 -2
- package/dist/services/index.mjs +0 -2
- package/dist/services-CoTqC4E6.mjs +0 -1098
- package/dist/tier-definition-Djf72UPa.d.mts +0 -120
- package/dist/tier-definition.port-BzrHYBRo.d.mts +0 -143
- /package/dist/{notification.port-BzUsH0It.d.mts → notification.port-9B5xlzxQ.d.mts} +0 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { a as RuleStatus, n as MemberStatus, o as RuleType, s as TransactionType } from "./index-DMK8a98J.mjs";
|
|
2
|
+
import { OperationContext } from "@classytic/primitives/context";
|
|
3
|
+
|
|
4
|
+
//#region src/domain/entities/earning-rule.d.ts
|
|
5
|
+
interface EarningConditions {
|
|
6
|
+
minOrderAmount?: number;
|
|
7
|
+
categories?: string[];
|
|
8
|
+
tiers?: string[];
|
|
9
|
+
actions?: string[];
|
|
10
|
+
dayOfWeek?: number[];
|
|
11
|
+
dateRange?: {
|
|
12
|
+
start?: Date;
|
|
13
|
+
end?: Date;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
interface EarningReward {
|
|
17
|
+
pointsPerAmount?: number;
|
|
18
|
+
amountPerPoint?: number;
|
|
19
|
+
fixedPoints?: number;
|
|
20
|
+
multiplier?: number;
|
|
21
|
+
roundingMode?: 'floor' | 'round' | 'ceil';
|
|
22
|
+
maxPointsPerTransaction?: number;
|
|
23
|
+
}
|
|
24
|
+
interface EarningRule {
|
|
25
|
+
_id: string;
|
|
26
|
+
programId: string;
|
|
27
|
+
name: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
type: RuleType;
|
|
30
|
+
status: RuleStatus;
|
|
31
|
+
priority: number;
|
|
32
|
+
conditions: EarningConditions;
|
|
33
|
+
reward: EarningReward;
|
|
34
|
+
startsAt?: Date;
|
|
35
|
+
endsAt?: Date;
|
|
36
|
+
metadata?: Record<string, unknown>;
|
|
37
|
+
createdAt: Date;
|
|
38
|
+
updatedAt: Date;
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/domain/entities/tier-definition.d.ts
|
|
42
|
+
interface TierQualification {
|
|
43
|
+
minLifetimePoints?: number;
|
|
44
|
+
minLifetimeSpend?: number;
|
|
45
|
+
evaluationPeriodDays?: number;
|
|
46
|
+
}
|
|
47
|
+
interface TierBenefits {
|
|
48
|
+
pointsMultiplier?: number;
|
|
49
|
+
discountPercent?: number;
|
|
50
|
+
freeShipping?: boolean;
|
|
51
|
+
customBenefits?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
interface TierDowngrade {
|
|
54
|
+
enabled: boolean;
|
|
55
|
+
gracePeriodDays: number;
|
|
56
|
+
}
|
|
57
|
+
interface TierDefinition {
|
|
58
|
+
_id: string;
|
|
59
|
+
programId: string;
|
|
60
|
+
name: string;
|
|
61
|
+
rank: number;
|
|
62
|
+
qualificationCriteria: TierQualification;
|
|
63
|
+
benefits: TierBenefits;
|
|
64
|
+
downgrade: TierDowngrade;
|
|
65
|
+
color?: string;
|
|
66
|
+
metadata?: Record<string, unknown>;
|
|
67
|
+
createdAt: Date;
|
|
68
|
+
updatedAt: Date;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/domain/entities/member.d.ts
|
|
72
|
+
interface MemberBalance {
|
|
73
|
+
current: number;
|
|
74
|
+
lifetime: number;
|
|
75
|
+
redeemed: number;
|
|
76
|
+
expired: number;
|
|
77
|
+
}
|
|
78
|
+
interface Member {
|
|
79
|
+
_id: string;
|
|
80
|
+
programId: string;
|
|
81
|
+
externalId: string;
|
|
82
|
+
externalType: string;
|
|
83
|
+
status: MemberStatus;
|
|
84
|
+
/** Public loyalty card identifier (e.g., MBR-DHK-00004821-8). Set by the integration layer. */
|
|
85
|
+
cardId?: string;
|
|
86
|
+
/** Referral code for the referral system (separate from cardId). Auto-generated on enrollment. */
|
|
87
|
+
referralCode: string;
|
|
88
|
+
tier: string | null;
|
|
89
|
+
tierOverride: string | null;
|
|
90
|
+
tierOverrideReason?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Optional TTL on a manual tier override. When set, `evaluateMember`
|
|
93
|
+
* treats the override as already cleared once `tierOverrideExpiresAt <=
|
|
94
|
+
* now`, and a host-scheduled `sweepExpiredOverrides` cron clears the
|
|
95
|
+
* field + emits a `TIER_OVERRIDE_EXPIRED` audit event.
|
|
96
|
+
*/
|
|
97
|
+
tierOverrideExpiresAt?: Date;
|
|
98
|
+
/** Optional upstream referrer for multi-tier referral chains. */
|
|
99
|
+
referredBy?: string;
|
|
100
|
+
tierQualifiedAt?: Date;
|
|
101
|
+
tierExpiresAt?: Date;
|
|
102
|
+
balance: MemberBalance;
|
|
103
|
+
enrolledAt: Date;
|
|
104
|
+
deactivatedAt?: Date;
|
|
105
|
+
metadata?: Record<string, unknown>;
|
|
106
|
+
createdAt: Date;
|
|
107
|
+
updatedAt: Date;
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/domain/entities/point-transaction.d.ts
|
|
111
|
+
interface PointTransaction {
|
|
112
|
+
_id: string;
|
|
113
|
+
memberId: string;
|
|
114
|
+
programId: string;
|
|
115
|
+
type: TransactionType;
|
|
116
|
+
points: number;
|
|
117
|
+
balanceAfter: number;
|
|
118
|
+
description: string;
|
|
119
|
+
referenceType?: string;
|
|
120
|
+
referenceId?: string;
|
|
121
|
+
idempotencyKey?: string;
|
|
122
|
+
earningRuleId?: string;
|
|
123
|
+
expiresAt?: Date;
|
|
124
|
+
expiredAt?: Date;
|
|
125
|
+
metadata?: Record<string, unknown>;
|
|
126
|
+
actorId: string;
|
|
127
|
+
createdAt: Date;
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region src/types/results.d.ts
|
|
131
|
+
interface BalanceSummary extends MemberBalance {
|
|
132
|
+
tier: string | null;
|
|
133
|
+
tierOverride: string | null;
|
|
134
|
+
}
|
|
135
|
+
interface EarningBreakdown {
|
|
136
|
+
ruleId: string;
|
|
137
|
+
ruleName: string;
|
|
138
|
+
points: number;
|
|
139
|
+
}
|
|
140
|
+
interface EarningResult {
|
|
141
|
+
totalPoints: number;
|
|
142
|
+
breakdown: EarningBreakdown[];
|
|
143
|
+
transactions: PointTransaction[];
|
|
144
|
+
}
|
|
145
|
+
interface TierEvaluation {
|
|
146
|
+
memberId: string;
|
|
147
|
+
previousTier: string | null;
|
|
148
|
+
newTier: string | null;
|
|
149
|
+
action: 'upgraded' | 'downgraded' | 'grace_period' | 'unchanged';
|
|
150
|
+
graceExpiresAt?: Date;
|
|
151
|
+
}
|
|
152
|
+
interface TierEvaluationBatch {
|
|
153
|
+
upgraded: number;
|
|
154
|
+
downgraded: number;
|
|
155
|
+
unchanged: number;
|
|
156
|
+
}
|
|
157
|
+
interface RedemptionValidation {
|
|
158
|
+
valid: boolean;
|
|
159
|
+
error?: string;
|
|
160
|
+
pointsToRedeem: number;
|
|
161
|
+
discountAmount: number;
|
|
162
|
+
maxAllowedPoints: number;
|
|
163
|
+
}
|
|
164
|
+
interface ExpirationResult {
|
|
165
|
+
membersAffected: number;
|
|
166
|
+
pointsExpired: number;
|
|
167
|
+
transactionCount: number;
|
|
168
|
+
}
|
|
169
|
+
interface PaginatedResult<T> {
|
|
170
|
+
docs: T[];
|
|
171
|
+
total: number;
|
|
172
|
+
page: number;
|
|
173
|
+
pages: number;
|
|
174
|
+
hasNext: boolean;
|
|
175
|
+
hasPrev: boolean;
|
|
176
|
+
}
|
|
177
|
+
interface ListQuery {
|
|
178
|
+
page?: number;
|
|
179
|
+
limit?: number;
|
|
180
|
+
sort?: Record<string, 1 | -1>;
|
|
181
|
+
}
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region src/types/index.d.ts
|
|
184
|
+
/**
|
|
185
|
+
* Context passed to every loyalty operation.
|
|
186
|
+
*
|
|
187
|
+
* The tenant key is dynamic — if you configured `tenant: { field: 'companyId', contextKey: 'companyId' }`,
|
|
188
|
+
* pass `{ companyId: '...' }` in the context. The `[key: string]: unknown` index allows this.
|
|
189
|
+
*
|
|
190
|
+
* For the default config (`tenant: true` or `tenant: undefined`), pass `organizationId`.
|
|
191
|
+
* For `tenant: false`, the tenant key is ignored.
|
|
192
|
+
*/
|
|
193
|
+
/**
|
|
194
|
+
* Extends `@classytic/primitives`' {@link OperationContext} with loyalty-
|
|
195
|
+
* specific fields. `actorId` is narrowed to a required `string` since every
|
|
196
|
+
* loyalty mutation is attributed; other primitives fields (`correlationId`,
|
|
197
|
+
* `traceId`, `requestId`, `session`, `metadata`) flow through unchanged.
|
|
198
|
+
*/
|
|
199
|
+
interface LoyaltyContext extends OperationContext {
|
|
200
|
+
/** Required for loyalty: who is performing this operation. Narrowed to string. */
|
|
201
|
+
actorId: string;
|
|
202
|
+
/** Narrowed from primitives' `IdLike` to string. */
|
|
203
|
+
organizationId?: string;
|
|
204
|
+
/** Override program ID for multi-program setups. */
|
|
205
|
+
programId?: string;
|
|
206
|
+
/** Dynamic tenant key support — e.g. `{ companyId: '...' }` — when a host
|
|
207
|
+
* configured a custom `contextKey`. */
|
|
208
|
+
[key: string]: unknown;
|
|
209
|
+
}
|
|
210
|
+
interface EnrollInput {
|
|
211
|
+
externalId: string;
|
|
212
|
+
externalType: string;
|
|
213
|
+
programId?: string;
|
|
214
|
+
tier?: string;
|
|
215
|
+
cardId?: string;
|
|
216
|
+
metadata?: Record<string, unknown>;
|
|
217
|
+
}
|
|
218
|
+
interface EarnPointsInput {
|
|
219
|
+
memberId: string;
|
|
220
|
+
points: number;
|
|
221
|
+
description: string;
|
|
222
|
+
referenceType?: string;
|
|
223
|
+
referenceId?: string;
|
|
224
|
+
earningRuleId?: string;
|
|
225
|
+
expiresAt?: Date;
|
|
226
|
+
idempotencyKey?: string;
|
|
227
|
+
metadata?: Record<string, unknown>;
|
|
228
|
+
}
|
|
229
|
+
interface AdjustPointsInput {
|
|
230
|
+
memberId: string;
|
|
231
|
+
points: number;
|
|
232
|
+
description: string;
|
|
233
|
+
reason: string;
|
|
234
|
+
referenceType?: string;
|
|
235
|
+
referenceId?: string;
|
|
236
|
+
idempotencyKey?: string;
|
|
237
|
+
metadata?: Record<string, unknown>;
|
|
238
|
+
}
|
|
239
|
+
interface CreateEarningRuleInput {
|
|
240
|
+
name: string;
|
|
241
|
+
type: 'order' | 'action' | 'category' | 'tier_bonus';
|
|
242
|
+
priority?: number;
|
|
243
|
+
description?: string;
|
|
244
|
+
conditions?: EarningConditions;
|
|
245
|
+
reward: EarningReward;
|
|
246
|
+
startsAt?: Date | string;
|
|
247
|
+
endsAt?: Date | string;
|
|
248
|
+
programId?: string;
|
|
249
|
+
metadata?: Record<string, unknown>;
|
|
250
|
+
}
|
|
251
|
+
interface UpdateEarningRuleInput {
|
|
252
|
+
name?: string;
|
|
253
|
+
priority?: number;
|
|
254
|
+
description?: string;
|
|
255
|
+
conditions?: EarningConditions;
|
|
256
|
+
reward?: EarningReward;
|
|
257
|
+
startsAt?: Date | string;
|
|
258
|
+
endsAt?: Date | string;
|
|
259
|
+
metadata?: Record<string, unknown>;
|
|
260
|
+
}
|
|
261
|
+
interface CreateTierInput {
|
|
262
|
+
name: string;
|
|
263
|
+
rank: number;
|
|
264
|
+
qualificationCriteria?: TierQualification;
|
|
265
|
+
benefits?: TierBenefits;
|
|
266
|
+
downgrade?: TierDowngrade;
|
|
267
|
+
color?: string;
|
|
268
|
+
programId?: string;
|
|
269
|
+
metadata?: Record<string, unknown>;
|
|
270
|
+
}
|
|
271
|
+
interface UpdateTierInput {
|
|
272
|
+
name?: string;
|
|
273
|
+
rank?: number;
|
|
274
|
+
qualificationCriteria?: TierQualification;
|
|
275
|
+
benefits?: TierBenefits;
|
|
276
|
+
downgrade?: TierDowngrade;
|
|
277
|
+
color?: string;
|
|
278
|
+
metadata?: Record<string, unknown>;
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
export { EarningRule as S, TierEvaluationBatch as _, EnrollInput as a, MemberBalance as b, UpdateTierInput as c, EarningResult as d, ExpirationResult as f, TierEvaluation as g, RedemptionValidation as h, EarnPointsInput as i, BalanceSummary as l, PaginatedResult as m, CreateEarningRuleInput as n, LoyaltyContext as o, ListQuery as p, CreateTierInput as r, UpdateEarningRuleInput as s, AdjustPointsInput as t, EarningBreakdown as u, PointTransaction as v, TierDefinition as x, Member as y };
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { o as LoyaltyContext } from "./index-2izQQext.mjs";
|
|
2
|
+
import { DomainEvent, DomainEvent as DomainEvent$1, EventHandler, EventHandler as EventHandler$1, EventTransport, EventTransport as EventTransport$1 } from "@classytic/primitives/events";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/events/in-process-bus.d.ts
|
|
6
|
+
interface InProcessLoyaltyBusOptions {
|
|
7
|
+
/** Logger for handler errors (default: console). */
|
|
8
|
+
logger?: {
|
|
9
|
+
error: (msg: string, ...args: unknown[]) => void;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
declare class InProcessLoyaltyBus implements EventTransport {
|
|
13
|
+
readonly name = "in-process-loyalty";
|
|
14
|
+
private handlers;
|
|
15
|
+
private logger;
|
|
16
|
+
constructor(options?: InProcessLoyaltyBusOptions);
|
|
17
|
+
publish(event: DomainEvent): Promise<void>;
|
|
18
|
+
subscribe(pattern: string, handler: EventHandler): Promise<() => void>;
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/events/helpers.d.ts
|
|
23
|
+
declare function createEvent$1<T>(type: string, payload: T, ctx?: LoyaltyContext, meta?: Partial<DomainEvent['meta']>): DomainEvent<T>;
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/events/loyalty-events.d.ts
|
|
26
|
+
/**
|
|
27
|
+
* Loyalty event name + payload map.
|
|
28
|
+
*
|
|
29
|
+
* Minimal surface. Loyalty emits events for its own lifecycle transitions
|
|
30
|
+
* only — member, points ledger, tier, redemption, and referral.
|
|
31
|
+
*
|
|
32
|
+
* For registration with an arc-compatible event registry, see
|
|
33
|
+
* `loyalty-event-catalog.ts` in this directory — it exposes each event as
|
|
34
|
+
* a `LoyaltyEventDefinition` with a Zod payload schema + JSON Schema
|
|
35
|
+
* derived via `z.toJSONSchema()` (PACKAGE_RULES §18.5).
|
|
36
|
+
*/
|
|
37
|
+
declare const LoyaltyEvents: {
|
|
38
|
+
readonly MEMBER_ENROLLED: "loyalty.member.enrolled";
|
|
39
|
+
readonly MEMBER_DEACTIVATED: "loyalty.member.deactivated";
|
|
40
|
+
readonly MEMBER_REACTIVATED: "loyalty.member.reactivated";
|
|
41
|
+
readonly MEMBER_SUSPENDED: "loyalty.member.suspended";
|
|
42
|
+
readonly POINTS_EARNED: "loyalty.points.earned";
|
|
43
|
+
readonly POINTS_REDEEMED: "loyalty.points.redeemed";
|
|
44
|
+
readonly POINTS_ADJUSTED: "loyalty.points.adjusted";
|
|
45
|
+
readonly POINTS_EXPIRED: "loyalty.points.expired";
|
|
46
|
+
readonly POINTS_EXPIRING_SOON: "loyalty.points.expiring_soon";
|
|
47
|
+
readonly TIER_UPGRADED: "loyalty.tier.upgraded";
|
|
48
|
+
readonly TIER_DOWNGRADED: "loyalty.tier.downgraded";
|
|
49
|
+
readonly TIER_GRACE_STARTED: "loyalty.tier.grace_started";
|
|
50
|
+
readonly TIER_OVERRIDE_CLEARED: "loyalty.tier.override_cleared";
|
|
51
|
+
readonly TIER_OVERRIDE_EXPIRED: "loyalty.tier.override_expired";
|
|
52
|
+
readonly REDEMPTION_RESERVED: "loyalty.redemption.reserved";
|
|
53
|
+
readonly REDEMPTION_CONFIRMED: "loyalty.redemption.confirmed";
|
|
54
|
+
readonly REDEMPTION_RELEASED: "loyalty.redemption.released";
|
|
55
|
+
readonly REDEMPTION_REVERSED: "loyalty.redemption.reversed";
|
|
56
|
+
readonly CAMPAIGN_AWARDED: "loyalty.campaign.awarded";
|
|
57
|
+
readonly REFERRAL_RECORDED: "loyalty.referral.recorded";
|
|
58
|
+
readonly REFERRAL_APPROVED: "loyalty.referral.approved";
|
|
59
|
+
readonly REFERRAL_REJECTED: "loyalty.referral.rejected";
|
|
60
|
+
readonly REFERRAL_REWARDED: "loyalty.referral.rewarded";
|
|
61
|
+
readonly MULTI_TIER_REFERRAL_AWARDED: "loyalty.referral.multi_tier_awarded";
|
|
62
|
+
};
|
|
63
|
+
type LoyaltyEventName = (typeof LoyaltyEvents)[keyof typeof LoyaltyEvents];
|
|
64
|
+
interface MemberLifecyclePayload {
|
|
65
|
+
memberId: string;
|
|
66
|
+
externalId: string;
|
|
67
|
+
externalType: string;
|
|
68
|
+
status: string;
|
|
69
|
+
}
|
|
70
|
+
interface PointsEarnedPayload {
|
|
71
|
+
memberId: string;
|
|
72
|
+
externalId: string;
|
|
73
|
+
externalType: string;
|
|
74
|
+
points: number;
|
|
75
|
+
balanceAfter: number;
|
|
76
|
+
transactionId: string;
|
|
77
|
+
earningRuleName?: string;
|
|
78
|
+
referenceType?: string;
|
|
79
|
+
referenceId?: string;
|
|
80
|
+
}
|
|
81
|
+
interface PointsAdjustedPayload {
|
|
82
|
+
memberId: string;
|
|
83
|
+
externalId: string;
|
|
84
|
+
points: number;
|
|
85
|
+
balanceAfter: number;
|
|
86
|
+
transactionId: string;
|
|
87
|
+
description: string;
|
|
88
|
+
}
|
|
89
|
+
interface PointsExpiredPayload {
|
|
90
|
+
membersAffected: number;
|
|
91
|
+
pointsExpired: number;
|
|
92
|
+
transactionCount: number;
|
|
93
|
+
}
|
|
94
|
+
interface TierChangedPayload {
|
|
95
|
+
memberId: string;
|
|
96
|
+
externalId: string;
|
|
97
|
+
previousTier: string | null;
|
|
98
|
+
newTier: string | null;
|
|
99
|
+
lifetimePoints: number;
|
|
100
|
+
}
|
|
101
|
+
interface RedemptionPayload {
|
|
102
|
+
memberId: string;
|
|
103
|
+
externalId: string;
|
|
104
|
+
redemptionId: string;
|
|
105
|
+
points: number;
|
|
106
|
+
discountAmount: number;
|
|
107
|
+
ownerType: string;
|
|
108
|
+
ownerId: string;
|
|
109
|
+
}
|
|
110
|
+
interface ReferralPayload {
|
|
111
|
+
referralId: string;
|
|
112
|
+
referrerId: string;
|
|
113
|
+
refereeId: string;
|
|
114
|
+
referralCode: string;
|
|
115
|
+
status: string;
|
|
116
|
+
referrerRewardPoints?: number;
|
|
117
|
+
refereeRewardPoints?: number;
|
|
118
|
+
}
|
|
119
|
+
interface TierOverrideLifecyclePayload {
|
|
120
|
+
memberId: string;
|
|
121
|
+
externalId: string;
|
|
122
|
+
tier: string;
|
|
123
|
+
reason?: string;
|
|
124
|
+
/** ISO string — Dates can't be JSON-schema'd. Present only on TTL-sweep path. */
|
|
125
|
+
expiredAt?: string;
|
|
126
|
+
}
|
|
127
|
+
interface RedemptionReversedPayload {
|
|
128
|
+
memberId: string;
|
|
129
|
+
externalId: string;
|
|
130
|
+
redemptionId: string;
|
|
131
|
+
/** Points credited back to the member by the reversal. */
|
|
132
|
+
pointsCredited: number;
|
|
133
|
+
/** Original confirmed points on the redemption. */
|
|
134
|
+
originalPoints: number;
|
|
135
|
+
proportional: boolean;
|
|
136
|
+
reason?: string;
|
|
137
|
+
transactionId: string;
|
|
138
|
+
}
|
|
139
|
+
interface CampaignAwardedPayload {
|
|
140
|
+
campaignId: string;
|
|
141
|
+
memberCount: number;
|
|
142
|
+
awarded: number;
|
|
143
|
+
skipped: number;
|
|
144
|
+
totalPoints: number;
|
|
145
|
+
}
|
|
146
|
+
interface MultiTierReferralAwardedPayload {
|
|
147
|
+
referralId: string;
|
|
148
|
+
refereeId: string;
|
|
149
|
+
/** Awards keyed by ancestor depth (1 = direct referrer). */
|
|
150
|
+
awards: Array<{
|
|
151
|
+
memberId: string;
|
|
152
|
+
depth: number;
|
|
153
|
+
points: number;
|
|
154
|
+
transactionId: string;
|
|
155
|
+
}>;
|
|
156
|
+
}
|
|
157
|
+
interface LoyaltyEventMap {
|
|
158
|
+
[LoyaltyEvents.MEMBER_ENROLLED]: MemberLifecyclePayload;
|
|
159
|
+
[LoyaltyEvents.MEMBER_DEACTIVATED]: MemberLifecyclePayload;
|
|
160
|
+
[LoyaltyEvents.MEMBER_REACTIVATED]: MemberLifecyclePayload;
|
|
161
|
+
[LoyaltyEvents.MEMBER_SUSPENDED]: MemberLifecyclePayload;
|
|
162
|
+
[LoyaltyEvents.POINTS_EARNED]: PointsEarnedPayload;
|
|
163
|
+
[LoyaltyEvents.POINTS_REDEEMED]: PointsAdjustedPayload;
|
|
164
|
+
[LoyaltyEvents.POINTS_ADJUSTED]: PointsAdjustedPayload;
|
|
165
|
+
[LoyaltyEvents.POINTS_EXPIRED]: PointsExpiredPayload;
|
|
166
|
+
[LoyaltyEvents.POINTS_EXPIRING_SOON]: PointsExpiredPayload;
|
|
167
|
+
[LoyaltyEvents.TIER_UPGRADED]: TierChangedPayload;
|
|
168
|
+
[LoyaltyEvents.TIER_DOWNGRADED]: TierChangedPayload;
|
|
169
|
+
[LoyaltyEvents.TIER_GRACE_STARTED]: TierChangedPayload;
|
|
170
|
+
[LoyaltyEvents.TIER_OVERRIDE_CLEARED]: TierOverrideLifecyclePayload;
|
|
171
|
+
[LoyaltyEvents.TIER_OVERRIDE_EXPIRED]: TierOverrideLifecyclePayload;
|
|
172
|
+
[LoyaltyEvents.REDEMPTION_RESERVED]: RedemptionPayload;
|
|
173
|
+
[LoyaltyEvents.REDEMPTION_CONFIRMED]: RedemptionPayload;
|
|
174
|
+
[LoyaltyEvents.REDEMPTION_RELEASED]: RedemptionPayload;
|
|
175
|
+
[LoyaltyEvents.REDEMPTION_REVERSED]: RedemptionReversedPayload;
|
|
176
|
+
[LoyaltyEvents.CAMPAIGN_AWARDED]: CampaignAwardedPayload;
|
|
177
|
+
[LoyaltyEvents.REFERRAL_RECORDED]: ReferralPayload;
|
|
178
|
+
[LoyaltyEvents.REFERRAL_APPROVED]: ReferralPayload;
|
|
179
|
+
[LoyaltyEvents.REFERRAL_REJECTED]: ReferralPayload;
|
|
180
|
+
[LoyaltyEvents.REFERRAL_REWARDED]: ReferralPayload;
|
|
181
|
+
[LoyaltyEvents.MULTI_TIER_REFERRAL_AWARDED]: MultiTierReferralAwardedPayload;
|
|
182
|
+
}
|
|
183
|
+
type LoyaltyEventPayload<E extends LoyaltyEventName> = LoyaltyEventMap[E];
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/events/loyalty-event-catalog.d.ts
|
|
186
|
+
interface LoyaltyEventSchema {
|
|
187
|
+
type: 'object';
|
|
188
|
+
properties?: Record<string, {
|
|
189
|
+
type?: string;
|
|
190
|
+
format?: string;
|
|
191
|
+
[key: string]: unknown;
|
|
192
|
+
}>;
|
|
193
|
+
required?: string[];
|
|
194
|
+
[key: string]: unknown;
|
|
195
|
+
}
|
|
196
|
+
interface LoyaltyEventDefinition<TSchema extends z.ZodType = z.ZodType> {
|
|
197
|
+
readonly name: string;
|
|
198
|
+
readonly version: number;
|
|
199
|
+
readonly description?: string;
|
|
200
|
+
readonly schema: LoyaltyEventSchema;
|
|
201
|
+
readonly zodSchema: TSchema;
|
|
202
|
+
create(payload: z.infer<TSchema>, meta?: Partial<DomainEvent['meta']>): DomainEvent<z.infer<TSchema>>;
|
|
203
|
+
readonly __payload?: z.infer<TSchema>;
|
|
204
|
+
}
|
|
205
|
+
type LoyaltyEventPayloadOf<D> = D extends LoyaltyEventDefinition<infer S> ? z.infer<S> : never;
|
|
206
|
+
declare const MemberEnrolled: LoyaltyEventDefinition<z.ZodObject<{
|
|
207
|
+
memberId: z.ZodString;
|
|
208
|
+
externalId: z.ZodString;
|
|
209
|
+
externalType: z.ZodString;
|
|
210
|
+
status: z.ZodString;
|
|
211
|
+
}, z.core.$strip>>;
|
|
212
|
+
declare const MemberDeactivated: LoyaltyEventDefinition<z.ZodObject<{
|
|
213
|
+
memberId: z.ZodString;
|
|
214
|
+
externalId: z.ZodString;
|
|
215
|
+
externalType: z.ZodString;
|
|
216
|
+
status: z.ZodString;
|
|
217
|
+
}, z.core.$strip>>;
|
|
218
|
+
declare const MemberReactivated: LoyaltyEventDefinition<z.ZodObject<{
|
|
219
|
+
memberId: z.ZodString;
|
|
220
|
+
externalId: z.ZodString;
|
|
221
|
+
externalType: z.ZodString;
|
|
222
|
+
status: z.ZodString;
|
|
223
|
+
}, z.core.$strip>>;
|
|
224
|
+
declare const MemberSuspended: LoyaltyEventDefinition<z.ZodObject<{
|
|
225
|
+
memberId: z.ZodString;
|
|
226
|
+
externalId: z.ZodString;
|
|
227
|
+
externalType: z.ZodString;
|
|
228
|
+
status: z.ZodString;
|
|
229
|
+
}, z.core.$strip>>;
|
|
230
|
+
declare const PointsEarned: LoyaltyEventDefinition<z.ZodObject<{
|
|
231
|
+
memberId: z.ZodString;
|
|
232
|
+
externalId: z.ZodString;
|
|
233
|
+
externalType: z.ZodString;
|
|
234
|
+
points: z.ZodNumber;
|
|
235
|
+
balanceAfter: z.ZodNumber;
|
|
236
|
+
transactionId: z.ZodString;
|
|
237
|
+
earningRuleName: z.ZodOptional<z.ZodString>;
|
|
238
|
+
referenceType: z.ZodOptional<z.ZodString>;
|
|
239
|
+
referenceId: z.ZodOptional<z.ZodString>;
|
|
240
|
+
}, z.core.$strip>>;
|
|
241
|
+
declare const PointsRedeemed: LoyaltyEventDefinition<z.ZodObject<{
|
|
242
|
+
memberId: z.ZodString;
|
|
243
|
+
externalId: z.ZodString;
|
|
244
|
+
points: z.ZodNumber;
|
|
245
|
+
balanceAfter: z.ZodNumber;
|
|
246
|
+
transactionId: z.ZodString;
|
|
247
|
+
description: z.ZodString;
|
|
248
|
+
}, z.core.$strip>>;
|
|
249
|
+
declare const PointsAdjusted: LoyaltyEventDefinition<z.ZodObject<{
|
|
250
|
+
memberId: z.ZodString;
|
|
251
|
+
externalId: z.ZodString;
|
|
252
|
+
points: z.ZodNumber;
|
|
253
|
+
balanceAfter: z.ZodNumber;
|
|
254
|
+
transactionId: z.ZodString;
|
|
255
|
+
description: z.ZodString;
|
|
256
|
+
}, z.core.$strip>>;
|
|
257
|
+
declare const PointsExpired: LoyaltyEventDefinition<z.ZodObject<{
|
|
258
|
+
membersAffected: z.ZodNumber;
|
|
259
|
+
pointsExpired: z.ZodNumber;
|
|
260
|
+
transactionCount: z.ZodNumber;
|
|
261
|
+
}, z.core.$strip>>;
|
|
262
|
+
declare const PointsExpiringSoon: LoyaltyEventDefinition<z.ZodObject<{
|
|
263
|
+
membersAffected: z.ZodNumber;
|
|
264
|
+
pointsExpired: z.ZodNumber;
|
|
265
|
+
transactionCount: z.ZodNumber;
|
|
266
|
+
}, z.core.$strip>>;
|
|
267
|
+
declare const TierUpgraded: LoyaltyEventDefinition<z.ZodObject<{
|
|
268
|
+
memberId: z.ZodString;
|
|
269
|
+
externalId: z.ZodString;
|
|
270
|
+
previousTier: z.ZodNullable<z.ZodString>;
|
|
271
|
+
newTier: z.ZodNullable<z.ZodString>;
|
|
272
|
+
lifetimePoints: z.ZodNumber;
|
|
273
|
+
}, z.core.$strip>>;
|
|
274
|
+
declare const TierDowngraded: LoyaltyEventDefinition<z.ZodObject<{
|
|
275
|
+
memberId: z.ZodString;
|
|
276
|
+
externalId: z.ZodString;
|
|
277
|
+
previousTier: z.ZodNullable<z.ZodString>;
|
|
278
|
+
newTier: z.ZodNullable<z.ZodString>;
|
|
279
|
+
lifetimePoints: z.ZodNumber;
|
|
280
|
+
}, z.core.$strip>>;
|
|
281
|
+
declare const TierGraceStarted: LoyaltyEventDefinition<z.ZodObject<{
|
|
282
|
+
memberId: z.ZodString;
|
|
283
|
+
externalId: z.ZodString;
|
|
284
|
+
previousTier: z.ZodNullable<z.ZodString>;
|
|
285
|
+
newTier: z.ZodNullable<z.ZodString>;
|
|
286
|
+
lifetimePoints: z.ZodNumber;
|
|
287
|
+
}, z.core.$strip>>;
|
|
288
|
+
declare const TierOverrideCleared: LoyaltyEventDefinition<z.ZodObject<{
|
|
289
|
+
memberId: z.ZodString;
|
|
290
|
+
externalId: z.ZodString;
|
|
291
|
+
tier: z.ZodString;
|
|
292
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
293
|
+
expiredAt: z.ZodOptional<z.ZodString>;
|
|
294
|
+
}, z.core.$strip>>;
|
|
295
|
+
declare const TierOverrideExpired: LoyaltyEventDefinition<z.ZodObject<{
|
|
296
|
+
memberId: z.ZodString;
|
|
297
|
+
externalId: z.ZodString;
|
|
298
|
+
tier: z.ZodString;
|
|
299
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
300
|
+
expiredAt: z.ZodOptional<z.ZodString>;
|
|
301
|
+
}, z.core.$strip>>;
|
|
302
|
+
declare const RedemptionReserved: LoyaltyEventDefinition<z.ZodObject<{
|
|
303
|
+
memberId: z.ZodString;
|
|
304
|
+
externalId: z.ZodString;
|
|
305
|
+
redemptionId: z.ZodString;
|
|
306
|
+
points: z.ZodNumber;
|
|
307
|
+
discountAmount: z.ZodNumber;
|
|
308
|
+
ownerType: z.ZodString;
|
|
309
|
+
ownerId: z.ZodString;
|
|
310
|
+
}, z.core.$strip>>;
|
|
311
|
+
declare const RedemptionConfirmed: LoyaltyEventDefinition<z.ZodObject<{
|
|
312
|
+
memberId: z.ZodString;
|
|
313
|
+
externalId: z.ZodString;
|
|
314
|
+
redemptionId: z.ZodString;
|
|
315
|
+
points: z.ZodNumber;
|
|
316
|
+
discountAmount: z.ZodNumber;
|
|
317
|
+
ownerType: z.ZodString;
|
|
318
|
+
ownerId: z.ZodString;
|
|
319
|
+
}, z.core.$strip>>;
|
|
320
|
+
declare const RedemptionReleased: LoyaltyEventDefinition<z.ZodObject<{
|
|
321
|
+
memberId: z.ZodString;
|
|
322
|
+
externalId: z.ZodString;
|
|
323
|
+
redemptionId: z.ZodString;
|
|
324
|
+
points: z.ZodNumber;
|
|
325
|
+
discountAmount: z.ZodNumber;
|
|
326
|
+
ownerType: z.ZodString;
|
|
327
|
+
ownerId: z.ZodString;
|
|
328
|
+
}, z.core.$strip>>;
|
|
329
|
+
declare const RedemptionReversed: LoyaltyEventDefinition<z.ZodObject<{
|
|
330
|
+
memberId: z.ZodString;
|
|
331
|
+
externalId: z.ZodString;
|
|
332
|
+
redemptionId: z.ZodString;
|
|
333
|
+
pointsCredited: z.ZodNumber;
|
|
334
|
+
originalPoints: z.ZodNumber;
|
|
335
|
+
proportional: z.ZodBoolean;
|
|
336
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
337
|
+
transactionId: z.ZodString;
|
|
338
|
+
}, z.core.$strip>>;
|
|
339
|
+
declare const CampaignAwarded: LoyaltyEventDefinition<z.ZodObject<{
|
|
340
|
+
campaignId: z.ZodString;
|
|
341
|
+
memberCount: z.ZodNumber;
|
|
342
|
+
awarded: z.ZodNumber;
|
|
343
|
+
skipped: z.ZodNumber;
|
|
344
|
+
totalPoints: z.ZodNumber;
|
|
345
|
+
}, z.core.$strip>>;
|
|
346
|
+
declare const ReferralRecorded: LoyaltyEventDefinition<z.ZodObject<{
|
|
347
|
+
referralId: z.ZodString;
|
|
348
|
+
referrerId: z.ZodString;
|
|
349
|
+
refereeId: z.ZodString;
|
|
350
|
+
referralCode: z.ZodString;
|
|
351
|
+
status: z.ZodString;
|
|
352
|
+
referrerRewardPoints: z.ZodOptional<z.ZodNumber>;
|
|
353
|
+
refereeRewardPoints: z.ZodOptional<z.ZodNumber>;
|
|
354
|
+
}, z.core.$strip>>;
|
|
355
|
+
declare const ReferralApproved: LoyaltyEventDefinition<z.ZodObject<{
|
|
356
|
+
referralId: z.ZodString;
|
|
357
|
+
referrerId: z.ZodString;
|
|
358
|
+
refereeId: z.ZodString;
|
|
359
|
+
referralCode: z.ZodString;
|
|
360
|
+
status: z.ZodString;
|
|
361
|
+
referrerRewardPoints: z.ZodOptional<z.ZodNumber>;
|
|
362
|
+
refereeRewardPoints: z.ZodOptional<z.ZodNumber>;
|
|
363
|
+
}, z.core.$strip>>;
|
|
364
|
+
declare const ReferralRejected: LoyaltyEventDefinition<z.ZodObject<{
|
|
365
|
+
referralId: z.ZodString;
|
|
366
|
+
referrerId: z.ZodString;
|
|
367
|
+
refereeId: z.ZodString;
|
|
368
|
+
referralCode: z.ZodString;
|
|
369
|
+
status: z.ZodString;
|
|
370
|
+
referrerRewardPoints: z.ZodOptional<z.ZodNumber>;
|
|
371
|
+
refereeRewardPoints: z.ZodOptional<z.ZodNumber>;
|
|
372
|
+
}, z.core.$strip>>;
|
|
373
|
+
declare const ReferralRewarded: LoyaltyEventDefinition<z.ZodObject<{
|
|
374
|
+
referralId: z.ZodString;
|
|
375
|
+
referrerId: z.ZodString;
|
|
376
|
+
refereeId: z.ZodString;
|
|
377
|
+
referralCode: z.ZodString;
|
|
378
|
+
status: z.ZodString;
|
|
379
|
+
referrerRewardPoints: z.ZodOptional<z.ZodNumber>;
|
|
380
|
+
refereeRewardPoints: z.ZodOptional<z.ZodNumber>;
|
|
381
|
+
}, z.core.$strip>>;
|
|
382
|
+
declare const MultiTierReferralAwarded: LoyaltyEventDefinition<z.ZodObject<{
|
|
383
|
+
referralId: z.ZodString;
|
|
384
|
+
refereeId: z.ZodString;
|
|
385
|
+
awards: z.ZodArray<z.ZodObject<{
|
|
386
|
+
memberId: z.ZodString;
|
|
387
|
+
depth: z.ZodNumber;
|
|
388
|
+
points: z.ZodNumber;
|
|
389
|
+
transactionId: z.ZodString;
|
|
390
|
+
}, z.core.$strip>>;
|
|
391
|
+
}, z.core.$strip>>;
|
|
392
|
+
/**
|
|
393
|
+
* Every loyalty event defined in the package — pass to Arc's
|
|
394
|
+
* `EventRegistry`. Hosts wire ONE array; the whole `loyalty.*` namespace
|
|
395
|
+
* becomes introspectable via OpenAPI and auto-validated at publish time
|
|
396
|
+
* when `eventPlugin({ validateMode: 'reject' })` is set.
|
|
397
|
+
*/
|
|
398
|
+
declare const loyaltyEventDefinitions: ReadonlyArray<LoyaltyEventDefinition>;
|
|
399
|
+
//#endregion
|
|
400
|
+
export { TierUpgraded as A, PointsEarnedPayload as B, ReferralRecorded as C, TierGraceStarted as D, TierDowngraded as E, LoyaltyEventPayload as F, TierChangedPayload as G, RedemptionPayload as H, LoyaltyEvents as I, InProcessLoyaltyBus as J, TierOverrideLifecyclePayload as K, MemberLifecyclePayload as L, CampaignAwardedPayload as M, LoyaltyEventMap as N, TierOverrideCleared as O, LoyaltyEventName as P, MultiTierReferralAwardedPayload as R, ReferralApproved as S, ReferralRewarded as T, RedemptionReversedPayload as U, PointsExpiredPayload as V, ReferralPayload as W, InProcessLoyaltyBusOptions as Y, PointsRedeemed as _, LoyaltyEventDefinition as a, RedemptionReserved as b, MemberDeactivated as c, MemberSuspended as d, MultiTierReferralAwarded as f, PointsExpiringSoon as g, PointsExpired as h, CampaignAwarded as i, loyaltyEventDefinitions as j, TierOverrideExpired as k, MemberEnrolled as l, PointsEarned as m, EventHandler$1 as n, LoyaltyEventPayloadOf as o, PointsAdjusted as p, createEvent$1 as q, EventTransport$1 as r, LoyaltyEventSchema as s, DomainEvent$1 as t, MemberReactivated as u, RedemptionConfirmed as v, ReferralRejected as w, RedemptionReversed as x, RedemptionReleased as y, PointsAdjustedPayload as z };
|
|
@@ -4,7 +4,7 @@ declare const MEMBER_STATUSES: readonly ["active", "inactive", "suspended"];
|
|
|
4
4
|
declare const RULE_TYPES: readonly ["order", "action", "category", "tier_bonus"];
|
|
5
5
|
declare const RULE_STATUSES: readonly ["active", "paused", "expired"];
|
|
6
6
|
declare const REFERRAL_STATUSES: readonly ["pending", "approved", "rejected", "expired"];
|
|
7
|
-
declare const REDEMPTION_STATUSES: readonly ["reserved", "confirmed", "released", "expired"];
|
|
7
|
+
declare const REDEMPTION_STATUSES: readonly ["reserved", "confirmed", "released", "expired", "reversed"];
|
|
8
8
|
declare const EARNING_ACTIONS: readonly ["signup", "referral", "birthday", "review", "profile_complete"];
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region src/domain/enums/index.d.ts
|