Commit 112a2d08 authored by ianshaw's avatar ianshaw
Browse files

chore: 更新依赖、配置和代码生成

主要更新:
- 更新 go.mod/go.sum 依赖
- 重新生成 Ent ORM 代码
- 更新 Wire 依赖注入配置
- 添加 docker-compose.override.yml 到 .gitignore
- 更新 README 文档(Simple Mode 说明和已知问题)
- 清理调试日志
- 其他代码优化和格式修复
parent b1702de5
// Package claude provides Claude API client constants and utilities.
package claude package claude
// Claude Code 客户端相关常量 // Claude Code 客户端相关常量
...@@ -17,13 +16,13 @@ const DefaultBetaHeader = BetaClaudeCode + "," + BetaOAuth + "," + BetaInterleav ...@@ -17,13 +16,13 @@ const DefaultBetaHeader = BetaClaudeCode + "," + BetaOAuth + "," + BetaInterleav
// HaikuBetaHeader Haiku 模型使用的 anthropic-beta header(不需要 claude-code beta) // HaikuBetaHeader Haiku 模型使用的 anthropic-beta header(不需要 claude-code beta)
const HaikuBetaHeader = BetaOAuth + "," + BetaInterleavedThinking const HaikuBetaHeader = BetaOAuth + "," + BetaInterleavedThinking
// APIKeyBetaHeader API-key 账号建议使用的 anthropic-beta header(不包含 oauth) // ApiKeyBetaHeader API-key 账号建议使用的 anthropic-beta header(不包含 oauth)
const APIKeyBetaHeader = BetaClaudeCode + "," + BetaInterleavedThinking + "," + BetaFineGrainedToolStreaming const ApiKeyBetaHeader = BetaClaudeCode + "," + BetaInterleavedThinking + "," + BetaFineGrainedToolStreaming
// APIKeyHaikuBetaHeader Haiku 模型在 API-key 账号下使用的 anthropic-beta header(不包含 oauth / claude-code) // ApiKeyHaikuBetaHeader Haiku 模型在 API-key 账号下使用的 anthropic-beta header(不包含 oauth / claude-code)
const APIKeyHaikuBetaHeader = BetaInterleavedThinking const ApiKeyHaikuBetaHeader = BetaInterleavedThinking
// DefaultHeaders are the default request headers for Claude Code client. // Claude Code 客户端默认请求头
var DefaultHeaders = map[string]string{ var DefaultHeaders = map[string]string{
"User-Agent": "claude-cli/2.0.62 (external, cli)", "User-Agent": "claude-cli/2.0.62 (external, cli)",
"X-Stainless-Lang": "js", "X-Stainless-Lang": "js",
......
// Package errors provides custom error types and error handling utilities.
// nolint:mnd // nolint:mnd
package errors package errors
......
// Package gemini provides minimal fallback model metadata for Gemini native endpoints.
package gemini 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 { type Model struct {
Name string `json:"name"` Name string `json:"name"`
......
// Package googleapi provides utilities for Google API interactions.
package googleapi package googleapi
import "net/http" import "net/http"
......
// Package oauth provides OAuth 2.0 utilities including PKCE flow, session management, and token exchange.
package oauth package oauth
import ( import (
......
// Package openai provides OpenAI API models and configuration.
package openai package openai
import _ "embed" import _ "embed"
......
...@@ -327,7 +327,7 @@ func ParseIDToken(idToken string) (*IDTokenClaims, error) { ...@@ -327,7 +327,7 @@ func ParseIDToken(idToken string) (*IDTokenClaims, error) {
return &claims, nil return &claims, nil
} }
// UserInfo extracts user information from ID Token claims // ExtractUserInfo extracts user information from ID Token claims
type UserInfo struct { type UserInfo struct {
Email string Email string
ChatGPTAccountID string ChatGPTAccountID string
......
// Package pagination provides utilities for handling paginated queries and results.
package pagination package pagination
// PaginationParams 分页参数 // PaginationParams 分页参数
......
// Package response provides HTTP response utilities for standardized API responses and error handling.
package response package response
import ( import (
......
// Package sysutil provides system-level utilities for service management.
package sysutil package sysutil
import ( import (
......
// Package usagestats defines types for tracking and reporting API usage statistics.
package usagestats package usagestats
import "time" import "time"
...@@ -11,8 +10,8 @@ type DashboardStats struct { ...@@ -11,8 +10,8 @@ type DashboardStats struct {
ActiveUsers int64 `json:"active_users"` // 今日有请求的用户数 ActiveUsers int64 `json:"active_users"` // 今日有请求的用户数
// API Key 统计 // API Key 统计
TotalAPIKeys int64 `json:"total_api_keys"` TotalApiKeys int64 `json:"total_api_keys"`
ActiveAPIKeys int64 `json:"active_api_keys"` // 状态为 active 的 API Key 数 ActiveApiKeys int64 `json:"active_api_keys"` // 状态为 active 的 API Key 数
// 账户统计 // 账户统计
TotalAccounts int64 `json:"total_accounts"` TotalAccounts int64 `json:"total_accounts"`
...@@ -83,10 +82,10 @@ type UserUsageTrendPoint struct { ...@@ -83,10 +82,10 @@ type UserUsageTrendPoint struct {
ActualCost float64 `json:"actual_cost"` // 实际扣除 ActualCost float64 `json:"actual_cost"` // 实际扣除
} }
// APIKeyUsageTrendPoint represents API key usage trend data point // ApiKeyUsageTrendPoint represents API key usage trend data point
type APIKeyUsageTrendPoint struct { type ApiKeyUsageTrendPoint struct {
Date string `json:"date"` Date string `json:"date"`
APIKeyID int64 `json:"api_key_id"` ApiKeyID int64 `json:"api_key_id"`
KeyName string `json:"key_name"` KeyName string `json:"key_name"`
Requests int64 `json:"requests"` Requests int64 `json:"requests"`
Tokens int64 `json:"tokens"` Tokens int64 `json:"tokens"`
...@@ -95,8 +94,8 @@ type APIKeyUsageTrendPoint struct { ...@@ -95,8 +94,8 @@ type APIKeyUsageTrendPoint struct {
// UserDashboardStats 用户仪表盘统计 // UserDashboardStats 用户仪表盘统计
type UserDashboardStats struct { type UserDashboardStats struct {
// API Key 统计 // API Key 统计
TotalAPIKeys int64 `json:"total_api_keys"` TotalApiKeys int64 `json:"total_api_keys"`
ActiveAPIKeys int64 `json:"active_api_keys"` ActiveApiKeys int64 `json:"active_api_keys"`
// 累计 Token 使用统计 // 累计 Token 使用统计
TotalRequests int64 `json:"total_requests"` TotalRequests int64 `json:"total_requests"`
...@@ -129,7 +128,7 @@ type UserDashboardStats struct { ...@@ -129,7 +128,7 @@ type UserDashboardStats struct {
// UsageLogFilters represents filters for usage log queries // UsageLogFilters represents filters for usage log queries
type UsageLogFilters struct { type UsageLogFilters struct {
UserID int64 UserID int64
APIKeyID int64 ApiKeyID int64
AccountID int64 AccountID int64
GroupID int64 GroupID int64
Model string Model string
...@@ -158,9 +157,9 @@ type BatchUserUsageStats struct { ...@@ -158,9 +157,9 @@ type BatchUserUsageStats struct {
TotalActualCost float64 `json:"total_actual_cost"` TotalActualCost float64 `json:"total_actual_cost"`
} }
// BatchAPIKeyUsageStats represents usage stats for a single API key // BatchApiKeyUsageStats represents usage stats for a single API key
type BatchAPIKeyUsageStats struct { type BatchApiKeyUsageStats struct {
APIKeyID int64 `json:"api_key_id"` ApiKeyID int64 `json:"api_key_id"`
TodayActualCost float64 `json:"today_actual_cost"` TodayActualCost float64 `json:"today_actual_cost"`
TotalActualCost float64 `json:"total_actual_cost"` TotalActualCost float64 `json:"total_actual_cost"`
} }
......
...@@ -135,12 +135,12 @@ func (s *AccountRepoSuite) TestListWithFilters() { ...@@ -135,12 +135,12 @@ func (s *AccountRepoSuite) TestListWithFilters() {
name: "filter_by_type", name: "filter_by_type",
setup: func(client *dbent.Client) { setup: func(client *dbent.Client) {
mustCreateAccount(s.T(), client, &service.Account{Name: "t1", Type: service.AccountTypeOAuth}) 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, wantCount: 1,
validate: func(accounts []service.Account) { validate: func(accounts []service.Account) {
s.Require().Equal(service.AccountTypeAPIKey, accounts[0].Type) s.Require().Equal(service.AccountTypeApiKey, accounts[0].Type)
}, },
}, },
{ {
......
...@@ -80,7 +80,7 @@ func TestUserRepository_RemoveGroupFromAllowedGroups_RemovesAllOccurrences(t *te ...@@ -80,7 +80,7 @@ func TestUserRepository_RemoveGroupFromAllowedGroups_RemovesAllOccurrences(t *te
require.NotContains(t, u2After.AllowedGroups, targetGroup.ID) require.NotContains(t, u2After.AllowedGroups, targetGroup.ID)
} }
func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsAPIKeys(t *testing.T) { func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsApiKeys(t *testing.T) {
ctx := context.Background() ctx := context.Background()
tx := testEntTx(t) tx := testEntTx(t)
entClient := tx.Client() entClient := tx.Client()
...@@ -98,7 +98,7 @@ func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsAPIKeys(t *t ...@@ -98,7 +98,7 @@ func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsAPIKeys(t *t
userRepo := newUserRepositoryWithSQL(entClient, tx) userRepo := newUserRepositoryWithSQL(entClient, tx)
groupRepo := newGroupRepositoryWithSQL(entClient, tx) groupRepo := newGroupRepositoryWithSQL(entClient, tx)
apiKeyRepo := NewAPIKeyRepository(entClient) apiKeyRepo := NewApiKeyRepository(entClient)
u := &service.User{ u := &service.User{
Email: uniqueTestValue(t, "cascade-user") + "@example.com", Email: uniqueTestValue(t, "cascade-user") + "@example.com",
...@@ -110,7 +110,7 @@ func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsAPIKeys(t *t ...@@ -110,7 +110,7 @@ func TestGroupRepository_DeleteCascade_RemovesAllowedGroupsAndClearsAPIKeys(t *t
} }
require.NoError(t, userRepo.Create(ctx, u)) require.NoError(t, userRepo.Create(ctx, u))
key := &service.APIKey{ key := &service.ApiKey{
UserID: u.ID, UserID: u.ID,
Key: uniqueTestValue(t, "sk-test-delete-cascade"), Key: uniqueTestValue(t, "sk-test-delete-cascade"),
Name: "test key", Name: "test key",
......
...@@ -24,7 +24,7 @@ type apiKeyCache struct { ...@@ -24,7 +24,7 @@ type apiKeyCache struct {
rdb *redis.Client rdb *redis.Client
} }
func NewAPIKeyCache(rdb *redis.Client) service.APIKeyCache { func NewApiKeyCache(rdb *redis.Client) service.ApiKeyCache {
return &apiKeyCache{rdb: rdb} return &apiKeyCache{rdb: rdb}
} }
......
...@@ -13,11 +13,11 @@ import ( ...@@ -13,11 +13,11 @@ import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
type APIKeyCacheSuite struct { type ApiKeyCacheSuite struct {
IntegrationRedisSuite IntegrationRedisSuite
} }
func (s *APIKeyCacheSuite) TestCreateAttemptCount() { func (s *ApiKeyCacheSuite) TestCreateAttemptCount() {
tests := []struct { tests := []struct {
name string name string
fn func(ctx context.Context, rdb *redis.Client, cache *apiKeyCache) fn func(ctx context.Context, rdb *redis.Client, cache *apiKeyCache)
...@@ -78,7 +78,7 @@ func (s *APIKeyCacheSuite) TestCreateAttemptCount() { ...@@ -78,7 +78,7 @@ func (s *APIKeyCacheSuite) TestCreateAttemptCount() {
} }
} }
func (s *APIKeyCacheSuite) TestDailyUsage() { func (s *ApiKeyCacheSuite) TestDailyUsage() {
tests := []struct { tests := []struct {
name string name string
fn func(ctx context.Context, rdb *redis.Client, cache *apiKeyCache) fn func(ctx context.Context, rdb *redis.Client, cache *apiKeyCache)
...@@ -122,6 +122,6 @@ func (s *APIKeyCacheSuite) TestDailyUsage() { ...@@ -122,6 +122,6 @@ func (s *APIKeyCacheSuite) TestDailyUsage() {
} }
} }
func TestAPIKeyCacheSuite(t *testing.T) { func TestApiKeyCacheSuite(t *testing.T) {
suite.Run(t, new(APIKeyCacheSuite)) suite.Run(t, new(ApiKeyCacheSuite))
} }
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestAPIKeyRateLimitKey(t *testing.T) { func TestApiKeyRateLimitKey(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
userID int64 userID int64
......
...@@ -16,17 +16,17 @@ type apiKeyRepository struct { ...@@ -16,17 +16,17 @@ type apiKeyRepository struct {
client *dbent.Client client *dbent.Client
} }
func NewAPIKeyRepository(client *dbent.Client) service.APIKeyRepository { func NewApiKeyRepository(client *dbent.Client) service.ApiKeyRepository {
return &apiKeyRepository{client: client} 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 { func (r *apiKeyRepository) Create(ctx context.Context, key *service.ApiKey) error {
created, err := r.client.APIKey.Create(). created, err := r.client.ApiKey.Create().
SetUserID(key.UserID). SetUserID(key.UserID).
SetKey(key.Key). SetKey(key.Key).
SetName(key.Name). SetName(key.Name).
...@@ -38,10 +38,10 @@ func (r *apiKeyRepository) Create(ctx context.Context, key *service.APIKey) erro ...@@ -38,10 +38,10 @@ func (r *apiKeyRepository) Create(ctx context.Context, key *service.APIKey) erro
key.CreatedAt = created.CreatedAt key.CreatedAt = created.CreatedAt
key.UpdatedAt = created.UpdatedAt 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(). m, err := r.activeQuery().
Where(apikey.IDEQ(id)). Where(apikey.IDEQ(id)).
WithUser(). WithUser().
...@@ -49,7 +49,7 @@ func (r *apiKeyRepository) GetByID(ctx context.Context, id int64) (*service.APIK ...@@ -49,7 +49,7 @@ func (r *apiKeyRepository) GetByID(ctx context.Context, id int64) (*service.APIK
Only(ctx) Only(ctx)
if err != nil { if err != nil {
if dbent.IsNotFound(err) { if dbent.IsNotFound(err) {
return nil, service.ErrAPIKeyNotFound return nil, service.ErrApiKeyNotFound
} }
return nil, err return nil, err
} }
...@@ -59,7 +59,7 @@ func (r *apiKeyRepository) GetByID(ctx context.Context, id int64) (*service.APIK ...@@ -59,7 +59,7 @@ func (r *apiKeyRepository) GetByID(ctx context.Context, id int64) (*service.APIK
// GetOwnerID 根据 API Key ID 获取其所有者(用户)的 ID。 // GetOwnerID 根据 API Key ID 获取其所有者(用户)的 ID。
// 相比 GetByID,此方法性能更优,因为: // 相比 GetByID,此方法性能更优,因为:
// - 使用 Select() 只查询 user_id 字段,减少数据传输量 // - 使用 Select() 只查询 user_id 字段,减少数据传输量
// - 不加载完整的 APIKey 实体及其关联数据(User、Group 等) // - 不加载完整的 ApiKey 实体及其关联数据(User、Group 等)
// - 适用于权限验证等只需用户 ID 的场景(如删除前的所有权检查) // - 适用于权限验证等只需用户 ID 的场景(如删除前的所有权检查)
func (r *apiKeyRepository) GetOwnerID(ctx context.Context, id int64) (int64, error) { func (r *apiKeyRepository) GetOwnerID(ctx context.Context, id int64) (int64, error) {
m, err := r.activeQuery(). m, err := r.activeQuery().
...@@ -68,14 +68,14 @@ func (r *apiKeyRepository) GetOwnerID(ctx context.Context, id int64) (int64, err ...@@ -68,14 +68,14 @@ func (r *apiKeyRepository) GetOwnerID(ctx context.Context, id int64) (int64, err
Only(ctx) Only(ctx)
if err != nil { if err != nil {
if dbent.IsNotFound(err) { if dbent.IsNotFound(err) {
return 0, service.ErrAPIKeyNotFound return 0, service.ErrApiKeyNotFound
} }
return 0, err return 0, err
} }
return m.UserID, nil 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(). m, err := r.activeQuery().
Where(apikey.KeyEQ(key)). Where(apikey.KeyEQ(key)).
WithUser(). WithUser().
...@@ -83,21 +83,21 @@ func (r *apiKeyRepository) GetByKey(ctx context.Context, key string) (*service.A ...@@ -83,21 +83,21 @@ func (r *apiKeyRepository) GetByKey(ctx context.Context, key string) (*service.A
Only(ctx) Only(ctx)
if err != nil { if err != nil {
if dbent.IsNotFound(err) { if dbent.IsNotFound(err) {
return nil, service.ErrAPIKeyNotFound return nil, service.ErrApiKeyNotFound
} }
return nil, err return nil, err
} }
return apiKeyEntityToService(m), nil 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,若在两步之间发生软删除, // 之前的实现先检查 Exist 再 UpdateOneID,若在两步之间发生软删除,
// 则会更新已删除的记录。 // 则会更新已删除的记录。
// 这里选择 Update().Where(),确保只有未软删除记录能被更新。 // 这里选择 Update().Where(),确保只有未软删除记录能被更新。
// 同时显式设置 updated_at,避免二次查询带来的并发可见性问题。 // 同时显式设置 updated_at,避免二次查询带来的并发可见性问题。
now := time.Now() now := time.Now()
builder := r.client.APIKey.Update(). builder := r.client.ApiKey.Update().
Where(apikey.IDEQ(key.ID), apikey.DeletedAtIsNil()). Where(apikey.IDEQ(key.ID), apikey.DeletedAtIsNil()).
SetName(key.Name). SetName(key.Name).
SetStatus(key.Status). SetStatus(key.Status).
...@@ -114,7 +114,7 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro ...@@ -114,7 +114,7 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro
} }
if affected == 0 { if affected == 0 {
// 更新影响行数为 0,说明记录不存在或已被软删除。 // 更新影响行数为 0,说明记录不存在或已被软删除。
return service.ErrAPIKeyNotFound return service.ErrApiKeyNotFound
} }
// 使用同一时间戳回填,避免并发删除导致二次查询失败。 // 使用同一时间戳回填,避免并发删除导致二次查询失败。
...@@ -124,18 +124,18 @@ func (r *apiKeyRepository) Update(ctx context.Context, key *service.APIKey) erro ...@@ -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 { func (r *apiKeyRepository) Delete(ctx context.Context, id int64) error {
// 显式软删除:避免依赖 Hook 行为,确保 deleted_at 一定被设置。 // 显式软删除:避免依赖 Hook 行为,确保 deleted_at 一定被设置。
affected, err := r.client.APIKey.Update(). affected, err := r.client.ApiKey.Update().
Where(apikey.IDEQ(id), apikey.DeletedAtIsNil()). Where(apikey.IDEQ(id), apikey.DeletedAtIsNil()).
SetDeletedAt(time.Now()). SetDeletedAt(time.Now()).
Save(ctx) Save(ctx)
if err != nil { if err != nil {
if dbent.IsNotFound(err) { if dbent.IsNotFound(err) {
return service.ErrAPIKeyNotFound return service.ErrApiKeyNotFound
} }
return err return err
} }
if affected == 0 { if affected == 0 {
exists, err := r.client.APIKey.Query(). exists, err := r.client.ApiKey.Query().
Where(apikey.IDEQ(id)). Where(apikey.IDEQ(id)).
Exist(mixins.SkipSoftDelete(ctx)) Exist(mixins.SkipSoftDelete(ctx))
if err != nil { if err != nil {
...@@ -144,12 +144,12 @@ func (r *apiKeyRepository) Delete(ctx context.Context, id int64) error { ...@@ -144,12 +144,12 @@ func (r *apiKeyRepository) Delete(ctx context.Context, id int64) error {
if exists { if exists {
return nil return nil
} }
return service.ErrAPIKeyNotFound return service.ErrApiKeyNotFound
} }
return nil 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)) q := r.activeQuery().Where(apikey.UserIDEQ(userID))
total, err := q.Count(ctx) total, err := q.Count(ctx)
...@@ -167,7 +167,7 @@ func (r *apiKeyRepository) ListByUserID(ctx context.Context, userID int64, param ...@@ -167,7 +167,7 @@ func (r *apiKeyRepository) ListByUserID(ctx context.Context, userID int64, param
return nil, nil, err return nil, nil, err
} }
outKeys := make([]service.APIKey, 0, len(keys)) outKeys := make([]service.ApiKey, 0, len(keys))
for i := range keys { for i := range keys {
outKeys = append(outKeys, *apiKeyEntityToService(keys[i])) outKeys = append(outKeys, *apiKeyEntityToService(keys[i]))
} }
...@@ -180,7 +180,7 @@ func (r *apiKeyRepository) VerifyOwnership(ctx context.Context, userID int64, ap ...@@ -180,7 +180,7 @@ func (r *apiKeyRepository) VerifyOwnership(ctx context.Context, userID int64, ap
return []int64{}, nil return []int64{}, nil
} }
ids, err := r.client.APIKey.Query(). ids, err := r.client.ApiKey.Query().
Where(apikey.UserIDEQ(userID), apikey.IDIn(apiKeyIDs...), apikey.DeletedAtIsNil()). Where(apikey.UserIDEQ(userID), apikey.IDIn(apiKeyIDs...), apikey.DeletedAtIsNil()).
IDs(ctx) IDs(ctx)
if err != nil { if err != nil {
...@@ -199,7 +199,7 @@ func (r *apiKeyRepository) ExistsByKey(ctx context.Context, key string) (bool, e ...@@ -199,7 +199,7 @@ func (r *apiKeyRepository) ExistsByKey(ctx context.Context, key string) (bool, e
return count > 0, err 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)) q := r.activeQuery().Where(apikey.GroupIDEQ(groupID))
total, err := q.Count(ctx) total, err := q.Count(ctx)
...@@ -217,7 +217,7 @@ func (r *apiKeyRepository) ListByGroupID(ctx context.Context, groupID int64, par ...@@ -217,7 +217,7 @@ func (r *apiKeyRepository) ListByGroupID(ctx context.Context, groupID int64, par
return nil, nil, err return nil, nil, err
} }
outKeys := make([]service.APIKey, 0, len(keys)) outKeys := make([]service.ApiKey, 0, len(keys))
for i := range keys { for i := range keys {
outKeys = append(outKeys, *apiKeyEntityToService(keys[i])) outKeys = append(outKeys, *apiKeyEntityToService(keys[i]))
} }
...@@ -225,8 +225,8 @@ func (r *apiKeyRepository) ListByGroupID(ctx context.Context, groupID int64, par ...@@ -225,8 +225,8 @@ func (r *apiKeyRepository) ListByGroupID(ctx context.Context, groupID int64, par
return outKeys, paginationResultFromTotal(int64(total), params), nil return outKeys, paginationResultFromTotal(int64(total), params), nil
} }
// SearchAPIKeys searches API keys by user ID and/or keyword (name) // 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) { func (r *apiKeyRepository) SearchApiKeys(ctx context.Context, userID int64, keyword string, limit int) ([]service.ApiKey, error) {
q := r.activeQuery() q := r.activeQuery()
if userID > 0 { if userID > 0 {
q = q.Where(apikey.UserIDEQ(userID)) q = q.Where(apikey.UserIDEQ(userID))
...@@ -241,7 +241,7 @@ func (r *apiKeyRepository) SearchAPIKeys(ctx context.Context, userID int64, keyw ...@@ -241,7 +241,7 @@ func (r *apiKeyRepository) SearchAPIKeys(ctx context.Context, userID int64, keyw
return nil, err return nil, err
} }
outKeys := make([]service.APIKey, 0, len(keys)) outKeys := make([]service.ApiKey, 0, len(keys))
for i := range keys { for i := range keys {
outKeys = append(outKeys, *apiKeyEntityToService(keys[i])) outKeys = append(outKeys, *apiKeyEntityToService(keys[i]))
} }
...@@ -250,7 +250,7 @@ func (r *apiKeyRepository) SearchAPIKeys(ctx context.Context, userID int64, keyw ...@@ -250,7 +250,7 @@ func (r *apiKeyRepository) SearchAPIKeys(ctx context.Context, userID int64, keyw
// ClearGroupIDByGroupID 将指定分组的所有 API Key 的 group_id 设为 nil // ClearGroupIDByGroupID 将指定分组的所有 API Key 的 group_id 设为 nil
func (r *apiKeyRepository) ClearGroupIDByGroupID(ctx context.Context, groupID int64) (int64, error) { 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()). Where(apikey.GroupIDEQ(groupID), apikey.DeletedAtIsNil()).
ClearGroupID(). ClearGroupID().
Save(ctx) Save(ctx)
...@@ -263,11 +263,11 @@ func (r *apiKeyRepository) CountByGroupID(ctx context.Context, groupID int64) (i ...@@ -263,11 +263,11 @@ func (r *apiKeyRepository) CountByGroupID(ctx context.Context, groupID int64) (i
return int64(count), err return int64(count), err
} }
func apiKeyEntityToService(m *dbent.APIKey) *service.APIKey { func apiKeyEntityToService(m *dbent.ApiKey) *service.ApiKey {
if m == nil { if m == nil {
return nil return nil
} }
out := &service.APIKey{ out := &service.ApiKey{
ID: m.ID, ID: m.ID,
UserID: m.UserID, UserID: m.UserID,
Key: m.Key, Key: m.Key,
......
...@@ -12,30 +12,30 @@ import ( ...@@ -12,30 +12,30 @@ import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
type APIKeyRepoSuite struct { type ApiKeyRepoSuite struct {
suite.Suite suite.Suite
ctx context.Context ctx context.Context
client *dbent.Client client *dbent.Client
repo *apiKeyRepository repo *apiKeyRepository
} }
func (s *APIKeyRepoSuite) SetupTest() { func (s *ApiKeyRepoSuite) SetupTest() {
s.ctx = context.Background() s.ctx = context.Background()
tx := testEntTx(s.T()) tx := testEntTx(s.T())
s.client = tx.Client() s.client = tx.Client()
s.repo = NewAPIKeyRepository(s.client).(*apiKeyRepository) s.repo = NewApiKeyRepository(s.client).(*apiKeyRepository)
} }
func TestAPIKeyRepoSuite(t *testing.T) { func TestApiKeyRepoSuite(t *testing.T) {
suite.Run(t, new(APIKeyRepoSuite)) suite.Run(t, new(ApiKeyRepoSuite))
} }
// --- Create / GetByID / GetByKey --- // --- Create / GetByID / GetByKey ---
func (s *APIKeyRepoSuite) TestCreate() { func (s *ApiKeyRepoSuite) TestCreate() {
user := s.mustCreateUser("create@test.com") user := s.mustCreateUser("create@test.com")
key := &service.APIKey{ key := &service.ApiKey{
UserID: user.ID, UserID: user.ID,
Key: "sk-create-test", Key: "sk-create-test",
Name: "Test Key", Name: "Test Key",
...@@ -51,16 +51,16 @@ func (s *APIKeyRepoSuite) TestCreate() { ...@@ -51,16 +51,16 @@ func (s *APIKeyRepoSuite) TestCreate() {
s.Require().Equal("sk-create-test", got.Key) 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) _, err := s.repo.GetByID(s.ctx, 999999)
s.Require().Error(err, "expected error for non-existent ID") s.Require().Error(err, "expected error for non-existent ID")
} }
func (s *APIKeyRepoSuite) TestGetByKey() { func (s *ApiKeyRepoSuite) TestGetByKey() {
user := s.mustCreateUser("getbykey@test.com") user := s.mustCreateUser("getbykey@test.com")
group := s.mustCreateGroup("g-key") group := s.mustCreateGroup("g-key")
key := &service.APIKey{ key := &service.ApiKey{
UserID: user.ID, UserID: user.ID,
Key: "sk-getbykey", Key: "sk-getbykey",
Name: "My Key", Name: "My Key",
...@@ -78,16 +78,16 @@ func (s *APIKeyRepoSuite) TestGetByKey() { ...@@ -78,16 +78,16 @@ func (s *APIKeyRepoSuite) TestGetByKey() {
s.Require().Equal(group.ID, got.Group.ID) 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") _, err := s.repo.GetByKey(s.ctx, "non-existent-key")
s.Require().Error(err, "expected error for non-existent key") s.Require().Error(err, "expected error for non-existent key")
} }
// --- Update --- // --- Update ---
func (s *APIKeyRepoSuite) TestUpdate() { func (s *ApiKeyRepoSuite) TestUpdate() {
user := s.mustCreateUser("update@test.com") user := s.mustCreateUser("update@test.com")
key := &service.APIKey{ key := &service.ApiKey{
UserID: user.ID, UserID: user.ID,
Key: "sk-update", Key: "sk-update",
Name: "Original", Name: "Original",
...@@ -108,10 +108,10 @@ func (s *APIKeyRepoSuite) TestUpdate() { ...@@ -108,10 +108,10 @@ func (s *APIKeyRepoSuite) TestUpdate() {
s.Require().Equal(service.StatusDisabled, got.Status) s.Require().Equal(service.StatusDisabled, got.Status)
} }
func (s *APIKeyRepoSuite) TestUpdate_ClearGroupID() { func (s *ApiKeyRepoSuite) TestUpdate_ClearGroupID() {
user := s.mustCreateUser("cleargroup@test.com") user := s.mustCreateUser("cleargroup@test.com")
group := s.mustCreateGroup("g-clear") group := s.mustCreateGroup("g-clear")
key := &service.APIKey{ key := &service.ApiKey{
UserID: user.ID, UserID: user.ID,
Key: "sk-clear-group", Key: "sk-clear-group",
Name: "Group Key", Name: "Group Key",
...@@ -131,9 +131,9 @@ func (s *APIKeyRepoSuite) TestUpdate_ClearGroupID() { ...@@ -131,9 +131,9 @@ func (s *APIKeyRepoSuite) TestUpdate_ClearGroupID() {
// --- Delete --- // --- Delete ---
func (s *APIKeyRepoSuite) TestDelete() { func (s *ApiKeyRepoSuite) TestDelete() {
user := s.mustCreateUser("delete@test.com") user := s.mustCreateUser("delete@test.com")
key := &service.APIKey{ key := &service.ApiKey{
UserID: user.ID, UserID: user.ID,
Key: "sk-delete", Key: "sk-delete",
Name: "Delete Me", Name: "Delete Me",
...@@ -150,10 +150,10 @@ func (s *APIKeyRepoSuite) TestDelete() { ...@@ -150,10 +150,10 @@ func (s *APIKeyRepoSuite) TestDelete() {
// --- ListByUserID / CountByUserID --- // --- ListByUserID / CountByUserID ---
func (s *APIKeyRepoSuite) TestListByUserID() { func (s *ApiKeyRepoSuite) TestListByUserID() {
user := s.mustCreateUser("listbyuser@test.com") user := s.mustCreateUser("listbyuser@test.com")
s.mustCreateAPIKey(user.ID, "sk-list-1", "Key 1", nil) 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-2", "Key 2", nil)
keys, page, err := s.repo.ListByUserID(s.ctx, user.ID, pagination.PaginationParams{Page: 1, PageSize: 10}) keys, page, err := s.repo.ListByUserID(s.ctx, user.ID, pagination.PaginationParams{Page: 1, PageSize: 10})
s.Require().NoError(err, "ListByUserID") s.Require().NoError(err, "ListByUserID")
...@@ -161,10 +161,10 @@ func (s *APIKeyRepoSuite) TestListByUserID() { ...@@ -161,10 +161,10 @@ func (s *APIKeyRepoSuite) TestListByUserID() {
s.Require().Equal(int64(2), page.Total) s.Require().Equal(int64(2), page.Total)
} }
func (s *APIKeyRepoSuite) TestListByUserID_Pagination() { func (s *ApiKeyRepoSuite) TestListByUserID_Pagination() {
user := s.mustCreateUser("paging@test.com") user := s.mustCreateUser("paging@test.com")
for i := 0; i < 5; i++ { 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}) 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() { ...@@ -174,10 +174,10 @@ func (s *APIKeyRepoSuite) TestListByUserID_Pagination() {
s.Require().Equal(3, page.Pages) s.Require().Equal(3, page.Pages)
} }
func (s *APIKeyRepoSuite) TestCountByUserID() { func (s *ApiKeyRepoSuite) TestCountByUserID() {
user := s.mustCreateUser("count@test.com") user := s.mustCreateUser("count@test.com")
s.mustCreateAPIKey(user.ID, "sk-count-1", "K1", nil) s.mustCreateApiKey(user.ID, "sk-count-1", "K1", nil)
s.mustCreateAPIKey(user.ID, "sk-count-2", "K2", nil) s.mustCreateApiKey(user.ID, "sk-count-2", "K2", nil)
count, err := s.repo.CountByUserID(s.ctx, user.ID) count, err := s.repo.CountByUserID(s.ctx, user.ID)
s.Require().NoError(err, "CountByUserID") s.Require().NoError(err, "CountByUserID")
...@@ -186,13 +186,13 @@ func (s *APIKeyRepoSuite) TestCountByUserID() { ...@@ -186,13 +186,13 @@ func (s *APIKeyRepoSuite) TestCountByUserID() {
// --- ListByGroupID / CountByGroupID --- // --- ListByGroupID / CountByGroupID ---
func (s *APIKeyRepoSuite) TestListByGroupID() { func (s *ApiKeyRepoSuite) TestListByGroupID() {
user := s.mustCreateUser("listbygroup@test.com") user := s.mustCreateUser("listbygroup@test.com")
group := s.mustCreateGroup("g-list") group := s.mustCreateGroup("g-list")
s.mustCreateAPIKey(user.ID, "sk-grp-1", "K1", &group.ID) 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-2", "K2", &group.ID)
s.mustCreateAPIKey(user.ID, "sk-grp-3", "K3", nil) // no group 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}) keys, page, err := s.repo.ListByGroupID(s.ctx, group.ID, pagination.PaginationParams{Page: 1, PageSize: 10})
s.Require().NoError(err, "ListByGroupID") s.Require().NoError(err, "ListByGroupID")
...@@ -202,10 +202,10 @@ func (s *APIKeyRepoSuite) TestListByGroupID() { ...@@ -202,10 +202,10 @@ func (s *APIKeyRepoSuite) TestListByGroupID() {
s.Require().NotNil(keys[0].User) s.Require().NotNil(keys[0].User)
} }
func (s *APIKeyRepoSuite) TestCountByGroupID() { func (s *ApiKeyRepoSuite) TestCountByGroupID() {
user := s.mustCreateUser("countgroup@test.com") user := s.mustCreateUser("countgroup@test.com")
group := s.mustCreateGroup("g-count") 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) count, err := s.repo.CountByGroupID(s.ctx, group.ID)
s.Require().NoError(err, "CountByGroupID") s.Require().NoError(err, "CountByGroupID")
...@@ -214,9 +214,9 @@ func (s *APIKeyRepoSuite) TestCountByGroupID() { ...@@ -214,9 +214,9 @@ func (s *APIKeyRepoSuite) TestCountByGroupID() {
// --- ExistsByKey --- // --- ExistsByKey ---
func (s *APIKeyRepoSuite) TestExistsByKey() { func (s *ApiKeyRepoSuite) TestExistsByKey() {
user := s.mustCreateUser("exists@test.com") 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") exists, err := s.repo.ExistsByKey(s.ctx, "sk-exists")
s.Require().NoError(err, "ExistsByKey") s.Require().NoError(err, "ExistsByKey")
...@@ -227,47 +227,47 @@ func (s *APIKeyRepoSuite) TestExistsByKey() { ...@@ -227,47 +227,47 @@ func (s *APIKeyRepoSuite) TestExistsByKey() {
s.Require().False(notExists) s.Require().False(notExists)
} }
// --- SearchAPIKeys --- // --- SearchApiKeys ---
func (s *APIKeyRepoSuite) TestSearchAPIKeys() { func (s *ApiKeyRepoSuite) TestSearchApiKeys() {
user := s.mustCreateUser("search@test.com") user := s.mustCreateUser("search@test.com")
s.mustCreateAPIKey(user.ID, "sk-search-1", "Production Key", nil) 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-2", "Development Key", nil)
found, err := s.repo.SearchAPIKeys(s.ctx, user.ID, "prod", 10) found, err := s.repo.SearchApiKeys(s.ctx, user.ID, "prod", 10)
s.Require().NoError(err, "SearchAPIKeys") s.Require().NoError(err, "SearchApiKeys")
s.Require().Len(found, 1) s.Require().Len(found, 1)
s.Require().Contains(found[0].Name, "Production") s.Require().Contains(found[0].Name, "Production")
} }
func (s *APIKeyRepoSuite) TestSearchAPIKeys_NoKeyword() { func (s *ApiKeyRepoSuite) TestSearchApiKeys_NoKeyword() {
user := s.mustCreateUser("searchnokw@test.com") user := s.mustCreateUser("searchnokw@test.com")
s.mustCreateAPIKey(user.ID, "sk-nk-1", "K1", nil) s.mustCreateApiKey(user.ID, "sk-nk-1", "K1", nil)
s.mustCreateAPIKey(user.ID, "sk-nk-2", "K2", 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().NoError(err)
s.Require().Len(found, 2) s.Require().Len(found, 2)
} }
func (s *APIKeyRepoSuite) TestSearchAPIKeys_NoUserID() { func (s *ApiKeyRepoSuite) TestSearchApiKeys_NoUserID() {
user := s.mustCreateUser("searchnouid@test.com") 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().NoError(err)
s.Require().Len(found, 1) s.Require().Len(found, 1)
} }
// --- ClearGroupIDByGroupID --- // --- ClearGroupIDByGroupID ---
func (s *APIKeyRepoSuite) TestClearGroupIDByGroupID() { func (s *ApiKeyRepoSuite) TestClearGroupIDByGroupID() {
user := s.mustCreateUser("cleargrp@test.com") user := s.mustCreateUser("cleargrp@test.com")
group := s.mustCreateGroup("g-clear-bulk") group := s.mustCreateGroup("g-clear-bulk")
k1 := s.mustCreateAPIKey(user.ID, "sk-clr-1", "K1", &group.ID) k1 := s.mustCreateApiKey(user.ID, "sk-clr-1", "K1", &group.ID)
k2 := s.mustCreateAPIKey(user.ID, "sk-clr-2", "K2", &group.ID) k2 := s.mustCreateApiKey(user.ID, "sk-clr-2", "K2", &group.ID)
s.mustCreateAPIKey(user.ID, "sk-clr-3", "K3", nil) // no group s.mustCreateApiKey(user.ID, "sk-clr-3", "K3", nil) // no group
affected, err := s.repo.ClearGroupIDByGroupID(s.ctx, group.ID) affected, err := s.repo.ClearGroupIDByGroupID(s.ctx, group.ID)
s.Require().NoError(err, "ClearGroupIDByGroupID") s.Require().NoError(err, "ClearGroupIDByGroupID")
...@@ -284,10 +284,10 @@ func (s *APIKeyRepoSuite) TestClearGroupIDByGroupID() { ...@@ -284,10 +284,10 @@ func (s *APIKeyRepoSuite) TestClearGroupIDByGroupID() {
// --- Combined CRUD/Search/ClearGroupID (original test preserved as integration) --- // --- 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") user := s.mustCreateUser("k@example.com")
group := s.mustCreateGroup("g-k") 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 key.GroupID = &group.ID
got, err := s.repo.GetByKey(s.ctx, key.Key) got, err := s.repo.GetByKey(s.ctx, key.Key)
...@@ -320,13 +320,13 @@ func (s *APIKeyRepoSuite) TestCRUD_Search_ClearGroupID() { ...@@ -320,13 +320,13 @@ func (s *APIKeyRepoSuite) TestCRUD_Search_ClearGroupID() {
s.Require().NoError(err, "ExistsByKey") s.Require().NoError(err, "ExistsByKey")
s.Require().True(exists, "expected key to exist") s.Require().True(exists, "expected key to exist")
found, err := s.repo.SearchAPIKeys(s.ctx, user.ID, "renam", 10) found, err := s.repo.SearchApiKeys(s.ctx, user.ID, "renam", 10)
s.Require().NoError(err, "SearchAPIKeys") s.Require().NoError(err, "SearchApiKeys")
s.Require().Len(found, 1) s.Require().Len(found, 1)
s.Require().Equal(key.ID, found[0].ID) s.Require().Equal(key.ID, found[0].ID)
// ClearGroupIDByGroupID // 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 k2.GroupID = &group.ID
countBefore, err := s.repo.CountByGroupID(s.ctx, group.ID) countBefore, err := s.repo.CountByGroupID(s.ctx, group.ID)
...@@ -346,7 +346,7 @@ func (s *APIKeyRepoSuite) TestCRUD_Search_ClearGroupID() { ...@@ -346,7 +346,7 @@ func (s *APIKeyRepoSuite) TestCRUD_Search_ClearGroupID() {
s.Require().Equal(int64(0), countAfter, "expected 0 keys in group after clear") 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() s.T().Helper()
u, err := s.client.User.Create(). u, err := s.client.User.Create().
...@@ -359,7 +359,7 @@ func (s *APIKeyRepoSuite) mustCreateUser(email string) *service.User { ...@@ -359,7 +359,7 @@ func (s *APIKeyRepoSuite) mustCreateUser(email string) *service.User {
return userEntityToService(u) return userEntityToService(u)
} }
func (s *APIKeyRepoSuite) mustCreateGroup(name string) *service.Group { func (s *ApiKeyRepoSuite) mustCreateGroup(name string) *service.Group {
s.T().Helper() s.T().Helper()
g, err := s.client.Group.Create(). g, err := s.client.Group.Create().
...@@ -370,10 +370,10 @@ func (s *APIKeyRepoSuite) mustCreateGroup(name string) *service.Group { ...@@ -370,10 +370,10 @@ func (s *APIKeyRepoSuite) mustCreateGroup(name string) *service.Group {
return groupEntityToService(g) 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() s.T().Helper()
k := &service.APIKey{ k := &service.ApiKey{
UserID: userID, UserID: userID,
Key: key, Key: key,
Name: name, Name: name,
......
// Package repository 提供应用程序的基础设施层组件。 // Package infrastructure 提供应用程序的基础设施层组件。
// 包括数据库连接初始化、ORM 客户端管理、Redis 连接、数据库迁移等核心功能。 // 包括数据库连接初始化、ORM 客户端管理、Redis 连接、数据库迁移等核心功能。
package repository package repository
......
...@@ -243,7 +243,7 @@ func mustCreateAccount(t *testing.T, client *dbent.Client, a *service.Account) * ...@@ -243,7 +243,7 @@ func mustCreateAccount(t *testing.T, client *dbent.Client, a *service.Account) *
return a 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() t.Helper()
ctx := context.Background() ctx := context.Background()
...@@ -257,7 +257,7 @@ func mustCreateAPIKey(t *testing.T, client *dbent.Client, k *service.APIKey) *se ...@@ -257,7 +257,7 @@ func mustCreateAPIKey(t *testing.T, client *dbent.Client, k *service.APIKey) *se
k.Name = "default" k.Name = "default"
} }
create := client.APIKey.Create(). create := client.ApiKey.Create().
SetUserID(k.UserID). SetUserID(k.UserID).
SetKey(k.Key). SetKey(k.Key).
SetName(k.Name). SetName(k.Name).
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment