xpeditis2.0/apps/backend/src/infrastructure/carriers/one/one.connector.ts
David 4b00ee2601
Some checks failed
CI/CD Pipeline - Xpeditis PreProd / Frontend - Docker Build & Push (push) Blocked by required conditions
CI/CD Pipeline - Xpeditis PreProd / Deploy to PreProd Server (push) Blocked by required conditions
CI/CD Pipeline - Xpeditis PreProd / Run Smoke Tests (push) Blocked by required conditions
CI/CD Pipeline - Xpeditis PreProd / Backend - Build & Test (push) Failing after 5m53s
CI/CD Pipeline - Xpeditis PreProd / Backend - Docker Build & Push (push) Has been skipped
CI/CD Pipeline - Xpeditis PreProd / Frontend - Build & Test (push) Has been cancelled
fix: replace relative domain imports with TypeScript path aliases
- Replace all ../../domain/ imports with @domain/ across 67 files
- Configure NestJS to use tsconfig.build.json with rootDir
- Add tsc-alias to resolve path aliases after build
- This fixes 'Cannot find module' TypeScript compilation errors

Fixed files:
- 30 files in application layer
- 37 files in infrastructure layer
2025-11-16 19:20:58 +01:00

103 lines
3.2 KiB
TypeScript

/**
* ONE (Ocean Network Express) Connector
*
* Implements CarrierConnectorPort for ONE 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 { ONERequestMapper } from './one.mapper';
@Injectable()
export class ONEConnectorAdapter extends BaseCarrierConnector implements CarrierConnectorPort {
private readonly apiUrl: string;
private readonly username: string;
private readonly password: string;
constructor(
private readonly configService: ConfigService,
private readonly requestMapper: ONERequestMapper
) {
const config: CarrierConfig = {
name: 'ONE',
code: 'ONEY',
baseUrl: configService.get<string>('ONE_API_URL', 'https://api.one-line.com/v1'),
timeout: 5000,
maxRetries: 3,
circuitBreakerThreshold: 50,
circuitBreakerTimeout: 30000,
};
super(config);
this.apiUrl = config.baseUrl;
this.username = this.configService.get<string>('ONE_USERNAME', '');
this.password = this.configService.get<string>('ONE_PASSWORD', '');
}
async searchRates(input: CarrierRateSearchInput): Promise<RateQuote[]> {
this.logger.log(`Searching ONE rates: ${input.origin} -> ${input.destination}`);
try {
const oneRequest = this.requestMapper.toONERequest(input);
// ONE uses Basic Auth
const authHeader = Buffer.from(`${this.username}:${this.password}`).toString('base64');
const response = await this.makeRequest({
url: `${this.apiUrl}/rates/instant-quotes`,
method: 'POST',
data: oneRequest,
headers: {
Authorization: `Basic ${authHeader}`,
'Content-Type': 'application/json',
},
});
const rateQuotes = this.requestMapper.fromONEResponse(response.data, input);
this.logger.log(`Found ${rateQuotes.length} ONE rates`);
return rateQuotes;
} catch (error: any) {
this.logger.error(`ONE API error: ${error?.message || 'Unknown error'}`);
if (error?.response?.status === 400) {
this.logger.warn('ONE invalid request parameters');
}
return [];
}
}
async checkAvailability(input: CarrierAvailabilityInput): Promise<number> {
try {
const authHeader = Buffer.from(`${this.username}:${this.password}`).toString('base64');
const response = await this.makeRequest({
url: `${this.apiUrl}/capacity/slots`,
method: 'POST',
data: {
origin_port: input.origin,
destination_port: input.destination,
cargo_cutoff_date: input.departureDate,
equipment_type: input.containerType,
quantity: input.quantity,
},
headers: {
Authorization: `Basic ${authHeader}`,
},
});
return (response.data as any).slots_available || 0;
} catch (error: any) {
this.logger.error(`ONE availability check error: ${error?.message || 'Unknown error'}`);
return 0;
}
}
}