From 71c28e436a1156ac8a3db1924095f4427454f79c Mon Sep 17 00:00:00 2001 From: ianshaw Date: Thu, 25 Dec 2025 06:43:57 -0800 Subject: [PATCH] =?UTF-8?q?feat(service):=20=E5=AE=9A=E4=B9=89=20Gemini=20?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=8F=A3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 定义 OAuth 服务接口 - 定义 Token 缓存服务接口 - 定义 Code Assist 服务接口 --- backend/internal/service/gemini_oauth.go | 13 +++++++++++++ backend/internal/service/gemini_token_cache.go | 16 ++++++++++++++++ backend/internal/service/geminicli_codeassist.go | 13 +++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 backend/internal/service/gemini_oauth.go create mode 100644 backend/internal/service/gemini_token_cache.go create mode 100644 backend/internal/service/geminicli_codeassist.go diff --git a/backend/internal/service/gemini_oauth.go b/backend/internal/service/gemini_oauth.go new file mode 100644 index 00000000..185d6c55 --- /dev/null +++ b/backend/internal/service/gemini_oauth.go @@ -0,0 +1,13 @@ +package ports + +import ( + "context" + + "github.com/Wei-Shaw/sub2api/internal/pkg/geminicli" +) + +// GeminiOAuthClient performs Google OAuth token exchange/refresh for Gemini integration. +type GeminiOAuthClient interface { + ExchangeCode(ctx context.Context, code, codeVerifier, redirectURI, proxyURL string) (*geminicli.TokenResponse, error) + RefreshToken(ctx context.Context, refreshToken, proxyURL string) (*geminicli.TokenResponse, error) +} diff --git a/backend/internal/service/gemini_token_cache.go b/backend/internal/service/gemini_token_cache.go new file mode 100644 index 00000000..79a5f948 --- /dev/null +++ b/backend/internal/service/gemini_token_cache.go @@ -0,0 +1,16 @@ +package ports + +import ( + "context" + "time" +) + +// GeminiTokenCache stores short-lived access tokens and coordinates refresh to avoid stampedes. +type GeminiTokenCache interface { + // cacheKey should be stable for the token scope; for GeminiCli OAuth we primarily use project_id. + GetAccessToken(ctx context.Context, cacheKey string) (string, error) + SetAccessToken(ctx context.Context, cacheKey string, token string, ttl time.Duration) error + + AcquireRefreshLock(ctx context.Context, cacheKey string, ttl time.Duration) (bool, error) + ReleaseRefreshLock(ctx context.Context, cacheKey string) error +} diff --git a/backend/internal/service/geminicli_codeassist.go b/backend/internal/service/geminicli_codeassist.go new file mode 100644 index 00000000..2d742b24 --- /dev/null +++ b/backend/internal/service/geminicli_codeassist.go @@ -0,0 +1,13 @@ +package ports + +import ( + "context" + + "github.com/Wei-Shaw/sub2api/internal/pkg/geminicli" +) + +// GeminiCliCodeAssistClient calls GeminiCli internal Code Assist endpoints. +type GeminiCliCodeAssistClient interface { + LoadCodeAssist(ctx context.Context, accessToken, proxyURL string, req *geminicli.LoadCodeAssistRequest) (*geminicli.LoadCodeAssistResponse, error) + OnboardUser(ctx context.Context, accessToken, proxyURL string, req *geminicli.OnboardUserRequest) (*geminicli.OnboardUserResponse, error) +}