feat: 서비스 태그 목록/수정 API 구현 (#70)
All checks were successful
SPMS_API/pipeline/head This commit looks good
All checks were successful
SPMS_API/pipeline/head This commit looks good
Reviewed-on: https://git.ipstein.myds.me/SPMS/SPMS_API/pulls/71
This commit is contained in:
commit
e288f28123
|
|
@ -178,6 +178,35 @@ public class ServiceController : ControllerBase
|
||||||
return Ok(ApiResponse<CredentialsResponseDto>.Success(result));
|
return Ok(ApiResponse<CredentialsResponseDto>.Success(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("tags/list")]
|
||||||
|
[SwaggerOperation(
|
||||||
|
Summary = "태그 목록 조회",
|
||||||
|
Description = "서비스에 등록된 태그 목록을 조회합니다.")]
|
||||||
|
[SwaggerResponse(200, "조회 성공", typeof(ApiResponse<ServiceTagsResponseDto>))]
|
||||||
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
||||||
|
[SwaggerResponse(403, "권한 없음")]
|
||||||
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
||||||
|
public async Task<IActionResult> GetTagsAsync([FromBody] ServiceTagsRequestDto request)
|
||||||
|
{
|
||||||
|
var result = await _serviceManagementService.GetTagsAsync(request);
|
||||||
|
return Ok(ApiResponse<ServiceTagsResponseDto>.Success(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("tags/update")]
|
||||||
|
[SwaggerOperation(
|
||||||
|
Summary = "태그 수정",
|
||||||
|
Description = "서비스의 태그 목록을 수정합니다. 최대 10개까지 등록 가능합니다.")]
|
||||||
|
[SwaggerResponse(200, "수정 성공", typeof(ApiResponse<ServiceTagsResponseDto>))]
|
||||||
|
[SwaggerResponse(400, "잘못된 요청 또는 변경 없음")]
|
||||||
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
||||||
|
[SwaggerResponse(403, "권한 없음")]
|
||||||
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
||||||
|
public async Task<IActionResult> UpdateTagsAsync([FromBody] UpdateServiceTagsRequestDto request)
|
||||||
|
{
|
||||||
|
var result = await _serviceManagementService.UpdateTagsAsync(request);
|
||||||
|
return Ok(ApiResponse<ServiceTagsResponseDto>.Success(result));
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("{serviceCode}/ip/list")]
|
[HttpPost("{serviceCode}/ip/list")]
|
||||||
[SwaggerOperation(
|
[SwaggerOperation(
|
||||||
Summary = "IP 화이트리스트 조회",
|
Summary = "IP 화이트리스트 조회",
|
||||||
|
|
|
||||||
11
SPMS.Application/DTOs/Service/ServiceTagsRequestDto.cs
Normal file
11
SPMS.Application/DTOs/Service/ServiceTagsRequestDto.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace SPMS.Application.DTOs.Service;
|
||||||
|
|
||||||
|
public class ServiceTagsRequestDto
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "서비스 코드는 필수입니다.")]
|
||||||
|
[JsonPropertyName("service_code")]
|
||||||
|
public string ServiceCode { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
23
SPMS.Application/DTOs/Service/ServiceTagsResponseDto.cs
Normal file
23
SPMS.Application/DTOs/Service/ServiceTagsResponseDto.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace SPMS.Application.DTOs.Service;
|
||||||
|
|
||||||
|
public class ServiceTagsResponseDto
|
||||||
|
{
|
||||||
|
[JsonPropertyName("service_code")]
|
||||||
|
public string ServiceCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public List<TagItemDto> Tags { get; set; } = new();
|
||||||
|
|
||||||
|
[JsonPropertyName("total_count")]
|
||||||
|
public int TotalCount { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TagItemDto
|
||||||
|
{
|
||||||
|
[JsonPropertyName("tag_index")]
|
||||||
|
public int TagIndex { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("tag_name")]
|
||||||
|
public string TagName { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
15
SPMS.Application/DTOs/Service/UpdateServiceTagsRequestDto.cs
Normal file
15
SPMS.Application/DTOs/Service/UpdateServiceTagsRequestDto.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace SPMS.Application.DTOs.Service;
|
||||||
|
|
||||||
|
public class UpdateServiceTagsRequestDto
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "서비스 코드는 필수입니다.")]
|
||||||
|
[JsonPropertyName("service_code")]
|
||||||
|
public string ServiceCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "태그 목록은 필수입니다.")]
|
||||||
|
[MaxLength(10, ErrorMessage = "태그는 최대 10개까지 등록할 수 있습니다.")]
|
||||||
|
public List<string> Tags { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,10 @@ public interface IServiceManagementService
|
||||||
Task RegisterFcmCredentialsAsync(string serviceCode, FcmCredentialsRequestDto request);
|
Task RegisterFcmCredentialsAsync(string serviceCode, FcmCredentialsRequestDto request);
|
||||||
Task<CredentialsResponseDto> GetCredentialsAsync(string serviceCode);
|
Task<CredentialsResponseDto> GetCredentialsAsync(string serviceCode);
|
||||||
|
|
||||||
|
// Tags
|
||||||
|
Task<ServiceTagsResponseDto> GetTagsAsync(ServiceTagsRequestDto request);
|
||||||
|
Task<ServiceTagsResponseDto> UpdateTagsAsync(UpdateServiceTagsRequestDto request);
|
||||||
|
|
||||||
// IP Whitelist
|
// IP Whitelist
|
||||||
Task<IpListResponseDto> GetIpListAsync(string serviceCode);
|
Task<IpListResponseDto> GetIpListAsync(string serviceCode);
|
||||||
Task<ServiceIpDto> AddIpAsync(string serviceCode, AddIpRequestDto request);
|
Task<ServiceIpDto> AddIpAsync(string serviceCode, AddIpRequestDto request);
|
||||||
|
|
|
||||||
|
|
@ -454,6 +454,76 @@ public class ServiceManagementService : IServiceManagementService
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceTagsResponseDto> GetTagsAsync(ServiceTagsRequestDto request)
|
||||||
|
{
|
||||||
|
var service = await _serviceRepository.GetByServiceCodeAsync(request.ServiceCode);
|
||||||
|
if (service is null)
|
||||||
|
{
|
||||||
|
throw new SpmsException(
|
||||||
|
ErrorCodes.NotFound,
|
||||||
|
"서비스를 찾을 수 없습니다.",
|
||||||
|
404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BuildTagsResponse(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServiceTagsResponseDto> UpdateTagsAsync(UpdateServiceTagsRequestDto request)
|
||||||
|
{
|
||||||
|
var service = await _serviceRepository.GetByServiceCodeAsync(request.ServiceCode);
|
||||||
|
if (service is null)
|
||||||
|
{
|
||||||
|
throw new SpmsException(
|
||||||
|
ErrorCodes.NotFound,
|
||||||
|
"서비스를 찾을 수 없습니다.",
|
||||||
|
404);
|
||||||
|
}
|
||||||
|
|
||||||
|
var newTagsJson = JsonSerializer.Serialize(request.Tags);
|
||||||
|
if (newTagsJson == service.Tags)
|
||||||
|
{
|
||||||
|
throw new SpmsException(
|
||||||
|
ErrorCodes.NoChange,
|
||||||
|
"변경된 내용이 없습니다.",
|
||||||
|
400);
|
||||||
|
}
|
||||||
|
|
||||||
|
service.Tags = newTagsJson;
|
||||||
|
service.UpdatedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
_serviceRepository.Update(service);
|
||||||
|
await _unitOfWork.SaveChangesAsync();
|
||||||
|
|
||||||
|
return BuildTagsResponse(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ServiceTagsResponseDto BuildTagsResponse(Service service)
|
||||||
|
{
|
||||||
|
var tagNames = new List<string>();
|
||||||
|
if (!string.IsNullOrEmpty(service.Tags))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tagNames = JsonSerializer.Deserialize<List<string>>(service.Tags) ?? new List<string>();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Invalid JSON, return empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ServiceTagsResponseDto
|
||||||
|
{
|
||||||
|
ServiceCode = service.ServiceCode,
|
||||||
|
Tags = tagNames.Select((name, index) => new TagItemDto
|
||||||
|
{
|
||||||
|
TagIndex = index,
|
||||||
|
TagName = name
|
||||||
|
}).ToList(),
|
||||||
|
TotalCount = tagNames.Count
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IpListResponseDto> GetIpListAsync(string serviceCode)
|
public async Task<IpListResponseDto> GetIpListAsync(string serviceCode)
|
||||||
{
|
{
|
||||||
var service = await _serviceRepository.GetByServiceCodeWithIpsAsync(serviceCode);
|
var service = await _serviceRepository.GetByServiceCodeWithIpsAsync(serviceCode);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user