using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; using SPMS.Application.DTOs.Notification; using SPMS.Application.Interfaces; using SPMS.Domain.Common; using SPMS.Domain.Exceptions; namespace SPMS.API.Controllers; [ApiController] [Route("v1/in/notification")] [Authorize] [ApiExplorerSettings(GroupName = "notification")] public class NotificationController : ControllerBase { private readonly INotificationService _notificationService; public NotificationController(INotificationService notificationService) { _notificationService = notificationService; } [HttpPost("summary")] [SwaggerOperation(Summary = "알림 요약 조회", Description = "최근 N건의 알림과 미읽 건수를 반환합니다. 헤더 뱃지용.")] public async Task GetSummaryAsync([FromBody] NotificationSummaryRequestDto request) { var adminId = GetAdminId(); var result = await _notificationService.GetSummaryAsync(adminId, request); return Ok(ApiResponse.Success(result)); } [HttpPost("list")] [SwaggerOperation(Summary = "알림 목록 조회", Description = "알림 목록을 페이지 단위로 조회합니다. 카테고리/기간/읽음 필터를 지원합니다.")] public async Task GetListAsync([FromBody] NotificationListRequestDto request) { var adminId = GetAdminId(); var result = await _notificationService.GetListAsync(adminId, request); return Ok(ApiResponse.Success(result)); } [HttpPost("read")] [SwaggerOperation(Summary = "알림 읽음 처리", Description = "단건 알림을 읽음 처리합니다. 이미 읽은 알림은 무시(멱등).")] public async Task MarkAsReadAsync([FromBody] NotificationReadRequestDto request) { var adminId = GetAdminId(); var result = await _notificationService.MarkAsReadAsync(adminId, request); return Ok(ApiResponse.Success(result)); } [HttpPost("read-all")] [SwaggerOperation(Summary = "알림 전체 읽음", Description = "해당 관리자의 모든 미읽 알림을 일괄 읽음 처리합니다.")] public async Task MarkAllAsReadAsync() { var adminId = GetAdminId(); var result = await _notificationService.MarkAllAsReadAsync(adminId); return Ok(ApiResponse.Success(result)); } private long GetAdminId() { var adminIdClaim = User.FindFirst("adminId")?.Value; if (string.IsNullOrEmpty(adminIdClaim) || !long.TryParse(adminIdClaim, out var adminId)) throw new SpmsException(ErrorCodes.Unauthorized, "인증 정보가 올바르지 않습니다.", 401); return adminId; } }