improvement: 서비스 목록/상세 응답에 플랫폼 상태 판정 추가 (#216)
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/217
This commit is contained in:
commit
044ebc17d0
|
|
@ -103,7 +103,7 @@ public class ServiceController : ControllerBase
|
|||
[HttpPost("list")]
|
||||
[SwaggerOperation(
|
||||
Summary = "서비스 목록 조회",
|
||||
Description = "등록된 서비스 목록을 조회합니다. 페이징, 검색, 상태 필터를 지원합니다.")]
|
||||
Description = "등록된 서비스 목록을 조회합니다. 페이징, 검색, 상태 필터를 지원합니다. 각 항목에 platforms 필드로 Android/iOS 자격증명 상태(credentialStatus: ok/warn/error)를 포함합니다.")]
|
||||
[SwaggerResponse(200, "조회 성공", typeof(ApiResponse<ServiceListResponseDto>))]
|
||||
[SwaggerResponse(401, "인증되지 않은 요청")]
|
||||
[SwaggerResponse(403, "권한 없음")]
|
||||
|
|
@ -116,7 +116,7 @@ public class ServiceController : ControllerBase
|
|||
[HttpPost("{serviceCode}")]
|
||||
[SwaggerOperation(
|
||||
Summary = "서비스 상세 조회",
|
||||
Description = "특정 서비스의 상세 정보를 조회합니다.")]
|
||||
Description = "특정 서비스의 상세 정보를 조회합니다. apnsAuthType(p8/p12)과 platforms 필드로 각 플랫폼의 자격증명 상태(credentialStatus: ok/warn/error), 만료일(expiresAt) 정보를 포함합니다.")]
|
||||
[SwaggerResponse(200, "조회 성공", typeof(ApiResponse<ServiceResponseDto>))]
|
||||
[SwaggerResponse(401, "인증되지 않은 요청")]
|
||||
[SwaggerResponse(403, "권한 없음")]
|
||||
|
|
|
|||
33
SPMS.Application/DTOs/Service/PlatformSummaryDto.cs
Normal file
33
SPMS.Application/DTOs/Service/PlatformSummaryDto.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
namespace SPMS.Application.DTOs.Service;
|
||||
|
||||
/// <summary>
|
||||
/// 서비스의 플랫폼(Android/iOS) 자격증명 상태 요약
|
||||
/// </summary>
|
||||
public class PlatformSummaryDto
|
||||
{
|
||||
public PlatformCredentialSummaryDto? Android { get; set; }
|
||||
public PlatformCredentialSummaryDto? Ios { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 개별 플랫폼 자격증명 상태
|
||||
/// </summary>
|
||||
public class PlatformCredentialSummaryDto
|
||||
{
|
||||
public bool Registered { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 자격증명 상태: ok | warn | error | none
|
||||
/// </summary>
|
||||
public string CredentialStatus { get; set; } = "none";
|
||||
|
||||
/// <summary>
|
||||
/// 상태 사유 (warn/error 시 표시)
|
||||
/// </summary>
|
||||
public string? StatusReason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// p12 인증서 만료일 (p12 타입만 해당)
|
||||
/// </summary>
|
||||
public DateTime? ExpiresAt { get; set; }
|
||||
}
|
||||
|
|
@ -18,4 +18,5 @@ public class ServiceSummaryDto
|
|||
public string Status { get; set; } = string.Empty;
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public int DeviceCount { get; set; }
|
||||
public PlatformSummaryDto? Platforms { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ public class ServiceResponseDto
|
|||
public string? ApnsBundleId { get; set; }
|
||||
public string? ApnsKeyId { get; set; }
|
||||
public string? ApnsTeamId { get; set; }
|
||||
public string? ApnsAuthType { get; set; }
|
||||
public bool HasApnsKey { get; set; }
|
||||
public bool HasFcmCredentials { get; set; }
|
||||
public PlatformSummaryDto? Platforms { get; set; }
|
||||
public string? WebhookUrl { get; set; }
|
||||
public string? Tags { get; set; }
|
||||
public string SubTier { get; set; } = string.Empty;
|
||||
|
|
|
|||
|
|
@ -886,7 +886,8 @@ public class ServiceManagementService : IServiceManagementService
|
|||
SubTier = service.SubTier.ToString(),
|
||||
Status = service.Status.ToString(),
|
||||
CreatedAt = service.CreatedAt,
|
||||
DeviceCount = service.Devices?.Count ?? 0
|
||||
DeviceCount = service.Devices?.Count ?? 0,
|
||||
Platforms = BuildPlatformSummary(service)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -902,8 +903,10 @@ public class ServiceManagementService : IServiceManagementService
|
|||
ApnsBundleId = service.ApnsBundleId,
|
||||
ApnsKeyId = service.ApnsKeyId,
|
||||
ApnsTeamId = service.ApnsTeamId,
|
||||
ApnsAuthType = service.ApnsAuthType,
|
||||
HasApnsKey = !string.IsNullOrEmpty(service.ApnsPrivateKey),
|
||||
HasFcmCredentials = !string.IsNullOrEmpty(service.FcmCredentials),
|
||||
Platforms = BuildPlatformSummary(service),
|
||||
WebhookUrl = service.WebhookUrl,
|
||||
Tags = service.Tags,
|
||||
SubTier = service.SubTier.ToString(),
|
||||
|
|
@ -916,4 +919,87 @@ public class ServiceManagementService : IServiceManagementService
|
|||
AllowedIps = service.ServiceIps?.Select(ip => ip.IpAddress).ToList() ?? new List<string>()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 서비스의 플랫폼 자격증명 상태를 판정하여 PlatformSummaryDto를 반환합니다.
|
||||
/// Android: FcmCredentials 유무로 판정
|
||||
/// iOS: ApnsAuthType(p8/p12)에 따라 만료 상태 포함 판정
|
||||
/// </summary>
|
||||
private static PlatformSummaryDto? BuildPlatformSummary(Service service)
|
||||
{
|
||||
var android = BuildAndroidSummary(service);
|
||||
var ios = BuildIosSummary(service);
|
||||
|
||||
// 양쪽 다 null이면 null 반환
|
||||
if (android == null && ios == null)
|
||||
return null;
|
||||
|
||||
return new PlatformSummaryDto
|
||||
{
|
||||
Android = android,
|
||||
Ios = ios
|
||||
};
|
||||
}
|
||||
|
||||
private static PlatformCredentialSummaryDto? BuildAndroidSummary(Service service)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.FcmCredentials))
|
||||
return null;
|
||||
|
||||
return new PlatformCredentialSummaryDto
|
||||
{
|
||||
Registered = true,
|
||||
CredentialStatus = "ok"
|
||||
};
|
||||
}
|
||||
|
||||
private static PlatformCredentialSummaryDto? BuildIosSummary(Service service)
|
||||
{
|
||||
// APNs 미등록
|
||||
if (string.IsNullOrEmpty(service.ApnsBundleId))
|
||||
return null;
|
||||
|
||||
var summary = new PlatformCredentialSummaryDto
|
||||
{
|
||||
Registered = true
|
||||
};
|
||||
|
||||
if (service.ApnsAuthType == "p12")
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
if (service.ApnsCertExpiresAt.HasValue)
|
||||
{
|
||||
if (service.ApnsCertExpiresAt.Value < now)
|
||||
{
|
||||
summary.CredentialStatus = "error";
|
||||
summary.StatusReason = "p12 인증서가 만료되었습니다.";
|
||||
}
|
||||
else if (service.ApnsCertExpiresAt.Value < now.AddDays(30))
|
||||
{
|
||||
summary.CredentialStatus = "warn";
|
||||
summary.StatusReason = "p12 인증서 만료가 30일 이내입니다.";
|
||||
}
|
||||
else
|
||||
{
|
||||
summary.CredentialStatus = "ok";
|
||||
}
|
||||
|
||||
summary.ExpiresAt = service.ApnsCertExpiresAt;
|
||||
}
|
||||
else
|
||||
{
|
||||
// p12인데 만료일 정보 없음 (비정상)
|
||||
summary.CredentialStatus = "warn";
|
||||
summary.StatusReason = "p12 인증서 만료일 정보가 없습니다.";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// p8 또는 레거시(AuthType null + PrivateKey 존재)
|
||||
summary.CredentialStatus = "ok";
|
||||
}
|
||||
|
||||
return summary;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user