fix: billing gate broke for scale/enterprise and downgraded users#794
fix: billing gate broke for scale/enterprise and downgraded users#794graphite-app[bot] merged 1 commit intomainfrom
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-app | 55ef8ab | Mar 22 2026, 04:08 PM |
|
Claude finished @Prasanna721's task in 1m 47s —— View job Review Complete
Overview: Fixes billing gate logic to support scale/enterprise tiers and handle downgraded users during their billing grace period. Issues found: None — this looks good to ship. The updated
The plan detection in Note on Sentry comment: The previous inline comment about Note on deployment failure: The Cloudflare deployment failure appears unrelated to these code changes. The logic is sound; this may be a CI configuration issue worth investigating separately. Score: 10/10 |
There was a problem hiding this comment.
Overview: Fixes billing gate logic to support scale/enterprise tiers and users in their remaining billing period after downgrading.
Issues found: None — this looks good to ship.
The isAllowedFrom function correctly:
- Checks from the minimum required tier upward through the hierarchy (pro → scale → enterprise)
- Uses
allowed || status !== nullto grant access if the user has an active subscription OR is still within their billing period after cancellation - The plan detection in
use-token-usage.tscorrectly checks from highest tier down to determine the user's current plan
The 403 handling in plugins-detail.tsx provides a clear error message instead of a generic failure.
Score: 10/10
0e96f6f to
9c1bf38
Compare
packages/lib/queries.ts
Outdated
| const minIndex = PLAN_TIERS.indexOf(minimumTier) | ||
| return PLAN_TIERS.slice(minIndex).some((tier) => { | ||
| const s = status[tier] | ||
| return s != null && (s.allowed || s.status !== null) |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
7a8150a to
c6c059e
Compare
|
Updated the This aligns with how console-v2 handles billing gates — it reads Since |
| const minIndex = PLAN_TIERS.indexOf(minimumTier) | ||
| return PLAN_TIERS.slice(minIndex).some((tier) => { | ||
| const s = status[tier] | ||
| return s?.status === "active" | ||
| }) | ||
| } | ||
|
|
||
| export const fetchSubscriptionStatus = ( |
There was a problem hiding this comment.
Bug: The isAllowedFrom function only checks for status === "active" and ignores the allowed flag, incorrectly locking out users who are in a grace period after downgrading.
Severity: HIGH
Suggested Fix
Modify the isAllowedFrom function to check both the allowed flag and the subscription status. The condition inside the some callback should be updated to check if s?.status === "active" or if s?.allowed is true.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: packages/lib/queries.ts#L29-L36
Potential issue: The `isAllowedFrom` function determines feature access based on
subscription status. It correctly fetches both `status` and an `allowed` flag for each
subscription tier. However, the logic only checks if `s?.status === "active"` and
completely ignores the `s.allowed` boolean. This contradicts the PR's goal, which is to
grant access to users who have downgraded but are still in their billing period
(indicated by `allowed: true`). As a result, these users will be incorrectly locked out
of paid features.
Merge activity
|
The subscription check on plugins, connections, and usage pages was hardcoded to only look at `api_pro`. Users on scale or enterprise plans saw "Upgrade to Pro" and couldn't create plugin keys or manage connections. Also, the check only looked at product `status` but not the `allowed` flag from autumn — so users who downgraded but were still in their billing period got locked out early.
9d8f994 to
55ef8ab
Compare
| const minIndex = PLAN_TIERS.indexOf(minimumTier) | ||
| return PLAN_TIERS.slice(minIndex).some((tier) => { | ||
| const s = status[tier] | ||
| return s?.status === "active" | ||
| }) |
There was a problem hiding this comment.
Bug: The isAllowedFrom function only checks if a subscription status is "active", ignoring the allowed flag. This will lock out users in a grace period after downgrading.
Severity: HIGH
Suggested Fix
Modify the isAllowedFrom function to correctly handle grace periods by checking the allowed flag in addition to the status. The logic should return true if s?.allowed is true or if s?.status === "active". This ensures users in a grace period retain access as intended.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: packages/lib/queries.ts#L29-L33
Potential issue: The `isAllowedFrom` function determines feature access based on
subscription tier. While the `fetchSubscriptionStatus` function correctly fetches both a
subscription `status` and an `allowed` flag for real-time entitlement, the gating logic
in `isAllowedFrom` only checks if `s?.status === "active"`. It completely ignores the
`allowed` flag. Consequently, users who have downgraded but are still within their paid
billing period (a "grace period" where `allowed` would be `true` but `status` is not
"active") will be incorrectly locked out of features like plugins and connections. This
contradicts the intended fix of the pull request.
The subscription check on plugins, connections, and usage pages was hardcoded to only look at
api_pro. Users on scale or enterprise plans saw "Upgrade to Pro" and couldn't create plugin keys or manage connections.Also, the check only looked at product
statusbut not theallowedflag from autumn — so users who downgraded but were still in their billing period got locked out early.