Display tax information in the upcoming invoice breakdown.
- Show a "Tax" line item with amount and rate tooltip when tax is
successfully calculated
- Show a warning row when tax estimation fails, prompting users to
verify their billing address
- Update Current Costs and Projected Costs tooltips to indicate whether
tax is included or could not be estimated
## Test plan
- [ ] Verify tax row appears with correct amount
when `tax_status` is `calculated`
- [ ] Verify tax rate percentage shows in the tooltip (e.g., "Estimated
tax at 10%...")
- [ ] Verify warning row appears when `tax_status` is `failed`
- [ ] Verify no tax row appears when `tax_status` is `not_applicable`
- [ ] Verify "Applicable tax included." appears in Current/Projected
Costs tooltips when tax is calculated
- [ ] Verify "Tax could not be estimated and is not included." appears
in tooltips when tax fails
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Upcoming invoices now include tax details and a tax status.
* Billing breakdown shows projected tax and conditionally displays
projected totals excluding tax when applicable.
* If tax estimation fails, a “Tax — Could not be estimated” row appears
and totals reflect the failure.
* Added "Stripe Projects" as a billing partner option and clarified that
projected amounts may be explicitly null.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Problem
We'd like to update react to `19` but many of our dependencies don't
support it.
## Solution
Update those dependencies. This PR focuses on `react-hook-form`
## How to test
Play with some forms, especially those that use arrays of values
(database/enumerated types for instance) and the highly dynamic ones
(auth providers for instance)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
* **Chores**
* Bumped the form-handling library version across apps and packages for
improved compatibility and stability.
* **Refactor**
* Improved component form typings and generics in the studio to increase
type safety and reduce potential runtime issues.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Upgrade vite and vitest to their latest major versions across the
monorepo, along with related packages.
**Changed:**
- `vite` catalog: `^7.3.2` → `^8.0.8` (Rolldown replaces esbuild/Rollup)
- `vitest` catalog: `^3.2.0` → `^4.1.4`
- `@vitejs/plugin-react`: `^4.3.4` → `^6.0.1`
- `@vitest/coverage-v8`: `^3.2.0` → `^4.1.4`
- `@vitest/ui`: `^3.2.0` → `^4.1.4`
- `vite-tsconfig-paths`: `^4.3.2` / `^5.1.4` → `^6.1.1`
**Pinned to vite 7:**
- `apps/lite-studio` — `@react-router/dev` hasn't declared vite 8
support yet
- `blocks/vue` — Nuxt plugins (`vite-plugin-inspect`, `vite-dev-rpc`,
`vite-hot-client`, `vite-plugin-vue-tracer`) haven't declared vite 8
support yet
**Test fixes for vitest 4 breaking changes:**
- **`apps/studio/lib/api/snippets.utils.test.ts`** — Replaced
`vi.mock('fs/promises')` automock with an explicit factory. Vitest 4's
automocking doesn't create mock functions for getter-based exports on
Node built-ins, so `mockedFS.access.mockResolvedValue` etc. were
`undefined`.
- **`apps/studio/lib/api/self-hosted/functions/index.test.ts`** —
Changed `mockReturnValue` to `mockImplementation(function() { ... })`
for a constructor mock. Vitest 4 no longer allows `mockReturnValue` when
the mock is called with `new`.
- **`apps/studio/tests/pages/api/mcp/index.test.ts`** — Changed arrow
function to regular `function` in `mockImplementation` for
`StreamableHTTPServerTransport`. Arrow functions can't be constructors,
and vitest 4 now enforces this.
- **`packages/ui-patterns/vitest.setup.ts`** — Changed `ResizeObserver`
mock from arrow function to regular `function` for the same constructor
enforcement reason. This was crashing Radix popover rendering in jsdom.
## To test
- `pnpm test:studio` — all 226 test files should pass
- `pnpm --filter ui-patterns vitest run` — all 183 tests should pass
- `pnpm --filter www test -- --run` — all 19 tests should pass
- `pnpm --filter ui vitest run` — all tests should pass
- `pnpm --filter dev-tools vitest run` — all tests should pass
- `pnpm --filter ai-commands vitest run` — all tests should pass
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Standardized and updated development tooling versions and version
sources for consistent installs across the repo (Vite, Vitest,
vite-tsconfig-paths and related plugins/catalog entries).
* **Tests**
* Improved test mocks and typings (updated mock
factories/implementations and tightened spy/type assertions) to increase
test reliability and compatibility with updated tooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
## Problem
When a project is paused, in a failed state, or about to be deleted,
users have no obvious way to take a logical backup of their data before
proceeding. This is particularly risky at deletion time — once deleted,
data is gone.
## Solution
Introduce a new `LogicalBackupCliInstructions` component that surfaces
ready-to-run `supabase db dump` commands pre-filled with the project's
direct connection details.
### Where it appears
| State | How |
|---|---|
| Project paused (restorable) | Inline in `ProjectPausedState` with a
note to resume first |
| Pause failed | Dialog via "Download backup" button when no backup is
available |
| Restore failed | Dialog via "Download backup" button when no backup is
available |
| Delete project modal | Inline in `DeleteProjectModal` for all plans |
Not shown in `PauseDisabledState` (project paused 90+ days, compute
stopped — `pg_dump` would fail anyway).
### What the component does
- Fetches the project's direct connection settings via
`useProjectSettingsV2Query`
- Builds a connection URI with a `[YOUR-PASSWORD]` placeholder (password
is never stored or displayed)
- Shows three shell commands to dump roles, schema, and data separately
— mirroring the [logical backup
docs](https://supabase.com/docs/guides/platform/backups)
- Optionally shows a **Reset database password** button (gated on
`UPDATE projects` permission); shown in the paused state, hidden
elsewhere via `showResetPassword={false}`
- Includes inline guidance to percent-encode special characters in the
password
### Shell safety
The generated `--db-url` values are wrapped in single quotes to prevent
shell metacharacter expansion when users paste and run the commands.
`npx supabase login` is intentionally omitted — the `--db-url` flag
authenticates directly against Postgres and does not require a Supabase
account.
### Backup button behaviour in failed states
The "Download backup" button in `PauseFailedState` and
`RestoreFailedState` now always stays enabled:
- **Backup available** — downloads immediately (unchanged)
- **No backup / physical backups** — opens a dialog with CLI
instructions instead of silently failing
## How to test
**Delete project flow**
1. Open any project → Settings → General → Delete project
2. Verify the CLI backup section appears with the project's host, port,
user, and db name pre-filled
3. Verify no Reset database password button is shown
**Paused project**
1. Open a paused project (`ProjectPausedState`) — verify CLI
instructions appear with the "Your project must be resumed before
running these commands." note
2. Open a project paused for 90+ days (`PauseDisabledState`) — verify
CLI instructions do not appear
**Failed states**
1. Simulate a pause-failed or restore-failed state
2. If a downloadable backup exists — "Download backup" downloads it
directly
3. Block the backup API or use a project with physical backups —
"Download backup" should open the CLI instructions dialog
**Error state**
1. Block the project settings API call (DevTools → Network → block
request)
2. Verify an error message appears with a link to Database settings
3. Verify a loading skeleton shows while the request is in flight
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Problem
The "Healthy / Unhealthy" badge on the Observability overview was
alarming — showing **UNHEALTHY** even when every bar in the chart looked
fine. Two root causes:
1. **The threshold is aggressive.** Any period where the aggregate error
rate is ≥ 1% flips the badge to "Unhealthy", even if that 1% came from a
short burst that is visually indistinguishable in the chart.
2. **Period-wide aggregation hides spikes.** The badge status is
computed over the entire selected time window (e.g. 24 h). A 5-minute
spike at 20% errors diluted across 24 h of mostly-clean traffic can push
the aggregate just over 1%, triggering "Unhealthy" while all chart bars
look green.
The badge wording ("Unhealthy") also implies a current service problem,
whereas the underlying metric is a historical aggregate — making it easy
to misread.
## Change
Remove the badge entirely. The per-row error/warning rate indicator
(e.g. `● 1.34% errors`) already surfaces the key signal without the
alarming label, and the bar chart lets users see the actual shape of
traffic over time.
## On spike visibility in charts
The charts already use **COUNT per time bucket** (not averages), so
individual bars faithfully represent event volume. The bucket
granularity does compress spikes for longer windows (hourly buckets for
1–3 day views, daily for 7-day), but that's a separate concern from the
badge. If we want to surface burst detection in the future, a better
approach would be per-bucket threshold highlighting rather than a single
period-wide badge.
https://claude.ai/code/session_01E1ejWyuR9BV4qcTyiGGVVY
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Removed the service health status indicator from the Service Health
Table.
* **New Features**
* Replaced per-row bar charts with a line chart showing error/warning
rates alongside OK series.
* Added a centered "No data" placeholder when chart data is empty and
preserved click interactions on chart points.
* Y-axis values now display as percentages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude <noreply@anthropic.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
This enables the user to restart an unhealthy project as opposed to
pausing and reactivating.
cc @GaryAustin1
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added detection and dedicated UI for unhealthy projects with restart
capability.
* Enabled automatic recovery monitoring that dismisses unhealthy state
once the project recovers.
* **Bug Fixes**
* Updated pause button to display appropriate message when project is
unhealthy.
* Extended restart functionality to support unhealthy project states.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
This is a follow up for both our classic and scoped PAT's to add events
for tracking created and deleted.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Enhanced telemetry for access token creation and removal.
* Creation events now include token type (classic or scoped), expiry
setting, scope/resource access and permission counts when applicable.
* Removal events now include token type (classic or scoped).
* Instrumentation added across token creation and deletion flows to
improve analytics and auditing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
When users have enabled a SMS hook, they can't update the TOPT test
values anymore.
This is because `formik` sent disabled inputs values in the form payload
while `react-hook-form` correctly does not.
## Solution
Make the inputs read only instead of disabled
## How to test
- Enable SMS auth
- Add a SMS hook
- Update the SMS auth settings
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Improvements**
* Authentication provider form fields now use read-only mode instead of
being disabled, preserving focus and interaction while preventing edits
across text, secret, multiline, numeric, select, boolean, and datetime
inputs.
* A new optional read-only prop was added to form fields for consistent
behavior.
* **Fixes**
* Initial form values recalculation was corrected so they update
reliably when the selected provider changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes#44873
When creating a new cron job, `getDatabaseCronJob` is called to check if
the name already exists. If that call throws (network error, DB
connection issue), the catch block shows an error toast but doesn't
return. Execution falls through to `upsertCronJob`, creating the job
without validating name uniqueness.
The fix adds `return` in the catch block so the mutation doesn't fire
after a failed validation check.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed cron job validation error handling to properly halt processing
when name validation fails and display appropriate error feedback.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
Closes#44872
The "Empty organization" admonition in the subscription upgrade dialog
checks `.length === 5` instead of `.length === 0`. The warning text says
"This organization has no active projects" but only shows for orgs with
exactly 5 active projects.
Introduced in #44494 (b9e83b25).
The adjacent `.length === 1` check for the single-project note is
correct, confirming this is a count comparison that should be `0`.
Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
Removes the "New" banner from the email notification templates section
as the features has been GA-ed for ~6 months now.
<img width="1844" height="758" alt="CleanShot 2026-04-15 at 10 30 33@2x"
src="https://github.com/user-attachments/assets/4415f651-7274-4565-8e2d-4a66f8bbd100"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Removed the security notifications acknowledgement feature from the
email templates interface, including the dismissible notification tip
and associated state management.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Reorder AddPaymentMethodForm and PaymentMethodSelection to use a dry run
validation → Stripe payment setup → real update flow:
- Validate address and tax ID via `dry_run: true` before touching Stripe
- Proceed with Stripe payment method creation / 3DS only if validation
passes
- Persist the customer profile update with dry run disabled after Stripe
succeeds
- Add `dry_run` support
to `useOrganizationCustomerProfileUpdateMutation`
- Add `getFormValues()` to `PaymentMethodElementRef` to read address and
tax ID form state
- Delete the now-unused `organization-tax-id-update-mutation.ts`
## Test plan
### Adding a Payment Method
From the billing dashboard `/org/_/billing`:
- [ ] Add a payment method with a valid tax ID: should dry-run
validate, then create the payment method via Stripe, then persist the
billing profile
- [ ] Add a payment method with an invalid tax ID: should show a
validation error from the dry run and not proceed to Stripe payment
setup
- [ ] Add a payment method with the "primary billing address" checkbox
unchecked: should skip the customer profile update entirely and only
create the payment method
- [ ] Add a payment method where Stripe 3DS fails: billing profile
should not be persisted (only the dry run ran)
### Credit Top Up
- [ ] Top up credits with a new payment method and valid tax ID: should
dry-run validate, then create the payment method, then process the
top-up
- [ ] Top up credits with a new payment method and invalid tax ID:
should show a validation error from the dry run and not proceed to
Stripe payment method creation
### Plan Upgrade
- [ ] Upgrade plan with a new payment method and valid tax ID: should
dry-run validate before creating the payment method
- [ ] Upgrade plan with a new payment method and invalid tax ID: should
show a validation error and not proceed to Stripe
- [ ] Upgrade plan with an existing payment method: should proceed
without dry-run validation
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
This connects the Advisor from the splinter repo. Below are the list of
changes:
- Register advisor which should appear in both the legacy Advisors and
Advisors sidebar.
- Adds a "Dismiss" button to the admonition inside the bucket view.
- Makes the check for select policy on public buckets tiny bit
stricter/truer.
This is awaiting the [PR](https://github.com/supabase/splinter/pull/152)
in splinter going in!
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a security lint that flags public storage buckets allowing
listing, with a direct "View bucket" link.
* Users can dismiss public-bucket warnings per project+bucket for 14
days via a Dismiss button.
* **Improvements**
* Tightened policy detection to better target bucket-scoped select
policies and avoid unrelated matches.
* **Telemetry**
* Added events for policy removal and dismiss-button clicks.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Call the new `POST /platform/organizations/preview-creation` endpoint
when creating an organization on a paid plan to show a tax breakdown
before submission
- Preview is triggered reactively when the user completes the billing
address in the Stripe AddressElement (debounced, same pattern as
subscription upgrades)
- Displays plan price, tax line (with percentage), and total due today -
hides the plan price row when there's no tax adjustment
## Test plan
- [ ] Create a new org on the Free plan - no preview should appear
- [ ] Create a new org on Pro/Team - fill in billing address with all
fields including name
- [ ] Verify tax preview appears after address is complete (1s
debounce)
- [ ] Verify tax line shows for taxable jurisdictions (NY Zip Code
10001), hidden for non-taxable
- [ ] Verify plan price row is hidden when total equals plan price (no
tax)
- [ ] Change address country - verify preview updates
- [ ] Add a tax ID - verify preview updates
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Pricing preview during organization signup that shows plan price
differences, tax details (rate/amount or estimation failure), and “Total
due today.”
* Preview updates reactively based on selected plan and spend cap (PRO
without spend cap treated as PAYG) and appears only for paid plans after
preview initialization.
* Debounced billing address and tax ID input collection for accurate
previews; panel opacity reduced while fetching.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## TL;DR
fixes an inconsistent UI state where the image transformations toggle
could appear enabled + blur
even when the feature is unavailable for that account
## ex:
| Before | After |
| --- | --- |
| enabled and blurred | disabled and blurred |
| <img width="1295" height="389" alt="Before: image transformations
toggle appears enabled while blurred"
src="https://github.com/user-attachments/assets/2f9617b3-9f45-4cdd-8ba7-a360e1ba9754"
/> | <img width="1316" height="386" alt="After: image transformations
toggle appears disabled and blurred"
src="https://github.com/user-attachments/assets/f6be26fd-1390-49c9-b30c-880344eaeca8"
/> | |
## ref:
- closes https://github.com/supabase/supabase/issues/44844
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed the image transformation toggle so it visually reflects both the
user's entitlement and the saved setting, ensuring the control
accurately shows when the feature is available and enabled.
* Preserved the existing disabled behavior for users without access or
update rights so functionality remains unchanged.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
We currently have 2 libraries for schema validation: `yup` that was used
with `formik` and `zod` which is now the preferred one.
## Solution
- Migrate to `zod`
- Fix validation isn't applied on email template form
- Fix `react-hook-form` form state usage
No visual changes.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Switched form validation to a unified Zod-based approach across
authentication UIs.
* **Improvements**
* Template editor and email templates now validate via provided Zod
schemas.
* SMTP and captcha settings receive conditional validation, improved
numeric handling, and clearer required-field behavior.
* Validation import/style consistency tidied.
* **Bug Fixes**
* Consistent dirty-state detection so Save/Cancel visibility and
enabled/disabled behavior are reliable across auth forms.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Context
Have Branching 2.0 as the default behaviour + remove it from feature
preview
Behaviour should match staging / prod if branching 2.0 feature preview
is toggled on
## To test
- [ ] Test branching flow in general for any oddities
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Removed the Branching 2.0 preview and cleared its persisted preview
setting; branching UI and branch editing are now available without
opt‑in.
* Simplified branch management flows and empty states by removing
preview-dependent conditions and tooltips.
* Made GitHub branch sync optional in create/edit forms and simplified
validation and submit behavior.
* "Create merge request" and related branch actions now render
consistently across the UI.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Remove `@headlessui/react` as a direct dependency from both
`apps/studio` and `packages/ui`. It's incompatible with React 19 (at the
pinned v1 version) and overlaps with our existing Radix/shadcn
primitives.
The only usage was the `<Transition>` component in 3 files + a dead
`Overlay` component in `packages/ui`.
**Removed:**
- `@headlessui/react` from `apps/studio/package.json` and
`packages/ui/package.json`
- Dead `packages/ui/src/lib/Overlay/` directory (not exported or
imported anywhere)
**Changed:**
- `ChooseFunctionForm.tsx` — replaced `Transition` with a shadcn
`Accordion` for the "View definition" toggle
- `FileExplorerColumn.tsx` — replaced `Transition` with `framer-motion`
`AnimatePresence` for drag-over overlay
- `PreviewPane.tsx` — removed `Transition` wrapper entirely (wasn't
visually animating on prod), replaced with simple conditional render
Note: `@headlessui/react` will remain in `pnpm-lock.yaml` as a
transitive dependency of `@graphiql/react` and
`@graphiql/plugin-doc-explorer` — that's expected and not something we
control.
## To test
- **Triggers page** (`/dashboard/project/_/database/triggers`): Create
or edit a trigger, click "Choose a function" to open the side panel.
Click "View definition" on a function row — the SQL definition should
expand/collapse with a smooth height animation. Clicking the row itself
should still select the function.
- **Storage explorer**
(`/dashboard/project/_/storage/buckets/<bucket>`): Navigate into a
folder, drag a file over the column — the drag overlay should fade
in/out smoothly.
- **Storage file preview**
(`/dashboard/project/_/storage/buckets/<bucket>`): Click on a file — the
preview pane should appear on the right (no animation, same as current
prod behaviour).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Replaced several transition wrappers with new animation/mounting
behavior for overlays, preview panes, and drag-over UI to improve
consistency and responsiveness.
* Swapped the function-definition toggle for an Accordion and updated
click handling to prevent accidental row selection.
* Removed the legacy overlay component, its context, and associated
overlay styling.
* **Chores**
* Removed HeadlessUI dependency from project packages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
Previously, when a user performed a client-side navigation to the
passkeys page, the settings would not be shown despite passkeys being
enabled. This was a result of the stale form data being passed as the
initial values.
This PR removes the `useEffect` in favour of the `values` prop.
## Summary
- The `availableTaxIds` memo and
preselect `useEffect` in `NewPaymentMethodElement` depended on the
full `stripeAddress` object. Since the
Stripe `AddressElement` fires `onChange` on every keystroke (org name,
street, city, etc.), this created a new object reference each time,
causing the memo to recompute and the effect to re-fire, which
cleared `tax_id_value` to `''`.
- Narrowed both dependencies to `addressCountry`, so the tax ID is only
reset when the billing country actually changes.
- Used a `prevCountryRef` to distinguish initial mount from country
changes: on mount we preserve any existing `currentTaxId`, on country
change we always reset to the new country's default.
## Test plan
- [ ] New org flow: select paid plan, check "purchasing as a business",
fill in tax ID value, type in org name / address fields - tax ID should
persist
- [ ] New org flow: change country - tax ID selector should update to
the new country's default
- [ ] Plan upgrade flow: open upgrade dialog with existing tax ID, type
in address fields - tax ID should persist
- [ ] Plan upgrade flow: change country - tax ID should reset to new
country's default
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Tax ID handling is now country-aware and updates correctly when the
billing country changes.
* Address name and country persist across form remounts, preventing
accidental resets when toggling purchase mode.
* Tax ID selection/reset logic refined to avoid overwriting existing tax
IDs on initial load and to choose appropriate defaults after country
changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Increases the minimum credit top-up to $300.
### Testing
- Head to `/org/_/billing`
- Assert that you're not able to do a top-up for less than $300
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Updates**
* Increased the minimum credit top-up amount from 100 USD to 300 USD.
Form defaults and placeholder text updated to reflect the new minimum.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **New Features**
* Added Passkeys configuration page to manage WebAuthn relying-party
settings and enable/disable passkey auth.
* Added a Beta "Passkeys" item to the Auth settings menu.
* Enabled saving passkey-related authentication parameters.
* **Tests**
* Added test coverage to ensure the Passkeys menu appears or is omitted
based on feature flags.
* **Chores**
* Removed an unused import to tidy the code.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: fadymak <dev@fadymak.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
## TL;DR
fixes a cron job parsing issue where the `HTTP request body`
could include content from a later argument when editing an existing job
## ex:
<table>
<tr>
<td valign="top" width="50%">
<strong>Before:</strong>
<br />
when editing some existing <code>net.http_post(...)</code> cron jobs,
studio populated the <code>HTTP Request Body</code> field with extra
content from the following argument instead of only the body value
<br /><br />
<img width="532" height="108" alt="before"
src="https://github.com/user-attachments/assets/eccf1f6b-3e4c-4d6d-8611-e144794fac8f"
/>
</td>
<td valign="top" width="50%">
<strong>After:</strong>
<br />
now it stops parsing the body at the correct boundary, so the <code>HTTP
Request Body</code> field only contains the intended body content
<br /><br />
<img width="165" height="69" alt="after"
src="https://github.com/user-attachments/assets/92f5cf44-ad8c-409c-a0f5-5b9c1664ccd0"
/>
</td>
</tr>
</table>
added a smol regress test aswell :)
## ref:
- closes https://github.com/supabase/supabase/issues/44794
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed parsing of cron job commands with quoted JSON body parameters
and additional arguments to ensure headers and timeout parameters are
correctly recognized.
* **Tests**
* Added test case to validate correct parsing of complex cron job
command configurations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Follow-up to #44801 — fixes the data layer issue flagged in the review
comment.
The previous fix handled the display crash (`table.columns.map` when
`columns` is undefined) but left the edit/save path broken. When a
Stripe wrapper table has `null` columns from the DB (e.g. `jsonb_agg`
returns `NULL` when there are no rows), `formatWrapperTables` was
forwarding that `null` directly into the react-hook-form state. The Zod
`tableSchema` declares `columns` as a non-optional `z.array(...)`, so
the zodResolver rejected the form silently on save — the Save button
appeared to do nothing with no error shown to the user.
## Change
In `Wrappers.utils.ts`, `formatWrapperTables`:
```ts
// before
columns: table.columns,
// after
columns: table.columns ?? [],
```
This ensures the form is always initialized with a valid array,
satisfying the Zod schema and allowing saves to proceed normally.
---
Slack thread:
https://supabase.slack.com/archives/C063LNYJJKS/p1776067210776939?thread_ts=1776067141.988569&cid=C063LNYJJKShttps://claude.ai/code/session_01N6nyTggA68yktWg4b46ssL
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed an issue where wrapper tables could fail to display correctly
when column data was missing or invalid.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude <noreply@anthropic.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Supabase Dashboard - Connect
## What is the current behavior?
On the new `<ConnectSheet />` component their is no deep linking like
the previous `<Connect />` component
## What is the new behavior?
Deep linking added onto framework and other options, Example local
links:
http://localhost:8082/project/default?showConnect=true&connectTab=framework&framework=nextjs&using=pageshttp://localhost:8082/project/default?showConnect=true&connectTab=mcp&mcpClient=goose
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Connect Sheet supports URL query parameters for pre-configuring
connection settings (framework, using, method, type, mcpClient).
* Legacy tab identifiers are accepted for compatibility.
* **Improvements**
* Opening, switching, and closing the Connect Sheet now more reliably
syncs and clears related parameters to avoid stale state.
* **Tests**
* Added end-to-end tests covering deep-linking, legacy aliases, and
parameter clearing on close/mode change.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Summary
- Adds null check for `table.columns` in `CreateWrapperSheet` and
`EditWrapperSheet` to prevent runtime errors when columns are undefined
- Fixes TypeError: "can't access property 'map', e.columns is undefined"
on `/dashboard/project/[ref]/integrations/stripe_wrapper/overview`
## Problem
When viewing the Stripe wrapper integration overview page, users
encounter a JavaScript error because `table.columns` can be undefined in
some cases, but the code attempts to call `.map()` on it directly.
## Solution
Changed `table.columns.map(...)` to `(table.columns ?? []).map(...)` to
safely handle cases where columns is undefined by defaulting to an empty
array.
## Test plan
- [ ] Navigate to
`/dashboard/project/[ref]/integrations/stripe_wrapper/overview` with a
wrapper that has tables with undefined columns
- [ ] Verify no JavaScript error occurs
- [ ] Verify tables without columns display correctly (showing "Columns:
" with nothing after)
---
Slack thread:
https://supabase.slack.com/archives/C063LNYJJKS/p1776067210776939?thread_ts=1776067141.988569&cid=C063LNYJJKShttps://claude.ai/code/session_01N6nyTggA68yktWg4b46ssL
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed a stability issue in wrapper integrations where missing or
undefined column information from foreign tables could cause display
problems. The interface now safely handles these edge cases with
improved spacing and more reliable column rendering, ensuring consistent
and predictable presentation of integration data regardless of data
availability or table configuration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude <noreply@anthropic.com>
## Problem
We currently have 2 libraries for schema validation: `yup` that was used
with `formik` and `zod` which is now the preferred one.
## Solution
Migrate the MFA settings form to use `zod`.
No visual changes.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* MFA settings forms now use stronger, consistent schema validation with
numeric input coercion and improved typing for more reliable form
behavior.
* Simplified form reset/synchronization for more predictable state
updates.
* **Bug Fixes**
* MFA update requests now send only intended fields.
* Fixed Enhanced MFA Security “Save changes” button to show the correct
loading state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
- Remove the outdated GitHub discussion feedback link from the "Queue
table operations" dashboard setting
- Clean up the unused `discussionsUrl` prop and related rendering logic
from `DashboardToggle`
Closes FE-2973
## Test plan
- [ ] Verify the "Queue table operations" toggle in Account >
Preferences no longer shows a "Give feedback" link
- [ ] Verify the "Edit entities in SQL" toggle still renders correctly
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Refactor**
* Removed the feedback link from dashboard settings toggles. The "Give
feedback" option is no longer available in the preferences interface.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## TL;DR
fixes the Auth Users provider badge for Web3 users so it reflects the
actual enabled provider state
## problem
Web3 authenticated users appeared `Disabled` in `Authentication -> Users
-> Provider Information`
This happened because the user provider is stored as `web3`, while the
actual enabled state is chain specific (`solana` / `ethereum`)
<p align="left">
<img width="443" height="281" alt="Image"
src="https://github.com/user-attachments/assets/4918cbdb-75a4-4bd9-b9e5-511dcced5447"
/>
</p>
## solution
When the provider is `web3`, resolve the enabled badge from
`raw_user_meta_data.custom_claims.chain` (saw that in the payload while
testing) and map it to the correct Web3 config flag:
- `solana` -> `EXTERNAL_WEB3_SOLANA_ENABLED`
- `ethereum` -> `EXTERNAL_WEB3_ETHEREUM_ENABLED`
<p align="left">
<img width="148" height="43" alt="image"
src="https://github.com/user-attachments/assets/9d21b8fc-da93-4dcd-9cdb-5c0eacef2a27"
/>
</p>
## ref:
- closes https://github.com/supabase/supabase/issues/44724
- closes https://github.com/supabase/supabase/issues/39568
- closes https://github.com/orgs/supabase/discussions/39563
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Corrected web3 provider enabled status detection by mapping user chain
configuration to provider settings.
* **Tests**
* Added test coverage for web3 user enabled status display.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
- Consolidate tax ID saving into the `PUT
/organizations/{slug}/customer` endpoint instead of using a
separate `/tax-ids` endpoint
## Test plan
### Updating billing information
From the billing dashboard`/org/_/billing`:
- [ ] Manually test updating billing address + tax ID from org billing
settings - single API call should save both
- [ ] Clear the Tax ID in the org, save and assert that it has been
deleted
- [ ] Modify all the fields in the address form, including TaxID. Click
"Cancel" and assert that everything has returned to the previous values.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Billing address and tax ID updates are now sent in a single update
operation.
* Error messaging for billing updates consolidated into a single failure
notification.
* Tax ID handling clarified: you can clear tax ID explicitly or leave it
unchanged; omitting address fields no longer overwrites existing
address.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Simplify the Connect modal for Multigres/High Availability projects.
Pooling is always on for these projects, so the connection method
distinction doesn't apply.
**Removed:**
- Connection Method selector (Direct/Transaction/Session) for HA
projects
- IPv4 add-on panel for HA projects
- Pooler badge (Shared/Dedicated) for HA projects
**Changed:**
- "Type" label renamed to "Connection Type" for HA projects
- Default connection method set to `transaction` (instead of `direct`)
for HA projects
Non-HA projects are completely unaffected.
## To test
- Open Connect sheet → Direct tab on a **non-HA project** — verify
everything looks the same as before
- Open Connect sheet → Direct tab on an **HA project** — verify:
- No Connection Method radio selector
- Label reads "Connection Type" instead of "Type"
- No IPv4 status panel
- No pooler badge
- Connection string displays correctly
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Improvements**
* Connection UI now adapts for high-availability projects: hides pooler
options and IPv4 status, and updates the connection type label for
clarity.
* **Tests**
* Added tests covering connection configuration behavior when a project
is high-availability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
## Problem
The input groups components introduced in #44282 don't have the
validation attributes when invalid. This hurts accessibility and also
break the design:
<img width="1730" height="324" alt="image"
src="https://github.com/user-attachments/assets/a3fb8d86-f3a8-46bb-aa53-d0599c11f056"
/>
## Solution
This is because the wrapper `<FormControl_Shadcn_>` passes the
validation props to its direct child.
The solution is to avoid applying them on the `<InputGroup>` and to
apply them manually on the inputs.
I also fixed a small accessibility issue by moving the addon texts after
the input so that screen readers announce them in the correct order. No
visual change for this
<img width="587" height="158" alt="image"
src="https://github.com/user-attachments/assets/1f8858ea-6659-45f9-964e-8c43a7fe14ba"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Unified numeric input layout by moving unit labels/suffixes (e.g.,
"seconds", "GB", "%", "connections", "digits", "IOPS", "MB/s", "rows")
to appear after their inputs for a consistent, predictable form
appearance.
* **Accessibility**
* Form controls now expose IDs and ARIA attributes from form context
when available, improving screen-reader descriptions and error
association.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
## Problem
#44677 modified the previous behaviour on callback URLs. It used to
prevent users to remove the URL if only one was provided.
## Solution
Restore the previous behaviour.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed the Remove button behavior for OAuth callback URLs. The button
now only appears when multiple callback URLs are configured, preventing
accidental deletion of the only redirect URI.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
-
[**SUPABASE-APP-E2R**](https://supabase.sentry.io/issues/SUPABASE-APP-E2R):
Guard against undefined entries in notifications array in
`AdvisorButton` (optional chaining on `.some()` callbacks)
-
[**SUPABASE-APP-EBA**](https://supabase.sentry.io/issues/SUPABASE-APP-EBA):
Remove render-time `handleError()` throw in `useEdgeFunctionsDiff` — the
hook already handles missing body data gracefully
-
[**SUPABASE-APP-BVN**](https://supabase.sentry.io/issues/SUPABASE-APP-BVN)
/
[**SUPABASE-APP-BTV**](https://supabase.sentry.io/issues/SUPABASE-APP-BTV):
Guard `localStorage` access in `FeaturePreviewContext` with try-catch,
matching the established pattern in `useLocalStorage.ts` (Safari private
browsing)
-
[**SUPABASE-APP-AV3**](https://supabase.sentry.io/issues/SUPABASE-APP-AV3):
Filter stale folder IDs before passing `expandedIds` to
`react-accessible-treeview` in the SQL editor nav
## Test plan
- [x] Verify AdvisorButton renders without errors when notifications
data has sparse pages
- [x] Verify branch merge page loads when edge function body fetch fails
- [x] Verify feature previews initialize correctly in Safari private
browsing
- [x] Verify SQL editor folder expand/collapse works after deleting a
folder
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Feature preview now falls back safely when browser storage is
unavailable
* Notifications display updated to tolerate missing entries without
errors
* Private snippets navigation no longer preserves expansion state for
removed nodes
* **Refactor**
* Streamlined error aggregation in edge functions diff processing
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
Foreign wrapper forms still use `formik` but we now use
`react-hook-form` everywhere and we'd like to reduce our dependencies.
## Solution
This PR focuses on migrating the OAuth apps form to `react-hook-form`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Reworked the OAuth app publish form to use schema-driven validation
and managed callback URL fields.
* Replaced bespoke URL state/handlers with add/remove field array logic;
consolidated error rendering.
* Submission, loading and preview now reflect real-time form state and
reset correctly when the panel or selection changes.
* **Bug Fixes**
* Improved URL validation to handle localhost cases and optional
HTTPS-only enforcement.
* **Tests**
* Extended URL validation tests to cover localhost, HTTP/HTTPS and
HTTPS-only scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Show OAuth server endpoints in oauth server settings page.
Preview: [OAuth Server
settings](https://studio-staging-git-chore-show-oauth-server-endpoints-supabase.vercel.app/dashboard/project/_/auth/oauth-server)
<img width="1138" height="496" alt="Screenshot 2026-01-09 at 12 00 31"
src="https://github.com/user-attachments/assets/eeca7726-0426-4abe-990d-271b702e4f7b"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added an OAuth endpoints table showing Authorization, Token, JWKS, and
Discovery/OpenID URLs with copy-to-clipboard and a masked preview mode.
* Inline preview of the Authorization URL when an authorization path is
set.
* **Improvements**
* Reorganized OAuth server settings for clearer enable/disable flow,
conditional field visibility, and disable confirmation.
* Dynamic loading of the endpoints table, improved loading skeletons,
layout refinements, and form reset to reflect saved defaults.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Ali Waseem <waseema393@gmail.com>
## Summary
Removes `_DEFAULT` from the publishable key env var name across all
Connect and ConnectSheet framework content, so that e.g.
`NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY` becomes
`NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY`. This matches the docs and sample
apps.
### Connect
- Next.js (App Router)
- Next.js (Pages Router)
- React (Create React App)
- React (Vite)
- Remix
- SolidJS
- SvelteKit
### ConnectSheet
- Next.js (App Router)
- Next.js (Pages Router)
- React (Create React App)
- React (Vite)
- Remix
- SolidJS
- SvelteKit
- Vue.js
- shadcn env step
Resolves FE-2934
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Standardized environment variable names in generated connection/setup
instructions: when a publishable key is present the templates now
reference the publishable env var (e.g.,
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, VITE_SUPABASE_PUBLISHABLE_KEY,
REACT_APP_SUPABASE_PUBLISHABLE_KEY, etc.) with unchanged anon-key
fallback behavior.
* Updated cURL/tab placeholders to reflect the new publishable-key
identifier when hiding keys.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The Connect Sheet install step only listed `@supabase/supabase-js`, but
the generated code for Next.js (app router) and Remix imports from
`@supabase/ssr` – so users following the steps immediately hit import
errors.
**Added:**
- `EXTRA_PACKAGES` map in `connect.schema.ts` – frameworks declare
additional packages on top of the base library install, keyed by
`framework/variant` for granularity (e.g. `nextjs/app` gets
`@supabase/ssr`, `nextjs/pages` does not)
- Install content component appends extras automatically
- Step title pluralises to "Install packages" when extras are present
- Tests for extra packages, variant-specific install commands, and step
titles
**Changed:**
- Next.js steps now branch on `frameworkVariant` so app router and pages
router can have different install steps
- Remix gets an explicit entry in the step tree (previously fell through
to DEFAULT)
## To test
- Open Connect Sheet → Framework → Next.js → App Router
- Install step should say "Install packages" and show `npm install
@supabase/supabase-js @supabase/ssr`
- Switch to Pages Router
- Install step should say "Install package" and show `npm install
@supabase/supabase-js`
- Switch to Remix
- Install step should say "Install packages" and show `npm install
@supabase/supabase-js @supabase/ssr`
- Other frameworks (Vue, SvelteKit, etc.) should be unchanged
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Enhanced package installation guidance to include framework-specific
additional packages (e.g., @supabase/ssr for Next.js App Router and
Remix).
* Installation step labels now accurately reflect the number of packages
being installed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
## Problem
Foreign wrapper forms still use `formik` but we now use
`react-hook-form` everywhere and we'd like to reduce our dependencies.
## Solution
- [x] Write e2e tests for wrappers
- [x] Migrate to `react-hook-form`
## Notes
I tried to cover the 3 cases I identified for foreign wrappers with e2e
tests:
- Add all available tables to a new schema (stripe)
- Add selected tables to a new table (stripe)
- Create dynamic columns (s3 wrapper)
However, they are not exhaustive as I can't test the integration
actually works, only that it was created successfully. Besides, I can't
test the Iceberg wrapper case as it needs actual S3 buckets.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Enhanced column-type selector with searchable combobox, enum support,
icons, and optional recommendation prompts.
* **Refactor**
* Migrated many wrapper/table/editor forms to a schema-driven form
system with stronger validation, dynamic field arrays, and consistent
form controls.
* Updated input field integration to work with the new form control
model.
* **Bug Fixes**
* Improved handling of missing wrapper/error states during wrapper
loading.
* **Tests**
* Added unit tests for form schemas and end-to-end tests for wrapper
creation flows.
* **Chores**
* Removed legacy dynamic-columns component.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Bug fix
## What is the current behavior?
After clicking delete on a project, the `onSuccess` callback
unconditionally redirects to `/org/{slug}` or `/organizations`. If the
user has already navigated away from the project page before the
deletion completes, this causes an unwanted redirect back to the
organizations page.
## What is the new behavior?
The redirect now only happens if the user is still viewing the deleted
project's page (`router.asPath.startsWith(/project/${projectRef})`). If
they've already navigated away, only the success toast is shown.
## Additional context
The Next.js pages router object is mutable, so `router.asPath` reflects
the current URL at callback execution time, not at closure creation
time.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed navigation behavior after project deletion to avoid unnecessary
redirects when you've already navigated away from the deleted project.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
This takes our dialog to review compute upgrade's and gives it a bit
more visual clarity (as it can get confusing). Simplification and clear
communication of what differences there are.
| Before | After |
|--------|--------|
| <img width="663" height="722" alt="Screenshot 2026-04-07 at 16 58 33"
src="https://github.com/user-attachments/assets/dbb699b4-89ad-4172-8c23-e5d1ca5045f8"
/> | <img width="608" height="635" alt="Screenshot 2026-04-08 at 12 28
32"
src="https://github.com/user-attachments/assets/9a4a5952-6049-4cda-86e6-73773f001010"
/> |
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **UI Improvements**
* Redesigned disk review dialog to a stacked "Before/After" layout with
a clear vertical breakdown of changes.
* Replaced badges/tooltips with inline per-line monthly deltas and
explicit summed totals.
* Replica note moved inline; cooldown and throughput explanations
consolidated and more broadly shown when storage type changes.
* Arrow between totals updated and "After" state emphasized.
* **Chores**
* Updated dialog spacing, padding, min-width, confirm button styling,
and dialog wording.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What kind of change does this PR introduce?
Chore / UI consistency fix. Resolves DEPR-418.
## What is the current behavior?
Shortcut hints are still hand-built in several high-traffic Studio
surfaces, which leads to inconsistent rendering and stale
platform-specific markup. Buttons in particular can end up with awkward
spacing and baseline alignment when shortcut labels are inserted
directly into the button text.
## What is the new behavior?
This PR standardises those shortcut hints around `KeyboardShortcut` and
updates the surrounding layout primitives to support that approach more
cleanly.
It includes:
- Design docs
- using `KeyboardShortcut` in the table side-panel `ActionBar`
- replacing hardcoded operation queue button shortcuts in
`OperationQueueSidePanel`
- standardising the command menu trigger shortcut chip and updating the
`LayoutHeader` overrides to match the new DOM shape
- replacing the AI editor empty-state `Cmd/Ctrl + K` hint with
`KeyboardShortcut`
- refining shared shortcut/button primitives so inline shortcuts align
better when used as button accessories
- keeping the SQL utility shortcut work on this branch consistent with
the same shared component approach
| Before | After |
| --- | --- |
| <img width="1454" height="902" alt="CleanShot 2026-03-27 at 15 55
32@2x"
src="https://github.com/user-attachments/assets/3a8de192-3f4c-480b-9d26-9b28becd0ee3"
/> | <img width="1488" height="906" alt="CleanShot 2026-03-27 at 15 29
31@2x-63A17C58-D023-4D3A-9355-6C40A6485328"
src="https://github.com/user-attachments/assets/46ef7f7a-2b8b-4c10-8935-84ca5ad44562"
/> |
| <img width="738" height="328" alt="CleanShot 2026-03-27 at 15 57
07@2x"
src="https://github.com/user-attachments/assets/ad459c41-867d-42f9-a8cb-c936af8326b7"
/> | <img width="726" height="290" alt="CleanShot 2026-03-27 at 15 56
29@2x-ECE4E10F-9693-4ED8-B085-DC436A839F52"
src="https://github.com/user-attachments/assets/95b4bfb4-ec34-4080-8b69-211b5045ca26"
/> |
## Later todo
- [ ] Replace the string-based SQL editor placeholder shortcut in
`SQLEditor` once that placeholder API supports rich content
- [ ] Refactor `CommandOption` to use `KeyboardShortcut` instead of
bespoke platform detection and command-key markup
- [ ] Standardise the remaining DataTable shortcut hints
(`DataTableToolbar`, `DataTableResetButton`, `DataTableFilterCommand`,
`DataTableFilterControlsDrawer`) around `KeyboardShortcut`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Introduced a new KeyboardShortcut component for displaying keyboard
shortcuts with two visual variants (pill and inline).
* Standardized keyboard shortcut indicators across the application
interface for consistent user experience.
* **Bug Fixes**
* Fixed capitalization inconsistencies in button labels and hotkey
settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
The "INSERTED AT (UTC)" column in the Database Migrations UI showed
local time instead of UTC. For a user in Buenos Aires (UTC-3), a
migration timestamped at UTC 08:33:31 would show 05:33:31 in the table.
The tooltip's relative time also showed "in 3 hours" (future) for a
migration that had already run, because the UTC offset was applied in
the wrong direction.
Root cause: `parseMigrationVersion` parsed the version string (format
`YYYYMMDDHHmmss`, which the Supabase CLI generates in UTC) using
`dayjs()` without the UTC flag, so dayjs interpreted the digits as local
time.
## Fix
- Changed `parseMigrationVersion` to use `dayjs.utc()` so the version
string is correctly interpreted as a UTC timestamp.
- Updated the label formatter in `Migrations.tsx` to use
`.utc().format()`, so the displayed time matches the column header
("INSERTED AT (UTC)").
- Added the dayjs UTC plugin setup to the test file and added a
regression test that asserts `toISOString()` returns the correct UTC
time.
## Before
<img width="1102" height="658" alt="CleanShot 2026-04-08 at 12 41 18@2x"
src="https://github.com/user-attachments/assets/5eccdfb1-757c-4794-b24f-6a2c71f483dc"
/>
## After
<img width="1126" height="612" alt="CleanShot 2026-04-08 at 12 42 03@2x"
src="https://github.com/user-attachments/assets/6f3da69f-ace5-4758-b025-b49d8b325034"
/>
## How to test
- Set your browser/OS timezone to something other than UTC (e.g.
America/Buenos_Aires, UTC-3).
- Open the Database Migrations page for a project that has migrations.
- The "INSERTED AT (UTC)" column should show the UTC time matching the
version number digits (e.g. version `20260406083331` should show `06 Apr
2026, 08:33:31`).
- Hover over the timestamp. The tooltip should show the same value for
"UTC", a correctly offset value for your local timezone, and a relative
time that reflects the past (e.g. "3 hours ago", not "in 3 hours").
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Migration timestamps now parsed and displayed in UTC for consistent,
accurate labels; unparsable versions show "Unknown".
* **New Features**
* Improved migration version labeling for clearer, uniformly formatted
date/time shown in the UI.
* **Tests**
* Expanded tests for migration parsing and label formatting; test setup
updated for UTC handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary
- Removes the "API Docs" navigation item from the sidebar and mobile
menu
- Removes the `UI_PREVIEW_API_SIDE_PANEL` feature preview flag since the
feature is fully rolled out
- Makes API docs buttons unconditionally visible across Auth Users,
Storage, Edge Functions, and SecondLevelNav
## Test plan
- [x] `NavigationBar.utils` tests pass (26 tests)
- [x] `FileExplorerHeader` tests pass (6 tests)
- [x] TypeScript compiles with no errors
- [ ] Verify sidebar no longer shows "API Docs" nav item
- [ ] Verify API docs buttons still appear in Auth Users, Storage, and
Edge Functions pages
- [ ] Verify feature preview modal no longer lists "Project API
documentation"
Resolves FE-2759
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* APIDocs button can optionally display a label and use a custom
tooltip.
* **Chores**
* Removed the API docs side-panel feature flag and its localStorage key.
* “API Docs” navigation entry removed; sidebar no longer special-cases
that route.
* Back links and API Docs buttons now render consistently across the app
(no flag gating).
* **Tests**
* Tests updated to stop depending on the removed feature-flag behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Layout shifting due to projects and orgs not fully ready
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved loading state handling in disk management interfaces. UI
elements now properly hide while project and organization data are
loading, preventing incomplete information from displaying prematurely.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
This PR adds support for configuring end-user IP address forwarding to
Supabase Auth, as well as docs explaining the feature.
## What is the current behavior?
These settings don't exist in Studio. Users that wish to enable IP
address forwarding must do so through the management API.
## What is the new behavior?
Users can enable IP address forwarding in Studio directly without
needing to use the management API.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added an "IP Address Forwarding" toggle in Auth rate limit settings as
a separate section with its own Save/Cancel behavior.
* **Documentation**
* Added a guide detailing when/how to forward end-user IPs, how to
enable the setting, required key types, Management API examples, and an
SDK/SSR snippet.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Cemal Kılıç <cemalkilic@users.noreply.github.com>