From afaeb6d116f402453226c6764fdf6ae028e26e98 Mon Sep 17 00:00:00 2001 From: SEAN Date: Wed, 25 Feb 2026 16:56:59 +0900 Subject: [PATCH] =?UTF-8?q?improvement:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EA=B8=B0=EA=B8=B0=20=EB=AA=A9=EB=A1=9D=20API=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=20(#237)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DeviceListRequestDto: keyword, marketing_agreed 필터 추가 - DeviceSummaryDto: 8개 응답 필드 추가 (device_token, service_name, service_code, os_version, app_version, marketing_agreed, is_active, created_at) - DeviceRepository: keyword/marketingAgreed 필터 + Include(Service) 추가 - DeviceService: 새 필터 전달 + 응답 매핑 확장 Closes #237 --- .../DTOs/Device/DeviceListRequestDto.cs | 6 +++++ .../DTOs/Device/DeviceListResponseDto.cs | 24 +++++++++++++++++++ SPMS.Application/Services/DeviceService.cs | 13 ++++++++-- SPMS.Domain/Interfaces/IDeviceRepository.cs | 3 ++- .../Repositories/DeviceRepository.cs | 18 ++++++++++++-- 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/SPMS.Application/DTOs/Device/DeviceListRequestDto.cs b/SPMS.Application/DTOs/Device/DeviceListRequestDto.cs index a4ee404..c61fd57 100644 --- a/SPMS.Application/DTOs/Device/DeviceListRequestDto.cs +++ b/SPMS.Application/DTOs/Device/DeviceListRequestDto.cs @@ -21,4 +21,10 @@ public class DeviceListRequestDto [JsonPropertyName("is_active")] public bool? IsActive { get; set; } + + [JsonPropertyName("keyword")] + public string? Keyword { get; set; } + + [JsonPropertyName("marketing_agreed")] + public bool? MarketingAgreed { get; set; } } diff --git a/SPMS.Application/DTOs/Device/DeviceListResponseDto.cs b/SPMS.Application/DTOs/Device/DeviceListResponseDto.cs index 6a85b3f..0d170ff 100644 --- a/SPMS.Application/DTOs/Device/DeviceListResponseDto.cs +++ b/SPMS.Application/DTOs/Device/DeviceListResponseDto.cs @@ -31,4 +31,28 @@ public class DeviceSummaryDto [JsonPropertyName("last_active_at")] public DateTime? LastActiveAt { get; set; } + + [JsonPropertyName("device_token")] + public string DeviceToken { get; set; } = string.Empty; + + [JsonPropertyName("service_name")] + public string ServiceName { get; set; } = string.Empty; + + [JsonPropertyName("service_code")] + public string ServiceCode { get; set; } = string.Empty; + + [JsonPropertyName("os_version")] + public string? OsVersion { get; set; } + + [JsonPropertyName("app_version")] + public string? AppVersion { get; set; } + + [JsonPropertyName("marketing_agreed")] + public bool MarketingAgreed { get; set; } + + [JsonPropertyName("is_active")] + public bool IsActive { get; set; } + + [JsonPropertyName("created_at")] + public DateTime CreatedAt { get; set; } } diff --git a/SPMS.Application/Services/DeviceService.cs b/SPMS.Application/Services/DeviceService.cs index afbfcd7..bde9344 100644 --- a/SPMS.Application/Services/DeviceService.cs +++ b/SPMS.Application/Services/DeviceService.cs @@ -127,7 +127,8 @@ public class DeviceService : IDeviceService var (items, totalCount) = await _deviceRepository.GetPagedAsync( serviceId, request.Page, request.Size, - platform, request.PushAgreed, request.IsActive, request.Tags); + platform, request.PushAgreed, request.IsActive, request.Tags, + request.Keyword, request.MarketingAgreed); var totalPages = (int)Math.Ceiling((double)totalCount / request.Size); @@ -140,7 +141,15 @@ public class DeviceService : IDeviceService Model = d.DeviceModel, PushAgreed = d.PushAgreed, Tags = ParseTags(d.Tags), - LastActiveAt = d.UpdatedAt + LastActiveAt = d.UpdatedAt, + DeviceToken = d.DeviceToken, + ServiceName = d.Service?.ServiceName ?? string.Empty, + ServiceCode = d.Service?.ServiceCode ?? string.Empty, + OsVersion = d.OsVersion, + AppVersion = d.AppVersion, + MarketingAgreed = d.MarketingAgreed, + IsActive = d.IsActive, + CreatedAt = d.CreatedAt }).ToList(), Pagination = new DTOs.Notice.PaginationDto { diff --git a/SPMS.Domain/Interfaces/IDeviceRepository.cs b/SPMS.Domain/Interfaces/IDeviceRepository.cs index 57a28e8..3b1a279 100644 --- a/SPMS.Domain/Interfaces/IDeviceRepository.cs +++ b/SPMS.Domain/Interfaces/IDeviceRepository.cs @@ -12,5 +12,6 @@ public interface IDeviceRepository : IRepository Task<(IReadOnlyList Items, int TotalCount)> GetPagedAsync( long? serviceId, int page, int size, Platform? platform = null, bool? pushAgreed = null, - bool? isActive = null, List? tags = null); + bool? isActive = null, List? tags = null, + string? keyword = null, bool? marketingAgreed = null); } diff --git a/SPMS.Infrastructure/Persistence/Repositories/DeviceRepository.cs b/SPMS.Infrastructure/Persistence/Repositories/DeviceRepository.cs index c8f1e13..ea7df13 100644 --- a/SPMS.Infrastructure/Persistence/Repositories/DeviceRepository.cs +++ b/SPMS.Infrastructure/Persistence/Repositories/DeviceRepository.cs @@ -34,9 +34,11 @@ public class DeviceRepository : Repository, IDeviceRepository public async Task<(IReadOnlyList Items, int TotalCount)> GetPagedAsync( long? serviceId, int page, int size, Platform? platform = null, bool? pushAgreed = null, - bool? isActive = null, List? tags = null) + bool? isActive = null, List? tags = null, + string? keyword = null, bool? marketingAgreed = null) { - IQueryable query = _dbSet; + IQueryable query = _dbSet.Include(d => d.Service); + if (serviceId.HasValue) query = query.Where(d => d.ServiceId == serviceId.Value); @@ -49,6 +51,18 @@ public class DeviceRepository : Repository, IDeviceRepository if (isActive.HasValue) query = query.Where(d => d.IsActive == isActive.Value); + if (marketingAgreed.HasValue) + query = query.Where(d => d.MarketingAgreed == marketingAgreed.Value); + + if (!string.IsNullOrWhiteSpace(keyword)) + { + var trimmed = keyword.Trim(); + if (long.TryParse(trimmed, out var deviceId)) + query = query.Where(d => d.Id == deviceId || d.DeviceToken.Contains(trimmed)); + else + query = query.Where(d => d.DeviceToken.Contains(trimmed)); + } + if (tags != null && tags.Count > 0) { foreach (var tag in tags)