# Transaction Reversal Management Documentation

## Overview

This document provides comprehensive guidelines for managing transaction reversals and preventing stuck transactions in the `pos_temp_transaction` table within the three-table architecture transaction processing lifecycle.

## Core Principles

1. **Never clean temp table without reversal processing**
2. **All timeout scenarios must trigger automatic reversals**  
3. **Atomic operations for all temp table modifications**
4. **Proper status tracking throughout reversal lifecycle**

## Architecture Components

### Database Tables

- **`pos_temp_transaction`** - Active/in-progress transactions with status tracking
- **`pos_transaction`** - Successfully completed transactions
- **`pos_failed_transaction`** - Failed or declined transactions
- **`pos_transaction_reversal`** - Reversal tracking and audit trail

### Service Components

- **`TransactionRouter`** - Enhanced with reversal-aware processing
- **`TransactionAuxUtils`** - Core transaction and reversal utilities
- **`ReversalService`** - Handles all reversal scenarios
- **`ReversalMetrics`** - Monitoring and alerting system
- **`ReversalConfig`** - Centralized configuration management

## Reversal Scenarios and Implementation

### 1. Duplicate Request Detection and Stale Transaction Cleanup

**Scenario**: New MTI 0200/0100 request with existing temp transaction older than 45 seconds

```java
// TransactionRouter integration
if (!reversalService.checkAndHandleStaleTransactions(bankTid, bankMid)) {
    logger.log("Stale transaction cleanup in progress for terminal: " + bankTid);
    ISOMsg busyResponse = generateErrorMsg(request);
    busyResponse.set(39, "76"); // Blocked terminal - cleanup in progress
    return busyResponse;
}
```

**Implementation Details**:
- Checks age of existing temp transactions before processing new requests
- Initiates reversal for transactions older than configurable threshold (default: 45 seconds)
- Blocks new transactions until reversal completes
- Uses atomic operations to prevent race conditions

### 2. Response Timeout Auto-Reversal

**Scenario**: Bank response timeout triggers automatic reversal

```java
// Enhanced bank communication with timeout handling
try {
    long bankRequestStart = System.currentTimeMillis();
    acqResponse = acquirerChannel.transceive(acqRequest, acquirerConnection);
    long bankRequestDuration = System.currentTimeMillis() - bankRequestStart;
    logger.log("Bank response received in " + bankRequestDuration + "ms");
    
} catch (Exception communicationException) {
    logger.log("Communication error with acquirer: " + communicationException.getMessage());
    reversalService.handleConnectionLoss(tempTransaction);
    return generateTimeoutErrorMsg(request);
}

if (acqResponse == null) {
    reversalService.handleResponseTimeout(tempTransaction);
    return generateTimeoutErrorMsg(request);
}
```

**Implementation Details**:
- Monitors bank communication timeouts
- Automatically initiates MTI 0400/0420 reversal messages
- Updates temp transaction status during reversal process
- Implements retry mechanism for failed reversals

### 3. Connection Loss During Transaction

**Scenario**: TCP/IP connection lost while waiting for bank response

```java
public void handleConnectionLoss(PosTempTransaction tempTransaction) {
    // Mark transaction as connection lost
    transactionAuxUtils.updateTempTransactionStatus(
        tempTransaction.getId(), 
        PosTempTransaction.TempTransactionStatus.CONNECTION_LOST
    );
    
    // Wait for connection recovery with timeout
    if (waitForConnectionRecovery(CONNECTION_RECOVERY_TIMEOUT_SECONDS * 1000)) {
        initiateReversal(tempTransaction, PosTransactionReversal.REASON_CONNECTION_LOST);
    } else {
        // Mark for manual review if connection doesn't recover
        transactionAuxUtils.updateTempTransactionStatus(
            tempTransaction.getId(), 
            PosTempTransaction.TempTransactionStatus.PENDING_MANUAL_REVIEW
        );
    }
}
```

**Implementation Details**:
- Detects connection failures during bank communication
- Attempts connection recovery with configurable timeout
- Initiates reversal once connection is restored
- Escalates to manual review if connection cannot be restored

### 4. System Startup Cleanup

**Scenario**: System restart with orphaned temp transactions

```java
@PostConstruct
public void cleanupOrphanedTransactions() {
    logger.log("Starting system startup cleanup of orphaned temp transactions");
    
    List<PosTempTransaction> orphanedTemps = transactionAuxUtils.findStaleTemps(
        STARTUP_CLEANUP_AGE_THRESHOLD_MINUTES
    );
    
    int cleanedUp = 0;
    for (PosTempTransaction tempTxn : orphanedTemps) {
        try {
            if (!transactionAuxUtils.reversalExists(tempTxn)) {
                initiateReversal(tempTxn, PosTransactionReversal.REASON_SYSTEM_STARTUP);
                cleanedUp++;
            }
        } catch (Exception e) {
            logger.log("Error during startup cleanup of temp txn " + tempTxn.getId());
        }
    }
    
    logger.log("System startup cleanup completed: " + cleanedUp + " transactions processed");
}
```

**Implementation Details**:
- Runs automatically on system startup (`@PostConstruct`)
- Finds temp transactions older than threshold (default: 5 minutes)
- Initiates reversals for orphaned transactions
- Prevents duplicate reversals by checking existing reversal records

### 5. Database Transaction Rollback

**Scenario**: Database error during temp to final table movement

```java
// Enhanced success/failure handling with database error recovery
try {
    if ("00".equals(responseCode) || "10".equals(responseCode) || "11".equals(responseCode)) {
        PosTransaction successTxn = transactionAuxUtils.createSuccessTransactionFromTemp(tempTransaction, response);
        transactionAuxUtils.moveTempToSuccess(tempTransaction.getId(), successTxn);
        logger.log("Transaction successful for terminal " + bankTid);
    } else {
        PosFailedTransaction failedTxn = transactionAuxUtils.createFailedTransactionFromTemp(tempTransaction, response);
        transactionAuxUtils.moveTempToFailed(tempTransaction.getId(), failedTxn);
        logger.log("Transaction failed for terminal " + bankTid);
    }
    
} catch (Exception dbError) {
    logger.log("Database error during transaction completion: " + dbError.getMessage());
    reversalService.handleDatabaseError(tempTransaction, dbError);
    
    // Return system error to POS
    ISOMsg errorResponse = (ISOMsg)request.clone(SUPPORTED_FIELDS);
    errorResponse.setResponseMTI();
    errorResponse.set(39, "96"); // System error
    return errorResponse;
}
```

**Implementation Details**:
- Catches database errors during atomic temp-to-final operations
- Initiates reversal when local database operations fail
- Ensures bank and local systems remain synchronized
- Returns appropriate error codes to POS terminal

## Configuration Parameters

```properties
# Reversal timing configuration
reversal.stale.transaction.threshold.seconds=45
reversal.response.timeout.seconds=30
reversal.retry.max.attempts=3
reversal.retry.delay.seconds=60

# Connection management
connection.recovery.timeout.seconds=30
connection.health.check.interval.seconds=10

# Cleanup configuration
startup.cleanup.age.threshold.minutes=5
scheduled.cleanup.interval.minutes=15

# Monitoring thresholds
monitoring.max.pending.reversals=10
monitoring.max.temp.age.minutes=10
monitoring.max.reversal.rate.threshold=0.05
```

This comprehensive approach ensures that no transaction can get permanently stuck in the temp table while maintaining proper reversal procedures with the bank.