Commit f51ad2e1 authored by Forest's avatar Forest
Browse files

refactor: 删除 ports 目录

parent f57f12c6
......@@ -3,10 +3,11 @@ package repository
import (
"context"
"errors"
"time"
"github.com/Wei-Shaw/sub2api/internal/model"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"time"
"github.com/Wei-Shaw/sub2api/internal/service"
"gorm.io/gorm"
"gorm.io/gorm/clause"
......@@ -357,7 +358,7 @@ func (r *AccountRepository) UpdateExtra(ctx context.Context, id int64, updates m
// BulkUpdate updates multiple accounts with the provided fields.
// It merges credentials/extra JSONB fields instead of overwriting them.
func (r *AccountRepository) BulkUpdate(ctx context.Context, ids []int64, updates ports.AccountBulkUpdate) (int64, error) {
func (r *AccountRepository) BulkUpdate(ctx context.Context, ids []int64, updates service.AccountBulkUpdate) (int64, error) {
if len(ids) == 0 {
return 0, nil
}
......
......@@ -9,7 +9,7 @@ import (
"github.com/Wei-Shaw/sub2api/internal/model"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/stretchr/testify/suite"
"gorm.io/gorm"
)
......@@ -513,7 +513,7 @@ func (s *AccountRepoSuite) TestBulkUpdate() {
a2 := mustCreateAccount(s.T(), s.db, &model.Account{Name: "bulk2", Priority: 1})
newPriority := 99
affected, err := s.repo.BulkUpdate(s.ctx, []int64{a1.ID, a2.ID}, ports.AccountBulkUpdate{
affected, err := s.repo.BulkUpdate(s.ctx, []int64{a1.ID, a2.ID}, service.AccountBulkUpdate{
Priority: &newPriority,
})
s.Require().NoError(err)
......@@ -531,7 +531,7 @@ func (s *AccountRepoSuite) TestBulkUpdate_MergeCredentials() {
Credentials: model.JSONB{"existing": "value"},
})
_, err := s.repo.BulkUpdate(s.ctx, []int64{a1.ID}, ports.AccountBulkUpdate{
_, err := s.repo.BulkUpdate(s.ctx, []int64{a1.ID}, service.AccountBulkUpdate{
Credentials: model.JSONB{"new_key": "new_value"},
})
s.Require().NoError(err)
......@@ -547,7 +547,7 @@ func (s *AccountRepoSuite) TestBulkUpdate_MergeExtra() {
Extra: model.JSONB{"existing": "val"},
})
_, err := s.repo.BulkUpdate(s.ctx, []int64{a1.ID}, ports.AccountBulkUpdate{
_, err := s.repo.BulkUpdate(s.ctx, []int64{a1.ID}, service.AccountBulkUpdate{
Extra: model.JSONB{"new_key": "new_val"},
})
s.Require().NoError(err)
......@@ -558,7 +558,7 @@ func (s *AccountRepoSuite) TestBulkUpdate_MergeExtra() {
}
func (s *AccountRepoSuite) TestBulkUpdate_EmptyIDs() {
affected, err := s.repo.BulkUpdate(s.ctx, []int64{}, ports.AccountBulkUpdate{})
affected, err := s.repo.BulkUpdate(s.ctx, []int64{}, service.AccountBulkUpdate{})
s.Require().NoError(err)
s.Require().Zero(affected)
}
......@@ -566,7 +566,7 @@ func (s *AccountRepoSuite) TestBulkUpdate_EmptyIDs() {
func (s *AccountRepoSuite) TestBulkUpdate_EmptyUpdates() {
a1 := mustCreateAccount(s.T(), s.db, &model.Account{Name: "bulk-empty"})
affected, err := s.repo.BulkUpdate(s.ctx, []int64{a1.ID}, ports.AccountBulkUpdate{})
affected, err := s.repo.BulkUpdate(s.ctx, []int64{a1.ID}, service.AccountBulkUpdate{})
s.Require().NoError(err)
s.Require().Zero(affected)
}
......
......@@ -5,8 +5,7 @@ import (
"fmt"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
)
......@@ -19,7 +18,7 @@ type apiKeyCache struct {
rdb *redis.Client
}
func NewApiKeyCache(rdb *redis.Client) ports.ApiKeyCache {
func NewApiKeyCache(rdb *redis.Client) service.ApiKeyCache {
return &apiKeyCache{rdb: rdb}
}
......
......@@ -8,8 +8,7 @@ import (
"strconv"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
)
......@@ -58,7 +57,7 @@ type billingCache struct {
rdb *redis.Client
}
func NewBillingCache(rdb *redis.Client) ports.BillingCache {
func NewBillingCache(rdb *redis.Client) service.BillingCache {
return &billingCache{rdb: rdb}
}
......@@ -90,7 +89,7 @@ func (c *billingCache) InvalidateUserBalance(ctx context.Context, userID int64)
return c.rdb.Del(ctx, key).Err()
}
func (c *billingCache) GetSubscriptionCache(ctx context.Context, userID, groupID int64) (*ports.SubscriptionCacheData, error) {
func (c *billingCache) GetSubscriptionCache(ctx context.Context, userID, groupID int64) (*service.SubscriptionCacheData, error) {
key := fmt.Sprintf("%s%d:%d", billingSubKeyPrefix, userID, groupID)
result, err := c.rdb.HGetAll(ctx, key).Result()
if err != nil {
......@@ -102,8 +101,8 @@ func (c *billingCache) GetSubscriptionCache(ctx context.Context, userID, groupID
return c.parseSubscriptionCache(result)
}
func (c *billingCache) parseSubscriptionCache(data map[string]string) (*ports.SubscriptionCacheData, error) {
result := &ports.SubscriptionCacheData{}
func (c *billingCache) parseSubscriptionCache(data map[string]string) (*service.SubscriptionCacheData, error) {
result := &service.SubscriptionCacheData{}
result.Status = data[subFieldStatus]
if result.Status == "" {
......@@ -136,7 +135,7 @@ func (c *billingCache) parseSubscriptionCache(data map[string]string) (*ports.Su
return result, nil
}
func (c *billingCache) SetSubscriptionCache(ctx context.Context, userID, groupID int64, data *ports.SubscriptionCacheData) error {
func (c *billingCache) SetSubscriptionCache(ctx context.Context, userID, groupID int64, data *service.SubscriptionCacheData) error {
if data == nil {
return nil
}
......
......@@ -8,7 +8,7 @@ import (
"testing"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
......@@ -21,18 +21,18 @@ type BillingCacheSuite struct {
func (s *BillingCacheSuite) TestUserBalance() {
tests := []struct {
name string
fn func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache)
fn func(ctx context.Context, rdb *redis.Client, cache service.BillingCache)
}{
{
name: "missing_key_returns_redis_nil",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
_, err := cache.GetUserBalance(ctx, 1)
require.ErrorIs(s.T(), err, redis.Nil, "expected redis.Nil for missing balance key")
},
},
{
name: "deduct_on_nonexistent_is_noop",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(1)
balanceKey := fmt.Sprintf("%s%d", billingBalanceKeyPrefix, userID)
......@@ -44,7 +44,7 @@ func (s *BillingCacheSuite) TestUserBalance() {
},
{
name: "set_and_get_with_ttl",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(2)
balanceKey := fmt.Sprintf("%s%d", billingBalanceKeyPrefix, userID)
......@@ -61,7 +61,7 @@ func (s *BillingCacheSuite) TestUserBalance() {
},
{
name: "deduct_reduces_balance",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(3)
require.NoError(s.T(), cache.SetUserBalance(ctx, userID, 10.5), "SetUserBalance")
......@@ -74,7 +74,7 @@ func (s *BillingCacheSuite) TestUserBalance() {
},
{
name: "invalidate_removes_key",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(100)
balanceKey := fmt.Sprintf("%s%d", billingBalanceKeyPrefix, userID)
......@@ -96,7 +96,7 @@ func (s *BillingCacheSuite) TestUserBalance() {
},
{
name: "deduct_refreshes_ttl",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(103)
balanceKey := fmt.Sprintf("%s%d", billingBalanceKeyPrefix, userID)
......@@ -133,11 +133,11 @@ func (s *BillingCacheSuite) TestUserBalance() {
func (s *BillingCacheSuite) TestSubscriptionCache() {
tests := []struct {
name string
fn func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache)
fn func(ctx context.Context, rdb *redis.Client, cache service.BillingCache)
}{
{
name: "missing_key_returns_redis_nil",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(10)
groupID := int64(20)
......@@ -147,7 +147,7 @@ func (s *BillingCacheSuite) TestSubscriptionCache() {
},
{
name: "update_usage_on_nonexistent_is_noop",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(11)
groupID := int64(21)
subKey := fmt.Sprintf("%s%d:%d", billingSubKeyPrefix, userID, groupID)
......@@ -161,12 +161,12 @@ func (s *BillingCacheSuite) TestSubscriptionCache() {
},
{
name: "set_and_get_with_ttl",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(12)
groupID := int64(22)
subKey := fmt.Sprintf("%s%d:%d", billingSubKeyPrefix, userID, groupID)
data := &ports.SubscriptionCacheData{
data := &service.SubscriptionCacheData{
Status: "active",
ExpiresAt: time.Now().Add(1 * time.Hour),
DailyUsage: 1.0,
......@@ -189,11 +189,11 @@ func (s *BillingCacheSuite) TestSubscriptionCache() {
},
{
name: "update_usage_increments_all_fields",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(13)
groupID := int64(23)
data := &ports.SubscriptionCacheData{
data := &service.SubscriptionCacheData{
Status: "active",
ExpiresAt: time.Now().Add(1 * time.Hour),
DailyUsage: 1.0,
......@@ -214,12 +214,12 @@ func (s *BillingCacheSuite) TestSubscriptionCache() {
},
{
name: "invalidate_removes_key",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(101)
groupID := int64(10)
subKey := fmt.Sprintf("%s%d:%d", billingSubKeyPrefix, userID, groupID)
data := &ports.SubscriptionCacheData{
data := &service.SubscriptionCacheData{
Status: "active",
ExpiresAt: time.Now().Add(1 * time.Hour),
DailyUsage: 1.0,
......@@ -245,7 +245,7 @@ func (s *BillingCacheSuite) TestSubscriptionCache() {
},
{
name: "missing_status_returns_parsing_error",
fn: func(ctx context.Context, rdb *redis.Client, cache ports.BillingCache) {
fn: func(ctx context.Context, rdb *redis.Client, cache service.BillingCache) {
userID := int64(102)
groupID := int64(11)
subKey := fmt.Sprintf("%s%d:%d", billingSubKeyPrefix, userID, groupID)
......
......@@ -5,8 +5,7 @@ import (
"fmt"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
)
......@@ -107,7 +106,7 @@ type concurrencyCache struct {
rdb *redis.Client
}
func NewConcurrencyCache(rdb *redis.Client) ports.ConcurrencyCache {
func NewConcurrencyCache(rdb *redis.Client) service.ConcurrencyCache {
return &concurrencyCache{rdb: rdb}
}
......
......@@ -8,7 +8,7 @@ import (
"testing"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
......@@ -16,7 +16,7 @@ import (
type ConcurrencyCacheSuite struct {
IntegrationRedisSuite
cache ports.ConcurrencyCache
cache service.ConcurrencyCache
}
func (s *ConcurrencyCacheSuite) SetupTest() {
......
......@@ -5,8 +5,7 @@ import (
"encoding/json"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
)
......@@ -16,24 +15,24 @@ type emailCache struct {
rdb *redis.Client
}
func NewEmailCache(rdb *redis.Client) ports.EmailCache {
func NewEmailCache(rdb *redis.Client) service.EmailCache {
return &emailCache{rdb: rdb}
}
func (c *emailCache) GetVerificationCode(ctx context.Context, email string) (*ports.VerificationCodeData, error) {
func (c *emailCache) GetVerificationCode(ctx context.Context, email string) (*service.VerificationCodeData, error) {
key := verifyCodeKeyPrefix + email
val, err := c.rdb.Get(ctx, key).Result()
if err != nil {
return nil, err
}
var data ports.VerificationCodeData
var data service.VerificationCodeData
if err := json.Unmarshal([]byte(val), &data); err != nil {
return nil, err
}
return &data, nil
}
func (c *emailCache) SetVerificationCode(ctx context.Context, email string, data *ports.VerificationCodeData, ttl time.Duration) error {
func (c *emailCache) SetVerificationCode(ctx context.Context, email string, data *service.VerificationCodeData, ttl time.Duration) error {
key := verifyCodeKeyPrefix + email
val, err := json.Marshal(data)
if err != nil {
......
......@@ -7,7 +7,7 @@ import (
"testing"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
......@@ -15,7 +15,7 @@ import (
type EmailCacheSuite struct {
IntegrationRedisSuite
cache ports.EmailCache
cache service.EmailCache
}
func (s *EmailCacheSuite) SetupTest() {
......@@ -31,7 +31,7 @@ func (s *EmailCacheSuite) TestGetVerificationCode_Missing() {
func (s *EmailCacheSuite) TestSetAndGetVerificationCode() {
email := "a@example.com"
emailTTL := 2 * time.Minute
data := &ports.VerificationCodeData{Code: "123456", Attempts: 1, CreatedAt: time.Now()}
data := &service.VerificationCodeData{Code: "123456", Attempts: 1, CreatedAt: time.Now()}
require.NoError(s.T(), s.cache.SetVerificationCode(s.ctx, email, data, emailTTL), "SetVerificationCode")
......@@ -44,7 +44,7 @@ func (s *EmailCacheSuite) TestSetAndGetVerificationCode() {
func (s *EmailCacheSuite) TestVerificationCode_TTL() {
email := "ttl@example.com"
emailTTL := 2 * time.Minute
data := &ports.VerificationCodeData{Code: "654321", Attempts: 0, CreatedAt: time.Now()}
data := &service.VerificationCodeData{Code: "654321", Attempts: 0, CreatedAt: time.Now()}
require.NoError(s.T(), s.cache.SetVerificationCode(s.ctx, email, data, emailTTL), "SetVerificationCode")
......@@ -56,7 +56,7 @@ func (s *EmailCacheSuite) TestVerificationCode_TTL() {
func (s *EmailCacheSuite) TestDeleteVerificationCode() {
email := "delete@example.com"
data := &ports.VerificationCodeData{Code: "999999", Attempts: 0, CreatedAt: time.Now()}
data := &service.VerificationCodeData{Code: "999999", Attempts: 0, CreatedAt: time.Now()}
require.NoError(s.T(), s.cache.SetVerificationCode(s.ctx, email, data, 2*time.Minute), "SetVerificationCode")
......
......@@ -4,8 +4,7 @@ import (
"context"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
)
......@@ -15,7 +14,7 @@ type gatewayCache struct {
rdb *redis.Client
}
func NewGatewayCache(rdb *redis.Client) ports.GatewayCache {
func NewGatewayCache(rdb *redis.Client) service.GatewayCache {
return &gatewayCache{rdb: rdb}
}
......
......@@ -7,7 +7,7 @@ import (
"testing"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
......@@ -15,7 +15,7 @@ import (
type GatewayCacheSuite struct {
IntegrationRedisSuite
cache ports.GatewayCache
cache service.GatewayCache
}
func (s *GatewayCacheSuite) SetupTest() {
......
......@@ -6,7 +6,7 @@ import (
"time"
"github.com/Wei-Shaw/sub2api/internal/config"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
)
// httpUpstreamService is a generic HTTP upstream service that can be used for
......@@ -17,7 +17,7 @@ type httpUpstreamService struct {
}
// NewHTTPUpstream creates a new generic HTTP upstream service
func NewHTTPUpstream(cfg *config.Config) ports.HTTPUpstream {
func NewHTTPUpstream(cfg *config.Config) service.HTTPUpstream {
responseHeaderTimeout := time.Duration(cfg.Gateway.ResponseHeaderTimeout) * time.Second
if responseHeaderTimeout == 0 {
responseHeaderTimeout = 300 * time.Second
......
......@@ -6,8 +6,7 @@ import (
"fmt"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
)
......@@ -20,24 +19,24 @@ type identityCache struct {
rdb *redis.Client
}
func NewIdentityCache(rdb *redis.Client) ports.IdentityCache {
func NewIdentityCache(rdb *redis.Client) service.IdentityCache {
return &identityCache{rdb: rdb}
}
func (c *identityCache) GetFingerprint(ctx context.Context, accountID int64) (*ports.Fingerprint, error) {
func (c *identityCache) GetFingerprint(ctx context.Context, accountID int64) (*service.Fingerprint, error) {
key := fmt.Sprintf("%s%d", fingerprintKeyPrefix, accountID)
val, err := c.rdb.Get(ctx, key).Result()
if err != nil {
return nil, err
}
var fp ports.Fingerprint
var fp service.Fingerprint
if err := json.Unmarshal([]byte(val), &fp); err != nil {
return nil, err
}
return &fp, nil
}
func (c *identityCache) SetFingerprint(ctx context.Context, accountID int64, fp *ports.Fingerprint) error {
func (c *identityCache) SetFingerprint(ctx context.Context, accountID int64, fp *service.Fingerprint) error {
key := fmt.Sprintf("%s%d", fingerprintKeyPrefix, accountID)
val, err := json.Marshal(fp)
if err != nil {
......
......@@ -8,7 +8,7 @@ import (
"testing"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
......@@ -30,7 +30,7 @@ func (s *IdentityCacheSuite) TestGetFingerprint_Missing() {
}
func (s *IdentityCacheSuite) TestSetAndGetFingerprint() {
fp := &ports.Fingerprint{ClientID: "c1", UserAgent: "ua"}
fp := &service.Fingerprint{ClientID: "c1", UserAgent: "ua"}
require.NoError(s.T(), s.cache.SetFingerprint(s.ctx, 1, fp), "SetFingerprint")
gotFP, err := s.cache.GetFingerprint(s.ctx, 1)
require.NoError(s.T(), err, "GetFingerprint")
......@@ -39,7 +39,7 @@ func (s *IdentityCacheSuite) TestSetAndGetFingerprint() {
}
func (s *IdentityCacheSuite) TestFingerprint_TTL() {
fp := &ports.Fingerprint{ClientID: "c1", UserAgent: "ua"}
fp := &service.Fingerprint{ClientID: "c1", UserAgent: "ua"}
require.NoError(s.T(), s.cache.SetFingerprint(s.ctx, 2, fp))
fpKey := fmt.Sprintf("%s%d", fingerprintKeyPrefix, 2)
......
......@@ -7,13 +7,12 @@ import (
"time"
"github.com/Wei-Shaw/sub2api/internal/pkg/openai"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/imroc/req/v3"
)
// NewOpenAIOAuthClient creates a new OpenAI OAuth client
func NewOpenAIOAuthClient() ports.OpenAIOAuthClient {
func NewOpenAIOAuthClient() service.OpenAIOAuthClient {
return &openaiOAuthService{tokenURL: openai.TokenURL}
}
......
......@@ -5,8 +5,7 @@ import (
"fmt"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
)
......@@ -20,7 +19,7 @@ type redeemCache struct {
rdb *redis.Client
}
func NewRedeemCache(rdb *redis.Client) ports.RedeemCache {
func NewRedeemCache(rdb *redis.Client) service.RedeemCache {
return &redeemCache{rdb: rdb}
}
......
......@@ -4,8 +4,7 @@ import (
"context"
"time"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/redis/go-redis/v9"
)
......@@ -15,7 +14,7 @@ type updateCache struct {
rdb *redis.Client
}
func NewUpdateCache(rdb *redis.Client) ports.UpdateCache {
func NewUpdateCache(rdb *redis.Client) service.UpdateCache {
return &updateCache{rdb: rdb}
}
......
package repository
import (
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/google/wire"
)
......@@ -40,13 +39,13 @@ var ProviderSet = wire.NewSet(
NewOpenAIOAuthClient,
// Bind concrete repositories to service port interfaces
wire.Bind(new(ports.UserRepository), new(*UserRepository)),
wire.Bind(new(ports.ApiKeyRepository), new(*ApiKeyRepository)),
wire.Bind(new(ports.GroupRepository), new(*GroupRepository)),
wire.Bind(new(ports.AccountRepository), new(*AccountRepository)),
wire.Bind(new(ports.ProxyRepository), new(*ProxyRepository)),
wire.Bind(new(ports.RedeemCodeRepository), new(*RedeemCodeRepository)),
wire.Bind(new(ports.UsageLogRepository), new(*UsageLogRepository)),
wire.Bind(new(ports.SettingRepository), new(*SettingRepository)),
wire.Bind(new(ports.UserSubscriptionRepository), new(*UserSubscriptionRepository)),
wire.Bind(new(service.UserRepository), new(*UserRepository)),
wire.Bind(new(service.ApiKeyRepository), new(*ApiKeyRepository)),
wire.Bind(new(service.GroupRepository), new(*GroupRepository)),
wire.Bind(new(service.AccountRepository), new(*AccountRepository)),
wire.Bind(new(service.ProxyRepository), new(*ProxyRepository)),
wire.Bind(new(service.RedeemCodeRepository), new(*RedeemCodeRepository)),
wire.Bind(new(service.UsageLogRepository), new(*UsageLogRepository)),
wire.Bind(new(service.SettingRepository), new(*SettingRepository)),
wire.Bind(new(service.UserSubscriptionRepository), new(*UserSubscriptionRepository)),
)
......@@ -4,10 +4,10 @@ import (
"context"
"errors"
"fmt"
"time"
"github.com/Wei-Shaw/sub2api/internal/model"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"gorm.io/gorm"
)
......@@ -15,6 +15,51 @@ var (
ErrAccountNotFound = errors.New("account not found")
)
type AccountRepository interface {
Create(ctx context.Context, account *model.Account) error
GetByID(ctx context.Context, id int64) (*model.Account, error)
// GetByCRSAccountID finds an account previously synced from CRS.
// Returns (nil, nil) if not found.
GetByCRSAccountID(ctx context.Context, crsAccountID string) (*model.Account, error)
Update(ctx context.Context, account *model.Account) error
Delete(ctx context.Context, id int64) error
List(ctx context.Context, params pagination.PaginationParams) ([]model.Account, *pagination.PaginationResult, error)
ListWithFilters(ctx context.Context, params pagination.PaginationParams, platform, accountType, status, search string) ([]model.Account, *pagination.PaginationResult, error)
ListByGroup(ctx context.Context, groupID int64) ([]model.Account, error)
ListActive(ctx context.Context) ([]model.Account, error)
ListByPlatform(ctx context.Context, platform string) ([]model.Account, error)
UpdateLastUsed(ctx context.Context, id int64) error
SetError(ctx context.Context, id int64, errorMsg string) error
SetSchedulable(ctx context.Context, id int64, schedulable bool) error
BindGroups(ctx context.Context, accountID int64, groupIDs []int64) error
ListSchedulable(ctx context.Context) ([]model.Account, error)
ListSchedulableByGroupID(ctx context.Context, groupID int64) ([]model.Account, error)
ListSchedulableByPlatform(ctx context.Context, platform string) ([]model.Account, error)
ListSchedulableByGroupIDAndPlatform(ctx context.Context, groupID int64, platform string) ([]model.Account, error)
SetRateLimited(ctx context.Context, id int64, resetAt time.Time) error
SetOverloaded(ctx context.Context, id int64, until time.Time) 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
BulkUpdate(ctx context.Context, ids []int64, updates AccountBulkUpdate) (int64, error)
}
// AccountBulkUpdate describes the fields that can be updated in a bulk operation.
// Nil pointers mean "do not change".
type AccountBulkUpdate struct {
Name *string
ProxyID *int64
Concurrency *int
Priority *int
Status *string
Credentials map[string]any
Extra map[string]any
}
// CreateAccountRequest 创建账号请求
type CreateAccountRequest struct {
Name string `json:"name"`
......@@ -42,12 +87,12 @@ type UpdateAccountRequest struct {
// AccountService 账号管理服务
type AccountService struct {
accountRepo ports.AccountRepository
groupRepo ports.GroupRepository
accountRepo AccountRepository
groupRepo GroupRepository
}
// NewAccountService 创建账号服务实例
func NewAccountService(accountRepo ports.AccountRepository, groupRepo ports.GroupRepository) *AccountService {
func NewAccountService(accountRepo AccountRepository, groupRepo GroupRepository) *AccountService {
return &AccountService{
accountRepo: accountRepo,
groupRepo: groupRepo,
......
......@@ -17,8 +17,6 @@ import (
"github.com/Wei-Shaw/sub2api/internal/model"
"github.com/Wei-Shaw/sub2api/internal/pkg/claude"
"github.com/Wei-Shaw/sub2api/internal/pkg/openai"
"github.com/Wei-Shaw/sub2api/internal/service/ports"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
......@@ -40,14 +38,14 @@ type TestEvent struct {
// AccountTestService handles account testing operations
type AccountTestService struct {
accountRepo ports.AccountRepository
accountRepo AccountRepository
oauthService *OAuthService
openaiOAuthService *OpenAIOAuthService
httpUpstream ports.HTTPUpstream
httpUpstream HTTPUpstream
}
// NewAccountTestService creates a new AccountTestService
func NewAccountTestService(accountRepo ports.AccountRepository, oauthService *OAuthService, openaiOAuthService *OpenAIOAuthService, httpUpstream ports.HTTPUpstream) *AccountTestService {
func NewAccountTestService(accountRepo AccountRepository, oauthService *OAuthService, openaiOAuthService *OpenAIOAuthService, httpUpstream HTTPUpstream) *AccountTestService {
return &AccountTestService{
accountRepo: accountRepo,
oauthService: oauthService,
......
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