localgreenchain/pages/api/agents/lineage/anomalies.ts
Claude 27cfad5d18
Deploy PlantLineageAgent with API endpoints and tests
Add REST API endpoints for the PlantLineageAgent:
- GET /api/agents/lineage - Agent status and network statistics
- POST /api/agents/lineage - Start/stop/pause/resume agent
- GET /api/agents/lineage/[plantId] - Lineage analysis for specific plant
- GET /api/agents/lineage/anomalies - List detected lineage anomalies

Includes comprehensive test suite with 25 passing tests.
2025-11-23 00:25:42 +00:00

79 lines
2.4 KiB
TypeScript

/**
* API Route: Get lineage anomalies detected by PlantLineageAgent
* GET /api/agents/lineage/anomalies
*/
import type { NextApiRequest, NextApiResponse } from 'next';
import { getPlantLineageAgent } from '../../../../lib/agents';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'GET') {
return res.status(405).json({ success: false, error: 'Method not allowed' });
}
try {
const { severity, type, limit } = req.query;
const agent = getPlantLineageAgent();
let anomalies = agent.getAnomalies();
// Filter by severity if specified
if (severity && typeof severity === 'string') {
const validSeverities = ['low', 'medium', 'high'];
if (!validSeverities.includes(severity)) {
return res.status(400).json({
success: false,
error: `Invalid severity. Must be one of: ${validSeverities.join(', ')}`
});
}
anomalies = anomalies.filter(a => a.severity === severity);
}
// Filter by type if specified
if (type && typeof type === 'string') {
const validTypes = ['orphan', 'circular', 'invalid_generation', 'missing_parent', 'suspicious_location'];
if (!validTypes.includes(type)) {
return res.status(400).json({
success: false,
error: `Invalid type. Must be one of: ${validTypes.join(', ')}`
});
}
anomalies = anomalies.filter(a => a.type === type);
}
// Apply limit if specified
const maxResults = limit ? Math.min(parseInt(limit as string, 10), 100) : 50;
anomalies = anomalies.slice(0, maxResults);
// Group by type for summary
const byType: Record<string, number> = {};
const bySeverity: Record<string, number> = {};
const allAnomalies = agent.getAnomalies();
for (const anomaly of allAnomalies) {
byType[anomaly.type] = (byType[anomaly.type] || 0) + 1;
bySeverity[anomaly.severity] = (bySeverity[anomaly.severity] || 0) + 1;
}
res.status(200).json({
success: true,
summary: {
total: allAnomalies.length,
byType,
bySeverity,
},
filters: {
severity: severity || null,
type: type || null,
limit: maxResults,
},
anomalies,
});
} catch (error: any) {
console.error('Error getting lineage anomalies:', error);
res.status(500).json({ success: false, error: error.message || 'Internal server error' });
}
}