mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-20 20:04:24 +00:00
- 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
170 lines
5.4 KiB
Go
170 lines
5.4 KiB
Go
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"`
|
|
}
|