feat(api-key): add independent quota and expiration support
This feature allows API Keys to have their own quota limits and expiration times, independent of the user's balance. Backend: - Add quota, quota_used, expires_at fields to api_key schema - Implement IsExpired() and IsQuotaExhausted() checks in middleware - Add ResetQuota and ClearExpiration API endpoints - Integrate quota billing in gateway handlers (OpenAI, Anthropic, Gemini) - Include quota/expiration fields in auth cache for performance - Expiration check returns 403, quota exhausted returns 429 Frontend: - Add quota and expiration inputs to key create/edit dialog - Add quick-select buttons for expiration (+7, +30, +90 days) - Add reset quota confirmation dialog - Add expires_at column to keys list - Add i18n translations for new features (en/zh) Migration: - Add 045_add_api_key_quota.sql for new columns
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/Wei-Shaw/sub2api/internal/domain"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema"
|
||||
"entgo.io/ent/schema/edge"
|
||||
@@ -52,6 +53,23 @@ func (APIKey) Fields() []ent.Field {
|
||||
field.JSON("ip_blacklist", []string{}).
|
||||
Optional().
|
||||
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 {
|
||||
index.Fields("group_id"),
|
||||
index.Fields("status"),
|
||||
index.Fields("deleted_at"),
|
||||
// Index for quota queries
|
||||
index.Fields("quota", "quota_used"),
|
||||
index.Fields("expires_at"),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user