forked from StellarSplit/StellarSplit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpayment-reconciliation.processor.ts
More file actions
89 lines (78 loc) · 2.63 KB
/
Copy pathpayment-reconciliation.processor.ts
File metadata and controls
89 lines (78 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { Injectable, Logger } from "@nestjs/common";
import { Processor, Process } from "@nestjs/bull";
import { Job } from "bull";
import { PaymentReconciliationService } from "./payment-reconciliation.service";
/**
* Queue processor for payment reconciliation jobs
*/
@Processor("payment-reconciliation")
@Injectable()
export class PaymentReconciliationProcessor {
private readonly logger = new Logger(PaymentReconciliationProcessor.name);
constructor(
private readonly reconciliationService: PaymentReconciliationService,
) {}
/**
* Process reconciliation job for a single payment
*/
@Process("reconcile-payment")
async handleReconcilePayment(job: Job<{ paymentId: string }>): Promise<void> {
const { paymentId } = job.data;
this.logger.log(`Processing reconciliation job for payment: ${paymentId}`);
try {
const result = await this.reconciliationService.reconcilePayment(paymentId);
this.logger.log(
`Reconciliation result for ${paymentId}: ${result.newStatus}`,
);
// If the payment was confirmed or failed, emit final events
if (
result.newStatus === "confirmed" ||
result.newStatus === "failed"
) {
this.logger.log(
`Payment ${paymentId} reached final state: ${result.newStatus}`,
);
}
} catch (error: unknown) {
this.logger.error(
`Failed to reconcile payment ${paymentId}: ${(error as Error).message}`,
);
throw error;
}
}
/**
* Process batch reconciliation job
*/
@Process("reconcile-batch")
async handleReconcileBatch(
job: Job<{ paymentIds: string[] }>,
): Promise<void> {
const { paymentIds } = job.data;
this.logger.log(
`Processing batch reconciliation for ${paymentIds.length} payments`,
);
const results = await Promise.allSettled(
paymentIds.map((id: string) => this.reconciliationService.reconcilePayment(id)),
);
const successful = results.filter(
(r: PromiseSettledResult<any>) => r.status === "fulfilled",
).length;
const failed = results.filter(
(r: PromiseSettledResult<any>) => r.status === "rejected",
).length;
this.logger.log(
`Batch reconciliation complete: ${successful} successful, ${failed} failed`,
);
// If there are failures, we could implement retry logic here
if (failed > 0) {
const failedIds = results
.map((r: PromiseSettledResult<any>, i: number) =>
r.status === "rejected" ? paymentIds[i] : null,
)
.filter(Boolean) as string[];
this.logger.warn(
`Failed payment IDs: ${JSON.stringify(failedIds)}`,
);
}
}
}