from fastapi import APIRouter, Depends, HTTPException from typing import List, Dict, Any from core.security import verify_api_key from ml_services.nlp_graph_ai import nlp_graph_service from models.schemas import GraphEdge from core.db import db_handler router = APIRouter(prefix="/api/v1/intel", tags=["Intelligence & Analysis"]) @router.post("/fraud-rings") async def detect_fraud_rings( edges: List[GraphEdge], api_key: str = Depends(verify_api_key) ): try: result = nlp_graph_service.detect_fraud_rings(edges) # Save analysis to DB if db_handler.db is not None: await db_handler.db["fraud_rings"].insert_one({ "communities": result["communities"], "mule_hubs": result["top_mule_hubs"], "edge_count": len(edges) }) return { "fraud_rings": result["communities"], "count": len(result["communities"]), "mule_hubs": result["top_mule_hubs"] } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/geo/hotspots") async def get_hotspots( eps: float = 0.01, min_samples: int = 3, api_key: str = Depends(verify_api_key) ): try: # Fetch coordinates from MongoDB coordinates = [] if db_handler.db is not None: # We look for incidents with valid Point locations cursor = db_handler.db["incidents"].find({"location": {"$ne": None}}) async for document in cursor: loc = document.get("location") if loc and loc.get("type") == "Point" and len(loc.get("coordinates", [])) == 2: # coordinates: [longitude, latitude] - map to [lat, lng] for DBSCAN lng, lat = loc["coordinates"] coordinates.append([lat, lng]) clusters = nlp_graph_service.cluster_hotspots(coordinates, eps=eps, min_samples=min_samples) # Convert clusters to GeoJSON points for frontend rendering geojson_features = [] for i, cluster in enumerate(clusters): for lat, lng in cluster: geojson_features.append({ "type": "Feature", "geometry": { "type": "Point", "coordinates": [lng, lat] }, "properties": { "cluster_id": i } }) return {"type": "FeatureCollection", "features": geojson_features} except Exception as e: raise HTTPException(status_code=500, detail=str(e))