Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions backend/internal/domain/account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,12 +558,15 @@ func normalizeBillingPlan(value string) string {
}

func isPaidBillingPlan(value string) bool {
switch normalizeBillingPlan(value) {
case "super", "supergrok", "supergrokpro", "supergrokheavy", "supergroklite",
normalized := normalizeBillingPlan(value)
switch normalized {
case "super", "supergrok", "supergrokpro", "supergrokheavy", "supergroklite", "supergrokplus",
"grokpro", "xpremium", "xpremiumplus", "apikey":
return true
default:
return false
// SuperGrok Plus and later SuperGrok* tiers should stay paid even when
// weekly numeric limits are zero and the exact plan name is new.
return strings.HasPrefix(normalized, "supergrok")
}
}

Expand Down
2 changes: 2 additions & 0 deletions backend/internal/domain/account/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ func TestBillingIsPaidMatchesSQLSignals(t *testing.T) {
{PrepaidBalance: 5},
{PlanName: "SuperGrok"},
{PlanName: "SuperGrok Heavy"},
{PlanName: "SuperGrokPlus"},
{PlanName: "SuperGrok Plus"},
{PlanCode: "supergrok_lite"},
{PlanName: "X Premium+"},
} {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ type quotaBreakdownJSON struct {

const (
accountUpdateBatchSize = 500
accountPaidPlanSignal = `(LOWER(REPLACE(REPLACE(REPLACE(REPLACE(TRIM(billing.plan_code), ' ', ''), '_', ''), '-', ''), '+', 'plus')) IN ('super', 'supergrok', 'supergrokpro', 'supergrokheavy', 'supergroklite', 'grokpro', 'xpremium', 'xpremiumplus', 'apikey') OR LOWER(REPLACE(REPLACE(REPLACE(REPLACE(TRIM(billing.plan_name), ' ', ''), '_', ''), '-', ''), '+', 'plus')) IN ('super', 'supergrok', 'supergrokpro', 'supergrokheavy', 'supergroklite', 'grokpro', 'xpremium', 'xpremiumplus', 'apikey'))`
accountNormalizedPlanCode = `LOWER(REPLACE(REPLACE(REPLACE(REPLACE(TRIM(billing.plan_code), ' ', ''), '_', ''), '-', ''), '+', 'plus'))`
accountNormalizedPlanName = `LOWER(REPLACE(REPLACE(REPLACE(REPLACE(TRIM(billing.plan_name), ' ', ''), '_', ''), '-', ''), '+', 'plus'))`
accountPaidPlanNames = `'super', 'supergrok', 'supergrokpro', 'supergrokheavy', 'supergroklite', 'supergrokplus', 'grokpro', 'xpremium', 'xpremiumplus', 'apikey'`
accountPaidPlanSignal = `(` + accountNormalizedPlanCode + ` IN (` + accountPaidPlanNames + `) OR ` + accountNormalizedPlanName + ` IN (` + accountPaidPlanNames + `) OR substr(` + accountNormalizedPlanCode + `, 1, 9) = 'supergrok' OR substr(` + accountNormalizedPlanName + `, 1, 9) = 'supergrok')`
accountFreePlanSignal = `(LOWER(REPLACE(REPLACE(REPLACE(REPLACE(TRIM(billing.plan_code), ' ', ''), '_', ''), '-', ''), '+', 'plus')) IN ('free', 'grokfree', 'freetier', 'basic', 'grokbasic', 'xbasic') OR LOWER(REPLACE(REPLACE(REPLACE(REPLACE(TRIM(billing.plan_name), ' ', ''), '_', ''), '-', ''), '+', 'plus')) IN ('free', 'grokfree', 'freetier', 'basic', 'grokbasic', 'xbasic'))`
accountPaidBillingSignals = `(` + accountPaidPlanSignal + ` OR billing.monthly_limit > 0 OR billing.on_demand_cap > 0 OR billing.on_demand_used > 0 OR billing.prepaid_balance > 0)`
accountPaidBillingPredicate = `EXISTS (SELECT 1 FROM account_billing_snapshots billing WHERE billing.account_id = provider_accounts.id AND ` + accountPaidBillingSignals + `)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,32 @@ func TestListFiltersRecognizesInferredFreeBilling(t *testing.T) {
assertAccountFilterCount(t, ctx, accounts, repository.AccountListFilter{QuotaType: "unknown", Now: now}, 0)
}

func TestListFiltersRecognizesSuperGrokPlusAsPaid(t *testing.T) {
ctx := context.Background()
database, err := OpenSQLite(ctx, filepath.Join(t.TempDir(), "supergrok-plus.db"))
if err != nil {
t.Fatal(err)
}
defer database.Close()
if err := database.InitializeSchema(ctx); err != nil {
t.Fatal(err)
}
now := time.Now().UTC()
value := accountModel{IdentityKey: testIdentityKey("plus"), Provider: "grok_build", Name: "plus", SourceKey: "plus", Enabled: true, AuthStatus: "active", Priority: 1}
if err := database.db.WithContext(ctx).Create(&value).Error; err != nil {
t.Fatal(err)
}
if err := database.db.WithContext(ctx).Create(&billingModel{
AccountID: value.ID, PlanName: "SuperGrokPlus", IsUnifiedBillingUser: true, UsagePeriodType: "USAGE_PERIOD_TYPE_WEEKLY", SyncedAt: now,
}).Error; err != nil {
t.Fatal(err)
}
accounts := NewAccountRepository(database)
assertAccountFilterCount(t, ctx, accounts, repository.AccountListFilter{QuotaType: "paid", Now: now}, 1)
assertAccountFilterCount(t, ctx, accounts, repository.AccountListFilter{QuotaType: "free", Now: now}, 0)
assertAccountFilterCount(t, ctx, accounts, repository.AccountListFilter{QuotaType: "unknown", Now: now}, 0)
}

func assertAccountFilterCount(t *testing.T, ctx context.Context, accounts *AccountRepository, filter repository.AccountListFilter, expected int64) {
t.Helper()
_, total, err := accounts.List(ctx, repository.AccountListQuery{Page: repository.PageQuery{Limit: 20}, Filter: filter})
Expand Down
8 changes: 8 additions & 0 deletions backend/internal/infra/provider/cli/billing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ func TestParseBillingMatchesObservedBuildPayloads(t *testing.T) {
if !credits.IsPaid() {
t.Fatal("explicit SuperGrok tier must remain paid even when numeric limits are zero")
}

plus, err := parseBilling([]byte(`{"onDemandEnabled":false,"subscriptionTier":"SuperGrokPlus","config":{"creditUsagePercent":0,"currentPeriod":{"type":"USAGE_PERIOD_TYPE_WEEKLY","start":"2026-08-22T10:54:49.503515+00:00","end":"2026-08-29T10:54:49.503515+00:00"},"onDemandCap":{"val":0},"onDemandUsed":{"val":0},"isUnifiedBillingUser":true,"prepaidBalance":{"val":0},"topUpMethod":"TOP_UP_METHOD_SAVED_PAYMENT_METHOD"}}`))
if err != nil {
t.Fatal(err)
}
if plus.PlanName != "SuperGrokPlus" || !plus.IsPaid() {
t.Fatalf("SuperGrokPlus must be paid: %#v", plus)
}
}

func TestParseSubscriptionTierAndJWTFallback(t *testing.T) {
Expand Down
Loading