Spaces:
Paused
Paused
File size: 5,073 Bytes
4ae946d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | import logging
from datetime import datetime, timedelta
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import text
from sqlalchemy.orm import Session
from app.modules.auth.service import auth_service
from core.database import User, get_db
from .schemas import TransactionFlowResponse
from .service import AnalyticsTimeframe, analytics_service
logger = logging.getLogger(__name__)
router = APIRouter()
@router.get("/cases")
async def get_case_analytics(
date_from: str | None = None,
date_to: str | None = None,
db: Session = Depends(get_db),
current_user: User = Depends(auth_service.get_current_user),
):
"""Get optimized case analytics"""
try:
date_from_parsed = datetime.fromisoformat(date_from) if date_from else None
date_to_parsed = datetime.fromisoformat(date_to) if date_to else None
analytics = analytics_service.get_case_analytics(
db, date_from_parsed, date_to_parsed
)
return analytics
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/transactions")
async def get_transaction_analytics(
case_id: str | None = None,
date_from: str | None = None,
date_to: str | None = None,
db: Session = Depends(get_db),
current_user: User = Depends(auth_service.get_current_user),
):
"""Get transaction analytics with optimized aggregates"""
try:
date_from_parsed = datetime.fromisoformat(date_from) if date_from else None
date_to_parsed = datetime.fromisoformat(date_to) if date_to else None
analytics = analytics_service.get_transaction_aggregates(
db, case_id, date_from_parsed, date_to_parsed
)
return analytics
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/overview")
async def get_system_overview(
db: Session = Depends(get_db),
current_user: User = Depends(auth_service.get_current_user),
):
"""Get system overview statistics"""
try:
from app.modules.cases.service import case_service
case_stats = case_service.get_case_stats(db)
# Get recent cases using CaseService
recent_cases_data = case_service.get_cases_paginated(
db, page=1, per_page=5, filters={}
)
recent_cases = recent_cases_data.get("cases", [])
return {
"case_stats": case_stats,
"recent_cases": [
{
"id": case.id,
"title": case.title,
"status": (
case.status.value
if hasattr(case.status, "value")
else case.status
),
"created_at": (
case.created_at.isoformat() if case.created_at else None
),
}
for case in recent_cases
],
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/temporal-flow", response_model=list[TransactionFlowResponse])
async def get_temporal_flow(
days: int = 30,
limit: int = 2000,
db: Session = Depends(get_db),
current_user: User = Depends(auth_service.get_current_user),
):
"""Get temporal flow data for visualization"""
try:
cutoff_date = (datetime.now() - timedelta(days=days)).isoformat()
query = """
SELECT t.id, t.customer_name, t.merchant_name, t.amount, t.date, t.merchant_category, t.risk_score
FROM transactions t
WHERE t.date >= :cutoff_date
ORDER BY t.date ASC
LIMIT :limit
"""
result = db.execute(text(query), {"cutoff_date": cutoff_date, "limit": limit})
flows = []
for row in result:
risk_score = float(row[6]) if row[6] else 0.0
tx_type = "normal"
if risk_score > 80:
tx_type = "flagged"
elif risk_score > 50:
tx_type = "suspicious"
flows.append(
{
"id": str(row[0]),
"source": row[1] or "Unknown Source",
"target": row[2] or "Unknown Target",
"amount": float(row[3]),
"timestamp": str(row[4]),
"type": tx_type,
"category": row[5] or "Uncategorized",
"risk_score": risk_score,
}
)
return flows
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/behavioral")
async def get_behavioral_analytics(
current_user: User = Depends(auth_service.get_current_user),
):
"""Get behavioral analytics for heatmaps"""
try:
risk_heatmaps = await analytics_service.generate_risk_heatmaps(
AnalyticsTimeframe.MONTH
)
return risk_heatmaps
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
|