casefile-repository-mcp-server
Version:
Vessel casefile management system with MCP integration for maritime operations
144 lines • 5.4 kB
JavaScript
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