61b39d49bd
- Implemented `/v0/management/usage` endpoint for fetching queued usage records from Redis. - Included validation for `count` parameter to ensure positive integers. - Added unit tests for queue retrieval and validation, with authentication validation in integration tests. - Updated management routing to include the new endpoint.
56 lines
1.3 KiB
Go
56 lines
1.3 KiB
Go
package management
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/router-for-me/CLIProxyAPI/v6/internal/redisqueue"
|
|
)
|
|
|
|
type usageQueueRecord []byte
|
|
|
|
func (r usageQueueRecord) MarshalJSON() ([]byte, error) {
|
|
if json.Valid(r) {
|
|
return append([]byte(nil), r...), nil
|
|
}
|
|
return json.Marshal(string(r))
|
|
}
|
|
|
|
// GetUsage pops queued usage records from the Redis-compatible usage queue.
|
|
func (h *Handler) GetUsage(c *gin.Context) {
|
|
if h == nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "handler unavailable"})
|
|
return
|
|
}
|
|
|
|
count, errCount := parseUsageQueueCount(c.Query("count"))
|
|
if errCount != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": errCount.Error()})
|
|
return
|
|
}
|
|
|
|
items := redisqueue.PopOldest(count)
|
|
records := make([]usageQueueRecord, 0, len(items))
|
|
for _, item := range items {
|
|
records = append(records, usageQueueRecord(append([]byte(nil), item...)))
|
|
}
|
|
|
|
c.JSON(http.StatusOK, records)
|
|
}
|
|
|
|
func parseUsageQueueCount(value string) (int, error) {
|
|
value = strings.TrimSpace(value)
|
|
if value == "" {
|
|
return 1, nil
|
|
}
|
|
count, errCount := strconv.Atoi(value)
|
|
if errCount != nil || count <= 0 {
|
|
return 0, errors.New("count must be a positive integer")
|
|
}
|
|
return count, nil
|
|
}
|