import { Get, Path, Query, Request, Response, Route, Security, SuccessResponse, Tags, Delete } from 'tsoa'; import { ValidationError } from '../middleware/errorHandler'; import { auditService } from '../services/audit.service'; import { AuditAction } from '@prisma/client'; import { ListAuditLogsResponse, AuditLogResponse, AuditLogStats, } from '../types/audit.types'; @Route('api/admin/audit-logs') @Tags('Admin/AuditLogs') export class AuditController { /** * ดึงรายการ audit logs ทั้งหมด * Get all audit logs with filters and pagination * @param userId - กรองตาม user ID * @param action - กรองตาม action type * @param entityType - กรองตาม entity type (Course, User, Lesson, etc.) * @param entityId - กรองตาม entity ID * @param startDate - วันที่เริ่มต้น (ISO format) * @param endDate - วันที่สิ้นสุด (ISO format) * @param page - หน้าที่ต้องการ * @param limit - จำนวนรายการต่อหน้า */ @Get('') @Security('jwt', ['admin']) @SuccessResponse('200', 'Audit logs retrieved successfully') @Response('401', 'Unauthorized') @Response('403', 'Forbidden - Admin only') public async getAuditLogs( @Request() request: any, @Query() userId?: number, @Query() action?: AuditAction, @Query() entityType?: string, @Query() entityId?: number, @Query() startDate?: string, @Query() endDate?: string, @Query() page?: number, @Query() limit?: number ): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await auditService.getLogs({ userId, action, entityType, entityId, startDate: startDate ? new Date(startDate) : undefined, endDate: endDate ? new Date(endDate) : undefined, page: page || 1, limit: limit || 50, }); } /** * ดึง audit log by ID * Get audit log detail by ID * @param logId - รหัส audit log */ @Get('{logId}') @Security('jwt', ['admin']) @SuccessResponse('200', 'Audit log retrieved successfully') @Response('401', 'Unauthorized') @Response('403', 'Forbidden - Admin only') @Response('404', 'Audit log not found') public async getAuditLogById( @Request() request: any, @Path() logId: number ): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } const log = await auditService.getLogById(logId); if (!log) { throw new ValidationError('Audit log not found'); } return log; } /** * ดึงสถิติ audit logs สำหรับ dashboard * Get audit log statistics for admin dashboard */ @Get('stats/summary') @Security('jwt', ['admin']) @SuccessResponse('200', 'Audit stats retrieved successfully') @Response('401', 'Unauthorized') @Response('403', 'Forbidden - Admin only') public async getAuditStats(@Request() request: any): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await auditService.getStats(); } /** * ดึง history ของ entity เฉพาะ * Get audit history for a specific entity * @param entityType - ประเภท entity (Course, User, Lesson, etc.) * @param entityId - รหัส entity */ @Get('entity/{entityType}/{entityId}') @Security('jwt', ['admin']) @SuccessResponse('200', 'Entity history retrieved successfully') @Response('401', 'Unauthorized') @Response('403', 'Forbidden - Admin only') public async getEntityHistory( @Request() request: any, @Path() entityType: string, @Path() entityId: number ): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await auditService.getEntityHistory(entityType, entityId); } /** * ดึง activity ของ user เฉพาะ * Get activity logs for a specific user * @param userId - รหัส user * @param limit - จำนวนรายการ */ @Get('user/{userId}/activity') @Security('jwt', ['admin']) @SuccessResponse('200', 'User activity retrieved successfully') @Response('401', 'Unauthorized') @Response('403', 'Forbidden - Admin only') public async getUserActivity( @Request() request: any, @Path() userId: number, @Query() limit?: number ): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await auditService.getUserActivity(userId, limit || 50); } /** * ลบ audit logs เก่า (maintenance) * Delete old audit logs for maintenance * @param days - ลบ logs ที่เก่ากว่ากี่วัน */ @Delete('cleanup') @Security('jwt', ['admin']) @SuccessResponse('200', 'Old logs deleted successfully') @Response('401', 'Unauthorized') @Response('403', 'Forbidden - Admin only') public async deleteOldLogs( @Request() request: any, @Query() days: number = 90 ): Promise<{ deleted: number; message: string }> { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } if (days < 30) { throw new ValidationError('Cannot delete logs newer than 30 days'); } const deleted = await auditService.deleteOldLogs(days); return { deleted, message: `Deleted ${deleted} audit logs older than ${days} days`, }; } }