@classytic/revenue 1.1.4 → 2.0.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.
- package/CHANGELOG.md +90 -0
- package/README.md +638 -632
- package/dist/audit-B39B0Sdq.mjs +53 -0
- package/dist/audit-DZ0eTr9g.d.mts +89 -0
- package/dist/bridges/index.d.mts +2 -0
- package/dist/bridges/index.mjs +1 -0
- package/dist/context-DRqSeTPM.d.mts +35 -0
- package/dist/core/state-machines.d.mts +53 -0
- package/dist/core/state-machines.mjs +153 -0
- package/dist/engine-types-CcjIb4Fy.d.mts +611 -0
- package/dist/enums/index.d.mts +3 -157
- package/dist/enums/index.mjs +3 -55
- package/dist/errors-DHa8JVQ-.mjs +92 -0
- package/dist/escrow.schema-BBv9oVEW.mjs +322 -0
- package/dist/escrow.schema-D5X32LwX.d.mts +629 -0
- package/dist/event-constants-CEMitnIV.mjs +53 -0
- package/dist/events/index.d.mts +3 -0
- package/dist/events/index.mjs +4 -0
- package/dist/index.d.mts +77 -9
- package/dist/index.mjs +465 -29
- package/dist/monetization.enums-BtiU3t8o.mjs +39 -0
- package/dist/monetization.enums-D2xbxXJM.d.mts +34 -0
- package/dist/plugins/plugin.interface.d.mts +28 -0
- package/dist/plugins/plugin.interface.mjs +26 -0
- package/dist/providers/index.d.mts +2 -3
- package/dist/providers/index.mjs +2 -2
- package/dist/{base-DCoyIUj6.mjs → registry-DhFMsSn5.mjs} +34 -36
- package/dist/{base-CsTlVQJe.d.mts → registry-SvIGPAx_.d.mts} +73 -66
- package/dist/repositories/create-repositories.d.mts +21 -0
- package/dist/repositories/create-repositories.mjs +12 -0
- package/dist/revenue-bridges-sdlrR85c.d.mts +145 -0
- package/dist/revenue-event-catalog-BX3g7RUi.d.mts +823 -0
- package/dist/revenue-event-catalog-LqxPnsU_.mjs +388 -0
- package/dist/settlement.repository-DHIPx5S4.mjs +771 -0
- package/dist/shared/index.d.mts +2 -0
- package/dist/shared/index.mjs +4 -0
- package/dist/splits-BAfY-a9P.mjs +123 -0
- package/dist/subscription.enums-tfoAgsTv.mjs +172 -0
- package/dist/transaction.enums-u4MshXcL.d.mts +154 -0
- package/dist/validators/index.d.mts +2 -0
- package/dist/validators/index.mjs +3 -0
- package/package.json +37 -38
- package/dist/application/services/index.d.mts +0 -4
- package/dist/application/services/index.mjs +0 -3
- package/dist/category-resolver-DV83N8ok.mjs +0 -284
- package/dist/commission-split-BzB8cd39.mjs +0 -485
- package/dist/core/events.d.mts +0 -294
- package/dist/core/events.mjs +0 -100
- package/dist/core/index.d.mts +0 -9
- package/dist/core/index.mjs +0 -8
- package/dist/errors-rRdOqnWx.d.mts +0 -787
- package/dist/escrow.enums-CZGrrdg7.mjs +0 -101
- package/dist/escrow.enums-DwdLuuve.d.mts +0 -78
- package/dist/idempotency-DaYcUGY1.mjs +0 -172
- package/dist/index-Dsp7H5Wb.d.mts +0 -471
- package/dist/infrastructure/plugins/index.d.mts +0 -239
- package/dist/infrastructure/plugins/index.mjs +0 -345
- package/dist/money-CvrDOijQ.mjs +0 -271
- package/dist/money-DPG8AtJ8.d.mts +0 -112
- package/dist/payment.enums-HAuAS9Pp.d.mts +0 -70
- package/dist/payment.enums-tEFVa-Xp.mjs +0 -69
- package/dist/plugin-BbK0OVHy.d.mts +0 -327
- package/dist/plugin-Cd_V04Em.mjs +0 -210
- package/dist/reconciliation/index.d.mts +0 -193
- package/dist/reconciliation/index.mjs +0 -192
- package/dist/retry-HHCOXYdn.d.mts +0 -186
- package/dist/revenue-BhdS7nXh.mjs +0 -553
- package/dist/schemas/index.d.mts +0 -2665
- package/dist/schemas/index.mjs +0 -717
- package/dist/schemas/validation.d.mts +0 -375
- package/dist/schemas/validation.mjs +0 -325
- package/dist/settlement.enums-DFhkqZEY.d.mts +0 -132
- package/dist/settlement.schema-DnNSFpGd.d.mts +0 -344
- package/dist/settlement.service-DjzAjezU.d.mts +0 -594
- package/dist/settlement.service-DmdKv0Zu.mjs +0 -2511
- package/dist/split.enums-BrjabxIX.mjs +0 -86
- package/dist/split.enums-DmskfLOM.d.mts +0 -43
- package/dist/tax-BoCt5cEd.d.mts +0 -61
- package/dist/tax-EQ15DO81.mjs +0 -162
- package/dist/transaction.enums-pCyMFT4Z.mjs +0 -96
- package/dist/utils/index.d.mts +0 -428
- package/dist/utils/index.mjs +0 -346
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import { B as TransactionDocument, h as MongooseModel } from "../index-Dsp7H5Wb.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/shared/types/reconciliation.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Gateway Settlement Record
|
|
6
|
-
* Data from payment gateway's settlement report (Stripe, PayPal, etc.)
|
|
7
|
-
*/
|
|
8
|
-
interface GatewaySettlement {
|
|
9
|
-
/** Settlement ID from gateway */
|
|
10
|
-
settlementId: string;
|
|
11
|
-
/** Transaction/payment ID from gateway */
|
|
12
|
-
transactionId: string;
|
|
13
|
-
/** Amount settled */
|
|
14
|
-
amount: number;
|
|
15
|
-
/** Currency */
|
|
16
|
-
currency: string;
|
|
17
|
-
/** When funds were settled */
|
|
18
|
-
settledAt: Date;
|
|
19
|
-
/** Gateway fee deducted */
|
|
20
|
-
gatewayFee?: number;
|
|
21
|
-
/** Net amount received (amount - gatewayFee) */
|
|
22
|
-
netAmount?: number;
|
|
23
|
-
/** Payment status in gateway */
|
|
24
|
-
status?: string;
|
|
25
|
-
/** Additional gateway metadata */
|
|
26
|
-
metadata?: Record<string, unknown>;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Reconciliation Options
|
|
30
|
-
* Configuration for reconciliation process
|
|
31
|
-
*/
|
|
32
|
-
interface ReconciliationOptions {
|
|
33
|
-
/** Filter by organization */
|
|
34
|
-
organizationId?: string;
|
|
35
|
-
/** Filter by payment gateway */
|
|
36
|
-
gateway?: string;
|
|
37
|
-
/** Start date for reconciliation period */
|
|
38
|
-
startDate?: Date;
|
|
39
|
-
/** End date for reconciliation period */
|
|
40
|
-
endDate?: Date;
|
|
41
|
-
/** Automatically match by transactionId */
|
|
42
|
-
autoMatch?: boolean;
|
|
43
|
-
/** Tolerance for amount mismatches (in cents) */
|
|
44
|
-
amountTolerance?: number;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Reconciliation Report
|
|
48
|
-
* Result of reconciling gateway settlements with database transactions
|
|
49
|
-
*/
|
|
50
|
-
interface ReconciliationReport {
|
|
51
|
-
/** Summary statistics */
|
|
52
|
-
summary: {
|
|
53
|
-
/** Total transactions in gateway report */totalGatewayTransactions: number; /** Total transactions in database */
|
|
54
|
-
totalDbTransactions: number; /** Number of matched transactions */
|
|
55
|
-
matched: number; /** Number missing in database */
|
|
56
|
-
missing: number; /** Number extra in database (not in gateway) */
|
|
57
|
-
extra: number; /** Number with amount mismatches */
|
|
58
|
-
amountMismatches: number; /** Total amount difference across all mismatches */
|
|
59
|
-
totalAmountDiff: number;
|
|
60
|
-
};
|
|
61
|
-
/** Transactions in gateway but not in database */
|
|
62
|
-
missingInDb: GatewaySettlement[];
|
|
63
|
-
/** Transactions in database but not in gateway */
|
|
64
|
-
missingInGateway: TransactionDocument[];
|
|
65
|
-
/** Transactions with amount mismatches */
|
|
66
|
-
amountMismatches: Array<{
|
|
67
|
-
transactionId: string;
|
|
68
|
-
gatewayAmount: number;
|
|
69
|
-
dbAmount: number;
|
|
70
|
-
diff: number;
|
|
71
|
-
transaction?: TransactionDocument;
|
|
72
|
-
gatewayRecord?: GatewaySettlement;
|
|
73
|
-
}>;
|
|
74
|
-
/** Successfully matched transactions */
|
|
75
|
-
matched: Array<{
|
|
76
|
-
transactionId: string;
|
|
77
|
-
amount: number;
|
|
78
|
-
transaction: TransactionDocument;
|
|
79
|
-
gatewayRecord: GatewaySettlement;
|
|
80
|
-
}>;
|
|
81
|
-
/** Reconciliation metadata */
|
|
82
|
-
metadata: {
|
|
83
|
-
reconciledAt: Date;
|
|
84
|
-
period: {
|
|
85
|
-
start?: Date;
|
|
86
|
-
end?: Date;
|
|
87
|
-
};
|
|
88
|
-
gateway?: string;
|
|
89
|
-
organizationId?: string;
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Discrepancy Type
|
|
94
|
-
*/
|
|
95
|
-
type DiscrepancyType = 'missing_in_db' | 'missing_in_gateway' | 'amount_mismatch' | 'status_mismatch';
|
|
96
|
-
/**
|
|
97
|
-
* Discrepancy Record
|
|
98
|
-
* Individual reconciliation discrepancy
|
|
99
|
-
*/
|
|
100
|
-
interface Discrepancy {
|
|
101
|
-
type: DiscrepancyType;
|
|
102
|
-
transactionId: string;
|
|
103
|
-
severity: 'low' | 'medium' | 'high';
|
|
104
|
-
description: string;
|
|
105
|
-
gatewayData?: GatewaySettlement;
|
|
106
|
-
dbData?: TransactionDocument;
|
|
107
|
-
diff?: number;
|
|
108
|
-
}
|
|
109
|
-
//#endregion
|
|
110
|
-
//#region src/reconciliation/reconciler.d.ts
|
|
111
|
-
/**
|
|
112
|
-
* Reconcile gateway settlements with database transactions
|
|
113
|
-
*
|
|
114
|
-
* Compares payment gateway's settlement report with your database to identify:
|
|
115
|
-
* - Transactions in gateway but missing in DB
|
|
116
|
-
* - Transactions in DB but missing in gateway
|
|
117
|
-
* - Amount mismatches between gateway and DB
|
|
118
|
-
*
|
|
119
|
-
* @param gatewaySettlements - Settlement data from payment gateway
|
|
120
|
-
* @param TransactionModel - Mongoose Transaction model
|
|
121
|
-
* @param options - Reconciliation options
|
|
122
|
-
* @returns Reconciliation report with findings
|
|
123
|
-
*
|
|
124
|
-
* @example
|
|
125
|
-
* ```typescript
|
|
126
|
-
* import { reconcileSettlement } from '@classytic/revenue/reconciliation';
|
|
127
|
-
*
|
|
128
|
-
* // Get Stripe settlements for January
|
|
129
|
-
* const stripeSettlements = await stripe.balanceTransactions.list({
|
|
130
|
-
* created: { gte: jan1, lte: jan31 },
|
|
131
|
-
* });
|
|
132
|
-
*
|
|
133
|
-
* // Reconcile with database
|
|
134
|
-
* const report = await reconcileSettlement(
|
|
135
|
-
* stripeSettlements.data.map(s => ({
|
|
136
|
-
* settlementId: s.id,
|
|
137
|
-
* transactionId: s.source,
|
|
138
|
-
* amount: s.amount,
|
|
139
|
-
* currency: s.currency,
|
|
140
|
-
* settledAt: new Date(s.created * 1000),
|
|
141
|
-
* gatewayFee: s.fee,
|
|
142
|
-
* netAmount: s.net,
|
|
143
|
-
* })),
|
|
144
|
-
* TransactionModel,
|
|
145
|
-
* { gateway: 'stripe', startDate: jan1, endDate: jan31 }
|
|
146
|
-
* );
|
|
147
|
-
*
|
|
148
|
-
* console.log(report.summary);
|
|
149
|
-
* // { matched: 1245, missing: 2, extra: 1, amountMismatches: 3 }
|
|
150
|
-
* ```
|
|
151
|
-
*/
|
|
152
|
-
declare function reconcileSettlement(gatewaySettlements: GatewaySettlement[], TransactionModel: MongooseModel<TransactionDocument>, options?: ReconciliationOptions): Promise<ReconciliationReport>;
|
|
153
|
-
/**
|
|
154
|
-
* Find transactions missing in database
|
|
155
|
-
*
|
|
156
|
-
* @param organizationId - Organization to check
|
|
157
|
-
* @param dateRange - Date range to search
|
|
158
|
-
* @param gateway - Payment gateway
|
|
159
|
-
* @param TransactionModel - Mongoose Transaction model
|
|
160
|
-
* @returns Missing transaction IDs
|
|
161
|
-
*/
|
|
162
|
-
declare function findMissingTransactions(_organizationId: string, _dateRange: {
|
|
163
|
-
start: Date;
|
|
164
|
-
end: Date;
|
|
165
|
-
}, _gateway: string, _TransactionModel: MongooseModel<TransactionDocument>): Promise<{
|
|
166
|
-
inGateway: string[];
|
|
167
|
-
inDb: string[];
|
|
168
|
-
}>;
|
|
169
|
-
/**
|
|
170
|
-
* Find amount mismatches between gateway and database
|
|
171
|
-
*
|
|
172
|
-
* @param organizationId - Organization to check
|
|
173
|
-
* @param dateRange - Date range to search
|
|
174
|
-
* @param threshold - Amount difference threshold (cents)
|
|
175
|
-
* @param TransactionModel - Mongoose Transaction model
|
|
176
|
-
* @returns Array of mismatches
|
|
177
|
-
*/
|
|
178
|
-
declare function findAmountMismatches(_organizationId: string, _dateRange: {
|
|
179
|
-
start: Date;
|
|
180
|
-
end: Date;
|
|
181
|
-
}, _threshold: number | undefined, _TransactionModel: MongooseModel<TransactionDocument>): Promise<Array<{
|
|
182
|
-
transactionId: string;
|
|
183
|
-
diff: number;
|
|
184
|
-
}>>;
|
|
185
|
-
/**
|
|
186
|
-
* Generate reconciliation discrepancies
|
|
187
|
-
*
|
|
188
|
-
* @param report - Reconciliation report
|
|
189
|
-
* @returns Array of discrepancies sorted by severity
|
|
190
|
-
*/
|
|
191
|
-
declare function generateDiscrepancies(report: ReconciliationReport): Discrepancy[];
|
|
192
|
-
//#endregion
|
|
193
|
-
export { type Discrepancy, type DiscrepancyType, type GatewaySettlement, type ReconciliationOptions, type ReconciliationReport, findAmountMismatches, findMissingTransactions, generateDiscrepancies, reconcileSettlement };
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
//#region src/reconciliation/reconciler.ts
|
|
2
|
-
/**
|
|
3
|
-
* Reconcile gateway settlements with database transactions
|
|
4
|
-
*
|
|
5
|
-
* Compares payment gateway's settlement report with your database to identify:
|
|
6
|
-
* - Transactions in gateway but missing in DB
|
|
7
|
-
* - Transactions in DB but missing in gateway
|
|
8
|
-
* - Amount mismatches between gateway and DB
|
|
9
|
-
*
|
|
10
|
-
* @param gatewaySettlements - Settlement data from payment gateway
|
|
11
|
-
* @param TransactionModel - Mongoose Transaction model
|
|
12
|
-
* @param options - Reconciliation options
|
|
13
|
-
* @returns Reconciliation report with findings
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```typescript
|
|
17
|
-
* import { reconcileSettlement } from '@classytic/revenue/reconciliation';
|
|
18
|
-
*
|
|
19
|
-
* // Get Stripe settlements for January
|
|
20
|
-
* const stripeSettlements = await stripe.balanceTransactions.list({
|
|
21
|
-
* created: { gte: jan1, lte: jan31 },
|
|
22
|
-
* });
|
|
23
|
-
*
|
|
24
|
-
* // Reconcile with database
|
|
25
|
-
* const report = await reconcileSettlement(
|
|
26
|
-
* stripeSettlements.data.map(s => ({
|
|
27
|
-
* settlementId: s.id,
|
|
28
|
-
* transactionId: s.source,
|
|
29
|
-
* amount: s.amount,
|
|
30
|
-
* currency: s.currency,
|
|
31
|
-
* settledAt: new Date(s.created * 1000),
|
|
32
|
-
* gatewayFee: s.fee,
|
|
33
|
-
* netAmount: s.net,
|
|
34
|
-
* })),
|
|
35
|
-
* TransactionModel,
|
|
36
|
-
* { gateway: 'stripe', startDate: jan1, endDate: jan31 }
|
|
37
|
-
* );
|
|
38
|
-
*
|
|
39
|
-
* console.log(report.summary);
|
|
40
|
-
* // { matched: 1245, missing: 2, extra: 1, amountMismatches: 3 }
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
async function reconcileSettlement(gatewaySettlements, TransactionModel, options = {}) {
|
|
44
|
-
const { organizationId, gateway, startDate, endDate, autoMatch: _autoMatch = true, amountTolerance = 1 } = options;
|
|
45
|
-
const query = {};
|
|
46
|
-
if (organizationId) query.organizationId = organizationId;
|
|
47
|
-
if (gateway) query["gateway.type"] = gateway;
|
|
48
|
-
if (startDate || endDate) {
|
|
49
|
-
query.createdAt = {};
|
|
50
|
-
if (startDate) query.createdAt.$gte = startDate;
|
|
51
|
-
if (endDate) query.createdAt.$lte = endDate;
|
|
52
|
-
}
|
|
53
|
-
const dbTransactions = await TransactionModel.find(query);
|
|
54
|
-
const gatewayMap = /* @__PURE__ */ new Map();
|
|
55
|
-
const dbMap = /* @__PURE__ */ new Map();
|
|
56
|
-
for (const settlement of gatewaySettlements) gatewayMap.set(settlement.transactionId, settlement);
|
|
57
|
-
for (const transaction of dbTransactions) {
|
|
58
|
-
const key = transaction.gateway?.paymentIntentId || transaction._id.toString();
|
|
59
|
-
dbMap.set(key, transaction);
|
|
60
|
-
}
|
|
61
|
-
const report = {
|
|
62
|
-
summary: {
|
|
63
|
-
totalGatewayTransactions: gatewaySettlements.length,
|
|
64
|
-
totalDbTransactions: dbTransactions.length,
|
|
65
|
-
matched: 0,
|
|
66
|
-
missing: 0,
|
|
67
|
-
extra: 0,
|
|
68
|
-
amountMismatches: 0,
|
|
69
|
-
totalAmountDiff: 0
|
|
70
|
-
},
|
|
71
|
-
missingInDb: [],
|
|
72
|
-
missingInGateway: [],
|
|
73
|
-
amountMismatches: [],
|
|
74
|
-
matched: [],
|
|
75
|
-
metadata: {
|
|
76
|
-
reconciledAt: /* @__PURE__ */ new Date(),
|
|
77
|
-
period: {
|
|
78
|
-
start: startDate,
|
|
79
|
-
end: endDate
|
|
80
|
-
},
|
|
81
|
-
gateway,
|
|
82
|
-
organizationId
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
for (const [gatewayTxId, gatewaySettlement] of gatewayMap.entries()) {
|
|
86
|
-
const dbTransaction = dbMap.get(gatewayTxId);
|
|
87
|
-
if (!dbTransaction) {
|
|
88
|
-
report.missingInDb.push(gatewaySettlement);
|
|
89
|
-
report.summary.missing++;
|
|
90
|
-
} else {
|
|
91
|
-
const amountDiff = Math.abs(dbTransaction.amount - gatewaySettlement.amount);
|
|
92
|
-
if (amountDiff > amountTolerance) {
|
|
93
|
-
report.amountMismatches.push({
|
|
94
|
-
transactionId: gatewayTxId,
|
|
95
|
-
gatewayAmount: gatewaySettlement.amount,
|
|
96
|
-
dbAmount: dbTransaction.amount,
|
|
97
|
-
diff: dbTransaction.amount - gatewaySettlement.amount,
|
|
98
|
-
transaction: dbTransaction,
|
|
99
|
-
gatewayRecord: gatewaySettlement
|
|
100
|
-
});
|
|
101
|
-
report.summary.amountMismatches++;
|
|
102
|
-
report.summary.totalAmountDiff += amountDiff;
|
|
103
|
-
} else {
|
|
104
|
-
report.matched.push({
|
|
105
|
-
transactionId: gatewayTxId,
|
|
106
|
-
amount: dbTransaction.amount,
|
|
107
|
-
transaction: dbTransaction,
|
|
108
|
-
gatewayRecord: gatewaySettlement
|
|
109
|
-
});
|
|
110
|
-
report.summary.matched++;
|
|
111
|
-
}
|
|
112
|
-
dbMap.delete(gatewayTxId);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
for (const [_, transaction] of dbMap.entries()) {
|
|
116
|
-
report.missingInGateway.push(transaction);
|
|
117
|
-
report.summary.extra++;
|
|
118
|
-
}
|
|
119
|
-
return report;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Find transactions missing in database
|
|
123
|
-
*
|
|
124
|
-
* @param organizationId - Organization to check
|
|
125
|
-
* @param dateRange - Date range to search
|
|
126
|
-
* @param gateway - Payment gateway
|
|
127
|
-
* @param TransactionModel - Mongoose Transaction model
|
|
128
|
-
* @returns Missing transaction IDs
|
|
129
|
-
*/
|
|
130
|
-
async function findMissingTransactions(_organizationId, _dateRange, _gateway, _TransactionModel) {
|
|
131
|
-
return {
|
|
132
|
-
inGateway: [],
|
|
133
|
-
inDb: []
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Find amount mismatches between gateway and database
|
|
138
|
-
*
|
|
139
|
-
* @param organizationId - Organization to check
|
|
140
|
-
* @param dateRange - Date range to search
|
|
141
|
-
* @param threshold - Amount difference threshold (cents)
|
|
142
|
-
* @param TransactionModel - Mongoose Transaction model
|
|
143
|
-
* @returns Array of mismatches
|
|
144
|
-
*/
|
|
145
|
-
async function findAmountMismatches(_organizationId, _dateRange, _threshold = 1, _TransactionModel) {
|
|
146
|
-
return [];
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Generate reconciliation discrepancies
|
|
150
|
-
*
|
|
151
|
-
* @param report - Reconciliation report
|
|
152
|
-
* @returns Array of discrepancies sorted by severity
|
|
153
|
-
*/
|
|
154
|
-
function generateDiscrepancies(report) {
|
|
155
|
-
const discrepancies = [];
|
|
156
|
-
for (const gateway of report.missingInDb) discrepancies.push({
|
|
157
|
-
type: "missing_in_db",
|
|
158
|
-
transactionId: gateway.transactionId,
|
|
159
|
-
severity: "high",
|
|
160
|
-
description: `Transaction ${gateway.transactionId} found in gateway (${gateway.amount} ${gateway.currency}) but missing in database`,
|
|
161
|
-
gatewayData: gateway
|
|
162
|
-
});
|
|
163
|
-
for (const transaction of report.missingInGateway) discrepancies.push({
|
|
164
|
-
type: "missing_in_gateway",
|
|
165
|
-
transactionId: transaction._id.toString(),
|
|
166
|
-
severity: "medium",
|
|
167
|
-
description: `Transaction ${transaction._id} found in database but not in gateway report`,
|
|
168
|
-
dbData: transaction
|
|
169
|
-
});
|
|
170
|
-
for (const mismatch of report.amountMismatches) {
|
|
171
|
-
const severity = Math.abs(mismatch.diff) > 1e3 ? "high" : Math.abs(mismatch.diff) > 100 ? "medium" : "low";
|
|
172
|
-
discrepancies.push({
|
|
173
|
-
type: "amount_mismatch",
|
|
174
|
-
transactionId: mismatch.transactionId,
|
|
175
|
-
severity,
|
|
176
|
-
description: `Amount mismatch: Gateway shows ${mismatch.gatewayAmount}, DB shows ${mismatch.dbAmount} (diff: ${mismatch.diff})`,
|
|
177
|
-
gatewayData: mismatch.gatewayRecord,
|
|
178
|
-
dbData: mismatch.transaction,
|
|
179
|
-
diff: mismatch.diff
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
const severityOrder = {
|
|
183
|
-
high: 0,
|
|
184
|
-
medium: 1,
|
|
185
|
-
low: 2
|
|
186
|
-
};
|
|
187
|
-
discrepancies.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
|
188
|
-
return discrepancies;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
//#endregion
|
|
192
|
-
export { findAmountMismatches, findMissingTransactions, generateDiscrepancies, reconcileSettlement };
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
//#region src/core/result.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Result Type - Rust-inspired error handling
|
|
4
|
-
* @classytic/revenue
|
|
5
|
-
*
|
|
6
|
-
* No more try/catch - explicit, type-safe error handling
|
|
7
|
-
* Inspired by: Rust Result<T, E>, neverthrow, Effect-TS
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Success result
|
|
11
|
-
*/
|
|
12
|
-
interface Ok<T> {
|
|
13
|
-
readonly ok: true;
|
|
14
|
-
readonly value: T;
|
|
15
|
-
readonly error?: never;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Error result
|
|
19
|
-
*/
|
|
20
|
-
interface Err<E> {
|
|
21
|
-
readonly ok: false;
|
|
22
|
-
readonly error: E;
|
|
23
|
-
readonly value?: never;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Result type - either Ok<T> or Err<E>
|
|
27
|
-
*/
|
|
28
|
-
type Result<T, E = Error> = Ok<T> | Err<E>;
|
|
29
|
-
/**
|
|
30
|
-
* Create a success result
|
|
31
|
-
*/
|
|
32
|
-
declare function ok<T>(value: T): Ok<T>;
|
|
33
|
-
/**
|
|
34
|
-
* Create an error result
|
|
35
|
-
*/
|
|
36
|
-
declare function err<E>(error: E): Err<E>;
|
|
37
|
-
/**
|
|
38
|
-
* Check if result is Ok
|
|
39
|
-
*/
|
|
40
|
-
declare function isOk<T, E>(result: Result<T, E>): result is Ok<T>;
|
|
41
|
-
/**
|
|
42
|
-
* Check if result is Err
|
|
43
|
-
*/
|
|
44
|
-
declare function isErr<T, E>(result: Result<T, E>): result is Err<E>;
|
|
45
|
-
/**
|
|
46
|
-
* Unwrap a result, throwing if it's an error
|
|
47
|
-
* Use sparingly - prefer pattern matching
|
|
48
|
-
*/
|
|
49
|
-
declare function unwrap<T, E>(result: Result<T, E>): T;
|
|
50
|
-
/**
|
|
51
|
-
* Unwrap a result with a default value
|
|
52
|
-
*/
|
|
53
|
-
declare function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T;
|
|
54
|
-
/**
|
|
55
|
-
* Map over a successful result
|
|
56
|
-
*/
|
|
57
|
-
declare function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;
|
|
58
|
-
/**
|
|
59
|
-
* Map over an error result
|
|
60
|
-
*/
|
|
61
|
-
declare function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
|
|
62
|
-
/**
|
|
63
|
-
* Flat map (chain) results
|
|
64
|
-
*/
|
|
65
|
-
declare function flatMap<T, U, E>(result: Result<T, E>, fn: (value: T) => Result<U, E>): Result<U, E>;
|
|
66
|
-
/**
|
|
67
|
-
* Try-catch wrapper that returns Result
|
|
68
|
-
*/
|
|
69
|
-
declare function tryCatch<T, E = Error>(fn: () => Promise<T>, mapError?: (e: unknown) => E): Promise<Result<T, E>>;
|
|
70
|
-
/**
|
|
71
|
-
* Synchronous try-catch wrapper
|
|
72
|
-
*/
|
|
73
|
-
declare function tryCatchSync<T, E = Error>(fn: () => T, mapError?: (e: unknown) => E): Result<T, E>;
|
|
74
|
-
/**
|
|
75
|
-
* Combine multiple results - all must succeed
|
|
76
|
-
*/
|
|
77
|
-
declare function all<T extends readonly Result<unknown, unknown>[]>(results: T): Result<{ [K in keyof T]: T[K] extends Result<infer U, unknown> ? U : never }, T[number] extends Result<unknown, infer E> ? E : never>;
|
|
78
|
-
/**
|
|
79
|
-
* Pattern match on result
|
|
80
|
-
*/
|
|
81
|
-
declare function match<T, E, U>(result: Result<T, E>, handlers: {
|
|
82
|
-
ok: (value: T) => U;
|
|
83
|
-
err: (error: E) => U;
|
|
84
|
-
}): U;
|
|
85
|
-
declare const Result: {
|
|
86
|
-
readonly ok: typeof ok;
|
|
87
|
-
readonly err: typeof err;
|
|
88
|
-
readonly isOk: typeof isOk;
|
|
89
|
-
readonly isErr: typeof isErr;
|
|
90
|
-
readonly unwrap: typeof unwrap;
|
|
91
|
-
readonly unwrapOr: typeof unwrapOr;
|
|
92
|
-
readonly map: typeof map;
|
|
93
|
-
readonly mapErr: typeof mapErr;
|
|
94
|
-
readonly flatMap: typeof flatMap;
|
|
95
|
-
readonly tryCatch: typeof tryCatch;
|
|
96
|
-
readonly tryCatchSync: typeof tryCatchSync;
|
|
97
|
-
readonly all: typeof all;
|
|
98
|
-
readonly match: typeof match;
|
|
99
|
-
};
|
|
100
|
-
//#endregion
|
|
101
|
-
//#region src/shared/utils/resilience/retry.d.ts
|
|
102
|
-
interface RetryConfig {
|
|
103
|
-
/** Maximum number of retry attempts (default: 3) */
|
|
104
|
-
maxAttempts: number;
|
|
105
|
-
/** Base delay in milliseconds (default: 1000) */
|
|
106
|
-
baseDelay: number;
|
|
107
|
-
/** Maximum delay in milliseconds (default: 30000) */
|
|
108
|
-
maxDelay: number;
|
|
109
|
-
/** Backoff multiplier (default: 2) */
|
|
110
|
-
backoffMultiplier: number;
|
|
111
|
-
/** Jitter factor 0-1 (default: 0.1) */
|
|
112
|
-
jitter: number;
|
|
113
|
-
/** Which errors are retryable */
|
|
114
|
-
retryIf?: (error: unknown) => boolean;
|
|
115
|
-
/** Callback on each retry */
|
|
116
|
-
onRetry?: (error: unknown, attempt: number, delay: number) => void;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Execute operation with retry logic
|
|
120
|
-
*/
|
|
121
|
-
declare function retry<T>(operation: () => Promise<T>, config?: Partial<RetryConfig>): Promise<T>;
|
|
122
|
-
type CircuitState = 'closed' | 'open' | 'half-open';
|
|
123
|
-
interface CircuitBreakerConfig {
|
|
124
|
-
/** Number of failures before opening circuit */
|
|
125
|
-
failureThreshold: number;
|
|
126
|
-
/** Time in ms to wait before half-opening */
|
|
127
|
-
resetTimeout: number;
|
|
128
|
-
/** Number of successes in half-open to close circuit */
|
|
129
|
-
successThreshold: number;
|
|
130
|
-
/** Monitor window in ms */
|
|
131
|
-
monitorWindow: number;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Circuit breaker for preventing cascade failures
|
|
135
|
-
* Inspired by: Netflix Hystrix, resilience4j
|
|
136
|
-
*/
|
|
137
|
-
declare class CircuitBreaker {
|
|
138
|
-
private state;
|
|
139
|
-
private failures;
|
|
140
|
-
private successes;
|
|
141
|
-
private lastFailure?;
|
|
142
|
-
private config;
|
|
143
|
-
constructor(config?: Partial<CircuitBreakerConfig>);
|
|
144
|
-
/**
|
|
145
|
-
* Execute operation through circuit breaker
|
|
146
|
-
*/
|
|
147
|
-
execute<T>(operation: () => Promise<T>): Promise<T>;
|
|
148
|
-
/**
|
|
149
|
-
* Execute with Result type
|
|
150
|
-
*/
|
|
151
|
-
executeWithResult<T>(operation: () => Promise<T>): Promise<Result<T, CircuitOpenError | Error>>;
|
|
152
|
-
private onSuccess;
|
|
153
|
-
private onFailure;
|
|
154
|
-
private shouldAttemptReset;
|
|
155
|
-
private cleanOldFailures;
|
|
156
|
-
private reset;
|
|
157
|
-
/**
|
|
158
|
-
* Get current circuit state
|
|
159
|
-
*/
|
|
160
|
-
getState(): CircuitState;
|
|
161
|
-
/**
|
|
162
|
-
* Manually reset circuit
|
|
163
|
-
*/
|
|
164
|
-
forceReset(): void;
|
|
165
|
-
/**
|
|
166
|
-
* Get circuit statistics
|
|
167
|
-
*/
|
|
168
|
-
getStats(): {
|
|
169
|
-
state: CircuitState;
|
|
170
|
-
failures: number;
|
|
171
|
-
successes: number;
|
|
172
|
-
lastFailure?: Date;
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Error thrown when circuit is open
|
|
177
|
-
*/
|
|
178
|
-
declare class CircuitOpenError extends Error {
|
|
179
|
-
constructor(message: string);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Create a circuit breaker
|
|
183
|
-
*/
|
|
184
|
-
declare function createCircuitBreaker(config?: Partial<CircuitBreakerConfig>): CircuitBreaker;
|
|
185
|
-
//#endregion
|
|
186
|
-
export { unwrapOr as S, match as _, createCircuitBreaker as a, tryCatchSync as b, Ok as c, err as d, flatMap as f, mapErr as g, map as h, RetryConfig as i, Result as l, isOk as m, CircuitBreakerConfig as n, retry as o, isErr as p, CircuitState as r, Err as s, CircuitBreaker as t, all as u, ok as v, unwrap as x, tryCatch as y };
|