diff --git a/internal/api/handler.go b/internal/api/handler.go index 339d4bc..09d99f3 100644 --- a/internal/api/handler.go +++ b/internal/api/handler.go @@ -58,15 +58,17 @@ func (h *Handler) CreateProvider(c *gin.Context) { } provider := model.Provider{ - Name: req.Name, - Type: req.Type, - BaseURL: req.BaseURL, - APIKey: req.APIKey, - Group: group, - Models: strings.Join(req.Models, ","), - Status: status, - AutoBan: autoBan, - BanReason: req.BanReason, + Name: req.Name, + Type: req.Type, + BaseURL: req.BaseURL, + APIKey: req.APIKey, + GoogleProject: strings.TrimSpace(req.GoogleProject), + GoogleLocation: strings.TrimSpace(req.GoogleLocation), + Group: group, + Models: strings.Join(req.Models, ","), + Status: status, + AutoBan: autoBan, + BanReason: req.BanReason, } if !req.BanUntil.IsZero() { tu := req.BanUntil.UTC() @@ -133,6 +135,12 @@ func (h *Handler) UpdateProvider(c *gin.Context) { if req.APIKey != "" { update["api_key"] = req.APIKey } + if strings.TrimSpace(req.GoogleProject) != "" { + update["google_project"] = strings.TrimSpace(req.GoogleProject) + } + if strings.TrimSpace(req.GoogleLocation) != "" { + update["google_location"] = strings.TrimSpace(req.GoogleLocation) + } if req.Models != nil { update["models"] = strings.Join(req.Models, ",") } diff --git a/internal/dto/provider.go b/internal/dto/provider.go index 45714ad..304a18f 100644 --- a/internal/dto/provider.go +++ b/internal/dto/provider.go @@ -4,16 +4,18 @@ import "time" // ProviderDTO defines inbound payload for provider creation/update. type ProviderDTO struct { - Name string `json:"name"` - Type string `json:"type"` - BaseURL string `json:"base_url"` - APIKey string `json:"api_key"` - Group string `json:"group"` - 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"` + Name string `json:"name"` + Type string `json:"type"` + BaseURL string `json:"base_url"` + APIKey string `json:"api_key"` + GoogleProject string `json:"google_project,omitempty"` + GoogleLocation string `json:"google_location,omitempty"` + Group string `json:"group"` + 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"` // Optional control params SkipRouting bool `json:"skip_routing,omitempty"` // if true, do not add to routing tables (e.g., disabled) diff --git a/internal/model/models.go b/internal/model/models.go index 4d0f7db..c8518a0 100644 --- a/internal/model/models.go +++ b/internal/model/models.go @@ -36,16 +36,18 @@ type Key struct { // Provider remains the same. type Provider struct { gorm.Model - Name string `gorm:"not null" json:"name"` - Type string `gorm:"not null" json:"type"` // openai, anthropic, etc. - BaseURL string `json:"base_url"` - APIKey string `json:"api_key"` - 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") - 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 + Name string `gorm:"not null" json:"name"` + Type string `gorm:"not null" json:"type"` // openai, anthropic, etc. + BaseURL string `json:"base_url"` + APIKey string `json:"api_key"` + GoogleProject string `gorm:"size:128" json:"google_project,omitempty"` + GoogleLocation string `gorm:"size:64" json:"google_location,omitempty"` + 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") + 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. diff --git a/internal/service/sync.go b/internal/service/sync.go index f718730..fa9a902 100644 --- a/internal/service/sync.go +++ b/internal/service/sync.go @@ -66,16 +66,18 @@ func (s *SyncService) SyncProvider(provider *model.Provider) error { models := strings.Split(provider.Models, ",") snap := providerSnapshot{ - ID: provider.ID, - Name: provider.Name, - Type: provider.Type, - BaseURL: provider.BaseURL, - APIKey: provider.APIKey, - Group: group, - Models: models, - Status: normalizeStatus(provider.Status), - AutoBan: provider.AutoBan, - BanReason: provider.BanReason, + ID: provider.ID, + Name: provider.Name, + Type: provider.Type, + BaseURL: provider.BaseURL, + APIKey: provider.APIKey, + GoogleProject: provider.GoogleProject, + GoogleLocation: provider.GoogleLocation, + Group: group, + Models: models, + Status: normalizeStatus(provider.Status), + AutoBan: provider.AutoBan, + BanReason: provider.BanReason, } if provider.BanUntil != nil { snap.BanUntil = provider.BanUntil.UTC().Unix() @@ -124,17 +126,19 @@ func (s *SyncService) SyncModel(m *model.Model) error { } type providerSnapshot struct { - ID uint `json:"id"` - Name string `json:"name"` - Type string `json:"type"` - BaseURL string `json:"base_url"` - APIKey string `json:"api_key"` - Group string `json:"group"` - 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 + ID uint `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + BaseURL string `json:"base_url"` + APIKey string `json:"api_key"` + GoogleProject string `json:"google_project,omitempty"` + GoogleLocation string `json:"google_location,omitempty"` + Group string `json:"group"` + 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:* @@ -198,16 +202,18 @@ func (s *SyncService) SyncAll(db *gorm.DB) error { models := strings.Split(p.Models, ",") snap := providerSnapshot{ - ID: p.ID, - Name: p.Name, - Type: p.Type, - BaseURL: p.BaseURL, - APIKey: p.APIKey, - Group: group, - Models: models, - Status: normalizeStatus(p.Status), - AutoBan: p.AutoBan, - BanReason: p.BanReason, + ID: p.ID, + Name: p.Name, + Type: p.Type, + BaseURL: p.BaseURL, + APIKey: p.APIKey, + GoogleProject: p.GoogleProject, + GoogleLocation: p.GoogleLocation, + Group: group, + Models: models, + Status: normalizeStatus(p.Status), + AutoBan: p.AutoBan, + BanReason: p.BanReason, } if p.BanUntil != nil { snap.BanUntil = p.BanUntil.UTC().Unix()