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
290 lines • 10.8 kB
JavaScript
import { getDatabase } from './mongodb.js';
import { config } from './config.js';
import { logger } from './logger.js';
import { getCompanyImoNumbers, shouldBypassImoFiltering } from './imoUtils.js';
export function getArtifact(toolName, url) {
const timestamp = Math.floor(Date.now() / 1000);
const safeUrl = url instanceof Promise ? "" : (url ?? "");
return {
id: "msg_browser_ghi789",
parentTaskId: `task_${toolName}_${timestamp}`,
timestamp: timestamp,
agent: {
id: "agent_siya_browser",
name: "SIYA",
type: "qna"
},
messageType: "action",
action: {
tool: "browser",
operation: "browsing",
params: {
url: safeUrl,
pageTitle: `Tool response for ${toolName}`,
visual: {
icon: "browser",
color: "#2D8CFF"
},
stream: {
type: "vnc",
streamId: "stream_browser_1",
target: "browser"
}
}
},
content: `Viewed page: ${toolName}`,
artifacts: [
{
id: `artifact_webpage_${Date.now()}_${Math.floor(Math.random() * 1000)}`,
type: "browser_view",
content: {
url: safeUrl,
title: toolName,
screenshot: "",
textContent: `Observed output of cmd \`${toolName}\` executed:`,
extractedInfo: {}
},
metadata: {
domainName: "example.com",
visitTimestamp: Date.now(),
category: "web_page"
}
}
],
status: "completed"
};
}
/**
* Get data link from documents
*/
export async function getDataLink(data) {
const url = 'https://app-api.siya.com/v1.0/vessel-info/qna-snapshot';
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImlkIjoiNjRkMzdhMDM1Mjk5YjFlMDQxOTFmOTJhIiwiZmlyc3ROYW1lIjoiU3lpYSIsImxhc3ROYW1lIjoiRGV2IiwiZW1haWwiOiJkZXZAc3lpYS5haSIsInJvbGUiOiJhZG1pbiIsInJvbGVJZCI6IjVmNGUyODFkZDE4MjM0MzY4NDE1ZjViZiIsImlhdCI6MTc0MDgwODg2OH0sImlhdCI6MTc0MDgwODg2OCwiZXhwIjoxNzcyMzQ0ODY4fQ.1grxEO0aO7wfkSNDzpLMHXFYuXjaA1bBguw2SJS9r2M'
};
try {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify({ data })
});
const result = await response.json();
if (result.status === 'OK') {
return result.resultData;
}
else {
return null;
}
}
catch (error) {
console.error('Error fetching data link:', error);
return null;
}
}
/**
* Insert data link to MongoDB
*/
export async function insertDataLinkToMongodb(dataLink, linkHeader, sessionId, imo, vesselName) {
try {
const db = await getDatabase();
const collection = db.collection('casefile_data');
const sessionExists = await collection.findOne({ sessionId });
const linkData = {
link: dataLink,
linkHeader: linkHeader
};
if (sessionExists) {
await collection.updateOne({ sessionId }, {
$push: {
links: {
$each: [linkData] // Fixes the typing issue
}
},
$set: {
datetime: new Date().toISOString()
}
});
}
else {
const newEntry = {
sessionId,
imo: imo ?? "",
vesselName: vesselName ?? "",
links: [linkData],
datetime: new Date().toISOString(),
};
await collection.insertOne(newEntry);
}
}
catch (error) {
console.error('Error inserting data link to MongoDB:', error);
}
}
/**
* Update Typesense filter with company IMO numbers for filtering
* @param filter - Existing filter string
* @returns Updated filter string with IMO restrictions
*/
export function updateTypesenseFilterWithCompanyImos(filter) {
const companyName = config.companyName;
// Skip filtering for admin companies
if (!companyName || shouldBypassImoFiltering(companyName)) {
logger.debug(`Skipping Typesense IMO filtering for admin company: ${companyName}`);
return filter;
}
const companyImos = getCompanyImoNumbers();
// If no IMO numbers configured, return original filter
if (companyImos.length === 0) {
logger.warn('No company IMO numbers configured. Skipping Typesense IMO filtering.');
return filter;
}
// Create IMO filter for Typesense
const imoFilter = `imo:[${companyImos.join(",")}]`;
// Combine with existing filter
if (filter && filter.trim()) {
const combinedFilter = `${filter} && ${imoFilter}`;
logger.debug(`Applied Typesense IMO filter: ${combinedFilter}`);
return combinedFilter;
}
else {
logger.debug(`Applied Typesense IMO filter: ${imoFilter}`);
return imoFilter;
}
}
/**
* Update MongoDB filter with company IMO numbers for filtering
* @param filter - Existing MongoDB filter object
* @returns Updated filter object with IMO restrictions
*/
export function updateMongoFilterWithCompanyImos(filter) {
const companyName = config.companyName;
// Skip filtering for admin companies
if (!companyName || shouldBypassImoFiltering(companyName)) {
logger.debug(`Skipping MongoDB IMO filtering for admin company: ${companyName}`);
return filter;
}
const companyImos = getCompanyImoNumbers();
// If no IMO numbers configured, return original filter
if (companyImos.length === 0) {
logger.warn('No company IMO numbers configured. Skipping MongoDB IMO filtering.');
return filter;
}
// Create a copy of the filter to avoid modifying the original
const updatedFilter = { ...filter };
// Convert IMO numbers to integers for MongoDB query
const imoNumbers = companyImos.map(imo => Number(imo));
// Add IMO restriction to the filter
updatedFilter.imo = { $in: imoNumbers };
logger.debug(`Applied MongoDB IMO filter: ${JSON.stringify(updatedFilter)}`);
return updatedFilter;
}
/**
* Update MongoDB aggregation pipeline with company IMO numbers for filtering
* @param pipeline - Existing MongoDB aggregation pipeline
* @returns Updated pipeline with IMO restrictions
*/
export function updateMongoAggregationWithCompanyImos(pipeline) {
const companyName = config.companyName;
// Skip filtering for admin companies
if (!companyName || shouldBypassImoFiltering(companyName)) {
logger.debug(`Skipping MongoDB aggregation IMO filtering for admin company: ${companyName}`);
return pipeline;
}
const companyImos = getCompanyImoNumbers();
// If no IMO numbers configured, return original pipeline
if (companyImos.length === 0) {
logger.warn('No company IMO numbers configured. Skipping MongoDB aggregation IMO filtering.');
return pipeline;
}
// Convert IMO numbers to integers for MongoDB query
const imoNumbers = companyImos.map(imo => Number(imo));
// Create IMO match stage
const imoMatchStage = {
$match: {
imo: { $in: imoNumbers }
}
};
// Add IMO filter as the first stage in the pipeline
const updatedPipeline = [imoMatchStage, ...pipeline];
logger.debug(`Applied MongoDB aggregation IMO filter: ${JSON.stringify(imoMatchStage)}`);
return updatedPipeline;
}
/**
* Update search query parameters with company IMO filtering
* @param searchParams - Search parameters object
* @returns Updated search parameters with IMO restrictions
*/
export function updateSearchParamsWithCompanyImos(searchParams) {
const companyName = config.companyName;
// Skip filtering for admin companies
if (!companyName || shouldBypassImoFiltering(companyName)) {
logger.debug(`Skipping search params IMO filtering for admin company: ${companyName}`);
return searchParams;
}
const companyImos = getCompanyImoNumbers();
// If no IMO numbers configured, return original params
if (companyImos.length === 0) {
logger.warn('No company IMO numbers configured. Skipping search params IMO filtering.');
return searchParams;
}
// Create a copy of the search params
const updatedParams = { ...searchParams };
// Update filter_by parameter for Typesense
if (updatedParams.filter_by) {
updatedParams.filter_by = updateTypesenseFilterWithCompanyImos(updatedParams.filter_by);
}
else {
updatedParams.filter_by = updateTypesenseFilterWithCompanyImos('');
}
logger.debug(`Updated search params with IMO filtering: ${JSON.stringify(updatedParams)}`);
return updatedParams;
}
/**
* Check if a vessel IMO is authorized for the current company
* @param imo - IMO number to check
* @returns True if authorized, false otherwise
*/
export function isVesselAuthorizedForCompany(imo) {
const companyName = config.companyName;
// Allow access for admin companies
if (!companyName || shouldBypassImoFiltering(companyName)) {
return true;
}
const companyImos = getCompanyImoNumbers();
// If no IMO numbers configured, deny access
if (companyImos.length === 0) {
return false;
}
const imoNumber = Number(imo);
const companyImoNumbers = companyImos.map(imo => Number(imo));
return companyImoNumbers.includes(imoNumber);
}
/**
* Get authorized IMO numbers for the current company
* @returns Array of authorized IMO numbers
*/
export function getAuthorizedImoNumbers() {
const companyName = config.companyName;
// For admin companies, return empty array (no restrictions)
if (!companyName || shouldBypassImoFiltering(companyName)) {
return [];
}
return getCompanyImoNumbers();
}
/**
* Log IMO filtering activity for monitoring
* @param action - Action being performed
* @param details - Additional details about the filtering
*/
export function logImoFilteringActivity(action, details = {}) {
const companyName = config.companyName;
const companyImos = getCompanyImoNumbers();
logger.info(`IMO filtering activity: ${action}`, {
companyName,
companyImoCount: companyImos.length,
isAdminCompany: companyName ? shouldBypassImoFiltering(companyName) : false,
...details
});
}
//# sourceMappingURL=helpers.js.map