@higher.archi/boe 1.0.28 → 1.0.30
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/dist/engines/decay/engine.d.ts +32 -1
- package/dist/engines/decay/engine.d.ts.map +1 -1
- package/dist/engines/decay/engine.js +69 -0
- package/dist/engines/decay/engine.js.map +1 -1
- package/dist/engines/decay/index.d.ts +1 -1
- package/dist/engines/decay/index.d.ts.map +1 -1
- package/dist/engines/decay/index.js.map +1 -1
- package/dist/engines/decay/strategy.d.ts +4 -2
- package/dist/engines/decay/strategy.d.ts.map +1 -1
- package/dist/engines/decay/strategy.js +24 -0
- package/dist/engines/decay/strategy.js.map +1 -1
- package/dist/engines/decay/types.d.ts +9 -0
- package/dist/engines/decay/types.d.ts.map +1 -1
- package/dist/engines/loyalty/compiler.d.ts +11 -0
- package/dist/engines/loyalty/compiler.d.ts.map +1 -0
- package/dist/engines/loyalty/compiler.js +144 -0
- package/dist/engines/loyalty/compiler.js.map +1 -0
- package/dist/engines/loyalty/engine.d.ts +76 -0
- package/dist/engines/loyalty/engine.d.ts.map +1 -0
- package/dist/engines/loyalty/engine.js +132 -0
- package/dist/engines/loyalty/engine.js.map +1 -0
- package/dist/engines/loyalty/index.d.ts +8 -0
- package/dist/engines/loyalty/index.d.ts.map +1 -0
- package/dist/engines/loyalty/index.js +17 -0
- package/dist/engines/loyalty/index.js.map +1 -0
- package/dist/engines/loyalty/strategy.d.ts +35 -0
- package/dist/engines/loyalty/strategy.d.ts.map +1 -0
- package/dist/engines/loyalty/strategy.js +405 -0
- package/dist/engines/loyalty/strategy.js.map +1 -0
- package/dist/engines/loyalty/types.d.ts +190 -0
- package/dist/engines/loyalty/types.d.ts.map +1 -0
- package/dist/engines/loyalty/types.js +11 -0
- package/dist/engines/loyalty/types.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engines/decay/engine.ts +93 -1
- package/src/engines/decay/index.ts +2 -1
- package/src/engines/decay/strategy.ts +33 -0
- package/src/engines/decay/types.ts +10 -0
- package/src/engines/loyalty/compiler.ts +174 -0
- package/src/engines/loyalty/engine.ts +174 -0
- package/src/engines/loyalty/index.ts +43 -0
- package/src/engines/loyalty/strategy.ts +532 -0
- package/src/engines/loyalty/types.ts +252 -0
- package/src/index.ts +39 -1
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loyalty Engine Types
|
|
3
|
+
*
|
|
4
|
+
* Point ledger engine that manages earning rules with category multipliers,
|
|
5
|
+
* point transactions (earn/redeem/transfer/expire), tier-qualified balances,
|
|
6
|
+
* and promotion stacking. Unlike other BOE engines, the Loyalty engine
|
|
7
|
+
* maintains running balance state across operations.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { Condition } from '../../core/types/condition';
|
|
11
|
+
|
|
12
|
+
// ========================================
|
|
13
|
+
// Semantic Types
|
|
14
|
+
// ========================================
|
|
15
|
+
|
|
16
|
+
/** Loyalty strategy to use */
|
|
17
|
+
export type LoyaltyStrategy = 'earning' | 'redemption' | 'tier-evaluation';
|
|
18
|
+
|
|
19
|
+
/** Point transaction type */
|
|
20
|
+
export type PointTransactionType = 'earn' | 'redeem' | 'expire' | 'transfer' | 'adjust';
|
|
21
|
+
|
|
22
|
+
/** Member tier status */
|
|
23
|
+
export type TierStatus = 'qualified' | 'at-risk' | 'downgrade-pending' | 'locked';
|
|
24
|
+
|
|
25
|
+
/** Qualifying metric for tier evaluation */
|
|
26
|
+
export type QualifyingMetric = 'points-earned' | 'qualifying-spend' | 'qualifying-nights' | 'qualifying-flights';
|
|
27
|
+
|
|
28
|
+
/** Evaluation period for tier assessment */
|
|
29
|
+
export type EvaluationPeriod = 'rolling-12-months' | 'calendar-year' | 'custom';
|
|
30
|
+
|
|
31
|
+
// ========================================
|
|
32
|
+
// Core Domain Types
|
|
33
|
+
// ========================================
|
|
34
|
+
|
|
35
|
+
/** An earning rule that maps activities to points */
|
|
36
|
+
export type EarningRule = {
|
|
37
|
+
id: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
category?: string;
|
|
40
|
+
baseRate: number;
|
|
41
|
+
multiplier?: number;
|
|
42
|
+
conditions?: Condition[];
|
|
43
|
+
bonusPoints?: number;
|
|
44
|
+
promotionId?: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** A redemption option specifying how points can be spent */
|
|
48
|
+
export type RedemptionOption = {
|
|
49
|
+
id: string;
|
|
50
|
+
name?: string;
|
|
51
|
+
type: string;
|
|
52
|
+
pointsRequired: number;
|
|
53
|
+
value: number;
|
|
54
|
+
unit?: string;
|
|
55
|
+
conditions?: Condition[];
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** A tier definition with qualifying thresholds and benefits */
|
|
59
|
+
export type LoyaltyTierDefinition = {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
qualifyingThreshold: number;
|
|
63
|
+
qualifyingMetric: QualifyingMetric;
|
|
64
|
+
benefits: string[];
|
|
65
|
+
multiplierBonus?: number;
|
|
66
|
+
retentionThreshold?: number;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** A promotion rule that stacks multipliers or bonus points */
|
|
70
|
+
export type PromotionRule = {
|
|
71
|
+
id: string;
|
|
72
|
+
name?: string;
|
|
73
|
+
multiplier?: number;
|
|
74
|
+
bonusPoints?: number;
|
|
75
|
+
categories?: string[];
|
|
76
|
+
startDate?: string;
|
|
77
|
+
endDate?: string;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/** Expiration policy for points */
|
|
81
|
+
export type ExpirationPolicy = {
|
|
82
|
+
inactivityDays?: number;
|
|
83
|
+
absoluteMonths?: number;
|
|
84
|
+
graceDays?: number;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// ========================================
|
|
88
|
+
// Ledger Types (First-Class State)
|
|
89
|
+
// ========================================
|
|
90
|
+
|
|
91
|
+
/** A single point transaction record */
|
|
92
|
+
export type PointTransaction = {
|
|
93
|
+
id: string;
|
|
94
|
+
memberId: string;
|
|
95
|
+
type: PointTransactionType;
|
|
96
|
+
points: number;
|
|
97
|
+
category?: string;
|
|
98
|
+
ruleId?: string;
|
|
99
|
+
timestamp: string;
|
|
100
|
+
metadata?: Record<string, any>;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/** Running balance for a member */
|
|
104
|
+
export type MemberBalance = {
|
|
105
|
+
memberId: string;
|
|
106
|
+
totalEarned: number;
|
|
107
|
+
totalRedeemed: number;
|
|
108
|
+
totalExpired: number;
|
|
109
|
+
currentBalance: number;
|
|
110
|
+
qualifyingPoints: number;
|
|
111
|
+
currentTier?: string;
|
|
112
|
+
tierQualifiedAt?: string;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// ========================================
|
|
116
|
+
// Source RuleSet Types (Discriminated Union)
|
|
117
|
+
// ========================================
|
|
118
|
+
|
|
119
|
+
type LoyaltyRuleSetBase = {
|
|
120
|
+
id: string;
|
|
121
|
+
name?: string;
|
|
122
|
+
mode: 'loyalty';
|
|
123
|
+
tiers?: LoyaltyTierDefinition[];
|
|
124
|
+
expirationPolicy?: ExpirationPolicy;
|
|
125
|
+
promotions?: PromotionRule[];
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/** Earning strategy: compute points earned from purchase/activity events */
|
|
129
|
+
export type EarningRuleSet = LoyaltyRuleSetBase & {
|
|
130
|
+
strategy: 'earning';
|
|
131
|
+
earningRules: EarningRule[];
|
|
132
|
+
defaultRate?: number;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/** Redemption strategy: process point redemption requests */
|
|
136
|
+
export type RedemptionRuleSet = LoyaltyRuleSetBase & {
|
|
137
|
+
strategy: 'redemption';
|
|
138
|
+
redemptionOptions: RedemptionOption[];
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/** Tier evaluation strategy: evaluate members against tier thresholds */
|
|
142
|
+
export type TierEvaluationRuleSet = LoyaltyRuleSetBase & {
|
|
143
|
+
strategy: 'tier-evaluation';
|
|
144
|
+
evaluationPeriod?: EvaluationPeriod;
|
|
145
|
+
tiers: LoyaltyTierDefinition[];
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export type LoyaltyRuleSet =
|
|
149
|
+
| EarningRuleSet
|
|
150
|
+
| RedemptionRuleSet
|
|
151
|
+
| TierEvaluationRuleSet;
|
|
152
|
+
|
|
153
|
+
// ========================================
|
|
154
|
+
// Compiled RuleSet Types
|
|
155
|
+
// ========================================
|
|
156
|
+
|
|
157
|
+
type CompiledLoyaltyRuleSetBase = {
|
|
158
|
+
id: string;
|
|
159
|
+
name?: string;
|
|
160
|
+
mode: 'loyalty';
|
|
161
|
+
tiers: LoyaltyTierDefinition[];
|
|
162
|
+
expirationPolicy: ExpirationPolicy;
|
|
163
|
+
promotions: PromotionRule[];
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export type CompiledEarningRuleSet = CompiledLoyaltyRuleSetBase & {
|
|
167
|
+
strategy: 'earning';
|
|
168
|
+
earningRules: EarningRule[];
|
|
169
|
+
defaultRate: number;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export type CompiledRedemptionRuleSet = CompiledLoyaltyRuleSetBase & {
|
|
173
|
+
strategy: 'redemption';
|
|
174
|
+
redemptionOptions: RedemptionOption[];
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export type CompiledTierEvaluationRuleSet = CompiledLoyaltyRuleSetBase & {
|
|
178
|
+
strategy: 'tier-evaluation';
|
|
179
|
+
evaluationPeriod: EvaluationPeriod;
|
|
180
|
+
tiers: LoyaltyTierDefinition[];
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export type CompiledLoyaltyRuleSet =
|
|
184
|
+
| CompiledEarningRuleSet
|
|
185
|
+
| CompiledRedemptionRuleSet
|
|
186
|
+
| CompiledTierEvaluationRuleSet;
|
|
187
|
+
|
|
188
|
+
// ========================================
|
|
189
|
+
// Result Types
|
|
190
|
+
// ========================================
|
|
191
|
+
|
|
192
|
+
/** Result from earning strategy execution */
|
|
193
|
+
export type EarningResult = {
|
|
194
|
+
memberId: string;
|
|
195
|
+
transactions: PointTransaction[];
|
|
196
|
+
pointsEarned: number;
|
|
197
|
+
bonusPointsEarned: number;
|
|
198
|
+
promotionsApplied: string[];
|
|
199
|
+
newBalance: number;
|
|
200
|
+
executionTimeMs: number;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
/** Result from redemption strategy execution */
|
|
204
|
+
export type RedemptionResult = {
|
|
205
|
+
memberId: string;
|
|
206
|
+
redemption: PointTransaction;
|
|
207
|
+
pointsRedeemed: number;
|
|
208
|
+
redemptionValue: number;
|
|
209
|
+
remainingBalance: number;
|
|
210
|
+
executionTimeMs: number;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
/** Per-member tier evaluation result */
|
|
214
|
+
export type MemberTierResult = {
|
|
215
|
+
memberId: string;
|
|
216
|
+
currentTier: string;
|
|
217
|
+
previousTier?: string;
|
|
218
|
+
qualifyingPoints: number;
|
|
219
|
+
nextTierThreshold?: number;
|
|
220
|
+
pointsToNextTier?: number;
|
|
221
|
+
status: TierStatus;
|
|
222
|
+
benefits: string[];
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
/** Result from tier-evaluation strategy execution */
|
|
226
|
+
export type TierEvaluationResult = {
|
|
227
|
+
members: MemberTierResult[];
|
|
228
|
+
tierDistribution: Record<string, number>;
|
|
229
|
+
executionTimeMs: number;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
/** Union of all loyalty results */
|
|
233
|
+
export type LoyaltyResult = EarningResult | RedemptionResult | TierEvaluationResult;
|
|
234
|
+
|
|
235
|
+
// ========================================
|
|
236
|
+
// Runtime Types
|
|
237
|
+
// ========================================
|
|
238
|
+
|
|
239
|
+
/** Options for earning execution */
|
|
240
|
+
export type LoyaltyOptions = {
|
|
241
|
+
asOf?: Date;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
/** Result from ingest() -- streaming earning with running balance */
|
|
245
|
+
export type LoyaltyIngestResult = {
|
|
246
|
+
memberId: string;
|
|
247
|
+
pointsEarned: number;
|
|
248
|
+
bonusPointsEarned: number;
|
|
249
|
+
promotionsApplied: string[];
|
|
250
|
+
newBalance: number;
|
|
251
|
+
transactions: PointTransaction[];
|
|
252
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -34,6 +34,7 @@ export { EnsembleEngine } from './engines/ensemble';
|
|
|
34
34
|
export { SentimentEngine } from './engines/sentiment';
|
|
35
35
|
export { NegotiationEngine } from './engines/negotiation';
|
|
36
36
|
export { DecayEngine } from './engines/decay';
|
|
37
|
+
export { LoyaltyEngine } from './engines/loyalty';
|
|
37
38
|
|
|
38
39
|
// ========================================
|
|
39
40
|
// Core Types & Utilities
|
|
@@ -581,9 +582,46 @@ export type {
|
|
|
581
582
|
ReEngagementEvent,
|
|
582
583
|
EntityDecayResult,
|
|
583
584
|
DecayResult,
|
|
584
|
-
DecayOptions
|
|
585
|
+
DecayOptions,
|
|
586
|
+
DecayIngestResult
|
|
585
587
|
} from './engines/decay';
|
|
586
588
|
|
|
589
|
+
// Loyalty
|
|
590
|
+
export {
|
|
591
|
+
LoyaltyExecutor,
|
|
592
|
+
compileLoyaltyRuleSet,
|
|
593
|
+
loyaltyStrategy
|
|
594
|
+
} from './engines/loyalty';
|
|
595
|
+
export type {
|
|
596
|
+
LoyaltyStrategy,
|
|
597
|
+
PointTransactionType,
|
|
598
|
+
TierStatus,
|
|
599
|
+
QualifyingMetric,
|
|
600
|
+
EvaluationPeriod,
|
|
601
|
+
EarningRule,
|
|
602
|
+
RedemptionOption,
|
|
603
|
+
LoyaltyTierDefinition,
|
|
604
|
+
PromotionRule,
|
|
605
|
+
ExpirationPolicy,
|
|
606
|
+
PointTransaction,
|
|
607
|
+
MemberBalance,
|
|
608
|
+
EarningRuleSet,
|
|
609
|
+
RedemptionRuleSet,
|
|
610
|
+
TierEvaluationRuleSet,
|
|
611
|
+
LoyaltyRuleSet,
|
|
612
|
+
CompiledEarningRuleSet,
|
|
613
|
+
CompiledRedemptionRuleSet,
|
|
614
|
+
CompiledTierEvaluationRuleSet,
|
|
615
|
+
CompiledLoyaltyRuleSet,
|
|
616
|
+
EarningResult,
|
|
617
|
+
RedemptionResult,
|
|
618
|
+
MemberTierResult,
|
|
619
|
+
TierEvaluationResult,
|
|
620
|
+
LoyaltyResult,
|
|
621
|
+
LoyaltyOptions,
|
|
622
|
+
LoyaltyIngestResult
|
|
623
|
+
} from './engines/loyalty';
|
|
624
|
+
|
|
587
625
|
// ========================================
|
|
588
626
|
// Utility Functions (from old modules, re-exported for convenience)
|
|
589
627
|
// ========================================
|