using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; using SPMS.Application.DTOs.Stats; using SPMS.Application.Interfaces; using SPMS.Domain.Common; namespace SPMS.API.Controllers; [ApiController] [Route("v1/in/stats")] [ApiExplorerSettings(GroupName = "stats")] public class StatsController : ControllerBase { private readonly IStatsService _statsService; public StatsController(IStatsService statsService) { _statsService = statsService; } [HttpPost("daily")] [SwaggerOperation(Summary = "일별 통계 조회", Description = "기간별 일별 발송/성공/실패/열람 통계를 조회합니다. X-Service-Code 헤더 미지정 시 전체 서비스 통계를 조회합니다.")] public async Task GetDailyAsync([FromBody] DailyStatRequestDto request) { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetDailyAsync(serviceId, request); return Ok(ApiResponse.Success(result, "조회 성공")); } [HttpPost("summary")] [SwaggerOperation(Summary = "요약 통계 조회", Description = "대시보드 요약 통계를 조회합니다. X-Service-Code 헤더 미지정 시 전체 서비스 통계를 조회합니다.")] public async Task GetSummaryAsync() { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetSummaryAsync(serviceId); return Ok(ApiResponse.Success(result, "조회 성공")); } [HttpPost("message")] [SwaggerOperation(Summary = "메시지별 통계 조회", Description = "특정 메시지의 발송 통계를 조회합니다. X-Service-Code 헤더 미지정 시 전체 서비스 통계를 조회합니다.")] public async Task GetMessageStatAsync([FromBody] MessageStatRequestDto request) { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetMessageStatAsync(serviceId, request); return Ok(ApiResponse.Success(result, "조회 성공")); } [HttpPost("hourly")] [SwaggerOperation(Summary = "시간대별 통계 조회", Description = "시간대별 발송 추이를 조회합니다. X-Service-Code 헤더 미지정 시 전체 서비스 통계를 조회합니다.")] public async Task GetHourlyAsync([FromBody] HourlyStatRequestDto request) { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetHourlyAsync(serviceId, request); return Ok(ApiResponse.Success(result, "조회 성공")); } [HttpPost("device")] [SwaggerOperation(Summary = "디바이스 통계 조회", Description = "플랫폼/모델별 디바이스 분포를 조회합니다. X-Service-Code 헤더 미지정 시 전체 서비스 통계를 조회합니다.")] public async Task GetDeviceStatAsync() { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetDeviceStatAsync(serviceId); return Ok(ApiResponse.Success(result, "조회 성공")); } [HttpPost("export")] [SwaggerOperation(Summary = "통계 리포트 다운로드", Description = "일별/시간대별/플랫폼별 통계를 엑셀(.xlsx) 파일로 다운로드합니다. X-Service-Code 헤더 미지정 시 전체 서비스 통계를 조회합니다.")] public async Task ExportReportAsync([FromBody] StatsExportRequestDto request) { var serviceId = GetOptionalServiceId(); var fileBytes = await _statsService.ExportReportAsync(serviceId, request); var fileName = $"stats_report_{request.StartDate}_{request.EndDate}.xlsx"; return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName); } [HttpPost("failure")] [SwaggerOperation(Summary = "실패원인 통계 조회", Description = "실패 원인별 집계를 상위 N개로 조회합니다. X-Service-Code 헤더 미지정 시 전체 서비스 통계를 조회합니다.")] public async Task GetFailureStatAsync([FromBody] FailureStatRequestDto request) { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetFailureStatAsync(serviceId, request); return Ok(ApiResponse.Success(result, "조회 성공")); } [HttpPost("dashboard")] [SwaggerOperation(Summary = "대시보드 통합 조회", Description = "KPI, 일별 추이, 시간대별 분포, 플랫폼 비율, 상위 메시지를 한번에 조회합니다. X-Service-Code 헤더 미지정 시 전체 서비스 통계를 조회합니다.")] public async Task GetDashboardAsync([FromBody] DashboardRequestDto request) { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetDashboardAsync(serviceId, request); return Ok(ApiResponse.Success(result, "조회 성공")); } [HttpPost("history/list")] [SwaggerOperation(Summary = "이력 목록 조회", Description = "메시지별 발송 이력 목록을 조회합니다. keyword/status/date 필터를 지원합니다. X-Service-Code 헤더 미지정 시 전체 서비스 이력을 조회합니다.")] public async Task GetHistoryListAsync([FromBody] HistoryListRequestDto request) { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetHistoryListAsync(serviceId, request); return Ok(ApiResponse.Success(result, "조회 성공")); } [HttpPost("history/detail")] [SwaggerOperation(Summary = "이력 상세 조회", Description = "특정 메시지의 발송 이력 상세(기본정보+집계+실패사유+본문)를 조회합니다. X-Service-Code 헤더 미지정 시 전체 서비스에서 검색합니다.")] public async Task GetHistoryDetailAsync([FromBody] HistoryDetailRequestDto request) { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetHistoryDetailAsync(serviceId, request); return Ok(ApiResponse.Success(result, "조회 성공")); } [HttpPost("send-log")] [SwaggerOperation(Summary = "발송 상세 로그 조회", Description = "특정 메시지의 개별 디바이스별 발송 상세 로그를 조회합니다. X-Service-Code 헤더 미지정 시 전체 서비스 통계를 조회합니다.")] public async Task GetSendLogDetailAsync([FromBody] SendLogDetailRequestDto request) { var serviceId = GetOptionalServiceId(); var result = await _statsService.GetSendLogDetailAsync(serviceId, request); return Ok(ApiResponse.Success(result, "조회 성공")); } private long? GetOptionalServiceId() { if (HttpContext.Items.TryGetValue("ServiceId", out var obj) && obj is long id) return id; return null; } }