mirror of
https://github.com/supabase/supabase.git
synced 2026-05-06 08:56:46 -04:00
fix(studio): drive compute card cores/memory from infra_compute_size (#45334)
## Summary Fixes [FE-3095](https://linear.app/supabase/issue/FE-3095/compute-size-hover-card-shows-badge-and-cpumemory-from-out-of-sync). The compute size hover card on the project home dashboard was sourcing its badge and its CPU/memory rows from two different cached responses, which can disagree: | Field shown | Previous source | |---|---| | Badge ("XLARGE") | `project.infra_compute_size` (project-detail query) | | Cores / memory | `selected_addons[compute_instance].variant.meta` (project-addons query) | A customer reported seeing an **XLARGE** badge next to **2-core ARM (Shared) / 1 GB** — the micro-tier specs — and asked whether their upgrade had actually been applied. The upgrade was applied; only the rendered card was contradictory. ## Fix Source both the badge and the CPU/memory rows from the same logical fact: look up the variant in `available_addons` whose identifier matches `ci_${infra_compute_size}` and read its `meta`. `available_addons` is essentially a static catalog of variant specs, so once it's loaded the card cannot show specs that disagree with the badge. This also collapses the special-cased `INSTANCE_MICRO_SPECS` fallback into the existing `getAvailableComputeOptions` helper (which already provides micro/nano fallbacks). The nano UX text ("Shared / Up to 0.5 GB") is preserved by switching that JSX branch to key on `computeSize === 'nano'`. ## Out of scope - `useProjectAddonUpdateMutation` does not invalidate `projectKeys.detail`. That's hygiene worth doing later, but project-detail has a 30s `staleTime` and the resize already drives 5s polling via the `RESIZING` status path, so the badge refreshes naturally and this fix doesn't depend on it. ## Test plan - [ ] Hover the compute badge on a project at each compute size (nano, micro, small, ..., 16xlarge) and confirm CPU and memory rows match the badge. - [ ] Resize a project from micro → large; on completion, confirm the hover card shows large specs (no transient micro values). - [ ] Open the dashboard for a free-tier project on micro that has no `compute_instance` entry in `selected_addons` and confirm the card still shows micro specs (i.e. `getAvailableComputeOptions` micro fallback is engaged). - [ ] Confirm the "Unlock more compute" CTA still appears for non-highest sizes and disappears at the highest size.
This commit is contained in:
@@ -4,14 +4,12 @@ import { Button, cn, HoverCard, HoverCardContent, HoverCardTrigger, Separator }
|
||||
import { ComputeBadge } from 'ui-patterns/ComputeBadge'
|
||||
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
|
||||
|
||||
import { getAddons } from '@/components/interfaces/Billing/Subscription/Subscription.utils'
|
||||
import { getAvailableComputeOptions } from '@/components/interfaces/DiskManagement/DiskManagement.utils'
|
||||
import { ProjectDetail } from '@/data/projects/project-detail-query'
|
||||
import { useOrgSubscriptionQuery } from '@/data/subscriptions/org-subscription-query'
|
||||
import { useProjectAddonsQuery } from '@/data/subscriptions/project-addons-query'
|
||||
import { ProjectAddonVariantMeta } from '@/data/subscriptions/types'
|
||||
import { ResourceWarning } from '@/data/usage/resource-warnings-query'
|
||||
import { getCloudProviderArchitecture } from '@/lib/cloudprovider-utils'
|
||||
import { INSTANCE_MICRO_SPECS } from '@/lib/constants'
|
||||
import { useTrack } from '@/lib/telemetry/track'
|
||||
|
||||
export const ChevronsUpAnimated = () => (
|
||||
@@ -76,23 +74,14 @@ export const ComputeBadgeWrapper = ({
|
||||
{ projectRef },
|
||||
{ enabled: open }
|
||||
)
|
||||
const selectedAddons = addons?.selected_addons ?? []
|
||||
|
||||
const { computeInstance } = getAddons(selectedAddons)
|
||||
const computeInstanceMeta = computeInstance?.variant?.meta
|
||||
|
||||
const meta = (
|
||||
computeInstanceMeta === undefined && computeSize === 'micro'
|
||||
? INSTANCE_MICRO_SPECS
|
||||
: computeInstanceMeta
|
||||
) as ProjectAddonVariantMeta
|
||||
|
||||
const availableCompute = addons?.available_addons.find(
|
||||
(addon) => addon.name === 'Compute Instance'
|
||||
)?.variants
|
||||
|
||||
const highestComputeAvailable = availableCompute?.[availableCompute.length - 1].identifier
|
||||
// Derive cores/memory from the same source as the badge (infra_compute_size) by looking up
|
||||
// the matching variant in available_addons. Sourcing from selected_addons can drift out of
|
||||
// sync with infra_compute_size and produce a card that contradicts its own badge.
|
||||
const computeOptions = getAvailableComputeOptions(addons?.available_addons ?? [], cloudProvider)
|
||||
const meta = computeOptions.find((variant) => variant.identifier === `ci_${computeSize}`)?.meta
|
||||
|
||||
const highestComputeAvailable = computeOptions[computeOptions.length - 1]?.identifier
|
||||
const isHighestCompute = computeSize === highestComputeAvailable?.replace('ci_', '')
|
||||
|
||||
const { data, isPending: isLoadingSubscriptions } = useOrgSubscriptionQuery(
|
||||
@@ -161,7 +150,12 @@ export const ComputeBadgeWrapper = ({
|
||||
) : (
|
||||
<>
|
||||
<div className="flex flex-col gap-1">
|
||||
{meta !== undefined ? (
|
||||
{computeSize === 'nano' ? (
|
||||
<>
|
||||
<Row label="CPU" stat="Shared" />
|
||||
<Row label="Memory" stat="Up to 0.5 GB" />
|
||||
</>
|
||||
) : meta !== undefined ? (
|
||||
<>
|
||||
<Row
|
||||
label="CPU"
|
||||
@@ -169,13 +163,7 @@ export const ComputeBadgeWrapper = ({
|
||||
/>
|
||||
<Row label="Memory" stat={`${meta.memory_gb ?? '-'} GB`} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{/* meta is only undefined for nano sized compute */}
|
||||
<Row label="CPU" stat="Shared" />
|
||||
<Row label="Memory" stat="Up to 0.5 GB" />
|
||||
</>
|
||||
)}
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user