@classytic/revenue 1.1.3 → 2.0.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 (82) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +638 -632
  3. package/dist/audit-B39B0Sdq.mjs +53 -0
  4. package/dist/audit-DZ0eTr9g.d.mts +89 -0
  5. package/dist/bridges/index.d.mts +2 -0
  6. package/dist/bridges/index.mjs +1 -0
  7. package/dist/context-DRqSeTPM.d.mts +35 -0
  8. package/dist/core/state-machines.d.mts +35 -0
  9. package/dist/core/state-machines.mjs +134 -0
  10. package/dist/engine-types-CcjIb4Fy.d.mts +611 -0
  11. package/dist/enums/index.d.mts +3 -157
  12. package/dist/enums/index.mjs +3 -55
  13. package/dist/errors-DHa8JVQ-.mjs +92 -0
  14. package/dist/escrow.schema-BBv9oVEW.mjs +322 -0
  15. package/dist/escrow.schema-CC8XuD46.d.mts +629 -0
  16. package/dist/event-constants-CEMitnIV.mjs +53 -0
  17. package/dist/events/index.d.mts +3 -0
  18. package/dist/events/index.mjs +4 -0
  19. package/dist/index.d.mts +77 -9
  20. package/dist/index.mjs +465 -29
  21. package/dist/monetization.enums-BtiU3t8o.mjs +39 -0
  22. package/dist/monetization.enums-D2xbxXJM.d.mts +34 -0
  23. package/dist/plugins/plugin.interface.d.mts +28 -0
  24. package/dist/plugins/plugin.interface.mjs +26 -0
  25. package/dist/providers/index.d.mts +2 -3
  26. package/dist/providers/index.mjs +2 -2
  27. package/dist/{base-DCoyIUj6.mjs → registry-DhFMsSn5.mjs} +34 -36
  28. package/dist/{base-CsTlVQJe.d.mts → registry-SvIGPAx_.d.mts} +73 -66
  29. package/dist/repositories/create-repositories.d.mts +21 -0
  30. package/dist/repositories/create-repositories.mjs +12 -0
  31. package/dist/revenue-bridges-sdlrR85c.d.mts +145 -0
  32. package/dist/revenue-event-catalog-BX3g7RUi.d.mts +823 -0
  33. package/dist/revenue-event-catalog-LqxPnsU_.mjs +388 -0
  34. package/dist/settlement.repository-Cy3mMWGH.mjs +771 -0
  35. package/dist/shared/index.d.mts +2 -0
  36. package/dist/shared/index.mjs +4 -0
  37. package/dist/split.enums-CQE3ekH1.mjs +172 -0
  38. package/dist/split.enums-Dw4zCrcZ.d.mts +154 -0
  39. package/dist/splits-BAfY-a9P.mjs +123 -0
  40. package/dist/validators/index.d.mts +2 -0
  41. package/dist/validators/index.mjs +3 -0
  42. package/package.json +32 -36
  43. package/dist/application/services/index.d.mts +0 -4
  44. package/dist/application/services/index.mjs +0 -3
  45. package/dist/category-resolver-DV83N8ok.mjs +0 -284
  46. package/dist/commission-split-BzB8cd39.mjs +0 -485
  47. package/dist/core/events.d.mts +0 -294
  48. package/dist/core/events.mjs +0 -100
  49. package/dist/core/index.d.mts +0 -9
  50. package/dist/core/index.mjs +0 -8
  51. package/dist/errors-CorrWz7A.d.mts +0 -787
  52. package/dist/escrow.enums-CZGrrdg7.mjs +0 -101
  53. package/dist/escrow.enums-DwdLuuve.d.mts +0 -78
  54. package/dist/idempotency-DaYcUGY1.mjs +0 -172
  55. package/dist/index-Dsp7H5Wb.d.mts +0 -471
  56. package/dist/infrastructure/plugins/index.d.mts +0 -239
  57. package/dist/infrastructure/plugins/index.mjs +0 -345
  58. package/dist/money-CvrDOijQ.mjs +0 -271
  59. package/dist/money-DPG8AtJ8.d.mts +0 -112
  60. package/dist/payment.enums-HAuAS9Pp.d.mts +0 -70
  61. package/dist/payment.enums-tEFVa-Xp.mjs +0 -69
  62. package/dist/plugin-BbK0OVHy.d.mts +0 -327
  63. package/dist/plugin-Cd_V04Em.mjs +0 -210
  64. package/dist/reconciliation/index.d.mts +0 -193
  65. package/dist/reconciliation/index.mjs +0 -192
  66. package/dist/retry-HHCOXYdn.d.mts +0 -186
  67. package/dist/revenue-9scqKSef.mjs +0 -553
  68. package/dist/schemas/index.d.mts +0 -2665
  69. package/dist/schemas/index.mjs +0 -717
  70. package/dist/schemas/validation.d.mts +0 -375
  71. package/dist/schemas/validation.mjs +0 -325
  72. package/dist/settlement.enums-DFhkqZEY.d.mts +0 -132
  73. package/dist/settlement.schema-D5uWB5tP.d.mts +0 -344
  74. package/dist/settlement.service-BxuiHpNC.d.mts +0 -594
  75. package/dist/settlement.service-CUxbUTzT.mjs +0 -2510
  76. package/dist/split.enums-BrjabxIX.mjs +0 -86
  77. package/dist/split.enums-DmskfLOM.d.mts +0 -43
  78. package/dist/tax-BoCt5cEd.d.mts +0 -61
  79. package/dist/tax-EQ15DO81.mjs +0 -162
  80. package/dist/transaction.enums-pCyMFT4Z.mjs +0 -96
  81. package/dist/utils/index.d.mts +0 -428
  82. package/dist/utils/index.mjs +0 -346
