diff --git a/SPMS.API/Controllers/ServiceController.cs b/SPMS.API/Controllers/ServiceController.cs index 7c94cb4..8af1835 100644 --- a/SPMS.API/Controllers/ServiceController.cs +++ b/SPMS.API/Controllers/ServiceController.cs @@ -57,6 +57,21 @@ public class ServiceController : ControllerBase return Ok(ApiResponse.Success(result)); } + [HttpPost("delete")] + [SwaggerOperation( + Summary = "서비스 삭제", + Description = "서비스를 Soft Delete 처리합니다. IsDeleted=true, 상태를 Suspended로 변경합니다.")] + [SwaggerResponse(200, "삭제 성공", typeof(ApiResponse))] + [SwaggerResponse(401, "인증되지 않은 요청")] + [SwaggerResponse(403, "권한 없음")] + [SwaggerResponse(404, "서비스를 찾을 수 없음")] + [SwaggerResponse(409, "이미 삭제된 서비스")] + public async Task DeleteAsync([FromBody] DeleteServiceRequestDto request) + { + await _serviceManagementService.DeleteAsync(request); + return Ok(ApiResponse.Success()); + } + [HttpPost("list")] [SwaggerOperation( Summary = "서비스 목록 조회", diff --git a/SPMS.Application/DTOs/Service/DeleteServiceRequestDto.cs b/SPMS.Application/DTOs/Service/DeleteServiceRequestDto.cs new file mode 100644 index 0000000..9a77845 --- /dev/null +++ b/SPMS.Application/DTOs/Service/DeleteServiceRequestDto.cs @@ -0,0 +1,11 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; + +namespace SPMS.Application.DTOs.Service; + +public class DeleteServiceRequestDto +{ + [Required(ErrorMessage = "서비스 코드는 필수입니다.")] + [JsonPropertyName("service_code")] + public string ServiceCode { get; set; } = string.Empty; +} diff --git a/SPMS.Application/Interfaces/IServiceManagementService.cs b/SPMS.Application/Interfaces/IServiceManagementService.cs index 5d01a8c..19afd94 100644 --- a/SPMS.Application/Interfaces/IServiceManagementService.cs +++ b/SPMS.Application/Interfaces/IServiceManagementService.cs @@ -8,6 +8,7 @@ public interface IServiceManagementService Task UpdateAsync(UpdateServiceRequestDto request); Task GetListAsync(ServiceListRequestDto request); Task GetByServiceCodeAsync(string serviceCode); + Task DeleteAsync(DeleteServiceRequestDto request); Task ChangeStatusAsync(string serviceCode, ChangeServiceStatusRequestDto request); Task RefreshApiKeyAsync(string serviceCode); Task RegisterApnsCredentialsAsync(string serviceCode, ApnsCredentialsRequestDto request); diff --git a/SPMS.Application/Services/ServiceManagementService.cs b/SPMS.Application/Services/ServiceManagementService.cs index d382fdd..b70989b 100644 --- a/SPMS.Application/Services/ServiceManagementService.cs +++ b/SPMS.Application/Services/ServiceManagementService.cs @@ -233,6 +233,34 @@ public class ServiceManagementService : IServiceManagementService return MapToDto(serviceWithIps ?? service); } + public async Task DeleteAsync(DeleteServiceRequestDto request) + { + var service = await _serviceRepository.GetByServiceCodeAsync(request.ServiceCode); + if (service is null) + { + throw new SpmsException( + ErrorCodes.NotFound, + "서비스를 찾을 수 없습니다.", + 404); + } + + if (service.IsDeleted) + { + throw new SpmsException( + ErrorCodes.Conflict, + "이미 삭제된 서비스입니다.", + 409); + } + + service.IsDeleted = true; + service.DeletedAt = DateTime.UtcNow; + service.Status = ServiceStatus.Suspended; + service.UpdatedAt = DateTime.UtcNow; + + _serviceRepository.Update(service); + await _unitOfWork.SaveChangesAsync(); + } + public async Task ChangeStatusAsync(string serviceCode, ChangeServiceStatusRequestDto request) { var service = await _serviceRepository.GetByServiceCodeAsync(serviceCode);