Skip to content

Balance Verification API

The Balance Verification Service reconciles cached wallet balances against the ledger to detect and flag discrepancies.

Overview

Keshless maintains two balance representations:

  1. Cached Balance - User.walletBalance / Vendor.walletBalance (fast reads)
  2. Ledger Balance - Sum of all posted ledger entries (source of truth)

The Balance Verification Service ensures these stay synchronized.

Service Methods

verifyUserBalance(userId)

Verify a single user's balance.

Parameters:

ParameterTypeRequiredDescription
userIdstringYesUser ID

Returns:

typescript
{
  userId: string;
  walletBalance: number;   // Cached balance
  ledgerBalance: number;   // Calculated from ledger
  difference: number;      // Absolute difference
  isReconciled: boolean;   // true if difference < E0.01
}

Example:

typescript
const result = await balanceVerificationService.verifyUserBalance('user-123');
if (!result.isReconciled) {
  console.warn(`Discrepancy: E${result.difference}`);
}

verifyVendorBalance(vendorId)

Verify a single vendor's balance.

Returns: Same structure as verifyUserBalance


verifyAccountBalance(accountCode, userId?, vendorId?)

Verify an account balance cache against ledger.

Parameters:

ParameterTypeRequiredDescription
accountCodestringYesAccount code (e.g., 1110)
userIdstringNoUser ID for entity-specific
vendorIdstringNoVendor ID for entity-specific

Returns:

typescript
{
  accountCode: string;
  entityUserId?: string;
  entityVendorId?: string;
  cachedBalance: number;
  ledgerBalance: number;
  difference: number;
  isReconciled: boolean;
}

verifyAllUserBalances(options)

Verify all user balances in batch.

Parameters:

ParameterTypeDescription
options.triggeredBystringActor ID for audit
options.limitnumberMax users to check

Returns: Reconciliation record with discrepancies

Example:

typescript
const reconciliation = await balanceVerificationService.verifyAllUserBalances({
  triggeredBy: 'admin-456',
  limit: 1000
});

console.log(`Checked: ${reconciliation.notes}`);
console.log(`Discrepancies: ${reconciliation.discrepancies.length}`);

verifyAllVendorBalances(options)

Verify all vendor balances in batch.

Returns: Reconciliation record


verifyAllAccountBalances(options)

Verify all account balance caches.

Returns: Reconciliation record


correctUserBalance(userId, correctedBy, reason)

Correct a user's balance discrepancy by updating wallet balance to match ledger.

Parameters:

ParameterTypeRequiredDescription
userIdstringYesUser ID
correctedBystringYesAdmin ID
reasonstringYesCorrection reason

Side Effects:

  • Updates User.walletBalance to match ledger
  • Creates AuditLog entry with MANUAL_ADJUSTMENT event

Example:

typescript
await balanceVerificationService.correctUserBalance(
  'user-123',
  'admin-456',
  'Monthly reconciliation correction'
);

correctVendorBalance(vendorId, correctedBy, reason)

Correct a vendor's balance discrepancy.


getReconciliationSummary(reconciliationId)

Get detailed summary of a reconciliation run.

Returns:

typescript
{
  reconciliation: Reconciliation;
  criticalDiscrepancies: number;  // > E100
  highPriorityDiscrepancies: number;  // > E10
  totalDiscrepancyAmount: number;
}

autoCorrectSmallDiscrepancies(threshold, dryRun)

Automatically correct discrepancies under a threshold.

Parameters:

ParameterTypeDefaultDescription
thresholdnumber1.0Max amount (E) to auto-correct
dryRunbooleanfalsePreview without changes

Returns:

typescript
{
  corrected: number;
  totalAmount: number;
  errors: Array<{ entityId: string; error: string }>;
}

Example:

typescript
// Preview corrections under E1.00
const preview = await balanceVerificationService.autoCorrectSmallDiscrepancies(1.0, true);
console.log(`Would correct ${preview.corrected} discrepancies (E${preview.totalAmount})`);

// Execute corrections
const result = await balanceVerificationService.autoCorrectSmallDiscrepancies(1.0, false);

Discrepancy Severity Levels

SeverityThresholdAction
CRITICAL> E100Immediate investigation
HIGH> E10Manual review required
MEDIUM≤ E10May auto-correct

Reconciliation Record Schema

typescript
{
  id: string;
  reconciliationType: 'BALANCE_VERIFICATION' | 'ACCOUNT_RECONCILIATION';
  periodStart: Date;
  periodEnd: Date;
  systemBalance: Decimal;
  calculatedBalance: Decimal;
  difference: Decimal;
  isReconciled: boolean;
  reconciledAt?: Date;
  discrepancies: Array<{
    accountCode: string;
    accountName: string;
    entityUserId?: string;
    entityVendorId?: string;
    entityType: 'User' | 'Vendor' | 'System';
    expectedBalance: number;
    actualBalance: number;
    difference: number;
    severity: 'CRITICAL' | 'HIGH' | 'MEDIUM';
  }>;
  notes: string;
  resolution?: string;
}

Scheduled Verification

Balance verification runs automatically via Cloud Scheduler:

JobScheduleScope
User Balance CheckDaily 3:00 AMAll users with balance > 0
Vendor Balance CheckDaily 3:30 AMAll vendors with balance > 0
Account Balance CheckDaily 4:00 AMAll cached balances

Dashboard Integration

Access reconciliation reports in the admin dashboard:

  • Reconciliation History: /admin/reconciliations
  • Discrepancy Details: /admin/reconciliations/:id
  • Correction Log: /admin/audit-logs?type=MANUAL_ADJUSTMENT

Internal use only - Keshless Payment Platform