/** * Script to ensure account has required balance * Usage: ts-node -r tsconfig-paths/register scripts/ensure-account-balance.ts */ import { LedgerAdapterFactory } from '../src/ledger/adapter/factory'; import { Currency } from '../src/models/payment'; import { TransactionType } from '../src/models/transaction'; import { query } from '../src/database/connection'; import { v4 as uuidv4 } from 'uuid'; const ACCOUNT_NUMBER = 'US64000000000000000000001'; const CURRENCY = 'EUR' as Currency; const REQUIRED_BALANCE = 97000000000.00; async function ensureAccountBalance() { try { console.log(`Checking balance for account ${ACCOUNT_NUMBER} (${CURRENCY})...`); const adapter = LedgerAdapterFactory.getAdapter(); const currentBalance = await adapter.getBalance(ACCOUNT_NUMBER, CURRENCY); console.log('Current balance:', { totalBalance: currentBalance.totalBalance, availableBalance: currentBalance.availableBalance, reservedBalance: currentBalance.reservedBalance, }); if (currentBalance.totalBalance >= REQUIRED_BALANCE) { console.log(`✓ Account already has sufficient balance: ${currentBalance.totalBalance.toFixed(2)} ${CURRENCY}`); console.log(` Required: ${REQUIRED_BALANCE.toFixed(2)} ${CURRENCY}`); return; } const difference = REQUIRED_BALANCE - currentBalance.totalBalance; console.log(`Account balance is insufficient. Adding ${difference.toFixed(2)} ${CURRENCY}...`); // Create a system payment record for the initial balance seed const systemPaymentId = uuidv4(); await query( `INSERT INTO payments ( id, payment_id, type, amount, currency, sender_account, sender_bic, receiver_account, receiver_bic, beneficiary_name, maker_operator_id, status ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, (SELECT id FROM operators LIMIT 1), $11) ON CONFLICT (payment_id) DO NOTHING`, [ systemPaymentId, 'SYSTEM-INITIAL-BALANCE', 'FI_TO_FI', difference, CURRENCY, 'SYSTEM', 'SYSTEM', ACCOUNT_NUMBER, 'SYSTEM', 'Initial Balance Seed', 'SETTLED', ] ); // Get the payment ID (may have been created or already exists) const paymentResult = await query( `SELECT id FROM payments WHERE payment_id = $1`, ['SYSTEM-INITIAL-BALANCE'] ); if (paymentResult.rows.length === 0) { throw new Error('Failed to create system payment record'); } const paymentId = paymentResult.rows[0].id; // Create a credit transaction to bring balance to required amount const transactionId = uuidv4(); await query( `INSERT INTO ledger_postings ( internal_transaction_id, payment_id, account_number, transaction_type, amount, currency, status, posting_timestamp, reference ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, [ transactionId, paymentId, ACCOUNT_NUMBER, TransactionType.CREDIT, difference, CURRENCY, 'POSTED', new Date(), 'INITIAL_BALANCE_SEED', ] ); // Verify new balance const newBalance = await adapter.getBalance(ACCOUNT_NUMBER, CURRENCY); console.log('✓ Balance updated successfully!'); console.log('New balance:', { totalBalance: newBalance.totalBalance.toFixed(2), availableBalance: newBalance.availableBalance.toFixed(2), reservedBalance: newBalance.reservedBalance.toFixed(2), }); if (newBalance.totalBalance >= REQUIRED_BALANCE) { console.log(`✓ Account now has sufficient balance: ${newBalance.totalBalance.toFixed(2)} ${CURRENCY}`); } else { console.error(`✗ Error: Balance still insufficient: ${newBalance.totalBalance.toFixed(2)} ${CURRENCY}`); process.exit(1); } } catch (error: any) { console.error('Error ensuring account balance:', error.message); console.error(error.stack); process.exit(1); } } // Run if executed directly if (require.main === module) { ensureAccountBalance() .then(() => { console.log('Script completed successfully'); process.exit(0); }) .catch((error) => { console.error('Script failed:', error); process.exit(1); }); } export { ensureAccountBalance };