from rest_framework import viewsets, permissions, status from rest_framework.response import Response from rest_framework.decorators import action from django.db.models import Avg, Count, Q from django.utils import timezone from datetime import timedelta from api.models import InferenceAuditLog from api.serializers.audit_serializer import InferenceAuditLogSerializer # นำเข้า Permission ที่จำเป็น from permissions.permission_classes import IsAdminOrOperator, IsViewerOrHigher class AuditLogViewSet(viewsets.ReadOnlyModelViewSet): """ API สำหรับการเข้าถึง Inference Audit Log และสถิติรวม (รวมการดึง Summary ด้วย) """ queryset = InferenceAuditLog.objects.all() serializer_class = InferenceAuditLogSerializer permission_classes = [permissions.IsAuthenticated] lookup_field = 'id' lookup_url_kwarg = 'id' def retrieve(self, request, *args, **kwargs): # บังคับให้ Lookup Key (pk) เป็น String kwargs[self.lookup_url_kwarg] = str(kwargs[self.lookup_url_kwarg]) return super().retrieve(request, *args, **kwargs) def get_queryset(self): # คืน Log ล่าสุด 10 รายการ (สำหรับ Recent Events ใน Dashboard) return self.queryset.select_related('user').order_by('-timestamp')[:10] # 📌 เพิ่ม order_by เพื่อให้ได้ล่าสุดจริง ๆ # ----------------------------------------------- # Custom Action: ดึงสถิติรวม Dynamic (สำหรับ Viewer, Operator, Admin) # Endpoint: GET /api/v1/audit/summary/ # ----------------------------------------------- @action( detail=False, methods=['get'], url_path='summary', # อนุญาตให้เข้าถึงสำหรับทุก Role ใน Dashboard permission_classes=[IsViewerOrHigher] ) def get_summary(self, request): user = request.user # 1. ตรวจสอบ Role เพื่อกำหนดขอบเขตข้อมูลที่จะแสดง (Dynamic View) # ตรวจสอบว่าผู้ใช้เป็น ADMIN หรือ OPERATOR หรือไม่ is_high_privilege = user.role in ['ADMIN', 'OPERATOR'] # กำหนดขีดจำกัดและข้อมูลที่จะรวม log_limit = 10 if is_high_privilege else 5 include_latency = is_high_privilege # Latency เป็นข้อมูลเชิงเทคนิค one_day_ago = timezone.now() - timedelta(hours=24) queryset = self.queryset.filter(timestamp__gte=one_day_ago) # 2. คำนวณสถิติพื้นฐาน (ใช้ร่วมกัน) metrics = queryset.aggregate( total_runs=Count('id'), success_count=Count('id', filter=Q(is_success=True)), # คำนวณ Avg Latency เฉพาะถ้าผู้ใช้มีสิทธิ์สูง avg_latency_ms=Avg('latency_ms') if include_latency else None ) # 3. คำนวณ Success Rate total = metrics.get('total_runs', 0) success = metrics.get('success_count', 0) success_rate = (success / total) * 100 if total > 0 else 0 # 4. ดึง Log ล่าสุดตามสิทธิ์ last_logs = self.queryset.select_related('user').order_by('-timestamp')[:log_limit] response_data = { "time_window": "24 hours", "total_runs": total, "success_rate": round(success_rate, 2), "last_logs": InferenceAuditLogSerializer(last_logs, many=True).data } # 5. เพิ่ม Latency เข้าไปใน Response เฉพาะ Role ที่มีสิทธิ์สูง if include_latency: response_data['avg_latency_ms'] = round(metrics.get('avg_latency_ms', 0) or 0, 2) return Response(response_data)