UNPKG

casefile-repository-mcp-server

Version:

Vessel casefile management system with MCP integration for maritime operations

144 lines 5.4 kB
import { MongoClient } from 'mongodb'; import { logger } from './logger.js'; import { config } from './config.js'; // In-memory cache for company IMO numbers let companyImoNumbers = []; let companyDatabaseClient = null; /** * Initialize company database connection */ export async function initializeCompanyDatabase() { if (!config.companyDbUri) { logger.warn('Company database URI not configured. IMO filtering will be limited.'); return; } try { companyDatabaseClient = new MongoClient(config.companyDbUri); await companyDatabaseClient.connect(); logger.info('Company database connection established'); } catch (error) { logger.error('Failed to connect to company database:', error); throw error; } } /** * Fetch company IMO numbers from MongoDB * @param companyName - Name of the company to fetch IMO numbers for * @returns Array of IMO numbers as strings */ export async function fetchCompanyImoNumbers(companyName) { if (!companyDatabaseClient) { await initializeCompanyDatabase(); } if (!companyDatabaseClient) { throw new Error('Company database connection not available'); } try { const db = companyDatabaseClient.db(config.companyDbName); const collection = db.collection('common_group_details'); logger.info(`Fetching IMO numbers for company: ${companyName}`); const result = await collection.findOne({ groupName: companyName }, { projection: { imo: 1, imoList: 1, groupImoList: 1, _id: 0 } }); if (!result) { logger.warn(`No IMO data found for company: ${companyName}`); return []; } // Combine IMO numbers from all three fields const imoNumbers = []; if (result.imo) { imoNumbers.push(result.imo); } if (result.imoList && Array.isArray(result.imoList)) { imoNumbers.push(...result.imoList); } if (result.groupImoList && Array.isArray(result.groupImoList)) { imoNumbers.push(...result.groupImoList); } // Convert to string array for consistent handling const imoStrings = imoNumbers.map(imo => String(imo)); logger.info(`Successfully fetched ${imoStrings.length} IMO numbers for company: ${companyName}`); return imoStrings; } catch (error) { logger.error(`Error fetching IMO numbers for company ${companyName}:`, error); throw error; } } /** * Set cached company IMO numbers * @param imos - Array of IMO numbers to cache */ export function setCompanyImoNumbers(imos) { companyImoNumbers = imos; logger.debug(`Cached ${imos.length} IMO numbers for company filtering`); } /** * Get cached company IMO numbers * @returns Array of cached IMO numbers */ export function getCompanyImoNumbers() { return companyImoNumbers; } /** * Check if an IMO number is valid for the current company * @param imoNumber - IMO number to validate (string or number) * @returns True if IMO is valid for the company, false otherwise */ export function isValidImoForCompany(imoNumber) { // If no company IMO numbers are cached, allow all (fallback) if (companyImoNumbers.length === 0) { return true; } const imoNum = Number(imoNumber); const companyImosNum = companyImoNumbers.map(imo => Number(imo)); return companyImosNum.includes(imoNum); } /** * Check if IMO filtering should be bypassed for admin companies * @param companyName - Name of the company * @returns True if filtering should be bypassed, false otherwise */ export function shouldBypassImoFiltering(companyName) { const bypassCompanies = ['Synergy', 'Admin', 'SYIA', 'System']; return bypassCompanies.includes(companyName); } /** * Validate IMO number with detailed error messaging * @param imoNumber - IMO number to validate * @param companyName - Name of the company (for error messages) * @returns Validation result with error message if invalid */ export function validateImoNumber(imoNumber, companyName) { const currentCompanyName = companyName || config.companyName || 'current company'; // Skip validation for admin companies if (shouldBypassImoFiltering(currentCompanyName)) { return { isValid: true }; } // If no company IMO numbers are cached, allow all if (companyImoNumbers.length === 0) { return { isValid: true }; } const imoNum = Number(imoNumber); const companyImosNum = companyImoNumbers.map(imo => Number(imo)); if (companyImosNum.includes(imoNum)) { return { isValid: true }; } // Generate error message with available IMO numbers (limited to first 10) const displayImos = companyImoNumbers.slice(0, 10); const moreCount = companyImoNumbers.length > 10 ? ` (and ${companyImoNumbers.length - 10} more)` : ''; return { isValid: false, errorMessage: `Vessel with this IMO ${imoNumber} is not part of ${currentCompanyName}. Available IMO numbers: ${displayImos.join(', ')}${moreCount}` }; } /** * Close company database connection */ export async function closeCompanyDatabase() { if (companyDatabaseClient) { await companyDatabaseClient.close(); companyDatabaseClient = null; logger.info('Company database connection closed'); } } //# sourceMappingURL=imoUtils.js.map