Files
telecom-platform/apps/api-server/internal/handlers/charging_handler.go
T
nutcas3 6d0c0ced1b feat: Add charging handler with credit management endpoints for IP-based operations
- Add ChargingHandler struct with ChargingEngineClient dependency
- Add NewChargingHandler constructor
- Add CheckCredit endpoint to validate sufficient credit for requested bytes
- Add GetBalance endpoint to retrieve current balance for an IP
- Add AddCredit endpoint to add bytes to an IP's credit
- Add DeductCredit endpoint to deduct bytes from an IP's credit
- Add IP parameter validation and JSON request binding
2026-04-25 03:28:51 +03:00

113 lines
2.8 KiB
Go

package handlers
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/nutcas3/telecom-platform/apps/api-server/internal/services"
)
// ChargingHandler handles charging engine integration
type ChargingHandler struct {
engineClient *services.ChargingEngineClient
}
// NewChargingHandler creates a new charging handler
func NewChargingHandler(engineClient *services.ChargingEngineClient) *ChargingHandler {
return &ChargingHandler{
engineClient: engineClient,
}
}
// CheckCredit checks if an IP has sufficient credit
func (h *ChargingHandler) CheckCredit(c *gin.Context) {
ip := c.Param("ip")
if ip == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "IP address is required"})
return
}
var req struct {
BytesRequested uint64 `json:"bytes_requested" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
result, err := h.engineClient.CheckCredit(c.Request.Context(), ip, req.BytesRequested)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, result)
}
// GetBalance gets the current balance for an IP
func (h *ChargingHandler) GetBalance(c *gin.Context) {
ip := c.Param("ip")
if ip == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "IP address is required"})
return
}
result, err := h.engineClient.GetBalance(c.Request.Context(), ip)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, result)
}
// AddCredit adds credit to an IP
func (h *ChargingHandler) AddCredit(c *gin.Context) {
ip := c.Param("ip")
if ip == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "IP address is required"})
return
}
var req struct {
BytesToAdd uint64 `json:"bytes_to_add" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err := h.engineClient.AddCredit(c.Request.Context(), ip, req.BytesToAdd)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "success"})
}
// DeductCredit deducts credit from an IP
func (h *ChargingHandler) DeductCredit(c *gin.Context) {
ip := c.Param("ip")
if ip == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "IP address is required"})
return
}
var req struct {
BytesUsed uint64 `json:"bytes_used" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err := h.engineClient.DeductCredit(c.Request.Context(), ip, req.BytesUsed)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "success"})
}