@classytic/loyalty 0.7.0 → 0.10.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.
Files changed (32) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/dist/constants-DfrENxFG.mjs +75 -0
  3. package/dist/domain/earn-base.d.mts +35 -0
  4. package/dist/domain/earn-base.mjs +37 -0
  5. package/dist/domain/enums/index.d.mts +2 -2
  6. package/dist/domain/enums/index.mjs +1 -2
  7. package/dist/domain/rule-schedule.d.mts +24 -0
  8. package/dist/domain/rule-schedule.mjs +12 -0
  9. package/dist/events/index.d.mts +2 -2
  10. package/dist/events/index.mjs +3 -3
  11. package/dist/{events-BLjg3uLA.mjs → events-DhZolW61.mjs} +104 -4
  12. package/dist/{index-BIPHUsfR.d.mts → index-BvyzKU7R.d.mts} +283 -34
  13. package/dist/{index-BIhVuwIZ.d.mts → index-CorB0JL6.d.mts} +255 -109
  14. package/dist/index-DRrEhE0r.d.mts +604 -0
  15. package/dist/{index-YUFamhDk.d.mts → index-Db5Gb7x_.d.mts} +187 -39
  16. package/dist/index-tjMMmPzU.d.mts +36 -0
  17. package/dist/index.d.mts +121 -30
  18. package/dist/index.mjs +59 -10
  19. package/dist/{loyalty-events-DXirolM_.mjs → loyalty-events-j29B66YW.mjs} +20 -13
  20. package/dist/models/index.d.mts +2 -2
  21. package/dist/models/index.mjs +1 -2
  22. package/dist/{models-weWqS5Bc.mjs → models-BEGLduz1.mjs} +276 -7
  23. package/dist/notifications/index.d.mts +3 -4
  24. package/dist/repositories/index.d.mts +2 -2
  25. package/dist/repositories/index.mjs +1 -2
  26. package/dist/{repositories-DErtHQou.mjs → repositories-ER68JmUo.mjs} +1161 -99
  27. package/dist/types/index.d.mts +2 -3
  28. package/package.json +39 -22
  29. package/dist/config-CtkGj3xZ.d.mts +0 -178
  30. package/dist/constants-DOPBh6kt.mjs +0 -48
  31. package/dist/index-Cp_sXNpG.d.mts +0 -349
  32. package/dist/index-D_Oe3aDk.d.mts +0 -19
@@ -1,3 +1,2 @@
1
- import { _ as TierEvaluationBatch, a as EnrollInput, c as UpdateTierInput, d as EarningResult, f as ExpirationResult, g as TierEvaluation, h as RedemptionValidation, i as EarnPointsInput, l as BalanceSummary, m as PaginatedResult, n as CreateEarningRuleInput, o as LoyaltyContext, p as ListQuery, r as CreateTierInput, s as UpdateEarningRuleInput, t as AdjustPointsInput, u as EarningBreakdown } from "../index-Cp_sXNpG.mjs";
2
- import { a as ModelName, c as ResolvedConfig, i as LoyaltyShape, l as ResolvedTenant, o as PluginType, r as LoyaltyRuntime, s as RepositoryPlugins, t as IndexDefinition, u as TenantConfig } from "../config-CtkGj3xZ.mjs";
3
- export { AdjustPointsInput, type BalanceSummary, CreateEarningRuleInput, CreateTierInput, EarnPointsInput, type EarningBreakdown, type EarningResult, EnrollInput, type ExpirationResult, type IndexDefinition, type ListQuery, LoyaltyContext, type LoyaltyRuntime, type LoyaltyShape, type ModelName, type PaginatedResult, type PluginType, type RedemptionValidation, type RepositoryPlugins, type ResolvedConfig, type ResolvedTenant, type TenantConfig, type TierEvaluation, type TierEvaluationBatch, UpdateEarningRuleInput, UpdateTierInput };
1
+ import { A as RepositoryPlugins, C as IndexDefinition, D as LoyaltyShape, E as LoyaltyRuntime, M as ResolvedTenant, N as TenantConfig, O as ModelName, _ as RedemptionValidation, a as EnrollInput, c as UpdateTierInput, d as EarningBreakdown, f as EarningResult, g as PaginatedResult, i as EarnPointsInput, j as ResolvedConfig, k as PluginType, l as BalanceSummary, m as ListQuery, n as CreateEarningRuleInput, o as LoyaltyContext, p as ExpirationResult, r as CreateTierInput, s as UpdateEarningRuleInput, t as AdjustPointsInput, u as EarnReversalResult, v as TierEvaluation, y as TierEvaluationBatch } from "../index-DRrEhE0r.mjs";
2
+ export { AdjustPointsInput, type BalanceSummary, CreateEarningRuleInput, CreateTierInput, EarnPointsInput, type EarnReversalResult, type EarningBreakdown, type EarningResult, EnrollInput, type ExpirationResult, type IndexDefinition, type ListQuery, LoyaltyContext, type LoyaltyRuntime, type LoyaltyShape, type ModelName, type PaginatedResult, type PluginType, type RedemptionValidation, type RepositoryPlugins, type ResolvedConfig, type ResolvedTenant, type TenantConfig, type TierEvaluation, type TierEvaluationBatch, UpdateEarningRuleInput, UpdateTierInput };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/loyalty",
3
- "version": "0.7.0",
3
+ "version": "0.10.0",
4
4
  "description": "Loyalty points, tiers, earning rules, referrals, and redemption engine for MongoDB",
