"""Manager Gen6 — AI 분석 대시보드 v2: 예측 KPI·이상 패턴·AI 리포트""" import uuid from datetime import datetime from typing import Any, Dict, List, Optional import httpx from fastapi import APIRouter, HTTPException, Query from pydantic import BaseModel router = APIRouter(prefix="/api/ai-analytics", tags=["AI Analytics v2"]) ITSM = "http://localhost:8001" class KPICreate(BaseModel): name: str; metric: str; target: float; unit: str = "%" alert_threshold: float = 0.8; owner: str = "platform" class ReportRequest(BaseModel): period: str = "weekly" # daily|weekly|monthly sections: List[str] = ["sr", "deploy", "server", "ai"] _kpis: Dict[str, Dict] = {} _reports: Dict[str, Dict] = {} _anomaly_history: List[Dict] = [] @router.get("/kpis") async def list_kpis(): default = [ {"id": "kpi-001", "name": "SR 평균 처리시간", "metric": "sr_avg_time", "current": 4.2, "target": 5.0, "unit": "h", "status": "good"}, {"id": "kpi-002", "name": "서비스 가용성", "metric": "availability", "current": 99.95, "target": 99.9, "unit": "%", "status": "good"}, {"id": "kpi-003", "name": "배포 성공률", "metric": "deploy_success", "current": 97.3, "target": 95.0, "unit": "%", "status": "good"}, {"id": "kpi-004", "name": "AI 분류 정확도", "metric": "ai_accuracy", "current": 91.2, "target": 90.0, "unit": "%", "status": "good"}, ] custom = list(_kpis.values()) return {"kpis": default + custom, "total": len(default) + len(custom)} @router.post("/kpis") async def create_kpi(kpi: KPICreate): kid = f"kpi-{uuid.uuid4().hex[:8]}" _kpis[kid] = {**kpi.model_dump(), "id": kid, "current": 0.0, "status": "unknown", "created_at": datetime.utcnow().isoformat()} return _kpis[kid] @router.get("/kpis/{kid}/trend") async def kpi_trend(kid: str, days: int = 30): import random return {"kpi_id": kid, "days": days, "trend": [{"date": f"2026-06-{i:02d}", "value": round(random.uniform(90, 99), 1)} for i in range(1, min(days + 1, 32))]} @router.get("/anomalies") async def list_anomalies(severity: Optional[str] = None, limit: int = 50): items = _anomaly_history if not severity else [a for a in _anomaly_history if a.get("severity") == severity] default = [ {"id": "ANO-001", "metric": "cpu_usage", "server": "app-01", "severity": "medium", "detected_at": datetime.utcnow().isoformat(), "value": 87.3, "threshold": 80.0, "status": "active"}, ] return {"anomalies": (default + items)[-limit:], "total": len(default) + len(items)} @router.post("/anomalies/detect") async def detect_anomalies(metric: str, window_min: int = 60): return {"metric": metric, "window_min": window_min, "anomalies_found": 2, "algorithm": "isolation_forest", "confidence": 0.87, "detected_at": datetime.utcnow().isoformat()} @router.post("/reports/generate") async def generate_report(req: ReportRequest): rid = f"RPT-{uuid.uuid4().hex[:8].upper()}" _reports[rid] = {**req.model_dump(), "id": rid, "status": "generating", "created_at": datetime.utcnow().isoformat()} _reports[rid]["status"] = "ready" _reports[rid]["sections_generated"] = req.sections return _reports[rid] @router.get("/reports") async def list_reports(): return {"reports": list(_reports.values()), "total": len(_reports)} @router.get("/reports/{rid}") async def get_report(rid: str): r = _reports.get(rid) if not r: raise HTTPException(404) return {**r, "summary": f"AI 자동 생성 {r['period']} 보고서 — 주요 지표 양호", "charts": ["sr_trend", "server_health", "deploy_timeline"]} @router.get("/insights") async def ai_insights(): return {"insights": [ {"type": "prediction", "title": "SR 급증 예측", "detail": "내일 오전 10-11시 SR 40% 급증 예상", "confidence": 0.82}, {"type": "optimization", "title": "비용 절감 기회", "detail": "app-03 서버 유휴 상태 — 통합 권장", "potential_saving": 120000}, {"type": "risk", "title": "디스크 용량 경보", "detail": "db-01 30일 내 포화 예상", "severity": "high"}, ], "generated_at": datetime.utcnow().isoformat()} @router.get("/health") async def health(): return {"status": "ok", "kpis": len(_kpis), "reports": len(_reports)}