using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; using SPMS.Application.DTOs.Service; using SPMS.Application.Interfaces; using SPMS.Domain.Common; namespace SPMS.API.Controllers; [ApiController] [Route("v1/in/service")] [ApiExplorerSettings(GroupName = "service")] [Authorize(Roles = "Super")] public class ServiceController : ControllerBase { private readonly IServiceManagementService _serviceManagementService; public ServiceController(IServiceManagementService serviceManagementService) { _serviceManagementService = serviceManagementService; } [HttpPost("list")] [SwaggerOperation( Summary = "서비스 목록 조회", Description = "등록된 서비스 목록을 조회합니다. 페이징, 검색, 상태 필터를 지원합니다.")] [SwaggerResponse(200, "조회 성공", typeof(ApiResponse))] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] public async Task GetListAsync([FromBody] ServiceListRequestDto request) { var result = await _serviceManagementService.GetListAsync(request); return Ok(ApiResponse.Success(result)); } [HttpPost("{serviceCode}")] [SwaggerOperation( Summary = "서비스 상세 조회", Description = "특정 서비스의 상세 정보를 조회합니다.")] [SwaggerResponse(200, "조회 성공", typeof(ApiResponse))] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "서비스를 찾을 수 없음")] public async Task GetByServiceCodeAsync([FromRoute] string serviceCode) { var result = await _serviceManagementService.GetByServiceCodeAsync(serviceCode); return Ok(ApiResponse.Success(result)); } [HttpPost("{serviceCode}/status")] [SwaggerOperation( Summary = "서비스 상태 변경", Description = "서비스의 상태를 변경합니다. (Active: 0, Suspended: 1)")] [SwaggerResponse(200, "상태 변경 성공", typeof(ApiResponse))] [SwaggerResponse(400, "잘못된 요청 또는 이미 해당 상태")] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "서비스를 찾을 수 없음")] public async Task ChangeStatusAsync( [FromRoute] string serviceCode, [FromBody] ChangeServiceStatusRequestDto request) { var result = await _serviceManagementService.ChangeStatusAsync(serviceCode, request); return Ok(ApiResponse.Success(result)); } [HttpPost("{serviceCode}/apikey/refresh")] [SwaggerOperation( Summary = "API Key 재발급", Description = "서비스의 API Key를 재발급합니다. 기존 키는 즉시 무효화되며, 새 키는 1회만 표시됩니다.")] [SwaggerResponse(200, "재발급 성공", typeof(ApiResponse))] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "서비스를 찾을 수 없음")] public async Task RefreshApiKeyAsync([FromRoute] string serviceCode) { var result = await _serviceManagementService.RefreshApiKeyAsync(serviceCode); return Ok(ApiResponse.Success(result)); } [HttpPost("{serviceCode}/apns")] [SwaggerOperation( Summary = "APNs 키 등록", Description = "APNs 푸시 발송을 위한 인증 정보를 등록합니다. .p8 파일 내용, Key ID(10자리), Team ID(10자리), Bundle ID가 필요합니다.")] [SwaggerResponse(200, "등록 성공", typeof(ApiResponse))] [SwaggerResponse(400, "잘못된 요청 (유효하지 않은 키 형식)")] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "서비스를 찾을 수 없음")] public async Task RegisterApnsCredentialsAsync( [FromRoute] string serviceCode, [FromBody] ApnsCredentialsRequestDto request) { await _serviceManagementService.RegisterApnsCredentialsAsync(serviceCode, request); return Ok(ApiResponse.Success()); } [HttpPost("{serviceCode}/fcm")] [SwaggerOperation( Summary = "FCM 키 등록", Description = "FCM 푸시 발송을 위한 Service Account JSON을 등록합니다. Firebase Console에서 다운로드한 service-account.json 내용이 필요합니다.")] [SwaggerResponse(200, "등록 성공", typeof(ApiResponse))] [SwaggerResponse(400, "잘못된 요청 (유효하지 않은 JSON 형식)")] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "서비스를 찾을 수 없음")] public async Task RegisterFcmCredentialsAsync( [FromRoute] string serviceCode, [FromBody] FcmCredentialsRequestDto request) { await _serviceManagementService.RegisterFcmCredentialsAsync(serviceCode, request); return Ok(ApiResponse.Success()); } [HttpPost("{serviceCode}/credentials")] [SwaggerOperation( Summary = "푸시 키 정보 조회", Description = "서비스에 등록된 APNs/FCM 키의 메타 정보를 조회합니다. 민감 정보(Private Key)는 반환되지 않습니다.")] [SwaggerResponse(200, "조회 성공", typeof(ApiResponse))] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "서비스를 찾을 수 없음")] public async Task GetCredentialsAsync([FromRoute] string serviceCode) { var result = await _serviceManagementService.GetCredentialsAsync(serviceCode); return Ok(ApiResponse.Success(result)); } }