5
5
  "author": "Classytic",
6
6
  "homepage": "https://www.npmjs.com/package/@classytic/loyalty",
@@ -21,30 +21,47 @@
21
21
  },
22
22
  "exports": {
23
23
  ".": {
24
+ "@classytic/source": "./src/index.ts",
24
25
  "types": "./dist/index.d.mts",
25
26
  "default": "./dist/index.mjs"
26
27
  },
27
28
  "./domain/enums": {
29
+ "@classytic/source": "./src/domain/enums/index.ts",
28
30
  "types": "./dist/domain/enums/index.d.mts",
29
31
  "default": "./dist/domain/enums/index.mjs"
30
32
  },
33
+ "./domain/rule-schedule": {
34
+ "@classytic/source": "./src/domain/rule-schedule.ts",
35
+ "types": "./dist/domain/rule-schedule.d.mts",
36
+ "default": "./dist/domain/rule-schedule.mjs"
37
+ },
38
+ "./domain/earn-base": {
39
+ "@classytic/source": "./src/domain/earn-base.ts",
40
+ "types": "./dist/domain/earn-base.d.mts",
41
+ "default": "./dist/domain/earn-base.mjs"
42
+ },
31
43
  "./models": {
44
+ "@classytic/source": "./src/models/index.ts",
32
45
  "types": "./dist/models/index.d.mts",
33
46
  "default": "./dist/models/index.mjs"
34
47
  },
35
48
  "./repositories": {
49
+ "@classytic/source": "./src/repositories/index.ts",
36
50
  "types": "./dist/repositories/index.d.mts",
37
51
  "default": "./dist/repositories/index.mjs"
38
52
  },
39
53
  "./events": {
54
+ "@classytic/source": "./src/events/index.ts",
40
55
  "types": "./dist/events/index.d.mts",
41
56
  "default": "./dist/events/index.mjs"
42
57
  },
43
58
  "./types": {
59
+ "@classytic/source": "./src/types/index.ts",
44
60
  "types": "./dist/types/index.d.mts",
45
61
  "default": "./dist/types/index.mjs"
46
62
  },
47
63
  "./notifications": {
64
+ "@classytic/source": "./src/notifications/index.ts",
48
65
  "types": "./dist/notifications/index.d.mts",
49
66
  "default": "./dist/notifications/index.mjs"
50
67
  }
@@ -78,30 +95,30 @@
78
95
  "release": "npm run push -- main && npm run release:tag && npm publish"
79
96
  },
80
97
  "peerDependencies": {
81
- "@classytic/mongokit": ">=3.38.1",
82
- "@classytic/primitives": ">=0.27.0",
83
- "@classytic/repo-core": ">=0.27.1",
84
- "@classytic/validation": ">=0.5.0",
85
- "mongoose": ">=9.4.1",
98
+ "@classytic/mongokit": ">=3.41.0",
99
+ "@classytic/primitives": ">=0.32.0",
100
+ "@classytic/repo-core": ">=0.31.0",
101
+ "@classytic/validation": ">=0.6.0",
102
+ "mongoose": ">=9.11.0",
86
103
  "zod": ">=4.0.0"
87
104
  },
