Commit Graph

333 Commits

Author SHA1 Message Date
Coenen Benjamin
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>
2026-09-07 11:24:42 +02:00
Charis
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 -->
2026-09-01 09:07:54 -04:00
Alaister Young
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>
2026-08-31 10:10:30 +00:00
Alaister Young
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>
2026-08-31 10:55:23 +08:00
Joshen Lim
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 -->
2026-08-27 22:17:34 +08:00
Danny White
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>
2026-08-26 07:01:47 +00:00
Ivan Vasilov
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 -->
2026-08-25 13:56:40 +02:00
Ali Waseem
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 -->
2026-08-21 08:27:37 -06:00
claude[bot]
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>
2026-08-21 11:32:22 +02:00
Alaister Young
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>
2026-08-17 09:15:53 +00:00
Jordi Enric
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 -->
2026-08-06 16:02:56 +07:00
Charis
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 -->
2026-08-04 09:02:40 -04:00
Alaister Young
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>
2026-08-04 13:58:43 +07:00
Charis
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 -->
2026-07-31 09:01:05 -04:00
Ali Waseem
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 -->
2026-07-29 11:16:47 -06:00
Cemal Kılıç
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 -->
2026-07-28 10:31:17 +02:00
Alaister Young
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>
2026-07-27 17:58:32 +08:00
Alaister Young
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>
2026-07-23 00:08:11 +08:00
Cemal Kılıç
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>
2026-07-21 12:13:13 +02:00
Joshen Lim
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 -->
2026-07-20 11:02:15 +08:00
Jordi Enric
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 -->
2026-07-17 10:07:00 +02:00
Alaister Young
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>
2026-07-16 23:46:40 +08:00
Mert YEREKAPAN
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 -->
2026-07-15 12:17:07 +00:00
Jordi Enric
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>
2026-07-10 16:38:41 +00:00
Cemal Kılıç
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 -->
2026-07-09 16:32:31 +02:00
Joshen Lim
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 -->
2026-07-08 23:21:48 +08:00
Alaister Young
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>
2026-07-08 14:52:59 +08:00
Alaister Young
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>
2026-07-08 12:32:11 +08:00
Danny White
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 -->
2026-07-07 18:05:19 +00:00
Andrey A.
a6a04f24cd fix(studio): correct exposed-schema settings for the Data API (#47511) 2026-07-07 16:37:21 +02:00
Ali Waseem
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>
2026-07-02 08:38:17 +00:00
Charis
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 -->
2026-06-29 13:28:46 -04:00
Gildas Garcia
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
2026-06-29 15:46:16 +02:00
Jordi Enric
2aa1b52234 feat(studio): add feature to rewrite queries DEBUG-145 (#47266)
## Problem

Moving the Logs Explorer to ClickHouse means users' saved BigQuery
queries no longer run.
<img width="2430" height="1010" alt="CleanShot 2026-06-29 at 11 36
04@2x"
src="https://github.com/user-attachments/assets/ae0ab155-7d3d-4ae9-81c3-22bf3a88cf8c"
/>

## Fix

Rewrite the query with AI instead of a SQL transpiler. AI handles the
long tail of nested fields and dialect differences far better than a
rule-based rewriter, and it needs no extra runtime dependency.

- `rewriteLogsSqlWithAI` posts the current query to
`/api/ai/code/complete` with `dialect: 'clickhouse'`. The endpoint skips
the Postgres schema and best-practices for that dialect and uses
logs-specific instructions and model so the output is ClickHouse logs
SQL (FROM `logs` + `source` filter, no `unnest` joins, nested fields
read from `log_attributes['...']`).
- The query's `source` is detected and its real `log_attributes` keys
are fetched and passed to the model, so it maps to exact paths instead
of guessing.
- The rewrite runs in the background and is proposed as a side-by-side
accept/discard diff in the editor. The AI Assistant panel is not opened.
- Entry points: a banner shown only for legacy-looking queries
(dismissal persisted), and a "Fix Query" button next to Field Reference.
- The Field Reference drawers discover `log_attributes` keys from real
data so the listed fields match what the source actually emits.

## Dependencies

Built on top of #47265 (Logs Explorer -> OTEL endpoint) — that is the
base branch of this PR. Merge #47265 first. Behind `otelLegacyLogs` (off
by default).

Part of DEBUG-145 (split from #47087).

## How to test

- Open the Logs Explorer with a BigQuery logs query (the templates have
some), click "Fix Query", and confirm the diff shows valid ClickHouse
SQL. Accept it and confirm the applied query runs.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added an OTEL legacy logs workflow (behind a feature flag) with an
interactive banner and a “Fix Query” ClickHouse rewrite action,
including an accept/discard diff review overlay.
* Introduced OTEL-aware field reference rendering with dynamic discovery
of `log_attributes` keys and updated OTEL source insertion behavior.
* Enabled dialect-aware SQL completion for ClickHouse logs, using
logs-specific instructions and output constraints.
* **Bug Fixes**
* Improved rewrite flow validation and handling, including log source
detection and cleanup of AI-generated SQL formatting.
* **Tests**
* Added Vitest coverage for rewrite prompt generation,
detection/classification utilities, SQL fence stripping, OTEL field
mapping, and OTEL log attribute key discovery.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-06-29 14:31:18 +02:00
Saxon Fletcher
143769afac feat(studio): shared High Availability disabled hook and UI primitives (#47322)
Add generic building blocks for blocking features on High Availability
projects:

- useHighAvailability hook: HA state only (isHighAvailability,
isPending)
- HighAvailabilityDisabledEmptyState (full-page empty state)
- HighAvailabilityDisabledSectionNotice (in-section admonition)

The components carry a generic default title/description; consuming
pages pass their own copy via props. HA state is read from the project's
high_availability flag (same source as the High Availability badge on
the project home page).


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added clearer messaging for features that aren’t available in High
Availability projects.
* Introduced a standard High Availability status check to help the app
adapt what it shows.
* **Bug Fixes**
* Hid non-applicable schema options when High Availability is enabled,
reducing confusion in selection lists.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 16:08:24 +08:00
Jordi Enric
e0ba04caf4 feat(studio): migrate per-service log pages to OTEL endpoint behind a flag DEBUG-145 (#47264)
## Problem

The legacy per-service log pages (postgres, auth, api, edge functions,
storage, realtime, cron, etc.) and the single-log detail panel query the
BigQuery-backed `logs.all` analytics endpoint. We are moving these reads
onto the OTEL ClickHouse endpoint (`logs.all.otel`).

## Fix

- Add `Logs.utils.otel.ts`: ClickHouse query builders
(rows/count/chart/single) + row mappers that target the single `logs`
table keyed by `source`, reading fields from the `log_attributes` map
and aliasing columns to the leaf names the renderers expect.
- Parameterize `buildWhereClauses` / `genWhereStatement` in
`Logs.utils.ts` so the OTEL builders reuse the shared nested AND/OR
filter grouping. Defaults keep the BigQuery behavior unchanged.
- Gate `useLogsPreview` (rows, count, chart) and `useSingleLog` (detail)
on the new `otelLegacyLogs` flag. BigQuery stays the default when the
flag is off.
- Extract the OTEL timestamp parser into `parseOtelTimestamp`
(`otel-inspection.utils.ts`) and reuse it in
`unified-logs-infinite-query.ts` (replaces an inline copy of the same
logic; no behavior change).

## Dependencies

None. Standalone, safe to merge on its own. Behind `otelLegacyLogs` (off
by default), so no user-facing change.

Part of DEBUG-145 (split from #47087).

## How to test

- In staging, go to Legacy Logs. 
- All logs pages should work the same as before. 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added OTEL-backed logs support for preview, count, chart, and
single-log details when enabled.
* **Bug Fixes**
* Improved timestamp parsing/normalization for OTEL data to ensure
correct display and pagination.
* Enhanced filtering behavior, including safer handling of unknown
filter keys and invalid values across OTEL queries.
* Improved single-log result shaping to preserve expected API/database
metadata in OTEL mode.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:31:22 +02:00
Gildas Garcia
f34aa108d5 chore: dead code cleanup (#47294)
## Problem

There's still more unused code in the repository which slows down
everything:
- checkouts
- tooling
- probably builds (not sure how good turbopack is at handling this)

## Solution

- remove old unused code
- remove more recent code after checking git history to ensure it's not
unfinished/ongoing work

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Removed several unused interface, onboarding, and helper components
from the studio app.
* Cleaned up outdated branching, integrations, query performance,
support, and table/grid UI elements.
  * Removed a few unused utility hooks and key-mapping logic.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 12:34:19 +02:00
Alaister Young
9eab4f8fbf build(studio): Vite/TanStack-Start build pipeline behind flag (stack 1/6, from #46424) (#47107)
**Stack 1/6** of the TanStack Start migration (#46424), split into
reviewable, independently-mergeable PRs.

> [!IMPORTANT]
> **Next stays the default and only active framework after this PR.**
This wires up the Vite/TanStack-Start build pipeline behind the
`STUDIO_FRAMEWORK` flag, but there are no TanStack routes yet — so the
TanStack build isn't functional or tested until later PRs in the stack.
Nothing about the Next build, dev, or deploy changes behaviourally here.

## What's in this PR
- **Dispatch:** `dev`/`build`/`start` now go through
`scripts/dispatch.js`, which runs the Next variant unless
`STUDIO_FRAMEWORK=tanstack`. The original commands are preserved as
`dev:next`/`build:next`/`start:next`.
- **Build pipeline:** `vite.config.ts`, `serve.js`, `smoke-server.mjs`,
vite/tanstack deps, `turbo.jsonc`.
- **`tsconfig.json`:** `jsx: react-jsx`, `moduleResolution: Bundler`,
`target: ES2022`. Because `include` is `**/*.ts(x)`, this re-typechecks
the whole app, so the companion adaptations below land with it.
- **Shared adaptations (companions to the tsconfig change):**
`BufferSource` casts, `packages/ui` unused-`React` import removals, etc.
- **Routing/middleware plumbing:** `next.config.ts` +
`redirects.shared.ts` (redirect rules now shared with `vercel.ts`),
`proxy.ts`/`start.ts` middleware + `hosted-api-allowlist.ts`.

## Verification
Run locally off `master`: frozen install ✓, `studio` typecheck ✓, **Next
build ✓** (compiles + generates all routes), lint ratchet ✓ ("some rules
improved"), prettier ✓.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a hosted API endpoint allowlist to return 404 for non-supported
`/api/*` routes.
* Introduced a TanStack route-migration checklist and expanded TanStack
Start routing support.
* **Improvements**
* Enhanced deployment refresh/detection by tightening cookie handling
for “latest deployment” updates.
* Centralized redirect/maintenance-mode rules for consistent platform vs
self-hosted behavior.
* Improved production serving with a dedicated static + proxy server and
a post-build smoke test.
* **Dependencies**
* Updated TanStack-related packages and React Table/query tooling
versions.
* **Documentation / Chores**
* Updated formatting and tooling config; added shared build environment
parsing utilities.
<!-- 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>
2026-06-24 17:55:22 +08:00
Joshen Lim
fd0f2dd459 Scope last visited organization local storage to profile (#47071)
## Context

If a user switches account without an explicit log out via the
dashboard, landing back on `/org` will redirect users to the last
visited organization as stored in local storage, in which it can result
in the following state if the last visited organization does not exist
in the current account
<img width="2538" height="1060" alt="image"
src="https://github.com/user-attachments/assets/270e482a-3515-48ef-898b-87e76fce80d6"
/>

## Changes involved
Am opting to scope the last visited organization to the user profile
instead - this would be a bit more cleaner than trying to actively clear
the last visited org slug from local storage with implicit account
changes as there's no deterministic way to track that (afaik) from FE
side of things

## To test
Can reproduce the problem as such
- Ensure that you have 2 accounts to log in with, and one account has an
org that the other is not a part of
- For the organization that has the "extra" org, ensure that you click
into it so that the last visited org slug is saved in local storage
- Mimic changing accounts by visiting
`/auth/v1/authorize?provider=github` (using the domain for the env that
you're testing on - e.g localhost:8000 for local, or green for staging
preview)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Unified “last visited organization” handling across the Studio UI with
a shared hook, improving consistency for home/dashboard return,
cancel/back navigation, and account routing.

* **Bug Fixes**
* Updated redirects to only route to an organization when a valid
last-visited value is available; otherwise users go to the general
organizations page.
* Kept MFA enrollment and factor delete/leave flows aligned to the
unified last-visited organization value.

* **Tests**
* Updated onboarding and layout tests to match the new last-visited
organization storage key format and hook/query success behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-18 17:42:18 +08:00
Saxon Fletcher
e491182054 Auth flow improvements (#46967)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES/NO

## What kind of change does this PR introduce?

Bug fix, feature, docs update, ...

## What is the current behavior?

Please link any relevant issues here.

## What is the new behavior?

Feel free to include screenshots if it includes visual changes.

## Additional context

Add any other context or screenshots.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added “Continue with {provider}” sign-in and sign-up flows using
enabled external identity providers.
* Enabled inbound branding to focus a specific provider for customized
sign-in/sign-up experiences.

* **Improvements**
* Refined the sign-in options layout and “last used” tracking for
clearer authentication choices.
* Updated account identity/provider connection experiences (link/unlink
and management UI).

* **Bug Fixes**
  * Fixed hydration mismatches in sign-in and password-related layouts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-06-18 15:34:56 +08:00
Pamela Chia
dc5ddd8c4c chore(telemetry): align event interface names with action strings (#47048)
## Summary

Aligns 16 telemetry event interface identifiers in
`packages/common/telemetry-constants.ts` so each interface name equals
the PascalCase of its `action` string (`PascalCase(action) + Event`).
This is a follow-up to the GROWTH-798 audit (#45964), which fixed the
`action` strings and several interface names but left these 16
identifiers mismatched. I renamed identifiers only: every `action`
string is untouched, so there is zero impact on PostHog event names or
historical data.

Before this change, 176/192 interfaces matched the convention. This
brings it to 192/192.

## Changes

Structural renames (interface name was dropping or reordering words vs
the action):
- `AskAIEvent` to `AskAiClickedEvent`
- `CopyAsMarkdownEvent` to `CopyAsMarkdownClickedEvent`
- `DocsRecommendation404ClickedEvent` to
`Docs404RecommendationClickedEvent` (from #46990)
- `EventPageCtaClickedEvent` to `WwwEventPageCtaClickedEvent` (completes
the interface side of GROWTH-798 HIGH #1)
- `ImportDataFileAddedEvent` to `ImportDataDropzoneFileAddedEvent` (also
updates the consumer `apps/studio/hooks/ui/useCsvFileDrop.ts`)
- `QueryPerformanceAIExplanationButtonClickedEvent` to
`QueryPerformanceExplainWithAiButtonClickedEvent`

Initialism casing (normalized to the file-majority lowercase transform;
`Sql` 9:2, `Api` 3:2, `Ai` 6:2):
- `CustomReportAddSQLBlockClickedEvent` to
`CustomReportAddSqlBlockClickedEvent`
- `CustomReportAssistantSQLBlockAddedEvent` to
`CustomReportAssistantSqlBlockAddedEvent`
- `HomepageGitHubButtonClickedEvent` to
`HomepageGithubButtonClickedEvent`
- `MetricsAPIBannerCtaButtonClickedEvent` to
`MetricsApiBannerCtaButtonClickedEvent`
- `MetricsAPIBannerDismissButtonClickedEvent` to
`MetricsApiBannerDismissButtonClickedEvent`
- `TableRLSEnabledEvent` to `TableRlsEnabledEvent`
- `RLSGeneratePoliciesClickedEvent` to `RlsGeneratePoliciesClickedEvent`
- `RLSGeneratedPolicyRemovedEvent` to `RlsGeneratedPolicyRemovedEvent`
- `RLSGeneratedPoliciesCreatedEvent` to
`RlsGeneratedPoliciesCreatedEvent`
- `RLSTesterRunQueryClickedEvent` to `RlsTesterRunQueryClickedEvent`

## Testing

Type-only change, no runtime or PostHog behavior to exercise. Verified
that all 192 interfaces now match `PascalCase(action) + Event` (0
mismatches), the `TelemetryEvent` union has no duplicates, no old
identifier names remain anywhere in the repo, and the one external
consumer (`useCsvFileDrop.ts`) still resolves via its `['action']`
indexed access since the action strings are unchanged.

## Linear

- fixes GROWTH-928


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated internal telemetry infrastructure for consistency and
maintainability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-17 23:31:03 +08:00
Gildas Garcia
96d43099bb chore: refactor Button API so that it can be used a standard button (#46880)
## Problem

Our `<Button>` component breaks the default `button` contract by
redefining the `type` prop to set its variant (`primary`, `default`,
etc) instead of the button type (`submit`, `button`, etc).
This is confusing and forces to write more code when using it with
shadcn components that expect/inject the standard button props.

## Solution

- rename the `type` prop to `variant`
- rename the `htmlType` prop to `type`
- propagate the changes where necessary
- format code

## How to test

As this is just prop renaming, if it builds it's ok

---------

Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-06-16 23:59:58 +02:00
Ivan Vasilov
92e79e67d9 feat: Add error state to charts (#46991)
This PR adds an error state to the usage charts on the Project home
page.

<img width="1708" height="471" alt="Screenshot 2026-06-16 at 18 10 20"
src="https://github.com/user-attachments/assets/cba87dad-5e23-4cd1-b787-0ea699445d7f"
/>

I also added an error state to the charts in the [design
system](https://design-system-git-feat-chart-error-state-supabase.vercel.app/design-system/docs/ui-patterns/charts#chart-states).


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Charts now display error states when data retrieval or processing
fails, providing users with clear feedback about issues.
* Improved error visibility and handling across analytics and charting
components for better transparency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-16 16:18:17 +00:00
Joshen Lim
1baaded0bb Consolidate execute-sql-query into execute-sql-mutation (#46944)
## Context

Just some clean up as I was going through stuff
- `useExecuteSqlQuery` is deprecated and not used at all
- As such `execute-sql-query` is technically irrelevant, the more
relevant file is `execute-sql-mutation`
- Hence opting to consolidate `execute-sql-query` into
`execute-sql-mutation`
- Also removing `ExecuteSqlError` since its just re-exporting the
`ResponseError` type

There's a lot of file changes but its essentially just updating the
importing statements across the files
2026-06-16 00:07:16 +08:00
Mert YEREKAPAN
2191669d08 feat(studio): add upgrade CTA placement experiment (#45858)
## Summary

Replaces the header upgrade CTA (PR #44494, which design team wanted to
iterate on) with a placement experiment that tests three non-chrome
surfaces for the free-plan "Upgrade to Pro" CTA.

PostHog flag `upgradeCtaPlacement` (free-plan users only) with four
arms:

| Variant | Surface |
| --- | --- |
| `control` | No CTA (baseline cohort, still tracked) |
| `user_dropdown` | Full-width button pinned in the account dropdown |
| `org_projects_list` | Project-card-shaped usage tile, first card in
the org project grid |

## Details

### `user_dropdown`
- Full-width `Upgrade to Pro` button in `UserDropdown`, gated to
org-scoped routes only (`/project/*`, `/org/*`) so the org-billing CTA
never shows on `/account`, `/organizations`, etc. — addresses the scope
concern raised in review.
- Dropdown uses controlled `open` state so it closes before navigation
(it lives in the global layout, so a route change alone wouldn't dismiss
the overlay).


### `org_projects_list`
- `PlanUsageCard` renders as the first `<li>` in the project grid (via
`ProjectList`'s `prependCard`), matching `ProjectCard` shape so it reads
like another project tile. Also renders during the project-list loading
state to avoid pop-in.
<img width="3804" height="1494" alt="Arc 2026-06-08 20 02 54"
src="https://github.com/user-attachments/assets/09c2218c-43d1-49ce-bae7-5075c9750d72"
/>

### Shared card styling
- Metric rows (Egress, Database size, Monthly active users, File
storage) show `current / limit` with a progress ring; ring/value turn
warning at ≥80% and over at ≥100%.
- Rows are clickable deep-links to `/org/[slug]/usage#<anchor>` with a
hover chevron and dashed separators; the same row component is used by
both the embedded and project-card variants.
- Skeleton placeholder renders from first paint so the card reserves
layout while `useOrgUsageQuery` resolves.
- Exposure is fired optimistically while the org query loads (skeleton
shows immediately), but the experiment exposure event only fires once
free-plan is confirmed.

### Telemetry
- `upgrade_cta_clicked` with `placement: user_dropdown | home_usage_card
| org_projects_list`.
- `upgrade_cta_placement_experiment_exposed` with `variant` — the custom
exposure event (snake_case experiment id `upgrade_cta_placement`; the
flag key stays camelCase `upgradeCtaPlacement`).

### Header CTA sunset
- `HeaderUpgradeButton` and its wiring in `LayoutHeader` /
`MobileNavigationBar` removed (master's #46144 already removed the
button; this branch drops the remaining `header_upgrade_cta_clicked`
event).

## Before merging
- [x] Create the `upgradeCtaPlacement` flag + experiment in PostHog (4
variants, free-plan targeting, custom exposure event
`upgrade_cta_placement_experiment_exposed`).
- [x] Archive the now-orphaned `headerUpgradeCta` flag.

## Test plan
- [x] Override the flag per variant via the dev toolbar on staging;
confirm each surface renders and `upgrade_cta_clicked` fires with the
right `placement`.
- [x] `control` shows no CTA but still emits the exposure event.
- [x] Paid-plan org and self-hosted (`IS_PLATFORM=false`) show nothing.
- [x] Clicking a metric row deep-links to the matching usage section;
clicking Upgrade routes to billing.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Experimentally surface an “Upgrade to Pro” CTA in the user dropdown
and on the projects page for eligible free-plan orgs.
* Added a Plan Usage card showing free-plan metrics and upgrade prompts
on the organization projects page; hides when irrelevant or errored.
* Project list and its loading view support inserting a custom/prepend
card in card mode.

* **Telemetry**
* Added tracking for CTA clicks and experiment exposure; placement is
persisted per org.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: kemal <hello@kemal.earth>
2026-06-10 11:20:27 +00:00
Jordi Enric
2c915ca9fb fix(observability): align overview Connections count with details view DEBUG-75 (#46271) 2026-06-09 16:23:26 +02:00
Gildas Garcia
ff34a6753c chore: remove unnecessary <PreventNavigationOnUnsavedChanges> (#46763)
## Problem

Since the refactor done in #43900, the
`<PreventNavigationOnUnsavedChanges>` does not bring much value.

## Solution

Remove `PreventNavigationOnUnsavedChanges` and update consumers to
leverage `usePreventNavigationOnUnsavedChanges` and
`DiscardChangesConfirmationDialog`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Improved the architecture of unsaved-changes navigation handling
across multiple features. Components now use a more modular hook-based
approach for better code organization and consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-09 15:30:18 +02:00
Ali Waseem
1c2d28d5b3 chore: wrap local storage into helper methods that are safer (#46628)
## 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?

- Noticing our code we have many patterns of calling localstorage and
handling those errors
- We should add those in a single well tested file
- Handle those errors in the singleton which makes it easier for us to
debug customer issues. Logger is outputing local storage warnings for
feature we expose
- Side effect of this is random crashes on studio when local storage
isn't available or handled correctly

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Improved browser storage handling across the app for more reliable
persistence and graceful behavior in restricted or non-browser
environments (settings, previews, charts, tabs, sign-in/session flows,
integrations, and UI state).

* **New Features**
* Introduced a safe storage layer to standardize and harden
local/session persistence.

* **Tests**
  * Added comprehensive tests covering the new safe storage behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-04 07:41:28 -06:00
Jordi Enric
a7dda67549 feat(studio): add Multigres logs collection for HA projects (#46499)
## Problem

High availability (Multigres) projects don't expose Multigres service
logs in the Studio logs UI, so users on HA projects have no entry point
to inspect them.

## Fix

Add a `Multigres` logs collection, gated behind the `multigresLogs`
ConfigCat flag **and** the project's `high_availability` flag
(`useShowMultigresLogs`):

- New `Multigres` entry in the logs sidebar `Collections`, linking to a
new `multigres-logs` page that queries the `multigres_logs` table.
- Wire `multigres_logs` through the logs constants, types, table SQL,
query type, and service labels.
- Row formatting: parse the JSON `event_message` and render `level`
through `SeverityFormatter` and `msg` through `TextFormatter`, matching
the other service collections (instead of dumping raw JSON).
- `WARN` severity is now styled like `WARNING` (amber), since Multigres
emits `level: WARN`.
- Log detail drawer: parse the JSON `event_message` and spread its keys
onto the log so each field (level, msg, query, error, connection_id,
etc.) renders as its own collapsible row.
- Single-log query omits the `metadata` column for `multigres_logs` (the
table has no such column), fixing an `INVALID_ARGUMENT` error when
opening the detail drawer.
- Event chart: parse the level out of `event_message` via `JSON_VALUE`
so error/warning bars are counted (the table has no top-level level
column).
- Add the `multigres_logs` source schema to the Field Reference drawer,
same gating.

## Why a feature flag

`high_availability` is an existing product feature that predates
Multigres, so existing HA projects could otherwise see a broken
collection querying a `multigres_logs` table they don't have. Requiring
the `multigresLogs` flag ships the feature dark and decouples rollout
from HA status. The flag must be created in ConfigCat before enabling;
until then `useFlag` returns false and the feature stays hidden.

## How to test

- Enable the `multigresLogs` flag (or override locally) and open a
project where `high_availability` is `true`.
- Navigate to `Logs`. Confirm a `Multigres` entry appears under
`Collections` (after `Replication`).
- Open it: the page loads at `/project/<ref>/logs/multigres-logs` and
queries `multigres_logs`.
- Confirm rows show a colored severity pill (including amber `WARN`) and
a readable message rather than raw JSON.
- Confirm the chart counts error/warning bars correctly.
- Click a row: the detail drawer shows each parsed field as its own row,
with no error.
- Open the Field Reference drawer and confirm `Multigres` is listed as a
source.
- With the flag off, or on a non-HA project, confirm the collection and
Field Reference source are both hidden.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Multigres added as a dedicated log source with its own Logs page,
sidebar entry, and query type.
* Log list and preview now parse Multigres payloads to surface
timestamp, severity, and formatted message.
* Multigres integrated into charting, prompt labels, and field-reference
UI (hidden unless enabled).
* New hook controls showing Multigres UI only when feature flag + HA
project condition are met.
* **Bug Fixes**
  * Severity rendering treats "WARN" the same as "WARNING".
* **Tests**
  * Unit tests added for Multigres parsing and the show-Multigres hook.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 12:00:19 +02:00
Etienne Stalmans
fa55a9c4bd chore: use ro connstring for observability (#44806)
## 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?

function change

## What is the current behavior?

defaults to the read-write connection string when doing observability
report queries

## What is the new behavior?

uses the read-only connection string instead

## Additional context

these should only ever be read-only operations, reporting should not
have side effects and this adds a guardrail to ensure that remains the
case


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

**Bug Fixes**
- Corrected database replica query handling by using read-only
connection strings for replica database access.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-02 17:03:22 +02:00