mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 19:44:12 +00:00
Add analytics helper functions (calculateComparison, calculateTrends, calculateROI) and extend the analytics API route with three new tabs for video metric comparison, trend analysis, and ROI calculation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
123 lines
2.7 KiB
TypeScript
123 lines
2.7 KiB
TypeScript
/**
|
|
* YouTube Analytics Helper Functions
|
|
*
|
|
* Provides calculation utilities for video comparison, trend analysis,
|
|
* and ROI metrics used by the analytics API route.
|
|
*/
|
|
|
|
interface VideoWithPerformance {
|
|
id: number
|
|
title: string
|
|
performance: {
|
|
views?: number
|
|
likes?: number
|
|
comments?: number
|
|
ctr?: number
|
|
watchTimeMinutes?: number
|
|
impressions?: number
|
|
subscribersGained?: number
|
|
avgViewPercentage?: number
|
|
}
|
|
costs?: {
|
|
estimatedProductionCost?: number
|
|
estimatedProductionHours?: number
|
|
estimatedRevenue?: number
|
|
}
|
|
}
|
|
|
|
type Metric =
|
|
| 'views'
|
|
| 'likes'
|
|
| 'comments'
|
|
| 'ctr'
|
|
| 'watchTimeMinutes'
|
|
| 'impressions'
|
|
| 'subscribersGained'
|
|
|
|
function getMetricValue(video: VideoWithPerformance, metric: Metric): number {
|
|
return video.performance?.[metric] ?? 0
|
|
}
|
|
|
|
function calculateComparison(
|
|
videos: VideoWithPerformance[],
|
|
metric: Metric,
|
|
): Array<{ videoId: number; title: string; value: number }> {
|
|
return videos.map((v) => ({
|
|
videoId: v.id,
|
|
title: v.title,
|
|
value: getMetricValue(v, metric),
|
|
}))
|
|
}
|
|
|
|
function calculateTrends(
|
|
videos: VideoWithPerformance[],
|
|
metric: Metric,
|
|
): {
|
|
trend: string
|
|
growth: number
|
|
average?: number
|
|
latest?: number
|
|
min?: number
|
|
max?: number
|
|
} {
|
|
if (videos.length < 2) {
|
|
return { trend: 'insufficient_data', growth: 0 }
|
|
}
|
|
|
|
const values = videos
|
|
.map((v) => getMetricValue(v, metric))
|
|
.sort((a, b) => a - b)
|
|
|
|
const avg = values.reduce((sum, v) => sum + v, 0) / values.length
|
|
const latest = values[values.length - 1]
|
|
const min = values[0]
|
|
const max = values[values.length - 1]
|
|
|
|
let trend: string
|
|
if (latest > avg) {
|
|
trend = 'up'
|
|
} else if (latest < avg) {
|
|
trend = 'down'
|
|
} else {
|
|
trend = 'stable'
|
|
}
|
|
|
|
const growth = avg > 0 ? ((latest - avg) / avg) * 100 : 0
|
|
|
|
return { trend, average: avg, latest, growth, min, max }
|
|
}
|
|
|
|
function calculateROI(
|
|
videos: VideoWithPerformance[],
|
|
): Array<{
|
|
videoId: number
|
|
title: string
|
|
cost: number
|
|
revenue: number
|
|
roi: number
|
|
cpv: number
|
|
revenuePerView: number
|
|
views: number
|
|
}> {
|
|
return videos
|
|
.filter((v) => v.costs?.estimatedProductionCost && v.costs.estimatedProductionCost > 0)
|
|
.map((v) => {
|
|
const cost = v.costs!.estimatedProductionCost!
|
|
const revenue = v.costs?.estimatedRevenue ?? 0
|
|
const views = v.performance?.views ?? 0
|
|
|
|
return {
|
|
videoId: v.id,
|
|
title: v.title,
|
|
cost,
|
|
revenue,
|
|
roi: cost > 0 ? ((revenue - cost) / cost) * 100 : 0,
|
|
cpv: views > 0 ? cost / views : 0,
|
|
revenuePerView: views > 0 ? revenue / views : 0,
|
|
views,
|
|
}
|
|
})
|
|
}
|
|
|
|
export { calculateComparison, calculateTrends, calculateROI }
|
|
export type { VideoWithPerformance, Metric }
|