88
105
  "devDependencies": {
89
- "@biomejs/biome": "^2.4.9",
90
- "@classytic/dev-tools": "^0.2.0",
91
- "@classytic/mongokit": "^3.38.1",
92
- "@classytic/primitives": ">=0.27.0",
93
- "@classytic/repo-core": ">=0.27.1",
94
- "@classytic/validation": ">=0.5.0",
95
- "@types/node": "^25.5.0",
96
- "@vitest/coverage-v8": "^3.2.4",
97
- "knip": "^6.3.0",
98
- "mongodb-memory-server": "^10.2.3",
99
- "mongoose": "^9.4.1",
100
- "publint": "^0.3.23",
101
- "tsdown": "^0.22.14",
102
- "typescript": "^5.7.0",
103
- "vitest": "^3.0.0",
104
- "zod": "^4.3.6"
106
+ "@biomejs/biome": "^2.5.15",
107
+ "@classytic/dev-tools": "^0.2.1",
108
+ "@classytic/mongokit": "^3.43.0",
109
+ "@classytic/primitives": "^0.34.0",
110
+ "@classytic/repo-core": "^0.31.1",
111
+ "@classytic/validation": "^0.6.0",
112
+ "@types/node": "^26.6.5",
113
+ "@vitest/coverage-v8": "^5.0.5",
114
+ "knip": "^6.41.0",
115
+ "mongodb-memory-server": "^11.3.0",
116
+ "mongoose": "^9.11.2",
117
+ "publint": "^0.3.25",
118
+ "tsdown": "^0.23.1",
119
+ "typescript": "^7.0.2",
120
+ "vitest": "^5.0.5",
121
+ "zod": "^4.6.7"
105
122
  },
