통계 추이 차트 원장 지표 보정

This commit is contained in:
2026-07-29 15:39:09 +09:00
parent 8a6963e8e1
commit 65924292b4
8 changed files with 67 additions and 11 deletions

View File

@@ -892,6 +892,48 @@ const getAllPostContentSessionScrollAggregate = async (sql, startDay, endDay) =>
return rows[0] || {}
}
/**
* 차트 버킷별 콘텐츠 세션 지표를 조회한다.
* @param {import('postgres').Sql} sql - DB 클라이언트
* @param {Array<Object>} trendRows - 차트 버킷 행
* @param {string} today - 오늘 날짜 키
* @returns {Promise<Map<string, Object>>} 버킷 키별 원장 지표
*/
const getTrendContentSessionMetricMap = async (sql, trendRows, today) => {
const metricMap = new Map()
for (const row of trendRows) {
const startDay = row.start_day ? new Date(row.start_day).toISOString().slice(0, 10) : ''
const endDay = row.end_day ? new Date(row.end_day).toISOString().slice(0, 10) : ''
if (!startDay || !endDay || !canUseContentSessionAggregateForRange(startDay, today)) {
continue
}
const siteRows = await getSiteContentSessionAggregate(sql, startDay, endDay)
const postRows = await getAllPostContentSessionScrollAggregate(sql, startDay, endDay)
const hasSiteRows = hasContentSessionAggregateRows(siteRows)
const hasPostRows = hasContentSessionAggregateRows(postRows)
if (!hasSiteRows && !hasPostRows) {
continue
}
const engagedViews = Number(siteRows?.engaged_views || 0)
const totalEngagedSeconds = Number(siteRows?.total_engaged_seconds || 0)
metricMap.set(`${startDay}:${endDay}`, {
avg_engaged_seconds: hasSiteRows && engagedViews > 0
? Math.round(totalEngagedSeconds / engagedViews)
: null,
post_views: hasPostRows ? Number(postRows?.views || 0) : null,
scroll_50: hasPostRows ? Number(postRows?.scroll_50 || 0) : null
})
}
return metricMap
}
/**
* 날짜 문자열이 통계 조회 형식인지 확인한다.
* @param {string} value - 날짜 문자열
@@ -1722,6 +1764,8 @@ export const getAnalyticsSummary = async (options = {}) => {
GROUP BY day, source_group
`
const trendContentMetricMap = await getTrendContentSessionMetricMap(sql, trendRows, today)
const engagedViews = Number(engagementRow?.engaged_views || 0)
const totalEngagedSeconds = Number(engagementRow?.total_engaged_seconds || 0)
const todayEngagedViews = Number(todayEngagementRow?.engaged_views || 0)
@@ -1783,13 +1827,17 @@ export const getAnalyticsSummary = async (options = {}) => {
trends: trendRows.map((row) => {
const startDay = row.start_day ? new Date(row.start_day).toISOString().slice(0, 10) : ''
const endDay = row.end_day ? new Date(row.end_day).toISOString().slice(0, 10) : ''
const contentMetric = trendContentMetricMap.get(`${startDay}:${endDay}`)
const trafficBreakdown = startDay && endDay
? aggregateTrafficBreakdownForRange(startDay, endDay)
: { trafficSearch: 0, trafficSns: 0, trafficOther: 0 }
const trendAvgEngagedSeconds = contentMetric?.avg_engaged_seconds ?? row.avg_engaged_seconds
const trendScroll50 = contentMetric?.scroll_50 ?? row.scroll_50
const trendPostViews = contentMetric?.post_views ?? row.post_views
const scroll50Reach = Math.min(
Number(row.scroll_50 || 0),
Number(row.post_views || 0)
Number(trendScroll50 || 0),
Number(trendPostViews || 0)
)
return {
@@ -1808,7 +1856,7 @@ export const getAnalyticsSummary = async (options = {}) => {
trafficSearch: trafficBreakdown.trafficSearch,
trafficSns: trafficBreakdown.trafficSns,
trafficOther: trafficBreakdown.trafficOther,
avgEngagedSeconds: Number(row.avg_engaged_seconds || 0),
avgEngagedSeconds: Number(trendAvgEngagedSeconds || 0),
scroll50Reach
}
}),