xpeditis2.0/apps/backend/src/infrastructure/carriers/hapag-lloyd/hapag-lloyd.connector.ts
David-Henri ARNAUD 07258e5adb feature phase 3
2025-10-13 13:58:39 +02:00

99 lines
2.9 KiB
TypeScript

/**
* Hapag-Lloyd Connector
*
* Implements CarrierConnectorPort for Hapag-Lloyd Quick Quotes API
*/
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import {
CarrierConnectorPort,
CarrierRateSearchInput,
CarrierAvailabilityInput
} from '../../../domain/ports/out/carrier-connector.port';
import { RateQuote } from '../../../domain/entities/rate-quote.entity';
import { BaseCarrierConnector, CarrierConfig } from '../base-carrier.connector';
import { HapagLloydRequestMapper } from './hapag-lloyd.mapper';
@Injectable()
export class HapagLloydConnectorAdapter
extends BaseCarrierConnector
implements CarrierConnectorPort
{
private readonly apiUrl: string;
private readonly apiKey: string;
constructor(
private readonly configService: ConfigService,
private readonly requestMapper: HapagLloydRequestMapper,
) {
const config: CarrierConfig = {
name: 'Hapag-Lloyd',
code: 'HLCU',
baseUrl: configService.get<string>('HAPAG_API_URL', 'https://api.hapag-lloyd.com/v1'),
timeout: 5000,
maxRetries: 3,
circuitBreakerThreshold: 50,
circuitBreakerTimeout: 30000,
};
super(config);
this.apiUrl = config.baseUrl;
this.apiKey = this.configService.get<string>('HAPAG_API_KEY', '');
}
async searchRates(input: CarrierRateSearchInput): Promise<RateQuote[]> {
this.logger.log(`Searching Hapag-Lloyd rates: ${input.origin} -> ${input.destination}`);
try {
const hapagRequest = this.requestMapper.toHapagRequest(input);
const response = await this.makeRequest({
url: `${this.apiUrl}/quick-quotes`,
method: 'POST',
data: hapagRequest,
headers: {
'API-Key': this.apiKey,
'Content-Type': 'application/json',
},
});
const rateQuotes = this.requestMapper.fromHapagResponse(response.data, input);
this.logger.log(`Found ${rateQuotes.length} Hapag-Lloyd rates`);
return rateQuotes;
} catch (error: any) {
this.logger.error(`Hapag-Lloyd API error: ${error?.message || 'Unknown error'}`);
if (error?.response?.status === 503) {
this.logger.warn('Hapag-Lloyd service temporarily unavailable');
}
return [];
}
}
async checkAvailability(input: CarrierAvailabilityInput): Promise<number> {
try {
const response = await this.makeRequest({
url: `${this.apiUrl}/availability`,
method: 'GET',
params: {
origin: input.origin,
destination: input.destination,
departure_date: input.departureDate,
equipment_type: input.containerType,
quantity: input.quantity,
},
headers: {
'API-Key': this.apiKey,
},
});
return (response.data as any).available_capacity || 0;
} catch (error: any) {
this.logger.error(`Hapag-Lloyd availability check error: ${error?.message || 'Unknown error'}`);
return 0;
}
}
}