@clduab11/gemini-flow
Version:
Revolutionary AI agent swarm coordination platform with Google Services integration, multimedia processing, and production-ready monitoring. Features 8 Google AI services, quantum computing capabilities, and enterprise-grade security.
996 lines (830 loc) • 31.3 kB
text/typescript
/**
* Transaction Integrity Verification System
*
* Provides comprehensive transaction integrity validation for Google Services
* integration workflows, ensuring ACID properties across distributed operations,
* handling partial failures, and maintaining data consistency.
*/
import { EventEmitter } from 'events';
import { createHash } from 'crypto';
import { performance } from 'perf_hooks';
export interface TransactionContext {
transactionId: string;
sessionId: string;
initiator: string;
startTime: Date;
timeout: number;
isolation: 'read_uncommitted' | 'read_committed' | 'repeatable_read' | 'serializable';
operations: TransactionOperation[];
checkpoints: TransactionCheckpoint[];
compensations: CompensationAction[];
state: TransactionState;
metadata: Record<string, any>;
}
export interface TransactionOperation {
operationId: string;
service: string;
type: 'create' | 'read' | 'update' | 'delete' | 'execute';
endpoint: string;
payload: any;
expectedResult?: any;
timestamp: Date;
status: 'pending' | 'executing' | 'completed' | 'failed' | 'compensated';
duration?: number;
result?: any;
error?: Error;
retryCount: number;
maxRetries: number;
idempotencyKey?: string;
}
export interface TransactionCheckpoint {
checkpointId: string;
timestamp: Date;
operationId: string;
state: any;
checksum: string;
canRollback: boolean;
rollbackData?: any;
}
export interface CompensationAction {
actionId: string;
operationId: string;
service: string;
action: 'rollback' | 'compensate' | 'retry';
payload: any;
status: 'pending' | 'executing' | 'completed' | 'failed';
timestamp?: Date;
result?: any;
error?: Error;
}
export interface TransactionState {
phase: 'preparing' | 'committing' | 'committed' | 'aborting' | 'aborted' | 'partial';
completedOperations: number;
totalOperations: number;
errorCount: number;
consistencyLevel: 'strong' | 'eventual' | 'weak' | 'unknown';
isolationViolations: number;
integrityScore: number;
}
export interface TransactionReport {
transactionId: string;
sessionId: string;
startTime: Date;
endTime: Date;
duration: number;
finalState: TransactionState;
operations: TransactionOperation[];
checkpoints: TransactionCheckpoint[];
compensations: CompensationAction[];
integrityVerification: IntegrityVerificationResult;
recommendations: string[];
}
export interface IntegrityVerificationResult {
atomicity: {
score: number;
violations: AtomicityViolation[];
passed: boolean;
};
consistency: {
score: number;
violations: ConsistencyViolation[];
passed: boolean;
};
isolation: {
score: number;
violations: IsolationViolation[];
passed: boolean;
};
durability: {
score: number;
violations: DurabilityViolation[];
passed: boolean;
};
overall: {
score: number;
passed: boolean;
grade: 'A' | 'B' | 'C' | 'D' | 'F';
};
}
export interface AtomicityViolation {
type: 'partial_commit' | 'incomplete_rollback' | 'orphaned_operation';
operationId: string;
service: string;
description: string;
severity: 'high' | 'medium' | 'low';
impact: string;
}
export interface ConsistencyViolation {
type: 'data_inconsistency' | 'constraint_violation' | 'referential_integrity';
services: string[];
description: string;
dataPoints: any[];
severity: 'high' | 'medium' | 'low';
}
export interface IsolationViolation {
type: 'dirty_read' | 'non_repeatable_read' | 'phantom_read' | 'lost_update';
operationIds: string[];
description: string;
severity: 'high' | 'medium' | 'low';
}
export interface DurabilityViolation {
type: 'data_loss' | 'checkpoint_failure' | 'recovery_failure';
operationId: string;
description: string;
severity: 'high' | 'medium' | 'low';
recoverability: 'recoverable' | 'partial' | 'lost';
}
export class TransactionIntegrityVerifier extends EventEmitter {
private activeTransactions: Map<string, TransactionContext> = new Map();
private transactionHistory: Map<string, TransactionReport[]> = new Map();
private globalState: Map<string, any> = new Map();
private locks: Map<string, Set<string>> = new Map();
constructor(
private config: {
defaultTimeout?: number;
maxRetries?: number;
checkpointFrequency?: number;
isolationLevel?: 'read_uncommitted' | 'read_committed' | 'repeatable_read' | 'serializable';
} = {}
) {
super();
}
/**
* Begin a new distributed transaction
*/
async beginTransaction(
sessionId: string,
initiator: string,
options: {
timeout?: number;
isolation?: 'read_uncommitted' | 'read_committed' | 'repeatable_read' | 'serializable';
metadata?: Record<string, any>;
} = {}
): Promise<string> {
const transactionId = this.generateTransactionId();
const context: TransactionContext = {
transactionId,
sessionId,
initiator,
startTime: new Date(),
timeout: options.timeout || this.config.defaultTimeout || 300000, // 5 minutes default
isolation: options.isolation || this.config.isolationLevel || 'read_committed',
operations: [],
checkpoints: [],
compensations: [],
state: {
phase: 'preparing',
completedOperations: 0,
totalOperations: 0,
errorCount: 0,
consistencyLevel: 'strong',
isolationViolations: 0,
integrityScore: 1.0
},
metadata: options.metadata || {}
};
this.activeTransactions.set(transactionId, context);
// Set transaction timeout
setTimeout(() => {
this.handleTransactionTimeout(transactionId);
}, context.timeout);
this.emit('transactionBegan', {
transactionId,
sessionId,
initiator,
isolation: context.isolation
});
return transactionId;
}
/**
* Add an operation to a transaction
*/
async addOperation(
transactionId: string,
operation: Omit<TransactionOperation, 'operationId' | 'timestamp' | 'status' | 'retryCount'>
): Promise<string> {
const context = this.activeTransactions.get(transactionId);
if (!context) {
throw new Error(`Transaction ${transactionId} not found`);
}
if (context.state.phase !== 'preparing') {
throw new Error(`Cannot add operations to transaction in ${context.state.phase} phase`);
}
const operationId = this.generateOperationId(transactionId);
const transactionOperation: TransactionOperation = {
...operation,
operationId,
timestamp: new Date(),
status: 'pending',
retryCount: 0,
maxRetries: this.config.maxRetries || 3
};
context.operations.push(transactionOperation);
context.state.totalOperations++;
// Create checkpoint for rollback capability
if (operation.type !== 'read') {
await this.createCheckpoint(transactionId, operationId);
}
this.emit('operationAdded', {
transactionId,
operationId,
service: operation.service,
type: operation.type
});
return operationId;
}
/**
* Execute a transaction operation with integrity checks
*/
async executeOperation(
transactionId: string,
operationId: string
): Promise<any> {
const context = this.activeTransactions.get(transactionId);
if (!context) {
throw new Error(`Transaction ${transactionId} not found`);
}
const operation = context.operations.find(op => op.operationId === operationId);
if (!operation) {
throw new Error(`Operation ${operationId} not found`);
}
if (operation.status !== 'pending') {
throw new Error(`Operation ${operationId} is not in pending state`);
}
// Acquire locks for isolation
await this.acquireLocks(transactionId, operation);
operation.status = 'executing';
const startTime = performance.now();
try {
// Perform pre-execution validation
await this.validatePreExecution(context, operation);
// Execute the operation
const result = await this.performOperation(operation);
// Perform post-execution validation
await this.validatePostExecution(context, operation, result);
operation.result = result;
operation.status = 'completed';
operation.duration = performance.now() - startTime;
context.state.completedOperations++;
// Update integrity score
this.updateIntegrityScore(context);
this.emit('operationCompleted', {
transactionId,
operationId,
duration: operation.duration,
result
});
return result;
} catch (error) {
operation.error = error as Error;
operation.status = 'failed';
operation.duration = performance.now() - startTime;
context.state.errorCount++;
this.emit('operationFailed', {
transactionId,
operationId,
error: error as Error,
retryCount: operation.retryCount
});
// Attempt retry if allowed
if (operation.retryCount < operation.maxRetries) {
return this.retryOperation(transactionId, operationId);
}
// Create compensation action
await this.createCompensationAction(transactionId, operationId, error as Error);
throw error;
} finally {
// Release locks
this.releaseLocks(transactionId, operation);
}
}
/**
* Commit the transaction
*/
async commitTransaction(transactionId: string): Promise<TransactionReport> {
const context = this.activeTransactions.get(transactionId);
if (!context) {
throw new Error(`Transaction ${transactionId} not found`);
}
context.state.phase = 'committing';
try {
// Validate all operations completed successfully
const failedOps = context.operations.filter(op => op.status === 'failed');
if (failedOps.length > 0) {
throw new Error(`Cannot commit transaction with ${failedOps.length} failed operations`);
}
// Perform final integrity verification
const integrityResult = await this.verifyTransactionIntegrity(context);
if (!integrityResult.overall.passed) {
throw new Error(`Transaction integrity verification failed: ${integrityResult.overall.score}`);
}
// Commit all operations
await this.performCommit(context);
context.state.phase = 'committed';
const report = await this.generateTransactionReport(context, integrityResult);
// Store in history
const history = this.transactionHistory.get(context.sessionId) || [];
history.push(report);
this.transactionHistory.set(context.sessionId, history);
// Cleanup
this.activeTransactions.delete(transactionId);
this.emit('transactionCommitted', {
transactionId,
sessionId: context.sessionId,
duration: report.duration,
integrityScore: integrityResult.overall.score
});
return report;
} catch (error) {
// Rollback on commit failure
await this.rollbackTransaction(transactionId, error as Error);
throw error;
}
}
/**
* Rollback the transaction
*/
async rollbackTransaction(transactionId: string, reason?: Error): Promise<void> {
const context = this.activeTransactions.get(transactionId);
if (!context) {
throw new Error(`Transaction ${transactionId} not found`);
}
context.state.phase = 'aborting';
try {
// Execute compensations in reverse order
const completedOps = context.operations
.filter(op => op.status === 'completed')
.reverse();
for (const operation of completedOps) {
await this.compensateOperation(context, operation);
}
// Restore from checkpoints
await this.restoreFromCheckpoints(context);
context.state.phase = 'aborted';
this.emit('transactionRolledBack', {
transactionId,
sessionId: context.sessionId,
reason: reason?.message,
compensationsExecuted: context.compensations.length
});
} catch (rollbackError) {
context.state.phase = 'partial';
this.emit('rollbackFailed', {
transactionId,
originalError: reason,
rollbackError
});
throw rollbackError;
} finally {
this.activeTransactions.delete(transactionId);
}
}
/**
* Verify transaction integrity (ACID properties)
*/
async verifyTransactionIntegrity(context: TransactionContext): Promise<IntegrityVerificationResult> {
const atomicity = await this.verifyAtomicity(context);
const consistency = await this.verifyConsistency(context);
const isolation = await this.verifyIsolation(context);
const durability = await this.verifyDurability(context);
const overallScore = (atomicity.score + consistency.score + isolation.score + durability.score) / 4;
const overallPassed = atomicity.passed && consistency.passed && isolation.passed && durability.passed;
let grade: 'A' | 'B' | 'C' | 'D' | 'F';
if (overallScore >= 0.9) grade = 'A';
else if (overallScore >= 0.8) grade = 'B';
else if (overallScore >= 0.7) grade = 'C';
else if (overallScore >= 0.6) grade = 'D';
else grade = 'F';
return {
atomicity,
consistency,
isolation,
durability,
overall: {
score: overallScore,
passed: overallPassed,
grade
}
};
}
// Private helper methods
private async verifyAtomicity(context: TransactionContext): Promise<{score: number, violations: AtomicityViolation[], passed: boolean}> {
const violations: AtomicityViolation[] = [];
// Check for partial commits
const completedOps = context.operations.filter(op => op.status === 'completed').length;
const failedOps = context.operations.filter(op => op.status === 'failed').length;
if (completedOps > 0 && failedOps > 0 && context.state.phase !== 'aborting') {
violations.push({
type: 'partial_commit',
operationId: 'multiple',
service: 'multiple',
description: `Transaction has both completed (${completedOps}) and failed (${failedOps}) operations`,
severity: 'high',
impact: 'Data inconsistency across services'
});
}
// Check for incomplete rollbacks
const uncompensdatedOps = context.operations.filter(op =>
op.status === 'completed' &&
!context.compensations.some(comp => comp.operationId === op.operationId && comp.status === 'completed')
);
if (context.state.phase === 'aborted' && uncompensdatedOps.length > 0) {
violations.push({
type: 'incomplete_rollback',
operationId: uncompensdatedOps[0].operationId,
service: uncompensdatedOps[0].service,
description: `${uncompensdatedOps.length} operations not compensated during rollback`,
severity: 'high',
impact: 'Partial data remains committed'
});
}
// Check for orphaned operations
context.operations.forEach(op => {
if (op.status === 'executing' && Date.now() - op.timestamp.getTime() > 60000) {
violations.push({
type: 'orphaned_operation',
operationId: op.operationId,
service: op.service,
description: 'Operation has been executing for over 60 seconds',
severity: 'medium',
impact: 'Resource leakage and inconsistent state'
});
}
});
const score = Math.max(0, 1 - (violations.length * 0.2));
return {
score,
violations,
passed: violations.filter(v => v.severity === 'high').length === 0
};
}
private async verifyConsistency(context: TransactionContext): Promise<{score: number, violations: ConsistencyViolation[], passed: boolean}> {
const violations: ConsistencyViolation[] = [];
// Group operations by data entity
const entityGroups = new Map<string, TransactionOperation[]>();
context.operations.forEach(op => {
const entityKey = this.extractEntityKey(op);
if (!entityGroups.has(entityKey)) {
entityGroups.set(entityKey, []);
}
entityGroups.get(entityKey)!.push(op);
});
// Check consistency within each entity group
for (const [entityKey, operations] of entityGroups) {
const dataStates = operations
.filter(op => op.result && op.status === 'completed')
.map(op => ({ service: op.service, data: op.result }));
if (dataStates.length > 1) {
const inconsistencies = this.detectDataInconsistencies(dataStates);
if (inconsistencies.length > 0) {
violations.push({
type: 'data_inconsistency',
services: [...new Set(dataStates.map(ds => ds.service))],
description: `Inconsistent data states detected for entity ${entityKey}`,
dataPoints: inconsistencies,
severity: 'high'
});
}
}
}
const score = Math.max(0, 1 - (violations.length * 0.3));
return {
score,
violations,
passed: violations.filter(v => v.severity === 'high').length === 0
};
}
private async verifyIsolation(context: TransactionContext): Promise<{score: number, violations: IsolationViolation[], passed: boolean}> {
const violations: IsolationViolation[] = [];
// This would typically check for isolation violations across concurrent transactions
// For now, we'll check for potential issues within the transaction
const score = Math.max(0, 1 - (context.state.isolationViolations * 0.1));
return {
score,
violations,
passed: context.state.isolationViolations === 0
};
}
private async verifyDurability(context: TransactionContext): Promise<{score: number, violations: DurabilityViolation[], passed: boolean}> {
const violations: DurabilityViolation[] = [];
// Check checkpoint integrity
const checkpointFailures = context.checkpoints.filter(cp => !cp.canRollback);
checkpointFailures.forEach(cp => {
violations.push({
type: 'checkpoint_failure',
operationId: cp.operationId,
description: `Checkpoint ${cp.checkpointId} cannot be used for rollback`,
severity: 'medium',
recoverability: 'partial'
});
});
const score = Math.max(0, 1 - (violations.length * 0.15));
return {
score,
violations,
passed: violations.filter(v => v.severity === 'high').length === 0
};
}
private generateTransactionId(): string {
return `txn-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
private generateOperationId(transactionId: string): string {
const context = this.activeTransactions.get(transactionId);
const opCount = context ? context.operations.length : 0;
return `${transactionId}-op-${opCount + 1}`;
}
private async createCheckpoint(transactionId: string, operationId: string): Promise<void> {
const context = this.activeTransactions.get(transactionId);
if (!context) return;
const checkpointId = `${operationId}-checkpoint-${Date.now()}`;
const state = this.captureCurrentState(operationId);
const checkpoint: TransactionCheckpoint = {
checkpointId,
timestamp: new Date(),
operationId,
state,
checksum: this.calculateStateChecksum(state),
canRollback: true,
rollbackData: this.captureRollbackData(operationId)
};
context.checkpoints.push(checkpoint);
}
private async performOperation(operation: TransactionOperation): Promise<any> {
// This would typically make HTTP requests to actual services
// For testing purposes, we'll simulate the operation
await new Promise(resolve => setTimeout(resolve, 100 + Math.random() * 200));
// Simulate occasional failures for testing
if (Math.random() < 0.05) { // 5% failure rate
throw new Error(`Simulated failure for operation ${operation.operationId}`);
}
return {
operationId: operation.operationId,
service: operation.service,
timestamp: new Date(),
result: 'success',
data: operation.payload
};
}
private async retryOperation(transactionId: string, operationId: string): Promise<any> {
const context = this.activeTransactions.get(transactionId);
if (!context) throw new Error(`Transaction ${transactionId} not found`);
const operation = context.operations.find(op => op.operationId === operationId);
if (!operation) throw new Error(`Operation ${operationId} not found`);
operation.retryCount++;
operation.status = 'pending';
// Exponential backoff
const delay = Math.min(1000 * Math.pow(2, operation.retryCount - 1), 30000);
await new Promise(resolve => setTimeout(resolve, delay));
return this.executeOperation(transactionId, operationId);
}
private async createCompensationAction(
transactionId: string,
operationId: string,
error: Error
): Promise<void> {
const context = this.activeTransactions.get(transactionId);
if (!context) return;
const operation = context.operations.find(op => op.operationId === operationId);
if (!operation) return;
const compensation: CompensationAction = {
actionId: `${operationId}-compensation`,
operationId,
service: operation.service,
action: 'rollback',
payload: this.generateCompensationPayload(operation),
status: 'pending'
};
context.compensations.push(compensation);
}
private generateCompensationPayload(operation: TransactionOperation): any {
// Generate appropriate compensation payload based on operation type
switch (operation.type) {
case 'create':
return { action: 'delete', id: operation.result?.id };
case 'update':
return { action: 'restore', previousState: operation.result?.previousState };
case 'delete':
return { action: 'restore', data: operation.result?.deletedData };
default:
return { action: 'noop' };
}
}
private async handleTransactionTimeout(transactionId: string): Promise<void> {
const context = this.activeTransactions.get(transactionId);
if (!context) return;
if (context.state.phase === 'preparing' || context.state.phase === 'committing') {
this.emit('transactionTimeout', { transactionId, phase: context.state.phase });
await this.rollbackTransaction(transactionId, new Error('Transaction timeout'));
}
}
private extractEntityKey(operation: TransactionOperation): string {
// Extract entity key from operation for consistency checking
return operation.payload?.entityId || operation.payload?.id || 'unknown';
}
private detectDataInconsistencies(dataStates: Array<{service: string, data: any}>): any[] {
const inconsistencies: any[] = [];
// Simple consistency check - compare common fields
const commonFields = ['id', 'status', 'timestamp', 'version'];
commonFields.forEach(field => {
const values = dataStates
.filter(ds => ds.data[field] !== undefined)
.map(ds => ({ service: ds.service, value: ds.data[field] }));
const uniqueValues = new Set(values.map(v => v.value));
if (uniqueValues.size > 1) {
inconsistencies.push({
field,
values,
description: `Field '${field}' has different values across services`
});
}
});
return inconsistencies;
}
private updateIntegrityScore(context: TransactionContext): void {
const totalOps = context.state.totalOperations;
const completedOps = context.state.completedOperations;
const errorCount = context.state.errorCount;
if (totalOps === 0) {
context.state.integrityScore = 1.0;
return;
}
const completionRate = completedOps / totalOps;
const errorRate = errorCount / totalOps;
const isolationPenalty = context.state.isolationViolations * 0.1;
context.state.integrityScore = Math.max(0, completionRate - errorRate - isolationPenalty);
}
private async acquireLocks(transactionId: string, operation: TransactionOperation): Promise<void> {
// Simple lock mechanism for demonstration
const resourceKey = `${operation.service}:${this.extractEntityKey(operation)}`;
if (!this.locks.has(resourceKey)) {
this.locks.set(resourceKey, new Set());
}
this.locks.get(resourceKey)!.add(transactionId);
}
private releaseLocks(transactionId: string, operation: TransactionOperation): void {
const resourceKey = `${operation.service}:${this.extractEntityKey(operation)}`;
if (this.locks.has(resourceKey)) {
this.locks.get(resourceKey)!.delete(transactionId);
if (this.locks.get(resourceKey)!.size === 0) {
this.locks.delete(resourceKey);
}
}
}
private async validatePreExecution(context: TransactionContext, operation: TransactionOperation): Promise<void> {
// Pre-execution validation logic
if (operation.idempotencyKey) {
// Check if operation with same idempotency key already executed
const existingOp = context.operations.find(
op => op.idempotencyKey === operation.idempotencyKey && op.status === 'completed'
);
if (existingOp) {
throw new Error(`Operation with idempotency key ${operation.idempotencyKey} already executed`);
}
}
}
private async validatePostExecution(
context: TransactionContext,
operation: TransactionOperation,
result: any
): Promise<void> {
// Post-execution validation logic
if (operation.expectedResult) {
const isExpectedResult = this.compareResults(result, operation.expectedResult);
if (!isExpectedResult) {
throw new Error(`Operation result does not match expected result`);
}
}
}
private compareResults(actual: any, expected: any): boolean {
// Simple result comparison - can be enhanced for complex objects
return JSON.stringify(actual) === JSON.stringify(expected);
}
private captureCurrentState(operationId: string): any {
// Capture current state for checkpoint
return {
operationId,
timestamp: new Date(),
globalState: Object.fromEntries(this.globalState)
};
}
private calculateStateChecksum(state: any): string {
const serialized = JSON.stringify(state, Object.keys(state).sort());
return createHash('sha256').update(serialized).digest('hex').substr(0, 16);
}
private captureRollbackData(operationId: string): any {
// Capture data needed for rollback
return {
operationId,
rollbackInstructions: [],
stateSnapshot: this.captureCurrentState(operationId)
};
}
private async performCommit(context: TransactionContext): Promise<void> {
// Perform actual commit operations
for (const operation of context.operations) {
if (operation.status === 'completed') {
// Mark as permanently committed
operation.result = { ...operation.result, committed: true };
}
}
}
private async compensateOperation(context: TransactionContext, operation: TransactionOperation): Promise<void> {
const compensation = context.compensations.find(comp => comp.operationId === operation.operationId);
if (!compensation) return;
compensation.status = 'executing';
compensation.timestamp = new Date();
try {
// Execute compensation
const result = await this.performCompensation(compensation);
compensation.result = result;
compensation.status = 'completed';
// Mark original operation as compensated
operation.status = 'compensated';
} catch (error) {
compensation.error = error as Error;
compensation.status = 'failed';
throw error;
}
}
private async performCompensation(compensation: CompensationAction): Promise<any> {
// Simulate compensation operation
await new Promise(resolve => setTimeout(resolve, 50 + Math.random() * 100));
return {
compensationId: compensation.actionId,
action: compensation.action,
timestamp: new Date(),
result: 'compensated'
};
}
private async restoreFromCheckpoints(context: TransactionContext): Promise<void> {
// Restore state from checkpoints
for (const checkpoint of context.checkpoints.reverse()) {
if (checkpoint.canRollback && checkpoint.rollbackData) {
// Restore state from checkpoint
this.restoreState(checkpoint.rollbackData);
}
}
}
private restoreState(rollbackData: any): void {
// Restore global state from rollback data
if (rollbackData.stateSnapshot?.globalState) {
this.globalState.clear();
Object.entries(rollbackData.stateSnapshot.globalState).forEach(([key, value]) => {
this.globalState.set(key, value);
});
}
}
private async generateTransactionReport(
context: TransactionContext,
integrityResult: IntegrityVerificationResult
): Promise<TransactionReport> {
const endTime = new Date();
const duration = endTime.getTime() - context.startTime.getTime();
const recommendations: string[] = [];
// Generate recommendations based on integrity results
if (!integrityResult.atomicity.passed) {
recommendations.push('Implement better error handling and rollback mechanisms');
}
if (!integrityResult.consistency.passed) {
recommendations.push('Add data validation and consistency checks across services');
}
if (!integrityResult.isolation.passed) {
recommendations.push('Implement proper locking and isolation mechanisms');
}
if (!integrityResult.durability.passed) {
recommendations.push('Improve checkpoint and recovery mechanisms');
}
return {
transactionId: context.transactionId,
sessionId: context.sessionId,
startTime: context.startTime,
endTime,
duration,
finalState: context.state,
operations: [...context.operations],
checkpoints: [...context.checkpoints],
compensations: [...context.compensations],
integrityVerification: integrityResult,
recommendations
};
}
/**
* Get transaction history for a session
*/
getTransactionHistory(sessionId: string): TransactionReport[] {
return this.transactionHistory.get(sessionId) || [];
}
/**
* Get active transaction context
*/
getActiveTransaction(transactionId: string): TransactionContext | undefined {
return this.activeTransactions.get(transactionId);
}
/**
* Get all active transactions
*/
getActiveTransactions(): TransactionContext[] {
return Array.from(this.activeTransactions.values());
}
}
export default TransactionIntegrityVerifier;