mirror of
https://github.com/supabase/supabase.git
synced 2026-10-14 05:39:11 +03:00
chore/function-recent-errors
6556
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ded5bc525b |
Joshen/fe 4000 activity table to show queries which are blockers (#48383)
## Context One for Database Connections - allow a user to view the root blocking queries Adds an additional filter button here that toggles the view <img width="738" height="142" alt="image" src="https://github.com/user-attachments/assets/9fea17ba-c6f6-419d-8847-47dba67fc00a" /> When toggled, will render a list of the _root_ blocking queries - these are queries that are at the end of the blocking chain (or otherwise the problematic ones causing other queries to be blocked) <img width="964" height="420" alt="image" src="https://github.com/user-attachments/assets/5300f523-6abe-49b6-92d0-7e16bbddd291" /> Within this view - you can expand the row to view the blocking chain <img width="950" height="335" alt="image" src="https://github.com/user-attachments/assets/bb07095a-3841-4db6-8959-ac2bb264ebf6" /> ## Other changes involved - Realised that "Top blocker" overview metric card logic is incorrect - Was previously naively checking the length of the `blocked_by` array, but it should be consider the nested chain length instead, so this PR fixes that <img width="364" height="108" alt="image" src="https://github.com/user-attachments/assets/89beccef-f6f0-43d1-9dcf-fc35958b09e5" /> - Clicking the PID if highlighted on a metric card will not scroll to the PID if it's already selected. This PR fixes that <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a **Root blockers** view to highlight sessions that block others, with expandable blocking chains revealing related waiting activity. * **Bug Fixes** * Updated blocking metrics to use **transitive** blocker counts and improved cycle protection and behavior when activity records are missing. * The blockers view now consistently affects state/application/role quantities, and **reset filters** clears the view. * **Refactor / UI** * Improved the sessions table with grouped/nested rows, clearer waiting indicators, and more consistent expand/collapse behavior. * **Tests** * Expanded coverage for blocking/waiting chain traversal and branching scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d845768fcf |
chore(claude): add react-hook-form skill (#48431)
Adds a Claude skill encoding correct React Hook Form usage, so
AI-written form code follows best practices instead of copying the
anti-patterns common in older Studio code (prop-form
`form.watch()`/`formState` subscriptions, subscription-only watches,
unguarded `valueAsNumber`, `?? undefined` controlled values, defaults
computed from unloaded queries).
**Added:**
- `.claude/skills/react-hook-form/SKILL.md` — subscription model
(`useWatch`/`useFormState` with `control`), canonical zod + `FormField`
composition (layout deferred to `studio-ui-patterns`), `values:` option
for async data, null normalization for controlled inputs, number-input
handling, dirty-state and gating rules, plus a fix-what-you-touch policy
aligned with the `no-use-watch` lint ratchet
**Changed:**
- `.claude/CLAUDE.md` and `apps/studio/CLAUDE.md` — register the skill
in the skill lists/table
- `.coderabbit.yaml` — add the skill to the existing Studio
code-guidelines entry so CodeRabbit applies it when reviewing Studio
code
Benchmarked on three real form tasks (adding a live-updating field to
`ThroughputField`, a new sheet form with async + nullable data, a
review-changes step in `EditBucketModal`), each run with and without the
skill: 13/13 assertions with the skill vs 8/13 baseline. The baseline
shipped a genuine bug in one task — a `null` server default flowed into
a `''` its own schema rejected, making Save unreachable — which the
skill run avoided.
## To test
- Ask Claude Code to add a field to any Studio form and check it loads
the skill (it's in the studio CLAUDE.md skill table) and uses
`useWatch({ control, name })` rather than `form.watch`
- Skim `SKILL.md` for anything that contradicts current form conventions
— `apps/design-system` demos remain the layout source of truth
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Added a new monorepo “react-hook-form” skill guide with recommended
patterns for safe form subscriptions, wiring, default values,
reset/submission flows, and common anti-patterns.
* Updated Studio skills/load guidance to expand and reorder the skills
matrix, including form logic and copywriting guidance.
* Updated required skill coverage so `react-hook-form` is included for
any form-related work.
* **Chores**
* Expanded automated review enforcement so Studio form code is checked
against the new “react-hook-form” skill guidance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
|
||
|
|
bb9e3d8168 |
Joshen/fe 3967 support top for postgres in self hosted and local (#48386)
## Context Allow self-host / local dashboard to access the "Observability" pages Currently only Query Performance will be accessible - eventually once Database Connections is publicly ready, it'll also be accessible here too <img width="518" height="312" alt="image" src="https://github.com/user-attachments/assets/18e5f6c7-ca77-4e90-81ec-c303bd31dc33" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Navigation, sidebar, and mobile menus now consistently display **Observability** and **Logs** based on enabled features, including the unified logs preview. * **Observability** destinations now adapt to platform and settings so users land on the correct Query Performance view. * **Bug Fixes** * Improved Query Performance loading layout for a smoother loading experience. * Database selection is now shown only on supported platform environments. * **Tests** * Updated navigation/menu tests to match the new routing behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
618e003136 |
Modernize compute and disk configuration (#48368)
## Summary This is a precursor to unifying "compute and disk" and "infrastructure pages". First step is just updating the existing compute and disk page to make use of standard page and form patterns. - Reorganizes the existing Compute and Disk form into the established settings layout pattern, with Scaling, Compute, Disk, and Advanced sections. - Moves billing deltas to section headers while retaining the sticky review footer. - Adds animated notices, validation-error scrolling, and a responsive compute-size selector (2 columns by default, 3 from 680px, and 4 from 900px). - Preserves permissions, entitlements, cooldowns, read-only warnings, replica pricing, GP3 validation, Nano/PITR locks, and the free Micro upgrade treatment. - Keeps the redesigned experience on `/settings/compute-and-disk` so it can be reviewed independently of the route cutover. ## Stack 1. #48368 (this PR) 2. #48369 3. #48370 ## How to test 1. Check out `chore/infra-compute-1-config` and start Studio with `pnpm dev:studio`. 2. Open `/project/<ref>/settings/compute-and-disk`. 3. Confirm the page header and Scaling, Compute, Disk, and Advanced sections follow the standard settings-page spacing, with the plan notice directly below the Scaling header. 4. Change the compute size and disk configuration. Confirm billing deltas appear in the relevant section headers and the sticky review footer summarizes and applies the pending changes. 5. Enter invalid GP3 IOPS or throughput values and submit. Confirm the validation message is shown and the first invalid field is scrolled into view. 6. Exercise representative project states: insufficient permissions, read-only mode, resize cooldown, Nano with PITR, a project with read replicas, and a free Micro upgrade. Confirm the existing locks, warnings, pricing, and upgrade treatment remain intact. 7. Resize the viewport and confirm the compute cards use 2 columns by default, 3 columns from 680px, and no more than 4 columns from 900px. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Reworked the Compute and Disk settings UI into clearer sectioned pages, including smoother navigation to the first validation error. - Added a transitional in-form NoticeBar for consistent alert rendering. - Improved billing change badges to reflect accurate before/after totals. - **Bug Fixes** - Fixed disk IOPS/throughput pricing to include replica-based charges. - Strengthened disk sizing validation (GP3 limits, legacy/size edge cases, spend-cap behavior, and provider-specific constraints). - **Refactor** - Updated key form field layouts for improved readability. - **Tests** - Expanded schema validation and pricing/billing badge test coverage. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
a99c83fe03 |
fix(studio): give Search nav trigger a visible hover state (#48319)
## What kind of change does this PR introduce? Bug fix / UI polish. ## What is the current behavior? The Studio header "Search..." command menu entry point has no useful hover state in light mode. It used `hover:bg-surface-100`, which maps to elevated `--card` and brightens toward white, so the hover effectively disappears against the near-white header. It also lacked `cursor-pointer` and used a weaker border than nearby header controls like Connect. ## What is the new behavior? `CommandMenuTriggerInput` now matches the Connect button's default variant interaction: - `cursor-pointer` - `border-strong` with `hover:border-stronger` - `hover:bg-selection` (same fill as Connect; aliased to accent) Studio `LayoutHeader` drops the redundant `bg-transparent` override now that transparent is the shared default. | After | | --- | | <img width="2561" height="267" alt="CleanShot 2026-07-24 at 17 06 09@2x" src="https://github.com/user-attachments/assets/5a855512-9b7e-40b8-861f-647c87d472a7" /> | ## Additional context Docs top nav also consumes `CommandMenuTriggerInput`, so it picks up the same trigger styling. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Style** * Updated the command menu trigger appearance with a transparent background and stronger border. * Improved hover styling for clearer visual feedback. * Standardized command menu trigger styling across platform and non-platform layouts. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
37dded67d1 |
feat: unify SkipToContent across studio, docs, www, and design-system (#48314)
## What kind of change does this PR introduce? Feature / a11y polish ## What is the current behavior? Studio and Docs each had their own skip-to-content link (different styling and behaviour). www and design-system had none. ## What is the new behavior? Shared `SkipToContent` in `ui-patterns`, adopted by Studio, Docs, www, and design-system. Documented as a fragment with a short note under Accessibility → Jumping ahead. Tab once to reveal the button (top-left), Enter to jump to a content-only `<main>`. | After | | --- | | <img width="836" height="324" alt="CleanShot 2026-07-24 at 14 08 47@2x" src="https://github.com/user-attachments/assets/6df29452-e53a-4eca-8f64-946f2b9f605d" /> | ## To test Shared steps for every app: enable Tab key navigation if needed, load the preview, press **Tab** once — skip button should slide in top-left. Press **Enter** — focus jumps to main content (no blue ring on `<main>`). Press **Tab** again — first interactive control in the page body, not the sidebar/nav. Hover the skip button — solid fill, clear hover state, no chrome showing through. - **Studio** — [preview](https://studio-staging-git-dnywh-featskip-to-content-supabase.vercel.app) → sign in → any project page - **Docs** — [preview](https://docs-git-dnywh-featskip-to-content-supabase.vercel.app) → any docs page with sidebar - **www** — [preview](https://zone-www-dot-com-git-dnywh-featskip-to-content-supabase.vercel.app) → homepage or any marketing page with the default nav - **Design system** — [preview](https://design-system-git-dnywh-featskip-to-content-supabase.vercel.app) → any docs page (confirm Tab from content does **not** walk the sidebar), plus [Skip to Content fragment](https://design-system-git-dnywh-featskip-to-content-supabase.vercel.app/docs/fragments/skip-to-content) ## Additional context Follow-up to #47694 / #48303 (Studio) and #47515 (Docs). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a reusable “Skip to content” accessibility link across key layouts and pages. - Updated main landmarks to support keyboard focus and skip-link navigation (`id="main"`). - **Accessibility** - Skip links now follow consistent landmark-target conventions and remain hidden until focused. - Improved documentation for skip links/jump shortcuts in persistent chrome layouts. - **Documentation** - Added a dedicated Skip to Content fragment, navigation entry, and expanded accessibility guidance. - Updated button description wording in component docs. - **Tests** - Added component tests for SkipToContent. - **Chores** - Exposed SkipToContent via additional public package entry points. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d5436ae826 |
feat(studio): log date range domain + session logRange state (#48401)
## 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? Feature (+ a small refactor and a docs/convention note). PR 4 of the stacked SQL-editor query-source series (Database vs Logs). ## What is the current behavior? The SQL editor has no representation of a logs query's time range: `querySource.ts` only knows how to map a snippet type to a source (`getSnippetSource`), and session state (`sql-editor-session-state.ts`) tracks results and the row limit but not a per-snippet time range. The Logs date picker's pure range helpers (`parseCustomInput`, `generateDynamicHelper`, the `Unit` type) are trapped inside the `Logs.DatePickers.tsx` React component. ## What is the new behavior? - **Logs time-range domain** in `querySource.ts`: branded `IsoDateTimeString` + `isoDateTimeString()`, `RelativeTimeUnit`, a `LogDateRange` discriminated union (relative/absolute), `DEFAULT_LOG_DATE_RANGE`, a single date-picker parser (`datePickerValueToLogDateRange` / `logDateRangeToDatePickerValue` — handles the five presets *and* dynamic `2h`/`30m` helpers; `calcTo === ''` means "now"; unparseable helpers degrade to absolute), and `resolveLogRunRange` which re-resolves relative ranges against `now` at run time (reusing the existing `ResolvedLogDateRange` shape). - **Session state**: per-snippet `logRange` + `setLogRange` — session-only, never written to snippet content, so it works on read-only shared snippets and is cleaned up in `clearForSnippet`. - **Refactor**: extracted the picker's framework-free helpers into a new pure `Logs.datePickerHelpers.ts`; the logs domain now shares the `Unit` type and reuses `generateDynamicHelper` instead of duplicating them. Importers point at the new module directly (no re-export shim). Hardened the amount parse against `NaN`. - **Full unit coverage** in `querySource.test.ts`. Recorded the no-shim refactoring convention in the `studio-best-practices` skill. Verification: `pnpm typecheck` clean, lint ratchet improved, 43 tests pass (querySource + Logs.Datepickers), Prettier clean. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added robust Logs date-range modeling with support for relative (e.g., last N units) and absolute time periods. - SQL Editor sessions now remember log date ranges per snippet. - **Bug Fixes** - Safer handling of invalid or missing date inputs, with sensible fallback to default/current time. - **Tests** - Added/expanded automated coverage for date-range conversion, helper parsing, and resolution behavior. - **Refactor** - Centralized date-picker helper utilities for reuse across the Logs and SQL query experience. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ca2b50a0a7 |
chore(ui-patterns): collapse the admonition shim into ui-patterns/Admonition (#48377)
Follow-up to #48344: collapses the two resolution paths for the Admonition module into one. `src/admonition.tsx` was a back-compat shim re-exporting `src/Admonition/`. Two ways to resolve one module is exactly what produced the macOS self-import bug fixed in #48344, and the local typecheck errors that #48374 worked around. This removes the shim and standardizes on the PascalCase subpath, matching every other export in the package. **Changed:** - Codemodded all 246 `ui-patterns/admonition` imports to `ui-patterns/Admonition` (240 `.tsx`, 5 `.mdx`, 1 `.ts` across studio, docs, www, design-system, and lite-studio) - Pointed the 5 internal `'../admonition'` imports back at the `'../Admonition'` directory **Removed:** - `packages/ui-patterns/src/admonition.tsx`, and its `./admonition` entry in the exports map (regenerated with `pnpm gen:exports`) ## To test - `grep -r "ui-patterns/admonition" --include='*.ts*'` → no hits - `pnpm test:case-hazards` → passes - `pnpm typecheck` → all 15 tasks green - `pnpm --filter studio run lint:ratchet` → passes - `pnpm --filter ui-patterns vitest run src/Admonition` → 11 tests pass <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Standardized Admonition component imports across the application and documentation. * Improved compatibility with case-sensitive environments by using the canonical component path. * Removed the legacy Admonition import entry point. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
fa5eb17277 |
feat(studio): discriminated snippet union + source-aware writes (#48313)
Stacked on #48305. ## What PR 3 of the stacked SQL-editor query-source series (Database vs Logs). Stacked on the PR 2 branch `charislam/log-sql-content-shape`. Turns `SnippetWithContent` into a discriminated union on `type` and makes all snippet writes source-aware: - `data/content/sql-folders-query.ts`: `SnippetWithContent` is now `{ type: 'sql'; content?: SqlSnippets.Content } | { type: 'log_sql'; content?: LogSqlSnippets.Content } | { type: 'report'; content?: never }`. `report` is kept (the content endpoints' wire type carries it) but has no SQL content — its body is `Dashboards.Content`, loaded through the separate `Content` union. - `setSql` brands per type (`untrustedLogSql` vs `untrustedSql`). - `buildUpsertPayload` persists `snippet.type` (no longer hardcoded `'sql'`). - `createSqlSnippetSkeletonV2({ source })` emits the matching type + content shape with the `as any` cast removed. - New `components/interfaces/SQLEditor/querySource.ts`: `SqlSnippetSource` + `getSnippetSource`. - `seedSnippet` test helper gains a `source` arg. - New `remapWireSnippet` boundary helper in `content-remap.ts` concentrates the single wire->domain assertion, so `content-id-query` / `content-upsert-mutation` call sites are cast-free (no `as unknown as`). - Collateral: query result types aligned to the union; `updateSnippet` no longer accepts `type` (source is immutable); db-only editor read paths narrow away `log_sql`. ## Why Impossible-states-impossible typing: a snippet's brand follows its content type, so logs SQL and database SQL can never cross execution paths. No behavior change for existing database snippets. ## Testing - \`pnpm typecheck\` — clean - \`pnpm --filter studio run lint:ratchet\` — no new warnings - \`pnpm test:studio\` (data/content, SQLEditor, state/sql-editor) — passing, including new tests for \`getSnippetSource\`, source-aware \`setSql\`, type-aware \`buildUpsertPayload\`, and both skeleton shapes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added source-aware creation for SQL editor snippets, including log-based SQL snippets. * Introduced backend source mapping so log snippets are treated as log_sql. * **Bug Fixes** * Improved SQL retrieval/prettification so log snippets no longer use the wrong fallback content. * Ensured log snippets are sanitized and preserve correct type, content, identifiers, and statuses during save/upsert flows. * **Tests** * Expanded unit and integration coverage for log snippet creation, source mapping, editing, prettification, and upsert payloads. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7743fee3ab |
feat(studio): log_sql content shape + remap content.sql to unchecked_sql (#48305)
## What PR **2 of 9** in the SQL-editor query-source (Database vs Logs) stack. **Base:** `charislam/snippet-source-typing` (#48301) — this is a stacked PR; review/merge that one first. Client-side rename only — **the wire format is unchanged** (the platform API still stores and returns `content.sql`). This moves the frontend `LogSqlSnippets.Content` field to the branded `unchecked_sql`, matching `SqlSnippets.Content`, and hardens the remap boundary so the rename can't silently drop saved query text. ## Changes - **`types/userContent.ts`** — `LogSqlSnippets.Content`'s plain `sql: string` becomes `unchecked_sql: UntrustedLogSqlFragment` (the brand added in PR 1). Shape kept minimal: `{ content_id, unchecked_sql, schema_version }`. - **`data/content/content-remap.ts`** — extend `remapSqlContentField`/`unmapSqlContentField` to `log_sql`, branding **per type** (`untrustedLogSql` for logs, `untrustedSql` for database) and never mixing brands. **Defensive unmap**: content missing `unchecked_sql` is never clobbered with `sql: undefined`; a residual raw `sql` field (a missed save-path rename) throws in development to surface the bug loudly, while production no-ops safely. - **Legacy Logs Explorer consumers** updated to the branded field: the explorer save/update paths, `SavedQueriesItem`, `RecentQueriesItem`, and the recent-queries page. - **Two db-only write sites** that leaned on `LogSqlSnippets.Content.sql`: `EditorPanel` now saves `unchecked_sql`, and `MoveQueryModal` switches to the SQL-editor-specific `getSqlSnippetById` so its content is typed as `SqlSnippets.Content` — no narrowing or casting. ## Tests - **content-remap**: `log_sql` remap/unmap round-trip with the logs brand; the defensive-unmap no-op (prod) and dev throw. - **content-upsert-mutation**: a `log_sql` payload reaches the wire as a plain `content.sql` and the response remaps back to `unchecked_sql` (the data-loss-critical round-trip shared by both explorer save-new and `SavedQueriesItem` update). ## Verification - `pnpm --filter studio run typecheck` ✓ - `pnpm --filter studio run lint:ratchet` ✓ (no new warnings) - `pnpm test:studio` for `data/content` + `Settings/Logs` — 139 passing ✓ - Prettier ✓ Nothing is user-visible yet — logs snippet entry points arrive later in the stack behind the `sqlEditorLogsSource` flag. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved handling of saved and recent log queries across the SQL editor and Logs Explorer. - Log SQL now uses `unchecked_sql` (branded as untrusted) consistently when creating, editing, moving, and reopening queries, with correct remapping to/from the API boundary. - Fixed saved-query update payloads to preserve the right query content and omit legacy fields. - **Tests** - Added/expanded Vitest coverage for saved log query editing, recent-log normalization, and `log_sql` remap/upsert request/response behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ec1c889349 |
feat(studio): logs SQL brands + execution data layer (#48301)
## 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? Feature (data layer only — PR 1 of the SQL-editor query-source stack; nothing user-visible yet, no consumers). ## What is the current behavior? The Studio SQL editor only runs queries against Postgres. There is no type-safe brand for user-authored logs SQL and no execution/normalization layer for running SQL against the logs/analytics (ClickHouse) backend. ## What is the new behavior? Pure additions, no behavior change: - `data/logs/safe-analytics-sql.ts` — adds distinct untrusted/safe brands for user-authored logs SQL (`UntrustedLogSqlFragment`, `untrustedLogSql`, `acceptUntrustedLogsSql`), mirroring pg-meta's `UntrustedSqlFragment` but kept intentionally disjoint so Postgres and logs SQL can never cross boundaries. - `data/logs/execute-logs-sql-mutation.ts` (new) — `executeLogsSql` wraps `executeAnalyticsSql`, attaches the resolved time range as request params (`iso_timestamp_start/end`, never spliced into SQL), and normalizes to `{ rows, error? }`; `mapLogsError` normalizes the analytics backend's structured 200-body error into the `{ message }` shape the result pane reads; `useExecuteLogsSqlMutation` collapses transport and 200-body errors into React Query's single `onError` path. - Unit tests for `mapLogsError`, the brands (including compile-time disjointness vs pg-meta brands), and safe composition. Verification: `pnpm test:studio` (new suites, 26 passed), `pnpm typecheck`, `lint:ratchet` (no new warnings), and Prettier all pass. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added the ability to run user-authored logs SQL with resolved start/end timestamps. * Normalized query error handling so failures surface a clear message (including sensible fallbacks) and integrates with mutation error flows (with a default error toast when not customized). * Introduced safety branding for logs SQL fragments, including promotion to runnable safe SQL. * **Tests** * Added tests covering error normalization across multiple malformed/empty error shapes. * Added tests ensuring logs SQL branding preserves/accepts only the intended types and rejects unsafe inputs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b8310dbf23 |
feat(studio): move SIWC rollout gate to ConfigCat (#48360)
## 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? Replace the deploy-gated `dashboard_auth:sign_in_with_chatgpt` AND-gate with useFlag('ShowSignInWithChatGptButton') OR'd against the existing localStorage opt-in switch, so rollout/rollback no longer requires a frontend deploy. Remove the now-dead static flag, its only consumer was this gate. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * ChatGPT sign-in availability now responds to either the local opt-in setting or the updated configuration flag. * GitHub sign-in continues to follow its dedicated feature setting. * **Bug Fixes** * Corrected identity provider visibility across different sign-in configuration combinations. * **Chores** * Removed the obsolete ChatGPT sign-in feature setting. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
69f3c43118 |
fix(studio): close Vercel create popup on cancel (#48371)
## What kind of change does this PR introduce? Bug fix / UX polish. ## What is the current behavior? Cancel on the Vercel create interstitial redirects to Vercel’s `next` URL. That finishes the install flow and shows “Completing installation…” / “Installation complete”, even though the user cancelled. The Deploy Button job still proceeds and fails. The button was also labelled “Return to Vercel”, which read like an alternate success path. | Before | | --- | | <img width="719" height="118" alt="Create Vercel Project Supabase" src="https://github.com/user-attachments/assets/c7ad261a-f132-4226-b460-21ec267595c0" />| | <img width="800" height="599" alt="95801" src="https://github.com/user-attachments/assets/6d235c4b-be90-4d5e-89bc-a68933f9dc46" /> | ## What is the new behavior? - _Return to Vercel_ button now labelled **Cancel** - **Cancel** closes the popup via `window.close()` (same honest abort as manually closing the window) - If the browser blocks programmatic close, Cancel is replaced by muted fallback copy: “Close window to cancel” (`role="status"` / `aria-live="polite"`) - Cancel is left-aligned with `justify-between` when there’s no additional-costs block; with costs, both actions stay on the right - Removes the free-limit hint line about returning to Vercel (Cancel makes that self-evident) - Success path is unchanged: after create, we still redirect via `next` - `/new` Cancel still navigates into Studio (`cancelAction: 'studio'`). This is unchanged behaviour | After (Fallback) | | --- | | <img width="713" height="103" alt="img" src="https://github.com/user-attachments/assets/95aafc0d-1c3d-4093-9681-88ad0a40f9fe" /> | ## Additional context Follow-up to #48311. Vercel’s `next` URL has no documented cancel/abort status, so closing the popup is the correct escape hatch. ### To test Full Deploy Button popup cancel can’t be verified on prod until this merges. Locally: 1. Open Studio on this branch. 2. In `ProjectCreationFooter.tsx`, temporarily force the fallback: ```ts const [showCloseWindowHint, setShowCloseWindowHint] = useState(true) ``` 3. Load create-project UI: - Free org / no costs: Confirm Cancel is left, Create is right (`justify-between`). With the forced hint, Cancel is replaced by “Close window to cancel”. - Paid org with additional costs: Confirm costs on the left; hint/Create on the right. 4. Revert `useState` to `false`. 5. Optional: open a Vercel create interstitial URL in a normal tab (not a popup), click Cancel. `window.close()` fails and the hint should replace Cancel after ~100ms. 6. On `/new/[slug]`, Confirm Cancel still returns to the Studio dashboard (not close-window). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Updated Project Creation Cancel to close the popup window directly when applicable, with a “close window to cancel” hint when closing isn’t available. * **Bug Fixes** * Removed Vercel-specific “return and restart” messaging and related return-url handling. * Standardized Cancel navigation for non-popup flows to return to the last relevant location (or the organizations page). * **Refactor** * Improved Project Creation footer layout/visibility for additional cost details. * **Chores** * Simplified the free-project limit warning configuration by removing an unused option. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
0987824674 |
Clean up + add unit tests for database connections (#48372)
## Context As per PR title - no functional / visual changes, just some code clean up / refactor + adding unit tests <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added database connection metrics covering active, blocked, and idle-in-transaction queries. * Enhanced insights for the longest-running query and the top blocker (most queries blocked), including warning indicators based on duration thresholds. * **Bug Fixes** * Improved consistency and accuracy of database-activity calculations in the connection overview. * **Refactor** * Centralized metric derivation so the UI uses the same computed logic everywhere. * **Tests** * Added metric-calculation tests with controlled time to validate multiple scenarios and warning behaviors. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c9ed51c99e |
fix(studio): add return to Vercel escape hatch (#48311)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix / UX improvement for the Vercel Deploy Button create-project interstitial. ## What is the current behavior? On the Vercel create-project step, the organization picker is locked (correct — the integration is bound to that org) and Cancel is hidden. If the org can't create a free project (member free-project limits), users hit a dead end: Upgrade may not help, and there's no way out of the popup. Also includes a small capitalisation nit on the Vercel install page. | Before | | --- | | <img width="800" height="629" alt="Create Vercel Project Supabase" src="https://github.com/user-attachments/assets/2acdc7a3-eb99-43c6-9135-557370647da1" /> | ## What is the new behavior? - Replaces `hideCancelButton` with `cancelAction: 'studio' | 'vercel' | 'hidden'` - Vercel create flow shows **Return to Vercel**, which redirects to the install `next` URL (closing the popup cleanly) - Free-project-limit admonition adds a Vercel-only hint pointing at that button: “Or return to Vercel and restart with a different organization.” - Main `/new` Cancel behaviour is unchanged - Org picker stays disabled ## Additional context Org switching mid-create is intentionally not allowed. That would orphan the Vercel install. Returning to Vercel is the safe escape hatch so users can restart Deploy Button with another org, or free a project slot / upgrade and try again. ## To test As far as I can tell, this is impossible to test on prod. Shortly after merge though, you could test the following: - [ ] Happy path: create still works; Return to Vercel is secondary and does not block submit - [ ] Free-limit blocked org: Create disabled, Return to Vercel visible and redirects to `next` - [ ] Main `/new`: Cancel still goes to last org / organizations <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced project creation flow for Vercel: when a valid return destination is available, users can choose **“Return to Vercel”**. - Added additional messaging in the free-project-limit warning to guide users back to Vercel and restart with a different organization (when applicable). - **Bug Fixes** - Improved cancel behavior and routing consistency by only enabling Vercel return when the destination is valid. - **Style** - Updated the Vercel integration interstitial title capitalization for consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
4893c396db |
fix(studio): split cron_job_cleanup dialog-open from enable to stop double-counting (#48348)
<!-- ccr-slack-attribution --> _Requested by **Pam Chia** · [Slack thread](https://supabase.slack.com/archives/C076KTY11DF/p1785115156767339?thread_ts=1785115156.767339&cid=C076KTY11DF)_ ## What kind of change does this PR introduce? Bug fix (telemetry). ## What is the current behavior? Clicking the header "Enable cleanup" button fires `cron_job_cleanup_enable_button_clicked` when it merely OPENS the confirmation dialog (`origin: 'header'`), and fires it AGAIN when the dialog is confirmed (`origin: 'dialog'` + `retentionInterval`). So every successful enable logs the event twice, and a naive `count(cron_job_cleanup_enable_button_clicked)` roughly doubles the true number of cleanups enabled. The dual-fire was introduced in #48200. ## What is the new behavior? Opening the dialog fires a new `cron_job_cleanup_dialog_opened` event, and `cron_job_cleanup_enable_button_clicked` fires only on confirm — when cleanup is actually scheduled. Each event now maps 1:1 to a distinct user action. **How:** - Added `cron_job_cleanup_dialog_opened` to the shared telemetry catalog (`packages/common/telemetry-constants.ts`). - Removed the now-redundant `origin` property from `cron_job_cleanup_enable_button_clicked` (the two events encode what `origin` used to); kept `retentionInterval`. - Updated the emit sites in `apps/studio/components/interfaces/Integrations/CronJobs/CronJobsTab.EnableCleanupButton.tsx`: the header open now sends `cron_job_cleanup_dialog_opened`; the dialog confirm sends `cron_job_cleanup_enable_button_clicked` with just `retentionInterval`. ## Additional context `origin` already technically separated the two paths (`count(origin='dialog')` gave the true number), but splitting into two named events removes the footgun of anyone aggregating the raw event. Note for reviewers: I kept the existing event key `cron_job_cleanup_enable_button_clicked` for the confirm path rather than renaming it to something like `cron_job_cleanup_enabled` — happy to rename if preferred, but keeping the key avoids churn on such a new event. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Analytics** * Improved tracking for the cron job cleanup flow by distinguishing when the cleanup confirmation dialog is opened from when cleanup is enabled. * Updated event details to more accurately reflect the cleanup scheduling and confirmation steps. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
01541b95cb |
fix(studio): keep organization_slug in oauth signup redirect (#48352)
Email signups inside a partner OAuth flow lose `organization_slug` on the post-confirmation redirect: the OAuth branch in `SignUpForm` hand-builds the `/authorize` return URL from only `auth_id` and `token`, and the component's nuqs hook never reads the param at all. The consent screen uses `organization_slug` to preselect and lock the partner's requested org, so affected multi-org users land on an empty picker and the partner's requested org is silently dropped. The GitHub-OAuth signup path goes through `buildPathWithParams` and preserves the param, which is how this went unnoticed. I validated the drop in production traffic before fixing: joining sign-up pageviews to their post-signup `/authorize` return on the `auth_id` URL param (30d), 28 of 36 resolvable flows came back without the slug, and the 8 that kept it were the GitHub branch. ## To test Needs a partner OAuth authorize link that includes an org, opened signed-out: `/dashboard/authorize?auth_id=<id>&organization_slug=<slug>` (note `auth_id` records expire quickly, so generate a fresh authorize request from an OAuth app). - [x] Sign up with email from that flow; after confirmation the redirect lands on `/authorize` with `organization_slug` still in the URL - [ ] Consent screen shows the requested org preselected and locked - [x] Same flow without `organization_slug` behaves as before (no trailing empty params in the redirect URL) ## Linear - fixes GROWTH-1031 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved sign-up redirects during authentication flows by preserving invitation tokens and organization information. * Enhanced handling of sign-up links containing organization details. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
da847254d5 |
fix: ESLint errors relating to accessibility (alt attribute and tableEditor components) (#48186)
## 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? Improvements for screen readers: - Added `alt` attributes to image components - Added `aria-label` attributes and Tooltip to buttons ## What is the current behavior? `aria-label`, `alt` attributes and Tooltip were missing ## What is the new behavior? Buttons have now `aria-label` attributes and Tooltip. Images have `alt` attributes ## Additional context I’ve added `aria-label` attributes to the buttons in the Pagination.tsx component, but these buttons don’t trigger any action. Shouldn’t we be using non-interactive elements here? No visual changes have been made. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Accessibility** * Added a tooltip to the “date options” control when the value is nullable. * Improved screen-reader labeling by adding an `aria-label` to the number editor input. * Added explicit `aria-label` text to pagination footer buttons for loading, error, and help/estimate states (and marked the error-state button as disabled). * **UI** * Updated the pagination loading-state button to rely on the button’s built-in loading behavior instead of a custom spinner icon. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com> |
||
|
|
f01ac83ebc |
Fix Studio contributor README links and Node version note (#47571)
## 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? docs update ## Description - Replace the broken checklist link in apps/studio/README.md with the main contributing guide. - Update the Studio setup note in apps/studio/README.md to match the repo Node pin in .nvmrc. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated the contribution instructions to point to the main contributing guide. * Bumped the recommended Node.js version in the developer quickstart from v20 to v22. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6f8fe470a6 | ref(pipelines): Update pricing descriptions given new egress calculation (#48241) | ||
|
|
6058ee7962 |
Add focus states for spans in overview cards (#48354)
## Context Tiny one to address for a11y stuff for the spans in the metric cards for database connections overview section <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Style** * Improved hover and keyboard-focus styling for process ID details in database observability metrics. * Added a pointer cursor and smoother visual transitions to make interactive details easier to identify. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
22284f1786 |
Use table for roles tooltip instead (#48353)
## Context Opting to use native `table` element instead for the roles tooltip in `DatabaseConnections` to better handle varying role name lengths ### Before <img width="314" height="226" alt="image" src="https://github.com/user-attachments/assets/f8a5f7a2-be2f-4ad6-a1f0-7a7812800819" /> ### After <img width="332" height="191" alt="image" src="https://github.com/user-attachments/assets/dcb30f5d-641c-4b42-b31d-bf6d76086791" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Style** * Improved the layout and readability of the “Connections by roles” tooltip in database observability metrics. * Role labels and connection counts are now presented in a clearer tabular format. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
60e6a89f9d |
fix: make high availability in project creation form public (#48338)
Move "High availability" from internal-only to public. Closes MUL-668. ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix ## What is the current behavior? "High availability" is an internal-only config <img width="724" height="1126" alt="Screenshot 2026-07-26 at 8 15 57 PM" src="https://github.com/user-attachments/assets/83e1856b-9020-4b65-a019-27e3cc29bae9" /> ## What is the new behavior? "High availability" is a public user-facing config <img width="724" height="1036" alt="Screenshot 2026-07-26 at 8 15 31 PM" src="https://github.com/user-attachments/assets/4f369058-ce91-4bcf-bd3c-120277363b1a" /> Still hidden without the org entitlement, i.e. currently not available anywhere on prod <img width="724" height="931" alt="Screenshot 2026-07-26 at 8 18 58 PM" src="https://github.com/user-attachments/assets/3e1deb76-210c-416b-b716-45ff6e3b0afd" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a High availability option directly to the project creation form. * The option is shown when available for the account and hidden when unavailable. * Enabling High availability automatically selects AWS as the cloud provider. * **Bug Fixes** * Corrected validation for incompatible High availability and OrioleDB selections. * **Tests** * Added coverage for High availability visibility, eligibility, and form submission behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b9ab634cd0 |
fix(studio): stop 403'd integration queries from looping on remount (#48350)
Resolves FE-4014
A user with a project-scoped role opening any project integration
overview (e.g. Cron) hits an unbounded request loop — the page sits on a
skeleton forever while hammering the platform API until it gets rate
limited.
**Changed:**
- `useProjectOAuthIntegrationData` now passes `retryOnMount: false` to
its five queries, so a 403 settles as a terminal error instead of
refetching on every consumer mount
## Why
Project-scoped roles have no org-level permissions, so `GET
/platform/organizations/{slug}/oauth/apps` 403s. We don't retry 4xx, so
the query settles into `error` with no data — and an errored query with
no data is never fresh, so it refetches on *every* new observer mount.
That feeds a loop: refetch → `isLoading` true → `IntegrationPage` swaps
its whole subtree to a skeleton → `<Component />` unmounts → 403 lands →
`isLoading` false → remounts → mounts fresh observers → refetch.
Measured ~20 req/s (480 observer add/removes and 120 requests in a 6s
window) until the API 429s it, then it continues at the retry cadence
indefinitely.
The other four queries in that hook can 403 the same way for restricted
roles, and any one of them alone sustains the loop — hence the option on
all five.
Not fixed here: `IntegrationPage` tearing down its subtree whenever
`isLoading` flips
(`pages/project/[ref]/integrations/[id]/[pageId]/[childId]/index.tsx:58-94`)
is the amplifier that turns a wasted request into a loop, and will still
reset UI state on any background refetch. Worth a follow-up.
## To test
Needs an account with a project-scoped role in a shared org (not an org
owner/admin).
- Open `/project/{ref}/integrations` for that project, click into Cron
(or any integration) → overview should render, not sit on a skeleton
- Network tab: `organizations/{slug}/oauth/apps?type=authorized` should
fire once and 403, not repeat
- Console should show 1 error, not hundreds ending in a 429
- As an org owner, integration overviews should behave exactly as before
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Prevented repeated refetching of integration data after handled
authorization/403 errors, avoiding refetch loops on remount.
* Improved consistency on integration landing screens by standardizing
how related integration queries are enabled and retried.
* **Enhancements**
* Added permission-aware loading/error handling for OAuth integration
data, showing OAuth results only when the selected organization grants
read access.
* **Chores**
* Updated permission-check typings to treat an explicitly empty project
reference as absent.
* **Tests**
* Extended integration settings tests with permission fixtures to cover
OAuth read access.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
|
||
|
|
19dfbd250a |
feat(auth): expose access token expiry under auth settings (#48236)
Exposes the access token expiry (`JWT_EXP`) under `Auth -> Sessions` settings as opposed to the Legacy JWT settings previously used. <img width="1632" height="1199" alt="Screenshot 2026-07-23 at 10 06 33" src="https://github.com/user-attachments/assets/85356e57-da95-404c-852a-21cf9cab2b74" /> <img width="1198" height="1119" alt="Screenshot 2026-07-23 at 10 06 19" src="https://github.com/user-attachments/assets/bfa64b3b-1902-45eb-83ed-ca8bc12673af" /> <img width="1237" height="513" alt="Screenshot 2026-07-23 at 10 03 44" src="https://github.com/user-attachments/assets/85779e9b-30f2-48c5-9faa-4c650d450227" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an **Access Tokens** section to configure JWT expiration with dedicated Save/Cancel controls and success/error toasts. * Enforced a maximum JWT expiration value (must be **less than 604800 seconds**). * **Bug Fixes** * Updated the Sessions auth page text to better clarify configuration for access tokens, refresh tokens, and user sessions. * **Documentation** * Updated JWT expiration guidance to point to **Auth settings → Access Tokens** (replacing legacy JWT secret references). * **Chores** * Expanded automated tests covering Access Tokens saving and validation. * **Refactor** * Removed JWT expiration editing from the legacy JWT Secrets area, consolidating it under Access Tokens. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
cbb076ddf1 |
Blocked by card to only highlight if any query is blocked longer than 10 sec (#48292)
## Context As per PR title - we're currently showing a "danger" state for the blocked by metric card as long as there's at least query that's blocked. This may come off as too noisy in a real database scenario hence opting to fine tune this behaviour a little ## Changes involved We'll now only show the "danger" state for the blocked by metric card if any of the blocked queries are blocked for longer than 10 seconds <img width="356" height="256" alt="image" src="https://github.com/user-attachments/assets/e7db5d7e-749a-4c4e-b519-9433a639b0a0" /> Otherwise will just be a default card <img width="359" height="266" alt="image" src="https://github.com/user-attachments/assets/f9aad85f-8d74-4f55-a3c5-a859d46bd8c1" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added clearer blocked-query monitoring, including the longest-blocked process and duration. - Added interactive selection for the longest-blocked process. - **Bug Fixes** - Improved activity-duration tracking across active and idle-in-transaction states. - Blocked-query warnings now reflect duration thresholds rather than query count alone. - Prevented negative duration values in blocked-query metrics. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fb7debec25 |
Add top blocker overview card (#48290)
## Context Adds a "Top blocker" overview card for Database Connections This should provide a better signal if there's any process that's behaving as a bottleneck for multiple blocked queries <img width="977" height="256" alt="image" src="https://github.com/user-attachments/assets/3d5129a8-f0d7-40a6-808e-0d902889d997" /> ^ We only highlight the card in red if the query is blocking more than 3 other queries to account - otherwise the signal might be too noisy <img width="965" height="262" alt="image" src="https://github.com/user-attachments/assets/f3fda77a-8d52-4e5d-8717-66a26f511a3c" /> ## Other changes involved - Am swapping the card positions around a little - Longest running query card shows the PID as the primary information, followed by the duration of the run <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a **Top blocker** metric to the Database Connections Overview to highlight the PID/account blocking the most other queries. * Warning styling now appears when a query blocks more than **3** other queries. * Reorganized the metrics layout and ordering for improved visibility (active, idle-in-transaction, blocked, top blocker, and longest running). * **Bug Fixes** * Updated tooltip and guidance text for clearer explanations of blocked and idle-in-transaction states. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2b27ed0ab1 |
fix(docs) Improve a11y for Admonitions with file refactor (#48112)
Closes FE-3914 ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## Problem On screenreader, I found that the Admonition was not behaving as it should: - There was no way on screenreader to tell what type of note I was seeing - I could not tell when a note began or ended. - The screenreader also read aloud an 'image' icon without knowing what it was. - Notes with titles were an `h5`, breaking header hierarchy structures. ## Solution This PR does several things to resolve the issue: - Adds `aria-hidden` to all icons. Instead of duplicating code, I refactored the icons into a Base Icon and moved Admonitions into its own folder. - ~Adds a text label for each of the notes. For example, "**Note:**". This is a standard practice in other documentation. If there is a title, it is added there. Otherwise, it's added to the description.~ Change reverted from design feedback. - ~Adds `role='note'` and `aria-label` to the Admonition. While `<aside>` is recommended semantic HTML, the base UI element does not allow for that change.~ This will be done in a follow-up for docs only. - Refactors Admonition into a folder with files so that it is more readable - Removes `h5` by default with a new prop to declare a header Additionally adjusts the icon so that it aligns with text better. ## Testing 1. Open documentation preview 2. Navigate to any guide and see its admonition. Compare to live. You can also see the Design System: https://design-system-git-a11y-docs-admonition-supabase.vercel.app/design-system/docs/fragments/admonition 3. See the icon position is in line with the text. 4. See the text label. 5. Use a screenreader like Voiceover on the admonition. Hear that it is clearly defined. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Added the Admonition UI pattern with support for `type`, `layout`, `title`/`description`, optional actions, and configurable icons. - Expanded Admonition’s public export surface with dedicated subpath entry points and icon/type exports. - **Bug Fixes** - Standardized Admonition import path casing across related components. - **Documentation** - Updated design system examples to use `type="warning"` instead of `variant="warning"`. - **Tests** - Added/updated the Admonition test coverage and removed the legacy test file. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com> |
||
|
|
84e273cf0b |
fix(studio): alignment of compute pricing blocks on compute settings (#48289)
## 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? Fixes alignment issues across viewports with the size blocks on compute & disk page. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added responsive container support for horizontal form layouts. * Compute-size options now adapt more smoothly to available screen space. * Preserved existing loading states, error messages, pricing details, locked options, and larger-compute guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8d4d3b57e0 |
feat(studio): add tanstack variant to the studio docker image (#48091)
Makes the self-hosted Docker image buildable with the TanStack/Vite
build alongside the existing Next one. The Dockerfile's new
`STUDIO_FRAMEWORK` build arg (default: `next`) selects which framework
lands in the image — the same variable `scripts/dispatch.js` keys on
everywhere else, so `--build-arg STUDIO_FRAMEWORK=tanstack` is the
docker spelling of the existing switch. Both flavors assemble a
normalized `/srv` tree, so a single production stage serves either with
the same CMD (`node apps/studio/server.js`), port 3000, and healthcheck.
Unlike Next's self-contained standalone output, the Vite SSR bundle
externalizes studio's dependencies and resolves them from `node_modules`
at request time, so the tanstack runtime tree is a prod-only `pnpm
deploy` plus the built `dist/`. The boot smoke test runs a second time
against that pruned tree, so a runtime import that's missing from
`dependencies` fails the image build instead of 500ing the deployed
container — which is exactly how this PR caught four packages
misclassified as devDependencies (`braintrust` +
`@smithy/property-provider` via the AI routes, `libpg-query` via the
parse-query API route, `@radix-ui/react-use-escape-keydown` via the
Queues panel; split into its own commit).
**Changed:**
- `apps/studio/Dockerfile`: `ARG STUDIO_FRAMEWORK` selects `build-next`
/ `build-tanstack` stages via `FROM build-${STUDIO_FRAMEWORK}`; both
normalize into one production layout
- `apps/studio/package.json`: moved the four runtime-imported packages
from devDependencies to dependencies (versions unchanged)
- `apps/studio/vite.config.ts`: pinned `preview.host` to `127.0.0.1` —
the prerender step boots `vite preview` and crawls its resolved URL, and
the default `localhost` host lets the server bind the IPv6 loopback
while the crawler fetches `127.0.0.1`, which ECONNREFUSEDs the whole
build inside BuildKit containers
- `.github/workflows/studio-docker-build.yml`: builds the tanstack image
as a second step (reuses the first build's layer cache; job name
unchanged)
**Added:**
- `build:studio:docker:tanstack` root script
Note: the tanstack image is ~2.0GB vs ~1.2GB for Next (externalized
`node_modules`); shrinking it via file tracing is a follow-up. Nothing
self-hosters pull changes until a tanstack-built image is published —
this makes it buildable and CI-checked.
## To test
- `pnpm build:studio:docker` then run the image against a stack —
behavior unchanged (healthcheck `/api/platform/profile` 200, `/` 307s to
`/project/default`)
- `pnpm build:studio:docker:tanstack` then run that image with the same
env — same healthcheck, redirect, and data endpoints (projects, pg-meta)
respond 200; browser loads Project Overview / Table Editor with no
requests leaving the container
- Both verified locally against the CLI stack (`host.docker.internal`
env, container reports `healthy`)
- Vercel + e2e checks on this PR exercise the `preview.host` change on
their runners
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added TanStack-based Studio build support with a framework-selectable
Docker image.
- Added a local build command for the TanStack Studio Docker image.
- **Build & Deployment**
- Updated the Studio Docker build workflow to also publish a
TanStack-tagged Studio image when relevant.
- **Bug Fixes**
- Improved `vite preview` behavior in containers by binding to IPv4
loopback.
- Standardized the Studio container runtime port to `3000`.
- **Chores**
- Updated Studio runtime packages to support the TanStack build.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
|
||
|
|
74a57861b3 |
chore(studio): remove region limitation for vector buckets (#48248)
## 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? Remove the region limitation on vector buckets ## What is the current behavior? Currently vector buckets are limited to a subset of Supabase regions ## What is the new behavior? All supabase regions now have access to vector buckets ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Vector buckets are now available based solely on platform enablement, without region-based restrictions. * **Bug Fixes** * Removed the region limitation message and related region availability checks from the Storage Vectors page. * Updated vector bucket upgrade behavior to reflect platform availability more consistently. * **Tests** * Updated coverage to reflect the simplified platform-based availability behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
99fd5d0117 |
fix: Refactor some suspicious Valtio uses (#48141)
This PR is partly driven by changes in https://github.com/supabase/supabase/pull/48102. Claude identified code smells of Valtio state which are not bugs at the moment, but we should address in case their usage changes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved AI assistant message updates to prevent unexpected state changes. * Fixed table editing behavior to preserve shared data and prevent accidental in-place mutations. * Improved consent handling by preventing SDK internals from being altered by state management. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6cff728742 |
feat(studio): polish Connect sheet mode selector and steps (#48266)
## What kind of change does this PR introduce? UI polish for the Connect sheet: clearer mode selection, wider sheet layout, and step/content chrome across Direct, Server, MCP, and shadcn flows. ## What is the current behavior? - Connect modes use a weak selected state and an awkward grid layout. - The sheet can jump width below the `lg` breakpoint when switching modes. - Direct connection chrome is noisy (reset in a footer, Title Case / mono pooler labels, mismatched copy-button sizes). - Several steps use admonitions or extra tips that repeat footer guidance. - Case-sensitive import of `InlineLink` breaks Linux/Vercel builds. ## What is the new behavior? ### Mode selector and sheet - Stronger selected/hover treatment; comfortable single row that wraps via `@container`. - Empty odd slots use a sunk placeholder cell. - Sheet uses `size="lg"` with `max-w-4xl` and `w-full min-w-0` so width stays stable when switching modes. ### Steps chrome - “Follow these steps” header with a copy-prompt action for coding agents. - Optional steps labelled `(optional)`. - Shared `CodeBlock` for install snippets; MCP feature groups preselect all except Storage. - Server / shadcn tips folded into footers; IPv4 add-on admonition is responsive with an inline Learn more link and a single Enable action. ### Direct connection - Connection string and connection parameters stay one step (same credentials, two formats). - Reset database password lives in the string card title row beside Shared/Dedicated pooler. - Card titles use sans + sentence case (`Shared pooler`, `Connection parameters`); `.env` stays mono. - Icon-only copy buttons match CodeBlock square sizing; row actions sit slightly closer to the right edge (`pr-2`). - Shared pooler toggle copy clarified. | Before | After | | --- | --- | | <img width="390" height="763" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/adca3cc5-94f8-47e5-a4a2-2831790f430a" /> | <img width="390" height="763" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/f03afe58-e654-435e-a821-835f6243ca95" /> | | <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/79f08620-7e1e-4246-a70f-801606c0f499" /> | <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/fb45e851-955e-46c2-90f1-afecb93d6ac4" /> | | <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/eda36d21-bba7-46ab-ad48-134acf93b471" /> | <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/b7b728c6-fc92-46a7-8e3f-2f182c56ece7" /> | ### Test plan - [ ] Open **Connect** and confirm mode cells select/hover clearly; narrow the sheet and confirm wrap + stable width. - [ ] Direct: switch Direct / Transaction / Session; confirm pooler title, reset in title row, parameters table, and percent-encode note. - [ ] Toggle IPv4 shared pooler on Transaction; confirm string updates and admonition/Learn more behaviour when on IPv4-only paths. - [ ] Server: `.env` Copy all / row copy sizing; install command copy. - [ ] MCP / shadcn / Framework: steps still resolve and copy prompt still builds a useful agent prompt. - [ ] Spot-check light/dark and a Linux/Vercel build (InlineLink import casing). |
||
|
|
2a17985a1c |
fix: Skip to main content link should be visible when focused (#48303)
## Problem #47694 introduced a _Skip to main content_ link allowing keyboard users to jump to the main section without having to tab through all the navigation elements. However, this link is completely invisible which means sighted users will not see what is actually focused. ## Solution The best practice for such links is to make them visible on focus. For instance on https://tetralogical.com: <img width="1556" height="305" alt="image" src="https://github.com/user-attachments/assets/e36f6d73-98b0-46ca-b464-72540a482b5f" /> Here's what it looks like on Studio: <img width="1835" height="335" alt="image" src="https://github.com/user-attachments/assets/71623306-587a-48aa-b955-43d3368f6073" /> ## How to test - Make sure your browser allows to tab to links (https://www.articulatesupport.com/article/How-to-Enable-Tab-Key-Navigation-on-a-Mac) - Open https://studio-staging-git-gildasgarcia-fe-3805-add-ski-cf6824-supabase.vercel.app and sign in - Once the Studio is loaded, verify the button isn't be visible - Press _Tab_: the button should be visible. - Press _Enter_, then press _Tab: the organizations search input should be focused |
||
|
|
69570a357d |
fix(studio): route vercel deploy-button params to create despite marketplace source (#48258)
## What kind of change does this PR introduce? Bug fix for the Vercel Deploy Button → Studio handoff. ## What is the current behavior? Vercel sometimes opens our install popup with `source=marketplace` while still sending Deploy Button params (`currentProjectId`, `external-id`). We trust `source` alone, so users are routed to choose-project (connect) instead of create — which is why create never gets reached in the Deploy Button flow. ## What is the new behavior? - When both Deploy Button signals (`currentProjectId` + `externalId`) are present, route to create even if Vercel sent `source=marketplace` / `external` - Hide Skip (and related empty-state copy) on choose-project when those signals are present, so Deploy Button users can't continue without linking ## Additional context Stacked on #48230. Test plan: - [ ] Unit tests for `resolveVercelInstallSource` / `hasVercelDeployButtonSignals` pass - [ ] Deploy Button flow with mislabeled `source=marketplace` + both params → lands on create after org install/continue - [ ] Genuine marketplace install (no `currentProjectId`/`external-id`) → still lands on choose-project with Skip available - [ ] If choose-project is opened with both Deploy Button params, Skip is hidden <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved Vercel installation handling for Deploy Button workflows, ensuring the correct setup path is selected. - Added clearer project-connection guidance when no projects are available (including conditional skip copy). - **Bug Fixes** - Prevented Deploy Button installations from incorrectly offering a skip option. - Preserved the skip-and-connect-later guidance for other Vercel installation flows. - Improved recognition of Deploy Button installations even when the reported Vercel source differs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
8c092185ae |
feat: paused project restore window copy and backup downloads (#48279)
Shows the restore deadline as a date on the paused-project screens, and offers backup downloads while a paused project is still restorable (previously only after the restore window ended). Depends on a backend change — keep as draft until that is live. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Extended the paused-project restore window from 90 days to up to 1 year. * Added clearer, downloadable options for database backups and storage objects while a project is paused. * Paused-project screens now show an “available until” date when applicable (and updated resume guidance). * **Documentation** * Updated platform and troubleshooting guides to reflect the new 1-year restore window and post-window recovery limitations. * **Bug Fixes** * Standardized restore-window wording across the pause confirmation and paused-state UI. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
cea246d195 |
Fix: improve accessibility for icon buttons (Table Editor menu) (#47639)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix (accessibility improvement) ## What is the current behavior? Icon-only buttons do not have explicit accessible names for screen readers or tooltips. ## What is the new behavior? All icon-only buttons now have explicit accessible names using visually hidden text (sr-only), ensuring proper screen reader support. ## Additional context Tooltip text is preserved or added for visual users. No visual changes were introduced. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Accessibility Improvements** * Updated table editor action controls with clearer, context-aware `aria-label`s (e.g., “Add new column”, “More options for …”, “New table”). * **UI Refinements** * Added hover tooltips to key table editor actions, including add-column, more-options dropdown triggers, and create-new-table button, improving discoverability and guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a06eb5f26f |
[FE-3724] feat(studio): add enable cleanup button to cron jobs page (#48200)
Adds a standalone **Enable cleanup** button to the Cron Jobs page header so users can schedule the daily `delete-job-run-details` cleanup job proactively — previously this was only reachable inside the conditional "table too big" overflow dialog. Addresses [FE-3724](https://linear.app/supabase/issue/FE-3724/enable-pg-cron-cleanup-job-from-ui-and-api) (the UI half; the Management API half needs platform-side work). **Added:** - `Enable cleanup` button in the cron jobs header (left of Refresh), hidden while the existence check loads and whenever a `delete-job-run-details` job already exists - Confirmation dialog with a retention-period select (defaults to 7 days), live SQL preview, and telemetry (`cron_job_cleanup_enable_button_clicked` with `origin` + `retentionInterval`) - Component tests (MSW) for visibility gating and the schedule/cancel flows - E2E regression test for the full schedule → delete → button-reappears cycle **Fixed:** - Name-based `useCronJobQuery` lookup: the `queryFn` dropped the `name` param, and a not-found job returned `undefined` (rejected by react-query v5) — now passes `name` through and returns `CronJob | null` - Cache invalidation gaps: create/delete now invalidate the whole cron-jobs prefix (list, count, job details), so the footer count updates after create/delete and the button reappears after the cleanup job is deleted. The schedule mutation deliberately invalidates only the existence check + count (see inline comment) - Pre-existing e2e leak: the cleanup-workflow test left `delete-job-run-details` scheduled; it now cleans up after itself ## Screenshots | Header button | Dialog | | --- | --- | | <img width="890" height="325" alt="Screenshot 2026-07-22 at 9 44 40 PM" src="https://github.com/user-attachments/assets/966cd640-d8a6-4c8f-92e7-73151bf4de9c" /> | <img width="512" height="461" alt="fe3724-dialog" src="https://github.com/user-attachments/assets/6be1785f-cc7e-4048-a648-9ef260b0949f" /> | ## To test - Go to a project's Integrations → Cron → Jobs with pg_cron enabled and no `delete-job-run-details` job → the `Enable cleanup` button shows next to Refresh - Open the dialog, switch retention intervals → the SQL preview updates; confirm → success toast, the job appears in the grid (`0 12 * * *`), and the button disappears without a reload - Delete the `delete-job-run-details` job from the grid → the button reappears without a reload - Create then delete any other job → the footer `Total: N jobs` count updates both ways without a reload - Regression: with the high-query-cost banner forced (or via the e2e), the overflow dialog's "Schedule cleanup job" step still shows its success state — the dialog must not close mid-flow <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Added an **Enable cleanup** action to the Cron Jobs tab header, including a retention selector and SQL preview. * Enabling schedules the daily cleanup, shows a success toast, updates the grid, and hides the enable button; **Cancel** closes the dialog without scheduling. * **Bug Fixes** * Improved cron job lookup to work by name when needed. * Refreshed related cron job data more reliably after scheduling and deletion. * **Telemetry** * Added an event for cleanup enable button clicks. * **Tests** * Added component and Playwright coverage for enable/cancel/schedule/delete and cleanup banner flows. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
223a10d1bb |
Add query filter for Database Connections (#48242)
## Context Adds a way to filter against the query string in Database Connections <img width="682" height="161" alt="image" src="https://github.com/user-attachments/assets/1ba6d678-553a-4a1a-9da9-412532c626df" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a free-text search filter for database activity sessions. * Search works alongside existing state, role, and application filters. * Filter option counts now reflect the current search results. * **Bug Fixes** * Improved filter reset behavior to reliably clear search along with all other selections. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b2b150fa3c |
feat(pipelines): Add UI selector for choosing which tables to skip copy of (#47808)
## Summary Adds initial-copy scoping to Pipelines in Studio. Users can copy all existing rows, skip all initial copies, copy only selected publication tables, or skip selected table copies. All publication tables continue streaming new changes regardless of the initial-copy policy. The policy now round-trips through create, edit, validation, and the generated Management API contract. Initial-copy estimates and table-restart confirmations use the same scope. Edit requests also preserve redacted credentials and pipeline settings that Studio does not own. This completes the Studio layer of the [ETL API change](https://github.com/supabase/etl/pull/897) and [Management API change](https://github.com/supabase/platform/pull/35479). ## Screenshots ### Selector <img width="1153" height="465" alt="image" src="https://github.com/user-attachments/assets/bf615e82-ee61-4222-979d-a8695a957e82" /> ### Select certain tables only <img width="1153" height="465" alt="image" src="https://github.com/user-attachments/assets/28adaa24-f239-4d1d-8fb8-fdb1988320cd" /> ### Confirm copy costs As the final step before the pipeline is created: <img width="597" height="619" alt="image" src="https://github.com/user-attachments/assets/a660bd87-bfb8-41c5-8099-4cdbdef943bf" /> ### Policy-aware initial-copy estimate #### Copy no table is selected <img width="407" height="464" alt="image" src="https://github.com/user-attachments/assets/99d859ec-2ec3-452a-ab69-11924a8db260" /> #### Some tables are selected <img width="407" height="464" alt="image" src="https://github.com/user-attachments/assets/e68aedf4-66bc-4372-98ef-0dd7fecef324" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added configurable “initial table copy” policies (copy/skip all and copy/skip selected) during replication setup, including table-picker behavior, pruning of stale selections, and updated restart/cost estimates. - **Bug Fixes** - Improved restart flows to consistently use `schema.table` identity and simplified “errored tables” targeting to match error-state tables. - Reduced unnecessary loading by gating publication/table fetches to when panels are visible; improved validation/toast handling when publication tables are unavailable. - **Tests** - Added/expanded coverage for destination form submission, table-copy selection, restart/cost dialogs, and copy-estimate summarization. - **Style** - Refreshed warning/label text for clearer configuration and confirmation messaging. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Victor Farazdagi <simple.square@gmail.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
a1df468edd |
Add keyboard shortcut to live mode (#48280)
## Context As per PR title - there's already a keyboard shortcut mapping for the live mode toggle that was originally present in `UnifiedLogs`, so this reuses that. Opting for a more explicit tooltip copy as well as "Live" doesn't really explain what it does <img width="257" height="82" alt="image" src="https://github.com/user-attachments/assets/2159eef3-6291-4fdc-93ca-da706c8688f0" /> <img width="195" height="101" alt="image" src="https://github.com/user-attachments/assets/0d5d211c-af66-406d-9cff-7de7b15f0892" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added keyboard shortcut support for toggling live updates in database connections. * Added shortcut guidance to the Live/Pause control. * Resuming live updates now refreshes activity immediately and updates the displayed timestamp. * **Bug Fixes** * Improved live-refresh controls and messaging to clearly reflect the refresh cadence. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6c6a721cb7 |
fix(pg-meta): scope remaining O(catalog) introspection queries behind pgMetaScopedIntrospection (#48148)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix (performance), follow-up to #47894, plus regression-guard tests. ## What is the current behavior? #47894 scoped the Table Editor and entity-definition introspection queries, but four more `@supabase/pg-meta` query families still do O(catalog) work per request. On a production project with a very large catalog (hundreds of schemas, ~465K `pg_constraint` rows) they run 5 to 55 seconds each, trip the 58s `statement_timeout`, and spill sorts to temp files. During a recent "DB CPU > 85%" incident on such a project, 24 of 27 active backends were running these queries concurrently. 1. **`tables.retrieve()` (single-table lookup by name+schema or id)**: the `tables`/`columns` CTEs scan the whole catalog (`pg_class`, `pg_constraint`, `pg_index`, all of `pg_attribute`, per-table sizes) and the one-table predicate is applied only on the outer select. Same bug class #47894 fixed for the OID-based table editor query; this sibling path never got the treatment. It accounted for 94 of the 96 statement-timeout cancellations in the incident. 2. **Types listing**: the `t_enums` and `t_attributes` subqueries aggregate the entire `pg_enum` and every composite relation before the wrapper's schema filter applies. 3. **Table privileges**: `aclexplode` + double `pg_roles` join + GROUP BY over every relation in the database; schema/OID filters applied only after aggregation, in both `list()` and `retrieve()`. 4. **Row counts**: `getTableRowsCountSql` treats `reltuples = -1` (never-analyzed table) as "small table, run exact count(*)". A freshly bulk-loaded multi-million-row table times out on every Table Editor pagination render. Two Studio-side amplifiers turned one slow query into a sustained load storm: - `useTableQuery` (behind `tables.retrieve()`) mounts once per visible foreign-key grid cell via `ForeignKeyFormatter`, so a single Table Editor view fires ~20 concurrent copies against the FK target table. A timed-out query caches nothing, and TanStack retries errored no-data queries on every observer mount by default, so scrolling kept re-issuing the 58s scan. - `useTableApiAccessQuery` fetched table privileges for the entire database and filtered down to one schema client-side. ## What is the new behavior? **pg-meta (all behind the existing `pgMetaScopedIntrospection` flag, same rollout mechanism as #47894; `scoped: false` keeps serving the current SQL):** - `tables.retrieve()`: the identifier is resolved to a scalar `targetOid` init-plan and pushed into the base scan, primary-key, relationships (both FK directions kept: `conrelid` or `confrelid`) and columns CTEs. A materialized `target` CTE was deliberately avoided: it acts as an optimization barrier and forces the very seq scans being removed. - Types: filter `pg_type`/`pg_namespace` first, then compute enums/attributes per surviving row via correlated index-scan subqueries (`pg_enum(enumtypid, enumsortorder)`, `pg_attribute(attrelid, attnum)`). - Table privileges: schema/OID predicates injected into the base WHERE before `aclexplode`/GROUP BY for `list()` and `retrieve()`. - Row counts: `reltuples = -1` is treated as "unknown" and gated on physical size via `pg_relation_size` (a cheap stat call; `relpages` is equally stale pre-vacuum). At or below `THRESHOLD_ESTIMATE_BYTES` (~10MB, derived from `THRESHOLD_COUNT` at a conservative ~200 bytes/row) the exact count runs as before: fast by construction, and it avoids bogus estimates since Postgres floors never-vacuumed heaps at 10 pages, so an empty table would otherwise report ~2K estimated rows. Above the gate the count routes through the EXPLAIN-based `pg_temp.count_estimate`, or returns `-1`/`is_estimate = true` in read-only contexts where the temp function cannot be created. The scoped branch embeds the estimated select via `literal()` instead of legacy's apostrophe-only escaping, so it stays correct under `standard_conforming_strings = off`. `enforceExactCount` unchanged. **Studio:** - The flag decision is contained in the data layer instead of prop-drilled: a small imperative accessor (`apps/studio/data/scoped-introspection.ts`) is hydrated from `useFlag` via a one-line `useSyncScopedIntrospection()` call in `DefaultLayout`, and the query functions read it internally when building the pg-meta SQL. `DefaultLayout` is shared by both the Next and TanStack router trees; hydrating from `_app.tsx` alone would leave TanStack-served pages permanently unscoped since `routes/__root.tsx` mounts its own flag provider. Cold loads cannot race the flag: the query functions await a readiness promise that resolves only after the sync hook has hydrated the accessor with a loaded flag store (immediately on self-hosted where flags are disabled; a 5s safety net armed lazily on the first `ready()` call - not at module import, which would let the timer expire before a project page ever mounts - bounds genuine ConfigCat outages). No component threading, no query-key changes (remaining tradeoff, documented in the module: a mid-session flag flip can serve stale-keyed caches until refetch, fine for a session-stable rollout flag). #47894's existing threading is left as-is and gets deleted together with the flag in the cleanup PR. Also fixes the previously-missing `scoped` pass-through in `getTableRowsCount`. - Flag-independent hardening: `useTableQuery` now sets `retryOnMount: false`, `refetchOnWindowFocus: false` and `staleTime: 5min`. Errored (timed-out) queries no longer refire on every grid cell remount, while stale successful metadata still revalidates on mount after `staleTime`. - `useTableApiAccessQuery` now passes `includedSchemas: [schemaName]`; the client-side filter stays as a safety net. - The rows-count query is `enabled`-gated on the permission check settling, so a transiently-false `canSQLAdminWrite` can no longer cache a read-only `-1` count for a writable user (read replicas short-circuit synchronously as before). **Regression guards (extending the #47894 infrastructure):** - Execution-based scoped-vs-legacy equivalence tests for all four queries: both variants run against the test database and are compared with raw `toEqual` - no normalization, ids included (types across 6 option combos, privileges incl. multi-grantee + PUBLIC, `tables.retrieve` for both identifier branches, row counts for every case where the two paths must agree). Two documented exceptions where only the LEGACY side is sorted, because a de-normalized diagnostic run proved legacy emits genuinely plan-dependent order there (an adversarial-FK fixture shows it is neither oid, name, nor creation order): the `types.list` outer row order (scoped adds `order by t.oid`; legacy has no ORDER BY) and the `tables.retrieve` relationships array (scoped orders by `constraint_name` + column-name tie-breakers - a composite two-column FK expands to 4 entries sharing one constraint_name). Everything else (privileges via `aclexplode` over the same relacl, columns by `ordinal_position`, primary keys by `indkey` order, enums by `enumsortorder`) is byte-identical between the two paths with no test-side help. The one intentional value divergence, never-analyzed tables above the size gate where legacy's exact count is the timeout bug itself, is asserted explicitly as a divergence. - Plan-guard budgets for every scoped query against the stress catalog (extended with 200 enums + 200 composite types). Residual seq scans are justified in-budget: `pg_constraint` max 2 (no index on `confrelid`), `pg_attrdef` max 1, `pg_authid` max 2 (scales with role count, not schema count). - Legacy templates carry a FROZEN do-not-edit marker (they must keep matching production behavior until the flag cleanup deletes them); the ordinary test suite runs against the legacy default, so behavioral drift there fails regular tests. ### Validation - pg-meta: typecheck clean; the affected suites (types, table-privileges, tables, rows-count, catalog-plan-guard) pass in full. - Cross-version: the scoped-vs-legacy equivalence and rows-count behavioral suites were validated on PostgreSQL 14, 15, and 17 (identical results on all three). Two version-marginal planner choices surfaced on 17 (`pg_type` / `pg_class` seq scan vs full-index bitmap for per-schema listings, both structurally unavoidable without an index leading on the namespace column) and are carried as justified plan-guard budget entries. A full 468-test suite run sequentially: 452 passed, 16 failures verified environmental (13 timeouts in an untouched file that passes 27/27 in isolation on the marathon-run cluster, 3 cluster-global role collisions from container reuse). - Studio: `pnpm --filter studio typecheck` clean; 39/39 tests across the touched data hooks; eslint clean on touched files. ### Rollout Same staged ConfigCat rollout as #47894 via `pgMetaScopedIntrospection` (user-email targeting first, then percentage, then 100%). The `useTableQuery` hardening and the API-access schema scoping ship unflagged (behavior-safe). Gate before percentage rollout: functionally verify the FK popover/selector UX under the new `staleTime`/`retryOnMount` settings (a just-edited FK target must not look stale anywhere Studio does not already refetch on save). Once fully rolled out, the legacy templates and flag get deleted together with #47894's in one cleanup PR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
4b24cf028a |
chore(claude): improve CLAUDE.md files and skill triggering (#48261)
Improves the repo's agent guidance: distills the always-required `studio-best-practices` skill into `apps/studio/CLAUDE.md`, tunes every skill description for reliable triggering, and mechanically enforces the generated-files rule. Grounded in Anthropic's official CLAUDE.md guidance (see justifications below). ## The main change: Studio CLAUDE.md gets a Code style section **Why:** `studio-best-practices` was a skill that instructed agents to *always* load it before any Studio code work. Anthropic's guidance draws the line as: sometimes-relevant guidance → skill (loaded on demand); always-relevant guidance → CLAUDE.md. A skill that must always load has failed the test for being a skill — it costs a tool-call round trip and, worse, silently does nothing in sessions that forget to load it. Since `apps/studio/CLAUDE.md` is lazy-loaded only when an agent touches Studio files, inlining is properly scoped: non-Studio sessions never pay for it. **Why not verbatim:** the skill was 175 lines, mostly ❌/✅ worked examples teaching practices models already know. Inlining it whole would push the file past the ~200-line point where Anthropic warns rules start getting lost. Instead each section was distilled to the rule it exists to enforce — e.g. the loading/error/success section kept its code block because the *shape* (early returns at top level, flat `&&` chains inline) is the prescription, and prose loses it. **The framing that makes the generic rules earn their place:** models default to matching surrounding code, and not all existing Studio code follows these practices. The section opens with "older Studio code predates some of these conventions — follow them rather than mirroring nearby legacy patterns," which converts otherwise-redundant React advice into an explicit instruction to break from local precedent. One rule was added that the old skill lacked: `useEffect` is for external-system sync only (~364 Studio files contain effects, many in patterns we don't want copied). **Changed:** - `apps/studio/CLAUDE.md` — new Code style section (84 lines total, within budget); skills table no longer mandates a pre-load - `.claude/CLAUDE.md` — dropped `pnpm install` from commands (guessable; Anthropic's test: "would removing this cause mistakes?") **Removed:** - `.claude/skills/studio-best-practices/` — fully absorbed; its cross-references to other skills were already covered by the skills routing table ## Skill description tuning Descriptions are the only signal an agent sees before deciding to load a skill, and the observed failure mode is under-triggering on tasks that don't name the skill. Nine descriptions reworded: front-loaded matchable keywords, added incidental-trigger cases (e.g. a new feature that adds copy is a `copywriting` moment), and disambiguated overlaps (`vitest` is now the API reference deferring to `studio-testing` for strategy). The `safe-sql-execution` rewrite was additionally validated with skill-creator's trigger-eval loop against 20 realistic queries: held-out test accuracy 54% → 71%, with zero false triggers across all iterations. (`vitest` shows under `.agents/` because `.claude/skills/vitest` symlinks there.) ## Generated-files enforcement **Added:** `permissions.deny` rules in `.claude/settings.json` for the six generated-file globs the root CLAUDE.md already lists. CLAUDE.md prose is advisory; permission rules are mechanical and also gate sandboxed Bash writes. (Verified live: the rule blocked an unintended regeneration of `database-types.ts` during testing.) ## To test - CI: prettier + typos checks pass (docs-only + settings change, no app code) - In a fresh Claude Code session in the repo: ask it to edit `apps/studio/routeTree.gen.ts` — should be denied by the new permission rule - Ask it to do any Studio UI task — it should pick up the Code style rules from `apps/studio/CLAUDE.md` without loading a best-practices skill <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated development guidance for testing, copywriting, SQL safety, telemetry, queries, error handling, and toolbar reviews. * Restructured Vitest references into clearer tables and improved formatting across several guides. * Added Studio code-style conventions and clarified when task-specific guidance should be applied. * Removed outdated Studio best-practices guidance. * **Chores** * Added safeguards preventing edits to generated and protected files. * Simplified the documented development command sequence. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
7f42765070 |
Joshen/fe 3983 no way to create a new project in vercel integration when (#48230)
## Context For the Vercel integration flow (e.g "Deploy with Vercel" button on GH) If an organization has no projects, there currently isn't a way to create a project and connect it in the same session - users can only hit "Skip". This addresses that by directing users to the /deploy-button/new-project route in this scenario <img width="505" height="539" alt="image" src="https://github.com/user-attachments/assets/6cc85030-42c7-4e58-b4b3-cb8ac0f5da9e" /> ## Other changes involved - Also separates `ProjectLinker` into smaller components - preference for avoiding declaration of components within a component ## To test I'm not sure if this can be tested on staging to be honest, but otherwise we can give it a go on production after the changes are through, as this doesn't change any existing logic to the usual "Connect project" flow I did try clicking the "Deploy with Vercel" button on a repo, and just changing the URL to the staging URL at the Supabase step - seems to work <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary * **UI Improvements** * Streamlined the Vercel/GitHub project-linking step while keeping the same create/connect/skip flow, including the searchable project picker, branding/status indicators, and the feature-flagged “create new project” option. * On the Vercel choose-project step, the default selection now reflects the current project context. * **Bug Fixes / Tests** * Improved Vercel install routing query handling to preserve deploy-button configuration when present, with updated automated test coverage. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com> |
||
|
|
d0e781a960 |
Allow users to continue with org if integration installed (#48231)
## Context For the Vercel integration, if the source is marketplace, currently selecting an organization that already has the integration installed prevents the user from proceeding. <img width="267" height="172" alt="image" src="https://github.com/user-attachments/assets/ba3aafa0-f753-4797-89cd-a7f1e16bbdb2" /> Whereas users should just be able to proceed and select a project from within the organization <img width="435" height="226" alt="image" src="https://github.com/user-attachments/assets/e659bc20-6980-4ef2-af5c-8612af99668b" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Enhanced the Vercel integration installation flow with dynamic primary button text (“Continue” vs “Install integration”) based on installation status. * **Bug Fixes** * Updated the install button so it no longer disables when the selected organization already has the Vercel marketplace integration installed. * Removed the “already installed” warning from the main render path. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com> |
||
|
|
f653600517 |
fix(studio): make failed Postgres upgrade banner dismissible (#48260)
- The failed-upgrade banner reflects the API's last-known upgrade status, which stays "Failed" indefinitely even after a project is restored, so it never went away - A hard refresh didn't help, since this isn't client-cached state - Adds a dismiss action, scoped to the attempt's `initiated_at` so a future failed upgrade still shows the banner Fixes FE-3964 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a dismiss control to project upgrade failure notifications. * Dismissed notifications remain hidden for the current project until a new upgrade failure occurs. * Contact support remains available alongside the dismiss option. * **Bug Fixes** * Improved upgrade failure banner behavior by persisting dismissal state across page visits. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7781ee0d04 |
fix(studio): correct realtime settings UI limits to match backend (#48253)
Realtime settings validation in Studio didn't match the backend's actual limits: - \`max_presence_events_per_second\` allowed up to 10000 (backend caps at 5000), - \`max_payload_size_in_kb\` allowed up to 3000 (backend caps at 10000) - \`max_events_per_second\` allowed up to 10000 (backend caps at 50000). Updated the Zod schema limits in both branches of the form's discriminated union to match. Fixes FE-3991 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Increased the allowed limits for realtime event throughput, presence events, and payload size settings. * Administrators can now configure higher-capacity realtime workloads, including payloads up to 10,000 KB. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e6ad56101f |
fix: MFA list Added on value uses last_challenged_at instead of created_at (#48252)
Fixes FE-3985. `TOTPFactors` was displaying `updated_at` (which mirrors `last_challenged_at`) for "Added on" instead of `created_at`. |
||
|
|
8108528682 |
Fix: Update the auth user field in the Logs page (#48237)
- Fix the user filter to work with `edge_logs`. - Update the `auth_user` field to be derived from other log attributes. - Removed filtering for `postgres_logs` since it didn't really filter by user actions, only by user id mentions. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved unified logs user filtering to rely only on exact attribution identifiers from authentication and edge log sources, removing partial message-based matching. - Updated unified logs user identification by deriving `auth_user` from authentication actor IDs or edge JWT subject values. - Refined “user filter reachability” logic to consider only attributable log types (auth and edge). - **Tests** - Adjusted unified logs query tests to match the updated attribution routing and reachability outcomes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
efc0ad3fce |
fix: fix migration dialog does not show the correct content in some edge cases (#48239)
## Problem When two projects have migrations with the same version but different content, the details panel does not update the content and shows the first loaded migration one. ## Solution This is because the CodeEditor does not react to content only changes. Settings its `key` ensures it does. Unfortunately, we can't unit test that the CodeEditor content changes correctly. ## How to test - create two projects and push a migration with the same version but different content on them - open the _Database/Migrations_ page for the first project - click the _View migration SQL_ and ensure its content matches the migration for this project - select the other project using the top bar - click the _View migration SQL_ and ensure its content matches the migration for this project <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved migration SQL display when switching between migrations or projects. * Ensured the code editor consistently refreshes with the currently selected migration’s statements. * Improved type safety for the migration search input. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |