Files
supabase/apps/studio/data/config/disk-attributes-update-mutation.ts
Jordi Enric 022b510269 fix: centralize compute disk limits data and update documentation (#41242)
https://linear.app/supabase/issue/FE-2226/fix-incorrect-baseline-and-max-iopsthroughput-values

- Centralized compute/disk limits in
packages/shared-data/compute-disk-limits.ts (MB/s, baseline+max
IOPS/throughput) and re-exported from shared-data.
- Hooked Docs compute/disk table into shared data, converted docs
text/table to MB/s baseline/max.
- Removed duplicated compute IOPS/throughput constants from Studio,
Studio now imports shared data.
- Updated Studio disk schema: compute-aware MAX IOPS/throughput
validation (MB/s), defaults computeSize to ci_micro, and gp3/io2 checks
use compute caps.
- Clarified disk update mutation to send throughput as MB/s despite
backend throughput_mbps field name.
- Added tests for compute-size mappings and IOPS helper logic.
- Added Infra ownership for shared compute/disk data in CODEOWNERS.
- Locked zod version via catalog and added zod dep to shared-data.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a reusable Compute Disk Limits table and centralized compute
disk limits dataset for dynamic display.

* **Documentation**
* Replaced static per-size tables with a component-driven MB/s view;
clarified baseline vs. burst behavior and updated guides and
troubleshooting.

* **Bug Fixes**
* Validation and UI guidance now honor compute-size limits for IOPS and
throughput.

* **Tests**
  * Expanded unit tests for sizing, mappings, and edge cases.

* **Chores**
* Published shared-data exports, added a validation schema, pinned a
dependency, and added ownership entries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-03 10:52:42 +00:00

76 lines
2.5 KiB
TypeScript

import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { handleError, post } from 'data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from 'types'
import { configKeys } from './keys'
export const COOLDOWN_DURATION = 60 * 60 * 6
export type UpdateDiskAttributesVariables = {
ref?: string
storageType: 'gp3' | 'io2'
provisionedIOPS: number
throughput?: number // MB/s
totalSize: number
}
// [Joshen] Need to fix this
export async function updateDiskAttributes(updates: UpdateDiskAttributesVariables) {
if (!updates.ref) throw new Error('ref is required')
// NOTE(kamil): This should be expressed in types as discriminated union, but it requires
// reworking of a whole form that provides data to that mutation
const attributes =
updates.storageType === 'gp3'
? {
iops: updates.provisionedIOPS,
// API field name is throughput_mbps (legacy), but values are treated as MB/s in the platform API.
// If the platform switches to MiB/s, convert here before sending.
throughput_mbps: updates.throughput!,
size_gb: updates.totalSize,
type: updates.storageType,
}
: {
iops: updates.provisionedIOPS,
size_gb: updates.totalSize,
type: updates.storageType,
}
const { data, error } = await post('/platform/projects/{ref}/disk', {
params: { path: { ref: updates.ref } },
body: { attributes },
})
if (error) handleError(error)
return data
}
type UpdateDiskAttributesData = Awaited<ReturnType<typeof updateDiskAttributes>>
export const useUpdateDiskAttributesMutation = ({
onSuccess,
onError,
...options
}: Omit<
UseCustomMutationOptions<UpdateDiskAttributesData, ResponseError, UpdateDiskAttributesVariables>,
'mutationFn'
> = {}) => {
const queryClient = useQueryClient()
return useMutation<UpdateDiskAttributesData, ResponseError, UpdateDiskAttributesVariables>({
mutationFn: (vars) => updateDiskAttributes(vars),
async onSuccess(data, variables, context) {
const { ref } = variables
await queryClient.invalidateQueries({ queryKey: configKeys.diskAttributes(ref) })
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
if (onError === undefined) {
toast.error(`Failed to update disk attributes: ${data.message}`)
} else {
onError(data, variables, context)
}
},
...options,
})
}