diff --git a/SPMS.API/Controllers/ServiceController.cs b/SPMS.API/Controllers/ServiceController.cs index 0f8801e..e9869ba 100644 --- a/SPMS.API/Controllers/ServiceController.cs +++ b/SPMS.API/Controllers/ServiceController.cs @@ -21,6 +21,18 @@ public class ServiceController : ControllerBase _serviceManagementService = serviceManagementService; } + [HttpPost("name/check")] + [SwaggerOperation( + Summary = "서비스명 중복 체크", + Description = "서비스 등록 전 서비스명 사용 가능 여부를 확인합니다.")] + [SwaggerResponse(200, "중복 체크 성공", typeof(ApiResponse))] + [SwaggerResponse(400, "잘못된 요청")] + public async Task CheckServiceNameAsync([FromBody] ServiceNameCheckRequestDto request) + { + var result = await _serviceManagementService.CheckServiceNameAsync(request); + return Ok(ApiResponse.Success(result)); + } + [HttpPost("create")] [SwaggerOperation( Summary = "서비스 등록", diff --git a/SPMS.Application/DTOs/Service/CreateServiceRequestDto.cs b/SPMS.Application/DTOs/Service/CreateServiceRequestDto.cs index e2bdaed..990bdef 100644 --- a/SPMS.Application/DTOs/Service/CreateServiceRequestDto.cs +++ b/SPMS.Application/DTOs/Service/CreateServiceRequestDto.cs @@ -5,7 +5,7 @@ namespace SPMS.Application.DTOs.Service; public class CreateServiceRequestDto { [Required(ErrorMessage = "서비스명은 필수입니다.")] - [StringLength(100, ErrorMessage = "서비스명은 100자 이내여야 합니다.")] + [StringLength(100, MinimumLength = 2, ErrorMessage = "서비스명은 2~100자여야 합니다.")] public string ServiceName { get; set; } = string.Empty; [StringLength(500, ErrorMessage = "설명은 500자 이내여야 합니다.")] diff --git a/SPMS.Application/DTOs/Service/ServiceNameCheckRequestDto.cs b/SPMS.Application/DTOs/Service/ServiceNameCheckRequestDto.cs new file mode 100644 index 0000000..db4c72c --- /dev/null +++ b/SPMS.Application/DTOs/Service/ServiceNameCheckRequestDto.cs @@ -0,0 +1,10 @@ +using System.ComponentModel.DataAnnotations; + +namespace SPMS.Application.DTOs.Service; + +public class ServiceNameCheckRequestDto +{ + [Required(ErrorMessage = "서비스명은 필수입니다.")] + [StringLength(100, MinimumLength = 1)] + public string ServiceName { get; set; } = string.Empty; +} diff --git a/SPMS.Application/DTOs/Service/ServiceNameCheckResponseDto.cs b/SPMS.Application/DTOs/Service/ServiceNameCheckResponseDto.cs new file mode 100644 index 0000000..1beabc4 --- /dev/null +++ b/SPMS.Application/DTOs/Service/ServiceNameCheckResponseDto.cs @@ -0,0 +1,7 @@ +namespace SPMS.Application.DTOs.Service; + +public class ServiceNameCheckResponseDto +{ + public string ServiceName { get; set; } = string.Empty; + public bool IsAvailable { get; set; } +} diff --git a/SPMS.Application/Interfaces/IServiceManagementService.cs b/SPMS.Application/Interfaces/IServiceManagementService.cs index 9641a5b..b6a195c 100644 --- a/SPMS.Application/Interfaces/IServiceManagementService.cs +++ b/SPMS.Application/Interfaces/IServiceManagementService.cs @@ -4,6 +4,7 @@ namespace SPMS.Application.Interfaces; public interface IServiceManagementService { + Task CheckServiceNameAsync(ServiceNameCheckRequestDto request); Task CreateAsync(CreateServiceRequestDto request, long adminId); Task UpdateAsync(UpdateServiceRequestDto request); Task GetListAsync(ServiceListRequestDto request); diff --git a/SPMS.Application/Services/ServiceManagementService.cs b/SPMS.Application/Services/ServiceManagementService.cs index 78ae887..d53636f 100644 --- a/SPMS.Application/Services/ServiceManagementService.cs +++ b/SPMS.Application/Services/ServiceManagementService.cs @@ -27,6 +27,16 @@ public class ServiceManagementService : IServiceManagementService _credentialEncryptionService = credentialEncryptionService; } + public async Task CheckServiceNameAsync(ServiceNameCheckRequestDto request) + { + var exists = await _serviceRepository.ServiceNameExistsAsync(request.ServiceName); + return new ServiceNameCheckResponseDto + { + ServiceName = request.ServiceName, + IsAvailable = !exists + }; + } + public async Task CreateAsync(CreateServiceRequestDto request, long adminId) { // 서비스명 중복 검사 @@ -34,7 +44,7 @@ public class ServiceManagementService : IServiceManagementService if (nameExists) { throw new SpmsException( - ErrorCodes.Conflict, + ErrorCodes.ServiceNameDuplicate, "이미 존재하는 서비스명입니다.", 409); } @@ -97,7 +107,7 @@ public class ServiceManagementService : IServiceManagementService if (nameExists) { throw new SpmsException( - ErrorCodes.Conflict, + ErrorCodes.ServiceNameDuplicate, "이미 존재하는 서비스명입니다.", 409); } diff --git a/SPMS.Domain/Common/ErrorCodes.cs b/SPMS.Domain/Common/ErrorCodes.cs index 6e3dff9..76ee6fc 100644 --- a/SPMS.Domain/Common/ErrorCodes.cs +++ b/SPMS.Domain/Common/ErrorCodes.cs @@ -36,6 +36,7 @@ public static class ErrorCodes public const string DecryptionFailed = "131"; public const string InvalidCredentials = "132"; public const string ServiceScopeRequired = "133"; + public const string ServiceNameDuplicate = "134"; // === Device (4) === public const string DeviceNotFound = "141";