mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 11:02:54 +00:00
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:
@@ -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"`
|
||||
}
|
||||
Reference in New Issue
Block a user