From 05a45dd1edbaeb972d960e181b18cb4878b49674 Mon Sep 17 00:00:00 2001 From: Danny White <3104761+dnywh@users.noreply.github.com> Date: Wed, 23 Sep 2026 08:52:07 +1000 Subject: [PATCH] feat(studio): rename Replication to Pipelines (#50637) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What kind of change does this PR introduce? Feature and docs update. ## What is the current behavior? The Dashboard lists Pipelines destinations under Database > Replication. Read replicas have moved to Infrastructure, but the temporary notices remain on the destinations page and new destination sheet. Closes PIPE-1021. ## What is the new behavior? The canonical Dashboard routes are Database > Pipelines, while legacy Replication list and detail URLs permanently redirect to the equivalent Pipelines routes. Navigation, command palette, shortcuts, pipeline links, docs, and current marketing copy use Pipelines. Read-replica notices and their obsolete dismissal state are removed. | Before | After | | --- | --- | | Replication Database Agua Basket
Supabase | 2540 | The Management API, pipeline behaviour, replication logs, and Postgres replication terminology remain unchanged. ## To test - Open `/project//database/pipelines` and confirm the Database navigation, page header, and pipeline breadcrumb say Pipelines. - Open `/project//database/replication?source=bookmark#destinations` and a legacy pipeline detail URL. Confirm each redirects to the matching Pipelines URL while preserving parameters and fragments. - From the Pipelines page, open Add destination. Confirm no read-replica migration notice appears. - Open the Pipelines guide and confirm its Dashboard steps lead to Database > Pipelines. ## Before merge - [ ] Get changelog entry reviewed https://github.com/supabase/changelog/pull/262 and prepare to merge simultaneously ## Summary by CodeRabbit - **New Features** - Added dedicated **Database > Pipelines** pages for pipeline lists and details. - Added permanent redirects from legacy Replication URLs to their corresponding Pipelines pages. - Read replica management links now open **Settings > Infrastructure**. - **Documentation** - Updated Pipelines setup, monitoring, troubleshooting, and usage guidance to reference the current dashboard locations. - Updated Realtime guidance to use **Database > Publications**. - **Updates** - Renamed dashboard navigation, breadcrumbs, commands, and keyboard shortcuts from **Replication** to **Pipelines**. - Removed the “Read replicas have moved” notification. --------- Co-authored-by: Joshen Lim --- .../database/replication/pipelines-faq.mdx | 2 +- .../replication/pipelines-monitoring.mdx | 4 +- .../guides/database/replication/pipelines.mdx | 4 +- .../platform/manage-your-usage/pipelines.mdx | 2 +- ...ltime-postgres-changes-troubleshooting.mdx | 4 +- apps/studio/TANSTACK_MIGRATION.md | 6 +- .../Database/Backups/PITR/PITRSelection.tsx | 2 +- .../DestinationTypeSelection.test.tsx | 43 ----- .../DestinationTypeSelection.tsx | 2 - .../ReadReplicasMovedCallout.test.tsx | 66 ------- .../ReadReplicasMovedCallout.tsx | 50 ------ .../Replication/DestinationRow.test.tsx | 12 +- .../Database/Replication/DestinationRow.tsx | 2 +- .../ReplicationPipelineLayout.test.tsx | 4 +- .../Replication/ReplicationPipelineLayout.tsx | 6 +- .../Database/Replication/RowMenu.tsx | 2 +- .../Infrastructure/UpgradeWarnings.tsx | 2 +- .../NamespaceWithTables/TableRowComponent.tsx | 2 +- .../DatabaseLayout/Database.Commands.tsx | 6 +- .../DatabaseLayout/DatabaseMenu.utils.tsx | 6 +- ...licationLayout.tsx => PipelinesLayout.tsx} | 4 +- .../[pipelineId].tsx | 12 +- .../{replication => pipelines}/index.tsx | 18 +- .../replication/replica/[replicaId].tsx | 34 ---- apps/studio/redirects.shared.test.ts | 27 +++ apps/studio/redirects.shared.ts | 10 ++ apps/studio/routeTree.gen.ts | 167 ++++++++---------- .../{replication.tsx => pipelines.tsx} | 8 +- .../$ref/database/pipelines/$pipelineId.tsx | 11 ++ .../project/$ref/database/pipelines/index.tsx | 11 ++ .../$ref/database/replication/$pipelineId.tsx | 11 -- .../$ref/database/replication/index.tsx | 11 -- .../replication/replica/$replicaId.tsx | 11 -- .../state/shortcuts/registry/database-nav.ts | 2 +- ...5-12-02-introducing-supabase-pipelines.mdx | 2 +- apps/www/data/features.tsx | 2 +- packages/common/constants/local-storage.ts | 4 - 37 files changed, 187 insertions(+), 385 deletions(-) delete mode 100644 apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicasMovedCallout.test.tsx delete mode 100644 apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicasMovedCallout.tsx rename apps/studio/components/layouts/DatabaseLayout/{ReplicationLayout.tsx => PipelinesLayout.tsx} (77%) rename apps/studio/pages/project/[ref]/database/{replication => pipelines}/[pipelineId].tsx (76%) rename apps/studio/pages/project/[ref]/database/{replication => pipelines}/index.tsx (85%) delete mode 100644 apps/studio/pages/project/[ref]/database/replication/replica/[replicaId].tsx rename apps/studio/routes/project/$ref/database/{replication.tsx => pipelines.tsx} (68%) create mode 100644 apps/studio/routes/project/$ref/database/pipelines/$pipelineId.tsx create mode 100644 apps/studio/routes/project/$ref/database/pipelines/index.tsx delete mode 100644 apps/studio/routes/project/$ref/database/replication/$pipelineId.tsx delete mode 100644 apps/studio/routes/project/$ref/database/replication/index.tsx delete mode 100644 apps/studio/routes/project/$ref/database/replication/replica/$replicaId.tsx diff --git a/apps/docs/content/guides/database/replication/pipelines-faq.mdx b/apps/docs/content/guides/database/replication/pipelines-faq.mdx index 53cc52fb01e..c723e019561 100644 --- a/apps/docs/content/guides/database/replication/pipelines-faq.mdx +++ b/apps/docs/content/guides/database/replication/pipelines-faq.mdx @@ -10,7 +10,7 @@ sidebar_label: 'FAQ' ## Which plans support Pipelines? -Pipelines requires a Pro, Team, or Enterprise plan. During public alpha, availability varies by organization; an eligible plan does not guarantee access. If unavailable, request access from **Database > Replication** or contact your account manager. +Pipelines requires a Pro, Team, or Enterprise plan. During public alpha, availability varies by organization; an eligible plan does not guarantee access. If unavailable, request access from **Database > Pipelines** or contact your account manager. ## What destinations are supported? diff --git a/apps/docs/content/guides/database/replication/pipelines-monitoring.mdx b/apps/docs/content/guides/database/replication/pipelines-monitoring.mdx index e943b76b23c..c69c786fdf0 100644 --- a/apps/docs/content/guides/database/replication/pipelines-monitoring.mdx +++ b/apps/docs/content/guides/database/replication/pipelines-monitoring.mdx @@ -12,7 +12,7 @@ Use the Dashboard to check [replication progress](#viewing-detailed-pipeline-met ## Viewing pipeline status -Open [**Database > Replication**](/dashboard/project/_/database/replication) to see each destination's pipeline status. +Open [**Database > Pipelines**](/dashboard/project/_/database/pipelines) to see each destination's pipeline status. ### Pipeline states @@ -163,7 +163,7 @@ When you restart table replication: The pipeline stops temporarily to apply the table restart. The Dashboard restarts it automatically, or starts it if it was stopped. Replication for other tables is paused during this process, and their unfinished initial syncs can restart from scratch. -Before restarting, use **Edit pipeline** to check the **Initial sync** selection. Include any affected tables whose existing source rows you need to copy again, then apply your changes. Open the pipeline from the list on **Database > Replication**. +Before restarting, use **Edit pipeline** to check the **Initial sync** selection. Include any affected tables whose existing source rows you need to copy again, then apply your changes. Open the pipeline from the list on **Database > Pipelines**. ### Restart a single table diff --git a/apps/docs/content/guides/database/replication/pipelines.mdx b/apps/docs/content/guides/database/replication/pipelines.mdx index 5e031e5913d..71390159c34 100644 --- a/apps/docs/content/guides/database/replication/pipelines.mdx +++ b/apps/docs/content/guides/database/replication/pipelines.mdx @@ -47,7 +47,7 @@ Pipelines installs an `etl` schema and a database event trigger to track replica -1. Navigate to the [**Database > Replication**](/dashboard/project/_/database/replication) section of the Dashboard +1. Navigate to the [**Database > Pipelines**](/dashboard/project/_/database/pipelines) section of the Dashboard 2. Click **Add pipeline** to show the replication side panel 3. Select a destination available to your organization 4. If Pipelines is not yet enabled, click **Enable Pipelines**, review the dialog, and confirm **Enable Pipelines**. @@ -175,7 +175,7 @@ If the main replication slot is lost and **Recreate slot** is enabled, startup r ### Disabling Pipelines -Delete all pipelines first. Then open the three-dot actions menu on the Replication page and click **Disable Pipelines**. +Delete all pipelines first. Then open the three-dot actions menu on the Pipelines page and click **Disable Pipelines**. For cleanup details, see [What happens when you disable Pipelines?](/docs/guides/database/replication/pipelines-faq#what-happens-when-you-disable-pipelines). diff --git a/apps/docs/content/guides/platform/manage-your-usage/pipelines.mdx b/apps/docs/content/guides/platform/manage-your-usage/pipelines.mdx index 2325101bf3c..b5c2b5b0fc6 100644 --- a/apps/docs/content/guides/platform/manage-your-usage/pipelines.mdx +++ b/apps/docs/content/guides/platform/manage-your-usage/pipelines.mdx @@ -84,7 +84,7 @@ Pipeline hours are billed in arrears. Deleting the pipeline after 24 hours ends - Include only the tables and columns that you need at the destination. - Keep high-churn tables out of the publication when their changes are not needed for analytics. -- If you no longer require replication, delete the pipeline through your [project's replication settings](/dashboard/project/_/database/replication) to stop pipeline-hour charges. +- If you no longer require replication, delete the pipeline through your [project's Pipelines settings](/dashboard/project/_/database/pipelines) to stop pipeline-hour charges. ## How data processed is measured diff --git a/apps/docs/content/troubleshooting/realtime-postgres-changes-troubleshooting.mdx b/apps/docs/content/troubleshooting/realtime-postgres-changes-troubleshooting.mdx index 2d5bcfa2608..04881ce20e7 100644 --- a/apps/docs/content/troubleshooting/realtime-postgres-changes-troubleshooting.mdx +++ b/apps/docs/content/troubleshooting/realtime-postgres-changes-troubleshooting.mdx @@ -27,7 +27,7 @@ If the table's missing from the results: alter publication supabase_realtime add table your_table; ``` -Or toggle it on from **Database → Replication** in the dashboard. +Or toggle it on from **Database → Publications** in the dashboard. This gets overlooked on a table created recently — creating the table and enabling Realtime on it are two separate steps: @@ -203,7 +203,7 @@ channel.subscribe(async (status) => { Sometimes the answer is straightforward. Check: - **Project Settings → Realtime** — enabled at the project level? -- **Database → Replication** — toggle on for this specific table? +- **Database → Publications** — toggle on for this specific table? Check this again after a project's been paused and restarted — the replication slot can need to reconnect. If the project's under heavier load than usual, also check the Realtime "Concurrent Peak Connections" quota — hitting that limit can look a lot like a broken subscription. diff --git a/apps/studio/TANSTACK_MIGRATION.md b/apps/studio/TANSTACK_MIGRATION.md index 07db3d5658b..1ef32b7e503 100644 --- a/apps/studio/TANSTACK_MIGRATION.md +++ b/apps/studio/TANSTACK_MIGRATION.md @@ -85,7 +85,7 @@ These are the layout-only TanStack files. Most hold a single product layout comp - [x] `routes/project/$ref.tsx` — DefaultLayout only. **Delta vs plan:** ProjectLayoutWithAuth omitted from the shell because product layouts (DatabaseLayout, AuthLayout, StorageLayout, …) already render `withAuth(... ProjectLayout ...)` internally — adding it here would double-wrap. The home page (`/project/$ref/index.tsx`) wraps itself in `ProjectLayoutWithAuth` since it has no product layout. - [x] `routes/project/$ref/database.tsx` — DatabaseLayout (reads `databaseLayoutTitle` from leaf `staticData`) - [x] `routes/project/$ref/database/triggers.tsx` — sub-shell with `PageLayout` + permission gate + nav items, inlined from `DatabaseTriggersLayout`. **Delta vs plan:** the existing `DatabaseTriggersLayout` component wraps `` internally, so re-using it inside the database.tsx shell would double-wrap. Inlined the inner part instead; the Next-side component is left untouched (still used by the `pages/...` files we re-export). -- [x] `routes/project/$ref/database/replication.tsx` — sub-shell providing `PipelineRequestStatusProvider`, mirrors `ReplicationLayout` on the Next side. Sets `databaseLayoutTitle: 'Replication'` for the whole subtree (leaf routes no longer redeclare it) so the provider stays a single instance across navigation between `replication/index`, `replication/$pipelineId`, and `replication/replica/$replicaId` — those three leaves all read pipeline start/stop state via `usePipelineRequestStatus`, which previously lived on `DatabaseLayout` itself and mounted for every non-Replication Database page too. +- [x] `routes/project/$ref/database/pipelines.tsx` — sub-shell providing `PipelineRequestStatusProvider`, mirrors `PipelinesLayout` on the Next side. Sets `databaseLayoutTitle: 'Pipelines'` for the whole subtree so the provider stays a single instance across navigation between the Pipelines list and detail routes. Legacy Replication routes are retained only for redirects, while the replica detail route redirects to Infrastructure. - [x] `routes/project/$ref/auth.tsx` — AuthLayout (reads `authLayoutTitle` from leaf `staticData`). **Delta vs plan:** shell honours a `skipAuthLayout: true` opt-out in `staticData` for leaves whose own body or sub-layout already wraps in `AuthLayout` (`AuthProvidersLayout`, `AuthEmailsLayout`, `pages/.../auth/third-party.tsx`) — without it those routes would double-wrap (which also doubles `withAuth` + `ProjectLayout`). - ~~`routes/project/$ref/auth/templates.tsx` — AuthEmailsLayout~~ **Delta vs plan: not landed.** A unified `templates.tsx` sub-shell would force `templates/$templateId.tsx` (which uses plain `AuthLayout`, not `AuthEmailsLayout`) into the wrong wrapping. Instead `templates/index.tsx` and `auth/smtp.tsx` each set `skipAuthLayout: true` and wrap themselves in `AuthEmailsLayout`; `templates/$templateId.tsx` uses the standard auth shell with `authLayoutTitle: 'Emails'`. - [x] `routes/project/$ref/storage.tsx` — StorageLayout + StorageBucketsLayout (reads `storageLayoutTitle`, optional `skipStorageBucketsLayout`, `storageBucketsLayoutTitle`, `storageBucketsLayoutHideSubtitle` from leaf `staticData`). **Delta vs plan:** the shell wraps in BOTH StorageLayout and StorageBucketsLayout by default — every storage page except bucket-detail pages uses both. Bucket-detail pages set `skipStorageBucketsLayout: true`. `/storage/s3` uses `storageBucketsLayout{Title,HideSubtitle}` to override the inner header. @@ -182,8 +182,8 @@ These are the layout-only TanStack files. Most hold a single product layout comp - [x] A `routes/project/$ref/database/tables/$id.tsx` ← `pages/project/[ref]/database/tables/[id].tsx` - [x] A `routes/project/$ref/database/publications/index.tsx` ← `pages/project/[ref]/database/publications/index.tsx` - [x] A `routes/project/$ref/database/publications/$id.tsx` ← `pages/project/[ref]/database/publications/[id].tsx` -- [x] A `routes/project/$ref/database/replication/index.tsx` ← `pages/project/[ref]/database/replication/index.tsx` -- [x] A `routes/project/$ref/database/replication/$pipelineId.tsx` ← `pages/project/[ref]/database/replication/[pipelineId].tsx` +- [x] A `routes/project/$ref/database/pipelines/index.tsx` ← `pages/project/[ref]/database/pipelines/index.tsx` +- [x] A `routes/project/$ref/database/pipelines/$pipelineId.tsx` ← `pages/project/[ref]/database/pipelines/[pipelineId].tsx` - [x] A `routes/project/$ref/database/replication/replica/$replicaId.tsx` ← `pages/project/[ref]/database/replication/replica/[replicaId].tsx` (redirects to Infrastructure) - [x] A `routes/project/$ref/database/triggers/index.tsx` ← `pages/project/[ref]/database/triggers/index.tsx` - [x] A `routes/project/$ref/database/triggers/data.tsx` ← `pages/project/[ref]/database/triggers/data.tsx` (sub-shell at `database/triggers.tsx` provides PageLayout + nav, parent shell provides DatabaseLayout) diff --git a/apps/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx b/apps/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx index 2721d07f7f0..fbc58643165 100644 --- a/apps/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx +++ b/apps/studio/components/interfaces/Database/Backups/PITR/PITRSelection.tsx @@ -101,7 +101,7 @@ export const PITRSelection = () => {
diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationTypeSelection.test.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationTypeSelection.test.tsx index 178ddfbab7d..448552370ab 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationTypeSelection.test.tsx +++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationTypeSelection.test.tsx @@ -30,14 +30,6 @@ vi.mock('../useIsETLPrivateAlpha', () => ({ useIsETLClickHousePrivateAlpha: () => mockClickHouseEnabled(), })) -const mockInfrastructureReadReplicas = vi.fn(() => true) - -vi.mock('@/hooks/misc/useIsFeatureEnabled', () => ({ - useIsFeatureEnabled: () => ({ - infrastructureReadReplicas: mockInfrastructureReadReplicas(), - }), -})) - // Background queries from useDestinationInformation (sources + pipelines fire // even in create mode). Prevent retries so unmatched handlers fail fast. vi.mock('@/data/replication/utils', () => ({ @@ -59,7 +51,6 @@ const addBackgroundMocks = () => { describe('DestinationTypeSelection', () => { beforeEach(() => { - mockInfrastructureReadReplicas.mockReturnValue(true) window.localStorage.clear() }) @@ -162,39 +153,5 @@ describe('DestinationTypeSelection', () => { customRender(, { nuqs: { searchParams: { edit: '1' } } }) expect(await screen.findByRole('combobox')).toBeDisabled() - expect(screen.queryByText('Read replicas have moved')).not.toBeInTheDocument() - }) - - test('shows a callout pointing read replicas to Infrastructure in create mode', async () => { - mockBigQueryEnabled.mockReturnValue(false) - mockIcebergEnabled.mockReturnValue(false) - mockDucklakeEnabled.mockReturnValue(false) - mockSnowflakeEnabled.mockReturnValue(false) - mockClickHouseEnabled.mockReturnValue(false) - mockInfrastructureReadReplicas.mockReturnValue(true) - addBackgroundMocks() - - customRender() - - expect(await screen.findByText('Read replicas have moved')).toBeInTheDocument() - expect(screen.getByRole('link', { name: 'Go to Infrastructure' })).toHaveAttribute( - 'href', - expect.stringContaining('/settings/infrastructure') - ) - }) - - test('hides the read replicas callout when Infrastructure read replicas are disabled', async () => { - mockBigQueryEnabled.mockReturnValue(false) - mockIcebergEnabled.mockReturnValue(false) - mockDucklakeEnabled.mockReturnValue(false) - mockSnowflakeEnabled.mockReturnValue(false) - mockClickHouseEnabled.mockReturnValue(false) - mockInfrastructureReadReplicas.mockReturnValue(false) - addBackgroundMocks() - - customRender() - - expect(await screen.findByText('Select a destination type')).toBeInTheDocument() - expect(screen.queryByText('Read replicas have moved')).not.toBeInTheDocument() }) }) diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationTypeSelection.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationTypeSelection.tsx index 955e9616356..4747a703566 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationTypeSelection.tsx +++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationTypeSelection.tsx @@ -20,7 +20,6 @@ import { useIsETLSnowflakePrivateAlpha, } from '../useIsETLPrivateAlpha' import { DestinationType } from './DestinationPanel.types' -import { ReadReplicasMovedCallout } from './ReadReplicasMovedCallout' interface DestinationTypeOption { value: DestinationType @@ -193,7 +192,6 @@ export const DestinationTypeSelection = () => { - {!editMode && } ) } diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicasMovedCallout.test.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicasMovedCallout.test.tsx deleted file mode 100644 index 9a32598a717..00000000000 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicasMovedCallout.test.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { screen } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { LOCAL_STORAGE_KEYS } from 'common' -import { beforeEach, describe, expect, test, vi } from 'vitest' - -import { ReadReplicasMovedCallout } from './ReadReplicasMovedCallout' -import { customRender } from '@/tests/lib/custom-render' - -const mockInfrastructureReadReplicas = vi.fn(() => true) - -vi.mock('@/hooks/misc/useIsFeatureEnabled', () => ({ - useIsFeatureEnabled: () => ({ - infrastructureReadReplicas: mockInfrastructureReadReplicas(), - }), -})) - -describe('ReadReplicasMovedCallout', () => { - beforeEach(() => { - mockInfrastructureReadReplicas.mockReturnValue(true) - window.localStorage.clear() - }) - - test('renders the notice with a link to Infrastructure', async () => { - customRender() - - expect(await screen.findByText('Read replicas have moved')).toBeInTheDocument() - expect(screen.getByRole('link', { name: 'Go to Infrastructure' })).toHaveAttribute( - 'href', - expect.stringContaining('/settings/infrastructure') - ) - }) - - test('hides after dismiss and persists via localStorage', async () => { - const user = userEvent.setup() - customRender() - - expect(await screen.findByText('Read replicas have moved')).toBeInTheDocument() - await user.click(screen.getByRole('button', { name: 'Dismiss read replicas moved notice' })) - - expect(screen.queryByText('Read replicas have moved')).not.toBeInTheDocument() - expect( - window.localStorage.getItem( - LOCAL_STORAGE_KEYS.READ_REPLICAS_MOVED_CALLOUT_DISMISSED('default') - ) - ).toBe('true') - }) - - test('stays hidden when previously dismissed', async () => { - window.localStorage.setItem( - LOCAL_STORAGE_KEYS.READ_REPLICAS_MOVED_CALLOUT_DISMISSED('default'), - 'true' - ) - - customRender() - - await expect(screen.findByText('Read replicas have moved')).rejects.toThrow() - }) - - test('hides when Infrastructure read replicas are disabled', () => { - mockInfrastructureReadReplicas.mockReturnValue(false) - - customRender() - - expect(screen.queryByText('Read replicas have moved')).not.toBeInTheDocument() - }) -}) diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicasMovedCallout.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicasMovedCallout.tsx deleted file mode 100644 index fdb46db5422..00000000000 --- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicasMovedCallout.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { LOCAL_STORAGE_KEYS, useParams } from 'common' -import { X } from 'lucide-react' -import Link from 'next/link' -import { Button } from 'ui' -import { Admonition } from 'ui-patterns/Admonition' - -import { getInfrastructurePath } from '@/components/interfaces/Settings/Infrastructure/Infrastructure.utils' -import { ButtonTooltip } from '@/components/ui/ButtonTooltip' -import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' -import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage' - -/** Shown while muscle-memory still opens Database → Replication for replicas. */ -export const ReadReplicasMovedCallout = ({ className }: { className?: string }) => { - const { ref: projectRef } = useParams() - const { infrastructureReadReplicas } = useIsFeatureEnabled(['infrastructure:read_replicas']) - const [isDismissed, setIsDismissed, { isSuccess: isDismissalLoaded }] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.READ_REPLICAS_MOVED_CALLOUT_DISMISSED(projectRef ?? 'unknown'), - false - ) - - if (!projectRef || !infrastructureReadReplicas || !isDismissalLoaded || isDismissed) { - return null - } - - return ( -
- - - } - variant="text" - className="w-6" - tooltip={{ content: { side: 'bottom', text: 'Dismiss' } }} - aria-label="Dismiss read replicas moved notice" - onClick={() => setIsDismissed(true)} - /> - - } - /> -
- ) -} diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationRow.test.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationRow.test.tsx index 6e564842dcd..24d0c73b802 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationRow.test.tsx +++ b/apps/studio/components/interfaces/Database/Replication/DestinationRow.test.tsx @@ -147,7 +147,7 @@ describe('DestinationRow', () => { test('waits for asynchronous shutdown before deleting the pipeline', async () => { addAllMocks() - routerMock.setCurrentUrl('/project/default/database/replication') + routerMock.setCurrentUrl('/project/default/database/pipelines') let isStopping = false let completeShutdown: () => void = () => {} const shutdown = new Promise((resolve) => { @@ -214,7 +214,7 @@ describe('DestinationRow', () => { test('keeps deletion retryable when shutdown status cannot be verified', async () => { addAllMocks() - routerMock.setCurrentUrl('/project/default/database/replication') + routerMock.setCurrentUrl('/project/default/database/pipelines') let isStopping = false const deleted = vi.fn() addAPIMock({ @@ -275,7 +275,7 @@ describe('DestinationRow', () => { test('navigates to the pipeline when the row is clicked', async () => { addAllMocks() - routerMock.setCurrentUrl('/project/default/database/replication') + routerMock.setCurrentUrl('/project/default/database/pipelines') customRender() @@ -283,19 +283,19 @@ describe('DestinationRow', () => { expect(row).not.toBeNull() await userEvent.click(row!) - expect(routerMock.asPath).toBe(`/project/default/database/replication/${PIPELINE_ID}`) + expect(routerMock.asPath).toBe(`/project/default/database/pipelines/${PIPELINE_ID}`) }) test('does not navigate when the row overflow menu is opened', async () => { addAllMocks() - routerMock.setCurrentUrl('/project/default/database/replication') + routerMock.setCurrentUrl('/project/default/database/pipelines') customRender() await screen.findByText('supabase_realtime') await userEvent.click(screen.getByRole('button', { name: 'Pipeline options' })) - expect(routerMock.asPath).toBe('/project/default/database/replication') + expect(routerMock.asPath).toBe('/project/default/database/pipelines') }) test('shows "Caught up" when confirmed_flush_lsn_bytes is 0', async () => { diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationRow.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationRow.tsx index 13642b71984..7766862c6da 100644 --- a/apps/studio/components/interfaces/Database/Replication/DestinationRow.tsx +++ b/apps/studio/components/interfaces/Database/Replication/DestinationRow.tsx @@ -105,7 +105,7 @@ export const DestinationRow = ({ destinationId }: DestinationRowProps) => { const hasUpdate = Boolean(versionData?.new_version) const handleNavigation = pipeline - ? createNavigationHandler(`/project/${projectRef}/database/replication/${pipeline.id}`, router) + ? createNavigationHandler(`/project/${projectRef}/database/pipelines/${pipeline.id}`, router) : undefined const onDeleteClick = async () => { diff --git a/apps/studio/components/interfaces/Database/Replication/ReplicationPipelineLayout.test.tsx b/apps/studio/components/interfaces/Database/Replication/ReplicationPipelineLayout.test.tsx index bdae345e2d1..9c48dcf2a57 100644 --- a/apps/studio/components/interfaces/Database/Replication/ReplicationPipelineLayout.test.tsx +++ b/apps/studio/components/interfaces/Database/Replication/ReplicationPipelineLayout.test.tsx @@ -203,9 +203,9 @@ describe('ReplicationPipelineLayout', () => { renderLayout(
Overview content
) expect(await screen.findByRole('heading', { name: 'Analytics warehouse' })).toBeVisible() - expect(screen.getByRole('link', { name: 'Replication' })).toHaveAttribute( + expect(screen.getByRole('link', { name: 'Pipelines' })).toHaveAttribute( 'href', - '/project/default/database/replication' + '/project/default/database/pipelines' ) expect(screen.getByRole('link', { name: 'View logs' }).getAttribute('href')).toContain( 'pipeline_id' diff --git a/apps/studio/components/interfaces/Database/Replication/ReplicationPipelineLayout.tsx b/apps/studio/components/interfaces/Database/Replication/ReplicationPipelineLayout.tsx index a7f3f18f8d6..bff037701c2 100644 --- a/apps/studio/components/interfaces/Database/Replication/ReplicationPipelineLayout.tsx +++ b/apps/studio/components/interfaces/Database/Replication/ReplicationPipelineLayout.tsx @@ -196,7 +196,7 @@ export const ReplicationPipelineLayout = ({ children }: PropsWithChildren) => { }) setShowDeleteDestination(false) toast.success(`Deleted pipeline "${pipeline.destination_name}"`) - router.push(`/project/${projectRef}/database/replication`) + router.push(`/project/${projectRef}/database/pipelines`) } catch (error) { toast.error(`Failed to delete pipeline: ${(error as ResponseError).message}`) } finally { @@ -215,7 +215,7 @@ export const ReplicationPipelineLayout = ({ children }: PropsWithChildren) => { slotClassName="sticky top-0 z-20 bg-sidebar" actions={ - + @@ -225,7 +225,7 @@ export const ReplicationPipelineLayout = ({ children }: PropsWithChildren) => { - Replication + Pipelines diff --git a/apps/studio/components/interfaces/Database/Replication/RowMenu.tsx b/apps/studio/components/interfaces/Database/Replication/RowMenu.tsx index 7f5de5d01f7..35fb8b73edd 100644 --- a/apps/studio/components/interfaces/Database/Replication/RowMenu.tsx +++ b/apps/studio/components/interfaces/Database/Replication/RowMenu.tsx @@ -175,7 +175,7 @@ export const RowMenu = ({ - +

View details

diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/UpgradeWarnings.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/UpgradeWarnings.tsx index 5e38f99ed15..e46f572409b 100644 --- a/apps/studio/components/interfaces/Settings/Infrastructure/UpgradeWarnings.tsx +++ b/apps/studio/components/interfaces/Settings/Infrastructure/UpgradeWarnings.tsx @@ -21,7 +21,7 @@ export const ReadReplicasWarning = ({ latestPgVersion }: { latestPgVersion: stri description={`You will need to remove all read replicas prior to upgrading your Postgres version to the latest available (${latestPgVersion}).`} actions={ } /> diff --git a/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/NamespaceWithTables/TableRowComponent.tsx b/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/NamespaceWithTables/TableRowComponent.tsx index 226f45de9ca..3a088212579 100644 --- a/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/NamespaceWithTables/TableRowComponent.tsx +++ b/apps/studio/components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/NamespaceWithTables/TableRowComponent.tsx @@ -357,7 +357,7 @@ export const TableRowComponent = ({ table, schema, namespace }: TableRowComponen {!!inferredPostgresTable && (

View pipeline

diff --git a/apps/studio/components/layouts/DatabaseLayout/Database.Commands.tsx b/apps/studio/components/layouts/DatabaseLayout/Database.Commands.tsx index 8c3787ae22f..d3ccb8da7b7 100644 --- a/apps/studio/components/layouts/DatabaseLayout/Database.Commands.tsx +++ b/apps/studio/components/layouts/DatabaseLayout/Database.Commands.tsx @@ -89,9 +89,9 @@ export function useDatabaseGotoCommands(options?: CommandOptions) { ? [ { id: 'nav-database-replication', - name: 'Replication', - value: 'Database: Replication', - route: `/project/${ref}/database/replication`, + name: 'Pipelines', + value: 'Database: Pipelines', + route: `/project/${ref}/database/pipelines`, defaultHidden: true, } as IRouteCommand, ] diff --git a/apps/studio/components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx b/apps/studio/components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx index 3a24136e309..119f9736aac 100644 --- a/apps/studio/components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx +++ b/apps/studio/components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx @@ -123,9 +123,9 @@ export const useGenerateDatabaseMenu = (): ProductMenuGroup[] => { items: [ IS_PLATFORM && showPgReplicate && { - name: 'Replication', - key: 'replication', - url: getDatabaseURL('replication'), + name: 'Pipelines', + key: 'pipelines', + url: getDatabaseURL('pipelines'), label: enablePgReplicate ? 'New' : undefined, shortcutId: SHORTCUT_IDS.NAV_DATABASE_REPLICATION, }, diff --git a/apps/studio/components/layouts/DatabaseLayout/ReplicationLayout.tsx b/apps/studio/components/layouts/DatabaseLayout/PipelinesLayout.tsx similarity index 77% rename from apps/studio/components/layouts/DatabaseLayout/ReplicationLayout.tsx rename to apps/studio/components/layouts/DatabaseLayout/PipelinesLayout.tsx index 691bb26bd75..bae571053c6 100644 --- a/apps/studio/components/layouts/DatabaseLayout/ReplicationLayout.tsx +++ b/apps/studio/components/layouts/DatabaseLayout/PipelinesLayout.tsx @@ -4,11 +4,11 @@ import { PropsWithChildren } from 'react' import { DatabaseLayout } from './DatabaseLayout' import { PipelineRequestStatusProvider } from '@/state/replication-pipeline-request-status' -export const ReplicationLayout = ({ children }: PropsWithChildren) => { +export const PipelinesLayout = ({ children }: PropsWithChildren) => { const { ref: projectRef } = useParams() return ( - + {children} ) diff --git a/apps/studio/pages/project/[ref]/database/replication/[pipelineId].tsx b/apps/studio/pages/project/[ref]/database/pipelines/[pipelineId].tsx similarity index 76% rename from apps/studio/pages/project/[ref]/database/replication/[pipelineId].tsx rename to apps/studio/pages/project/[ref]/database/pipelines/[pipelineId].tsx index f7e385af40c..38b696b2431 100644 --- a/apps/studio/pages/project/[ref]/database/replication/[pipelineId].tsx +++ b/apps/studio/pages/project/[ref]/database/pipelines/[pipelineId].tsx @@ -5,11 +5,11 @@ import { useContext, useEffect } from 'react' import { ReplicationPipelineLayout } from '@/components/interfaces/Database/Replication/ReplicationPipelineLayout' import { ReplicationPipelineStatus } from '@/components/interfaces/Database/Replication/ReplicationPipelineStatus/ReplicationPipelineStatus' import { useIsETLPrivateAlpha } from '@/components/interfaces/Database/Replication/useIsETLPrivateAlpha' -import { ReplicationLayout } from '@/components/layouts/DatabaseLayout/ReplicationLayout' +import { PipelinesLayout } from '@/components/layouts/DatabaseLayout/PipelinesLayout' import { DefaultLayout } from '@/components/layouts/DefaultLayout' import type { NextPageWithLayout } from '@/types' -const DatabaseReplicationPage: NextPageWithLayout = () => { +const DatabasePipelinesPage: NextPageWithLayout = () => { const router = useRouter() const { ref: projectRef } = useParams() const { hasLoaded } = useContext(FeatureFlagContext) @@ -17,7 +17,7 @@ const DatabaseReplicationPage: NextPageWithLayout = () => { useEffect(() => { if (hasLoaded && !enablePgReplicate) { - router.replace(`/project/${projectRef}/database/replication`) + router.replace(`/project/${projectRef}/database/pipelines`) } }, [router, hasLoaded, projectRef, enablePgReplicate]) @@ -32,10 +32,10 @@ const DatabaseReplicationPage: NextPageWithLayout = () => { ) } -DatabaseReplicationPage.getLayout = (page) => ( +DatabasePipelinesPage.getLayout = (page) => ( - {page} + {page} ) -export default DatabaseReplicationPage +export default DatabasePipelinesPage diff --git a/apps/studio/pages/project/[ref]/database/replication/index.tsx b/apps/studio/pages/project/[ref]/database/pipelines/index.tsx similarity index 85% rename from apps/studio/pages/project/[ref]/database/replication/index.tsx rename to apps/studio/pages/project/[ref]/database/pipelines/index.tsx index d9e3cbd2b38..6c030934ed4 100644 --- a/apps/studio/pages/project/[ref]/database/replication/index.tsx +++ b/apps/studio/pages/project/[ref]/database/pipelines/index.tsx @@ -12,12 +12,11 @@ import { import { PageSection, PageSectionContent } from 'ui-patterns/PageSection' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' -import { ReadReplicasMovedCallout } from '@/components/interfaces/Database/Replication/DestinationPanel/ReadReplicasMovedCallout' import { Destinations } from '@/components/interfaces/Database/Replication/Destinations' import { PIPELINES_FEEDBACK_URL } from '@/components/interfaces/Database/Replication/Replication.constants' import { ReplicationDiagram } from '@/components/interfaces/Database/Replication/ReplicationDiagram' import { InstanceConfiguration } from '@/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration' -import { ReplicationLayout } from '@/components/layouts/DatabaseLayout/ReplicationLayout' +import { PipelinesLayout } from '@/components/layouts/DatabaseLayout/PipelinesLayout' import { DefaultLayout } from '@/components/layouts/DefaultLayout' import { DocsButton } from '@/components/ui/DocsButton' import { UnknownInterface } from '@/components/ui/UnknownInterface' @@ -27,7 +26,7 @@ import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { DOCS_URL } from '@/lib/constants' import type { NextPageWithLayout } from '@/types' -const DatabaseReplicationPage: NextPageWithLayout = () => { +const DatabasePipelinesPage: NextPageWithLayout = () => { const { data: selectedProject, isPending } = useSelectedProjectQuery() const { isHighAvailability } = useHighAvailability() const showPgReplicate = useIsFeatureEnabled('database:replication') @@ -42,7 +41,7 @@ const DatabaseReplicationPage: NextPageWithLayout = () => { - Replication + Pipelines High Availability cluster topology @@ -66,7 +65,7 @@ const DatabaseReplicationPage: NextPageWithLayout = () => { - Replication + Pipelines Send data to external destinations @@ -76,7 +75,7 @@ const DatabaseReplicationPage: NextPageWithLayout = () => { Leave feedback - + @@ -87,7 +86,6 @@ const DatabaseReplicationPage: NextPageWithLayout = () => { ) : ( - @@ -98,10 +96,10 @@ const DatabaseReplicationPage: NextPageWithLayout = () => { ) } -DatabaseReplicationPage.getLayout = (page) => ( +DatabasePipelinesPage.getLayout = (page) => ( - {page} + {page} ) -export default DatabaseReplicationPage +export default DatabasePipelinesPage diff --git a/apps/studio/pages/project/[ref]/database/replication/replica/[replicaId].tsx b/apps/studio/pages/project/[ref]/database/replication/replica/[replicaId].tsx deleted file mode 100644 index ab3d428fb00..00000000000 --- a/apps/studio/pages/project/[ref]/database/replication/replica/[replicaId].tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { useParams } from 'common' -import { useRouter } from 'next/router' -import { useEffect } from 'react' -import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' - -import { getReadReplicaPath } from '@/components/interfaces/Settings/Infrastructure/Infrastructure.utils' -import { ReplicationLayout } from '@/components/layouts/DatabaseLayout/ReplicationLayout' -import { DefaultLayout } from '@/components/layouts/DefaultLayout' -import type { NextPageWithLayout } from '@/types' - -/** @deprecated Redirects to Settings → Infrastructure replica detail. */ -const DatabaseReadReplicaRedirectPage: NextPageWithLayout = () => { - const router = useRouter() - const { ref, replicaId } = useParams() - - useEffect(() => { - if (!ref || !replicaId) return - router.replace(getReadReplicaPath(ref, replicaId)) - }, [ref, replicaId, router]) - - return ( -
- -
- ) -} - -DatabaseReadReplicaRedirectPage.getLayout = (page) => ( - - {page} - -) - -export default DatabaseReadReplicaRedirectPage diff --git a/apps/studio/redirects.shared.test.ts b/apps/studio/redirects.shared.test.ts index fa08c3a640a..128645cc631 100644 --- a/apps/studio/redirects.shared.test.ts +++ b/apps/studio/redirects.shared.test.ts @@ -79,6 +79,33 @@ describe('matchRedirect query/hash preservation', () => { }) }) + it('redirects the legacy replication list route to Pipelines while preserving query and hash', () => { + expect( + matchRedirect({ + pathname: '/project/abc/database/replication', + search: { source: 'bookmark' }, + isPlatform: true, + hash: 'destinations', + }) + ).toEqual({ + destination: '/project/abc/database/pipelines?source=bookmark#destinations', + permanent: true, + }) + }) + + it('redirects legacy pipeline detail URLs to Pipelines', () => { + expect( + matchRedirect({ + pathname: '/project/abc/database/replication/pipeline-1', + search: {}, + isPlatform: true, + }) + ).toEqual({ + destination: '/project/abc/database/pipelines/pipeline-1', + permanent: true, + }) + }) + it('redirects the legacy compute billing panel to the CPU section', () => { expect( matchRedirect({ diff --git a/apps/studio/redirects.shared.ts b/apps/studio/redirects.shared.ts index e3f2b6f6f53..a0c920a2661 100644 --- a/apps/studio/redirects.shared.ts +++ b/apps/studio/redirects.shared.ts @@ -124,6 +124,16 @@ export const SHARED_REDIRECTS: StudioRedirect[] = [ destination: '/project/:ref/settings/infrastructure/replica/:replicaId', permanent: true, }, + { + source: '/project/:ref/database/replication', + destination: '/project/:ref/database/pipelines', + permanent: true, + }, + { + source: '/project/:ref/database/replication/:pipelineId', + destination: '/project/:ref/database/pipelines/:pipelineId', + permanent: true, + }, { source: '/project/:ref/settings/billing/subscription', has: [{ type: 'query', key: 'panel', value: 'pitr' }], diff --git a/apps/studio/routeTree.gen.ts b/apps/studio/routeTree.gen.ts index 462138879cd..8ca051240cc 100644 --- a/apps/studio/routeTree.gen.ts +++ b/apps/studio/routeTree.gen.ts @@ -153,8 +153,8 @@ import { Route as ProjectRefDatabaseTriggersRouteImport } from './routes/project import { Route as ProjectRefDatabaseSettingsRouteImport } from './routes/project/$ref/database/settings' import { Route as ProjectRefDatabaseSchemasRouteImport } from './routes/project/$ref/database/schemas' import { Route as ProjectRefDatabaseRolesRouteImport } from './routes/project/$ref/database/roles' -import { Route as ProjectRefDatabaseReplicationRouteImport } from './routes/project/$ref/database/replication' import { Route as ProjectRefDatabasePoliciesRouteImport } from './routes/project/$ref/database/policies' +import { Route as ProjectRefDatabasePipelinesRouteImport } from './routes/project/$ref/database/pipelines' import { Route as ProjectRefDatabaseMigrationsRouteImport } from './routes/project/$ref/database/migrations' import { Route as ProjectRefDatabaseIndexesRouteImport } from './routes/project/$ref/database/indexes' import { Route as ProjectRefDatabaseFunctionsRouteImport } from './routes/project/$ref/database/functions' @@ -220,8 +220,8 @@ import { Route as ProjectRefIntegrationsIdIndexRouteImport } from './routes/proj import { Route as ProjectRefFunctionsFunctionSlugIndexRouteImport } from './routes/project/$ref/functions/$functionSlug/index' import { Route as ProjectRefDatabaseTriggersIndexRouteImport } from './routes/project/$ref/database/triggers/index' import { Route as ProjectRefDatabaseTablesIndexRouteImport } from './routes/project/$ref/database/tables/index' -import { Route as ProjectRefDatabaseReplicationIndexRouteImport } from './routes/project/$ref/database/replication/index' import { Route as ProjectRefDatabasePublicationsIndexRouteImport } from './routes/project/$ref/database/publications/index' +import { Route as ProjectRefDatabasePipelinesIndexRouteImport } from './routes/project/$ref/database/pipelines/index' import { Route as ProjectRefAuthTemplatesIndexRouteImport } from './routes/project/$ref/auth/templates/index' import { Route as ApiPlatformProjectsRefIndexRouteImport } from './routes/api/platform/projects/$ref/index' import { Route as AppOrgSlugWebhooksIndexRouteImport } from './routes/_app/org/$slug/webhooks/index' @@ -245,8 +245,8 @@ import { Route as ProjectRefExplorerChatIdRouteImport } from './routes/project/$ import { Route as ProjectRefDatabaseTriggersEventRouteImport } from './routes/project/$ref/database/triggers/event' import { Route as ProjectRefDatabaseTriggersDataRouteImport } from './routes/project/$ref/database/triggers/data' import { Route as ProjectRefDatabaseTablesIdRouteImport } from './routes/project/$ref/database/tables/$id' -import { Route as ProjectRefDatabaseReplicationPipelineIdRouteImport } from './routes/project/$ref/database/replication/$pipelineId' import { Route as ProjectRefDatabasePublicationsIdRouteImport } from './routes/project/$ref/database/publications/$id' +import { Route as ProjectRefDatabasePipelinesPipelineIdRouteImport } from './routes/project/$ref/database/pipelines/$pipelineId' import { Route as ProjectRefDatabaseBackupsScheduledRouteImport } from './routes/project/$ref/database/backups/scheduled' import { Route as ProjectRefDatabaseBackupsRestoreToNewProjectRouteImport } from './routes/project/$ref/database/backups/restore-to-new-project' import { Route as ProjectRefDatabaseBackupsPitrRouteImport } from './routes/project/$ref/database/backups/pitr' @@ -294,7 +294,6 @@ import { Route as ProjectRefStorageVectorsBucketsBucketIdRouteImport } from './r import { Route as ProjectRefStorageFilesBucketsBucketIdRouteImport } from './routes/project/$ref/storage/files/buckets/$bucketId' import { Route as ProjectRefStorageAnalyticsBucketsBucketIdRouteImport } from './routes/project/$ref/storage/analytics/buckets/$bucketId' import { Route as ProjectRefSettingsInfrastructureReplicaReplicaIdRouteImport } from './routes/project/$ref/settings/infrastructure/replica/$replicaId' -import { Route as ProjectRefDatabaseReplicationReplicaReplicaIdRouteImport } from './routes/project/$ref/database/replication/replica/$replicaId' import { Route as ApiV1ProjectsRefTypesTypescriptRouteImport } from './routes/api/v1/projects/$ref/types/typescript' import { Route as ApiV1ProjectsRefDatabaseMigrationsRouteImport } from './routes/api/v1/projects/$ref/database/migrations' import { Route as ApiV1ProjectsRefApiKeysIdRouteImport } from './routes/api/v1/projects/$ref/api-keys/$id' @@ -1102,18 +1101,18 @@ const ProjectRefDatabaseRolesRoute = ProjectRefDatabaseRolesRouteImport.update({ path: '/roles', getParentRoute: () => ProjectRefDatabaseRoute, } as any) -const ProjectRefDatabaseReplicationRoute = - ProjectRefDatabaseReplicationRouteImport.update({ - id: '/replication', - path: '/replication', - getParentRoute: () => ProjectRefDatabaseRoute, - } as any) const ProjectRefDatabasePoliciesRoute = ProjectRefDatabasePoliciesRouteImport.update({ id: '/policies', path: '/policies', getParentRoute: () => ProjectRefDatabaseRoute, } as any) +const ProjectRefDatabasePipelinesRoute = + ProjectRefDatabasePipelinesRouteImport.update({ + id: '/pipelines', + path: '/pipelines', + getParentRoute: () => ProjectRefDatabaseRoute, + } as any) const ProjectRefDatabaseMigrationsRoute = ProjectRefDatabaseMigrationsRouteImport.update({ id: '/migrations', @@ -1470,18 +1469,18 @@ const ProjectRefDatabaseTablesIndexRoute = path: '/tables/', getParentRoute: () => ProjectRefDatabaseRoute, } as any) -const ProjectRefDatabaseReplicationIndexRoute = - ProjectRefDatabaseReplicationIndexRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => ProjectRefDatabaseReplicationRoute, - } as any) const ProjectRefDatabasePublicationsIndexRoute = ProjectRefDatabasePublicationsIndexRouteImport.update({ id: '/publications/', path: '/publications/', getParentRoute: () => ProjectRefDatabaseRoute, } as any) +const ProjectRefDatabasePipelinesIndexRoute = + ProjectRefDatabasePipelinesIndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => ProjectRefDatabasePipelinesRoute, + } as any) const ProjectRefAuthTemplatesIndexRoute = ProjectRefAuthTemplatesIndexRouteImport.update({ id: '/templates/', @@ -1619,18 +1618,18 @@ const ProjectRefDatabaseTablesIdRoute = path: '/tables/$id', getParentRoute: () => ProjectRefDatabaseRoute, } as any) -const ProjectRefDatabaseReplicationPipelineIdRoute = - ProjectRefDatabaseReplicationPipelineIdRouteImport.update({ - id: '/$pipelineId', - path: '/$pipelineId', - getParentRoute: () => ProjectRefDatabaseReplicationRoute, - } as any) const ProjectRefDatabasePublicationsIdRoute = ProjectRefDatabasePublicationsIdRouteImport.update({ id: '/publications/$id', path: '/publications/$id', getParentRoute: () => ProjectRefDatabaseRoute, } as any) +const ProjectRefDatabasePipelinesPipelineIdRoute = + ProjectRefDatabasePipelinesPipelineIdRouteImport.update({ + id: '/$pipelineId', + path: '/$pipelineId', + getParentRoute: () => ProjectRefDatabasePipelinesRoute, + } as any) const ProjectRefDatabaseBackupsScheduledRoute = ProjectRefDatabaseBackupsScheduledRouteImport.update({ id: '/backups/scheduled', @@ -1910,12 +1909,6 @@ const ProjectRefSettingsInfrastructureReplicaReplicaIdRoute = path: '/infrastructure/replica/$replicaId', getParentRoute: () => ProjectRefSettingsRoute, } as any) -const ProjectRefDatabaseReplicationReplicaReplicaIdRoute = - ProjectRefDatabaseReplicationReplicaReplicaIdRouteImport.update({ - id: '/replica/$replicaId', - path: '/replica/$replicaId', - getParentRoute: () => ProjectRefDatabaseReplicationRoute, - } as any) const ApiV1ProjectsRefTypesTypescriptRoute = ApiV1ProjectsRefTypesTypescriptRouteImport.update({ id: '/api/v1/projects/$ref/types/typescript', @@ -2270,8 +2263,8 @@ export interface FileRoutesByFullPath { '/project/$ref/database/functions': typeof ProjectRefDatabaseFunctionsRoute '/project/$ref/database/indexes': typeof ProjectRefDatabaseIndexesRoute '/project/$ref/database/migrations': typeof ProjectRefDatabaseMigrationsRoute + '/project/$ref/database/pipelines': typeof ProjectRefDatabasePipelinesRouteWithChildren '/project/$ref/database/policies': typeof ProjectRefDatabasePoliciesRoute - '/project/$ref/database/replication': typeof ProjectRefDatabaseReplicationRouteWithChildren '/project/$ref/database/roles': typeof ProjectRefDatabaseRolesRoute '/project/$ref/database/schemas': typeof ProjectRefDatabaseSchemasRoute '/project/$ref/database/settings': typeof ProjectRefDatabaseSettingsRoute @@ -2371,8 +2364,8 @@ export interface FileRoutesByFullPath { '/project/$ref/database/backups/pitr': typeof ProjectRefDatabaseBackupsPitrRoute '/project/$ref/database/backups/restore-to-new-project': typeof ProjectRefDatabaseBackupsRestoreToNewProjectRoute '/project/$ref/database/backups/scheduled': typeof ProjectRefDatabaseBackupsScheduledRoute + '/project/$ref/database/pipelines/$pipelineId': typeof ProjectRefDatabasePipelinesPipelineIdRoute '/project/$ref/database/publications/$id': typeof ProjectRefDatabasePublicationsIdRoute - '/project/$ref/database/replication/$pipelineId': typeof ProjectRefDatabaseReplicationPipelineIdRoute '/project/$ref/database/tables/$id': typeof ProjectRefDatabaseTablesIdRoute '/project/$ref/database/triggers/data': typeof ProjectRefDatabaseTriggersDataRoute '/project/$ref/database/triggers/event': typeof ProjectRefDatabaseTriggersEventRoute @@ -2396,8 +2389,8 @@ export interface FileRoutesByFullPath { '/org/$slug/webhooks/': typeof AppOrgSlugWebhooksIndexRoute '/api/platform/projects/$ref/': typeof ApiPlatformProjectsRefIndexRoute '/project/$ref/auth/templates/': typeof ProjectRefAuthTemplatesIndexRoute + '/project/$ref/database/pipelines/': typeof ProjectRefDatabasePipelinesIndexRoute '/project/$ref/database/publications/': typeof ProjectRefDatabasePublicationsIndexRoute - '/project/$ref/database/replication/': typeof ProjectRefDatabaseReplicationIndexRoute '/project/$ref/database/tables/': typeof ProjectRefDatabaseTablesIndexRoute '/project/$ref/database/triggers/': typeof ProjectRefDatabaseTriggersIndexRoute '/project/$ref/functions/$functionSlug/': typeof ProjectRefFunctionsFunctionSlugIndexRoute @@ -2422,7 +2415,6 @@ export interface FileRoutesByFullPath { '/api/v1/projects/$ref/api-keys/$id': typeof ApiV1ProjectsRefApiKeysIdRoute '/api/v1/projects/$ref/database/migrations': typeof ApiV1ProjectsRefDatabaseMigrationsRoute '/api/v1/projects/$ref/types/typescript': typeof ApiV1ProjectsRefTypesTypescriptRoute - '/project/$ref/database/replication/replica/$replicaId': typeof ProjectRefDatabaseReplicationReplicaReplicaIdRoute '/project/$ref/settings/infrastructure/replica/$replicaId': typeof ProjectRefSettingsInfrastructureReplicaReplicaIdRoute '/project/$ref/storage/analytics/buckets/$bucketId': typeof ProjectRefStorageAnalyticsBucketsBucketIdRoute '/project/$ref/storage/files/buckets/$bucketId': typeof ProjectRefStorageFilesBucketsBucketIdRoute @@ -2679,8 +2671,8 @@ export interface FileRoutesByTo { '/project/$ref/database/backups/pitr': typeof ProjectRefDatabaseBackupsPitrRoute '/project/$ref/database/backups/restore-to-new-project': typeof ProjectRefDatabaseBackupsRestoreToNewProjectRoute '/project/$ref/database/backups/scheduled': typeof ProjectRefDatabaseBackupsScheduledRoute + '/project/$ref/database/pipelines/$pipelineId': typeof ProjectRefDatabasePipelinesPipelineIdRoute '/project/$ref/database/publications/$id': typeof ProjectRefDatabasePublicationsIdRoute - '/project/$ref/database/replication/$pipelineId': typeof ProjectRefDatabaseReplicationPipelineIdRoute '/project/$ref/database/tables/$id': typeof ProjectRefDatabaseTablesIdRoute '/project/$ref/database/triggers/data': typeof ProjectRefDatabaseTriggersDataRoute '/project/$ref/database/triggers/event': typeof ProjectRefDatabaseTriggersEventRoute @@ -2704,8 +2696,8 @@ export interface FileRoutesByTo { '/org/$slug/webhooks': typeof AppOrgSlugWebhooksIndexRoute '/api/platform/projects/$ref': typeof ApiPlatformProjectsRefIndexRoute '/project/$ref/auth/templates': typeof ProjectRefAuthTemplatesIndexRoute + '/project/$ref/database/pipelines': typeof ProjectRefDatabasePipelinesIndexRoute '/project/$ref/database/publications': typeof ProjectRefDatabasePublicationsIndexRoute - '/project/$ref/database/replication': typeof ProjectRefDatabaseReplicationIndexRoute '/project/$ref/database/tables': typeof ProjectRefDatabaseTablesIndexRoute '/project/$ref/database/triggers': typeof ProjectRefDatabaseTriggersIndexRoute '/project/$ref/functions/$functionSlug': typeof ProjectRefFunctionsFunctionSlugIndexRoute @@ -2730,7 +2722,6 @@ export interface FileRoutesByTo { '/api/v1/projects/$ref/api-keys/$id': typeof ApiV1ProjectsRefApiKeysIdRoute '/api/v1/projects/$ref/database/migrations': typeof ApiV1ProjectsRefDatabaseMigrationsRoute '/api/v1/projects/$ref/types/typescript': typeof ApiV1ProjectsRefTypesTypescriptRoute - '/project/$ref/database/replication/replica/$replicaId': typeof ProjectRefDatabaseReplicationReplicaReplicaIdRoute '/project/$ref/settings/infrastructure/replica/$replicaId': typeof ProjectRefSettingsInfrastructureReplicaReplicaIdRoute '/project/$ref/storage/analytics/buckets/$bucketId': typeof ProjectRefStorageAnalyticsBucketsBucketIdRoute '/project/$ref/storage/files/buckets/$bucketId': typeof ProjectRefStorageFilesBucketsBucketIdRoute @@ -2904,8 +2895,8 @@ export interface FileRoutesById { '/project/$ref/database/functions': typeof ProjectRefDatabaseFunctionsRoute '/project/$ref/database/indexes': typeof ProjectRefDatabaseIndexesRoute '/project/$ref/database/migrations': typeof ProjectRefDatabaseMigrationsRoute + '/project/$ref/database/pipelines': typeof ProjectRefDatabasePipelinesRouteWithChildren '/project/$ref/database/policies': typeof ProjectRefDatabasePoliciesRoute - '/project/$ref/database/replication': typeof ProjectRefDatabaseReplicationRouteWithChildren '/project/$ref/database/roles': typeof ProjectRefDatabaseRolesRoute '/project/$ref/database/schemas': typeof ProjectRefDatabaseSchemasRoute '/project/$ref/database/settings': typeof ProjectRefDatabaseSettingsRoute @@ -3005,8 +2996,8 @@ export interface FileRoutesById { '/project/$ref/database/backups/pitr': typeof ProjectRefDatabaseBackupsPitrRoute '/project/$ref/database/backups/restore-to-new-project': typeof ProjectRefDatabaseBackupsRestoreToNewProjectRoute '/project/$ref/database/backups/scheduled': typeof ProjectRefDatabaseBackupsScheduledRoute + '/project/$ref/database/pipelines/$pipelineId': typeof ProjectRefDatabasePipelinesPipelineIdRoute '/project/$ref/database/publications/$id': typeof ProjectRefDatabasePublicationsIdRoute - '/project/$ref/database/replication/$pipelineId': typeof ProjectRefDatabaseReplicationPipelineIdRoute '/project/$ref/database/tables/$id': typeof ProjectRefDatabaseTablesIdRoute '/project/$ref/database/triggers/data': typeof ProjectRefDatabaseTriggersDataRoute '/project/$ref/database/triggers/event': typeof ProjectRefDatabaseTriggersEventRoute @@ -3030,8 +3021,8 @@ export interface FileRoutesById { '/_app/org/$slug/webhooks/': typeof AppOrgSlugWebhooksIndexRoute '/api/platform/projects/$ref/': typeof ApiPlatformProjectsRefIndexRoute '/project/$ref/auth/templates/': typeof ProjectRefAuthTemplatesIndexRoute + '/project/$ref/database/pipelines/': typeof ProjectRefDatabasePipelinesIndexRoute '/project/$ref/database/publications/': typeof ProjectRefDatabasePublicationsIndexRoute - '/project/$ref/database/replication/': typeof ProjectRefDatabaseReplicationIndexRoute '/project/$ref/database/tables/': typeof ProjectRefDatabaseTablesIndexRoute '/project/$ref/database/triggers/': typeof ProjectRefDatabaseTriggersIndexRoute '/project/$ref/functions/$functionSlug/': typeof ProjectRefFunctionsFunctionSlugIndexRoute @@ -3056,7 +3047,6 @@ export interface FileRoutesById { '/api/v1/projects/$ref/api-keys/$id': typeof ApiV1ProjectsRefApiKeysIdRoute '/api/v1/projects/$ref/database/migrations': typeof ApiV1ProjectsRefDatabaseMigrationsRoute '/api/v1/projects/$ref/types/typescript': typeof ApiV1ProjectsRefTypesTypescriptRoute - '/project/$ref/database/replication/replica/$replicaId': typeof ProjectRefDatabaseReplicationReplicaReplicaIdRoute '/project/$ref/settings/infrastructure/replica/$replicaId': typeof ProjectRefSettingsInfrastructureReplicaReplicaIdRoute '/project/$ref/storage/analytics/buckets/$bucketId': typeof ProjectRefStorageAnalyticsBucketsBucketIdRoute '/project/$ref/storage/files/buckets/$bucketId': typeof ProjectRefStorageFilesBucketsBucketIdRoute @@ -3229,8 +3219,8 @@ export interface FileRouteTypes { | '/project/$ref/database/functions' | '/project/$ref/database/indexes' | '/project/$ref/database/migrations' + | '/project/$ref/database/pipelines' | '/project/$ref/database/policies' - | '/project/$ref/database/replication' | '/project/$ref/database/roles' | '/project/$ref/database/schemas' | '/project/$ref/database/settings' @@ -3330,8 +3320,8 @@ export interface FileRouteTypes { | '/project/$ref/database/backups/pitr' | '/project/$ref/database/backups/restore-to-new-project' | '/project/$ref/database/backups/scheduled' + | '/project/$ref/database/pipelines/$pipelineId' | '/project/$ref/database/publications/$id' - | '/project/$ref/database/replication/$pipelineId' | '/project/$ref/database/tables/$id' | '/project/$ref/database/triggers/data' | '/project/$ref/database/triggers/event' @@ -3355,8 +3345,8 @@ export interface FileRouteTypes { | '/org/$slug/webhooks/' | '/api/platform/projects/$ref/' | '/project/$ref/auth/templates/' + | '/project/$ref/database/pipelines/' | '/project/$ref/database/publications/' - | '/project/$ref/database/replication/' | '/project/$ref/database/tables/' | '/project/$ref/database/triggers/' | '/project/$ref/functions/$functionSlug/' @@ -3381,7 +3371,6 @@ export interface FileRouteTypes { | '/api/v1/projects/$ref/api-keys/$id' | '/api/v1/projects/$ref/database/migrations' | '/api/v1/projects/$ref/types/typescript' - | '/project/$ref/database/replication/replica/$replicaId' | '/project/$ref/settings/infrastructure/replica/$replicaId' | '/project/$ref/storage/analytics/buckets/$bucketId' | '/project/$ref/storage/files/buckets/$bucketId' @@ -3638,8 +3627,8 @@ export interface FileRouteTypes { | '/project/$ref/database/backups/pitr' | '/project/$ref/database/backups/restore-to-new-project' | '/project/$ref/database/backups/scheduled' + | '/project/$ref/database/pipelines/$pipelineId' | '/project/$ref/database/publications/$id' - | '/project/$ref/database/replication/$pipelineId' | '/project/$ref/database/tables/$id' | '/project/$ref/database/triggers/data' | '/project/$ref/database/triggers/event' @@ -3663,8 +3652,8 @@ export interface FileRouteTypes { | '/org/$slug/webhooks' | '/api/platform/projects/$ref' | '/project/$ref/auth/templates' + | '/project/$ref/database/pipelines' | '/project/$ref/database/publications' - | '/project/$ref/database/replication' | '/project/$ref/database/tables' | '/project/$ref/database/triggers' | '/project/$ref/functions/$functionSlug' @@ -3689,7 +3678,6 @@ export interface FileRouteTypes { | '/api/v1/projects/$ref/api-keys/$id' | '/api/v1/projects/$ref/database/migrations' | '/api/v1/projects/$ref/types/typescript' - | '/project/$ref/database/replication/replica/$replicaId' | '/project/$ref/settings/infrastructure/replica/$replicaId' | '/project/$ref/storage/analytics/buckets/$bucketId' | '/project/$ref/storage/files/buckets/$bucketId' @@ -3862,8 +3850,8 @@ export interface FileRouteTypes { | '/project/$ref/database/functions' | '/project/$ref/database/indexes' | '/project/$ref/database/migrations' + | '/project/$ref/database/pipelines' | '/project/$ref/database/policies' - | '/project/$ref/database/replication' | '/project/$ref/database/roles' | '/project/$ref/database/schemas' | '/project/$ref/database/settings' @@ -3963,8 +3951,8 @@ export interface FileRouteTypes { | '/project/$ref/database/backups/pitr' | '/project/$ref/database/backups/restore-to-new-project' | '/project/$ref/database/backups/scheduled' + | '/project/$ref/database/pipelines/$pipelineId' | '/project/$ref/database/publications/$id' - | '/project/$ref/database/replication/$pipelineId' | '/project/$ref/database/tables/$id' | '/project/$ref/database/triggers/data' | '/project/$ref/database/triggers/event' @@ -3988,8 +3976,8 @@ export interface FileRouteTypes { | '/_app/org/$slug/webhooks/' | '/api/platform/projects/$ref/' | '/project/$ref/auth/templates/' + | '/project/$ref/database/pipelines/' | '/project/$ref/database/publications/' - | '/project/$ref/database/replication/' | '/project/$ref/database/tables/' | '/project/$ref/database/triggers/' | '/project/$ref/functions/$functionSlug/' @@ -4014,7 +4002,6 @@ export interface FileRouteTypes { | '/api/v1/projects/$ref/api-keys/$id' | '/api/v1/projects/$ref/database/migrations' | '/api/v1/projects/$ref/types/typescript' - | '/project/$ref/database/replication/replica/$replicaId' | '/project/$ref/settings/infrastructure/replica/$replicaId' | '/project/$ref/storage/analytics/buckets/$bucketId' | '/project/$ref/storage/files/buckets/$bucketId' @@ -5190,13 +5177,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ProjectRefDatabaseRolesRouteImport parentRoute: typeof ProjectRefDatabaseRoute } - '/project/$ref/database/replication': { - id: '/project/$ref/database/replication' - path: '/replication' - fullPath: '/project/$ref/database/replication' - preLoaderRoute: typeof ProjectRefDatabaseReplicationRouteImport - parentRoute: typeof ProjectRefDatabaseRoute - } '/project/$ref/database/policies': { id: '/project/$ref/database/policies' path: '/policies' @@ -5204,6 +5184,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ProjectRefDatabasePoliciesRouteImport parentRoute: typeof ProjectRefDatabaseRoute } + '/project/$ref/database/pipelines': { + id: '/project/$ref/database/pipelines' + path: '/pipelines' + fullPath: '/project/$ref/database/pipelines' + preLoaderRoute: typeof ProjectRefDatabasePipelinesRouteImport + parentRoute: typeof ProjectRefDatabaseRoute + } '/project/$ref/database/migrations': { id: '/project/$ref/database/migrations' path: '/migrations' @@ -5659,13 +5646,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ProjectRefDatabaseTablesIndexRouteImport parentRoute: typeof ProjectRefDatabaseRoute } - '/project/$ref/database/replication/': { - id: '/project/$ref/database/replication/' - path: '/' - fullPath: '/project/$ref/database/replication/' - preLoaderRoute: typeof ProjectRefDatabaseReplicationIndexRouteImport - parentRoute: typeof ProjectRefDatabaseReplicationRoute - } '/project/$ref/database/publications/': { id: '/project/$ref/database/publications/' path: '/publications' @@ -5673,6 +5653,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ProjectRefDatabasePublicationsIndexRouteImport parentRoute: typeof ProjectRefDatabaseRoute } + '/project/$ref/database/pipelines/': { + id: '/project/$ref/database/pipelines/' + path: '/' + fullPath: '/project/$ref/database/pipelines/' + preLoaderRoute: typeof ProjectRefDatabasePipelinesIndexRouteImport + parentRoute: typeof ProjectRefDatabasePipelinesRoute + } '/project/$ref/auth/templates/': { id: '/project/$ref/auth/templates/' path: '/templates' @@ -5834,13 +5821,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ProjectRefDatabaseTablesIdRouteImport parentRoute: typeof ProjectRefDatabaseRoute } - '/project/$ref/database/replication/$pipelineId': { - id: '/project/$ref/database/replication/$pipelineId' - path: '/$pipelineId' - fullPath: '/project/$ref/database/replication/$pipelineId' - preLoaderRoute: typeof ProjectRefDatabaseReplicationPipelineIdRouteImport - parentRoute: typeof ProjectRefDatabaseReplicationRoute - } '/project/$ref/database/publications/$id': { id: '/project/$ref/database/publications/$id' path: '/publications/$id' @@ -5848,6 +5828,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ProjectRefDatabasePublicationsIdRouteImport parentRoute: typeof ProjectRefDatabaseRoute } + '/project/$ref/database/pipelines/$pipelineId': { + id: '/project/$ref/database/pipelines/$pipelineId' + path: '/$pipelineId' + fullPath: '/project/$ref/database/pipelines/$pipelineId' + preLoaderRoute: typeof ProjectRefDatabasePipelinesPipelineIdRouteImport + parentRoute: typeof ProjectRefDatabasePipelinesRoute + } '/project/$ref/database/backups/scheduled': { id: '/project/$ref/database/backups/scheduled' path: '/backups/scheduled' @@ -6177,13 +6164,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ProjectRefSettingsInfrastructureReplicaReplicaIdRouteImport parentRoute: typeof ProjectRefSettingsRoute } - '/project/$ref/database/replication/replica/$replicaId': { - id: '/project/$ref/database/replication/replica/$replicaId' - path: '/replica/$replicaId' - fullPath: '/project/$ref/database/replication/replica/$replicaId' - preLoaderRoute: typeof ProjectRefDatabaseReplicationReplicaReplicaIdRouteImport - parentRoute: typeof ProjectRefDatabaseReplicationRoute - } '/api/v1/projects/$ref/types/typescript': { id: '/api/v1/projects/$ref/types/typescript' path: '/api/v1/projects/$ref/types/typescript' @@ -6694,25 +6674,22 @@ const ProjectRefComputeRouteChildren: ProjectRefComputeRouteChildren = { const ProjectRefComputeRouteWithChildren = ProjectRefComputeRoute._addFileChildren(ProjectRefComputeRouteChildren) -interface ProjectRefDatabaseReplicationRouteChildren { - ProjectRefDatabaseReplicationPipelineIdRoute: typeof ProjectRefDatabaseReplicationPipelineIdRoute - ProjectRefDatabaseReplicationIndexRoute: typeof ProjectRefDatabaseReplicationIndexRoute - ProjectRefDatabaseReplicationReplicaReplicaIdRoute: typeof ProjectRefDatabaseReplicationReplicaReplicaIdRoute +interface ProjectRefDatabasePipelinesRouteChildren { + ProjectRefDatabasePipelinesPipelineIdRoute: typeof ProjectRefDatabasePipelinesPipelineIdRoute + ProjectRefDatabasePipelinesIndexRoute: typeof ProjectRefDatabasePipelinesIndexRoute } -const ProjectRefDatabaseReplicationRouteChildren: ProjectRefDatabaseReplicationRouteChildren = +const ProjectRefDatabasePipelinesRouteChildren: ProjectRefDatabasePipelinesRouteChildren = { - ProjectRefDatabaseReplicationPipelineIdRoute: - ProjectRefDatabaseReplicationPipelineIdRoute, - ProjectRefDatabaseReplicationIndexRoute: - ProjectRefDatabaseReplicationIndexRoute, - ProjectRefDatabaseReplicationReplicaReplicaIdRoute: - ProjectRefDatabaseReplicationReplicaReplicaIdRoute, + ProjectRefDatabasePipelinesPipelineIdRoute: + ProjectRefDatabasePipelinesPipelineIdRoute, + ProjectRefDatabasePipelinesIndexRoute: + ProjectRefDatabasePipelinesIndexRoute, } -const ProjectRefDatabaseReplicationRouteWithChildren = - ProjectRefDatabaseReplicationRoute._addFileChildren( - ProjectRefDatabaseReplicationRouteChildren, +const ProjectRefDatabasePipelinesRouteWithChildren = + ProjectRefDatabasePipelinesRoute._addFileChildren( + ProjectRefDatabasePipelinesRouteChildren, ) interface ProjectRefDatabaseTriggersRouteChildren { @@ -6739,8 +6716,8 @@ interface ProjectRefDatabaseRouteChildren { ProjectRefDatabaseFunctionsRoute: typeof ProjectRefDatabaseFunctionsRoute ProjectRefDatabaseIndexesRoute: typeof ProjectRefDatabaseIndexesRoute ProjectRefDatabaseMigrationsRoute: typeof ProjectRefDatabaseMigrationsRoute + ProjectRefDatabasePipelinesRoute: typeof ProjectRefDatabasePipelinesRouteWithChildren ProjectRefDatabasePoliciesRoute: typeof ProjectRefDatabasePoliciesRoute - ProjectRefDatabaseReplicationRoute: typeof ProjectRefDatabaseReplicationRouteWithChildren ProjectRefDatabaseRolesRoute: typeof ProjectRefDatabaseRolesRoute ProjectRefDatabaseSchemasRoute: typeof ProjectRefDatabaseSchemasRoute ProjectRefDatabaseSettingsRoute: typeof ProjectRefDatabaseSettingsRoute @@ -6762,9 +6739,9 @@ const ProjectRefDatabaseRouteChildren: ProjectRefDatabaseRouteChildren = { ProjectRefDatabaseFunctionsRoute: ProjectRefDatabaseFunctionsRoute, ProjectRefDatabaseIndexesRoute: ProjectRefDatabaseIndexesRoute, ProjectRefDatabaseMigrationsRoute: ProjectRefDatabaseMigrationsRoute, + ProjectRefDatabasePipelinesRoute: + ProjectRefDatabasePipelinesRouteWithChildren, ProjectRefDatabasePoliciesRoute: ProjectRefDatabasePoliciesRoute, - ProjectRefDatabaseReplicationRoute: - ProjectRefDatabaseReplicationRouteWithChildren, ProjectRefDatabaseRolesRoute: ProjectRefDatabaseRolesRoute, ProjectRefDatabaseSchemasRoute: ProjectRefDatabaseSchemasRoute, ProjectRefDatabaseSettingsRoute: ProjectRefDatabaseSettingsRoute, diff --git a/apps/studio/routes/project/$ref/database/replication.tsx b/apps/studio/routes/project/$ref/database/pipelines.tsx similarity index 68% rename from apps/studio/routes/project/$ref/database/replication.tsx rename to apps/studio/routes/project/$ref/database/pipelines.tsx index 5789e1d41e1..c6b69c52c6d 100644 --- a/apps/studio/routes/project/$ref/database/replication.tsx +++ b/apps/studio/routes/project/$ref/database/pipelines.tsx @@ -3,14 +3,14 @@ import { useParams } from 'common' import { PipelineRequestStatusProvider } from '@/state/replication-pipeline-request-status' -export const Route = createFileRoute('/project/$ref/database/replication')({ - component: ReplicationShell, +export const Route = createFileRoute('/project/$ref/database/pipelines')({ + component: PipelinesShell, staticData: { - databaseLayoutTitle: 'Replication', + databaseLayoutTitle: 'Pipelines', }, }) -function ReplicationShell() { +function PipelinesShell() { const { ref: projectRef } = useParams() return ( diff --git a/apps/studio/routes/project/$ref/database/pipelines/$pipelineId.tsx b/apps/studio/routes/project/$ref/database/pipelines/$pipelineId.tsx new file mode 100644 index 00000000000..ff4d3021d6d --- /dev/null +++ b/apps/studio/routes/project/$ref/database/pipelines/$pipelineId.tsx @@ -0,0 +1,11 @@ +import { createFileRoute } from '@tanstack/react-router' + +import DatabasePipelinesPage from '@/pages/project/[ref]/database/pipelines/[pipelineId]' + +export const Route = createFileRoute('/project/$ref/database/pipelines/$pipelineId')({ + component: DatabasePipelinesPipelineRoute, +}) + +function DatabasePipelinesPipelineRoute() { + return +} diff --git a/apps/studio/routes/project/$ref/database/pipelines/index.tsx b/apps/studio/routes/project/$ref/database/pipelines/index.tsx new file mode 100644 index 00000000000..08fbf20fe8f --- /dev/null +++ b/apps/studio/routes/project/$ref/database/pipelines/index.tsx @@ -0,0 +1,11 @@ +import { createFileRoute } from '@tanstack/react-router' + +import DatabasePipelinesPage from '@/pages/project/[ref]/database/pipelines/index' + +export const Route = createFileRoute('/project/$ref/database/pipelines/')({ + component: DatabasePipelinesIndexRoute, +}) + +function DatabasePipelinesIndexRoute() { + return +} diff --git a/apps/studio/routes/project/$ref/database/replication/$pipelineId.tsx b/apps/studio/routes/project/$ref/database/replication/$pipelineId.tsx deleted file mode 100644 index 5f8a6c5e63a..00000000000 --- a/apps/studio/routes/project/$ref/database/replication/$pipelineId.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createFileRoute } from '@tanstack/react-router' - -import DatabaseReplicationPage from '@/pages/project/[ref]/database/replication/[pipelineId]' - -export const Route = createFileRoute('/project/$ref/database/replication/$pipelineId')({ - component: DatabaseReplicationPipelineRoute, -}) - -function DatabaseReplicationPipelineRoute() { - return -} diff --git a/apps/studio/routes/project/$ref/database/replication/index.tsx b/apps/studio/routes/project/$ref/database/replication/index.tsx deleted file mode 100644 index a44af3e705d..00000000000 --- a/apps/studio/routes/project/$ref/database/replication/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createFileRoute } from '@tanstack/react-router' - -import DatabaseReplicationPage from '@/pages/project/[ref]/database/replication/index' - -export const Route = createFileRoute('/project/$ref/database/replication/')({ - component: DatabaseReplicationIndexRoute, -}) - -function DatabaseReplicationIndexRoute() { - return -} diff --git a/apps/studio/routes/project/$ref/database/replication/replica/$replicaId.tsx b/apps/studio/routes/project/$ref/database/replication/replica/$replicaId.tsx deleted file mode 100644 index 5898207e6d1..00000000000 --- a/apps/studio/routes/project/$ref/database/replication/replica/$replicaId.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createFileRoute } from '@tanstack/react-router' - -import DatabaseReadReplicaRedirectPage from '@/pages/project/[ref]/database/replication/replica/[replicaId]' - -export const Route = createFileRoute('/project/$ref/database/replication/replica/$replicaId')({ - component: DatabaseReplicationReplicaRoute, -}) - -function DatabaseReplicationReplicaRoute() { - return -} diff --git a/apps/studio/state/shortcuts/registry/database-nav.ts b/apps/studio/state/shortcuts/registry/database-nav.ts index 499cfa02e79..c4634970092 100644 --- a/apps/studio/state/shortcuts/registry/database-nav.ts +++ b/apps/studio/state/shortcuts/registry/database-nav.ts @@ -125,7 +125,7 @@ export const databaseNavRegistry: RegistryDefinations = { }, [DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_REPLICATION]: { id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_REPLICATION, - label: 'Go to Replication', + label: 'Go to Pipelines', sequence: ['D', 'L'], showInSettings: false, referenceGroup: SHORTCUT_REFERENCE_GROUPS.NAVIGATION_DATABASE, diff --git a/apps/www/_blog/2025-12-02-introducing-supabase-pipelines.mdx b/apps/www/_blog/2025-12-02-introducing-supabase-pipelines.mdx index 0ab739d6940..67d19cff91c 100644 --- a/apps/www/_blog/2025-12-02-introducing-supabase-pipelines.mdx +++ b/apps/www/_blog/2025-12-02-introducing-supabase-pipelines.mdx @@ -65,7 +65,7 @@ for tables in schema public; ### Step 2: Enable Pipelines -Navigate to `Database` in your Supabase Dashboard. Select the `Replication` tab, click `Add destination`, choose a Pipelines destination, and click `Enable Pipelines`. +Navigate to `Database` in your Supabase Dashboard. Select the `Pipelines` tab, click `Add destination`, choose a Pipelines destination, and click `Enable Pipelines`. ### Step 3: Configure the destination diff --git a/apps/www/data/features.tsx b/apps/www/data/features.tsx index c9168c78b0e..f2ffebdd4dc 100644 --- a/apps/www/data/features.tsx +++ b/apps/www/data/features.tsx @@ -657,7 +657,7 @@ Foreign Data Wrappers simplify data integration by bringing external data into y BigQuery is currently available. ClickHouse, DuckLake, and Snowflake are in Early Access. [Request access](/go/supabase-pipelines-new-destinations) to these destinations. ## Setup -Create a Postgres publication for the tables to replicate. In Database > Replication, add a Pipelines destination, configure its settings, and monitor the pipeline from the Dashboard. +Create a Postgres publication for the tables to replicate. In Database > Pipelines, add a Pipelines destination, configure its settings, and monitor the pipeline from the Dashboard. ## Requirements Requirements depend on the destination. BigQuery and ClickHouse ReplacingMergeTree require source tables to have primary keys and require the publication to include those columns. ClickHouse updates require REPLICA IDENTITY FULL. ClickHouse deletes require primary-key or full identity. DuckLake updates and deletes require a primary-key identity, replica-identity index, or full identity. With a primary-key identity or replica-identity index, include every identity column in the publication. Snowflake updates require REPLICA IDENTITY FULL. Snowflake deletes require a published row identity. diff --git a/packages/common/constants/local-storage.ts b/packages/common/constants/local-storage.ts index 920f99b18e4..a8714a1040b 100644 --- a/packages/common/constants/local-storage.ts +++ b/packages/common/constants/local-storage.ts @@ -110,10 +110,6 @@ export const LOCAL_STORAGE_KEYS = { // RLS event trigger banner dismissed RLS_EVENT_TRIGGER_BANNER_DISMISSED: (ref: string) => `rls-event-trigger-banner-dismissed-${ref}`, - // Read replicas moved from Replication → Infrastructure - READ_REPLICAS_MOVED_CALLOUT_DISMISSED: (ref: string) => - `read-replicas-moved-callout-dismissed-${ref}`, - PROJECT_SECURITY_DISMISSED_AT: (ref: string) => `project-security-dismissed-at-${ref}`, ORGANIZATION_MARKETPLACE_BANNER_DISMISSED: (orgSlug: string, managedBy: string) =>