106
123
  "keywords": [
107
124
  "loyalty",
@@ -1,178 +0,0 @@
1
- import { t as NotificationAdapter } from "./notification.port-wY4IKimz.mjs";
2
- import { ResolvedTenantConfig, TenantConfig } from "@classytic/repo-core/tenant";
3
- import { EventTransport } from "@classytic/primitives/events";
4
- import { OutboxStore } from "@classytic/primitives/outbox";
5
- //#region src/types/config.d.ts
6
- type LoyaltyModelName = 'Member' | 'PointTransaction' | 'EarningRule' | 'TierDefinition' | 'Redemption' | 'Referral';
7
- type TenantConfig$1 = TenantConfig | boolean;
8
- /** @deprecated Use `ResolvedTenantConfig` from `@classytic/repo-core/tenant`. */
9
- type ResolvedTenant = ResolvedTenantConfig;
10
- interface IndexDefinition {
11
- fields: Record<string, 1 | -1>;
12
- options?: Record<string, unknown> | undefined;
13
- }
14
- type ModelName = 'member' | 'pointTransaction' | 'earningRule' | 'tierDefinition' | 'redemption' | 'referral';
15
- type PluginType = unknown;
16
- interface RepositoryPlugins {
17
- member?: PluginType[] | undefined;
18
- pointTransaction?: PluginType[] | undefined;
19
- earningRule?: PluginType[] | undefined;
20
- tierDefinition?: PluginType[] | undefined;
21
- redemption?: PluginType[] | undefined;
22
- referral?: PluginType[] | undefined;
23
- }
24
- interface LoyaltyShape {
25
- tenant?: TenantConfig$1 | undefined;
26
- /**
27
- * IANA timezone name (e.g. `'Asia/Dhaka'`, `'America/New_York'`) used to
28
- * evaluate wall-clock rule conditions — currently `EarningConditions.dayOfWeek`
29
- * ("2× points on Fridays"). Resolved DST-exact per instant via
30
- * `@classytic/primitives/timezone`. Validated at boot: an unknown zone throws
31
- * `ValidationError`, never a silent mis-evaluation.
32
- *
33
- * Omitted → **UTC** (the day boundary is the UTC calendar day). Either way the
34
- * result NEVER depends on the deploy machine's `TZ` env. PACKAGE_RULES P12.
35
- */
36
- timezone?: string | undefined;
37
- program?: {
38
- id?: string | undefined;
39
- /**
40
- * RATE: integer minor units ONE point redeems for (≥ 1) in the host's
41
- * ambient currency. `pointValueMinor: 10` = 1 point → 10 paisa
42
- * (৳0.10, i.e. the old `conversionRate: 10` "10 points per ৳1").
43
- * Replaces `conversionRate` (0.5.x), whose implicit per-1-MAJOR-unit
44
- * basis was ambiguous.
45
- */
46
- pointValueMinor?: number | undefined;
47
- } | undefined;
48
- redemption?: {
49
- minPoints?: number | undefined;
50
- /**
51
- * Minimum order total eligible for redemption — **integer minor
52
- * units** (paisa for BDT). Compared against `validate()`'s
53
- * `orderTotal` (also minor units).
54
- */
55
- minOrderAmount?: number | undefined;
56
- maxRedeemPercent?: number | undefined;
57
- reservationTtlMinutes?: number | undefined;
58
- } | undefined;
59
- referral?: {
60
- referrerRewardPoints?: number | undefined;
61
- refereeRewardPoints?: number | undefined;
62
- maxPerPeriod?: number | undefined;
63
- periodDays?: number | undefined;
64
- requireApproval?: boolean | undefined;
65
- codeLength?: number | undefined;
66
- /**
67
- * Maximum ancestor depth for multi-tier referral rewards. When >= 2,
68
- * the direct referrer gets `tierRates[0]` percent of
69
- * `referrerRewardPoints`, the 2nd-tier ancestor gets `tierRates[1]`,
70
- * etc. Depth 1 = direct referrer (matches single-hop legacy path).
71
- * Default: 1 (single-hop, preserves prior behaviour).
72
- */
73
- maxDepth?: number | undefined;
74
- /**
75
- * Percent rates (0–100) per depth. `tierRates[0]` is the direct
76
- * referrer's share. Omitted depths fall back to 0. Example:
77
- * `{ maxDepth: 3, tierRates: [100, 50, 25] }` — direct gets 100%,
78
- * grand-referrer 50%, great-grand 25%.
79
- */
80
- tierRates?: number[] | undefined;
81
- } | undefined;
82
- expiry?: {
83
- enabled?: boolean | undefined;
84
- defaultDays?: number | undefined;
85
- } | undefined;
86
- indexes?: Partial<Record<ModelName, IndexDefinition[]>> | undefined;
87
- autoIndex?: boolean | Partial<Record<LoyaltyModelName, boolean>> | undefined;
88
- /**
89
- * Optional prefix prepended to every physical collection this package
90
- * creates (see PACKAGE_RULES.md §20.1). Unset → default names
91
- * (`loyalty_members`, `loyalty_point_transactions`, `loyalty_earning_rules`,
92
- * `loyalty_tier_definitions`, `loyalty_redemptions`, `loyalty_referrals`).
93
- * Model names and `ref:` populate are unaffected.
94
- */
95
- collectionPrefix?: string | undefined;
96
- /**
97
- * When true, existing Mongoose models with loyalty's names are deleted
98
- * from the connection before re-registering. Hot-reload / test fixtures
99
- * only. Default `false` — collision throws mongokit's `ModelCollisionError`.
100
- * Hosts that need two loyalty engines should use two Mongoose connections
101
- * (`mongoose.createConnection(...)`). See PACKAGE_RULES.md §21.
102
- */
103
- forceRecreate?: boolean | undefined;
104
- }
105
- interface LoyaltyRuntime {
106
- /**
107
- * Arc-compatible event transport. When omitted, the engine creates (and
108
- * OWNS, so `close()` closes) an `InProcessLoyaltyBus` — a ~60-line structural
109
- * match of arc's `MemoryEventTransport`. A host-supplied transport is the
110
- * host's to close. See PACKAGE_RULES §13.
111
- */
112
- eventTransport?: EventTransport | undefined;
113
- /**
114
- * Host-owned outbox store (PACKAGE_RULES §5.5 + P8). When present, every
115
- * domain event is persisted via `outbox.save(event, { session })` **before**
116
- * `eventTransport.publish(event)`. `session` is threaded from `ctx.session`
117
- * so the outbox row commits atomically with the business write.
118
- *
119
- * Loyalty does NOT ship a store. Hosts wire arc's `repositoryAsOutboxStore(mongokitRepo)`
120
- * over their own `event_outbox` collection, arc's `MemoryOutboxStore`, or any
121
- * custom Postgres / Redis / Kafka implementation of the contract. When
122
- * omitted, events flow through `eventTransport` only (no durable log).
123
- */
124
- outbox?: OutboxStore | undefined;
125
- notifications?: NotificationAdapter | undefined;
126
- plugins?: RepositoryPlugins | undefined;
127
- /**
128
- * Skip the boot-time capability gate that asserts the backend supports
129
- * multi-document `transactions`. Loyalty's point-mutation verbs (earn,
130
- * adjust, reserve, confirm, release, reverse, processExpirations) run inside
131
- * `withTransaction`; without a replica set those writes are NOT atomic.
132
- * Leave `false` (default) in production — set `true` only for local-dev on
133
- * standalone Mongo, accepting partial-write risk. See PACKAGE_RULES
134
- * "Runtime capabilities".
135
- */
136
- allowNonTransactional?: boolean | undefined;
137
- /**
138
- * Where the engine's boot warnings go — today, the `allowNonTransactional`
139
- * downgrade notice. Defaults to `console`. A downgrade that carries
140
- * partial-write risk on stored value must be VISIBLE, and a host that routes
141
- * logs elsewhere would otherwise never see it.
142
- */
143
- logger?: {
144
- warn?(message: string, ...args: unknown[]): void;
145
- error?(message: string, ...args: unknown[]): void;
146
- } | undefined;
147
- }
148
- interface ResolvedConfig {
149
- programId: string;
150
- /** Integer minor units one point redeems for (≥ 1). See `LoyaltyShape.program.pointValueMinor`. */
151
- pointValueMinor: number;
152
- redemption: {
153
- minPoints: number;
154
- /** Integer minor units. */
155
- minOrderAmount: number;
156
- maxRedeemPercent: number;
157
- reservationTtlMinutes: number;
158
- };
159
- referral: {
160
- referrerRewardPoints: number;
161
- refereeRewardPoints: number;
162
- maxPerPeriod: number;
163
- periodDays: number;
164
- requireApproval: boolean;
165
- codeLength: number;
166
- maxDepth: number;
167
- tierRates: number[];
168
- };
169
- expiry: {
170
- enabled: boolean;
171
- defaultDays?: number;
172
- };
173
- /** Resolved IANA zone for wall-clock rule evaluation; `undefined` = UTC. */
174
- timezone?: string;
175
- tenant: ResolvedTenantConfig;
176
- }
177
- //#endregion
178
- export { ModelName as a, ResolvedConfig as c, LoyaltyShape as i, ResolvedTenant as l, LoyaltyModelName as n, PluginType as o, LoyaltyRuntime as r, RepositoryPlugins as s, IndexDefinition as t, TenantConfig$1 as u };
@@ -1,48 +0,0 @@
1
- //#region src/constants.ts
2
- const DEFAULT_PROGRAM_ID = "default";
3
- const TRANSACTION_TYPES = Object.freeze([
4
- "earn",
5
- "redeem",
6
- "adjust",
7
- "expire",
8
- "transfer",
9
- "referral_bonus"
10
- ]);
11
- const MEMBER_STATUSES = Object.freeze([
12
- "active",
13
- "inactive",
14
- "suspended"
15
- ]);
16
- const RULE_TYPES = Object.freeze([
17
- "order",
18
- "action",
19
- "category",
20
- "tier_bonus"
21
- ]);
22
- const RULE_STATUSES = Object.freeze([
23
- "active",
24
- "paused",
25
- "expired"
26
- ]);
27
- const REFERRAL_STATUSES = Object.freeze([
28
- "pending",
29
- "approved",
30
- "rejected",
31
- "expired"
32
- ]);
33
- const REDEMPTION_STATUSES = Object.freeze([
34
- "reserved",
35
- "confirmed",
36
- "released",
37
- "expired",
38
- "reversed"
39
- ]);
40
- const EARNING_ACTIONS = Object.freeze([
41
- "signup",
42
- "referral",
43
- "birthday",
44
- "review",
45
- "profile_complete"
46
- ]);
47
- //#endregion
48
- export { REFERRAL_STATUSES as a, TRANSACTION_TYPES as c, REDEMPTION_STATUSES as i, EARNING_ACTIONS as n, RULE_STATUSES as o, MEMBER_STATUSES as r, RULE_TYPES as s, DEFAULT_PROGRAM_ID as t };