feat: 디바이스 태그/동의 설정 API 구현 (#96)
All checks were successful
SPMS_API/pipeline/head This commit looks good

Reviewed-on: https://git.ipstein.myds.me/SPMS/SPMS_API/pulls/97
This commit is contained in:
김선규 2026-02-10 05:50:57 +00:00
commit 314df2e664
5 changed files with 81 additions and 0 deletions

View File

@ -55,6 +55,24 @@ public class DeviceController : ControllerBase
return Ok(ApiResponse.Success()); return Ok(ApiResponse.Success());
} }
[HttpPost("tags")]
[SwaggerOperation(Summary = "태그 설정", Description = "디바이스 태그를 설정합니다. 빈 배열 전달 시 모든 태그 해제.")]
public async Task<IActionResult> SetTagsAsync([FromBody] DeviceTagsRequestDto request)
{
var serviceId = GetServiceId();
await _deviceService.SetTagsAsync(serviceId, request);
return Ok(ApiResponse.Success());
}
[HttpPost("agree")]
[SwaggerOperation(Summary = "동의 설정", Description = "푸시/마케팅 수신 동의를 설정합니다.")]
public async Task<IActionResult> SetAgreeAsync([FromBody] DeviceAgreeRequestDto request)
{
var serviceId = GetServiceId();
await _deviceService.SetAgreeAsync(serviceId, request);
return Ok(ApiResponse.Success());
}
[HttpPost("list")] [HttpPost("list")]
[Authorize] [Authorize]
[SwaggerOperation(Summary = "디바이스 목록", Description = "대시보드에서 디바이스 목록을 조회합니다. JWT 인증 필요.")] [SwaggerOperation(Summary = "디바이스 목록", Description = "대시보드에서 디바이스 목록을 조회합니다. JWT 인증 필요.")]

View File

@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace SPMS.Application.DTOs.Device;
public class DeviceAgreeRequestDto
{
[Required]
[JsonPropertyName("device_id")]
public long DeviceId { get; set; }
[Required]
[JsonPropertyName("push_agreed")]
public bool PushAgreed { get; set; }
[Required]
[JsonPropertyName("marketing_agreed")]
public bool MarketingAgreed { get; set; }
}

View File

@ -0,0 +1,15 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace SPMS.Application.DTOs.Device;
public class DeviceTagsRequestDto
{
[Required]
[JsonPropertyName("device_id")]
public long DeviceId { get; set; }
[Required]
[JsonPropertyName("tags")]
public List<int> Tags { get; set; } = new();
}

View File

@ -9,4 +9,6 @@ public interface IDeviceService
Task UpdateAsync(long serviceId, DeviceUpdateRequestDto request); Task UpdateAsync(long serviceId, DeviceUpdateRequestDto request);
Task DeleteAsync(long serviceId, DeviceDeleteRequestDto request); Task DeleteAsync(long serviceId, DeviceDeleteRequestDto request);
Task<DeviceListResponseDto> GetListAsync(long serviceId, DeviceListRequestDto request); Task<DeviceListResponseDto> GetListAsync(long serviceId, DeviceListRequestDto request);
Task SetTagsAsync(long serviceId, DeviceTagsRequestDto request);
Task SetAgreeAsync(long serviceId, DeviceAgreeRequestDto request);
} }

View File

@ -144,6 +144,33 @@ public class DeviceService : IDeviceService
}; };
} }
public async Task SetTagsAsync(long serviceId, DeviceTagsRequestDto request)
{
var device = await _deviceRepository.GetByIdAndServiceAsync(request.DeviceId, serviceId);
if (device == null)
throw new SpmsException(ErrorCodes.DeviceNotFound, "존재하지 않는 디바이스입니다.", 404);
device.Tags = JsonSerializer.Serialize(request.Tags);
device.UpdatedAt = DateTime.UtcNow;
_deviceRepository.Update(device);
await _unitOfWork.SaveChangesAsync();
}
public async Task SetAgreeAsync(long serviceId, DeviceAgreeRequestDto request)
{
var device = await _deviceRepository.GetByIdAndServiceAsync(request.DeviceId, serviceId);
if (device == null)
throw new SpmsException(ErrorCodes.DeviceNotFound, "존재하지 않는 디바이스입니다.", 404);
device.PushAgreed = request.PushAgreed;
device.MarketingAgreed = request.MarketingAgreed;
device.AgreeUpdatedAt = DateTime.UtcNow;
if (request.MarketingAgreed != device.MarketingAgreed)
device.MktAgreeUpdatedAt = DateTime.UtcNow;
_deviceRepository.Update(device);
await _unitOfWork.SaveChangesAsync();
}
private static Platform ParsePlatform(string platform) private static Platform ParsePlatform(string platform)
{ {
return platform.ToLowerInvariant() switch return platform.ToLowerInvariant() switch