Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
4cce21b1
Unverified
Commit
4cce21b1
authored
Feb 03, 2026
by
Wesley Liddick
Committed by
GitHub
Feb 03, 2026
Browse files
Merge branch 'main' into main
parents
0707f3d9
c0c9c984
Changes
52
Hide whitespace changes
Inline
Side-by-side
backend/Dockerfile
View file @
4cce21b1
FROM
golang:1.25.
5
-alpine
FROM
golang:1.25.
6
-alpine
WORKDIR
/app
WORKDIR
/app
...
@@ -15,7 +15,7 @@ RUN go mod download
...
@@ -15,7 +15,7 @@ RUN go mod download
COPY
. .
COPY
. .
# 构建应用
# 构建应用
RUN
go build
-o
main cmd/server/
main.go
RUN
go build
-o
main
./
cmd/server/
# 暴露端口
# 暴露端口
EXPOSE
8080
EXPOSE
8080
...
...
backend/cmd/server/wire_gen.go
View file @
4cce21b1
...
@@ -173,8 +173,8 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
...
@@ -173,8 +173,8 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
userAttributeService
:=
service
.
NewUserAttributeService
(
userAttributeDefinitionRepository
,
userAttributeValueRepository
)
userAttributeService
:=
service
.
NewUserAttributeService
(
userAttributeDefinitionRepository
,
userAttributeValueRepository
)
userAttributeHandler
:=
admin
.
NewUserAttributeHandler
(
userAttributeService
)
userAttributeHandler
:=
admin
.
NewUserAttributeHandler
(
userAttributeService
)
adminHandlers
:=
handler
.
ProvideAdminHandlers
(
dashboardHandler
,
adminUserHandler
,
groupHandler
,
accountHandler
,
adminAnnouncementHandler
,
oAuthHandler
,
openAIOAuthHandler
,
geminiOAuthHandler
,
antigravityOAuthHandler
,
proxyHandler
,
adminRedeemHandler
,
promoHandler
,
settingHandler
,
opsHandler
,
systemHandler
,
adminSubscriptionHandler
,
adminUsageHandler
,
userAttributeHandler
)
adminHandlers
:=
handler
.
ProvideAdminHandlers
(
dashboardHandler
,
adminUserHandler
,
groupHandler
,
accountHandler
,
adminAnnouncementHandler
,
oAuthHandler
,
openAIOAuthHandler
,
geminiOAuthHandler
,
antigravityOAuthHandler
,
proxyHandler
,
adminRedeemHandler
,
promoHandler
,
settingHandler
,
opsHandler
,
systemHandler
,
adminSubscriptionHandler
,
adminUsageHandler
,
userAttributeHandler
)
gatewayHandler
:=
handler
.
NewGatewayHandler
(
gatewayService
,
geminiMessagesCompatService
,
antigravityGatewayService
,
userService
,
concurrencyService
,
billingCacheService
,
usageService
,
configConfig
)
gatewayHandler
:=
handler
.
NewGatewayHandler
(
gatewayService
,
geminiMessagesCompatService
,
antigravityGatewayService
,
userService
,
concurrencyService
,
billingCacheService
,
usageService
,
apiKeyService
,
configConfig
)
openAIGatewayHandler
:=
handler
.
NewOpenAIGatewayHandler
(
openAIGatewayService
,
concurrencyService
,
billingCacheService
,
configConfig
)
openAIGatewayHandler
:=
handler
.
NewOpenAIGatewayHandler
(
openAIGatewayService
,
concurrencyService
,
billingCacheService
,
apiKeyService
,
configConfig
)
handlerSettingHandler
:=
handler
.
ProvideSettingHandler
(
settingService
,
buildInfo
)
handlerSettingHandler
:=
handler
.
ProvideSettingHandler
(
settingService
,
buildInfo
)
totpHandler
:=
handler
.
NewTotpHandler
(
totpService
)
totpHandler
:=
handler
.
NewTotpHandler
(
totpService
)
handlers
:=
handler
.
ProvideHandlers
(
authHandler
,
userHandler
,
apiKeyHandler
,
usageHandler
,
redeemHandler
,
subscriptionHandler
,
announcementHandler
,
adminHandlers
,
gatewayHandler
,
openAIGatewayHandler
,
handlerSettingHandler
,
totpHandler
)
handlers
:=
handler
.
ProvideHandlers
(
authHandler
,
userHandler
,
apiKeyHandler
,
usageHandler
,
redeemHandler
,
subscriptionHandler
,
announcementHandler
,
adminHandlers
,
gatewayHandler
,
openAIGatewayHandler
,
handlerSettingHandler
,
totpHandler
)
...
...
backend/ent/apikey.go
View file @
4cce21b1
...
@@ -40,6 +40,12 @@ type APIKey struct {
...
@@ -40,6 +40,12 @@ type APIKey struct {
IPWhitelist
[]
string
`json:"ip_whitelist,omitempty"`
IPWhitelist
[]
string
`json:"ip_whitelist,omitempty"`
// Blocked IPs/CIDRs
// Blocked IPs/CIDRs
IPBlacklist
[]
string
`json:"ip_blacklist,omitempty"`
IPBlacklist
[]
string
`json:"ip_blacklist,omitempty"`
// Quota limit in USD for this API key (0 = unlimited)
Quota
float64
`json:"quota,omitempty"`
// Used quota amount in USD
QuotaUsed
float64
`json:"quota_used,omitempty"`
// Expiration time for this API key (null = never expires)
ExpiresAt
*
time
.
Time
`json:"expires_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the APIKeyQuery when eager-loading is set.
// The values are being populated by the APIKeyQuery when eager-loading is set.
Edges
APIKeyEdges
`json:"edges"`
Edges
APIKeyEdges
`json:"edges"`
...
@@ -97,11 +103,13 @@ func (*APIKey) scanValues(columns []string) ([]any, error) {
...
@@ -97,11 +103,13 @@ func (*APIKey) scanValues(columns []string) ([]any, error) {
switch
columns
[
i
]
{
switch
columns
[
i
]
{
case
apikey
.
FieldIPWhitelist
,
apikey
.
FieldIPBlacklist
:
case
apikey
.
FieldIPWhitelist
,
apikey
.
FieldIPBlacklist
:
values
[
i
]
=
new
([]
byte
)
values
[
i
]
=
new
([]
byte
)
case
apikey
.
FieldQuota
,
apikey
.
FieldQuotaUsed
:
values
[
i
]
=
new
(
sql
.
NullFloat64
)
case
apikey
.
FieldID
,
apikey
.
FieldUserID
,
apikey
.
FieldGroupID
:
case
apikey
.
FieldID
,
apikey
.
FieldUserID
,
apikey
.
FieldGroupID
:
values
[
i
]
=
new
(
sql
.
NullInt64
)
values
[
i
]
=
new
(
sql
.
NullInt64
)
case
apikey
.
FieldKey
,
apikey
.
FieldName
,
apikey
.
FieldStatus
:
case
apikey
.
FieldKey
,
apikey
.
FieldName
,
apikey
.
FieldStatus
:
values
[
i
]
=
new
(
sql
.
NullString
)
values
[
i
]
=
new
(
sql
.
NullString
)
case
apikey
.
FieldCreatedAt
,
apikey
.
FieldUpdatedAt
,
apikey
.
FieldDeletedAt
:
case
apikey
.
FieldCreatedAt
,
apikey
.
FieldUpdatedAt
,
apikey
.
FieldDeletedAt
,
apikey
.
FieldExpiresAt
:
values
[
i
]
=
new
(
sql
.
NullTime
)
values
[
i
]
=
new
(
sql
.
NullTime
)
default
:
default
:
values
[
i
]
=
new
(
sql
.
UnknownType
)
values
[
i
]
=
new
(
sql
.
UnknownType
)
...
@@ -190,6 +198,25 @@ func (_m *APIKey) assignValues(columns []string, values []any) error {
...
@@ -190,6 +198,25 @@ func (_m *APIKey) assignValues(columns []string, values []any) error {
return
fmt
.
Errorf
(
"unmarshal field ip_blacklist: %w"
,
err
)
return
fmt
.
Errorf
(
"unmarshal field ip_blacklist: %w"
,
err
)
}
}
}
}
case
apikey
.
FieldQuota
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field quota"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Quota
=
value
.
Float64
}
case
apikey
.
FieldQuotaUsed
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field quota_used"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
QuotaUsed
=
value
.
Float64
}
case
apikey
.
FieldExpiresAt
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field expires_at"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
ExpiresAt
=
new
(
time
.
Time
)
*
_m
.
ExpiresAt
=
value
.
Time
}
default
:
default
:
_m
.
selectValues
.
Set
(
columns
[
i
],
values
[
i
])
_m
.
selectValues
.
Set
(
columns
[
i
],
values
[
i
])
}
}
...
@@ -274,6 +301,17 @@ func (_m *APIKey) String() string {
...
@@ -274,6 +301,17 @@ func (_m *APIKey) String() string {
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"ip_blacklist="
)
builder
.
WriteString
(
"ip_blacklist="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
IPBlacklist
))
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
IPBlacklist
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"quota="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Quota
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"quota_used="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
QuotaUsed
))
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
ExpiresAt
;
v
!=
nil
{
builder
.
WriteString
(
"expires_at="
)
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
builder
.
WriteByte
(
')'
)
builder
.
WriteByte
(
')'
)
return
builder
.
String
()
return
builder
.
String
()
}
}
...
...
backend/ent/apikey/apikey.go
View file @
4cce21b1
...
@@ -35,6 +35,12 @@ const (
...
@@ -35,6 +35,12 @@ const (
FieldIPWhitelist
=
"ip_whitelist"
FieldIPWhitelist
=
"ip_whitelist"
// FieldIPBlacklist holds the string denoting the ip_blacklist field in the database.
// FieldIPBlacklist holds the string denoting the ip_blacklist field in the database.
FieldIPBlacklist
=
"ip_blacklist"
FieldIPBlacklist
=
"ip_blacklist"
// FieldQuota holds the string denoting the quota field in the database.
FieldQuota
=
"quota"
// FieldQuotaUsed holds the string denoting the quota_used field in the database.
FieldQuotaUsed
=
"quota_used"
// FieldExpiresAt holds the string denoting the expires_at field in the database.
FieldExpiresAt
=
"expires_at"
// EdgeUser holds the string denoting the user edge name in mutations.
// EdgeUser holds the string denoting the user edge name in mutations.
EdgeUser
=
"user"
EdgeUser
=
"user"
// EdgeGroup holds the string denoting the group edge name in mutations.
// EdgeGroup holds the string denoting the group edge name in mutations.
...
@@ -79,6 +85,9 @@ var Columns = []string{
...
@@ -79,6 +85,9 @@ var Columns = []string{
FieldStatus
,
FieldStatus
,
FieldIPWhitelist
,
FieldIPWhitelist
,
FieldIPBlacklist
,
FieldIPBlacklist
,
FieldQuota
,
FieldQuotaUsed
,
FieldExpiresAt
,
}
}
// ValidColumn reports if the column name is valid (part of the table columns).
// ValidColumn reports if the column name is valid (part of the table columns).
...
@@ -113,6 +122,10 @@ var (
...
@@ -113,6 +122,10 @@ var (
DefaultStatus
string
DefaultStatus
string
// StatusValidator is a validator for the "status" field. It is called by the builders before save.
// StatusValidator is a validator for the "status" field. It is called by the builders before save.
StatusValidator
func
(
string
)
error
StatusValidator
func
(
string
)
error
// DefaultQuota holds the default value on creation for the "quota" field.
DefaultQuota
float64
// DefaultQuotaUsed holds the default value on creation for the "quota_used" field.
DefaultQuotaUsed
float64
)
)
// OrderOption defines the ordering options for the APIKey queries.
// OrderOption defines the ordering options for the APIKey queries.
...
@@ -163,6 +176,21 @@ func ByStatus(opts ...sql.OrderTermOption) OrderOption {
...
@@ -163,6 +176,21 @@ func ByStatus(opts ...sql.OrderTermOption) OrderOption {
return
sql
.
OrderByField
(
FieldStatus
,
opts
...
)
.
ToFunc
()
return
sql
.
OrderByField
(
FieldStatus
,
opts
...
)
.
ToFunc
()
}
}
// ByQuota orders the results by the quota field.
func
ByQuota
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldQuota
,
opts
...
)
.
ToFunc
()
}
// ByQuotaUsed orders the results by the quota_used field.
func
ByQuotaUsed
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldQuotaUsed
,
opts
...
)
.
ToFunc
()
}
// ByExpiresAt orders the results by the expires_at field.
func
ByExpiresAt
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldExpiresAt
,
opts
...
)
.
ToFunc
()
}
// ByUserField orders the results by user field.
// ByUserField orders the results by user field.
func
ByUserField
(
field
string
,
opts
...
sql
.
OrderTermOption
)
OrderOption
{
func
ByUserField
(
field
string
,
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
func
(
s
*
sql
.
Selector
)
{
return
func
(
s
*
sql
.
Selector
)
{
...
...
backend/ent/apikey/where.go
View file @
4cce21b1
...
@@ -95,6 +95,21 @@ func Status(v string) predicate.APIKey {
...
@@ -95,6 +95,21 @@ func Status(v string) predicate.APIKey {
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldStatus
,
v
))
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldStatus
,
v
))
}
}
// Quota applies equality check predicate on the "quota" field. It's identical to QuotaEQ.
func
Quota
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldQuota
,
v
))
}
// QuotaUsed applies equality check predicate on the "quota_used" field. It's identical to QuotaUsedEQ.
func
QuotaUsed
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldQuotaUsed
,
v
))
}
// ExpiresAt applies equality check predicate on the "expires_at" field. It's identical to ExpiresAtEQ.
func
ExpiresAt
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldExpiresAt
,
v
))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func
CreatedAtEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
func
CreatedAtEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldCreatedAt
,
v
))
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldCreatedAt
,
v
))
...
@@ -490,6 +505,136 @@ func IPBlacklistNotNil() predicate.APIKey {
...
@@ -490,6 +505,136 @@ func IPBlacklistNotNil() predicate.APIKey {
return
predicate
.
APIKey
(
sql
.
FieldNotNull
(
FieldIPBlacklist
))
return
predicate
.
APIKey
(
sql
.
FieldNotNull
(
FieldIPBlacklist
))
}
}
// QuotaEQ applies the EQ predicate on the "quota" field.
func
QuotaEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldQuota
,
v
))
}
// QuotaNEQ applies the NEQ predicate on the "quota" field.
func
QuotaNEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldQuota
,
v
))
}
// QuotaIn applies the In predicate on the "quota" field.
func
QuotaIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldQuota
,
vs
...
))
}
// QuotaNotIn applies the NotIn predicate on the "quota" field.
func
QuotaNotIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldQuota
,
vs
...
))
}
// QuotaGT applies the GT predicate on the "quota" field.
func
QuotaGT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldQuota
,
v
))
}
// QuotaGTE applies the GTE predicate on the "quota" field.
func
QuotaGTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldQuota
,
v
))
}
// QuotaLT applies the LT predicate on the "quota" field.
func
QuotaLT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldQuota
,
v
))
}
// QuotaLTE applies the LTE predicate on the "quota" field.
func
QuotaLTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldQuota
,
v
))
}
// QuotaUsedEQ applies the EQ predicate on the "quota_used" field.
func
QuotaUsedEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldQuotaUsed
,
v
))
}
// QuotaUsedNEQ applies the NEQ predicate on the "quota_used" field.
func
QuotaUsedNEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldQuotaUsed
,
v
))
}
// QuotaUsedIn applies the In predicate on the "quota_used" field.
func
QuotaUsedIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldQuotaUsed
,
vs
...
))
}
// QuotaUsedNotIn applies the NotIn predicate on the "quota_used" field.
func
QuotaUsedNotIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldQuotaUsed
,
vs
...
))
}
// QuotaUsedGT applies the GT predicate on the "quota_used" field.
func
QuotaUsedGT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldQuotaUsed
,
v
))
}
// QuotaUsedGTE applies the GTE predicate on the "quota_used" field.
func
QuotaUsedGTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldQuotaUsed
,
v
))
}
// QuotaUsedLT applies the LT predicate on the "quota_used" field.
func
QuotaUsedLT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldQuotaUsed
,
v
))
}
// QuotaUsedLTE applies the LTE predicate on the "quota_used" field.
func
QuotaUsedLTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldQuotaUsed
,
v
))
}
// ExpiresAtEQ applies the EQ predicate on the "expires_at" field.
func
ExpiresAtEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldExpiresAt
,
v
))
}
// ExpiresAtNEQ applies the NEQ predicate on the "expires_at" field.
func
ExpiresAtNEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldExpiresAt
,
v
))
}
// ExpiresAtIn applies the In predicate on the "expires_at" field.
func
ExpiresAtIn
(
vs
...
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldExpiresAt
,
vs
...
))
}
// ExpiresAtNotIn applies the NotIn predicate on the "expires_at" field.
func
ExpiresAtNotIn
(
vs
...
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldExpiresAt
,
vs
...
))
}
// ExpiresAtGT applies the GT predicate on the "expires_at" field.
func
ExpiresAtGT
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldExpiresAt
,
v
))
}
// ExpiresAtGTE applies the GTE predicate on the "expires_at" field.
func
ExpiresAtGTE
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldExpiresAt
,
v
))
}
// ExpiresAtLT applies the LT predicate on the "expires_at" field.
func
ExpiresAtLT
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldExpiresAt
,
v
))
}
// ExpiresAtLTE applies the LTE predicate on the "expires_at" field.
func
ExpiresAtLTE
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldExpiresAt
,
v
))
}
// ExpiresAtIsNil applies the IsNil predicate on the "expires_at" field.
func
ExpiresAtIsNil
()
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIsNull
(
FieldExpiresAt
))
}
// ExpiresAtNotNil applies the NotNil predicate on the "expires_at" field.
func
ExpiresAtNotNil
()
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotNull
(
FieldExpiresAt
))
}
// HasUser applies the HasEdge predicate on the "user" edge.
// HasUser applies the HasEdge predicate on the "user" edge.
func
HasUser
()
predicate
.
APIKey
{
func
HasUser
()
predicate
.
APIKey
{
return
predicate
.
APIKey
(
func
(
s
*
sql
.
Selector
)
{
return
predicate
.
APIKey
(
func
(
s
*
sql
.
Selector
)
{
...
...
backend/ent/apikey_create.go
View file @
4cce21b1
...
@@ -125,6 +125,48 @@ func (_c *APIKeyCreate) SetIPBlacklist(v []string) *APIKeyCreate {
...
@@ -125,6 +125,48 @@ func (_c *APIKeyCreate) SetIPBlacklist(v []string) *APIKeyCreate {
return
_c
return
_c
}
}
// SetQuota sets the "quota" field.
func
(
_c
*
APIKeyCreate
)
SetQuota
(
v
float64
)
*
APIKeyCreate
{
_c
.
mutation
.
SetQuota
(
v
)
return
_c
}
// SetNillableQuota sets the "quota" field if the given value is not nil.
func
(
_c
*
APIKeyCreate
)
SetNillableQuota
(
v
*
float64
)
*
APIKeyCreate
{
if
v
!=
nil
{
_c
.
SetQuota
(
*
v
)
}
return
_c
}
// SetQuotaUsed sets the "quota_used" field.
func
(
_c
*
APIKeyCreate
)
SetQuotaUsed
(
v
float64
)
*
APIKeyCreate
{
_c
.
mutation
.
SetQuotaUsed
(
v
)
return
_c
}
// SetNillableQuotaUsed sets the "quota_used" field if the given value is not nil.
func
(
_c
*
APIKeyCreate
)
SetNillableQuotaUsed
(
v
*
float64
)
*
APIKeyCreate
{
if
v
!=
nil
{
_c
.
SetQuotaUsed
(
*
v
)
}
return
_c
}
// SetExpiresAt sets the "expires_at" field.
func
(
_c
*
APIKeyCreate
)
SetExpiresAt
(
v
time
.
Time
)
*
APIKeyCreate
{
_c
.
mutation
.
SetExpiresAt
(
v
)
return
_c
}
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
func
(
_c
*
APIKeyCreate
)
SetNillableExpiresAt
(
v
*
time
.
Time
)
*
APIKeyCreate
{
if
v
!=
nil
{
_c
.
SetExpiresAt
(
*
v
)
}
return
_c
}
// SetUser sets the "user" edge to the User entity.
// SetUser sets the "user" edge to the User entity.
func
(
_c
*
APIKeyCreate
)
SetUser
(
v
*
User
)
*
APIKeyCreate
{
func
(
_c
*
APIKeyCreate
)
SetUser
(
v
*
User
)
*
APIKeyCreate
{
return
_c
.
SetUserID
(
v
.
ID
)
return
_c
.
SetUserID
(
v
.
ID
)
...
@@ -205,6 +247,14 @@ func (_c *APIKeyCreate) defaults() error {
...
@@ -205,6 +247,14 @@ func (_c *APIKeyCreate) defaults() error {
v
:=
apikey
.
DefaultStatus
v
:=
apikey
.
DefaultStatus
_c
.
mutation
.
SetStatus
(
v
)
_c
.
mutation
.
SetStatus
(
v
)
}
}
if
_
,
ok
:=
_c
.
mutation
.
Quota
();
!
ok
{
v
:=
apikey
.
DefaultQuota
_c
.
mutation
.
SetQuota
(
v
)
}
if
_
,
ok
:=
_c
.
mutation
.
QuotaUsed
();
!
ok
{
v
:=
apikey
.
DefaultQuotaUsed
_c
.
mutation
.
SetQuotaUsed
(
v
)
}
return
nil
return
nil
}
}
...
@@ -243,6 +293,12 @@ func (_c *APIKeyCreate) check() error {
...
@@ -243,6 +293,12 @@ func (_c *APIKeyCreate) check() error {
return
&
ValidationError
{
Name
:
"status"
,
err
:
fmt
.
Errorf
(
`ent: validator failed for field "APIKey.status": %w`
,
err
)}
return
&
ValidationError
{
Name
:
"status"
,
err
:
fmt
.
Errorf
(
`ent: validator failed for field "APIKey.status": %w`
,
err
)}
}
}
}
}
if
_
,
ok
:=
_c
.
mutation
.
Quota
();
!
ok
{
return
&
ValidationError
{
Name
:
"quota"
,
err
:
errors
.
New
(
`ent: missing required field "APIKey.quota"`
)}
}
if
_
,
ok
:=
_c
.
mutation
.
QuotaUsed
();
!
ok
{
return
&
ValidationError
{
Name
:
"quota_used"
,
err
:
errors
.
New
(
`ent: missing required field "APIKey.quota_used"`
)}
}
if
len
(
_c
.
mutation
.
UserIDs
())
==
0
{
if
len
(
_c
.
mutation
.
UserIDs
())
==
0
{
return
&
ValidationError
{
Name
:
"user"
,
err
:
errors
.
New
(
`ent: missing required edge "APIKey.user"`
)}
return
&
ValidationError
{
Name
:
"user"
,
err
:
errors
.
New
(
`ent: missing required edge "APIKey.user"`
)}
}
}
...
@@ -305,6 +361,18 @@ func (_c *APIKeyCreate) createSpec() (*APIKey, *sqlgraph.CreateSpec) {
...
@@ -305,6 +361,18 @@ func (_c *APIKeyCreate) createSpec() (*APIKey, *sqlgraph.CreateSpec) {
_spec
.
SetField
(
apikey
.
FieldIPBlacklist
,
field
.
TypeJSON
,
value
)
_spec
.
SetField
(
apikey
.
FieldIPBlacklist
,
field
.
TypeJSON
,
value
)
_node
.
IPBlacklist
=
value
_node
.
IPBlacklist
=
value
}
}
if
value
,
ok
:=
_c
.
mutation
.
Quota
();
ok
{
_spec
.
SetField
(
apikey
.
FieldQuota
,
field
.
TypeFloat64
,
value
)
_node
.
Quota
=
value
}
if
value
,
ok
:=
_c
.
mutation
.
QuotaUsed
();
ok
{
_spec
.
SetField
(
apikey
.
FieldQuotaUsed
,
field
.
TypeFloat64
,
value
)
_node
.
QuotaUsed
=
value
}
if
value
,
ok
:=
_c
.
mutation
.
ExpiresAt
();
ok
{
_spec
.
SetField
(
apikey
.
FieldExpiresAt
,
field
.
TypeTime
,
value
)
_node
.
ExpiresAt
=
&
value
}
if
nodes
:=
_c
.
mutation
.
UserIDs
();
len
(
nodes
)
>
0
{
if
nodes
:=
_c
.
mutation
.
UserIDs
();
len
(
nodes
)
>
0
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
M2O
,
Rel
:
sqlgraph
.
M2O
,
...
@@ -539,6 +607,60 @@ func (u *APIKeyUpsert) ClearIPBlacklist() *APIKeyUpsert {
...
@@ -539,6 +607,60 @@ func (u *APIKeyUpsert) ClearIPBlacklist() *APIKeyUpsert {
return
u
return
u
}
}
// SetQuota sets the "quota" field.
func
(
u
*
APIKeyUpsert
)
SetQuota
(
v
float64
)
*
APIKeyUpsert
{
u
.
Set
(
apikey
.
FieldQuota
,
v
)
return
u
}
// UpdateQuota sets the "quota" field to the value that was provided on create.
func
(
u
*
APIKeyUpsert
)
UpdateQuota
()
*
APIKeyUpsert
{
u
.
SetExcluded
(
apikey
.
FieldQuota
)
return
u
}
// AddQuota adds v to the "quota" field.
func
(
u
*
APIKeyUpsert
)
AddQuota
(
v
float64
)
*
APIKeyUpsert
{
u
.
Add
(
apikey
.
FieldQuota
,
v
)
return
u
}
// SetQuotaUsed sets the "quota_used" field.
func
(
u
*
APIKeyUpsert
)
SetQuotaUsed
(
v
float64
)
*
APIKeyUpsert
{
u
.
Set
(
apikey
.
FieldQuotaUsed
,
v
)
return
u
}
// UpdateQuotaUsed sets the "quota_used" field to the value that was provided on create.
func
(
u
*
APIKeyUpsert
)
UpdateQuotaUsed
()
*
APIKeyUpsert
{
u
.
SetExcluded
(
apikey
.
FieldQuotaUsed
)
return
u
}
// AddQuotaUsed adds v to the "quota_used" field.
func
(
u
*
APIKeyUpsert
)
AddQuotaUsed
(
v
float64
)
*
APIKeyUpsert
{
u
.
Add
(
apikey
.
FieldQuotaUsed
,
v
)
return
u
}
// SetExpiresAt sets the "expires_at" field.
func
(
u
*
APIKeyUpsert
)
SetExpiresAt
(
v
time
.
Time
)
*
APIKeyUpsert
{
u
.
Set
(
apikey
.
FieldExpiresAt
,
v
)
return
u
}
// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create.
func
(
u
*
APIKeyUpsert
)
UpdateExpiresAt
()
*
APIKeyUpsert
{
u
.
SetExcluded
(
apikey
.
FieldExpiresAt
)
return
u
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
u
*
APIKeyUpsert
)
ClearExpiresAt
()
*
APIKeyUpsert
{
u
.
SetNull
(
apikey
.
FieldExpiresAt
)
return
u
}
// UpdateNewValues updates the mutable fields using the new values that were set on create.
// UpdateNewValues updates the mutable fields using the new values that were set on create.
// Using this option is equivalent to using:
// Using this option is equivalent to using:
//
//
...
@@ -738,6 +860,69 @@ func (u *APIKeyUpsertOne) ClearIPBlacklist() *APIKeyUpsertOne {
...
@@ -738,6 +860,69 @@ func (u *APIKeyUpsertOne) ClearIPBlacklist() *APIKeyUpsertOne {
})
})
}
}
// SetQuota sets the "quota" field.
func
(
u
*
APIKeyUpsertOne
)
SetQuota
(
v
float64
)
*
APIKeyUpsertOne
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
SetQuota
(
v
)
})
}
// AddQuota adds v to the "quota" field.
func
(
u
*
APIKeyUpsertOne
)
AddQuota
(
v
float64
)
*
APIKeyUpsertOne
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
AddQuota
(
v
)
})
}
// UpdateQuota sets the "quota" field to the value that was provided on create.
func
(
u
*
APIKeyUpsertOne
)
UpdateQuota
()
*
APIKeyUpsertOne
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
UpdateQuota
()
})
}
// SetQuotaUsed sets the "quota_used" field.
func
(
u
*
APIKeyUpsertOne
)
SetQuotaUsed
(
v
float64
)
*
APIKeyUpsertOne
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
SetQuotaUsed
(
v
)
})
}
// AddQuotaUsed adds v to the "quota_used" field.
func
(
u
*
APIKeyUpsertOne
)
AddQuotaUsed
(
v
float64
)
*
APIKeyUpsertOne
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
AddQuotaUsed
(
v
)
})
}
// UpdateQuotaUsed sets the "quota_used" field to the value that was provided on create.
func
(
u
*
APIKeyUpsertOne
)
UpdateQuotaUsed
()
*
APIKeyUpsertOne
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
UpdateQuotaUsed
()
})
}
// SetExpiresAt sets the "expires_at" field.
func
(
u
*
APIKeyUpsertOne
)
SetExpiresAt
(
v
time
.
Time
)
*
APIKeyUpsertOne
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
SetExpiresAt
(
v
)
})
}
// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create.
func
(
u
*
APIKeyUpsertOne
)
UpdateExpiresAt
()
*
APIKeyUpsertOne
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
UpdateExpiresAt
()
})
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
u
*
APIKeyUpsertOne
)
ClearExpiresAt
()
*
APIKeyUpsertOne
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
ClearExpiresAt
()
})
}
// Exec executes the query.
// Exec executes the query.
func
(
u
*
APIKeyUpsertOne
)
Exec
(
ctx
context
.
Context
)
error
{
func
(
u
*
APIKeyUpsertOne
)
Exec
(
ctx
context
.
Context
)
error
{
if
len
(
u
.
create
.
conflict
)
==
0
{
if
len
(
u
.
create
.
conflict
)
==
0
{
...
@@ -1103,6 +1288,69 @@ func (u *APIKeyUpsertBulk) ClearIPBlacklist() *APIKeyUpsertBulk {
...
@@ -1103,6 +1288,69 @@ func (u *APIKeyUpsertBulk) ClearIPBlacklist() *APIKeyUpsertBulk {
})
})
}
}
// SetQuota sets the "quota" field.
func
(
u
*
APIKeyUpsertBulk
)
SetQuota
(
v
float64
)
*
APIKeyUpsertBulk
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
SetQuota
(
v
)
})
}
// AddQuota adds v to the "quota" field.
func
(
u
*
APIKeyUpsertBulk
)
AddQuota
(
v
float64
)
*
APIKeyUpsertBulk
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
AddQuota
(
v
)
})
}
// UpdateQuota sets the "quota" field to the value that was provided on create.
func
(
u
*
APIKeyUpsertBulk
)
UpdateQuota
()
*
APIKeyUpsertBulk
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
UpdateQuota
()
})
}
// SetQuotaUsed sets the "quota_used" field.
func
(
u
*
APIKeyUpsertBulk
)
SetQuotaUsed
(
v
float64
)
*
APIKeyUpsertBulk
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
SetQuotaUsed
(
v
)
})
}
// AddQuotaUsed adds v to the "quota_used" field.
func
(
u
*
APIKeyUpsertBulk
)
AddQuotaUsed
(
v
float64
)
*
APIKeyUpsertBulk
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
AddQuotaUsed
(
v
)
})
}
// UpdateQuotaUsed sets the "quota_used" field to the value that was provided on create.
func
(
u
*
APIKeyUpsertBulk
)
UpdateQuotaUsed
()
*
APIKeyUpsertBulk
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
UpdateQuotaUsed
()
})
}
// SetExpiresAt sets the "expires_at" field.
func
(
u
*
APIKeyUpsertBulk
)
SetExpiresAt
(
v
time
.
Time
)
*
APIKeyUpsertBulk
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
SetExpiresAt
(
v
)
})
}
// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create.
func
(
u
*
APIKeyUpsertBulk
)
UpdateExpiresAt
()
*
APIKeyUpsertBulk
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
UpdateExpiresAt
()
})
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
u
*
APIKeyUpsertBulk
)
ClearExpiresAt
()
*
APIKeyUpsertBulk
{
return
u
.
Update
(
func
(
s
*
APIKeyUpsert
)
{
s
.
ClearExpiresAt
()
})
}
// Exec executes the query.
// Exec executes the query.
func
(
u
*
APIKeyUpsertBulk
)
Exec
(
ctx
context
.
Context
)
error
{
func
(
u
*
APIKeyUpsertBulk
)
Exec
(
ctx
context
.
Context
)
error
{
if
u
.
create
.
err
!=
nil
{
if
u
.
create
.
err
!=
nil
{
...
...
backend/ent/apikey_update.go
View file @
4cce21b1
...
@@ -170,6 +170,68 @@ func (_u *APIKeyUpdate) ClearIPBlacklist() *APIKeyUpdate {
...
@@ -170,6 +170,68 @@ func (_u *APIKeyUpdate) ClearIPBlacklist() *APIKeyUpdate {
return
_u
return
_u
}
}
// SetQuota sets the "quota" field.
func
(
_u
*
APIKeyUpdate
)
SetQuota
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
ResetQuota
()
_u
.
mutation
.
SetQuota
(
v
)
return
_u
}
// SetNillableQuota sets the "quota" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableQuota
(
v
*
float64
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetQuota
(
*
v
)
}
return
_u
}
// AddQuota adds value to the "quota" field.
func
(
_u
*
APIKeyUpdate
)
AddQuota
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
AddQuota
(
v
)
return
_u
}
// SetQuotaUsed sets the "quota_used" field.
func
(
_u
*
APIKeyUpdate
)
SetQuotaUsed
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
ResetQuotaUsed
()
_u
.
mutation
.
SetQuotaUsed
(
v
)
return
_u
}
// SetNillableQuotaUsed sets the "quota_used" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableQuotaUsed
(
v
*
float64
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetQuotaUsed
(
*
v
)
}
return
_u
}
// AddQuotaUsed adds value to the "quota_used" field.
func
(
_u
*
APIKeyUpdate
)
AddQuotaUsed
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
AddQuotaUsed
(
v
)
return
_u
}
// SetExpiresAt sets the "expires_at" field.
func
(
_u
*
APIKeyUpdate
)
SetExpiresAt
(
v
time
.
Time
)
*
APIKeyUpdate
{
_u
.
mutation
.
SetExpiresAt
(
v
)
return
_u
}
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableExpiresAt
(
v
*
time
.
Time
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetExpiresAt
(
*
v
)
}
return
_u
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
_u
*
APIKeyUpdate
)
ClearExpiresAt
()
*
APIKeyUpdate
{
_u
.
mutation
.
ClearExpiresAt
()
return
_u
}
// SetUser sets the "user" edge to the User entity.
// SetUser sets the "user" edge to the User entity.
func
(
_u
*
APIKeyUpdate
)
SetUser
(
v
*
User
)
*
APIKeyUpdate
{
func
(
_u
*
APIKeyUpdate
)
SetUser
(
v
*
User
)
*
APIKeyUpdate
{
return
_u
.
SetUserID
(
v
.
ID
)
return
_u
.
SetUserID
(
v
.
ID
)
...
@@ -350,6 +412,24 @@ func (_u *APIKeyUpdate) sqlSave(ctx context.Context) (_node int, err error) {
...
@@ -350,6 +412,24 @@ func (_u *APIKeyUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if
_u
.
mutation
.
IPBlacklistCleared
()
{
if
_u
.
mutation
.
IPBlacklistCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldIPBlacklist
,
field
.
TypeJSON
)
_spec
.
ClearField
(
apikey
.
FieldIPBlacklist
,
field
.
TypeJSON
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
Quota
();
ok
{
_spec
.
SetField
(
apikey
.
FieldQuota
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedQuota
();
ok
{
_spec
.
AddField
(
apikey
.
FieldQuota
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
QuotaUsed
();
ok
{
_spec
.
SetField
(
apikey
.
FieldQuotaUsed
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedQuotaUsed
();
ok
{
_spec
.
AddField
(
apikey
.
FieldQuotaUsed
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
ExpiresAt
();
ok
{
_spec
.
SetField
(
apikey
.
FieldExpiresAt
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
ExpiresAtCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldExpiresAt
,
field
.
TypeTime
)
}
if
_u
.
mutation
.
UserCleared
()
{
if
_u
.
mutation
.
UserCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
M2O
,
Rel
:
sqlgraph
.
M2O
,
...
@@ -611,6 +691,68 @@ func (_u *APIKeyUpdateOne) ClearIPBlacklist() *APIKeyUpdateOne {
...
@@ -611,6 +691,68 @@ func (_u *APIKeyUpdateOne) ClearIPBlacklist() *APIKeyUpdateOne {
return
_u
return
_u
}
}
// SetQuota sets the "quota" field.
func
(
_u
*
APIKeyUpdateOne
)
SetQuota
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
ResetQuota
()
_u
.
mutation
.
SetQuota
(
v
)
return
_u
}
// SetNillableQuota sets the "quota" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableQuota
(
v
*
float64
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetQuota
(
*
v
)
}
return
_u
}
// AddQuota adds value to the "quota" field.
func
(
_u
*
APIKeyUpdateOne
)
AddQuota
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
AddQuota
(
v
)
return
_u
}
// SetQuotaUsed sets the "quota_used" field.
func
(
_u
*
APIKeyUpdateOne
)
SetQuotaUsed
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
ResetQuotaUsed
()
_u
.
mutation
.
SetQuotaUsed
(
v
)
return
_u
}
// SetNillableQuotaUsed sets the "quota_used" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableQuotaUsed
(
v
*
float64
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetQuotaUsed
(
*
v
)
}
return
_u
}
// AddQuotaUsed adds value to the "quota_used" field.
func
(
_u
*
APIKeyUpdateOne
)
AddQuotaUsed
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
AddQuotaUsed
(
v
)
return
_u
}
// SetExpiresAt sets the "expires_at" field.
func
(
_u
*
APIKeyUpdateOne
)
SetExpiresAt
(
v
time
.
Time
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
SetExpiresAt
(
v
)
return
_u
}
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableExpiresAt
(
v
*
time
.
Time
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetExpiresAt
(
*
v
)
}
return
_u
}
// ClearExpiresAt clears the value of the "expires_at" field.
func
(
_u
*
APIKeyUpdateOne
)
ClearExpiresAt
()
*
APIKeyUpdateOne
{
_u
.
mutation
.
ClearExpiresAt
()
return
_u
}
// SetUser sets the "user" edge to the User entity.
// SetUser sets the "user" edge to the User entity.
func
(
_u
*
APIKeyUpdateOne
)
SetUser
(
v
*
User
)
*
APIKeyUpdateOne
{
func
(
_u
*
APIKeyUpdateOne
)
SetUser
(
v
*
User
)
*
APIKeyUpdateOne
{
return
_u
.
SetUserID
(
v
.
ID
)
return
_u
.
SetUserID
(
v
.
ID
)
...
@@ -821,6 +963,24 @@ func (_u *APIKeyUpdateOne) sqlSave(ctx context.Context) (_node *APIKey, err erro
...
@@ -821,6 +963,24 @@ func (_u *APIKeyUpdateOne) sqlSave(ctx context.Context) (_node *APIKey, err erro
if
_u
.
mutation
.
IPBlacklistCleared
()
{
if
_u
.
mutation
.
IPBlacklistCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldIPBlacklist
,
field
.
TypeJSON
)
_spec
.
ClearField
(
apikey
.
FieldIPBlacklist
,
field
.
TypeJSON
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
Quota
();
ok
{
_spec
.
SetField
(
apikey
.
FieldQuota
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedQuota
();
ok
{
_spec
.
AddField
(
apikey
.
FieldQuota
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
QuotaUsed
();
ok
{
_spec
.
SetField
(
apikey
.
FieldQuotaUsed
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedQuotaUsed
();
ok
{
_spec
.
AddField
(
apikey
.
FieldQuotaUsed
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
ExpiresAt
();
ok
{
_spec
.
SetField
(
apikey
.
FieldExpiresAt
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
ExpiresAtCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldExpiresAt
,
field
.
TypeTime
)
}
if
_u
.
mutation
.
UserCleared
()
{
if
_u
.
mutation
.
UserCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
M2O
,
Rel
:
sqlgraph
.
M2O
,
...
...
backend/ent/migrate/schema.go
View file @
4cce21b1
...
@@ -20,6 +20,9 @@ var (
...
@@ -20,6 +20,9 @@ var (
{
Name
:
"status"
,
Type
:
field
.
TypeString
,
Size
:
20
,
Default
:
"active"
},
{
Name
:
"status"
,
Type
:
field
.
TypeString
,
Size
:
20
,
Default
:
"active"
},
{
Name
:
"ip_whitelist"
,
Type
:
field
.
TypeJSON
,
Nullable
:
true
},
{
Name
:
"ip_whitelist"
,
Type
:
field
.
TypeJSON
,
Nullable
:
true
},
{
Name
:
"ip_blacklist"
,
Type
:
field
.
TypeJSON
,
Nullable
:
true
},
{
Name
:
"ip_blacklist"
,
Type
:
field
.
TypeJSON
,
Nullable
:
true
},
{
Name
:
"quota"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
Name
:
"quota_used"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
Name
:
"expires_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
},
{
Name
:
"group_id"
,
Type
:
field
.
TypeInt64
,
Nullable
:
true
},
{
Name
:
"group_id"
,
Type
:
field
.
TypeInt64
,
Nullable
:
true
},
{
Name
:
"user_id"
,
Type
:
field
.
TypeInt64
},
{
Name
:
"user_id"
,
Type
:
field
.
TypeInt64
},
}
}
...
@@ -31,13 +34,13 @@ var (
...
@@ -31,13 +34,13 @@ var (
ForeignKeys
:
[]
*
schema
.
ForeignKey
{
ForeignKeys
:
[]
*
schema
.
ForeignKey
{
{
{
Symbol
:
"api_keys_groups_api_keys"
,
Symbol
:
"api_keys_groups_api_keys"
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
9
]},
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
12
]},
RefColumns
:
[]
*
schema
.
Column
{
GroupsColumns
[
0
]},
RefColumns
:
[]
*
schema
.
Column
{
GroupsColumns
[
0
]},
OnDelete
:
schema
.
SetNull
,
OnDelete
:
schema
.
SetNull
,
},
},
{
{
Symbol
:
"api_keys_users_api_keys"
,
Symbol
:
"api_keys_users_api_keys"
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
1
0
]},
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
1
3
]},
RefColumns
:
[]
*
schema
.
Column
{
UsersColumns
[
0
]},
RefColumns
:
[]
*
schema
.
Column
{
UsersColumns
[
0
]},
OnDelete
:
schema
.
NoAction
,
OnDelete
:
schema
.
NoAction
,
},
},
...
@@ -46,12 +49,12 @@ var (
...
@@ -46,12 +49,12 @@ var (
{
{
Name
:
"apikey_user_id"
,
Name
:
"apikey_user_id"
,
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
1
0
]},
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
1
3
]},
},
},
{
{
Name
:
"apikey_group_id"
,
Name
:
"apikey_group_id"
,
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
9
]},
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
12
]},
},
},
{
{
Name
:
"apikey_status"
,
Name
:
"apikey_status"
,
...
@@ -63,6 +66,16 @@ var (
...
@@ -63,6 +66,16 @@ var (
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
3
]},
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
3
]},
},
},
{
Name
:
"apikey_quota_quota_used"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
9
],
APIKeysColumns
[
10
]},
},
{
Name
:
"apikey_expires_at"
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
11
]},
},
},
},
}
}
// AccountsColumns holds the columns for the "accounts" table.
// AccountsColumns holds the columns for the "accounts" table.
...
...
backend/ent/mutation.go
View file @
4cce21b1
...
@@ -79,6 +79,11 @@ type APIKeyMutation struct {
...
@@ -79,6 +79,11 @@ type APIKeyMutation struct {
appendip_whitelist []string
appendip_whitelist []string
ip_blacklist *[]string
ip_blacklist *[]string
appendip_blacklist []string
appendip_blacklist []string
quota *float64
addquota *float64
quota_used *float64
addquota_used *float64
expires_at *time.Time
clearedFields map[string]struct{}
clearedFields map[string]struct{}
user *int64
user *int64
cleareduser bool
cleareduser bool
...
@@ -634,6 +639,167 @@ func (m *APIKeyMutation) ResetIPBlacklist() {
...
@@ -634,6 +639,167 @@ func (m *APIKeyMutation) ResetIPBlacklist() {
delete(m.clearedFields, apikey.FieldIPBlacklist)
delete(m.clearedFields, apikey.FieldIPBlacklist)
}
}
// SetQuota sets the "quota" field.
func (m *APIKeyMutation) SetQuota(f float64) {
m.quota = &f
m.addquota = nil
}
// Quota returns the value of the "quota" field in the mutation.
func (m *APIKeyMutation) Quota() (r float64, exists bool) {
v := m.quota
if v == nil {
return
}
return *v, true
}
// OldQuota returns the old "quota" field's value of the APIKey entity.
// If the APIKey object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *APIKeyMutation) OldQuota(ctx context.Context) (v float64, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldQuota is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldQuota requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldQuota: %w", err)
}
return oldValue.Quota, nil
}
// AddQuota adds f to the "quota" field.
func (m *APIKeyMutation) AddQuota(f float64) {
if m.addquota != nil {
*m.addquota += f
} else {
m.addquota = &f
}
}
// AddedQuota returns the value that was added to the "quota" field in this mutation.
func (m *APIKeyMutation) AddedQuota() (r float64, exists bool) {
v := m.addquota
if v == nil {
return
}
return *v, true
}
// ResetQuota resets all changes to the "quota" field.
func (m *APIKeyMutation) ResetQuota() {
m.quota = nil
m.addquota = nil
}
// SetQuotaUsed sets the "quota_used" field.
func (m *APIKeyMutation) SetQuotaUsed(f float64) {
m.quota_used = &f
m.addquota_used = nil
}
// QuotaUsed returns the value of the "quota_used" field in the mutation.
func (m *APIKeyMutation) QuotaUsed() (r float64, exists bool) {
v := m.quota_used
if v == nil {
return
}
return *v, true
}
// OldQuotaUsed returns the old "quota_used" field's value of the APIKey entity.
// If the APIKey object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *APIKeyMutation) OldQuotaUsed(ctx context.Context) (v float64, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldQuotaUsed is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldQuotaUsed requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldQuotaUsed: %w", err)
}
return oldValue.QuotaUsed, nil
}
// AddQuotaUsed adds f to the "quota_used" field.
func (m *APIKeyMutation) AddQuotaUsed(f float64) {
if m.addquota_used != nil {
*m.addquota_used += f
} else {
m.addquota_used = &f
}
}
// AddedQuotaUsed returns the value that was added to the "quota_used" field in this mutation.
func (m *APIKeyMutation) AddedQuotaUsed() (r float64, exists bool) {
v := m.addquota_used
if v == nil {
return
}
return *v, true
}
// ResetQuotaUsed resets all changes to the "quota_used" field.
func (m *APIKeyMutation) ResetQuotaUsed() {
m.quota_used = nil
m.addquota_used = nil
}
// SetExpiresAt sets the "expires_at" field.
func (m *APIKeyMutation) SetExpiresAt(t time.Time) {
m.expires_at = &t
}
// ExpiresAt returns the value of the "expires_at" field in the mutation.
func (m *APIKeyMutation) ExpiresAt() (r time.Time, exists bool) {
v := m.expires_at
if v == nil {
return
}
return *v, true
}
// OldExpiresAt returns the old "expires_at" field's value of the APIKey entity.
// If the APIKey object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *APIKeyMutation) OldExpiresAt(ctx context.Context) (v *time.Time, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldExpiresAt is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldExpiresAt requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldExpiresAt: %w", err)
}
return oldValue.ExpiresAt, nil
}
// ClearExpiresAt clears the value of the "expires_at" field.
func (m *APIKeyMutation) ClearExpiresAt() {
m.expires_at = nil
m.clearedFields[apikey.FieldExpiresAt] = struct{}{}
}
// ExpiresAtCleared returns if the "expires_at" field was cleared in this mutation.
func (m *APIKeyMutation) ExpiresAtCleared() bool {
_, ok := m.clearedFields[apikey.FieldExpiresAt]
return ok
}
// ResetExpiresAt resets all changes to the "expires_at" field.
func (m *APIKeyMutation) ResetExpiresAt() {
m.expires_at = nil
delete(m.clearedFields, apikey.FieldExpiresAt)
}
// ClearUser clears the "user" edge to the User entity.
// ClearUser clears the "user" edge to the User entity.
func (m *APIKeyMutation) ClearUser() {
func (m *APIKeyMutation) ClearUser() {
m.cleareduser = true
m.cleareduser = true
...
@@ -776,7 +942,7 @@ func (m *APIKeyMutation) Type() string {
...
@@ -776,7 +942,7 @@ func (m *APIKeyMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
// AddedFields().
func (m *APIKeyMutation) Fields() []string {
func (m *APIKeyMutation) Fields() []string {
fields := make([]string, 0, 1
0
)
fields := make([]string, 0, 1
3
)
if m.created_at != nil {
if m.created_at != nil {
fields = append(fields, apikey.FieldCreatedAt)
fields = append(fields, apikey.FieldCreatedAt)
}
}
...
@@ -807,6 +973,15 @@ func (m *APIKeyMutation) Fields() []string {
...
@@ -807,6 +973,15 @@ func (m *APIKeyMutation) Fields() []string {
if m.ip_blacklist != nil {
if m.ip_blacklist != nil {
fields = append(fields, apikey.FieldIPBlacklist)
fields = append(fields, apikey.FieldIPBlacklist)
}
}
if m.quota != nil {
fields = append(fields, apikey.FieldQuota)
}
if m.quota_used != nil {
fields = append(fields, apikey.FieldQuotaUsed)
}
if m.expires_at != nil {
fields = append(fields, apikey.FieldExpiresAt)
}
return fields
return fields
}
}
...
@@ -835,6 +1010,12 @@ func (m *APIKeyMutation) Field(name string) (ent.Value, bool) {
...
@@ -835,6 +1010,12 @@ func (m *APIKeyMutation) Field(name string) (ent.Value, bool) {
return m.IPWhitelist()
return m.IPWhitelist()
case apikey.FieldIPBlacklist:
case apikey.FieldIPBlacklist:
return m.IPBlacklist()
return m.IPBlacklist()
case apikey.FieldQuota:
return m.Quota()
case apikey.FieldQuotaUsed:
return m.QuotaUsed()
case apikey.FieldExpiresAt:
return m.ExpiresAt()
}
}
return nil, false
return nil, false
}
}
...
@@ -864,6 +1045,12 @@ func (m *APIKeyMutation) OldField(ctx context.Context, name string) (ent.Value,
...
@@ -864,6 +1045,12 @@ func (m *APIKeyMutation) OldField(ctx context.Context, name string) (ent.Value,
return m.OldIPWhitelist(ctx)
return m.OldIPWhitelist(ctx)
case apikey.FieldIPBlacklist:
case apikey.FieldIPBlacklist:
return m.OldIPBlacklist(ctx)
return m.OldIPBlacklist(ctx)
case apikey.FieldQuota:
return m.OldQuota(ctx)
case apikey.FieldQuotaUsed:
return m.OldQuotaUsed(ctx)
case apikey.FieldExpiresAt:
return m.OldExpiresAt(ctx)
}
}
return nil, fmt.Errorf("unknown APIKey field %s", name)
return nil, fmt.Errorf("unknown APIKey field %s", name)
}
}
...
@@ -943,6 +1130,27 @@ func (m *APIKeyMutation) SetField(name string, value ent.Value) error {
...
@@ -943,6 +1130,27 @@ func (m *APIKeyMutation) SetField(name string, value ent.Value) error {
}
}
m.SetIPBlacklist(v)
m.SetIPBlacklist(v)
return nil
return nil
case apikey.FieldQuota:
v, ok := value.(float64)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetQuota(v)
return nil
case apikey.FieldQuotaUsed:
v, ok := value.(float64)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetQuotaUsed(v)
return nil
case apikey.FieldExpiresAt:
v, ok := value.(time.Time)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetExpiresAt(v)
return nil
}
}
return fmt.Errorf("unknown APIKey field %s", name)
return fmt.Errorf("unknown APIKey field %s", name)
}
}
...
@@ -951,6 +1159,12 @@ func (m *APIKeyMutation) SetField(name string, value ent.Value) error {
...
@@ -951,6 +1159,12 @@ func (m *APIKeyMutation) SetField(name string, value ent.Value) error {
// this mutation.
// this mutation.
func (m *APIKeyMutation) AddedFields() []string {
func (m *APIKeyMutation) AddedFields() []string {
var fields []string
var fields []string
if m.addquota != nil {
fields = append(fields, apikey.FieldQuota)
}
if m.addquota_used != nil {
fields = append(fields, apikey.FieldQuotaUsed)
}
return fields
return fields
}
}
...
@@ -959,6 +1173,10 @@ func (m *APIKeyMutation) AddedFields() []string {
...
@@ -959,6 +1173,10 @@ func (m *APIKeyMutation) AddedFields() []string {
// was not set, or was not defined in the schema.
// was not set, or was not defined in the schema.
func (m *APIKeyMutation) AddedField(name string) (ent.Value, bool) {
func (m *APIKeyMutation) AddedField(name string) (ent.Value, bool) {
switch name {
switch name {
case apikey.FieldQuota:
return m.AddedQuota()
case apikey.FieldQuotaUsed:
return m.AddedQuotaUsed()
}
}
return nil, false
return nil, false
}
}
...
@@ -968,6 +1186,20 @@ func (m *APIKeyMutation) AddedField(name string) (ent.Value, bool) {
...
@@ -968,6 +1186,20 @@ func (m *APIKeyMutation) AddedField(name string) (ent.Value, bool) {
// type.
// type.
func (m *APIKeyMutation) AddField(name string, value ent.Value) error {
func (m *APIKeyMutation) AddField(name string, value ent.Value) error {
switch name {
switch name {
case apikey.FieldQuota:
v, ok := value.(float64)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.AddQuota(v)
return nil
case apikey.FieldQuotaUsed:
v, ok := value.(float64)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.AddQuotaUsed(v)
return nil
}
}
return fmt.Errorf("unknown APIKey numeric field %s", name)
return fmt.Errorf("unknown APIKey numeric field %s", name)
}
}
...
@@ -988,6 +1220,9 @@ func (m *APIKeyMutation) ClearedFields() []string {
...
@@ -988,6 +1220,9 @@ func (m *APIKeyMutation) ClearedFields() []string {
if m.FieldCleared(apikey.FieldIPBlacklist) {
if m.FieldCleared(apikey.FieldIPBlacklist) {
fields = append(fields, apikey.FieldIPBlacklist)
fields = append(fields, apikey.FieldIPBlacklist)
}
}
if m.FieldCleared(apikey.FieldExpiresAt) {
fields = append(fields, apikey.FieldExpiresAt)
}
return fields
return fields
}
}
...
@@ -1014,6 +1249,9 @@ func (m *APIKeyMutation) ClearField(name string) error {
...
@@ -1014,6 +1249,9 @@ func (m *APIKeyMutation) ClearField(name string) error {
case apikey.FieldIPBlacklist:
case apikey.FieldIPBlacklist:
m.ClearIPBlacklist()
m.ClearIPBlacklist()
return nil
return nil
case apikey.FieldExpiresAt:
m.ClearExpiresAt()
return nil
}
}
return fmt.Errorf("unknown APIKey nullable field %s", name)
return fmt.Errorf("unknown APIKey nullable field %s", name)
}
}
...
@@ -1052,6 +1290,15 @@ func (m *APIKeyMutation) ResetField(name string) error {
...
@@ -1052,6 +1290,15 @@ func (m *APIKeyMutation) ResetField(name string) error {
case apikey.FieldIPBlacklist:
case apikey.FieldIPBlacklist:
m.ResetIPBlacklist()
m.ResetIPBlacklist()
return nil
return nil
case apikey.FieldQuota:
m.ResetQuota()
return nil
case apikey.FieldQuotaUsed:
m.ResetQuotaUsed()
return nil
case apikey.FieldExpiresAt:
m.ResetExpiresAt()
return nil
}
}
return fmt.Errorf("unknown APIKey field %s", name)
return fmt.Errorf("unknown APIKey field %s", name)
}
}
...
...
backend/ent/runtime/runtime.go
View file @
4cce21b1
...
@@ -91,6 +91,14 @@ func init() {
...
@@ -91,6 +91,14 @@ func init() {
apikey
.
DefaultStatus
=
apikeyDescStatus
.
Default
.
(
string
)
apikey
.
DefaultStatus
=
apikeyDescStatus
.
Default
.
(
string
)
// apikey.StatusValidator is a validator for the "status" field. It is called by the builders before save.
// apikey.StatusValidator is a validator for the "status" field. It is called by the builders before save.
apikey
.
StatusValidator
=
apikeyDescStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
apikey
.
StatusValidator
=
apikeyDescStatus
.
Validators
[
0
]
.
(
func
(
string
)
error
)
// apikeyDescQuota is the schema descriptor for quota field.
apikeyDescQuota
:=
apikeyFields
[
7
]
.
Descriptor
()
// apikey.DefaultQuota holds the default value on creation for the quota field.
apikey
.
DefaultQuota
=
apikeyDescQuota
.
Default
.
(
float64
)
// apikeyDescQuotaUsed is the schema descriptor for quota_used field.
apikeyDescQuotaUsed
:=
apikeyFields
[
8
]
.
Descriptor
()
// apikey.DefaultQuotaUsed holds the default value on creation for the quota_used field.
apikey
.
DefaultQuotaUsed
=
apikeyDescQuotaUsed
.
Default
.
(
float64
)
accountMixin
:=
schema
.
Account
{}
.
Mixin
()
accountMixin
:=
schema
.
Account
{}
.
Mixin
()
accountMixinHooks1
:=
accountMixin
[
1
]
.
Hooks
()
accountMixinHooks1
:=
accountMixin
[
1
]
.
Hooks
()
account
.
Hooks
[
0
]
=
accountMixinHooks1
[
0
]
account
.
Hooks
[
0
]
=
accountMixinHooks1
[
0
]
...
...
backend/ent/schema/api_key.go
View file @
4cce21b1
...
@@ -5,6 +5,7 @@ import (
...
@@ -5,6 +5,7 @@ import (
"github.com/Wei-Shaw/sub2api/internal/domain"
"github.com/Wei-Shaw/sub2api/internal/domain"
"entgo.io/ent"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/edge"
...
@@ -52,6 +53,23 @@ func (APIKey) Fields() []ent.Field {
...
@@ -52,6 +53,23 @@ func (APIKey) Fields() []ent.Field {
field
.
JSON
(
"ip_blacklist"
,
[]
string
{})
.
field
.
JSON
(
"ip_blacklist"
,
[]
string
{})
.
Optional
()
.
Optional
()
.
Comment
(
"Blocked IPs/CIDRs"
),
Comment
(
"Blocked IPs/CIDRs"
),
// ========== Quota fields ==========
// Quota limit in USD (0 = unlimited)
field
.
Float
(
"quota"
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(20,8)"
})
.
Default
(
0
)
.
Comment
(
"Quota limit in USD for this API key (0 = unlimited)"
),
// Used quota amount
field
.
Float
(
"quota_used"
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(20,8)"
})
.
Default
(
0
)
.
Comment
(
"Used quota amount in USD"
),
// Expiration time (nil = never expires)
field
.
Time
(
"expires_at"
)
.
Optional
()
.
Nillable
()
.
Comment
(
"Expiration time for this API key (null = never expires)"
),
}
}
}
}
...
@@ -77,5 +95,8 @@ func (APIKey) Indexes() []ent.Index {
...
@@ -77,5 +95,8 @@ func (APIKey) Indexes() []ent.Index {
index
.
Fields
(
"group_id"
),
index
.
Fields
(
"group_id"
),
index
.
Fields
(
"status"
),
index
.
Fields
(
"status"
),
index
.
Fields
(
"deleted_at"
),
index
.
Fields
(
"deleted_at"
),
// Index for quota queries
index
.
Fields
(
"quota"
,
"quota_used"
),
index
.
Fields
(
"expires_at"
),
}
}
}
}
backend/internal/handler/admin/admin_service_stub_test.go
View file @
4cce21b1
...
@@ -290,5 +290,9 @@ func (s *stubAdminService) ExpireRedeemCode(ctx context.Context, id int64) (*ser
...
@@ -290,5 +290,9 @@ func (s *stubAdminService) ExpireRedeemCode(ctx context.Context, id int64) (*ser
return
&
code
,
nil
return
&
code
,
nil
}
}
func
(
s
*
stubAdminService
)
GetUserBalanceHistory
(
ctx
context
.
Context
,
userID
int64
,
page
,
pageSize
int
,
codeType
string
)
([]
service
.
RedeemCode
,
int64
,
float64
,
error
)
{
return
s
.
redeems
,
int64
(
len
(
s
.
redeems
)),
100.0
,
nil
}
// Ensure stub implements interface.
// Ensure stub implements interface.
var
_
service
.
AdminService
=
(
*
stubAdminService
)(
nil
)
var
_
service
.
AdminService
=
(
*
stubAdminService
)(
nil
)
backend/internal/handler/admin/user_handler.go
View file @
4cce21b1
...
@@ -277,3 +277,44 @@ func (h *UserHandler) GetUserUsage(c *gin.Context) {
...
@@ -277,3 +277,44 @@ func (h *UserHandler) GetUserUsage(c *gin.Context) {
response
.
Success
(
c
,
stats
)
response
.
Success
(
c
,
stats
)
}
}
// GetBalanceHistory handles getting user's balance/concurrency change history
// GET /api/v1/admin/users/:id/balance-history
// Query params:
// - type: filter by record type (balance, admin_balance, concurrency, admin_concurrency, subscription)
func
(
h
*
UserHandler
)
GetBalanceHistory
(
c
*
gin
.
Context
)
{
userID
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid user ID"
)
return
}
page
,
pageSize
:=
response
.
ParsePagination
(
c
)
codeType
:=
c
.
Query
(
"type"
)
codes
,
total
,
totalRecharged
,
err
:=
h
.
adminService
.
GetUserBalanceHistory
(
c
.
Request
.
Context
(),
userID
,
page
,
pageSize
,
codeType
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
// Convert to admin DTO (includes notes field for admin visibility)
out
:=
make
([]
dto
.
AdminRedeemCode
,
0
,
len
(
codes
))
for
i
:=
range
codes
{
out
=
append
(
out
,
*
dto
.
RedeemCodeFromServiceAdmin
(
&
codes
[
i
]))
}
// Custom response with total_recharged alongside pagination
pages
:=
int
((
total
+
int64
(
pageSize
)
-
1
)
/
int64
(
pageSize
))
if
pages
<
1
{
pages
=
1
}
response
.
Success
(
c
,
gin
.
H
{
"items"
:
out
,
"total"
:
total
,
"page"
:
page
,
"page_size"
:
pageSize
,
"pages"
:
pages
,
"total_recharged"
:
totalRecharged
,
})
}
backend/internal/handler/api_key_handler.go
View file @
4cce21b1
...
@@ -3,6 +3,7 @@ package handler
...
@@ -3,6 +3,7 @@ package handler
import
(
import
(
"strconv"
"strconv"
"time"
"github.com/Wei-Shaw/sub2api/internal/handler/dto"
"github.com/Wei-Shaw/sub2api/internal/handler/dto"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
...
@@ -27,11 +28,13 @@ func NewAPIKeyHandler(apiKeyService *service.APIKeyService) *APIKeyHandler {
...
@@ -27,11 +28,13 @@ func NewAPIKeyHandler(apiKeyService *service.APIKeyService) *APIKeyHandler {
// CreateAPIKeyRequest represents the create API key request payload
// CreateAPIKeyRequest represents the create API key request payload
type
CreateAPIKeyRequest
struct
{
type
CreateAPIKeyRequest
struct
{
Name
string
`json:"name" binding:"required"`
Name
string
`json:"name" binding:"required"`
GroupID
*
int64
`json:"group_id"`
// nullable
GroupID
*
int64
`json:"group_id"`
// nullable
CustomKey
*
string
`json:"custom_key"`
// 可选的自定义key
CustomKey
*
string
`json:"custom_key"`
// 可选的自定义key
IPWhitelist
[]
string
`json:"ip_whitelist"`
// IP 白名单
IPWhitelist
[]
string
`json:"ip_whitelist"`
// IP 白名单
IPBlacklist
[]
string
`json:"ip_blacklist"`
// IP 黑名单
IPBlacklist
[]
string
`json:"ip_blacklist"`
// IP 黑名单
Quota
*
float64
`json:"quota"`
// 配额限制 (USD)
ExpiresInDays
*
int
`json:"expires_in_days"`
// 过期天数
}
}
// UpdateAPIKeyRequest represents the update API key request payload
// UpdateAPIKeyRequest represents the update API key request payload
...
@@ -41,6 +44,9 @@ type UpdateAPIKeyRequest struct {
...
@@ -41,6 +44,9 @@ type UpdateAPIKeyRequest struct {
Status
string
`json:"status" binding:"omitempty,oneof=active inactive"`
Status
string
`json:"status" binding:"omitempty,oneof=active inactive"`
IPWhitelist
[]
string
`json:"ip_whitelist"`
// IP 白名单
IPWhitelist
[]
string
`json:"ip_whitelist"`
// IP 白名单
IPBlacklist
[]
string
`json:"ip_blacklist"`
// IP 黑名单
IPBlacklist
[]
string
`json:"ip_blacklist"`
// IP 黑名单
Quota
*
float64
`json:"quota"`
// 配额限制 (USD), 0=无限制
ExpiresAt
*
string
`json:"expires_at"`
// 过期时间 (ISO 8601)
ResetQuota
*
bool
`json:"reset_quota"`
// 重置已用配额
}
}
// List handles listing user's API keys with pagination
// List handles listing user's API keys with pagination
...
@@ -114,11 +120,15 @@ func (h *APIKeyHandler) Create(c *gin.Context) {
...
@@ -114,11 +120,15 @@ func (h *APIKeyHandler) Create(c *gin.Context) {
}
}
svcReq
:=
service
.
CreateAPIKeyRequest
{
svcReq
:=
service
.
CreateAPIKeyRequest
{
Name
:
req
.
Name
,
Name
:
req
.
Name
,
GroupID
:
req
.
GroupID
,
GroupID
:
req
.
GroupID
,
CustomKey
:
req
.
CustomKey
,
CustomKey
:
req
.
CustomKey
,
IPWhitelist
:
req
.
IPWhitelist
,
IPWhitelist
:
req
.
IPWhitelist
,
IPBlacklist
:
req
.
IPBlacklist
,
IPBlacklist
:
req
.
IPBlacklist
,
ExpiresInDays
:
req
.
ExpiresInDays
,
}
if
req
.
Quota
!=
nil
{
svcReq
.
Quota
=
*
req
.
Quota
}
}
key
,
err
:=
h
.
apiKeyService
.
Create
(
c
.
Request
.
Context
(),
subject
.
UserID
,
svcReq
)
key
,
err
:=
h
.
apiKeyService
.
Create
(
c
.
Request
.
Context
(),
subject
.
UserID
,
svcReq
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -153,6 +163,8 @@ func (h *APIKeyHandler) Update(c *gin.Context) {
...
@@ -153,6 +163,8 @@ func (h *APIKeyHandler) Update(c *gin.Context) {
svcReq
:=
service
.
UpdateAPIKeyRequest
{
svcReq
:=
service
.
UpdateAPIKeyRequest
{
IPWhitelist
:
req
.
IPWhitelist
,
IPWhitelist
:
req
.
IPWhitelist
,
IPBlacklist
:
req
.
IPBlacklist
,
IPBlacklist
:
req
.
IPBlacklist
,
Quota
:
req
.
Quota
,
ResetQuota
:
req
.
ResetQuota
,
}
}
if
req
.
Name
!=
""
{
if
req
.
Name
!=
""
{
svcReq
.
Name
=
&
req
.
Name
svcReq
.
Name
=
&
req
.
Name
...
@@ -161,6 +173,21 @@ func (h *APIKeyHandler) Update(c *gin.Context) {
...
@@ -161,6 +173,21 @@ func (h *APIKeyHandler) Update(c *gin.Context) {
if
req
.
Status
!=
""
{
if
req
.
Status
!=
""
{
svcReq
.
Status
=
&
req
.
Status
svcReq
.
Status
=
&
req
.
Status
}
}
// Parse expires_at if provided
if
req
.
ExpiresAt
!=
nil
{
if
*
req
.
ExpiresAt
==
""
{
// Empty string means clear expiration
svcReq
.
ExpiresAt
=
nil
svcReq
.
ClearExpiration
=
true
}
else
{
t
,
err
:=
time
.
Parse
(
time
.
RFC3339
,
*
req
.
ExpiresAt
)
if
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid expires_at format: "
+
err
.
Error
())
return
}
svcReq
.
ExpiresAt
=
&
t
}
}
key
,
err
:=
h
.
apiKeyService
.
Update
(
c
.
Request
.
Context
(),
keyID
,
subject
.
UserID
,
svcReq
)
key
,
err
:=
h
.
apiKeyService
.
Update
(
c
.
Request
.
Context
(),
keyID
,
subject
.
UserID
,
svcReq
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
backend/internal/handler/dto/mappers.go
View file @
4cce21b1
...
@@ -76,6 +76,9 @@ func APIKeyFromService(k *service.APIKey) *APIKey {
...
@@ -76,6 +76,9 @@ func APIKeyFromService(k *service.APIKey) *APIKey {
Status
:
k
.
Status
,
Status
:
k
.
Status
,
IPWhitelist
:
k
.
IPWhitelist
,
IPWhitelist
:
k
.
IPWhitelist
,
IPBlacklist
:
k
.
IPBlacklist
,
IPBlacklist
:
k
.
IPBlacklist
,
Quota
:
k
.
Quota
,
QuotaUsed
:
k
.
QuotaUsed
,
ExpiresAt
:
k
.
ExpiresAt
,
CreatedAt
:
k
.
CreatedAt
,
CreatedAt
:
k
.
CreatedAt
,
UpdatedAt
:
k
.
UpdatedAt
,
UpdatedAt
:
k
.
UpdatedAt
,
User
:
UserFromServiceShallow
(
k
.
User
),
User
:
UserFromServiceShallow
(
k
.
User
),
...
...
backend/internal/handler/dto/types.go
View file @
4cce21b1
...
@@ -32,16 +32,19 @@ type AdminUser struct {
...
@@ -32,16 +32,19 @@ type AdminUser struct {
}
}
type
APIKey
struct
{
type
APIKey
struct
{
ID
int64
`json:"id"`
ID
int64
`json:"id"`
UserID
int64
`json:"user_id"`
UserID
int64
`json:"user_id"`
Key
string
`json:"key"`
Key
string
`json:"key"`
Name
string
`json:"name"`
Name
string
`json:"name"`
GroupID
*
int64
`json:"group_id"`
GroupID
*
int64
`json:"group_id"`
Status
string
`json:"status"`
Status
string
`json:"status"`
IPWhitelist
[]
string
`json:"ip_whitelist"`
IPWhitelist
[]
string
`json:"ip_whitelist"`
IPBlacklist
[]
string
`json:"ip_blacklist"`
IPBlacklist
[]
string
`json:"ip_blacklist"`
CreatedAt
time
.
Time
`json:"created_at"`
Quota
float64
`json:"quota"`
// Quota limit in USD (0 = unlimited)
UpdatedAt
time
.
Time
`json:"updated_at"`
QuotaUsed
float64
`json:"quota_used"`
// Used quota amount in USD
ExpiresAt
*
time
.
Time
`json:"expires_at"`
// Expiration time (nil = never expires)
CreatedAt
time
.
Time
`json:"created_at"`
UpdatedAt
time
.
Time
`json:"updated_at"`
User
*
User
`json:"user,omitempty"`
User
*
User
`json:"user,omitempty"`
Group
*
Group
`json:"group,omitempty"`
Group
*
Group
`json:"group,omitempty"`
...
...
backend/internal/handler/gateway_handler.go
View file @
4cce21b1
...
@@ -32,6 +32,7 @@ type GatewayHandler struct {
...
@@ -32,6 +32,7 @@ type GatewayHandler struct {
userService
*
service
.
UserService
userService
*
service
.
UserService
billingCacheService
*
service
.
BillingCacheService
billingCacheService
*
service
.
BillingCacheService
usageService
*
service
.
UsageService
usageService
*
service
.
UsageService
apiKeyService
*
service
.
APIKeyService
concurrencyHelper
*
ConcurrencyHelper
concurrencyHelper
*
ConcurrencyHelper
maxAccountSwitches
int
maxAccountSwitches
int
maxAccountSwitchesGemini
int
maxAccountSwitchesGemini
int
...
@@ -46,6 +47,7 @@ func NewGatewayHandler(
...
@@ -46,6 +47,7 @@ func NewGatewayHandler(
concurrencyService
*
service
.
ConcurrencyService
,
concurrencyService
*
service
.
ConcurrencyService
,
billingCacheService
*
service
.
BillingCacheService
,
billingCacheService
*
service
.
BillingCacheService
,
usageService
*
service
.
UsageService
,
usageService
*
service
.
UsageService
,
apiKeyService
*
service
.
APIKeyService
,
cfg
*
config
.
Config
,
cfg
*
config
.
Config
,
)
*
GatewayHandler
{
)
*
GatewayHandler
{
pingInterval
:=
time
.
Duration
(
0
)
pingInterval
:=
time
.
Duration
(
0
)
...
@@ -67,6 +69,7 @@ func NewGatewayHandler(
...
@@ -67,6 +69,7 @@ func NewGatewayHandler(
userService
:
userService
,
userService
:
userService
,
billingCacheService
:
billingCacheService
,
billingCacheService
:
billingCacheService
,
usageService
:
usageService
,
usageService
:
usageService
,
apiKeyService
:
apiKeyService
,
concurrencyHelper
:
NewConcurrencyHelper
(
concurrencyService
,
SSEPingFormatClaude
,
pingInterval
),
concurrencyHelper
:
NewConcurrencyHelper
(
concurrencyService
,
SSEPingFormatClaude
,
pingInterval
),
maxAccountSwitches
:
maxAccountSwitches
,
maxAccountSwitches
:
maxAccountSwitches
,
maxAccountSwitchesGemini
:
maxAccountSwitchesGemini
,
maxAccountSwitchesGemini
:
maxAccountSwitchesGemini
,
...
@@ -321,13 +324,14 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
...
@@ -321,13 +324,14 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
if
err
:=
h
.
gatewayService
.
RecordUsage
(
ctx
,
&
service
.
RecordUsageInput
{
if
err
:=
h
.
gatewayService
.
RecordUsage
(
ctx
,
&
service
.
RecordUsageInput
{
Result
:
result
,
Result
:
result
,
APIKey
:
apiKey
,
APIKey
:
apiKey
,
User
:
apiKey
.
User
,
User
:
apiKey
.
User
,
Account
:
usedAccount
,
Account
:
usedAccount
,
Subscription
:
subscription
,
Subscription
:
subscription
,
UserAgent
:
ua
,
UserAgent
:
ua
,
IPAddress
:
clientIP
,
IPAddress
:
clientIP
,
APIKeyService
:
h
.
apiKeyService
,
});
err
!=
nil
{
});
err
!=
nil
{
log
.
Printf
(
"Record usage failed: %v"
,
err
)
log
.
Printf
(
"Record usage failed: %v"
,
err
)
}
}
...
@@ -513,13 +517,13 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
...
@@ -513,13 +517,13 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
Subscription
:
currentSubscription
,
Subscription
:
currentSubscription
,
UserAgent
:
ua
,
UserAgent
:
ua
,
IPAddress
:
clientIP
,
IPAddress
:
clientIP
,
APIKeyService
:
h
.
apiKeyService
,
});
err
!=
nil
{
});
err
!=
nil
{
log
.
Printf
(
"Record usage failed: %v"
,
err
)
log
.
Printf
(
"Record usage failed: %v"
,
err
)
}
}
}(
result
,
account
,
userAgent
,
clientIP
)
}(
result
,
account
,
userAgent
,
clientIP
)
return
return
}
}
if
!
retryWithFallback
{
if
!
retryWithFallback
{
return
return
}
}
...
...
backend/internal/handler/gemini_v1beta_handler.go
View file @
4cce21b1
...
@@ -386,6 +386,7 @@ func (h *GatewayHandler) GeminiV1BetaModels(c *gin.Context) {
...
@@ -386,6 +386,7 @@ func (h *GatewayHandler) GeminiV1BetaModels(c *gin.Context) {
IPAddress
:
ip
,
IPAddress
:
ip
,
LongContextThreshold
:
200000
,
// Gemini 200K 阈值
LongContextThreshold
:
200000
,
// Gemini 200K 阈值
LongContextMultiplier
:
2.0
,
// 超出部分双倍计费
LongContextMultiplier
:
2.0
,
// 超出部分双倍计费
APIKeyService
:
h
.
apiKeyService
,
});
err
!=
nil
{
});
err
!=
nil
{
log
.
Printf
(
"Record usage failed: %v"
,
err
)
log
.
Printf
(
"Record usage failed: %v"
,
err
)
}
}
...
...
backend/internal/handler/openai_gateway_handler.go
View file @
4cce21b1
...
@@ -24,6 +24,7 @@ import (
...
@@ -24,6 +24,7 @@ import (
type
OpenAIGatewayHandler
struct
{
type
OpenAIGatewayHandler
struct
{
gatewayService
*
service
.
OpenAIGatewayService
gatewayService
*
service
.
OpenAIGatewayService
billingCacheService
*
service
.
BillingCacheService
billingCacheService
*
service
.
BillingCacheService
apiKeyService
*
service
.
APIKeyService
concurrencyHelper
*
ConcurrencyHelper
concurrencyHelper
*
ConcurrencyHelper
maxAccountSwitches
int
maxAccountSwitches
int
}
}
...
@@ -33,6 +34,7 @@ func NewOpenAIGatewayHandler(
...
@@ -33,6 +34,7 @@ func NewOpenAIGatewayHandler(
gatewayService
*
service
.
OpenAIGatewayService
,
gatewayService
*
service
.
OpenAIGatewayService
,
concurrencyService
*
service
.
ConcurrencyService
,
concurrencyService
*
service
.
ConcurrencyService
,
billingCacheService
*
service
.
BillingCacheService
,
billingCacheService
*
service
.
BillingCacheService
,
apiKeyService
*
service
.
APIKeyService
,
cfg
*
config
.
Config
,
cfg
*
config
.
Config
,
)
*
OpenAIGatewayHandler
{
)
*
OpenAIGatewayHandler
{
pingInterval
:=
time
.
Duration
(
0
)
pingInterval
:=
time
.
Duration
(
0
)
...
@@ -46,6 +48,7 @@ func NewOpenAIGatewayHandler(
...
@@ -46,6 +48,7 @@ func NewOpenAIGatewayHandler(
return
&
OpenAIGatewayHandler
{
return
&
OpenAIGatewayHandler
{
gatewayService
:
gatewayService
,
gatewayService
:
gatewayService
,
billingCacheService
:
billingCacheService
,
billingCacheService
:
billingCacheService
,
apiKeyService
:
apiKeyService
,
concurrencyHelper
:
NewConcurrencyHelper
(
concurrencyService
,
SSEPingFormatComment
,
pingInterval
),
concurrencyHelper
:
NewConcurrencyHelper
(
concurrencyService
,
SSEPingFormatComment
,
pingInterval
),
maxAccountSwitches
:
maxAccountSwitches
,
maxAccountSwitches
:
maxAccountSwitches
,
}
}
...
@@ -299,13 +302,14 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) {
...
@@ -299,13 +302,14 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) {
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
if
err
:=
h
.
gatewayService
.
RecordUsage
(
ctx
,
&
service
.
OpenAIRecordUsageInput
{
if
err
:=
h
.
gatewayService
.
RecordUsage
(
ctx
,
&
service
.
OpenAIRecordUsageInput
{
Result
:
result
,
Result
:
result
,
APIKey
:
apiKey
,
APIKey
:
apiKey
,
User
:
apiKey
.
User
,
User
:
apiKey
.
User
,
Account
:
usedAccount
,
Account
:
usedAccount
,
Subscription
:
subscription
,
Subscription
:
subscription
,
UserAgent
:
ua
,
UserAgent
:
ua
,
IPAddress
:
ip
,
IPAddress
:
ip
,
APIKeyService
:
h
.
apiKeyService
,
});
err
!=
nil
{
});
err
!=
nil
{
log
.
Printf
(
"Record usage failed: %v"
,
err
)
log
.
Printf
(
"Record usage failed: %v"
,
err
)
}
}
...
...
backend/internal/repository/api_key_repo.go
View file @
4cce21b1
...
@@ -33,7 +33,10 @@ func (r *apiKeyRepository) Create(ctx context.Context, key *service.APIKey) erro
...
@@ -33,7 +33,10 @@ func (r *apiKeyRepository) Create(ctx context.Context, key *service.APIKey) erro
SetKey
(
key
.
Key
)
.
SetKey
(
key
.
Key
)
.
SetName
(
key
.
Name
)
.
SetName
(
key
.
Name
)
.
SetStatus
(
key
.
Status
)
.
SetStatus
(
key
.
Status
)
.
SetNillableGroupID
(
key
.
GroupID
)
SetNillableGroupID
(
key
.
GroupID
)
.
SetQuota
(
key
.
Quota
)
.
SetQuotaUsed
(
key
.
QuotaUsed
)
.
SetNillableExpiresAt
(
key
.
ExpiresAt
)
if
len
(
key
.
IPWhitelist
)
>
0
{
if
len
(
key
.
IPWhitelist
)
>
0
{
builder
.
SetIPWhitelist
(
key
.
IPWhitelist
)
builder
.
SetIPWhitelist
(
key
.
IPWhitelist
)
...
@@ -110,6 +113,9 @@ func (r *apiKeyRepository) GetByKeyForAuth(ctx context.Context, key string) (*se
...
@@ -110,6 +113,9 @@ func (r *apiKeyRepository) GetByKeyForAuth(ctx context.Context, key string) (*se
apikey
.
FieldStatus
,
apikey
.
FieldStatus
,
apikey
.
FieldIPWhitelist
,
apikey
.
FieldIPWhitelist
,
apikey
.
FieldIPBlacklist
,
apikey
.
FieldIPBlacklist
,
apikey
.
FieldQuota
,
apikey
.
FieldQuotaUsed
,
apikey
.
FieldExpiresAt
,
)
.
)
.
WithUser
(
func
(
q
*
dbent
.
UserQuery
)
{
WithUser
(
func
(
q
*
dbent
.
UserQuery
)
{
q
.
Select
(
q
.
Select
(
...
@@ -164,6 +170,8 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro
...
@@ -164,6 +170,8 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro
Where
(
apikey
.
IDEQ
(
key
.
ID
),
apikey
.
DeletedAtIsNil
())
.
Where
(
apikey
.
IDEQ
(
key
.
ID
),
apikey
.
DeletedAtIsNil
())
.
SetName
(
key
.
Name
)
.
SetName
(
key
.
Name
)
.
SetStatus
(
key
.
Status
)
.
SetStatus
(
key
.
Status
)
.
SetQuota
(
key
.
Quota
)
.
SetQuotaUsed
(
key
.
QuotaUsed
)
.
SetUpdatedAt
(
now
)
SetUpdatedAt
(
now
)
if
key
.
GroupID
!=
nil
{
if
key
.
GroupID
!=
nil
{
builder
.
SetGroupID
(
*
key
.
GroupID
)
builder
.
SetGroupID
(
*
key
.
GroupID
)
...
@@ -171,6 +179,13 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro
...
@@ -171,6 +179,13 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro
builder
.
ClearGroupID
()
builder
.
ClearGroupID
()
}
}
// Expiration time
if
key
.
ExpiresAt
!=
nil
{
builder
.
SetExpiresAt
(
*
key
.
ExpiresAt
)
}
else
{
builder
.
ClearExpiresAt
()
}
// IP 限制字段
// IP 限制字段
if
len
(
key
.
IPWhitelist
)
>
0
{
if
len
(
key
.
IPWhitelist
)
>
0
{
builder
.
SetIPWhitelist
(
key
.
IPWhitelist
)
builder
.
SetIPWhitelist
(
key
.
IPWhitelist
)
...
@@ -360,6 +375,38 @@ func (r *apiKeyRepository) ListKeysByGroupID(ctx context.Context, groupID int64)
...
@@ -360,6 +375,38 @@ func (r *apiKeyRepository) ListKeysByGroupID(ctx context.Context, groupID int64)
return
keys
,
nil
return
keys
,
nil
}
}
// IncrementQuotaUsed atomically increments the quota_used field and returns the new value
func
(
r
*
apiKeyRepository
)
IncrementQuotaUsed
(
ctx
context
.
Context
,
id
int64
,
amount
float64
)
(
float64
,
error
)
{
// Use raw SQL for atomic increment to avoid race conditions
// First get current value
m
,
err
:=
r
.
activeQuery
()
.
Where
(
apikey
.
IDEQ
(
id
))
.
Select
(
apikey
.
FieldQuotaUsed
)
.
Only
(
ctx
)
if
err
!=
nil
{
if
dbent
.
IsNotFound
(
err
)
{
return
0
,
service
.
ErrAPIKeyNotFound
}
return
0
,
err
}
newValue
:=
m
.
QuotaUsed
+
amount
// Update with new value
affected
,
err
:=
r
.
client
.
APIKey
.
Update
()
.
Where
(
apikey
.
IDEQ
(
id
),
apikey
.
DeletedAtIsNil
())
.
SetQuotaUsed
(
newValue
)
.
Save
(
ctx
)
if
err
!=
nil
{
return
0
,
err
}
if
affected
==
0
{
return
0
,
service
.
ErrAPIKeyNotFound
}
return
newValue
,
nil
}
func
apiKeyEntityToService
(
m
*
dbent
.
APIKey
)
*
service
.
APIKey
{
func
apiKeyEntityToService
(
m
*
dbent
.
APIKey
)
*
service
.
APIKey
{
if
m
==
nil
{
if
m
==
nil
{
return
nil
return
nil
...
@@ -375,6 +422,9 @@ func apiKeyEntityToService(m *dbent.APIKey) *service.APIKey {
...
@@ -375,6 +422,9 @@ func apiKeyEntityToService(m *dbent.APIKey) *service.APIKey {
CreatedAt
:
m
.
CreatedAt
,
CreatedAt
:
m
.
CreatedAt
,
UpdatedAt
:
m
.
UpdatedAt
,
UpdatedAt
:
m
.
UpdatedAt
,
GroupID
:
m
.
GroupID
,
GroupID
:
m
.
GroupID
,
Quota
:
m
.
Quota
,
QuotaUsed
:
m
.
QuotaUsed
,
ExpiresAt
:
m
.
ExpiresAt
,
}
}
if
m
.
Edges
.
User
!=
nil
{
if
m
.
Edges
.
User
!=
nil
{
out
.
User
=
userEntityToService
(
m
.
Edges
.
User
)
out
.
User
=
userEntityToService
(
m
.
Edges
.
User
)
...
...
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment