feat: Add analytics handler with churn prediction, market metrics, and analytics types

- Add AnalyticsHandler with NewAnalyticsHandler constructor
- Add PredictChurn endpoint returning risk level, score, predicted date, reasons, and recommendations
- Add GetAtRiskCustomers with risk level filtering and configurable limit (max 1000)
- Add GetMarketMetrics returning market size, subscribers, share, growth rate, and country breakdown
- Add ChurnPrediction struct with ProfileID, RiskLevel, RiskScore
This commit is contained in:
nutcas3
2026-05-03 13:25:31 +03:00
parent 2c6643e228
commit d011945ec2
@@ -0,0 +1,169 @@
package handlers
import (
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
// AnalyticsHandler handles analytics-related HTTP requests
type AnalyticsHandler struct{}
// NewAnalyticsHandler creates a new analytics handler
func NewAnalyticsHandler() *AnalyticsHandler {
return &AnalyticsHandler{}
}
// ChurnPrediction represents a churn prediction response
type ChurnPrediction struct {
ProfileID string `json:"profile_id"`
RiskLevel string `json:"risk_level"`
RiskScore float64 `json:"risk_score"`
PredictedChurnDate string `json:"predicted_churn_date,omitempty"`
Reasons []string `json:"reasons"`
Recommendations []string `json:"recommendations"`
LastUpdated time.Time `json:"last_updated"`
}
// ChurnMetrics represents churn metrics
type ChurnMetrics struct {
Period string `json:"period"`
TotalSubscribers int64 `json:"total_subscribers"`
ChurnedSubscribers int64 `json:"churned_subscribers"`
ChurnRate float64 `json:"churn_rate_pct"`
MonthlyChurnRate float64 `json:"monthly_churn_rate_pct"`
AnnualChurnRate float64 `json:"annual_churn_rate_pct"`
AverageTenureDays float64 `json:"average_tenure_days"`
RiskDistribution map[string]int64 `json:"risk_distribution"`
GeneratedAt time.Time `json:"generated_at"`
}
// PredictChurn predicts churn for a profile
func (h *AnalyticsHandler) PredictChurn(c *gin.Context) {
var req struct {
ProfileID string `json:"profile_id" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Simulated churn prediction
prediction := ChurnPrediction{
ProfileID: req.ProfileID,
RiskLevel: "medium",
RiskScore: 45.5,
PredictedChurnDate: time.Now().AddDate(0, 2, 0).Format("2006-01-02"),
Reasons: []string{
"Decreased usage over last 30 days",
"No recent plan upgrades",
"Support tickets increased",
},
Recommendations: []string{
"Offer loyalty discount",
"Proactive customer outreach",
"Personalized plan recommendation",
},
LastUpdated: time.Now(),
}
c.JSON(http.StatusOK, prediction)
}
// GetAtRiskCustomers returns customers at risk of churning
func (h *AnalyticsHandler) GetAtRiskCustomers(c *gin.Context) {
riskLevel := c.DefaultQuery("risk_level", "high")
limitStr := c.DefaultQuery("limit", "100")
limit, _ := strconv.Atoi(limitStr)
if limit > 1000 {
limit = 1000
}
// Simulated at-risk customers
customers := make([]ChurnPrediction, 0)
for i := 0; i < min(limit, 10); i++ {
customers = append(customers, ChurnPrediction{
ProfileID: "profile-" + strconv.Itoa(i+1),
RiskLevel: riskLevel,
RiskScore: 70.0 + float64(i)*2,
PredictedChurnDate: time.Now().AddDate(0, 0, 30+i*7).Format("2006-01-02"),
Reasons: []string{"Low engagement", "Billing issues"},
Recommendations: []string{"Retention offer", "Account review"},
LastUpdated: time.Now(),
})
}
c.JSON(http.StatusOK, customers)
}
// MarketMetrics represents market analytics
type MarketMetrics struct {
Period string `json:"period"`
TotalMarketSize int64 `json:"total_market_size"`
OurSubscribers int64 `json:"our_subscribers"`
MarketShare float64 `json:"market_share_pct"`
GrowthRate float64 `json:"growth_rate_pct"`
ByCountry map[string]any `json:"by_country"`
GeneratedAt time.Time `json:"generated_at"`
}
// GetMarketMetrics returns market penetration metrics
func (h *AnalyticsHandler) GetMarketMetrics(c *gin.Context) {
period := c.DefaultQuery("period", "monthly")
metrics := MarketMetrics{
Period: period,
TotalMarketSize: 5500000000, // Global mobile subscribers ~5.5B
OurSubscribers: 150000,
MarketShare: 0.0027,
GrowthRate: 12.5,
ByCountry: map[string]any{
"US": map[string]any{
"market_size": 330000000,
"our_subs": 45000,
"penetration": 0.014,
"growth_rate": 8.5,
},
"UK": map[string]any{
"market_size": 67000000,
"our_subs": 25000,
"penetration": 0.037,
"growth_rate": 15.2,
},
"DE": map[string]any{
"market_size": 83000000,
"our_subs": 30000,
"penetration": 0.036,
"growth_rate": 11.8,
},
},
GeneratedAt: time.Now(),
}
c.JSON(http.StatusOK, metrics)
}
// MaintenanceMetrics represents predictive maintenance metrics
type MaintenanceMetrics struct {
Period string `json:"period"`
TotalAssets int64 `json:"total_assets"`
HealthyAssets int64 `json:"healthy_assets"`
AssetsNeedingAttention int64 `json:"assets_needing_attention"`
Uptime float64 `json:"uptime_pct"`
MeanTimeToFailure float64 `json:"mean_time_to_failure_hours"`
MeanTimeToRepair float64 `json:"mean_time_to_repair_hours"`
GeneratedAt time.Time `json:"generated_at"`
}
// PricingMetrics represents pricing optimization metrics
type PricingMetrics struct {
Period string `json:"period"`
TotalRevenue float64 `json:"total_revenue"`
ARPU float64 `json:"arpu"`
PriceElasticity float64 `json:"price_elasticity"`
CompetitiveIndex float64 `json:"competitive_index"`
OptimizationROI float64 `json:"optimization_roi_pct"`
GeneratedAt time.Time `json:"generated_at"`
}