xpeditis2.0/apps/backend/src/domain/value-objects/port-code.vo.ts
David-Henri ARNAUD 1044900e98 feature phase
2025-10-08 16:56:27 +02:00

67 lines
1.5 KiB
TypeScript

/**
* PortCode Value Object
*
* Encapsulates UN/LOCODE port code validation and behavior
*
* Business Rules:
* - Port code must follow UN/LOCODE format (2-letter country + 3-letter/digit location)
* - Port code is always uppercase
* - Port code is immutable
*
* Format: CCLLL
* - CC: ISO 3166-1 alpha-2 country code
* - LLL: 3-character location code (letters or digits)
*
* Examples: NLRTM (Rotterdam), USNYC (New York), SGSIN (Singapore)
*/
export class PortCode {
private readonly value: string;
private constructor(code: string) {
this.value = code;
}
static create(code: string): PortCode {
if (!code || code.trim().length === 0) {
throw new Error('Port code cannot be empty.');
}
const normalized = code.trim().toUpperCase();
if (!PortCode.isValid(normalized)) {
throw new Error(
`Invalid port code format: ${code}. Must follow UN/LOCODE format (e.g., NLRTM, USNYC).`
);
}
return new PortCode(normalized);
}
private static isValid(code: string): boolean {
// UN/LOCODE format: 2-letter country code + 3-character location code
const unlocodePattern = /^[A-Z]{2}[A-Z0-9]{3}$/;
return unlocodePattern.test(code);
}
getValue(): string {
return this.value;
}
getCountryCode(): string {
return this.value.substring(0, 2);
}
getLocationCode(): string {
return this.value.substring(2);
}
equals(other: PortCode): boolean {
return this.value === other.value;
}
toString(): string {
return this.value;
}
}