mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-08-28 05:25:33 +00:00
fix: billing gate broke for scale/enterprise and downgraded users (#794)
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.
This commit is contained in:
parent
2ce55c43bc
commit
55ef8ab899
8 changed files with 84 additions and 78 deletions
|
|
@ -1,7 +1,12 @@
|
|||
"use client"
|
||||
|
||||
import { $fetch } from "@lib/api"
|
||||
import { fetchConnectionsFeature } from "@lib/queries"
|
||||
import {
|
||||
DEFAULT_SUBSCRIPTION_STATUS,
|
||||
fetchConnectionsFeature,
|
||||
fetchSubscriptionStatus,
|
||||
isAllowedFrom,
|
||||
} from "@lib/queries"
|
||||
import type { ConnectionResponseSchema } from "@repo/validation/api"
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
|
||||
import { GoogleDrive, Notion, OneDrive } from "@ui/assets/icons"
|
||||
|
|
@ -51,7 +56,9 @@ interface ConnectContentProps {
|
|||
export function ConnectContent({ selectedProject }: ConnectContentProps) {
|
||||
const queryClient = useQueryClient()
|
||||
const autumn = useCustomer()
|
||||
const [isProUser, setIsProUser] = useState(false)
|
||||
const { data: subscriptionStatus = DEFAULT_SUBSCRIPTION_STATUS } =
|
||||
fetchSubscriptionStatus(autumn, !autumn.isLoading)
|
||||
const isProUser = isAllowedFrom(subscriptionStatus, "api_pro")
|
||||
const [connectingProvider, setConnectingProvider] =
|
||||
useState<ConnectorProvider | null>(null)
|
||||
const [isUpgrading, setIsUpgrading] = useState(false)
|
||||
|
|
@ -60,17 +67,6 @@ export function ConnectContent({ selectedProject }: ConnectContentProps) {
|
|||
connection: Connection | null
|
||||
}>({ open: false, connection: null })
|
||||
|
||||
// Check Pro status
|
||||
useEffect(() => {
|
||||
if (!autumn.isLoading) {
|
||||
setIsProUser(
|
||||
autumn.customer?.products?.some(
|
||||
(product) => product.id === "api_pro",
|
||||
) ?? false,
|
||||
)
|
||||
}
|
||||
}, [autumn.isLoading, autumn.customer])
|
||||
|
||||
const handleUpgrade = async () => {
|
||||
setIsUpgrading(true)
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
import { dmSans125ClassName } from "@/lib/fonts"
|
||||
import { cn } from "@lib/utils"
|
||||
import { $fetch } from "@lib/api"
|
||||
import { fetchSubscriptionStatus } from "@lib/queries"
|
||||
import {
|
||||
DEFAULT_SUBSCRIPTION_STATUS,
|
||||
fetchSubscriptionStatus,
|
||||
isAllowedFrom,
|
||||
} from "@lib/queries"
|
||||
import { GoogleDrive, Notion, OneDrive } from "@ui/assets/icons"
|
||||
import { useCustomer } from "autumn-js/react"
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
|
||||
|
|
@ -181,11 +185,11 @@ export function ConnectionsDetail() {
|
|||
[]) as Project[]
|
||||
|
||||
const {
|
||||
data: status = { api_pro: { allowed: false, status: null } },
|
||||
data: status = DEFAULT_SUBSCRIPTION_STATUS,
|
||||
isLoading: isCheckingStatus,
|
||||
} = fetchSubscriptionStatus(autumn, !autumn.isLoading)
|
||||
|
||||
const hasProProduct = status.api_pro?.status !== null
|
||||
const hasProProduct = isAllowedFrom(status, "api_pro")
|
||||
|
||||
const connectionsFeature = autumn.customer?.features?.connections
|
||||
const connectionsUsed = connectionsFeature?.usage ?? 0
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@ import { cn } from "@lib/utils"
|
|||
import { dmSans125ClassName } from "@/lib/fonts"
|
||||
import { authClient } from "@lib/auth"
|
||||
import { useAuth } from "@lib/auth-context"
|
||||
import { fetchSubscriptionStatus } from "@lib/queries"
|
||||
import {
|
||||
DEFAULT_SUBSCRIPTION_STATUS,
|
||||
fetchSubscriptionStatus,
|
||||
isAllowedFrom,
|
||||
} from "@lib/queries"
|
||||
import { useCustomer } from "autumn-js/react"
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
|
||||
import {
|
||||
|
|
@ -17,7 +21,6 @@ import {
|
|||
ExternalLink,
|
||||
Key,
|
||||
Loader,
|
||||
Plug,
|
||||
Trash2,
|
||||
Zap,
|
||||
} from "lucide-react"
|
||||
|
|
@ -31,7 +34,6 @@ import {
|
|||
DialogTitle,
|
||||
DialogPortal,
|
||||
} from "@ui/components/dialog"
|
||||
import { analytics } from "@/lib/analytics"
|
||||
|
||||
interface PluginInfo {
|
||||
id: string
|
||||
|
|
@ -108,11 +110,11 @@ export function PluginsDetail() {
|
|||
const [keyCopied, setKeyCopied] = useState(false)
|
||||
|
||||
const {
|
||||
data: status = { api_pro: { allowed: false, status: null } },
|
||||
data: status = DEFAULT_SUBSCRIPTION_STATUS,
|
||||
isLoading: isCheckingStatus,
|
||||
} = fetchSubscriptionStatus(autumn, !autumn.isLoading)
|
||||
|
||||
const hasProProduct = status.api_pro?.status !== null
|
||||
const hasProProduct = isAllowedFrom(status, "api_pro")
|
||||
|
||||
const { data: pluginsData } = useQuery({
|
||||
queryFn: async () => {
|
||||
|
|
@ -181,6 +183,9 @@ export function PluginsDetail() {
|
|||
credentials: "include",
|
||||
})
|
||||
if (!res.ok) {
|
||||
if (res.status === 403) {
|
||||
throw new Error("A Pro plan is required to connect plugins.")
|
||||
}
|
||||
const errorData = (await res.json().catch(() => ({}))) as {
|
||||
message?: string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
import { dmSans125ClassName } from "@/lib/fonts"
|
||||
import { cn } from "@lib/utils"
|
||||
import { $fetch } from "@lib/api"
|
||||
import { fetchSubscriptionStatus } from "@lib/queries"
|
||||
import {
|
||||
DEFAULT_SUBSCRIPTION_STATUS,
|
||||
fetchSubscriptionStatus,
|
||||
isAllowedFrom,
|
||||
} from "@lib/queries"
|
||||
import { GoogleDrive, Notion, OneDrive } from "@ui/assets/icons"
|
||||
import { useCustomer } from "autumn-js/react"
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
|
||||
|
|
@ -348,13 +352,11 @@ export default function ConnectionsMCP() {
|
|||
|
||||
// Billing data
|
||||
const {
|
||||
data: status = {
|
||||
api_pro: { allowed: false, status: null },
|
||||
},
|
||||
data: status = DEFAULT_SUBSCRIPTION_STATUS,
|
||||
isLoading: isCheckingStatus,
|
||||
} = fetchSubscriptionStatus(autumn, !autumn.isLoading)
|
||||
|
||||
const hasProProduct = status.api_pro?.status !== null
|
||||
const hasProProduct = isAllowedFrom(status, "api_pro")
|
||||
|
||||
// Get connections data directly from autumn customer
|
||||
const connectionsFeature = autumn.customer?.features?.connections
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
import { fetchMemoriesFeature, fetchSubscriptionStatus } from "@lib/queries"
|
||||
import {
|
||||
DEFAULT_SUBSCRIPTION_STATUS,
|
||||
fetchMemoriesFeature,
|
||||
fetchSubscriptionStatus,
|
||||
isAllowedFrom,
|
||||
} from "@lib/queries"
|
||||
import type { useCustomer } from "autumn-js/react"
|
||||
|
||||
export function useMemoriesUsage(autumn: ReturnType<typeof useCustomer>) {
|
||||
const {
|
||||
data: status = {
|
||||
api_pro: { allowed: false, status: null },
|
||||
},
|
||||
data: status = DEFAULT_SUBSCRIPTION_STATUS,
|
||||
isLoading: isCheckingStatus,
|
||||
} = fetchSubscriptionStatus(autumn, !autumn.isLoading)
|
||||
|
||||
const proStatus = status.api_pro
|
||||
const hasProProduct = proStatus?.status !== null
|
||||
const hasProProduct = isAllowedFrom(status, "api_pro")
|
||||
|
||||
const { data: memoriesCheck, isLoading: isLoadingMemories } =
|
||||
fetchMemoriesFeature(autumn, !isCheckingStatus && !autumn.isLoading)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import { fetchSubscriptionStatus } from "@lib/queries"
|
||||
import {
|
||||
DEFAULT_SUBSCRIPTION_STATUS,
|
||||
fetchSubscriptionStatus,
|
||||
isAllowedFrom,
|
||||
} from "@lib/queries"
|
||||
import type { useCustomer } from "autumn-js/react"
|
||||
import { calculateUsagePercent, getDaysRemaining } from "@/lib/billing-utils"
|
||||
|
||||
|
|
@ -6,20 +10,16 @@ export type PlanType = "free" | "pro" | "scale" | "enterprise"
|
|||
|
||||
export function useTokenUsage(autumn: ReturnType<typeof useCustomer>) {
|
||||
const {
|
||||
data: status = {
|
||||
api_pro: { allowed: false, status: null },
|
||||
api_scale: { allowed: false, status: null },
|
||||
api_enterprise: { allowed: false, status: null },
|
||||
},
|
||||
data: status = DEFAULT_SUBSCRIPTION_STATUS,
|
||||
isLoading: isCheckingStatus,
|
||||
} = fetchSubscriptionStatus(autumn, !autumn.isLoading)
|
||||
|
||||
let currentPlan: PlanType = "free"
|
||||
if (status.api_enterprise?.status !== null) {
|
||||
if (isAllowedFrom(status, "api_enterprise")) {
|
||||
currentPlan = "enterprise"
|
||||
} else if (status.api_scale?.status !== null) {
|
||||
} else if (isAllowedFrom(status, "api_scale")) {
|
||||
currentPlan = "scale"
|
||||
} else if (status.api_pro?.status !== null) {
|
||||
} else if (isAllowedFrom(status, "api_pro")) {
|
||||
currentPlan = "pro"
|
||||
}
|
||||
|
||||
|
|
|
|||
15
bun.lock
15
bun.lock
|
|
@ -322,11 +322,12 @@
|
|||
},
|
||||
"packages/tools": {
|
||||
"name": "@supermemory/tools",
|
||||
"version": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "^2.0.25",
|
||||
"@ai-sdk/openai": "^2.0.23",
|
||||
"ai": "^5.0.29",
|
||||
"lru-cache": "^11.2.6",
|
||||
"openai": "^4.104.0",
|
||||
"supermemory": "^3.0.0-alpha.26",
|
||||
"zod": "^4.1.5",
|
||||
|
|
@ -3476,7 +3477,7 @@
|
|||
|
||||
"lowercase-keys": ["lowercase-keys@3.0.0", "", {}, "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ=="],
|
||||
|
||||
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||
"lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
|
||||
|
||||
"lucide-react": ["lucide-react@0.525.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ=="],
|
||||
|
||||
|
|
@ -4934,8 +4935,6 @@
|
|||
|
||||
"@mastra/core/hono-openapi": ["hono-openapi@1.3.0", "", { "peerDependencies": { "@hono/standard-validator": "^0.2.0", "@standard-community/standard-json": "^0.3.5", "@standard-community/standard-openapi": "^0.2.9", "@types/json-schema": "^7.0.15", "hono": "^4.8.3", "openapi-types": "^12.1.3" }, "optionalPeers": ["@hono/standard-validator", "hono"] }, "sha512-xDvCWpWEIv0weEmnl3EjRQzqbHIO8LnfzMuYOCmbuyE5aes6aXxLg4vM3ybnoZD5TiTUkA6PuRQPJs3R7WRBig=="],
|
||||
|
||||
"@mastra/core/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
|
||||
|
||||
"@mastra/core/p-retry": ["p-retry@7.1.1", "", { "dependencies": { "is-network-error": "^1.1.0" } }, "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w=="],
|
||||
|
||||
"@mdx-js/mdx/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
||||
|
|
@ -5198,6 +5197,8 @@
|
|||
|
||||
"@types/serve-static/@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="],
|
||||
|
||||
"@vanilla-extract/css/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||
|
||||
"@vanilla-extract/integration/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="],
|
||||
|
||||
"@vitest/mocker/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
||||
|
|
@ -5470,6 +5471,8 @@
|
|||
|
||||
"parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||
|
||||
"path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||
|
||||
"postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||
|
||||
"postcss-load-config/lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
|
||||
|
|
@ -6554,8 +6557,6 @@
|
|||
|
||||
"@opennextjs/cloudflare/glob/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
|
||||
|
||||
"@opennextjs/cloudflare/glob/path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
|
||||
|
||||
"@puppeteer/browsers/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
|
||||
"@puppeteer/browsers/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
||||
|
|
@ -6572,8 +6573,6 @@
|
|||
|
||||
"@sentry/bundler-plugin-core/glob/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
|
||||
|
||||
"@sentry/bundler-plugin-core/glob/path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
|
||||
|
||||
"@supermemory/tools/@ai-sdk/anthropic/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
|
||||
|
||||
"agents/@modelcontextprotocol/sdk/express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
|
||||
|
|
|
|||
|
|
@ -8,20 +8,41 @@ import { $fetch } from "./api"
|
|||
type DocumentsResponse = z.infer<typeof DocumentsWithMemoriesResponseSchema>
|
||||
type DocumentWithMemories = DocumentsResponse["documents"][0]
|
||||
|
||||
export const PLAN_TIERS = ["api_pro", "api_scale", "api_enterprise"] as const
|
||||
export type PlanTier = (typeof PLAN_TIERS)[number]
|
||||
|
||||
export type SubscriptionStatusMap = Record<
|
||||
string,
|
||||
{ allowed: boolean; status: string | null }
|
||||
>
|
||||
|
||||
export const DEFAULT_SUBSCRIPTION_STATUS: SubscriptionStatusMap = {
|
||||
api_pro: { allowed: false, status: null },
|
||||
api_scale: { allowed: false, status: null },
|
||||
api_enterprise: { allowed: false, status: null },
|
||||
}
|
||||
|
||||
export function isAllowedFrom(
|
||||
status: SubscriptionStatusMap,
|
||||
minimumTier: PlanTier,
|
||||
): boolean {
|
||||
const minIndex = PLAN_TIERS.indexOf(minimumTier)
|
||||
return PLAN_TIERS.slice(minIndex).some((tier) => {
|
||||
const s = status[tier]
|
||||
return s?.status === "active"
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchSubscriptionStatus = (
|
||||
autumn: ReturnType<typeof useCustomer>,
|
||||
isEnabled: boolean,
|
||||
) =>
|
||||
useQuery({
|
||||
queryFn: async () => {
|
||||
const allPlans = ["api_pro", "api_scale", "api_enterprise"]
|
||||
const statusMap: Record<
|
||||
string,
|
||||
{ allowed: boolean; status: string | null }
|
||||
> = {}
|
||||
const statusMap: SubscriptionStatusMap = {}
|
||||
|
||||
await Promise.all(
|
||||
allPlans.map(async (plan) => {
|
||||
PLAN_TIERS.map(async (plan) => {
|
||||
try {
|
||||
const res = autumn.check({
|
||||
productId: plan,
|
||||
|
|
@ -83,29 +104,6 @@ export const fetchConnectionsFeature = (
|
|||
enabled: isEnabled,
|
||||
})
|
||||
|
||||
// Product checks
|
||||
export const fetchApiProProduct = (autumn: ReturnType<typeof useCustomer>) =>
|
||||
useQuery({
|
||||
queryFn: async () => {
|
||||
const res = autumn.check({ productId: "api_pro" })
|
||||
return res.data
|
||||
},
|
||||
queryKey: ["autumn-product", "api_pro"],
|
||||
staleTime: 30 * 1000, // 30 seconds
|
||||
gcTime: 5 * 60 * 1000, // 5 minutes
|
||||
})
|
||||
|
||||
export const fetchProProduct = (autumn: ReturnType<typeof useCustomer>) =>
|
||||
useQuery({
|
||||
queryFn: async () => {
|
||||
const res = autumn.check({ productId: "pro" })
|
||||
return res.data
|
||||
},
|
||||
queryKey: ["autumn-product", "pro"],
|
||||
staleTime: 30 * 1000, // 30 seconds
|
||||
gcTime: 5 * 60 * 1000, // 5 minutes
|
||||
})
|
||||
|
||||
export const useDeleteDocument = (selectedProject: string) => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue