improvement: 대시보드 KPI 변화량/변화율 필드 추가 (#262)
- DashboardKpiDto에 success_rate_change, device_count_change, today_sent_change_rate 필드 추가 - StatsService.GetDashboardAsync에 직전 기간 성공률 변화, 오늘 신규 디바이스 수, 발송 변화율 계산 로직 구현 Closes #262
This commit is contained in:
parent
b02910a213
commit
9dcdd56b2f
|
|
@ -46,6 +46,15 @@ public class DashboardKpiDto
|
|||
[JsonPropertyName("active_service_count")]
|
||||
public int ActiveServiceCount { get; set; }
|
||||
|
||||
[JsonPropertyName("success_rate_change")]
|
||||
public double SuccessRateChange { get; set; }
|
||||
|
||||
[JsonPropertyName("device_count_change")]
|
||||
public int DeviceCountChange { get; set; }
|
||||
|
||||
[JsonPropertyName("today_sent_change_rate")]
|
||||
public double TodaySentChangeRate { get; set; }
|
||||
|
||||
[JsonPropertyName("today")]
|
||||
public PeriodStatDto Today { get; set; } = new();
|
||||
|
||||
|
|
|
|||
|
|
@ -433,6 +433,44 @@ public class StatsService : IStatsService
|
|||
var activeServiceCount = await _serviceRepository.CountAsync(s => s.Status == ServiceStatus.Active && !s.IsDeleted);
|
||||
var topMessages = await _messageRepository.GetTopBySendCountAsync(serviceId, 5);
|
||||
|
||||
// KPI 변화량 계산
|
||||
var (startDate, endDate) = ParseDateRange(request.StartDate, request.EndDate);
|
||||
|
||||
// 1) success_rate_change: 직전 동일 기간 대비 성공률 변화 (pp)
|
||||
var duration = endDate.DayNumber - startDate.DayNumber + 1;
|
||||
var prevEnd = startDate.AddDays(-1);
|
||||
var prevStart = prevEnd.AddDays(-(duration - 1));
|
||||
var prevStats = await _dailyStatRepository.GetByDateRangeAsync(serviceId, prevStart, prevEnd);
|
||||
|
||||
var currentSend = daily.Summary.TotalSend;
|
||||
var currentSuccess = daily.Summary.TotalSuccess;
|
||||
var prevSend = prevStats.Sum(s => (long)s.SentCnt);
|
||||
var prevSuccess = prevStats.Sum(s => (long)s.SuccessCnt);
|
||||
|
||||
var currentRate = currentSend > 0 ? (double)currentSuccess / currentSend * 100 : 0;
|
||||
var prevRate = prevSend > 0 ? (double)prevSuccess / prevSend * 100 : 0;
|
||||
var successRateChange = prevSend > 0 ? Math.Round(currentRate - prevRate, 1) : 0;
|
||||
|
||||
// 2) device_count_change: 오늘 신규 등록 디바이스 수
|
||||
var todayDateTime = DateTime.UtcNow.Date;
|
||||
var tomorrowDateTime = todayDateTime.AddDays(1);
|
||||
var deviceCountChange = serviceId.HasValue
|
||||
? await _deviceRepository.CountAsync(d => d.ServiceId == serviceId.Value
|
||||
&& d.CreatedAt >= todayDateTime && d.CreatedAt < tomorrowDateTime)
|
||||
: await _deviceRepository.CountAsync(d =>
|
||||
d.CreatedAt >= todayDateTime && d.CreatedAt < tomorrowDateTime);
|
||||
|
||||
// 3) today_sent_change_rate: 오늘 vs 어제 발송 수 변화율 (%)
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var yesterday = today.AddDays(-1);
|
||||
var yesterdayStats = await _dailyStatRepository.GetByDateRangeAsync(serviceId, yesterday, yesterday);
|
||||
var yesterdaySent = yesterdayStats.Sum(s => s.SentCnt);
|
||||
var todaySent = summary.Today.SendCount;
|
||||
|
||||
var todaySentChangeRate = yesterdaySent > 0
|
||||
? Math.Round((double)(todaySent - yesterdaySent) / yesterdaySent * 100, 1)
|
||||
: 0;
|
||||
|
||||
return new DashboardResponseDto
|
||||
{
|
||||
Kpi = new DashboardKpiDto
|
||||
|
|
@ -445,6 +483,9 @@ public class StatsService : IStatsService
|
|||
TotalOpen = summary.TotalOpen,
|
||||
AvgCtr = summary.AvgCtr,
|
||||
ActiveServiceCount = activeServiceCount,
|
||||
SuccessRateChange = successRateChange,
|
||||
DeviceCountChange = deviceCountChange,
|
||||
TodaySentChangeRate = todaySentChangeRate,
|
||||
Today = summary.Today,
|
||||
ThisMonth = summary.ThisMonth
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user