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
a80ec5d8
Commit
a80ec5d8
authored
Mar 03, 2026
by
shaw
Browse files
feat: apikey支持5h/1d/7d速率控制
parent
b7df7ce5
Changes
33
Expand all
Hide whitespace changes
Inline
Side-by-side
backend/cmd/server/wire_gen.go
View file @
a80ec5d8
...
@@ -58,11 +58,12 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
...
@@ -58,11 +58,12 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
promoCodeRepository
:=
repository
.
NewPromoCodeRepository
(
client
)
promoCodeRepository
:=
repository
.
NewPromoCodeRepository
(
client
)
billingCache
:=
repository
.
NewBillingCache
(
redisClient
)
billingCache
:=
repository
.
NewBillingCache
(
redisClient
)
userSubscriptionRepository
:=
repository
.
NewUserSubscriptionRepository
(
client
)
userSubscriptionRepository
:=
repository
.
NewUserSubscriptionRepository
(
client
)
billingCacheService
:=
service
.
NewBillingCacheService
(
billingCache
,
userRepository
,
userSubscriptionRepository
,
configConfig
)
apiKeyRepository
:=
repository
.
NewAPIKeyRepository
(
client
,
db
)
apiKeyRepository
:=
r
epository
.
NewAPI
KeyRepository
(
client
)
billingCacheService
:=
service
.
NewBillingCacheService
(
billingCache
,
userRepository
,
userSubscriptionR
epository
,
api
KeyRepository
,
configConfig
)
userGroupRateRepository
:=
repository
.
NewUserGroupRateRepository
(
db
)
userGroupRateRepository
:=
repository
.
NewUserGroupRateRepository
(
db
)
apiKeyCache
:=
repository
.
NewAPIKeyCache
(
redisClient
)
apiKeyCache
:=
repository
.
NewAPIKeyCache
(
redisClient
)
apiKeyService
:=
service
.
NewAPIKeyService
(
apiKeyRepository
,
userRepository
,
groupRepository
,
userSubscriptionRepository
,
userGroupRateRepository
,
apiKeyCache
,
configConfig
)
apiKeyService
:=
service
.
NewAPIKeyService
(
apiKeyRepository
,
userRepository
,
groupRepository
,
userSubscriptionRepository
,
userGroupRateRepository
,
apiKeyCache
,
configConfig
)
apiKeyService
.
SetRateLimitCacheInvalidator
(
billingCache
)
apiKeyAuthCacheInvalidator
:=
service
.
ProvideAPIKeyAuthCacheInvalidator
(
apiKeyService
)
apiKeyAuthCacheInvalidator
:=
service
.
ProvideAPIKeyAuthCacheInvalidator
(
apiKeyService
)
promoService
:=
service
.
NewPromoService
(
promoCodeRepository
,
userRepository
,
billingCacheService
,
client
,
apiKeyAuthCacheInvalidator
)
promoService
:=
service
.
NewPromoService
(
promoCodeRepository
,
userRepository
,
billingCacheService
,
client
,
apiKeyAuthCacheInvalidator
)
subscriptionService
:=
service
.
NewSubscriptionService
(
groupRepository
,
userSubscriptionRepository
,
billingCacheService
,
client
,
configConfig
)
subscriptionService
:=
service
.
NewSubscriptionService
(
groupRepository
,
userSubscriptionRepository
,
billingCacheService
,
client
,
configConfig
)
...
...
backend/cmd/server/wire_gen_test.go
View file @
a80ec5d8
...
@@ -42,7 +42,7 @@ func TestProvideCleanup_WithMinimalDependencies_NoPanic(t *testing.T) {
...
@@ -42,7 +42,7 @@ func TestProvideCleanup_WithMinimalDependencies_NoPanic(t *testing.T) {
subscriptionExpirySvc
:=
service
.
NewSubscriptionExpiryService
(
nil
,
time
.
Second
)
subscriptionExpirySvc
:=
service
.
NewSubscriptionExpiryService
(
nil
,
time
.
Second
)
pricingSvc
:=
service
.
NewPricingService
(
cfg
,
nil
)
pricingSvc
:=
service
.
NewPricingService
(
cfg
,
nil
)
emailQueueSvc
:=
service
.
NewEmailQueueService
(
nil
,
1
)
emailQueueSvc
:=
service
.
NewEmailQueueService
(
nil
,
1
)
billingCacheSvc
:=
service
.
NewBillingCacheService
(
nil
,
nil
,
nil
,
cfg
)
billingCacheSvc
:=
service
.
NewBillingCacheService
(
nil
,
nil
,
nil
,
nil
,
cfg
)
idempotencyCleanupSvc
:=
service
.
NewIdempotencyCleanupService
(
nil
,
cfg
)
idempotencyCleanupSvc
:=
service
.
NewIdempotencyCleanupService
(
nil
,
cfg
)
schedulerSnapshotSvc
:=
service
.
NewSchedulerSnapshotService
(
nil
,
nil
,
nil
,
nil
,
cfg
)
schedulerSnapshotSvc
:=
service
.
NewSchedulerSnapshotService
(
nil
,
nil
,
nil
,
nil
,
cfg
)
opsSystemLogSinkSvc
:=
service
.
NewOpsSystemLogSink
(
nil
)
opsSystemLogSinkSvc
:=
service
.
NewOpsSystemLogSink
(
nil
)
...
...
backend/ent/apikey.go
View file @
a80ec5d8
...
@@ -48,6 +48,24 @@ type APIKey struct {
...
@@ -48,6 +48,24 @@ type APIKey struct {
QuotaUsed
float64
`json:"quota_used,omitempty"`
QuotaUsed
float64
`json:"quota_used,omitempty"`
// Expiration time for this API key (null = never expires)
// Expiration time for this API key (null = never expires)
ExpiresAt
*
time
.
Time
`json:"expires_at,omitempty"`
ExpiresAt
*
time
.
Time
`json:"expires_at,omitempty"`
// Rate limit in USD per 5 hours (0 = unlimited)
RateLimit5h
float64
`json:"rate_limit_5h,omitempty"`
// Rate limit in USD per day (0 = unlimited)
RateLimit1d
float64
`json:"rate_limit_1d,omitempty"`
// Rate limit in USD per 7 days (0 = unlimited)
RateLimit7d
float64
`json:"rate_limit_7d,omitempty"`
// Used amount in USD for the current 5h window
Usage5h
float64
`json:"usage_5h,omitempty"`
// Used amount in USD for the current 1d window
Usage1d
float64
`json:"usage_1d,omitempty"`
// Used amount in USD for the current 7d window
Usage7d
float64
`json:"usage_7d,omitempty"`
// Start time of the current 5h rate limit window
Window5hStart
*
time
.
Time
`json:"window_5h_start,omitempty"`
// Start time of the current 1d rate limit window
Window1dStart
*
time
.
Time
`json:"window_1d_start,omitempty"`
// Start time of the current 7d rate limit window
Window7dStart
*
time
.
Time
`json:"window_7d_start,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"`
...
@@ -105,13 +123,13 @@ func (*APIKey) scanValues(columns []string) ([]any, error) {
...
@@ -105,13 +123,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
:
case
apikey
.
FieldQuota
,
apikey
.
FieldQuotaUsed
,
apikey
.
FieldRateLimit5h
,
apikey
.
FieldRateLimit1d
,
apikey
.
FieldRateLimit7d
,
apikey
.
FieldUsage5h
,
apikey
.
FieldUsage1d
,
apikey
.
FieldUsage7d
:
values
[
i
]
=
new
(
sql
.
NullFloat64
)
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
,
apikey
.
FieldLastUsedAt
,
apikey
.
FieldExpiresAt
:
case
apikey
.
FieldCreatedAt
,
apikey
.
FieldUpdatedAt
,
apikey
.
FieldDeletedAt
,
apikey
.
FieldLastUsedAt
,
apikey
.
FieldExpiresAt
,
apikey
.
FieldWindow5hStart
,
apikey
.
FieldWindow1dStart
,
apikey
.
FieldWindow7dStart
:
values
[
i
]
=
new
(
sql
.
NullTime
)
values
[
i
]
=
new
(
sql
.
NullTime
)
default
:
default
:
values
[
i
]
=
new
(
sql
.
UnknownType
)
values
[
i
]
=
new
(
sql
.
UnknownType
)
...
@@ -226,6 +244,63 @@ func (_m *APIKey) assignValues(columns []string, values []any) error {
...
@@ -226,6 +244,63 @@ func (_m *APIKey) assignValues(columns []string, values []any) error {
_m
.
ExpiresAt
=
new
(
time
.
Time
)
_m
.
ExpiresAt
=
new
(
time
.
Time
)
*
_m
.
ExpiresAt
=
value
.
Time
*
_m
.
ExpiresAt
=
value
.
Time
}
}
case
apikey
.
FieldRateLimit5h
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field rate_limit_5h"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
RateLimit5h
=
value
.
Float64
}
case
apikey
.
FieldRateLimit1d
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field rate_limit_1d"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
RateLimit1d
=
value
.
Float64
}
case
apikey
.
FieldRateLimit7d
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field rate_limit_7d"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
RateLimit7d
=
value
.
Float64
}
case
apikey
.
FieldUsage5h
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field usage_5h"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Usage5h
=
value
.
Float64
}
case
apikey
.
FieldUsage1d
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field usage_1d"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Usage1d
=
value
.
Float64
}
case
apikey
.
FieldUsage7d
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullFloat64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field usage_7d"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Usage7d
=
value
.
Float64
}
case
apikey
.
FieldWindow5hStart
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field window_5h_start"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Window5hStart
=
new
(
time
.
Time
)
*
_m
.
Window5hStart
=
value
.
Time
}
case
apikey
.
FieldWindow1dStart
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field window_1d_start"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Window1dStart
=
new
(
time
.
Time
)
*
_m
.
Window1dStart
=
value
.
Time
}
case
apikey
.
FieldWindow7dStart
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field window_7d_start"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Window7dStart
=
new
(
time
.
Time
)
*
_m
.
Window7dStart
=
value
.
Time
}
default
:
default
:
_m
.
selectValues
.
Set
(
columns
[
i
],
values
[
i
])
_m
.
selectValues
.
Set
(
columns
[
i
],
values
[
i
])
}
}
...
@@ -326,6 +401,39 @@ func (_m *APIKey) String() string {
...
@@ -326,6 +401,39 @@ func (_m *APIKey) String() string {
builder
.
WriteString
(
"expires_at="
)
builder
.
WriteString
(
"expires_at="
)
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
}
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"rate_limit_5h="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
RateLimit5h
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"rate_limit_1d="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
RateLimit1d
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"rate_limit_7d="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
RateLimit7d
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"usage_5h="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Usage5h
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"usage_1d="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Usage1d
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"usage_7d="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Usage7d
))
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
Window5hStart
;
v
!=
nil
{
builder
.
WriteString
(
"window_5h_start="
)
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
Window1dStart
;
v
!=
nil
{
builder
.
WriteString
(
"window_1d_start="
)
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
Window7dStart
;
v
!=
nil
{
builder
.
WriteString
(
"window_7d_start="
)
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
builder
.
WriteByte
(
')'
)
builder
.
WriteByte
(
')'
)
return
builder
.
String
()
return
builder
.
String
()
}
}
...
...
backend/ent/apikey/apikey.go
View file @
a80ec5d8
...
@@ -43,6 +43,24 @@ const (
...
@@ -43,6 +43,24 @@ const (
FieldQuotaUsed
=
"quota_used"
FieldQuotaUsed
=
"quota_used"
// FieldExpiresAt holds the string denoting the expires_at field in the database.
// FieldExpiresAt holds the string denoting the expires_at field in the database.
FieldExpiresAt
=
"expires_at"
FieldExpiresAt
=
"expires_at"
// FieldRateLimit5h holds the string denoting the rate_limit_5h field in the database.
FieldRateLimit5h
=
"rate_limit_5h"
// FieldRateLimit1d holds the string denoting the rate_limit_1d field in the database.
FieldRateLimit1d
=
"rate_limit_1d"
// FieldRateLimit7d holds the string denoting the rate_limit_7d field in the database.
FieldRateLimit7d
=
"rate_limit_7d"
// FieldUsage5h holds the string denoting the usage_5h field in the database.
FieldUsage5h
=
"usage_5h"
// FieldUsage1d holds the string denoting the usage_1d field in the database.
FieldUsage1d
=
"usage_1d"
// FieldUsage7d holds the string denoting the usage_7d field in the database.
FieldUsage7d
=
"usage_7d"
// FieldWindow5hStart holds the string denoting the window_5h_start field in the database.
FieldWindow5hStart
=
"window_5h_start"
// FieldWindow1dStart holds the string denoting the window_1d_start field in the database.
FieldWindow1dStart
=
"window_1d_start"
// FieldWindow7dStart holds the string denoting the window_7d_start field in the database.
FieldWindow7dStart
=
"window_7d_start"
// 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.
...
@@ -91,6 +109,15 @@ var Columns = []string{
...
@@ -91,6 +109,15 @@ var Columns = []string{
FieldQuota
,
FieldQuota
,
FieldQuotaUsed
,
FieldQuotaUsed
,
FieldExpiresAt
,
FieldExpiresAt
,
FieldRateLimit5h
,
FieldRateLimit1d
,
FieldRateLimit7d
,
FieldUsage5h
,
FieldUsage1d
,
FieldUsage7d
,
FieldWindow5hStart
,
FieldWindow1dStart
,
FieldWindow7dStart
,
}
}
// 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).
...
@@ -129,6 +156,18 @@ var (
...
@@ -129,6 +156,18 @@ var (
DefaultQuota
float64
DefaultQuota
float64
// DefaultQuotaUsed holds the default value on creation for the "quota_used" field.
// DefaultQuotaUsed holds the default value on creation for the "quota_used" field.
DefaultQuotaUsed
float64
DefaultQuotaUsed
float64
// DefaultRateLimit5h holds the default value on creation for the "rate_limit_5h" field.
DefaultRateLimit5h
float64
// DefaultRateLimit1d holds the default value on creation for the "rate_limit_1d" field.
DefaultRateLimit1d
float64
// DefaultRateLimit7d holds the default value on creation for the "rate_limit_7d" field.
DefaultRateLimit7d
float64
// DefaultUsage5h holds the default value on creation for the "usage_5h" field.
DefaultUsage5h
float64
// DefaultUsage1d holds the default value on creation for the "usage_1d" field.
DefaultUsage1d
float64
// DefaultUsage7d holds the default value on creation for the "usage_7d" field.
DefaultUsage7d
float64
)
)
// OrderOption defines the ordering options for the APIKey queries.
// OrderOption defines the ordering options for the APIKey queries.
...
@@ -199,6 +238,51 @@ func ByExpiresAt(opts ...sql.OrderTermOption) OrderOption {
...
@@ -199,6 +238,51 @@ func ByExpiresAt(opts ...sql.OrderTermOption) OrderOption {
return
sql
.
OrderByField
(
FieldExpiresAt
,
opts
...
)
.
ToFunc
()
return
sql
.
OrderByField
(
FieldExpiresAt
,
opts
...
)
.
ToFunc
()
}
}
// ByRateLimit5h orders the results by the rate_limit_5h field.
func
ByRateLimit5h
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldRateLimit5h
,
opts
...
)
.
ToFunc
()
}
// ByRateLimit1d orders the results by the rate_limit_1d field.
func
ByRateLimit1d
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldRateLimit1d
,
opts
...
)
.
ToFunc
()
}
// ByRateLimit7d orders the results by the rate_limit_7d field.
func
ByRateLimit7d
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldRateLimit7d
,
opts
...
)
.
ToFunc
()
}
// ByUsage5h orders the results by the usage_5h field.
func
ByUsage5h
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldUsage5h
,
opts
...
)
.
ToFunc
()
}
// ByUsage1d orders the results by the usage_1d field.
func
ByUsage1d
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldUsage1d
,
opts
...
)
.
ToFunc
()
}
// ByUsage7d orders the results by the usage_7d field.
func
ByUsage7d
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldUsage7d
,
opts
...
)
.
ToFunc
()
}
// ByWindow5hStart orders the results by the window_5h_start field.
func
ByWindow5hStart
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldWindow5hStart
,
opts
...
)
.
ToFunc
()
}
// ByWindow1dStart orders the results by the window_1d_start field.
func
ByWindow1dStart
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldWindow1dStart
,
opts
...
)
.
ToFunc
()
}
// ByWindow7dStart orders the results by the window_7d_start field.
func
ByWindow7dStart
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldWindow7dStart
,
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 @
a80ec5d8
...
@@ -115,6 +115,51 @@ func ExpiresAt(v time.Time) predicate.APIKey {
...
@@ -115,6 +115,51 @@ func ExpiresAt(v time.Time) predicate.APIKey {
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldExpiresAt
,
v
))
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldExpiresAt
,
v
))
}
}
// RateLimit5h applies equality check predicate on the "rate_limit_5h" field. It's identical to RateLimit5hEQ.
func
RateLimit5h
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldRateLimit5h
,
v
))
}
// RateLimit1d applies equality check predicate on the "rate_limit_1d" field. It's identical to RateLimit1dEQ.
func
RateLimit1d
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldRateLimit1d
,
v
))
}
// RateLimit7d applies equality check predicate on the "rate_limit_7d" field. It's identical to RateLimit7dEQ.
func
RateLimit7d
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldRateLimit7d
,
v
))
}
// Usage5h applies equality check predicate on the "usage_5h" field. It's identical to Usage5hEQ.
func
Usage5h
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldUsage5h
,
v
))
}
// Usage1d applies equality check predicate on the "usage_1d" field. It's identical to Usage1dEQ.
func
Usage1d
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldUsage1d
,
v
))
}
// Usage7d applies equality check predicate on the "usage_7d" field. It's identical to Usage7dEQ.
func
Usage7d
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldUsage7d
,
v
))
}
// Window5hStart applies equality check predicate on the "window_5h_start" field. It's identical to Window5hStartEQ.
func
Window5hStart
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldWindow5hStart
,
v
))
}
// Window1dStart applies equality check predicate on the "window_1d_start" field. It's identical to Window1dStartEQ.
func
Window1dStart
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldWindow1dStart
,
v
))
}
// Window7dStart applies equality check predicate on the "window_7d_start" field. It's identical to Window7dStartEQ.
func
Window7dStart
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldWindow7dStart
,
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
))
...
@@ -690,6 +735,396 @@ func ExpiresAtNotNil() predicate.APIKey {
...
@@ -690,6 +735,396 @@ func ExpiresAtNotNil() predicate.APIKey {
return
predicate
.
APIKey
(
sql
.
FieldNotNull
(
FieldExpiresAt
))
return
predicate
.
APIKey
(
sql
.
FieldNotNull
(
FieldExpiresAt
))
}
}
// RateLimit5hEQ applies the EQ predicate on the "rate_limit_5h" field.
func
RateLimit5hEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldRateLimit5h
,
v
))
}
// RateLimit5hNEQ applies the NEQ predicate on the "rate_limit_5h" field.
func
RateLimit5hNEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldRateLimit5h
,
v
))
}
// RateLimit5hIn applies the In predicate on the "rate_limit_5h" field.
func
RateLimit5hIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldRateLimit5h
,
vs
...
))
}
// RateLimit5hNotIn applies the NotIn predicate on the "rate_limit_5h" field.
func
RateLimit5hNotIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldRateLimit5h
,
vs
...
))
}
// RateLimit5hGT applies the GT predicate on the "rate_limit_5h" field.
func
RateLimit5hGT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldRateLimit5h
,
v
))
}
// RateLimit5hGTE applies the GTE predicate on the "rate_limit_5h" field.
func
RateLimit5hGTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldRateLimit5h
,
v
))
}
// RateLimit5hLT applies the LT predicate on the "rate_limit_5h" field.
func
RateLimit5hLT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldRateLimit5h
,
v
))
}
// RateLimit5hLTE applies the LTE predicate on the "rate_limit_5h" field.
func
RateLimit5hLTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldRateLimit5h
,
v
))
}
// RateLimit1dEQ applies the EQ predicate on the "rate_limit_1d" field.
func
RateLimit1dEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldRateLimit1d
,
v
))
}
// RateLimit1dNEQ applies the NEQ predicate on the "rate_limit_1d" field.
func
RateLimit1dNEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldRateLimit1d
,
v
))
}
// RateLimit1dIn applies the In predicate on the "rate_limit_1d" field.
func
RateLimit1dIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldRateLimit1d
,
vs
...
))
}
// RateLimit1dNotIn applies the NotIn predicate on the "rate_limit_1d" field.
func
RateLimit1dNotIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldRateLimit1d
,
vs
...
))
}
// RateLimit1dGT applies the GT predicate on the "rate_limit_1d" field.
func
RateLimit1dGT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldRateLimit1d
,
v
))
}
// RateLimit1dGTE applies the GTE predicate on the "rate_limit_1d" field.
func
RateLimit1dGTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldRateLimit1d
,
v
))
}
// RateLimit1dLT applies the LT predicate on the "rate_limit_1d" field.
func
RateLimit1dLT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldRateLimit1d
,
v
))
}
// RateLimit1dLTE applies the LTE predicate on the "rate_limit_1d" field.
func
RateLimit1dLTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldRateLimit1d
,
v
))
}
// RateLimit7dEQ applies the EQ predicate on the "rate_limit_7d" field.
func
RateLimit7dEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldRateLimit7d
,
v
))
}
// RateLimit7dNEQ applies the NEQ predicate on the "rate_limit_7d" field.
func
RateLimit7dNEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldRateLimit7d
,
v
))
}
// RateLimit7dIn applies the In predicate on the "rate_limit_7d" field.
func
RateLimit7dIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldRateLimit7d
,
vs
...
))
}
// RateLimit7dNotIn applies the NotIn predicate on the "rate_limit_7d" field.
func
RateLimit7dNotIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldRateLimit7d
,
vs
...
))
}
// RateLimit7dGT applies the GT predicate on the "rate_limit_7d" field.
func
RateLimit7dGT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldRateLimit7d
,
v
))
}
// RateLimit7dGTE applies the GTE predicate on the "rate_limit_7d" field.
func
RateLimit7dGTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldRateLimit7d
,
v
))
}
// RateLimit7dLT applies the LT predicate on the "rate_limit_7d" field.
func
RateLimit7dLT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldRateLimit7d
,
v
))
}
// RateLimit7dLTE applies the LTE predicate on the "rate_limit_7d" field.
func
RateLimit7dLTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldRateLimit7d
,
v
))
}
// Usage5hEQ applies the EQ predicate on the "usage_5h" field.
func
Usage5hEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldUsage5h
,
v
))
}
// Usage5hNEQ applies the NEQ predicate on the "usage_5h" field.
func
Usage5hNEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldUsage5h
,
v
))
}
// Usage5hIn applies the In predicate on the "usage_5h" field.
func
Usage5hIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldUsage5h
,
vs
...
))
}
// Usage5hNotIn applies the NotIn predicate on the "usage_5h" field.
func
Usage5hNotIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldUsage5h
,
vs
...
))
}
// Usage5hGT applies the GT predicate on the "usage_5h" field.
func
Usage5hGT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldUsage5h
,
v
))
}
// Usage5hGTE applies the GTE predicate on the "usage_5h" field.
func
Usage5hGTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldUsage5h
,
v
))
}
// Usage5hLT applies the LT predicate on the "usage_5h" field.
func
Usage5hLT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldUsage5h
,
v
))
}
// Usage5hLTE applies the LTE predicate on the "usage_5h" field.
func
Usage5hLTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldUsage5h
,
v
))
}
// Usage1dEQ applies the EQ predicate on the "usage_1d" field.
func
Usage1dEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldUsage1d
,
v
))
}
// Usage1dNEQ applies the NEQ predicate on the "usage_1d" field.
func
Usage1dNEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldUsage1d
,
v
))
}
// Usage1dIn applies the In predicate on the "usage_1d" field.
func
Usage1dIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldUsage1d
,
vs
...
))
}
// Usage1dNotIn applies the NotIn predicate on the "usage_1d" field.
func
Usage1dNotIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldUsage1d
,
vs
...
))
}
// Usage1dGT applies the GT predicate on the "usage_1d" field.
func
Usage1dGT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldUsage1d
,
v
))
}
// Usage1dGTE applies the GTE predicate on the "usage_1d" field.
func
Usage1dGTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldUsage1d
,
v
))
}
// Usage1dLT applies the LT predicate on the "usage_1d" field.
func
Usage1dLT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldUsage1d
,
v
))
}
// Usage1dLTE applies the LTE predicate on the "usage_1d" field.
func
Usage1dLTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldUsage1d
,
v
))
}
// Usage7dEQ applies the EQ predicate on the "usage_7d" field.
func
Usage7dEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldUsage7d
,
v
))
}
// Usage7dNEQ applies the NEQ predicate on the "usage_7d" field.
func
Usage7dNEQ
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldUsage7d
,
v
))
}
// Usage7dIn applies the In predicate on the "usage_7d" field.
func
Usage7dIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldUsage7d
,
vs
...
))
}
// Usage7dNotIn applies the NotIn predicate on the "usage_7d" field.
func
Usage7dNotIn
(
vs
...
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldUsage7d
,
vs
...
))
}
// Usage7dGT applies the GT predicate on the "usage_7d" field.
func
Usage7dGT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldUsage7d
,
v
))
}
// Usage7dGTE applies the GTE predicate on the "usage_7d" field.
func
Usage7dGTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldUsage7d
,
v
))
}
// Usage7dLT applies the LT predicate on the "usage_7d" field.
func
Usage7dLT
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldUsage7d
,
v
))
}
// Usage7dLTE applies the LTE predicate on the "usage_7d" field.
func
Usage7dLTE
(
v
float64
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldUsage7d
,
v
))
}
// Window5hStartEQ applies the EQ predicate on the "window_5h_start" field.
func
Window5hStartEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldWindow5hStart
,
v
))
}
// Window5hStartNEQ applies the NEQ predicate on the "window_5h_start" field.
func
Window5hStartNEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldWindow5hStart
,
v
))
}
// Window5hStartIn applies the In predicate on the "window_5h_start" field.
func
Window5hStartIn
(
vs
...
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldWindow5hStart
,
vs
...
))
}
// Window5hStartNotIn applies the NotIn predicate on the "window_5h_start" field.
func
Window5hStartNotIn
(
vs
...
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldWindow5hStart
,
vs
...
))
}
// Window5hStartGT applies the GT predicate on the "window_5h_start" field.
func
Window5hStartGT
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldWindow5hStart
,
v
))
}
// Window5hStartGTE applies the GTE predicate on the "window_5h_start" field.
func
Window5hStartGTE
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldWindow5hStart
,
v
))
}
// Window5hStartLT applies the LT predicate on the "window_5h_start" field.
func
Window5hStartLT
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldWindow5hStart
,
v
))
}
// Window5hStartLTE applies the LTE predicate on the "window_5h_start" field.
func
Window5hStartLTE
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldWindow5hStart
,
v
))
}
// Window5hStartIsNil applies the IsNil predicate on the "window_5h_start" field.
func
Window5hStartIsNil
()
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIsNull
(
FieldWindow5hStart
))
}
// Window5hStartNotNil applies the NotNil predicate on the "window_5h_start" field.
func
Window5hStartNotNil
()
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotNull
(
FieldWindow5hStart
))
}
// Window1dStartEQ applies the EQ predicate on the "window_1d_start" field.
func
Window1dStartEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldWindow1dStart
,
v
))
}
// Window1dStartNEQ applies the NEQ predicate on the "window_1d_start" field.
func
Window1dStartNEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldWindow1dStart
,
v
))
}
// Window1dStartIn applies the In predicate on the "window_1d_start" field.
func
Window1dStartIn
(
vs
...
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldWindow1dStart
,
vs
...
))
}
// Window1dStartNotIn applies the NotIn predicate on the "window_1d_start" field.
func
Window1dStartNotIn
(
vs
...
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldWindow1dStart
,
vs
...
))
}
// Window1dStartGT applies the GT predicate on the "window_1d_start" field.
func
Window1dStartGT
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldWindow1dStart
,
v
))
}
// Window1dStartGTE applies the GTE predicate on the "window_1d_start" field.
func
Window1dStartGTE
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldWindow1dStart
,
v
))
}
// Window1dStartLT applies the LT predicate on the "window_1d_start" field.
func
Window1dStartLT
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldWindow1dStart
,
v
))
}
// Window1dStartLTE applies the LTE predicate on the "window_1d_start" field.
func
Window1dStartLTE
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldWindow1dStart
,
v
))
}
// Window1dStartIsNil applies the IsNil predicate on the "window_1d_start" field.
func
Window1dStartIsNil
()
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIsNull
(
FieldWindow1dStart
))
}
// Window1dStartNotNil applies the NotNil predicate on the "window_1d_start" field.
func
Window1dStartNotNil
()
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotNull
(
FieldWindow1dStart
))
}
// Window7dStartEQ applies the EQ predicate on the "window_7d_start" field.
func
Window7dStartEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldEQ
(
FieldWindow7dStart
,
v
))
}
// Window7dStartNEQ applies the NEQ predicate on the "window_7d_start" field.
func
Window7dStartNEQ
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNEQ
(
FieldWindow7dStart
,
v
))
}
// Window7dStartIn applies the In predicate on the "window_7d_start" field.
func
Window7dStartIn
(
vs
...
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIn
(
FieldWindow7dStart
,
vs
...
))
}
// Window7dStartNotIn applies the NotIn predicate on the "window_7d_start" field.
func
Window7dStartNotIn
(
vs
...
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotIn
(
FieldWindow7dStart
,
vs
...
))
}
// Window7dStartGT applies the GT predicate on the "window_7d_start" field.
func
Window7dStartGT
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGT
(
FieldWindow7dStart
,
v
))
}
// Window7dStartGTE applies the GTE predicate on the "window_7d_start" field.
func
Window7dStartGTE
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldGTE
(
FieldWindow7dStart
,
v
))
}
// Window7dStartLT applies the LT predicate on the "window_7d_start" field.
func
Window7dStartLT
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLT
(
FieldWindow7dStart
,
v
))
}
// Window7dStartLTE applies the LTE predicate on the "window_7d_start" field.
func
Window7dStartLTE
(
v
time
.
Time
)
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldLTE
(
FieldWindow7dStart
,
v
))
}
// Window7dStartIsNil applies the IsNil predicate on the "window_7d_start" field.
func
Window7dStartIsNil
()
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldIsNull
(
FieldWindow7dStart
))
}
// Window7dStartNotNil applies the NotNil predicate on the "window_7d_start" field.
func
Window7dStartNotNil
()
predicate
.
APIKey
{
return
predicate
.
APIKey
(
sql
.
FieldNotNull
(
FieldWindow7dStart
))
}
// 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 @
a80ec5d8
This diff is collapsed.
Click to expand it.
backend/ent/apikey_update.go
View file @
a80ec5d8
...
@@ -252,6 +252,192 @@ func (_u *APIKeyUpdate) ClearExpiresAt() *APIKeyUpdate {
...
@@ -252,6 +252,192 @@ func (_u *APIKeyUpdate) ClearExpiresAt() *APIKeyUpdate {
return
_u
return
_u
}
}
// SetRateLimit5h sets the "rate_limit_5h" field.
func
(
_u
*
APIKeyUpdate
)
SetRateLimit5h
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
ResetRateLimit5h
()
_u
.
mutation
.
SetRateLimit5h
(
v
)
return
_u
}
// SetNillableRateLimit5h sets the "rate_limit_5h" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableRateLimit5h
(
v
*
float64
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetRateLimit5h
(
*
v
)
}
return
_u
}
// AddRateLimit5h adds value to the "rate_limit_5h" field.
func
(
_u
*
APIKeyUpdate
)
AddRateLimit5h
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
AddRateLimit5h
(
v
)
return
_u
}
// SetRateLimit1d sets the "rate_limit_1d" field.
func
(
_u
*
APIKeyUpdate
)
SetRateLimit1d
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
ResetRateLimit1d
()
_u
.
mutation
.
SetRateLimit1d
(
v
)
return
_u
}
// SetNillableRateLimit1d sets the "rate_limit_1d" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableRateLimit1d
(
v
*
float64
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetRateLimit1d
(
*
v
)
}
return
_u
}
// AddRateLimit1d adds value to the "rate_limit_1d" field.
func
(
_u
*
APIKeyUpdate
)
AddRateLimit1d
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
AddRateLimit1d
(
v
)
return
_u
}
// SetRateLimit7d sets the "rate_limit_7d" field.
func
(
_u
*
APIKeyUpdate
)
SetRateLimit7d
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
ResetRateLimit7d
()
_u
.
mutation
.
SetRateLimit7d
(
v
)
return
_u
}
// SetNillableRateLimit7d sets the "rate_limit_7d" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableRateLimit7d
(
v
*
float64
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetRateLimit7d
(
*
v
)
}
return
_u
}
// AddRateLimit7d adds value to the "rate_limit_7d" field.
func
(
_u
*
APIKeyUpdate
)
AddRateLimit7d
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
AddRateLimit7d
(
v
)
return
_u
}
// SetUsage5h sets the "usage_5h" field.
func
(
_u
*
APIKeyUpdate
)
SetUsage5h
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
ResetUsage5h
()
_u
.
mutation
.
SetUsage5h
(
v
)
return
_u
}
// SetNillableUsage5h sets the "usage_5h" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableUsage5h
(
v
*
float64
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetUsage5h
(
*
v
)
}
return
_u
}
// AddUsage5h adds value to the "usage_5h" field.
func
(
_u
*
APIKeyUpdate
)
AddUsage5h
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
AddUsage5h
(
v
)
return
_u
}
// SetUsage1d sets the "usage_1d" field.
func
(
_u
*
APIKeyUpdate
)
SetUsage1d
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
ResetUsage1d
()
_u
.
mutation
.
SetUsage1d
(
v
)
return
_u
}
// SetNillableUsage1d sets the "usage_1d" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableUsage1d
(
v
*
float64
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetUsage1d
(
*
v
)
}
return
_u
}
// AddUsage1d adds value to the "usage_1d" field.
func
(
_u
*
APIKeyUpdate
)
AddUsage1d
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
AddUsage1d
(
v
)
return
_u
}
// SetUsage7d sets the "usage_7d" field.
func
(
_u
*
APIKeyUpdate
)
SetUsage7d
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
ResetUsage7d
()
_u
.
mutation
.
SetUsage7d
(
v
)
return
_u
}
// SetNillableUsage7d sets the "usage_7d" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableUsage7d
(
v
*
float64
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetUsage7d
(
*
v
)
}
return
_u
}
// AddUsage7d adds value to the "usage_7d" field.
func
(
_u
*
APIKeyUpdate
)
AddUsage7d
(
v
float64
)
*
APIKeyUpdate
{
_u
.
mutation
.
AddUsage7d
(
v
)
return
_u
}
// SetWindow5hStart sets the "window_5h_start" field.
func
(
_u
*
APIKeyUpdate
)
SetWindow5hStart
(
v
time
.
Time
)
*
APIKeyUpdate
{
_u
.
mutation
.
SetWindow5hStart
(
v
)
return
_u
}
// SetNillableWindow5hStart sets the "window_5h_start" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableWindow5hStart
(
v
*
time
.
Time
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetWindow5hStart
(
*
v
)
}
return
_u
}
// ClearWindow5hStart clears the value of the "window_5h_start" field.
func
(
_u
*
APIKeyUpdate
)
ClearWindow5hStart
()
*
APIKeyUpdate
{
_u
.
mutation
.
ClearWindow5hStart
()
return
_u
}
// SetWindow1dStart sets the "window_1d_start" field.
func
(
_u
*
APIKeyUpdate
)
SetWindow1dStart
(
v
time
.
Time
)
*
APIKeyUpdate
{
_u
.
mutation
.
SetWindow1dStart
(
v
)
return
_u
}
// SetNillableWindow1dStart sets the "window_1d_start" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableWindow1dStart
(
v
*
time
.
Time
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetWindow1dStart
(
*
v
)
}
return
_u
}
// ClearWindow1dStart clears the value of the "window_1d_start" field.
func
(
_u
*
APIKeyUpdate
)
ClearWindow1dStart
()
*
APIKeyUpdate
{
_u
.
mutation
.
ClearWindow1dStart
()
return
_u
}
// SetWindow7dStart sets the "window_7d_start" field.
func
(
_u
*
APIKeyUpdate
)
SetWindow7dStart
(
v
time
.
Time
)
*
APIKeyUpdate
{
_u
.
mutation
.
SetWindow7dStart
(
v
)
return
_u
}
// SetNillableWindow7dStart sets the "window_7d_start" field if the given value is not nil.
func
(
_u
*
APIKeyUpdate
)
SetNillableWindow7dStart
(
v
*
time
.
Time
)
*
APIKeyUpdate
{
if
v
!=
nil
{
_u
.
SetWindow7dStart
(
*
v
)
}
return
_u
}
// ClearWindow7dStart clears the value of the "window_7d_start" field.
func
(
_u
*
APIKeyUpdate
)
ClearWindow7dStart
()
*
APIKeyUpdate
{
_u
.
mutation
.
ClearWindow7dStart
()
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
)
...
@@ -456,6 +642,60 @@ func (_u *APIKeyUpdate) sqlSave(ctx context.Context) (_node int, err error) {
...
@@ -456,6 +642,60 @@ func (_u *APIKeyUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if
_u
.
mutation
.
ExpiresAtCleared
()
{
if
_u
.
mutation
.
ExpiresAtCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldExpiresAt
,
field
.
TypeTime
)
_spec
.
ClearField
(
apikey
.
FieldExpiresAt
,
field
.
TypeTime
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
RateLimit5h
();
ok
{
_spec
.
SetField
(
apikey
.
FieldRateLimit5h
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedRateLimit5h
();
ok
{
_spec
.
AddField
(
apikey
.
FieldRateLimit5h
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
RateLimit1d
();
ok
{
_spec
.
SetField
(
apikey
.
FieldRateLimit1d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedRateLimit1d
();
ok
{
_spec
.
AddField
(
apikey
.
FieldRateLimit1d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
RateLimit7d
();
ok
{
_spec
.
SetField
(
apikey
.
FieldRateLimit7d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedRateLimit7d
();
ok
{
_spec
.
AddField
(
apikey
.
FieldRateLimit7d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Usage5h
();
ok
{
_spec
.
SetField
(
apikey
.
FieldUsage5h
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedUsage5h
();
ok
{
_spec
.
AddField
(
apikey
.
FieldUsage5h
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Usage1d
();
ok
{
_spec
.
SetField
(
apikey
.
FieldUsage1d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedUsage1d
();
ok
{
_spec
.
AddField
(
apikey
.
FieldUsage1d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Usage7d
();
ok
{
_spec
.
SetField
(
apikey
.
FieldUsage7d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedUsage7d
();
ok
{
_spec
.
AddField
(
apikey
.
FieldUsage7d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Window5hStart
();
ok
{
_spec
.
SetField
(
apikey
.
FieldWindow5hStart
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
Window5hStartCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldWindow5hStart
,
field
.
TypeTime
)
}
if
value
,
ok
:=
_u
.
mutation
.
Window1dStart
();
ok
{
_spec
.
SetField
(
apikey
.
FieldWindow1dStart
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
Window1dStartCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldWindow1dStart
,
field
.
TypeTime
)
}
if
value
,
ok
:=
_u
.
mutation
.
Window7dStart
();
ok
{
_spec
.
SetField
(
apikey
.
FieldWindow7dStart
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
Window7dStartCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldWindow7dStart
,
field
.
TypeTime
)
}
if
_u
.
mutation
.
UserCleared
()
{
if
_u
.
mutation
.
UserCleared
()
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
edge
:=
&
sqlgraph
.
EdgeSpec
{
Rel
:
sqlgraph
.
M2O
,
Rel
:
sqlgraph
.
M2O
,
...
@@ -799,6 +1039,192 @@ func (_u *APIKeyUpdateOne) ClearExpiresAt() *APIKeyUpdateOne {
...
@@ -799,6 +1039,192 @@ func (_u *APIKeyUpdateOne) ClearExpiresAt() *APIKeyUpdateOne {
return
_u
return
_u
}
}
// SetRateLimit5h sets the "rate_limit_5h" field.
func
(
_u
*
APIKeyUpdateOne
)
SetRateLimit5h
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
ResetRateLimit5h
()
_u
.
mutation
.
SetRateLimit5h
(
v
)
return
_u
}
// SetNillableRateLimit5h sets the "rate_limit_5h" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableRateLimit5h
(
v
*
float64
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetRateLimit5h
(
*
v
)
}
return
_u
}
// AddRateLimit5h adds value to the "rate_limit_5h" field.
func
(
_u
*
APIKeyUpdateOne
)
AddRateLimit5h
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
AddRateLimit5h
(
v
)
return
_u
}
// SetRateLimit1d sets the "rate_limit_1d" field.
func
(
_u
*
APIKeyUpdateOne
)
SetRateLimit1d
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
ResetRateLimit1d
()
_u
.
mutation
.
SetRateLimit1d
(
v
)
return
_u
}
// SetNillableRateLimit1d sets the "rate_limit_1d" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableRateLimit1d
(
v
*
float64
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetRateLimit1d
(
*
v
)
}
return
_u
}
// AddRateLimit1d adds value to the "rate_limit_1d" field.
func
(
_u
*
APIKeyUpdateOne
)
AddRateLimit1d
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
AddRateLimit1d
(
v
)
return
_u
}
// SetRateLimit7d sets the "rate_limit_7d" field.
func
(
_u
*
APIKeyUpdateOne
)
SetRateLimit7d
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
ResetRateLimit7d
()
_u
.
mutation
.
SetRateLimit7d
(
v
)
return
_u
}
// SetNillableRateLimit7d sets the "rate_limit_7d" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableRateLimit7d
(
v
*
float64
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetRateLimit7d
(
*
v
)
}
return
_u
}
// AddRateLimit7d adds value to the "rate_limit_7d" field.
func
(
_u
*
APIKeyUpdateOne
)
AddRateLimit7d
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
AddRateLimit7d
(
v
)
return
_u
}
// SetUsage5h sets the "usage_5h" field.
func
(
_u
*
APIKeyUpdateOne
)
SetUsage5h
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
ResetUsage5h
()
_u
.
mutation
.
SetUsage5h
(
v
)
return
_u
}
// SetNillableUsage5h sets the "usage_5h" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableUsage5h
(
v
*
float64
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetUsage5h
(
*
v
)
}
return
_u
}
// AddUsage5h adds value to the "usage_5h" field.
func
(
_u
*
APIKeyUpdateOne
)
AddUsage5h
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
AddUsage5h
(
v
)
return
_u
}
// SetUsage1d sets the "usage_1d" field.
func
(
_u
*
APIKeyUpdateOne
)
SetUsage1d
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
ResetUsage1d
()
_u
.
mutation
.
SetUsage1d
(
v
)
return
_u
}
// SetNillableUsage1d sets the "usage_1d" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableUsage1d
(
v
*
float64
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetUsage1d
(
*
v
)
}
return
_u
}
// AddUsage1d adds value to the "usage_1d" field.
func
(
_u
*
APIKeyUpdateOne
)
AddUsage1d
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
AddUsage1d
(
v
)
return
_u
}
// SetUsage7d sets the "usage_7d" field.
func
(
_u
*
APIKeyUpdateOne
)
SetUsage7d
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
ResetUsage7d
()
_u
.
mutation
.
SetUsage7d
(
v
)
return
_u
}
// SetNillableUsage7d sets the "usage_7d" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableUsage7d
(
v
*
float64
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetUsage7d
(
*
v
)
}
return
_u
}
// AddUsage7d adds value to the "usage_7d" field.
func
(
_u
*
APIKeyUpdateOne
)
AddUsage7d
(
v
float64
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
AddUsage7d
(
v
)
return
_u
}
// SetWindow5hStart sets the "window_5h_start" field.
func
(
_u
*
APIKeyUpdateOne
)
SetWindow5hStart
(
v
time
.
Time
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
SetWindow5hStart
(
v
)
return
_u
}
// SetNillableWindow5hStart sets the "window_5h_start" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableWindow5hStart
(
v
*
time
.
Time
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetWindow5hStart
(
*
v
)
}
return
_u
}
// ClearWindow5hStart clears the value of the "window_5h_start" field.
func
(
_u
*
APIKeyUpdateOne
)
ClearWindow5hStart
()
*
APIKeyUpdateOne
{
_u
.
mutation
.
ClearWindow5hStart
()
return
_u
}
// SetWindow1dStart sets the "window_1d_start" field.
func
(
_u
*
APIKeyUpdateOne
)
SetWindow1dStart
(
v
time
.
Time
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
SetWindow1dStart
(
v
)
return
_u
}
// SetNillableWindow1dStart sets the "window_1d_start" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableWindow1dStart
(
v
*
time
.
Time
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetWindow1dStart
(
*
v
)
}
return
_u
}
// ClearWindow1dStart clears the value of the "window_1d_start" field.
func
(
_u
*
APIKeyUpdateOne
)
ClearWindow1dStart
()
*
APIKeyUpdateOne
{
_u
.
mutation
.
ClearWindow1dStart
()
return
_u
}
// SetWindow7dStart sets the "window_7d_start" field.
func
(
_u
*
APIKeyUpdateOne
)
SetWindow7dStart
(
v
time
.
Time
)
*
APIKeyUpdateOne
{
_u
.
mutation
.
SetWindow7dStart
(
v
)
return
_u
}
// SetNillableWindow7dStart sets the "window_7d_start" field if the given value is not nil.
func
(
_u
*
APIKeyUpdateOne
)
SetNillableWindow7dStart
(
v
*
time
.
Time
)
*
APIKeyUpdateOne
{
if
v
!=
nil
{
_u
.
SetWindow7dStart
(
*
v
)
}
return
_u
}
// ClearWindow7dStart clears the value of the "window_7d_start" field.
func
(
_u
*
APIKeyUpdateOne
)
ClearWindow7dStart
()
*
APIKeyUpdateOne
{
_u
.
mutation
.
ClearWindow7dStart
()
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
)
...
@@ -1033,6 +1459,60 @@ func (_u *APIKeyUpdateOne) sqlSave(ctx context.Context) (_node *APIKey, err erro
...
@@ -1033,6 +1459,60 @@ func (_u *APIKeyUpdateOne) sqlSave(ctx context.Context) (_node *APIKey, err erro
if
_u
.
mutation
.
ExpiresAtCleared
()
{
if
_u
.
mutation
.
ExpiresAtCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldExpiresAt
,
field
.
TypeTime
)
_spec
.
ClearField
(
apikey
.
FieldExpiresAt
,
field
.
TypeTime
)
}
}
if
value
,
ok
:=
_u
.
mutation
.
RateLimit5h
();
ok
{
_spec
.
SetField
(
apikey
.
FieldRateLimit5h
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedRateLimit5h
();
ok
{
_spec
.
AddField
(
apikey
.
FieldRateLimit5h
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
RateLimit1d
();
ok
{
_spec
.
SetField
(
apikey
.
FieldRateLimit1d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedRateLimit1d
();
ok
{
_spec
.
AddField
(
apikey
.
FieldRateLimit1d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
RateLimit7d
();
ok
{
_spec
.
SetField
(
apikey
.
FieldRateLimit7d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedRateLimit7d
();
ok
{
_spec
.
AddField
(
apikey
.
FieldRateLimit7d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Usage5h
();
ok
{
_spec
.
SetField
(
apikey
.
FieldUsage5h
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedUsage5h
();
ok
{
_spec
.
AddField
(
apikey
.
FieldUsage5h
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Usage1d
();
ok
{
_spec
.
SetField
(
apikey
.
FieldUsage1d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedUsage1d
();
ok
{
_spec
.
AddField
(
apikey
.
FieldUsage1d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Usage7d
();
ok
{
_spec
.
SetField
(
apikey
.
FieldUsage7d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AddedUsage7d
();
ok
{
_spec
.
AddField
(
apikey
.
FieldUsage7d
,
field
.
TypeFloat64
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Window5hStart
();
ok
{
_spec
.
SetField
(
apikey
.
FieldWindow5hStart
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
Window5hStartCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldWindow5hStart
,
field
.
TypeTime
)
}
if
value
,
ok
:=
_u
.
mutation
.
Window1dStart
();
ok
{
_spec
.
SetField
(
apikey
.
FieldWindow1dStart
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
Window1dStartCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldWindow1dStart
,
field
.
TypeTime
)
}
if
value
,
ok
:=
_u
.
mutation
.
Window7dStart
();
ok
{
_spec
.
SetField
(
apikey
.
FieldWindow7dStart
,
field
.
TypeTime
,
value
)
}
if
_u
.
mutation
.
Window7dStartCleared
()
{
_spec
.
ClearField
(
apikey
.
FieldWindow7dStart
,
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 @
a80ec5d8
...
@@ -24,6 +24,15 @@ var (
...
@@ -24,6 +24,15 @@ var (
{
Name
:
"quota"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
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
:
"quota_used"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
Name
:
"expires_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
},
{
Name
:
"expires_at"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
},
{
Name
:
"rate_limit_5h"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
Name
:
"rate_limit_1d"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
Name
:
"rate_limit_7d"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
Name
:
"usage_5h"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
Name
:
"usage_1d"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
Name
:
"usage_7d"
,
Type
:
field
.
TypeFloat64
,
Default
:
0
,
SchemaType
:
map
[
string
]
string
{
"postgres"
:
"decimal(20,8)"
}},
{
Name
:
"window_5h_start"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
},
{
Name
:
"window_1d_start"
,
Type
:
field
.
TypeTime
,
Nullable
:
true
},
{
Name
:
"window_7d_start"
,
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
},
}
}
...
@@ -35,13 +44,13 @@ var (
...
@@ -35,13 +44,13 @@ var (
ForeignKeys
:
[]
*
schema
.
ForeignKey
{
ForeignKeys
:
[]
*
schema
.
ForeignKey
{
{
{
Symbol
:
"api_keys_groups_api_keys"
,
Symbol
:
"api_keys_groups_api_keys"
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
13
]},
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
22
]},
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
[
14
]},
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
23
]},
RefColumns
:
[]
*
schema
.
Column
{
UsersColumns
[
0
]},
RefColumns
:
[]
*
schema
.
Column
{
UsersColumns
[
0
]},
OnDelete
:
schema
.
NoAction
,
OnDelete
:
schema
.
NoAction
,
},
},
...
@@ -50,12 +59,12 @@ var (
...
@@ -50,12 +59,12 @@ var (
{
{
Name
:
"apikey_user_id"
,
Name
:
"apikey_user_id"
,
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
14
]},
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
23
]},
},
},
{
{
Name
:
"apikey_group_id"
,
Name
:
"apikey_group_id"
,
Unique
:
false
,
Unique
:
false
,
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
13
]},
Columns
:
[]
*
schema
.
Column
{
APIKeysColumns
[
22
]},
},
},
{
{
Name
:
"apikey_status"
,
Name
:
"apikey_status"
,
...
...
backend/ent/mutation.go
View file @
a80ec5d8
This diff is collapsed.
Click to expand it.
backend/ent/runtime/runtime.go
View file @
a80ec5d8
...
@@ -102,6 +102,30 @@ func init() {
...
@@ -102,6 +102,30 @@ func init() {
apikeyDescQuotaUsed
:=
apikeyFields
[
9
]
.
Descriptor
()
apikeyDescQuotaUsed
:=
apikeyFields
[
9
]
.
Descriptor
()
// apikey.DefaultQuotaUsed holds the default value on creation for the quota_used field.
// apikey.DefaultQuotaUsed holds the default value on creation for the quota_used field.
apikey
.
DefaultQuotaUsed
=
apikeyDescQuotaUsed
.
Default
.
(
float64
)
apikey
.
DefaultQuotaUsed
=
apikeyDescQuotaUsed
.
Default
.
(
float64
)
// apikeyDescRateLimit5h is the schema descriptor for rate_limit_5h field.
apikeyDescRateLimit5h
:=
apikeyFields
[
11
]
.
Descriptor
()
// apikey.DefaultRateLimit5h holds the default value on creation for the rate_limit_5h field.
apikey
.
DefaultRateLimit5h
=
apikeyDescRateLimit5h
.
Default
.
(
float64
)
// apikeyDescRateLimit1d is the schema descriptor for rate_limit_1d field.
apikeyDescRateLimit1d
:=
apikeyFields
[
12
]
.
Descriptor
()
// apikey.DefaultRateLimit1d holds the default value on creation for the rate_limit_1d field.
apikey
.
DefaultRateLimit1d
=
apikeyDescRateLimit1d
.
Default
.
(
float64
)
// apikeyDescRateLimit7d is the schema descriptor for rate_limit_7d field.
apikeyDescRateLimit7d
:=
apikeyFields
[
13
]
.
Descriptor
()
// apikey.DefaultRateLimit7d holds the default value on creation for the rate_limit_7d field.
apikey
.
DefaultRateLimit7d
=
apikeyDescRateLimit7d
.
Default
.
(
float64
)
// apikeyDescUsage5h is the schema descriptor for usage_5h field.
apikeyDescUsage5h
:=
apikeyFields
[
14
]
.
Descriptor
()
// apikey.DefaultUsage5h holds the default value on creation for the usage_5h field.
apikey
.
DefaultUsage5h
=
apikeyDescUsage5h
.
Default
.
(
float64
)
// apikeyDescUsage1d is the schema descriptor for usage_1d field.
apikeyDescUsage1d
:=
apikeyFields
[
15
]
.
Descriptor
()
// apikey.DefaultUsage1d holds the default value on creation for the usage_1d field.
apikey
.
DefaultUsage1d
=
apikeyDescUsage1d
.
Default
.
(
float64
)
// apikeyDescUsage7d is the schema descriptor for usage_7d field.
apikeyDescUsage7d
:=
apikeyFields
[
16
]
.
Descriptor
()
// apikey.DefaultUsage7d holds the default value on creation for the usage_7d field.
apikey
.
DefaultUsage7d
=
apikeyDescUsage7d
.
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 @
a80ec5d8
...
@@ -74,6 +74,47 @@ func (APIKey) Fields() []ent.Field {
...
@@ -74,6 +74,47 @@ func (APIKey) Fields() []ent.Field {
Optional
()
.
Optional
()
.
Nillable
()
.
Nillable
()
.
Comment
(
"Expiration time for this API key (null = never expires)"
),
Comment
(
"Expiration time for this API key (null = never expires)"
),
// ========== Rate limit fields ==========
// Rate limit configuration (0 = unlimited)
field
.
Float
(
"rate_limit_5h"
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(20,8)"
})
.
Default
(
0
)
.
Comment
(
"Rate limit in USD per 5 hours (0 = unlimited)"
),
field
.
Float
(
"rate_limit_1d"
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(20,8)"
})
.
Default
(
0
)
.
Comment
(
"Rate limit in USD per day (0 = unlimited)"
),
field
.
Float
(
"rate_limit_7d"
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(20,8)"
})
.
Default
(
0
)
.
Comment
(
"Rate limit in USD per 7 days (0 = unlimited)"
),
// Rate limit usage tracking
field
.
Float
(
"usage_5h"
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(20,8)"
})
.
Default
(
0
)
.
Comment
(
"Used amount in USD for the current 5h window"
),
field
.
Float
(
"usage_1d"
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(20,8)"
})
.
Default
(
0
)
.
Comment
(
"Used amount in USD for the current 1d window"
),
field
.
Float
(
"usage_7d"
)
.
SchemaType
(
map
[
string
]
string
{
dialect
.
Postgres
:
"decimal(20,8)"
})
.
Default
(
0
)
.
Comment
(
"Used amount in USD for the current 7d window"
),
// Window start times
field
.
Time
(
"window_5h_start"
)
.
Optional
()
.
Nillable
()
.
Comment
(
"Start time of the current 5h rate limit window"
),
field
.
Time
(
"window_1d_start"
)
.
Optional
()
.
Nillable
()
.
Comment
(
"Start time of the current 1d rate limit window"
),
field
.
Time
(
"window_7d_start"
)
.
Optional
()
.
Nillable
()
.
Comment
(
"Start time of the current 7d rate limit window"
),
}
}
}
}
...
...
backend/go.mod
View file @
a80ec5d8
...
@@ -180,8 +180,6 @@ require (
...
@@ -180,8 +180,6 @@ require (
golang.org/x/text v0.34.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/tools v0.41.0 // indirect
golang.org/x/tools v0.41.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 // indirect
google.golang.org/grpc v1.75.1 // indirect
google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
modernc.org/libc v1.67.6 // indirect
modernc.org/libc v1.67.6 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/mathutil v1.7.1 // indirect
...
...
backend/internal/handler/api_key_handler.go
View file @
a80ec5d8
...
@@ -36,6 +36,11 @@ type CreateAPIKeyRequest struct {
...
@@ -36,6 +36,11 @@ type CreateAPIKeyRequest struct {
IPBlacklist
[]
string
`json:"ip_blacklist"`
// IP 黑名单
IPBlacklist
[]
string
`json:"ip_blacklist"`
// IP 黑名单
Quota
*
float64
`json:"quota"`
// 配额限制 (USD)
Quota
*
float64
`json:"quota"`
// 配额限制 (USD)
ExpiresInDays
*
int
`json:"expires_in_days"`
// 过期天数
ExpiresInDays
*
int
`json:"expires_in_days"`
// 过期天数
// Rate limit fields (0 = unlimited)
RateLimit5h
*
float64
`json:"rate_limit_5h"`
RateLimit1d
*
float64
`json:"rate_limit_1d"`
RateLimit7d
*
float64
`json:"rate_limit_7d"`
}
}
// UpdateAPIKeyRequest represents the update API key request payload
// UpdateAPIKeyRequest represents the update API key request payload
...
@@ -48,6 +53,12 @@ type UpdateAPIKeyRequest struct {
...
@@ -48,6 +53,12 @@ type UpdateAPIKeyRequest struct {
Quota
*
float64
`json:"quota"`
// 配额限制 (USD), 0=无限制
Quota
*
float64
`json:"quota"`
// 配额限制 (USD), 0=无限制
ExpiresAt
*
string
`json:"expires_at"`
// 过期时间 (ISO 8601)
ExpiresAt
*
string
`json:"expires_at"`
// 过期时间 (ISO 8601)
ResetQuota
*
bool
`json:"reset_quota"`
// 重置已用配额
ResetQuota
*
bool
`json:"reset_quota"`
// 重置已用配额
// Rate limit fields (nil = no change, 0 = unlimited)
RateLimit5h
*
float64
`json:"rate_limit_5h"`
RateLimit1d
*
float64
`json:"rate_limit_1d"`
RateLimit7d
*
float64
`json:"rate_limit_7d"`
ResetRateLimitUsage
*
bool
`json:"reset_rate_limit_usage"`
// 重置限速用量
}
}
// List handles listing user's API keys with pagination
// List handles listing user's API keys with pagination
...
@@ -131,6 +142,15 @@ func (h *APIKeyHandler) Create(c *gin.Context) {
...
@@ -131,6 +142,15 @@ func (h *APIKeyHandler) Create(c *gin.Context) {
if
req
.
Quota
!=
nil
{
if
req
.
Quota
!=
nil
{
svcReq
.
Quota
=
*
req
.
Quota
svcReq
.
Quota
=
*
req
.
Quota
}
}
if
req
.
RateLimit5h
!=
nil
{
svcReq
.
RateLimit5h
=
*
req
.
RateLimit5h
}
if
req
.
RateLimit1d
!=
nil
{
svcReq
.
RateLimit1d
=
*
req
.
RateLimit1d
}
if
req
.
RateLimit7d
!=
nil
{
svcReq
.
RateLimit7d
=
*
req
.
RateLimit7d
}
executeUserIdempotentJSON
(
c
,
"user.api_keys.create"
,
req
,
service
.
DefaultWriteIdempotencyTTL
(),
func
(
ctx
context
.
Context
)
(
any
,
error
)
{
executeUserIdempotentJSON
(
c
,
"user.api_keys.create"
,
req
,
service
.
DefaultWriteIdempotencyTTL
(),
func
(
ctx
context
.
Context
)
(
any
,
error
)
{
key
,
err
:=
h
.
apiKeyService
.
Create
(
ctx
,
subject
.
UserID
,
svcReq
)
key
,
err
:=
h
.
apiKeyService
.
Create
(
ctx
,
subject
.
UserID
,
svcReq
)
...
@@ -163,10 +183,14 @@ func (h *APIKeyHandler) Update(c *gin.Context) {
...
@@ -163,10 +183,14 @@ 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
,
Quota
:
req
.
Quota
,
ResetQuota
:
req
.
ResetQuota
,
ResetQuota
:
req
.
ResetQuota
,
RateLimit5h
:
req
.
RateLimit5h
,
RateLimit1d
:
req
.
RateLimit1d
,
RateLimit7d
:
req
.
RateLimit7d
,
ResetRateLimitUsage
:
req
.
ResetRateLimitUsage
,
}
}
if
req
.
Name
!=
""
{
if
req
.
Name
!=
""
{
svcReq
.
Name
=
&
req
.
Name
svcReq
.
Name
=
&
req
.
Name
...
...
backend/internal/handler/dto/mappers.go
View file @
a80ec5d8
...
@@ -72,22 +72,31 @@ func APIKeyFromService(k *service.APIKey) *APIKey {
...
@@ -72,22 +72,31 @@ func APIKeyFromService(k *service.APIKey) *APIKey {
return
nil
return
nil
}
}
return
&
APIKey
{
return
&
APIKey
{
ID
:
k
.
ID
,
ID
:
k
.
ID
,
UserID
:
k
.
UserID
,
UserID
:
k
.
UserID
,
Key
:
k
.
Key
,
Key
:
k
.
Key
,
Name
:
k
.
Name
,
Name
:
k
.
Name
,
GroupID
:
k
.
GroupID
,
GroupID
:
k
.
GroupID
,
Status
:
k
.
Status
,
Status
:
k
.
Status
,
IPWhitelist
:
k
.
IPWhitelist
,
IPWhitelist
:
k
.
IPWhitelist
,
IPBlacklist
:
k
.
IPBlacklist
,
IPBlacklist
:
k
.
IPBlacklist
,
LastUsedAt
:
k
.
LastUsedAt
,
LastUsedAt
:
k
.
LastUsedAt
,
Quota
:
k
.
Quota
,
Quota
:
k
.
Quota
,
QuotaUsed
:
k
.
QuotaUsed
,
QuotaUsed
:
k
.
QuotaUsed
,
ExpiresAt
:
k
.
ExpiresAt
,
ExpiresAt
:
k
.
ExpiresAt
,
CreatedAt
:
k
.
CreatedAt
,
CreatedAt
:
k
.
CreatedAt
,
UpdatedAt
:
k
.
UpdatedAt
,
UpdatedAt
:
k
.
UpdatedAt
,
User
:
UserFromServiceShallow
(
k
.
User
),
RateLimit5h
:
k
.
RateLimit5h
,
Group
:
GroupFromServiceShallow
(
k
.
Group
),
RateLimit1d
:
k
.
RateLimit1d
,
RateLimit7d
:
k
.
RateLimit7d
,
Usage5h
:
k
.
Usage5h
,
Usage1d
:
k
.
Usage1d
,
Usage7d
:
k
.
Usage7d
,
Window5hStart
:
k
.
Window5hStart
,
Window1dStart
:
k
.
Window1dStart
,
Window7dStart
:
k
.
Window7dStart
,
User
:
UserFromServiceShallow
(
k
.
User
),
Group
:
GroupFromServiceShallow
(
k
.
Group
),
}
}
}
}
...
...
backend/internal/handler/dto/types.go
View file @
a80ec5d8
...
@@ -47,6 +47,17 @@ type APIKey struct {
...
@@ -47,6 +47,17 @@ type APIKey struct {
CreatedAt
time
.
Time
`json:"created_at"`
CreatedAt
time
.
Time
`json:"created_at"`
UpdatedAt
time
.
Time
`json:"updated_at"`
UpdatedAt
time
.
Time
`json:"updated_at"`
// Rate limit fields
RateLimit5h
float64
`json:"rate_limit_5h"`
RateLimit1d
float64
`json:"rate_limit_1d"`
RateLimit7d
float64
`json:"rate_limit_7d"`
Usage5h
float64
`json:"usage_5h"`
Usage1d
float64
`json:"usage_1d"`
Usage7d
float64
`json:"usage_7d"`
Window5hStart
*
time
.
Time
`json:"window_5h_start"`
Window1dStart
*
time
.
Time
`json:"window_1d_start"`
Window7dStart
*
time
.
Time
`json:"window_7d_start"`
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 @
a80ec5d8
...
@@ -1445,6 +1445,18 @@ func billingErrorDetails(err error) (status int, code, message string) {
...
@@ -1445,6 +1445,18 @@ func billingErrorDetails(err error) (status int, code, message string) {
}
}
return
http
.
StatusServiceUnavailable
,
"billing_service_error"
,
msg
return
http
.
StatusServiceUnavailable
,
"billing_service_error"
,
msg
}
}
if
errors
.
Is
(
err
,
service
.
ErrAPIKeyRateLimit5hExceeded
)
{
msg
:=
pkgerrors
.
Message
(
err
)
return
http
.
StatusTooManyRequests
,
"rate_limit_exceeded"
,
msg
}
if
errors
.
Is
(
err
,
service
.
ErrAPIKeyRateLimit1dExceeded
)
{
msg
:=
pkgerrors
.
Message
(
err
)
return
http
.
StatusTooManyRequests
,
"rate_limit_exceeded"
,
msg
}
if
errors
.
Is
(
err
,
service
.
ErrAPIKeyRateLimit7dExceeded
)
{
msg
:=
pkgerrors
.
Message
(
err
)
return
http
.
StatusTooManyRequests
,
"rate_limit_exceeded"
,
msg
}
msg
:=
pkgerrors
.
Message
(
err
)
msg
:=
pkgerrors
.
Message
(
err
)
if
msg
==
""
{
if
msg
==
""
{
logger
.
L
()
.
With
(
logger
.
L
()
.
With
(
...
...
backend/internal/repository/api_key_repo.go
View file @
a80ec5d8
...
@@ -2,6 +2,7 @@ package repository
...
@@ -2,6 +2,7 @@ package repository
import
(
import
(
"context"
"context"
"database/sql"
"time"
"time"
dbent
"github.com/Wei-Shaw/sub2api/ent"
dbent
"github.com/Wei-Shaw/sub2api/ent"
...
@@ -16,10 +17,11 @@ import (
...
@@ -16,10 +17,11 @@ import (
type
apiKeyRepository
struct
{
type
apiKeyRepository
struct
{
client
*
dbent
.
Client
client
*
dbent
.
Client
sql
sqlExecutor
}
}
func
NewAPIKeyRepository
(
client
*
dbent
.
Client
)
service
.
APIKeyRepository
{
func
NewAPIKeyRepository
(
client
*
dbent
.
Client
,
sqlDB
*
sql
.
DB
)
service
.
APIKeyRepository
{
return
&
apiKeyRepository
{
client
:
client
}
return
&
apiKeyRepository
{
client
:
client
,
sql
:
sqlDB
}
}
}
func
(
r
*
apiKeyRepository
)
activeQuery
()
*
dbent
.
APIKeyQuery
{
func
(
r
*
apiKeyRepository
)
activeQuery
()
*
dbent
.
APIKeyQuery
{
...
@@ -37,7 +39,10 @@ func (r *apiKeyRepository) Create(ctx context.Context, key *service.APIKey) erro
...
@@ -37,7 +39,10 @@ func (r *apiKeyRepository) Create(ctx context.Context, key *service.APIKey) erro
SetNillableLastUsedAt
(
key
.
LastUsedAt
)
.
SetNillableLastUsedAt
(
key
.
LastUsedAt
)
.
SetQuota
(
key
.
Quota
)
.
SetQuota
(
key
.
Quota
)
.
SetQuotaUsed
(
key
.
QuotaUsed
)
.
SetQuotaUsed
(
key
.
QuotaUsed
)
.
SetNillableExpiresAt
(
key
.
ExpiresAt
)
SetNillableExpiresAt
(
key
.
ExpiresAt
)
.
SetRateLimit5h
(
key
.
RateLimit5h
)
.
SetRateLimit1d
(
key
.
RateLimit1d
)
.
SetRateLimit7d
(
key
.
RateLimit7d
)
if
len
(
key
.
IPWhitelist
)
>
0
{
if
len
(
key
.
IPWhitelist
)
>
0
{
builder
.
SetIPWhitelist
(
key
.
IPWhitelist
)
builder
.
SetIPWhitelist
(
key
.
IPWhitelist
)
...
@@ -118,6 +123,9 @@ func (r *apiKeyRepository) GetByKeyForAuth(ctx context.Context, key string) (*se
...
@@ -118,6 +123,9 @@ func (r *apiKeyRepository) GetByKeyForAuth(ctx context.Context, key string) (*se
apikey
.
FieldQuota
,
apikey
.
FieldQuota
,
apikey
.
FieldQuotaUsed
,
apikey
.
FieldQuotaUsed
,
apikey
.
FieldExpiresAt
,
apikey
.
FieldExpiresAt
,
apikey
.
FieldRateLimit5h
,
apikey
.
FieldRateLimit1d
,
apikey
.
FieldRateLimit7d
,
)
.
)
.
WithUser
(
func
(
q
*
dbent
.
UserQuery
)
{
WithUser
(
func
(
q
*
dbent
.
UserQuery
)
{
q
.
Select
(
q
.
Select
(
...
@@ -179,6 +187,12 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro
...
@@ -179,6 +187,12 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro
SetStatus
(
key
.
Status
)
.
SetStatus
(
key
.
Status
)
.
SetQuota
(
key
.
Quota
)
.
SetQuota
(
key
.
Quota
)
.
SetQuotaUsed
(
key
.
QuotaUsed
)
.
SetQuotaUsed
(
key
.
QuotaUsed
)
.
SetRateLimit5h
(
key
.
RateLimit5h
)
.
SetRateLimit1d
(
key
.
RateLimit1d
)
.
SetRateLimit7d
(
key
.
RateLimit7d
)
.
SetUsage5h
(
key
.
Usage5h
)
.
SetUsage1d
(
key
.
Usage1d
)
.
SetUsage7d
(
key
.
Usage7d
)
.
SetUpdatedAt
(
now
)
SetUpdatedAt
(
now
)
if
key
.
GroupID
!=
nil
{
if
key
.
GroupID
!=
nil
{
builder
.
SetGroupID
(
*
key
.
GroupID
)
builder
.
SetGroupID
(
*
key
.
GroupID
)
...
@@ -193,6 +207,23 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro
...
@@ -193,6 +207,23 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro
builder
.
ClearExpiresAt
()
builder
.
ClearExpiresAt
()
}
}
// Rate limit window start times
if
key
.
Window5hStart
!=
nil
{
builder
.
SetWindow5hStart
(
*
key
.
Window5hStart
)
}
else
{
builder
.
ClearWindow5hStart
()
}
if
key
.
Window1dStart
!=
nil
{
builder
.
SetWindow1dStart
(
*
key
.
Window1dStart
)
}
else
{
builder
.
ClearWindow1dStart
()
}
if
key
.
Window7dStart
!=
nil
{
builder
.
SetWindow7dStart
(
*
key
.
Window7dStart
)
}
else
{
builder
.
ClearWindow7dStart
()
}
// IP 限制字段
// IP 限制字段
if
len
(
key
.
IPWhitelist
)
>
0
{
if
len
(
key
.
IPWhitelist
)
>
0
{
builder
.
SetIPWhitelist
(
key
.
IPWhitelist
)
builder
.
SetIPWhitelist
(
key
.
IPWhitelist
)
...
@@ -412,25 +443,88 @@ func (r *apiKeyRepository) UpdateLastUsed(ctx context.Context, id int64, usedAt
...
@@ -412,25 +443,88 @@ func (r *apiKeyRepository) UpdateLastUsed(ctx context.Context, id int64, usedAt
return
nil
return
nil
}
}
// IncrementRateLimitUsage atomically increments all rate limit usage counters and initializes
// window start times via COALESCE if not already set.
func
(
r
*
apiKeyRepository
)
IncrementRateLimitUsage
(
ctx
context
.
Context
,
id
int64
,
cost
float64
)
error
{
_
,
err
:=
r
.
sql
.
ExecContext
(
ctx
,
`
UPDATE api_keys SET
usage_5h = usage_5h + $1,
usage_1d = usage_1d + $1,
usage_7d = usage_7d + $1,
window_5h_start = COALESCE(window_5h_start, NOW()),
window_1d_start = COALESCE(window_1d_start, NOW()),
window_7d_start = COALESCE(window_7d_start, NOW()),
updated_at = NOW()
WHERE id = $2 AND deleted_at IS NULL`
,
cost
,
id
)
return
err
}
// ResetRateLimitWindows resets expired rate limit windows atomically.
func
(
r
*
apiKeyRepository
)
ResetRateLimitWindows
(
ctx
context
.
Context
,
id
int64
)
error
{
_
,
err
:=
r
.
sql
.
ExecContext
(
ctx
,
`
UPDATE api_keys SET
usage_5h = CASE WHEN window_5h_start IS NOT NULL AND window_5h_start + INTERVAL '5 hours' <= NOW() THEN 0 ELSE usage_5h END,
window_5h_start = CASE WHEN window_5h_start IS NOT NULL AND window_5h_start + INTERVAL '5 hours' <= NOW() THEN NOW() ELSE window_5h_start END,
usage_1d = CASE WHEN window_1d_start IS NOT NULL AND window_1d_start + INTERVAL '24 hours' <= NOW() THEN 0 ELSE usage_1d END,
window_1d_start = CASE WHEN window_1d_start IS NOT NULL AND window_1d_start + INTERVAL '24 hours' <= NOW() THEN NOW() ELSE window_1d_start END,
usage_7d = CASE WHEN window_7d_start IS NOT NULL AND window_7d_start + INTERVAL '7 days' <= NOW() THEN 0 ELSE usage_7d END,
window_7d_start = CASE WHEN window_7d_start IS NOT NULL AND window_7d_start + INTERVAL '7 days' <= NOW() THEN NOW() ELSE window_7d_start END,
updated_at = NOW()
WHERE id = $1 AND deleted_at IS NULL`
,
id
)
return
err
}
// GetRateLimitData returns the current rate limit usage and window start times for an API key.
func
(
r
*
apiKeyRepository
)
GetRateLimitData
(
ctx
context
.
Context
,
id
int64
)
(
*
service
.
APIKeyRateLimitData
,
error
)
{
rows
,
err
:=
r
.
sql
.
QueryContext
(
ctx
,
`
SELECT usage_5h, usage_1d, usage_7d, window_5h_start, window_1d_start, window_7d_start
FROM api_keys
WHERE id = $1 AND deleted_at IS NULL`
,
id
)
if
err
!=
nil
{
return
nil
,
err
}
defer
rows
.
Close
()
if
!
rows
.
Next
()
{
return
nil
,
service
.
ErrAPIKeyNotFound
}
data
:=
&
service
.
APIKeyRateLimitData
{}
if
err
:=
rows
.
Scan
(
&
data
.
Usage5h
,
&
data
.
Usage1d
,
&
data
.
Usage7d
,
&
data
.
Window5hStart
,
&
data
.
Window1dStart
,
&
data
.
Window7dStart
);
err
!=
nil
{
return
nil
,
err
}
return
data
,
rows
.
Err
()
}
func
apiKeyEntityToService
(
m
*
dbent
.
APIKey
)
*
service
.
APIKey
{
func
apiKeyEntityToService
(
m
*
dbent
.
APIKey
)
*
service
.
APIKey
{
if
m
==
nil
{
if
m
==
nil
{
return
nil
return
nil
}
}
out
:=
&
service
.
APIKey
{
out
:=
&
service
.
APIKey
{
ID
:
m
.
ID
,
ID
:
m
.
ID
,
UserID
:
m
.
UserID
,
UserID
:
m
.
UserID
,
Key
:
m
.
Key
,
Key
:
m
.
Key
,
Name
:
m
.
Name
,
Name
:
m
.
Name
,
Status
:
m
.
Status
,
Status
:
m
.
Status
,
IPWhitelist
:
m
.
IPWhitelist
,
IPWhitelist
:
m
.
IPWhitelist
,
IPBlacklist
:
m
.
IPBlacklist
,
IPBlacklist
:
m
.
IPBlacklist
,
LastUsedAt
:
m
.
LastUsedAt
,
LastUsedAt
:
m
.
LastUsedAt
,
CreatedAt
:
m
.
CreatedAt
,
CreatedAt
:
m
.
CreatedAt
,
UpdatedAt
:
m
.
UpdatedAt
,
UpdatedAt
:
m
.
UpdatedAt
,
GroupID
:
m
.
GroupID
,
GroupID
:
m
.
GroupID
,
Quota
:
m
.
Quota
,
Quota
:
m
.
Quota
,
QuotaUsed
:
m
.
QuotaUsed
,
QuotaUsed
:
m
.
QuotaUsed
,
ExpiresAt
:
m
.
ExpiresAt
,
ExpiresAt
:
m
.
ExpiresAt
,
RateLimit5h
:
m
.
RateLimit5h
,
RateLimit1d
:
m
.
RateLimit1d
,
RateLimit7d
:
m
.
RateLimit7d
,
Usage5h
:
m
.
Usage5h
,
Usage1d
:
m
.
Usage1d
,
Usage7d
:
m
.
Usage7d
,
Window5hStart
:
m
.
Window5hStart
,
Window1dStart
:
m
.
Window1dStart
,
Window7dStart
:
m
.
Window7dStart
,
}
}
if
m
.
Edges
.
User
!=
nil
{
if
m
.
Edges
.
User
!=
nil
{
out
.
User
=
userEntityToService
(
m
.
Edges
.
User
)
out
.
User
=
userEntityToService
(
m
.
Edges
.
User
)
...
...
backend/internal/repository/billing_cache.go
View file @
a80ec5d8
...
@@ -14,10 +14,12 @@ import (
...
@@ -14,10 +14,12 @@ import (
)
)
const
(
const
(
billingBalanceKeyPrefix
=
"billing:balance:"
billingBalanceKeyPrefix
=
"billing:balance:"
billingSubKeyPrefix
=
"billing:sub:"
billingSubKeyPrefix
=
"billing:sub:"
billingCacheTTL
=
5
*
time
.
Minute
billingRateLimitKeyPrefix
=
"apikey:rate:"
billingCacheJitter
=
30
*
time
.
Second
billingCacheTTL
=
5
*
time
.
Minute
billingCacheJitter
=
30
*
time
.
Second
rateLimitCacheTTL
=
7
*
24
*
time
.
Hour
// 7 days matches the longest window
)
)
// jitteredTTL 返回带随机抖动的 TTL,防止缓存雪崩
// jitteredTTL 返回带随机抖动的 TTL,防止缓存雪崩
...
@@ -49,6 +51,20 @@ const (
...
@@ -49,6 +51,20 @@ const (
subFieldVersion
=
"version"
subFieldVersion
=
"version"
)
)
// billingRateLimitKey generates the Redis key for API key rate limit cache.
func
billingRateLimitKey
(
keyID
int64
)
string
{
return
fmt
.
Sprintf
(
"%s%d"
,
billingRateLimitKeyPrefix
,
keyID
)
}
const
(
rateLimitFieldUsage5h
=
"usage_5h"
rateLimitFieldUsage1d
=
"usage_1d"
rateLimitFieldUsage7d
=
"usage_7d"
rateLimitFieldWindow5h
=
"window_5h"
rateLimitFieldWindow1d
=
"window_1d"
rateLimitFieldWindow7d
=
"window_7d"
)
var
(
var
(
deductBalanceScript
=
redis
.
NewScript
(
`
deductBalanceScript
=
redis
.
NewScript
(
`
local current = redis.call('GET', KEYS[1])
local current = redis.call('GET', KEYS[1])
...
@@ -73,6 +89,21 @@ var (
...
@@ -73,6 +89,21 @@ var (
redis.call('EXPIRE', KEYS[1], ARGV[2])
redis.call('EXPIRE', KEYS[1], ARGV[2])
return 1
return 1
`
)
`
)
// updateRateLimitUsageScript atomically increments all three rate limit usage counters.
// Returns 0 if the key doesn't exist (cache miss), 1 on success.
updateRateLimitUsageScript
=
redis
.
NewScript
(
`
local exists = redis.call('EXISTS', KEYS[1])
if exists == 0 then
return 0
end
local cost = tonumber(ARGV[1])
redis.call('HINCRBYFLOAT', KEYS[1], 'usage_5h', cost)
redis.call('HINCRBYFLOAT', KEYS[1], 'usage_1d', cost)
redis.call('HINCRBYFLOAT', KEYS[1], 'usage_7d', cost)
redis.call('EXPIRE', KEYS[1], ARGV[2])
return 1
`
)
)
)
type
billingCache
struct
{
type
billingCache
struct
{
...
@@ -195,3 +226,69 @@ func (c *billingCache) InvalidateSubscriptionCache(ctx context.Context, userID,
...
@@ -195,3 +226,69 @@ func (c *billingCache) InvalidateSubscriptionCache(ctx context.Context, userID,
key
:=
billingSubKey
(
userID
,
groupID
)
key
:=
billingSubKey
(
userID
,
groupID
)
return
c
.
rdb
.
Del
(
ctx
,
key
)
.
Err
()
return
c
.
rdb
.
Del
(
ctx
,
key
)
.
Err
()
}
}
func
(
c
*
billingCache
)
GetAPIKeyRateLimit
(
ctx
context
.
Context
,
keyID
int64
)
(
*
service
.
APIKeyRateLimitCacheData
,
error
)
{
key
:=
billingRateLimitKey
(
keyID
)
result
,
err
:=
c
.
rdb
.
HGetAll
(
ctx
,
key
)
.
Result
()
if
err
!=
nil
{
return
nil
,
err
}
if
len
(
result
)
==
0
{
return
nil
,
redis
.
Nil
}
data
:=
&
service
.
APIKeyRateLimitCacheData
{}
if
v
,
ok
:=
result
[
rateLimitFieldUsage5h
];
ok
{
data
.
Usage5h
,
_
=
strconv
.
ParseFloat
(
v
,
64
)
}
if
v
,
ok
:=
result
[
rateLimitFieldUsage1d
];
ok
{
data
.
Usage1d
,
_
=
strconv
.
ParseFloat
(
v
,
64
)
}
if
v
,
ok
:=
result
[
rateLimitFieldUsage7d
];
ok
{
data
.
Usage7d
,
_
=
strconv
.
ParseFloat
(
v
,
64
)
}
if
v
,
ok
:=
result
[
rateLimitFieldWindow5h
];
ok
{
data
.
Window5h
,
_
=
strconv
.
ParseInt
(
v
,
10
,
64
)
}
if
v
,
ok
:=
result
[
rateLimitFieldWindow1d
];
ok
{
data
.
Window1d
,
_
=
strconv
.
ParseInt
(
v
,
10
,
64
)
}
if
v
,
ok
:=
result
[
rateLimitFieldWindow7d
];
ok
{
data
.
Window7d
,
_
=
strconv
.
ParseInt
(
v
,
10
,
64
)
}
return
data
,
nil
}
func
(
c
*
billingCache
)
SetAPIKeyRateLimit
(
ctx
context
.
Context
,
keyID
int64
,
data
*
service
.
APIKeyRateLimitCacheData
)
error
{
if
data
==
nil
{
return
nil
}
key
:=
billingRateLimitKey
(
keyID
)
fields
:=
map
[
string
]
any
{
rateLimitFieldUsage5h
:
data
.
Usage5h
,
rateLimitFieldUsage1d
:
data
.
Usage1d
,
rateLimitFieldUsage7d
:
data
.
Usage7d
,
rateLimitFieldWindow5h
:
data
.
Window5h
,
rateLimitFieldWindow1d
:
data
.
Window1d
,
rateLimitFieldWindow7d
:
data
.
Window7d
,
}
pipe
:=
c
.
rdb
.
Pipeline
()
pipe
.
HSet
(
ctx
,
key
,
fields
)
pipe
.
Expire
(
ctx
,
key
,
rateLimitCacheTTL
)
_
,
err
:=
pipe
.
Exec
(
ctx
)
return
err
}
func
(
c
*
billingCache
)
UpdateAPIKeyRateLimitUsage
(
ctx
context
.
Context
,
keyID
int64
,
cost
float64
)
error
{
key
:=
billingRateLimitKey
(
keyID
)
_
,
err
:=
updateRateLimitUsageScript
.
Run
(
ctx
,
c
.
rdb
,
[]
string
{
key
},
cost
,
int
(
rateLimitCacheTTL
.
Seconds
()))
.
Result
()
if
err
!=
nil
&&
!
errors
.
Is
(
err
,
redis
.
Nil
)
{
log
.
Printf
(
"Warning: update rate limit usage cache failed for api key %d: %v"
,
keyID
,
err
)
return
err
}
return
nil
}
func
(
c
*
billingCache
)
InvalidateAPIKeyRateLimit
(
ctx
context
.
Context
,
keyID
int64
)
error
{
key
:=
billingRateLimitKey
(
keyID
)
return
c
.
rdb
.
Del
(
ctx
,
key
)
.
Err
()
}
backend/internal/server/middleware/api_key_auth_google_test.go
View file @
a80ec5d8
...
@@ -95,6 +95,15 @@ func (f fakeAPIKeyRepo) UpdateLastUsed(ctx context.Context, id int64, usedAt tim
...
@@ -95,6 +95,15 @@ func (f fakeAPIKeyRepo) UpdateLastUsed(ctx context.Context, id int64, usedAt tim
}
}
return
nil
return
nil
}
}
func
(
f
fakeAPIKeyRepo
)
IncrementRateLimitUsage
(
ctx
context
.
Context
,
id
int64
,
cost
float64
)
error
{
return
nil
}
func
(
f
fakeAPIKeyRepo
)
ResetRateLimitWindows
(
ctx
context
.
Context
,
id
int64
)
error
{
return
nil
}
func
(
f
fakeAPIKeyRepo
)
GetRateLimitData
(
ctx
context
.
Context
,
id
int64
)
(
*
service
.
APIKeyRateLimitData
,
error
)
{
return
&
service
.
APIKeyRateLimitData
{},
nil
}
func
(
f
fakeGoogleSubscriptionRepo
)
Create
(
ctx
context
.
Context
,
sub
*
service
.
UserSubscription
)
error
{
func
(
f
fakeGoogleSubscriptionRepo
)
Create
(
ctx
context
.
Context
,
sub
*
service
.
UserSubscription
)
error
{
return
errors
.
New
(
"not implemented"
)
return
errors
.
New
(
"not implemented"
)
...
...
backend/internal/service/api_key.go
View file @
a80ec5d8
...
@@ -36,12 +36,28 @@ type APIKey struct {
...
@@ -36,12 +36,28 @@ type APIKey struct {
Quota
float64
// Quota limit in USD (0 = unlimited)
Quota
float64
// Quota limit in USD (0 = unlimited)
QuotaUsed
float64
// Used quota amount
QuotaUsed
float64
// Used quota amount
ExpiresAt
*
time
.
Time
// Expiration time (nil = never expires)
ExpiresAt
*
time
.
Time
// Expiration time (nil = never expires)
// Rate limit fields
RateLimit5h
float64
// Rate limit in USD per 5h (0 = unlimited)
RateLimit1d
float64
// Rate limit in USD per 1d (0 = unlimited)
RateLimit7d
float64
// Rate limit in USD per 7d (0 = unlimited)
Usage5h
float64
// Used amount in current 5h window
Usage1d
float64
// Used amount in current 1d window
Usage7d
float64
// Used amount in current 7d window
Window5hStart
*
time
.
Time
// Start of current 5h window
Window1dStart
*
time
.
Time
// Start of current 1d window
Window7dStart
*
time
.
Time
// Start of current 7d window
}
}
func
(
k
*
APIKey
)
IsActive
()
bool
{
func
(
k
*
APIKey
)
IsActive
()
bool
{
return
k
.
Status
==
StatusActive
return
k
.
Status
==
StatusActive
}
}
// HasRateLimits returns true if any rate limit window is configured
func
(
k
*
APIKey
)
HasRateLimits
()
bool
{
return
k
.
RateLimit5h
>
0
||
k
.
RateLimit1d
>
0
||
k
.
RateLimit7d
>
0
}
// IsExpired checks if the API key has expired
// IsExpired checks if the API key has expired
func
(
k
*
APIKey
)
IsExpired
()
bool
{
func
(
k
*
APIKey
)
IsExpired
()
bool
{
if
k
.
ExpiresAt
==
nil
{
if
k
.
ExpiresAt
==
nil
{
...
...
Prev
1
2
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