Files
dbis_core/src/infrastructure/quantum/proxy/quantum-translation.service.ts
2026-03-02 12:14:07 -08:00

289 lines
7.6 KiB
TypeScript

// Quantum Translation Service
// FX & risk translation for legacy protocols
import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';
export interface QuantumTranslationRequest {
legacyProtocol: 'SWIFT' | 'ISO20022' | 'ACH' | 'SEPA' | 'PRIVATE_BANK';
transactionData: any;
amount: string;
currencyCode: string;
}
export interface QuantumTranslationResult {
translationId: string;
fxRate: Decimal;
riskScore: Decimal;
quantumCompatibleAmount: Decimal;
quantumCompatibleCurrency: string;
protocolMapping: any;
}
export class QuantumTranslationService {
/**
* Translate legacy transaction to quantum-compatible format
* Handles FX conversion and risk assessment
*/
async translateLegacyTransaction(
request: QuantumTranslationRequest
): Promise<QuantumTranslationResult> {
logger.info('QPS: Translating legacy transaction', {
legacyProtocol: request.legacyProtocol,
});
const translationId = `QPS-TRANS-${uuidv4()}`;
// Step 1: Get protocol mapping
const protocolMapping = await this.getProtocolMapping(request.legacyProtocol);
// Step 2: Translate FX
const fxTranslation = await this.translateFx({
amount: request.amount,
currencyCode: request.currencyCode,
legacyProtocol: request.legacyProtocol,
});
// Step 3: Translate risk
const riskTranslation = await this.translateRisk({
transactionData: request.transactionData,
legacyProtocol: request.legacyProtocol,
});
// Step 4: Create quantum-compatible format
const quantumCompatibleAmount = fxTranslation.quantumAmount;
const quantumCompatibleCurrency = fxTranslation.quantumCurrency;
// Step 5: Save translation record
const translation = await prisma.quantum_translations.create({
data: {
id: uuidv4(),
translationId,
legacyProtocol: request.legacyProtocol,
legacyAmount: new Decimal(request.amount),
legacyCurrency: request.currencyCode,
quantumAmount: quantumCompatibleAmount,
quantumCurrency: quantumCompatibleCurrency,
fxRate: fxTranslation.fxRate,
riskScore: riskTranslation.riskScore,
protocolMapping: protocolMapping as any,
transactionData: request.transactionData as any,
status: 'completed',
createdAt: new Date(),
updatedAt: new Date(),
},
});
logger.info('QPS: Translation completed', {
translationId,
quantumAmount: quantumCompatibleAmount.toString(),
});
return {
translationId,
fxRate: fxTranslation.fxRate,
riskScore: riskTranslation.riskScore,
quantumCompatibleAmount,
quantumCompatibleCurrency,
protocolMapping,
};
}
/**
* Get protocol mapping for legacy protocol
*/
private async getProtocolMapping(
legacyProtocol: string
): Promise<any> {
const mapping = await prisma.legacy_protocol_mappings.findFirst({
where: { legacyProtocol, status: 'active' },
});
if (mapping) {
return mapping.mappingConfig;
}
// Default mappings
const defaultMappings: Record<string, any> = {
SWIFT: {
messageType: 'MT103',
quantumFormat: 'ISO20022',
fieldMapping: {
sender: 'sourceBankId',
receiver: 'destinationBankId',
amount: 'amount',
currency: 'currencyCode',
},
},
ISO20022: {
messageType: 'pacs.008',
quantumFormat: 'ISO20022',
fieldMapping: {
debtor: 'sourceBankId',
creditor: 'destinationBankId',
amount: 'amount',
currency: 'currencyCode',
},
},
ACH: {
messageType: 'ACH',
quantumFormat: 'ISO20022',
fieldMapping: {
originator: 'sourceBankId',
receiver: 'destinationBankId',
amount: 'amount',
currency: 'currencyCode',
},
},
SEPA: {
messageType: 'pain.001',
quantumFormat: 'ISO20022',
fieldMapping: {
debtor: 'sourceBankId',
creditor: 'destinationBankId',
amount: 'amount',
currency: 'currencyCode',
},
},
PRIVATE_BANK: {
messageType: 'PRIVATE',
quantumFormat: 'ISO20022',
fieldMapping: {
from: 'sourceBankId',
to: 'destinationBankId',
value: 'amount',
currency: 'currencyCode',
},
},
};
return defaultMappings[legacyProtocol] || {};
}
/**
* Translate FX for legacy protocol
*/
private async translateFx(data: {
amount: string;
currencyCode: string;
legacyProtocol: string;
}): Promise<{
fxRate: Decimal;
quantumAmount: Decimal;
quantumCurrency: string;
}> {
// In production, would fetch real-time FX rates
// For now, use 1:1 for same currency, or apply protocol-specific rates
const amount = new Decimal(data.amount);
// Default: quantum currency is same as legacy currency
let quantumCurrency = data.currencyCode;
let fxRate = new Decimal(1);
// Protocol-specific FX adjustments
switch (data.legacyProtocol) {
case 'SWIFT':
// SWIFT typically uses spot rates
fxRate = new Decimal(1); // Placeholder
break;
case 'ISO20022':
// ISO20022 uses reference rates
fxRate = new Decimal(1); // Placeholder
break;
case 'ACH':
// ACH uses domestic rates
fxRate = new Decimal(1); // Placeholder
break;
case 'SEPA':
// SEPA uses EUR rates
if (data.currencyCode !== 'EUR') {
// Convert to EUR
quantumCurrency = 'EUR';
fxRate = new Decimal(0.85); // Example EUR rate
}
break;
default:
fxRate = new Decimal(1);
}
const quantumAmount = amount.times(fxRate);
return {
fxRate,
quantumAmount,
quantumCurrency,
};
}
/**
* Translate risk for legacy protocol
*/
private async translateRisk(data: {
transactionData: any;
legacyProtocol: string;
}): Promise<{ riskScore: Decimal }> {
// Base risk score
let riskScore = new Decimal(0.1); // Low risk by default
// Protocol-specific risk adjustments
switch (data.legacyProtocol) {
case 'SWIFT':
// SWIFT has lower risk (established network)
riskScore = new Decimal(0.05);
break;
case 'ISO20022':
// ISO20022 has standardized risk
riskScore = new Decimal(0.08);
break;
case 'ACH':
// ACH has domestic risk
riskScore = new Decimal(0.12);
break;
case 'SEPA':
// SEPA has EU risk
riskScore = new Decimal(0.06);
break;
case 'PRIVATE_BANK':
// Private bank has higher risk
riskScore = new Decimal(0.15);
break;
}
// Additional risk factors from transaction data
if (data.transactionData.amount > 1000000) {
riskScore = riskScore.plus(0.1); // Large amount increases risk
}
return { riskScore };
}
/**
* Get translation by ID
*/
async getTranslation(translationId: string) {
return await prisma.quantum_translations.findUnique({
where: { translationId },
});
}
/**
* Get translations by protocol
*/
async getTranslationsByProtocol(
legacyProtocol: string,
limit: number = 100
) {
return await prisma.quantum_translations.findMany({
where: { legacyProtocol },
orderBy: { createdAt: 'desc' },
take: limit,
});
}
}
export const quantumTranslationService = new QuantumTranslationService();