mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
feat(provider): add status and banning mechanism
Introduce fields for managing provider status (active, auto_disabled, manual_disabled) and banning logic. - Add Status, AutoBan, BanReason, and BanUntil to Provider model and DTO - Update CreateProvider handler to process new fields with defaults - Extend sync service to propagate status and ban information in snapshots - Serialize BanUntil as Unix timestamp for sync compatibility
This commit is contained in:
@@ -48,6 +48,15 @@ func (h *Handler) CreateProvider(c *gin.Context) {
|
|||||||
group = "default"
|
group = "default"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status := strings.TrimSpace(req.Status)
|
||||||
|
if status == "" {
|
||||||
|
status = "active"
|
||||||
|
}
|
||||||
|
autoBan := true
|
||||||
|
if req.AutoBan != nil {
|
||||||
|
autoBan = *req.AutoBan
|
||||||
|
}
|
||||||
|
|
||||||
provider := model.Provider{
|
provider := model.Provider{
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
Type: req.Type,
|
Type: req.Type,
|
||||||
@@ -55,6 +64,13 @@ func (h *Handler) CreateProvider(c *gin.Context) {
|
|||||||
APIKey: req.APIKey,
|
APIKey: req.APIKey,
|
||||||
Group: group,
|
Group: group,
|
||||||
Models: strings.Join(req.Models, ","),
|
Models: strings.Join(req.Models, ","),
|
||||||
|
Status: status,
|
||||||
|
AutoBan: autoBan,
|
||||||
|
BanReason: req.BanReason,
|
||||||
|
}
|
||||||
|
if !req.BanUntil.IsZero() {
|
||||||
|
tu := req.BanUntil.UTC()
|
||||||
|
provider.BanUntil = &tu
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.db.Create(&provider).Error; err != nil {
|
if err := h.db.Create(&provider).Error; err != nil {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package dto
|
package dto
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
// ProviderDTO defines inbound payload for provider creation/update.
|
// ProviderDTO defines inbound payload for provider creation/update.
|
||||||
type ProviderDTO struct {
|
type ProviderDTO struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
@@ -8,4 +10,8 @@ type ProviderDTO struct {
|
|||||||
APIKey string `json:"api_key"`
|
APIKey string `json:"api_key"`
|
||||||
Group string `json:"group"`
|
Group string `json:"group"`
|
||||||
Models []string `json:"models"` // List of supported model names
|
Models []string `json:"models"` // List of supported model names
|
||||||
|
Status string `json:"status"`
|
||||||
|
AutoBan *bool `json:"auto_ban,omitempty"`
|
||||||
|
BanReason string `json:"ban_reason,omitempty"`
|
||||||
|
BanUntil time.Time `json:"ban_until,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,6 +42,10 @@ type Provider struct {
|
|||||||
APIKey string `json:"api_key"`
|
APIKey string `json:"api_key"`
|
||||||
Group string `gorm:"default:'default'" json:"group"` // routing group/tier
|
Group string `gorm:"default:'default'" json:"group"` // routing group/tier
|
||||||
Models string `json:"models"` // comma-separated list of supported models (e.g. "gpt-4,gpt-3.5-turbo")
|
Models string `json:"models"` // comma-separated list of supported models (e.g. "gpt-4,gpt-3.5-turbo")
|
||||||
|
Status string `gorm:"size:50;default:'active'" json:"status"` // active, auto_disabled, manual_disabled
|
||||||
|
AutoBan bool `gorm:"default:true" json:"auto_ban"` // whether DP-triggered disable is allowed
|
||||||
|
BanReason string `gorm:"size:255" json:"ban_reason"` // reason for current disable
|
||||||
|
BanUntil *time.Time `json:"ban_until"` // optional TTL for disable
|
||||||
}
|
}
|
||||||
|
|
||||||
// Model remains the same.
|
// Model remains the same.
|
||||||
|
|||||||
@@ -72,6 +72,12 @@ func (s *SyncService) SyncProvider(provider *model.Provider) error {
|
|||||||
APIKey: provider.APIKey,
|
APIKey: provider.APIKey,
|
||||||
Group: group,
|
Group: group,
|
||||||
Models: models,
|
Models: models,
|
||||||
|
Status: normalizeStatus(provider.Status),
|
||||||
|
AutoBan: provider.AutoBan,
|
||||||
|
BanReason: provider.BanReason,
|
||||||
|
}
|
||||||
|
if provider.BanUntil != nil {
|
||||||
|
snap.BanUntil = provider.BanUntil.UTC().Unix()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Update Provider Config
|
// 1. Update Provider Config
|
||||||
@@ -118,6 +124,10 @@ type providerSnapshot struct {
|
|||||||
APIKey string `json:"api_key"`
|
APIKey string `json:"api_key"`
|
||||||
Group string `json:"group"`
|
Group string `json:"group"`
|
||||||
Models []string `json:"models"`
|
Models []string `json:"models"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
AutoBan bool `json:"auto_ban"`
|
||||||
|
BanReason string `json:"ban_reason,omitempty"`
|
||||||
|
BanUntil int64 `json:"ban_until,omitempty"` // unix seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
// keySnapshot is no longer needed as we write directly to auth:token:*
|
// keySnapshot is no longer needed as we write directly to auth:token:*
|
||||||
@@ -188,6 +198,12 @@ func (s *SyncService) SyncAll(db *gorm.DB) error {
|
|||||||
APIKey: p.APIKey,
|
APIKey: p.APIKey,
|
||||||
Group: group,
|
Group: group,
|
||||||
Models: models,
|
Models: models,
|
||||||
|
Status: normalizeStatus(p.Status),
|
||||||
|
AutoBan: p.AutoBan,
|
||||||
|
BanReason: p.BanReason,
|
||||||
|
}
|
||||||
|
if p.BanUntil != nil {
|
||||||
|
snap.BanUntil = p.BanUntil.UTC().Unix()
|
||||||
}
|
}
|
||||||
payload, err := sonic.Marshal(snap)
|
payload, err := sonic.Marshal(snap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -273,3 +289,16 @@ func normalizeGroup(group string) string {
|
|||||||
}
|
}
|
||||||
return group
|
return group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func normalizeStatus(status string) string {
|
||||||
|
st := strings.ToLower(strings.TrimSpace(status))
|
||||||
|
if st == "" {
|
||||||
|
return "active"
|
||||||
|
}
|
||||||
|
switch st {
|
||||||
|
case "active", "auto_disabled", "manual_disabled":
|
||||||
|
return st
|
||||||
|
default:
|
||||||
|
return st
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user