From 112a2d0866c7746ca817ea8a27e186eab4da52c4 Mon Sep 17 00:00:00 2001 From: ianshaw Date: Sat, 3 Jan 2026 06:37:08 -0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E3=80=81=E9=85=8D=E7=BD=AE=E5=92=8C=E4=BB=A3=E7=A0=81=E7=94=9F?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要更新: - 更新 go.mod/go.sum 依赖 - 重新生成 Ent ORM 代码 - 更新 Wire 依赖注入配置 - 添加 docker-compose.override.yml 到 .gitignore - 更新 README 文档(Simple Mode 说明和已知问题) - 清理调试日志 - 其他代码优化和格式修复 --- .gitignore | 4 +- README.md | 16 + README_CN.md | 4 + backend/__tmp_test | 0 backend/cmd/server/wire.go | 18 - backend/cmd/server/wire_gen.go | 66 +- backend/ent/apikey.go | 68 +- backend/ent/apikey/apikey.go | 2 +- backend/ent/apikey/where.go | 404 ++-- backend/ent/apikey_create.go | 362 ++-- backend/ent/apikey_delete.go | 30 +- backend/ent/apikey_query.go | 178 +- backend/ent/apikey_update.go | 176 +- backend/ent/client.go | 410 ++-- backend/ent/driver_access.go | 1 - backend/ent/group.go | 6 +- backend/ent/group/group.go | 2 +- backend/ent/group/where.go | 2 +- backend/ent/group_create.go | 6 +- backend/ent/group_query.go | 18 +- backend/ent/group_update.go | 28 +- backend/ent/hook/hook.go | 24 +- backend/ent/intercept/intercept.go | 58 +- backend/ent/migrate/schema.go | 140 +- backend/ent/mutation.go | 1912 ++++++++--------- backend/ent/predicate/predicate.go | 6 +- backend/ent/runtime/runtime.go | 122 +- backend/ent/schema/api_key.go | 14 +- backend/ent/schema/group.go | 2 +- backend/ent/schema/usage_log.go | 2 +- backend/ent/schema/user.go | 2 +- backend/ent/tx.go | 8 +- backend/ent/usagelog.go | 6 +- backend/ent/usagelog/usagelog.go | 2 +- backend/ent/usagelog/where.go | 2 +- backend/ent/usagelog_create.go | 4 +- backend/ent/usagelog_query.go | 14 +- backend/ent/usagelog_update.go | 12 +- backend/ent/user.go | 6 +- backend/ent/user/user.go | 2 +- backend/ent/user/where.go | 2 +- backend/ent/user_create.go | 6 +- backend/ent/user_query.go | 18 +- backend/ent/user_update.go | 28 +- backend/go.mod | 1 - backend/go.sum | 2 - backend/internal/config/config.go | 5 +- backend/internal/config/wire.go | 1 - .../handler/admin/dashboard_handler.go | 28 +- .../internal/handler/admin/group_handler.go | 4 +- .../internal/handler/admin/setting_handler.go | 192 +- .../internal/handler/admin/usage_handler.go | 20 +- .../internal/handler/admin/user_handler.go | 4 +- backend/internal/handler/api_key_handler.go | 18 +- backend/internal/handler/dto/settings.go | 29 +- backend/internal/handler/handler.go | 1 - .../handler/openai_gateway_handler.go | 12 +- backend/internal/handler/setting_handler.go | 4 +- backend/internal/handler/usage_handler.go | 30 +- backend/internal/handler/wire.go | 3 - backend/internal/pkg/claude/constants.go | 11 +- backend/internal/pkg/errors/types.go | 1 - backend/internal/pkg/gemini/models.go | 4 +- backend/internal/pkg/googleapi/status.go | 1 - backend/internal/pkg/oauth/oauth.go | 1 - backend/internal/pkg/openai/constants.go | 1 - backend/internal/pkg/openai/oauth.go | 2 +- backend/internal/pkg/pagination/pagination.go | 1 - backend/internal/pkg/response/response.go | 1 - backend/internal/pkg/sysutil/restart.go | 1 - .../pkg/usagestats/usage_log_types.go | 23 +- .../account_repo_integration_test.go | 6 +- ...llowed_groups_contract_integration_test.go | 6 +- backend/internal/repository/api_key_cache.go | 2 +- .../api_key_cache_integration_test.go | 10 +- .../internal/repository/api_key_cache_test.go | 2 +- backend/internal/repository/api_key_repo.go | 60 +- .../api_key_repo_integration_test.go | 118 +- backend/internal/repository/ent.go | 2 +- .../repository/fixtures_integration_test.go | 4 +- backend/internal/repository/group_repo.go | 4 +- .../soft_delete_ent_integration_test.go | 28 +- backend/internal/repository/user_repo.go | 93 +- backend/internal/repository/wire.go | 6 +- backend/internal/server/http.go | 5 +- .../internal/server/middleware/admin_auth.go | 37 +- .../server/middleware/api_key_auth.go | 85 +- .../server/middleware/api_key_auth_google.go | 16 +- .../middleware/api_key_auth_google_test.go | 82 +- .../server/middleware/api_key_auth_test.go | 48 +- backend/internal/server/middleware/logger.go | 5 +- .../internal/server/middleware/middleware.go | 6 +- backend/internal/server/middleware/wire.go | 6 +- backend/internal/server/router.go | 8 +- backend/internal/server/routes/common.go | 1 - backend/internal/server/routes/user.go | 2 +- backend/internal/service/account.go | 135 +- backend/internal/service/account_service.go | 4 +- .../service/account_service_delete_test.go | 8 + .../internal/service/account_test_service.go | 6 +- backend/internal/service/api_key.go | 4 +- backend/internal/service/api_key_service.go | 118 +- .../service/api_key_service_delete_test.go | 58 +- .../internal/service/billing_cache_service.go | 2 +- backend/internal/service/crs_sync_service.go | 14 +- backend/internal/service/dashboard_service.go | 8 +- backend/internal/service/domain_constants.go | 33 +- backend/internal/service/email_service.go | 46 +- .../service/openai_gateway_service.go | 20 +- backend/internal/service/setting_service.go | 140 +- backend/internal/service/settings_view.go | 29 +- backend/internal/service/update_service.go | 10 +- backend/internal/service/usage_clamp.go | 35 + backend/internal/service/usage_log.go | 4 +- backend/internal/service/usage_service.go | 22 +- backend/internal/service/user.go | 2 +- .../service/user_attribute_service.go | 30 +- backend/internal/service/wire.go | 34 +- backend/internal/setup/cli.go | 1 - backend/internal/setup/setup.go | 6 +- backend/internal/web/embed_off.go | 1 - 121 files changed, 3058 insertions(+), 2948 deletions(-) create mode 100644 backend/__tmp_test create mode 100644 backend/internal/service/usage_clamp.go diff --git a/.gitignore b/.gitignore index c386360e..b764039e 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ pnpm-debug.log* .env.*.local *.env !.env.example +docker-compose.override.yml # =================== # IDE / 编辑器 @@ -78,8 +79,6 @@ temp/ *.log *.bak .cache/ -.gemini-clipboard/ -migrations/ # =================== # 构建产物 @@ -121,3 +120,4 @@ code-reviews/ AGENTS.md backend/cmd/server/server deploy/docker-compose.override.yml +.gocache/ diff --git a/README.md b/README.md index a6d051b0..c3a37e68 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,16 @@ go generate ./cmd/server --- +## Simple Mode + +Simple Mode is designed for individual developers or internal teams who want quick access without full SaaS features. + +- Enable: Set environment variable `RUN_MODE=simple` +- Difference: Hides SaaS-related features and skips billing process +- Security note: In production, you must also set `SIMPLE_MODE_CONFIRM=true` to allow startup + +--- + ## Antigravity Support Sub2API supports [Antigravity](https://antigravity.so/) accounts. After authorization, dedicated endpoints are available for Claude and Gemini models. @@ -321,6 +331,12 @@ Antigravity accounts support optional **hybrid scheduling**. When enabled, the g > **⚠️ Warning**: Anthropic Claude and Antigravity Claude **cannot be mixed within the same conversation context**. Use groups to isolate them properly. +### Known Issues + +In Claude Code, Plan Mode cannot exit automatically. (Normally when using the native Claude API, after planning is complete, Claude Code will pop up options for users to approve or reject the plan.) + +**Workaround**: Press `Shift + Tab` to manually exit Plan Mode, then type your response to approve or reject the plan. + --- ## Project Structure diff --git a/README_CN.md b/README_CN.md index 0e15be1f..8fe46c51 100644 --- a/README_CN.md +++ b/README_CN.md @@ -331,6 +331,10 @@ Antigravity 账户支持可选的**混合调度**功能。开启后,通用端 > **⚠️ 注意**:Anthropic Claude 和 Antigravity Claude **不能在同一上下文中混合使用**,请通过分组功能做好隔离。 + +### 已知问题 +在 Claude Code 中,无法自动退出Plan Mode。(正常使用原生Claude Api时,Plan 完成后,Claude Code会弹出弹出选项让用户同意或拒绝Plan。) +解决办法:shift + Tab,手动退出Plan mode,然后输入内容 告诉 Claude Code 同意或拒绝 Plan --- ## 项目结构 diff --git a/backend/__tmp_test b/backend/__tmp_test new file mode 100644 index 00000000..e69de29b diff --git a/backend/cmd/server/wire.go b/backend/cmd/server/wire.go index dcc807c3..ff6ab4e6 100644 --- a/backend/cmd/server/wire.go +++ b/backend/cmd/server/wire.go @@ -70,13 +70,7 @@ func provideCleanup( openaiOAuth *service.OpenAIOAuthService, geminiOAuth *service.GeminiOAuthService, antigravityOAuth *service.AntigravityOAuthService, - antigravityQuota *service.AntigravityQuotaRefresher, - opsMetricsCollector *service.OpsMetricsCollector, - opsAlertService *service.OpsAlertService, ) func() { - if opsAlertService != nil { - opsAlertService.Start() - } return func() { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() @@ -86,14 +80,6 @@ func provideCleanup( name string fn func() error }{ - {"OpsMetricsCollector", func() error { - opsMetricsCollector.Stop() - return nil - }}, - {"OpsAlertService", func() error { - opsAlertService.Stop() - return nil - }}, {"TokenRefreshService", func() error { tokenRefresh.Stop() return nil @@ -126,10 +112,6 @@ func provideCleanup( antigravityOAuth.Stop() return nil }}, - {"AntigravityQuotaRefresher", func() error { - antigravityQuota.Stop() - return nil - }}, {"Redis", func() error { return rdb.Close() }}, diff --git a/backend/cmd/server/wire_gen.go b/backend/cmd/server/wire_gen.go index b186c68e..7c0ec52e 100644 --- a/backend/cmd/server/wire_gen.go +++ b/backend/cmd/server/wire_gen.go @@ -55,11 +55,11 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { userService := service.NewUserService(userRepository) authHandler := handler.NewAuthHandler(configConfig, authService, userService) userHandler := handler.NewUserHandler(userService) - apiKeyRepository := repository.NewAPIKeyRepository(client) + apiKeyRepository := repository.NewApiKeyRepository(client) groupRepository := repository.NewGroupRepository(client, db) userSubscriptionRepository := repository.NewUserSubscriptionRepository(client) - apiKeyCache := repository.NewAPIKeyCache(redisClient) - apiKeyService := service.NewAPIKeyService(apiKeyRepository, userRepository, groupRepository, userSubscriptionRepository, apiKeyCache, configConfig) + apiKeyCache := repository.NewApiKeyCache(redisClient) + apiKeyService := service.NewApiKeyService(apiKeyRepository, userRepository, groupRepository, userSubscriptionRepository, apiKeyCache, configConfig) apiKeyHandler := handler.NewAPIKeyHandler(apiKeyService) usageLogRepository := repository.NewUsageLogRepository(client, db) usageService := service.NewUsageService(usageLogRepository, userRepository) @@ -74,9 +74,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { subscriptionHandler := handler.NewSubscriptionHandler(subscriptionService) dashboardService := service.NewDashboardService(usageLogRepository) dashboardHandler := admin.NewDashboardHandler(dashboardService) - opsRepository := repository.NewOpsRepository(client, db, redisClient) - opsService := service.NewOpsService(opsRepository, db) - opsHandler := admin.NewOpsHandler(opsService) accountRepository := repository.NewAccountRepository(client, db) proxyRepository := repository.NewProxyRepository(client, db) proxyExitInfoProber := repository.NewProxyExitInfoProber() @@ -91,16 +88,19 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { geminiCliCodeAssistClient := repository.NewGeminiCliCodeAssistClient() geminiOAuthService := service.NewGeminiOAuthService(proxyRepository, geminiOAuthClient, geminiCliCodeAssistClient, configConfig) geminiQuotaService := service.NewGeminiQuotaService(configConfig, settingRepository) - rateLimitService := service.NewRateLimitService(accountRepository, usageLogRepository, configConfig, geminiQuotaService) + tempUnschedCache := repository.NewTempUnschedCache(redisClient) + rateLimitService := service.NewRateLimitService(accountRepository, usageLogRepository, configConfig, geminiQuotaService, tempUnschedCache) claudeUsageFetcher := repository.NewClaudeUsageFetcher() - accountUsageService := service.NewAccountUsageService(accountRepository, usageLogRepository, claudeUsageFetcher, geminiQuotaService) + antigravityQuotaFetcher := service.NewAntigravityQuotaFetcher(proxyRepository) + usageCache := service.NewUsageCache() + accountUsageService := service.NewAccountUsageService(accountRepository, usageLogRepository, claudeUsageFetcher, geminiQuotaService, antigravityQuotaFetcher, usageCache) geminiTokenCache := repository.NewGeminiTokenCache(redisClient) geminiTokenProvider := service.NewGeminiTokenProvider(accountRepository, geminiTokenCache, geminiOAuthService) gatewayCache := repository.NewGatewayCache(redisClient) antigravityOAuthService := service.NewAntigravityOAuthService(proxyRepository) antigravityTokenProvider := service.NewAntigravityTokenProvider(accountRepository, geminiTokenCache, antigravityOAuthService) httpUpstream := repository.NewHTTPUpstream(configConfig) - antigravityGatewayService := service.NewAntigravityGatewayService(accountRepository, gatewayCache, antigravityTokenProvider, rateLimitService, httpUpstream) + antigravityGatewayService := service.NewAntigravityGatewayService(accountRepository, gatewayCache, antigravityTokenProvider, rateLimitService, httpUpstream, settingService) accountTestService := service.NewAccountTestService(accountRepository, oAuthService, openAIOAuthService, geminiTokenProvider, antigravityGatewayService, httpUpstream) concurrencyCache := repository.ProvideConcurrencyCache(redisClient, configConfig) concurrencyService := service.ProvideConcurrencyService(concurrencyCache, accountRepository, configConfig) @@ -124,24 +124,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { userAttributeValueRepository := repository.NewUserAttributeValueRepository(client) userAttributeService := service.NewUserAttributeService(userAttributeDefinitionRepository, userAttributeValueRepository) userAttributeHandler := admin.NewUserAttributeHandler(userAttributeService) - adminHandlers := handler.ProvideAdminHandlers( - dashboardHandler, - opsHandler, - adminUserHandler, - groupHandler, - accountHandler, - oAuthHandler, - openAIOAuthHandler, - geminiOAuthHandler, - antigravityOAuthHandler, - proxyHandler, - adminRedeemHandler, - settingHandler, - systemHandler, - adminSubscriptionHandler, - adminUsageHandler, - userAttributeHandler, - ) + adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, settingHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler, userAttributeHandler) pricingRemoteClient := repository.NewPricingRemoteClient() pricingService, err := service.ProvidePricingService(configConfig, pricingRemoteClient) if err != nil { @@ -154,21 +137,18 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { deferredService := service.ProvideDeferredService(accountRepository, timingWheelService) gatewayService := service.NewGatewayService(accountRepository, groupRepository, usageLogRepository, userRepository, userSubscriptionRepository, gatewayCache, configConfig, concurrencyService, billingService, rateLimitService, billingCacheService, identityService, httpUpstream, deferredService) geminiMessagesCompatService := service.NewGeminiMessagesCompatService(accountRepository, groupRepository, gatewayCache, geminiTokenProvider, rateLimitService, httpUpstream, antigravityGatewayService) - gatewayHandler := handler.NewGatewayHandler(gatewayService, geminiMessagesCompatService, antigravityGatewayService, userService, concurrencyService, billingCacheService, opsService) + gatewayHandler := handler.NewGatewayHandler(gatewayService, geminiMessagesCompatService, antigravityGatewayService, userService, concurrencyService, billingCacheService) openAIGatewayService := service.NewOpenAIGatewayService(accountRepository, usageLogRepository, userRepository, userSubscriptionRepository, gatewayCache, configConfig, concurrencyService, billingService, rateLimitService, billingCacheService, httpUpstream, deferredService) - openAIGatewayHandler := handler.NewOpenAIGatewayHandler(openAIGatewayService, concurrencyService, billingCacheService, opsService) + openAIGatewayHandler := handler.NewOpenAIGatewayHandler(openAIGatewayService, concurrencyService, billingCacheService) handlerSettingHandler := handler.ProvideSettingHandler(settingService, buildInfo) handlers := handler.ProvideHandlers(authHandler, userHandler, apiKeyHandler, usageHandler, redeemHandler, subscriptionHandler, adminHandlers, gatewayHandler, openAIGatewayHandler, handlerSettingHandler) jwtAuthMiddleware := middleware.NewJWTAuthMiddleware(authService, userService) adminAuthMiddleware := middleware.NewAdminAuthMiddleware(authService, userService, settingService) - apiKeyAuthMiddleware := middleware.NewAPIKeyAuthMiddleware(apiKeyService, subscriptionService, configConfig, opsService) + apiKeyAuthMiddleware := middleware.NewApiKeyAuthMiddleware(apiKeyService, subscriptionService, configConfig) engine := server.ProvideRouter(configConfig, handlers, jwtAuthMiddleware, adminAuthMiddleware, apiKeyAuthMiddleware, apiKeyService, subscriptionService) httpServer := server.ProvideHTTPServer(configConfig, engine) tokenRefreshService := service.ProvideTokenRefreshService(accountRepository, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, configConfig) - antigravityQuotaRefresher := service.ProvideAntigravityQuotaRefresher(accountRepository, proxyRepository, antigravityOAuthService, configConfig) - opsAlertService := service.ProvideOpsAlertService(opsService, userService, emailService) - opsMetricsCollector := service.ProvideOpsMetricsCollector(opsService, concurrencyService) - v := provideCleanup(client, redisClient, tokenRefreshService, pricingService, emailQueueService, billingCacheService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, antigravityQuotaRefresher, opsMetricsCollector, opsAlertService) + v := provideCleanup(client, redisClient, tokenRefreshService, pricingService, emailQueueService, billingCacheService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService) application := &Application{ Server: httpServer, Cleanup: v, @@ -201,13 +181,7 @@ func provideCleanup( openaiOAuth *service.OpenAIOAuthService, geminiOAuth *service.GeminiOAuthService, antigravityOAuth *service.AntigravityOAuthService, - antigravityQuota *service.AntigravityQuotaRefresher, - opsMetricsCollector *service.OpsMetricsCollector, - opsAlertService *service.OpsAlertService, ) func() { - if opsAlertService != nil { - opsAlertService.Start() - } return func() { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() @@ -216,14 +190,6 @@ func provideCleanup( name string fn func() error }{ - {"OpsMetricsCollector", func() error { - opsMetricsCollector.Stop() - return nil - }}, - {"OpsAlertService", func() error { - opsAlertService.Stop() - return nil - }}, {"TokenRefreshService", func() error { tokenRefresh.Stop() return nil @@ -256,10 +222,6 @@ func provideCleanup( antigravityOAuth.Stop() return nil }}, - {"AntigravityQuotaRefresher", func() error { - antigravityQuota.Stop() - return nil - }}, {"Redis", func() error { return rdb.Close() }}, diff --git a/backend/ent/apikey.go b/backend/ent/apikey.go index fe3ad0cf..61ac15fa 100644 --- a/backend/ent/apikey.go +++ b/backend/ent/apikey.go @@ -14,8 +14,8 @@ import ( "github.com/Wei-Shaw/sub2api/ent/user" ) -// APIKey is the model entity for the APIKey schema. -type APIKey struct { +// ApiKey is the model entity for the ApiKey schema. +type ApiKey struct { config `json:"-"` // ID of the ent. ID int64 `json:"id,omitempty"` @@ -36,13 +36,13 @@ type APIKey struct { // Status holds the value of the "status" field. Status string `json:"status,omitempty"` // Edges holds the relations/edges for other nodes in the graph. - // The values are being populated by the APIKeyQuery when eager-loading is set. - Edges APIKeyEdges `json:"edges"` + // The values are being populated by the ApiKeyQuery when eager-loading is set. + Edges ApiKeyEdges `json:"edges"` selectValues sql.SelectValues } -// APIKeyEdges holds the relations/edges for other nodes in the graph. -type APIKeyEdges struct { +// ApiKeyEdges holds the relations/edges for other nodes in the graph. +type ApiKeyEdges struct { // User holds the value of the user edge. User *User `json:"user,omitempty"` // Group holds the value of the group edge. @@ -56,7 +56,7 @@ type APIKeyEdges struct { // UserOrErr returns the User value or an error if the edge // was not loaded in eager-loading, or loaded but was not found. -func (e APIKeyEdges) UserOrErr() (*User, error) { +func (e ApiKeyEdges) UserOrErr() (*User, error) { if e.User != nil { return e.User, nil } else if e.loadedTypes[0] { @@ -67,7 +67,7 @@ func (e APIKeyEdges) UserOrErr() (*User, error) { // GroupOrErr returns the Group value or an error if the edge // was not loaded in eager-loading, or loaded but was not found. -func (e APIKeyEdges) GroupOrErr() (*Group, error) { +func (e ApiKeyEdges) GroupOrErr() (*Group, error) { if e.Group != nil { return e.Group, nil } else if e.loadedTypes[1] { @@ -78,7 +78,7 @@ func (e APIKeyEdges) GroupOrErr() (*Group, error) { // UsageLogsOrErr returns the UsageLogs value or an error if the edge // was not loaded in eager-loading. -func (e APIKeyEdges) UsageLogsOrErr() ([]*UsageLog, error) { +func (e ApiKeyEdges) UsageLogsOrErr() ([]*UsageLog, error) { if e.loadedTypes[2] { return e.UsageLogs, nil } @@ -86,7 +86,7 @@ func (e APIKeyEdges) UsageLogsOrErr() ([]*UsageLog, error) { } // scanValues returns the types for scanning values from sql.Rows. -func (*APIKey) scanValues(columns []string) ([]any, error) { +func (*ApiKey) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { @@ -104,8 +104,8 @@ func (*APIKey) scanValues(columns []string) ([]any, error) { } // assignValues assigns the values that were returned from sql.Rows (after scanning) -// to the APIKey fields. -func (_m *APIKey) assignValues(columns []string, values []any) error { +// to the ApiKey fields. +func (_m *ApiKey) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -174,49 +174,49 @@ func (_m *APIKey) assignValues(columns []string, values []any) error { return nil } -// Value returns the ent.Value that was dynamically selected and assigned to the APIKey. +// Value returns the ent.Value that was dynamically selected and assigned to the ApiKey. // This includes values selected through modifiers, order, etc. -func (_m *APIKey) Value(name string) (ent.Value, error) { +func (_m *ApiKey) Value(name string) (ent.Value, error) { return _m.selectValues.Get(name) } -// QueryUser queries the "user" edge of the APIKey entity. -func (_m *APIKey) QueryUser() *UserQuery { - return NewAPIKeyClient(_m.config).QueryUser(_m) +// QueryUser queries the "user" edge of the ApiKey entity. +func (_m *ApiKey) QueryUser() *UserQuery { + return NewApiKeyClient(_m.config).QueryUser(_m) } -// QueryGroup queries the "group" edge of the APIKey entity. -func (_m *APIKey) QueryGroup() *GroupQuery { - return NewAPIKeyClient(_m.config).QueryGroup(_m) +// QueryGroup queries the "group" edge of the ApiKey entity. +func (_m *ApiKey) QueryGroup() *GroupQuery { + return NewApiKeyClient(_m.config).QueryGroup(_m) } -// QueryUsageLogs queries the "usage_logs" edge of the APIKey entity. -func (_m *APIKey) QueryUsageLogs() *UsageLogQuery { - return NewAPIKeyClient(_m.config).QueryUsageLogs(_m) +// QueryUsageLogs queries the "usage_logs" edge of the ApiKey entity. +func (_m *ApiKey) QueryUsageLogs() *UsageLogQuery { + return NewApiKeyClient(_m.config).QueryUsageLogs(_m) } -// Update returns a builder for updating this APIKey. -// Note that you need to call APIKey.Unwrap() before calling this method if this APIKey +// Update returns a builder for updating this ApiKey. +// Note that you need to call ApiKey.Unwrap() before calling this method if this ApiKey // was returned from a transaction, and the transaction was committed or rolled back. -func (_m *APIKey) Update() *APIKeyUpdateOne { - return NewAPIKeyClient(_m.config).UpdateOne(_m) +func (_m *ApiKey) Update() *ApiKeyUpdateOne { + return NewApiKeyClient(_m.config).UpdateOne(_m) } -// Unwrap unwraps the APIKey entity that was returned from a transaction after it was closed, +// Unwrap unwraps the ApiKey entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (_m *APIKey) Unwrap() *APIKey { +func (_m *ApiKey) Unwrap() *ApiKey { _tx, ok := _m.config.driver.(*txDriver) if !ok { - panic("ent: APIKey is not a transactional entity") + panic("ent: ApiKey is not a transactional entity") } _m.config.driver = _tx.drv return _m } // String implements the fmt.Stringer. -func (_m *APIKey) String() string { +func (_m *ApiKey) String() string { var builder strings.Builder - builder.WriteString("APIKey(") + builder.WriteString("ApiKey(") builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("created_at=") builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) @@ -249,5 +249,5 @@ func (_m *APIKey) String() string { return builder.String() } -// APIKeys is a parsable slice of APIKey. -type APIKeys []*APIKey +// ApiKeys is a parsable slice of ApiKey. +type ApiKeys []*ApiKey diff --git a/backend/ent/apikey/apikey.go b/backend/ent/apikey/apikey.go index 91f7d620..f03b2daa 100644 --- a/backend/ent/apikey/apikey.go +++ b/backend/ent/apikey/apikey.go @@ -109,7 +109,7 @@ var ( StatusValidator func(string) error ) -// OrderOption defines the ordering options for the APIKey queries. +// OrderOption defines the ordering options for the ApiKey queries. type OrderOption func(*sql.Selector) // ByID orders the results by the id field. diff --git a/backend/ent/apikey/where.go b/backend/ent/apikey/where.go index 5e739006..95bc4e2a 100644 --- a/backend/ent/apikey/where.go +++ b/backend/ent/apikey/where.go @@ -11,468 +11,468 @@ import ( ) // ID filters vertices based on their ID field. -func ID(id int64) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldID, id)) +func ID(id int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. -func IDEQ(id int64) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldID, id)) +func IDEQ(id int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. -func IDNEQ(id int64) predicate.APIKey { - return predicate.APIKey(sql.FieldNEQ(FieldID, id)) +func IDNEQ(id int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. -func IDIn(ids ...int64) predicate.APIKey { - return predicate.APIKey(sql.FieldIn(FieldID, ids...)) +func IDIn(ids ...int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. -func IDNotIn(ids ...int64) predicate.APIKey { - return predicate.APIKey(sql.FieldNotIn(FieldID, ids...)) +func IDNotIn(ids ...int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. -func IDGT(id int64) predicate.APIKey { - return predicate.APIKey(sql.FieldGT(FieldID, id)) +func IDGT(id int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. -func IDGTE(id int64) predicate.APIKey { - return predicate.APIKey(sql.FieldGTE(FieldID, id)) +func IDGTE(id int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. -func IDLT(id int64) predicate.APIKey { - return predicate.APIKey(sql.FieldLT(FieldID, id)) +func IDLT(id int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. -func IDLTE(id int64) predicate.APIKey { - return predicate.APIKey(sql.FieldLTE(FieldID, id)) +func IDLTE(id int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLTE(FieldID, id)) } // CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. -func CreatedAt(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldCreatedAt, v)) +func CreatedAt(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldCreatedAt, v)) } // UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. -func UpdatedAt(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldUpdatedAt, v)) +func UpdatedAt(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldUpdatedAt, v)) } // DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ. -func DeletedAt(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldDeletedAt, v)) +func DeletedAt(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldDeletedAt, v)) } // UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. -func UserID(v int64) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldUserID, v)) +func UserID(v int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldUserID, v)) } // Key applies equality check predicate on the "key" field. It's identical to KeyEQ. -func Key(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldKey, v)) +func Key(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldKey, v)) } // Name applies equality check predicate on the "name" field. It's identical to NameEQ. -func Name(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldName, v)) +func Name(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldName, v)) } // GroupID applies equality check predicate on the "group_id" field. It's identical to GroupIDEQ. -func GroupID(v int64) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldGroupID, v)) +func GroupID(v int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldGroupID, v)) } // Status applies equality check predicate on the "status" field. It's identical to StatusEQ. -func Status(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldStatus, v)) +func Status(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldStatus, v)) } // CreatedAtEQ applies the EQ predicate on the "created_at" field. -func CreatedAtEQ(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldCreatedAt, v)) +func CreatedAtEQ(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldCreatedAt, v)) } // CreatedAtNEQ applies the NEQ predicate on the "created_at" field. -func CreatedAtNEQ(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldNEQ(FieldCreatedAt, v)) +func CreatedAtNEQ(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNEQ(FieldCreatedAt, v)) } // CreatedAtIn applies the In predicate on the "created_at" field. -func CreatedAtIn(vs ...time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldIn(FieldCreatedAt, vs...)) +func CreatedAtIn(vs ...time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldIn(FieldCreatedAt, vs...)) } // CreatedAtNotIn applies the NotIn predicate on the "created_at" field. -func CreatedAtNotIn(vs ...time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldNotIn(FieldCreatedAt, vs...)) +func CreatedAtNotIn(vs ...time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotIn(FieldCreatedAt, vs...)) } // CreatedAtGT applies the GT predicate on the "created_at" field. -func CreatedAtGT(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldGT(FieldCreatedAt, v)) +func CreatedAtGT(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGT(FieldCreatedAt, v)) } // CreatedAtGTE applies the GTE predicate on the "created_at" field. -func CreatedAtGTE(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldGTE(FieldCreatedAt, v)) +func CreatedAtGTE(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGTE(FieldCreatedAt, v)) } // CreatedAtLT applies the LT predicate on the "created_at" field. -func CreatedAtLT(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldLT(FieldCreatedAt, v)) +func CreatedAtLT(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLT(FieldCreatedAt, v)) } // CreatedAtLTE applies the LTE predicate on the "created_at" field. -func CreatedAtLTE(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldLTE(FieldCreatedAt, v)) +func CreatedAtLTE(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLTE(FieldCreatedAt, v)) } // UpdatedAtEQ applies the EQ predicate on the "updated_at" field. -func UpdatedAtEQ(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldUpdatedAt, v)) +func UpdatedAtEQ(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldUpdatedAt, v)) } // UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. -func UpdatedAtNEQ(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldNEQ(FieldUpdatedAt, v)) +func UpdatedAtNEQ(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNEQ(FieldUpdatedAt, v)) } // UpdatedAtIn applies the In predicate on the "updated_at" field. -func UpdatedAtIn(vs ...time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldIn(FieldUpdatedAt, vs...)) +func UpdatedAtIn(vs ...time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldIn(FieldUpdatedAt, vs...)) } // UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. -func UpdatedAtNotIn(vs ...time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldNotIn(FieldUpdatedAt, vs...)) +func UpdatedAtNotIn(vs ...time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotIn(FieldUpdatedAt, vs...)) } // UpdatedAtGT applies the GT predicate on the "updated_at" field. -func UpdatedAtGT(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldGT(FieldUpdatedAt, v)) +func UpdatedAtGT(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGT(FieldUpdatedAt, v)) } // UpdatedAtGTE applies the GTE predicate on the "updated_at" field. -func UpdatedAtGTE(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldGTE(FieldUpdatedAt, v)) +func UpdatedAtGTE(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGTE(FieldUpdatedAt, v)) } // UpdatedAtLT applies the LT predicate on the "updated_at" field. -func UpdatedAtLT(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldLT(FieldUpdatedAt, v)) +func UpdatedAtLT(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLT(FieldUpdatedAt, v)) } // UpdatedAtLTE applies the LTE predicate on the "updated_at" field. -func UpdatedAtLTE(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldLTE(FieldUpdatedAt, v)) +func UpdatedAtLTE(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLTE(FieldUpdatedAt, v)) } // DeletedAtEQ applies the EQ predicate on the "deleted_at" field. -func DeletedAtEQ(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldDeletedAt, v)) +func DeletedAtEQ(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldDeletedAt, v)) } // DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field. -func DeletedAtNEQ(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldNEQ(FieldDeletedAt, v)) +func DeletedAtNEQ(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNEQ(FieldDeletedAt, v)) } // DeletedAtIn applies the In predicate on the "deleted_at" field. -func DeletedAtIn(vs ...time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldIn(FieldDeletedAt, vs...)) +func DeletedAtIn(vs ...time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldIn(FieldDeletedAt, vs...)) } // DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field. -func DeletedAtNotIn(vs ...time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldNotIn(FieldDeletedAt, vs...)) +func DeletedAtNotIn(vs ...time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotIn(FieldDeletedAt, vs...)) } // DeletedAtGT applies the GT predicate on the "deleted_at" field. -func DeletedAtGT(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldGT(FieldDeletedAt, v)) +func DeletedAtGT(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGT(FieldDeletedAt, v)) } // DeletedAtGTE applies the GTE predicate on the "deleted_at" field. -func DeletedAtGTE(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldGTE(FieldDeletedAt, v)) +func DeletedAtGTE(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGTE(FieldDeletedAt, v)) } // DeletedAtLT applies the LT predicate on the "deleted_at" field. -func DeletedAtLT(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldLT(FieldDeletedAt, v)) +func DeletedAtLT(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLT(FieldDeletedAt, v)) } // DeletedAtLTE applies the LTE predicate on the "deleted_at" field. -func DeletedAtLTE(v time.Time) predicate.APIKey { - return predicate.APIKey(sql.FieldLTE(FieldDeletedAt, v)) +func DeletedAtLTE(v time.Time) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLTE(FieldDeletedAt, v)) } // DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field. -func DeletedAtIsNil() predicate.APIKey { - return predicate.APIKey(sql.FieldIsNull(FieldDeletedAt)) +func DeletedAtIsNil() predicate.ApiKey { + return predicate.ApiKey(sql.FieldIsNull(FieldDeletedAt)) } // DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field. -func DeletedAtNotNil() predicate.APIKey { - return predicate.APIKey(sql.FieldNotNull(FieldDeletedAt)) +func DeletedAtNotNil() predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotNull(FieldDeletedAt)) } // UserIDEQ applies the EQ predicate on the "user_id" field. -func UserIDEQ(v int64) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldUserID, v)) +func UserIDEQ(v int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldUserID, v)) } // UserIDNEQ applies the NEQ predicate on the "user_id" field. -func UserIDNEQ(v int64) predicate.APIKey { - return predicate.APIKey(sql.FieldNEQ(FieldUserID, v)) +func UserIDNEQ(v int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNEQ(FieldUserID, v)) } // UserIDIn applies the In predicate on the "user_id" field. -func UserIDIn(vs ...int64) predicate.APIKey { - return predicate.APIKey(sql.FieldIn(FieldUserID, vs...)) +func UserIDIn(vs ...int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldIn(FieldUserID, vs...)) } // UserIDNotIn applies the NotIn predicate on the "user_id" field. -func UserIDNotIn(vs ...int64) predicate.APIKey { - return predicate.APIKey(sql.FieldNotIn(FieldUserID, vs...)) +func UserIDNotIn(vs ...int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotIn(FieldUserID, vs...)) } // KeyEQ applies the EQ predicate on the "key" field. -func KeyEQ(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldKey, v)) +func KeyEQ(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldKey, v)) } // KeyNEQ applies the NEQ predicate on the "key" field. -func KeyNEQ(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldNEQ(FieldKey, v)) +func KeyNEQ(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNEQ(FieldKey, v)) } // KeyIn applies the In predicate on the "key" field. -func KeyIn(vs ...string) predicate.APIKey { - return predicate.APIKey(sql.FieldIn(FieldKey, vs...)) +func KeyIn(vs ...string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldIn(FieldKey, vs...)) } // KeyNotIn applies the NotIn predicate on the "key" field. -func KeyNotIn(vs ...string) predicate.APIKey { - return predicate.APIKey(sql.FieldNotIn(FieldKey, vs...)) +func KeyNotIn(vs ...string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotIn(FieldKey, vs...)) } // KeyGT applies the GT predicate on the "key" field. -func KeyGT(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldGT(FieldKey, v)) +func KeyGT(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGT(FieldKey, v)) } // KeyGTE applies the GTE predicate on the "key" field. -func KeyGTE(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldGTE(FieldKey, v)) +func KeyGTE(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGTE(FieldKey, v)) } // KeyLT applies the LT predicate on the "key" field. -func KeyLT(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldLT(FieldKey, v)) +func KeyLT(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLT(FieldKey, v)) } // KeyLTE applies the LTE predicate on the "key" field. -func KeyLTE(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldLTE(FieldKey, v)) +func KeyLTE(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLTE(FieldKey, v)) } // KeyContains applies the Contains predicate on the "key" field. -func KeyContains(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldContains(FieldKey, v)) +func KeyContains(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldContains(FieldKey, v)) } // KeyHasPrefix applies the HasPrefix predicate on the "key" field. -func KeyHasPrefix(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldHasPrefix(FieldKey, v)) +func KeyHasPrefix(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldHasPrefix(FieldKey, v)) } // KeyHasSuffix applies the HasSuffix predicate on the "key" field. -func KeyHasSuffix(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldHasSuffix(FieldKey, v)) +func KeyHasSuffix(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldHasSuffix(FieldKey, v)) } // KeyEqualFold applies the EqualFold predicate on the "key" field. -func KeyEqualFold(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldEqualFold(FieldKey, v)) +func KeyEqualFold(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEqualFold(FieldKey, v)) } // KeyContainsFold applies the ContainsFold predicate on the "key" field. -func KeyContainsFold(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldContainsFold(FieldKey, v)) +func KeyContainsFold(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldContainsFold(FieldKey, v)) } // NameEQ applies the EQ predicate on the "name" field. -func NameEQ(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldName, v)) +func NameEQ(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldName, v)) } // NameNEQ applies the NEQ predicate on the "name" field. -func NameNEQ(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldNEQ(FieldName, v)) +func NameNEQ(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNEQ(FieldName, v)) } // NameIn applies the In predicate on the "name" field. -func NameIn(vs ...string) predicate.APIKey { - return predicate.APIKey(sql.FieldIn(FieldName, vs...)) +func NameIn(vs ...string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldIn(FieldName, vs...)) } // NameNotIn applies the NotIn predicate on the "name" field. -func NameNotIn(vs ...string) predicate.APIKey { - return predicate.APIKey(sql.FieldNotIn(FieldName, vs...)) +func NameNotIn(vs ...string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotIn(FieldName, vs...)) } // NameGT applies the GT predicate on the "name" field. -func NameGT(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldGT(FieldName, v)) +func NameGT(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGT(FieldName, v)) } // NameGTE applies the GTE predicate on the "name" field. -func NameGTE(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldGTE(FieldName, v)) +func NameGTE(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGTE(FieldName, v)) } // NameLT applies the LT predicate on the "name" field. -func NameLT(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldLT(FieldName, v)) +func NameLT(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLT(FieldName, v)) } // NameLTE applies the LTE predicate on the "name" field. -func NameLTE(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldLTE(FieldName, v)) +func NameLTE(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLTE(FieldName, v)) } // NameContains applies the Contains predicate on the "name" field. -func NameContains(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldContains(FieldName, v)) +func NameContains(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldContains(FieldName, v)) } // NameHasPrefix applies the HasPrefix predicate on the "name" field. -func NameHasPrefix(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldHasPrefix(FieldName, v)) +func NameHasPrefix(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldHasPrefix(FieldName, v)) } // NameHasSuffix applies the HasSuffix predicate on the "name" field. -func NameHasSuffix(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldHasSuffix(FieldName, v)) +func NameHasSuffix(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldHasSuffix(FieldName, v)) } // NameEqualFold applies the EqualFold predicate on the "name" field. -func NameEqualFold(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldEqualFold(FieldName, v)) +func NameEqualFold(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEqualFold(FieldName, v)) } // NameContainsFold applies the ContainsFold predicate on the "name" field. -func NameContainsFold(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldContainsFold(FieldName, v)) +func NameContainsFold(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldContainsFold(FieldName, v)) } // GroupIDEQ applies the EQ predicate on the "group_id" field. -func GroupIDEQ(v int64) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldGroupID, v)) +func GroupIDEQ(v int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldGroupID, v)) } // GroupIDNEQ applies the NEQ predicate on the "group_id" field. -func GroupIDNEQ(v int64) predicate.APIKey { - return predicate.APIKey(sql.FieldNEQ(FieldGroupID, v)) +func GroupIDNEQ(v int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNEQ(FieldGroupID, v)) } // GroupIDIn applies the In predicate on the "group_id" field. -func GroupIDIn(vs ...int64) predicate.APIKey { - return predicate.APIKey(sql.FieldIn(FieldGroupID, vs...)) +func GroupIDIn(vs ...int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldIn(FieldGroupID, vs...)) } // GroupIDNotIn applies the NotIn predicate on the "group_id" field. -func GroupIDNotIn(vs ...int64) predicate.APIKey { - return predicate.APIKey(sql.FieldNotIn(FieldGroupID, vs...)) +func GroupIDNotIn(vs ...int64) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotIn(FieldGroupID, vs...)) } // GroupIDIsNil applies the IsNil predicate on the "group_id" field. -func GroupIDIsNil() predicate.APIKey { - return predicate.APIKey(sql.FieldIsNull(FieldGroupID)) +func GroupIDIsNil() predicate.ApiKey { + return predicate.ApiKey(sql.FieldIsNull(FieldGroupID)) } // GroupIDNotNil applies the NotNil predicate on the "group_id" field. -func GroupIDNotNil() predicate.APIKey { - return predicate.APIKey(sql.FieldNotNull(FieldGroupID)) +func GroupIDNotNil() predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotNull(FieldGroupID)) } // StatusEQ applies the EQ predicate on the "status" field. -func StatusEQ(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldEQ(FieldStatus, v)) +func StatusEQ(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEQ(FieldStatus, v)) } // StatusNEQ applies the NEQ predicate on the "status" field. -func StatusNEQ(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldNEQ(FieldStatus, v)) +func StatusNEQ(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNEQ(FieldStatus, v)) } // StatusIn applies the In predicate on the "status" field. -func StatusIn(vs ...string) predicate.APIKey { - return predicate.APIKey(sql.FieldIn(FieldStatus, vs...)) +func StatusIn(vs ...string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldIn(FieldStatus, vs...)) } // StatusNotIn applies the NotIn predicate on the "status" field. -func StatusNotIn(vs ...string) predicate.APIKey { - return predicate.APIKey(sql.FieldNotIn(FieldStatus, vs...)) +func StatusNotIn(vs ...string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldNotIn(FieldStatus, vs...)) } // StatusGT applies the GT predicate on the "status" field. -func StatusGT(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldGT(FieldStatus, v)) +func StatusGT(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGT(FieldStatus, v)) } // StatusGTE applies the GTE predicate on the "status" field. -func StatusGTE(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldGTE(FieldStatus, v)) +func StatusGTE(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldGTE(FieldStatus, v)) } // StatusLT applies the LT predicate on the "status" field. -func StatusLT(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldLT(FieldStatus, v)) +func StatusLT(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLT(FieldStatus, v)) } // StatusLTE applies the LTE predicate on the "status" field. -func StatusLTE(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldLTE(FieldStatus, v)) +func StatusLTE(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldLTE(FieldStatus, v)) } // StatusContains applies the Contains predicate on the "status" field. -func StatusContains(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldContains(FieldStatus, v)) +func StatusContains(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldContains(FieldStatus, v)) } // StatusHasPrefix applies the HasPrefix predicate on the "status" field. -func StatusHasPrefix(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldHasPrefix(FieldStatus, v)) +func StatusHasPrefix(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldHasPrefix(FieldStatus, v)) } // StatusHasSuffix applies the HasSuffix predicate on the "status" field. -func StatusHasSuffix(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldHasSuffix(FieldStatus, v)) +func StatusHasSuffix(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldHasSuffix(FieldStatus, v)) } // StatusEqualFold applies the EqualFold predicate on the "status" field. -func StatusEqualFold(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldEqualFold(FieldStatus, v)) +func StatusEqualFold(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldEqualFold(FieldStatus, v)) } // StatusContainsFold applies the ContainsFold predicate on the "status" field. -func StatusContainsFold(v string) predicate.APIKey { - return predicate.APIKey(sql.FieldContainsFold(FieldStatus, v)) +func StatusContainsFold(v string) predicate.ApiKey { + return predicate.ApiKey(sql.FieldContainsFold(FieldStatus, v)) } // HasUser applies the HasEdge predicate on the "user" edge. -func HasUser() predicate.APIKey { - return predicate.APIKey(func(s *sql.Selector) { +func HasUser() predicate.ApiKey { + return predicate.ApiKey(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), @@ -482,8 +482,8 @@ func HasUser() predicate.APIKey { } // HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates). -func HasUserWith(preds ...predicate.User) predicate.APIKey { - return predicate.APIKey(func(s *sql.Selector) { +func HasUserWith(preds ...predicate.User) predicate.ApiKey { + return predicate.ApiKey(func(s *sql.Selector) { step := newUserStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { for _, p := range preds { @@ -494,8 +494,8 @@ func HasUserWith(preds ...predicate.User) predicate.APIKey { } // HasGroup applies the HasEdge predicate on the "group" edge. -func HasGroup() predicate.APIKey { - return predicate.APIKey(func(s *sql.Selector) { +func HasGroup() predicate.ApiKey { + return predicate.ApiKey(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), sqlgraph.Edge(sqlgraph.M2O, true, GroupTable, GroupColumn), @@ -505,8 +505,8 @@ func HasGroup() predicate.APIKey { } // HasGroupWith applies the HasEdge predicate on the "group" edge with a given conditions (other predicates). -func HasGroupWith(preds ...predicate.Group) predicate.APIKey { - return predicate.APIKey(func(s *sql.Selector) { +func HasGroupWith(preds ...predicate.Group) predicate.ApiKey { + return predicate.ApiKey(func(s *sql.Selector) { step := newGroupStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { for _, p := range preds { @@ -517,8 +517,8 @@ func HasGroupWith(preds ...predicate.Group) predicate.APIKey { } // HasUsageLogs applies the HasEdge predicate on the "usage_logs" edge. -func HasUsageLogs() predicate.APIKey { - return predicate.APIKey(func(s *sql.Selector) { +func HasUsageLogs() predicate.ApiKey { + return predicate.ApiKey(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), sqlgraph.Edge(sqlgraph.O2M, false, UsageLogsTable, UsageLogsColumn), @@ -528,8 +528,8 @@ func HasUsageLogs() predicate.APIKey { } // HasUsageLogsWith applies the HasEdge predicate on the "usage_logs" edge with a given conditions (other predicates). -func HasUsageLogsWith(preds ...predicate.UsageLog) predicate.APIKey { - return predicate.APIKey(func(s *sql.Selector) { +func HasUsageLogsWith(preds ...predicate.UsageLog) predicate.ApiKey { + return predicate.ApiKey(func(s *sql.Selector) { step := newUsageLogsStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { for _, p := range preds { @@ -540,16 +540,16 @@ func HasUsageLogsWith(preds ...predicate.UsageLog) predicate.APIKey { } // And groups predicates with the AND operator between them. -func And(predicates ...predicate.APIKey) predicate.APIKey { - return predicate.APIKey(sql.AndPredicates(predicates...)) +func And(predicates ...predicate.ApiKey) predicate.ApiKey { + return predicate.ApiKey(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. -func Or(predicates ...predicate.APIKey) predicate.APIKey { - return predicate.APIKey(sql.OrPredicates(predicates...)) +func Or(predicates ...predicate.ApiKey) predicate.ApiKey { + return predicate.ApiKey(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. -func Not(p predicate.APIKey) predicate.APIKey { - return predicate.APIKey(sql.NotPredicates(p)) +func Not(p predicate.ApiKey) predicate.ApiKey { + return predicate.ApiKey(sql.NotPredicates(p)) } diff --git a/backend/ent/apikey_create.go b/backend/ent/apikey_create.go index 2098872c..5b984b21 100644 --- a/backend/ent/apikey_create.go +++ b/backend/ent/apikey_create.go @@ -17,22 +17,22 @@ import ( "github.com/Wei-Shaw/sub2api/ent/user" ) -// APIKeyCreate is the builder for creating a APIKey entity. -type APIKeyCreate struct { +// ApiKeyCreate is the builder for creating a ApiKey entity. +type ApiKeyCreate struct { config - mutation *APIKeyMutation + mutation *ApiKeyMutation hooks []Hook conflict []sql.ConflictOption } // SetCreatedAt sets the "created_at" field. -func (_c *APIKeyCreate) SetCreatedAt(v time.Time) *APIKeyCreate { +func (_c *ApiKeyCreate) SetCreatedAt(v time.Time) *ApiKeyCreate { _c.mutation.SetCreatedAt(v) return _c } // SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (_c *APIKeyCreate) SetNillableCreatedAt(v *time.Time) *APIKeyCreate { +func (_c *ApiKeyCreate) SetNillableCreatedAt(v *time.Time) *ApiKeyCreate { if v != nil { _c.SetCreatedAt(*v) } @@ -40,13 +40,13 @@ func (_c *APIKeyCreate) SetNillableCreatedAt(v *time.Time) *APIKeyCreate { } // SetUpdatedAt sets the "updated_at" field. -func (_c *APIKeyCreate) SetUpdatedAt(v time.Time) *APIKeyCreate { +func (_c *ApiKeyCreate) SetUpdatedAt(v time.Time) *ApiKeyCreate { _c.mutation.SetUpdatedAt(v) return _c } // SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. -func (_c *APIKeyCreate) SetNillableUpdatedAt(v *time.Time) *APIKeyCreate { +func (_c *ApiKeyCreate) SetNillableUpdatedAt(v *time.Time) *ApiKeyCreate { if v != nil { _c.SetUpdatedAt(*v) } @@ -54,13 +54,13 @@ func (_c *APIKeyCreate) SetNillableUpdatedAt(v *time.Time) *APIKeyCreate { } // SetDeletedAt sets the "deleted_at" field. -func (_c *APIKeyCreate) SetDeletedAt(v time.Time) *APIKeyCreate { +func (_c *ApiKeyCreate) SetDeletedAt(v time.Time) *ApiKeyCreate { _c.mutation.SetDeletedAt(v) return _c } // SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil. -func (_c *APIKeyCreate) SetNillableDeletedAt(v *time.Time) *APIKeyCreate { +func (_c *ApiKeyCreate) SetNillableDeletedAt(v *time.Time) *ApiKeyCreate { if v != nil { _c.SetDeletedAt(*v) } @@ -68,31 +68,31 @@ func (_c *APIKeyCreate) SetNillableDeletedAt(v *time.Time) *APIKeyCreate { } // SetUserID sets the "user_id" field. -func (_c *APIKeyCreate) SetUserID(v int64) *APIKeyCreate { +func (_c *ApiKeyCreate) SetUserID(v int64) *ApiKeyCreate { _c.mutation.SetUserID(v) return _c } // SetKey sets the "key" field. -func (_c *APIKeyCreate) SetKey(v string) *APIKeyCreate { +func (_c *ApiKeyCreate) SetKey(v string) *ApiKeyCreate { _c.mutation.SetKey(v) return _c } // SetName sets the "name" field. -func (_c *APIKeyCreate) SetName(v string) *APIKeyCreate { +func (_c *ApiKeyCreate) SetName(v string) *ApiKeyCreate { _c.mutation.SetName(v) return _c } // SetGroupID sets the "group_id" field. -func (_c *APIKeyCreate) SetGroupID(v int64) *APIKeyCreate { +func (_c *ApiKeyCreate) SetGroupID(v int64) *ApiKeyCreate { _c.mutation.SetGroupID(v) return _c } // SetNillableGroupID sets the "group_id" field if the given value is not nil. -func (_c *APIKeyCreate) SetNillableGroupID(v *int64) *APIKeyCreate { +func (_c *ApiKeyCreate) SetNillableGroupID(v *int64) *ApiKeyCreate { if v != nil { _c.SetGroupID(*v) } @@ -100,13 +100,13 @@ func (_c *APIKeyCreate) SetNillableGroupID(v *int64) *APIKeyCreate { } // SetStatus sets the "status" field. -func (_c *APIKeyCreate) SetStatus(v string) *APIKeyCreate { +func (_c *ApiKeyCreate) SetStatus(v string) *ApiKeyCreate { _c.mutation.SetStatus(v) return _c } // SetNillableStatus sets the "status" field if the given value is not nil. -func (_c *APIKeyCreate) SetNillableStatus(v *string) *APIKeyCreate { +func (_c *ApiKeyCreate) SetNillableStatus(v *string) *ApiKeyCreate { if v != nil { _c.SetStatus(*v) } @@ -114,23 +114,23 @@ func (_c *APIKeyCreate) SetNillableStatus(v *string) *APIKeyCreate { } // 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) } // SetGroup sets the "group" edge to the Group entity. -func (_c *APIKeyCreate) SetGroup(v *Group) *APIKeyCreate { +func (_c *ApiKeyCreate) SetGroup(v *Group) *ApiKeyCreate { return _c.SetGroupID(v.ID) } // AddUsageLogIDs adds the "usage_logs" edge to the UsageLog entity by IDs. -func (_c *APIKeyCreate) AddUsageLogIDs(ids ...int64) *APIKeyCreate { +func (_c *ApiKeyCreate) AddUsageLogIDs(ids ...int64) *ApiKeyCreate { _c.mutation.AddUsageLogIDs(ids...) return _c } // AddUsageLogs adds the "usage_logs" edges to the UsageLog entity. -func (_c *APIKeyCreate) AddUsageLogs(v ...*UsageLog) *APIKeyCreate { +func (_c *ApiKeyCreate) AddUsageLogs(v ...*UsageLog) *ApiKeyCreate { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -138,13 +138,13 @@ func (_c *APIKeyCreate) AddUsageLogs(v ...*UsageLog) *APIKeyCreate { return _c.AddUsageLogIDs(ids...) } -// Mutation returns the APIKeyMutation object of the builder. -func (_c *APIKeyCreate) Mutation() *APIKeyMutation { +// Mutation returns the ApiKeyMutation object of the builder. +func (_c *ApiKeyCreate) Mutation() *ApiKeyMutation { return _c.mutation } -// Save creates the APIKey in the database. -func (_c *APIKeyCreate) Save(ctx context.Context) (*APIKey, error) { +// Save creates the ApiKey in the database. +func (_c *ApiKeyCreate) Save(ctx context.Context) (*ApiKey, error) { if err := _c.defaults(); err != nil { return nil, err } @@ -152,7 +152,7 @@ func (_c *APIKeyCreate) Save(ctx context.Context) (*APIKey, error) { } // SaveX calls Save and panics if Save returns an error. -func (_c *APIKeyCreate) SaveX(ctx context.Context) *APIKey { +func (_c *ApiKeyCreate) SaveX(ctx context.Context) *ApiKey { v, err := _c.Save(ctx) if err != nil { panic(err) @@ -161,20 +161,20 @@ func (_c *APIKeyCreate) SaveX(ctx context.Context) *APIKey { } // Exec executes the query. -func (_c *APIKeyCreate) Exec(ctx context.Context) error { +func (_c *ApiKeyCreate) Exec(ctx context.Context) error { _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (_c *APIKeyCreate) ExecX(ctx context.Context) { +func (_c *ApiKeyCreate) ExecX(ctx context.Context) { if err := _c.Exec(ctx); err != nil { panic(err) } } // defaults sets the default values of the builder before save. -func (_c *APIKeyCreate) defaults() error { +func (_c *ApiKeyCreate) defaults() error { if _, ok := _c.mutation.CreatedAt(); !ok { if apikey.DefaultCreatedAt == nil { return fmt.Errorf("ent: uninitialized apikey.DefaultCreatedAt (forgotten import ent/runtime?)") @@ -197,47 +197,47 @@ func (_c *APIKeyCreate) defaults() error { } // check runs all checks and user-defined validators on the builder. -func (_c *APIKeyCreate) check() error { +func (_c *ApiKeyCreate) check() error { if _, ok := _c.mutation.CreatedAt(); !ok { - return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "APIKey.created_at"`)} + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "ApiKey.created_at"`)} } if _, ok := _c.mutation.UpdatedAt(); !ok { - return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "APIKey.updated_at"`)} + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "ApiKey.updated_at"`)} } if _, ok := _c.mutation.UserID(); !ok { - return &ValidationError{Name: "user_id", err: errors.New(`ent: missing required field "APIKey.user_id"`)} + return &ValidationError{Name: "user_id", err: errors.New(`ent: missing required field "ApiKey.user_id"`)} } if _, ok := _c.mutation.Key(); !ok { - return &ValidationError{Name: "key", err: errors.New(`ent: missing required field "APIKey.key"`)} + return &ValidationError{Name: "key", err: errors.New(`ent: missing required field "ApiKey.key"`)} } if v, ok := _c.mutation.Key(); ok { if err := apikey.KeyValidator(v); err != nil { - return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "APIKey.key": %w`, err)} + return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "ApiKey.key": %w`, err)} } } if _, ok := _c.mutation.Name(); !ok { - return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "APIKey.name"`)} + return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "ApiKey.name"`)} } if v, ok := _c.mutation.Name(); ok { if err := apikey.NameValidator(v); err != nil { - return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "APIKey.name": %w`, err)} + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "ApiKey.name": %w`, err)} } } if _, ok := _c.mutation.Status(); !ok { - return &ValidationError{Name: "status", err: errors.New(`ent: missing required field "APIKey.status"`)} + return &ValidationError{Name: "status", err: errors.New(`ent: missing required field "ApiKey.status"`)} } if v, ok := _c.mutation.Status(); ok { if err := apikey.StatusValidator(v); err != nil { - 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 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"`)} } return nil } -func (_c *APIKeyCreate) sqlSave(ctx context.Context) (*APIKey, error) { +func (_c *ApiKeyCreate) sqlSave(ctx context.Context) (*ApiKey, error) { if err := _c.check(); err != nil { return nil, err } @@ -255,9 +255,9 @@ func (_c *APIKeyCreate) sqlSave(ctx context.Context) (*APIKey, error) { return _node, nil } -func (_c *APIKeyCreate) createSpec() (*APIKey, *sqlgraph.CreateSpec) { +func (_c *ApiKeyCreate) createSpec() (*ApiKey, *sqlgraph.CreateSpec) { var ( - _node = &APIKey{config: _c.config} + _node = &ApiKey{config: _c.config} _spec = sqlgraph.NewCreateSpec(apikey.Table, sqlgraph.NewFieldSpec(apikey.FieldID, field.TypeInt64)) ) _spec.OnConflict = _c.conflict @@ -341,7 +341,7 @@ func (_c *APIKeyCreate) createSpec() (*APIKey, *sqlgraph.CreateSpec) { // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // -// client.APIKey.Create(). +// client.ApiKey.Create(). // SetCreatedAt(v). // OnConflict( // // Update the row with the new values @@ -350,13 +350,13 @@ func (_c *APIKeyCreate) createSpec() (*APIKey, *sqlgraph.CreateSpec) { // ). // // Override some of the fields with custom // // update values. -// Update(func(u *ent.APIKeyUpsert) { +// Update(func(u *ent.ApiKeyUpsert) { // SetCreatedAt(v+v). // }). // Exec(ctx) -func (_c *APIKeyCreate) OnConflict(opts ...sql.ConflictOption) *APIKeyUpsertOne { +func (_c *ApiKeyCreate) OnConflict(opts ...sql.ConflictOption) *ApiKeyUpsertOne { _c.conflict = opts - return &APIKeyUpsertOne{ + return &ApiKeyUpsertOne{ create: _c, } } @@ -364,121 +364,121 @@ func (_c *APIKeyCreate) OnConflict(opts ...sql.ConflictOption) *APIKeyUpsertOne // OnConflictColumns calls `OnConflict` and configures the columns // as conflict target. Using this option is equivalent to using: // -// client.APIKey.Create(). +// client.ApiKey.Create(). // OnConflict(sql.ConflictColumns(columns...)). // Exec(ctx) -func (_c *APIKeyCreate) OnConflictColumns(columns ...string) *APIKeyUpsertOne { +func (_c *ApiKeyCreate) OnConflictColumns(columns ...string) *ApiKeyUpsertOne { _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) - return &APIKeyUpsertOne{ + return &ApiKeyUpsertOne{ create: _c, } } type ( - // APIKeyUpsertOne is the builder for "upsert"-ing - // one APIKey node. - APIKeyUpsertOne struct { - create *APIKeyCreate + // ApiKeyUpsertOne is the builder for "upsert"-ing + // one ApiKey node. + ApiKeyUpsertOne struct { + create *ApiKeyCreate } - // APIKeyUpsert is the "OnConflict" setter. - APIKeyUpsert struct { + // ApiKeyUpsert is the "OnConflict" setter. + ApiKeyUpsert struct { *sql.UpdateSet } ) // SetUpdatedAt sets the "updated_at" field. -func (u *APIKeyUpsert) SetUpdatedAt(v time.Time) *APIKeyUpsert { +func (u *ApiKeyUpsert) SetUpdatedAt(v time.Time) *ApiKeyUpsert { u.Set(apikey.FieldUpdatedAt, v) return u } // UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. -func (u *APIKeyUpsert) UpdateUpdatedAt() *APIKeyUpsert { +func (u *ApiKeyUpsert) UpdateUpdatedAt() *ApiKeyUpsert { u.SetExcluded(apikey.FieldUpdatedAt) return u } // SetDeletedAt sets the "deleted_at" field. -func (u *APIKeyUpsert) SetDeletedAt(v time.Time) *APIKeyUpsert { +func (u *ApiKeyUpsert) SetDeletedAt(v time.Time) *ApiKeyUpsert { u.Set(apikey.FieldDeletedAt, v) return u } // UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create. -func (u *APIKeyUpsert) UpdateDeletedAt() *APIKeyUpsert { +func (u *ApiKeyUpsert) UpdateDeletedAt() *ApiKeyUpsert { u.SetExcluded(apikey.FieldDeletedAt) return u } // ClearDeletedAt clears the value of the "deleted_at" field. -func (u *APIKeyUpsert) ClearDeletedAt() *APIKeyUpsert { +func (u *ApiKeyUpsert) ClearDeletedAt() *ApiKeyUpsert { u.SetNull(apikey.FieldDeletedAt) return u } // SetUserID sets the "user_id" field. -func (u *APIKeyUpsert) SetUserID(v int64) *APIKeyUpsert { +func (u *ApiKeyUpsert) SetUserID(v int64) *ApiKeyUpsert { u.Set(apikey.FieldUserID, v) return u } // UpdateUserID sets the "user_id" field to the value that was provided on create. -func (u *APIKeyUpsert) UpdateUserID() *APIKeyUpsert { +func (u *ApiKeyUpsert) UpdateUserID() *ApiKeyUpsert { u.SetExcluded(apikey.FieldUserID) return u } // SetKey sets the "key" field. -func (u *APIKeyUpsert) SetKey(v string) *APIKeyUpsert { +func (u *ApiKeyUpsert) SetKey(v string) *ApiKeyUpsert { u.Set(apikey.FieldKey, v) return u } // UpdateKey sets the "key" field to the value that was provided on create. -func (u *APIKeyUpsert) UpdateKey() *APIKeyUpsert { +func (u *ApiKeyUpsert) UpdateKey() *ApiKeyUpsert { u.SetExcluded(apikey.FieldKey) return u } // SetName sets the "name" field. -func (u *APIKeyUpsert) SetName(v string) *APIKeyUpsert { +func (u *ApiKeyUpsert) SetName(v string) *ApiKeyUpsert { u.Set(apikey.FieldName, v) return u } // UpdateName sets the "name" field to the value that was provided on create. -func (u *APIKeyUpsert) UpdateName() *APIKeyUpsert { +func (u *ApiKeyUpsert) UpdateName() *ApiKeyUpsert { u.SetExcluded(apikey.FieldName) return u } // SetGroupID sets the "group_id" field. -func (u *APIKeyUpsert) SetGroupID(v int64) *APIKeyUpsert { +func (u *ApiKeyUpsert) SetGroupID(v int64) *ApiKeyUpsert { u.Set(apikey.FieldGroupID, v) return u } // UpdateGroupID sets the "group_id" field to the value that was provided on create. -func (u *APIKeyUpsert) UpdateGroupID() *APIKeyUpsert { +func (u *ApiKeyUpsert) UpdateGroupID() *ApiKeyUpsert { u.SetExcluded(apikey.FieldGroupID) return u } // ClearGroupID clears the value of the "group_id" field. -func (u *APIKeyUpsert) ClearGroupID() *APIKeyUpsert { +func (u *ApiKeyUpsert) ClearGroupID() *ApiKeyUpsert { u.SetNull(apikey.FieldGroupID) return u } // SetStatus sets the "status" field. -func (u *APIKeyUpsert) SetStatus(v string) *APIKeyUpsert { +func (u *ApiKeyUpsert) SetStatus(v string) *ApiKeyUpsert { u.Set(apikey.FieldStatus, v) return u } // UpdateStatus sets the "status" field to the value that was provided on create. -func (u *APIKeyUpsert) UpdateStatus() *APIKeyUpsert { +func (u *ApiKeyUpsert) UpdateStatus() *ApiKeyUpsert { u.SetExcluded(apikey.FieldStatus) return u } @@ -486,12 +486,12 @@ func (u *APIKeyUpsert) UpdateStatus() *APIKeyUpsert { // UpdateNewValues updates the mutable fields using the new values that were set on create. // Using this option is equivalent to using: // -// client.APIKey.Create(). +// client.ApiKey.Create(). // OnConflict( // sql.ResolveWithNewValues(), // ). // Exec(ctx) -func (u *APIKeyUpsertOne) UpdateNewValues() *APIKeyUpsertOne { +func (u *ApiKeyUpsertOne) UpdateNewValues() *ApiKeyUpsertOne { u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { if _, exists := u.create.mutation.CreatedAt(); exists { @@ -504,159 +504,159 @@ func (u *APIKeyUpsertOne) UpdateNewValues() *APIKeyUpsertOne { // Ignore sets each column to itself in case of conflict. // Using this option is equivalent to using: // -// client.APIKey.Create(). +// client.ApiKey.Create(). // OnConflict(sql.ResolveWithIgnore()). // Exec(ctx) -func (u *APIKeyUpsertOne) Ignore() *APIKeyUpsertOne { +func (u *ApiKeyUpsertOne) Ignore() *ApiKeyUpsertOne { u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) return u } // DoNothing configures the conflict_action to `DO NOTHING`. // Supported only by SQLite and PostgreSQL. -func (u *APIKeyUpsertOne) DoNothing() *APIKeyUpsertOne { +func (u *ApiKeyUpsertOne) DoNothing() *ApiKeyUpsertOne { u.create.conflict = append(u.create.conflict, sql.DoNothing()) return u } -// Update allows overriding fields `UPDATE` values. See the APIKeyCreate.OnConflict +// Update allows overriding fields `UPDATE` values. See the ApiKeyCreate.OnConflict // documentation for more info. -func (u *APIKeyUpsertOne) Update(set func(*APIKeyUpsert)) *APIKeyUpsertOne { +func (u *ApiKeyUpsertOne) Update(set func(*ApiKeyUpsert)) *ApiKeyUpsertOne { u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { - set(&APIKeyUpsert{UpdateSet: update}) + set(&ApiKeyUpsert{UpdateSet: update}) })) return u } // SetUpdatedAt sets the "updated_at" field. -func (u *APIKeyUpsertOne) SetUpdatedAt(v time.Time) *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) SetUpdatedAt(v time.Time) *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.SetUpdatedAt(v) }) } // UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. -func (u *APIKeyUpsertOne) UpdateUpdatedAt() *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) UpdateUpdatedAt() *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateUpdatedAt() }) } // SetDeletedAt sets the "deleted_at" field. -func (u *APIKeyUpsertOne) SetDeletedAt(v time.Time) *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) SetDeletedAt(v time.Time) *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.SetDeletedAt(v) }) } // UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create. -func (u *APIKeyUpsertOne) UpdateDeletedAt() *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) UpdateDeletedAt() *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateDeletedAt() }) } // ClearDeletedAt clears the value of the "deleted_at" field. -func (u *APIKeyUpsertOne) ClearDeletedAt() *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) ClearDeletedAt() *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.ClearDeletedAt() }) } // SetUserID sets the "user_id" field. -func (u *APIKeyUpsertOne) SetUserID(v int64) *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) SetUserID(v int64) *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.SetUserID(v) }) } // UpdateUserID sets the "user_id" field to the value that was provided on create. -func (u *APIKeyUpsertOne) UpdateUserID() *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) UpdateUserID() *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateUserID() }) } // SetKey sets the "key" field. -func (u *APIKeyUpsertOne) SetKey(v string) *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) SetKey(v string) *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.SetKey(v) }) } // UpdateKey sets the "key" field to the value that was provided on create. -func (u *APIKeyUpsertOne) UpdateKey() *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) UpdateKey() *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateKey() }) } // SetName sets the "name" field. -func (u *APIKeyUpsertOne) SetName(v string) *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) SetName(v string) *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.SetName(v) }) } // UpdateName sets the "name" field to the value that was provided on create. -func (u *APIKeyUpsertOne) UpdateName() *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) UpdateName() *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateName() }) } // SetGroupID sets the "group_id" field. -func (u *APIKeyUpsertOne) SetGroupID(v int64) *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) SetGroupID(v int64) *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.SetGroupID(v) }) } // UpdateGroupID sets the "group_id" field to the value that was provided on create. -func (u *APIKeyUpsertOne) UpdateGroupID() *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) UpdateGroupID() *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateGroupID() }) } // ClearGroupID clears the value of the "group_id" field. -func (u *APIKeyUpsertOne) ClearGroupID() *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) ClearGroupID() *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.ClearGroupID() }) } // SetStatus sets the "status" field. -func (u *APIKeyUpsertOne) SetStatus(v string) *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) SetStatus(v string) *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.SetStatus(v) }) } // UpdateStatus sets the "status" field to the value that was provided on create. -func (u *APIKeyUpsertOne) UpdateStatus() *APIKeyUpsertOne { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertOne) UpdateStatus() *ApiKeyUpsertOne { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateStatus() }) } // 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 { - return errors.New("ent: missing options for APIKeyCreate.OnConflict") + return errors.New("ent: missing options for ApiKeyCreate.OnConflict") } return u.create.Exec(ctx) } // ExecX is like Exec, but panics if an error occurs. -func (u *APIKeyUpsertOne) ExecX(ctx context.Context) { +func (u *ApiKeyUpsertOne) ExecX(ctx context.Context) { if err := u.create.Exec(ctx); err != nil { panic(err) } } // Exec executes the UPSERT query and returns the inserted/updated ID. -func (u *APIKeyUpsertOne) ID(ctx context.Context) (id int64, err error) { +func (u *ApiKeyUpsertOne) ID(ctx context.Context) (id int64, err error) { node, err := u.create.Save(ctx) if err != nil { return id, err @@ -665,7 +665,7 @@ func (u *APIKeyUpsertOne) ID(ctx context.Context) (id int64, err error) { } // IDX is like ID, but panics if an error occurs. -func (u *APIKeyUpsertOne) IDX(ctx context.Context) int64 { +func (u *ApiKeyUpsertOne) IDX(ctx context.Context) int64 { id, err := u.ID(ctx) if err != nil { panic(err) @@ -673,28 +673,28 @@ func (u *APIKeyUpsertOne) IDX(ctx context.Context) int64 { return id } -// APIKeyCreateBulk is the builder for creating many APIKey entities in bulk. -type APIKeyCreateBulk struct { +// ApiKeyCreateBulk is the builder for creating many ApiKey entities in bulk. +type ApiKeyCreateBulk struct { config err error - builders []*APIKeyCreate + builders []*ApiKeyCreate conflict []sql.ConflictOption } -// Save creates the APIKey entities in the database. -func (_c *APIKeyCreateBulk) Save(ctx context.Context) ([]*APIKey, error) { +// Save creates the ApiKey entities in the database. +func (_c *ApiKeyCreateBulk) Save(ctx context.Context) ([]*ApiKey, error) { if _c.err != nil { return nil, _c.err } specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) - nodes := make([]*APIKey, len(_c.builders)) + nodes := make([]*ApiKey, len(_c.builders)) mutators := make([]Mutator, len(_c.builders)) for i := range _c.builders { func(i int, root context.Context) { builder := _c.builders[i] builder.defaults() var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*APIKeyMutation) + mutation, ok := m.(*ApiKeyMutation) if !ok { return nil, fmt.Errorf("unexpected mutation type %T", m) } @@ -742,7 +742,7 @@ func (_c *APIKeyCreateBulk) Save(ctx context.Context) ([]*APIKey, error) { } // SaveX is like Save, but panics if an error occurs. -func (_c *APIKeyCreateBulk) SaveX(ctx context.Context) []*APIKey { +func (_c *ApiKeyCreateBulk) SaveX(ctx context.Context) []*ApiKey { v, err := _c.Save(ctx) if err != nil { panic(err) @@ -751,13 +751,13 @@ func (_c *APIKeyCreateBulk) SaveX(ctx context.Context) []*APIKey { } // Exec executes the query. -func (_c *APIKeyCreateBulk) Exec(ctx context.Context) error { +func (_c *ApiKeyCreateBulk) Exec(ctx context.Context) error { _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (_c *APIKeyCreateBulk) ExecX(ctx context.Context) { +func (_c *ApiKeyCreateBulk) ExecX(ctx context.Context) { if err := _c.Exec(ctx); err != nil { panic(err) } @@ -766,7 +766,7 @@ func (_c *APIKeyCreateBulk) ExecX(ctx context.Context) { // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // -// client.APIKey.CreateBulk(builders...). +// client.ApiKey.CreateBulk(builders...). // OnConflict( // // Update the row with the new values // // the was proposed for insertion. @@ -774,13 +774,13 @@ func (_c *APIKeyCreateBulk) ExecX(ctx context.Context) { // ). // // Override some of the fields with custom // // update values. -// Update(func(u *ent.APIKeyUpsert) { +// Update(func(u *ent.ApiKeyUpsert) { // SetCreatedAt(v+v). // }). // Exec(ctx) -func (_c *APIKeyCreateBulk) OnConflict(opts ...sql.ConflictOption) *APIKeyUpsertBulk { +func (_c *ApiKeyCreateBulk) OnConflict(opts ...sql.ConflictOption) *ApiKeyUpsertBulk { _c.conflict = opts - return &APIKeyUpsertBulk{ + return &ApiKeyUpsertBulk{ create: _c, } } @@ -788,31 +788,31 @@ func (_c *APIKeyCreateBulk) OnConflict(opts ...sql.ConflictOption) *APIKeyUpsert // OnConflictColumns calls `OnConflict` and configures the columns // as conflict target. Using this option is equivalent to using: // -// client.APIKey.Create(). +// client.ApiKey.Create(). // OnConflict(sql.ConflictColumns(columns...)). // Exec(ctx) -func (_c *APIKeyCreateBulk) OnConflictColumns(columns ...string) *APIKeyUpsertBulk { +func (_c *ApiKeyCreateBulk) OnConflictColumns(columns ...string) *ApiKeyUpsertBulk { _c.conflict = append(_c.conflict, sql.ConflictColumns(columns...)) - return &APIKeyUpsertBulk{ + return &ApiKeyUpsertBulk{ create: _c, } } -// APIKeyUpsertBulk is the builder for "upsert"-ing -// a bulk of APIKey nodes. -type APIKeyUpsertBulk struct { - create *APIKeyCreateBulk +// ApiKeyUpsertBulk is the builder for "upsert"-ing +// a bulk of ApiKey nodes. +type ApiKeyUpsertBulk struct { + create *ApiKeyCreateBulk } // UpdateNewValues updates the mutable fields using the new values that // were set on create. Using this option is equivalent to using: // -// client.APIKey.Create(). +// client.ApiKey.Create(). // OnConflict( // sql.ResolveWithNewValues(), // ). // Exec(ctx) -func (u *APIKeyUpsertBulk) UpdateNewValues() *APIKeyUpsertBulk { +func (u *ApiKeyUpsertBulk) UpdateNewValues() *ApiKeyUpsertBulk { u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { for _, b := range u.create.builders { @@ -827,160 +827,160 @@ func (u *APIKeyUpsertBulk) UpdateNewValues() *APIKeyUpsertBulk { // Ignore sets each column to itself in case of conflict. // Using this option is equivalent to using: // -// client.APIKey.Create(). +// client.ApiKey.Create(). // OnConflict(sql.ResolveWithIgnore()). // Exec(ctx) -func (u *APIKeyUpsertBulk) Ignore() *APIKeyUpsertBulk { +func (u *ApiKeyUpsertBulk) Ignore() *ApiKeyUpsertBulk { u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore()) return u } // DoNothing configures the conflict_action to `DO NOTHING`. // Supported only by SQLite and PostgreSQL. -func (u *APIKeyUpsertBulk) DoNothing() *APIKeyUpsertBulk { +func (u *ApiKeyUpsertBulk) DoNothing() *ApiKeyUpsertBulk { u.create.conflict = append(u.create.conflict, sql.DoNothing()) return u } -// Update allows overriding fields `UPDATE` values. See the APIKeyCreateBulk.OnConflict +// Update allows overriding fields `UPDATE` values. See the ApiKeyCreateBulk.OnConflict // documentation for more info. -func (u *APIKeyUpsertBulk) Update(set func(*APIKeyUpsert)) *APIKeyUpsertBulk { +func (u *ApiKeyUpsertBulk) Update(set func(*ApiKeyUpsert)) *ApiKeyUpsertBulk { u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) { - set(&APIKeyUpsert{UpdateSet: update}) + set(&ApiKeyUpsert{UpdateSet: update}) })) return u } // SetUpdatedAt sets the "updated_at" field. -func (u *APIKeyUpsertBulk) SetUpdatedAt(v time.Time) *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) SetUpdatedAt(v time.Time) *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.SetUpdatedAt(v) }) } // UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. -func (u *APIKeyUpsertBulk) UpdateUpdatedAt() *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) UpdateUpdatedAt() *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateUpdatedAt() }) } // SetDeletedAt sets the "deleted_at" field. -func (u *APIKeyUpsertBulk) SetDeletedAt(v time.Time) *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) SetDeletedAt(v time.Time) *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.SetDeletedAt(v) }) } // UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create. -func (u *APIKeyUpsertBulk) UpdateDeletedAt() *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) UpdateDeletedAt() *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateDeletedAt() }) } // ClearDeletedAt clears the value of the "deleted_at" field. -func (u *APIKeyUpsertBulk) ClearDeletedAt() *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) ClearDeletedAt() *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.ClearDeletedAt() }) } // SetUserID sets the "user_id" field. -func (u *APIKeyUpsertBulk) SetUserID(v int64) *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) SetUserID(v int64) *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.SetUserID(v) }) } // UpdateUserID sets the "user_id" field to the value that was provided on create. -func (u *APIKeyUpsertBulk) UpdateUserID() *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) UpdateUserID() *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateUserID() }) } // SetKey sets the "key" field. -func (u *APIKeyUpsertBulk) SetKey(v string) *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) SetKey(v string) *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.SetKey(v) }) } // UpdateKey sets the "key" field to the value that was provided on create. -func (u *APIKeyUpsertBulk) UpdateKey() *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) UpdateKey() *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateKey() }) } // SetName sets the "name" field. -func (u *APIKeyUpsertBulk) SetName(v string) *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) SetName(v string) *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.SetName(v) }) } // UpdateName sets the "name" field to the value that was provided on create. -func (u *APIKeyUpsertBulk) UpdateName() *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) UpdateName() *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateName() }) } // SetGroupID sets the "group_id" field. -func (u *APIKeyUpsertBulk) SetGroupID(v int64) *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) SetGroupID(v int64) *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.SetGroupID(v) }) } // UpdateGroupID sets the "group_id" field to the value that was provided on create. -func (u *APIKeyUpsertBulk) UpdateGroupID() *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) UpdateGroupID() *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateGroupID() }) } // ClearGroupID clears the value of the "group_id" field. -func (u *APIKeyUpsertBulk) ClearGroupID() *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) ClearGroupID() *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.ClearGroupID() }) } // SetStatus sets the "status" field. -func (u *APIKeyUpsertBulk) SetStatus(v string) *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) SetStatus(v string) *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.SetStatus(v) }) } // UpdateStatus sets the "status" field to the value that was provided on create. -func (u *APIKeyUpsertBulk) UpdateStatus() *APIKeyUpsertBulk { - return u.Update(func(s *APIKeyUpsert) { +func (u *ApiKeyUpsertBulk) UpdateStatus() *ApiKeyUpsertBulk { + return u.Update(func(s *ApiKeyUpsert) { s.UpdateStatus() }) } // 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 { return u.create.err } for i, b := range u.create.builders { if len(b.conflict) != 0 { - return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the APIKeyCreateBulk instead", i) + return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the ApiKeyCreateBulk instead", i) } } if len(u.create.conflict) == 0 { - return errors.New("ent: missing options for APIKeyCreateBulk.OnConflict") + return errors.New("ent: missing options for ApiKeyCreateBulk.OnConflict") } return u.create.Exec(ctx) } // ExecX is like Exec, but panics if an error occurs. -func (u *APIKeyUpsertBulk) ExecX(ctx context.Context) { +func (u *ApiKeyUpsertBulk) ExecX(ctx context.Context) { if err := u.create.Exec(ctx); err != nil { panic(err) } diff --git a/backend/ent/apikey_delete.go b/backend/ent/apikey_delete.go index 761db81d..6e5c200c 100644 --- a/backend/ent/apikey_delete.go +++ b/backend/ent/apikey_delete.go @@ -12,26 +12,26 @@ import ( "github.com/Wei-Shaw/sub2api/ent/predicate" ) -// APIKeyDelete is the builder for deleting a APIKey entity. -type APIKeyDelete struct { +// ApiKeyDelete is the builder for deleting a ApiKey entity. +type ApiKeyDelete struct { config hooks []Hook - mutation *APIKeyMutation + mutation *ApiKeyMutation } -// Where appends a list predicates to the APIKeyDelete builder. -func (_d *APIKeyDelete) Where(ps ...predicate.APIKey) *APIKeyDelete { +// Where appends a list predicates to the ApiKeyDelete builder. +func (_d *ApiKeyDelete) Where(ps ...predicate.ApiKey) *ApiKeyDelete { _d.mutation.Where(ps...) return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (_d *APIKeyDelete) Exec(ctx context.Context) (int, error) { +func (_d *ApiKeyDelete) Exec(ctx context.Context) (int, error) { return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (_d *APIKeyDelete) ExecX(ctx context.Context) int { +func (_d *ApiKeyDelete) ExecX(ctx context.Context) int { n, err := _d.Exec(ctx) if err != nil { panic(err) @@ -39,7 +39,7 @@ func (_d *APIKeyDelete) ExecX(ctx context.Context) int { return n } -func (_d *APIKeyDelete) sqlExec(ctx context.Context) (int, error) { +func (_d *ApiKeyDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(apikey.Table, sqlgraph.NewFieldSpec(apikey.FieldID, field.TypeInt64)) if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { @@ -56,19 +56,19 @@ func (_d *APIKeyDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } -// APIKeyDeleteOne is the builder for deleting a single APIKey entity. -type APIKeyDeleteOne struct { - _d *APIKeyDelete +// ApiKeyDeleteOne is the builder for deleting a single ApiKey entity. +type ApiKeyDeleteOne struct { + _d *ApiKeyDelete } -// Where appends a list predicates to the APIKeyDelete builder. -func (_d *APIKeyDeleteOne) Where(ps ...predicate.APIKey) *APIKeyDeleteOne { +// Where appends a list predicates to the ApiKeyDelete builder. +func (_d *ApiKeyDeleteOne) Where(ps ...predicate.ApiKey) *ApiKeyDeleteOne { _d._d.mutation.Where(ps...) return _d } // Exec executes the deletion query. -func (_d *APIKeyDeleteOne) Exec(ctx context.Context) error { +func (_d *ApiKeyDeleteOne) Exec(ctx context.Context) error { n, err := _d._d.Exec(ctx) switch { case err != nil: @@ -81,7 +81,7 @@ func (_d *APIKeyDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (_d *APIKeyDeleteOne) ExecX(ctx context.Context) { +func (_d *ApiKeyDeleteOne) ExecX(ctx context.Context) { if err := _d.Exec(ctx); err != nil { panic(err) } diff --git a/backend/ent/apikey_query.go b/backend/ent/apikey_query.go index 6e5c0f5e..d4029feb 100644 --- a/backend/ent/apikey_query.go +++ b/backend/ent/apikey_query.go @@ -19,13 +19,13 @@ import ( "github.com/Wei-Shaw/sub2api/ent/user" ) -// APIKeyQuery is the builder for querying APIKey entities. -type APIKeyQuery struct { +// ApiKeyQuery is the builder for querying ApiKey entities. +type ApiKeyQuery struct { config ctx *QueryContext order []apikey.OrderOption inters []Interceptor - predicates []predicate.APIKey + predicates []predicate.ApiKey withUser *UserQuery withGroup *GroupQuery withUsageLogs *UsageLogQuery @@ -34,39 +34,39 @@ type APIKeyQuery struct { path func(context.Context) (*sql.Selector, error) } -// Where adds a new predicate for the APIKeyQuery builder. -func (_q *APIKeyQuery) Where(ps ...predicate.APIKey) *APIKeyQuery { +// Where adds a new predicate for the ApiKeyQuery builder. +func (_q *ApiKeyQuery) Where(ps ...predicate.ApiKey) *ApiKeyQuery { _q.predicates = append(_q.predicates, ps...) return _q } // Limit the number of records to be returned by this query. -func (_q *APIKeyQuery) Limit(limit int) *APIKeyQuery { +func (_q *ApiKeyQuery) Limit(limit int) *ApiKeyQuery { _q.ctx.Limit = &limit return _q } // Offset to start from. -func (_q *APIKeyQuery) Offset(offset int) *APIKeyQuery { +func (_q *ApiKeyQuery) Offset(offset int) *ApiKeyQuery { _q.ctx.Offset = &offset return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (_q *APIKeyQuery) Unique(unique bool) *APIKeyQuery { +func (_q *ApiKeyQuery) Unique(unique bool) *ApiKeyQuery { _q.ctx.Unique = &unique return _q } // Order specifies how the records should be ordered. -func (_q *APIKeyQuery) Order(o ...apikey.OrderOption) *APIKeyQuery { +func (_q *ApiKeyQuery) Order(o ...apikey.OrderOption) *ApiKeyQuery { _q.order = append(_q.order, o...) return _q } // QueryUser chains the current query on the "user" edge. -func (_q *APIKeyQuery) QueryUser() *UserQuery { +func (_q *ApiKeyQuery) QueryUser() *UserQuery { query := (&UserClient{config: _q.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := _q.prepareQuery(ctx); err != nil { @@ -88,7 +88,7 @@ func (_q *APIKeyQuery) QueryUser() *UserQuery { } // QueryGroup chains the current query on the "group" edge. -func (_q *APIKeyQuery) QueryGroup() *GroupQuery { +func (_q *ApiKeyQuery) QueryGroup() *GroupQuery { query := (&GroupClient{config: _q.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := _q.prepareQuery(ctx); err != nil { @@ -110,7 +110,7 @@ func (_q *APIKeyQuery) QueryGroup() *GroupQuery { } // QueryUsageLogs chains the current query on the "usage_logs" edge. -func (_q *APIKeyQuery) QueryUsageLogs() *UsageLogQuery { +func (_q *ApiKeyQuery) QueryUsageLogs() *UsageLogQuery { query := (&UsageLogClient{config: _q.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := _q.prepareQuery(ctx); err != nil { @@ -131,9 +131,9 @@ func (_q *APIKeyQuery) QueryUsageLogs() *UsageLogQuery { return query } -// First returns the first APIKey entity from the query. -// Returns a *NotFoundError when no APIKey was found. -func (_q *APIKeyQuery) First(ctx context.Context) (*APIKey, error) { +// First returns the first ApiKey entity from the query. +// Returns a *NotFoundError when no ApiKey was found. +func (_q *ApiKeyQuery) First(ctx context.Context) (*ApiKey, error) { nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err @@ -145,7 +145,7 @@ func (_q *APIKeyQuery) First(ctx context.Context) (*APIKey, error) { } // FirstX is like First, but panics if an error occurs. -func (_q *APIKeyQuery) FirstX(ctx context.Context) *APIKey { +func (_q *ApiKeyQuery) FirstX(ctx context.Context) *ApiKey { node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) @@ -153,9 +153,9 @@ func (_q *APIKeyQuery) FirstX(ctx context.Context) *APIKey { return node } -// FirstID returns the first APIKey ID from the query. -// Returns a *NotFoundError when no APIKey ID was found. -func (_q *APIKeyQuery) FirstID(ctx context.Context) (id int64, err error) { +// FirstID returns the first ApiKey ID from the query. +// Returns a *NotFoundError when no ApiKey ID was found. +func (_q *ApiKeyQuery) FirstID(ctx context.Context) (id int64, err error) { var ids []int64 if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return @@ -168,7 +168,7 @@ func (_q *APIKeyQuery) FirstID(ctx context.Context) (id int64, err error) { } // FirstIDX is like FirstID, but panics if an error occurs. -func (_q *APIKeyQuery) FirstIDX(ctx context.Context) int64 { +func (_q *ApiKeyQuery) FirstIDX(ctx context.Context) int64 { id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) @@ -176,10 +176,10 @@ func (_q *APIKeyQuery) FirstIDX(ctx context.Context) int64 { return id } -// Only returns a single APIKey entity found by the query, ensuring it only returns one. -// Returns a *NotSingularError when more than one APIKey entity is found. -// Returns a *NotFoundError when no APIKey entities are found. -func (_q *APIKeyQuery) Only(ctx context.Context) (*APIKey, error) { +// Only returns a single ApiKey entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one ApiKey entity is found. +// Returns a *NotFoundError when no ApiKey entities are found. +func (_q *ApiKeyQuery) Only(ctx context.Context) (*ApiKey, error) { nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err @@ -195,7 +195,7 @@ func (_q *APIKeyQuery) Only(ctx context.Context) (*APIKey, error) { } // OnlyX is like Only, but panics if an error occurs. -func (_q *APIKeyQuery) OnlyX(ctx context.Context) *APIKey { +func (_q *ApiKeyQuery) OnlyX(ctx context.Context) *ApiKey { node, err := _q.Only(ctx) if err != nil { panic(err) @@ -203,10 +203,10 @@ func (_q *APIKeyQuery) OnlyX(ctx context.Context) *APIKey { return node } -// OnlyID is like Only, but returns the only APIKey ID in the query. -// Returns a *NotSingularError when more than one APIKey ID is found. +// OnlyID is like Only, but returns the only ApiKey ID in the query. +// Returns a *NotSingularError when more than one ApiKey ID is found. // Returns a *NotFoundError when no entities are found. -func (_q *APIKeyQuery) OnlyID(ctx context.Context) (id int64, err error) { +func (_q *ApiKeyQuery) OnlyID(ctx context.Context) (id int64, err error) { var ids []int64 if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return @@ -223,7 +223,7 @@ func (_q *APIKeyQuery) OnlyID(ctx context.Context) (id int64, err error) { } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (_q *APIKeyQuery) OnlyIDX(ctx context.Context) int64 { +func (_q *ApiKeyQuery) OnlyIDX(ctx context.Context) int64 { id, err := _q.OnlyID(ctx) if err != nil { panic(err) @@ -231,18 +231,18 @@ func (_q *APIKeyQuery) OnlyIDX(ctx context.Context) int64 { return id } -// All executes the query and returns a list of APIKeys. -func (_q *APIKeyQuery) All(ctx context.Context) ([]*APIKey, error) { +// All executes the query and returns a list of ApiKeys. +func (_q *ApiKeyQuery) All(ctx context.Context) ([]*ApiKey, error) { ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) if err := _q.prepareQuery(ctx); err != nil { return nil, err } - qr := querierAll[[]*APIKey, *APIKeyQuery]() - return withInterceptors[[]*APIKey](ctx, _q, qr, _q.inters) + qr := querierAll[[]*ApiKey, *ApiKeyQuery]() + return withInterceptors[[]*ApiKey](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (_q *APIKeyQuery) AllX(ctx context.Context) []*APIKey { +func (_q *ApiKeyQuery) AllX(ctx context.Context) []*ApiKey { nodes, err := _q.All(ctx) if err != nil { panic(err) @@ -250,8 +250,8 @@ func (_q *APIKeyQuery) AllX(ctx context.Context) []*APIKey { return nodes } -// IDs executes the query and returns a list of APIKey IDs. -func (_q *APIKeyQuery) IDs(ctx context.Context) (ids []int64, err error) { +// IDs executes the query and returns a list of ApiKey IDs. +func (_q *ApiKeyQuery) IDs(ctx context.Context) (ids []int64, err error) { if _q.ctx.Unique == nil && _q.path != nil { _q.Unique(true) } @@ -263,7 +263,7 @@ func (_q *APIKeyQuery) IDs(ctx context.Context) (ids []int64, err error) { } // IDsX is like IDs, but panics if an error occurs. -func (_q *APIKeyQuery) IDsX(ctx context.Context) []int64 { +func (_q *ApiKeyQuery) IDsX(ctx context.Context) []int64 { ids, err := _q.IDs(ctx) if err != nil { panic(err) @@ -272,16 +272,16 @@ func (_q *APIKeyQuery) IDsX(ctx context.Context) []int64 { } // Count returns the count of the given query. -func (_q *APIKeyQuery) Count(ctx context.Context) (int, error) { +func (_q *ApiKeyQuery) Count(ctx context.Context) (int, error) { ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return withInterceptors[int](ctx, _q, querierCount[*APIKeyQuery](), _q.inters) + return withInterceptors[int](ctx, _q, querierCount[*ApiKeyQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (_q *APIKeyQuery) CountX(ctx context.Context) int { +func (_q *ApiKeyQuery) CountX(ctx context.Context) int { count, err := _q.Count(ctx) if err != nil { panic(err) @@ -290,7 +290,7 @@ func (_q *APIKeyQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (_q *APIKeyQuery) Exist(ctx context.Context) (bool, error) { +func (_q *ApiKeyQuery) Exist(ctx context.Context) (bool, error) { ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) switch _, err := _q.FirstID(ctx); { case IsNotFound(err): @@ -303,7 +303,7 @@ func (_q *APIKeyQuery) Exist(ctx context.Context) (bool, error) { } // ExistX is like Exist, but panics if an error occurs. -func (_q *APIKeyQuery) ExistX(ctx context.Context) bool { +func (_q *ApiKeyQuery) ExistX(ctx context.Context) bool { exist, err := _q.Exist(ctx) if err != nil { panic(err) @@ -311,18 +311,18 @@ func (_q *APIKeyQuery) ExistX(ctx context.Context) bool { return exist } -// Clone returns a duplicate of the APIKeyQuery builder, including all associated steps. It can be +// Clone returns a duplicate of the ApiKeyQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (_q *APIKeyQuery) Clone() *APIKeyQuery { +func (_q *ApiKeyQuery) Clone() *ApiKeyQuery { if _q == nil { return nil } - return &APIKeyQuery{ + return &ApiKeyQuery{ config: _q.config, ctx: _q.ctx.Clone(), order: append([]apikey.OrderOption{}, _q.order...), inters: append([]Interceptor{}, _q.inters...), - predicates: append([]predicate.APIKey{}, _q.predicates...), + predicates: append([]predicate.ApiKey{}, _q.predicates...), withUser: _q.withUser.Clone(), withGroup: _q.withGroup.Clone(), withUsageLogs: _q.withUsageLogs.Clone(), @@ -334,7 +334,7 @@ func (_q *APIKeyQuery) Clone() *APIKeyQuery { // WithUser tells the query-builder to eager-load the nodes that are connected to // the "user" edge. The optional arguments are used to configure the query builder of the edge. -func (_q *APIKeyQuery) WithUser(opts ...func(*UserQuery)) *APIKeyQuery { +func (_q *ApiKeyQuery) WithUser(opts ...func(*UserQuery)) *ApiKeyQuery { query := (&UserClient{config: _q.config}).Query() for _, opt := range opts { opt(query) @@ -345,7 +345,7 @@ func (_q *APIKeyQuery) WithUser(opts ...func(*UserQuery)) *APIKeyQuery { // WithGroup tells the query-builder to eager-load the nodes that are connected to // the "group" edge. The optional arguments are used to configure the query builder of the edge. -func (_q *APIKeyQuery) WithGroup(opts ...func(*GroupQuery)) *APIKeyQuery { +func (_q *ApiKeyQuery) WithGroup(opts ...func(*GroupQuery)) *ApiKeyQuery { query := (&GroupClient{config: _q.config}).Query() for _, opt := range opts { opt(query) @@ -356,7 +356,7 @@ func (_q *APIKeyQuery) WithGroup(opts ...func(*GroupQuery)) *APIKeyQuery { // WithUsageLogs tells the query-builder to eager-load the nodes that are connected to // the "usage_logs" edge. The optional arguments are used to configure the query builder of the edge. -func (_q *APIKeyQuery) WithUsageLogs(opts ...func(*UsageLogQuery)) *APIKeyQuery { +func (_q *ApiKeyQuery) WithUsageLogs(opts ...func(*UsageLogQuery)) *ApiKeyQuery { query := (&UsageLogClient{config: _q.config}).Query() for _, opt := range opts { opt(query) @@ -375,13 +375,13 @@ func (_q *APIKeyQuery) WithUsageLogs(opts ...func(*UsageLogQuery)) *APIKeyQuery // Count int `json:"count,omitempty"` // } // -// client.APIKey.Query(). +// client.ApiKey.Query(). // GroupBy(apikey.FieldCreatedAt). // Aggregate(ent.Count()). // Scan(ctx, &v) -func (_q *APIKeyQuery) GroupBy(field string, fields ...string) *APIKeyGroupBy { +func (_q *ApiKeyQuery) GroupBy(field string, fields ...string) *ApiKeyGroupBy { _q.ctx.Fields = append([]string{field}, fields...) - grbuild := &APIKeyGroupBy{build: _q} + grbuild := &ApiKeyGroupBy{build: _q} grbuild.flds = &_q.ctx.Fields grbuild.label = apikey.Label grbuild.scan = grbuild.Scan @@ -397,23 +397,23 @@ func (_q *APIKeyQuery) GroupBy(field string, fields ...string) *APIKeyGroupBy { // CreatedAt time.Time `json:"created_at,omitempty"` // } // -// client.APIKey.Query(). +// client.ApiKey.Query(). // Select(apikey.FieldCreatedAt). // Scan(ctx, &v) -func (_q *APIKeyQuery) Select(fields ...string) *APIKeySelect { +func (_q *ApiKeyQuery) Select(fields ...string) *ApiKeySelect { _q.ctx.Fields = append(_q.ctx.Fields, fields...) - sbuild := &APIKeySelect{APIKeyQuery: _q} + sbuild := &ApiKeySelect{ApiKeyQuery: _q} sbuild.label = apikey.Label sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan return sbuild } -// Aggregate returns a APIKeySelect configured with the given aggregations. -func (_q *APIKeyQuery) Aggregate(fns ...AggregateFunc) *APIKeySelect { +// Aggregate returns a ApiKeySelect configured with the given aggregations. +func (_q *ApiKeyQuery) Aggregate(fns ...AggregateFunc) *ApiKeySelect { return _q.Select().Aggregate(fns...) } -func (_q *APIKeyQuery) prepareQuery(ctx context.Context) error { +func (_q *ApiKeyQuery) prepareQuery(ctx context.Context) error { for _, inter := range _q.inters { if inter == nil { return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") @@ -439,9 +439,9 @@ func (_q *APIKeyQuery) prepareQuery(ctx context.Context) error { return nil } -func (_q *APIKeyQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*APIKey, error) { +func (_q *ApiKeyQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*ApiKey, error) { var ( - nodes = []*APIKey{} + nodes = []*ApiKey{} _spec = _q.querySpec() loadedTypes = [3]bool{ _q.withUser != nil, @@ -450,10 +450,10 @@ func (_q *APIKeyQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*APIKe } ) _spec.ScanValues = func(columns []string) ([]any, error) { - return (*APIKey).scanValues(nil, columns) + return (*ApiKey).scanValues(nil, columns) } _spec.Assign = func(columns []string, values []any) error { - node := &APIKey{config: _q.config} + node := &ApiKey{config: _q.config} nodes = append(nodes, node) node.Edges.loadedTypes = loadedTypes return node.assignValues(columns, values) @@ -469,29 +469,29 @@ func (_q *APIKeyQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*APIKe } if query := _q.withUser; query != nil { if err := _q.loadUser(ctx, query, nodes, nil, - func(n *APIKey, e *User) { n.Edges.User = e }); err != nil { + func(n *ApiKey, e *User) { n.Edges.User = e }); err != nil { return nil, err } } if query := _q.withGroup; query != nil { if err := _q.loadGroup(ctx, query, nodes, nil, - func(n *APIKey, e *Group) { n.Edges.Group = e }); err != nil { + func(n *ApiKey, e *Group) { n.Edges.Group = e }); err != nil { return nil, err } } if query := _q.withUsageLogs; query != nil { if err := _q.loadUsageLogs(ctx, query, nodes, - func(n *APIKey) { n.Edges.UsageLogs = []*UsageLog{} }, - func(n *APIKey, e *UsageLog) { n.Edges.UsageLogs = append(n.Edges.UsageLogs, e) }); err != nil { + func(n *ApiKey) { n.Edges.UsageLogs = []*UsageLog{} }, + func(n *ApiKey, e *UsageLog) { n.Edges.UsageLogs = append(n.Edges.UsageLogs, e) }); err != nil { return nil, err } } return nodes, nil } -func (_q *APIKeyQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*APIKey, init func(*APIKey), assign func(*APIKey, *User)) error { +func (_q *ApiKeyQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*ApiKey, init func(*ApiKey), assign func(*ApiKey, *User)) error { ids := make([]int64, 0, len(nodes)) - nodeids := make(map[int64][]*APIKey) + nodeids := make(map[int64][]*ApiKey) for i := range nodes { fk := nodes[i].UserID if _, ok := nodeids[fk]; !ok { @@ -518,9 +518,9 @@ func (_q *APIKeyQuery) loadUser(ctx context.Context, query *UserQuery, nodes []* } return nil } -func (_q *APIKeyQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes []*APIKey, init func(*APIKey), assign func(*APIKey, *Group)) error { +func (_q *ApiKeyQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes []*ApiKey, init func(*ApiKey), assign func(*ApiKey, *Group)) error { ids := make([]int64, 0, len(nodes)) - nodeids := make(map[int64][]*APIKey) + nodeids := make(map[int64][]*ApiKey) for i := range nodes { if nodes[i].GroupID == nil { continue @@ -550,9 +550,9 @@ func (_q *APIKeyQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes [ } return nil } -func (_q *APIKeyQuery) loadUsageLogs(ctx context.Context, query *UsageLogQuery, nodes []*APIKey, init func(*APIKey), assign func(*APIKey, *UsageLog)) error { +func (_q *ApiKeyQuery) loadUsageLogs(ctx context.Context, query *UsageLogQuery, nodes []*ApiKey, init func(*ApiKey), assign func(*ApiKey, *UsageLog)) error { fks := make([]driver.Value, 0, len(nodes)) - nodeids := make(map[int64]*APIKey) + nodeids := make(map[int64]*ApiKey) for i := range nodes { fks = append(fks, nodes[i].ID) nodeids[nodes[i].ID] = nodes[i] @@ -581,7 +581,7 @@ func (_q *APIKeyQuery) loadUsageLogs(ctx context.Context, query *UsageLogQuery, return nil } -func (_q *APIKeyQuery) sqlCount(ctx context.Context) (int, error) { +func (_q *ApiKeyQuery) sqlCount(ctx context.Context) (int, error) { _spec := _q.querySpec() _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { @@ -590,7 +590,7 @@ func (_q *APIKeyQuery) sqlCount(ctx context.Context) (int, error) { return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (_q *APIKeyQuery) querySpec() *sqlgraph.QuerySpec { +func (_q *ApiKeyQuery) querySpec() *sqlgraph.QuerySpec { _spec := sqlgraph.NewQuerySpec(apikey.Table, apikey.Columns, sqlgraph.NewFieldSpec(apikey.FieldID, field.TypeInt64)) _spec.From = _q.sql if unique := _q.ctx.Unique; unique != nil { @@ -636,7 +636,7 @@ func (_q *APIKeyQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (_q *APIKeyQuery) sqlQuery(ctx context.Context) *sql.Selector { +func (_q *ApiKeyQuery) sqlQuery(ctx context.Context) *sql.Selector { builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(apikey.Table) columns := _q.ctx.Fields @@ -668,28 +668,28 @@ func (_q *APIKeyQuery) sqlQuery(ctx context.Context) *sql.Selector { return selector } -// APIKeyGroupBy is the group-by builder for APIKey entities. -type APIKeyGroupBy struct { +// ApiKeyGroupBy is the group-by builder for ApiKey entities. +type ApiKeyGroupBy struct { selector - build *APIKeyQuery + build *ApiKeyQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (_g *APIKeyGroupBy) Aggregate(fns ...AggregateFunc) *APIKeyGroupBy { +func (_g *ApiKeyGroupBy) Aggregate(fns ...AggregateFunc) *ApiKeyGroupBy { _g.fns = append(_g.fns, fns...) return _g } // Scan applies the selector query and scans the result into the given value. -func (_g *APIKeyGroupBy) Scan(ctx context.Context, v any) error { +func (_g *ApiKeyGroupBy) Scan(ctx context.Context, v any) error { ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) if err := _g.build.prepareQuery(ctx); err != nil { return err } - return scanWithInterceptors[*APIKeyQuery, *APIKeyGroupBy](ctx, _g.build, _g, _g.build.inters, v) + return scanWithInterceptors[*ApiKeyQuery, *ApiKeyGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (_g *APIKeyGroupBy) sqlScan(ctx context.Context, root *APIKeyQuery, v any) error { +func (_g *ApiKeyGroupBy) sqlScan(ctx context.Context, root *ApiKeyQuery, v any) error { selector := root.sqlQuery(ctx).Select() aggregation := make([]string, 0, len(_g.fns)) for _, fn := range _g.fns { @@ -716,28 +716,28 @@ func (_g *APIKeyGroupBy) sqlScan(ctx context.Context, root *APIKeyQuery, v any) return sql.ScanSlice(rows, v) } -// APIKeySelect is the builder for selecting fields of APIKey entities. -type APIKeySelect struct { - *APIKeyQuery +// ApiKeySelect is the builder for selecting fields of ApiKey entities. +type ApiKeySelect struct { + *ApiKeyQuery selector } // Aggregate adds the given aggregation functions to the selector query. -func (_s *APIKeySelect) Aggregate(fns ...AggregateFunc) *APIKeySelect { +func (_s *ApiKeySelect) Aggregate(fns ...AggregateFunc) *ApiKeySelect { _s.fns = append(_s.fns, fns...) return _s } // Scan applies the selector query and scans the result into the given value. -func (_s *APIKeySelect) Scan(ctx context.Context, v any) error { +func (_s *ApiKeySelect) Scan(ctx context.Context, v any) error { ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) if err := _s.prepareQuery(ctx); err != nil { return err } - return scanWithInterceptors[*APIKeyQuery, *APIKeySelect](ctx, _s.APIKeyQuery, _s, _s.inters, v) + return scanWithInterceptors[*ApiKeyQuery, *ApiKeySelect](ctx, _s.ApiKeyQuery, _s, _s.inters, v) } -func (_s *APIKeySelect) sqlScan(ctx context.Context, root *APIKeyQuery, v any) error { +func (_s *ApiKeySelect) sqlScan(ctx context.Context, root *ApiKeyQuery, v any) error { selector := root.sqlQuery(ctx) aggregation := make([]string, 0, len(_s.fns)) for _, fn := range _s.fns { diff --git a/backend/ent/apikey_update.go b/backend/ent/apikey_update.go index 4a16369b..3259bfd9 100644 --- a/backend/ent/apikey_update.go +++ b/backend/ent/apikey_update.go @@ -18,33 +18,33 @@ import ( "github.com/Wei-Shaw/sub2api/ent/user" ) -// APIKeyUpdate is the builder for updating APIKey entities. -type APIKeyUpdate struct { +// ApiKeyUpdate is the builder for updating ApiKey entities. +type ApiKeyUpdate struct { config hooks []Hook - mutation *APIKeyMutation + mutation *ApiKeyMutation } -// Where appends a list predicates to the APIKeyUpdate builder. -func (_u *APIKeyUpdate) Where(ps ...predicate.APIKey) *APIKeyUpdate { +// Where appends a list predicates to the ApiKeyUpdate builder. +func (_u *ApiKeyUpdate) Where(ps ...predicate.ApiKey) *ApiKeyUpdate { _u.mutation.Where(ps...) return _u } // SetUpdatedAt sets the "updated_at" field. -func (_u *APIKeyUpdate) SetUpdatedAt(v time.Time) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetUpdatedAt(v time.Time) *ApiKeyUpdate { _u.mutation.SetUpdatedAt(v) return _u } // SetDeletedAt sets the "deleted_at" field. -func (_u *APIKeyUpdate) SetDeletedAt(v time.Time) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetDeletedAt(v time.Time) *ApiKeyUpdate { _u.mutation.SetDeletedAt(v) return _u } // SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil. -func (_u *APIKeyUpdate) SetNillableDeletedAt(v *time.Time) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetNillableDeletedAt(v *time.Time) *ApiKeyUpdate { if v != nil { _u.SetDeletedAt(*v) } @@ -52,19 +52,19 @@ func (_u *APIKeyUpdate) SetNillableDeletedAt(v *time.Time) *APIKeyUpdate { } // ClearDeletedAt clears the value of the "deleted_at" field. -func (_u *APIKeyUpdate) ClearDeletedAt() *APIKeyUpdate { +func (_u *ApiKeyUpdate) ClearDeletedAt() *ApiKeyUpdate { _u.mutation.ClearDeletedAt() return _u } // SetUserID sets the "user_id" field. -func (_u *APIKeyUpdate) SetUserID(v int64) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetUserID(v int64) *ApiKeyUpdate { _u.mutation.SetUserID(v) return _u } // SetNillableUserID sets the "user_id" field if the given value is not nil. -func (_u *APIKeyUpdate) SetNillableUserID(v *int64) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetNillableUserID(v *int64) *ApiKeyUpdate { if v != nil { _u.SetUserID(*v) } @@ -72,13 +72,13 @@ func (_u *APIKeyUpdate) SetNillableUserID(v *int64) *APIKeyUpdate { } // SetKey sets the "key" field. -func (_u *APIKeyUpdate) SetKey(v string) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetKey(v string) *ApiKeyUpdate { _u.mutation.SetKey(v) return _u } // SetNillableKey sets the "key" field if the given value is not nil. -func (_u *APIKeyUpdate) SetNillableKey(v *string) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetNillableKey(v *string) *ApiKeyUpdate { if v != nil { _u.SetKey(*v) } @@ -86,13 +86,13 @@ func (_u *APIKeyUpdate) SetNillableKey(v *string) *APIKeyUpdate { } // SetName sets the "name" field. -func (_u *APIKeyUpdate) SetName(v string) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetName(v string) *ApiKeyUpdate { _u.mutation.SetName(v) return _u } // SetNillableName sets the "name" field if the given value is not nil. -func (_u *APIKeyUpdate) SetNillableName(v *string) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetNillableName(v *string) *ApiKeyUpdate { if v != nil { _u.SetName(*v) } @@ -100,13 +100,13 @@ func (_u *APIKeyUpdate) SetNillableName(v *string) *APIKeyUpdate { } // SetGroupID sets the "group_id" field. -func (_u *APIKeyUpdate) SetGroupID(v int64) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetGroupID(v int64) *ApiKeyUpdate { _u.mutation.SetGroupID(v) return _u } // SetNillableGroupID sets the "group_id" field if the given value is not nil. -func (_u *APIKeyUpdate) SetNillableGroupID(v *int64) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetNillableGroupID(v *int64) *ApiKeyUpdate { if v != nil { _u.SetGroupID(*v) } @@ -114,19 +114,19 @@ func (_u *APIKeyUpdate) SetNillableGroupID(v *int64) *APIKeyUpdate { } // ClearGroupID clears the value of the "group_id" field. -func (_u *APIKeyUpdate) ClearGroupID() *APIKeyUpdate { +func (_u *ApiKeyUpdate) ClearGroupID() *ApiKeyUpdate { _u.mutation.ClearGroupID() return _u } // SetStatus sets the "status" field. -func (_u *APIKeyUpdate) SetStatus(v string) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetStatus(v string) *ApiKeyUpdate { _u.mutation.SetStatus(v) return _u } // SetNillableStatus sets the "status" field if the given value is not nil. -func (_u *APIKeyUpdate) SetNillableStatus(v *string) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetNillableStatus(v *string) *ApiKeyUpdate { if v != nil { _u.SetStatus(*v) } @@ -134,23 +134,23 @@ func (_u *APIKeyUpdate) SetNillableStatus(v *string) *APIKeyUpdate { } // 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) } // SetGroup sets the "group" edge to the Group entity. -func (_u *APIKeyUpdate) SetGroup(v *Group) *APIKeyUpdate { +func (_u *ApiKeyUpdate) SetGroup(v *Group) *ApiKeyUpdate { return _u.SetGroupID(v.ID) } // AddUsageLogIDs adds the "usage_logs" edge to the UsageLog entity by IDs. -func (_u *APIKeyUpdate) AddUsageLogIDs(ids ...int64) *APIKeyUpdate { +func (_u *ApiKeyUpdate) AddUsageLogIDs(ids ...int64) *ApiKeyUpdate { _u.mutation.AddUsageLogIDs(ids...) return _u } // AddUsageLogs adds the "usage_logs" edges to the UsageLog entity. -func (_u *APIKeyUpdate) AddUsageLogs(v ...*UsageLog) *APIKeyUpdate { +func (_u *ApiKeyUpdate) AddUsageLogs(v ...*UsageLog) *ApiKeyUpdate { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -158,37 +158,37 @@ func (_u *APIKeyUpdate) AddUsageLogs(v ...*UsageLog) *APIKeyUpdate { return _u.AddUsageLogIDs(ids...) } -// Mutation returns the APIKeyMutation object of the builder. -func (_u *APIKeyUpdate) Mutation() *APIKeyMutation { +// Mutation returns the ApiKeyMutation object of the builder. +func (_u *ApiKeyUpdate) Mutation() *ApiKeyMutation { return _u.mutation } // ClearUser clears the "user" edge to the User entity. -func (_u *APIKeyUpdate) ClearUser() *APIKeyUpdate { +func (_u *ApiKeyUpdate) ClearUser() *ApiKeyUpdate { _u.mutation.ClearUser() return _u } // ClearGroup clears the "group" edge to the Group entity. -func (_u *APIKeyUpdate) ClearGroup() *APIKeyUpdate { +func (_u *ApiKeyUpdate) ClearGroup() *ApiKeyUpdate { _u.mutation.ClearGroup() return _u } // ClearUsageLogs clears all "usage_logs" edges to the UsageLog entity. -func (_u *APIKeyUpdate) ClearUsageLogs() *APIKeyUpdate { +func (_u *ApiKeyUpdate) ClearUsageLogs() *ApiKeyUpdate { _u.mutation.ClearUsageLogs() return _u } // RemoveUsageLogIDs removes the "usage_logs" edge to UsageLog entities by IDs. -func (_u *APIKeyUpdate) RemoveUsageLogIDs(ids ...int64) *APIKeyUpdate { +func (_u *ApiKeyUpdate) RemoveUsageLogIDs(ids ...int64) *ApiKeyUpdate { _u.mutation.RemoveUsageLogIDs(ids...) return _u } // RemoveUsageLogs removes "usage_logs" edges to UsageLog entities. -func (_u *APIKeyUpdate) RemoveUsageLogs(v ...*UsageLog) *APIKeyUpdate { +func (_u *ApiKeyUpdate) RemoveUsageLogs(v ...*UsageLog) *ApiKeyUpdate { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -197,7 +197,7 @@ func (_u *APIKeyUpdate) RemoveUsageLogs(v ...*UsageLog) *APIKeyUpdate { } // Save executes the query and returns the number of nodes affected by the update operation. -func (_u *APIKeyUpdate) Save(ctx context.Context) (int, error) { +func (_u *ApiKeyUpdate) Save(ctx context.Context) (int, error) { if err := _u.defaults(); err != nil { return 0, err } @@ -205,7 +205,7 @@ func (_u *APIKeyUpdate) Save(ctx context.Context) (int, error) { } // SaveX is like Save, but panics if an error occurs. -func (_u *APIKeyUpdate) SaveX(ctx context.Context) int { +func (_u *ApiKeyUpdate) SaveX(ctx context.Context) int { affected, err := _u.Save(ctx) if err != nil { panic(err) @@ -214,20 +214,20 @@ func (_u *APIKeyUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (_u *APIKeyUpdate) Exec(ctx context.Context) error { +func (_u *ApiKeyUpdate) Exec(ctx context.Context) error { _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (_u *APIKeyUpdate) ExecX(ctx context.Context) { +func (_u *ApiKeyUpdate) ExecX(ctx context.Context) { if err := _u.Exec(ctx); err != nil { panic(err) } } // defaults sets the default values of the builder before save. -func (_u *APIKeyUpdate) defaults() error { +func (_u *ApiKeyUpdate) defaults() error { if _, ok := _u.mutation.UpdatedAt(); !ok { if apikey.UpdateDefaultUpdatedAt == nil { return fmt.Errorf("ent: uninitialized apikey.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)") @@ -239,29 +239,29 @@ func (_u *APIKeyUpdate) defaults() error { } // check runs all checks and user-defined validators on the builder. -func (_u *APIKeyUpdate) check() error { +func (_u *ApiKeyUpdate) check() error { if v, ok := _u.mutation.Key(); ok { if err := apikey.KeyValidator(v); err != nil { - return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "APIKey.key": %w`, err)} + return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "ApiKey.key": %w`, err)} } } if v, ok := _u.mutation.Name(); ok { if err := apikey.NameValidator(v); err != nil { - return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "APIKey.name": %w`, err)} + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "ApiKey.name": %w`, err)} } } if v, ok := _u.mutation.Status(); ok { if err := apikey.StatusValidator(v); err != nil { - 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 _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 { - return errors.New(`ent: clearing a required unique edge "APIKey.user"`) + return errors.New(`ent: clearing a required unique edge "ApiKey.user"`) } return nil } -func (_u *APIKeyUpdate) sqlSave(ctx context.Context) (_node int, err error) { +func (_u *ApiKeyUpdate) sqlSave(ctx context.Context) (_node int, err error) { if err := _u.check(); err != nil { return _node, err } @@ -406,28 +406,28 @@ func (_u *APIKeyUpdate) sqlSave(ctx context.Context) (_node int, err error) { return _node, nil } -// APIKeyUpdateOne is the builder for updating a single APIKey entity. -type APIKeyUpdateOne struct { +// ApiKeyUpdateOne is the builder for updating a single ApiKey entity. +type ApiKeyUpdateOne struct { config fields []string hooks []Hook - mutation *APIKeyMutation + mutation *ApiKeyMutation } // SetUpdatedAt sets the "updated_at" field. -func (_u *APIKeyUpdateOne) SetUpdatedAt(v time.Time) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetUpdatedAt(v time.Time) *ApiKeyUpdateOne { _u.mutation.SetUpdatedAt(v) return _u } // SetDeletedAt sets the "deleted_at" field. -func (_u *APIKeyUpdateOne) SetDeletedAt(v time.Time) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetDeletedAt(v time.Time) *ApiKeyUpdateOne { _u.mutation.SetDeletedAt(v) return _u } // SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil. -func (_u *APIKeyUpdateOne) SetNillableDeletedAt(v *time.Time) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetNillableDeletedAt(v *time.Time) *ApiKeyUpdateOne { if v != nil { _u.SetDeletedAt(*v) } @@ -435,19 +435,19 @@ func (_u *APIKeyUpdateOne) SetNillableDeletedAt(v *time.Time) *APIKeyUpdateOne { } // ClearDeletedAt clears the value of the "deleted_at" field. -func (_u *APIKeyUpdateOne) ClearDeletedAt() *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) ClearDeletedAt() *ApiKeyUpdateOne { _u.mutation.ClearDeletedAt() return _u } // SetUserID sets the "user_id" field. -func (_u *APIKeyUpdateOne) SetUserID(v int64) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetUserID(v int64) *ApiKeyUpdateOne { _u.mutation.SetUserID(v) return _u } // SetNillableUserID sets the "user_id" field if the given value is not nil. -func (_u *APIKeyUpdateOne) SetNillableUserID(v *int64) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetNillableUserID(v *int64) *ApiKeyUpdateOne { if v != nil { _u.SetUserID(*v) } @@ -455,13 +455,13 @@ func (_u *APIKeyUpdateOne) SetNillableUserID(v *int64) *APIKeyUpdateOne { } // SetKey sets the "key" field. -func (_u *APIKeyUpdateOne) SetKey(v string) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetKey(v string) *ApiKeyUpdateOne { _u.mutation.SetKey(v) return _u } // SetNillableKey sets the "key" field if the given value is not nil. -func (_u *APIKeyUpdateOne) SetNillableKey(v *string) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetNillableKey(v *string) *ApiKeyUpdateOne { if v != nil { _u.SetKey(*v) } @@ -469,13 +469,13 @@ func (_u *APIKeyUpdateOne) SetNillableKey(v *string) *APIKeyUpdateOne { } // SetName sets the "name" field. -func (_u *APIKeyUpdateOne) SetName(v string) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetName(v string) *ApiKeyUpdateOne { _u.mutation.SetName(v) return _u } // SetNillableName sets the "name" field if the given value is not nil. -func (_u *APIKeyUpdateOne) SetNillableName(v *string) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetNillableName(v *string) *ApiKeyUpdateOne { if v != nil { _u.SetName(*v) } @@ -483,13 +483,13 @@ func (_u *APIKeyUpdateOne) SetNillableName(v *string) *APIKeyUpdateOne { } // SetGroupID sets the "group_id" field. -func (_u *APIKeyUpdateOne) SetGroupID(v int64) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetGroupID(v int64) *ApiKeyUpdateOne { _u.mutation.SetGroupID(v) return _u } // SetNillableGroupID sets the "group_id" field if the given value is not nil. -func (_u *APIKeyUpdateOne) SetNillableGroupID(v *int64) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetNillableGroupID(v *int64) *ApiKeyUpdateOne { if v != nil { _u.SetGroupID(*v) } @@ -497,19 +497,19 @@ func (_u *APIKeyUpdateOne) SetNillableGroupID(v *int64) *APIKeyUpdateOne { } // ClearGroupID clears the value of the "group_id" field. -func (_u *APIKeyUpdateOne) ClearGroupID() *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) ClearGroupID() *ApiKeyUpdateOne { _u.mutation.ClearGroupID() return _u } // SetStatus sets the "status" field. -func (_u *APIKeyUpdateOne) SetStatus(v string) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetStatus(v string) *ApiKeyUpdateOne { _u.mutation.SetStatus(v) return _u } // SetNillableStatus sets the "status" field if the given value is not nil. -func (_u *APIKeyUpdateOne) SetNillableStatus(v *string) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetNillableStatus(v *string) *ApiKeyUpdateOne { if v != nil { _u.SetStatus(*v) } @@ -517,23 +517,23 @@ func (_u *APIKeyUpdateOne) SetNillableStatus(v *string) *APIKeyUpdateOne { } // 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) } // SetGroup sets the "group" edge to the Group entity. -func (_u *APIKeyUpdateOne) SetGroup(v *Group) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) SetGroup(v *Group) *ApiKeyUpdateOne { return _u.SetGroupID(v.ID) } // AddUsageLogIDs adds the "usage_logs" edge to the UsageLog entity by IDs. -func (_u *APIKeyUpdateOne) AddUsageLogIDs(ids ...int64) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) AddUsageLogIDs(ids ...int64) *ApiKeyUpdateOne { _u.mutation.AddUsageLogIDs(ids...) return _u } // AddUsageLogs adds the "usage_logs" edges to the UsageLog entity. -func (_u *APIKeyUpdateOne) AddUsageLogs(v ...*UsageLog) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) AddUsageLogs(v ...*UsageLog) *ApiKeyUpdateOne { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -541,37 +541,37 @@ func (_u *APIKeyUpdateOne) AddUsageLogs(v ...*UsageLog) *APIKeyUpdateOne { return _u.AddUsageLogIDs(ids...) } -// Mutation returns the APIKeyMutation object of the builder. -func (_u *APIKeyUpdateOne) Mutation() *APIKeyMutation { +// Mutation returns the ApiKeyMutation object of the builder. +func (_u *ApiKeyUpdateOne) Mutation() *ApiKeyMutation { return _u.mutation } // ClearUser clears the "user" edge to the User entity. -func (_u *APIKeyUpdateOne) ClearUser() *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) ClearUser() *ApiKeyUpdateOne { _u.mutation.ClearUser() return _u } // ClearGroup clears the "group" edge to the Group entity. -func (_u *APIKeyUpdateOne) ClearGroup() *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) ClearGroup() *ApiKeyUpdateOne { _u.mutation.ClearGroup() return _u } // ClearUsageLogs clears all "usage_logs" edges to the UsageLog entity. -func (_u *APIKeyUpdateOne) ClearUsageLogs() *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) ClearUsageLogs() *ApiKeyUpdateOne { _u.mutation.ClearUsageLogs() return _u } // RemoveUsageLogIDs removes the "usage_logs" edge to UsageLog entities by IDs. -func (_u *APIKeyUpdateOne) RemoveUsageLogIDs(ids ...int64) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) RemoveUsageLogIDs(ids ...int64) *ApiKeyUpdateOne { _u.mutation.RemoveUsageLogIDs(ids...) return _u } // RemoveUsageLogs removes "usage_logs" edges to UsageLog entities. -func (_u *APIKeyUpdateOne) RemoveUsageLogs(v ...*UsageLog) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) RemoveUsageLogs(v ...*UsageLog) *ApiKeyUpdateOne { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -579,21 +579,21 @@ func (_u *APIKeyUpdateOne) RemoveUsageLogs(v ...*UsageLog) *APIKeyUpdateOne { return _u.RemoveUsageLogIDs(ids...) } -// Where appends a list predicates to the APIKeyUpdate builder. -func (_u *APIKeyUpdateOne) Where(ps ...predicate.APIKey) *APIKeyUpdateOne { +// Where appends a list predicates to the ApiKeyUpdate builder. +func (_u *ApiKeyUpdateOne) Where(ps ...predicate.ApiKey) *ApiKeyUpdateOne { _u.mutation.Where(ps...) return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (_u *APIKeyUpdateOne) Select(field string, fields ...string) *APIKeyUpdateOne { +func (_u *ApiKeyUpdateOne) Select(field string, fields ...string) *ApiKeyUpdateOne { _u.fields = append([]string{field}, fields...) return _u } -// Save executes the query and returns the updated APIKey entity. -func (_u *APIKeyUpdateOne) Save(ctx context.Context) (*APIKey, error) { +// Save executes the query and returns the updated ApiKey entity. +func (_u *ApiKeyUpdateOne) Save(ctx context.Context) (*ApiKey, error) { if err := _u.defaults(); err != nil { return nil, err } @@ -601,7 +601,7 @@ func (_u *APIKeyUpdateOne) Save(ctx context.Context) (*APIKey, error) { } // SaveX is like Save, but panics if an error occurs. -func (_u *APIKeyUpdateOne) SaveX(ctx context.Context) *APIKey { +func (_u *ApiKeyUpdateOne) SaveX(ctx context.Context) *ApiKey { node, err := _u.Save(ctx) if err != nil { panic(err) @@ -610,20 +610,20 @@ func (_u *APIKeyUpdateOne) SaveX(ctx context.Context) *APIKey { } // Exec executes the query on the entity. -func (_u *APIKeyUpdateOne) Exec(ctx context.Context) error { +func (_u *ApiKeyUpdateOne) Exec(ctx context.Context) error { _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (_u *APIKeyUpdateOne) ExecX(ctx context.Context) { +func (_u *ApiKeyUpdateOne) ExecX(ctx context.Context) { if err := _u.Exec(ctx); err != nil { panic(err) } } // defaults sets the default values of the builder before save. -func (_u *APIKeyUpdateOne) defaults() error { +func (_u *ApiKeyUpdateOne) defaults() error { if _, ok := _u.mutation.UpdatedAt(); !ok { if apikey.UpdateDefaultUpdatedAt == nil { return fmt.Errorf("ent: uninitialized apikey.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)") @@ -635,36 +635,36 @@ func (_u *APIKeyUpdateOne) defaults() error { } // check runs all checks and user-defined validators on the builder. -func (_u *APIKeyUpdateOne) check() error { +func (_u *ApiKeyUpdateOne) check() error { if v, ok := _u.mutation.Key(); ok { if err := apikey.KeyValidator(v); err != nil { - return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "APIKey.key": %w`, err)} + return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "ApiKey.key": %w`, err)} } } if v, ok := _u.mutation.Name(); ok { if err := apikey.NameValidator(v); err != nil { - return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "APIKey.name": %w`, err)} + return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "ApiKey.name": %w`, err)} } } if v, ok := _u.mutation.Status(); ok { if err := apikey.StatusValidator(v); err != nil { - 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 _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 { - return errors.New(`ent: clearing a required unique edge "APIKey.user"`) + return errors.New(`ent: clearing a required unique edge "ApiKey.user"`) } return nil } -func (_u *APIKeyUpdateOne) sqlSave(ctx context.Context) (_node *APIKey, err error) { +func (_u *ApiKeyUpdateOne) sqlSave(ctx context.Context) (_node *ApiKey, err error) { if err := _u.check(); err != nil { return _node, err } _spec := sqlgraph.NewUpdateSpec(apikey.Table, apikey.Columns, sqlgraph.NewFieldSpec(apikey.FieldID, field.TypeInt64)) id, ok := _u.mutation.ID() if !ok { - return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "APIKey.id" for update`)} + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "ApiKey.id" for update`)} } _spec.Node.ID.Value = id if fields := _u.fields; len(fields) > 0 { @@ -807,7 +807,7 @@ func (_u *APIKeyUpdateOne) sqlSave(ctx context.Context) (_node *APIKey, err erro } _spec.Edges.Add = append(_spec.Edges.Add, edge) } - _node = &APIKey{config: _u.config} + _node = &ApiKey{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { diff --git a/backend/ent/client.go b/backend/ent/client.go index 33832277..fab70489 100644 --- a/backend/ent/client.go +++ b/backend/ent/client.go @@ -37,12 +37,12 @@ type Client struct { config // Schema is the client for creating, migrating and dropping schema. Schema *migrate.Schema - // APIKey is the client for interacting with the APIKey builders. - APIKey *APIKeyClient // Account is the client for interacting with the Account builders. Account *AccountClient // AccountGroup is the client for interacting with the AccountGroup builders. AccountGroup *AccountGroupClient + // ApiKey is the client for interacting with the ApiKey builders. + ApiKey *ApiKeyClient // Group is the client for interacting with the Group builders. Group *GroupClient // Proxy is the client for interacting with the Proxy builders. @@ -74,9 +74,9 @@ func NewClient(opts ...Option) *Client { func (c *Client) init() { c.Schema = migrate.NewSchema(c.driver) - c.APIKey = NewAPIKeyClient(c.config) c.Account = NewAccountClient(c.config) c.AccountGroup = NewAccountGroupClient(c.config) + c.ApiKey = NewApiKeyClient(c.config) c.Group = NewGroupClient(c.config) c.Proxy = NewProxyClient(c.config) c.RedeemCode = NewRedeemCodeClient(c.config) @@ -179,9 +179,9 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { return &Tx{ ctx: ctx, config: cfg, - APIKey: NewAPIKeyClient(cfg), Account: NewAccountClient(cfg), AccountGroup: NewAccountGroupClient(cfg), + ApiKey: NewApiKeyClient(cfg), Group: NewGroupClient(cfg), Proxy: NewProxyClient(cfg), RedeemCode: NewRedeemCodeClient(cfg), @@ -211,9 +211,9 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) return &Tx{ ctx: ctx, config: cfg, - APIKey: NewAPIKeyClient(cfg), Account: NewAccountClient(cfg), AccountGroup: NewAccountGroupClient(cfg), + ApiKey: NewApiKeyClient(cfg), Group: NewGroupClient(cfg), Proxy: NewProxyClient(cfg), RedeemCode: NewRedeemCodeClient(cfg), @@ -230,7 +230,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) // Debug returns a new debug-client. It's used to get verbose logging on specific operations. // // client.Debug(). -// APIKey. +// Account. // Query(). // Count(ctx) func (c *Client) Debug() *Client { @@ -253,9 +253,9 @@ func (c *Client) Close() error { // In order to add hooks to a specific client, call: `client.Node.Use(...)`. func (c *Client) Use(hooks ...Hook) { for _, n := range []interface{ Use(...Hook) }{ - c.APIKey, c.Account, c.AccountGroup, c.Group, c.Proxy, c.RedeemCode, c.Setting, - c.UsageLog, c.User, c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue, - c.UserSubscription, + c.Account, c.AccountGroup, c.ApiKey, c.Group, c.Proxy, c.RedeemCode, c.Setting, + c.UsageLog, c.User, c.UserAllowedGroup, c.UserAttributeDefinition, + c.UserAttributeValue, c.UserSubscription, } { n.Use(hooks...) } @@ -265,9 +265,9 @@ func (c *Client) Use(hooks ...Hook) { // In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`. func (c *Client) Intercept(interceptors ...Interceptor) { for _, n := range []interface{ Intercept(...Interceptor) }{ - c.APIKey, c.Account, c.AccountGroup, c.Group, c.Proxy, c.RedeemCode, c.Setting, - c.UsageLog, c.User, c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue, - c.UserSubscription, + c.Account, c.AccountGroup, c.ApiKey, c.Group, c.Proxy, c.RedeemCode, c.Setting, + c.UsageLog, c.User, c.UserAllowedGroup, c.UserAttributeDefinition, + c.UserAttributeValue, c.UserSubscription, } { n.Intercept(interceptors...) } @@ -276,12 +276,12 @@ func (c *Client) Intercept(interceptors ...Interceptor) { // Mutate implements the ent.Mutator interface. func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { switch m := m.(type) { - case *APIKeyMutation: - return c.APIKey.mutate(ctx, m) case *AccountMutation: return c.Account.mutate(ctx, m) case *AccountGroupMutation: return c.AccountGroup.mutate(ctx, m) + case *ApiKeyMutation: + return c.ApiKey.mutate(ctx, m) case *GroupMutation: return c.Group.mutate(ctx, m) case *ProxyMutation: @@ -307,189 +307,6 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { } } -// APIKeyClient is a client for the APIKey schema. -type APIKeyClient struct { - config -} - -// NewAPIKeyClient returns a client for the APIKey from the given config. -func NewAPIKeyClient(c config) *APIKeyClient { - return &APIKeyClient{config: c} -} - -// Use adds a list of mutation hooks to the hooks stack. -// A call to `Use(f, g, h)` equals to `apikey.Hooks(f(g(h())))`. -func (c *APIKeyClient) Use(hooks ...Hook) { - c.hooks.APIKey = append(c.hooks.APIKey, hooks...) -} - -// Intercept adds a list of query interceptors to the interceptors stack. -// A call to `Intercept(f, g, h)` equals to `apikey.Intercept(f(g(h())))`. -func (c *APIKeyClient) Intercept(interceptors ...Interceptor) { - c.inters.APIKey = append(c.inters.APIKey, interceptors...) -} - -// Create returns a builder for creating a APIKey entity. -func (c *APIKeyClient) Create() *APIKeyCreate { - mutation := newAPIKeyMutation(c.config, OpCreate) - return &APIKeyCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// CreateBulk returns a builder for creating a bulk of APIKey entities. -func (c *APIKeyClient) CreateBulk(builders ...*APIKeyCreate) *APIKeyCreateBulk { - return &APIKeyCreateBulk{config: c.config, builders: builders} -} - -// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates -// a builder and applies setFunc on it. -func (c *APIKeyClient) MapCreateBulk(slice any, setFunc func(*APIKeyCreate, int)) *APIKeyCreateBulk { - rv := reflect.ValueOf(slice) - if rv.Kind() != reflect.Slice { - return &APIKeyCreateBulk{err: fmt.Errorf("calling to APIKeyClient.MapCreateBulk with wrong type %T, need slice", slice)} - } - builders := make([]*APIKeyCreate, rv.Len()) - for i := 0; i < rv.Len(); i++ { - builders[i] = c.Create() - setFunc(builders[i], i) - } - return &APIKeyCreateBulk{config: c.config, builders: builders} -} - -// Update returns an update builder for APIKey. -func (c *APIKeyClient) Update() *APIKeyUpdate { - mutation := newAPIKeyMutation(c.config, OpUpdate) - return &APIKeyUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOne returns an update builder for the given entity. -func (c *APIKeyClient) UpdateOne(_m *APIKey) *APIKeyUpdateOne { - mutation := newAPIKeyMutation(c.config, OpUpdateOne, withAPIKey(_m)) - return &APIKeyUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOneID returns an update builder for the given id. -func (c *APIKeyClient) UpdateOneID(id int64) *APIKeyUpdateOne { - mutation := newAPIKeyMutation(c.config, OpUpdateOne, withAPIKeyID(id)) - return &APIKeyUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// Delete returns a delete builder for APIKey. -func (c *APIKeyClient) Delete() *APIKeyDelete { - mutation := newAPIKeyMutation(c.config, OpDelete) - return &APIKeyDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// DeleteOne returns a builder for deleting the given entity. -func (c *APIKeyClient) DeleteOne(_m *APIKey) *APIKeyDeleteOne { - return c.DeleteOneID(_m.ID) -} - -// DeleteOneID returns a builder for deleting the given entity by its id. -func (c *APIKeyClient) DeleteOneID(id int64) *APIKeyDeleteOne { - builder := c.Delete().Where(apikey.ID(id)) - builder.mutation.id = &id - builder.mutation.op = OpDeleteOne - return &APIKeyDeleteOne{builder} -} - -// Query returns a query builder for APIKey. -func (c *APIKeyClient) Query() *APIKeyQuery { - return &APIKeyQuery{ - config: c.config, - ctx: &QueryContext{Type: TypeAPIKey}, - inters: c.Interceptors(), - } -} - -// Get returns a APIKey entity by its id. -func (c *APIKeyClient) Get(ctx context.Context, id int64) (*APIKey, error) { - return c.Query().Where(apikey.ID(id)).Only(ctx) -} - -// GetX is like Get, but panics if an error occurs. -func (c *APIKeyClient) GetX(ctx context.Context, id int64) *APIKey { - obj, err := c.Get(ctx, id) - if err != nil { - panic(err) - } - return obj -} - -// QueryUser queries the user edge of a APIKey. -func (c *APIKeyClient) QueryUser(_m *APIKey) *UserQuery { - query := (&UserClient{config: c.config}).Query() - query.path = func(context.Context) (fromV *sql.Selector, _ error) { - id := _m.ID - step := sqlgraph.NewStep( - sqlgraph.From(apikey.Table, apikey.FieldID, id), - sqlgraph.To(user.Table, user.FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, apikey.UserTable, apikey.UserColumn), - ) - fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) - return fromV, nil - } - return query -} - -// QueryGroup queries the group edge of a APIKey. -func (c *APIKeyClient) QueryGroup(_m *APIKey) *GroupQuery { - query := (&GroupClient{config: c.config}).Query() - query.path = func(context.Context) (fromV *sql.Selector, _ error) { - id := _m.ID - step := sqlgraph.NewStep( - sqlgraph.From(apikey.Table, apikey.FieldID, id), - sqlgraph.To(group.Table, group.FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, apikey.GroupTable, apikey.GroupColumn), - ) - fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) - return fromV, nil - } - return query -} - -// QueryUsageLogs queries the usage_logs edge of a APIKey. -func (c *APIKeyClient) QueryUsageLogs(_m *APIKey) *UsageLogQuery { - query := (&UsageLogClient{config: c.config}).Query() - query.path = func(context.Context) (fromV *sql.Selector, _ error) { - id := _m.ID - step := sqlgraph.NewStep( - sqlgraph.From(apikey.Table, apikey.FieldID, id), - sqlgraph.To(usagelog.Table, usagelog.FieldID), - sqlgraph.Edge(sqlgraph.O2M, false, apikey.UsageLogsTable, apikey.UsageLogsColumn), - ) - fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) - return fromV, nil - } - return query -} - -// Hooks returns the client hooks. -func (c *APIKeyClient) Hooks() []Hook { - hooks := c.hooks.APIKey - return append(hooks[:len(hooks):len(hooks)], apikey.Hooks[:]...) -} - -// Interceptors returns the client interceptors. -func (c *APIKeyClient) Interceptors() []Interceptor { - inters := c.inters.APIKey - return append(inters[:len(inters):len(inters)], apikey.Interceptors[:]...) -} - -func (c *APIKeyClient) mutate(ctx context.Context, m *APIKeyMutation) (Value, error) { - switch m.Op() { - case OpCreate: - return (&APIKeyCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) - case OpUpdate: - return (&APIKeyUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) - case OpUpdateOne: - return (&APIKeyUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) - case OpDelete, OpDeleteOne: - return (&APIKeyDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) - default: - return nil, fmt.Errorf("ent: unknown APIKey mutation op: %q", m.Op()) - } -} - // AccountClient is a client for the Account schema. type AccountClient struct { config @@ -805,6 +622,189 @@ func (c *AccountGroupClient) mutate(ctx context.Context, m *AccountGroupMutation } } +// ApiKeyClient is a client for the ApiKey schema. +type ApiKeyClient struct { + config +} + +// NewApiKeyClient returns a client for the ApiKey from the given config. +func NewApiKeyClient(c config) *ApiKeyClient { + return &ApiKeyClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `apikey.Hooks(f(g(h())))`. +func (c *ApiKeyClient) Use(hooks ...Hook) { + c.hooks.ApiKey = append(c.hooks.ApiKey, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `apikey.Intercept(f(g(h())))`. +func (c *ApiKeyClient) Intercept(interceptors ...Interceptor) { + c.inters.ApiKey = append(c.inters.ApiKey, interceptors...) +} + +// Create returns a builder for creating a ApiKey entity. +func (c *ApiKeyClient) Create() *ApiKeyCreate { + mutation := newApiKeyMutation(c.config, OpCreate) + return &ApiKeyCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of ApiKey entities. +func (c *ApiKeyClient) CreateBulk(builders ...*ApiKeyCreate) *ApiKeyCreateBulk { + return &ApiKeyCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *ApiKeyClient) MapCreateBulk(slice any, setFunc func(*ApiKeyCreate, int)) *ApiKeyCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &ApiKeyCreateBulk{err: fmt.Errorf("calling to ApiKeyClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*ApiKeyCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &ApiKeyCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for ApiKey. +func (c *ApiKeyClient) Update() *ApiKeyUpdate { + mutation := newApiKeyMutation(c.config, OpUpdate) + return &ApiKeyUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *ApiKeyClient) UpdateOne(_m *ApiKey) *ApiKeyUpdateOne { + mutation := newApiKeyMutation(c.config, OpUpdateOne, withApiKey(_m)) + return &ApiKeyUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *ApiKeyClient) UpdateOneID(id int64) *ApiKeyUpdateOne { + mutation := newApiKeyMutation(c.config, OpUpdateOne, withApiKeyID(id)) + return &ApiKeyUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for ApiKey. +func (c *ApiKeyClient) Delete() *ApiKeyDelete { + mutation := newApiKeyMutation(c.config, OpDelete) + return &ApiKeyDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *ApiKeyClient) DeleteOne(_m *ApiKey) *ApiKeyDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *ApiKeyClient) DeleteOneID(id int64) *ApiKeyDeleteOne { + builder := c.Delete().Where(apikey.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &ApiKeyDeleteOne{builder} +} + +// Query returns a query builder for ApiKey. +func (c *ApiKeyClient) Query() *ApiKeyQuery { + return &ApiKeyQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeApiKey}, + inters: c.Interceptors(), + } +} + +// Get returns a ApiKey entity by its id. +func (c *ApiKeyClient) Get(ctx context.Context, id int64) (*ApiKey, error) { + return c.Query().Where(apikey.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *ApiKeyClient) GetX(ctx context.Context, id int64) *ApiKey { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryUser queries the user edge of a ApiKey. +func (c *ApiKeyClient) QueryUser(_m *ApiKey) *UserQuery { + query := (&UserClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(apikey.Table, apikey.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, apikey.UserTable, apikey.UserColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryGroup queries the group edge of a ApiKey. +func (c *ApiKeyClient) QueryGroup(_m *ApiKey) *GroupQuery { + query := (&GroupClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(apikey.Table, apikey.FieldID, id), + sqlgraph.To(group.Table, group.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, apikey.GroupTable, apikey.GroupColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryUsageLogs queries the usage_logs edge of a ApiKey. +func (c *ApiKeyClient) QueryUsageLogs(_m *ApiKey) *UsageLogQuery { + query := (&UsageLogClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(apikey.Table, apikey.FieldID, id), + sqlgraph.To(usagelog.Table, usagelog.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, apikey.UsageLogsTable, apikey.UsageLogsColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *ApiKeyClient) Hooks() []Hook { + hooks := c.hooks.ApiKey + return append(hooks[:len(hooks):len(hooks)], apikey.Hooks[:]...) +} + +// Interceptors returns the client interceptors. +func (c *ApiKeyClient) Interceptors() []Interceptor { + inters := c.inters.ApiKey + return append(inters[:len(inters):len(inters)], apikey.Interceptors[:]...) +} + +func (c *ApiKeyClient) mutate(ctx context.Context, m *ApiKeyMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&ApiKeyCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&ApiKeyUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&ApiKeyUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&ApiKeyDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown ApiKey mutation op: %q", m.Op()) + } +} + // GroupClient is a client for the Group schema. type GroupClient struct { config @@ -914,8 +914,8 @@ func (c *GroupClient) GetX(ctx context.Context, id int64) *Group { } // QueryAPIKeys queries the api_keys edge of a Group. -func (c *GroupClient) QueryAPIKeys(_m *Group) *APIKeyQuery { - query := (&APIKeyClient{config: c.config}).Query() +func (c *GroupClient) QueryAPIKeys(_m *Group) *ApiKeyQuery { + query := (&ApiKeyClient{config: c.config}).Query() query.path = func(context.Context) (fromV *sql.Selector, _ error) { id := _m.ID step := sqlgraph.NewStep( @@ -1642,8 +1642,8 @@ func (c *UsageLogClient) QueryUser(_m *UsageLog) *UserQuery { } // QueryAPIKey queries the api_key edge of a UsageLog. -func (c *UsageLogClient) QueryAPIKey(_m *UsageLog) *APIKeyQuery { - query := (&APIKeyClient{config: c.config}).Query() +func (c *UsageLogClient) QueryAPIKey(_m *UsageLog) *ApiKeyQuery { + query := (&ApiKeyClient{config: c.config}).Query() query.path = func(context.Context) (fromV *sql.Selector, _ error) { id := _m.ID step := sqlgraph.NewStep( @@ -1839,8 +1839,8 @@ func (c *UserClient) GetX(ctx context.Context, id int64) *User { } // QueryAPIKeys queries the api_keys edge of a User. -func (c *UserClient) QueryAPIKeys(_m *User) *APIKeyQuery { - query := (&APIKeyClient{config: c.config}).Query() +func (c *UserClient) QueryAPIKeys(_m *User) *ApiKeyQuery { + query := (&ApiKeyClient{config: c.config}).Query() query.path = func(context.Context) (fromV *sql.Selector, _ error) { id := _m.ID step := sqlgraph.NewStep( @@ -2627,12 +2627,12 @@ func (c *UserSubscriptionClient) mutate(ctx context.Context, m *UserSubscription // hooks and interceptors per client, for fast access. type ( hooks struct { - APIKey, Account, AccountGroup, Group, Proxy, RedeemCode, Setting, UsageLog, + Account, AccountGroup, ApiKey, Group, Proxy, RedeemCode, Setting, UsageLog, User, UserAllowedGroup, UserAttributeDefinition, UserAttributeValue, UserSubscription []ent.Hook } inters struct { - APIKey, Account, AccountGroup, Group, Proxy, RedeemCode, Setting, UsageLog, + Account, AccountGroup, ApiKey, Group, Proxy, RedeemCode, Setting, UsageLog, User, UserAllowedGroup, UserAttributeDefinition, UserAttributeValue, UserSubscription []ent.Interceptor } diff --git a/backend/ent/driver_access.go b/backend/ent/driver_access.go index 05bb6872..b0693572 100644 --- a/backend/ent/driver_access.go +++ b/backend/ent/driver_access.go @@ -1,4 +1,3 @@ -// Package ent provides database entity definitions and operations. package ent import "entgo.io/ent/dialect" diff --git a/backend/ent/group.go b/backend/ent/group.go index e8687224..9b1e8604 100644 --- a/backend/ent/group.go +++ b/backend/ent/group.go @@ -54,7 +54,7 @@ type Group struct { // GroupEdges holds the relations/edges for other nodes in the graph. type GroupEdges struct { // APIKeys holds the value of the api_keys edge. - APIKeys []*APIKey `json:"api_keys,omitempty"` + APIKeys []*ApiKey `json:"api_keys,omitempty"` // RedeemCodes holds the value of the redeem_codes edge. RedeemCodes []*RedeemCode `json:"redeem_codes,omitempty"` // Subscriptions holds the value of the subscriptions edge. @@ -76,7 +76,7 @@ type GroupEdges struct { // APIKeysOrErr returns the APIKeys value or an error if the edge // was not loaded in eager-loading. -func (e GroupEdges) APIKeysOrErr() ([]*APIKey, error) { +func (e GroupEdges) APIKeysOrErr() ([]*ApiKey, error) { if e.loadedTypes[0] { return e.APIKeys, nil } @@ -285,7 +285,7 @@ func (_m *Group) Value(name string) (ent.Value, error) { } // QueryAPIKeys queries the "api_keys" edge of the Group entity. -func (_m *Group) QueryAPIKeys() *APIKeyQuery { +func (_m *Group) QueryAPIKeys() *ApiKeyQuery { return NewGroupClient(_m.config).QueryAPIKeys(_m) } diff --git a/backend/ent/group/group.go b/backend/ent/group/group.go index 1934b17b..8dc53c49 100644 --- a/backend/ent/group/group.go +++ b/backend/ent/group/group.go @@ -63,7 +63,7 @@ const ( Table = "groups" // APIKeysTable is the table that holds the api_keys relation/edge. APIKeysTable = "api_keys" - // APIKeysInverseTable is the table name for the APIKey entity. + // APIKeysInverseTable is the table name for the ApiKey entity. // It exists in this package in order to avoid circular dependency with the "apikey" package. APIKeysInverseTable = "api_keys" // APIKeysColumn is the table column denoting the api_keys relation/edge. diff --git a/backend/ent/group/where.go b/backend/ent/group/where.go index cb553242..ac18a418 100644 --- a/backend/ent/group/where.go +++ b/backend/ent/group/where.go @@ -842,7 +842,7 @@ func HasAPIKeys() predicate.Group { } // HasAPIKeysWith applies the HasEdge predicate on the "api_keys" edge with a given conditions (other predicates). -func HasAPIKeysWith(preds ...predicate.APIKey) predicate.Group { +func HasAPIKeysWith(preds ...predicate.ApiKey) predicate.Group { return predicate.Group(func(s *sql.Selector) { step := newAPIKeysStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { diff --git a/backend/ent/group_create.go b/backend/ent/group_create.go index 0613c78e..383a1352 100644 --- a/backend/ent/group_create.go +++ b/backend/ent/group_create.go @@ -216,14 +216,14 @@ func (_c *GroupCreate) SetNillableDefaultValidityDays(v *int) *GroupCreate { return _c } -// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs. +// AddAPIKeyIDs adds the "api_keys" edge to the ApiKey entity by IDs. func (_c *GroupCreate) AddAPIKeyIDs(ids ...int64) *GroupCreate { _c.mutation.AddAPIKeyIDs(ids...) return _c } -// AddAPIKeys adds the "api_keys" edges to the APIKey entity. -func (_c *GroupCreate) AddAPIKeys(v ...*APIKey) *GroupCreate { +// AddAPIKeys adds the "api_keys" edges to the ApiKey entity. +func (_c *GroupCreate) AddAPIKeys(v ...*ApiKey) *GroupCreate { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID diff --git a/backend/ent/group_query.go b/backend/ent/group_query.go index 3cc976cb..93a8d8c2 100644 --- a/backend/ent/group_query.go +++ b/backend/ent/group_query.go @@ -31,7 +31,7 @@ type GroupQuery struct { order []group.OrderOption inters []Interceptor predicates []predicate.Group - withAPIKeys *APIKeyQuery + withAPIKeys *ApiKeyQuery withRedeemCodes *RedeemCodeQuery withSubscriptions *UserSubscriptionQuery withUsageLogs *UsageLogQuery @@ -76,8 +76,8 @@ func (_q *GroupQuery) Order(o ...group.OrderOption) *GroupQuery { } // QueryAPIKeys chains the current query on the "api_keys" edge. -func (_q *GroupQuery) QueryAPIKeys() *APIKeyQuery { - query := (&APIKeyClient{config: _q.config}).Query() +func (_q *GroupQuery) QueryAPIKeys() *ApiKeyQuery { + query := (&ApiKeyClient{config: _q.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := _q.prepareQuery(ctx); err != nil { return nil, err @@ -459,8 +459,8 @@ func (_q *GroupQuery) Clone() *GroupQuery { // WithAPIKeys tells the query-builder to eager-load the nodes that are connected to // the "api_keys" edge. The optional arguments are used to configure the query builder of the edge. -func (_q *GroupQuery) WithAPIKeys(opts ...func(*APIKeyQuery)) *GroupQuery { - query := (&APIKeyClient{config: _q.config}).Query() +func (_q *GroupQuery) WithAPIKeys(opts ...func(*ApiKeyQuery)) *GroupQuery { + query := (&ApiKeyClient{config: _q.config}).Query() for _, opt := range opts { opt(query) } @@ -654,8 +654,8 @@ func (_q *GroupQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Group, } if query := _q.withAPIKeys; query != nil { if err := _q.loadAPIKeys(ctx, query, nodes, - func(n *Group) { n.Edges.APIKeys = []*APIKey{} }, - func(n *Group, e *APIKey) { n.Edges.APIKeys = append(n.Edges.APIKeys, e) }); err != nil { + func(n *Group) { n.Edges.APIKeys = []*ApiKey{} }, + func(n *Group, e *ApiKey) { n.Edges.APIKeys = append(n.Edges.APIKeys, e) }); err != nil { return nil, err } } @@ -711,7 +711,7 @@ func (_q *GroupQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Group, return nodes, nil } -func (_q *GroupQuery) loadAPIKeys(ctx context.Context, query *APIKeyQuery, nodes []*Group, init func(*Group), assign func(*Group, *APIKey)) error { +func (_q *GroupQuery) loadAPIKeys(ctx context.Context, query *ApiKeyQuery, nodes []*Group, init func(*Group), assign func(*Group, *ApiKey)) error { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[int64]*Group) for i := range nodes { @@ -724,7 +724,7 @@ func (_q *GroupQuery) loadAPIKeys(ctx context.Context, query *APIKeyQuery, nodes if len(query.ctx.Fields) > 0 { query.ctx.AppendFieldOnce(apikey.FieldGroupID) } - query.Where(predicate.APIKey(func(s *sql.Selector) { + query.Where(predicate.ApiKey(func(s *sql.Selector) { s.Where(sql.InValues(s.C(group.APIKeysColumn), fks...)) })) neighbors, err := query.All(ctx) diff --git a/backend/ent/group_update.go b/backend/ent/group_update.go index 43dcf319..1825a892 100644 --- a/backend/ent/group_update.go +++ b/backend/ent/group_update.go @@ -273,14 +273,14 @@ func (_u *GroupUpdate) AddDefaultValidityDays(v int) *GroupUpdate { return _u } -// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs. +// AddAPIKeyIDs adds the "api_keys" edge to the ApiKey entity by IDs. func (_u *GroupUpdate) AddAPIKeyIDs(ids ...int64) *GroupUpdate { _u.mutation.AddAPIKeyIDs(ids...) return _u } -// AddAPIKeys adds the "api_keys" edges to the APIKey entity. -func (_u *GroupUpdate) AddAPIKeys(v ...*APIKey) *GroupUpdate { +// AddAPIKeys adds the "api_keys" edges to the ApiKey entity. +func (_u *GroupUpdate) AddAPIKeys(v ...*ApiKey) *GroupUpdate { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -368,20 +368,20 @@ func (_u *GroupUpdate) Mutation() *GroupMutation { return _u.mutation } -// ClearAPIKeys clears all "api_keys" edges to the APIKey entity. +// ClearAPIKeys clears all "api_keys" edges to the ApiKey entity. func (_u *GroupUpdate) ClearAPIKeys() *GroupUpdate { _u.mutation.ClearAPIKeys() return _u } -// RemoveAPIKeyIDs removes the "api_keys" edge to APIKey entities by IDs. +// RemoveAPIKeyIDs removes the "api_keys" edge to ApiKey entities by IDs. func (_u *GroupUpdate) RemoveAPIKeyIDs(ids ...int64) *GroupUpdate { _u.mutation.RemoveAPIKeyIDs(ids...) return _u } -// RemoveAPIKeys removes "api_keys" edges to APIKey entities. -func (_u *GroupUpdate) RemoveAPIKeys(v ...*APIKey) *GroupUpdate { +// RemoveAPIKeys removes "api_keys" edges to ApiKey entities. +func (_u *GroupUpdate) RemoveAPIKeys(v ...*ApiKey) *GroupUpdate { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -1195,14 +1195,14 @@ func (_u *GroupUpdateOne) AddDefaultValidityDays(v int) *GroupUpdateOne { return _u } -// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs. +// AddAPIKeyIDs adds the "api_keys" edge to the ApiKey entity by IDs. func (_u *GroupUpdateOne) AddAPIKeyIDs(ids ...int64) *GroupUpdateOne { _u.mutation.AddAPIKeyIDs(ids...) return _u } -// AddAPIKeys adds the "api_keys" edges to the APIKey entity. -func (_u *GroupUpdateOne) AddAPIKeys(v ...*APIKey) *GroupUpdateOne { +// AddAPIKeys adds the "api_keys" edges to the ApiKey entity. +func (_u *GroupUpdateOne) AddAPIKeys(v ...*ApiKey) *GroupUpdateOne { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -1290,20 +1290,20 @@ func (_u *GroupUpdateOne) Mutation() *GroupMutation { return _u.mutation } -// ClearAPIKeys clears all "api_keys" edges to the APIKey entity. +// ClearAPIKeys clears all "api_keys" edges to the ApiKey entity. func (_u *GroupUpdateOne) ClearAPIKeys() *GroupUpdateOne { _u.mutation.ClearAPIKeys() return _u } -// RemoveAPIKeyIDs removes the "api_keys" edge to APIKey entities by IDs. +// RemoveAPIKeyIDs removes the "api_keys" edge to ApiKey entities by IDs. func (_u *GroupUpdateOne) RemoveAPIKeyIDs(ids ...int64) *GroupUpdateOne { _u.mutation.RemoveAPIKeyIDs(ids...) return _u } -// RemoveAPIKeys removes "api_keys" edges to APIKey entities. -func (_u *GroupUpdateOne) RemoveAPIKeys(v ...*APIKey) *GroupUpdateOne { +// RemoveAPIKeys removes "api_keys" edges to ApiKey entities. +func (_u *GroupUpdateOne) RemoveAPIKeys(v ...*ApiKey) *GroupUpdateOne { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID diff --git a/backend/ent/hook/hook.go b/backend/ent/hook/hook.go index e82b00f9..3aa5d186 100644 --- a/backend/ent/hook/hook.go +++ b/backend/ent/hook/hook.go @@ -9,18 +9,6 @@ import ( "github.com/Wei-Shaw/sub2api/ent" ) -// The APIKeyFunc type is an adapter to allow the use of ordinary -// function as APIKey mutator. -type APIKeyFunc func(context.Context, *ent.APIKeyMutation) (ent.Value, error) - -// Mutate calls f(ctx, m). -func (f APIKeyFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { - if mv, ok := m.(*ent.APIKeyMutation); ok { - return f(ctx, mv) - } - return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.APIKeyMutation", m) -} - // The AccountFunc type is an adapter to allow the use of ordinary // function as Account mutator. type AccountFunc func(context.Context, *ent.AccountMutation) (ent.Value, error) @@ -45,6 +33,18 @@ func (f AccountGroupFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.AccountGroupMutation", m) } +// The ApiKeyFunc type is an adapter to allow the use of ordinary +// function as ApiKey mutator. +type ApiKeyFunc func(context.Context, *ent.ApiKeyMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f ApiKeyFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.ApiKeyMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ApiKeyMutation", m) +} + // The GroupFunc type is an adapter to allow the use of ordinary // function as Group mutator. type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error) diff --git a/backend/ent/intercept/intercept.go b/backend/ent/intercept/intercept.go index 6add6fed..9f694d67 100644 --- a/backend/ent/intercept/intercept.go +++ b/backend/ent/intercept/intercept.go @@ -80,33 +80,6 @@ func (f TraverseFunc) Traverse(ctx context.Context, q ent.Query) error { return f(ctx, query) } -// The APIKeyFunc type is an adapter to allow the use of ordinary function as a Querier. -type APIKeyFunc func(context.Context, *ent.APIKeyQuery) (ent.Value, error) - -// Query calls f(ctx, q). -func (f APIKeyFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) { - if q, ok := q.(*ent.APIKeyQuery); ok { - return f(ctx, q) - } - return nil, fmt.Errorf("unexpected query type %T. expect *ent.APIKeyQuery", q) -} - -// The TraverseAPIKey type is an adapter to allow the use of ordinary function as Traverser. -type TraverseAPIKey func(context.Context, *ent.APIKeyQuery) error - -// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline. -func (f TraverseAPIKey) Intercept(next ent.Querier) ent.Querier { - return next -} - -// Traverse calls f(ctx, q). -func (f TraverseAPIKey) Traverse(ctx context.Context, q ent.Query) error { - if q, ok := q.(*ent.APIKeyQuery); ok { - return f(ctx, q) - } - return fmt.Errorf("unexpected query type %T. expect *ent.APIKeyQuery", q) -} - // The AccountFunc type is an adapter to allow the use of ordinary function as a Querier. type AccountFunc func(context.Context, *ent.AccountQuery) (ent.Value, error) @@ -161,6 +134,33 @@ func (f TraverseAccountGroup) Traverse(ctx context.Context, q ent.Query) error { return fmt.Errorf("unexpected query type %T. expect *ent.AccountGroupQuery", q) } +// The ApiKeyFunc type is an adapter to allow the use of ordinary function as a Querier. +type ApiKeyFunc func(context.Context, *ent.ApiKeyQuery) (ent.Value, error) + +// Query calls f(ctx, q). +func (f ApiKeyFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) { + if q, ok := q.(*ent.ApiKeyQuery); ok { + return f(ctx, q) + } + return nil, fmt.Errorf("unexpected query type %T. expect *ent.ApiKeyQuery", q) +} + +// The TraverseApiKey type is an adapter to allow the use of ordinary function as Traverser. +type TraverseApiKey func(context.Context, *ent.ApiKeyQuery) error + +// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline. +func (f TraverseApiKey) Intercept(next ent.Querier) ent.Querier { + return next +} + +// Traverse calls f(ctx, q). +func (f TraverseApiKey) Traverse(ctx context.Context, q ent.Query) error { + if q, ok := q.(*ent.ApiKeyQuery); ok { + return f(ctx, q) + } + return fmt.Errorf("unexpected query type %T. expect *ent.ApiKeyQuery", q) +} + // The GroupFunc type is an adapter to allow the use of ordinary function as a Querier. type GroupFunc func(context.Context, *ent.GroupQuery) (ent.Value, error) @@ -434,12 +434,12 @@ func (f TraverseUserSubscription) Traverse(ctx context.Context, q ent.Query) err // NewQuery returns the generic Query interface for the given typed query. func NewQuery(q ent.Query) (Query, error) { switch q := q.(type) { - case *ent.APIKeyQuery: - return &query[*ent.APIKeyQuery, predicate.APIKey, apikey.OrderOption]{typ: ent.TypeAPIKey, tq: q}, nil case *ent.AccountQuery: return &query[*ent.AccountQuery, predicate.Account, account.OrderOption]{typ: ent.TypeAccount, tq: q}, nil case *ent.AccountGroupQuery: return &query[*ent.AccountGroupQuery, predicate.AccountGroup, accountgroup.OrderOption]{typ: ent.TypeAccountGroup, tq: q}, nil + case *ent.ApiKeyQuery: + return &query[*ent.ApiKeyQuery, predicate.ApiKey, apikey.OrderOption]{typ: ent.TypeApiKey, tq: q}, nil case *ent.GroupQuery: return &query[*ent.GroupQuery, predicate.Group, group.OrderOption]{typ: ent.TypeGroup, tq: q}, nil case *ent.ProxyQuery: diff --git a/backend/ent/migrate/schema.go b/backend/ent/migrate/schema.go index b85630ea..d532b34b 100644 --- a/backend/ent/migrate/schema.go +++ b/backend/ent/migrate/schema.go @@ -9,60 +9,6 @@ import ( ) var ( - // APIKeysColumns holds the columns for the "api_keys" table. - APIKeysColumns = []*schema.Column{ - {Name: "id", Type: field.TypeInt64, Increment: true}, - {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, - {Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, - {Name: "deleted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, - {Name: "key", Type: field.TypeString, Unique: true, Size: 128}, - {Name: "name", Type: field.TypeString, Size: 100}, - {Name: "status", Type: field.TypeString, Size: 20, Default: "active"}, - {Name: "group_id", Type: field.TypeInt64, Nullable: true}, - {Name: "user_id", Type: field.TypeInt64}, - } - // APIKeysTable holds the schema information for the "api_keys" table. - APIKeysTable = &schema.Table{ - Name: "api_keys", - Columns: APIKeysColumns, - PrimaryKey: []*schema.Column{APIKeysColumns[0]}, - ForeignKeys: []*schema.ForeignKey{ - { - Symbol: "api_keys_groups_api_keys", - Columns: []*schema.Column{APIKeysColumns[7]}, - RefColumns: []*schema.Column{GroupsColumns[0]}, - OnDelete: schema.SetNull, - }, - { - Symbol: "api_keys_users_api_keys", - Columns: []*schema.Column{APIKeysColumns[8]}, - RefColumns: []*schema.Column{UsersColumns[0]}, - OnDelete: schema.NoAction, - }, - }, - Indexes: []*schema.Index{ - { - Name: "apikey_user_id", - Unique: false, - Columns: []*schema.Column{APIKeysColumns[8]}, - }, - { - Name: "apikey_group_id", - Unique: false, - Columns: []*schema.Column{APIKeysColumns[7]}, - }, - { - Name: "apikey_status", - Unique: false, - Columns: []*schema.Column{APIKeysColumns[6]}, - }, - { - Name: "apikey_deleted_at", - Unique: false, - Columns: []*schema.Column{APIKeysColumns[3]}, - }, - }, - } // AccountsColumns holds the columns for the "accounts" table. AccountsColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt64, Increment: true}, @@ -198,6 +144,60 @@ var ( }, }, } + // APIKeysColumns holds the columns for the "api_keys" table. + APIKeysColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "deleted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, + {Name: "key", Type: field.TypeString, Unique: true, Size: 128}, + {Name: "name", Type: field.TypeString, Size: 100}, + {Name: "status", Type: field.TypeString, Size: 20, Default: "active"}, + {Name: "group_id", Type: field.TypeInt64, Nullable: true}, + {Name: "user_id", Type: field.TypeInt64}, + } + // APIKeysTable holds the schema information for the "api_keys" table. + APIKeysTable = &schema.Table{ + Name: "api_keys", + Columns: APIKeysColumns, + PrimaryKey: []*schema.Column{APIKeysColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "api_keys_groups_api_keys", + Columns: []*schema.Column{APIKeysColumns[7]}, + RefColumns: []*schema.Column{GroupsColumns[0]}, + OnDelete: schema.SetNull, + }, + { + Symbol: "api_keys_users_api_keys", + Columns: []*schema.Column{APIKeysColumns[8]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + Indexes: []*schema.Index{ + { + Name: "apikey_user_id", + Unique: false, + Columns: []*schema.Column{APIKeysColumns[8]}, + }, + { + Name: "apikey_group_id", + Unique: false, + Columns: []*schema.Column{APIKeysColumns[7]}, + }, + { + Name: "apikey_status", + Unique: false, + Columns: []*schema.Column{APIKeysColumns[6]}, + }, + { + Name: "apikey_deleted_at", + Unique: false, + Columns: []*schema.Column{APIKeysColumns[3]}, + }, + }, + } // GroupsColumns holds the columns for the "groups" table. GroupsColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt64, Increment: true}, @@ -368,8 +368,8 @@ var ( {Name: "duration_ms", Type: field.TypeInt, Nullable: true}, {Name: "first_token_ms", Type: field.TypeInt, Nullable: true}, {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, - {Name: "api_key_id", Type: field.TypeInt64}, {Name: "account_id", Type: field.TypeInt64}, + {Name: "api_key_id", Type: field.TypeInt64}, {Name: "group_id", Type: field.TypeInt64, Nullable: true}, {Name: "user_id", Type: field.TypeInt64}, {Name: "subscription_id", Type: field.TypeInt64, Nullable: true}, @@ -381,15 +381,15 @@ var ( PrimaryKey: []*schema.Column{UsageLogsColumns[0]}, ForeignKeys: []*schema.ForeignKey{ { - Symbol: "usage_logs_api_keys_usage_logs", + Symbol: "usage_logs_accounts_usage_logs", Columns: []*schema.Column{UsageLogsColumns[21]}, - RefColumns: []*schema.Column{APIKeysColumns[0]}, + RefColumns: []*schema.Column{AccountsColumns[0]}, OnDelete: schema.NoAction, }, { - Symbol: "usage_logs_accounts_usage_logs", + Symbol: "usage_logs_api_keys_usage_logs", Columns: []*schema.Column{UsageLogsColumns[22]}, - RefColumns: []*schema.Column{AccountsColumns[0]}, + RefColumns: []*schema.Column{APIKeysColumns[0]}, OnDelete: schema.NoAction, }, { @@ -420,12 +420,12 @@ var ( { Name: "usagelog_api_key_id", Unique: false, - Columns: []*schema.Column{UsageLogsColumns[21]}, + Columns: []*schema.Column{UsageLogsColumns[22]}, }, { Name: "usagelog_account_id", Unique: false, - Columns: []*schema.Column{UsageLogsColumns[22]}, + Columns: []*schema.Column{UsageLogsColumns[21]}, }, { Name: "usagelog_group_id", @@ -460,7 +460,7 @@ var ( { Name: "usagelog_api_key_id_created_at", Unique: false, - Columns: []*schema.Column{UsageLogsColumns[21], UsageLogsColumns[20]}, + Columns: []*schema.Column{UsageLogsColumns[22], UsageLogsColumns[20]}, }, }, } @@ -702,9 +702,9 @@ var ( } // Tables holds all the tables in the schema. Tables = []*schema.Table{ - APIKeysTable, AccountsTable, AccountGroupsTable, + APIKeysTable, GroupsTable, ProxiesTable, RedeemCodesTable, @@ -719,11 +719,6 @@ var ( ) func init() { - APIKeysTable.ForeignKeys[0].RefTable = GroupsTable - APIKeysTable.ForeignKeys[1].RefTable = UsersTable - APIKeysTable.Annotation = &entsql.Annotation{ - Table: "api_keys", - } AccountsTable.ForeignKeys[0].RefTable = ProxiesTable AccountsTable.Annotation = &entsql.Annotation{ Table: "accounts", @@ -733,6 +728,11 @@ func init() { AccountGroupsTable.Annotation = &entsql.Annotation{ Table: "account_groups", } + APIKeysTable.ForeignKeys[0].RefTable = GroupsTable + APIKeysTable.ForeignKeys[1].RefTable = UsersTable + APIKeysTable.Annotation = &entsql.Annotation{ + Table: "api_keys", + } GroupsTable.Annotation = &entsql.Annotation{ Table: "groups", } @@ -747,8 +747,8 @@ func init() { SettingsTable.Annotation = &entsql.Annotation{ Table: "settings", } - UsageLogsTable.ForeignKeys[0].RefTable = APIKeysTable - UsageLogsTable.ForeignKeys[1].RefTable = AccountsTable + UsageLogsTable.ForeignKeys[0].RefTable = AccountsTable + UsageLogsTable.ForeignKeys[1].RefTable = APIKeysTable UsageLogsTable.ForeignKeys[2].RefTable = GroupsTable UsageLogsTable.ForeignKeys[3].RefTable = UsersTable UsageLogsTable.ForeignKeys[4].RefTable = UserSubscriptionsTable diff --git a/backend/ent/mutation.go b/backend/ent/mutation.go index 90ee37b6..7d5fd2ad 100644 --- a/backend/ent/mutation.go +++ b/backend/ent/mutation.go @@ -36,954 +36,21 @@ const ( OpUpdateOne = ent.OpUpdateOne // Node types. - TypeAPIKey = "APIKey" - TypeAccount = "Account" - TypeAccountGroup = "AccountGroup" - TypeGroup = "Group" - TypeProxy = "Proxy" - TypeRedeemCode = "RedeemCode" - TypeSetting = "Setting" - TypeUsageLog = "UsageLog" - TypeUser = "User" - TypeUserAllowedGroup = "UserAllowedGroup" + TypeAccount = "Account" + TypeAccountGroup = "AccountGroup" + TypeApiKey = "ApiKey" + TypeGroup = "Group" + TypeProxy = "Proxy" + TypeRedeemCode = "RedeemCode" + TypeSetting = "Setting" + TypeUsageLog = "UsageLog" + TypeUser = "User" + TypeUserAllowedGroup = "UserAllowedGroup" TypeUserAttributeDefinition = "UserAttributeDefinition" TypeUserAttributeValue = "UserAttributeValue" - TypeUserSubscription = "UserSubscription" + TypeUserSubscription = "UserSubscription" ) -// APIKeyMutation represents an operation that mutates the APIKey nodes in the graph. -type APIKeyMutation struct { - config - op Op - typ string - id *int64 - created_at *time.Time - updated_at *time.Time - deleted_at *time.Time - key *string - name *string - status *string - clearedFields map[string]struct{} - user *int64 - cleareduser bool - group *int64 - clearedgroup bool - usage_logs map[int64]struct{} - removedusage_logs map[int64]struct{} - clearedusage_logs bool - done bool - oldValue func(context.Context) (*APIKey, error) - predicates []predicate.APIKey -} - -var _ ent.Mutation = (*APIKeyMutation)(nil) - -// apikeyOption allows management of the mutation configuration using functional options. -type apikeyOption func(*APIKeyMutation) - -// newAPIKeyMutation creates new mutation for the APIKey entity. -func newAPIKeyMutation(c config, op Op, opts ...apikeyOption) *APIKeyMutation { - m := &APIKeyMutation{ - config: c, - op: op, - typ: TypeAPIKey, - clearedFields: make(map[string]struct{}), - } - for _, opt := range opts { - opt(m) - } - return m -} - -// withAPIKeyID sets the ID field of the mutation. -func withAPIKeyID(id int64) apikeyOption { - return func(m *APIKeyMutation) { - var ( - err error - once sync.Once - value *APIKey - ) - m.oldValue = func(ctx context.Context) (*APIKey, error) { - once.Do(func() { - if m.done { - err = errors.New("querying old values post mutation is not allowed") - } else { - value, err = m.Client().APIKey.Get(ctx, id) - } - }) - return value, err - } - m.id = &id - } -} - -// withAPIKey sets the old APIKey of the mutation. -func withAPIKey(node *APIKey) apikeyOption { - return func(m *APIKeyMutation) { - m.oldValue = func(context.Context) (*APIKey, error) { - return node, nil - } - m.id = &node.ID - } -} - -// Client returns a new `ent.Client` from the mutation. If the mutation was -// executed in a transaction (ent.Tx), a transactional client is returned. -func (m APIKeyMutation) Client() *Client { - client := &Client{config: m.config} - client.init() - return client -} - -// Tx returns an `ent.Tx` for mutations that were executed in transactions; -// it returns an error otherwise. -func (m APIKeyMutation) Tx() (*Tx, error) { - if _, ok := m.driver.(*txDriver); !ok { - return nil, errors.New("ent: mutation is not running in a transaction") - } - tx := &Tx{config: m.config} - tx.init() - return tx, nil -} - -// ID returns the ID value in the mutation. Note that the ID is only available -// if it was provided to the builder or after it was returned from the database. -func (m *APIKeyMutation) ID() (id int64, exists bool) { - if m.id == nil { - return - } - return *m.id, true -} - -// IDs queries the database and returns the entity ids that match the mutation's predicate. -// That means, if the mutation is applied within a transaction with an isolation level such -// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated -// or updated by the mutation. -func (m *APIKeyMutation) IDs(ctx context.Context) ([]int64, error) { - switch { - case m.op.Is(OpUpdateOne | OpDeleteOne): - id, exists := m.ID() - if exists { - return []int64{id}, nil - } - fallthrough - case m.op.Is(OpUpdate | OpDelete): - return m.Client().APIKey.Query().Where(m.predicates...).IDs(ctx) - default: - return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) - } -} - -// SetCreatedAt sets the "created_at" field. -func (m *APIKeyMutation) SetCreatedAt(t time.Time) { - m.created_at = &t -} - -// CreatedAt returns the value of the "created_at" field in the mutation. -func (m *APIKeyMutation) CreatedAt() (r time.Time, exists bool) { - v := m.created_at - if v == nil { - return - } - return *v, true -} - -// OldCreatedAt returns the old "created_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) OldCreatedAt(ctx context.Context) (v time.Time, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldCreatedAt requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) - } - return oldValue.CreatedAt, nil -} - -// ResetCreatedAt resets all changes to the "created_at" field. -func (m *APIKeyMutation) ResetCreatedAt() { - m.created_at = nil -} - -// SetUpdatedAt sets the "updated_at" field. -func (m *APIKeyMutation) SetUpdatedAt(t time.Time) { - m.updated_at = &t -} - -// UpdatedAt returns the value of the "updated_at" field in the mutation. -func (m *APIKeyMutation) UpdatedAt() (r time.Time, exists bool) { - v := m.updated_at - if v == nil { - return - } - return *v, true -} - -// OldUpdatedAt returns the old "updated_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) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldUpdatedAt requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) - } - return oldValue.UpdatedAt, nil -} - -// ResetUpdatedAt resets all changes to the "updated_at" field. -func (m *APIKeyMutation) ResetUpdatedAt() { - m.updated_at = nil -} - -// SetDeletedAt sets the "deleted_at" field. -func (m *APIKeyMutation) SetDeletedAt(t time.Time) { - m.deleted_at = &t -} - -// DeletedAt returns the value of the "deleted_at" field in the mutation. -func (m *APIKeyMutation) DeletedAt() (r time.Time, exists bool) { - v := m.deleted_at - if v == nil { - return - } - return *v, true -} - -// OldDeletedAt returns the old "deleted_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) OldDeletedAt(ctx context.Context) (v *time.Time, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldDeletedAt is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldDeletedAt requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldDeletedAt: %w", err) - } - return oldValue.DeletedAt, nil -} - -// ClearDeletedAt clears the value of the "deleted_at" field. -func (m *APIKeyMutation) ClearDeletedAt() { - m.deleted_at = nil - m.clearedFields[apikey.FieldDeletedAt] = struct{}{} -} - -// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation. -func (m *APIKeyMutation) DeletedAtCleared() bool { - _, ok := m.clearedFields[apikey.FieldDeletedAt] - return ok -} - -// ResetDeletedAt resets all changes to the "deleted_at" field. -func (m *APIKeyMutation) ResetDeletedAt() { - m.deleted_at = nil - delete(m.clearedFields, apikey.FieldDeletedAt) -} - -// SetUserID sets the "user_id" field. -func (m *APIKeyMutation) SetUserID(i int64) { - m.user = &i -} - -// UserID returns the value of the "user_id" field in the mutation. -func (m *APIKeyMutation) UserID() (r int64, exists bool) { - v := m.user - if v == nil { - return - } - return *v, true -} - -// OldUserID returns the old "user_id" 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) OldUserID(ctx context.Context) (v int64, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldUserID is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldUserID requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldUserID: %w", err) - } - return oldValue.UserID, nil -} - -// ResetUserID resets all changes to the "user_id" field. -func (m *APIKeyMutation) ResetUserID() { - m.user = nil -} - -// SetKey sets the "key" field. -func (m *APIKeyMutation) SetKey(s string) { - m.key = &s -} - -// Key returns the value of the "key" field in the mutation. -func (m *APIKeyMutation) Key() (r string, exists bool) { - v := m.key - if v == nil { - return - } - return *v, true -} - -// OldKey returns the old "key" 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) OldKey(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldKey is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldKey requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldKey: %w", err) - } - return oldValue.Key, nil -} - -// ResetKey resets all changes to the "key" field. -func (m *APIKeyMutation) ResetKey() { - m.key = nil -} - -// SetName sets the "name" field. -func (m *APIKeyMutation) SetName(s string) { - m.name = &s -} - -// Name returns the value of the "name" field in the mutation. -func (m *APIKeyMutation) Name() (r string, exists bool) { - v := m.name - if v == nil { - return - } - return *v, true -} - -// OldName returns the old "name" 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) OldName(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldName is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldName requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldName: %w", err) - } - return oldValue.Name, nil -} - -// ResetName resets all changes to the "name" field. -func (m *APIKeyMutation) ResetName() { - m.name = nil -} - -// SetGroupID sets the "group_id" field. -func (m *APIKeyMutation) SetGroupID(i int64) { - m.group = &i -} - -// GroupID returns the value of the "group_id" field in the mutation. -func (m *APIKeyMutation) GroupID() (r int64, exists bool) { - v := m.group - if v == nil { - return - } - return *v, true -} - -// OldGroupID returns the old "group_id" 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) OldGroupID(ctx context.Context) (v *int64, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldGroupID is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldGroupID requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldGroupID: %w", err) - } - return oldValue.GroupID, nil -} - -// ClearGroupID clears the value of the "group_id" field. -func (m *APIKeyMutation) ClearGroupID() { - m.group = nil - m.clearedFields[apikey.FieldGroupID] = struct{}{} -} - -// GroupIDCleared returns if the "group_id" field was cleared in this mutation. -func (m *APIKeyMutation) GroupIDCleared() bool { - _, ok := m.clearedFields[apikey.FieldGroupID] - return ok -} - -// ResetGroupID resets all changes to the "group_id" field. -func (m *APIKeyMutation) ResetGroupID() { - m.group = nil - delete(m.clearedFields, apikey.FieldGroupID) -} - -// SetStatus sets the "status" field. -func (m *APIKeyMutation) SetStatus(s string) { - m.status = &s -} - -// Status returns the value of the "status" field in the mutation. -func (m *APIKeyMutation) Status() (r string, exists bool) { - v := m.status - if v == nil { - return - } - return *v, true -} - -// OldStatus returns the old "status" 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) OldStatus(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldStatus is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldStatus requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldStatus: %w", err) - } - return oldValue.Status, nil -} - -// ResetStatus resets all changes to the "status" field. -func (m *APIKeyMutation) ResetStatus() { - m.status = nil -} - -// ClearUser clears the "user" edge to the User entity. -func (m *APIKeyMutation) ClearUser() { - m.cleareduser = true - m.clearedFields[apikey.FieldUserID] = struct{}{} -} - -// UserCleared reports if the "user" edge to the User entity was cleared. -func (m *APIKeyMutation) UserCleared() bool { - return m.cleareduser -} - -// UserIDs returns the "user" edge IDs in the mutation. -// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use -// UserID instead. It exists only for internal usage by the builders. -func (m *APIKeyMutation) UserIDs() (ids []int64) { - if id := m.user; id != nil { - ids = append(ids, *id) - } - return -} - -// ResetUser resets all changes to the "user" edge. -func (m *APIKeyMutation) ResetUser() { - m.user = nil - m.cleareduser = false -} - -// ClearGroup clears the "group" edge to the Group entity. -func (m *APIKeyMutation) ClearGroup() { - m.clearedgroup = true - m.clearedFields[apikey.FieldGroupID] = struct{}{} -} - -// GroupCleared reports if the "group" edge to the Group entity was cleared. -func (m *APIKeyMutation) GroupCleared() bool { - return m.GroupIDCleared() || m.clearedgroup -} - -// GroupIDs returns the "group" edge IDs in the mutation. -// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use -// GroupID instead. It exists only for internal usage by the builders. -func (m *APIKeyMutation) GroupIDs() (ids []int64) { - if id := m.group; id != nil { - ids = append(ids, *id) - } - return -} - -// ResetGroup resets all changes to the "group" edge. -func (m *APIKeyMutation) ResetGroup() { - m.group = nil - m.clearedgroup = false -} - -// AddUsageLogIDs adds the "usage_logs" edge to the UsageLog entity by ids. -func (m *APIKeyMutation) AddUsageLogIDs(ids ...int64) { - if m.usage_logs == nil { - m.usage_logs = make(map[int64]struct{}) - } - for i := range ids { - m.usage_logs[ids[i]] = struct{}{} - } -} - -// ClearUsageLogs clears the "usage_logs" edge to the UsageLog entity. -func (m *APIKeyMutation) ClearUsageLogs() { - m.clearedusage_logs = true -} - -// UsageLogsCleared reports if the "usage_logs" edge to the UsageLog entity was cleared. -func (m *APIKeyMutation) UsageLogsCleared() bool { - return m.clearedusage_logs -} - -// RemoveUsageLogIDs removes the "usage_logs" edge to the UsageLog entity by IDs. -func (m *APIKeyMutation) RemoveUsageLogIDs(ids ...int64) { - if m.removedusage_logs == nil { - m.removedusage_logs = make(map[int64]struct{}) - } - for i := range ids { - delete(m.usage_logs, ids[i]) - m.removedusage_logs[ids[i]] = struct{}{} - } -} - -// RemovedUsageLogs returns the removed IDs of the "usage_logs" edge to the UsageLog entity. -func (m *APIKeyMutation) RemovedUsageLogsIDs() (ids []int64) { - for id := range m.removedusage_logs { - ids = append(ids, id) - } - return -} - -// UsageLogsIDs returns the "usage_logs" edge IDs in the mutation. -func (m *APIKeyMutation) UsageLogsIDs() (ids []int64) { - for id := range m.usage_logs { - ids = append(ids, id) - } - return -} - -// ResetUsageLogs resets all changes to the "usage_logs" edge. -func (m *APIKeyMutation) ResetUsageLogs() { - m.usage_logs = nil - m.clearedusage_logs = false - m.removedusage_logs = nil -} - -// Where appends a list predicates to the APIKeyMutation builder. -func (m *APIKeyMutation) Where(ps ...predicate.APIKey) { - m.predicates = append(m.predicates, ps...) -} - -// WhereP appends storage-level predicates to the APIKeyMutation builder. Using this method, -// users can use type-assertion to append predicates that do not depend on any generated package. -func (m *APIKeyMutation) WhereP(ps ...func(*sql.Selector)) { - p := make([]predicate.APIKey, len(ps)) - for i := range ps { - p[i] = ps[i] - } - m.Where(p...) -} - -// Op returns the operation name. -func (m *APIKeyMutation) Op() Op { - return m.op -} - -// SetOp allows setting the mutation operation. -func (m *APIKeyMutation) SetOp(op Op) { - m.op = op -} - -// Type returns the node type of this mutation (APIKey). -func (m *APIKeyMutation) Type() string { - return m.typ -} - -// Fields returns all fields that were changed during this mutation. Note that in -// order to get all numeric fields that were incremented/decremented, call -// AddedFields(). -func (m *APIKeyMutation) Fields() []string { - fields := make([]string, 0, 8) - if m.created_at != nil { - fields = append(fields, apikey.FieldCreatedAt) - } - if m.updated_at != nil { - fields = append(fields, apikey.FieldUpdatedAt) - } - if m.deleted_at != nil { - fields = append(fields, apikey.FieldDeletedAt) - } - if m.user != nil { - fields = append(fields, apikey.FieldUserID) - } - if m.key != nil { - fields = append(fields, apikey.FieldKey) - } - if m.name != nil { - fields = append(fields, apikey.FieldName) - } - if m.group != nil { - fields = append(fields, apikey.FieldGroupID) - } - if m.status != nil { - fields = append(fields, apikey.FieldStatus) - } - return fields -} - -// Field returns the value of a field with the given name. The second boolean -// return value indicates that this field was not set, or was not defined in the -// schema. -func (m *APIKeyMutation) Field(name string) (ent.Value, bool) { - switch name { - case apikey.FieldCreatedAt: - return m.CreatedAt() - case apikey.FieldUpdatedAt: - return m.UpdatedAt() - case apikey.FieldDeletedAt: - return m.DeletedAt() - case apikey.FieldUserID: - return m.UserID() - case apikey.FieldKey: - return m.Key() - case apikey.FieldName: - return m.Name() - case apikey.FieldGroupID: - return m.GroupID() - case apikey.FieldStatus: - return m.Status() - } - return nil, false -} - -// OldField returns the old value of the field from the database. An error is -// returned if the mutation operation is not UpdateOne, or the query to the -// database failed. -func (m *APIKeyMutation) OldField(ctx context.Context, name string) (ent.Value, error) { - switch name { - case apikey.FieldCreatedAt: - return m.OldCreatedAt(ctx) - case apikey.FieldUpdatedAt: - return m.OldUpdatedAt(ctx) - case apikey.FieldDeletedAt: - return m.OldDeletedAt(ctx) - case apikey.FieldUserID: - return m.OldUserID(ctx) - case apikey.FieldKey: - return m.OldKey(ctx) - case apikey.FieldName: - return m.OldName(ctx) - case apikey.FieldGroupID: - return m.OldGroupID(ctx) - case apikey.FieldStatus: - return m.OldStatus(ctx) - } - return nil, fmt.Errorf("unknown APIKey field %s", name) -} - -// SetField sets the value of a field with the given name. It returns an error if -// the field is not defined in the schema, or if the type mismatched the field -// type. -func (m *APIKeyMutation) SetField(name string, value ent.Value) error { - switch name { - case apikey.FieldCreatedAt: - v, ok := value.(time.Time) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetCreatedAt(v) - return nil - case apikey.FieldUpdatedAt: - v, ok := value.(time.Time) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetUpdatedAt(v) - return nil - case apikey.FieldDeletedAt: - v, ok := value.(time.Time) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetDeletedAt(v) - return nil - case apikey.FieldUserID: - v, ok := value.(int64) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetUserID(v) - return nil - case apikey.FieldKey: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetKey(v) - return nil - case apikey.FieldName: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetName(v) - return nil - case apikey.FieldGroupID: - v, ok := value.(int64) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetGroupID(v) - return nil - case apikey.FieldStatus: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetStatus(v) - return nil - } - return fmt.Errorf("unknown APIKey field %s", name) -} - -// AddedFields returns all numeric fields that were incremented/decremented during -// this mutation. -func (m *APIKeyMutation) AddedFields() []string { - var fields []string - return fields -} - -// AddedField returns the numeric value that was incremented/decremented on a field -// with the given name. The second boolean return value indicates that this field -// was not set, or was not defined in the schema. -func (m *APIKeyMutation) AddedField(name string) (ent.Value, bool) { - switch name { - } - return nil, false -} - -// AddField adds the value to the field with the given name. It returns an error if -// the field is not defined in the schema, or if the type mismatched the field -// type. -func (m *APIKeyMutation) AddField(name string, value ent.Value) error { - switch name { - } - return fmt.Errorf("unknown APIKey numeric field %s", name) -} - -// ClearedFields returns all nullable fields that were cleared during this -// mutation. -func (m *APIKeyMutation) ClearedFields() []string { - var fields []string - if m.FieldCleared(apikey.FieldDeletedAt) { - fields = append(fields, apikey.FieldDeletedAt) - } - if m.FieldCleared(apikey.FieldGroupID) { - fields = append(fields, apikey.FieldGroupID) - } - return fields -} - -// FieldCleared returns a boolean indicating if a field with the given name was -// cleared in this mutation. -func (m *APIKeyMutation) FieldCleared(name string) bool { - _, ok := m.clearedFields[name] - return ok -} - -// ClearField clears the value of the field with the given name. It returns an -// error if the field is not defined in the schema. -func (m *APIKeyMutation) ClearField(name string) error { - switch name { - case apikey.FieldDeletedAt: - m.ClearDeletedAt() - return nil - case apikey.FieldGroupID: - m.ClearGroupID() - return nil - } - return fmt.Errorf("unknown APIKey nullable field %s", name) -} - -// ResetField resets all changes in the mutation for the field with the given name. -// It returns an error if the field is not defined in the schema. -func (m *APIKeyMutation) ResetField(name string) error { - switch name { - case apikey.FieldCreatedAt: - m.ResetCreatedAt() - return nil - case apikey.FieldUpdatedAt: - m.ResetUpdatedAt() - return nil - case apikey.FieldDeletedAt: - m.ResetDeletedAt() - return nil - case apikey.FieldUserID: - m.ResetUserID() - return nil - case apikey.FieldKey: - m.ResetKey() - return nil - case apikey.FieldName: - m.ResetName() - return nil - case apikey.FieldGroupID: - m.ResetGroupID() - return nil - case apikey.FieldStatus: - m.ResetStatus() - return nil - } - return fmt.Errorf("unknown APIKey field %s", name) -} - -// AddedEdges returns all edge names that were set/added in this mutation. -func (m *APIKeyMutation) AddedEdges() []string { - edges := make([]string, 0, 3) - if m.user != nil { - edges = append(edges, apikey.EdgeUser) - } - if m.group != nil { - edges = append(edges, apikey.EdgeGroup) - } - if m.usage_logs != nil { - edges = append(edges, apikey.EdgeUsageLogs) - } - return edges -} - -// AddedIDs returns all IDs (to other nodes) that were added for the given edge -// name in this mutation. -func (m *APIKeyMutation) AddedIDs(name string) []ent.Value { - switch name { - case apikey.EdgeUser: - if id := m.user; id != nil { - return []ent.Value{*id} - } - case apikey.EdgeGroup: - if id := m.group; id != nil { - return []ent.Value{*id} - } - case apikey.EdgeUsageLogs: - ids := make([]ent.Value, 0, len(m.usage_logs)) - for id := range m.usage_logs { - ids = append(ids, id) - } - return ids - } - return nil -} - -// RemovedEdges returns all edge names that were removed in this mutation. -func (m *APIKeyMutation) RemovedEdges() []string { - edges := make([]string, 0, 3) - if m.removedusage_logs != nil { - edges = append(edges, apikey.EdgeUsageLogs) - } - return edges -} - -// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with -// the given name in this mutation. -func (m *APIKeyMutation) RemovedIDs(name string) []ent.Value { - switch name { - case apikey.EdgeUsageLogs: - ids := make([]ent.Value, 0, len(m.removedusage_logs)) - for id := range m.removedusage_logs { - ids = append(ids, id) - } - return ids - } - return nil -} - -// ClearedEdges returns all edge names that were cleared in this mutation. -func (m *APIKeyMutation) ClearedEdges() []string { - edges := make([]string, 0, 3) - if m.cleareduser { - edges = append(edges, apikey.EdgeUser) - } - if m.clearedgroup { - edges = append(edges, apikey.EdgeGroup) - } - if m.clearedusage_logs { - edges = append(edges, apikey.EdgeUsageLogs) - } - return edges -} - -// EdgeCleared returns a boolean which indicates if the edge with the given name -// was cleared in this mutation. -func (m *APIKeyMutation) EdgeCleared(name string) bool { - switch name { - case apikey.EdgeUser: - return m.cleareduser - case apikey.EdgeGroup: - return m.clearedgroup - case apikey.EdgeUsageLogs: - return m.clearedusage_logs - } - return false -} - -// ClearEdge clears the value of the edge with the given name. It returns an error -// if that edge is not defined in the schema. -func (m *APIKeyMutation) ClearEdge(name string) error { - switch name { - case apikey.EdgeUser: - m.ClearUser() - return nil - case apikey.EdgeGroup: - m.ClearGroup() - return nil - } - return fmt.Errorf("unknown APIKey unique edge %s", name) -} - -// ResetEdge resets all changes to the edge with the given name in this mutation. -// It returns an error if the edge is not defined in the schema. -func (m *APIKeyMutation) ResetEdge(name string) error { - switch name { - case apikey.EdgeUser: - m.ResetUser() - return nil - case apikey.EdgeGroup: - m.ResetGroup() - return nil - case apikey.EdgeUsageLogs: - m.ResetUsageLogs() - return nil - } - return fmt.Errorf("unknown APIKey edge %s", name) -} - // AccountMutation represents an operation that mutates the Account nodes in the graph. type AccountMutation struct { config @@ -3359,6 +2426,939 @@ func (m *AccountGroupMutation) ResetEdge(name string) error { return fmt.Errorf("unknown AccountGroup edge %s", name) } +// ApiKeyMutation represents an operation that mutates the ApiKey nodes in the graph. +type ApiKeyMutation struct { + config + op Op + typ string + id *int64 + created_at *time.Time + updated_at *time.Time + deleted_at *time.Time + key *string + name *string + status *string + clearedFields map[string]struct{} + user *int64 + cleareduser bool + group *int64 + clearedgroup bool + usage_logs map[int64]struct{} + removedusage_logs map[int64]struct{} + clearedusage_logs bool + done bool + oldValue func(context.Context) (*ApiKey, error) + predicates []predicate.ApiKey +} + +var _ ent.Mutation = (*ApiKeyMutation)(nil) + +// apikeyOption allows management of the mutation configuration using functional options. +type apikeyOption func(*ApiKeyMutation) + +// newApiKeyMutation creates new mutation for the ApiKey entity. +func newApiKeyMutation(c config, op Op, opts ...apikeyOption) *ApiKeyMutation { + m := &ApiKeyMutation{ + config: c, + op: op, + typ: TypeApiKey, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withApiKeyID sets the ID field of the mutation. +func withApiKeyID(id int64) apikeyOption { + return func(m *ApiKeyMutation) { + var ( + err error + once sync.Once + value *ApiKey + ) + m.oldValue = func(ctx context.Context) (*ApiKey, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().ApiKey.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withApiKey sets the old ApiKey of the mutation. +func withApiKey(node *ApiKey) apikeyOption { + return func(m *ApiKeyMutation) { + m.oldValue = func(context.Context) (*ApiKey, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m ApiKeyMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m ApiKeyMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *ApiKeyMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *ApiKeyMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().ApiKey.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetCreatedAt sets the "created_at" field. +func (m *ApiKeyMutation) SetCreatedAt(t time.Time) { + m.created_at = &t +} + +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *ApiKeyMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at + if v == nil { + return + } + return *v, true +} + +// OldCreatedAt returns the old "created_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) OldCreatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldCreatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) + } + return oldValue.CreatedAt, nil +} + +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *ApiKeyMutation) ResetCreatedAt() { + m.created_at = nil +} + +// SetUpdatedAt sets the "updated_at" field. +func (m *ApiKeyMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *ApiKeyMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_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) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *ApiKeyMutation) ResetUpdatedAt() { + m.updated_at = nil +} + +// SetDeletedAt sets the "deleted_at" field. +func (m *ApiKeyMutation) SetDeletedAt(t time.Time) { + m.deleted_at = &t +} + +// DeletedAt returns the value of the "deleted_at" field in the mutation. +func (m *ApiKeyMutation) DeletedAt() (r time.Time, exists bool) { + v := m.deleted_at + if v == nil { + return + } + return *v, true +} + +// OldDeletedAt returns the old "deleted_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) OldDeletedAt(ctx context.Context) (v *time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDeletedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDeletedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDeletedAt: %w", err) + } + return oldValue.DeletedAt, nil +} + +// ClearDeletedAt clears the value of the "deleted_at" field. +func (m *ApiKeyMutation) ClearDeletedAt() { + m.deleted_at = nil + m.clearedFields[apikey.FieldDeletedAt] = struct{}{} +} + +// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation. +func (m *ApiKeyMutation) DeletedAtCleared() bool { + _, ok := m.clearedFields[apikey.FieldDeletedAt] + return ok +} + +// ResetDeletedAt resets all changes to the "deleted_at" field. +func (m *ApiKeyMutation) ResetDeletedAt() { + m.deleted_at = nil + delete(m.clearedFields, apikey.FieldDeletedAt) +} + +// SetUserID sets the "user_id" field. +func (m *ApiKeyMutation) SetUserID(i int64) { + m.user = &i +} + +// UserID returns the value of the "user_id" field in the mutation. +func (m *ApiKeyMutation) UserID() (r int64, exists bool) { + v := m.user + if v == nil { + return + } + return *v, true +} + +// OldUserID returns the old "user_id" 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) OldUserID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUserID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUserID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserID: %w", err) + } + return oldValue.UserID, nil +} + +// ResetUserID resets all changes to the "user_id" field. +func (m *ApiKeyMutation) ResetUserID() { + m.user = nil +} + +// SetKey sets the "key" field. +func (m *ApiKeyMutation) SetKey(s string) { + m.key = &s +} + +// Key returns the value of the "key" field in the mutation. +func (m *ApiKeyMutation) Key() (r string, exists bool) { + v := m.key + if v == nil { + return + } + return *v, true +} + +// OldKey returns the old "key" 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) OldKey(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldKey is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldKey requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldKey: %w", err) + } + return oldValue.Key, nil +} + +// ResetKey resets all changes to the "key" field. +func (m *ApiKeyMutation) ResetKey() { + m.key = nil +} + +// SetName sets the "name" field. +func (m *ApiKeyMutation) SetName(s string) { + m.name = &s +} + +// Name returns the value of the "name" field in the mutation. +func (m *ApiKeyMutation) Name() (r string, exists bool) { + v := m.name + if v == nil { + return + } + return *v, true +} + +// OldName returns the old "name" 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) OldName(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldName is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldName requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldName: %w", err) + } + return oldValue.Name, nil +} + +// ResetName resets all changes to the "name" field. +func (m *ApiKeyMutation) ResetName() { + m.name = nil +} + +// SetGroupID sets the "group_id" field. +func (m *ApiKeyMutation) SetGroupID(i int64) { + m.group = &i +} + +// GroupID returns the value of the "group_id" field in the mutation. +func (m *ApiKeyMutation) GroupID() (r int64, exists bool) { + v := m.group + if v == nil { + return + } + return *v, true +} + +// OldGroupID returns the old "group_id" 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) OldGroupID(ctx context.Context) (v *int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldGroupID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldGroupID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldGroupID: %w", err) + } + return oldValue.GroupID, nil +} + +// ClearGroupID clears the value of the "group_id" field. +func (m *ApiKeyMutation) ClearGroupID() { + m.group = nil + m.clearedFields[apikey.FieldGroupID] = struct{}{} +} + +// GroupIDCleared returns if the "group_id" field was cleared in this mutation. +func (m *ApiKeyMutation) GroupIDCleared() bool { + _, ok := m.clearedFields[apikey.FieldGroupID] + return ok +} + +// ResetGroupID resets all changes to the "group_id" field. +func (m *ApiKeyMutation) ResetGroupID() { + m.group = nil + delete(m.clearedFields, apikey.FieldGroupID) +} + +// SetStatus sets the "status" field. +func (m *ApiKeyMutation) SetStatus(s string) { + m.status = &s +} + +// Status returns the value of the "status" field in the mutation. +func (m *ApiKeyMutation) Status() (r string, exists bool) { + v := m.status + if v == nil { + return + } + return *v, true +} + +// OldStatus returns the old "status" 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) OldStatus(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldStatus is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldStatus requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldStatus: %w", err) + } + return oldValue.Status, nil +} + +// ResetStatus resets all changes to the "status" field. +func (m *ApiKeyMutation) ResetStatus() { + m.status = nil +} + +// ClearUser clears the "user" edge to the User entity. +func (m *ApiKeyMutation) ClearUser() { + m.cleareduser = true + m.clearedFields[apikey.FieldUserID] = struct{}{} +} + +// UserCleared reports if the "user" edge to the User entity was cleared. +func (m *ApiKeyMutation) UserCleared() bool { + return m.cleareduser +} + +// UserIDs returns the "user" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// UserID instead. It exists only for internal usage by the builders. +func (m *ApiKeyMutation) UserIDs() (ids []int64) { + if id := m.user; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetUser resets all changes to the "user" edge. +func (m *ApiKeyMutation) ResetUser() { + m.user = nil + m.cleareduser = false +} + +// ClearGroup clears the "group" edge to the Group entity. +func (m *ApiKeyMutation) ClearGroup() { + m.clearedgroup = true + m.clearedFields[apikey.FieldGroupID] = struct{}{} +} + +// GroupCleared reports if the "group" edge to the Group entity was cleared. +func (m *ApiKeyMutation) GroupCleared() bool { + return m.GroupIDCleared() || m.clearedgroup +} + +// GroupIDs returns the "group" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// GroupID instead. It exists only for internal usage by the builders. +func (m *ApiKeyMutation) GroupIDs() (ids []int64) { + if id := m.group; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetGroup resets all changes to the "group" edge. +func (m *ApiKeyMutation) ResetGroup() { + m.group = nil + m.clearedgroup = false +} + +// AddUsageLogIDs adds the "usage_logs" edge to the UsageLog entity by ids. +func (m *ApiKeyMutation) AddUsageLogIDs(ids ...int64) { + if m.usage_logs == nil { + m.usage_logs = make(map[int64]struct{}) + } + for i := range ids { + m.usage_logs[ids[i]] = struct{}{} + } +} + +// ClearUsageLogs clears the "usage_logs" edge to the UsageLog entity. +func (m *ApiKeyMutation) ClearUsageLogs() { + m.clearedusage_logs = true +} + +// UsageLogsCleared reports if the "usage_logs" edge to the UsageLog entity was cleared. +func (m *ApiKeyMutation) UsageLogsCleared() bool { + return m.clearedusage_logs +} + +// RemoveUsageLogIDs removes the "usage_logs" edge to the UsageLog entity by IDs. +func (m *ApiKeyMutation) RemoveUsageLogIDs(ids ...int64) { + if m.removedusage_logs == nil { + m.removedusage_logs = make(map[int64]struct{}) + } + for i := range ids { + delete(m.usage_logs, ids[i]) + m.removedusage_logs[ids[i]] = struct{}{} + } +} + +// RemovedUsageLogs returns the removed IDs of the "usage_logs" edge to the UsageLog entity. +func (m *ApiKeyMutation) RemovedUsageLogsIDs() (ids []int64) { + for id := range m.removedusage_logs { + ids = append(ids, id) + } + return +} + +// UsageLogsIDs returns the "usage_logs" edge IDs in the mutation. +func (m *ApiKeyMutation) UsageLogsIDs() (ids []int64) { + for id := range m.usage_logs { + ids = append(ids, id) + } + return +} + +// ResetUsageLogs resets all changes to the "usage_logs" edge. +func (m *ApiKeyMutation) ResetUsageLogs() { + m.usage_logs = nil + m.clearedusage_logs = false + m.removedusage_logs = nil +} + +// Where appends a list predicates to the ApiKeyMutation builder. +func (m *ApiKeyMutation) Where(ps ...predicate.ApiKey) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the ApiKeyMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *ApiKeyMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.ApiKey, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *ApiKeyMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *ApiKeyMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (ApiKey). +func (m *ApiKeyMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *ApiKeyMutation) Fields() []string { + fields := make([]string, 0, 8) + if m.created_at != nil { + fields = append(fields, apikey.FieldCreatedAt) + } + if m.updated_at != nil { + fields = append(fields, apikey.FieldUpdatedAt) + } + if m.deleted_at != nil { + fields = append(fields, apikey.FieldDeletedAt) + } + if m.user != nil { + fields = append(fields, apikey.FieldUserID) + } + if m.key != nil { + fields = append(fields, apikey.FieldKey) + } + if m.name != nil { + fields = append(fields, apikey.FieldName) + } + if m.group != nil { + fields = append(fields, apikey.FieldGroupID) + } + if m.status != nil { + fields = append(fields, apikey.FieldStatus) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *ApiKeyMutation) Field(name string) (ent.Value, bool) { + switch name { + case apikey.FieldCreatedAt: + return m.CreatedAt() + case apikey.FieldUpdatedAt: + return m.UpdatedAt() + case apikey.FieldDeletedAt: + return m.DeletedAt() + case apikey.FieldUserID: + return m.UserID() + case apikey.FieldKey: + return m.Key() + case apikey.FieldName: + return m.Name() + case apikey.FieldGroupID: + return m.GroupID() + case apikey.FieldStatus: + return m.Status() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *ApiKeyMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case apikey.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case apikey.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + case apikey.FieldDeletedAt: + return m.OldDeletedAt(ctx) + case apikey.FieldUserID: + return m.OldUserID(ctx) + case apikey.FieldKey: + return m.OldKey(ctx) + case apikey.FieldName: + return m.OldName(ctx) + case apikey.FieldGroupID: + return m.OldGroupID(ctx) + case apikey.FieldStatus: + return m.OldStatus(ctx) + } + return nil, fmt.Errorf("unknown ApiKey field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *ApiKeyMutation) SetField(name string, value ent.Value) error { + switch name { + case apikey.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case apikey.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + case apikey.FieldDeletedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDeletedAt(v) + return nil + case apikey.FieldUserID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserID(v) + return nil + case apikey.FieldKey: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetKey(v) + return nil + case apikey.FieldName: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetName(v) + return nil + case apikey.FieldGroupID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetGroupID(v) + return nil + case apikey.FieldStatus: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetStatus(v) + return nil + } + return fmt.Errorf("unknown ApiKey field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *ApiKeyMutation) AddedFields() []string { + var fields []string + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *ApiKeyMutation) AddedField(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *ApiKeyMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown ApiKey numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *ApiKeyMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(apikey.FieldDeletedAt) { + fields = append(fields, apikey.FieldDeletedAt) + } + if m.FieldCleared(apikey.FieldGroupID) { + fields = append(fields, apikey.FieldGroupID) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *ApiKeyMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *ApiKeyMutation) ClearField(name string) error { + switch name { + case apikey.FieldDeletedAt: + m.ClearDeletedAt() + return nil + case apikey.FieldGroupID: + m.ClearGroupID() + return nil + } + return fmt.Errorf("unknown ApiKey nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *ApiKeyMutation) ResetField(name string) error { + switch name { + case apikey.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case apikey.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + case apikey.FieldDeletedAt: + m.ResetDeletedAt() + return nil + case apikey.FieldUserID: + m.ResetUserID() + return nil + case apikey.FieldKey: + m.ResetKey() + return nil + case apikey.FieldName: + m.ResetName() + return nil + case apikey.FieldGroupID: + m.ResetGroupID() + return nil + case apikey.FieldStatus: + m.ResetStatus() + return nil + } + return fmt.Errorf("unknown ApiKey field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *ApiKeyMutation) AddedEdges() []string { + edges := make([]string, 0, 3) + if m.user != nil { + edges = append(edges, apikey.EdgeUser) + } + if m.group != nil { + edges = append(edges, apikey.EdgeGroup) + } + if m.usage_logs != nil { + edges = append(edges, apikey.EdgeUsageLogs) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *ApiKeyMutation) AddedIDs(name string) []ent.Value { + switch name { + case apikey.EdgeUser: + if id := m.user; id != nil { + return []ent.Value{*id} + } + case apikey.EdgeGroup: + if id := m.group; id != nil { + return []ent.Value{*id} + } + case apikey.EdgeUsageLogs: + ids := make([]ent.Value, 0, len(m.usage_logs)) + for id := range m.usage_logs { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *ApiKeyMutation) RemovedEdges() []string { + edges := make([]string, 0, 3) + if m.removedusage_logs != nil { + edges = append(edges, apikey.EdgeUsageLogs) + } + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *ApiKeyMutation) RemovedIDs(name string) []ent.Value { + switch name { + case apikey.EdgeUsageLogs: + ids := make([]ent.Value, 0, len(m.removedusage_logs)) + for id := range m.removedusage_logs { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *ApiKeyMutation) ClearedEdges() []string { + edges := make([]string, 0, 3) + if m.cleareduser { + edges = append(edges, apikey.EdgeUser) + } + if m.clearedgroup { + edges = append(edges, apikey.EdgeGroup) + } + if m.clearedusage_logs { + edges = append(edges, apikey.EdgeUsageLogs) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *ApiKeyMutation) EdgeCleared(name string) bool { + switch name { + case apikey.EdgeUser: + return m.cleareduser + case apikey.EdgeGroup: + return m.clearedgroup + case apikey.EdgeUsageLogs: + return m.clearedusage_logs + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *ApiKeyMutation) ClearEdge(name string) error { + switch name { + case apikey.EdgeUser: + m.ClearUser() + return nil + case apikey.EdgeGroup: + m.ClearGroup() + return nil + } + return fmt.Errorf("unknown ApiKey unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *ApiKeyMutation) ResetEdge(name string) error { + switch name { + case apikey.EdgeUser: + m.ResetUser() + return nil + case apikey.EdgeGroup: + m.ResetGroup() + return nil + case apikey.EdgeUsageLogs: + m.ResetUsageLogs() + return nil + } + return fmt.Errorf("unknown ApiKey edge %s", name) +} + // GroupMutation represents an operation that mutates the Group nodes in the graph. type GroupMutation struct { config @@ -4178,7 +4178,7 @@ func (m *GroupMutation) ResetDefaultValidityDays() { m.adddefault_validity_days = nil } -// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by ids. +// AddAPIKeyIDs adds the "api_keys" edge to the ApiKey entity by ids. func (m *GroupMutation) AddAPIKeyIDs(ids ...int64) { if m.api_keys == nil { m.api_keys = make(map[int64]struct{}) @@ -4188,17 +4188,17 @@ func (m *GroupMutation) AddAPIKeyIDs(ids ...int64) { } } -// ClearAPIKeys clears the "api_keys" edge to the APIKey entity. +// ClearAPIKeys clears the "api_keys" edge to the ApiKey entity. func (m *GroupMutation) ClearAPIKeys() { m.clearedapi_keys = true } -// APIKeysCleared reports if the "api_keys" edge to the APIKey entity was cleared. +// APIKeysCleared reports if the "api_keys" edge to the ApiKey entity was cleared. func (m *GroupMutation) APIKeysCleared() bool { return m.clearedapi_keys } -// RemoveAPIKeyIDs removes the "api_keys" edge to the APIKey entity by IDs. +// RemoveAPIKeyIDs removes the "api_keys" edge to the ApiKey entity by IDs. func (m *GroupMutation) RemoveAPIKeyIDs(ids ...int64) { if m.removedapi_keys == nil { m.removedapi_keys = make(map[int64]struct{}) @@ -4209,7 +4209,7 @@ func (m *GroupMutation) RemoveAPIKeyIDs(ids ...int64) { } } -// RemovedAPIKeys returns the removed IDs of the "api_keys" edge to the APIKey entity. +// RemovedAPIKeys returns the removed IDs of the "api_keys" edge to the ApiKey entity. func (m *GroupMutation) RemovedAPIKeysIDs() (ids []int64) { for id := range m.removedapi_keys { ids = append(ids, id) @@ -9129,13 +9129,13 @@ func (m *UsageLogMutation) ResetUser() { m.cleareduser = false } -// ClearAPIKey clears the "api_key" edge to the APIKey entity. +// ClearAPIKey clears the "api_key" edge to the ApiKey entity. func (m *UsageLogMutation) ClearAPIKey() { m.clearedapi_key = true m.clearedFields[usagelog.FieldAPIKeyID] = struct{}{} } -// APIKeyCleared reports if the "api_key" edge to the APIKey entity was cleared. +// APIKeyCleared reports if the "api_key" edge to the ApiKey entity was cleared. func (m *UsageLogMutation) APIKeyCleared() bool { return m.clearedapi_key } @@ -10737,7 +10737,7 @@ func (m *UserMutation) ResetNotes() { m.notes = nil } -// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by ids. +// AddAPIKeyIDs adds the "api_keys" edge to the ApiKey entity by ids. func (m *UserMutation) AddAPIKeyIDs(ids ...int64) { if m.api_keys == nil { m.api_keys = make(map[int64]struct{}) @@ -10747,17 +10747,17 @@ func (m *UserMutation) AddAPIKeyIDs(ids ...int64) { } } -// ClearAPIKeys clears the "api_keys" edge to the APIKey entity. +// ClearAPIKeys clears the "api_keys" edge to the ApiKey entity. func (m *UserMutation) ClearAPIKeys() { m.clearedapi_keys = true } -// APIKeysCleared reports if the "api_keys" edge to the APIKey entity was cleared. +// APIKeysCleared reports if the "api_keys" edge to the ApiKey entity was cleared. func (m *UserMutation) APIKeysCleared() bool { return m.clearedapi_keys } -// RemoveAPIKeyIDs removes the "api_keys" edge to the APIKey entity by IDs. +// RemoveAPIKeyIDs removes the "api_keys" edge to the ApiKey entity by IDs. func (m *UserMutation) RemoveAPIKeyIDs(ids ...int64) { if m.removedapi_keys == nil { m.removedapi_keys = make(map[int64]struct{}) @@ -10768,7 +10768,7 @@ func (m *UserMutation) RemoveAPIKeyIDs(ids ...int64) { } } -// RemovedAPIKeys returns the removed IDs of the "api_keys" edge to the APIKey entity. +// RemovedAPIKeys returns the removed IDs of the "api_keys" edge to the ApiKey entity. func (m *UserMutation) RemovedAPIKeysIDs() (ids []int64) { for id := range m.removedapi_keys { ids = append(ids, id) diff --git a/backend/ent/predicate/predicate.go b/backend/ent/predicate/predicate.go index 87c56902..ae1bf007 100644 --- a/backend/ent/predicate/predicate.go +++ b/backend/ent/predicate/predicate.go @@ -6,15 +6,15 @@ import ( "entgo.io/ent/dialect/sql" ) -// APIKey is the predicate function for apikey builders. -type APIKey func(*sql.Selector) - // Account is the predicate function for account builders. type Account func(*sql.Selector) // AccountGroup is the predicate function for accountgroup builders. type AccountGroup func(*sql.Selector) +// ApiKey is the predicate function for apikey builders. +type ApiKey func(*sql.Selector) + // Group is the predicate function for group builders. type Group func(*sql.Selector) diff --git a/backend/ent/runtime/runtime.go b/backend/ent/runtime/runtime.go index 517e7195..12c3e7e3 100644 --- a/backend/ent/runtime/runtime.go +++ b/backend/ent/runtime/runtime.go @@ -25,67 +25,6 @@ import ( // (default values, validators, hooks and policies) and stitches it // to their package variables. func init() { - apikeyMixin := schema.APIKey{}.Mixin() - apikeyMixinHooks1 := apikeyMixin[1].Hooks() - apikey.Hooks[0] = apikeyMixinHooks1[0] - apikeyMixinInters1 := apikeyMixin[1].Interceptors() - apikey.Interceptors[0] = apikeyMixinInters1[0] - apikeyMixinFields0 := apikeyMixin[0].Fields() - _ = apikeyMixinFields0 - apikeyFields := schema.APIKey{}.Fields() - _ = apikeyFields - // apikeyDescCreatedAt is the schema descriptor for created_at field. - apikeyDescCreatedAt := apikeyMixinFields0[0].Descriptor() - // apikey.DefaultCreatedAt holds the default value on creation for the created_at field. - apikey.DefaultCreatedAt = apikeyDescCreatedAt.Default.(func() time.Time) - // apikeyDescUpdatedAt is the schema descriptor for updated_at field. - apikeyDescUpdatedAt := apikeyMixinFields0[1].Descriptor() - // apikey.DefaultUpdatedAt holds the default value on creation for the updated_at field. - apikey.DefaultUpdatedAt = apikeyDescUpdatedAt.Default.(func() time.Time) - // apikey.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. - apikey.UpdateDefaultUpdatedAt = apikeyDescUpdatedAt.UpdateDefault.(func() time.Time) - // apikeyDescKey is the schema descriptor for key field. - apikeyDescKey := apikeyFields[1].Descriptor() - // apikey.KeyValidator is a validator for the "key" field. It is called by the builders before save. - apikey.KeyValidator = func() func(string) error { - validators := apikeyDescKey.Validators - fns := [...]func(string) error{ - validators[0].(func(string) error), - validators[1].(func(string) error), - } - return func(key string) error { - for _, fn := range fns { - if err := fn(key); err != nil { - return err - } - } - return nil - } - }() - // apikeyDescName is the schema descriptor for name field. - apikeyDescName := apikeyFields[2].Descriptor() - // apikey.NameValidator is a validator for the "name" field. It is called by the builders before save. - apikey.NameValidator = func() func(string) error { - validators := apikeyDescName.Validators - fns := [...]func(string) error{ - validators[0].(func(string) error), - validators[1].(func(string) error), - } - return func(name string) error { - for _, fn := range fns { - if err := fn(name); err != nil { - return err - } - } - return nil - } - }() - // apikeyDescStatus is the schema descriptor for status field. - apikeyDescStatus := apikeyFields[4].Descriptor() - // apikey.DefaultStatus holds the default value on creation for the status field. - apikey.DefaultStatus = apikeyDescStatus.Default.(string) - // 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) accountMixin := schema.Account{}.Mixin() accountMixinHooks1 := accountMixin[1].Hooks() account.Hooks[0] = accountMixinHooks1[0] @@ -199,6 +138,67 @@ func init() { accountgroupDescCreatedAt := accountgroupFields[3].Descriptor() // accountgroup.DefaultCreatedAt holds the default value on creation for the created_at field. accountgroup.DefaultCreatedAt = accountgroupDescCreatedAt.Default.(func() time.Time) + apikeyMixin := schema.ApiKey{}.Mixin() + apikeyMixinHooks1 := apikeyMixin[1].Hooks() + apikey.Hooks[0] = apikeyMixinHooks1[0] + apikeyMixinInters1 := apikeyMixin[1].Interceptors() + apikey.Interceptors[0] = apikeyMixinInters1[0] + apikeyMixinFields0 := apikeyMixin[0].Fields() + _ = apikeyMixinFields0 + apikeyFields := schema.ApiKey{}.Fields() + _ = apikeyFields + // apikeyDescCreatedAt is the schema descriptor for created_at field. + apikeyDescCreatedAt := apikeyMixinFields0[0].Descriptor() + // apikey.DefaultCreatedAt holds the default value on creation for the created_at field. + apikey.DefaultCreatedAt = apikeyDescCreatedAt.Default.(func() time.Time) + // apikeyDescUpdatedAt is the schema descriptor for updated_at field. + apikeyDescUpdatedAt := apikeyMixinFields0[1].Descriptor() + // apikey.DefaultUpdatedAt holds the default value on creation for the updated_at field. + apikey.DefaultUpdatedAt = apikeyDescUpdatedAt.Default.(func() time.Time) + // apikey.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. + apikey.UpdateDefaultUpdatedAt = apikeyDescUpdatedAt.UpdateDefault.(func() time.Time) + // apikeyDescKey is the schema descriptor for key field. + apikeyDescKey := apikeyFields[1].Descriptor() + // apikey.KeyValidator is a validator for the "key" field. It is called by the builders before save. + apikey.KeyValidator = func() func(string) error { + validators := apikeyDescKey.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + } + return func(key string) error { + for _, fn := range fns { + if err := fn(key); err != nil { + return err + } + } + return nil + } + }() + // apikeyDescName is the schema descriptor for name field. + apikeyDescName := apikeyFields[2].Descriptor() + // apikey.NameValidator is a validator for the "name" field. It is called by the builders before save. + apikey.NameValidator = func() func(string) error { + validators := apikeyDescName.Validators + fns := [...]func(string) error{ + validators[0].(func(string) error), + validators[1].(func(string) error), + } + return func(name string) error { + for _, fn := range fns { + if err := fn(name); err != nil { + return err + } + } + return nil + } + }() + // apikeyDescStatus is the schema descriptor for status field. + apikeyDescStatus := apikeyFields[4].Descriptor() + // apikey.DefaultStatus holds the default value on creation for the status field. + apikey.DefaultStatus = apikeyDescStatus.Default.(string) + // 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) groupMixin := schema.Group{}.Mixin() groupMixinHooks1 := groupMixin[1].Hooks() group.Hooks[0] = groupMixinHooks1[0] diff --git a/backend/ent/schema/api_key.go b/backend/ent/schema/api_key.go index 94e572c5..f9ece05e 100644 --- a/backend/ent/schema/api_key.go +++ b/backend/ent/schema/api_key.go @@ -12,25 +12,25 @@ import ( "entgo.io/ent/schema/index" ) -// APIKey holds the schema definition for the APIKey entity. -type APIKey struct { +// ApiKey holds the schema definition for the ApiKey entity. +type ApiKey struct { ent.Schema } -func (APIKey) Annotations() []schema.Annotation { +func (ApiKey) Annotations() []schema.Annotation { return []schema.Annotation{ entsql.Annotation{Table: "api_keys"}, } } -func (APIKey) Mixin() []ent.Mixin { +func (ApiKey) Mixin() []ent.Mixin { return []ent.Mixin{ mixins.TimeMixin{}, mixins.SoftDeleteMixin{}, } } -func (APIKey) Fields() []ent.Field { +func (ApiKey) Fields() []ent.Field { return []ent.Field{ field.Int64("user_id"), field.String("key"). @@ -49,7 +49,7 @@ func (APIKey) Fields() []ent.Field { } } -func (APIKey) Edges() []ent.Edge { +func (ApiKey) Edges() []ent.Edge { return []ent.Edge{ edge.From("user", User.Type). Ref("api_keys"). @@ -64,7 +64,7 @@ func (APIKey) Edges() []ent.Edge { } } -func (APIKey) Indexes() []ent.Index { +func (ApiKey) Indexes() []ent.Index { return []ent.Index{ // key 字段已在 Fields() 中声明 Unique(),无需重复索引 index.Fields("user_id"), diff --git a/backend/ent/schema/group.go b/backend/ent/schema/group.go index 93dab1ab..7a8a5345 100644 --- a/backend/ent/schema/group.go +++ b/backend/ent/schema/group.go @@ -77,7 +77,7 @@ func (Group) Fields() []ent.Field { func (Group) Edges() []ent.Edge { return []ent.Edge{ - edge.To("api_keys", APIKey.Type), + edge.To("api_keys", ApiKey.Type), edge.To("redeem_codes", RedeemCode.Type), edge.To("subscriptions", UserSubscription.Type), edge.To("usage_logs", UsageLog.Type), diff --git a/backend/ent/schema/usage_log.go b/backend/ent/schema/usage_log.go index 81effa46..6f78e8a9 100644 --- a/backend/ent/schema/usage_log.go +++ b/backend/ent/schema/usage_log.go @@ -113,7 +113,7 @@ func (UsageLog) Edges() []ent.Edge { Field("user_id"). Required(). Unique(), - edge.From("api_key", APIKey.Type). + edge.From("api_key", ApiKey.Type). Ref("usage_logs"). Field("api_key_id"). Required(). diff --git a/backend/ent/schema/user.go b/backend/ent/schema/user.go index 11fecdfd..f29b6123 100644 --- a/backend/ent/schema/user.go +++ b/backend/ent/schema/user.go @@ -66,7 +66,7 @@ func (User) Fields() []ent.Field { func (User) Edges() []ent.Edge { return []ent.Edge{ - edge.To("api_keys", APIKey.Type), + edge.To("api_keys", ApiKey.Type), edge.To("redeem_codes", RedeemCode.Type), edge.To("subscriptions", UserSubscription.Type), edge.To("assigned_subscriptions", UserSubscription.Type), diff --git a/backend/ent/tx.go b/backend/ent/tx.go index e45204c0..b1bbdfc5 100644 --- a/backend/ent/tx.go +++ b/backend/ent/tx.go @@ -14,12 +14,12 @@ import ( // Tx is a transactional client that is created by calling Client.Tx(). type Tx struct { config - // APIKey is the client for interacting with the APIKey builders. - APIKey *APIKeyClient // Account is the client for interacting with the Account builders. Account *AccountClient // AccountGroup is the client for interacting with the AccountGroup builders. AccountGroup *AccountGroupClient + // ApiKey is the client for interacting with the ApiKey builders. + ApiKey *ApiKeyClient // Group is the client for interacting with the Group builders. Group *GroupClient // Proxy is the client for interacting with the Proxy builders. @@ -171,9 +171,9 @@ func (tx *Tx) Client() *Client { } func (tx *Tx) init() { - tx.APIKey = NewAPIKeyClient(tx.config) tx.Account = NewAccountClient(tx.config) tx.AccountGroup = NewAccountGroupClient(tx.config) + tx.ApiKey = NewApiKeyClient(tx.config) tx.Group = NewGroupClient(tx.config) tx.Proxy = NewProxyClient(tx.config) tx.RedeemCode = NewRedeemCodeClient(tx.config) @@ -193,7 +193,7 @@ func (tx *Tx) init() { // of them in order to commit or rollback the transaction. // // If a closed transaction is embedded in one of the generated entities, and the entity -// applies a query, for example: APIKey.QueryXXX(), the query will be executed +// applies a query, for example: Account.QueryXXX(), the query will be executed // through the driver which created this transaction. // // Note that txDriver is not goroutine safe. diff --git a/backend/ent/usagelog.go b/backend/ent/usagelog.go index 75e3173d..e01780fe 100644 --- a/backend/ent/usagelog.go +++ b/backend/ent/usagelog.go @@ -83,7 +83,7 @@ type UsageLogEdges struct { // User holds the value of the user edge. User *User `json:"user,omitempty"` // APIKey holds the value of the api_key edge. - APIKey *APIKey `json:"api_key,omitempty"` + APIKey *ApiKey `json:"api_key,omitempty"` // Account holds the value of the account edge. Account *Account `json:"account,omitempty"` // Group holds the value of the group edge. @@ -108,7 +108,7 @@ func (e UsageLogEdges) UserOrErr() (*User, error) { // APIKeyOrErr returns the APIKey value or an error if the edge // was not loaded in eager-loading, or loaded but was not found. -func (e UsageLogEdges) APIKeyOrErr() (*APIKey, error) { +func (e UsageLogEdges) APIKeyOrErr() (*ApiKey, error) { if e.APIKey != nil { return e.APIKey, nil } else if e.loadedTypes[1] { @@ -359,7 +359,7 @@ func (_m *UsageLog) QueryUser() *UserQuery { } // QueryAPIKey queries the "api_key" edge of the UsageLog entity. -func (_m *UsageLog) QueryAPIKey() *APIKeyQuery { +func (_m *UsageLog) QueryAPIKey() *ApiKeyQuery { return NewUsageLogClient(_m.config).QueryAPIKey(_m) } diff --git a/backend/ent/usagelog/usagelog.go b/backend/ent/usagelog/usagelog.go index 139721c4..bdc6f7e6 100644 --- a/backend/ent/usagelog/usagelog.go +++ b/backend/ent/usagelog/usagelog.go @@ -85,7 +85,7 @@ const ( UserColumn = "user_id" // APIKeyTable is the table that holds the api_key relation/edge. APIKeyTable = "usage_logs" - // APIKeyInverseTable is the table name for the APIKey entity. + // APIKeyInverseTable is the table name for the ApiKey entity. // It exists in this package in order to avoid circular dependency with the "apikey" package. APIKeyInverseTable = "api_keys" // APIKeyColumn is the table column denoting the api_key relation/edge. diff --git a/backend/ent/usagelog/where.go b/backend/ent/usagelog/where.go index 9db01140..9c260433 100644 --- a/backend/ent/usagelog/where.go +++ b/backend/ent/usagelog/where.go @@ -1175,7 +1175,7 @@ func HasAPIKey() predicate.UsageLog { } // HasAPIKeyWith applies the HasEdge predicate on the "api_key" edge with a given conditions (other predicates). -func HasAPIKeyWith(preds ...predicate.APIKey) predicate.UsageLog { +func HasAPIKeyWith(preds ...predicate.ApiKey) predicate.UsageLog { return predicate.UsageLog(func(s *sql.Selector) { step := newAPIKeyStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { diff --git a/backend/ent/usagelog_create.go b/backend/ent/usagelog_create.go index 36f3d277..bcba64b1 100644 --- a/backend/ent/usagelog_create.go +++ b/backend/ent/usagelog_create.go @@ -342,8 +342,8 @@ func (_c *UsageLogCreate) SetUser(v *User) *UsageLogCreate { return _c.SetUserID(v.ID) } -// SetAPIKey sets the "api_key" edge to the APIKey entity. -func (_c *UsageLogCreate) SetAPIKey(v *APIKey) *UsageLogCreate { +// SetAPIKey sets the "api_key" edge to the ApiKey entity. +func (_c *UsageLogCreate) SetAPIKey(v *ApiKey) *UsageLogCreate { return _c.SetAPIKeyID(v.ID) } diff --git a/backend/ent/usagelog_query.go b/backend/ent/usagelog_query.go index de64171a..8e5013cc 100644 --- a/backend/ent/usagelog_query.go +++ b/backend/ent/usagelog_query.go @@ -28,7 +28,7 @@ type UsageLogQuery struct { inters []Interceptor predicates []predicate.UsageLog withUser *UserQuery - withAPIKey *APIKeyQuery + withAPIKey *ApiKeyQuery withAccount *AccountQuery withGroup *GroupQuery withSubscription *UserSubscriptionQuery @@ -91,8 +91,8 @@ func (_q *UsageLogQuery) QueryUser() *UserQuery { } // QueryAPIKey chains the current query on the "api_key" edge. -func (_q *UsageLogQuery) QueryAPIKey() *APIKeyQuery { - query := (&APIKeyClient{config: _q.config}).Query() +func (_q *UsageLogQuery) QueryAPIKey() *ApiKeyQuery { + query := (&ApiKeyClient{config: _q.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := _q.prepareQuery(ctx); err != nil { return nil, err @@ -394,8 +394,8 @@ func (_q *UsageLogQuery) WithUser(opts ...func(*UserQuery)) *UsageLogQuery { // WithAPIKey tells the query-builder to eager-load the nodes that are connected to // the "api_key" edge. The optional arguments are used to configure the query builder of the edge. -func (_q *UsageLogQuery) WithAPIKey(opts ...func(*APIKeyQuery)) *UsageLogQuery { - query := (&APIKeyClient{config: _q.config}).Query() +func (_q *UsageLogQuery) WithAPIKey(opts ...func(*ApiKeyQuery)) *UsageLogQuery { + query := (&ApiKeyClient{config: _q.config}).Query() for _, opt := range opts { opt(query) } @@ -548,7 +548,7 @@ func (_q *UsageLogQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Usa } if query := _q.withAPIKey; query != nil { if err := _q.loadAPIKey(ctx, query, nodes, nil, - func(n *UsageLog, e *APIKey) { n.Edges.APIKey = e }); err != nil { + func(n *UsageLog, e *ApiKey) { n.Edges.APIKey = e }); err != nil { return nil, err } } @@ -602,7 +602,7 @@ func (_q *UsageLogQuery) loadUser(ctx context.Context, query *UserQuery, nodes [ } return nil } -func (_q *UsageLogQuery) loadAPIKey(ctx context.Context, query *APIKeyQuery, nodes []*UsageLog, init func(*UsageLog), assign func(*UsageLog, *APIKey)) error { +func (_q *UsageLogQuery) loadAPIKey(ctx context.Context, query *ApiKeyQuery, nodes []*UsageLog, init func(*UsageLog), assign func(*UsageLog, *ApiKey)) error { ids := make([]int64, 0, len(nodes)) nodeids := make(map[int64][]*UsageLog) for i := range nodes { diff --git a/backend/ent/usagelog_update.go b/backend/ent/usagelog_update.go index 45ad2e2a..55b8e234 100644 --- a/backend/ent/usagelog_update.go +++ b/backend/ent/usagelog_update.go @@ -509,8 +509,8 @@ func (_u *UsageLogUpdate) SetUser(v *User) *UsageLogUpdate { return _u.SetUserID(v.ID) } -// SetAPIKey sets the "api_key" edge to the APIKey entity. -func (_u *UsageLogUpdate) SetAPIKey(v *APIKey) *UsageLogUpdate { +// SetAPIKey sets the "api_key" edge to the ApiKey entity. +func (_u *UsageLogUpdate) SetAPIKey(v *ApiKey) *UsageLogUpdate { return _u.SetAPIKeyID(v.ID) } @@ -540,7 +540,7 @@ func (_u *UsageLogUpdate) ClearUser() *UsageLogUpdate { return _u } -// ClearAPIKey clears the "api_key" edge to the APIKey entity. +// ClearAPIKey clears the "api_key" edge to the ApiKey entity. func (_u *UsageLogUpdate) ClearAPIKey() *UsageLogUpdate { _u.mutation.ClearAPIKey() return _u @@ -1380,8 +1380,8 @@ func (_u *UsageLogUpdateOne) SetUser(v *User) *UsageLogUpdateOne { return _u.SetUserID(v.ID) } -// SetAPIKey sets the "api_key" edge to the APIKey entity. -func (_u *UsageLogUpdateOne) SetAPIKey(v *APIKey) *UsageLogUpdateOne { +// SetAPIKey sets the "api_key" edge to the ApiKey entity. +func (_u *UsageLogUpdateOne) SetAPIKey(v *ApiKey) *UsageLogUpdateOne { return _u.SetAPIKeyID(v.ID) } @@ -1411,7 +1411,7 @@ func (_u *UsageLogUpdateOne) ClearUser() *UsageLogUpdateOne { return _u } -// ClearAPIKey clears the "api_key" edge to the APIKey entity. +// ClearAPIKey clears the "api_key" edge to the ApiKey entity. func (_u *UsageLogUpdateOne) ClearAPIKey() *UsageLogUpdateOne { _u.mutation.ClearAPIKey() return _u diff --git a/backend/ent/user.go b/backend/ent/user.go index 20036475..d7e1668d 100644 --- a/backend/ent/user.go +++ b/backend/ent/user.go @@ -48,7 +48,7 @@ type User struct { // UserEdges holds the relations/edges for other nodes in the graph. type UserEdges struct { // APIKeys holds the value of the api_keys edge. - APIKeys []*APIKey `json:"api_keys,omitempty"` + APIKeys []*ApiKey `json:"api_keys,omitempty"` // RedeemCodes holds the value of the redeem_codes edge. RedeemCodes []*RedeemCode `json:"redeem_codes,omitempty"` // Subscriptions holds the value of the subscriptions edge. @@ -70,7 +70,7 @@ type UserEdges struct { // APIKeysOrErr returns the APIKeys value or an error if the edge // was not loaded in eager-loading. -func (e UserEdges) APIKeysOrErr() ([]*APIKey, error) { +func (e UserEdges) APIKeysOrErr() ([]*ApiKey, error) { if e.loadedTypes[0] { return e.APIKeys, nil } @@ -255,7 +255,7 @@ func (_m *User) Value(name string) (ent.Value, error) { } // QueryAPIKeys queries the "api_keys" edge of the User entity. -func (_m *User) QueryAPIKeys() *APIKeyQuery { +func (_m *User) QueryAPIKeys() *ApiKeyQuery { return NewUserClient(_m.config).QueryAPIKeys(_m) } diff --git a/backend/ent/user/user.go b/backend/ent/user/user.go index a6871c5d..9c40ab09 100644 --- a/backend/ent/user/user.go +++ b/backend/ent/user/user.go @@ -57,7 +57,7 @@ const ( Table = "users" // APIKeysTable is the table that holds the api_keys relation/edge. APIKeysTable = "api_keys" - // APIKeysInverseTable is the table name for the APIKey entity. + // APIKeysInverseTable is the table name for the ApiKey entity. // It exists in this package in order to avoid circular dependency with the "apikey" package. APIKeysInverseTable = "api_keys" // APIKeysColumn is the table column denoting the api_keys relation/edge. diff --git a/backend/ent/user/where.go b/backend/ent/user/where.go index 38812770..c3db075e 100644 --- a/backend/ent/user/where.go +++ b/backend/ent/user/where.go @@ -722,7 +722,7 @@ func HasAPIKeys() predicate.User { } // HasAPIKeysWith applies the HasEdge predicate on the "api_keys" edge with a given conditions (other predicates). -func HasAPIKeysWith(preds ...predicate.APIKey) predicate.User { +func HasAPIKeysWith(preds ...predicate.ApiKey) predicate.User { return predicate.User(func(s *sql.Selector) { step := newAPIKeysStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { diff --git a/backend/ent/user_create.go b/backend/ent/user_create.go index 4ce48d4b..6313db5f 100644 --- a/backend/ent/user_create.go +++ b/backend/ent/user_create.go @@ -166,14 +166,14 @@ func (_c *UserCreate) SetNillableNotes(v *string) *UserCreate { return _c } -// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs. +// AddAPIKeyIDs adds the "api_keys" edge to the ApiKey entity by IDs. func (_c *UserCreate) AddAPIKeyIDs(ids ...int64) *UserCreate { _c.mutation.AddAPIKeyIDs(ids...) return _c } -// AddAPIKeys adds the "api_keys" edges to the APIKey entity. -func (_c *UserCreate) AddAPIKeys(v ...*APIKey) *UserCreate { +// AddAPIKeys adds the "api_keys" edges to the ApiKey entity. +func (_c *UserCreate) AddAPIKeys(v ...*ApiKey) *UserCreate { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID diff --git a/backend/ent/user_query.go b/backend/ent/user_query.go index 0d65a2dd..80b182c1 100644 --- a/backend/ent/user_query.go +++ b/backend/ent/user_query.go @@ -30,7 +30,7 @@ type UserQuery struct { order []user.OrderOption inters []Interceptor predicates []predicate.User - withAPIKeys *APIKeyQuery + withAPIKeys *ApiKeyQuery withRedeemCodes *RedeemCodeQuery withSubscriptions *UserSubscriptionQuery withAssignedSubscriptions *UserSubscriptionQuery @@ -75,8 +75,8 @@ func (_q *UserQuery) Order(o ...user.OrderOption) *UserQuery { } // QueryAPIKeys chains the current query on the "api_keys" edge. -func (_q *UserQuery) QueryAPIKeys() *APIKeyQuery { - query := (&APIKeyClient{config: _q.config}).Query() +func (_q *UserQuery) QueryAPIKeys() *ApiKeyQuery { + query := (&ApiKeyClient{config: _q.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := _q.prepareQuery(ctx); err != nil { return nil, err @@ -458,8 +458,8 @@ func (_q *UserQuery) Clone() *UserQuery { // WithAPIKeys tells the query-builder to eager-load the nodes that are connected to // the "api_keys" edge. The optional arguments are used to configure the query builder of the edge. -func (_q *UserQuery) WithAPIKeys(opts ...func(*APIKeyQuery)) *UserQuery { - query := (&APIKeyClient{config: _q.config}).Query() +func (_q *UserQuery) WithAPIKeys(opts ...func(*ApiKeyQuery)) *UserQuery { + query := (&ApiKeyClient{config: _q.config}).Query() for _, opt := range opts { opt(query) } @@ -653,8 +653,8 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e } if query := _q.withAPIKeys; query != nil { if err := _q.loadAPIKeys(ctx, query, nodes, - func(n *User) { n.Edges.APIKeys = []*APIKey{} }, - func(n *User, e *APIKey) { n.Edges.APIKeys = append(n.Edges.APIKeys, e) }); err != nil { + func(n *User) { n.Edges.APIKeys = []*ApiKey{} }, + func(n *User, e *ApiKey) { n.Edges.APIKeys = append(n.Edges.APIKeys, e) }); err != nil { return nil, err } } @@ -712,7 +712,7 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e return nodes, nil } -func (_q *UserQuery) loadAPIKeys(ctx context.Context, query *APIKeyQuery, nodes []*User, init func(*User), assign func(*User, *APIKey)) error { +func (_q *UserQuery) loadAPIKeys(ctx context.Context, query *ApiKeyQuery, nodes []*User, init func(*User), assign func(*User, *ApiKey)) error { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[int64]*User) for i := range nodes { @@ -725,7 +725,7 @@ func (_q *UserQuery) loadAPIKeys(ctx context.Context, query *APIKeyQuery, nodes if len(query.ctx.Fields) > 0 { query.ctx.AppendFieldOnce(apikey.FieldUserID) } - query.Where(predicate.APIKey(func(s *sql.Selector) { + query.Where(predicate.ApiKey(func(s *sql.Selector) { s.Where(sql.InValues(s.C(user.APIKeysColumn), fks...)) })) neighbors, err := query.All(ctx) diff --git a/backend/ent/user_update.go b/backend/ent/user_update.go index 49ddf493..ed5d3a76 100644 --- a/backend/ent/user_update.go +++ b/backend/ent/user_update.go @@ -186,14 +186,14 @@ func (_u *UserUpdate) SetNillableNotes(v *string) *UserUpdate { return _u } -// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs. +// AddAPIKeyIDs adds the "api_keys" edge to the ApiKey entity by IDs. func (_u *UserUpdate) AddAPIKeyIDs(ids ...int64) *UserUpdate { _u.mutation.AddAPIKeyIDs(ids...) return _u } -// AddAPIKeys adds the "api_keys" edges to the APIKey entity. -func (_u *UserUpdate) AddAPIKeys(v ...*APIKey) *UserUpdate { +// AddAPIKeys adds the "api_keys" edges to the ApiKey entity. +func (_u *UserUpdate) AddAPIKeys(v ...*ApiKey) *UserUpdate { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -296,20 +296,20 @@ func (_u *UserUpdate) Mutation() *UserMutation { return _u.mutation } -// ClearAPIKeys clears all "api_keys" edges to the APIKey entity. +// ClearAPIKeys clears all "api_keys" edges to the ApiKey entity. func (_u *UserUpdate) ClearAPIKeys() *UserUpdate { _u.mutation.ClearAPIKeys() return _u } -// RemoveAPIKeyIDs removes the "api_keys" edge to APIKey entities by IDs. +// RemoveAPIKeyIDs removes the "api_keys" edge to ApiKey entities by IDs. func (_u *UserUpdate) RemoveAPIKeyIDs(ids ...int64) *UserUpdate { _u.mutation.RemoveAPIKeyIDs(ids...) return _u } -// RemoveAPIKeys removes "api_keys" edges to APIKey entities. -func (_u *UserUpdate) RemoveAPIKeys(v ...*APIKey) *UserUpdate { +// RemoveAPIKeys removes "api_keys" edges to ApiKey entities. +func (_u *UserUpdate) RemoveAPIKeys(v ...*ApiKey) *UserUpdate { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -1065,14 +1065,14 @@ func (_u *UserUpdateOne) SetNillableNotes(v *string) *UserUpdateOne { return _u } -// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs. +// AddAPIKeyIDs adds the "api_keys" edge to the ApiKey entity by IDs. func (_u *UserUpdateOne) AddAPIKeyIDs(ids ...int64) *UserUpdateOne { _u.mutation.AddAPIKeyIDs(ids...) return _u } -// AddAPIKeys adds the "api_keys" edges to the APIKey entity. -func (_u *UserUpdateOne) AddAPIKeys(v ...*APIKey) *UserUpdateOne { +// AddAPIKeys adds the "api_keys" edges to the ApiKey entity. +func (_u *UserUpdateOne) AddAPIKeys(v ...*ApiKey) *UserUpdateOne { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID @@ -1175,20 +1175,20 @@ func (_u *UserUpdateOne) Mutation() *UserMutation { return _u.mutation } -// ClearAPIKeys clears all "api_keys" edges to the APIKey entity. +// ClearAPIKeys clears all "api_keys" edges to the ApiKey entity. func (_u *UserUpdateOne) ClearAPIKeys() *UserUpdateOne { _u.mutation.ClearAPIKeys() return _u } -// RemoveAPIKeyIDs removes the "api_keys" edge to APIKey entities by IDs. +// RemoveAPIKeyIDs removes the "api_keys" edge to ApiKey entities by IDs. func (_u *UserUpdateOne) RemoveAPIKeyIDs(ids ...int64) *UserUpdateOne { _u.mutation.RemoveAPIKeyIDs(ids...) return _u } -// RemoveAPIKeys removes "api_keys" edges to APIKey entities. -func (_u *UserUpdateOne) RemoveAPIKeys(v ...*APIKey) *UserUpdateOne { +// RemoveAPIKeys removes "api_keys" edges to ApiKey entities. +func (_u *UserUpdateOne) RemoveAPIKeys(v ...*ApiKey) *UserUpdateOne { ids := make([]int64, len(v)) for i := range v { ids[i] = v[i].ID diff --git a/backend/go.mod b/backend/go.mod index 4c00bd2a..73bbf95c 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -69,7 +69,6 @@ require ( github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/subcommands v1.2.0 // indirect - github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl/v2 v2.18.1 // indirect diff --git a/backend/go.sum b/backend/go.sum index ee3c61e9..8272855e 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -118,8 +118,6 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.7.0 h1:JxUKI6+CVBgCO2WToKy/nQk0sS+amI9z9EjVmdaocj4= github.com/google/wire v0.7.0/go.mod h1:n6YbUQD9cPKTnHXEBN2DXlOp/mVADhVErcMFb0v3J18= -github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= -github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index b91e9d7c..f22539eb 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -1,4 +1,3 @@ -// Package config provides application configuration management. package config import ( @@ -140,7 +139,7 @@ type GatewayConfig struct { LogUpstreamErrorBodyMaxBytes int `mapstructure:"log_upstream_error_body_max_bytes"` // API-key 账号在客户端未提供 anthropic-beta 时,是否按需自动补齐(默认关闭以保持兼容) - InjectBetaForAPIKey bool `mapstructure:"inject_beta_for_apikey"` + InjectBetaForApiKey bool `mapstructure:"inject_beta_for_apikey"` // 是否允许对部分 400 错误触发 failover(默认关闭以避免改变语义) FailoverOn400 bool `mapstructure:"failover_on_400"` @@ -242,7 +241,7 @@ type DefaultConfig struct { AdminPassword string `mapstructure:"admin_password"` UserConcurrency int `mapstructure:"user_concurrency"` UserBalance float64 `mapstructure:"user_balance"` - APIKeyPrefix string `mapstructure:"api_key_prefix"` + ApiKeyPrefix string `mapstructure:"api_key_prefix"` RateMultiplier float64 `mapstructure:"rate_multiplier"` } diff --git a/backend/internal/config/wire.go b/backend/internal/config/wire.go index 60ee3d3b..ec26c401 100644 --- a/backend/internal/config/wire.go +++ b/backend/internal/config/wire.go @@ -1,4 +1,3 @@ -// Package config provides application configuration management. package config import "github.com/google/wire" diff --git a/backend/internal/handler/admin/dashboard_handler.go b/backend/internal/handler/admin/dashboard_handler.go index 2c8eb23a..a7dc6c4e 100644 --- a/backend/internal/handler/admin/dashboard_handler.go +++ b/backend/internal/handler/admin/dashboard_handler.go @@ -1,5 +1,3 @@ -// Package admin provides HTTP handlers for administrative operations including -// dashboard statistics, user management, API key management, and account management. package admin import ( @@ -77,8 +75,8 @@ func (h *DashboardHandler) GetStats(c *gin.Context) { "active_users": stats.ActiveUsers, // API Key 统计 - "total_api_keys": stats.TotalAPIKeys, - "active_api_keys": stats.ActiveAPIKeys, + "total_api_keys": stats.TotalApiKeys, + "active_api_keys": stats.ActiveApiKeys, // 账户统计 "total_accounts": stats.TotalAccounts, @@ -195,10 +193,10 @@ func (h *DashboardHandler) GetModelStats(c *gin.Context) { }) } -// GetAPIKeyUsageTrend handles getting API key usage trend data +// GetApiKeyUsageTrend handles getting API key usage trend data // GET /api/v1/admin/dashboard/api-keys-trend // Query params: start_date, end_date (YYYY-MM-DD), granularity (day/hour), limit (default 5) -func (h *DashboardHandler) GetAPIKeyUsageTrend(c *gin.Context) { +func (h *DashboardHandler) GetApiKeyUsageTrend(c *gin.Context) { startTime, endTime := parseTimeRange(c) granularity := c.DefaultQuery("granularity", "day") limitStr := c.DefaultQuery("limit", "5") @@ -207,7 +205,7 @@ func (h *DashboardHandler) GetAPIKeyUsageTrend(c *gin.Context) { limit = 5 } - trend, err := h.dashboardService.GetAPIKeyUsageTrend(c.Request.Context(), startTime, endTime, granularity, limit) + trend, err := h.dashboardService.GetApiKeyUsageTrend(c.Request.Context(), startTime, endTime, granularity, limit) if err != nil { response.Error(c, 500, "Failed to get API key usage trend") return @@ -275,26 +273,26 @@ func (h *DashboardHandler) GetBatchUsersUsage(c *gin.Context) { response.Success(c, gin.H{"stats": stats}) } -// BatchAPIKeysUsageRequest represents the request body for batch api key usage stats -type BatchAPIKeysUsageRequest struct { - APIKeyIDs []int64 `json:"api_key_ids" binding:"required"` +// BatchApiKeysUsageRequest represents the request body for batch api key usage stats +type BatchApiKeysUsageRequest struct { + ApiKeyIDs []int64 `json:"api_key_ids" binding:"required"` } -// GetBatchAPIKeysUsage handles getting usage stats for multiple API keys +// GetBatchApiKeysUsage handles getting usage stats for multiple API keys // POST /api/v1/admin/dashboard/api-keys-usage -func (h *DashboardHandler) GetBatchAPIKeysUsage(c *gin.Context) { - var req BatchAPIKeysUsageRequest +func (h *DashboardHandler) GetBatchApiKeysUsage(c *gin.Context) { + var req BatchApiKeysUsageRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "Invalid request: "+err.Error()) return } - if len(req.APIKeyIDs) == 0 { + if len(req.ApiKeyIDs) == 0 { response.Success(c, gin.H{"stats": map[string]any{}}) return } - stats, err := h.dashboardService.GetBatchAPIKeyUsageStats(c.Request.Context(), req.APIKeyIDs) + stats, err := h.dashboardService.GetBatchApiKeyUsageStats(c.Request.Context(), req.ApiKeyIDs) if err != nil { response.Error(c, 500, "Failed to get API key usage stats") return diff --git a/backend/internal/handler/admin/group_handler.go b/backend/internal/handler/admin/group_handler.go index 1ca54aaf..30225b76 100644 --- a/backend/internal/handler/admin/group_handler.go +++ b/backend/internal/handler/admin/group_handler.go @@ -237,9 +237,9 @@ func (h *GroupHandler) GetGroupAPIKeys(c *gin.Context) { return } - outKeys := make([]dto.APIKey, 0, len(keys)) + outKeys := make([]dto.ApiKey, 0, len(keys)) for i := range keys { - outKeys = append(outKeys, *dto.APIKeyFromService(&keys[i])) + outKeys = append(outKeys, *dto.ApiKeyFromService(&keys[i])) } response.Paginated(c, outKeys, total, page, pageSize) } diff --git a/backend/internal/handler/admin/setting_handler.go b/backend/internal/handler/admin/setting_handler.go index 05e9d9d0..d3716cb4 100644 --- a/backend/internal/handler/admin/setting_handler.go +++ b/backend/internal/handler/admin/setting_handler.go @@ -36,24 +36,29 @@ func (h *SettingHandler) GetSettings(c *gin.Context) { response.Success(c, dto.SystemSettings{ RegistrationEnabled: settings.RegistrationEnabled, EmailVerifyEnabled: settings.EmailVerifyEnabled, - SMTPHost: settings.SMTPHost, - SMTPPort: settings.SMTPPort, - SMTPUsername: settings.SMTPUsername, - SMTPPassword: settings.SMTPPassword, - SMTPFrom: settings.SMTPFrom, - SMTPFromName: settings.SMTPFromName, - SMTPUseTLS: settings.SMTPUseTLS, + SmtpHost: settings.SmtpHost, + SmtpPort: settings.SmtpPort, + SmtpUsername: settings.SmtpUsername, + SmtpPassword: settings.SmtpPassword, + SmtpFrom: settings.SmtpFrom, + SmtpFromName: settings.SmtpFromName, + SmtpUseTLS: settings.SmtpUseTLS, TurnstileEnabled: settings.TurnstileEnabled, TurnstileSiteKey: settings.TurnstileSiteKey, TurnstileSecretKey: settings.TurnstileSecretKey, SiteName: settings.SiteName, SiteLogo: settings.SiteLogo, SiteSubtitle: settings.SiteSubtitle, - APIBaseURL: settings.APIBaseURL, + ApiBaseUrl: settings.ApiBaseUrl, ContactInfo: settings.ContactInfo, - DocURL: settings.DocURL, + DocUrl: settings.DocUrl, DefaultConcurrency: settings.DefaultConcurrency, DefaultBalance: settings.DefaultBalance, + EnableModelFallback: settings.EnableModelFallback, + FallbackModelAnthropic: settings.FallbackModelAnthropic, + FallbackModelOpenAI: settings.FallbackModelOpenAI, + FallbackModelGemini: settings.FallbackModelGemini, + FallbackModelAntigravity: settings.FallbackModelAntigravity, }) } @@ -64,13 +69,13 @@ type UpdateSettingsRequest struct { EmailVerifyEnabled bool `json:"email_verify_enabled"` // 邮件服务设置 - SMTPHost string `json:"smtp_host"` - SMTPPort int `json:"smtp_port"` - SMTPUsername string `json:"smtp_username"` - SMTPPassword string `json:"smtp_password"` - SMTPFrom string `json:"smtp_from_email"` - SMTPFromName string `json:"smtp_from_name"` - SMTPUseTLS bool `json:"smtp_use_tls"` + SmtpHost string `json:"smtp_host"` + SmtpPort int `json:"smtp_port"` + SmtpUsername string `json:"smtp_username"` + SmtpPassword string `json:"smtp_password"` + SmtpFrom string `json:"smtp_from_email"` + SmtpFromName string `json:"smtp_from_name"` + SmtpUseTLS bool `json:"smtp_use_tls"` // Cloudflare Turnstile 设置 TurnstileEnabled bool `json:"turnstile_enabled"` @@ -81,13 +86,20 @@ type UpdateSettingsRequest struct { SiteName string `json:"site_name"` SiteLogo string `json:"site_logo"` SiteSubtitle string `json:"site_subtitle"` - APIBaseURL string `json:"api_base_url"` + ApiBaseUrl string `json:"api_base_url"` ContactInfo string `json:"contact_info"` - DocURL string `json:"doc_url"` + DocUrl string `json:"doc_url"` // 默认配置 DefaultConcurrency int `json:"default_concurrency"` DefaultBalance float64 `json:"default_balance"` + + // Model fallback configuration + EnableModelFallback bool `json:"enable_model_fallback"` + FallbackModelAnthropic string `json:"fallback_model_anthropic"` + FallbackModelOpenAI string `json:"fallback_model_openai"` + FallbackModelGemini string `json:"fallback_model_gemini"` + FallbackModelAntigravity string `json:"fallback_model_antigravity"` } // UpdateSettings 更新系统设置 @@ -106,8 +118,8 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { if req.DefaultBalance < 0 { req.DefaultBalance = 0 } - if req.SMTPPort <= 0 { - req.SMTPPort = 587 + if req.SmtpPort <= 0 { + req.SmtpPort = 587 } // Turnstile 参数验证 @@ -143,24 +155,29 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { settings := &service.SystemSettings{ RegistrationEnabled: req.RegistrationEnabled, EmailVerifyEnabled: req.EmailVerifyEnabled, - SMTPHost: req.SMTPHost, - SMTPPort: req.SMTPPort, - SMTPUsername: req.SMTPUsername, - SMTPPassword: req.SMTPPassword, - SMTPFrom: req.SMTPFrom, - SMTPFromName: req.SMTPFromName, - SMTPUseTLS: req.SMTPUseTLS, + SmtpHost: req.SmtpHost, + SmtpPort: req.SmtpPort, + SmtpUsername: req.SmtpUsername, + SmtpPassword: req.SmtpPassword, + SmtpFrom: req.SmtpFrom, + SmtpFromName: req.SmtpFromName, + SmtpUseTLS: req.SmtpUseTLS, TurnstileEnabled: req.TurnstileEnabled, TurnstileSiteKey: req.TurnstileSiteKey, TurnstileSecretKey: req.TurnstileSecretKey, SiteName: req.SiteName, SiteLogo: req.SiteLogo, SiteSubtitle: req.SiteSubtitle, - APIBaseURL: req.APIBaseURL, + ApiBaseUrl: req.ApiBaseUrl, ContactInfo: req.ContactInfo, - DocURL: req.DocURL, + DocUrl: req.DocUrl, DefaultConcurrency: req.DefaultConcurrency, DefaultBalance: req.DefaultBalance, + EnableModelFallback: req.EnableModelFallback, + FallbackModelAnthropic: req.FallbackModelAnthropic, + FallbackModelOpenAI: req.FallbackModelOpenAI, + FallbackModelGemini: req.FallbackModelGemini, + FallbackModelAntigravity: req.FallbackModelAntigravity, } if err := h.settingService.UpdateSettings(c.Request.Context(), settings); err != nil { @@ -178,67 +195,72 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { response.Success(c, dto.SystemSettings{ RegistrationEnabled: updatedSettings.RegistrationEnabled, EmailVerifyEnabled: updatedSettings.EmailVerifyEnabled, - SMTPHost: updatedSettings.SMTPHost, - SMTPPort: updatedSettings.SMTPPort, - SMTPUsername: updatedSettings.SMTPUsername, - SMTPPassword: updatedSettings.SMTPPassword, - SMTPFrom: updatedSettings.SMTPFrom, - SMTPFromName: updatedSettings.SMTPFromName, - SMTPUseTLS: updatedSettings.SMTPUseTLS, + SmtpHost: updatedSettings.SmtpHost, + SmtpPort: updatedSettings.SmtpPort, + SmtpUsername: updatedSettings.SmtpUsername, + SmtpPassword: updatedSettings.SmtpPassword, + SmtpFrom: updatedSettings.SmtpFrom, + SmtpFromName: updatedSettings.SmtpFromName, + SmtpUseTLS: updatedSettings.SmtpUseTLS, TurnstileEnabled: updatedSettings.TurnstileEnabled, TurnstileSiteKey: updatedSettings.TurnstileSiteKey, TurnstileSecretKey: updatedSettings.TurnstileSecretKey, SiteName: updatedSettings.SiteName, SiteLogo: updatedSettings.SiteLogo, SiteSubtitle: updatedSettings.SiteSubtitle, - APIBaseURL: updatedSettings.APIBaseURL, + ApiBaseUrl: updatedSettings.ApiBaseUrl, ContactInfo: updatedSettings.ContactInfo, - DocURL: updatedSettings.DocURL, + DocUrl: updatedSettings.DocUrl, DefaultConcurrency: updatedSettings.DefaultConcurrency, DefaultBalance: updatedSettings.DefaultBalance, + EnableModelFallback: updatedSettings.EnableModelFallback, + FallbackModelAnthropic: updatedSettings.FallbackModelAnthropic, + FallbackModelOpenAI: updatedSettings.FallbackModelOpenAI, + FallbackModelGemini: updatedSettings.FallbackModelGemini, + FallbackModelAntigravity: updatedSettings.FallbackModelAntigravity, }) } -// TestSMTPRequest 测试SMTP连接请求 -type TestSMTPRequest struct { - SMTPHost string `json:"smtp_host" binding:"required"` - SMTPPort int `json:"smtp_port"` - SMTPUsername string `json:"smtp_username"` - SMTPPassword string `json:"smtp_password"` - SMTPUseTLS bool `json:"smtp_use_tls"` +// TestSmtpRequest 测试SMTP连接请求 +type TestSmtpRequest struct { + SmtpHost string `json:"smtp_host" binding:"required"` + SmtpPort int `json:"smtp_port"` + SmtpUsername string `json:"smtp_username"` + SmtpPassword string `json:"smtp_password"` + SmtpUseTLS bool `json:"smtp_use_tls"` } -// TestSMTPConnection 测试SMTP连接 +// TestSmtpConnection 测试SMTP连接 // POST /api/v1/admin/settings/test-smtp -func (h *SettingHandler) TestSMTPConnection(c *gin.Context) { - var req TestSMTPRequest +func (h *SettingHandler) TestSmtpConnection(c *gin.Context) { + var req TestSmtpRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "Invalid request: "+err.Error()) return } - if req.SMTPPort <= 0 { - req.SMTPPort = 587 + if req.SmtpPort <= 0 { + req.SmtpPort = 587 } // 如果未提供密码,从数据库获取已保存的密码 - password := req.SMTPPassword + password := req.SmtpPassword if password == "" { - savedConfig, err := h.emailService.GetSMTPConfig(c.Request.Context()) + savedConfig, err := h.emailService.GetSmtpConfig(c.Request.Context()) if err == nil && savedConfig != nil { password = savedConfig.Password } } - config := &service.SMTPConfig{ - Host: req.SMTPHost, - Port: req.SMTPPort, - Username: req.SMTPUsername, + config := &service.SmtpConfig{ + Host: req.SmtpHost, + Port: req.SmtpPort, + Username: req.SmtpUsername, Password: password, - UseTLS: req.SMTPUseTLS, + UseTLS: req.SmtpUseTLS, } - err := h.emailService.TestSMTPConnectionWithConfig(config) + err := h.emailService.TestSmtpConnectionWithConfig(config) if err != nil { response.ErrorFrom(c, err) return @@ -250,13 +272,13 @@ func (h *SettingHandler) TestSMTPConnection(c *gin.Context) { // SendTestEmailRequest 发送测试邮件请求 type SendTestEmailRequest struct { Email string `json:"email" binding:"required,email"` - SMTPHost string `json:"smtp_host" binding:"required"` - SMTPPort int `json:"smtp_port"` - SMTPUsername string `json:"smtp_username"` - SMTPPassword string `json:"smtp_password"` - SMTPFrom string `json:"smtp_from_email"` - SMTPFromName string `json:"smtp_from_name"` - SMTPUseTLS bool `json:"smtp_use_tls"` + SmtpHost string `json:"smtp_host" binding:"required"` + SmtpPort int `json:"smtp_port"` + SmtpUsername string `json:"smtp_username"` + SmtpPassword string `json:"smtp_password"` + SmtpFrom string `json:"smtp_from_email"` + SmtpFromName string `json:"smtp_from_name"` + SmtpUseTLS bool `json:"smtp_use_tls"` } // SendTestEmail 发送测试邮件 @@ -268,27 +290,27 @@ func (h *SettingHandler) SendTestEmail(c *gin.Context) { return } - if req.SMTPPort <= 0 { - req.SMTPPort = 587 + if req.SmtpPort <= 0 { + req.SmtpPort = 587 } // 如果未提供密码,从数据库获取已保存的密码 - password := req.SMTPPassword + password := req.SmtpPassword if password == "" { - savedConfig, err := h.emailService.GetSMTPConfig(c.Request.Context()) + savedConfig, err := h.emailService.GetSmtpConfig(c.Request.Context()) if err == nil && savedConfig != nil { password = savedConfig.Password } } - config := &service.SMTPConfig{ - Host: req.SMTPHost, - Port: req.SMTPPort, - Username: req.SMTPUsername, + config := &service.SmtpConfig{ + Host: req.SmtpHost, + Port: req.SmtpPort, + Username: req.SmtpUsername, Password: password, - From: req.SMTPFrom, - FromName: req.SMTPFromName, - UseTLS: req.SMTPUseTLS, + From: req.SmtpFrom, + FromName: req.SmtpFromName, + UseTLS: req.SmtpUseTLS, } siteName := h.settingService.GetSiteName(c.Request.Context()) @@ -333,10 +355,10 @@ func (h *SettingHandler) SendTestEmail(c *gin.Context) { response.Success(c, gin.H{"message": "Test email sent successfully"}) } -// GetAdminAPIKey 获取管理员 API Key 状态 +// GetAdminApiKey 获取管理员 API Key 状态 // GET /api/v1/admin/settings/admin-api-key -func (h *SettingHandler) GetAdminAPIKey(c *gin.Context) { - maskedKey, exists, err := h.settingService.GetAdminAPIKeyStatus(c.Request.Context()) +func (h *SettingHandler) GetAdminApiKey(c *gin.Context) { + maskedKey, exists, err := h.settingService.GetAdminApiKeyStatus(c.Request.Context()) if err != nil { response.ErrorFrom(c, err) return @@ -348,10 +370,10 @@ func (h *SettingHandler) GetAdminAPIKey(c *gin.Context) { }) } -// RegenerateAdminAPIKey 生成/重新生成管理员 API Key +// RegenerateAdminApiKey 生成/重新生成管理员 API Key // POST /api/v1/admin/settings/admin-api-key/regenerate -func (h *SettingHandler) RegenerateAdminAPIKey(c *gin.Context) { - key, err := h.settingService.GenerateAdminAPIKey(c.Request.Context()) +func (h *SettingHandler) RegenerateAdminApiKey(c *gin.Context) { + key, err := h.settingService.GenerateAdminApiKey(c.Request.Context()) if err != nil { response.ErrorFrom(c, err) return @@ -362,10 +384,10 @@ func (h *SettingHandler) RegenerateAdminAPIKey(c *gin.Context) { }) } -// DeleteAdminAPIKey 删除管理员 API Key +// DeleteAdminApiKey 删除管理员 API Key // DELETE /api/v1/admin/settings/admin-api-key -func (h *SettingHandler) DeleteAdminAPIKey(c *gin.Context) { - if err := h.settingService.DeleteAdminAPIKey(c.Request.Context()); err != nil { +func (h *SettingHandler) DeleteAdminApiKey(c *gin.Context) { + if err := h.settingService.DeleteAdminApiKey(c.Request.Context()); err != nil { response.ErrorFrom(c, err) return } diff --git a/backend/internal/handler/admin/usage_handler.go b/backend/internal/handler/admin/usage_handler.go index 37da93d3..a75948f7 100644 --- a/backend/internal/handler/admin/usage_handler.go +++ b/backend/internal/handler/admin/usage_handler.go @@ -17,14 +17,14 @@ import ( // UsageHandler handles admin usage-related requests type UsageHandler struct { usageService *service.UsageService - apiKeyService *service.APIKeyService + apiKeyService *service.ApiKeyService adminService service.AdminService } // NewUsageHandler creates a new admin usage handler func NewUsageHandler( usageService *service.UsageService, - apiKeyService *service.APIKeyService, + apiKeyService *service.ApiKeyService, adminService service.AdminService, ) *UsageHandler { return &UsageHandler{ @@ -125,7 +125,7 @@ func (h *UsageHandler) List(c *gin.Context) { params := pagination.PaginationParams{Page: page, PageSize: pageSize} filters := usagestats.UsageLogFilters{ UserID: userID, - APIKeyID: apiKeyID, + ApiKeyID: apiKeyID, AccountID: accountID, GroupID: groupID, Model: model, @@ -207,7 +207,7 @@ func (h *UsageHandler) Stats(c *gin.Context) { } if apiKeyID > 0 { - stats, err := h.usageService.GetStatsByAPIKey(c.Request.Context(), apiKeyID, startTime, endTime) + stats, err := h.usageService.GetStatsByApiKey(c.Request.Context(), apiKeyID, startTime, endTime) if err != nil { response.ErrorFrom(c, err) return @@ -269,9 +269,9 @@ func (h *UsageHandler) SearchUsers(c *gin.Context) { response.Success(c, result) } -// SearchAPIKeys handles searching API keys by user +// SearchApiKeys handles searching API keys by user // GET /api/v1/admin/usage/search-api-keys -func (h *UsageHandler) SearchAPIKeys(c *gin.Context) { +func (h *UsageHandler) SearchApiKeys(c *gin.Context) { userIDStr := c.Query("user_id") keyword := c.Query("q") @@ -285,22 +285,22 @@ func (h *UsageHandler) SearchAPIKeys(c *gin.Context) { userID = id } - keys, err := h.apiKeyService.SearchAPIKeys(c.Request.Context(), userID, keyword, 30) + keys, err := h.apiKeyService.SearchApiKeys(c.Request.Context(), userID, keyword, 30) if err != nil { response.ErrorFrom(c, err) return } // Return simplified API key list (only id and name) - type SimpleAPIKey struct { + type SimpleApiKey struct { ID int64 `json:"id"` Name string `json:"name"` UserID int64 `json:"user_id"` } - result := make([]SimpleAPIKey, len(keys)) + result := make([]SimpleApiKey, len(keys)) for i, k := range keys { - result[i] = SimpleAPIKey{ + result[i] = SimpleApiKey{ ID: k.ID, Name: k.Name, UserID: k.UserID, diff --git a/backend/internal/handler/admin/user_handler.go b/backend/internal/handler/admin/user_handler.go index f8cd1d5a..11bdebd2 100644 --- a/backend/internal/handler/admin/user_handler.go +++ b/backend/internal/handler/admin/user_handler.go @@ -243,9 +243,9 @@ func (h *UserHandler) GetUserAPIKeys(c *gin.Context) { return } - out := make([]dto.APIKey, 0, len(keys)) + out := make([]dto.ApiKey, 0, len(keys)) for i := range keys { - out = append(out, *dto.APIKeyFromService(&keys[i])) + out = append(out, *dto.ApiKeyFromService(&keys[i])) } response.Paginated(c, out, total, page, pageSize) } diff --git a/backend/internal/handler/api_key_handler.go b/backend/internal/handler/api_key_handler.go index 8eff2924..790f4ac2 100644 --- a/backend/internal/handler/api_key_handler.go +++ b/backend/internal/handler/api_key_handler.go @@ -14,11 +14,11 @@ import ( // APIKeyHandler handles API key-related requests type APIKeyHandler struct { - apiKeyService *service.APIKeyService + apiKeyService *service.ApiKeyService } // NewAPIKeyHandler creates a new APIKeyHandler -func NewAPIKeyHandler(apiKeyService *service.APIKeyService) *APIKeyHandler { +func NewAPIKeyHandler(apiKeyService *service.ApiKeyService) *APIKeyHandler { return &APIKeyHandler{ apiKeyService: apiKeyService, } @@ -56,9 +56,9 @@ func (h *APIKeyHandler) List(c *gin.Context) { return } - out := make([]dto.APIKey, 0, len(keys)) + out := make([]dto.ApiKey, 0, len(keys)) for i := range keys { - out = append(out, *dto.APIKeyFromService(&keys[i])) + out = append(out, *dto.ApiKeyFromService(&keys[i])) } response.Paginated(c, out, result.Total, page, pageSize) } @@ -90,7 +90,7 @@ func (h *APIKeyHandler) GetByID(c *gin.Context) { return } - response.Success(c, dto.APIKeyFromService(key)) + response.Success(c, dto.ApiKeyFromService(key)) } // Create handles creating a new API key @@ -108,7 +108,7 @@ func (h *APIKeyHandler) Create(c *gin.Context) { return } - svcReq := service.CreateAPIKeyRequest{ + svcReq := service.CreateApiKeyRequest{ Name: req.Name, GroupID: req.GroupID, CustomKey: req.CustomKey, @@ -119,7 +119,7 @@ func (h *APIKeyHandler) Create(c *gin.Context) { return } - response.Success(c, dto.APIKeyFromService(key)) + response.Success(c, dto.ApiKeyFromService(key)) } // Update handles updating an API key @@ -143,7 +143,7 @@ func (h *APIKeyHandler) Update(c *gin.Context) { return } - svcReq := service.UpdateAPIKeyRequest{} + svcReq := service.UpdateApiKeyRequest{} if req.Name != "" { svcReq.Name = &req.Name } @@ -158,7 +158,7 @@ func (h *APIKeyHandler) Update(c *gin.Context) { return } - response.Success(c, dto.APIKeyFromService(key)) + response.Success(c, dto.ApiKeyFromService(key)) } // Delete handles deleting an API key diff --git a/backend/internal/handler/dto/settings.go b/backend/internal/handler/dto/settings.go index df3189a6..b0c2fda0 100644 --- a/backend/internal/handler/dto/settings.go +++ b/backend/internal/handler/dto/settings.go @@ -5,13 +5,13 @@ type SystemSettings struct { RegistrationEnabled bool `json:"registration_enabled"` EmailVerifyEnabled bool `json:"email_verify_enabled"` - SMTPHost string `json:"smtp_host"` - SMTPPort int `json:"smtp_port"` - SMTPUsername string `json:"smtp_username"` - SMTPPassword string `json:"smtp_password,omitempty"` - SMTPFrom string `json:"smtp_from_email"` - SMTPFromName string `json:"smtp_from_name"` - SMTPUseTLS bool `json:"smtp_use_tls"` + SmtpHost string `json:"smtp_host"` + SmtpPort int `json:"smtp_port"` + SmtpUsername string `json:"smtp_username"` + SmtpPassword string `json:"smtp_password,omitempty"` + SmtpFrom string `json:"smtp_from_email"` + SmtpFromName string `json:"smtp_from_name"` + SmtpUseTLS bool `json:"smtp_use_tls"` TurnstileEnabled bool `json:"turnstile_enabled"` TurnstileSiteKey string `json:"turnstile_site_key"` @@ -20,12 +20,19 @@ type SystemSettings struct { SiteName string `json:"site_name"` SiteLogo string `json:"site_logo"` SiteSubtitle string `json:"site_subtitle"` - APIBaseURL string `json:"api_base_url"` + ApiBaseUrl string `json:"api_base_url"` ContactInfo string `json:"contact_info"` - DocURL string `json:"doc_url"` + DocUrl string `json:"doc_url"` DefaultConcurrency int `json:"default_concurrency"` DefaultBalance float64 `json:"default_balance"` + + // Model fallback configuration + EnableModelFallback bool `json:"enable_model_fallback"` + FallbackModelAnthropic string `json:"fallback_model_anthropic"` + FallbackModelOpenAI string `json:"fallback_model_openai"` + FallbackModelGemini string `json:"fallback_model_gemini"` + FallbackModelAntigravity string `json:"fallback_model_antigravity"` } type PublicSettings struct { @@ -36,8 +43,8 @@ type PublicSettings struct { SiteName string `json:"site_name"` SiteLogo string `json:"site_logo"` SiteSubtitle string `json:"site_subtitle"` - APIBaseURL string `json:"api_base_url"` + ApiBaseUrl string `json:"api_base_url"` ContactInfo string `json:"contact_info"` - DocURL string `json:"doc_url"` + DocUrl string `json:"doc_url"` Version string `json:"version"` } diff --git a/backend/internal/handler/handler.go b/backend/internal/handler/handler.go index 8e03d7ca..817b71d3 100644 --- a/backend/internal/handler/handler.go +++ b/backend/internal/handler/handler.go @@ -7,7 +7,6 @@ import ( // AdminHandlers contains all admin-related HTTP handlers type AdminHandlers struct { Dashboard *admin.DashboardHandler - Ops *admin.OpsHandler User *admin.UserHandler Group *admin.GroupHandler Account *admin.AccountHandler diff --git a/backend/internal/handler/openai_gateway_handler.go b/backend/internal/handler/openai_gateway_handler.go index 3fa9956b..9931052d 100644 --- a/backend/internal/handler/openai_gateway_handler.go +++ b/backend/internal/handler/openai_gateway_handler.go @@ -22,7 +22,6 @@ type OpenAIGatewayHandler struct { gatewayService *service.OpenAIGatewayService billingCacheService *service.BillingCacheService concurrencyHelper *ConcurrencyHelper - opsService *service.OpsService } // NewOpenAIGatewayHandler creates a new OpenAIGatewayHandler @@ -30,21 +29,19 @@ func NewOpenAIGatewayHandler( gatewayService *service.OpenAIGatewayService, concurrencyService *service.ConcurrencyService, billingCacheService *service.BillingCacheService, - opsService *service.OpsService, ) *OpenAIGatewayHandler { return &OpenAIGatewayHandler{ gatewayService: gatewayService, billingCacheService: billingCacheService, concurrencyHelper: NewConcurrencyHelper(concurrencyService, SSEPingFormatNone), - opsService: opsService, } } // Responses handles OpenAI Responses API endpoint // POST /openai/v1/responses func (h *OpenAIGatewayHandler) Responses(c *gin.Context) { - // Get apiKey and user from context (set by APIKeyAuth middleware) - apiKey, ok := middleware2.GetAPIKeyFromContext(c) + // Get apiKey and user from context (set by ApiKeyAuth middleware) + apiKey, ok := middleware2.GetApiKeyFromContext(c) if !ok { h.errorResponse(c, http.StatusUnauthorized, "authentication_error", "Invalid API key") return @@ -82,7 +79,6 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) { // Extract model and stream reqModel, _ := reqBody["model"].(string) reqStream, _ := reqBody["stream"].(bool) - setOpsRequestContext(c, reqModel, reqStream) // 验证 model 必填 if reqModel == "" { @@ -239,7 +235,7 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) { defer cancel() if err := h.gatewayService.RecordUsage(ctx, &service.OpenAIRecordUsageInput{ Result: result, - APIKey: apiKey, + ApiKey: apiKey, User: apiKey.User, Account: usedAccount, Subscription: subscription, @@ -282,7 +278,6 @@ func (h *OpenAIGatewayHandler) mapUpstreamError(statusCode int) (int, string, st // handleStreamingAwareError handles errors that may occur after streaming has started func (h *OpenAIGatewayHandler) handleStreamingAwareError(c *gin.Context, status int, errType, message string, streamStarted bool) { if streamStarted { - recordOpsError(c, h.opsService, status, errType, message, service.PlatformOpenAI) // Stream already started, send error as SSE event then close flusher, ok := c.Writer.(http.Flusher) if ok { @@ -302,7 +297,6 @@ func (h *OpenAIGatewayHandler) handleStreamingAwareError(c *gin.Context, status // errorResponse returns OpenAI API format error response func (h *OpenAIGatewayHandler) errorResponse(c *gin.Context, status int, errType, message string) { - recordOpsError(c, h.opsService, status, errType, message, service.PlatformOpenAI) c.JSON(status, gin.H{ "error": gin.H{ "type": errType, diff --git a/backend/internal/handler/setting_handler.go b/backend/internal/handler/setting_handler.go index 3cae7a7f..90165288 100644 --- a/backend/internal/handler/setting_handler.go +++ b/backend/internal/handler/setting_handler.go @@ -39,9 +39,9 @@ func (h *SettingHandler) GetPublicSettings(c *gin.Context) { SiteName: settings.SiteName, SiteLogo: settings.SiteLogo, SiteSubtitle: settings.SiteSubtitle, - APIBaseURL: settings.APIBaseURL, + ApiBaseUrl: settings.ApiBaseUrl, ContactInfo: settings.ContactInfo, - DocURL: settings.DocURL, + DocUrl: settings.DocUrl, Version: h.version, }) } diff --git a/backend/internal/handler/usage_handler.go b/backend/internal/handler/usage_handler.go index 9e503d4c..a0cf9f2c 100644 --- a/backend/internal/handler/usage_handler.go +++ b/backend/internal/handler/usage_handler.go @@ -18,11 +18,11 @@ import ( // UsageHandler handles usage-related requests type UsageHandler struct { usageService *service.UsageService - apiKeyService *service.APIKeyService + apiKeyService *service.ApiKeyService } // NewUsageHandler creates a new UsageHandler -func NewUsageHandler(usageService *service.UsageService, apiKeyService *service.APIKeyService) *UsageHandler { +func NewUsageHandler(usageService *service.UsageService, apiKeyService *service.ApiKeyService) *UsageHandler { return &UsageHandler{ usageService: usageService, apiKeyService: apiKeyService, @@ -111,7 +111,7 @@ func (h *UsageHandler) List(c *gin.Context) { params := pagination.PaginationParams{Page: page, PageSize: pageSize} filters := usagestats.UsageLogFilters{ UserID: subject.UserID, // Always filter by current user for security - APIKeyID: apiKeyID, + ApiKeyID: apiKeyID, Model: model, Stream: stream, BillingType: billingType, @@ -235,7 +235,7 @@ func (h *UsageHandler) Stats(c *gin.Context) { var stats *service.UsageStats var err error if apiKeyID > 0 { - stats, err = h.usageService.GetStatsByAPIKey(c.Request.Context(), apiKeyID, startTime, endTime) + stats, err = h.usageService.GetStatsByApiKey(c.Request.Context(), apiKeyID, startTime, endTime) } else { stats, err = h.usageService.GetStatsByUser(c.Request.Context(), subject.UserID, startTime, endTime) } @@ -346,49 +346,49 @@ func (h *UsageHandler) DashboardModels(c *gin.Context) { }) } -// BatchAPIKeysUsageRequest represents the request for batch API keys usage -type BatchAPIKeysUsageRequest struct { - APIKeyIDs []int64 `json:"api_key_ids" binding:"required"` +// BatchApiKeysUsageRequest represents the request for batch API keys usage +type BatchApiKeysUsageRequest struct { + ApiKeyIDs []int64 `json:"api_key_ids" binding:"required"` } -// DashboardAPIKeysUsage handles getting usage stats for user's own API keys +// DashboardApiKeysUsage handles getting usage stats for user's own API keys // POST /api/v1/usage/dashboard/api-keys-usage -func (h *UsageHandler) DashboardAPIKeysUsage(c *gin.Context) { +func (h *UsageHandler) DashboardApiKeysUsage(c *gin.Context) { subject, ok := middleware2.GetAuthSubjectFromContext(c) if !ok { response.Unauthorized(c, "User not authenticated") return } - var req BatchAPIKeysUsageRequest + var req BatchApiKeysUsageRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "Invalid request: "+err.Error()) return } - if len(req.APIKeyIDs) == 0 { + if len(req.ApiKeyIDs) == 0 { response.Success(c, gin.H{"stats": map[string]any{}}) return } // Limit the number of API key IDs to prevent SQL parameter overflow - if len(req.APIKeyIDs) > 100 { + if len(req.ApiKeyIDs) > 100 { response.BadRequest(c, "Too many API key IDs (maximum 100 allowed)") return } - validAPIKeyIDs, err := h.apiKeyService.VerifyOwnership(c.Request.Context(), subject.UserID, req.APIKeyIDs) + validApiKeyIDs, err := h.apiKeyService.VerifyOwnership(c.Request.Context(), subject.UserID, req.ApiKeyIDs) if err != nil { response.ErrorFrom(c, err) return } - if len(validAPIKeyIDs) == 0 { + if len(validApiKeyIDs) == 0 { response.Success(c, gin.H{"stats": map[string]any{}}) return } - stats, err := h.usageService.GetBatchAPIKeyUsageStats(c.Request.Context(), validAPIKeyIDs) + stats, err := h.usageService.GetBatchApiKeyUsageStats(c.Request.Context(), validApiKeyIDs) if err != nil { response.ErrorFrom(c, err) return diff --git a/backend/internal/handler/wire.go b/backend/internal/handler/wire.go index 9a8e4c14..1695f8a9 100644 --- a/backend/internal/handler/wire.go +++ b/backend/internal/handler/wire.go @@ -10,7 +10,6 @@ import ( // ProvideAdminHandlers creates the AdminHandlers struct func ProvideAdminHandlers( dashboardHandler *admin.DashboardHandler, - opsHandler *admin.OpsHandler, userHandler *admin.UserHandler, groupHandler *admin.GroupHandler, accountHandler *admin.AccountHandler, @@ -28,7 +27,6 @@ func ProvideAdminHandlers( ) *AdminHandlers { return &AdminHandlers{ Dashboard: dashboardHandler, - Ops: opsHandler, User: userHandler, Group: groupHandler, Account: accountHandler, @@ -98,7 +96,6 @@ var ProviderSet = wire.NewSet( // Admin handlers admin.NewDashboardHandler, - admin.NewOpsHandler, admin.NewUserHandler, admin.NewGroupHandler, admin.NewAccountHandler, diff --git a/backend/internal/pkg/claude/constants.go b/backend/internal/pkg/claude/constants.go index ee5bddc4..0db3ed4a 100644 --- a/backend/internal/pkg/claude/constants.go +++ b/backend/internal/pkg/claude/constants.go @@ -1,4 +1,3 @@ -// Package claude provides Claude API client constants and utilities. package claude // Claude Code 客户端相关常量 @@ -17,13 +16,13 @@ const DefaultBetaHeader = BetaClaudeCode + "," + BetaOAuth + "," + BetaInterleav // HaikuBetaHeader Haiku 模型使用的 anthropic-beta header(不需要 claude-code beta) const HaikuBetaHeader = BetaOAuth + "," + BetaInterleavedThinking -// APIKeyBetaHeader API-key 账号建议使用的 anthropic-beta header(不包含 oauth) -const APIKeyBetaHeader = BetaClaudeCode + "," + BetaInterleavedThinking + "," + BetaFineGrainedToolStreaming +// ApiKeyBetaHeader API-key 账号建议使用的 anthropic-beta header(不包含 oauth) +const ApiKeyBetaHeader = BetaClaudeCode + "," + BetaInterleavedThinking + "," + BetaFineGrainedToolStreaming -// APIKeyHaikuBetaHeader Haiku 模型在 API-key 账号下使用的 anthropic-beta header(不包含 oauth / claude-code) -const APIKeyHaikuBetaHeader = BetaInterleavedThinking +// ApiKeyHaikuBetaHeader Haiku 模型在 API-key 账号下使用的 anthropic-beta header(不包含 oauth / claude-code) +const ApiKeyHaikuBetaHeader = BetaInterleavedThinking -// DefaultHeaders are the default request headers for Claude Code client. +// Claude Code 客户端默认请求头 var DefaultHeaders = map[string]string{ "User-Agent": "claude-cli/2.0.62 (external, cli)", "X-Stainless-Lang": "js", diff --git a/backend/internal/pkg/errors/types.go b/backend/internal/pkg/errors/types.go index e5d7f24a..dd98f6f5 100644 --- a/backend/internal/pkg/errors/types.go +++ b/backend/internal/pkg/errors/types.go @@ -1,4 +1,3 @@ -// Package errors provides custom error types and error handling utilities. // nolint:mnd package errors diff --git a/backend/internal/pkg/gemini/models.go b/backend/internal/pkg/gemini/models.go index 6bab22fa..2be13c44 100644 --- a/backend/internal/pkg/gemini/models.go +++ b/backend/internal/pkg/gemini/models.go @@ -1,7 +1,7 @@ -// Package gemini provides minimal fallback model metadata for Gemini native endpoints. package gemini -// This package is used when upstream model listing is unavailable (e.g. OAuth token missing AI Studio scopes). +// This package provides minimal fallback model metadata for Gemini native endpoints. +// It is used when upstream model listing is unavailable (e.g. OAuth token missing AI Studio scopes). type Model struct { Name string `json:"name"` diff --git a/backend/internal/pkg/googleapi/status.go b/backend/internal/pkg/googleapi/status.go index 2186906d..b8def1eb 100644 --- a/backend/internal/pkg/googleapi/status.go +++ b/backend/internal/pkg/googleapi/status.go @@ -1,4 +1,3 @@ -// Package googleapi provides utilities for Google API interactions. package googleapi import "net/http" diff --git a/backend/internal/pkg/oauth/oauth.go b/backend/internal/pkg/oauth/oauth.go index a52d417a..22dbff3f 100644 --- a/backend/internal/pkg/oauth/oauth.go +++ b/backend/internal/pkg/oauth/oauth.go @@ -1,4 +1,3 @@ -// Package oauth provides OAuth 2.0 utilities including PKCE flow, session management, and token exchange. package oauth import ( diff --git a/backend/internal/pkg/openai/constants.go b/backend/internal/pkg/openai/constants.go index c784d06e..d97507a8 100644 --- a/backend/internal/pkg/openai/constants.go +++ b/backend/internal/pkg/openai/constants.go @@ -1,4 +1,3 @@ -// Package openai provides OpenAI API models and configuration. package openai import _ "embed" diff --git a/backend/internal/pkg/openai/oauth.go b/backend/internal/pkg/openai/oauth.go index 4dadf839..90d2e001 100644 --- a/backend/internal/pkg/openai/oauth.go +++ b/backend/internal/pkg/openai/oauth.go @@ -327,7 +327,7 @@ func ParseIDToken(idToken string) (*IDTokenClaims, error) { return &claims, nil } -// UserInfo extracts user information from ID Token claims +// ExtractUserInfo extracts user information from ID Token claims type UserInfo struct { Email string ChatGPTAccountID string diff --git a/backend/internal/pkg/pagination/pagination.go b/backend/internal/pkg/pagination/pagination.go index 4800c3eb..12ff321e 100644 --- a/backend/internal/pkg/pagination/pagination.go +++ b/backend/internal/pkg/pagination/pagination.go @@ -1,4 +1,3 @@ -// Package pagination provides utilities for handling paginated queries and results. package pagination // PaginationParams 分页参数 diff --git a/backend/internal/pkg/response/response.go b/backend/internal/pkg/response/response.go index 7b76ca6d..87dc4264 100644 --- a/backend/internal/pkg/response/response.go +++ b/backend/internal/pkg/response/response.go @@ -1,4 +1,3 @@ -// Package response provides HTTP response utilities for standardized API responses and error handling. package response import ( diff --git a/backend/internal/pkg/sysutil/restart.go b/backend/internal/pkg/sysutil/restart.go index 0dd0e244..f390a6cf 100644 --- a/backend/internal/pkg/sysutil/restart.go +++ b/backend/internal/pkg/sysutil/restart.go @@ -1,4 +1,3 @@ -// Package sysutil provides system-level utilities for service management. package sysutil import ( diff --git a/backend/internal/pkg/usagestats/usage_log_types.go b/backend/internal/pkg/usagestats/usage_log_types.go index b37fe97f..946501d4 100644 --- a/backend/internal/pkg/usagestats/usage_log_types.go +++ b/backend/internal/pkg/usagestats/usage_log_types.go @@ -1,4 +1,3 @@ -// Package usagestats defines types for tracking and reporting API usage statistics. package usagestats import "time" @@ -11,8 +10,8 @@ type DashboardStats struct { ActiveUsers int64 `json:"active_users"` // 今日有请求的用户数 // API Key 统计 - TotalAPIKeys int64 `json:"total_api_keys"` - ActiveAPIKeys int64 `json:"active_api_keys"` // 状态为 active 的 API Key 数 + TotalApiKeys int64 `json:"total_api_keys"` + ActiveApiKeys int64 `json:"active_api_keys"` // 状态为 active 的 API Key 数 // 账户统计 TotalAccounts int64 `json:"total_accounts"` @@ -83,10 +82,10 @@ type UserUsageTrendPoint struct { ActualCost float64 `json:"actual_cost"` // 实际扣除 } -// APIKeyUsageTrendPoint represents API key usage trend data point -type APIKeyUsageTrendPoint struct { +// ApiKeyUsageTrendPoint represents API key usage trend data point +type ApiKeyUsageTrendPoint struct { Date string `json:"date"` - APIKeyID int64 `json:"api_key_id"` + ApiKeyID int64 `json:"api_key_id"` KeyName string `json:"key_name"` Requests int64 `json:"requests"` Tokens int64 `json:"tokens"` @@ -95,8 +94,8 @@ type APIKeyUsageTrendPoint struct { // UserDashboardStats 用户仪表盘统计 type UserDashboardStats struct { // API Key 统计 - TotalAPIKeys int64 `json:"total_api_keys"` - ActiveAPIKeys int64 `json:"active_api_keys"` + TotalApiKeys int64 `json:"total_api_keys"` + ActiveApiKeys int64 `json:"active_api_keys"` // 累计 Token 使用统计 TotalRequests int64 `json:"total_requests"` @@ -129,7 +128,7 @@ type UserDashboardStats struct { // UsageLogFilters represents filters for usage log queries type UsageLogFilters struct { UserID int64 - APIKeyID int64 + ApiKeyID int64 AccountID int64 GroupID int64 Model string @@ -158,9 +157,9 @@ type BatchUserUsageStats struct { TotalActualCost float64 `json:"total_actual_cost"` } -// BatchAPIKeyUsageStats represents usage stats for a single API key -type BatchAPIKeyUsageStats struct { - APIKeyID int64 `json:"api_key_id"` +// BatchApiKeyUsageStats represents usage stats for a single API key +type BatchApiKeyUsageStats struct { + ApiKeyID int64 `json:"api_key_id"` TodayActualCost float64 `json:"today_actual_cost"` TotalActualCost float64 `json:"total_actual_cost"` } diff --git a/backend/internal/repository/account_repo_integration_test.go b/backend/internal/repository/account_repo_integration_test.go index 250b141d..84a88f23 100644 --- a/backend/internal/repository/account_repo_integration_test.go +++ b/backend/internal/repository/account_repo_integration_test.go @@ -135,12 +135,12 @@ func (s *AccountRepoSuite) TestListWithFilters() { name: "filter_by_type", setup: func(client *dbent.Client) { mustCreateAccount(s.T(), client, &service.Account{Name: "t1", Type: service.AccountTypeOAuth}) - mustCreateAccount(s.T(), client, &service.Account{Name: "t2", Type: service.AccountTypeAPIKey}) + mustCreateAccount(s.T(), client, &service.Account{Name: "t2", Type: service.AccountTypeApiKey}) }, - accType: service.AccountTypeAPIKey, + accType: service.AccountTypeApiKey, wantCount: 1, validate: func(accounts []service.Account) { - s.Require().Equal(service.AccountTypeAPIKey, accounts[0].Type) + s.Require().Equal(service.AccountTypeApiKey, accounts[0].Type) }, }, { diff --git a/backend/internal/repository/allowed_groups_contract_integration_test.go b/backend/internal/repository/allowed_groups_contract_integration_test.go index e12ef6cc..02cde527 100644 --- a/backend/internal/repository/allowed_groups_contract_integration_test.go +++ b/backend/internal/repository/allowed_groups_contract_integration_test.go @@ -80,7 +80,7 @@ func TestUserRepository_RemoveGroupFromAllowedGroups_RemovesAllOccurrences(t *te require.NotContains(t, u2After.AllowedGroups, targetGroup.ID) } -func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsAPIKeys(t *testing.T) { +func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsApiKeys(t *testing.T) { ctx := context.Background() tx := testEntTx(t) entClient := tx.Client() @@ -98,7 +98,7 @@ func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsAPIKeys(t *t userRepo := newUserRepositoryWithSQL(entClient, tx) groupRepo := newGroupRepositoryWithSQL(entClient, tx) - apiKeyRepo := NewAPIKeyRepository(entClient) + apiKeyRepo := NewApiKeyRepository(entClient) u := &service.User{ Email: uniqueTestValue(t, "cascade-user") + "@example.com", @@ -110,7 +110,7 @@ func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsAPIKeys(t *t } require.NoError(t, userRepo.Create(ctx, u)) - key := &service.APIKey{ + key := &service.ApiKey{ UserID: u.ID, Key: uniqueTestValue(t, "sk-test-delete-cascade"), Name: "test key", diff --git a/backend/internal/repository/api_key_cache.go b/backend/internal/repository/api_key_cache.go index 73a929c5..84565b47 100644 --- a/backend/internal/repository/api_key_cache.go +++ b/backend/internal/repository/api_key_cache.go @@ -24,7 +24,7 @@ type apiKeyCache struct { rdb *redis.Client } -func NewAPIKeyCache(rdb *redis.Client) service.APIKeyCache { +func NewApiKeyCache(rdb *redis.Client) service.ApiKeyCache { return &apiKeyCache{rdb: rdb} } diff --git a/backend/internal/repository/api_key_cache_integration_test.go b/backend/internal/repository/api_key_cache_integration_test.go index f3c4b244..e9394917 100644 --- a/backend/internal/repository/api_key_cache_integration_test.go +++ b/backend/internal/repository/api_key_cache_integration_test.go @@ -13,11 +13,11 @@ import ( "github.com/stretchr/testify/suite" ) -type APIKeyCacheSuite struct { +type ApiKeyCacheSuite struct { IntegrationRedisSuite } -func (s *APIKeyCacheSuite) TestCreateAttemptCount() { +func (s *ApiKeyCacheSuite) TestCreateAttemptCount() { tests := []struct { name string fn func(ctx context.Context, rdb *redis.Client, cache *apiKeyCache) @@ -78,7 +78,7 @@ func (s *APIKeyCacheSuite) TestCreateAttemptCount() { } } -func (s *APIKeyCacheSuite) TestDailyUsage() { +func (s *ApiKeyCacheSuite) TestDailyUsage() { tests := []struct { name string fn func(ctx context.Context, rdb *redis.Client, cache *apiKeyCache) @@ -122,6 +122,6 @@ func (s *APIKeyCacheSuite) TestDailyUsage() { } } -func TestAPIKeyCacheSuite(t *testing.T) { - suite.Run(t, new(APIKeyCacheSuite)) +func TestApiKeyCacheSuite(t *testing.T) { + suite.Run(t, new(ApiKeyCacheSuite)) } diff --git a/backend/internal/repository/api_key_cache_test.go b/backend/internal/repository/api_key_cache_test.go index b14a710c..7ad84ba2 100644 --- a/backend/internal/repository/api_key_cache_test.go +++ b/backend/internal/repository/api_key_cache_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestAPIKeyRateLimitKey(t *testing.T) { +func TestApiKeyRateLimitKey(t *testing.T) { tests := []struct { name string userID int64 diff --git a/backend/internal/repository/api_key_repo.go b/backend/internal/repository/api_key_repo.go index 8db905d0..9fcee1ca 100644 --- a/backend/internal/repository/api_key_repo.go +++ b/backend/internal/repository/api_key_repo.go @@ -16,17 +16,17 @@ type apiKeyRepository struct { client *dbent.Client } -func NewAPIKeyRepository(client *dbent.Client) service.APIKeyRepository { +func NewApiKeyRepository(client *dbent.Client) service.ApiKeyRepository { return &apiKeyRepository{client: client} } -func (r *apiKeyRepository) activeQuery() *dbent.APIKeyQuery { +func (r *apiKeyRepository) activeQuery() *dbent.ApiKeyQuery { // 默认过滤已软删除记录,避免删除后仍被查询到。 - return r.client.APIKey.Query().Where(apikey.DeletedAtIsNil()) + return r.client.ApiKey.Query().Where(apikey.DeletedAtIsNil()) } -func (r *apiKeyRepository) Create(ctx context.Context, key *service.APIKey) error { - created, err := r.client.APIKey.Create(). +func (r *apiKeyRepository) Create(ctx context.Context, key *service.ApiKey) error { + created, err := r.client.ApiKey.Create(). SetUserID(key.UserID). SetKey(key.Key). SetName(key.Name). @@ -38,10 +38,10 @@ func (r *apiKeyRepository) Create(ctx context.Context, key *service.APIKey) erro key.CreatedAt = created.CreatedAt key.UpdatedAt = created.UpdatedAt } - return translatePersistenceError(err, nil, service.ErrAPIKeyExists) + return translatePersistenceError(err, nil, service.ErrApiKeyExists) } -func (r *apiKeyRepository) GetByID(ctx context.Context, id int64) (*service.APIKey, error) { +func (r *apiKeyRepository) GetByID(ctx context.Context, id int64) (*service.ApiKey, error) { m, err := r.activeQuery(). Where(apikey.IDEQ(id)). WithUser(). @@ -49,7 +49,7 @@ func (r *apiKeyRepository) GetByID(ctx context.Context, id int64) (*service.APIK Only(ctx) if err != nil { if dbent.IsNotFound(err) { - return nil, service.ErrAPIKeyNotFound + return nil, service.ErrApiKeyNotFound } return nil, err } @@ -59,7 +59,7 @@ func (r *apiKeyRepository) GetByID(ctx context.Context, id int64) (*service.APIK // GetOwnerID 根据 API Key ID 获取其所有者(用户)的 ID。 // 相比 GetByID,此方法性能更优,因为: // - 使用 Select() 只查询 user_id 字段,减少数据传输量 -// - 不加载完整的 APIKey 实体及其关联数据(User、Group 等) +// - 不加载完整的 ApiKey 实体及其关联数据(User、Group 等) // - 适用于权限验证等只需用户 ID 的场景(如删除前的所有权检查) func (r *apiKeyRepository) GetOwnerID(ctx context.Context, id int64) (int64, error) { m, err := r.activeQuery(). @@ -68,14 +68,14 @@ func (r *apiKeyRepository) GetOwnerID(ctx context.Context, id int64) (int64, err Only(ctx) if err != nil { if dbent.IsNotFound(err) { - return 0, service.ErrAPIKeyNotFound + return 0, service.ErrApiKeyNotFound } return 0, err } return m.UserID, nil } -func (r *apiKeyRepository) GetByKey(ctx context.Context, key string) (*service.APIKey, error) { +func (r *apiKeyRepository) GetByKey(ctx context.Context, key string) (*service.ApiKey, error) { m, err := r.activeQuery(). Where(apikey.KeyEQ(key)). WithUser(). @@ -83,21 +83,21 @@ func (r *apiKeyRepository) GetByKey(ctx context.Context, key string) (*service.A Only(ctx) if err != nil { if dbent.IsNotFound(err) { - return nil, service.ErrAPIKeyNotFound + return nil, service.ErrApiKeyNotFound } return nil, err } return apiKeyEntityToService(m), nil } -func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) error { +func (r *apiKeyRepository) Update(ctx context.Context, key *service.ApiKey) error { // 使用原子操作:将软删除检查与更新合并到同一语句,避免竞态条件。 // 之前的实现先检查 Exist 再 UpdateOneID,若在两步之间发生软删除, // 则会更新已删除的记录。 // 这里选择 Update().Where(),确保只有未软删除记录能被更新。 // 同时显式设置 updated_at,避免二次查询带来的并发可见性问题。 now := time.Now() - builder := r.client.APIKey.Update(). + builder := r.client.ApiKey.Update(). Where(apikey.IDEQ(key.ID), apikey.DeletedAtIsNil()). SetName(key.Name). SetStatus(key.Status). @@ -114,7 +114,7 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro } if affected == 0 { // 更新影响行数为 0,说明记录不存在或已被软删除。 - return service.ErrAPIKeyNotFound + return service.ErrApiKeyNotFound } // 使用同一时间戳回填,避免并发删除导致二次查询失败。 @@ -124,18 +124,18 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro func (r *apiKeyRepository) Delete(ctx context.Context, id int64) error { // 显式软删除:避免依赖 Hook 行为,确保 deleted_at 一定被设置。 - affected, err := r.client.APIKey.Update(). + affected, err := r.client.ApiKey.Update(). Where(apikey.IDEQ(id), apikey.DeletedAtIsNil()). SetDeletedAt(time.Now()). Save(ctx) if err != nil { if dbent.IsNotFound(err) { - return service.ErrAPIKeyNotFound + return service.ErrApiKeyNotFound } return err } if affected == 0 { - exists, err := r.client.APIKey.Query(). + exists, err := r.client.ApiKey.Query(). Where(apikey.IDEQ(id)). Exist(mixins.SkipSoftDelete(ctx)) if err != nil { @@ -144,12 +144,12 @@ func (r *apiKeyRepository) Delete(ctx context.Context, id int64) error { if exists { return nil } - return service.ErrAPIKeyNotFound + return service.ErrApiKeyNotFound } return nil } -func (r *apiKeyRepository) ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]service.APIKey, *pagination.PaginationResult, error) { +func (r *apiKeyRepository) ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]service.ApiKey, *pagination.PaginationResult, error) { q := r.activeQuery().Where(apikey.UserIDEQ(userID)) total, err := q.Count(ctx) @@ -167,7 +167,7 @@ func (r *apiKeyRepository) ListByUserID(ctx context.Context, userID int64, param return nil, nil, err } - outKeys := make([]service.APIKey, 0, len(keys)) + outKeys := make([]service.ApiKey, 0, len(keys)) for i := range keys { outKeys = append(outKeys, *apiKeyEntityToService(keys[i])) } @@ -180,7 +180,7 @@ func (r *apiKeyRepository) VerifyOwnership(ctx context.Context, userID int64, ap return []int64{}, nil } - ids, err := r.client.APIKey.Query(). + ids, err := r.client.ApiKey.Query(). Where(apikey.UserIDEQ(userID), apikey.IDIn(apiKeyIDs...), apikey.DeletedAtIsNil()). IDs(ctx) if err != nil { @@ -199,7 +199,7 @@ func (r *apiKeyRepository) ExistsByKey(ctx context.Context, key string) (bool, e return count > 0, err } -func (r *apiKeyRepository) ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]service.APIKey, *pagination.PaginationResult, error) { +func (r *apiKeyRepository) ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]service.ApiKey, *pagination.PaginationResult, error) { q := r.activeQuery().Where(apikey.GroupIDEQ(groupID)) total, err := q.Count(ctx) @@ -217,7 +217,7 @@ func (r *apiKeyRepository) ListByGroupID(ctx context.Context, groupID int64, par return nil, nil, err } - outKeys := make([]service.APIKey, 0, len(keys)) + outKeys := make([]service.ApiKey, 0, len(keys)) for i := range keys { outKeys = append(outKeys, *apiKeyEntityToService(keys[i])) } @@ -225,8 +225,8 @@ func (r *apiKeyRepository) ListByGroupID(ctx context.Context, groupID int64, par return outKeys, paginationResultFromTotal(int64(total), params), nil } -// SearchAPIKeys searches API keys by user ID and/or keyword (name) -func (r *apiKeyRepository) SearchAPIKeys(ctx context.Context, userID int64, keyword string, limit int) ([]service.APIKey, error) { +// SearchApiKeys searches API keys by user ID and/or keyword (name) +func (r *apiKeyRepository) SearchApiKeys(ctx context.Context, userID int64, keyword string, limit int) ([]service.ApiKey, error) { q := r.activeQuery() if userID > 0 { q = q.Where(apikey.UserIDEQ(userID)) @@ -241,7 +241,7 @@ func (r *apiKeyRepository) SearchAPIKeys(ctx context.Context, userID int64, keyw return nil, err } - outKeys := make([]service.APIKey, 0, len(keys)) + outKeys := make([]service.ApiKey, 0, len(keys)) for i := range keys { outKeys = append(outKeys, *apiKeyEntityToService(keys[i])) } @@ -250,7 +250,7 @@ func (r *apiKeyRepository) SearchAPIKeys(ctx context.Context, userID int64, keyw // ClearGroupIDByGroupID 将指定分组的所有 API Key 的 group_id 设为 nil func (r *apiKeyRepository) ClearGroupIDByGroupID(ctx context.Context, groupID int64) (int64, error) { - n, err := r.client.APIKey.Update(). + n, err := r.client.ApiKey.Update(). Where(apikey.GroupIDEQ(groupID), apikey.DeletedAtIsNil()). ClearGroupID(). Save(ctx) @@ -263,11 +263,11 @@ func (r *apiKeyRepository) CountByGroupID(ctx context.Context, groupID int64) (i return int64(count), err } -func apiKeyEntityToService(m *dbent.APIKey) *service.APIKey { +func apiKeyEntityToService(m *dbent.ApiKey) *service.ApiKey { if m == nil { return nil } - out := &service.APIKey{ + out := &service.ApiKey{ ID: m.ID, UserID: m.UserID, Key: m.Key, diff --git a/backend/internal/repository/api_key_repo_integration_test.go b/backend/internal/repository/api_key_repo_integration_test.go index 4b3161e4..79564ff0 100644 --- a/backend/internal/repository/api_key_repo_integration_test.go +++ b/backend/internal/repository/api_key_repo_integration_test.go @@ -12,30 +12,30 @@ import ( "github.com/stretchr/testify/suite" ) -type APIKeyRepoSuite struct { +type ApiKeyRepoSuite struct { suite.Suite ctx context.Context client *dbent.Client repo *apiKeyRepository } -func (s *APIKeyRepoSuite) SetupTest() { +func (s *ApiKeyRepoSuite) SetupTest() { s.ctx = context.Background() tx := testEntTx(s.T()) s.client = tx.Client() - s.repo = NewAPIKeyRepository(s.client).(*apiKeyRepository) + s.repo = NewApiKeyRepository(s.client).(*apiKeyRepository) } -func TestAPIKeyRepoSuite(t *testing.T) { - suite.Run(t, new(APIKeyRepoSuite)) +func TestApiKeyRepoSuite(t *testing.T) { + suite.Run(t, new(ApiKeyRepoSuite)) } // --- Create / GetByID / GetByKey --- -func (s *APIKeyRepoSuite) TestCreate() { +func (s *ApiKeyRepoSuite) TestCreate() { user := s.mustCreateUser("create@test.com") - key := &service.APIKey{ + key := &service.ApiKey{ UserID: user.ID, Key: "sk-create-test", Name: "Test Key", @@ -51,16 +51,16 @@ func (s *APIKeyRepoSuite) TestCreate() { s.Require().Equal("sk-create-test", got.Key) } -func (s *APIKeyRepoSuite) TestGetByID_NotFound() { +func (s *ApiKeyRepoSuite) TestGetByID_NotFound() { _, err := s.repo.GetByID(s.ctx, 999999) s.Require().Error(err, "expected error for non-existent ID") } -func (s *APIKeyRepoSuite) TestGetByKey() { +func (s *ApiKeyRepoSuite) TestGetByKey() { user := s.mustCreateUser("getbykey@test.com") group := s.mustCreateGroup("g-key") - key := &service.APIKey{ + key := &service.ApiKey{ UserID: user.ID, Key: "sk-getbykey", Name: "My Key", @@ -78,16 +78,16 @@ func (s *APIKeyRepoSuite) TestGetByKey() { s.Require().Equal(group.ID, got.Group.ID) } -func (s *APIKeyRepoSuite) TestGetByKey_NotFound() { +func (s *ApiKeyRepoSuite) TestGetByKey_NotFound() { _, err := s.repo.GetByKey(s.ctx, "non-existent-key") s.Require().Error(err, "expected error for non-existent key") } // --- Update --- -func (s *APIKeyRepoSuite) TestUpdate() { +func (s *ApiKeyRepoSuite) TestUpdate() { user := s.mustCreateUser("update@test.com") - key := &service.APIKey{ + key := &service.ApiKey{ UserID: user.ID, Key: "sk-update", Name: "Original", @@ -108,10 +108,10 @@ func (s *APIKeyRepoSuite) TestUpdate() { s.Require().Equal(service.StatusDisabled, got.Status) } -func (s *APIKeyRepoSuite) TestUpdate_ClearGroupID() { +func (s *ApiKeyRepoSuite) TestUpdate_ClearGroupID() { user := s.mustCreateUser("cleargroup@test.com") group := s.mustCreateGroup("g-clear") - key := &service.APIKey{ + key := &service.ApiKey{ UserID: user.ID, Key: "sk-clear-group", Name: "Group Key", @@ -131,9 +131,9 @@ func (s *APIKeyRepoSuite) TestUpdate_ClearGroupID() { // --- Delete --- -func (s *APIKeyRepoSuite) TestDelete() { +func (s *ApiKeyRepoSuite) TestDelete() { user := s.mustCreateUser("delete@test.com") - key := &service.APIKey{ + key := &service.ApiKey{ UserID: user.ID, Key: "sk-delete", Name: "Delete Me", @@ -150,10 +150,10 @@ func (s *APIKeyRepoSuite) TestDelete() { // --- ListByUserID / CountByUserID --- -func (s *APIKeyRepoSuite) TestListByUserID() { +func (s *ApiKeyRepoSuite) TestListByUserID() { user := s.mustCreateUser("listbyuser@test.com") - s.mustCreateAPIKey(user.ID, "sk-list-1", "Key 1", nil) - s.mustCreateAPIKey(user.ID, "sk-list-2", "Key 2", nil) + s.mustCreateApiKey(user.ID, "sk-list-1", "Key 1", nil) + s.mustCreateApiKey(user.ID, "sk-list-2", "Key 2", nil) keys, page, err := s.repo.ListByUserID(s.ctx, user.ID, pagination.PaginationParams{Page: 1, PageSize: 10}) s.Require().NoError(err, "ListByUserID") @@ -161,10 +161,10 @@ func (s *APIKeyRepoSuite) TestListByUserID() { s.Require().Equal(int64(2), page.Total) } -func (s *APIKeyRepoSuite) TestListByUserID_Pagination() { +func (s *ApiKeyRepoSuite) TestListByUserID_Pagination() { user := s.mustCreateUser("paging@test.com") for i := 0; i < 5; i++ { - s.mustCreateAPIKey(user.ID, "sk-page-"+string(rune('a'+i)), "Key", nil) + s.mustCreateApiKey(user.ID, "sk-page-"+string(rune('a'+i)), "Key", nil) } keys, page, err := s.repo.ListByUserID(s.ctx, user.ID, pagination.PaginationParams{Page: 1, PageSize: 2}) @@ -174,10 +174,10 @@ func (s *APIKeyRepoSuite) TestListByUserID_Pagination() { s.Require().Equal(3, page.Pages) } -func (s *APIKeyRepoSuite) TestCountByUserID() { +func (s *ApiKeyRepoSuite) TestCountByUserID() { user := s.mustCreateUser("count@test.com") - s.mustCreateAPIKey(user.ID, "sk-count-1", "K1", nil) - s.mustCreateAPIKey(user.ID, "sk-count-2", "K2", nil) + s.mustCreateApiKey(user.ID, "sk-count-1", "K1", nil) + s.mustCreateApiKey(user.ID, "sk-count-2", "K2", nil) count, err := s.repo.CountByUserID(s.ctx, user.ID) s.Require().NoError(err, "CountByUserID") @@ -186,13 +186,13 @@ func (s *APIKeyRepoSuite) TestCountByUserID() { // --- ListByGroupID / CountByGroupID --- -func (s *APIKeyRepoSuite) TestListByGroupID() { +func (s *ApiKeyRepoSuite) TestListByGroupID() { user := s.mustCreateUser("listbygroup@test.com") group := s.mustCreateGroup("g-list") - s.mustCreateAPIKey(user.ID, "sk-grp-1", "K1", &group.ID) - s.mustCreateAPIKey(user.ID, "sk-grp-2", "K2", &group.ID) - s.mustCreateAPIKey(user.ID, "sk-grp-3", "K3", nil) // no group + s.mustCreateApiKey(user.ID, "sk-grp-1", "K1", &group.ID) + s.mustCreateApiKey(user.ID, "sk-grp-2", "K2", &group.ID) + s.mustCreateApiKey(user.ID, "sk-grp-3", "K3", nil) // no group keys, page, err := s.repo.ListByGroupID(s.ctx, group.ID, pagination.PaginationParams{Page: 1, PageSize: 10}) s.Require().NoError(err, "ListByGroupID") @@ -202,10 +202,10 @@ func (s *APIKeyRepoSuite) TestListByGroupID() { s.Require().NotNil(keys[0].User) } -func (s *APIKeyRepoSuite) TestCountByGroupID() { +func (s *ApiKeyRepoSuite) TestCountByGroupID() { user := s.mustCreateUser("countgroup@test.com") group := s.mustCreateGroup("g-count") - s.mustCreateAPIKey(user.ID, "sk-gc-1", "K1", &group.ID) + s.mustCreateApiKey(user.ID, "sk-gc-1", "K1", &group.ID) count, err := s.repo.CountByGroupID(s.ctx, group.ID) s.Require().NoError(err, "CountByGroupID") @@ -214,9 +214,9 @@ func (s *APIKeyRepoSuite) TestCountByGroupID() { // --- ExistsByKey --- -func (s *APIKeyRepoSuite) TestExistsByKey() { +func (s *ApiKeyRepoSuite) TestExistsByKey() { user := s.mustCreateUser("exists@test.com") - s.mustCreateAPIKey(user.ID, "sk-exists", "K", nil) + s.mustCreateApiKey(user.ID, "sk-exists", "K", nil) exists, err := s.repo.ExistsByKey(s.ctx, "sk-exists") s.Require().NoError(err, "ExistsByKey") @@ -227,47 +227,47 @@ func (s *APIKeyRepoSuite) TestExistsByKey() { s.Require().False(notExists) } -// --- SearchAPIKeys --- +// --- SearchApiKeys --- -func (s *APIKeyRepoSuite) TestSearchAPIKeys() { +func (s *ApiKeyRepoSuite) TestSearchApiKeys() { user := s.mustCreateUser("search@test.com") - s.mustCreateAPIKey(user.ID, "sk-search-1", "Production Key", nil) - s.mustCreateAPIKey(user.ID, "sk-search-2", "Development Key", nil) + s.mustCreateApiKey(user.ID, "sk-search-1", "Production Key", nil) + s.mustCreateApiKey(user.ID, "sk-search-2", "Development Key", nil) - found, err := s.repo.SearchAPIKeys(s.ctx, user.ID, "prod", 10) - s.Require().NoError(err, "SearchAPIKeys") + found, err := s.repo.SearchApiKeys(s.ctx, user.ID, "prod", 10) + s.Require().NoError(err, "SearchApiKeys") s.Require().Len(found, 1) s.Require().Contains(found[0].Name, "Production") } -func (s *APIKeyRepoSuite) TestSearchAPIKeys_NoKeyword() { +func (s *ApiKeyRepoSuite) TestSearchApiKeys_NoKeyword() { user := s.mustCreateUser("searchnokw@test.com") - s.mustCreateAPIKey(user.ID, "sk-nk-1", "K1", nil) - s.mustCreateAPIKey(user.ID, "sk-nk-2", "K2", nil) + s.mustCreateApiKey(user.ID, "sk-nk-1", "K1", nil) + s.mustCreateApiKey(user.ID, "sk-nk-2", "K2", nil) - found, err := s.repo.SearchAPIKeys(s.ctx, user.ID, "", 10) + found, err := s.repo.SearchApiKeys(s.ctx, user.ID, "", 10) s.Require().NoError(err) s.Require().Len(found, 2) } -func (s *APIKeyRepoSuite) TestSearchAPIKeys_NoUserID() { +func (s *ApiKeyRepoSuite) TestSearchApiKeys_NoUserID() { user := s.mustCreateUser("searchnouid@test.com") - s.mustCreateAPIKey(user.ID, "sk-nu-1", "TestKey", nil) + s.mustCreateApiKey(user.ID, "sk-nu-1", "TestKey", nil) - found, err := s.repo.SearchAPIKeys(s.ctx, 0, "testkey", 10) + found, err := s.repo.SearchApiKeys(s.ctx, 0, "testkey", 10) s.Require().NoError(err) s.Require().Len(found, 1) } // --- ClearGroupIDByGroupID --- -func (s *APIKeyRepoSuite) TestClearGroupIDByGroupID() { +func (s *ApiKeyRepoSuite) TestClearGroupIDByGroupID() { user := s.mustCreateUser("cleargrp@test.com") group := s.mustCreateGroup("g-clear-bulk") - k1 := s.mustCreateAPIKey(user.ID, "sk-clr-1", "K1", &group.ID) - k2 := s.mustCreateAPIKey(user.ID, "sk-clr-2", "K2", &group.ID) - s.mustCreateAPIKey(user.ID, "sk-clr-3", "K3", nil) // no group + k1 := s.mustCreateApiKey(user.ID, "sk-clr-1", "K1", &group.ID) + k2 := s.mustCreateApiKey(user.ID, "sk-clr-2", "K2", &group.ID) + s.mustCreateApiKey(user.ID, "sk-clr-3", "K3", nil) // no group affected, err := s.repo.ClearGroupIDByGroupID(s.ctx, group.ID) s.Require().NoError(err, "ClearGroupIDByGroupID") @@ -284,10 +284,10 @@ func (s *APIKeyRepoSuite) TestClearGroupIDByGroupID() { // --- Combined CRUD/Search/ClearGroupID (original test preserved as integration) --- -func (s *APIKeyRepoSuite) TestCRUD_Search_ClearGroupID() { +func (s *ApiKeyRepoSuite) TestCRUD_Search_ClearGroupID() { user := s.mustCreateUser("k@example.com") group := s.mustCreateGroup("g-k") - key := s.mustCreateAPIKey(user.ID, "sk-test-1", "My Key", &group.ID) + key := s.mustCreateApiKey(user.ID, "sk-test-1", "My Key", &group.ID) key.GroupID = &group.ID got, err := s.repo.GetByKey(s.ctx, key.Key) @@ -320,13 +320,13 @@ func (s *APIKeyRepoSuite) TestCRUD_Search_ClearGroupID() { s.Require().NoError(err, "ExistsByKey") s.Require().True(exists, "expected key to exist") - found, err := s.repo.SearchAPIKeys(s.ctx, user.ID, "renam", 10) - s.Require().NoError(err, "SearchAPIKeys") + found, err := s.repo.SearchApiKeys(s.ctx, user.ID, "renam", 10) + s.Require().NoError(err, "SearchApiKeys") s.Require().Len(found, 1) s.Require().Equal(key.ID, found[0].ID) // ClearGroupIDByGroupID - k2 := s.mustCreateAPIKey(user.ID, "sk-test-2", "Group Key", &group.ID) + k2 := s.mustCreateApiKey(user.ID, "sk-test-2", "Group Key", &group.ID) k2.GroupID = &group.ID countBefore, err := s.repo.CountByGroupID(s.ctx, group.ID) @@ -346,7 +346,7 @@ func (s *APIKeyRepoSuite) TestCRUD_Search_ClearGroupID() { s.Require().Equal(int64(0), countAfter, "expected 0 keys in group after clear") } -func (s *APIKeyRepoSuite) mustCreateUser(email string) *service.User { +func (s *ApiKeyRepoSuite) mustCreateUser(email string) *service.User { s.T().Helper() u, err := s.client.User.Create(). @@ -359,7 +359,7 @@ func (s *APIKeyRepoSuite) mustCreateUser(email string) *service.User { return userEntityToService(u) } -func (s *APIKeyRepoSuite) mustCreateGroup(name string) *service.Group { +func (s *ApiKeyRepoSuite) mustCreateGroup(name string) *service.Group { s.T().Helper() g, err := s.client.Group.Create(). @@ -370,10 +370,10 @@ func (s *APIKeyRepoSuite) mustCreateGroup(name string) *service.Group { return groupEntityToService(g) } -func (s *APIKeyRepoSuite) mustCreateAPIKey(userID int64, key, name string, groupID *int64) *service.APIKey { +func (s *ApiKeyRepoSuite) mustCreateApiKey(userID int64, key, name string, groupID *int64) *service.ApiKey { s.T().Helper() - k := &service.APIKey{ + k := &service.ApiKey{ UserID: userID, Key: key, Name: name, diff --git a/backend/internal/repository/ent.go b/backend/internal/repository/ent.go index 9df74a83..d457ba72 100644 --- a/backend/internal/repository/ent.go +++ b/backend/internal/repository/ent.go @@ -1,4 +1,4 @@ -// Package repository 提供应用程序的基础设施层组件。 +// Package infrastructure 提供应用程序的基础设施层组件。 // 包括数据库连接初始化、ORM 客户端管理、Redis 连接、数据库迁移等核心功能。 package repository diff --git a/backend/internal/repository/fixtures_integration_test.go b/backend/internal/repository/fixtures_integration_test.go index c606b75e..ab8e8a4f 100644 --- a/backend/internal/repository/fixtures_integration_test.go +++ b/backend/internal/repository/fixtures_integration_test.go @@ -243,7 +243,7 @@ func mustCreateAccount(t *testing.T, client *dbent.Client, a *service.Account) * return a } -func mustCreateAPIKey(t *testing.T, client *dbent.Client, k *service.APIKey) *service.APIKey { +func mustCreateApiKey(t *testing.T, client *dbent.Client, k *service.ApiKey) *service.ApiKey { t.Helper() ctx := context.Background() @@ -257,7 +257,7 @@ func mustCreateAPIKey(t *testing.T, client *dbent.Client, k *service.APIKey) *se k.Name = "default" } - create := client.APIKey.Create(). + create := client.ApiKey.Create(). SetUserID(k.UserID). SetKey(k.Key). SetName(k.Name). diff --git a/backend/internal/repository/group_repo.go b/backend/internal/repository/group_repo.go index c4597ce2..53085247 100644 --- a/backend/internal/repository/group_repo.go +++ b/backend/internal/repository/group_repo.go @@ -293,8 +293,8 @@ func (r *groupRepository) DeleteCascade(ctx context.Context, id int64) ([]int64, // 2. Clear group_id for api keys bound to this group. // 仅更新未软删除的记录,避免修改已删除数据,保证审计与历史回溯一致性。 - // 与 APIKeyRepository 的软删除语义保持一致,减少跨模块行为差异。 - if _, err := txClient.APIKey.Update(). + // 与 ApiKeyRepository 的软删除语义保持一致,减少跨模块行为差异。 + if _, err := txClient.ApiKey.Update(). Where(apikey.GroupIDEQ(id), apikey.DeletedAtIsNil()). ClearGroupID(). Save(ctx); err != nil { diff --git a/backend/internal/repository/soft_delete_ent_integration_test.go b/backend/internal/repository/soft_delete_ent_integration_test.go index ccba9043..e3560ab5 100644 --- a/backend/internal/repository/soft_delete_ent_integration_test.go +++ b/backend/internal/repository/soft_delete_ent_integration_test.go @@ -34,15 +34,15 @@ func createEntUser(t *testing.T, ctx context.Context, client *dbent.Client, emai return u } -func TestEntSoftDelete_APIKey_DefaultFilterAndSkip(t *testing.T) { +func TestEntSoftDelete_ApiKey_DefaultFilterAndSkip(t *testing.T) { ctx := context.Background() // 使用全局 ent client,确保软删除验证在实际持久化数据上进行。 client := testEntClient(t) u := createEntUser(t, ctx, client, uniqueSoftDeleteValue(t, "sd-user")+"@example.com") - repo := NewAPIKeyRepository(client) - key := &service.APIKey{ + repo := NewApiKeyRepository(client) + key := &service.ApiKey{ UserID: u.ID, Key: uniqueSoftDeleteValue(t, "sk-soft-delete"), Name: "soft-delete", @@ -53,28 +53,28 @@ func TestEntSoftDelete_APIKey_DefaultFilterAndSkip(t *testing.T) { require.NoError(t, repo.Delete(ctx, key.ID), "soft delete api key") _, err := repo.GetByID(ctx, key.ID) - require.ErrorIs(t, err, service.ErrAPIKeyNotFound, "deleted rows should be hidden by default") + require.ErrorIs(t, err, service.ErrApiKeyNotFound, "deleted rows should be hidden by default") - _, err = client.APIKey.Query().Where(apikey.IDEQ(key.ID)).Only(ctx) + _, err = client.ApiKey.Query().Where(apikey.IDEQ(key.ID)).Only(ctx) require.Error(t, err, "default ent query should not see soft-deleted rows") require.True(t, dbent.IsNotFound(err), "expected ent not-found after default soft delete filter") - got, err := client.APIKey.Query(). + got, err := client.ApiKey.Query(). Where(apikey.IDEQ(key.ID)). Only(mixins.SkipSoftDelete(ctx)) require.NoError(t, err, "SkipSoftDelete should include soft-deleted rows") require.NotNil(t, got.DeletedAt, "deleted_at should be set after soft delete") } -func TestEntSoftDelete_APIKey_DeleteIdempotent(t *testing.T) { +func TestEntSoftDelete_ApiKey_DeleteIdempotent(t *testing.T) { ctx := context.Background() // 使用全局 ent client,避免事务回滚影响幂等性验证。 client := testEntClient(t) u := createEntUser(t, ctx, client, uniqueSoftDeleteValue(t, "sd-user2")+"@example.com") - repo := NewAPIKeyRepository(client) - key := &service.APIKey{ + repo := NewApiKeyRepository(client) + key := &service.ApiKey{ UserID: u.ID, Key: uniqueSoftDeleteValue(t, "sk-soft-delete2"), Name: "soft-delete2", @@ -86,15 +86,15 @@ func TestEntSoftDelete_APIKey_DeleteIdempotent(t *testing.T) { require.NoError(t, repo.Delete(ctx, key.ID), "second delete should be idempotent") } -func TestEntSoftDelete_APIKey_HardDeleteViaSkipSoftDelete(t *testing.T) { +func TestEntSoftDelete_ApiKey_HardDeleteViaSkipSoftDelete(t *testing.T) { ctx := context.Background() // 使用全局 ent client,确保 SkipSoftDelete 的硬删除语义可验证。 client := testEntClient(t) u := createEntUser(t, ctx, client, uniqueSoftDeleteValue(t, "sd-user3")+"@example.com") - repo := NewAPIKeyRepository(client) - key := &service.APIKey{ + repo := NewApiKeyRepository(client) + key := &service.ApiKey{ UserID: u.ID, Key: uniqueSoftDeleteValue(t, "sk-soft-delete3"), Name: "soft-delete3", @@ -105,10 +105,10 @@ func TestEntSoftDelete_APIKey_HardDeleteViaSkipSoftDelete(t *testing.T) { require.NoError(t, repo.Delete(ctx, key.ID), "soft delete api key") // Hard delete using SkipSoftDelete so the hook doesn't convert it to update-deleted_at. - _, err := client.APIKey.Delete().Where(apikey.IDEQ(key.ID)).Exec(mixins.SkipSoftDelete(ctx)) + _, err := client.ApiKey.Delete().Where(apikey.IDEQ(key.ID)).Exec(mixins.SkipSoftDelete(ctx)) require.NoError(t, err, "hard delete") - _, err = client.APIKey.Query(). + _, err = client.ApiKey.Query(). Where(apikey.IDEQ(key.ID)). Only(mixins.SkipSoftDelete(ctx)) require.True(t, dbent.IsNotFound(err), "expected row to be hard deleted") diff --git a/backend/internal/repository/user_repo.go b/backend/internal/repository/user_repo.go index 57c2ef83..7a6c9915 100644 --- a/backend/internal/repository/user_repo.go +++ b/backend/internal/repository/user_repo.go @@ -4,12 +4,13 @@ import ( "context" "database/sql" "errors" + "fmt" "sort" + "strings" dbent "github.com/Wei-Shaw/sub2api/ent" dbuser "github.com/Wei-Shaw/sub2api/ent/user" "github.com/Wei-Shaw/sub2api/ent/userallowedgroup" - "github.com/Wei-Shaw/sub2api/ent/userattributevalue" "github.com/Wei-Shaw/sub2api/ent/usersubscription" "github.com/Wei-Shaw/sub2api/internal/pkg/pagination" "github.com/Wei-Shaw/sub2api/internal/service" @@ -17,14 +18,15 @@ import ( type userRepository struct { client *dbent.Client + sql sqlExecutor } func NewUserRepository(client *dbent.Client, sqlDB *sql.DB) service.UserRepository { return newUserRepositoryWithSQL(client, sqlDB) } -func newUserRepositoryWithSQL(client *dbent.Client, _ sqlExecutor) *userRepository { - return &userRepository{client: client} +func newUserRepositoryWithSQL(client *dbent.Client, sqlq sqlExecutor) *userRepository { + return &userRepository{client: client, sql: sqlq} } func (r *userRepository) Create(ctx context.Context, userIn *service.User) error { @@ -194,7 +196,11 @@ func (r *userRepository) ListWithFilters(ctx context.Context, params pagination. // If attribute filters are specified, we need to filter by user IDs first var allowedUserIDs []int64 if len(filters.Attributes) > 0 { - allowedUserIDs = r.filterUsersByAttributes(ctx, filters.Attributes) + var attrErr error + allowedUserIDs, attrErr = r.filterUsersByAttributes(ctx, filters.Attributes) + if attrErr != nil { + return nil, nil, attrErr + } if len(allowedUserIDs) == 0 { // No users match the attribute filters return []service.User{}, paginationResultFromTotal(0, params), nil @@ -262,56 +268,53 @@ func (r *userRepository) ListWithFilters(ctx context.Context, params pagination. } // filterUsersByAttributes returns user IDs that match ALL the given attribute filters -func (r *userRepository) filterUsersByAttributes(ctx context.Context, attrs map[int64]string) []int64 { +func (r *userRepository) filterUsersByAttributes(ctx context.Context, attrs map[int64]string) ([]int64, error) { if len(attrs) == 0 { - return nil + return nil, nil } - // For each attribute filter, get the set of matching user IDs - // Then intersect all sets to get users matching ALL filters - var resultSet map[int64]struct{} - first := true + if r.sql == nil { + return nil, fmt.Errorf("sql executor is not configured") + } + clauses := make([]string, 0, len(attrs)) + args := make([]any, 0, len(attrs)*2+1) + argIndex := 1 for attrID, value := range attrs { - // Query user_attribute_values for this attribute - values, err := r.client.UserAttributeValue.Query(). - Where( - userattributevalue.AttributeIDEQ(attrID), - userattributevalue.ValueContainsFold(value), - ). - All(ctx) - if err != nil { - continue - } - - currentSet := make(map[int64]struct{}, len(values)) - for _, v := range values { - currentSet[v.UserID] = struct{}{} - } - - if first { - resultSet = currentSet - first = false - } else { - // Intersect with previous results - for userID := range resultSet { - if _, ok := currentSet[userID]; !ok { - delete(resultSet, userID) - } - } - } - - // Early exit if no users match - if len(resultSet) == 0 { - return nil - } + clauses = append(clauses, fmt.Sprintf("(attribute_id = $%d AND value ILIKE $%d)", argIndex, argIndex+1)) + args = append(args, attrID, "%"+value+"%") + argIndex += 2 } - result := make([]int64, 0, len(resultSet)) - for userID := range resultSet { + query := fmt.Sprintf( + `SELECT user_id + FROM user_attribute_values + WHERE %s + GROUP BY user_id + HAVING COUNT(DISTINCT attribute_id) = $%d`, + strings.Join(clauses, " OR "), + argIndex, + ) + args = append(args, len(attrs)) + + rows, err := r.sql.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + result := make([]int64, 0) + for rows.Next() { + var userID int64 + if scanErr := rows.Scan(&userID); scanErr != nil { + return nil, scanErr + } result = append(result, userID) } - return result + if err := rows.Err(); err != nil { + return nil, err + } + return result, nil } func (r *userRepository) UpdateBalance(ctx context.Context, id int64, amount float64) error { diff --git a/backend/internal/repository/wire.go b/backend/internal/repository/wire.go index 2aeb152c..198aed48 100644 --- a/backend/internal/repository/wire.go +++ b/backend/internal/repository/wire.go @@ -28,13 +28,12 @@ func ProvideConcurrencyCache(rdb *redis.Client, cfg *config.Config) service.Conc // ProviderSet is the Wire provider set for all repositories var ProviderSet = wire.NewSet( NewUserRepository, - NewAPIKeyRepository, + NewApiKeyRepository, NewGroupRepository, NewAccountRepository, NewProxyRepository, NewRedeemCodeRepository, NewUsageLogRepository, - NewOpsRepository, NewSettingRepository, NewUserSubscriptionRepository, NewUserAttributeDefinitionRepository, @@ -43,7 +42,8 @@ var ProviderSet = wire.NewSet( // Cache implementations NewGatewayCache, NewBillingCache, - NewAPIKeyCache, + NewApiKeyCache, + NewTempUnschedCache, ProvideConcurrencyCache, NewEmailCache, NewIdentityCache, diff --git a/backend/internal/server/http.go b/backend/internal/server/http.go index 81a993c0..b64220d9 100644 --- a/backend/internal/server/http.go +++ b/backend/internal/server/http.go @@ -1,4 +1,3 @@ -// Package server provides HTTP server setup and routing configuration. package server import ( @@ -26,8 +25,8 @@ func ProvideRouter( handlers *handler.Handlers, jwtAuth middleware2.JWTAuthMiddleware, adminAuth middleware2.AdminAuthMiddleware, - apiKeyAuth middleware2.APIKeyAuthMiddleware, - apiKeyService *service.APIKeyService, + apiKeyAuth middleware2.ApiKeyAuthMiddleware, + apiKeyService *service.ApiKeyService, subscriptionService *service.SubscriptionService, ) *gin.Engine { if cfg.Server.Mode == "release" { diff --git a/backend/internal/server/middleware/admin_auth.go b/backend/internal/server/middleware/admin_auth.go index 02e339ec..4f22d80c 100644 --- a/backend/internal/server/middleware/admin_auth.go +++ b/backend/internal/server/middleware/admin_auth.go @@ -32,7 +32,7 @@ func adminAuth( // 检查 x-api-key header(Admin API Key 认证) apiKey := c.GetHeader("x-api-key") if apiKey != "" { - if !validateAdminAPIKey(c, apiKey, settingService, userService) { + if !validateAdminApiKey(c, apiKey, settingService, userService) { return } c.Next() @@ -52,48 +52,19 @@ func adminAuth( } } - // WebSocket 请求无法设置自定义 header,允许在 query 中携带凭证 - if isWebSocketRequest(c) { - if token := strings.TrimSpace(c.Query("token")); token != "" { - if !validateJWTForAdmin(c, token, authService, userService) { - return - } - c.Next() - return - } - if apiKey := strings.TrimSpace(c.Query("api_key")); apiKey != "" { - if !validateAdminAPIKey(c, apiKey, settingService, userService) { - return - } - c.Next() - return - } - } - // 无有效认证信息 AbortWithError(c, 401, "UNAUTHORIZED", "Authorization required") } } -func isWebSocketRequest(c *gin.Context) bool { - if c == nil || c.Request == nil { - return false - } - if strings.EqualFold(c.GetHeader("Upgrade"), "websocket") { - return true - } - conn := strings.ToLower(c.GetHeader("Connection")) - return strings.Contains(conn, "upgrade") && strings.EqualFold(c.GetHeader("Upgrade"), "websocket") -} - -// validateAdminAPIKey 验证管理员 API Key -func validateAdminAPIKey( +// validateAdminApiKey 验证管理员 API Key +func validateAdminApiKey( c *gin.Context, key string, settingService *service.SettingService, userService *service.UserService, ) bool { - storedKey, err := settingService.GetAdminAPIKey(c.Request.Context()) + storedKey, err := settingService.GetAdminApiKey(c.Request.Context()) if err != nil { AbortWithError(c, 500, "INTERNAL_ERROR", "Internal server error") return false diff --git a/backend/internal/server/middleware/api_key_auth.go b/backend/internal/server/middleware/api_key_auth.go index c63d712d..75e508dd 100644 --- a/backend/internal/server/middleware/api_key_auth.go +++ b/backend/internal/server/middleware/api_key_auth.go @@ -11,13 +11,13 @@ import ( "github.com/gin-gonic/gin" ) -// NewAPIKeyAuthMiddleware 创建 API Key 认证中间件 -func NewAPIKeyAuthMiddleware(apiKeyService *service.APIKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config, opsService *service.OpsService) APIKeyAuthMiddleware { - return APIKeyAuthMiddleware(apiKeyAuthWithSubscription(apiKeyService, subscriptionService, cfg, opsService)) +// NewApiKeyAuthMiddleware 创建 API Key 认证中间件 +func NewApiKeyAuthMiddleware(apiKeyService *service.ApiKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config) ApiKeyAuthMiddleware { + return ApiKeyAuthMiddleware(apiKeyAuthWithSubscription(apiKeyService, subscriptionService, cfg)) } // apiKeyAuthWithSubscription API Key认证中间件(支持订阅验证) -func apiKeyAuthWithSubscription(apiKeyService *service.APIKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config, opsService *service.OpsService) gin.HandlerFunc { +func apiKeyAuthWithSubscription(apiKeyService *service.ApiKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config) gin.HandlerFunc { return func(c *gin.Context) { // 尝试从Authorization header中提取API key (Bearer scheme) authHeader := c.GetHeader("Authorization") @@ -53,7 +53,6 @@ func apiKeyAuthWithSubscription(apiKeyService *service.APIKeyService, subscripti // 如果所有header都没有API key if apiKeyString == "" { - recordOpsAuthError(c, opsService, nil, 401, "API key is required in Authorization header (Bearer scheme), x-api-key header, x-goog-api-key header, or key/api_key query parameter") AbortWithError(c, 401, "API_KEY_REQUIRED", "API key is required in Authorization header (Bearer scheme), x-api-key header, x-goog-api-key header, or key/api_key query parameter") return } @@ -61,40 +60,35 @@ func apiKeyAuthWithSubscription(apiKeyService *service.APIKeyService, subscripti // 从数据库验证API key apiKey, err := apiKeyService.GetByKey(c.Request.Context(), apiKeyString) if err != nil { - if errors.Is(err, service.ErrAPIKeyNotFound) { - recordOpsAuthError(c, opsService, nil, 401, "Invalid API key") + if errors.Is(err, service.ErrApiKeyNotFound) { AbortWithError(c, 401, "INVALID_API_KEY", "Invalid API key") return } - recordOpsAuthError(c, opsService, nil, 500, "Failed to validate API key") AbortWithError(c, 500, "INTERNAL_ERROR", "Failed to validate API key") return } // 检查API key是否激活 if !apiKey.IsActive() { - recordOpsAuthError(c, opsService, apiKey, 401, "API key is disabled") AbortWithError(c, 401, "API_KEY_DISABLED", "API key is disabled") return } // 检查关联的用户 if apiKey.User == nil { - recordOpsAuthError(c, opsService, apiKey, 401, "User associated with API key not found") AbortWithError(c, 401, "USER_NOT_FOUND", "User associated with API key not found") return } // 检查用户状态 if !apiKey.User.IsActive() { - recordOpsAuthError(c, opsService, apiKey, 401, "User account is not active") AbortWithError(c, 401, "USER_INACTIVE", "User account is not active") return } if cfg.RunMode == config.RunModeSimple { // 简易模式:跳过余额和订阅检查,但仍需设置必要的上下文 - c.Set(string(ContextKeyAPIKey), apiKey) + c.Set(string(ContextKeyApiKey), apiKey) c.Set(string(ContextKeyUser), AuthSubject{ UserID: apiKey.User.ID, Concurrency: apiKey.User.Concurrency, @@ -115,14 +109,12 @@ func apiKeyAuthWithSubscription(apiKeyService *service.APIKeyService, subscripti apiKey.Group.ID, ) if err != nil { - recordOpsAuthError(c, opsService, apiKey, 403, "No active subscription found for this group") AbortWithError(c, 403, "SUBSCRIPTION_NOT_FOUND", "No active subscription found for this group") return } // 验证订阅状态(是否过期、暂停等) if err := subscriptionService.ValidateSubscription(c.Request.Context(), subscription); err != nil { - recordOpsAuthError(c, opsService, apiKey, 403, err.Error()) AbortWithError(c, 403, "SUBSCRIPTION_INVALID", err.Error()) return } @@ -139,7 +131,6 @@ func apiKeyAuthWithSubscription(apiKeyService *service.APIKeyService, subscripti // 预检查用量限制(使用0作为额外费用进行预检查) if err := subscriptionService.CheckUsageLimits(c.Request.Context(), subscription, apiKey.Group, 0); err != nil { - recordOpsAuthError(c, opsService, apiKey, 429, err.Error()) AbortWithError(c, 429, "USAGE_LIMIT_EXCEEDED", err.Error()) return } @@ -149,14 +140,13 @@ func apiKeyAuthWithSubscription(apiKeyService *service.APIKeyService, subscripti } else { // 余额模式:检查用户余额 if apiKey.User.Balance <= 0 { - recordOpsAuthError(c, opsService, apiKey, 403, "Insufficient account balance") AbortWithError(c, 403, "INSUFFICIENT_BALANCE", "Insufficient account balance") return } } // 将API key和用户信息存入上下文 - c.Set(string(ContextKeyAPIKey), apiKey) + c.Set(string(ContextKeyApiKey), apiKey) c.Set(string(ContextKeyUser), AuthSubject{ UserID: apiKey.User.ID, Concurrency: apiKey.User.Concurrency, @@ -167,66 +157,13 @@ func apiKeyAuthWithSubscription(apiKeyService *service.APIKeyService, subscripti } } -func recordOpsAuthError(c *gin.Context, opsService *service.OpsService, apiKey *service.APIKey, status int, message string) { - if opsService == nil || c == nil { - return - } - - errType := "authentication_error" - phase := "auth" - severity := "P3" - switch status { - case 403: - errType = "billing_error" - phase = "billing" - case 429: - errType = "rate_limit_error" - phase = "billing" - severity = "P2" - case 500: - errType = "api_error" - phase = "internal" - severity = "P1" - } - - logEntry := &service.OpsErrorLog{ - Phase: phase, - Type: errType, - Severity: severity, - StatusCode: status, - Message: message, - ClientIP: c.ClientIP(), - RequestPath: func() string { - if c.Request != nil && c.Request.URL != nil { - return c.Request.URL.Path - } - return "" - }(), - } - - if apiKey != nil { - logEntry.APIKeyID = &apiKey.ID - if apiKey.User != nil { - logEntry.UserID = &apiKey.User.ID - } - if apiKey.GroupID != nil { - logEntry.GroupID = apiKey.GroupID - } - if apiKey.Group != nil { - logEntry.Platform = apiKey.Group.Platform - } - } - - enqueueOpsAuthErrorLog(opsService, logEntry) -} - -// GetAPIKeyFromContext 从上下文中获取API key -func GetAPIKeyFromContext(c *gin.Context) (*service.APIKey, bool) { - value, exists := c.Get(string(ContextKeyAPIKey)) +// GetApiKeyFromContext 从上下文中获取API key +func GetApiKeyFromContext(c *gin.Context) (*service.ApiKey, bool) { + value, exists := c.Get(string(ContextKeyApiKey)) if !exists { return nil, false } - apiKey, ok := value.(*service.APIKey) + apiKey, ok := value.(*service.ApiKey) return apiKey, ok } diff --git a/backend/internal/server/middleware/api_key_auth_google.go b/backend/internal/server/middleware/api_key_auth_google.go index 92d8b861..d8f47bd2 100644 --- a/backend/internal/server/middleware/api_key_auth_google.go +++ b/backend/internal/server/middleware/api_key_auth_google.go @@ -11,16 +11,16 @@ import ( "github.com/gin-gonic/gin" ) -// APIKeyAuthGoogle is a Google-style error wrapper for API key auth. -func APIKeyAuthGoogle(apiKeyService *service.APIKeyService, cfg *config.Config) gin.HandlerFunc { - return APIKeyAuthWithSubscriptionGoogle(apiKeyService, nil, cfg) +// ApiKeyAuthGoogle is a Google-style error wrapper for API key auth. +func ApiKeyAuthGoogle(apiKeyService *service.ApiKeyService, cfg *config.Config) gin.HandlerFunc { + return ApiKeyAuthWithSubscriptionGoogle(apiKeyService, nil, cfg) } -// APIKeyAuthWithSubscriptionGoogle behaves like APIKeyAuthWithSubscription but returns Google-style errors: +// ApiKeyAuthWithSubscriptionGoogle behaves like ApiKeyAuthWithSubscription but returns Google-style errors: // {"error":{"code":401,"message":"...","status":"UNAUTHENTICATED"}} // // It is intended for Gemini native endpoints (/v1beta) to match Gemini SDK expectations. -func APIKeyAuthWithSubscriptionGoogle(apiKeyService *service.APIKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config) gin.HandlerFunc { +func ApiKeyAuthWithSubscriptionGoogle(apiKeyService *service.ApiKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config) gin.HandlerFunc { return func(c *gin.Context) { apiKeyString := extractAPIKeyFromRequest(c) if apiKeyString == "" { @@ -30,7 +30,7 @@ func APIKeyAuthWithSubscriptionGoogle(apiKeyService *service.APIKeyService, subs apiKey, err := apiKeyService.GetByKey(c.Request.Context(), apiKeyString) if err != nil { - if errors.Is(err, service.ErrAPIKeyNotFound) { + if errors.Is(err, service.ErrApiKeyNotFound) { abortWithGoogleError(c, 401, "Invalid API key") return } @@ -53,7 +53,7 @@ func APIKeyAuthWithSubscriptionGoogle(apiKeyService *service.APIKeyService, subs // 简易模式:跳过余额和订阅检查 if cfg.RunMode == config.RunModeSimple { - c.Set(string(ContextKeyAPIKey), apiKey) + c.Set(string(ContextKeyApiKey), apiKey) c.Set(string(ContextKeyUser), AuthSubject{ UserID: apiKey.User.ID, Concurrency: apiKey.User.Concurrency, @@ -92,7 +92,7 @@ func APIKeyAuthWithSubscriptionGoogle(apiKeyService *service.APIKeyService, subs } } - c.Set(string(ContextKeyAPIKey), apiKey) + c.Set(string(ContextKeyApiKey), apiKey) c.Set(string(ContextKeyUser), AuthSubject{ UserID: apiKey.User.ID, Concurrency: apiKey.User.Concurrency, diff --git a/backend/internal/server/middleware/api_key_auth_google_test.go b/backend/internal/server/middleware/api_key_auth_google_test.go index b662096a..04d67977 100644 --- a/backend/internal/server/middleware/api_key_auth_google_test.go +++ b/backend/internal/server/middleware/api_key_auth_google_test.go @@ -16,53 +16,53 @@ import ( "github.com/stretchr/testify/require" ) -type fakeAPIKeyRepo struct { - getByKey func(ctx context.Context, key string) (*service.APIKey, error) +type fakeApiKeyRepo struct { + getByKey func(ctx context.Context, key string) (*service.ApiKey, error) } -func (f fakeAPIKeyRepo) Create(ctx context.Context, key *service.APIKey) error { +func (f fakeApiKeyRepo) Create(ctx context.Context, key *service.ApiKey) error { return errors.New("not implemented") } -func (f fakeAPIKeyRepo) GetByID(ctx context.Context, id int64) (*service.APIKey, error) { +func (f fakeApiKeyRepo) GetByID(ctx context.Context, id int64) (*service.ApiKey, error) { return nil, errors.New("not implemented") } -func (f fakeAPIKeyRepo) GetOwnerID(ctx context.Context, id int64) (int64, error) { +func (f fakeApiKeyRepo) GetOwnerID(ctx context.Context, id int64) (int64, error) { return 0, errors.New("not implemented") } -func (f fakeAPIKeyRepo) GetByKey(ctx context.Context, key string) (*service.APIKey, error) { +func (f fakeApiKeyRepo) GetByKey(ctx context.Context, key string) (*service.ApiKey, error) { if f.getByKey == nil { return nil, errors.New("unexpected call") } return f.getByKey(ctx, key) } -func (f fakeAPIKeyRepo) Update(ctx context.Context, key *service.APIKey) error { +func (f fakeApiKeyRepo) Update(ctx context.Context, key *service.ApiKey) error { return errors.New("not implemented") } -func (f fakeAPIKeyRepo) Delete(ctx context.Context, id int64) error { +func (f fakeApiKeyRepo) Delete(ctx context.Context, id int64) error { return errors.New("not implemented") } -func (f fakeAPIKeyRepo) ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]service.APIKey, *pagination.PaginationResult, error) { +func (f fakeApiKeyRepo) ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]service.ApiKey, *pagination.PaginationResult, error) { return nil, nil, errors.New("not implemented") } -func (f fakeAPIKeyRepo) VerifyOwnership(ctx context.Context, userID int64, apiKeyIDs []int64) ([]int64, error) { +func (f fakeApiKeyRepo) VerifyOwnership(ctx context.Context, userID int64, apiKeyIDs []int64) ([]int64, error) { return nil, errors.New("not implemented") } -func (f fakeAPIKeyRepo) CountByUserID(ctx context.Context, userID int64) (int64, error) { +func (f fakeApiKeyRepo) CountByUserID(ctx context.Context, userID int64) (int64, error) { return 0, errors.New("not implemented") } -func (f fakeAPIKeyRepo) ExistsByKey(ctx context.Context, key string) (bool, error) { +func (f fakeApiKeyRepo) ExistsByKey(ctx context.Context, key string) (bool, error) { return false, errors.New("not implemented") } -func (f fakeAPIKeyRepo) ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]service.APIKey, *pagination.PaginationResult, error) { +func (f fakeApiKeyRepo) ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]service.ApiKey, *pagination.PaginationResult, error) { return nil, nil, errors.New("not implemented") } -func (f fakeAPIKeyRepo) SearchAPIKeys(ctx context.Context, userID int64, keyword string, limit int) ([]service.APIKey, error) { +func (f fakeApiKeyRepo) SearchApiKeys(ctx context.Context, userID int64, keyword string, limit int) ([]service.ApiKey, error) { return nil, errors.New("not implemented") } -func (f fakeAPIKeyRepo) ClearGroupIDByGroupID(ctx context.Context, groupID int64) (int64, error) { +func (f fakeApiKeyRepo) ClearGroupIDByGroupID(ctx context.Context, groupID int64) (int64, error) { return 0, errors.New("not implemented") } -func (f fakeAPIKeyRepo) CountByGroupID(ctx context.Context, groupID int64) (int64, error) { +func (f fakeApiKeyRepo) CountByGroupID(ctx context.Context, groupID int64) (int64, error) { return 0, errors.New("not implemented") } @@ -74,8 +74,8 @@ type googleErrorResponse struct { } `json:"error"` } -func newTestAPIKeyService(repo service.APIKeyRepository) *service.APIKeyService { - return service.NewAPIKeyService( +func newTestApiKeyService(repo service.ApiKeyRepository) *service.ApiKeyService { + return service.NewApiKeyService( repo, nil, // userRepo (unused in GetByKey) nil, // groupRepo @@ -85,16 +85,16 @@ func newTestAPIKeyService(repo service.APIKeyRepository) *service.APIKeyService ) } -func TestAPIKeyAuthWithSubscriptionGoogle_MissingKey(t *testing.T) { +func TestApiKeyAuthWithSubscriptionGoogle_MissingKey(t *testing.T) { gin.SetMode(gin.TestMode) r := gin.New() - apiKeyService := newTestAPIKeyService(fakeAPIKeyRepo{ - getByKey: func(ctx context.Context, key string) (*service.APIKey, error) { + apiKeyService := newTestApiKeyService(fakeApiKeyRepo{ + getByKey: func(ctx context.Context, key string) (*service.ApiKey, error) { return nil, errors.New("should not be called") }, }) - r.Use(APIKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) + r.Use(ApiKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) r.GET("/v1beta/test", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) }) req := httptest.NewRequest(http.MethodGet, "/v1beta/test", nil) @@ -109,16 +109,16 @@ func TestAPIKeyAuthWithSubscriptionGoogle_MissingKey(t *testing.T) { require.Equal(t, "UNAUTHENTICATED", resp.Error.Status) } -func TestAPIKeyAuthWithSubscriptionGoogle_InvalidKey(t *testing.T) { +func TestApiKeyAuthWithSubscriptionGoogle_InvalidKey(t *testing.T) { gin.SetMode(gin.TestMode) r := gin.New() - apiKeyService := newTestAPIKeyService(fakeAPIKeyRepo{ - getByKey: func(ctx context.Context, key string) (*service.APIKey, error) { - return nil, service.ErrAPIKeyNotFound + apiKeyService := newTestApiKeyService(fakeApiKeyRepo{ + getByKey: func(ctx context.Context, key string) (*service.ApiKey, error) { + return nil, service.ErrApiKeyNotFound }, }) - r.Use(APIKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) + r.Use(ApiKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) r.GET("/v1beta/test", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) }) req := httptest.NewRequest(http.MethodGet, "/v1beta/test", nil) @@ -134,16 +134,16 @@ func TestAPIKeyAuthWithSubscriptionGoogle_InvalidKey(t *testing.T) { require.Equal(t, "UNAUTHENTICATED", resp.Error.Status) } -func TestAPIKeyAuthWithSubscriptionGoogle_RepoError(t *testing.T) { +func TestApiKeyAuthWithSubscriptionGoogle_RepoError(t *testing.T) { gin.SetMode(gin.TestMode) r := gin.New() - apiKeyService := newTestAPIKeyService(fakeAPIKeyRepo{ - getByKey: func(ctx context.Context, key string) (*service.APIKey, error) { + apiKeyService := newTestApiKeyService(fakeApiKeyRepo{ + getByKey: func(ctx context.Context, key string) (*service.ApiKey, error) { return nil, errors.New("db down") }, }) - r.Use(APIKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) + r.Use(ApiKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) r.GET("/v1beta/test", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) }) req := httptest.NewRequest(http.MethodGet, "/v1beta/test", nil) @@ -159,13 +159,13 @@ func TestAPIKeyAuthWithSubscriptionGoogle_RepoError(t *testing.T) { require.Equal(t, "INTERNAL", resp.Error.Status) } -func TestAPIKeyAuthWithSubscriptionGoogle_DisabledKey(t *testing.T) { +func TestApiKeyAuthWithSubscriptionGoogle_DisabledKey(t *testing.T) { gin.SetMode(gin.TestMode) r := gin.New() - apiKeyService := newTestAPIKeyService(fakeAPIKeyRepo{ - getByKey: func(ctx context.Context, key string) (*service.APIKey, error) { - return &service.APIKey{ + apiKeyService := newTestApiKeyService(fakeApiKeyRepo{ + getByKey: func(ctx context.Context, key string) (*service.ApiKey, error) { + return &service.ApiKey{ ID: 1, Key: key, Status: service.StatusDisabled, @@ -176,7 +176,7 @@ func TestAPIKeyAuthWithSubscriptionGoogle_DisabledKey(t *testing.T) { }, nil }, }) - r.Use(APIKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) + r.Use(ApiKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) r.GET("/v1beta/test", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) }) req := httptest.NewRequest(http.MethodGet, "/v1beta/test", nil) @@ -192,13 +192,13 @@ func TestAPIKeyAuthWithSubscriptionGoogle_DisabledKey(t *testing.T) { require.Equal(t, "UNAUTHENTICATED", resp.Error.Status) } -func TestAPIKeyAuthWithSubscriptionGoogle_InsufficientBalance(t *testing.T) { +func TestApiKeyAuthWithSubscriptionGoogle_InsufficientBalance(t *testing.T) { gin.SetMode(gin.TestMode) r := gin.New() - apiKeyService := newTestAPIKeyService(fakeAPIKeyRepo{ - getByKey: func(ctx context.Context, key string) (*service.APIKey, error) { - return &service.APIKey{ + apiKeyService := newTestApiKeyService(fakeApiKeyRepo{ + getByKey: func(ctx context.Context, key string) (*service.ApiKey, error) { + return &service.ApiKey{ ID: 1, Key: key, Status: service.StatusActive, @@ -210,7 +210,7 @@ func TestAPIKeyAuthWithSubscriptionGoogle_InsufficientBalance(t *testing.T) { }, nil }, }) - r.Use(APIKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) + r.Use(ApiKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{})) r.GET("/v1beta/test", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) }) req := httptest.NewRequest(http.MethodGet, "/v1beta/test", nil) diff --git a/backend/internal/server/middleware/api_key_auth_test.go b/backend/internal/server/middleware/api_key_auth_test.go index bcf596c1..841edd07 100644 --- a/backend/internal/server/middleware/api_key_auth_test.go +++ b/backend/internal/server/middleware/api_key_auth_test.go @@ -35,7 +35,7 @@ func TestSimpleModeBypassesQuotaCheck(t *testing.T) { Balance: 10, Concurrency: 3, } - apiKey := &service.APIKey{ + apiKey := &service.ApiKey{ ID: 100, UserID: user.ID, Key: "test-key", @@ -45,10 +45,10 @@ func TestSimpleModeBypassesQuotaCheck(t *testing.T) { } apiKey.GroupID = &group.ID - apiKeyRepo := &stubAPIKeyRepo{ - getByKey: func(ctx context.Context, key string) (*service.APIKey, error) { + apiKeyRepo := &stubApiKeyRepo{ + getByKey: func(ctx context.Context, key string) (*service.ApiKey, error) { if key != apiKey.Key { - return nil, service.ErrAPIKeyNotFound + return nil, service.ErrApiKeyNotFound } clone := *apiKey return &clone, nil @@ -57,7 +57,7 @@ func TestSimpleModeBypassesQuotaCheck(t *testing.T) { t.Run("simple_mode_bypasses_quota_check", func(t *testing.T) { cfg := &config.Config{RunMode: config.RunModeSimple} - apiKeyService := service.NewAPIKeyService(apiKeyRepo, nil, nil, nil, nil, cfg) + apiKeyService := service.NewApiKeyService(apiKeyRepo, nil, nil, nil, nil, cfg) subscriptionService := service.NewSubscriptionService(nil, &stubUserSubscriptionRepo{}, nil) router := newAuthTestRouter(apiKeyService, subscriptionService, cfg) @@ -71,7 +71,7 @@ func TestSimpleModeBypassesQuotaCheck(t *testing.T) { t.Run("standard_mode_enforces_quota_check", func(t *testing.T) { cfg := &config.Config{RunMode: config.RunModeStandard} - apiKeyService := service.NewAPIKeyService(apiKeyRepo, nil, nil, nil, nil, cfg) + apiKeyService := service.NewApiKeyService(apiKeyRepo, nil, nil, nil, nil, cfg) now := time.Now() sub := &service.UserSubscription{ @@ -110,75 +110,75 @@ func TestSimpleModeBypassesQuotaCheck(t *testing.T) { }) } -func newAuthTestRouter(apiKeyService *service.APIKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config) *gin.Engine { +func newAuthTestRouter(apiKeyService *service.ApiKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config) *gin.Engine { router := gin.New() - router.Use(gin.HandlerFunc(NewAPIKeyAuthMiddleware(apiKeyService, subscriptionService, cfg, nil))) + router.Use(gin.HandlerFunc(NewApiKeyAuthMiddleware(apiKeyService, subscriptionService, cfg))) router.GET("/t", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"ok": true}) }) return router } -type stubAPIKeyRepo struct { - getByKey func(ctx context.Context, key string) (*service.APIKey, error) +type stubApiKeyRepo struct { + getByKey func(ctx context.Context, key string) (*service.ApiKey, error) } -func (r *stubAPIKeyRepo) Create(ctx context.Context, key *service.APIKey) error { +func (r *stubApiKeyRepo) Create(ctx context.Context, key *service.ApiKey) error { return errors.New("not implemented") } -func (r *stubAPIKeyRepo) GetByID(ctx context.Context, id int64) (*service.APIKey, error) { +func (r *stubApiKeyRepo) GetByID(ctx context.Context, id int64) (*service.ApiKey, error) { return nil, errors.New("not implemented") } -func (r *stubAPIKeyRepo) GetOwnerID(ctx context.Context, id int64) (int64, error) { +func (r *stubApiKeyRepo) GetOwnerID(ctx context.Context, id int64) (int64, error) { return 0, errors.New("not implemented") } -func (r *stubAPIKeyRepo) GetByKey(ctx context.Context, key string) (*service.APIKey, error) { +func (r *stubApiKeyRepo) GetByKey(ctx context.Context, key string) (*service.ApiKey, error) { if r.getByKey != nil { return r.getByKey(ctx, key) } return nil, errors.New("not implemented") } -func (r *stubAPIKeyRepo) Update(ctx context.Context, key *service.APIKey) error { +func (r *stubApiKeyRepo) Update(ctx context.Context, key *service.ApiKey) error { return errors.New("not implemented") } -func (r *stubAPIKeyRepo) Delete(ctx context.Context, id int64) error { +func (r *stubApiKeyRepo) Delete(ctx context.Context, id int64) error { return errors.New("not implemented") } -func (r *stubAPIKeyRepo) ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]service.APIKey, *pagination.PaginationResult, error) { +func (r *stubApiKeyRepo) ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]service.ApiKey, *pagination.PaginationResult, error) { return nil, nil, errors.New("not implemented") } -func (r *stubAPIKeyRepo) VerifyOwnership(ctx context.Context, userID int64, apiKeyIDs []int64) ([]int64, error) { +func (r *stubApiKeyRepo) VerifyOwnership(ctx context.Context, userID int64, apiKeyIDs []int64) ([]int64, error) { return nil, errors.New("not implemented") } -func (r *stubAPIKeyRepo) CountByUserID(ctx context.Context, userID int64) (int64, error) { +func (r *stubApiKeyRepo) CountByUserID(ctx context.Context, userID int64) (int64, error) { return 0, errors.New("not implemented") } -func (r *stubAPIKeyRepo) ExistsByKey(ctx context.Context, key string) (bool, error) { +func (r *stubApiKeyRepo) ExistsByKey(ctx context.Context, key string) (bool, error) { return false, errors.New("not implemented") } -func (r *stubAPIKeyRepo) ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]service.APIKey, *pagination.PaginationResult, error) { +func (r *stubApiKeyRepo) ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]service.ApiKey, *pagination.PaginationResult, error) { return nil, nil, errors.New("not implemented") } -func (r *stubAPIKeyRepo) SearchAPIKeys(ctx context.Context, userID int64, keyword string, limit int) ([]service.APIKey, error) { +func (r *stubApiKeyRepo) SearchApiKeys(ctx context.Context, userID int64, keyword string, limit int) ([]service.ApiKey, error) { return nil, errors.New("not implemented") } -func (r *stubAPIKeyRepo) ClearGroupIDByGroupID(ctx context.Context, groupID int64) (int64, error) { +func (r *stubApiKeyRepo) ClearGroupIDByGroupID(ctx context.Context, groupID int64) (int64, error) { return 0, errors.New("not implemented") } -func (r *stubAPIKeyRepo) CountByGroupID(ctx context.Context, groupID int64) (int64, error) { +func (r *stubApiKeyRepo) CountByGroupID(ctx context.Context, groupID int64) (int64, error) { return 0, errors.New("not implemented") } diff --git a/backend/internal/server/middleware/logger.go b/backend/internal/server/middleware/logger.go index 092687bf..a9beeb40 100644 --- a/backend/internal/server/middleware/logger.go +++ b/backend/internal/server/middleware/logger.go @@ -2,14 +2,11 @@ package middleware import ( "log" - "regexp" "time" "github.com/gin-gonic/gin" ) -var sensitiveQueryParamRE = regexp.MustCompile(`(?i)([?&](?:token|api_key)=)[^&#]*`) - // Logger 请求日志中间件 func Logger() gin.HandlerFunc { return func(c *gin.Context) { @@ -29,7 +26,7 @@ func Logger() gin.HandlerFunc { method := c.Request.Method // 请求路径 - path := sensitiveQueryParamRE.ReplaceAllString(c.Request.URL.RequestURI(), "${1}***") + path := c.Request.URL.Path // 状态码 statusCode := c.Writer.Status() diff --git a/backend/internal/server/middleware/middleware.go b/backend/internal/server/middleware/middleware.go index 7e4c84d9..75b9f68e 100644 --- a/backend/internal/server/middleware/middleware.go +++ b/backend/internal/server/middleware/middleware.go @@ -1,5 +1,3 @@ -// Package middleware provides HTTP middleware components for authentication, -// authorization, logging, error recovery, and request processing. package middleware import ( @@ -17,8 +15,8 @@ const ( ContextKeyUser ContextKey = "user" // ContextKeyUserRole 当前用户角色(string) ContextKeyUserRole ContextKey = "user_role" - // ContextKeyAPIKey API密钥上下文键 - ContextKeyAPIKey ContextKey = "api_key" + // ContextKeyApiKey API密钥上下文键 + ContextKeyApiKey ContextKey = "api_key" // ContextKeySubscription 订阅上下文键 ContextKeySubscription ContextKey = "subscription" // ContextKeyForcePlatform 强制平台(用于 /antigravity 路由) diff --git a/backend/internal/server/middleware/wire.go b/backend/internal/server/middleware/wire.go index dc01b743..3ed79f37 100644 --- a/backend/internal/server/middleware/wire.go +++ b/backend/internal/server/middleware/wire.go @@ -11,12 +11,12 @@ type JWTAuthMiddleware gin.HandlerFunc // AdminAuthMiddleware 管理员认证中间件类型 type AdminAuthMiddleware gin.HandlerFunc -// APIKeyAuthMiddleware API Key 认证中间件类型 -type APIKeyAuthMiddleware gin.HandlerFunc +// ApiKeyAuthMiddleware API Key 认证中间件类型 +type ApiKeyAuthMiddleware gin.HandlerFunc // ProviderSet 中间件层的依赖注入 var ProviderSet = wire.NewSet( NewJWTAuthMiddleware, NewAdminAuthMiddleware, - NewAPIKeyAuthMiddleware, + NewApiKeyAuthMiddleware, ) diff --git a/backend/internal/server/router.go b/backend/internal/server/router.go index 6eebb6d8..2371dafb 100644 --- a/backend/internal/server/router.go +++ b/backend/internal/server/router.go @@ -17,8 +17,8 @@ func SetupRouter( handlers *handler.Handlers, jwtAuth middleware2.JWTAuthMiddleware, adminAuth middleware2.AdminAuthMiddleware, - apiKeyAuth middleware2.APIKeyAuthMiddleware, - apiKeyService *service.APIKeyService, + apiKeyAuth middleware2.ApiKeyAuthMiddleware, + apiKeyService *service.ApiKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config, ) *gin.Engine { @@ -43,8 +43,8 @@ func registerRoutes( h *handler.Handlers, jwtAuth middleware2.JWTAuthMiddleware, adminAuth middleware2.AdminAuthMiddleware, - apiKeyAuth middleware2.APIKeyAuthMiddleware, - apiKeyService *service.APIKeyService, + apiKeyAuth middleware2.ApiKeyAuthMiddleware, + apiKeyService *service.ApiKeyService, subscriptionService *service.SubscriptionService, cfg *config.Config, ) { diff --git a/backend/internal/server/routes/common.go b/backend/internal/server/routes/common.go index 7d3cfc4e..4989358d 100644 --- a/backend/internal/server/routes/common.go +++ b/backend/internal/server/routes/common.go @@ -1,4 +1,3 @@ -// Package routes 提供 HTTP 路由注册和处理函数 package routes import ( diff --git a/backend/internal/server/routes/user.go b/backend/internal/server/routes/user.go index ad2166fe..31a354fa 100644 --- a/backend/internal/server/routes/user.go +++ b/backend/internal/server/routes/user.go @@ -50,7 +50,7 @@ func RegisterUserRoutes( usage.GET("/dashboard/stats", h.Usage.DashboardStats) usage.GET("/dashboard/trend", h.Usage.DashboardTrend) usage.GET("/dashboard/models", h.Usage.DashboardModels) - usage.POST("/dashboard/api-keys-usage", h.Usage.DashboardAPIKeysUsage) + usage.POST("/dashboard/api-keys-usage", h.Usage.DashboardApiKeysUsage) } // 卡密兑换 diff --git a/backend/internal/service/account.go b/backend/internal/service/account.go index 0acf1aad..953090c2 100644 --- a/backend/internal/service/account.go +++ b/backend/internal/service/account.go @@ -29,6 +29,9 @@ type Account struct { RateLimitResetAt *time.Time OverloadUntil *time.Time + TempUnschedulableUntil *time.Time + TempUnschedulableReason string + SessionWindowStart *time.Time SessionWindowEnd *time.Time SessionWindowStatus string @@ -39,6 +42,13 @@ type Account struct { Groups []*Group } +type TempUnschedulableRule struct { + ErrorCode int `json:"error_code"` + Keywords []string `json:"keywords"` + DurationMinutes int `json:"duration_minutes"` + Description string `json:"description"` +} + func (a *Account) IsActive() bool { return a.Status == StatusActive } @@ -54,6 +64,9 @@ func (a *Account) IsSchedulable() bool { if a.RateLimitResetAt != nil && now.Before(*a.RateLimitResetAt) { return false } + if a.TempUnschedulableUntil != nil && now.Before(*a.TempUnschedulableUntil) { + return false + } return true } @@ -163,6 +176,114 @@ func (a *Account) GetCredentialAsTime(key string) *time.Time { return nil } +func (a *Account) IsTempUnschedulableEnabled() bool { + if a.Credentials == nil { + return false + } + raw, ok := a.Credentials["temp_unschedulable_enabled"] + if !ok || raw == nil { + return false + } + enabled, ok := raw.(bool) + return ok && enabled +} + +func (a *Account) GetTempUnschedulableRules() []TempUnschedulableRule { + if a.Credentials == nil { + return nil + } + raw, ok := a.Credentials["temp_unschedulable_rules"] + if !ok || raw == nil { + return nil + } + + arr, ok := raw.([]any) + if !ok { + return nil + } + + rules := make([]TempUnschedulableRule, 0, len(arr)) + for _, item := range arr { + entry, ok := item.(map[string]any) + if !ok || entry == nil { + continue + } + + rule := TempUnschedulableRule{ + ErrorCode: parseTempUnschedInt(entry["error_code"]), + Keywords: parseTempUnschedStrings(entry["keywords"]), + DurationMinutes: parseTempUnschedInt(entry["duration_minutes"]), + Description: parseTempUnschedString(entry["description"]), + } + + if rule.ErrorCode <= 0 || rule.DurationMinutes <= 0 || len(rule.Keywords) == 0 { + continue + } + + rules = append(rules, rule) + } + + return rules +} + +func parseTempUnschedString(value any) string { + s, ok := value.(string) + if !ok { + return "" + } + return strings.TrimSpace(s) +} + +func parseTempUnschedStrings(value any) []string { + if value == nil { + return nil + } + + var raw []string + switch v := value.(type) { + case []string: + raw = v + case []any: + raw = make([]string, 0, len(v)) + for _, item := range v { + if s, ok := item.(string); ok { + raw = append(raw, s) + } + } + default: + return nil + } + + out := make([]string, 0, len(raw)) + for _, item := range raw { + s := strings.TrimSpace(item) + if s != "" { + out = append(out, s) + } + } + return out +} + +func parseTempUnschedInt(value any) int { + switch v := value.(type) { + case int: + return v + case int64: + return int(v) + case float64: + return int(v) + case json.Number: + if i, err := v.Int64(); err == nil { + return int(i) + } + case string: + if i, err := strconv.Atoi(strings.TrimSpace(v)); err == nil { + return i + } + } + return 0 +} + func (a *Account) GetModelMapping() map[string]string { if a.Credentials == nil { return nil @@ -206,7 +327,7 @@ func (a *Account) GetMappedModel(requestedModel string) string { } func (a *Account) GetBaseURL() string { - if a.Type != AccountTypeAPIKey { + if a.Type != AccountTypeApiKey { return "" } baseURL := a.GetCredential("base_url") @@ -229,7 +350,7 @@ func (a *Account) GetExtraString(key string) string { } func (a *Account) IsCustomErrorCodesEnabled() bool { - if a.Type != AccountTypeAPIKey || a.Credentials == nil { + if a.Type != AccountTypeApiKey || a.Credentials == nil { return false } if v, ok := a.Credentials["custom_error_codes_enabled"]; ok { @@ -300,15 +421,15 @@ func (a *Account) IsOpenAIOAuth() bool { return a.IsOpenAI() && a.Type == AccountTypeOAuth } -func (a *Account) IsOpenAIAPIKey() bool { - return a.IsOpenAI() && a.Type == AccountTypeAPIKey +func (a *Account) IsOpenAIApiKey() bool { + return a.IsOpenAI() && a.Type == AccountTypeApiKey } func (a *Account) GetOpenAIBaseURL() string { if !a.IsOpenAI() { return "" } - if a.Type == AccountTypeAPIKey { + if a.Type == AccountTypeApiKey { baseURL := a.GetCredential("base_url") if baseURL != "" { return baseURL @@ -338,8 +459,8 @@ func (a *Account) GetOpenAIIDToken() string { return a.GetCredential("id_token") } -func (a *Account) GetOpenAIAPIKey() string { - if !a.IsOpenAIAPIKey() { +func (a *Account) GetOpenAIApiKey() string { + if !a.IsOpenAIApiKey() { return "" } return a.GetCredential("api_key") diff --git a/backend/internal/service/account_service.go b/backend/internal/service/account_service.go index 3dd165ac..6751d82e 100644 --- a/backend/internal/service/account_service.go +++ b/backend/internal/service/account_service.go @@ -1,5 +1,3 @@ -// Package service 提供业务逻辑层服务,封装领域模型的业务规则和操作流程。 -// 服务层协调 repository 层的数据访问,实现跨实体的业务逻辑,并为上层 API 提供统一的业务接口。 package service import ( @@ -51,6 +49,8 @@ type AccountRepository interface { SetRateLimited(ctx context.Context, id int64, resetAt time.Time) error SetOverloaded(ctx context.Context, id int64, until time.Time) error + SetTempUnschedulable(ctx context.Context, id int64, until time.Time, reason string) error + ClearTempUnschedulable(ctx context.Context, id int64) error ClearRateLimit(ctx context.Context, id int64) error UpdateSessionWindow(ctx context.Context, id int64, start, end *time.Time, status string) error UpdateExtra(ctx context.Context, id int64, updates map[string]any) error diff --git a/backend/internal/service/account_service_delete_test.go b/backend/internal/service/account_service_delete_test.go index 43703763..974a515c 100644 --- a/backend/internal/service/account_service_delete_test.go +++ b/backend/internal/service/account_service_delete_test.go @@ -139,6 +139,14 @@ func (s *accountRepoStub) SetOverloaded(ctx context.Context, id int64, until tim panic("unexpected SetOverloaded call") } +func (s *accountRepoStub) SetTempUnschedulable(ctx context.Context, id int64, until time.Time, reason string) error { + panic("unexpected SetTempUnschedulable call") +} + +func (s *accountRepoStub) ClearTempUnschedulable(ctx context.Context, id int64) error { + panic("unexpected ClearTempUnschedulable call") +} + func (s *accountRepoStub) ClearRateLimit(ctx context.Context, id int64) error { panic("unexpected ClearRateLimit call") } diff --git a/backend/internal/service/account_test_service.go b/backend/internal/service/account_test_service.go index 748c7993..7dd451cd 100644 --- a/backend/internal/service/account_test_service.go +++ b/backend/internal/service/account_test_service.go @@ -324,7 +324,7 @@ func (s *AccountTestService) testOpenAIAccountConnection(c *gin.Context, account chatgptAccountID = account.GetChatGPTAccountID() } else if account.Type == "apikey" { // API Key - use Platform API - authToken = account.GetOpenAIAPIKey() + authToken = account.GetOpenAIApiKey() if authToken == "" { return s.sendErrorAndEnd(c, "No API key available") } @@ -402,7 +402,7 @@ func (s *AccountTestService) testGeminiAccountConnection(c *gin.Context, account } // For API Key accounts with model mapping, map the model - if account.Type == AccountTypeAPIKey { + if account.Type == AccountTypeApiKey { mapping := account.GetModelMapping() if len(mapping) > 0 { if mappedModel, exists := mapping[testModelID]; exists { @@ -426,7 +426,7 @@ func (s *AccountTestService) testGeminiAccountConnection(c *gin.Context, account var err error switch account.Type { - case AccountTypeAPIKey: + case AccountTypeApiKey: req, err = s.buildGeminiAPIKeyRequest(ctx, account, testModelID, payload) case AccountTypeOAuth: req, err = s.buildGeminiOAuthRequest(ctx, account, testModelID, payload) diff --git a/backend/internal/service/api_key.go b/backend/internal/service/api_key.go index 0cf0f4f9..e76f0f8e 100644 --- a/backend/internal/service/api_key.go +++ b/backend/internal/service/api_key.go @@ -2,7 +2,7 @@ package service import "time" -type APIKey struct { +type ApiKey struct { ID int64 UserID int64 Key string @@ -15,6 +15,6 @@ type APIKey struct { Group *Group } -func (k *APIKey) IsActive() bool { +func (k *ApiKey) IsActive() bool { return k.Status == StatusActive } diff --git a/backend/internal/service/api_key_service.go b/backend/internal/service/api_key_service.go index ea53f81a..f22c383a 100644 --- a/backend/internal/service/api_key_service.go +++ b/backend/internal/service/api_key_service.go @@ -14,39 +14,39 @@ import ( ) var ( - ErrAPIKeyNotFound = infraerrors.NotFound("API_KEY_NOT_FOUND", "api key not found") + ErrApiKeyNotFound = infraerrors.NotFound("API_KEY_NOT_FOUND", "api key not found") ErrGroupNotAllowed = infraerrors.Forbidden("GROUP_NOT_ALLOWED", "user is not allowed to bind this group") - ErrAPIKeyExists = infraerrors.Conflict("API_KEY_EXISTS", "api key already exists") - ErrAPIKeyTooShort = infraerrors.BadRequest("API_KEY_TOO_SHORT", "api key must be at least 16 characters") - ErrAPIKeyInvalidChars = infraerrors.BadRequest("API_KEY_INVALID_CHARS", "api key can only contain letters, numbers, underscores, and hyphens") - ErrAPIKeyRateLimited = infraerrors.TooManyRequests("API_KEY_RATE_LIMITED", "too many failed attempts, please try again later") + ErrApiKeyExists = infraerrors.Conflict("API_KEY_EXISTS", "api key already exists") + ErrApiKeyTooShort = infraerrors.BadRequest("API_KEY_TOO_SHORT", "api key must be at least 16 characters") + ErrApiKeyInvalidChars = infraerrors.BadRequest("API_KEY_INVALID_CHARS", "api key can only contain letters, numbers, underscores, and hyphens") + ErrApiKeyRateLimited = infraerrors.TooManyRequests("API_KEY_RATE_LIMITED", "too many failed attempts, please try again later") ) const ( apiKeyMaxErrorsPerHour = 20 ) -type APIKeyRepository interface { - Create(ctx context.Context, key *APIKey) error - GetByID(ctx context.Context, id int64) (*APIKey, error) +type ApiKeyRepository interface { + Create(ctx context.Context, key *ApiKey) error + GetByID(ctx context.Context, id int64) (*ApiKey, error) // GetOwnerID 仅获取 API Key 的所有者 ID,用于删除前的轻量级权限验证 GetOwnerID(ctx context.Context, id int64) (int64, error) - GetByKey(ctx context.Context, key string) (*APIKey, error) - Update(ctx context.Context, key *APIKey) error + GetByKey(ctx context.Context, key string) (*ApiKey, error) + Update(ctx context.Context, key *ApiKey) error Delete(ctx context.Context, id int64) error - ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]APIKey, *pagination.PaginationResult, error) + ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]ApiKey, *pagination.PaginationResult, error) VerifyOwnership(ctx context.Context, userID int64, apiKeyIDs []int64) ([]int64, error) CountByUserID(ctx context.Context, userID int64) (int64, error) ExistsByKey(ctx context.Context, key string) (bool, error) - ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]APIKey, *pagination.PaginationResult, error) - SearchAPIKeys(ctx context.Context, userID int64, keyword string, limit int) ([]APIKey, error) + ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]ApiKey, *pagination.PaginationResult, error) + SearchApiKeys(ctx context.Context, userID int64, keyword string, limit int) ([]ApiKey, error) ClearGroupIDByGroupID(ctx context.Context, groupID int64) (int64, error) CountByGroupID(ctx context.Context, groupID int64) (int64, error) } -// APIKeyCache defines cache operations for API key service -type APIKeyCache interface { +// ApiKeyCache defines cache operations for API key service +type ApiKeyCache interface { GetCreateAttemptCount(ctx context.Context, userID int64) (int, error) IncrementCreateAttemptCount(ctx context.Context, userID int64) error DeleteCreateAttemptCount(ctx context.Context, userID int64) error @@ -55,40 +55,40 @@ type APIKeyCache interface { SetDailyUsageExpiry(ctx context.Context, apiKey string, ttl time.Duration) error } -// CreateAPIKeyRequest 创建API Key请求 -type CreateAPIKeyRequest struct { +// CreateApiKeyRequest 创建API Key请求 +type CreateApiKeyRequest struct { Name string `json:"name"` GroupID *int64 `json:"group_id"` CustomKey *string `json:"custom_key"` // 可选的自定义key } -// UpdateAPIKeyRequest 更新API Key请求 -type UpdateAPIKeyRequest struct { +// UpdateApiKeyRequest 更新API Key请求 +type UpdateApiKeyRequest struct { Name *string `json:"name"` GroupID *int64 `json:"group_id"` Status *string `json:"status"` } -// APIKeyService API Key服务 -type APIKeyService struct { - apiKeyRepo APIKeyRepository +// ApiKeyService API Key服务 +type ApiKeyService struct { + apiKeyRepo ApiKeyRepository userRepo UserRepository groupRepo GroupRepository userSubRepo UserSubscriptionRepository - cache APIKeyCache + cache ApiKeyCache cfg *config.Config } -// NewAPIKeyService 创建API Key服务实例 -func NewAPIKeyService( - apiKeyRepo APIKeyRepository, +// NewApiKeyService 创建API Key服务实例 +func NewApiKeyService( + apiKeyRepo ApiKeyRepository, userRepo UserRepository, groupRepo GroupRepository, userSubRepo UserSubscriptionRepository, - cache APIKeyCache, + cache ApiKeyCache, cfg *config.Config, -) *APIKeyService { - return &APIKeyService{ +) *ApiKeyService { + return &ApiKeyService{ apiKeyRepo: apiKeyRepo, userRepo: userRepo, groupRepo: groupRepo, @@ -99,7 +99,7 @@ func NewAPIKeyService( } // GenerateKey 生成随机API Key -func (s *APIKeyService) GenerateKey() (string, error) { +func (s *ApiKeyService) GenerateKey() (string, error) { // 生成32字节随机数据 bytes := make([]byte, 32) if _, err := rand.Read(bytes); err != nil { @@ -107,7 +107,7 @@ func (s *APIKeyService) GenerateKey() (string, error) { } // 转换为十六进制字符串并添加前缀 - prefix := s.cfg.Default.APIKeyPrefix + prefix := s.cfg.Default.ApiKeyPrefix if prefix == "" { prefix = "sk-" } @@ -117,10 +117,10 @@ func (s *APIKeyService) GenerateKey() (string, error) { } // ValidateCustomKey 验证自定义API Key格式 -func (s *APIKeyService) ValidateCustomKey(key string) error { +func (s *ApiKeyService) ValidateCustomKey(key string) error { // 检查长度 if len(key) < 16 { - return ErrAPIKeyTooShort + return ErrApiKeyTooShort } // 检查字符:只允许字母、数字、下划线、连字符 @@ -131,14 +131,14 @@ func (s *APIKeyService) ValidateCustomKey(key string) error { c == '_' || c == '-' { continue } - return ErrAPIKeyInvalidChars + return ErrApiKeyInvalidChars } return nil } -// checkAPIKeyRateLimit 检查用户创建自定义Key的错误次数是否超限 -func (s *APIKeyService) checkAPIKeyRateLimit(ctx context.Context, userID int64) error { +// checkApiKeyRateLimit 检查用户创建自定义Key的错误次数是否超限 +func (s *ApiKeyService) checkApiKeyRateLimit(ctx context.Context, userID int64) error { if s.cache == nil { return nil } @@ -150,14 +150,14 @@ func (s *APIKeyService) checkAPIKeyRateLimit(ctx context.Context, userID int64) } if count >= apiKeyMaxErrorsPerHour { - return ErrAPIKeyRateLimited + return ErrApiKeyRateLimited } return nil } -// incrementAPIKeyErrorCount 增加用户创建自定义Key的错误计数 -func (s *APIKeyService) incrementAPIKeyErrorCount(ctx context.Context, userID int64) { +// incrementApiKeyErrorCount 增加用户创建自定义Key的错误计数 +func (s *ApiKeyService) incrementApiKeyErrorCount(ctx context.Context, userID int64) { if s.cache == nil { return } @@ -168,7 +168,7 @@ func (s *APIKeyService) incrementAPIKeyErrorCount(ctx context.Context, userID in // canUserBindGroup 检查用户是否可以绑定指定分组 // 对于订阅类型分组:检查用户是否有有效订阅 // 对于标准类型分组:使用原有的 AllowedGroups 和 IsExclusive 逻辑 -func (s *APIKeyService) canUserBindGroup(ctx context.Context, user *User, group *Group) bool { +func (s *ApiKeyService) canUserBindGroup(ctx context.Context, user *User, group *Group) bool { // 订阅类型分组:需要有效订阅 if group.IsSubscriptionType() { _, err := s.userSubRepo.GetActiveByUserIDAndGroupID(ctx, user.ID, group.ID) @@ -179,7 +179,7 @@ func (s *APIKeyService) canUserBindGroup(ctx context.Context, user *User, group } // Create 创建API Key -func (s *APIKeyService) Create(ctx context.Context, userID int64, req CreateAPIKeyRequest) (*APIKey, error) { +func (s *ApiKeyService) Create(ctx context.Context, userID int64, req CreateApiKeyRequest) (*ApiKey, error) { // 验证用户存在 user, err := s.userRepo.GetByID(ctx, userID) if err != nil { @@ -204,7 +204,7 @@ func (s *APIKeyService) Create(ctx context.Context, userID int64, req CreateAPIK // 判断是否使用自定义Key if req.CustomKey != nil && *req.CustomKey != "" { // 检查限流(仅对自定义key进行限流) - if err := s.checkAPIKeyRateLimit(ctx, userID); err != nil { + if err := s.checkApiKeyRateLimit(ctx, userID); err != nil { return nil, err } @@ -219,9 +219,9 @@ func (s *APIKeyService) Create(ctx context.Context, userID int64, req CreateAPIK return nil, fmt.Errorf("check key exists: %w", err) } if exists { - // Key已存在,增加错误计数 - s.incrementAPIKeyErrorCount(ctx, userID) - return nil, ErrAPIKeyExists + // Key已存在,增加错误计数 + s.incrementApiKeyErrorCount(ctx, userID) + return nil, ErrApiKeyExists } key = *req.CustomKey @@ -235,7 +235,7 @@ func (s *APIKeyService) Create(ctx context.Context, userID int64, req CreateAPIK } // 创建API Key记录 - apiKey := &APIKey{ + apiKey := &ApiKey{ UserID: userID, Key: key, Name: req.Name, @@ -251,7 +251,7 @@ func (s *APIKeyService) Create(ctx context.Context, userID int64, req CreateAPIK } // List 获取用户的API Key列表 -func (s *APIKeyService) List(ctx context.Context, userID int64, params pagination.PaginationParams) ([]APIKey, *pagination.PaginationResult, error) { +func (s *ApiKeyService) List(ctx context.Context, userID int64, params pagination.PaginationParams) ([]ApiKey, *pagination.PaginationResult, error) { keys, pagination, err := s.apiKeyRepo.ListByUserID(ctx, userID, params) if err != nil { return nil, nil, fmt.Errorf("list api keys: %w", err) @@ -259,7 +259,7 @@ func (s *APIKeyService) List(ctx context.Context, userID int64, params paginatio return keys, pagination, nil } -func (s *APIKeyService) VerifyOwnership(ctx context.Context, userID int64, apiKeyIDs []int64) ([]int64, error) { +func (s *ApiKeyService) VerifyOwnership(ctx context.Context, userID int64, apiKeyIDs []int64) ([]int64, error) { if len(apiKeyIDs) == 0 { return []int64{}, nil } @@ -272,7 +272,7 @@ func (s *APIKeyService) VerifyOwnership(ctx context.Context, userID int64, apiKe } // GetByID 根据ID获取API Key -func (s *APIKeyService) GetByID(ctx context.Context, id int64) (*APIKey, error) { +func (s *ApiKeyService) GetByID(ctx context.Context, id int64) (*ApiKey, error) { apiKey, err := s.apiKeyRepo.GetByID(ctx, id) if err != nil { return nil, fmt.Errorf("get api key: %w", err) @@ -281,7 +281,7 @@ func (s *APIKeyService) GetByID(ctx context.Context, id int64) (*APIKey, error) } // GetByKey 根据Key字符串获取API Key(用于认证) -func (s *APIKeyService) GetByKey(ctx context.Context, key string) (*APIKey, error) { +func (s *ApiKeyService) GetByKey(ctx context.Context, key string) (*ApiKey, error) { // 尝试从Redis缓存获取 cacheKey := fmt.Sprintf("apikey:%s", key) @@ -301,7 +301,7 @@ func (s *APIKeyService) GetByKey(ctx context.Context, key string) (*APIKey, erro } // Update 更新API Key -func (s *APIKeyService) Update(ctx context.Context, id int64, userID int64, req UpdateAPIKeyRequest) (*APIKey, error) { +func (s *ApiKeyService) Update(ctx context.Context, id int64, userID int64, req UpdateApiKeyRequest) (*ApiKey, error) { apiKey, err := s.apiKeyRepo.GetByID(ctx, id) if err != nil { return nil, fmt.Errorf("get api key: %w", err) @@ -353,8 +353,8 @@ func (s *APIKeyService) Update(ctx context.Context, id int64, userID int64, req // Delete 删除API Key // 优化:使用 GetOwnerID 替代 GetByID 进行权限验证, -// 避免加载完整 APIKey 对象及其关联数据(User、Group),提升删除操作的性能 -func (s *APIKeyService) Delete(ctx context.Context, id int64, userID int64) error { +// 避免加载完整 ApiKey 对象及其关联数据(User、Group),提升删除操作的性能 +func (s *ApiKeyService) Delete(ctx context.Context, id int64, userID int64) error { // 仅获取所有者 ID 用于权限验证,而非加载完整对象 ownerID, err := s.apiKeyRepo.GetOwnerID(ctx, id) if err != nil { @@ -379,7 +379,7 @@ func (s *APIKeyService) Delete(ctx context.Context, id int64, userID int64) erro } // ValidateKey 验证API Key是否有效(用于认证中间件) -func (s *APIKeyService) ValidateKey(ctx context.Context, key string) (*APIKey, *User, error) { +func (s *ApiKeyService) ValidateKey(ctx context.Context, key string) (*ApiKey, *User, error) { // 获取API Key apiKey, err := s.GetByKey(ctx, key) if err != nil { @@ -406,7 +406,7 @@ func (s *APIKeyService) ValidateKey(ctx context.Context, key string) (*APIKey, * } // IncrementUsage 增加API Key使用次数(可选:用于统计) -func (s *APIKeyService) IncrementUsage(ctx context.Context, keyID int64) error { +func (s *ApiKeyService) IncrementUsage(ctx context.Context, keyID int64) error { // 使用Redis计数器 if s.cache != nil { cacheKey := fmt.Sprintf("apikey:usage:%d:%s", keyID, timezone.Now().Format("2006-01-02")) @@ -423,7 +423,7 @@ func (s *APIKeyService) IncrementUsage(ctx context.Context, keyID int64) error { // 返回用户可以选择的分组: // - 标准类型分组:公开的(非专属)或用户被明确允许的 // - 订阅类型分组:用户有有效订阅的 -func (s *APIKeyService) GetAvailableGroups(ctx context.Context, userID int64) ([]Group, error) { +func (s *ApiKeyService) GetAvailableGroups(ctx context.Context, userID int64) ([]Group, error) { // 获取用户信息 user, err := s.userRepo.GetByID(ctx, userID) if err != nil { @@ -460,7 +460,7 @@ func (s *APIKeyService) GetAvailableGroups(ctx context.Context, userID int64) ([ } // canUserBindGroupInternal 内部方法,检查用户是否可以绑定分组(使用预加载的订阅数据) -func (s *APIKeyService) canUserBindGroupInternal(user *User, group *Group, subscribedGroupIDs map[int64]bool) bool { +func (s *ApiKeyService) canUserBindGroupInternal(user *User, group *Group, subscribedGroupIDs map[int64]bool) bool { // 订阅类型分组:需要有效订阅 if group.IsSubscriptionType() { return subscribedGroupIDs[group.ID] @@ -469,8 +469,8 @@ func (s *APIKeyService) canUserBindGroupInternal(user *User, group *Group, subsc return user.CanBindGroup(group.ID, group.IsExclusive) } -func (s *APIKeyService) SearchAPIKeys(ctx context.Context, userID int64, keyword string, limit int) ([]APIKey, error) { - keys, err := s.apiKeyRepo.SearchAPIKeys(ctx, userID, keyword, limit) +func (s *ApiKeyService) SearchApiKeys(ctx context.Context, userID int64, keyword string, limit int) ([]ApiKey, error) { + keys, err := s.apiKeyRepo.SearchApiKeys(ctx, userID, keyword, limit) if err != nil { return nil, fmt.Errorf("search api keys: %w", err) } diff --git a/backend/internal/service/api_key_service_delete_test.go b/backend/internal/service/api_key_service_delete_test.go index 1b1bfb6f..deac8499 100644 --- a/backend/internal/service/api_key_service_delete_test.go +++ b/backend/internal/service/api_key_service_delete_test.go @@ -1,7 +1,7 @@ //go:build unit // API Key 服务删除方法的单元测试 -// 测试 APIKeyService.Delete 方法在各种场景下的行为, +// 测试 ApiKeyService.Delete 方法在各种场景下的行为, // 包括权限验证、缓存清理和错误处理 package service @@ -16,12 +16,12 @@ import ( "github.com/stretchr/testify/require" ) -// apiKeyRepoStub 是 APIKeyRepository 接口的测试桩实现。 -// 用于隔离测试 APIKeyService.Delete 方法,避免依赖真实数据库。 +// apiKeyRepoStub 是 ApiKeyRepository 接口的测试桩实现。 +// 用于隔离测试 ApiKeyService.Delete 方法,避免依赖真实数据库。 // // 设计说明: // - ownerID: 模拟 GetOwnerID 返回的所有者 ID -// - ownerErr: 模拟 GetOwnerID 返回的错误(如 ErrAPIKeyNotFound) +// - ownerErr: 模拟 GetOwnerID 返回的错误(如 ErrApiKeyNotFound) // - deleteErr: 模拟 Delete 返回的错误 // - deletedIDs: 记录被调用删除的 API Key ID,用于断言验证 type apiKeyRepoStub struct { @@ -33,11 +33,11 @@ type apiKeyRepoStub struct { // 以下方法在本测试中不应被调用,使用 panic 确保测试失败时能快速定位问题 -func (s *apiKeyRepoStub) Create(ctx context.Context, key *APIKey) error { +func (s *apiKeyRepoStub) Create(ctx context.Context, key *ApiKey) error { panic("unexpected Create call") } -func (s *apiKeyRepoStub) GetByID(ctx context.Context, id int64) (*APIKey, error) { +func (s *apiKeyRepoStub) GetByID(ctx context.Context, id int64) (*ApiKey, error) { panic("unexpected GetByID call") } @@ -47,11 +47,11 @@ func (s *apiKeyRepoStub) GetOwnerID(ctx context.Context, id int64) (int64, error return s.ownerID, s.ownerErr } -func (s *apiKeyRepoStub) GetByKey(ctx context.Context, key string) (*APIKey, error) { +func (s *apiKeyRepoStub) GetByKey(ctx context.Context, key string) (*ApiKey, error) { panic("unexpected GetByKey call") } -func (s *apiKeyRepoStub) Update(ctx context.Context, key *APIKey) error { +func (s *apiKeyRepoStub) Update(ctx context.Context, key *ApiKey) error { panic("unexpected Update call") } @@ -64,7 +64,7 @@ func (s *apiKeyRepoStub) Delete(ctx context.Context, id int64) error { // 以下是接口要求实现但本测试不关心的方法 -func (s *apiKeyRepoStub) ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]APIKey, *pagination.PaginationResult, error) { +func (s *apiKeyRepoStub) ListByUserID(ctx context.Context, userID int64, params pagination.PaginationParams) ([]ApiKey, *pagination.PaginationResult, error) { panic("unexpected ListByUserID call") } @@ -80,12 +80,12 @@ func (s *apiKeyRepoStub) ExistsByKey(ctx context.Context, key string) (bool, err panic("unexpected ExistsByKey call") } -func (s *apiKeyRepoStub) ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]APIKey, *pagination.PaginationResult, error) { +func (s *apiKeyRepoStub) ListByGroupID(ctx context.Context, groupID int64, params pagination.PaginationParams) ([]ApiKey, *pagination.PaginationResult, error) { panic("unexpected ListByGroupID call") } -func (s *apiKeyRepoStub) SearchAPIKeys(ctx context.Context, userID int64, keyword string, limit int) ([]APIKey, error) { - panic("unexpected SearchAPIKeys call") +func (s *apiKeyRepoStub) SearchApiKeys(ctx context.Context, userID int64, keyword string, limit int) ([]ApiKey, error) { + panic("unexpected SearchApiKeys call") } func (s *apiKeyRepoStub) ClearGroupIDByGroupID(ctx context.Context, groupID int64) (int64, error) { @@ -96,7 +96,7 @@ func (s *apiKeyRepoStub) CountByGroupID(ctx context.Context, groupID int64) (int panic("unexpected CountByGroupID call") } -// apiKeyCacheStub 是 APIKeyCache 接口的测试桩实现。 +// apiKeyCacheStub 是 ApiKeyCache 接口的测试桩实现。 // 用于验证删除操作时缓存清理逻辑是否被正确调用。 // // 设计说明: @@ -132,17 +132,17 @@ func (s *apiKeyCacheStub) SetDailyUsageExpiry(ctx context.Context, apiKey string return nil } -// TestAPIKeyService_Delete_OwnerMismatch 测试非所有者尝试删除时返回权限错误。 +// TestApiKeyService_Delete_OwnerMismatch 测试非所有者尝试删除时返回权限错误。 // 预期行为: // - GetOwnerID 返回所有者 ID 为 1 // - 调用者 userID 为 2(不匹配) // - 返回 ErrInsufficientPerms 错误 // - Delete 方法不被调用 // - 缓存不被清除 -func TestAPIKeyService_Delete_OwnerMismatch(t *testing.T) { +func TestApiKeyService_Delete_OwnerMismatch(t *testing.T) { repo := &apiKeyRepoStub{ownerID: 1} cache := &apiKeyCacheStub{} - svc := &APIKeyService{apiKeyRepo: repo, cache: cache} + svc := &ApiKeyService{apiKeyRepo: repo, cache: cache} err := svc.Delete(context.Background(), 10, 2) // API Key ID=10, 调用者 userID=2 require.ErrorIs(t, err, ErrInsufficientPerms) @@ -150,17 +150,17 @@ func TestAPIKeyService_Delete_OwnerMismatch(t *testing.T) { require.Empty(t, cache.invalidated) // 验证缓存未被清除 } -// TestAPIKeyService_Delete_Success 测试所有者成功删除 API Key 的场景。 +// TestApiKeyService_Delete_Success 测试所有者成功删除 API Key 的场景。 // 预期行为: // - GetOwnerID 返回所有者 ID 为 7 // - 调用者 userID 为 7(匹配) // - Delete 成功执行 // - 缓存被正确清除(使用 ownerID) // - 返回 nil 错误 -func TestAPIKeyService_Delete_Success(t *testing.T) { +func TestApiKeyService_Delete_Success(t *testing.T) { repo := &apiKeyRepoStub{ownerID: 7} cache := &apiKeyCacheStub{} - svc := &APIKeyService{apiKeyRepo: repo, cache: cache} + svc := &ApiKeyService{apiKeyRepo: repo, cache: cache} err := svc.Delete(context.Background(), 42, 7) // API Key ID=42, 调用者 userID=7 require.NoError(t, err) @@ -168,37 +168,37 @@ func TestAPIKeyService_Delete_Success(t *testing.T) { require.Equal(t, []int64{7}, cache.invalidated) // 验证所有者的缓存被清除 } -// TestAPIKeyService_Delete_NotFound 测试删除不存在的 API Key 时返回正确的错误。 +// TestApiKeyService_Delete_NotFound 测试删除不存在的 API Key 时返回正确的错误。 // 预期行为: -// - GetOwnerID 返回 ErrAPIKeyNotFound 错误 -// - 返回 ErrAPIKeyNotFound 错误(被 fmt.Errorf 包装) +// - GetOwnerID 返回 ErrApiKeyNotFound 错误 +// - 返回 ErrApiKeyNotFound 错误(被 fmt.Errorf 包装) // - Delete 方法不被调用 // - 缓存不被清除 -func TestAPIKeyService_Delete_NotFound(t *testing.T) { - repo := &apiKeyRepoStub{ownerErr: ErrAPIKeyNotFound} +func TestApiKeyService_Delete_NotFound(t *testing.T) { + repo := &apiKeyRepoStub{ownerErr: ErrApiKeyNotFound} cache := &apiKeyCacheStub{} - svc := &APIKeyService{apiKeyRepo: repo, cache: cache} + svc := &ApiKeyService{apiKeyRepo: repo, cache: cache} err := svc.Delete(context.Background(), 99, 1) - require.ErrorIs(t, err, ErrAPIKeyNotFound) + require.ErrorIs(t, err, ErrApiKeyNotFound) require.Empty(t, repo.deletedIDs) require.Empty(t, cache.invalidated) } -// TestAPIKeyService_Delete_DeleteFails 测试删除操作失败时的错误处理。 +// TestApiKeyService_Delete_DeleteFails 测试删除操作失败时的错误处理。 // 预期行为: // - GetOwnerID 返回正确的所有者 ID // - 所有权验证通过 // - 缓存被清除(在删除之前) // - Delete 被调用但返回错误 // - 返回包含 "delete api key" 的错误信息 -func TestAPIKeyService_Delete_DeleteFails(t *testing.T) { +func TestApiKeyService_Delete_DeleteFails(t *testing.T) { repo := &apiKeyRepoStub{ ownerID: 3, deleteErr: errors.New("delete failed"), } cache := &apiKeyCacheStub{} - svc := &APIKeyService{apiKeyRepo: repo, cache: cache} + svc := &ApiKeyService{apiKeyRepo: repo, cache: cache} err := svc.Delete(context.Background(), 3, 3) // API Key ID=3, 调用者 userID=3 require.Error(t, err) diff --git a/backend/internal/service/billing_cache_service.go b/backend/internal/service/billing_cache_service.go index 86148b37..9cdeed7b 100644 --- a/backend/internal/service/billing_cache_service.go +++ b/backend/internal/service/billing_cache_service.go @@ -445,7 +445,7 @@ func (s *BillingCacheService) InvalidateSubscription(ctx context.Context, userID // CheckBillingEligibility 检查用户是否有资格发起请求 // 余额模式:检查缓存余额 > 0 // 订阅模式:检查缓存用量未超过限额(Group限额从参数传入) -func (s *BillingCacheService) CheckBillingEligibility(ctx context.Context, user *User, apiKey *APIKey, group *Group, subscription *UserSubscription) error { +func (s *BillingCacheService) CheckBillingEligibility(ctx context.Context, user *User, apiKey *ApiKey, group *Group, subscription *UserSubscription) error { // 简易模式:跳过所有计费检查 if s.cfg.RunMode == config.RunModeSimple { return nil diff --git a/backend/internal/service/crs_sync_service.go b/backend/internal/service/crs_sync_service.go index 1647b62e..fd23ecb2 100644 --- a/backend/internal/service/crs_sync_service.go +++ b/backend/internal/service/crs_sync_service.go @@ -82,7 +82,7 @@ type crsExportResponse struct { OpenAIOAuthAccounts []crsOpenAIOAuthAccount `json:"openaiOAuthAccounts"` OpenAIResponsesAccounts []crsOpenAIResponsesAccount `json:"openaiResponsesAccounts"` GeminiOAuthAccounts []crsGeminiOAuthAccount `json:"geminiOAuthAccounts"` - GeminiAPIKeyAccounts []crsGeminiAPIKeyAccount `json:"geminiAPIKeyAccounts"` + GeminiAPIKeyAccounts []crsGeminiAPIKeyAccount `json:"geminiApiKeyAccounts"` } `json:"data"` } @@ -430,7 +430,7 @@ func (s *CRSSyncService) SyncFromCRS(ctx context.Context, input SyncFromCRSInput account := &Account{ Name: defaultName(src.Name, src.ID), Platform: PlatformAnthropic, - Type: AccountTypeAPIKey, + Type: AccountTypeApiKey, Credentials: credentials, Extra: extra, ProxyID: proxyID, @@ -455,7 +455,7 @@ func (s *CRSSyncService) SyncFromCRS(ctx context.Context, input SyncFromCRSInput existing.Extra = mergeMap(existing.Extra, extra) existing.Name = defaultName(src.Name, src.ID) existing.Platform = PlatformAnthropic - existing.Type = AccountTypeAPIKey + existing.Type = AccountTypeApiKey existing.Credentials = mergeMap(existing.Credentials, credentials) if proxyID != nil { existing.ProxyID = proxyID @@ -674,7 +674,7 @@ func (s *CRSSyncService) SyncFromCRS(ctx context.Context, input SyncFromCRSInput account := &Account{ Name: defaultName(src.Name, src.ID), Platform: PlatformOpenAI, - Type: AccountTypeAPIKey, + Type: AccountTypeApiKey, Credentials: credentials, Extra: extra, ProxyID: proxyID, @@ -699,7 +699,7 @@ func (s *CRSSyncService) SyncFromCRS(ctx context.Context, input SyncFromCRSInput existing.Extra = mergeMap(existing.Extra, extra) existing.Name = defaultName(src.Name, src.ID) existing.Platform = PlatformOpenAI - existing.Type = AccountTypeAPIKey + existing.Type = AccountTypeApiKey existing.Credentials = mergeMap(existing.Credentials, credentials) if proxyID != nil { existing.ProxyID = proxyID @@ -893,7 +893,7 @@ func (s *CRSSyncService) SyncFromCRS(ctx context.Context, input SyncFromCRSInput account := &Account{ Name: defaultName(src.Name, src.ID), Platform: PlatformGemini, - Type: AccountTypeAPIKey, + Type: AccountTypeApiKey, Credentials: credentials, Extra: extra, ProxyID: proxyID, @@ -918,7 +918,7 @@ func (s *CRSSyncService) SyncFromCRS(ctx context.Context, input SyncFromCRSInput existing.Extra = mergeMap(existing.Extra, extra) existing.Name = defaultName(src.Name, src.ID) existing.Platform = PlatformGemini - existing.Type = AccountTypeAPIKey + existing.Type = AccountTypeApiKey existing.Credentials = mergeMap(existing.Credentials, credentials) if proxyID != nil { existing.ProxyID = proxyID diff --git a/backend/internal/service/dashboard_service.go b/backend/internal/service/dashboard_service.go index f0b1f2a0..4de4a751 100644 --- a/backend/internal/service/dashboard_service.go +++ b/backend/internal/service/dashboard_service.go @@ -43,8 +43,8 @@ func (s *DashboardService) GetModelStatsWithFilters(ctx context.Context, startTi return stats, nil } -func (s *DashboardService) GetAPIKeyUsageTrend(ctx context.Context, startTime, endTime time.Time, granularity string, limit int) ([]usagestats.APIKeyUsageTrendPoint, error) { - trend, err := s.usageRepo.GetAPIKeyUsageTrend(ctx, startTime, endTime, granularity, limit) +func (s *DashboardService) GetApiKeyUsageTrend(ctx context.Context, startTime, endTime time.Time, granularity string, limit int) ([]usagestats.ApiKeyUsageTrendPoint, error) { + trend, err := s.usageRepo.GetApiKeyUsageTrend(ctx, startTime, endTime, granularity, limit) if err != nil { return nil, fmt.Errorf("get api key usage trend: %w", err) } @@ -67,8 +67,8 @@ func (s *DashboardService) GetBatchUserUsageStats(ctx context.Context, userIDs [ return stats, nil } -func (s *DashboardService) GetBatchAPIKeyUsageStats(ctx context.Context, apiKeyIDs []int64) (map[int64]*usagestats.BatchAPIKeyUsageStats, error) { - stats, err := s.usageRepo.GetBatchAPIKeyUsageStats(ctx, apiKeyIDs) +func (s *DashboardService) GetBatchApiKeyUsageStats(ctx context.Context, apiKeyIDs []int64) (map[int64]*usagestats.BatchApiKeyUsageStats, error) { + stats, err := s.usageRepo.GetBatchApiKeyUsageStats(ctx, apiKeyIDs) if err != nil { return nil, fmt.Errorf("get batch api key usage stats: %w", err) } diff --git a/backend/internal/service/domain_constants.go b/backend/internal/service/domain_constants.go index 5dde0df0..9d3d427f 100644 --- a/backend/internal/service/domain_constants.go +++ b/backend/internal/service/domain_constants.go @@ -28,7 +28,7 @@ const ( const ( AccountTypeOAuth = "oauth" // OAuth类型账号(full scope: profile + inference) AccountTypeSetupToken = "setup-token" // Setup Token类型账号(inference only scope) - AccountTypeAPIKey = "apikey" // API Key类型账号 + AccountTypeApiKey = "apikey" // API Key类型账号 ) // Redeem type constants @@ -64,13 +64,13 @@ const ( SettingKeyEmailVerifyEnabled = "email_verify_enabled" // 是否开启邮件验证 // 邮件服务设置 - SettingKeySMTPHost = "smtp_host" // SMTP服务器地址 - SettingKeySMTPPort = "smtp_port" // SMTP端口 - SettingKeySMTPUsername = "smtp_username" // SMTP用户名 - SettingKeySMTPPassword = "smtp_password" // SMTP密码(加密存储) - SettingKeySMTPFrom = "smtp_from" // 发件人地址 - SettingKeySMTPFromName = "smtp_from_name" // 发件人名称 - SettingKeySMTPUseTLS = "smtp_use_tls" // 是否使用TLS + SettingKeySmtpHost = "smtp_host" // SMTP服务器地址 + SettingKeySmtpPort = "smtp_port" // SMTP端口 + SettingKeySmtpUsername = "smtp_username" // SMTP用户名 + SettingKeySmtpPassword = "smtp_password" // SMTP密码(加密存储) + SettingKeySmtpFrom = "smtp_from" // 发件人地址 + SettingKeySmtpFromName = "smtp_from_name" // 发件人名称 + SettingKeySmtpUseTLS = "smtp_use_tls" // 是否使用TLS // Cloudflare Turnstile 设置 SettingKeyTurnstileEnabled = "turnstile_enabled" // 是否启用 Turnstile 验证 @@ -81,20 +81,27 @@ const ( SettingKeySiteName = "site_name" // 网站名称 SettingKeySiteLogo = "site_logo" // 网站Logo (base64) SettingKeySiteSubtitle = "site_subtitle" // 网站副标题 - SettingKeyAPIBaseURL = "api_base_url" // API端点地址(用于客户端配置和导入) + SettingKeyApiBaseUrl = "api_base_url" // API端点地址(用于客户端配置和导入) SettingKeyContactInfo = "contact_info" // 客服联系方式 - SettingKeyDocURL = "doc_url" // 文档链接 + SettingKeyDocUrl = "doc_url" // 文档链接 // 默认配置 SettingKeyDefaultConcurrency = "default_concurrency" // 新用户默认并发量 SettingKeyDefaultBalance = "default_balance" // 新用户默认余额 // 管理员 API Key - SettingKeyAdminAPIKey = "admin_api_key" // 全局管理员 API Key(用于外部系统集成) + SettingKeyAdminApiKey = "admin_api_key" // 全局管理员 API Key(用于外部系统集成) // Gemini 配额策略(JSON) SettingKeyGeminiQuotaPolicy = "gemini_quota_policy" + + // Model fallback settings + SettingKeyEnableModelFallback = "enable_model_fallback" + SettingKeyFallbackModelAnthropic = "fallback_model_anthropic" + SettingKeyFallbackModelOpenAI = "fallback_model_openai" + SettingKeyFallbackModelGemini = "fallback_model_gemini" + SettingKeyFallbackModelAntigravity = "fallback_model_antigravity" ) -// AdminAPIKeyPrefix is the prefix for admin API keys (distinct from user "sk-" keys) -const AdminAPIKeyPrefix = "admin-" +// Admin API Key prefix (distinct from user "sk-" keys) +const AdminApiKeyPrefix = "admin-" diff --git a/backend/internal/service/email_service.go b/backend/internal/service/email_service.go index d6a3c05b..6537b01e 100644 --- a/backend/internal/service/email_service.go +++ b/backend/internal/service/email_service.go @@ -40,8 +40,8 @@ const ( maxVerifyCodeAttempts = 5 ) -// SMTPConfig SMTP配置 -type SMTPConfig struct { +// SmtpConfig SMTP配置 +type SmtpConfig struct { Host string Port int Username string @@ -65,16 +65,16 @@ func NewEmailService(settingRepo SettingRepository, cache EmailCache) *EmailServ } } -// GetSMTPConfig 从数据库获取SMTP配置 -func (s *EmailService) GetSMTPConfig(ctx context.Context) (*SMTPConfig, error) { +// GetSmtpConfig 从数据库获取SMTP配置 +func (s *EmailService) GetSmtpConfig(ctx context.Context) (*SmtpConfig, error) { keys := []string{ - SettingKeySMTPHost, - SettingKeySMTPPort, - SettingKeySMTPUsername, - SettingKeySMTPPassword, - SettingKeySMTPFrom, - SettingKeySMTPFromName, - SettingKeySMTPUseTLS, + SettingKeySmtpHost, + SettingKeySmtpPort, + SettingKeySmtpUsername, + SettingKeySmtpPassword, + SettingKeySmtpFrom, + SettingKeySmtpFromName, + SettingKeySmtpUseTLS, } settings, err := s.settingRepo.GetMultiple(ctx, keys) @@ -82,34 +82,34 @@ func (s *EmailService) GetSMTPConfig(ctx context.Context) (*SMTPConfig, error) { return nil, fmt.Errorf("get smtp settings: %w", err) } - host := settings[SettingKeySMTPHost] + host := settings[SettingKeySmtpHost] if host == "" { return nil, ErrEmailNotConfigured } port := 587 // 默认端口 - if portStr := settings[SettingKeySMTPPort]; portStr != "" { + if portStr := settings[SettingKeySmtpPort]; portStr != "" { if p, err := strconv.Atoi(portStr); err == nil { port = p } } - useTLS := settings[SettingKeySMTPUseTLS] == "true" + useTLS := settings[SettingKeySmtpUseTLS] == "true" - return &SMTPConfig{ + return &SmtpConfig{ Host: host, Port: port, - Username: settings[SettingKeySMTPUsername], - Password: settings[SettingKeySMTPPassword], - From: settings[SettingKeySMTPFrom], - FromName: settings[SettingKeySMTPFromName], + Username: settings[SettingKeySmtpUsername], + Password: settings[SettingKeySmtpPassword], + From: settings[SettingKeySmtpFrom], + FromName: settings[SettingKeySmtpFromName], UseTLS: useTLS, }, nil } // SendEmail 发送邮件(使用数据库中保存的配置) func (s *EmailService) SendEmail(ctx context.Context, to, subject, body string) error { - config, err := s.GetSMTPConfig(ctx) + config, err := s.GetSmtpConfig(ctx) if err != nil { return err } @@ -117,7 +117,7 @@ func (s *EmailService) SendEmail(ctx context.Context, to, subject, body string) } // SendEmailWithConfig 使用指定配置发送邮件 -func (s *EmailService) SendEmailWithConfig(config *SMTPConfig, to, subject, body string) error { +func (s *EmailService) SendEmailWithConfig(config *SmtpConfig, to, subject, body string) error { from := config.From if config.FromName != "" { from = fmt.Sprintf("%s <%s>", config.FromName, config.From) @@ -306,8 +306,8 @@ func (s *EmailService) buildVerifyCodeEmailBody(code, siteName string) string { `, siteName, code) } -// TestSMTPConnectionWithConfig 使用指定配置测试SMTP连接 -func (s *EmailService) TestSMTPConnectionWithConfig(config *SMTPConfig) error { +// TestSmtpConnectionWithConfig 使用指定配置测试SMTP连接 +func (s *EmailService) TestSmtpConnectionWithConfig(config *SmtpConfig) error { addr := fmt.Sprintf("%s:%d", config.Host, config.Port) if config.UseTLS { diff --git a/backend/internal/service/openai_gateway_service.go b/backend/internal/service/openai_gateway_service.go index b9096715..6da587ad 100644 --- a/backend/internal/service/openai_gateway_service.go +++ b/backend/internal/service/openai_gateway_service.go @@ -487,8 +487,8 @@ func (s *OpenAIGatewayService) GetAccessToken(ctx context.Context, account *Acco return "", "", errors.New("access_token not found in credentials") } return accessToken, "oauth", nil - case AccountTypeAPIKey: - apiKey := account.GetOpenAIAPIKey() + case AccountTypeApiKey: + apiKey := account.GetOpenAIApiKey() if apiKey == "" { return "", "", errors.New("api_key not found in credentials") } @@ -627,7 +627,7 @@ func (s *OpenAIGatewayService) buildUpstreamRequest(ctx context.Context, c *gin. case AccountTypeOAuth: // OAuth accounts use ChatGPT internal API targetURL = chatgptCodexURL - case AccountTypeAPIKey: + case AccountTypeApiKey: // API Key accounts use Platform API or custom base URL baseURL := account.GetOpenAIBaseURL() if baseURL != "" { @@ -703,7 +703,13 @@ func (s *OpenAIGatewayService) handleErrorResponse(ctx context.Context, resp *ht } // Handle upstream error (mark account status) - s.rateLimitService.HandleUpstreamError(ctx, account, resp.StatusCode, resp.Header, body) + shouldDisable := false + if s.rateLimitService != nil { + shouldDisable = s.rateLimitService.HandleUpstreamError(ctx, account, resp.StatusCode, resp.Header, body) + } + if shouldDisable { + return nil, &UpstreamFailoverError{StatusCode: resp.StatusCode} + } // Return appropriate error response var errType, errMsg string @@ -940,7 +946,7 @@ func (s *OpenAIGatewayService) replaceModelInResponseBody(body []byte, fromModel // OpenAIRecordUsageInput input for recording usage type OpenAIRecordUsageInput struct { Result *OpenAIForwardResult - APIKey *APIKey + ApiKey *ApiKey User *User Account *Account Subscription *UserSubscription @@ -949,7 +955,7 @@ type OpenAIRecordUsageInput struct { // RecordUsage records usage and deducts balance func (s *OpenAIGatewayService) RecordUsage(ctx context.Context, input *OpenAIRecordUsageInput) error { result := input.Result - apiKey := input.APIKey + apiKey := input.ApiKey user := input.User account := input.Account subscription := input.Subscription @@ -991,7 +997,7 @@ func (s *OpenAIGatewayService) RecordUsage(ctx context.Context, input *OpenAIRec durationMs := int(result.Duration.Milliseconds()) usageLog := &UsageLog{ UserID: user.ID, - APIKeyID: apiKey.ID, + ApiKeyID: apiKey.ID, AccountID: account.ID, RequestID: result.RequestID, Model: result.Model, diff --git a/backend/internal/service/setting_service.go b/backend/internal/service/setting_service.go index 4c993871..44013a99 100644 --- a/backend/internal/service/setting_service.go +++ b/backend/internal/service/setting_service.go @@ -61,9 +61,9 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings SettingKeySiteName, SettingKeySiteLogo, SettingKeySiteSubtitle, - SettingKeyAPIBaseURL, + SettingKeyApiBaseUrl, SettingKeyContactInfo, - SettingKeyDocURL, + SettingKeyDocUrl, } settings, err := s.settingRepo.GetMultiple(ctx, keys) @@ -79,9 +79,9 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings SiteName: s.getStringOrDefault(settings, SettingKeySiteName, "Sub2API"), SiteLogo: settings[SettingKeySiteLogo], SiteSubtitle: s.getStringOrDefault(settings, SettingKeySiteSubtitle, "Subscription to API Conversion Platform"), - APIBaseURL: settings[SettingKeyAPIBaseURL], + ApiBaseUrl: settings[SettingKeyApiBaseUrl], ContactInfo: settings[SettingKeyContactInfo], - DocURL: settings[SettingKeyDocURL], + DocUrl: settings[SettingKeyDocUrl], }, nil } @@ -94,15 +94,15 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet updates[SettingKeyEmailVerifyEnabled] = strconv.FormatBool(settings.EmailVerifyEnabled) // 邮件服务设置(只有非空才更新密码) - updates[SettingKeySMTPHost] = settings.SMTPHost - updates[SettingKeySMTPPort] = strconv.Itoa(settings.SMTPPort) - updates[SettingKeySMTPUsername] = settings.SMTPUsername - if settings.SMTPPassword != "" { - updates[SettingKeySMTPPassword] = settings.SMTPPassword + updates[SettingKeySmtpHost] = settings.SmtpHost + updates[SettingKeySmtpPort] = strconv.Itoa(settings.SmtpPort) + updates[SettingKeySmtpUsername] = settings.SmtpUsername + if settings.SmtpPassword != "" { + updates[SettingKeySmtpPassword] = settings.SmtpPassword } - updates[SettingKeySMTPFrom] = settings.SMTPFrom - updates[SettingKeySMTPFromName] = settings.SMTPFromName - updates[SettingKeySMTPUseTLS] = strconv.FormatBool(settings.SMTPUseTLS) + updates[SettingKeySmtpFrom] = settings.SmtpFrom + updates[SettingKeySmtpFromName] = settings.SmtpFromName + updates[SettingKeySmtpUseTLS] = strconv.FormatBool(settings.SmtpUseTLS) // Cloudflare Turnstile 设置(只有非空才更新密钥) updates[SettingKeyTurnstileEnabled] = strconv.FormatBool(settings.TurnstileEnabled) @@ -115,14 +115,21 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet updates[SettingKeySiteName] = settings.SiteName updates[SettingKeySiteLogo] = settings.SiteLogo updates[SettingKeySiteSubtitle] = settings.SiteSubtitle - updates[SettingKeyAPIBaseURL] = settings.APIBaseURL + updates[SettingKeyApiBaseUrl] = settings.ApiBaseUrl updates[SettingKeyContactInfo] = settings.ContactInfo - updates[SettingKeyDocURL] = settings.DocURL + updates[SettingKeyDocUrl] = settings.DocUrl // 默认配置 updates[SettingKeyDefaultConcurrency] = strconv.Itoa(settings.DefaultConcurrency) updates[SettingKeyDefaultBalance] = strconv.FormatFloat(settings.DefaultBalance, 'f', 8, 64) + // Model fallback configuration + updates[SettingKeyEnableModelFallback] = strconv.FormatBool(settings.EnableModelFallback) + updates[SettingKeyFallbackModelAnthropic] = settings.FallbackModelAnthropic + updates[SettingKeyFallbackModelOpenAI] = settings.FallbackModelOpenAI + updates[SettingKeyFallbackModelGemini] = settings.FallbackModelGemini + updates[SettingKeyFallbackModelAntigravity] = settings.FallbackModelAntigravity + return s.settingRepo.SetMultiple(ctx, updates) } @@ -198,8 +205,14 @@ func (s *SettingService) InitializeDefaultSettings(ctx context.Context) error { SettingKeySiteLogo: "", SettingKeyDefaultConcurrency: strconv.Itoa(s.cfg.Default.UserConcurrency), SettingKeyDefaultBalance: strconv.FormatFloat(s.cfg.Default.UserBalance, 'f', 8, 64), - SettingKeySMTPPort: "587", - SettingKeySMTPUseTLS: "false", + SettingKeySmtpPort: "587", + SettingKeySmtpUseTLS: "false", + // Model fallback defaults + SettingKeyEnableModelFallback: "false", + SettingKeyFallbackModelAnthropic: "claude-3-5-sonnet-20241022", + SettingKeyFallbackModelOpenAI: "gpt-4o", + SettingKeyFallbackModelGemini: "gemini-2.5-pro", + SettingKeyFallbackModelAntigravity: "gemini-2.5-pro", } return s.settingRepo.SetMultiple(ctx, defaults) @@ -210,26 +223,26 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin result := &SystemSettings{ RegistrationEnabled: settings[SettingKeyRegistrationEnabled] == "true", EmailVerifyEnabled: settings[SettingKeyEmailVerifyEnabled] == "true", - SMTPHost: settings[SettingKeySMTPHost], - SMTPUsername: settings[SettingKeySMTPUsername], - SMTPFrom: settings[SettingKeySMTPFrom], - SMTPFromName: settings[SettingKeySMTPFromName], - SMTPUseTLS: settings[SettingKeySMTPUseTLS] == "true", + SmtpHost: settings[SettingKeySmtpHost], + SmtpUsername: settings[SettingKeySmtpUsername], + SmtpFrom: settings[SettingKeySmtpFrom], + SmtpFromName: settings[SettingKeySmtpFromName], + SmtpUseTLS: settings[SettingKeySmtpUseTLS] == "true", TurnstileEnabled: settings[SettingKeyTurnstileEnabled] == "true", TurnstileSiteKey: settings[SettingKeyTurnstileSiteKey], SiteName: s.getStringOrDefault(settings, SettingKeySiteName, "Sub2API"), SiteLogo: settings[SettingKeySiteLogo], SiteSubtitle: s.getStringOrDefault(settings, SettingKeySiteSubtitle, "Subscription to API Conversion Platform"), - APIBaseURL: settings[SettingKeyAPIBaseURL], + ApiBaseUrl: settings[SettingKeyApiBaseUrl], ContactInfo: settings[SettingKeyContactInfo], - DocURL: settings[SettingKeyDocURL], + DocUrl: settings[SettingKeyDocUrl], } // 解析整数类型 - if port, err := strconv.Atoi(settings[SettingKeySMTPPort]); err == nil { - result.SMTPPort = port + if port, err := strconv.Atoi(settings[SettingKeySmtpPort]); err == nil { + result.SmtpPort = port } else { - result.SMTPPort = 587 + result.SmtpPort = 587 } if concurrency, err := strconv.Atoi(settings[SettingKeyDefaultConcurrency]); err == nil { @@ -245,10 +258,17 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin result.DefaultBalance = s.cfg.Default.UserBalance } - // 敏感信息直接返回,方便测试连接时使用 - result.SMTPPassword = settings[SettingKeySMTPPassword] + // 敏感信息直接返回,方便测试连接时使用 + result.SmtpPassword = settings[SettingKeySmtpPassword] result.TurnstileSecretKey = settings[SettingKeyTurnstileSecretKey] + // Model fallback settings + result.EnableModelFallback = settings[SettingKeyEnableModelFallback] == "true" + result.FallbackModelAnthropic = s.getStringOrDefault(settings, SettingKeyFallbackModelAnthropic, "claude-3-5-sonnet-20241022") + result.FallbackModelOpenAI = s.getStringOrDefault(settings, SettingKeyFallbackModelOpenAI, "gpt-4o") + result.FallbackModelGemini = s.getStringOrDefault(settings, SettingKeyFallbackModelGemini, "gemini-2.5-pro") + result.FallbackModelAntigravity = s.getStringOrDefault(settings, SettingKeyFallbackModelAntigravity, "gemini-2.5-pro") + return result } @@ -278,28 +298,28 @@ func (s *SettingService) GetTurnstileSecretKey(ctx context.Context) string { return value } -// GenerateAdminAPIKey 生成新的管理员 API Key -func (s *SettingService) GenerateAdminAPIKey(ctx context.Context) (string, error) { +// GenerateAdminApiKey 生成新的管理员 API Key +func (s *SettingService) GenerateAdminApiKey(ctx context.Context) (string, error) { // 生成 32 字节随机数 = 64 位十六进制字符 bytes := make([]byte, 32) if _, err := rand.Read(bytes); err != nil { return "", fmt.Errorf("generate random bytes: %w", err) } - key := AdminAPIKeyPrefix + hex.EncodeToString(bytes) + key := AdminApiKeyPrefix + hex.EncodeToString(bytes) // 存储到 settings 表 - if err := s.settingRepo.Set(ctx, SettingKeyAdminAPIKey, key); err != nil { + if err := s.settingRepo.Set(ctx, SettingKeyAdminApiKey, key); err != nil { return "", fmt.Errorf("save admin api key: %w", err) } return key, nil } -// GetAdminAPIKeyStatus 获取管理员 API Key 状态 +// GetAdminApiKeyStatus 获取管理员 API Key 状态 // 返回脱敏的 key、是否存在、错误 -func (s *SettingService) GetAdminAPIKeyStatus(ctx context.Context) (maskedKey string, exists bool, err error) { - key, err := s.settingRepo.GetValue(ctx, SettingKeyAdminAPIKey) +func (s *SettingService) GetAdminApiKeyStatus(ctx context.Context) (maskedKey string, exists bool, err error) { + key, err := s.settingRepo.GetValue(ctx, SettingKeyAdminApiKey) if err != nil { if errors.Is(err, ErrSettingNotFound) { return "", false, nil @@ -320,10 +340,10 @@ func (s *SettingService) GetAdminAPIKeyStatus(ctx context.Context) (maskedKey st return maskedKey, true, nil } -// GetAdminAPIKey 获取完整的管理员 API Key(仅供内部验证使用) +// GetAdminApiKey 获取完整的管理员 API Key(仅供内部验证使用) // 如果未配置返回空字符串和 nil 错误,只有数据库错误时才返回 error -func (s *SettingService) GetAdminAPIKey(ctx context.Context) (string, error) { - key, err := s.settingRepo.GetValue(ctx, SettingKeyAdminAPIKey) +func (s *SettingService) GetAdminApiKey(ctx context.Context) (string, error) { + key, err := s.settingRepo.GetValue(ctx, SettingKeyAdminApiKey) if err != nil { if errors.Is(err, ErrSettingNotFound) { return "", nil // 未配置,返回空字符串 @@ -333,7 +353,45 @@ func (s *SettingService) GetAdminAPIKey(ctx context.Context) (string, error) { return key, nil } -// DeleteAdminAPIKey 删除管理员 API Key -func (s *SettingService) DeleteAdminAPIKey(ctx context.Context) error { - return s.settingRepo.Delete(ctx, SettingKeyAdminAPIKey) +// DeleteAdminApiKey 删除管理员 API Key +func (s *SettingService) DeleteAdminApiKey(ctx context.Context) error { + return s.settingRepo.Delete(ctx, SettingKeyAdminApiKey) +} + +// IsModelFallbackEnabled 检查是否启用模型兜底机制 +func (s *SettingService) IsModelFallbackEnabled(ctx context.Context) bool { + value, err := s.settingRepo.GetValue(ctx, SettingKeyEnableModelFallback) + if err != nil { + return false // Default: disabled + } + return value == "true" +} + +// GetFallbackModel 获取指定平台的兜底模型 +func (s *SettingService) GetFallbackModel(ctx context.Context, platform string) string { + var key string + var defaultModel string + + switch platform { + case PlatformAnthropic: + key = SettingKeyFallbackModelAnthropic + defaultModel = "claude-3-5-sonnet-20241022" + case PlatformOpenAI: + key = SettingKeyFallbackModelOpenAI + defaultModel = "gpt-4o" + case PlatformGemini: + key = SettingKeyFallbackModelGemini + defaultModel = "gemini-2.5-pro" + case PlatformAntigravity: + key = SettingKeyFallbackModelAntigravity + defaultModel = "gemini-2.5-pro" + default: + return "" + } + + value, err := s.settingRepo.GetValue(ctx, key) + if err != nil || value == "" { + return defaultModel + } + return value } diff --git a/backend/internal/service/settings_view.go b/backend/internal/service/settings_view.go index 83e139e7..b8cd0833 100644 --- a/backend/internal/service/settings_view.go +++ b/backend/internal/service/settings_view.go @@ -4,13 +4,13 @@ type SystemSettings struct { RegistrationEnabled bool EmailVerifyEnabled bool - SMTPHost string - SMTPPort int - SMTPUsername string - SMTPPassword string - SMTPFrom string - SMTPFromName string - SMTPUseTLS bool + SmtpHost string + SmtpPort int + SmtpUsername string + SmtpPassword string + SmtpFrom string + SmtpFromName string + SmtpUseTLS bool TurnstileEnabled bool TurnstileSiteKey string @@ -19,12 +19,19 @@ type SystemSettings struct { SiteName string SiteLogo string SiteSubtitle string - APIBaseURL string + ApiBaseUrl string ContactInfo string - DocURL string + DocUrl string DefaultConcurrency int DefaultBalance float64 + + // Model fallback configuration + EnableModelFallback bool `json:"enable_model_fallback"` + FallbackModelAnthropic string `json:"fallback_model_anthropic"` + FallbackModelOpenAI string `json:"fallback_model_openai"` + FallbackModelGemini string `json:"fallback_model_gemini"` + FallbackModelAntigravity string `json:"fallback_model_antigravity"` } type PublicSettings struct { @@ -35,8 +42,8 @@ type PublicSettings struct { SiteName string SiteLogo string SiteSubtitle string - APIBaseURL string + ApiBaseUrl string ContactInfo string - DocURL string + DocUrl string Version string } diff --git a/backend/internal/service/update_service.go b/backend/internal/service/update_service.go index 34ad4610..0c7e5a20 100644 --- a/backend/internal/service/update_service.go +++ b/backend/internal/service/update_service.go @@ -79,7 +79,7 @@ type ReleaseInfo struct { Name string `json:"name"` Body string `json:"body"` PublishedAt string `json:"published_at"` - HTMLURL string `json:"html_url"` + HtmlURL string `json:"html_url"` Assets []Asset `json:"assets,omitempty"` } @@ -96,13 +96,13 @@ type GitHubRelease struct { Name string `json:"name"` Body string `json:"body"` PublishedAt string `json:"published_at"` - HTMLURL string `json:"html_url"` + HtmlUrl string `json:"html_url"` Assets []GitHubAsset `json:"assets"` } type GitHubAsset struct { Name string `json:"name"` - BrowserDownloadURL string `json:"browser_download_url"` + BrowserDownloadUrl string `json:"browser_download_url"` Size int64 `json:"size"` } @@ -285,7 +285,7 @@ func (s *UpdateService) fetchLatestRelease(ctx context.Context) (*UpdateInfo, er for i, a := range release.Assets { assets[i] = Asset{ Name: a.Name, - DownloadURL: a.BrowserDownloadURL, + DownloadURL: a.BrowserDownloadUrl, Size: a.Size, } } @@ -298,7 +298,7 @@ func (s *UpdateService) fetchLatestRelease(ctx context.Context) (*UpdateInfo, er Name: release.Name, Body: release.Body, PublishedAt: release.PublishedAt, - HTMLURL: release.HTMLURL, + HtmlURL: release.HtmlUrl, Assets: assets, }, Cached: false, diff --git a/backend/internal/service/usage_clamp.go b/backend/internal/service/usage_clamp.go new file mode 100644 index 00000000..e81958d8 --- /dev/null +++ b/backend/internal/service/usage_clamp.go @@ -0,0 +1,35 @@ +package service + +import "time" + +// clampInt 将整数限制在指定范围内 +func clampInt(value, min, max int) int { + if value < min { + return min + } + if value > max { + return max + } + return value +} + +// clampFloat64 将浮点数限制在指定范围内 +func clampFloat64(value, min, max float64) float64 { + if value < min { + return min + } + if value > max { + return max + } + return value +} + +// remainingSecondsUntil 计算到指定时间的剩余秒数,保证非负 +func remainingSecondsUntil(t time.Time) int { + seconds := int(time.Until(t).Seconds()) + if seconds < 0 { + return 0 + } + return seconds +} + diff --git a/backend/internal/service/usage_log.go b/backend/internal/service/usage_log.go index ed0a8eb7..e822cd95 100644 --- a/backend/internal/service/usage_log.go +++ b/backend/internal/service/usage_log.go @@ -10,7 +10,7 @@ const ( type UsageLog struct { ID int64 UserID int64 - APIKeyID int64 + ApiKeyID int64 AccountID int64 RequestID string Model string @@ -42,7 +42,7 @@ type UsageLog struct { CreatedAt time.Time User *User - APIKey *APIKey + ApiKey *ApiKey Account *Account Group *Group Subscription *UserSubscription diff --git a/backend/internal/service/usage_service.go b/backend/internal/service/usage_service.go index ddb88bcf..e1e97671 100644 --- a/backend/internal/service/usage_service.go +++ b/backend/internal/service/usage_service.go @@ -17,7 +17,7 @@ var ( // CreateUsageLogRequest 创建使用日志请求 type CreateUsageLogRequest struct { UserID int64 `json:"user_id"` - APIKeyID int64 `json:"api_key_id"` + ApiKeyID int64 `json:"api_key_id"` AccountID int64 `json:"account_id"` RequestID string `json:"request_id"` Model string `json:"model"` @@ -75,7 +75,7 @@ func (s *UsageService) Create(ctx context.Context, req CreateUsageLogRequest) (* // 创建使用日志 usageLog := &UsageLog{ UserID: req.UserID, - APIKeyID: req.APIKeyID, + ApiKeyID: req.ApiKeyID, AccountID: req.AccountID, RequestID: req.RequestID, Model: req.Model, @@ -128,9 +128,9 @@ func (s *UsageService) ListByUser(ctx context.Context, userID int64, params pagi return logs, pagination, nil } -// ListByAPIKey 获取API Key的使用日志列表 -func (s *UsageService) ListByAPIKey(ctx context.Context, apiKeyID int64, params pagination.PaginationParams) ([]UsageLog, *pagination.PaginationResult, error) { - logs, pagination, err := s.usageRepo.ListByAPIKey(ctx, apiKeyID, params) +// ListByApiKey 获取API Key的使用日志列表 +func (s *UsageService) ListByApiKey(ctx context.Context, apiKeyID int64, params pagination.PaginationParams) ([]UsageLog, *pagination.PaginationResult, error) { + logs, pagination, err := s.usageRepo.ListByApiKey(ctx, apiKeyID, params) if err != nil { return nil, nil, fmt.Errorf("list usage logs: %w", err) } @@ -165,9 +165,9 @@ func (s *UsageService) GetStatsByUser(ctx context.Context, userID int64, startTi }, nil } -// GetStatsByAPIKey 获取API Key的使用统计 -func (s *UsageService) GetStatsByAPIKey(ctx context.Context, apiKeyID int64, startTime, endTime time.Time) (*UsageStats, error) { - stats, err := s.usageRepo.GetAPIKeyStatsAggregated(ctx, apiKeyID, startTime, endTime) +// GetStatsByApiKey 获取API Key的使用统计 +func (s *UsageService) GetStatsByApiKey(ctx context.Context, apiKeyID int64, startTime, endTime time.Time) (*UsageStats, error) { + stats, err := s.usageRepo.GetApiKeyStatsAggregated(ctx, apiKeyID, startTime, endTime) if err != nil { return nil, fmt.Errorf("get api key stats: %w", err) } @@ -270,9 +270,9 @@ func (s *UsageService) GetUserModelStats(ctx context.Context, userID int64, star return stats, nil } -// GetBatchAPIKeyUsageStats returns today/total actual_cost for given api keys. -func (s *UsageService) GetBatchAPIKeyUsageStats(ctx context.Context, apiKeyIDs []int64) (map[int64]*usagestats.BatchAPIKeyUsageStats, error) { - stats, err := s.usageRepo.GetBatchAPIKeyUsageStats(ctx, apiKeyIDs) +// GetBatchApiKeyUsageStats returns today/total actual_cost for given api keys. +func (s *UsageService) GetBatchApiKeyUsageStats(ctx context.Context, apiKeyIDs []int64) (map[int64]*usagestats.BatchApiKeyUsageStats, error) { + stats, err := s.usageRepo.GetBatchApiKeyUsageStats(ctx, apiKeyIDs) if err != nil { return nil, fmt.Errorf("get batch api key usage stats: %w", err) } diff --git a/backend/internal/service/user.go b/backend/internal/service/user.go index c565607e..894243df 100644 --- a/backend/internal/service/user.go +++ b/backend/internal/service/user.go @@ -21,7 +21,7 @@ type User struct { CreatedAt time.Time UpdatedAt time.Time - APIKeys []APIKey + ApiKeys []ApiKey Subscriptions []UserSubscription } diff --git a/backend/internal/service/user_attribute_service.go b/backend/internal/service/user_attribute_service.go index c27e29d0..6c2f8077 100644 --- a/backend/internal/service/user_attribute_service.go +++ b/backend/internal/service/user_attribute_service.go @@ -56,6 +56,10 @@ func (s *UserAttributeService) CreateDefinition(ctx context.Context, input Creat Enabled: input.Enabled, } + if err := validateDefinitionPattern(def); err != nil { + return nil, err + } + if err := s.defRepo.Create(ctx, def); err != nil { return nil, fmt.Errorf("create definition: %w", err) } @@ -108,6 +112,10 @@ func (s *UserAttributeService) UpdateDefinition(ctx context.Context, id int64, i def.Enabled = *input.Enabled } + if err := validateDefinitionPattern(def); err != nil { + return nil, err + } + if err := s.defRepo.Update(ctx, def); err != nil { return nil, fmt.Errorf("update definition: %w", err) } @@ -231,7 +239,10 @@ func (s *UserAttributeService) validateValue(def *UserAttributeDefinition, value // Pattern validation if v.Pattern != nil && *v.Pattern != "" && value != "" { re, err := regexp.Compile(*v.Pattern) - if err == nil && !re.MatchString(value) { + if err != nil { + return validationError(def.Name + " has an invalid pattern") + } + if !re.MatchString(value) { msg := def.Name + " format is invalid" if v.Message != nil && *v.Message != "" { msg = *v.Message @@ -293,3 +304,20 @@ func isValidAttributeType(t UserAttributeType) bool { } return false } + +func validateDefinitionPattern(def *UserAttributeDefinition) error { + if def == nil { + return nil + } + if def.Validation.Pattern == nil { + return nil + } + pattern := strings.TrimSpace(*def.Validation.Pattern) + if pattern == "" { + return nil + } + if _, err := regexp.Compile(pattern); err != nil { + return infraerrors.BadRequest("INVALID_ATTRIBUTE_PATTERN", fmt.Sprintf("invalid pattern for %s: %v", def.Name, err)) + } + return nil +} diff --git a/backend/internal/service/wire.go b/backend/internal/service/wire.go index f3cf5d0c..f52c2a4a 100644 --- a/backend/internal/service/wire.go +++ b/backend/internal/service/wire.go @@ -54,18 +54,6 @@ func ProvideTimingWheelService() *TimingWheelService { return svc } -// ProvideAntigravityQuotaRefresher creates and starts AntigravityQuotaRefresher -func ProvideAntigravityQuotaRefresher( - accountRepo AccountRepository, - proxyRepo ProxyRepository, - oauthSvc *AntigravityOAuthService, - cfg *config.Config, -) *AntigravityQuotaRefresher { - svc := NewAntigravityQuotaRefresher(accountRepo, proxyRepo, oauthSvc, cfg) - svc.Start() - return svc -} - // ProvideDeferredService creates and starts DeferredService func ProvideDeferredService(accountRepo AccountRepository, timingWheel *TimingWheelService) *DeferredService { svc := NewDeferredService(accountRepo, timingWheel, 10*time.Second) @@ -73,20 +61,6 @@ func ProvideDeferredService(accountRepo AccountRepository, timingWheel *TimingWh return svc } -// ProvideOpsMetricsCollector creates and starts OpsMetricsCollector. -func ProvideOpsMetricsCollector(opsService *OpsService, concurrencyService *ConcurrencyService) *OpsMetricsCollector { - svc := NewOpsMetricsCollector(opsService, concurrencyService) - svc.Start() - return svc -} - -// ProvideOpsAlertService creates and starts OpsAlertService. -func ProvideOpsAlertService(opsService *OpsService, userService *UserService, emailService *EmailService) *OpsAlertService { - svc := NewOpsAlertService(opsService, userService, emailService) - svc.Start() - return svc -} - // ProvideConcurrencyService creates ConcurrencyService and starts slot cleanup worker. func ProvideConcurrencyService(cache ConcurrencyCache, accountRepo AccountRepository, cfg *config.Config) *ConcurrencyService { svc := NewConcurrencyService(cache) @@ -101,14 +75,13 @@ var ProviderSet = wire.NewSet( // Core services NewAuthService, NewUserService, - NewAPIKeyService, + NewApiKeyService, NewGroupService, NewAccountService, NewProxyService, NewRedeemService, NewUsageService, NewDashboardService, - NewOpsService, ProvidePricingService, NewBillingService, NewBillingCacheService, @@ -139,8 +112,7 @@ var ProviderSet = wire.NewSet( ProvideTokenRefreshService, ProvideTimingWheelService, ProvideDeferredService, - ProvideAntigravityQuotaRefresher, - ProvideOpsMetricsCollector, - ProvideOpsAlertService, + NewAntigravityQuotaFetcher, NewUserAttributeService, + NewUsageCache, ) diff --git a/backend/internal/setup/cli.go b/backend/internal/setup/cli.go index ca13775d..0d57d93f 100644 --- a/backend/internal/setup/cli.go +++ b/backend/internal/setup/cli.go @@ -1,4 +1,3 @@ -// Package setup provides CLI-based installation wizard for initial system configuration. package setup import ( diff --git a/backend/internal/setup/setup.go b/backend/internal/setup/setup.go index 435f6289..230d016f 100644 --- a/backend/internal/setup/setup.go +++ b/backend/internal/setup/setup.go @@ -345,7 +345,7 @@ func writeConfigFile(cfg *SetupConfig) error { Default struct { UserConcurrency int `yaml:"user_concurrency"` UserBalance float64 `yaml:"user_balance"` - APIKeyPrefix string `yaml:"api_key_prefix"` + ApiKeyPrefix string `yaml:"api_key_prefix"` RateMultiplier float64 `yaml:"rate_multiplier"` } `yaml:"default"` RateLimit struct { @@ -367,12 +367,12 @@ func writeConfigFile(cfg *SetupConfig) error { Default: struct { UserConcurrency int `yaml:"user_concurrency"` UserBalance float64 `yaml:"user_balance"` - APIKeyPrefix string `yaml:"api_key_prefix"` + ApiKeyPrefix string `yaml:"api_key_prefix"` RateMultiplier float64 `yaml:"rate_multiplier"` }{ UserConcurrency: 5, UserBalance: 0, - APIKeyPrefix: "sk-", + ApiKeyPrefix: "sk-", RateMultiplier: 1.0, }, RateLimit: struct { diff --git a/backend/internal/web/embed_off.go b/backend/internal/web/embed_off.go index 0e59a4d2..ac57fb5c 100644 --- a/backend/internal/web/embed_off.go +++ b/backend/internal/web/embed_off.go @@ -1,6 +1,5 @@ //go:build !embed -// Package web provides web server functionality including embedded frontend support. package web import (