diff --git a/src/shared/repositories/repository.factory.ts b/src/shared/repositories/repository.factory.ts index 25e509e336..e9c3500e61 100644 --- a/src/shared/repositories/repository.factory.ts +++ b/src/shared/repositories/repository.factory.ts @@ -15,6 +15,7 @@ import { DepositRepository } from 'src/subdomains/supporting/address-pool/deposi import { DepositRouteRepository } from 'src/subdomains/supporting/address-pool/route/deposit-route.repository'; import { BankTxRepository } from 'src/subdomains/supporting/bank-tx/bank-tx/repositories/bank-tx.repository'; import { LiquidityOrderRepository } from 'src/subdomains/supporting/dex/repositories/liquidity-order.repository'; +import { FiatOutputRepository } from 'src/subdomains/supporting/fiat-output/fiat-output.repository'; import { CheckoutTxRepository } from 'src/subdomains/supporting/fiat-payin/repositories/checkout-tx.repository'; import { PayInRepository } from 'src/subdomains/supporting/payin/repositories/payin.repository'; import { TransactionSpecificationRepository } from 'src/subdomains/supporting/payment/repositories/transaction-specification.repository'; @@ -43,6 +44,7 @@ export class RepositoryFactory { public readonly lmOrder: LiquidityManagementOrderRepository; public readonly lmRule: LiquidityManagementRuleRepository; public readonly custodyOrder: CustodyOrderRepository; + public readonly fiatOutput: FiatOutputRepository; constructor(manager: EntityManager) { this.user = new UserRepository(manager); @@ -65,5 +67,6 @@ export class RepositoryFactory { this.lmOrder = new LiquidityManagementOrderRepository(manager); this.lmRule = new LiquidityManagementRuleRepository(manager); this.custodyOrder = new CustodyOrderRepository(manager); + this.fiatOutput = new FiatOutputRepository(manager); } } diff --git a/src/subdomains/core/monitoring/health.controller.ts b/src/subdomains/core/monitoring/health.controller.ts index dfd9d689cb..c1fbf7f8bd 100644 --- a/src/subdomains/core/monitoring/health.controller.ts +++ b/src/subdomains/core/monitoring/health.controller.ts @@ -139,12 +139,14 @@ export class HealthController { private checkPayment(state: SystemState | null): { status: HealthStatus; detail?: string } { const data = state?.payment?.combined?.data as { stuckPayments?: number; + stuckFiatOutputs?: number; unhandledCryptoInputs?: number; }; if (!data) return { status: HealthStatus.DEGRADED, detail: 'No payment data' }; const issues: string[] = []; if (data.stuckPayments > 0) issues.push(`${data.stuckPayments} stuck quotes`); + if (data.stuckFiatOutputs > 0) issues.push(`${data.stuckFiatOutputs} stuck fiat outputs`); if (data.unhandledCryptoInputs > 5) issues.push(`${data.unhandledCryptoInputs} unhandled inputs`); if (issues.length === 0) return { status: HealthStatus.OK }; diff --git a/src/subdomains/core/monitoring/observers/payment.observer.ts b/src/subdomains/core/monitoring/observers/payment.observer.ts index eb8a502628..8b48d32f0d 100644 --- a/src/subdomains/core/monitoring/observers/payment.observer.ts +++ b/src/subdomains/core/monitoring/observers/payment.observer.ts @@ -25,6 +25,7 @@ interface PaymentData { bankTxGsType: number; refRewardManualCheck: number; stuckPayments: number; + stuckFiatOutputs: number; pendingCustodyOrders: number; } @@ -108,6 +109,11 @@ export class PaymentObserver extends MetricObserver { ), created: LessThan(Util.hoursBefore(3)), }), + stuckFiatOutputs: await this.repos.fiatOutput.countBy({ + isReadyDate: LessThan(Util.hoursBefore(1)), + isTransmittedDate: IsNull(), + isComplete: false, + }), pendingCustodyOrders: await this.repos.custodyOrder.countBy({ status: CustodyOrderStatus.CONFIRMED, type: Not(In(CustodyIncomingTypes)),