## Problem
The pipeline wizard in #49243 needs publication, initial sync and
replication settings together on its data step.
## Solution
Compose `PipelineDataSection` from the existing controls and use it in
preview-enabled creation. It includes the publication selector,
initial-sync controls and data advanced settings, including BigQuery
table layout.
This preserves the grouping from #51570. Preview off and editing keep
the existing layout. Validation and creation behaviour stay the same; no
wizard routing is added. Stacked on #51570.
## Review instructions
1. Open the [Pipelines
preview](https://studio-staging-git-dnywh-featpipeline-data-section-supabase.vercel.app/dashboard/project/_/database/pipelines),
select a test project with Pipelines enabled and go to **Database →
Pipelines**. Enable **Pipeline creation wizard** in Feature Previews,
then click **Add pipeline**. Confirm **Data** follows **Destination
connection**, with publication and initial sync above its **Advanced
settings**.
2. Select a publication and change the initial-sync option. For
selected-table options, confirm the publication tables are available.
Click **New publication** in the publication selector and confirm the
existing creation panel opens, then cancel it.
3. Expand **Advanced settings** under **Data**. Confirm replication
settings appear, plus table layout for BigQuery, without connection pool
size, staleness or role. Change **Batch wait time**, collapse and reopen
the accordion, and confirm the value remains. Check desktop and phone
widths. Cancel and discard changes; no credentials or pipeline creation
are needed.
4. Turn the preview off and reopen **Add pipeline**. Confirm the
original layout remains. With the preview on, edit an existing pipeline
and confirm its original layout also remains.
## Problem
The pipeline wizard in #49243 needs connection settings before table
selection.
## Solution
With **Pipeline creation wizard** enabled, rearrange the creation sheet
into destination selection, **Destination connection**, then **Data**.
Group name, region, credentials and connection advanced settings
together. Keep publication, initial sync, replication settings and
BigQuery table layout in the data section.
Preview off and editing keep the existing layout. Validation and
creation behaviour stay the same. This still uses the sheet; no wizard
routing is added. Stacked on #51568.
| Feature Preview Off | Feature Preview On |
| --- | --- |
| <img width="1272" height="2536" alt="CleanShot 2026-10-13 at 13 16
36@2x"
src="https://github.com/user-attachments/assets/ebad1082-b9ae-4f5e-91ad-08638ea2b032"
/> | <img width="1244" height="2538" alt="CleanShot 2026-10-13 at 13 17
20@2x"
src="https://github.com/user-attachments/assets/b5400b31-d60e-44e7-a4d6-cca1732b7974"
/> |
| _One “Advanced settings” at the bottom of the sheet that combines
everything. Destination details handles Publication and Initial sync._ |
_An “Advanced settings” accordion under BigQuery settings. Another
“Advanced settings” under Data (clipped above). Data contains fields for
Publication and Initial sync._ |
## Review instructions
1. Open the [Pipelines
preview](https://studio-staging-git-dnywh-featpipeline-connectio-6d0876-supabase.vercel.app/dashboard/project/_/database/pipelines),
select a test project with Pipelines enabled and click **Add pipeline**.
Enable **Pipeline creation wizard** in Feature Previews, then reopen the
sheet. Confirm the order is destination cards → connection → data.
2. With BigQuery selected, expand **Advanced settings** under
**Destination connection**. Confirm it contains pool size and staleness.
Expand **Advanced settings** under **Data** below publication and
initial sync. Confirm it contains replication settings and table layout,
without duplicate connection fields. Change a value and collapse/reopen
the accordion; confirm it remains.
3. If available, select DuckLake or Snowflake. Confirm their connection
accordion contains **Pool size** or **Role**, respectively. ClickHouse
and Analytics Bucket have no connection accordion. Check desktop and
phone widths. Cancel and discard changes; no credentials or pipeline
creation are needed.
4. Turn the preview off and reopen **Add pipeline**. Confirm the
original layout returns. With the preview on, edit an existing pipeline
and confirm it also keeps the original layout.
## Problem
The pipeline creation wizard in #49243 needs a destination selection
step that can be reviewed before wizard routing lands.
## Solution
Add `PipelineDestinationSelection` with BigQuery, DuckLake, Snowflake,
ClickHouse and deprecated Analytics Bucket radio options, using Studio’s
existing destination logos. Show it in the creation sheet only when
**Pipeline creation wizard** is enabled in Feature Previews and allowed
by ConfigCat. Preview off and editing retain the existing dropdown.
This is an incremental preview: creation still uses the sheet. No wizard
routing or design-system changes are included.
| Feature Preview Off | Feature Preview On |
| --- | --- |
| <img width="1274" height="1316" alt="CleanShot 2026-10-13 at 10 39
24@2x"
src="https://github.com/user-attachments/assets/433e4fb1-5fa2-4dc3-982e-0aee6b266015"
/> | <img width="1250" height="1890" alt="CleanShot 2026-10-13 at 10 53
09@2x"
src="https://github.com/user-attachments/assets/033d7e43-1a57-4d61-90e8-9048e3560909"
/> |
## Review instructions
1. Open the [preview to Database →
Pipelines](https://studio-staging-git-dnywh-featpipeline-destinati-54dc7d-supabase.vercel.app/dashboard/project/_/database/pipelines),
select a test project with Pipelines enabled and click **Add pipeline**.
With **Pipeline creation wizard** off, confirm the existing destination
dropdown appears.
2. Close the sheet, enable **Pipeline creation wizard** in Feature
Previews and reopen **Add pipeline**. Confirm radio cards replace the
dropdown, with BigQuery selected initially and only destinations
available to your project shown.
3. If Analytics Bucket is available, confirm its card has a
**DEPRECATED** badge. Select it and confirm the bucket fields appear and
the description below says **Destination type cannot be changed after
creation. Analytics Bucket is deprecated.** Click another destination.
Confirm only one card is selected and the connection fields below switch
to that destination. Use arrow keys to move focus and Space to select a
destination. Check at desktop and phone widths. Cancel and discard
changes; no credentials or pipeline creation are needed.
4. With the preview still on, open an existing pipeline for editing.
Confirm its destination dropdown remains locked. Turn the preview off
and reopen **Add pipeline** to confirm the original dropdown returns.
## Problem
I recently joined Supabase as part of the Container Engineering team,
and adding myself to `humans.txt` is one of my onboarding tasks.
## Solution
Add my full name, Gonzalo Servat, to the team list in alphabetical
order, between Giuseppe Mandato and Greg Kress.
## Review instructions
1. Confirm Gonzalo Servat appears between Giuseppe Mandato and Greg
Kress.
2. Confirm the rest of the list is unchanged.
## Checklist
Check all before review:
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
## Problem
#51196 added `/apps/kb/` to CODEOWNERS with both `@supabase/docs` and
`@supabase/marketing`. Because of that, every knowledge base change also
asks marketing for review. Marketing should not be a required reviewer
for KB.
## Solution
Remove `@supabase/marketing` from the `/apps/kb/` line only.
`@supabase/docs` still owns KB. All other CODEOWNERS entries, including
marketing's `/apps/www/` ownership, are unchanged.
```diff
-/apps/kb/ @supabase/docs @supabase/marketing
+/apps/kb/ @supabase/docs
```
## Review instructions
1. Check that the diff is a single line in `.github/CODEOWNERS`.
2. Confirm `/apps/kb/` is still owned by `@supabase/docs`.
3. Optional: `gh api
repos/supabase/supabase/codeowners/errors?ref=tedd/remove-marketing-kb-codeowner`
returns no errors.
## Checklist
Check all before review:
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
Co-authored-by: supabase-vercel-tedd[bot] <336548405+supabase-vercel-tedd[bot]@users.noreply.github.com>
## Problem
Declarative schemas now runs on `pg-delta`. The Declarative Schemas
entry on the features page still describes the old diff flow: it points
readers to `supabase db diff`, says migrations come from the current
database state, and tells readers to use `supabase db dump` to start
from an existing project.
## Solution
Updates the `declarative-schemas` entry in `apps/www/data/features.tsx`:
- Adds a paragraph after the intro saying the feature now runs on
`pg-delta`, that it is in alpha, and how to opt in.
- Updates key benefit 5 to list grants, partitions, publications, and
domains, and extension-managed objects.
- Replaces the `supabase db diff` integration bullet with `supabase db
schema declarative sync`.
- Updates the intro bullet and three FAQ answers to match the current
docs: how migrations are generated, whether readers write their own
migration files, and how to start from an existing project (`supabase db
schema declarative generate --linked`, with `supabase db dump` kept for
the legacy engine).
The entry's status stays `PRODUCT_STAGES.GA`. The feature is GA and only
the new engine is alpha, and the new paragraph says so.
This should merge with or after the launch blog post (#51571), so the
page doesn't get ahead of the announcement.
## Preview links
| Site | Live | Preview | Search for |
| ---- | ---- | ------- | ---------- |
| WWW |
[/features/declarative-schemas](https://supabase.com/features/declarative-schemas)
| Vercel bot comment on this PR, `/features/declarative-schemas` | `now
runs on` |
## Review instructions
1. Open the live and preview links side by side.
2. Check that the new paragraph appears after the intro and renders its
inline code.
3. Check that key benefit 5 and the CLI integration bullet use the new
text.
4. Check the three updated FAQ answers: how declarative schemas differ
from migrations, whether you write your own migration files, and using
declarative schemas with an existing project.
5. Confirm the status badge still reads General Availability.
## Checklist
Check all before review:
- [ ] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Wendie Cheung <wendie.cheung@supabase.io>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Wen Bo Xie <wenbox323@gmail.com>
## Problem
Declarative Schemas 2.0 runs on `pg-delta`. It needs a launch blog post.
## Solution
Adds `apps/www/_blog/2026-10-13-declarative-schemas-2-0-pg-delta.mdx`,
which will publish at `/blog/declarative-schemas-2-0-pg-delta`.
The post covers why the diff engine was rebuilt, what the new diff
covers, how to turn it on, a four-step walkthrough, and what stays out
of scope.
Adds the social and thumbnail images in
`apps/www/public/images/blog/select-rewind-2026-declarative-schemas-2-blog/`
(`og.png`, `thumb.png`) and references them from `imgSocial` and
`imgThumb`.
## Preview links
| Site | Live | Preview | Search for |
| ---- | ---- | ------- | ---------- |
| WWW | Not live yet |
[/blog/declarative-schemas-2-0-pg-delta](https://zone-www-dot-com-git-wendiecheung-declarative-s-817801-supabase.vercel.app/blog/declarative-schemas-2-0-pg-delta)
| `Declarative Schemas 2.0` |
## Review instructions
1. Open the preview link.
2. Check that the comparison table, code blocks, and links render.
3. Check that the post shows its thumbnail on `/blog` and its social
image in the page metadata.
4. Confirm the frontmatter: title, description, authors (`avallete`,
`wenbo`), date, tags, and images.
## Checklist
Check all before review:
- [ ] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Wendie Cheung <wendie.cheung@supabase.io>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Wen Bo Xie <wenbox323@gmail.com>
Co-authored-by: Prashant Sridharan <prashant_sridharan@hotmail.com>
## Problem
Currently troubleshooting guides merged in a private repository trigger
an action to open a PR against our Docs project.
From now on, we want the `kb` to host the troubleshooting guides and
take care of all the Github discussion process while improving some of
its parts.
## Solution
With this PR now:
- All files and scripts related to handling the actions and processes
for handling troubleshooting entries and GitHub Discussion creation on
Docs are deleted.
- A new workflow to sync troubleshooting guides with Supabase's
`troubleshooting_entries` table was created with some improvements.
- Now troubleshooting entries are fetched at pre-build in `kb` project
directory.
- When troubleshooting guides are created a new script detects this,
creates the GitHub discussion for it, extracts the URL, and pushes the
row to a db table at `push`.
- When troubleshooting guides are updated, a checksum holding its title
and body is compared, and the GitHub discussion content gets updated.
_Note: all troubleshooting content hasn't been migrated for **kb**, so
content not ready is filtered and not placed in the directory. This
allow us to progressively migrate all pages without breaking the build._
<!--
## Preview links
If relevant, include links to changed pages for easy review access.
Copy the preview base URL from the Vercel bot comment on this PR. Use
the following table as an example template.
| Site | Live | Preview | Search for |
| -------------- |
-------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------
| ----------------------------- |
| WWW | [/blog/your-post](https://supabase.com/blog/your-post) |
[/blog/your-post](https://zone-www-dot-com-git-branch-name-supabase.vercel.app/blog/your-post)
| unique phrase from the change |
| Docs |
[/docs/guides/your-page](https://supabase.com/docs/guides/your-page) |
[/docs/guides/your-page](https://docs-git-branch-name-supabase.vercel.app/docs/guides/your-page)
| unique phrase from the change |
| Studio | [/dashboard](https://supabase.com/dashboard) |
[/dashboard](https://studio-git-branch-name-supabase.vercel.app/dashboard)
| unique phrase from the change |
| Design system | [/design-system](https://supabase.com/design-system) |
[/design-system](https://design-system-git-branch-name-supabase.vercel.app/design-system)
| unique phrase from the change |
| UI library | [/library](https://supabase.com/library) |
[/library](https://ui-library-git-branch-name-supabase.vercel.app/library)
| unique phrase from the change |
| Knowledge base |
[/kb/guides/your-page](https://supabase.com/kb/guides/your-page) |
[/kb/guides/your-page](https://kb-git-branch-name-supabase.vercel.app/kb/guides/your-page)
| unique phrase from the change |
-->
<!-- ## Additional context
Optionally add any other context or screenshots.
-->
## Review instructions
For the database workflow, sadly, we will have to wait and monitor, but
the fetching mechanism can be tested.
1. Go to the preview link for `kb`
2. Go to Topics > Troubleshooting
3. A new guide should be visible "Partial migrations and schema
inconsistencies from embedded transactions", click on its link
4. A page showing the guide's content should render
<img width="1022" height="810" alt="Screenshot 2026-10-07 at 13 19 17"
src="https://github.com/user-attachments/assets/cbd25a60-8721-4329-907f-f92de894c217"
/>
## Checklist
Check all before review:
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
## What
Fixes two bugs found while writing component tests for the platform
webhooks page (follow-up to FE-3749):
1. The webhooks API nests error details under an `error` key (`{ error:
{ code, message } }`), but the shared `handleError` only reads a
top-level `message`. This meant the friendly rate-limit message ("wait a
minute and try again") never actually fired, it always fell back to a
generic error. Fixed with a local unwrapping `handleError` in
`platform-webhooks-fetchers.ts`.
2. Every mutation handler on the page (`mutateAsync` for
create/update/delete/regenerate-secret/send-test-event/retry) left the
re-thrown error from React Query uncaught, producing an unhandled
promise rejection on every failure, even though the error toast itself
was already correct. Fixed by wrapping each call in try/catch.
## Why
Found while writing the stacked test PR for FE-3749; filed as
[FE-4620](https://linear.app/supabase/issue/FE-4620/two-webhook-error-handling-bugs-found-while-writing-retryrate-limit)
since it's a correctness fix independent of the test work.
## Testing
Manually verified both fixes on localhost: rate-limit retry now shows
the friendly message, and no `Uncaught (in promise)` errors appear in
the console on any mutation failure.
## What kind of change does this PR introduce?
Bug fix.
## What is the current behavior?
On a project whose database server statically checks `DO` blocks before
running them (Multigres does), several Studio actions fail:
- Creating a table shows "Failed to update API access privileges for new
table", although the table is created.
- Toggling Realtime for a table fails with `EXECUTE of a runtime-built
statement inside a PL/pgSQL body is not supported`.
- The same error blocks editing a role or schema (rename, owner, drop)
and changing column privileges.
All of these come from SQL that `@supabase/pg-meta` generates. Such a
server only accepts a dynamic `EXECUTE` when it can prove the statement
is fixed, and two shapes in our SQL prevent that:
- parentheses around the payload: `execute(format(...))`
- `%s` conversions in `format()` strings, which substitute raw text (for
example `%s` fed by `<oid>::regclass`, by a `string_agg(...)` subselect,
or by a variable holding a table list)
## What is the new behavior?
`tablePrivileges.grant/revoke`, `columnPrivileges.grant/revoke`,
`publications.update`, `roles.update/remove` and `schemas.update/remove`
generate SQL with no parentheses around the payload and only `%I`/`%L`
conversions:
- Table and column privileges name the table with `%I.%I`, taking the
schema and name from `pg_class`/`pg_namespace`.
- The publication update loops over the tables to drop and to add, with
the same `tables` semantics as before (`undefined` keeps the tables,
`null` publishes all tables, a list replaces them, bare names resolve
through the search path).
- `schemas.remove` picks between `drop schema … cascade` and `…
restrict` with two plain statements instead of a `%s` fed by a `CASE`.
- The grant and revoke format strings are built with `literal()`, so a
quote in a role name can't end the string early.
The statements are equivalent on regular Postgres.
## Additional context
- New tests: replacing, clearing and keeping a publication's tables,
switching between a table list and all tables, and a test (no database
needed) that fails if the generated SQL of any of these builders goes
back to `execute(...)` or `%s`.
- I ran the pg-meta tests against a local Postgres 17. A set of existing
snapshot tests were recorded on Postgres 14 and fail there with and
without this change (for example the new `MAINTAIN` privilege in table
privileges), so CI is the real check for those. The tests covering the
changed SQL pass.
- Some other Studio SQL is blocked on such servers for different reasons
(for example creating foreign servers, and `SET` inside a `DO` block).
It isn't addressed here.
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.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?
New blog post (www): "Ship changes to your Supabase backend with Grok
Bot", announcing Supabase joining the SpaceXAI Partner Network.
## What is the current behavior?
N/A
## What is the new behavior?
Adds `/blog/ship-changes-to-your-supabase-backend-with-grok-bot`, dated
2026-10-13, with Nick Littman, Elsa Heffernan, and Shaziya Bandukia as
authors.
## Additional context
Also updates Nick Littman's title in `authors.json` to Solution
Architect.
---------
Co-authored-by: dshukertjr <dshukertjr@gmail.com>
## Context
Shows the production branch as part of the branching empty state (Shifts
`BranchingEmptyState` into `Overview`)
It's so that users can still then reach the "View logs" button for the
production branch which was otherwise hidden
<img width="1214" height="531" alt="image"
src="https://github.com/user-attachments/assets/3bc702f2-950b-4d9e-8b4f-78149af9ed82"
/>
## Problem
When uploading a file with same name of already existing file, the ui
automatically creates a new file with incremental number and doesn't
consider the scenario of giving the possibility of storing the new
upload as a version of the already existing file.
## Solution
Provide modal to chose the behaviour when name conflict happens when
uploading a file:
- Replace existing file (same file with version history)
- Keep both (new file with incremental numbering)
https://github.com/user-attachments/assets/ee192be9-4087-4e14-89f1-1c82acf550cd
Manage edge case of clashes with files created when bucket had
versioning enabled (so with `is_versioned` flag to true) and clashing
upload happens when bucket is in SUSPENDED state.
https://github.com/user-attachments/assets/00694c77-07c1-405e-bd54-bdf0bf99d274
Unrelated fix:
- add "Delete permanently" action when selecting multiple files with
versioning enabled
<img width="510" height="203" alt="Screenshot 2026-10-13 at 15 59 27"
src="https://github.com/user-attachments/assets/5692fc23-2fd3-4259-9de2-3932aecbccd0"
/>
## Problem
The declarative schemas guide does not explain how pg-delta tracks
pg_cron jobs. Its guidance that schema diffs exclude row data can also
suggest that jobs stored in cron.job are excluded.
Readers need to know where to declare jobs, how changes become
migrations, and why jobs without unique names are skipped.
## Solution
Document the declarative workflow for pg_cron jobs, including:
- Declaring jobs in SQL files under supabase/schemas/.
- Giving each job a unique name.
- Generating migrations when job declarations change or are removed.
- The scheduling and unscheduling calls emitted by the engine.
Connect the DML caveat to the extension configuration explanation so
readers understand why supported configuration rows are tracked.
Validation: Prettier, Markdown generation, and git diff --check passed.
The cron workflow was checked against source code but was not executed
in a sandbox.
## Review instructions
1. Open the declarative database schemas guide in the docs preview.
2. Read Data manipulation language and follow the extension
configuration link.
3. In Extension-managed objects, confirm that the cron guidance explains
where to declare jobs, the naming requirement, and the generated
migration behavior.
4. Follow generate and apply a migration and confirm it leads to the
existing workflow.
## Checklist
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the /write-the-docs or /edit-the-docs skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
## Summary
- .npmrc is only read when deno.json or package.json also exists in the
function's directory. Adds a caution note to the private npm packages
section.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Documentation**
- Added a caution explaining that private NPM package configuration
requires a `deno.json` or `package.json` file in the function directory.
- Clarified that `.npmrc` is ignored when neither configuration file is
present.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- claude-slack-attribution -->
_Requested by **Charis Lam** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1791896774914759)_
**Before:** The `ratchet` check fails on any PR that includes current
master. The baseline for `shadcn/no-arbitrary-values` is 197, but master
has 198 since `text-[11px]` landed in `ArchivedVersionRestoreWidget.tsx`
via #51476. The baseline bot lowered it to 197 right after (#51524).
**After:** The baseline is 198, matching master, so the check passes
again.
This only changes that one rule's number (plus its per-file breakdown
entry for the widget) in
`apps/studio/.github/eslint-rule-baselines.json` and leaves the
underlying arbitrary value for its owner to fix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01TsqepmwoWCXiv9BTxQK7MD
---
_Generated by [Claude
Code](https://claude.ai/code/session_01TsqepmwoWCXiv9BTxQK7MD)_
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
The `pricingPanelPlanPresentation` experiment is concluded with
`fullscreen` as the winner. This makes it the only presentation and
removes the experiment code.
- Plan-change panel always opens as the full-screen overlay with the
pricing-page style cards.
- Removed the `control`, `parity`, `gaps` and `fullscreen-gaps`
presentations: the side-sheet shell, the original compact card, and the
"Not included" / "Plan limits" gap rows.
- Removed `plan-presentation.ts` (flag read, eligibility gate, exposure
tracking, gap lists) and its tests.
- Removed the `pricing_panel_plan_presentation_experiment_exposed` event
from `telemetry-constants.ts`.
- The panel no longer waits for PostHog flags to resolve before opening.
- `useTrackExperimentExposure` stays; it's kept across experiment gaps
in `knip.jsonc`.
**Behavior change for previously ineligible orgs:** partner-billed,
Stripe-managed, AWS Marketplace, Enterprise/Platform orgs and members
without billing write were held on `control` during the test. They now
also get the full-screen panel. Their partner-managed notices and
disabled CTAs are unchanged.
## After merge
- [ ] Archive the `pricingPanelPlanPresentation` flag and end the
experiment in PostHog.
## Test plan
- [x] `vitest` for `BillingSettings/Subscription`: 11 passing
(partner-managed messaging, full-screen shell, pricing-page cards, no
gap rows)
- [x] `tsc`: no errors in touched files
- [x] `knip --workspace apps/studio`: clean
- [ ] Preview: open `/org/[slug]/billing?panel=subscriptionPlan` for a
Free org and a partner-billed org
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Problem
Missing redirects for changed paths and pages leading to an extra ~1500
404's in the past 24 hours for folks (and bots) browsing our web
properties.
## Solution
Added redirects
## Preview links
https://zone-www-dot-com-git-kody-devrel-699-high-traff-584bc9-supabase.vercel.app/
(though most of these are docs links so the behavior actually won't be
visible in the preview)
<!-- claude-slack-attribution -->
_Requested by **Pam Chia** · [Slack
thread](https://supabase.slack.com/archives/C076KTY11DF/p1791767641595649?thread_ts=1791767641.595649&cid=C076KTY11DF)_
## Problem
**Before:** `docs_search_v2_search_submitted` (added in #51146) fires
when a Search V2 query settles on either the `results` or the
`noResults` state, but it only sends `query`. A search that found
nothing looks the same as one that found results, and no other Search V2
event carries the outcome, so the no-results rate for Search V2 can't be
computed.
**After:** the event also sends `hasResults`. It's `true` when the
endpoint returned at least one result and `false` when it returned none,
so zero-result searches can be counted and their queries inspected.
## Solution
- `packages/common/telemetry-constants.ts`:
`DocsSearchV2SearchSubmittedEvent` gains a doc-commented `hasResults:
boolean` property.
- `apps/docs/features/SearchV2/SearchV2Dialog.tsx`: the existing fire
site sends `hasResults: searchState.status === 'results'`. The
`useDocsSearchV2` reducer only sets `results` when the response has at
least one hit, and `noResults` otherwise, so the status is exactly the
outcome.
The change is additive: the event name and `query` are unchanged, and
the `loading`, `error`, and `initial` states still don't fire the event.
Linear:
[GROWTH-1330](https://linear.app/supabase/issue/GROWTH-1330/docs-search-v2-add-hasresults-to-docs-search-v2-search-submitted)
## Review instructions
1. Open the docs preview with the Search V2 flag query:
`?docs-search-v2=search-v2-active`.
2. Open search and type a query that returns results. In the network
tab, the `/platform/telemetry/event` request for
`docs_search_v2_search_submitted` has `custom_properties` `{ "query":
"...", "hasResults": true }`.
3. Type a query that returns nothing (for example random characters).
The event has `"hasResults": false`.
## Checklist
Check all before review:
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
(not applicable: no docs content changed)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01JaqCdU2sPkBMbaUmUPW75i
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JaqCdU2sPkBMbaUmUPW75i)_
Co-authored-by: Claude <noreply@anthropic.com>
## Problem
Project creation can send a request without a region, which the API
rejects. Empty region values pass frontend validation, and a failed
available-regions request fills in a static region name that cannot
resolve to a region selection.
## Fix
Keep the region selector controlled from mount and require a nonempty
value. Disable creation when available regions fail to load, guard
submission against unresolved region selections, and preserve the static
fallback for providers that use it.
Fixes
[FE-3884](https://linear.app/supabase/issue/FE-3884/project-creation-wizard-can-submit-with-an-empty-region).
## How to test
- Open the new-project form and verify the recommended region submits
without manually selecting a region.
- Submit with an empty region. Expected result: an inline validation
error appears and no project creation request is sent.
- Fail the available-regions endpoint, including after changing compute
size with a region already selected. Expected result: the region-loading
error appears, creation is disabled, and direct form submission sends no
project creation request.
- Run `pnpm --filter studio exec vitest --run
'tests/pages/new/[slug].test.tsx'
tests/pages/vercel-deploy-button-new-project.test.tsx
components/interfaces/ProjectCreation/ProjectCreation.schema.test.ts`.
Local validation: all 54 focused tests and formatting pass. Focused
ESLint has no errors. Local typecheck reports the existing image type
mismatch in InstructionBlocks.tsx; CI typecheck passed for the previous
commit.
This pull request enhances the project creation flow by introducing
support for filtering Postgres versions based on the OrioleDB engine.
The main changes involve updating the `PostgresVersionSelector`
component to allow filtering for OrioleDB-specific versions, and
integrating this logic into the internal-only configuration step of
project creation. This provides a clearer and more flexible experience
when selecting Postgres versions, especially for internal or advanced
users.
**Postgres Version Selection Enhancements:**
* Added a new `useOrioleDbForCreate` prop to `PostgresVersionSelector`,
allowing the component to filter available Postgres versions to only
OrioleDB-based options or exclude them, based on user selection. The
prop defaults to `undefined` for no filtering.
[[1]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9R41-R50)
[[2]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9R82-R85)
[[3]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9L92-R114)
* Added a `description` prop to `PostgresVersionSelector` for improved
UI guidance, and passed this prop through the form.
[[1]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9R41-R50)
[[2]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9R82-R85)
[[3]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9L139-R161)
**Integration with Project Creation Flow:**
* Updated `InternalOnlyConfiguration` to watch the `useOrioleDb` form
field and pass its value to `PostgresVersionSelector`, ensuring the
version list is filtered appropriately during project creation. Also,
conditionally set the description to guide users toward advanced
configuration for OrioleDB.
[[1]](diffhunk://#diff-f0fa51a1cc67bb1a2c38d2c595eb3cab3a45813a027a04942d684914f2c3de93R33)
[[2]](diffhunk://#diff-f0fa51a1cc67bb1a2c38d2c595eb3cab3a45813a027a04942d684914f2c3de93R60-R65)
* Adjusted the render order in `ProjectCreationForm` to ensure advanced
configuration and internal-only configuration are displayed in a logical
sequence.
**Other Improvements:**
* Imported the `isSuccess` utility from `effect/Result` in
`PostgresVersionSelector.tsx` to support the updated logic.
---------
Co-authored-by: Alaister Young <alaister@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Problem
Extends the create and edit form for OAuth apps. Adds two toggles and
their connections.
## How to test
In _Organization Settings \ OAuth Apps_
### New app
- You should be able to create an app without toggling any of the two
new options
- Toggling any of the two new option should require a confirmation that
blocks the form submition until checked
### Existing app
**The default values for existing apps are hard coded for now**
- You should be able to update any of the app props except the _Use the
permissions of the person who connects_ option which should be disabled.
- Toggling the _Ask for specific projects_ option should require a
confirmation that blocks the form submition until checked
---------
Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
## Problem
When users set up two-factor authentication (TOTP) in the dashboard, the
enrollment modal asks them to name their authenticator app, with the
placeholder suggesting `e.g.: Google Authenticator`. Many users keep or
type this example name without realizing it is simply a custom nickname
for the factor.
On the sign-in MFA screen (`SignInMfaForm.tsx`), the code input
previously rendered its label as:
> `Code generated by Google Authenticator`
This phrasing can lead users to believe that Supabase has locked their
account specifically to Google's authenticator app—even when they
actually scanned the QR code with Apple Passwords / iOS Keychain,
1Password, or Bitwarden. As reported in #51502, users who rely on their
iPhone's built-in authenticator can get alarmed, thinking their
authentication setup was unexpectedly swapped.
Furthermore, if a user is genuinely locked out (e.g. lost device and
backup codes), the "Email support" option previously only surfaced after
an explicit authentication exception occurred, rather than being readily
discoverable under the *"Unable to sign in?"* help section.
Closes#51502
## Solution
1. **Clear, standard form label & descriptive subtext**:
- Replaced the ambiguous `Code generated by [Friendly Name]` label with
a standard `Authentication code` label.
- Moved the factor's friendly name into the field description:
- When a name is configured: `From the authenticator app registered as
[Friendly Name]`
- Fallback when no name is set: `From the authenticator app registered
to this account`
- This makes it immediately obvious that `[Friendly Name]` is just the
custom label they chose, rather than a hard vendor requirement.
2. **Direct support escape hatch**:
- Added an **"Email support to regain access"** link directly into the
*"Unable to sign in?"* list in both `SignInMfaForm` and
`SignInRecoveryCodeForm`.
- Users who are stuck now have an immediate, obvious way to reach out
without needing to trigger errors or hunt down the support email.
3. **Extracted testable helper logic**:
- Extracted friendly-name normalization and support mailto generation
into a dedicated `SignInMfa.utils.ts` module.
- Added unit test coverage in `SignInMfa.utils.test.ts` (9 tests
covering trims, null/empty cases, and mailto parameters).
## Review instructions
1. Navigate to `/sign-in-mfa` (with an account that has a TOTP factor
enrolled).
2. Verify that the input label reads `Authentication code`.
3. Check the subtext: verify that it clarifies `From the authenticator
app registered as [Name]`.
4. Inspect the *"Unable to sign in?"* section at the bottom:
- Confirm that "Email support to regain access" is visible and opens a
pre-addressed email to `support@supabase.com` with subject `Unable to
sign in via MFA`.
5. Check `/sign-in-recovery-code` and verify the same support link is
present.
## Checklist
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] Unit tests added and passing (`vitest run
components/interfaces/SignIn/SignInMfa.utils.test.ts`)
- [x] Code passes Prettier formatting check
- [x] Code passes ESLint without adding warnings
## Context
Tiny refactor that I happened to pass by as I was reviewing other PRs
`useOrgProjectsInfiniteQuery` has a default `limit` value at 96 set in
the hook, 96 mainly for the home page to render a full row of cards
since cards are rendered in rows of 3
However, we have a couple of callsites for `useOrgProjectsInfiniteQuery`
that were passing a different `limit` value, hence these would be
triggered as a separate API request.
Am opting to remove the `limit` parameter from
`useOrgProjectsInfiniteQuery` so that the limit is standardized to 96
- So that data can be cached without having to invoke another API
request wherever `useOrgProjectsInfiniteQuery` is called
- I doubt that there'll be a need in a UI that will require calling
`useOrgProjectsInfiniteQuery` with a separate value for `limit` but
please do let me know otherwise if I might be overlooking anything!
## This PR
Adds **Show archived** to the file explorer's view options and list them
in the file explorer.
- `useStoragePreference` — `showArchivedInline`, stored per project
- `ArchivedFilesContext` — owns the archived list and which object is
selected
- `FileExplorer` — merges archived rows into each column and re-sorts,
since the server-side sort never sees them
- `FileExplorerRow` — dimmed striped rendering, no checkbox, no context
menu
- `FileExplorerHeader` — the toggle, rendered only behind the feature
preview
- `StorageExplorer` — mounts the provider
https://github.com/user-attachments/assets/a26551b4-b22d-485e-9d23-3e78c4a89315
Clicking an archived row opens a preview panel: where the file used to
live, when it was archived, its retained versions, and the actions to
bring it back or delete it permanently.
- `ArchivedFilePreviewPane` — the pane, replacing `PreviewPane` while an
archived row is selected
- `ArchivedVersionRestoreWidget` — takes over the top of the pane when a
specific retained version is selected
- `ArchivedVersionRow` — one version, with its restore / delete actions
- `StorageExplorerContent` — the pane swap
https://github.com/user-attachments/assets/03c9eae6-e9e3-4bd0-8145-953625e125d1
Other additions behind the feature preview:
- The buckets list show a **Versioning** column.
- `BucketVersioningPill` — a `file-stack` badge beside the bucket name
in the breadcrumbs, brand when versioning is enabled and warning when it
is suspended, so the bucket's state is visible from inside the explorer
rather than only from the buckets list.
https://github.com/user-attachments/assets/f4827aac-a9ff-4300-92ac-073848d63606
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
## Problem
The server and middleware reference pages on supabase.com still carry
alpha labels that were dropped from the source partials weeks ago.
#51031 (Sep 30) removed the alpha wording from the partials and #51276
(Oct 5) added the adapter removal date, but neither change reached the
live site.
The reference build (`apps/docs/scripts/build-reference-content.ts`,
`writeNewMarkdownPartials`) copies a partial to
`docs/ref/<library>/<name>.mdx` only when that file does not exist, and
the page renderer reads from `docs/ref`. Once a page has been seeded,
later edits to the partial are never picked up. The three affected pages
were seeded before those PRs merged.
The UI library MCP page has the same stale wording: it says the
`pipeline` entry form of `withSupabase` is alpha and tracks
`@supabase/middleware` 0.x. Middleware is at 1.x and `@supabase/server`
dropped the alpha label in supabase/server#185.
Linear:
[SDK-2161](https://linear.app/supabase/issue/SDK-2161/remove-the-public-beta-designation-from-supabaseserver).
Companion package PR: supabase/server#192.
## Solution
Copy the current partial bodies over their rendered twins. The
frontmatter is identical in each pair, and the partials are left
untouched:
- `apps/docs/docs/ref/server/frameworks.mdx`: adapters are now described
as deprecated with the December 1, 2026 removal date, the Versions note
tells readers to add `@supabase/middleware` as a direct dependency, the
migration steps include `npm install @supabase/middleware`, and "The
entry form is alpha" is gone.
- `apps/docs/docs/ref/middleware/introduction.mdx`: the "Alpha"
admonition is gone.
- `apps/docs/docs/ref/middleware/usage-examples.mdx`: the entry form
note no longer says alpha.
Rewrite one paragraph in `apps/ui-library/content/docs/headless/mcp.mdx`
so it states the version requirement (`@supabase/server` 1.6.0 or later)
and that the nested form behaves the same, without the alpha or 0.x
claims.
After this PR each `docs/ref` file is byte-identical to its partial, so
`diff` between the two is empty.
## Preview links
| Site | Live | Preview | Search for |
| ---------- |
---------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------
| --------------------------------------- |
| Docs |
[/docs/reference/server/frameworks](https://supabase.com/docs/reference/server/frameworks)
|
[/docs/reference/server/frameworks](https://docs-git-docs-drop-stale-alpha-labels-supabase.vercel.app/docs/reference/server/frameworks)
| `December 1, 2026` |
| Docs |
[/docs/reference/middleware/introduction](https://supabase.com/docs/reference/middleware/introduction)
|
[/docs/reference/middleware/introduction](https://docs-git-docs-drop-stale-alpha-labels-supabase.vercel.app/docs/reference/middleware/introduction)
| `is in alpha` (live only) |
| Docs |
[/docs/reference/middleware/usage-examples](https://supabase.com/docs/reference/middleware/usage-examples)
|
[/docs/reference/middleware/usage-examples](https://docs-git-docs-drop-stale-alpha-labels-supabase.vercel.app/docs/reference/middleware/usage-examples)
| `The entry form of` |
| UI library |
[/ui/docs/headless/mcp](https://supabase.com/ui/docs/headless/mcp) |
[/ui/docs/headless/mcp](https://ui-library-git-docs-drop-stale-alpha-labels-supabase.vercel.app/ui/docs/headless/mcp)
| `Composing` |
## Review instructions
1. Open the live and preview links for the frameworks page side by side.
Search for `alpha`: present on live, absent on preview. Search for
`December 1, 2026`: absent on live, present on preview.
2. Open the middleware introduction. The "Alpha" caution box is gone on
preview.
3. Open the middleware usage examples and expand the CORS example
details. The entry form note reads "needs `@supabase/server` 1.6.0 or
later" with no alpha.
4. Open the UI library MCP page. The paragraph after the `whoami` note
states the version requirement and no longer mentions alpha or 0.x.
5. Optional, in a checkout: `diff
apps/docs/spec/reference/server/v1/partials/frameworks.mdx
apps/docs/docs/ref/server/frameworks.mdx` prints nothing. Same for the
two middleware pages.
## Checklist
Check all before review:
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
The docs text is copied verbatim from partials that already went through
review in #51031 and #51276. The one rewritten paragraph in the UI
library page follows the Supabase writing style guide.
<!-- claude-slack-attribution -->
_Requested by **Sofia Calado** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1791792994853839?thread_ts=1791792994.853839&cid=C0161K73J1J)_
## Problem
**Before:** The Subprocessor List page
(`/legal/customer-resources/subprocessor-list`) showed one download
button, for the June 1, 2026 list.
**After:** The page shows two download buttons, newest first:
"Subprocessor List - Updated October 12, 2026" and "Subprocessor List -
Updated June 1, 2026". The June 1, 2026 PDF is kept as is.
This adds the October 12, 2026 subprocessor list as a new version
without replacing the existing one.
## Solution
How: the single `CURRENT_PDF` constant in
`apps/www/pages/legal/customer-resources/subprocessor-list.tsx` becomes
a `SUBPROCESSOR_LIST_VERSIONS` array (newest first, each entry has
`file` and `displayDate`), and the page maps over it to render one
button per version using the same `Button` and label format as before.
The new PDF is added as
`apps/www/public/legal/subprocessor-list/October-12-2026.pdf`, copied
byte for byte from the supplied file (2 pages, "As of October 12, 2026",
22 rows). The header comment now explains how to add a future version.
The page copy, the Customer.io subscribe form, the Legal Hub link, the
redirect and the DPA and FAQ links are untouched; none of them reference
a specific PDF.
## Review instructions
1. Open `/legal/customer-resources/subprocessor-list` on the Vercel
preview for this PR.
2. Confirm two buttons appear in this order: "Subprocessor List -
Updated October 12, 2026", then "Subprocessor List - Updated June 1,
2026".
3. Open each and confirm the PDF header date matches the button label.
4. Confirm the subscribe form below the buttons is unchanged.
**Not verified:** The Vercel preview and supabase.com are not reachable
from the environment this PR was prepared in, so the page was not viewed
rendered. `pnpm install` was not run, so ESLint and `tsc` did not run.
Prettier 3.8.1 was run on the changed file with the repo's formatting
options (the repo config's SQL plugin was not installed) and reported no
changes. The change was read through by hand for type and syntax errors.
## Checklist
- [ ] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01HtysymSUPZS8aJ1eTa7R9N
---
_Generated by [Claude
Code](https://claude.ai/code/session_01HtysymSUPZS8aJ1eTa7R9N)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Feature
Add a ".NET" option to the "Connect" flow in the Dashboard, with several
variants.
## Preview links
If relevant, include links to changed pages for easy review access.
Copy the preview base URL from the Vercel bot comment on this PR. Use
the following table as an example template.
| Site | Live | Preview | Search for |
| -------------- |
-------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------
| ----------------------------- |
| Studio | [/dashboard](https://supabase.com/dashboard) |
[/dashboard](https://studio-staging-git-guillaumefaas-sdk-1881-add-s-537090-supabase.vercel.app/)
| Add .NET option in Connect |
## Review instructions
1. Click on the "Connect" button when on a project page
2. Select ".NET" in the frameworks drop-down
3. Verify the 3 variants (ASP.NET Core, Unity, Console)
## Checklist
Check all before review:
- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
## This PR
On a versioned bucket a file or a version can be "soft deleted/archived"
or "permanently deleted".
- `archived-objects-query.ts` — `ArchivedObject` /
`ArchivedObjectVersion` types + `archivedObjectsQueryOptions`
- `archived-object-restore-mutation.ts` — bring an archived object back
into the live tree
- `archived-object-purge-mutation.ts` — delete it and every version,
permanently
- `archived-object-version-delete-mutation.ts` — remove one retained
version
- `archivedOverlay.utils.ts` — synthesizes the explorer rows for one
folder from the archived list
- `archivedVersions.utils.ts` — an archived object's history as one
flat, newest-first list
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
## Problem
The pipeline creation wizard in #49243 needs to reuse the pipeline
region display and publication and initial-sync wording in review. These
currently live inside the sheet’s fields.
## Solution
Extract `PipelineRegionReadonly` and shared selection copy, with the
existing sheet as their first consumer. Region styling, labels,
descriptions and selection behaviour stay the same.
## Review instructions
1. Open the [preview to Database →
Pipelines](https://studio-staging-git-dnywh-refactorpipeline-revie-080d09-supabase.vercel.app/dashboard/project/_/database/pipelines),
select a test project with Pipelines enabled and click **Add pipeline**.
2. Confirm **Pipeline region** still shows the flag, region name and
code as read-only information, with the same description and spacing.
3. Select a publication and open **Initial sync**. Confirm the four
options keep their existing labels and descriptions. Choose **Selected
tables only**, select a table, then choose **All except selected
tables**. Confirm the selection description switches from running to
skipping initial sync and still says ongoing replication includes every
publication table. Cancel and discard changes; no credentials or
pipeline creation are needed.
## Problem
The pipeline creation wizard in #49243 needs replication settings on its
data step, separately from destination connection settings. These fields
currently live inside the sheet’s Advanced settings accordion.
## Solution
Extract **Batch wait time**, **Table sync workers**, **Initial sync
connections per table** and **Invalidated slot behavior** into
`ReplicationFields`. Keep the existing accordion as its first consumer.
Labels, defaults, units, field order and empty-value handling stay the
same.
## Review instructions
1. Open the [preview to Database →
Pipelines](https://studio-staging-git-dnywh-refactorpipeline-repli-2d71d1-supabase.vercel.app/dashboard/project/_/database/pipelines),
select a test project with Pipelines enabled and click **Add pipeline**.
Expand **Advanced settings**.
2. Confirm the four replication settings appear in their existing order,
before BigQuery’s connection settings and table layout. For DuckLake,
**Pool size** stays above them; for Snowflake, **Role** stays below
them.
3. Enter `0` for **Batch wait time**, `8` for **Table sync workers** and
`3` for **Initial sync connections per table**. Clear and re-enter each
value. Confirm no `NaN` appears. Select **Recreate slot**, then collapse
and reopen the accordion. Confirm all values remain. Cancel and discard
changes; no credentials or pipeline creation are needed.