Complete remaining todos: MT103 mapping, version management, logging, config, FX rates, tests, docs
- Enhanced MT103 mapping with all fields and validation - Implemented version management system - Added structured logging with correlation IDs - Added configuration management from environment variables - Implemented FX rate service with caching and provider abstraction - Added comprehensive unit tests - Created architecture and developer documentation
This commit is contained in:
83
packages/rules-engine/src/__tests__/documentation.test.ts
Normal file
83
packages/rules-engine/src/__tests__/documentation.test.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { validateDocumentation } from '../documentation';
|
||||
import type { Transaction } from '@brazil-swift-ops/types';
|
||||
|
||||
describe('Documentation Validation', () => {
|
||||
it('should pass validation for complete transaction', () => {
|
||||
const transaction: Transaction = {
|
||||
id: 'TXN-1',
|
||||
direction: 'outbound',
|
||||
amount: 5000,
|
||||
currency: 'USD',
|
||||
orderingCustomer: {
|
||||
name: 'John Doe',
|
||||
taxId: '12345678909',
|
||||
country: 'BR',
|
||||
},
|
||||
beneficiary: {
|
||||
name: 'Jane Smith',
|
||||
taxId: '98765432100',
|
||||
country: 'BR',
|
||||
},
|
||||
purposeOfPayment: 'Payment for services rendered',
|
||||
status: 'pending',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
const result = validateDocumentation(transaction);
|
||||
expect(result.passed).toBe(true);
|
||||
expect(result.errors).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should fail validation for missing tax ID', () => {
|
||||
const transaction: Transaction = {
|
||||
id: 'TXN-2',
|
||||
direction: 'outbound',
|
||||
amount: 5000,
|
||||
currency: 'USD',
|
||||
orderingCustomer: {
|
||||
name: 'John Doe',
|
||||
country: 'BR',
|
||||
},
|
||||
beneficiary: {
|
||||
name: 'Jane Smith',
|
||||
country: 'BR',
|
||||
},
|
||||
purposeOfPayment: 'Payment',
|
||||
status: 'pending',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
const result = validateDocumentation(transaction);
|
||||
expect(result.passed).toBe(false);
|
||||
expect(result.errors.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should fail validation for missing purpose of payment', () => {
|
||||
const transaction: Transaction = {
|
||||
id: 'TXN-3',
|
||||
direction: 'outbound',
|
||||
amount: 5000,
|
||||
currency: 'USD',
|
||||
orderingCustomer: {
|
||||
name: 'John Doe',
|
||||
taxId: '12345678909',
|
||||
country: 'BR',
|
||||
},
|
||||
beneficiary: {
|
||||
name: 'Jane Smith',
|
||||
taxId: '98765432100',
|
||||
country: 'BR',
|
||||
},
|
||||
status: 'pending',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
const result = validateDocumentation(transaction);
|
||||
expect(result.passed).toBe(false);
|
||||
expect(result.errors.some((e) => e.includes('purpose'))).toBe(true);
|
||||
});
|
||||
});
|
||||
66
packages/rules-engine/src/__tests__/iof.test.ts
Normal file
66
packages/rules-engine/src/__tests__/iof.test.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { calculateIOF } from '../iof';
|
||||
import { setConfig, DEFAULT_CONFIG } from '../config';
|
||||
import type { Transaction } from '@brazil-swift-ops/types';
|
||||
|
||||
describe('IOF Calculation', () => {
|
||||
beforeEach(() => {
|
||||
setConfig(DEFAULT_CONFIG);
|
||||
});
|
||||
|
||||
it('should calculate IOF for inbound transaction', () => {
|
||||
const transaction: Transaction = {
|
||||
id: 'TXN-1',
|
||||
direction: 'inbound',
|
||||
amount: 10000,
|
||||
currency: 'USD',
|
||||
orderingCustomer: { name: 'Test', country: 'BR' },
|
||||
beneficiary: { name: 'Test', country: 'BR' },
|
||||
status: 'pending',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
const result = calculateIOF(transaction);
|
||||
expect(result.rate).toBe(DEFAULT_CONFIG.iofRateInbound);
|
||||
expect(result.amount).toBe(10000 * DEFAULT_CONFIG.iofRateInbound);
|
||||
expect(result.currency).toBe('BRL');
|
||||
});
|
||||
|
||||
it('should calculate IOF for outbound transaction', () => {
|
||||
const transaction: Transaction = {
|
||||
id: 'TXN-2',
|
||||
direction: 'outbound',
|
||||
amount: 10000,
|
||||
currency: 'USD',
|
||||
orderingCustomer: { name: 'Test', country: 'BR' },
|
||||
beneficiary: { name: 'Test', country: 'BR' },
|
||||
status: 'pending',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
const result = calculateIOF(transaction);
|
||||
expect(result.rate).toBe(DEFAULT_CONFIG.iofRateOutbound);
|
||||
expect(result.amount).toBe(10000 * DEFAULT_CONFIG.iofRateOutbound);
|
||||
expect(result.currency).toBe('BRL');
|
||||
});
|
||||
|
||||
it('should return zero IOF for non-BRL transactions without conversion', () => {
|
||||
const transaction: Transaction = {
|
||||
id: 'TXN-3',
|
||||
direction: 'inbound',
|
||||
amount: 10000,
|
||||
currency: 'EUR',
|
||||
orderingCustomer: { name: 'Test', country: 'BR' },
|
||||
beneficiary: { name: 'Test', country: 'BR' },
|
||||
status: 'pending',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
const result = calculateIOF(transaction);
|
||||
// IOF is calculated on BRL equivalent, so if no conversion provided, should handle gracefully
|
||||
expect(result.rate).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user