From b6ee9f0a320cbdd980c68e916ff551e1feb573a0 Mon Sep 17 00:00:00 2001 From: 22zyfeng-collab <241945674+22zyfeng-collab@users.noreply.github.com> Date: Tue, 8 Sep 2026 15:02:32 +0800 Subject: [PATCH] fix(antigravity): preserve OAuth subscription plan across account creation --- .../service/antigravity_oauth_service.go | 2 +- .../service/antigravity_oauth_service_test.go | 24 +++++++++++++++++++ frontend/src/api/admin/antigravity.ts | 1 + .../__tests__/useAntigravityOAuth.spec.ts | 14 +++++++++++ .../src/composables/useAntigravityOAuth.ts | 3 ++- 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/backend/internal/service/antigravity_oauth_service.go b/backend/internal/service/antigravity_oauth_service.go index 3a4600db0e..5d4390d9cf 100644 --- a/backend/internal/service/antigravity_oauth_service.go +++ b/backend/internal/service/antigravity_oauth_service.go @@ -90,7 +90,7 @@ type AntigravityTokenInfo struct { Email string `json:"email,omitempty"` ProjectID string `json:"project_id,omitempty"` ProjectIDMissing bool `json:"-"` - PlanType string `json:"-"` + PlanType string `json:"plan_type,omitempty"` PrivacyMode string `json:"-"` } diff --git a/backend/internal/service/antigravity_oauth_service_test.go b/backend/internal/service/antigravity_oauth_service_test.go index 1d2d823557..c89b3f0a44 100644 --- a/backend/internal/service/antigravity_oauth_service_test.go +++ b/backend/internal/service/antigravity_oauth_service_test.go @@ -1,6 +1,7 @@ package service import ( + "encoding/json" "testing" ) @@ -80,3 +81,26 @@ func TestResolveDefaultTierID(t *testing.T) { }) } } + +// The OAuth handler serializes this DTO before the browser creates or reauthorizes an account. +func TestAntigravityTokenInfoPreservesPlanTypeJSON(t *testing.T) { + for _, plan := range []string{"pro", "ultra", "free", ""} { + t.Run(plan, func(t *testing.T) { + data, err := json.Marshal(AntigravityTokenInfo{PlanType: plan}) + if err != nil { + t.Fatal(err) + } + var response map[string]any + if err := json.Unmarshal(data, &response); err != nil { + t.Fatal(err) + } + if plan == "" { + if _, exists := response["plan_type"]; exists { + t.Fatal("unknown plan must remain omitted") + } + } else if response["plan_type"] != plan { + t.Fatalf("OAuth response plan_type = %v, want %q", response["plan_type"], plan) + } + }) + } +} diff --git a/frontend/src/api/admin/antigravity.ts b/frontend/src/api/admin/antigravity.ts index 779fa9c1f8..7b351fab8e 100644 --- a/frontend/src/api/admin/antigravity.ts +++ b/frontend/src/api/admin/antigravity.ts @@ -29,6 +29,7 @@ export interface AntigravityTokenInfo { expires_at?: number | string expires_in?: number project_id?: string + plan_type?: string email?: string [key: string]: unknown } diff --git a/frontend/src/composables/__tests__/useAntigravityOAuth.spec.ts b/frontend/src/composables/__tests__/useAntigravityOAuth.spec.ts index fcb6f48b18..511f28b2be 100644 --- a/frontend/src/composables/__tests__/useAntigravityOAuth.spec.ts +++ b/frontend/src/composables/__tests__/useAntigravityOAuth.spec.ts @@ -54,3 +54,17 @@ describe('useAntigravityOAuth.buildCredentials', () => { expect(credentials.refresh_token).toBe('rotated-refresh-token') }) }) + +// This builder is shared by OAuth creation, refresh-token import and reauthorization. +describe('Antigravity subscription metadata', () => { + it.each(['pro', 'ultra', 'free'])('preserves the upstream %s plan when saving credentials', (plan) => { + const oauth = useAntigravityOAuth() + const credentials = oauth.buildCredentials({ plan_type: plan }) + expect(credentials.plan_type).toBe(plan) + }) + + it('does not invent a plan when subscription discovery is unavailable', () => { + const credentials = useAntigravityOAuth().buildCredentials({}) + expect(credentials).not.toHaveProperty('plan_type') + }) +}) diff --git a/frontend/src/composables/useAntigravityOAuth.ts b/frontend/src/composables/useAntigravityOAuth.ts index f480ea20bc..df0d264c0e 100644 --- a/frontend/src/composables/useAntigravityOAuth.ts +++ b/frontend/src/composables/useAntigravityOAuth.ts @@ -132,7 +132,8 @@ export function useAntigravityOAuth() { token_type: tokenInfo.token_type, expires_at: expiresAt, project_id: tokenInfo.project_id, - email: tokenInfo.email + email: tokenInfo.email, + ...(tokenInfo.plan_type ? { plan_type: tokenInfo.plan_type } : {}) } }