@classytic/loyalty 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/dist/config-DoZPGBfW.d.mts +136 -0
  3. package/dist/{constants-C75GvizO.mjs → constants-DkQYkOK1.mjs} +3 -2
  4. package/dist/domain/enums/index.d.mts +1 -1
  5. package/dist/domain/enums/index.mjs +1 -1
  6. package/dist/events/index.d.mts +2 -2
  7. package/dist/events/index.mjs +3 -3
  8. package/dist/events-BtZOdiPw.mjs +311 -0
  9. package/dist/index-BOWqBSWx.d.mts +281 -0
  10. package/dist/index-C4jFHS7m.d.mts +400 -0
  11. package/dist/index-ClPKmtxh.d.mts +361 -0
  12. package/dist/{index-CaH4GhSF.d.mts → index-DMK8a98J.d.mts} +1 -1
  13. package/dist/index.d.mts +28 -12
  14. package/dist/index.mjs +30 -26
  15. package/dist/loyalty-events-Cyt9TwX6.mjs +50 -0
  16. package/dist/models/index.d.mts +1225 -2
  17. package/dist/models/index.mjs +2 -2
  18. package/dist/{models-CrZPmVxt.mjs → models-uhh9c-7k.mjs} +104 -41
  19. package/dist/notifications/index.d.mts +1 -1
  20. package/dist/repositories/index.d.mts +2 -2
  21. package/dist/repositories/index.mjs +1 -1
  22. package/dist/repositories-DBSxe9st.mjs +1919 -0
  23. package/dist/types/index.d.mts +2 -2
  24. package/package.json +22 -17
  25. package/dist/config-aNigy4ec.d.mts +0 -90
  26. package/dist/domain/index.d.mts +0 -90
  27. package/dist/domain/index.mjs +0 -4
  28. package/dist/domain-errors-D7q-2LYD.mjs +0 -120
  29. package/dist/event-emitter.port-CLYPoMni.d.mts +0 -8
  30. package/dist/event-types-xQBtYBbX.mjs +0 -24
  31. package/dist/events-CprEWlN7.mjs +0 -25
  32. package/dist/index-B6ZstxSP.d.mts +0 -2357
  33. package/dist/index-BcoGeDco.d.mts +0 -127
  34. package/dist/index-DqzTjeEB.d.mts +0 -148
  35. package/dist/index-O7TL4R2P.d.mts +0 -86
  36. package/dist/index-_pg4J11t.d.mts +0 -191
  37. package/dist/repositories-qMX7Xh_y.mjs +0 -440
  38. package/dist/services/index.d.mts +0 -2
  39. package/dist/services/index.mjs +0 -2
  40. package/dist/services-CoTqC4E6.mjs +0 -1098
  41. package/dist/tier-definition-Djf72UPa.d.mts +0 -120
  42. package/dist/tier-definition.port-BzrHYBRo.d.mts +0 -143
  43. /package/dist/{notification.port-BzUsH0It.d.mts → notification.port-CJ9nXj0k.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-BOWqBSWx.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/helpers.d.ts
6
+ declare function createEvent$1<T>(type: string, payload: T, ctx?: LoyaltyContext, meta?: Partial<DomainEvent['meta']>): DomainEvent<T>;
7
+ //#endregion
8
+ //#region src/events/in-process-bus.d.ts
9
+ interface InProcessLoyaltyBusOptions {
10
+ /** Logger for handler errors (default: console). */
11
+ logger?: {
12
+ error: (msg: string, ...args: unknown[]) => void;
13
+ };
14
+ }
15
+ declare class InProcessLoyaltyBus implements EventTransport {
16
+ readonly name = "in-process-loyalty";
17
+ private handlers;
18
+ private logger;
19
+ constructor(options?: InProcessLoyaltyBusOptions);
20
+ publish(event: DomainEvent): Promise<void>;
21
+ subscribe(pattern: string, handler: EventHandler): Promise<() => void>;
22
+ close(): Promise<void>;
23
+ }
24
+ //#endregion
25
+ //#region src/events/loyalty-event-catalog.d.ts
26
+ interface LoyaltyEventSchema {
27
+ type: 'object';
28
+ properties?: Record<string, {
29
+ type?: string;
30
+ format?: string;
31
+ [key: string]: unknown;
32
+ }>;
33
+ required?: string[];
34
+ [key: string]: unknown;
35
+ }
36
+ interface LoyaltyEventDefinition<TSchema extends z.ZodType = z.ZodType> {
37
+ readonly name: string;
38
+ readonly version: number;
39
+ readonly description?: string;
40
+ readonly schema: LoyaltyEventSchema;
41
+ readonly zodSchema: TSchema;
42
+ create(payload: z.infer<TSchema>, meta?: Partial<DomainEvent['meta']>): DomainEvent<z.infer<TSchema>>;
43
+ readonly __payload?: z.infer<TSchema>;
44
+ }
45
+ type LoyaltyEventPayloadOf<D> = D extends LoyaltyEventDefinition<infer S> ? z.infer<S> : never;
46
+ declare const MemberEnrolled: LoyaltyEventDefinition<z.ZodObject<{
47
+ memberId: z.ZodString;
48
+ externalId: z.ZodString;
49
+ externalType: z.ZodString;
50
+ status: z.ZodString;
51
+ }, z.core.$strip>>;
52
+ declare const MemberDeactivated: LoyaltyEventDefinition<z.ZodObject<{
53
+ memberId: z.ZodString;
54
+ externalId: z.ZodString;
55
+ externalType: z.ZodString;
56
+ status: z.ZodString;
57
+ }, z.core.$strip>>;
58
+ declare const MemberReactivated: LoyaltyEventDefinition<z.ZodObject<{
59
+ memberId: z.ZodString;
60
+ externalId: z.ZodString;
61
+ externalType: z.ZodString;
62
+ status: z.ZodString;
63
+ }, z.core.$strip>>;
64
+ declare const MemberSuspended: LoyaltyEventDefinition<z.ZodObject<{
65
+ memberId: z.ZodString;
66
+ externalId: z.ZodString;
67
+ externalType: z.ZodString;
68
+ status: z.ZodString;
69
+ }, z.core.$strip>>;
70
+ declare const PointsEarned: LoyaltyEventDefinition<z.ZodObject<{
71
+ memberId: z.ZodString;
72
+ externalId: z.ZodString;
73
+ externalType: z.ZodString;
74
+ points: z.ZodNumber;
75
+ balanceAfter: z.ZodNumber;
76
+ transactionId: z.ZodString;
77
+ earningRuleName: z.ZodOptional<z.ZodString>;
78
+ referenceType: z.ZodOptional<z.ZodString>;
79
+ referenceId: z.ZodOptional<z.ZodString>;
80
+ }, z.core.$strip>>;
81
+ declare const PointsRedeemed: LoyaltyEventDefinition<z.ZodObject<{
82
+ memberId: z.ZodString;
83
+ externalId: z.ZodString;
84
+ points: z.ZodNumber;
85
+ balanceAfter: z.ZodNumber;
86
+ transactionId: z.ZodString;
87
+ description: z.ZodString;
88
+ }, z.core.$strip>>;
89
+ declare const PointsAdjusted: LoyaltyEventDefinition<z.ZodObject<{
90
+ memberId: z.ZodString;
91
+ externalId: z.ZodString;
92
+ points: z.ZodNumber;
93
+ balanceAfter: z.ZodNumber;
94
+ transactionId: z.ZodString;
95
+ description: z.ZodString;
96
+ }, z.core.$strip>>;
97
+ declare const PointsExpired: LoyaltyEventDefinition<z.ZodObject<{
98
+ membersAffected: z.ZodNumber;
99
+ pointsExpired: z.ZodNumber;
100
+ transactionCount: z.ZodNumber;
101
+ }, z.core.$strip>>;
102
+ declare const PointsExpiringSoon: LoyaltyEventDefinition<z.ZodObject<{
103
+ membersAffected: z.ZodNumber;
104
+ pointsExpired: z.ZodNumber;
105
+ transactionCount: z.ZodNumber;
106
+ }, z.core.$strip>>;
107
+ declare const TierUpgraded: LoyaltyEventDefinition<z.ZodObject<{
108
+ memberId: z.ZodString;
109
+ externalId: z.ZodString;
110
+ previousTier: z.ZodNullable<z.ZodString>;
111
+ newTier: z.ZodNullable<z.ZodString>;
112
+ lifetimePoints: z.ZodNumber;
113
+ }, z.core.$strip>>;
114
+ declare const TierDowngraded: LoyaltyEventDefinition<z.ZodObject<{
115
+ memberId: z.ZodString;
116
+ externalId: z.ZodString;
117
+ previousTier: z.ZodNullable<z.ZodString>;
118
+ newTier: z.ZodNullable<z.ZodString>;
119
+ lifetimePoints: z.ZodNumber;
120
+ }, z.core.$strip>>;
121
+ declare const TierGraceStarted: LoyaltyEventDefinition<z.ZodObject<{
122
+ memberId: z.ZodString;
123
+ externalId: z.ZodString;
124
+ previousTier: z.ZodNullable<z.ZodString>;
125
+ newTier: z.ZodNullable<z.ZodString>;
126
+ lifetimePoints: z.ZodNumber;
127
+ }, z.core.$strip>>;
128
+ declare const TierOverrideCleared: LoyaltyEventDefinition<z.ZodObject<{
129
+ memberId: z.ZodString;
130
+ externalId: z.ZodString;
131
+ tier: z.ZodString;
132
+ reason: z.ZodOptional<z.ZodString>;
133
+ expiredAt: z.ZodOptional<z.ZodString>;
134
+ }, z.core.$strip>>;
135
+ declare const TierOverrideExpired: LoyaltyEventDefinition<z.ZodObject<{
136
+ memberId: z.ZodString;
137
+ externalId: z.ZodString;
138
+ tier: z.ZodString;
139
+ reason: z.ZodOptional<z.ZodString>;
140
+ expiredAt: z.ZodOptional<z.ZodString>;
141
+ }, z.core.$strip>>;
142
+ declare const RedemptionReserved: LoyaltyEventDefinition<z.ZodObject<{
143
+ memberId: z.ZodString;
144
+ externalId: z.ZodString;
145
+ redemptionId: z.ZodString;
146
+ points: z.ZodNumber;
147
+ discountAmount: z.ZodNumber;
148
+ ownerType: z.ZodString;
149
+ ownerId: z.ZodString;
150
+ }, z.core.$strip>>;
151
+ declare const RedemptionConfirmed: LoyaltyEventDefinition<z.ZodObject<{
152
+ memberId: z.ZodString;
153
+ externalId: z.ZodString;
154
+ redemptionId: z.ZodString;
155
+ points: z.ZodNumber;
156
+ discountAmount: z.ZodNumber;
157
+ ownerType: z.ZodString;
158
+ ownerId: z.ZodString;
159
+ }, z.core.$strip>>;
160
+ declare const RedemptionReleased: LoyaltyEventDefinition<z.ZodObject<{
161
+ memberId: z.ZodString;
162
+ externalId: z.ZodString;
163
+ redemptionId: z.ZodString;
164
+ points: z.ZodNumber;
165
+ discountAmount: z.ZodNumber;
166
+ ownerType: z.ZodString;
167
+ ownerId: z.ZodString;
168
+ }, z.core.$strip>>;
169
+ declare const RedemptionReversed: LoyaltyEventDefinition<z.ZodObject<{
170
+ memberId: z.ZodString;
171
+ externalId: z.ZodString;
172
+ redemptionId: z.ZodString;
173
+ pointsCredited: z.ZodNumber;
174
+ originalPoints: z.ZodNumber;
175
+ proportional: z.ZodBoolean;
176
+ reason: z.ZodOptional<z.ZodString>;
177
+ transactionId: z.ZodString;
178
+ }, z.core.$strip>>;
179
+ declare const CampaignAwarded: LoyaltyEventDefinition<z.ZodObject<{
180
+ campaignId: z.ZodString;
181
+ memberCount: z.ZodNumber;
182
+ awarded: z.ZodNumber;
183
+ skipped: z.ZodNumber;
184
+ totalPoints: z.ZodNumber;
185
+ }, z.core.$strip>>;
186
+ declare const ReferralRecorded: LoyaltyEventDefinition<z.ZodObject<{
187
+ referralId: z.ZodString;
188
+ referrerId: z.ZodString;
189
+ refereeId: z.ZodString;
190
+ referralCode: z.ZodString;
191
+ status: z.ZodString;
192
+ referrerRewardPoints: z.ZodOptional<z.ZodNumber>;
193
+ refereeRewardPoints: z.ZodOptional<z.ZodNumber>;
194
+ }, z.core.$strip>>;
195
+ declare const ReferralApproved: LoyaltyEventDefinition<z.ZodObject<{
196
+ referralId: z.ZodString;
197
+ referrerId: z.ZodString;
198
+ refereeId: z.ZodString;
199
+ referralCode: z.ZodString;
200
+ status: z.ZodString;
201
+ referrerRewardPoints: z.ZodOptional<z.ZodNumber>;
202
+ refereeRewardPoints: z.ZodOptional<z.ZodNumber>;
203
+ }, z.core.$strip>>;
204
+ declare const ReferralRejected: LoyaltyEventDefinition<z.ZodObject<{
205
+ referralId: z.ZodString;
206
+ referrerId: z.ZodString;
207
+ refereeId: z.ZodString;
208
+ referralCode: z.ZodString;
209
+ status: z.ZodString;
210
+ referrerRewardPoints: z.ZodOptional<z.ZodNumber>;
211
+ refereeRewardPoints: z.ZodOptional<z.ZodNumber>;
212
+ }, z.core.$strip>>;
213
+ declare const ReferralRewarded: LoyaltyEventDefinition<z.ZodObject<{
214
+ referralId: z.ZodString;
215
+ referrerId: z.ZodString;
216
+ refereeId: z.ZodString;
217
+ referralCode: z.ZodString;
218
+ status: z.ZodString;
219
+ referrerRewardPoints: z.ZodOptional<z.ZodNumber>;
220
+ refereeRewardPoints: z.ZodOptional<z.ZodNumber>;
221
+ }, z.core.$strip>>;
222
+ declare const MultiTierReferralAwarded: LoyaltyEventDefinition<z.ZodObject<{
223
+ referralId: z.ZodString;
224
+ refereeId: z.ZodString;
225
+ awards: z.ZodArray<z.ZodObject<{
226
+ memberId: z.ZodString;
227
+ depth: z.ZodNumber;
228
+ points: z.ZodNumber;
229
+ transactionId: z.ZodString;
230
+ }, z.core.$strip>>;
231
+ }, z.core.$strip>>;
232
+ /**
233
+ * Every loyalty event defined in the package — pass to Arc's
234
+ * `EventRegistry`. Hosts wire ONE array; the whole `loyalty.*` namespace
235
+ * becomes introspectable via OpenAPI and auto-validated at publish time
236
+ * when `eventPlugin({ validateMode: 'reject' })` is set.
237
+ */
238
+ declare const loyaltyEventDefinitions: ReadonlyArray<LoyaltyEventDefinition>;
239
+ //#endregion
240
+ //#region src/events/loyalty-events.d.ts
241
+ /**
242
+ * Loyalty event name + payload map.
243
+ *
244
+ * Minimal surface. Loyalty emits events for its own lifecycle transitions
245
+ * only — member, points ledger, tier, redemption, and referral.
246
+ *
247
+ * For registration with an arc-compatible event registry, see
248
+ * `loyalty-event-catalog.ts` in this directory — it exposes each event as
249
+ * a `LoyaltyEventDefinition` with a Zod payload schema + JSON Schema
250
+ * derived via `z.toJSONSchema()` (PACKAGE_RULES §18.5).
251
+ */
252
+ declare const LoyaltyEvents: {
253
+ readonly MEMBER_ENROLLED: "loyalty.member.enrolled";
254
+ readonly MEMBER_DEACTIVATED: "loyalty.member.deactivated";
255
+ readonly MEMBER_REACTIVATED: "loyalty.member.reactivated";
256
+ readonly MEMBER_SUSPENDED: "loyalty.member.suspended";
257
+ readonly POINTS_EARNED: "loyalty.points.earned";
258
+ readonly POINTS_REDEEMED: "loyalty.points.redeemed";
259
+ readonly POINTS_ADJUSTED: "loyalty.points.adjusted";
260
+ readonly POINTS_EXPIRED: "loyalty.points.expired";
261
+ readonly POINTS_EXPIRING_SOON: "loyalty.points.expiring_soon";
262
+ readonly TIER_UPGRADED: "loyalty.tier.upgraded";
263
+ readonly TIER_DOWNGRADED: "loyalty.tier.downgraded";
264
+ readonly TIER_GRACE_STARTED: "loyalty.tier.grace_started";
265
+ readonly TIER_OVERRIDE_CLEARED: "loyalty.tier.override_cleared";
266
+ readonly TIER_OVERRIDE_EXPIRED: "loyalty.tier.override_expired";
267
+ readonly REDEMPTION_RESERVED: "loyalty.redemption.reserved";
268
+ readonly REDEMPTION_CONFIRMED: "loyalty.redemption.confirmed";
269
+ readonly REDEMPTION_RELEASED: "loyalty.redemption.released";
270
+ readonly REDEMPTION_REVERSED: "loyalty.redemption.reversed";
271
+ readonly CAMPAIGN_AWARDED: "loyalty.campaign.awarded";
272
+ readonly REFERRAL_RECORDED: "loyalty.referral.recorded";
273
+ readonly REFERRAL_APPROVED: "loyalty.referral.approved";
274
+ readonly REFERRAL_REJECTED: "loyalty.referral.rejected";
275
+ readonly REFERRAL_REWARDED: "loyalty.referral.rewarded";
276
+ readonly MULTI_TIER_REFERRAL_AWARDED: "loyalty.referral.multi_tier_awarded";
277
+ };
278
+ type LoyaltyEventName = (typeof LoyaltyEvents)[keyof typeof LoyaltyEvents];
279
+ interface MemberLifecyclePayload {
280
+ memberId: string;
281
+ externalId: string;
282
+ externalType: string;
283
+ status: string;
284
+ }
285
+ interface PointsEarnedPayload {
286
+ memberId: string;
287
+ externalId: string;
288
+ externalType: string;
289
+ points: number;
290
+ balanceAfter: number;
291
+ transactionId: string;
292
+ earningRuleName?: string;
293
+ referenceType?: string;
294
+ referenceId?: string;
295
+ }
296
+ interface PointsAdjustedPayload {
297
+ memberId: string;
298
+ externalId: string;
299
+ points: number;
300
+ balanceAfter: number;
301
+ transactionId: string;
302
+ description: string;
303
+ }
304
+ interface PointsExpiredPayload {
305
+ membersAffected: number;
306
+ pointsExpired: number;
307
+ transactionCount: number;
308
+ }
309
+ interface TierChangedPayload {
310
+ memberId: string;
311
+ externalId: string;
312
+ previousTier: string | null;
313
+ newTier: string | null;
314
+ lifetimePoints: number;
315
+ }
316
+ interface RedemptionPayload {
317
+ memberId: string;
318
+ externalId: string;
319
+ redemptionId: string;
320
+ points: number;
321
+ discountAmount: number;
322
+ ownerType: string;
323
+ ownerId: string;
324
+ }
325
+ interface ReferralPayload {
326
+ referralId: string;
327
+ referrerId: string;
328
+ refereeId: string;
329
+ referralCode: string;
330
+ status: string;
331
+ referrerRewardPoints?: number;
332
+ refereeRewardPoints?: number;
333
+ }
334
+ interface TierOverrideLifecyclePayload {
335
+ memberId: string;
336
+ externalId: string;
337
+ tier: string;
338
+ reason?: string;
339
+ /** ISO string — Dates can't be JSON-schema'd. Present only on TTL-sweep path. */
340
+ expiredAt?: string;
341
+ }
342
+ interface RedemptionReversedPayload {
343
+ memberId: string;
344
+ externalId: string;
345
+ redemptionId: string;
346
+ /** Points credited back to the member by the reversal. */
347
+ pointsCredited: number;
348
+ /** Original confirmed points on the redemption. */
349
+ originalPoints: number;
350
+ proportional: boolean;
351
+ reason?: string;
352
+ transactionId: string;
353
+ }
354
+ interface CampaignAwardedPayload {
355
+ campaignId: string;
356
+ memberCount: number;
357
+ awarded: number;
358
+ skipped: number;
359
+ totalPoints: number;
360
+ }
361
+ interface MultiTierReferralAwardedPayload {
362
+ referralId: string;
363
+ refereeId: string;
364
+ /** Awards keyed by ancestor depth (1 = direct referrer). */
365
+ awards: Array<{
366
+ memberId: string;
367
+ depth: number;
368
+ points: number;
369
+ transactionId: string;
370
+ }>;
371
+ }
372
+ interface LoyaltyEventMap {
373
+ [LoyaltyEvents.MEMBER_ENROLLED]: MemberLifecyclePayload;
374
+ [LoyaltyEvents.MEMBER_DEACTIVATED]: MemberLifecyclePayload;
375
+ [LoyaltyEvents.MEMBER_REACTIVATED]: MemberLifecyclePayload;
376
+ [LoyaltyEvents.MEMBER_SUSPENDED]: MemberLifecyclePayload;
377
+ [LoyaltyEvents.POINTS_EARNED]: PointsEarnedPayload;
378
+ [LoyaltyEvents.POINTS_REDEEMED]: PointsAdjustedPayload;
379
+ [LoyaltyEvents.POINTS_ADJUSTED]: PointsAdjustedPayload;
380
+ [LoyaltyEvents.POINTS_EXPIRED]: PointsExpiredPayload;
381
+ [LoyaltyEvents.POINTS_EXPIRING_SOON]: PointsExpiredPayload;
382
+ [LoyaltyEvents.TIER_UPGRADED]: TierChangedPayload;
383
+ [LoyaltyEvents.TIER_DOWNGRADED]: TierChangedPayload;
384
+ [LoyaltyEvents.TIER_GRACE_STARTED]: TierChangedPayload;
385
+ [LoyaltyEvents.TIER_OVERRIDE_CLEARED]: TierOverrideLifecyclePayload;
386
+ [LoyaltyEvents.TIER_OVERRIDE_EXPIRED]: TierOverrideLifecyclePayload;
387
+ [LoyaltyEvents.REDEMPTION_RESERVED]: RedemptionPayload;
388
+ [LoyaltyEvents.REDEMPTION_CONFIRMED]: RedemptionPayload;
389
+ [LoyaltyEvents.REDEMPTION_RELEASED]: RedemptionPayload;
390
+ [LoyaltyEvents.REDEMPTION_REVERSED]: RedemptionReversedPayload;
391
+ [LoyaltyEvents.CAMPAIGN_AWARDED]: CampaignAwardedPayload;
392
+ [LoyaltyEvents.REFERRAL_RECORDED]: ReferralPayload;
393
+ [LoyaltyEvents.REFERRAL_APPROVED]: ReferralPayload;
394
+ [LoyaltyEvents.REFERRAL_REJECTED]: ReferralPayload;
395
+ [LoyaltyEvents.REFERRAL_REWARDED]: ReferralPayload;
396
+ [LoyaltyEvents.MULTI_TIER_REFERRAL_AWARDED]: MultiTierReferralAwardedPayload;
397
+ }
398
+ type LoyaltyEventPayload<E extends LoyaltyEventName> = LoyaltyEventMap[E];
399
+ //#endregion
400
+ export { PointsExpired as A, ReferralRewarded as B, MemberDeactivated as C, MultiTierReferralAwarded as D, MemberSuspended as E, RedemptionReserved as F, TierUpgraded as G, TierGraceStarted as H, RedemptionReversed as I, InProcessLoyaltyBusOptions as J, loyaltyEventDefinitions as K, ReferralApproved as L, PointsRedeemed as M, RedemptionConfirmed as N, PointsAdjusted as O, RedemptionReleased as P, ReferralRecorded as R, LoyaltyEventSchema as S, MemberReactivated as T, TierOverrideCleared as U, TierDowngraded as V, TierOverrideExpired as W, createEvent$1 as Y, TierChangedPayload as _, LoyaltyEventMap as a, LoyaltyEventDefinition as b, LoyaltyEvents as c, PointsAdjustedPayload as d, PointsEarnedPayload as f, ReferralPayload as g, RedemptionReversedPayload as h, CampaignAwardedPayload as i, PointsExpiringSoon as j, PointsEarned as k, MemberLifecyclePayload as l, RedemptionPayload as m, EventHandler$1 as n, LoyaltyEventName as o, PointsExpiredPayload as p, InProcessLoyaltyBus as q, EventTransport$1 as r, LoyaltyEventPayload as s, DomainEvent$1 as t, MultiTierReferralAwardedPayload as u, TierOverrideLifecyclePayload as v, MemberEnrolled as w, LoyaltyEventPayloadOf as x, CampaignAwarded as y, ReferralRejected as z };