mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
4b2d163a1d86a22f5b263f0c054224111ef81106
350
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4b2d163a1d |
fix(orioledb): use alpha and beta conditionally based on AMI version (#51162)
## Problem - Older orioledb projects show "Public Beta" instead of "Public Alpha" in UI. - List of backups in the "Scheduled backups" tab hangs. ## Solution - show in the UI "Public Alpha" for projects older than 17.11.0.001-orioledb - show in the UI "Public Beta" for new projects - enable scheduled-backup query for "Public Beta" <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Backup availability messages now reflect OrioleDB’s current release stage rather than always describing it as public beta. * AWS backup queries are no longer disabled for every OrioleDB project; they remain disabled during the alpha stage. * **New Features** * Added an informational notice and documentation link for scheduled backups on AWS OrioleDB projects in alpha. * Added release-stage details to the PITR availability notice. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Charis <26616127+charislam@users.noreply.github.com> |
||
|
|
d22702e907 |
refactor(studio): extract user project regions + emergency override hooks (#51033)
## Summary - Extracts `useUserProjectRegions` (org + project region aggregation, fail-open on fetch errors) and `useEmergencyIncidentOverride` (the `ongoingIncident` flag / env var check) out of `useStatusPageBannerVisibility`, so the upcoming incident.io status-page banner can reuse both without duplicating the org/project fan-out logic. - No behavior change for the legacy banner except one intentional fix: `StatusPageBanner.utils.ts` compared the incident's affected regions (lowercased) against the user's regions (not normalized), so a mixed-case region on either side could silently fail to match. Both sides now go through the same `normalizeRegion` helper. - Part of the Linear FE-4057 stack (PR 5a of 6). Base branch is PR 4 (`charis/fe-4057-pr4-project-creation-status-admonition`), not master. Linear: FE-4057 ## Test plan - [x] `pnpm --filter studio run typecheck` - [x] `pnpm --filter studio run lint:ratchet` - [x] `pnpm knip --workspace apps/studio` - [x] `pnpm test:prettier` - [x] `pnpm --filter studio exec vitest run` on the touched test files and the `hooks/misc/` and `components/layouts/AppLayout/` directories (all passing, no regressions) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved status banner targeting by matching incidents against normalized regions across the user’s projects. * Updated banner visibility checks to handle incomplete project or region data, including when project information fails to load. * Improved loading behavior so the banner can be evaluated based on user-region data rather than waiting for separate organization and project requests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b2cf3693dd |
feat(studio): /api/status-page endpoint backed by incident.io Widget API (#50931)
## Summary * Adds `/api/status-page` (Next route + TanStack wrapper), backed by the [incident.io](<http://incident.io>) Widget API, annotating each item with `visible`, `show_banner`, and (for scheduled maintenances) `banner_lead_days`. * Deployment-mode visibility is driven by a new `status_page:visibility_field_ids` custom-content key. * Widget array parsing is fault-tolerant: a malformed item in one array is dropped and logged rather than failing the whole response, so one bad item can't hide a real ongoing incident. * 429s from [incident.io](<http://incident.io>) are retried with equal-jitter exponential backoff, respecting `Retry-After`, up to 2 retries. * Nothing consumes this endpoint yet — it replaces no existing behavior and changes nothing user-visible. Later PRs (this is PR 1 of a stack) wire up consumers behind the `incidentIoStatusPage` ConfigCat flag. Part of [FE-4057](https://linear.app/supabase/issue/FE-4057/frontend-bannerbot-reconfigured) — see Linear for full design context. ## Test plan - [X] `pnpm --filter studio run typecheck` - [X] `pnpm --filter studio run lint:ratchet` - [X] `pnpm knip --workspace apps/studio` - [X] `pnpm test:prettier` - [X] `pnpm --filter studio exec vitest run status-page` — 44 tests passing, including a regression test built from a real production [incident.io](<http://incident.io>) payload that initially failed to parse, and a compile-time type-safety regression test for the array-parsing helper Co-authored-by: Claude Code [charis@supabase.io](<mailto:charis@supabase.io>) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a status page that displays ongoing incidents and maintenance, with visibility and banner settings based on linked incident details. * Status page data is available through a new API endpoint, with caching for successful responses and degraded results. * **Bug Fixes** * Status page data can still display when some linked incident details are unavailable; affected results are marked as degraded. * Improved handling of invalid widget entries so they don’t prevent valid items from being processed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Code <charis@supabase.io> |
||
|
|
7994191e49 |
feat(studio): group consecutive assistant tool calls (#50893)
<img width="913" height="572" alt="image" src="https://github.com/user-attachments/assets/e8112085-508a-49e4-abb1-7550248e611e" /> ## Problem A single Assistant response often produces 10+ reasoning and lookup rows ("Reasoned", "Ran search_docs", …). They push the answer down the chat, use raw tool names, and a fast tool call flashes past before the row goes back to "Thinking...". ## Solution Consecutive reasoning and lookup rows fold into one collapsible group. - **Running:** the header shows a tool only while it executes ("Checking policies in public..."). Between calls it reads "Thinking...", however long that lasts. Each header label stays up for at least 1 second, so quick calls no longer flash. - **Finished:** the header lists what the tools did, e.g. "Searched docs and checked policies", or "…, and 2 more". - **Expanded (any time):** every call is listed under a vertical rule. Rows still in progress shimmer, including several at once for parallel calls. ## How to test 1. Run `pnpm dev:studio` and open the Assistant on a project with a few tables. 2. Ask something that needs several lookups, e.g. "What RLS policies do I have and what do the docs recommend for them?" 3. While it streams, check the collapsed header: - It shows each tool while it runs, then goes back to "Thinking..." between calls. - Labels don't flash. Each stays up for about a second. - Only the shimmer marks progress, with no blinking cursor underneath. 4. Expand the group mid-stream. Rows read like "Checking policies in public..." rather than tool names, and only rows still in progress shimmer. 5. When it finishes, the header lists the actions ("Searched docs and checked policies") and stops shimmering. 6. Press Stop while a group is running. The unfinished row reads "Response interrupted" and stops spinning. 7. Reload the chat. Older groups show their collapsed summaries. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * AI assistant tool activity is grouped into collapsible sections with progress labels while work is underway and summaries when complete. * Expand grouped activity to review reasoning and tool details. Active tools and reasoning are highlighted, while completed reasoning without text is hidden. * Progress labels remain visible briefly during transitions, and active responses display a shimmer effect. * **Bug Fixes** * The loading indicator no longer appears while the assistant is processing a tool group. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
509afd0bf0 | fix(o11y): support partial metric loading (#50867) | ||
|
|
a47397d5fe |
fix(common): restore narrow Feature type (#50850)
The platform API now types `ProfileResponse.disabled_features` as `string[]` (since #48981), which collapsed the `Feature` union to plain `string`, so `isFeatureEnabled` accepted any string and typos went uncaught. **Changed:** - `Feature` is now a local `RuntimeFeature` union (the profile-driven flags) plus the keys of `enabled-features.json`, instead of deriving from the API type - `useIsFeatureEnabled` casts the merged runtime disabled list to `Feature[]`, since the profile field is now `string[]` The runtime feature list duplicates what the backend knows. Once the enum is restored in the API spec, `Feature` can go back to deriving from the generated type. ## To test - `pnpm typecheck` passes - Passing a bogus string to `useIsFeatureEnabled` / `isFeatureEnabled` is now a type error - Nothing behavioral changes, so a quick sanity check that the sidebar / billing / org settings still render is enough <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **No user-facing changes** * This update does not change the app’s visible features or behavior. It includes internal typing adjustments only. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
+8 |
e273d2b818 |
chore(studio): move Explorer SQL Editor link to sidebar footer (#50829)
## What
- Moves the temporary "Switch to SQL Editor" button out of the Explorer
sidebar header into a footer section ("Looking for snippets?") with a
short explanation and an **Open SQL Editor** button.
- Replaces the header slot with a menu for the Explorer startup
preference (**Start page** / **SQL query**), instead of linking out to
account preferences.
## How to test
1. Enable the Explorer feature preview and open
`/project/<ref>/explorer`.
2. **Header menu:** click the ⋮ button next to the Explorer title. Pick
**SQL query**, then check that **Explorer startup** on `/account/me`
shows the same value (and vice versa).
3. **Footer:** click **Open SQL Editor**. You should land in the SQL
Editor with the **Back to Explorer** button in its title bar.
4. Open **Notebooks** or **Chats** in the sidebar and check that the
menu and footer are hidden there, like the old button was.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Choose whether the Explorer opens to the Start page or SQL query from
the Explorer preferences menu. Your selection is saved and retained when
you reopen the menu.
* Access the SQL Editor from the Explorer’s sidebar footer.
* Explorer preferences are available from the Explorer navigation
header.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Tyler <dshukertjr@gmail.com>
Co-authored-by: Nik Richers <nrichers@gmail.com>
Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
Co-authored-by: Jordi Enric <37541088+jordienr@users.noreply.github.com>
Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
Co-authored-by: Katerina Skroumpelou <mandarini@users.noreply.github.com>
Co-authored-by: Franek <franek@ferly.co.uk>
Co-authored-by: Franek Richardson <franek@supabase.io>
Co-authored-by: Michał Olszewski <35968924+charconstpointer@users.noreply.github.com>
Co-authored-by: Steven Eubank <47563310+smeubank@users.noreply.github.com>
Co-authored-by: Anthony Lio <lionnet.ant@gmail.com>
Co-authored-by: Joey Lei <6957385+leizerbeam@users.noreply.github.com>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
Co-authored-by: Samir Ketema <6003000+samirketema@users.noreply.github.com>
Co-authored-by: K-Dog (Kevin) <k.grueneberg1994@gmail.com>
|
||
|
|
8422045b86 |
chore: Use @supabase/config for the code configuration page (#50398)
How to test: 1. Connect a project to GH repo 2. Deploy the `config.toml` once 3. Change some setting in Auth 4. You should see a change in `/dashboard/project/_/settings/code-configuration` <img width="1271" height="1186" alt="Screenshot 2026-09-16 at 16 26 39" src="https://github.com/user-attachments/assets/dfc135a4-e495-489e-88fd-b760383793b4" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Configuration drift comparisons now use a consistent project configuration schema. - Drift details display complete current-environment and `config.toml` values, grouped by section. - Matching and unmanaged settings are organized into dedicated sections. - Configuration fields link directly to relevant Studio settings. - Added a warning that GitHub deployments overwrite local changes. - **Bug Fixes** - Configuration updates now refresh project configuration data automatically. - Improved labels and formatting for boolean and redirect URL values. - Drift errors identify invalid configuration paths and provide corrective guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ad30c04e0e |
Persist last visited explorer tab (#50557)
## Context Saves the last visited explorer tab via `useDashboardHistory`, such that landing back on `/explorer` will open the last visited page. Similar behaviour to Table Editor and SQL Editor Would also be useful when going between the SQL Editor and Explorer to bring snippets over <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Explorer now remembers and restores the last visited query, chat, or notebook tab. * Automatically returns to the Explorer home screen when a saved tab is unavailable. * Displays a loading state while the last visited tab is being restored. * **Bug Fixes** * Closing deleted chat tabs now clears their saved history. * **Tests** * Added coverage for Explorer tab restoration, loading states, and stale history cleanup. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4bb36b944f |
feat(studio): let High Compliance projects opt-in to Assistant data access (#50548)
Orgs with the HIPAA add-on had the Assistant's opt-in level forced to `disabled` on any project marked High Compliance, regardless of what the org picked in its AI settings. The restriction predated our AI provider BAAs. The consequence is those users see the Assistant failing to answer questions about their data w/ no clear path how to fix it, even though the LLM provider supports this use case. This PR removes these Assistant restrictions on the server and client so those projects honor the org's chosen level. Braintrust conversation tracing is unchanged and still blocked for these projects, see [this test case](https://github.com/supabase/supabase/blob/b9800ccf16/apps/studio/lib/ai/braintrust-logger.test.ts#L16-L20). See [comments](https://linear.app/supabase/issue/AI-1153/allow-hipaa-orgs-to-opt-in-to-assistant-data-access-for-high#comment-485a0d46) for legal approval and conditions. The client-side changes enable features like "Debug with AI" on SQL query failures, “Generate/Rename with AI” for snippet titles, and generated Assistant chat titles for these customers. The AI opt-in copy now adds a reminder to obtain consent from data subjects, linking the [shared responsibility model](https://supabase.com/docs/guides/deployment/shared-responsibility-model) based also on [this comment](https://linear.app/supabase/issue/AI-1153/allow-hipaa-orgs-to-opt-in-to-assistant-data-access-for-high#comment-f81ee610). <img width="400" alt="CleanShot 2026-09-17 at 5 01 02 PM@2x" src="https://github.com/user-attachments/assets/d02123f2-3e32-4d83-9f98-7d15e59222ef" /> To test with a HIPAA-enabled project in staging, you can use this [Plan Change [Staging]](https://app.hex.tech/supabase/app/Plan-Change-Staging-032BD32jo1EaisCS85qunf/latest) Hex to add the HIPAA add-on. Once the add-on is present, you can turn on High Compliance from a project's settings. Also in org settings, crank up the Assistant data opt-in level and verify the Assistant is able to answer questions about the project's data. My results testing with opt-in level "Schema, Logs & Database Data": | High compliance setting | Data opt-in working | |--------|--------| | <img width="1302" height="422" alt="CleanShot 2026-09-17 at 5 03 36 PM@2x" src="https://github.com/user-attachments/assets/c416371b-2eb8-49df-9c07-6d8eababb443" /> | <img width="1566" height="1516" alt="CleanShot 2026-09-17 at 5 05 14 PM@2x" src="https://github.com/user-attachments/assets/39624355-7f8f-46ce-9f08-a8acfb9da830" /> | Closes AI-1153 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features - AI-assisted query renaming, snippet title generation, debugging, and tools now follow organization AI opt-in settings rather than project HIPAA status. - Debugging assistance and AI actions remain available for eligible users without additional HIPAA-based blocking. - AI metadata warnings consistently show standard opt-in messaging and permission settings. - AI settings remind users to obtain consent before entering personal data and link to shared responsibility guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
64ab76262e | feat(studio): exhaustion banner links to metrics (#50276) | ||
|
|
6434c48999 |
feat(studio): migrate Auth reports to OTEL (#50469)
## Problem Auth observability charts always queried the legacy logs.all endpoint, even when the OTEL reports rollout was enabled. The existing OTEL SQL also had ClickHouse correctness and parity gaps around timestamp aliasing, JSON types, provider paths, missing values, and error-code attributes. ## Fix Route the ten Auth-specific charts through the OTEL query builders and logs.all.otel endpoint when otelReports is enabled. Preserve the BigQuery fallback, partition React Query caches by backend, and leave the shared API gateway charts on the legacy endpoint. Correct the OTEL queries by qualifying source timestamps, using typed and nullable JSON extraction, preserving missing actor and duration semantics, selecting the right provider path for each event shape, preferring the canonical Auth error-code attribute with a legacy fallback, and applying bounded result limits. Two-minute report intervals now use minute-level SQL buckets instead of falling through to hourly buckets. ## How to test - Run `CI=1 pnpm --filter studio exec vitest run data/reports/v2/auth.config.otel.test.ts hooks/misc/__tests__/useReportDateRange.test.ts` - Run `pnpm --filter studio run lint:ratchet` - Run `pnpm --filter studio run typecheck` - Expected result: all checks pass and generated OTEL SQL preserves legacy report semantics. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Auth observability charts can now use OpenTelemetry data when enabled, while retaining the existing reporting source otherwise. - Switching the data source automatically refreshes the relevant charts. - **Bug Fixes** - Improved Auth observability accuracy for provider, duration, actor, and error-code reporting. - Added safeguards to keep report queries within the supported result limit. - Corrected minute-level grouping for two-minute analytics intervals and three-hour date ranges. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
cc540ff302 |
feat(studio): add safe theme colour controls (#49804)
## What kind of change does this PR introduce? Feature. ## What is the current behaviour? Studio Appearance preferences only select a theme mode. The underlying theme colours cannot be adjusted, and the existing proof of concept allowed unsafe combinations and introduced a bespoke Slider variant. ## What is the new behaviour? - Preserves the existing System, Dark, Light, and Classic Dark theme options. Classic Dark remains a fixed preset. - Adds four theme colour controls using the existing Supabase Slider unchanged. Each control presents a consistent 0 to 100 scale mapped to bounded light and dark ranges. - Previews colour changes while dragging and persists them once the interaction finishes, including rapid pointer gestures. - Stores light and dark overrides separately, validates stored values, clamps legacy values, and removes overrides that return to their shipped defaults. - Adds concise descriptions for Chroma, Contrast, Surface, and Elevation step, with a scoped Reset action shown only when the active theme differs from its defaults. - Keeps Slider in a stable shared chunk so production builds do not create a circular dependency between generated UI chunks. | Before | After | | --- | --- | | <img width="1448" height="1284" alt="CleanShot 2026-09-15 at 14 33 53@2x" src="https://github.com/user-attachments/assets/d55151c7-b2a9-40c6-9468-e77ae685ac38" /> | <img width="1454" height="1958" alt="CleanShot 2026-09-15 at 17 48 47@2x" src="https://github.com/user-attachments/assets/9d302e67-76cc-4341-948c-81713dea2e93" /> | ## To test 1. Open `/account/me` and scroll to Appearance. 2. Switch between System, Dark, Light, and Classic Dark. Confirm the same four modes remain available in the account theme menu. 3. Confirm Classic Dark retains its existing appearance and does not show theme colour controls. 4. In System, Dark, or Light, move each Theme colors slider to both ends. Confirm the dashboard previews the change, remains readable, and the theme cards do not shift or remount. 5. Reload the page and confirm colour changes persist separately for Light and Dark. 6. Return all sliders to their defaults, or select Reset, and confirm the Reset action disappears. 7. In System mode, change the operating system theme and confirm each resolved mode restores its own colour settings. --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com> |
||
|
|
3bac7165bd |
chore(studio): move the TanStack Start deploy onto Nitro (#50030)
Moves the Studio TanStack Start build off the hand-rolled Vercel setup (an `api/server.js` function shim, rewrites in `vercel.ts`, a custom `?dpl=` skew-protection Vite plugin, and `scripts/serve.js` for self-hosted) and onto Nitro, which TanStack Start documents as its deployment path. Documents are served from the static SPA shell on the CDN; only `/api/*` and `/_serverFn/*` invoke the function. **Removed:** - `api/server.js`, `scripts/serve.js`, `scripts/smoke-server.mjs` - The `skewProtectionDpl` Vite plugin, `renderBuiltUrl`, and the `vite:preloadError` reload backstop in `router.tsx` (TanStack Router already reloads once on a failed lazy import) - Rewrites, `functions`, `outputDirectory`, and `cleanUrls` from `vercel.ts` (redirects and headers stay) - `magic-string` and `@jridgewell/remapping` devDependencies, the `preview` script **Added:** - `nitro` plugin in `vite.config.ts`. Preset is auto-detected: `.vercel/output` on Vercel, a self-contained node server in `.output` everywhere else. `vercel.immutableStaticFiles` puts hashed chunks under `/_vercel/immutable/` so tabs opened before a redeploy keep loading their chunks; `functions.maxDuration: 300` carries over the old function timeout - `scripts/vercel-spa-routes.ts`: Nitro module that rewrites the generated Build Output routes (documents -> `_shell.html`, allow-list -> `__server`, missing chunk -> 404, base-path prefixes), with a unit test - `server.ts`: TanStack Start server entry that initializes Sentry before the route tree loads and wraps the handler with `wrapFetchWithSentry` **Changed:** - `start:tanstack` runs `.output/server/index.mjs` directly with Node's `--env-file-if-exists` for the `.env` cascade. Node doesn't expand `$VAR` references, so `scripts/generateLocalEnv.js` now writes literal values into `.env.test` - Dockerfile's TanStack stage copies `.output` instead of running `pnpm deploy`; the `server.js` shim loads `.env` and imports the Nitro server - `NEXT_PUBLIC_BASE_PATH` (the platform's `/dashboard`) only sets the router basepath; Vite's `base` stays at the root so chunks can use the immutable store. The routes module emits prefixed rules for `/dashboard/api/*` and `/dashboard/_serverFn/*` and rewrites `public/` files requested under the prefix back to the root - Self-hosted security headers come from a Nitro `routeRules` entry; on Vercel they stay in `vercel.ts` - `tslib` is inlined for the build only: Nitro's dev runner has no interop for its CJS wrapper - Monaco's worker chunks follow the client assets dir so they land in the immutable store too Verified on the `studio-staging` preview (`STUDIO_FRAMEWORK=tanstack` is scoped to this branch there): documents come back as the static shell, `/dashboard/api/*` hits the function, `public/` files resolve under the prefix, a missing immutable chunk 404s. Across two deployments of this branch, the older deployment's chunks still load from the immutable store and requests carrying its `__vdpl` cookie are answered by that deployment. Self-hosted path covered by the TanStack E2E job and the Docker build job. ## To test - On the `studio-staging` preview: `/dashboard/project/<ref>` should show `content-disposition: inline; filename="_shell.html"` and a single-region `x-vercel-id`; `/dashboard/api/get-utc-time` a two-region id - Sign in and click through a few pages, including one that opens Monaco (SQL editor) so the worker chunks load - After the next deploy, a tab left open on the previous one should still navigate (lazy chunks) and call the API without errors - Self-hosted: `STUDIO_FRAMEWORK=tanstack pnpm --filter studio build && pnpm --filter studio start`, then check `/api/platform/profile` and that responses carry the security headers <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Production TanStack deployments now run on Nitro’s self-contained server output. * Vercel routing serves static pages first while directing API and server-function requests appropriately. * Server-function requests can include deployment identification for consistent handling. * Local environment generation now writes resolved configuration values. * **Bug Fixes** * Improved handling of missing static assets and SPA fallback routing. * Server-side error monitoring now captures request errors in the new runtime. * **Refactor** * Replaced the legacy production server and smoke-test workflow with Nitro-based startup. * Removed automatic reload handling for stale client assets. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
82d7d347c4 |
fix(studio): eliminate per-row query duplication on org team page (#50238)
## Summary * Fixes extreme slowness (browser-crashing on filter) on `/org/[slug]/team` for orgs with 200+ members. * Root cause: `MemberRow`/`MemberActions` each independently subscribed to org-wide React Query data (roles, projects, permissions, feature flags) and rendered a hidden `UpdateRolesPanel` per row. Filtering caused hundreds of duplicate query observers to mount/unmount on every keystroke, each scheduling its own stale-timeout bookkeeping and blocking the main thread for multiple seconds. * Hoisted all org-wide data fetching (`useOrganizationRolesV2Query`, `useOrgProjectsInfiniteQuery`, `usePermissionsQuery`, `useSelectedOrganizationQuery`, `useIsFeatureEnabled`) to `MembersView` and passed the results down as props. * Replaced the per-row `useAsyncCheckPermissions` hook calls in `MemberActions` with the underlying pure `doPermissionsCheck` function memoized locally, removing their internal query subscriptions. * Simplified `useGetRolesManagementPermissions` to stop calling a query-fetching fallback hook that was unreachable given all current call sites already pass `permissions`/`orgSlug` directly. * Replaced 200 hidden per-row `UpdateRolesPanel` instances with a single shared instance owned by `MembersView`, opened via an `onManageAccess` callback. * Cached the regex built by `doPermissionsCheck`'s `toRegexpString` instead of rebuilding it on every permission check. Diagnosed from two Chrome performance traces of the team page while typing in the filter box (multi-second main-thread blocking tasks traced to React Query `QueryObserver` mount/unmount storms). ## Test plan - [X] `tsc --noEmit` clean (only one pre-existing, unrelated error in `packages/ui-patterns`) - [X] `eslint` clean on all changed files (only pre-existing warnings) - [X] `vitest run tests/components/Organization/TeamSettings` — 51 tests pass - [X] Manually verify filtering is smooth on an org with 200+ members <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Team Settings provides centralized member access and role management. * Members can update roles through the access-management panel. * **Improvements** * Permission checks now more accurately handle organization and project scopes, including wildcard patterns. * Member search is debounced for smoother filtering while typing. * Access-management actions use current organization members, roles, permissions, and feature settings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
1966209483 |
chore(deps): upgrade vitest to v5 (#49994)
Upgrades Vitest from 4.1.4 to 5.0.0 across the monorepo, fixes the handful of things v5 turned into hard errors, and drops the `vi.clearAllMocks()` boilerplate that v5's `clearMocks` default makes redundant. **Changed:** - `vitest`, `@vitest/ui`, `@vitest/coverage-v8` 4.1.4 → 5.0.0 (catalog) - `vi.mock` calls that lived inside `beforeAll`/`beforeEach`/test bodies moved to module scope (v5 throws on nested calls). Affects the Studio and docs setup files and four Studio tests. - `detectBrowser` test restores `navigator` via `vi.unstubAllGlobals()` instead of assigning `global.navigator`, which now reaches jsdom's getter-only property. - `RowEditor.utils.test.ts` restores its `JSON.stringify` spy. It used to leak a throwing mock for the rest of the file, which v5's coverage provider now trips over. A later test in the same file had been asserting the leak's side effect (valid JSON reported as invalid) and now asserts the correct behavior. - `@testing-library/jest-dom` 6.6 → 7.0.1. Its vitest type augmentation resolves through a peer now, so it lands on each package's own `vitest` instead of whichever copy pnpm hoisted. Fixes `toBeInTheDocument` type errors in dev-tools after the reshuffle. - `@testing-library/react` 16.0.0 → 16.3.3 for the React 19 peer range. - `vite: catalog:` added to dev-tools, www, and common. Without it they resolved a newer vite than the catalog pin, which forked a second vitest instance in the lockfile. There's now one. - ai-commands custom matcher types use v5's `Matchers<R, T>` form. - 110 test files: `vi.clearAllMocks()` removed from `beforeEach`/`afterEach` hooks, along with hooks that only did that and the imports they left unused. Calls that also reset/restore mocks are untouched. Second commit, mechanical. **Added:** - `.vitest/` to the root gitignore (v5 writes JSON/JUnit/HTML reporter output there) **Removed:** - `vite-tsconfig-paths` catalog entry and deps. Vitest 5 resolves tsconfig paths itself. Release-age note: this sat in draft with a temporary `minimumReleaseAgeExclude` entry for `vitest` and `@vitest/*` while 5.0.0 was inside the workspace's 3-day `minimumReleaseAge` window. That window has closed, so the exclusion is gone and nothing bypasses the release-age gate. **Perf** (local, medians of 3 runs, same machine): | Suite | v4.1.4 | v5.0.0 | |---|---|---| | studio | 144.1s | 141.7s (-2%) | | studio `--coverage` | 156.9s | 146.4s (-7%) | | ui-patterns | 6.27s | 5.07s (-19%) | | ui `--coverage` | 3.35s | 2.14s (-36%) | | www | 0.89s | 0.47s (-47%) | Studio is dominated by jsdom environment setup per file, which v5 doesn't change. `vitest doctor` recommends keeping the current pool config: the vm pools and `isolate: false` all break tests. ## To test - `pnpm install --frozen-lockfile` succeeds with no `minimumReleaseAgeExclude` entry for vitest. - CI: Studio unit tests, ui, ui-patterns, www, docs, and typecheck/lint should all be green. The lint ratchet was checked locally: warning counts on touched Studio files are identical to master. - `pnpm test:studio` locally passes with coverage (588 files, 6240 tests). - Open a Studio test that uses `toBeInTheDocument` in your editor and confirm no type errors on jest-dom matchers, in Studio and in `packages/dev-tools`. - Known pre-existing failures unrelated to this PR: one dev-tools test (`getEventCountBadge` capped pill) fails on master too. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Tests - Improved test coverage for JSON validation and mobile navigation behavior. - Updated test setup, cleanup, environment configuration, and matcher support across application and shared package suites. - Removed obsolete coverage for alternate MCP transport selection. ## Chores - Streamlined TypeScript path resolution and Vitest reporter output handling. - Updated testing libraries and Vitest tooling across documentation, Studio, website, and shared packages. - Added Vitest reporter output to ignored files. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com> |
||
|
|
1131e3e2ce |
fix(ui): default Button variant to default instead of primary (#50160)
## What kind of change does this PR introduce? Bug fix / design-system alignment for the legacy `Button` from `ui`. ## What is the current behavior? Omitting `variant` on the legacy `Button` falls back to brand-green `primary`. That makes accidental greens easy, and it is hard to spot the real main action on busy pages. ## What is the new behavior? - Legacy `Button` now defaults to neutral `default` - Intentional primary CTAs (create, save, submit, marketing CTAs, and matching `ButtonTooltip` usages) now set `variant="primary"` so their appearance is unchanged - Neutral actions that previously relied on the old fallback (cancel, close, back, dashboard nav, and similar) become grey/white - Design-system docs updated; regression tests cover the new default `Button_Shadcn_` is unchanged. It already uses its own CVA default. This is PR 1 of 2 in a stack. PR 2 drops now-redundant `variant="default"` props. ## To test Studio (http://localhost:8082): - `/sign-in`: Sign in stays green - Open a project → Database → Tables: New table stays green - Auth → Users → Invite: Invite user stays green; Cancel / dismiss controls stay neutral - Project Settings → General: edit a field so Cancel and Save appear. Cancel is neutral, Save is green Design system (http://localhost:3003): - Components → Button: default demo is neutral; primary demo is green; featured preview is the default variant Marketing (optional): - www header: Start your project stays green; logged-in Dashboard is neutral <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Style** - Buttons now default to a neutral style, while primary actions across Studio, documentation, marketing pages, forms, dialogs, and error states use prominent primary styling. - Updated button examples and previews clarify the distinction between default and primary variants. - Event registration now includes a directional arrow icon. - **Tests** - Added coverage confirming default button styling and explicit primary styling behave as expected. - Updated related test fixtures to use primary styling where appropriate. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
11289328e5 |
add support for warehouse connection string (#49914)
Add support for connection string for warehouse. This PR gives the ability to enable warehouse on a project and also get the connection string to connect to. > This project is only available in staging for now and gated behind a feature flag <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a Warehouse connection option to the Connect dialog. - Select schemas and tables to replicate, with setup progress, error recovery, and retry support. - View copyable Warehouse connection details, credentials guidance, command-line instructions, and DuckLake setup scripts. - Warehouse availability is controlled by feature configuration. - **Tests** - Added coverage for Warehouse table selection, setup script generation, URL parsing, and connection configuration utilities. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Benjamin <5719034+bnjjj@users.noreply.github.com> Co-authored-by: Charis Lam <26616127+charislam@users.noreply.github.com> |
||
|
|
4b1f93bb99 |
feat(explorer): add path back to SQL Editor for snippet access (#49698)
## 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 ## What is the current behavior? Users who have opted into the Explorer feature preview have no way back to the SQL Editor from within Explorer, so they can't easily check their old snippets. ## What is the new behavior? - The Explorer sidebar title bar now has a button (using the same icon as the SQL Editor/Explorer nav entry) that links to the SQL Editor, with a tooltip explaining it's a temporary switch to access snippets. - Clicking it marks the visit as temporary in localStorage, which surfaces a matching "Back to Explorer" button in the SQL Editor title bar. Clicking that button clears the temporary flag and returns to Explorer. - Fixed the product menu title bar badge slot to sit flush right instead of directly next to the title text. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a quick switch from the Explorer to the project’s SQL Editor. * Added a “Back to Explorer” option in the SQL Editor when opened from Explorer. * Added tooltips to clarify these navigation actions. * Navigation state is preserved per project for a smoother return experience. * **UI Improvements** * Improved product menu spacing and title truncation for better layout handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e73811f1c8 |
fix(studio): restore useTrackExperimentExposure hook (#49763)
Restores `hooks/misc/useTrackExperimentExposure.ts`, fixing the typecheck failure on master that broke the latest Studio production deploy. The hook was deleted as dead code in #49719 (it was genuinely unused on master at the time), but #49534 was in flight and reintroduced a usage in `plan-presentation.ts`. The two PRs merged cleanly with no textual conflict, so nothing typechecked the combination until the deploy off master failed with: ``` plan-presentation.ts(5,44): error TS2307: Cannot find module '@/hooks/misc/useTrackExperimentExposure' ``` **Added:** - `apps/studio/hooks/misc/useTrackExperimentExposure.ts` — restored verbatim from before #49719; no longer dead code since `plan-presentation.ts` imports it ## To test - `pnpm --filter studio typecheck` passes (verified locally) - `pnpm knip --workspace apps/studio` no longer flags the hook (verified locally) - Studio production deploy succeeds once merged https://claude.ai/code/session_01XZGr2n1dBzJ7m3DYsGu852 Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
b0e31be89a |
chore(studio): remove dead code found by knip (#49719)
Removes Studio code that nothing imports, as reported by knip. First PR in a stack of three: this one is pure deletions, #49720 removes the unused dependencies, #49721 upgrades knip and adds the CI gate so this doesn't accumulate again. Every file was verified with a repo-wide grep for its basename, exported symbols, and string/dynamic imports before deletion — none are reachable via `next/dynamic`, a barrel file, or a config. **Removed:** - `Billing/Usage/UsageWarningAlerts/{CPU,RAM,DiskIOBandwidth}Warnings.tsx` (whole directory) - `DataWarehouse/FormFooterChangeBadge.tsx` (whole directory) - `Database/Replication/ReplicationDiagram/EmptyReplicationDiagram.tsx` - `Integrations/Vercel/OrganizationPicker.tsx` - `QueryInsights/QueryInsightsTable/QueryInsightsTableRow.tsx` - `hooks/misc/useTrackExperimentExposure.ts` - `data/ai/{parse-client-code,sql-policy}-mutation.ts`, `data/misc/parse-query-mutation.ts`, `data/database/table-check-rls-mutation.ts` - `data/notifications/notifications-v2-{archive-all-mutation,summary-query}.ts` + their two now-unused keys in `notifications/keys.ts` (`listV2` kept) - `data/platform-apps/platform-app-{update,signing-key-delete}-mutation.ts` - `DateTimeFormats.DATE_ONLY` and the unused `Notebooks.{MarkdownCell,LogCell,ChartConfig}` types **Changed:** - `ReportPadding` no longer has a duplicate default export; its 9 default importers (observability pages) now use the named export Not removed: `CONSTRAINT_TYPE`'s unused members mirror the closed set of `pg_constraint.contype` values, so they're documentation rather than dead code — suppressed narrowly in #49721's knip config instead. ## To test - `pnpm --filter studio run typecheck` and `lint:ratchet` pass - Observability pages (`/project/[ref]/observability/*`) still render with padding — they're the only code touched, via the `ReportPadding` import change - Notifications popover still loads and marks-as-read (the removed keys weren't used for invalidation) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Removed Features** - Removed CPU, memory, and disk usage warning alerts. - Removed the Vercel organization picker and empty replication diagram. - Removed query insights row actions and several SQL assistance tools. - Removed notification summary and archive-all capabilities. - Removed platform app update and signing-key deletion actions. - Removed the form change-count badge and experiment exposure tracking. - **Refactor** - Updated observability reports to use the revised report layout export. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
102d3d1df5 |
Disable disk management for HA projects (#49633)
## Context As per PR title, disables disk management for HA projects, which involves - Disabling "Increase disk size" CTAs in reports/database and the old disk config settings in database/settings - Disabling all input fields related to disk management in settings/infrastructure <img width="1076" height="857" alt="image" src="https://github.com/user-attachments/assets/bfbdfc36-8ae3-41ce-af12-c05b46e620f4" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added High Availability notices and restrictions throughout disk management settings. * Disabled disk size, IOPS, throughput, and autoscaling controls where High Availability limits changes. * Added explanatory tooltips for restricted disk-size actions. * Updated database observability controls to reflect High Availability restrictions. * **Accessibility** * Added an accessible label to the database observability refresh button. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ee3f78ff37 |
fix(studio): hide social sign-in after email sign-up (#49571)
## What kind of change does this PR introduce? Bug fix. Resolves [FE-4264](https://linear.app/supabase/issue/FE-4264/hide-social-sign-in-options-after-email-sign-up). ## What is the current behavior? After a successful email and password sign-up, GitHub and ChatGPT sign-in options remain visible even though they do not confirm or link the new account. The success state is presented in a bespoke `Alert` with verbose copywriting. ## What is the new behavior? The social sign-in options and divider are hidden after email sign-up succeeds. The email confirmation message and link back to sign in remain available. The success state is presented in a standard `success` `Admonition` with clearer copywriting. | Before | After | | --- | --- | | <img width="2576" height="1700" alt="CleanShot 2026-08-26 at 13 47 41@2x" src="https://github.com/user-attachments/assets/a29547b9-7949-4ff3-a1d4-db8bfb3beee6" /> | <img width="2576" height="1704" alt="CleanShot 2026-08-26 at 13 47 00@2x" src="https://github.com/user-attachments/assets/4f778571-74fe-4c20-b76e-a87e0391e4a9" /> | ## To test 1. Open `/sign-up` and complete an email and password sign-up. 2. Confirm the success message is shown without the GitHub, ChatGPT, or `or` options. 3. Open `/sign-in` and confirm GitHub and ChatGPT remain available there. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added shared provider options across sign-in and sign-up flows, including custom providers, external identity providers, and optional SSO. - Added an SSO sign-in button that preserves the current page context. - After successful email signup, alternative signup options are hidden and confirmation messaging appears. - **Bug Fixes** - Improved signup form spacing, submission state, and animated password guidance. - **Tests** - Added coverage for signup behavior across standard and focused-provider configurations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
e10f7cc808 |
feat: Add a config drift page in Studio (#48906)
## New Features - Initial work for showing configuration drift in Studio - This only works for Github-connected projects and it'll show a banner if the project state differs from the git-tracked `config.toml` - Currently behind a feature-flag `ConfigDrift`, enabled on local and staging. - There might be drift shown without changing any setting, this is work-in-progress. <img width="1217" height="1195" alt="Screenshot 2026-08-19 at 23 12 10" src="https://github.com/user-attachments/assets/fb0b18d8-1a93-4595-85cc-e8b8a3462847" /> ## How to test 1. Connect a project to a Github repo 2. Resync the branch on `/dashboard/project/_/branches`. This will trigger deployment of the `config.toml` on your project 3. Change some settings (I recommend `dashboard/project/_/auth/providers` 4. A banner should appear on all project pages with a link ## Tests - Added coverage for configuration conversion, normalization, matching, drift detection, and unmanaged settings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d8563cfc6a |
fix(studio): require full authentication for the support form (#49318)
The support form was exempted from the highest AAL check (since the original MFA rollout in #16813) so that users stuck on the MFA challenge could still file a ticket. The platform API now rejects AAL1 sessions with `403 Insufficient AAL: MFA required`, so for those users the form is simply broken — it renders an error toast and the submit would fail too. This requires AAL2 on `/support/new`, so an AAL1 session gets redirected to the MFA challenge and returns to the form afterwards, and removes the links to the support form from the MFA screen. A dedicated flow for users who can't get past MFA to reach us is being worked on separately and should be out soon! Fixes FE-4218 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added an “Email support” action for multi-factor authentication issues, with a prefilled subject line. - Provided clearer guidance when authentication factors cannot be retrieved. - **Bug Fixes** - Improved authentication error handling based on the session’s assurance level. - Reduced confusing permission and error messages for lower-assurance sessions. - Updated support page access to use standard authentication behavior for a more consistent sign-in experience. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
12a8e31fa6 |
chore(studio): render Sign in with ChatGPT unconditionally (#49375)
<!-- ccr-slack-attribution --> _Requested by **Ivan Vasilov** · [Slack thread](https://supabase.slack.com/archives/C0161K73J1J/p1787296019236949?thread_ts=1787296019.236949&cid=C0161K73J1J)_ ## 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? Chore / feature-flag cleanup. ## What is the current behavior? The "Sign in with ChatGPT" button on `/sign-in` and `/sign-up` sits behind three gates in `useEnabledIdentityProviders`: 1. the static `dashboard_auth:sign_in_with_chatgpt` feature flag, AND 2. either the `ShowSignInWithChatGptButton` ConfigCat flag, OR 3. the `SIGN_IN_CHATGPT_ENABLED` (`siwc-enabled`) localStorage opt-in, flipped by a shareable `?siwc-enabled=1` link via `useSiwcQueryParamOptIn`. The ConfigCat flag resolves client-side, so on a fresh load the button is absent for the first render and appears once the flag comes back. That pushes the rest of the sign-in options down and produces a visible layout shift on the sign-in page. ## What is the new behavior? ChatGPT is gated only by its static `dashboard_auth:sign_in_with_chatgpt` feature flag, which is resolved synchronously from `enabled-features.json`. The button renders on the first paint, with no async re-layout. Removed: - the `useFlag('ShowSignInWithChatGptButton')` call and the `chatgptLocalStorageEnabled || chatGptConfigCatFlagEnabled` branch in `apps/studio/hooks/misc/useEnabledIdentityProviders.ts` - `LOCAL_STORAGE_KEYS.SIGN_IN_CHATGPT_ENABLED` and its `LOCAL_STORAGE_KEYS_ALLOWLIST` entry in `packages/common/constants/local-storage.ts` - `apps/studio/hooks/misc/useSiwcQueryParamOptIn.ts` and its callers in `pages/sign-in.tsx` / `pages/sign-up.tsx` — its only job was writing that localStorage flag - the tests that covered the two removed rollout gates The static `dashboard_auth:sign_in_with_chatgpt` kill switch is untouched. ## Additional context The `ShowSignInWithChatGptButton` ConfigCat flag is reported as 100% enabled (per Joshen Lim in the linked thread). The repo contains no default value, allowlist, or env gate for it — the live value lives only in ConfigCat, so that number is not verifiable from here. Once this merges the flag is unreferenced and should be **archived in ConfigCat by a human**; nothing in ConfigCat was changed as part of this PR. Verification notes: `packages/common` typechecks clean (`tsc --noEmit`) and all touched files pass the repo's Prettier config. Studio's `typecheck`, `lint`, and `vitest` could not be run here — `pnpm install` fails in this environment because `npm.jsr.io` (needed for studio's `@std/path` dependency) is not reachable through the network allowlist, so `apps/studio/node_modules` was never installed. CI should be treated as the first real run of those checks. --- _Generated by [Claude Code](https://claude.ai/code/session_01M21SPvwf6FSthomX4Lj3ZC)_ Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
b044408e79 |
[FE-4185] feat(studio): custom content key for auth page logo link (#49130)
Adds a `dashboard_auth:logo_link_url` custom content key so white-labeled deployments can point the logged-out logo link at their own marketing site instead of the hardcoded `https://supabase.com`. **Added:** - `dashboard_auth:logo_link_url` custom content key (schema, types, default `null`, sample value) **Changed:** - `SignInLayout` and `ForgotPasswordLayout` now resolve the marketing-site logo href from custom content, falling back to `https://supabase.com` — these two shared layouts cover all auth pages (sign-in, sign-in-sso, sign-in-mfa, sign-in-partner, forgot/reset password) in both the Next and TanStack runtimes ## To test - On a normal deployment (key `null`): visit `/sign-in` and `/forgot-password` logged out — the logo should still link to `https://supabase.com` - Set `"dashboard_auth:logo_link_url": "https://example.com"` in `apps/studio/hooks/custom-content/custom-content.json` locally — the logo on those pages should link to `https://example.com` - Signed-in contexts (`logoLinkToMarketingSite` unset) still link to `/organizations` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for configuring the URL linked from authentication-page logos. * Authentication logos now use the configured destination when available. * Added a default destination to ensure logo links remain functional when no custom URL is set. * **Documentation** * Added sample configuration for the customizable authentication logo link. <!-- 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> |
||
|
|
93b5ae71bf |
chore: remove unused useProjectUsageStats hook (#48792)
## Problem `useProjectUsageStats` (`apps/studio/hooks/analytics/useProjectUsageStats.tsx`) has no importers anywhere in the codebase — dead code, and it also still queries BigQuery directly (`logs.all`, no OTEL path), which would've made it another gap in the reports→ClickHouse migration if it were ever wired up. ## Fix Deletes the file. Confirmed nothing imports it, and none of its own imports (`useFillTimeseriesSorted`, `useTimeseriesUnixToIso`, `genChartQuery`, `EventChart`) become unused as a result — all are still used elsewhere. ## How to test - `pnpm tsc --noEmit` — no errors referencing the removed file. - `pnpm vitest run hooks/analytics` — 28 tests pass, no breakage. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Removed the project usage analytics statistics feature, including its data retrieval, time-series processing, filtering, refresh controls, and loading/error states. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8b38e0d1ed |
feat(studio): ClickHouse dialect for logs snippet AI + rewrite to ClickHouse (#48501)
## 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, plus a refactor of the shared logs-rewrite flow. PR 8 of the SQL editor query-source series. Stacked on #48457 — review that one first, and merge this after it. ## What is the current behavior? A `log_sql` snippet runs against the ClickHouse-backed analytics endpoint, but the SQL editor's AI still writes Postgres: inline edits get Postgres system prompts, and the result is run through `sql-formatter`, which mangles ClickHouse backticks and `log_attributes` map lookups. Legacy Logs Explorer saved queries open in the editor as `log_sql` snippets. Those are BigQuery dialect and error against the ClickHouse endpoint the editor runs them on, with no in-editor way out — only the Logs Explorer offered a rewrite. The completion route was also asymmetric. It assembled a schema/code/instruction message for Postgres but forwarded `prompt` verbatim for ClickHouse, so a client wanting ClickHouse had to hand-build the equivalent string. ## What is the new behavior? **Inline AI speaks ClickHouse for logs snippets.** `sqlSourceToDialect` maps a snippet's source to `postgres`/`clickhouse` and `buildCompletionRequestBody` threads it through. For ClickHouse, `useSqlEditorAi` strips code fences from the response and skips `formatSql`. Execution and dialect both follow the snippet type, so a snippet's valid dialect never flips. **Rewrite to ClickHouse in the editor.** A banner offers the rewrite for a logs snippet whose text trips `looksLikeLegacyLogsQuery`, and proposes the result through the editor's existing AI diff view rather than replacing the snippet, so it's accepted or discarded like any other AI edit. Gated on `otelLegacyLogs`: on a non-migrated org the BigQuery text is still correct, so rewriting it would break a working query. The offer is a state machine (`offered` / `rewriting` / `failed` / `noRewriteNeeded` / `dismissed`) with a declarative table of valid transitions, so the states are mutually exclusive by construction and dismissal is terminal. A failure keeps its message and offers a retry; a response identical to the input is reported rather than opening an empty diff. **One place assembles completion prompts.** The route now uses a single template for both dialects, branching only the schema section and — for `intent: 'rewrite'` — the instruction. `lib/ai/clickhouse-logs.ts` is the single home for ClickHouse-logs prompt content, replacing two independently maintained descriptions of the same table. Clients carry no prompt text. **The rewrite flow is shared with the Logs Explorer.** Both surfaces previously hand-rolled the same sequence and had drifted: only one detected a no-op rewrite, they sourced `log_attributes` keys differently, and the Explorer formatted errors with an `as Error` cast. Both now use `useLegacyLogsRewrite` and the same state-driven banner, so the Explorer picks up no-op detection and typed error extraction. **Attribute keys are fetched on submit, not while typing.** The detected source would otherwise feed a reactive query key, making every edit that changed it cost another network call. `useLogsAttributeKeys` is imperative and goes through `queryClient.fetchQuery`, so a source already cached — including by the Explorer header and query panel, which subscribe reactively — is reused. This also closes a gap where inline edits never received keys at all, unlike full rewrites. `getErrorMessage` gains an optional typed fallback and no longer stringifies a bare object into `'[object Object]'`; every existing caller already hand-rolled a fallback, except `QueueSettings`, which interpolated the raw result and now passes one. Nothing here is user-visible until the `sqlEditorLogsSource` flag is enabled. Tests: dialect selection and request-body shape, the ClickHouse prompt content (including that the schema section does not restate the dialect rules), the reducer's valid and invalid transitions, `shouldOfferLegacyLogsRewrite`, on-submit key discovery with cache reuse, and `getErrorMessage`. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an Assistant banner to help rewrite legacy BigQuery-style logs queries into ClickHouse SQL. * SQL assistance now adapts to the selected query type, including relevant log attribute context. * Rewrite suggestions can be reviewed as editor diffs before being applied. * **Bug Fixes** * Improved rewrite failure handling, retry options, dismissal behavior, and “no rewrite needed” messaging. * Error notifications now provide a clearer fallback message when details are unavailable. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
270925b680 |
feat(studio): add dashboard_auth:sign_in_with_chatgpt enabled feature (#48677)
Adds a `dashboard_auth:sign_in_with_chatgpt` enabled-features flag so deployments can disable the sign in with ChatGPT button via `disabled_features`, the same way `dashboard_auth:sign_in_with_github` works. Previously the button was only gated by the ConfigCat rollout flag / localStorage opt-in, so white-labeled deployments with custom auth providers had no way to turn it off. **Added:** - `dashboard_auth:sign_in_with_chatgpt` (default `true`) in `enabled-features.json` + schema - Tests covering the feature-disabled state **Changed:** - `useEnabledIdentityProviders` now gates ChatGPT as `featureEnabled && (localStorageOptIn || configCatFlag)` — the feature flag is the static kill switch, the existing OR'd pair remains the rollout mechanism ## To test - Sign-in and sign-up pages behave exactly as before by default (flag defaults to `true`, ConfigCat/localStorage rollout gate unchanged) - With `dashboard_auth:sign_in_with_chatgpt` in a profile's `disabled_features`, the ChatGPT button no longer renders even with `?siwc-enabled=1` or the ConfigCat flag on - GitHub button gating unaffected <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a feature flag to control ChatGPT sign-in availability. - ChatGPT sign-in is now available only when the feature is enabled and an applicable rollout or opt-in condition is met. - **Tests** - Expanded coverage for ChatGPT and GitHub sign-in provider availability under different feature-flag and rollout conditions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
50e1eb7436 |
chore(eslint): bump eslint-config-next to v16 for useEffectEvent (#48458)
## 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? Chore / build (ESLint config upgrade + lint cleanup). ## What is the current behavior? `eslint-plugin-react-hooks` v5 (pulled in transitively by `eslint-config-next` v15) doesn't recognize stable `useEffectEvent`, so every effect that calls an effect-event handler needs an `eslint-disable react-hooks/exhaustive-deps` to silence a false positive. There are 30 such dead disables across Studio. ## What is the new behavior? Bumps `eslint-config-next` to v16, which pulls in `eslint-plugin-react-hooks` v7 whose `exhaustive-deps` understands `useEffectEvent`, and removes the 30 now-dead disable directives (and their orphaned explanatory comments). Supporting changes: - **Flat-config migration**: v16 is a native flat-config array (v15 was eslintrc), so `eslint-config-supabase` now spreads it directly instead of bridging through `FlatCompat`. - **React Compiler rules off**: v16 enables react-hooks v7's `recommended`, which layers the React Compiler lint rules on top of the two classic rules. These are switched off (derived dynamically from what next enables) to keep this change scoped to the `exhaustive-deps` improvement. - **Plugin-registration fallout** (v16 scopes plugin registration to a file glob rather than registering globally like FlatCompat did): stop re-registering `@typescript-eslint` (shared) and `jsx-a11y` (studio); scope our react / react-hooks / jsx-a11y rule overrides (studio, www) to v16's plugin glob so they don't error on files outside it (e.g. `.cjs`). - **Lint surface preserved**: v16's glob newly includes `.mts`/`.cts` (v15 didn't lint them), which surfaced pre-existing errors in tooling scripts. The shared config keeps the prior surface by leaving `.mts`/`.cts` unlinted; linting them is left as a separate change. - **Ratchet**: rebaselines `@tanstack/query/exhaustive-deps` 9 → 89. v15 forced next's `@babel/eslint-parser` onto `.ts` files, hiding these deps; v16 parses `.ts` with `@typescript-eslint/parser` and correctly surfaces the intentional `connectionString`-excluded-from-`queryKey` pattern. Worth a follow-up to review whether any are real cache-correctness bugs. - Drops three now-dead devDeps from `eslint-config-supabase`: `@eslint/eslintrc`, `@eslint/js`, `@typescript-eslint/eslint-plugin`. Verified locally: `turbo run lint` → 7/7 packages pass with 0 errors; Studio `lint:ratchet` passes; Prettier clean on changed files; typecheck unaffected. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Refined linting configuration and removed outdated lint suppressions across Studio. * Updated Next.js linting support and refreshed related development configuration. * Expanded lint baseline coverage for query-related code. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
66658ab339 |
fix(studio): bucket multi-hour report ranges hourly instead of by minute (#48409)
Selecting "Last 7 days" on an Observability report rendered only the most recent ~10 hours, while the header still showed the full range. `timestamp_trunc` only does minute/hour/day, so `analyticsIntervalToGranularity` floors any sub-hour interval to `minute`. The `'30m'` and `'10m'` intervals used for 7-day and 24-hour ranges therefore asked for 10,080 and 1,440 per-minute buckets. The analytics endpoint caps each query at 1,000 data points, and report queries are ordered newest-first with no `LIMIT`, so the oldest buckets got dropped. Confirmed against a production HAR: 168h requested, exactly 1,000 rows returned, 10.6h of data. Both tiers now use `'1h'` — 168 and 24 buckets respectively, well inside the cap. Applies to Edge Functions, Auth and Realtime reports, which share this helper. Remaining sites that can exceed 1,000 points, not touched here: - Logs event chart (`calcChartStart`) — minute buckets over a range extended 6h earlier (~1,080), and hourly over a range extended 5 days earlier (90d → 2,280) - API and Storage reports (`PRESET_CONFIG`) and `SharedAPIReport` — hardcoded `hour`, so a 90-day custom range is 2,160 points - Query Insights — hardcoded `MINUTE` grouped per query, so unbounded UnifiedLogs is fine; its ladder already caps at 720. Fixes FE-4023 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Updated report date-range interval selection for ranges up to seven days to use hourly granularity instead of 30-minute intervals for clearer, more consistent reporting. * **Tests** * Added automated coverage for interval granularity across minute-, hour-, and multi-week ranges. * Included assertions validating expected hourly bucket counts for a seven-day window. <!-- 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 --> |
||
|
|
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>
|
||
|
|
0fe2366659 |
[FE-3790] fix(studio): hide Multigres from user-facing surfaces (#48191)
Hides the "Multigres" term from user-facing surfaces — it's the tech powering High Availability projects, but "High Availability" is the only term users should see for now (per Slack discussion with Saxon/Ivan). **Changed:** - High Availability badge hover card (project overview) no longer says "Driven by Multigres" - Project creation HA toggle description drops the Multigres name + multigres.com link, keeps the informational copy - All schema dropdowns now hide the `multigres` schema on HA projects, by wiring in the previously-unused `filterSchemasForHighAvailability` helper: - `SchemaSelector` (shared — Table Editor, Functions, Indexes, Triggers, Schema Visualizer, etc.) - `ExposedSchemaSelector` (API settings → exposed schemas) - `EnableExtensionModal`, `CreateIndexSidePanel`, `ForeignKeySelector`, `WrapperTableEditor`, Integrations install sheet `AdvancedSettings` - SQL editor schema autocomplete (`useAddDefinitions`) - Schema list computations in the touched components are now memoized (incl. stabilizing `SchemaSelector`'s `excludedSchemas` default so the memo actually holds) **Added:** - Unit tests for `filterSchemasForHighAvailability` / `resolveHighAvailability` - MSW component test for `SchemaSelector` asserting `multigres` is hidden on HA projects and still shown on non-HA projects The filter is HA-gated on purpose: a self-hosted/non-HA user with their own schema named `multigres` still sees it. The flag-gated Multigres option in Logs is intentionally untouched — that exposure is kept for the Multigres team's debugging (separate track). ## To test - On an HA project (`high_availability: true`): hover the High Availability badge on project overview — no "Multigres" mention; open schema dropdowns in Table Editor / Database pages / SQL editor autocomplete — no `multigres` schema - Project creation with HA entitlement: toggle description has no Multigres wording/link - On a non-HA project: schema dropdowns behave as before <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Made schema dropdowns and related selectors high-availability aware across extensions, indexes, integrations, SQL editing, API exposed schemas, and relationship editors. * Updated project high-availability UI text and badge hover description to remove outdated branding and clarify horizontally scalable Postgres architecture. * **Tests** * Added coverage to ensure the schema “multigres” option is hidden/shown correctly based on high availability, and validated high-availability value handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
0b53a1869f |
fix(studio): wire up siwc-enabled query param opt-in on sign-in/sign-up (#48126)
Add `useSiwcQueryParamOptIn`, which flips on the ChatGPT sign-in rollout localStorage flag when `?siwc-enabled=1` is present, and call it from both pages/sign-in.tsx and pages/sign-up.tsx. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for enabling the sign-in experience via `?siwc-enabled=1`, automatically updating the stored opt-in flag on both sign-in and sign-up pages. * **Tests** * Added coverage confirming the stored flag is updated only for `siwc-enabled=1`, and not for missing, non-`1`, `0`, or repeated/array values. * Added assertions that the behavior is triggered consistently when rendering the sign-in and sign-up pages. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
8962308215 |
Add support for multiple custom auth providers in custom-content (#48030)
## Context Adds support for multiple custom auth providers in custom-content <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for multiple custom sign-in providers via a new plural configuration. * Updated the sign-in page to render all configured custom provider options while maintaining compatibility with the legacy single-provider setting. * Improved the custom provider button display to remove internal prefixes from provider names. * **Documentation** * Updated the configuration schema, examples, and sample data to document the new multi-provider setting. * Marked the legacy single-provider configuration as deprecated in favor of the plural option. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
18b273cde0 |
fix(studio): hide Postgres Version Upgrade logs behind a flag (#48007)
## Problem The legacy Logs Explorer's Postgres Version Upgrade page (Database Operations section) shows no results for most users. pg_upgrade_logs rows aren't tagged with the project attribute the shared logs endpoint scopes on, only a host field, so the project-scoped query returns nothing even though the data exists. ## Fix Hides the Database Operations sidebar section behind a new showPostgresUpgradeLogs feature flag (default off), following the same pattern as showMultigresLogs. The page route itself is untouched, only the sidebar entry point is gated. ## How to test - With the flag off, open the legacy Logs Explorer sidebar and confirm the Database Operations section and Postgres Version Upgrade item are gone - With the flag on, confirm the section and item render as before <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added conditional access to Postgres Version Upgrade logs based on feature availability. * Failed Postgres upgrade notifications now show a “View logs” option only when supported. * **Bug Fixes** * Prevented unsupported Postgres upgrade log links and navigation options from appearing. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
58621818d0 |
feat(studio): switch TanStack skew protection to ?dpl= query params (#48008)
Switches the TanStack build's Vercel skew protection from the `__vdpl` session cookie to `?dpl=<deployment-id>` query params baked into asset URLs at build time. Assets stay pinned to the deployment that built them, while document navigations and API fetches always reach the latest deployment (with the cookie, a session stayed fully pinned — including reloads — until the tab closed). **Removed:** - `pinDeploymentForSession` (the `__vdpl` cookie) from `router.tsx`, plus the cookie clearing in the refresh toast and the `vite:preloadError` backstop - `credentials: 'omit'` on the deployment-commit check — its only purpose was escaping the cookie pin, and API fetches are now inherently unpinned **Added:** - `skewProtectionDpl` plugin + `experimental.renderBuiltUrl` in `vite.config.ts`, active only when `VERCEL_SKEW_PROTECTION_ENABLED=1`. Full coverage needs three mechanisms (Vite has no single hook for this — see [vitejs/vite#13834](https://github.com/vitejs/vite/discussions/13834#discussioncomment-7469745)): 1. `renderBuiltUrl` — CSS `url()`s, images, workers, and `__vite__mapDeps` preload lists 2. a `generateBundle` (`order: 'post'`) rewrite of chunk-to-chunk `import`/`from` specifiers, which Rolldown emits as bare relative paths that `renderBuiltUrl` never sees — with sourcemaps recombined per chunk (`magic-string` + `@jridgewell/remapping` devDeps) so Sentry columns stay exact 3. a post-`buildApp` patch of the prerendered `_shell.html` (script/preload tags + embedded router manifest come from TanStack, not Vite's asset pipeline); without it the entry graph double-downloads because preload and import URLs differ ## To test - Built with fake `VERCEL_SKEW_PROTECTION_ENABLED=1 VERCEL_DEPLOYMENT_ID=dpl_TESTPIN123abc`: every chunk import specifier (static + dynamic), `__vite__mapDeps` entry, CSS font URL, and `_shell.html` asset URL carries `?dpl=`; zero unpinned `/assets/` references remain - Sourcemap accuracy verified by tracing a minified position through the recombined map: resolves to the exact original file/line/column (`use-check-latest-deploy.tsx:62:8`) - Built without the env vars: output contains no `dpl=` anywhere (self-hosted/e2e builds unaffected) - `smoke:tanstack` passes on both builds; `tsc --noEmit` and eslint clean - On the preview: load the dashboard, check Network tab — chunk/CSS requests should carry `?dpl=` matching the deployment; hard reload should hit the latest deployment (no pin on document requests) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Improved deployment consistency by pinning generated asset and module URLs to the current deployment (using `?dpl=`). * Simplified refresh and preload-error recovery to reduce reload-loop risk. * Kept API request behavior aligned with the updated deployment routing/pinning approach. * Preserved correct routing across deployment configurations. * **Developer Experience** * Added build-time tooling to rewrite pinned URLs for client assets while maintaining source map integrity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
320604d0e7 |
feat(studio): ship both upgrade CTA placements, remove A/B experiment (#47881)
## What Concludes the `upgradeCtaPlacement` experiment ([#45858](https://github.com/supabase/supabase/pull/45858)) by shipping **both** placements permanently and removing the A/B scaffolding. The experiment tested two upgrade-CTA placements against a control: - **`user_dropdown`** — an "Upgrade to Pro" button in the account/user dropdown - **`org_projects_list`** — a plan-usage card in the org project list Both moved paid conversion in the same direction over control with no activation downside, and they live on separate surfaces, so we're keeping both rather than picking one. ## Changes - **Remove the experiment machinery.** Deleted `useUpgradeCtaExperiment` (PostHog `upgradeCtaPlacement` flag read, `control` arm, variant selection, per-org localStorage seeding, exposure tracking) and replaced it with a small `useShowUpgradeCta` hook that gates purely on **free plan + hosted platform**. Both placements now render for every eligible free-plan org. - **Telemetry cleanup.** Removed the `upgrade_cta_placement_experiment_exposed` event (pure experiment scaffolding). Kept `upgrade_cta_clicked` (with its `placement` property) so we can still measure the CTAs going forward; de-experimented its wording. - **Dead code.** Removed the unused `prependCard` prop plumbing added to `ProjectList` / `EmptyStates` (no caller ever passed it — the org card renders via the `<aside>`). - De-experimented the remaining doc comments in `PlanUsageCard`. Gating is unchanged in spirit: paid orgs and self-hosted never see the CTA. `useShowUpgradeCta` waits until the org plan is known before returning true, so the CTA fades in for free users and never flashes for paid users. ## Testing - `pnpm --filter common typecheck` and `pnpm --filter studio typecheck` pass. - eslint + prettier clean on the changed files. - Manually checked <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Upgrade/usage CTAs now appear only when the organization is confirmed to be on a free plan, avoiding premature rendering before plan data is available. - Upgrade CTA visibility is now consistently driven across supported project and organization surfaces (including the user dropdown) for org-scoped routes. - **Bug Fixes** - Removed obsolete “prepend” placeholders from the project list loading and grid views to keep card layouts consistent. - **Documentation** - Clarified upgrade CTA telemetry wording and adjusted the frontend telemetry contract. - **Tests** - Added coverage for upgrade-CTA visibility behavior across key scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
17ee3e6977 |
feat(studio): add Multigres log type to unified logs FE-3785 (#47560)
## Problem The Multigres log type is available in the legacy logs collections but was missing from the new unified logs, so Multigres logs could not be selected or viewed there. ## Fix Wire the `multigres_logs` source into unified logs the same way the other single-source types (Realtime, Supavisor, PgBouncer) are: a display label, a filter condition, the derived `log_type` expression, a display-casing entry, and a sidebar icon. ## How to test - Open a project with Multigres logs and go to the new unified logs view - Open the Log Type filter and confirm "Multigres" appears as an option - Select "Multigres" and confirm rows from the `multigres_logs` source are returned and labeled "Multigres" with the network icon - Expected result: Multigres logs are filterable and display correctly, matching the legacy logs behavior ## Notes Level/severity uses the shared `severity_text` fallback that all non-HTTP sources rely on. If Multigres rows come back always classified as success, the OTEL pipeline may not populate `severity_text` for this source (legacy logs read the level from a JSON `event_message`), which would need a source-specific level branch. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for the **Multigres** log type in Unified Logs (labels, icon, and derived filtering/grouping/counting). * Unified Logs now renders Multigres **event_message** by extracting the `msg` field from valid JSON, with correct capitalization. * Unified Logs row click telemetry now recognizes **Multigres**. * The **Multigres** log type option is hidden when the selected project is not high-availability. * **Tests** * Added/updated unit tests for Multigres event-message parsing and shared event-message display behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3667601895 |
feat(studio): add sign in with ChatGPT (#47772)
## 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 ## Summary Introduce a "Sign in with ChatGPT" option gated by the new `dashboard_auth:sign_in_with_chatgpt` feature flag and a manual localStorage rollout switch (`SIGN_IN_CHATGPT_ENABLED`), since the feature is still WIP. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for signing in with ChatGPT alongside GitHub. * ChatGPT sign-in now depends on both a feature flag and an additional rollout setting. * Updated provider availability so the app can show the correct sign-in options. * **Bug Fixes** * Improved validation and coverage to ensure sign-in options appear only when fully enabled. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
944c5862f3 |
Chore/small refactors (#47740)
## Context Just extracting the fixes which I think are applicable from this [PR](https://github.com/supabase/supabase/pull/47695) Main files are - `apps/studio/hooks/analytics/useLogsQuery.tsx` - `packages/common/auth.tsx` - `packages/common/feature-flags.tsx` ## Changes involved - Adjust `useLogsQuery` to accept an object as prop, rather than 4 individual params - This one doesn't address any Sentry issues, but is just a improvement to the function's API imo, more readable - Adjust how user email is retrieved in `feature-flags` - Related Sentry issue [here](https://supabase.sentry.io/issues/7592718607/?project=5459134) - The error is a bit vague, but Claude's attempt to fix looks alright in general IMO - Minimally verified that feature flags are loading as expected still <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved log-related screens and queries for more reliable loading and filtering across the app. * Fixed profile and account data handling so identity details are retrieved more consistently. * Improved authentication handling to better recognize missing user data and keep the app stable. * Updated feature flag personalization to use more accurate account information. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
18431efb25 |
fix(studio): TanStack post-merge fixes — Monaco loader, fonts, CSP (from #46424) (#47657)
Post-merge fixes for the TanStack Start migration (#46424) — things that broke on the TanStack build as master evolved under the migration branches. Kept on their own branch off master rather than piling onto the E2E-matrix PR (#47119); all land on master and cascade up to S6 + the big PR. Common theme: a master PR changed something the Next pipeline handles via `next/font` / `pages/_app.tsx` / `next.config.ts`, but the hand-rolled TanStack equivalent (`routes/__root.tsx`, `styles/fonts.css`, `vercel.ts`) wasn't updated to match — invisible on the Next deploy, broken only on TanStack. --- ## 1. Monaco loader path (#47182) #47182 re-nested the served Monaco assets from a flat `public/monaco-editor/` layout into `public/monaco-editor/vs/` and updated `pages/_app.tsx`, but `routes/__root.tsx` still pointed `loader.config` at the old path, so `loader.js` 404'd and **no Monaco editor mounted anywhere in the TanStack build**. Now mirrors the Next config (`${origin}${BASE_PATH}/monaco-editor/vs`, window-guarded for SSR). Was failing the whole `tanstack` E2E shard on #47119. ## 2. Inter + Manrope fonts (#47306) #47306 renamed Tailwind's sans var `--font-custom` → `--font-sans` and added `--font-heading` (Manrope), set via `next/font` on Next. `fonts.css` still only set the now-ignored `--font-custom`, so the body fell back to the theme's system chain (`Circular, custom-font, Helvetica…`) at weight 450 — that's the "Inter weights look wrong". Manrope was missing entirely. - Wire `--font-sans` (Inter) + `--font-heading` (Manrope) to match `next/font`. - **Vendor all three families** (Inter, Manrope, Source Code Pro) via `@font-face` so nothing depends on the Google Fonts CDN — matches `next/font` self-hosting, and (see below) `font-src` doesn't allow `fonts.gstatic.com` anyway. Verified in-browser: computed `body` → `Inter`, headings → `Manrope`, all loading from local `/assets/*.woff2`. ## 3. Security headers / CSP (next.config.ts `headers()`) The Next build sets X-Frame-Options / X-Content-Type-Options / HSTS / **Content-Security-Policy** / Referrer-Policy via `next.config.ts`. The TanStack build never carried these over — `vercel.ts` only set cache-control, so **the deployed TanStack dashboard shipped with no CSP at all**. The TanStack deploy serves a static shell (no server to attach headers), so they go in the Vercel config: - `security-headers.ts` — shared source of truth, reuses `getCSP()`, env-gated exactly like next.config. - `vercel.ts` — apply to every response (all base-path prefixes): full `getCSP()` + HSTS on platform. - `scripts/serve.js` — the non-platform set (`frame-ancestors 'none'`) for the self-hosted server. **Tested the policy in a real browser** (temporarily enforced it on the TanStack build via /test-supabase-local): everything passed except one real gap — `font-src` was missing `data:`, so GraphiQL's bundled Monaco codicon font and Stripe's payment-element fonts (both data: URIs) were blocked (37 violations on a cold load). Added `data:` to `font-src` in `csp.ts` → violations drop to zero, SQL editor Monaco renders clean. That gap affects the Next build too. --- ## 4. `node:path` import crashing `/project/[ref]/merge` Found by a full-site click-through of the TanStack build (all product areas, ongoing — see below). `useEdgeFunctionsDiff.ts` + `EdgeFunctionsDiffPanel.tsx` did `import { basename } from 'path'` in client code. Webpack (Next) polyfills `path` in the browser; Vite externalizes it, so the whole `/merge` route crashed with "Module \"path\" has been externalized for browser compatibility". Replaced the two `basename` call sites with a string helper. Verified in-browser: `/merge` renders. ## 5. URL shape — Next-style search-param semantics + shim fixes The dashboard produced malformed URLs vs the Next build (strange query params, trailing slashes, `##` hashes). Root cause + audit verified empirically against `@tanstack/react-router@1.170.10`; all fixed with unit tests and browser-verified: - **`createRouter` used TanStack's default JSON search codec** — `?flag=true` became `?flag=%22true%22` via links, repeated `?filter=…&filter=…` collapsed into a JSON array (breaking multi-filter/sort table-editor URLs and the account-page round-trip, which double-encoded), and search values arrived as numbers/booleans where the app expects strings. New `lib/router-search-params.ts` (Next-style: strings in, strings out, repeated keys → string[]) wired into the router. - **Link shim** (`compat/next/link.tsx`): `URL.hash` includes the leading `#` while TanStack's `hash` prop adds its own → every `href="…#section"` navigated to `##section` (hash-scroll broke); `Object.fromEntries(searchParams)` dropped repeated query params. Both fixed. - **Trailing slash injected before the query** on every `?`-only relative navigation (`/auth/providers/?provider=…`): fixed in the compat router (prefix current pathname) and via a custom nuqs adapter (`lib/nuqs-tanstack-adapter.tsx`) replacing the stock tanstack-router adapter, whose `navigate({ to: '?…' })` writes hit the same TanStack behavior (123 files use nuqs). - **Pathname-less `router.push({ query })` leaked path params** — Next re-consumes `ref`/`id` from `query` into the path pattern; the shim didn't, yielding `/editor/17597?schema=public&ref=<ref>&id=17597&filter=…` from table-editor filter/sort, linter panels, and advisor shortcuts. The shim now defaults the pathname to the current route pattern and backfills omitted params. - **Redirects dropped query + hash** (Next's `redirects()` preserves them): `__root.tsx` `matchRedirect` and `routes/index.tsx` now carry incoming params/hash through (consumed rule params excluded, destination's own params win). `/?next=new-project&projectName=zzz` → `/new/new-project?projectName=zzz`; `/sql/quickstarts?template=x#frag` → `/sql/examples?template=x#frag`. Browser-verified post-fix: advisors `?preset=WARN`, providers `?provider=Google`, `?schema=auth` — all clean (no `/?`, no leaks); repeated `filter` params survive hydration; `=true` unquoted; single `#`. ## 6. TanStack `navigate` corrupting query values (Logs Explorer SQL newline loss) TanStack router-core treats a query string embedded in `navigate({ to })` as part of the *path*: `decodePath` percent-decodes it and `sanitizePathSegment` strips control characters, silently deleting every `%0A`. Logs Explorer's SQL (`s` param) lost its newlines on Run/reload — `order by timestamp desc` / `limit 5` glued into `desclimit 5`, which then failed the LIMIT lint. Pre-existing on the TanStack build (the stock nuqs adapter had the same shape); Next unaffected. Fixed by never embedding query strings in `to`: the nuqs adapter and the compat `router.push`/`replace`/`prefetch` (plus the `next/navigation` shim) now pass search as an object through the app codec (`splitInternalUrl` hoisted to `lib/internal-url.ts`). Guard test drives a real `createRouter` with multi-line SQL through both producers. Browser-verified: newlines survive the full Run → reload → re-Run cycle. ## 7. Integration overview markdown never loaded (all integrations) `MarkdownContent` used a template-literal dynamic import (``import(`@/static-data/integrations/${id}/overview.md`)``) — webpack builds a context module for that, Vite can't analyze it, so every integration detail page threw `Failed to resolve module specifier` and rendered no overview text. Fixed with an explicit lazy registry of literal imports (`static-data/integrations/overviews.ts`, drift-guarded by a test) plus an `mdRawLoader()` Vite plugin mirroring next.config's turbopack raw-loader rule. Both runtimes keep working; md stays out of the main bundle. ## 8. GraphiQL editor never mounted (`exports is not defined`) Our `umdAmdShortCircuit()` Vite plugin (which disarms Monaco's global AMD loader for deps like papaparse) rewrote `typeof define === 'function' && define.amd` to `false` inside `monaco-editor`'s bundled copy of marked — whose UMD relies on its own *local* `define` shim — so the whole optimized monaco chunk failed to evaluate and GraphiQL's editor pane stayed blank. The check now only short-circuits when `define` is the global AMD loader. Browser-verified: all four GraphiQL Monaco panes mount, queries execute. (Known follow-up: GraphiQL's Monaco workers fall back to the main thread under Vite — functional, worker wiring is Next-specific `setup-workers/webpack`.) ## 9. `@sentry/nextjs` bundling Next internals — built TanStack bundle crashed (caught by E2E) The E2E suite against the **built** TanStack bundle (not the dev server) found lazy chunks like `table-editor-*.js` dead on arrival: `@sentry/nextjs` (imported by ~25 client files) drags in `next/dist/shared/lib/constants`, whose module scope evaluates `process?.features?.typescript` — optional chaining doesn't guard an undeclared `process` in the browser, so the whole chunk failed at load with `ReferenceError: process is not defined`. Dev shims `process`, which is why weeks of dev-server testing never saw it. Fixed by aliasing `@sentry/nextjs` → `compat/sentry-nextjs.ts` (re-exports `@sentry/react`, same deduped 10.59.0, plus explicit stand-ins for the three Next-only APIs) in the Vite build only. Verified: fresh build has zero Next-internals markers in any chunk; table editor loads clean; full E2E suite run against the built bundle. Note for the stack: `alaister/tanstack-start` / the E2E-matrix branch already carried a different fix for the same crash (a `next/constants` shim) that never made it to master — the cherry-pick onto those branches keeps **both** (the shim covers any other transitive importer; the alias keeps Next internals out of the client bundle entirely). **Follow-up found while fixing:** Sentry is never *initialized* in the TanStack runtime — `instrumentation-client.ts` / `sentry.server.config.ts` are Next-convention files nothing imports under TanStack, so `captureException` calls are silent no-ops. Needs an `@sentry/react` init (+ `tanstackRouterBrowserTracingIntegration`) wired into the TanStack client entry as its own PR. ## 10. GraphiQL Monaco workers + edge-function Deno typings (Vite-only gaps) - **GraphiQL's Monaco workers ran on the main thread** under Vite ("Could not create web worker(s)…" — `setup-workers/webpack`'s `new URL(...)` form isn't rewritten by Vite). A `graphiqlViteWorkers()` plugin resolves the import to graphiql's own `setup-workers/vite` variant for client builds (SSR untouched, Next untouched); the setup-workers chain is `optimizeDeps.exclude`d because the Rolldown optimizer can't load `?worker` ids. - **Edge-function editors silently lost their Deno typings** — `AIEditor` loaded `public/deno/*.d.ts` via `/* @vite-ignore */` imports that always failed at runtime under Vite. The `.md` raw loader is generalized into `rawTextLoader` (exact-path allowlist for the two typings files, served as virtual string modules so the dep scanner never parses `.d.ts` syntax), and the imports are now static-analyzable literals that both bundlers handle (turbopack's raw-loader rules match them on the Next side). ## Split out for reviewability App-level fixes that reproduce on the Next build too (DOM-nesting hydration errors, the ghost deleted-snippet nav, the recurring pg-meta `migrations` 400) moved to their own PR: #47667. Sentry initialization for the TanStack runtime (captures were silent no-ops) is #47666, stacked on this PR. ## Full-site test campaign Drove every dashboard product area on the local TanStack build (Playwright, human-style) hunting migration regressions: redirects/404/catch-alls, org, account, project home/branches/merge, table editor CRUD, SQL editor (Monaco/run/save/templates/AI), all database pages, all auth pages, storage CRUD, edge functions + realtime, logs/observability, advisors, settings, integrations hub incl. nested routes, global UI (palette/connect/switchers/theme/fonts), and a cross-cutting sweep (document titles, back/forward chain, hard-refresh hydration on deep URLs, trailing-slash active state). Every failure found is fixed above and re-verified in-browser; remaining console quirks were cross-checked against the deployed Next build and are pre-existing (tracked separately). ## To test Most fixes are already browser-verified + covered by unit tests and the self-hosted E2E suite; the last two landed after the final browser pass and still need an in-browser check: 1. **GraphiQL Monaco workers** — restart the dev server (clear `apps/studio/node_modules/.vite` once first — the optimizer cache may hold a stale prebundle of the worker chain). Open `/project/<ref>/integrations/graphiql/graphiql` with the console open: the `Could not create web worker(s). Falling back to loading web worker code in main thread` warning must be gone, and DevTools → Sources → Threads shows the three workers (json, editor, graphql). Autocomplete in the query editor stays responsive. 2. **Edge-function Deno typings** — `/project/<ref>/functions/new`: no "Failed to load … typings" console error, and typing `Deno.` in the editor offers typed completions (e.g. `Deno.env`). Spot-checks for the rest (all previously verified): - `/project/<ref>/merge` renders (no "Module path" crash). - Multi-line SQL in Logs Explorer survives Run → reload (no `desclimit` gluing, no LIMIT-lint false failure); `s` param keeps `%0A`. - `/auth/providers` → open a provider → `?provider=…` with no trailing slash before `?`; table-editor filter/sort URLs carry no leaked `ref`/`id` params; `/?next=new-project&projectName=x` lands on `/new/new-project?projectName=x`. - Integration detail pages (cron/queues/vault/data_api) show their overview prose; GraphiQL query editor mounts. - Built bundle (`MODE=test vite build` + `start:tanstack`): table editor loads with no `process is not defined`. - `curl -sI` any page on a platform deploy: `X-Content-Type-Options: nosniff` (was the invalid `no-sniff`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Centralized integration overview markdown loading with registry-based lookup. * Improved Monaco loading/asset path handling for smoother editor startup. * **Bug Fixes** * Next-style navigation/search handling now preserves pathname, hash, repeated query keys, and special characters (including newlines). * Redirects now reliably carry over query and hash with correct precedence. * **Security/Configuration** * Updated CSP font sourcing and unified security headers delivery across environments; conditional HSTS behavior. * Refreshed font CSS variables and font-face definitions to match the theme. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- ### Review feedback: non-prod favicon (Joshen) The TanStack `__root.tsx` hardcoded the prod favicon; local + hosted staging now use the white staging favicon (`/favicon/staging`), matching what `pages/_app.tsx` passes to `MetaFaviconsPagesRouter` for non-prod. Rather than pull the pages-router component into the TanStack head, it reuses the same synchronous `NEXT_PUBLIC_ENVIRONMENT` signal the file already uses for `IS_DEV_TOOLBAR_ENABLED` (the `head()` route option isn't a React component, so it can't run `_app`'s async CLI check — but the env signal covers the reported local/staging case). --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
9af6e65df4 |
fix(studio): DOM-nesting hydration errors, ghost deleted-snippet nav, and migrations query 400s (#47667)
App-level fixes that reproduce on BOTH the Next and TanStack builds — split out of #47657 (which stays TanStack-only) for reviewability. All were found by a full-site click-through of the dashboard. ## Invalid HTML nesting (React 19 "will cause a hydration error" console errors) - **FormLayout description rendered in a `<p>`** (`packages/ui-patterns`): consumers pass arbitrary JSX (the RowEditor's `created_at` timezone note passes a `<div>` with `<p>`s) → `<p>`-in-`<p>` / `<div>`-in-`<p>`. Container is now a `<div>` with identical classes (Tailwind preflight makes them render the same). - **Switch toggles nested inside Tooltip trigger buttons** (button-in-button) in ColumnEditor ("Allow Nullable" + "Is Unique"), ExtensionRow, and PublicationsTableItem → repo-standard `TooltipTrigger asChild` + `<div>` wrapper. - **Saved log queries rendered a `<div>` directly inside `<tbody>`** (`/logs/explorer/saved`) → rows are now proper `<tr><td colSpan>` wrappers; the component itself is untouched (it's valid in its sidebar usage). - **Nested anchors in observability metric cards**: a card-level `<Link>` wrapped MetricCard's "More information" `<Link>` (identical URLs) → the chevron affordance renders as a `<span>` when no `href` is passed; clicks bubble to the card link, tooltips preserved. Design-system standalone usage unaffected. - **`objectFit="cover"` passed to modern `next/image`** on the featured integration card (unknown-prop warning) — the className already had `object-cover`; prop dropped. ## Ghost dead-snippet after deletion Deleting the active SQL snippet left its id in `useDashboardHistory` (`history.sql`), so the "SQL Editor" nav item navigated to `/sql/<deleted-id>` — content fetch 404s, no editor pane renders, and a phantom tab reappears. Fixed both ends: delete flows now purge dashboard history (and the tabs store clears a stale `previewTabId`), and `/sql/[id]` treats a snippet 404 as "clean up + `router.replace` to `/sql/new` + toast" instead of rendering the dead state. Unit tests for the store/history cleanup. ## `pg-meta` migrations query 400s on every project load `ActivityStats` on project home runs the migrations list query, whose SQL was a bare `select * from supabase_migrations.schema_migrations` — that table only exists once a migration has run, so every other project logged a failed `?key=migrations` request on every load (visible in production consoles too). The SQL is now guarded with `to_regclass` + `query_to_xml` (same pattern as the advisor lints' `storage.buckets` guard), returning zero rows instead of erroring; legacy version-only tables still work. Tested against real dockerized Postgres (absent table, populated ordering, special chars, legacy schema) + MSW hook tests. Found and verified via /test-supabase-local (browser click-through + console audit on both builds). ## To test Console must stay free of React DOM-nesting errors ("cannot be a descendant of" / "cannot contain a nested") on each surface: 1. Table editor → Insert row panel (`created_at` field renders its timezone note) and Edit column panel ("Allow Nullable"/"Is Unique" tooltips still hover). 2. `/database/extensions` and `/database/publications` → toggle switches render, tooltips hover. 3. `/logs/explorer/saved` (with ≥1 saved query) → rows render full-width inside the table, hover shows Actions. 4. `/observability` → no nested-anchor error on load; card body click and the chevron both navigate; label help-icons still show tooltips. 5. `/integrations` → no `objectFit` unknown-prop warning; featured card images still cover. 6. **Ghost snippet**: open a SQL snippet → delete it via the sidebar → click the "SQL Editor" nav item → lands on `/sql/new` (no phantom tab, no 404 content fetch). Direct-load `/sql/<random-uuid>` → toast + redirect to `/sql/new`. 7. **Migrations 400**: load project home with a project that has never run a migration → the `pg-meta/<ref>/query?key=migrations` request returns **200** with `[]` (previously a 400 on every load). Database → Migrations still lists real migrations when they exist. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Bug Fixes** * Deleted SQL snippets are fully removed from dashboard history and stale editor/tab state; users are redirected with a toast. * Closing preview tabs no longer leaves stale references. * Improved toggle/tooltip/dialog interactions to avoid broken UI, including metric headers showing tooltips even without direct links. * Migrations display safely when migration tables/relations are missing. * **UI Improvements** * Refreshed layout for saved queries, form descriptions, and integration imagery. * **Tests** * Added coverage for snippet history cleanup, tab removal, migrations SQL behavior, and query edge cases. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- ### Review feedback: `query_to_xml` breaks on Multigres (Ivan) The defensive migrations query (added here to stop the `?key=migrations` 400 when the table doesn't exist yet) originally guarded with `query_to_xml`, which is forbidden through Multigres's pooler (MUL-736 / PSQL-1318). Rewritten without `query_to_xml`/`xmltable` using the splinter#170 pattern: a PL/pgSQL `do` block guarded by `to_regclass` (PL/pgSQL defers planning, so a missing table never errors) stashes the rows into a transaction-local GUC via `set_config`, and a trailing `select` reads them back with `jsonb_array_elements`. Verified that postgres-meta sends the whole SQL as one simple-query string → single implicit transaction → the local GUC survives to the `select` and doesn't leak into the pooled connection. 6/6 dockerized-Postgres tests (absent table → `[]`, populated/ordered/special-chars, legacy version-only table, full pg-meta-shaped multi-statement string, GUC non-leakage). Note (out of scope, pre-existing): `packages/pg-meta/src/sql/studio/advisor/lints.ts` still uses `query_to_xml` — a separate pre-existing Multigres risk that should get its own splinter-pattern sync. --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> Co-authored-by: Saxon Fletcher <saxonafletcher@gmail.com> |
||
|
|
5dc054ae8f |
feat(studio): warn in Connect sheet when Data API is disabled (#47537)
## What kind of change does this PR introduce? Feature. Resolves DEPR-599. ## What is the current behavior? When the Data API is disabled (PostgREST has no exposed schemas), the Connect sheet still shows client-library setup steps for Framework and MCP modes without indicating that database queries will fail. ## What is the new behavior? When database access via the Connect instructions requires PostgREST, an inline warning appears above the steps (setup instructions remain visible): - **Framework**: warns when Data API is off; install, env vars, and auth/SSR setup still work - **MCP**: warns only when Database tools apply (selected explicitly, or by default when no feature filter is set) The warning fails open if PostgREST config cannot be loaded, and links to Data API settings via an "Enable Data API" CTA. | After | | --- | | <img width="1664" height="718" alt="CleanShot 2026-07-02 at 21 29 16@2x" src="https://github.com/user-attachments/assets/80d21927-c4dd-4158-8946-bf648b95e451" />| ## Additional context - Gating logic lives in `ConnectStepsSection.utils.ts` with unit tests - Out of scope: warning when Data API is on but zero tables/schemas are exposed - Coexists with the upcoming warehouse branch's catalog warning — that lives in a separate `WarehouseCatalogPanel` for `catalog` mode only <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Connection setup now checks Data API enablement and conditionally shows a “Data API disabled” warning, including an action to open Data API settings. * **Bug Fixes** * Warning logic now more accurately reflects the selected connection mode and chosen feature/tool selections. * **Tests** * Added a focused test suite covering the Data API configuration decision rules and when the warning should appear. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a6a04f24cd | fix(studio): correct exposed-schema settings for the Data API (#47511) | ||
|
|
3fcf980b0a |
fix(studio): batch of production Sentry crash fixes (array/null guards) (#47460)
Fixes a batch of production Studio crashes from Sentry (all caught by the global error boundary). Most are missing array/null guards where an endpoint typed as an array — or with a nested array field — returned a non-array body in production; a few are one-off render crashes. Resolves FE-3748. ## Issues fixed | Sentry | Error | Fix | | --- | --- | --- | | [J7R](https://supabase.sentry.io/issues/7492997940/) | Maximum update depth exceeded | Disable RadialBar animation in disk-cooldown countdown | | [JR5](https://supabase.sentry.io/issues/7548484681/) | resourceWarnings.find is not a function | Guard in ResourceExhaustionWarningBanner | | [JCJ](https://supabase.sentry.io/issues/7506024989/) | resourceWarnings.find is not a function | Guard in ProjectLayout + normalize query | | [K1Y](https://supabase.sentry.io/issues/7584792331/) | snippet.name on undefined | Optional-chain SQL editor download filename | | [B3K](https://supabase.sentry.io/issues/7141649636/) | pagination.count on undefined | Guard pagination in projects infinite query | | [JVP](https://supabase.sentry.io/issues/7560437621/) | schemas.some / extensions.find | Coerce pg-meta lists to arrays in useInstalledIntegrations | | [JR2](https://supabase.sentry.io/issues/7548339272/) | extensions.find is not a function | (same fix as JVP) | | [JQR](https://supabase.sentry.io/issues/7547163939/) | lints.filter is not a function | Normalize project lints query | | [JR3](https://supabase.sentry.io/issues/7548433501/) | entitlements.find is not a function | Guard call sites + normalize entitlements query | | [JQS](https://supabase.sentry.io/issues/7547557098/) | selected_addons.find is not a function | Normalize addons query arrays | <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved stability across several Studio screens by handling missing or unexpected data more safely. * Downloads now use a fallback name when a snippet name isn’t available. * Project, entitlement, schema, addon, warning, and extension views are less likely to break when data is missing or not in the expected format. * Pagination and countdown visuals now behave more consistently, with reduced chance of runtime errors or animation-related glitches. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com> |
||
|
|
0abfbdd3d7 |
fix(studio): preserve session and redirect to MFA when AAL elevation is needed (#47145)
## 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? `withAuth` calls `signOut()` and redirects to `/sign-in` whenever the current AAL is below the required level. For IdP-initiated SSO logins — where the user lands directly on `/dashboard` rather than passing through `/sign-in-mfa` — this destroys the valid AAL1 session that was just established. Subsequent mgmt-api requests then return 401 Unauthorized, and the user is dumped on `/sign-in` with no way to recover except restarting the SSO flow (which loops them back to the same state). The platform already returns an actionable `403 Insufficient AAL: MFA required` on the first mgmt-api request, but the dashboard does not capture it. ## What is the new behavior? `withAuth` now distinguishes between "not logged in" and "needs AAL elevation": - **Logged in but AAL1** → `router.push('/sign-in-mfa?returnTo=…')`, session preserved. The existing `/sign-in-mfa` page picks up the session, renders the MFA form, and bounces the user to `returnTo` after a successful challenge. - **Not logged in** → unchanged: `signOut()` then redirect to `/sign-in?returnTo=…`. - `/sign-in-mfa` is also added to the "already there, do nothing" guard so the user isn't re-redirected mid-challenge. This relies on the gotrue client's local AAL state via `useAuthenticatorAssuranceLevelQuery`, which fires before any mgmt-api request, so no fetcher-level error parsing is needed. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved multi-factor authentication (MFA) elevation flow to preserve user sessions instead of forcing sign-out and requiring users to restart sign-in. * Fixed unnecessary redirects when users are already on sign-in pages. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
c6fc456910 |
chore: cleanup duplicate exports studio (#47387)
## Problem Knip reports many duplicate exports (both named and default). Besides, we're moving away from default exports and even have an eslint rule to enforce it on new code. ## Solution - Cleanup those exports - Update imports when necessary No functional changes. If it builds, it's fine |