UNPKG

pms-analysis-reports-mcp-server

Version:

PMS analysis reports server handling maintenance reports, equipment analysis, compliance tracking, and performance metrics with ERP access for data extraction

194 lines 7.24 kB
import { MongoClient } from 'mongodb'; import { config } from './config.js'; import { logger } from './logger.js'; // Global variables for IMO management let companyImoNumbers = []; let companyDatabaseClient = null; /** * Initialize the company database connection for IMO fetching */ export async function initializeCompanyDatabase() { try { if (!config.companyDbUri) { logger.warn('Company database URI not configured. IMO filtering will be limited.'); return; } companyDatabaseClient = new MongoClient(config.companyDbUri, { maxPoolSize: config.mongoMaxPoolSize || 10, minPoolSize: config.mongoMinPoolSize || 2, connectTimeoutMS: config.mongoConnectionTimeout || 10000, socketTimeoutMS: config.mongoSocketTimeout || 45000, }); await companyDatabaseClient.connect(); logger.info('Company database connection established successfully'); } catch (error) { logger.error('Failed to initialize company database connection:', error); throw error; } } /** * Fetch IMO numbers for a specific company from the database * @param companyName - Name of the company to fetch IMO numbers for * @returns Array of IMO numbers as strings */ export async function fetchCompanyImoNumbers(companyName) { try { if (!companyDatabaseClient) { logger.warn('Company database client not initialized. Cannot fetch IMO numbers.'); return []; } const db = companyDatabaseClient.db(config.companyDbName); const collection = db.collection('common_group_details'); const result = await collection.findOne({ groupName: companyName }, { projection: { imo: 1, imoList: 1, groupImoList: 1, _id: 0 } }); if (!result) { logger.warn(`No IMO numbers found for company: ${companyName}`); return []; } // Combine IMO numbers from all three fields const imoNumbers = []; // Add single IMO number if present if (result.imo) { imoNumbers.push(result.imo); } // Add IMO list if present and is an array if (result.imoList && Array.isArray(result.imoList)) { imoNumbers.push(...result.imoList); } // Add group IMO list if present and is an array if (result.groupImoList && Array.isArray(result.groupImoList)) { imoNumbers.push(...result.groupImoList); } // Convert to strings and remove duplicates const uniqueImoNumbers = [...new Set(imoNumbers.map(imo => String(imo)))]; logger.info(`Successfully fetched ${uniqueImoNumbers.length} IMO numbers for company: ${companyName}`); return uniqueImoNumbers; } catch (error) { logger.error(`Failed to fetch IMO numbers for company ${companyName}:`, error); throw error; } } /** * Set the cached company IMO numbers * @param imoNumbers - Array of IMO numbers to cache */ export function setCompanyImoNumbers(imoNumbers) { companyImoNumbers = [...imoNumbers]; logger.debug(`Cached ${imoNumbers.length} IMO numbers for company filtering`); } /** * Get the cached company IMO numbers * @returns Array of cached IMO numbers */ export function getCompanyImoNumbers() { return [...companyImoNumbers]; } /** * Clear the cached company IMO numbers */ export function clearCompanyImoNumbers() { companyImoNumbers = []; logger.debug('Cleared cached IMO numbers'); } /** * Check if an IMO number is valid for the current company * @param imoNumber - IMO number to validate (string or number) * @returns true if valid, false otherwise */ export function isValidImoForCompany(imoNumber) { if (companyImoNumbers.length === 0) { // If no IMO numbers are cached, allow all (might be admin or system not configured) 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 to check * @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 format and company authorization * @param imoNumber - IMO number to validate * @param companyName - Company name for context * @returns Validation result with error message if invalid */ export function validateImoNumber(imoNumber, companyName) { // Basic format validation if (imoNumber === undefined || imoNumber === null) { return { isValid: false, errorMessage: 'IMO number is required' }; } const imoString = String(imoNumber).trim(); // Check if it contains only digits if (!/^\d+$/.test(imoString)) { return { isValid: false, errorMessage: 'IMO number must contain only digits' }; } const imoNum = Number(imoNumber); if (isNaN(imoNum) || imoNum <= 0) { return { isValid: false, errorMessage: 'IMO number must be a positive number' }; } // Skip company validation for admin companies if (companyName && shouldBypassImoFiltering(companyName)) { return { isValid: true }; } // Check company authorization if (!isValidImoForCompany(imoNumber)) { const availableImos = getCompanyImoNumbers(); const displayImos = availableImos.slice(0, 10); // Show first 10 IMOs const moreCount = availableImos.length > 10 ? `, and ${availableImos.length - 10} more` : ''; return { isValid: false, errorMessage: `IMO number ${imoNumber} is not associated with ${companyName}. Available IMO numbers: ${displayImos.join(', ')}${moreCount}` }; } return { isValid: true }; } /** * Get company IMO numbers with error handling * @returns Array of IMO numbers or empty array if error */ export function getCompanyImoNumbersSafe() { try { return getCompanyImoNumbers(); } catch (error) { logger.error('Error retrieving company IMO numbers:', error); return []; } } /** * Close the company database connection */ export async function closeCompanyDatabase() { try { if (companyDatabaseClient) { await companyDatabaseClient.close(); companyDatabaseClient = null; logger.info('Company database connection closed'); } } catch (error) { logger.error('Error closing company database connection:', error); } } /** * Get statistics about the current IMO filtering state * @returns Object containing filtering statistics */ export function getImoFilteringStats() { const companyName = config.companyName; return { companyName, totalImoNumbers: companyImoNumbers.length, isFilteringEnabled: companyName ? !shouldBypassImoFiltering(companyName) : false, isAdminCompany: companyName ? shouldBypassImoFiltering(companyName) : false }; } //# sourceMappingURL=imoUtils.js.map