@boundless-oss/atlas
Version:
Atlas - MCP Server for comprehensive startup project management
246 lines • 9.56 kB
JavaScript
export function setupWebSocketHandlers(io, performanceMonitor, securityManager, errorHandler, agileManager) {
console.error('📡 Setting up WebSocket handlers for real-time updates');
io.on('connection', (socket) => {
console.error(`📡 Client connected: ${socket.id}`);
// Send initial data on connection
handleInitialDataRequest(socket, performanceMonitor, securityManager, errorHandler, agileManager);
// Handle client requests for specific data
setupDataRequestHandlers(socket, performanceMonitor, securityManager, errorHandler, agileManager);
// Handle agile board interactions
if (agileManager) {
setupAgileInteractionHandlers(socket, agileManager, io);
}
socket.on('disconnect', (reason) => {
console.error(`📡 Client disconnected: ${socket.id} (${reason})`);
});
// Handle client errors
socket.on('error', (error) => {
console.error(`📡 WebSocket error from ${socket.id}:`, error);
});
});
}
async function handleInitialDataRequest(socket, performanceMonitor, securityManager, errorHandler, agileManager) {
try {
// Send initial performance data
const performanceData = await performanceMonitor.getSystemMetrics();
socket.emit('initial_performance', performanceData);
// Send initial security status
const securityStatus = await securityManager.getSecurityStatus();
socket.emit('initial_security', securityStatus);
// Send initial error summary
const errorPatterns = await errorHandler.analyzeErrorPatterns({
timeRange: '24h',
minOccurrences: 1,
groupBy: 'type'
});
socket.emit('initial_errors', errorPatterns);
// Send initial agile data if available
if (agileManager) {
try {
const sprints = await agileManager.getSprints?.() || [];
const activeSprint = await agileManager.getActiveSprint?.();
const stories = await agileManager.getAllStories?.() || [];
socket.emit('initial_agile', {
sprints,
activeSprint,
stories
});
}
catch (error) {
console.error('📡 Error loading agile data:', error);
socket.emit('initial_agile', { sprints: [], stories: [] });
}
}
console.error(`📡 Initial data sent to client: ${socket.id}`);
}
catch (error) {
console.error(`📡 Error sending initial data to ${socket.id}:`, error);
socket.emit('error', { message: 'Failed to load initial data' });
}
}
function setupDataRequestHandlers(socket, performanceMonitor, securityManager, errorHandler, agileManager) {
// Performance data requests
socket.on('request_performance_metrics', async (timeRange = '24h') => {
try {
const metrics = await performanceMonitor.getSystemMetrics();
socket.emit('performance_metrics_response', {
timeRange,
metrics,
timestamp: new Date().toISOString()
});
}
catch (error) {
socket.emit('error', { message: 'Failed to fetch performance metrics' });
}
});
socket.on('request_tool_metrics', async (toolName) => {
try {
const metrics = await performanceMonitor.getToolMetrics(toolName);
socket.emit('tool_metrics_response', {
toolName,
metrics,
timestamp: new Date().toISOString()
});
}
catch (error) {
socket.emit('error', { message: `Failed to fetch metrics for tool: ${toolName}` });
}
});
// Security data requests
socket.on('request_security_events', async (filters = {}) => {
try {
const events = await securityManager.getSecurityEvents(filters);
socket.emit('security_events_response', {
events,
filters,
timestamp: new Date().toISOString()
});
}
catch (error) {
socket.emit('error', { message: 'Failed to fetch security events' });
}
});
// Error analysis requests
socket.on('request_error_timeline', async (timeRange = '24h') => {
try {
const timeline = await errorHandler.getErrorTimeline({ timeRange });
socket.emit('error_timeline_response', {
timeline,
timeRange,
timestamp: new Date().toISOString()
});
}
catch (error) {
socket.emit('error', { message: 'Failed to fetch error timeline' });
}
});
socket.on('request_error_patterns', async (options = {}) => {
try {
const patterns = await errorHandler.analyzeErrorPatterns({
timeRange: '24h',
minOccurrences: 2,
groupBy: 'type',
...options
});
socket.emit('error_patterns_response', {
patterns,
options,
timestamp: new Date().toISOString()
});
}
catch (error) {
socket.emit('error', { message: 'Failed to analyze error patterns' });
}
});
}
function setupAgileInteractionHandlers(socket, agileManager, io) {
// Story movement (drag and drop)
socket.on('move_story', async (data) => {
try {
const { storyId, fromColumn, toColumn, index } = data;
// Update story in agile manager (if method exists)
if (agileManager.moveStory) {
await agileManager.moveStory(storyId, toColumn, index);
}
// Broadcast the move to all connected clients
io.emit('story_moved', {
storyId,
fromColumn,
toColumn,
index,
timestamp: new Date().toISOString(),
movedBy: socket.id
});
console.error(`📋 Story ${storyId} moved from ${fromColumn} to ${toColumn}`);
}
catch (error) {
console.error(`📋 Error moving story:`, error);
socket.emit('error', { message: 'Failed to move story' });
}
});
// Story updates
socket.on('update_story', async (data) => {
try {
const { storyId, updates } = data;
if (agileManager.updateStory) {
await agileManager.updateStory(storyId, updates);
}
// Broadcast the update to all connected clients
io.emit('story_updated', {
storyId,
updates,
timestamp: new Date().toISOString(),
updatedBy: socket.id
});
console.error(`📋 Story ${storyId} updated`);
}
catch (error) {
console.error(`📋 Error updating story:`, error);
socket.emit('error', { message: 'Failed to update story' });
}
});
// Sprint updates
socket.on('update_sprint', async (data) => {
try {
const { sprintId, updates } = data;
if (agileManager.updateSprint) {
await agileManager.updateSprint(sprintId, updates);
}
// Broadcast the update to all connected clients
io.emit('sprint_updated', {
sprintId,
updates,
timestamp: new Date().toISOString(),
updatedBy: socket.id
});
console.error(`📋 Sprint ${sprintId} updated`);
}
catch (error) {
console.error(`📋 Error updating sprint:`, error);
socket.emit('error', { message: 'Failed to update sprint' });
}
});
// Request current sprint data
socket.on('request_sprint_data', async (sprintId) => {
try {
let sprintData;
if (sprintId && agileManager.getSprint) {
sprintData = await agileManager.getSprint(sprintId);
}
else if (agileManager.getCurrentSprints) {
sprintData = await agileManager.getCurrentSprints();
}
socket.emit('sprint_data_response', {
sprintData,
sprintId,
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error(`📋 Error fetching sprint data:`, error);
socket.emit('error', { message: 'Failed to fetch sprint data' });
}
});
// Request stories for a sprint or board
socket.on('request_stories', async (filters = {}) => {
try {
let stories;
if (agileManager.getStories) {
stories = await agileManager.getStories(filters);
}
else if (agileManager.getActiveStories) {
stories = await agileManager.getActiveStories();
}
socket.emit('stories_response', {
stories,
filters,
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error(`📋 Error fetching stories:`, error);
socket.emit('error', { message: 'Failed to fetch stories' });
}
});
}
//# sourceMappingURL=websocket.js.map