@@ -0,0 +1,388 @@
1
+ import { t as REVENUE_EVENTS } from "./event-constants-CEMitnIV.mjs";
2
+ import { createEvent, matchEventPattern } from "@classytic/primitives/events";
3
+ import { z } from "zod";
4
+
5
+ //#region src/events/in-process-bus.ts
6
+ var InProcessRevenueBus = class {
7
+ name = "in-process-revenue";
8
+ handlers = /* @__PURE__ */ new Map();
9
+ logger;
10
+ constructor(options) {
11
+ this.logger = options?.logger ?? console;
12
+ }
13
+ async publish(event) {
14
+ const all = /* @__PURE__ */ new Set();
15
+ for (const [pattern, set] of this.handlers.entries()) if (matchEventPattern(pattern, event.type)) for (const h of set) all.add(h);
16
+ for (const handler of all) try {
17
+ await handler(event);
18
+ } catch (err) {
19
+ this.logger.error(`[InProcessRevenueBus] Handler error for ${event.type}:`, err);
20
+ }
21
+ }
22
+ async subscribe(pattern, handler) {
23
+ if (!this.handlers.has(pattern)) this.handlers.set(pattern, /* @__PURE__ */ new Set());
24
+ this.handlers.get(pattern)?.add(handler);
25
+ return () => {
26
+ const set = this.handlers.get(pattern);
27
+ if (!set) return;
28
+ set.delete(handler);
29
+ if (set.size === 0) this.handlers.delete(pattern);
30
+ };
31
+ }
32
+ async close() {
33
+ this.handlers.clear();
34
+ }
35
+ };
36
+
37
+ //#endregion
38
+ //#region src/events/revenue-event-catalog.ts
39
+ /**
40
+ * Revenue event catalog — Zod-source-of-truth definitions for every
41
+ * `revenue:*` event.
42
+ *
43
+ * Each definition exposes:
44
+ * - `.zodSchema` — source of truth, used by host code's `.safeParse()`
45
+ * - `.schema` — JSON Schema derived via `z.toJSONSchema()`, consumed
46
+ * by Arc's EventRegistry + OpenAPI plugin
47
+ * - `.create(...)` — DomainEvent envelope builder, structurally compatible
48
+ * with `@classytic/arc`'s `EventDefinitionOutput`
49
+ *
50
+ * Structurally compatible with Arc 2.10's `EventRegistry` — hosts register
51
+ * `revenueEventDefinitions` directly, no adapter code. Revenue does NOT
52
+ * import from `@classytic/arc` (PACKAGE_RULES §11); compatibility is purely
53
+ * structural.
54
+ *
55
+ * Payload shapes reflect what the repositories actually emit today:
56
+ * domain documents (transactions, subscriptions, settlements) are modelled
57
+ * as structured objects with key business fields required and a passthrough
58
+ * escape hatch for fields host code doesn't care about at validation time.
59
+ * See PACKAGE_RULES §18.5 for the full pattern.
60
+ *
61
+ * @example Wiring into an Arc app
62
+ * ```ts
63
+ * import { createEventRegistry } from '@classytic/arc/events';
64
+ * import { revenueEventDefinitions } from '@classytic/revenue/events';
65
+ *
66
+ * const registry = createEventRegistry();
67
+ * for (const def of revenueEventDefinitions) registry.register(def);
68
+ *
69
+ * const app = await createApp({
70
+ * arcPlugins: { events: { registry, validateMode: 'reject' } },
71
+ * });
72
+ * ```
73
+ */
74
+ function defineRevenueEvent(input) {
75
+ const { name, version = 1, description, zodSchema } = input;
76
+ return {
77
+ name,
78
+ version,
79
+ description,
80
+ schema: z.toJSONSchema(zodSchema),
81
+ zodSchema,
82
+ create(payload, meta) {
83
+ return createEvent(name, payload, {
84
+ resource: "revenue",
85
+ ...meta
86
+ });
87
+ }
88
+ };
89
+ }
90
+ const money = z.object({
91
+ amount: z.number().nonnegative(),
92
+ currency: z.string().length(3)
93
+ });
94
+ const transactionRef = z.object({
95
+ _id: z.union([z.string(), z.any()]).optional(),
96
+ publicId: z.string().optional(),
97
+ status: z.string().optional(),
98
+ monetizationType: z.string().optional(),
99
+ amount: money.optional()
100
+ }).passthrough();
101
+ const subscriptionRef = z.object({
102
+ _id: z.union([z.string(), z.any()]).optional(),
103
+ publicId: z.string().optional(),
104
+ status: z.string().optional(),
105
+ planId: z.string().optional(),
106
+ customerId: z.string().optional()
107
+ }).passthrough();
108
+ const settlementRef = z.object({
109
+ _id: z.union([z.string(), z.any()]).optional(),
110
+ publicId: z.string().optional(),
111
+ status: z.string().optional(),
112
+ totalAmount: money.optional(),
113
+ payoutMethod: z.string().optional()
114
+ }).passthrough();
115
+ const paymentVerifiedSchema = z.object({
116
+ transaction: transactionRef,
117
+ paymentResult: z.record(z.string(), z.unknown()).optional(),
118
+ verifiedBy: z.string().optional()
119
+ });
120
+ const paymentFailedSchema = z.object({
121
+ transaction: transactionRef,
122
+ paymentResult: z.record(z.string(), z.unknown()).optional(),
123
+ verifiedBy: z.string().optional()
124
+ });
125
+ const paymentProcessingSchema = z.object({
126
+ transaction: transactionRef,
127
+ paymentResult: z.record(z.string(), z.unknown()).optional(),
128
+ verifiedBy: z.string().optional()
129
+ });
130
+ const paymentRequiresActionSchema = z.object({
131
+ transaction: transactionRef,
132
+ paymentResult: z.record(z.string(), z.unknown()).optional(),
133
+ verifiedBy: z.string().optional()
134
+ });
135
+ const paymentRefundedSchema = z.object({
136
+ transaction: transactionRef,
137
+ refundTransaction: transactionRef,
138
+ refundAmount: money,
139
+ reason: z.string().optional(),
140
+ isPartialRefund: z.boolean()
141
+ });
142
+ const monetizationCreatedSchema = z.object({
143
+ monetizationType: z.string(),
144
+ transaction: transactionRef
145
+ });
146
+ const purchaseCreatedSchema = monetizationCreatedSchema;
147
+ const freeCreatedSchema = monetizationCreatedSchema;
148
+ const transactionUpdatedSchema = z.object({
149
+ transaction: transactionRef,
150
+ changedFields: z.array(z.string()).optional()
151
+ });
152
+ const subscriptionCreatedSchema = z.object({ subscription: subscriptionRef });
153
+ const subscriptionActivatedSchema = z.object({
154
+ subscription: subscriptionRef,
155
+ activatedAt: z.iso.datetime()
156
+ });
157
+ const subscriptionRenewedSchema = z.object({
158
+ subscription: subscriptionRef,
159
+ renewedAt: z.iso.datetime(),
160
+ nextPeriodStart: z.iso.datetime().optional(),
161
+ nextPeriodEnd: z.iso.datetime().optional()
162
+ });
163
+ const subscriptionCancelledSchema = z.object({
164
+ subscription: subscriptionRef,
165
+ immediate: z.boolean().optional(),
166
+ reason: z.string().optional()
167
+ });
168
+ const subscriptionPausedSchema = z.object({
169
+ subscription: subscriptionRef,
170
+ reason: z.string().optional()
171
+ });
172
+ const subscriptionResumedSchema = z.object({
173
+ subscription: subscriptionRef,
174
+ extendPeriod: z.boolean().optional()
175
+ });
176
+ const escrowHeldSchema = z.object({
177
+ transaction: transactionRef,
178
+ heldAmount: money,
179
+ reason: z.string().optional()
180
+ });
181
+ const escrowReleasedSchema = z.object({
182
+ transaction: transactionRef,
183
+ releaseAmount: money,
184
+ recipientId: z.string().optional(),
185
+ recipientType: z.string().optional(),
186
+ isFullRelease: z.boolean(),
187
+ isPartialRelease: z.boolean()
188
+ });
189
+ const escrowCancelledSchema = z.object({
190
+ transaction: transactionRef,
191
+ cancelledAmount: money.optional(),
192
+ reason: z.string().optional()
193
+ });
194
+ const escrowSplitSchema = z.object({
195
+ transaction: transactionRef,
196
+ splits: z.array(z.object({
197
+ recipientId: z.string(),
198
+ recipientType: z.string().optional(),
199
+ amount: money
200
+ }).passthrough()),
201
+ organizationPayout: money.optional()
202
+ });
203
+ const settlementCreatedSchema = z.object({ settlement: settlementRef });
204
+ const settlementScheduledSchema = z.object({
205
+ settlement: settlementRef,
206
+ scheduledAt: z.iso.datetime()
207
+ });
208
+ const settlementProcessingSchema = z.object({
209
+ settlement: settlementRef,
210
+ processedAt: z.iso.datetime()
211
+ });
212
+ const settlementCompletedSchema = z.object({
213
+ settlement: settlementRef,
214
+ completedAt: z.iso.datetime()
215
+ });
216
+ const settlementFailedSchema = z.object({
217
+ settlement: settlementRef,
218
+ reason: z.string(),
219
+ code: z.string().optional(),
220
+ retry: z.boolean().optional()
221
+ });
222
+ const webhookProcessedSchema = z.object({
223
+ webhookType: z.string(),
224
+ provider: z.string(),
225
+ event: z.record(z.string(), z.unknown()),
226
+ transaction: transactionRef.optional()
227
+ });
228
+ const PaymentVerified = defineRevenueEvent({
229
+ name: REVENUE_EVENTS.PAYMENT_VERIFIED,
230
+ description: "A payment transaction was verified by its provider.",
231
+ zodSchema: paymentVerifiedSchema
232
+ });
233
+ const PaymentFailed = defineRevenueEvent({
234
+ name: REVENUE_EVENTS.PAYMENT_FAILED,
235
+ description: "A payment verification failed.",
236
+ zodSchema: paymentFailedSchema
237
+ });
238
+ const PaymentProcessing = defineRevenueEvent({
239
+ name: REVENUE_EVENTS.PAYMENT_PROCESSING,
240
+ description: "A payment entered an in-progress state at the provider.",
241
+ zodSchema: paymentProcessingSchema
242
+ });
243
+ const PaymentRequiresAction = defineRevenueEvent({
244
+ name: REVENUE_EVENTS.PAYMENT_REQUIRES_ACTION,
245
+ description: "A payment requires additional customer action (3DS, OTP, etc.).",
246
+ zodSchema: paymentRequiresActionSchema
247
+ });
248
+ const PaymentRefunded = defineRevenueEvent({
249
+ name: REVENUE_EVENTS.PAYMENT_REFUNDED,
250
+ description: "A payment transaction was (partially or fully) refunded.",
251
+ zodSchema: paymentRefundedSchema
252
+ });
253
+ const MonetizationCreated = defineRevenueEvent({
254
+ name: REVENUE_EVENTS.MONETIZATION_CREATED,
255
+ description: "A monetization transaction (purchase, free grant, …) was created.",
256
+ zodSchema: monetizationCreatedSchema
257
+ });
258
+ const PurchaseCreated = defineRevenueEvent({
259
+ name: REVENUE_EVENTS.PURCHASE_CREATED,
260
+ description: "A one-shot purchase transaction was created.",
261
+ zodSchema: purchaseCreatedSchema
262
+ });
263
+ const FreeCreated = defineRevenueEvent({
264
+ name: REVENUE_EVENTS.FREE_CREATED,
265
+ description: "A free (zero-cost) transaction was granted.",
266
+ zodSchema: freeCreatedSchema
267
+ });
268
+ const TransactionUpdated = defineRevenueEvent({
269
+ name: REVENUE_EVENTS.TRANSACTION_UPDATED,
270
+ description: "Generic host-level update on a transaction record.",
271
+ zodSchema: transactionUpdatedSchema
272
+ });
273
+ const SubscriptionCreated = defineRevenueEvent({
274
+ name: REVENUE_EVENTS.SUBSCRIPTION_CREATED,
275
+ description: "A subscription was created (before first activation).",
276
+ zodSchema: subscriptionCreatedSchema
277
+ });
278
+ const SubscriptionActivated = defineRevenueEvent({
279
+ name: REVENUE_EVENTS.SUBSCRIPTION_ACTIVATED,
280
+ description: "A subscription became active (first successful charge).",
281
+ zodSchema: subscriptionActivatedSchema
282
+ });
283
+ const SubscriptionRenewed = defineRevenueEvent({
284
+ name: REVENUE_EVENTS.SUBSCRIPTION_RENEWED,
285
+ description: "A subscription renewal cycle succeeded.",
286
+ zodSchema: subscriptionRenewedSchema
287
+ });
288
+ const SubscriptionCancelled = defineRevenueEvent({
289
+ name: REVENUE_EVENTS.SUBSCRIPTION_CANCELLED,
290
+ description: "A subscription was cancelled (immediate or end-of-period).",
291
+ zodSchema: subscriptionCancelledSchema
292
+ });
293
+ const SubscriptionPaused = defineRevenueEvent({
294
+ name: REVENUE_EVENTS.SUBSCRIPTION_PAUSED,
295
+ description: "A subscription was paused.",
296
+ zodSchema: subscriptionPausedSchema
297
+ });
298
+ const SubscriptionResumed = defineRevenueEvent({
299
+ name: REVENUE_EVENTS.SUBSCRIPTION_RESUMED,
300
+ description: "A paused subscription was resumed.",
301
+ zodSchema: subscriptionResumedSchema
302
+ });
303
+ const EscrowHeld = defineRevenueEvent({
304
+ name: REVENUE_EVENTS.ESCROW_HELD,
305
+ description: "An amount was placed into escrow against a transaction.",
306
+ zodSchema: escrowHeldSchema
307
+ });
308
+ const EscrowReleased = defineRevenueEvent({
309
+ name: REVENUE_EVENTS.ESCROW_RELEASED,
310
+ description: "Escrow was released (full or partial) to a recipient.",
311
+ zodSchema: escrowReleasedSchema
312
+ });
313
+ const EscrowCancelled = defineRevenueEvent({
314
+ name: REVENUE_EVENTS.ESCROW_CANCELLED,
315
+ description: "An escrow hold was cancelled and funds returned.",
316
+ zodSchema: escrowCancelledSchema
317
+ });
318
+ const EscrowSplit = defineRevenueEvent({
319
+ name: REVENUE_EVENTS.ESCROW_SPLIT,
320
+ description: "Escrow was split across multiple recipients.",
321
+ zodSchema: escrowSplitSchema
322
+ });
323
+ const SettlementCreated = defineRevenueEvent({
324
+ name: REVENUE_EVENTS.SETTLEMENT_CREATED,
325
+ description: "A settlement record was created.",
326
+ zodSchema: settlementCreatedSchema
327
+ });
328
+ const SettlementScheduled = defineRevenueEvent({
329
+ name: REVENUE_EVENTS.SETTLEMENT_SCHEDULED,
330
+ description: "A settlement was scheduled for a future payout.",
331
+ zodSchema: settlementScheduledSchema
332
+ });
333
+ const SettlementProcessing = defineRevenueEvent({
334
+ name: REVENUE_EVENTS.SETTLEMENT_PROCESSING,
335
+ description: "A settlement entered the processing phase.",
336
+ zodSchema: settlementProcessingSchema
337
+ });
338
+ const SettlementCompleted = defineRevenueEvent({
339
+ name: REVENUE_EVENTS.SETTLEMENT_COMPLETED,
340
+ description: "A settlement completed successfully.",
341
+ zodSchema: settlementCompletedSchema
342
+ });
343
+ const SettlementFailed = defineRevenueEvent({
344
+ name: REVENUE_EVENTS.SETTLEMENT_FAILED,
345
+ description: "A settlement failed during processing.",
346
+ zodSchema: settlementFailedSchema
347
+ });
348
+ const WebhookProcessed = defineRevenueEvent({
349
+ name: REVENUE_EVENTS.WEBHOOK_PROCESSED,
350
+ description: "A provider webhook was processed by the revenue engine.",
351
+ zodSchema: webhookProcessedSchema
352
+ });
353
+ /**
354
+ * Every revenue event defined in the package — pass to Arc's
355
+ * `EventRegistry`. Hosts wire ONE array; the whole `revenue:*` namespace
356
+ * becomes introspectable via OpenAPI and auto-validated at publish time
357
+ * when `eventPlugin({ validateMode: 'reject' })` is set.
358
+ */
359
+ const revenueEventDefinitions = [
360
+ PaymentVerified,
361
+ PaymentFailed,
362
+ PaymentProcessing,
363
+ PaymentRequiresAction,
364
+ PaymentRefunded,
365
+ MonetizationCreated,
366
+ PurchaseCreated,
367
+ FreeCreated,
368
+ TransactionUpdated,
369
+ SubscriptionCreated,
370
+ SubscriptionActivated,
371
+ SubscriptionRenewed,
372
+ SubscriptionCancelled,
373
+ SubscriptionPaused,
374
+ SubscriptionResumed,
375
+ EscrowHeld,
376
+ EscrowReleased,
377
+ EscrowCancelled,
378
+ EscrowSplit,
379
+ SettlementCreated,
380
+ SettlementScheduled,
381
+ SettlementProcessing,
382
+ SettlementCompleted,
383
+ SettlementFailed,
384
+ WebhookProcessed
385
+ ];
386
+
387
+ //#endregion
388
+ export { SubscriptionResumed as C, InProcessRevenueBus as D, revenueEventDefinitions as E, SubscriptionRenewed as S, WebhookProcessed as T, SettlementScheduled as _, FreeCreated as a, SubscriptionCreated as b, PaymentProcessing as c, PaymentVerified as d, PurchaseCreated as f, SettlementProcessing as g, SettlementFailed as h, EscrowSplit as i, PaymentRefunded as l, SettlementCreated as m, EscrowHeld as n, MonetizationCreated as o, SettlementCompleted as p, EscrowReleased as r, PaymentFailed as s, EscrowCancelled as t, PaymentRequiresAction as u, SubscriptionActivated as v, TransactionUpdated as w, SubscriptionPaused as x, SubscriptionCancelled as y };