import { article1ObjectiveFromClause, buildClausePack, } from './contract-clause-packs'; import type { ContractDirection, ContractFreight, ContractServiceScope, ContractTemplateMeta, } from './contract-template.types'; export type { ContractTemplateMeta } from './contract-template.types'; const DIRECTION_LABELS: Record = { IMP: 'Import', EXP: 'Export', DOM: 'Domestic', }; const FREIGHT_LABELS: Record = { CON: 'Container', BULK: 'Bulk', }; const DIRECTIONS: ContractDirection[] = ['IMP', 'EXP', 'DOM']; const FREIGHTS: ContractFreight[] = ['CON', 'BULK']; const CURRENCIES = ['ETB', 'USD'] as const; const SERVICES: ContractServiceScope[] = ['TRANSPORT_ONLY', 'FORWARDING']; const KEY_PATTERN = /^(IMP|EXP|DOM)_(CON|BULK)_(ETB|USD)_(TRANSPORT_ONLY|FORWARDING)$/; function buildMeta( dir: ContractDirection, freight: ContractFreight, currency: string, service: ContractServiceScope, ): ContractTemplateMeta { const key = `${dir}_${freight}_${currency}_${service}`; const dirLabel = DIRECTION_LABELS[dir]; const freightLabel = FREIGHT_LABELS[freight]; const serviceLabel = service === 'FORWARDING' ? 'Rail and Forwarding' : 'Transport Only'; const corridor = dir === 'IMP' ? 'from SGTD railway freight station at Djibouti to Ethiopian dry ports and return of empty containers as applicable' : dir === 'EXP' ? 'from Ethiopian dry ports to SGTD and related export corridors' : 'between designated Ethiopian rail terminals'; const clauses = buildClausePack(dir, freight, service); return { key, direction: dir, freight, currency, serviceScope: service, title: `${dirLabel} ${freightLabel} Transport Service by Railway (${serviceLabel})`, directionLabel: dirLabel, freightLabel, whereas: `The Client has requested transportation of ${freightLabel.toLowerCase()} cargo ${corridor} using the Addis Ababa–Djibouti Railway line. The Service Provider has agreed to provide services per this contract.`, article1Objective: article1ObjectiveFromClause(clauses.article1), article1: clauses.article1, clientObligations: clauses.clientObligations, providerObligations: clauses.providerObligations, contractDocuments: clauses.contractDocuments, }; } /** Full template matrix (24 keys). */ export const CONTRACT_TEMPLATE_REGISTRY: Record = {}; for (const dir of DIRECTIONS) { for (const freight of FREIGHTS) { for (const currency of CURRENCIES) { for (const service of SERVICES) { const meta = buildMeta(dir, freight, currency, service); CONTRACT_TEMPLATE_REGISTRY[meta.key] = meta; } } } } export const CONTRACT_TEMPLATE_KEYS = Object.keys(CONTRACT_TEMPLATE_REGISTRY); export function listTemplateKeys(): string[] { return CONTRACT_TEMPLATE_KEYS; } export function getTemplateMeta(key: string): ContractTemplateMeta { const found = CONTRACT_TEMPLATE_REGISTRY[key]; if (found) return found; const fallbackClauses = buildClausePack('IMP', 'CON', 'TRANSPORT_ONLY'); return { key, direction: 'IMP', freight: 'CON', currency: 'USD', serviceScope: 'TRANSPORT_ONLY', title: 'Freight Contract Agreement', directionLabel: 'Freight', freightLabel: 'Cargo', whereas: 'The parties agree to railway freight services as described in the schedule below.', article1Objective: article1ObjectiveFromClause(fallbackClauses.article1), article1: fallbackClauses.article1, clientObligations: fallbackClauses.clientObligations, providerObligations: fallbackClauses.providerObligations, contractDocuments: fallbackClauses.contractDocuments, }; } export function isValidTemplateKey(key: string): boolean { return KEY_PATTERN.test(key); }