Commit Graph
38993 Commits
Author SHA1 Message Date
Claude ea3f383d60 feat(storage): fetch and mutate object versions against Storage
The object list endpoint now takes `noncurrentVersions`, `deleteMarkers`
and `exactMatch`, and returns `version`, `archived_at` and
`is_delete_marker` per row, so the version history has a real source.

- `objectVersionsQueryOptions` lists one object's history, with
  `exactMatch` so the path isn't read as a folder prefix
- Restoring is a move onto the object's own path with `sourceVersionId`,
  which consumes the source version rather than duplicating it
- Deleting one version addresses it as `{ path, versionId }`, which is a
  hard delete even on a versioned bucket
- Purging reads the history first and deletes every version by id, since
  a bare path would only hide whatever is current

Variables take the object's full bucket-relative `path` rather than its
leaf name, which is what these endpoints address.

`ObjectVersionAction` drops `restore`: the list endpoint has no
provenance field, so a restore is indistinguishable from an overwrite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N3euXsz25sTybsGTcxCFfn
2026-10-07 16:38:40 +02:00
Francesco Sansalvadore a3a8f5b87c improve comments 2026-10-07 16:38:40 +02:00
Francesco SansalvadoreandClaude Sonnet 5 ebde4234c9 refactor(storage): drop the unreachable cap-only lifecycle branch
A version cap with no expiration age isn't expressible in S3 — `NoncurrentDays`
is required on any `NoncurrentVersionExpiration` rule — and the bucket form now
disables the cap until an age is set. So `computeVersionFate` no longer has a
cap-only path: no age means no policy.

That also makes `expires-on-next-upload` reachable only from the `or` branch,
where an age is always present, so `daysRemaining` is required rather than
optional.

The cap-only test block is replaced by one asserting a lone cap is ignored, so a
cap arriving without an age can never start labelling versions for removal.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-07 16:38:40 +02:00
Francesco SansalvadoreandClaude Sonnet 5 2f46a9baa8 refactor(storage): say "retained" rather than "kept" for versions
Renames the `VersionFate` variant and its test wording to match the term used in
the form copy and the version history rows.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-07 16:38:40 +02:00
Francesco Sansalvadore d35e1f0f27 remove redundant test comment 2026-10-07 16:38:40 +02:00
Francesco SansalvadoreandClaude Sonnet 5 83d6b51941 feat(storage): add object versions data layer
Adds the query and mutation hooks the version history UI needs, written to the
studio `queryOptions` conventions with the endpoint calls stubbed. No mock
fixtures: `useObjectVersionsQuery` resolves to an empty list until the Storage
API exists, so the version history renders its empty state rather than
fabricated data, and swapping in the real endpoint is a one-function change per
file.

- `object-versions-query.ts` — the version list, plus the `ObjectVersion` and
  `LifecyclePolicy` types
- `object-version-restore-mutation.ts` — promote a noncurrent version to current
- `object-version-delete-mutation.ts` — remove one specific version
- `object-purge-mutation.ts` — delete an object and all of its versions,
  bypassing versioning
- `VersionHistory.utils.ts` — `computeVersionFate`, the pure rule deciding what
  removal outlook each version row shows
- `BroomSparklesIcon.tsx` — inline SVG for a glyph absent from lucide-react 0.436

The bucket's lifecycle policy is part of the `objectVersions` query key. The
prototype read it inside `queryFn` while leaving it out of the key, which left
stale expiry labels behind after a policy edit.

`computeVersionFate` is carried over from the prototype with its 9 reference
cases intact, minus four non-null assertions — the bounds are now narrowed
through a nullable local instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-07 16:38:40 +02:00
6ef729cb5c feat(storage): versioning bucket modals (FE-4161) (#49205)
| # | Branch | Base |
| - | ------ | ---- |
| 1 | `feat/storage-versioning-private-alpha` — merged | `master` |
| 2 | `feat/storage-versioning/002-bucket-form-fields` | `master` |
| 3 | `feat/storage-versioning/003-bucket-modals` ◀ | 2 |
| 4 | `feat/storage-versioning/004-object-versions-data` | 3 |
| 5 | `feat/storage-versioning/005-file-preview-versions` | 4 |
| 6 | `feat/storage-versioning/006-billing-storage-retention` | 5 |
| 7 | `feat/storage-versioning/007-archived-objects-data` | 6 |
| 8 | `feat/storage-versioning/008-archived-rows` | 7 |
| 9 | `feat/storage-versioning/009-archived-preview-pane` | 8 |
| 10 | `feat/storage-versioning/010-replace-file` | 9 |

## [3/10] Storage object versioning: wire into the bucket modals

**Base:** `feat/storage-versioning/002-bucket-form-fields` (PR 2)

### This PR

Mounts the object-versioning form section in the create and edit bucket
modals behind the feature preview, and saves it.

- create and edit bucket modals spread `bucketVersioningFormFields` into
their existing form schema
- lifecycle defaults  to 30 days / 10 versions
- edit adds a confirmation before suspending an actively versioned
bucket

## Enabling object versioning on a new bucket and setting lifecycle
policies


https://github.com/user-attachments/assets/194f8319-4929-432e-8a50-206f180a77a8

## Edit and suspend object-versioning


https://github.com/user-attachments/assets/f31e1d34-9840-4f5a-a269-6a911214742d

## To reproduce

1. Make sure storage versioning is enabled under feature previews >
Storage Versioning
2. Open Storage Bucket File explorer
3. create new bucket and enable Object Versioning
4. set lifecycle policy
- Noncurrent version expiration: can be either empty or >1
- Retained noncurrent versions: can be either empty or between 1 and 100
and can't exist without "Noncurrent version expiration"
5. Open new bucket with object versioning and test changing lifecycle
policies
6. Disabling object-versioning shows proper warning and updates
`versioning_status` to SUSPENDED (it can never go back to DISABLED once
it has been enabled on a bucket)

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-10-07 16:38:35 +02:00
Ivan VasilovandClaude Sonnet 5.5 075c611463 chore: bump vulnerable dependencies (#51381)
## Summary

- Bumps vulnerable transitive dependencies flagged by `pnpm audit`, one
commit per dependency (lockfile only, no permanent overrides):
proxy-addr, shell-quote, @fastify/busboy,
@graphql-tools/executor-legacy-ws, @modelcontextprotocol/sdk,
compression, http-cache-semantics, source-map-js, smol-toml, dompurify.
- Updates `scripts/fix-audit-vulnerability.ts` to be agent-friendly:
accepts a dependency name argument, adds `--json` (single JSON object on
stdout, logs on stderr, never prompts) and `--help`.

## Not fixed

The remaining audit findings could not be resolved by this script. Some
are blocked by `minimumReleaseAge` (braces, node-forge, sprintf-js);
others stay vulnerable even with an override and need a parent
dependency update or scoped override.

## Test plan

- [ ] CI passes (typecheck, lint, prettier)
- [ ] `pnpm audit` shows fewer findings than on master

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 16:23:43 +02:00
claude[bot]andClaude 6c6b19c6c6 chore(studio): report empty-body GET 200s to Sentry with a no-store probe (#51123)
<!-- ccr-slack-attribution -->
_Requested by **Ivan Vasilov** · [Slack
thread](https://supabase.slack.com/archives/C063LNYJJKS/p1790710416069689?thread_ts=1790710416.069689&cid=C063LNYJJKS)_

**Before:** When a Studio API GET comes back as a 200 with an empty
body, openapi-fetch hands the caller `{}` and we only see the downstream
crash, with no record of the response that caused it.

**After:** The first time this happens for an endpoint in a page
session, Studio sends one Sentry warning, `Empty response body on
successful API request`. It carries the response metadata, browser
state, resource timing, and the result of a single `cache: 'no-store'`
refetch. What the caller receives is unchanged.

## Problem

Studio crashes trace back to GET requests that return 200 with an empty
body, which openapi-fetch turns into `{}`. They are heavily skewed to
Firefox and Safari. The leading hypothesis is browser cache revalidation
(Express weak ETags, no `Cache-Control` on api.supabase.com), but
nothing confirms it yet. The `no-store` probe tells the two cases apart:
if the refetch has a body, the browser cache is the likely culprit; if
it is also empty, the server or the edge is sending empty bodies. This
data should show whether the fix belongs on the API side or the
Cloudflare side.

Context: #51041 (closed) tried to guard the crashing call sites instead.

## Needs API-side change to be fully useful

Cross-origin, Studio can only read CORS-safelisted response headers, and
resource timing sizes read as zero. If api.supabase.com sends
`Access-Control-Expose-Headers: ETag, cf-ray, cf-cache-status,
x-request-id` and `Timing-Allow-Origin: <studio origin>`, this event
will also carry the ETag, cf-ray, and cache status, plus the real
transfer and body sizes and the negotiated protocol. Until then, those
fields read as `null` or `0`.

## Solution

- `data/empty-body-diagnostics.ts` (new): `reportEmptyBodyResponse({
request, response, schemaPath })`.
- Runs only for `GET` and only when `IS_PLATFORM`. Empty POST/201 bodies
are legitimate.
- Reports at most once per templated endpoint per page session
(module-level `Set`).
- Endpoint: openapi-fetch's `schemaPath` (e.g.
`/platform/projects/{ref}/settings`), passed through
`templateEndpointPath`. That function drops the query string and hash,
replaces the segment after `projects`/`organizations`/`branches` with
`{ref}`/`{slug}`/`{branch}`, and replaces UUIDs, numeric IDs, and 20+
character alphanumeric IDs with `{id}`. I used `schemaPath` rather than
the request URL so user-chosen names (bucket names, function slugs)
never end up in tags or fingerprints.
- Probe: one plain `fetch(new Request(request, { cache: 'no-store', ...
}))` with a fresh `X-Request-Id` and a 10s `AbortController` timeout.
`AbortSignal.timeout` isn't available in older Safari. The probe
bypasses the openapi-fetch middleware, so it can't recurse. Only the
body's byte length is recorded, never its contents.
- Event: `level: 'warning'`, `fingerprint: ['empty-body-response',
endpoint]`, `tags: { endpoint, probe_has_body, empty_body_diagnostic:
'true' }`, where `probe_has_body` is `true` / `false` / `error`. `extra`
holds:
- the request: method, status, `response.type`, `redirected`, and the
original `X-Request-Id` (for API log lookup)
- response headers: `content-type`, `cache-control`, `last-modified`,
`expires`, `content-length`, `etag`, `cf-ray`, `cf-cache-status`,
`x-request-id`
- browser state: `visibilityState`, `navigator.onLine`, the navigation
type, ms since navigation start, and whether the page was restored from
bfcache
- the latest `PerformanceResourceTiming` for the URL (transfer, encoded,
and decoded size, `nextHopProtocol`, `responseStatus`)
- the probe: status, request ID, body length, `content-length`,
`content-type`, or the error name
- Fire-and-forget: everything is wrapped in a `try`/`catch`, and the
caller does not await it.
- `data/fetchers.ts`: the `onResponse` middleware passes `{ request,
schemaPath }` to `normalizeEmptyBodyResponse`, which calls the reporter
in its empty-body branch and also for a 200 that carries
`Content-Length: 0`. openapi-fetch short-circuits that case to `{}` the
same way, so it is the same symptom. The return value is unchanged in
every branch.
- `packages/common/sentry.ts`: `filterSentryEvent` normally keeps only
1% of events that aren't page crashes. It now sends events tagged
`empty_body_diagnostic` unsampled, with `codeSampleRate: '1'`. A
once-per-session warning would barely show up at 1%. Consent and
platform gating and the third-party filter still apply. www and docs
also use `filterSentryEvent`, but only Studio's reporter sets this tag,
so sampling for them and for every other Studio event is unchanged.

Sentry config: Studio's `beforeSend` doesn't otherwise drop this
message. It has no exception values, so the no-stack-trace filter
doesn't apply, and it matches no `ignoreErrors` entry.

## Review instructions

1. Check `normalizeEmptyBodyResponse` in `data/fetchers.ts`: the
reporter is `void`-called and its return value is untouched.
2. Check `probe()` in `data/empty-body-diagnostics.ts`: only
`byteLength` is read from the body. The probe reuses the original
request's headers and credentials (same auth as the original GET).
3. Check `filterSentryEvent` in `packages/common/sentry.ts`: only the
`empty_body_diagnostic` tag skips sampling.
4. Tests: `data/empty-body-diagnostics.test.ts` and
`packages/common/sentry.test.ts`.

## Verification

- Unit tests (`data/empty-body-diagnostics.test.ts`, new):
  - path templating cases
  - `probe_has_body` `true` / `false` / `error`
  - the secret body content never appears in the Sentry call
  - one report per endpoint
  - non-GET and non-platform requests are skipped
  - no throw when `fetch` or Sentry throws
- end-to-end through `client.GET`: still resolves `{}` and reports the
`schemaPath`, for both a missing `Content-Length` and `Content-Length:
0`
- `packages/common/sentry.test.ts`: tagged diagnostics are sent
unsampled, untagged or false-tagged ones are still sampled, and they're
still dropped without consent.

These tests, plus the existing `normalizeEmptyBodyResponse.test.ts`,
`handleError.test.ts`, and the rest of `sentry.test.ts`, pass (67 tests)
under vitest 5 + jsdom. I ran them in a minimal harness, not the full
`pnpm install` workspace, because the local checkout is sparse.
- I ran TypeScript 7.0.2 (`--strict`) on the five touched files against
the real `api-types`, with stubbed `common`/Sentry types. No errors in
the touched files.
- Prettier `--check` with the repo config passes, with and without
`SORT_IMPORTS=false`.
- Not run locally: the full studio typecheck, `lint:ratchet`, and knip.
CI covers them. The change adds no `any`, no default exports, and no
deps.

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01UefDak8XYLMi9aiEjDPXc5

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-07 16:15:57 +02:00
Yuvraj Singh d1205a05e9 fix(studio): default cron HTTP timeout when timeout_milliseconds is omitted (#51385)
## Problem

`parseCronJobCommand` reads the timeout of an `net.http_get` /
`net.http_post` cron command like this:

```ts
const timeout = timeoutMatch?.[1] || ''
// ...
timeoutMs: Number(timeout ?? 1000),
```

When the command has no `timeout_milliseconds` argument, `timeout` is
`''`, which isn't nullish, so the `?? 1000` fallback never applies and
`timeoutMs` becomes `Number('') === 0`.

`timeout_milliseconds` is optional in pg_net, so this is common for jobs
created in SQL, e.g.:

```sql
select cron.schedule('ping', '* * * * *', $$ select net.http_get(url:='https://example.com/health') $$);
```

Opening such a job in the cron editor shows a timeout of **0 ms**, and
saving fails validation (the field requires 1000 to 5000 ms) until the
user edits a value they never set.

## Solution

Use the parsed value when present, and otherwise fall back to pg_net's
default for `timeout_milliseconds` (5000 ms in current pg_net). That's
what the job actually runs with, so opening and saving it in Studio
doesn't change its behavior. It's also within the form's allowed range.

Added tests for the Edge Function and HTTP request paths without
`timeout_milliseconds`. Both fail on `master` (`timeoutMs: 0`), and the
existing cron tests still pass.

## Review instructions

1. In the SQL editor, run:
   ```sql
select cron.schedule('ping', '0 * * * *', $$ select
net.http_get(url:='https://example.com') $$);
   ```
2. Open Integrations > Cron > `ping` > Edit.
3. Before: the timeout field shows `0` and saving shows a validation
error. After: it shows `5000` and saves.
4. `pnpm --filter studio test
components/interfaces/Integrations/CronJobs/CronJobs.utils.test.ts`

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
2026-10-07 15:51:54 +02:00
Charis 22886fd304 feat(studio): add flag-gated general region selection (#51274)
## Problem

We want to be able to show free-plan organizations a simplified region
selector that only lists general regions (Americas, Europe,
Asia-Pacific), controlled per organization through ConfigCat.

## Solution

- ConfigCat flags are now evaluated with `organization_slug` and
`organization_created_at` (Unix seconds) custom attributes, so flags can
target and bucket by organization.
- `organization_created_at` is read from `GET
/platform/organizations/{slug}`, fetched only for free-plan
organizations, since the organization list response doesn't include it.
- Two flags:
- `freeTierGeneralRegionEnrollment`: the organization is enrolled
(control or test).
- `freeTierGeneralRegionSelection`: the organization sees only general
regions.
- For enrolled free organizations, the region selector stays in its
loading state until flags have been evaluated with the organization's
creation time, so specific regions aren't shown and then removed.
- In the test variant, the selector hides specific regions and shows a
footer linking to the plan upgrade panel. High Availability keeps its
own region list.
- Telemetry: new `free_tier_general_region_experiment_exposed` and
`free_tier_general_region_upgrade_clicked` events, and
`freeTierGeneralRegionExperiment` / `regionSelectionType` properties on
`project_creation_simple_version_submitted`.
- `created_at` is added to `OrganizationSlugResponse` in the generated
platform types, matching the API.

## Review instructions

1. With both flags off, open `/new/[slug]` for a free organization and
confirm the region selector is unchanged.
2. Using the dev toolbar, set `freeTierGeneralRegionEnrollment` and
`freeTierGeneralRegionSelection` to `true`. Confirm only general regions
are listed and the footer links to the billing plan panel.
3. Set `freeTierGeneralRegionSelection` to `false` and confirm the full
selector is shown.
4. Repeat with a paid organization and confirm the full selector is
always shown.
2026-10-07 09:43:28 -04:00
Charis ffe1ebc940 fix(studio): do not ignore requested model if available in base (#51388)
## Problem

The model selection logic in `generate-v4.ts` was incorrectly ignoring
the requested model even when it was available in the base model set.
The condition checked for access to advanced models or throttling in a
way that would force fallback to the default base model even when the
requested model was already a base model.

## Solution

Reordered the logical condition to first check if the effective model is
a base model ID, and only apply the access/throttle checks when the
requested model is not already a base model. This ensures the requested
model is respected when it's available.

Also threaded the `effectiveModel` parameter through to the assistant
response generator for better telemetry and debugging context.

## Review instructions

1. Check the logic change in
`apps/studio/pages/api/ai/sql/generate-v4.ts` line 164
2. Verify the condition now correctly checks
`isAssistantBaseModelId(effectiveModel)` first
3. Confirm `effectiveModel` is now passed to `generateAssistantResponse`
for proper telemetry

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-10-07 09:43:01 -04:00
Alaister YoungandAlaister Young 16bd06dfb8 fix(studio): silence status page errors when incident.io isn't configured (#51315)
Running Studio locally without the incident.io env vars produces a 500
from `/api/status-page` on every fetch, plus a server-side log and a
client `console.error`. Retries and the 5-minute refetch keep repeating
them, so the dev console stays noisy.

**Changed:**
- `lib/api/status-page.ts` – when `INCIDENT_IO_WIDGET_URL` is unset
outside production, return an empty (degraded, short-cached) status page
instead of throwing. The missing API key / status page ID log is also
limited to production. Production behavior is unchanged.
- `data/platform/status-page-query.ts` – remove the client-side
`console.error`, which repeated the error that React Query already
exposes

**Added:**
- Tests for the missing widget URL in dev (empty payload, no error log)
and in production (still throws)

## To test

- Run Studio locally in platform mode without `INCIDENT_IO_*` set: no
status page errors in the terminal or the browser console, and
`/api/status-page` returns 200 with empty arrays
- Support form and project creation still render normally (no status
banner, status page link points to status.supabase.com)

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-10-07 14:58:43 +02:00
454a232947 feat(studio): scoped oauth interstitial ui (#50090)
## 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?

The scoped OAuth consent interstitial: scope display, org/project
selection,
consent screen assembly, success screen, and post-submit role-validation
error state. Consolidates the former stacked PRs #49481, #49484, #49486,
#49489, #49951 into one reviewable unit (each contained the last; no
code
was dropped).

- Entirely behind `useFlag('oauthAppScopedGrants')` — no reachable UI
with
  the flag off.
- Runs on the mock data layer from #49476 (`USE_MOCKS`-gated); no real
  endpoints are called.
- Covers PROD-626, PROD-627, PROD-628, PROD-629, PROD-653.

Base is #49476 (data contracts + mocks); will retarget to master once it
merges.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
2026-10-07 10:56:24 +02:00
David McNeil 8083226229 chore: add David McNeil to humans.txt (#51376)
Add David McNeil to humans.txt
2026-10-07 09:59:53 +02:00
Alexis Aguilar 7d47e3bf80 chore(docs): add Alexis Aguilar to humans.txt (#51369)
## Problem

Alexis Aguilar is a new hire and isn't in the `humans.txt` file yet.

## Solution

Adds Alexis Aguilar to the `apps/docs/public/humans.txt` file :)

<!--
## Preview links

If relevant, include links to changed pages for easy review access.

Copy the preview base URL from the Vercel bot comment on this PR. Use
the following table as an example template.

| Site | Live | Preview | Search for |
| -------------- |
-------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------
| ----------------------------- |
| WWW | [/blog/your-post](https://supabase.com/blog/your-post) |
[/blog/your-post](https://zone-www-dot-com-git-branch-name-supabase.vercel.app/blog/your-post)
| unique phrase from the change |
| Docs |
[/docs/guides/your-page](https://supabase.com/docs/guides/your-page) |
[/docs/guides/your-page](https://docs-git-branch-name-supabase.vercel.app/docs/guides/your-page)
| unique phrase from the change |
| Studio | [/dashboard](https://supabase.com/dashboard) |
[/dashboard](https://studio-git-branch-name-supabase.vercel.app/dashboard)
| unique phrase from the change |
| Design system | [/design-system](https://supabase.com/design-system) |
[/design-system](https://design-system-git-branch-name-supabase.vercel.app/design-system)
| unique phrase from the change |
| UI library | [/library](https://supabase.com/library) |
[/library](https://ui-library-git-branch-name-supabase.vercel.app/library)
| unique phrase from the change |
| Knowledge base |
[/kb/guides/your-page](https://supabase.com/kb/guides/your-page) |
[/kb/guides/your-page](https://kb-git-branch-name-supabase.vercel.app/kb/guides/your-page)
| unique phrase from the change |
-->

<!-- ## Additional context

Optionally add any other context or screenshots.

-->

## Checklist

Check all before review:

- [X] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
2026-10-07 09:59:48 +02:00
Danny White a4910196b8 fix(studio): use Badge for auth provider enabled state (#51310)
## Problem

Auth Providers uses a bespoke Enabled/Disabled chip that mixes brand
tokens with primary colour. Custom Auth Providers already uses the
standard `Badge` for the same meaning.

## Solution

Replace the bespoke chip with the existing `Badge`:

```tsx
<Badge variant={isActive ? 'success' : 'default'}>
  {isActive ? 'Enabled' : 'Disabled'}
</Badge>
```

No new status primitive in this PR. Built-in providers now match Custom
Providers.

| Before | After |
| --- | --- |
| <img width="958" height="1568" alt="CleanShot 2026-10-06 at 17 19
40@2x"
src="https://github.com/user-attachments/assets/08850f4e-528a-4e47-958f-207e72783b16"
/> | <img width="934" height="1482" alt="CleanShot 2026-10-07 at 11 46
41@2x"
src="https://github.com/user-attachments/assets/232903f7-86bd-4c5c-ae1d-d873cddcf67b"
/> |

## Review instructions

1. Open Auth → Providers (built-in list). Confirm each provider shows a
small `Enabled` / `Disabled` Badge, with no brand/primary token mash-up
or oversized pill.
2. Optional: open Auth → Providers → Custom and compare the Enabled
column; it should feel like the same Badge treatment.

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
2026-10-07 17:30:30 +11:00
Danny White 5c4745a117 fix(studio): smooth Terms of Service dialog intro copy (#51370)
## Problem

Joshen left a copy nit on #51302 after merge: the dialog intro reads
awkwardly as two short lines.

## Solution

Merge them into one sentence: “We’ve updated our Terms of Service which
includes the following:”

## Review instructions

1. Open an organisation landing page (`/organizations` or `/org/<slug>`)
in the Studio preview.
2. Click **Learn more** on the Terms of Service notice.
3. Confirm the dialog opens with a single intro line before the bullet
list, not two separate sentences.

## Checklist

Check all before review:

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
2026-10-07 16:08:44 +11:00
Danny White d95ff5bda9 docs(design-system): rewrite sidebar page for monorepo tokens (#51165)
## Problem

The design-system Sidebar page was mostly an upstream shadcn paste:
first-person voice, a broken `/blocks` link, missing structure images,
CLI install steps that do not match this monorepo, and a long changelog
/ data-fetching tutorial that do not apply here.

Separately, it still taught classic shadcn **HSL channel** variables
plus `hsl(var(--sidebar-*))`. In this monorepo those tokens are **full
colours**. Mixing the two patterns produces invalid CSS.

Related call-site cleanup:
https://github.com/supabase/supabase/pull/51161

## Solution

- Rewrite the Sidebar docs as a shorter monorepo guide: import from
`'ui'`, structure, theming, provider / sidebar props, menu building
blocks, controlled mode, state styling.
- Move Studio’s `--sidebar-*` aliases into shared `packages/ui` compat
CSS so every app on the shared theme gets working `bg-sidebar`
utilities.
- Drop the duplicate definitions from Studio `globals.css`.

Left alone on purpose: brand / destructive channel tokens and docs that
correctly use `hsl(var(--brand-…))`.

## Review instructions

Design-system preview:
[design-system](https://design-system-git-dnywh-docssidebar-full-colour-tokens-supabase.vercel.app/)

1. [Live Sidebar
docs](https://supabase.com/design-system/docs/components/sidebar) ·
[Preview Sidebar
docs](https://design-system-git-dnywh-docssidebar-full-colour-tokens-supabase.vercel.app/design-system/docs/components/sidebar).
Confirm the page is no longer the upstream essay: no broken images, no
`/blocks` link, imports from `'ui'`, theming shows full-colour aliases.
2. Smoke Studio: left nav should look unchanged (same aliases, now from
compat.css).
3. Optional: in DevTools, confirm `--sidebar-background` resolves to a
full `oklch(...)` colour.

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)
2026-10-07 10:36:41 +11:00
Danny White 272bb26635 fix(studio): remove duplicate status page link in incident banner (#51305)
## Problem

During active incidents, the Studio status banner read:

> We are investigating a technical issue · Follow the status page for
updates Status page

The trailing "Status page" goes alongside plain-text copy that already
mentioned "status page".

## Solution

Match the emergency-override and legacy banners: make "status page" the
inline link inside the sentence, and drop the trailing link. Added a
regression test covering the link text and href.

| Figure |
| --- |
| <img width="1280" height="288" alt="6696"
src="https://github.com/user-attachments/assets/e267f0d0-5484-45a5-969f-03e184b903dd"
/> |
| _Before_ |
| <img width="1280" height="288" alt="47231"
src="https://github.com/user-attachments/assets/2beee89e-3674-43f5-9d13-6dc04d153549"
/> |
| _After_ |

## Review instructions

As of writing this: we have an active indident so you could just log in
to the [staging
preview](https://studio-staging-git-dnywh-dd493a51-supabase.vercel.app/).

Otherwise:

1. Open `apps/studio/components/layouts/AppLayout/StatusBanner.tsx` and
confirm the incident description is `Follow the [status page] for
updates` with no trailing "Status page" link.
2. Optionally run `pnpm --filter studio exec vitest run
components/layouts/AppLayout/StatusBanner.test.tsx`.
3. If you have a local Studio with an active incident (or
`ongoingIncident` override), confirm the banner shows a single linked
"status page" and no duplicate trailing link.
2026-10-06 23:16:25 +00:00
Danny White b5c865521f feat(studio): notify users about the Terms of Service update (#51302)
## Problem

Dashboard users need a notice about the Terms of Service update
alongside #51106 and #51107.

## Solution

Reuse the organisation landing-page notice pattern from #50397. A
compact “We've updated our Terms of Service.” notice opens the
explanation and agreement link through **Learn more**. Closing the
notice or choosing **Got it** remembers dismissal in the browser with a
new version-specific key.

```text
Organisation landing page
  Notice → Learn more → Explanation and Terms of Service link
  Close / Got it → Remember dismissal
```

| After |
| --- |
| <img width="628" height="444" alt="CleanShot 2026-10-06 at 14 47
46@2x"
src="https://github.com/user-attachments/assets/72922712-321f-4972-b20c-1a075e0745d0"
/> |
| _Banner_ |
| <img width="1078" height="718" alt="CleanShot 2026-10-06 at 16 58
18@2x"
src="https://github.com/user-attachments/assets/2109c2ab-e9b7-4855-8acb-42d5232cd002"
/> |
| _Dialog_ |

## Review instructions

1. Open `/organizations` or an organisation's `/org/<slug>` landing page
in the hosted Studio preview. Expect the compact notice.
2. Click **Learn more**. Expect the explanation and a link to the Terms
of Service. Escape closes the dialog without dismissing the notice.
3. Choose **Got it**, then reload. The notice stays dismissed. Repeat in
a fresh browser profile using **Close banner**.
4. Open a project or an organisation settings page. The notice should
not appear.
2026-10-07 09:09:01 +11:00
claude[bot]andClaude fb382b3018 Add Terms of Service v4 (effective October 5, 2026) (#51107)
<!-- ccr-slack-attribution -->
_Requested by **Nicole Kramer** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1790784371448999)_

## Problem

Commercial & Product Counsel supplied a new version of the Supabase
Terms of Service to be published as Version 4, effective October 5, 2026
(the same date the Enterprise Terms v4 update takes effect, once the
code freeze lifts).

## Solution

Adds `apps/www/data/legal/terms/v4.mdx` with the new agreement text
(transcribed from the supplied source document) and registers it as the
newest version in `apps/www/pages/terms.tsx`'s versions array, dated
October 5, 2026. Versions 1-3 are untouched. The new text also defines
"Supplemental Terms" and links it, at the one point the source
hyperlinks it, to `/legal/customer-resources/supplemental-terms`.

## Review instructions

1. Open the Vercel preview link for `/terms` below.
2. Confirm "Version 4" appears as the newest tab/version, dated October
5, 2026, with the updated agreement text.
3. Do not merge — this PR is held until the code freeze lifts on October
5, 2026 (see PRs #51100 and #51106 for the related Enterprise Terms /
Supplemental Terms work landing the same day).

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01K2vqszbsJiMJPABAnLMgaC


---
_Generated by [Claude
Code](https://claude.ai/code/session_01K2vqszbsJiMJPABAnLMgaC)_

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-07 09:07:10 +11:00
claude[bot]andClaude c006499d48 Add Enterprise Terms v4 (effective October 5, 2026) (#51106)
<!-- ccr-slack-attribution -->
_Requested by **Nicole Kramer** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1790784371448999)_

## Problem

The Enterprise SaaS Subscription Agreement at `/enterprise-terms` needed
a new version reflecting legal's latest draft, which introduces a
"Supplemental Terms" defined term, a standalone "Supabase"
contracting-entity definition (to support marketplace purchases), a new
Beta Releases warranty carve-out, and related marketplace billing/refund
language.

## Solution

Before: `/enterprise-terms` had three versions (v1–v3), with v3 dated
August 1, 2026, and no concept of "Supplemental Terms" anywhere in the
agreement.

After: adds **Version 4, effective October 5, 2026** as the newest entry
in the page's `versions` array (v1–v3 untouched):

- `apps/www/data/legal/enterprise-terms/v4.mdx` — new versioned MDX,
transcribed from legal's source document and following this directory's
existing formatting conventions (bold section numbers/defined terms,
`##`/`###` headings, no frontmatter or h1 — the h1 is rendered by
`PageHeader`).
- `apps/www/pages/enterprise-terms.tsx` — imports `v4.mdx` and adds it
to the front of the `versions` array with `effectiveDate: 'October 5,
2026'`.

How: the new v4 text is a faithful transcription of legal's draft onto
the existing v3 structure, so the diff is easy to review against v3 —
the substantive additions are the "Supabase" entity definition (1.9),
the "Supplemental Terms" defined term (1.13) and its references in
Section 2.1 (license scope) and Section 14.1 (order of precedence), a
new Section 10.5 (Beta Releases), and marketplace-related payment/refund
language in Section 5.1. The "Supplemental Terms" defined term is a live
markdown link to the new `/legal/customer-resources/supplemental-terms`
page (shipped separately in #51100) at its point of definition (Section
1.13), matching how the source document hyperlinks it.

## Review instructions

1. Open the `zone-www-dot-com` preview's `/enterprise-terms` page and
confirm the version selector defaults to "Version 4 — October 5, 2026".
2. Confirm Section 1.13 "Supplemental Terms" renders as a live link to
`/legal/customer-resources/supplemental-terms`.
3. Confirm Version 3 (and v1–v2) still render unchanged via the version
selector.

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] N/A — no docs topic edited (this is versioned legal content, not
`apps/docs`)

---

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01K2vqszbsJiMJPABAnLMgaC

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-07 09:06:49 +11:00
363dbdf1ad Use Flick Games' real logo files (#51364)
## Problem

#51285 (Flick Games case study) merged before the customer's actual logo
files were in hand. It shipped with a derived black/white wordmark
instead.

## Solution

Swaps in the real brand assets Ian Masters sent directly
(`FLICK_black_2048.png` / `FLICK_white_2048.png`) for
`on-light`/`on-dark` at `apps/www/public/images/customers/logos/`.
Tracked in
[MARKET-2252](https://linear.app/supabase/issue/MARKET-2252/case-study-flick-games-sept-23).

## Review instructions

1. Open the preview link for `/customers/flick-games`.
2. Check the logo renders correctly in both light and dark mode.

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [ ] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Wendie Cheung <wendie.cheung@supabase.io>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 14:19:34 -07:00
Charis ab383421c5 fix(studio): show sign-in banner based on Dashboard component [FE-3443] (#51283)
## Summary

* Makes sign-in banner visible on unauthenticated pages
  * Show only when one of the affected components is Dashboard
  * Works only when new status page (under feature flag) is being used
* Regression fix: Auth pages without the status banner (sign-up,
sign-in-mfa, sign-in-recovery-code, sign-in-sso, sign-in-partner,
forgot-password, forgot-password-mfa, reset-password) no longer reserve
dead space at the top for a banner they don't render

## Test plan

- [X] TypeScript: `tsc --noEmit` passes clean, no type errors
- [X] Unit tests: All new/existing tests pass in
`apps/studio/lib/status-page/status-page.utils.test.ts` and
`apps/studio/components/layouts/AppLayout/StatusBanner.utils.test.ts`
(697 files / 7833 tests, no regressions)
- [X] Manual verification: Sign-in page still renders the banner
correctly when an incident affecting Dashboard is active; no layout
regression

**Related:**
[FE-3443](https://linear.app/supabase/issue/FE-3443/only-show-sign-in-incident-banner-when-relevant)
2026-10-06 15:56:48 -04:00
Charis 28f59449c3 [FE-4543] fix(studio): remove outdated resize downtime warning (#51344)
## Summary

Removes the "Resizes may require more downtime than normal on this
project." warning from the disk/compute review dialog. This warning was
added for cross-architecture migrations during resize operations, which
are no longer performed, and has caused unnecessary customer support
inquiries.

## Closes
FE-4543

https://linear.app/supabase/issue/FE-4543
2026-10-06 15:34:15 -04:00
Connor Davis 32b16b7397 Add Connor Davis to humans.txt (#51360) 2026-10-06 15:21:43 -04:00
Lovro Mažgon 1a992761c1 chore(docs): Add Lovro Mažgon to humans.txt (#51354)
Add myself to humans.txt
2026-10-06 18:44:08 +02:00
John Jarvis 9a4ab14be2 chore: add John Jarvis to humans.txt (#51182)
## Problem

John Jarvis is missing from `humans.txt`.

## Solution

Add John Jarvis to `apps/docs/public/humans.txt`.

## Review instructions

Confirm the name is spelled correctly in the team list.

## Checklist

Check all before review:

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)

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

## Summary by CodeRabbit

* **Documentation**
  * Added John Jarvis to the team list.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-10-06 09:34:55 -07:00
Ivan VasilovandClaude Sonnet 5.5 9d1661dec1 chore: Reorganize the Files buckets code (#51350)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 15:29:35 +00:00
Jordi Enric c0c51dc168 test(logs): stabilize pathname refresh assertion DEBUG-230 (#51351)
## Problem

The Studio unit test added in #51112 failed on master because the
`/after` element returned by `findByText` was detached by a rerender
before `toBeInTheDocument` ran. The failure repeated across all three
test attempts in [this
job](https://github.com/supabase/supabase/actions/runs/37480673016/job/112327649118).

## Fix

Retry the DOM lookup and assertion together with `waitFor`, so each
attempt checks the current element synchronously. Keep the existing
timeout and assertions covering pathname refresh before the URL updates.

## How to test

- Run `pnpm --filter studio exec vitest run
components/interfaces/UnifiedLogs/UnifiedLogs.test.tsx`.
- Expected result: pathname options refresh after selecting POST and the
test passes.
- Prettier and `git diff --check` pass. Local Vitest was blocked before
assertions by the available dependency tree using React 18 instead of
React 19; ESLint was blocked by a missing `@eslint/compat` dependency.
CI validation is pending.
2026-10-06 09:11:00 -06:00
Jordi Enric d2ffd76395 perf(logs): load pathname facet counts on demand DEBUG-230 (#51112)
## Problem

Unified Logs included a pathname aggregation in every initial sidebar
count query, even when the pathname filter was closed. This issue is
tracked in
[DEBUG-230](https://linear.app/supabase/issue/DEBUG-230/fetch-sidebar-counts-only-when-needed).

## Fix

Remove pathname aggregation from the initial ClickHouse and BigQuery
count queries while keeping the existing shared count scans. Fetch
scoped pathname options through the existing facet query when the filter
opens or its search changes. Order limited pathname results by count,
validate response rows with Zod, and retain selected paths during
loading and validation errors. Use live sidebar filters while their URL
update is pending and URL filters after navigation. Cache results by
project and filter scope, and wait for feature flags before requesting
options.

## How to test

- Open Unified Logs, then open Pathname and search. Confirm options load
on demand.
- Change the time range, another filter, or navigate through browser
history. Confirm the options reflect the current scope.
- Close and reopen Pathname without changing the scope. Confirm cached
options return.
- Run the pathname filter component tests and Studio typecheck.
2026-10-06 16:38:30 +02:00
Pamela Chia 240e954390 fix(www): fix partners links and 404 redirects (#51294) 2026-10-06 07:14:38 -07:00
Joshen Lim eb20a4674d getTableDefinitionSql to escape SQL identifiers (#51258)
## Context

Similar to domain to https://github.com/supabase/supabase/pull/51256 -
`getTableDefinitionSql` doesn't escape SQL identifiers, which generates
invalid SQL on the dashboard's table editor for the "Copy table schema"
CTA, or the table definition tab.

Also fixes the "Copy table schema" CTA which was missing the `scoped`
parameter when calling `getTableDefinition`

Changes here addresses this issue, can test with a table named like
`test"table`
2026-10-06 21:34:36 +08:00
K-Dog (Kevin) 1da25a7e72 chore(hipaa): self-serve PITR (#51342)
There is no reason why HIPAA customers cannot self-serve PITR add-on.
Instead of telling customers to reach out to support, let them
self-serve it.

- Docs also wrongfully stated the need for Small compute add-on.
- Ability to self-serve PITR
- Only 28-day PITR available
- Price is now also correct and displays $0 (pending backend change)

When enabled (marked as HIPAA compliant):
<img width="1128" height="216" alt="Screenshot 2026-10-06 at 1 53 01 PM"
src="https://github.com/user-attachments/assets/d83982e7-c71b-4236-ab29-67f85fc40f39"
/>

When not enabled (marked as HIPAA compliant):
<img width="1132" height="255" alt="Screenshot 2026-10-06 at 1 53 55 PM"
src="https://github.com/user-attachments/assets/f182813b-2163-4905-8cdf-9c69983ec1b9"
/>

<img width="772" height="542" alt="Screenshot 2026-10-06 at 1 56 08 PM"
src="https://github.com/user-attachments/assets/2cd59439-74b9-49d6-90d1-47c8d1722c9f"
/>
2026-10-06 15:11:55 +02:00
Joshen Lim 23e7bbcdc6 Joshenlim/fe 3359 fix user permission UI for orgs with thousands of projects (#51329)
## Context

Adds virtualization to the organization team members page - browser
performance was facing issues for organizations with a large amount of
members (e.g 1000+), primarily due to some computation within
`MemberActions.tsx`, so virtualization addresses this by controlling the
number of member rows being rendered in the DOM at any one time.

<img width="1182" height="435" alt="image"
src="https://github.com/user-attachments/assets/e3da7036-c1c8-4d73-a363-85ecbdb79179"
/>


## Unrelated changes
- Updated `TeamSettings` to use the `PageContainer` components for UI
consistency
- Updated user `ProfileImage` to render the first alphabet of the email,
rather than a generic user icon
<img width="275" height="126" alt="image"
src="https://github.com/user-attachments/assets/17eae3b1-c527-4b8f-afcd-c5151bdaf869"
/>
- Updated row heights of member rows to be more smaller
- Updated MFA column to use tooltips with a clearer CTA for members that
don't have MFA enabled
<img width="332" height="144" alt="image"
src="https://github.com/user-attachments/assets/a479af31-7fec-454d-b64e-e6314fd6d55e"
/>
- Added a filter for MFA status  
<img width="375" height="177" alt="image"
src="https://github.com/user-attachments/assets/fd87105e-524d-4ded-b471-769592be96c7"
/>


## To test
- Can override the content for the `members` network request with the
following sample JSON, main thing is just to test that initial load +
searching should not run into any significant browser performance
issues.

[members-response-1000.json](https://github.com/user-attachments/files/33100317/members-response-1000.json)
- Can also test on production that this mock response does indeed cause
browser performance issues as well
2026-10-06 06:41:39 -06:00
6ecf98671a docs(platform): add Platform Webhooks guide and event catalog (#51098)
## Problem

Platform Webhooks (org- and project-level event notifications over the
Management API) has no public documentation. CTRL-1017 asks for a docs
page plus a specification of the available event types, so partners can
integrate without reading the OpenAPI spec or asking engineering
directly.

Closes CTRL-1017.

## Solution

**New guide covering the Management API path, plus an event catalog.**

Adds `apps/docs/content/guides/platform/webhooks.mdx`: concepts and
scoping, creating an endpoint, Standard Webhooks signature verification
and secret rotation, test events, and delivery/retry/ordering behavior.

Adds `apps/docs/content/guides/platform/webhooks/events.mdx`: the events
reference.

- Full payload documentation for the 8 project-lifecycle event types,
and a name-and-trigger table for the 12 branch, member, and billing
types whose payload fields aren't documented.
- Documents `*` for subscribing to every event.
- Access framing states the criterion: available to organizations on an
early access allowlist, with the `403` / `access_disabled` response for
everyone else.
- Nav entry under Platform > Project & Account Management, after
Personal Access Tokens, gated by `fullPlatformEnabled`.

**The page deliberately omits the dashboard UI.** See the first row of
the table below.

## Needs review before merge

| Item | Detail |
|
--------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| **The Studio webhooks UI is not wired to the API, so this page
documents the Management API only** | `PlatformWebhooksPage.tsx:29`
imports `PLATFORM_WEBHOOKS_MOCK_DATA`; `PlatformWebhooks.store.ts` has
no async or network code and hardcodes `createdBy:
'mock-user@supabase.io'`; nothing in `apps/studio` references
`webhooks/endpoints` or `webhooks/deliveries`, even though
`api-types/types/api-v2.d.ts` carries those paths 24 times. #43276
(DEPR-340) described it as "UI-only (with mock data)", and the
`DEPR-340-backend-integration-tracker.md` it pointed to is no longer in
the tree. A dashboard section can be added once the UI calls the API. |
| Possible reference slug collision | Project- and org-scoped operations
share identical `summary` values (both "Create endpoint", both "List
endpoints"). The page links to the reference introduction and names the
**Project webhooks** / **Organization webhooks** tags rather than
deep-linking a generated page. |

## Preview links

**Verified:** the new page returns 200 on the preview; the same path
returns 404 on production, confirming net-new content; the nav entry
renders on the preview build.

### Proof: new page renders on the PR preview

[Open the new page on
preview](https://docs-git-nikrichers-ctrl-1017-set-up-public-doc-fa3960-supabase.vercel.app/docs/guides/platform/webhooks)

<img width="2295" height="8039" alt="Screenshot 2026-10-05 at 11-47-06
Platform Webhooks Supabase Docs"
src="https://github.com/user-attachments/assets/7b1440d3-207d-4828-8593-77140bdcd73f"
/>

<img width="2295" height="12000" alt="Screenshot 2026-10-05 at 11-48-49
Platform Webhook Events Supabase Docs"
src="https://github.com/user-attachments/assets/2808a88e-558e-4f73-a12a-01382cd3f6a2"
/>


## Review instructions

1. Open the [PR
preview](https://docs-git-nikrichers-ctrl-1017-set-up-public-doc-fa3960-supabase.vercel.app/docs/guides/platform/webhooks)
and confirm the page renders as shown.
2. Confirm **Platform Webhooks** appears under **Platform > Project &
Account Management** in the sidebar, after **Personal Access Tokens**.
3. Confirm the five internal-guide values in the second row of the
needs-review table.
4. Decide with the Control Plane team whether the Studio UI ships wired
to the API, which determines when a dashboard section gets added: Studio
UI is slated for Q4, so it will not be shipped together.

## Checklist

Check all before review:

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)


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

* **Documentation**
* Added a Platform Webhooks guide covering endpoint setup, event
delivery, signature verification, test events, retries, retention,
idempotency, ordering, and listener best practices.
* Documented project and organization event types, payload schemas,
event scopes, and versioning, plus access restrictions for organizations
outside the allowlist.
* **Navigation**
* Added Platform Webhooks links, including Overview and Events, to the
platform navigation when the full platform is enabled.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Nik Richers <nik@validmind.ai>
Co-authored-by: Paweł Gulbinowicz <pawel.gulbinowicz@supabase.io>
Co-authored-by: Paweł Gulbinowicz <zamotany@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-10-06 14:30:16 +02:00
089133cc2c feat(storage): add bucket object versioning form fields (FE-4161) (#49203)
| # | Branch | Base |
| - | ------ | ---- |
| 1 | `feat/storage-versioning-private-alpha` — merged | `master` |
| 2 | `feat/storage-versioning/002-bucket-form-fields` ◀ | `master` |
| 3 | `feat/storage-versioning/003-bucket-modals` | 2 |
| 4 | `feat/storage-versioning/004-object-versions-data` | 3 |
| 5 | `feat/storage-versioning/005-file-preview-versions` | 4 |
| 6 | `feat/storage-versioning/006-billing-storage-retention` | 5 |
| 7 | `feat/storage-versioning/007-archived-objects-data` | 6 |
| 8 | `feat/storage-versioning/008-archived-rows` | 7 |
| 9 | `feat/storage-versioning/009-archived-preview-pane` | 8 |
| 10 | `feat/storage-versioning/010-replace-file` | 9 |

## [2/10] Storage object versioning: bucket form fields

The object versioning + lifecycle policy form section for the create and
edit bucket modals.
Mounted onto the ui in PR 3 #49205 

- `BucketVersioningFields` — the versioning switch and the suspension /
public-bucket / retention-tightening warnings
- `LifecyclePolicySection` — the retention window and version cap inputs
- `ExpirationModeToggle` — how the two conditions combine (and / or)
- `BucketVersioningFields.schema.ts` — zod fields the parent modals
spread into their own schema, plus `superRefineBucketVersioning`
- `BucketVersioningFields.utils.ts` — retention-tightening detection
- `StorageVersioning.constants.ts` — versioning state and expiration
mode types, the prefill defaults, and `getBucketVersioningState`

Note: a single s3 lifecycle policy expects both `version_expiry_days`
and `max_noncurrent_versions` and always evaluate the two fields within
the same policy with an AND logic. To enable both AND and OR/EITHER
logic, we save two distinct s3 policies so we can enforce the OR logic.

See demos and how to reproduce in #49205 

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

## Summary

* **New Features**
* Eligible projects with the preview enabled can configure object
versioning for storage buckets, including version expiration,
retained-version limits, and “and/or” lifecycle conditions.
* Settings default to 30 days and 10 retained versions, with validation
for retention values and requirements for setting a version limit.
* Notices highlight public buckets, missing lifecycle conditions,
suspending existing versioning, and changes that tighten retention
limits.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-10-06 14:24:50 +02:00
Illia Basalaiev 12afe39999 Docs/troubleshoot pg net privileges (#51275)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

New troubleshooting guides related to the current pg_net and pg_dump
extensions' behaviour.

## What is the current behavior?

## What is the new behavior?

Preview:
- [Revoking access to pg_net objects has no effect: no privileges could
be
revoked](https://docs-git-docs-troubleshoot-pg-net-privileges-supabase.vercel.app/docs/guides/troubleshooting/revoking-access-to-pg_net-objects-has-no-effect-0bbc16)
- [Database roles can read request headers queued by
pg_net](https://docs-git-docs-troubleshoot-pg-net-privileges-supabase.vercel.app/docs/guides/troubleshooting/database-roles-can-read-request-headers-queued-by-pg_net-ad6357)
- [pg_dump fails with 'query would be affected by row-level security
policy'](https://docs-git-docs-troubleshoot-pg-net-privileges-supabase.vercel.app/docs/guides/troubleshooting/pg_dump-fails-with-query-would-be-affected-by-row-level-security-policy-1d5783)
- [Custom role inherits privileges that were not explicitly
granted](https://docs-git-docs-troubleshoot-pg-net-privileges-supabase.vercel.app/docs/guides/troubleshooting/custom-role-inherits-privileges-that-were-not-explicitly-granted-ddaa1c)
2026-10-06 11:03:42 +02:00
Pamela Chia 20d752517f feat(docs): record search v2 rollout exposure (#51300) 2026-10-06 01:35:45 -07:00
Beng Eu 53a637a359 fix(studio): don't watch Next's .next build output in TanStack dev (#51308)
## Problem

Switching a local checkout from `STUDIO_FRAMEWORK=next` to `tanstack`
leaves `apps/studio/.next` behind, including a full `node_modules` copy
under `.next/standalone`. Vite's dev server watches all of it, logging
hundreds of `page reload .next/server/pages/...` lines and wasting file
handles.

## Change

Add `**/.next/**` to `server.watch.ignored` in
`apps/studio/vite.config.ts`. Vite's default ignores (`.git`,
`node_modules`) still apply.

## Verification

With a stale `.next` present, ran `STUDIO_FRAMEWORK=tanstack pnpm run
dev`, touched `.next/server/pages/account/me.html`: no reload logged
(previously ~220 `.next` reloads on startup).
2026-10-06 14:38:04 +08:00
Joshen LimandGildas Garcia dc95335a8d Joshenlim/fe 4068 warn users ai assistant history can be wiped (#51260)
## Context

Chats with the AI Assistant is currently stored locally on the browser
and not synced across devices which caused a bit of confusion for some
users when they realised they couldn't access their chat histories on
different devices. (Ideal state tbh is to persist the chat
conversations, but that'll need support on the BE)

PR here just adds a foot note to both the chat history dropdown in the
side panel + chat nav for the explorer regarding this - opting for
something with a small footprint
<img width="293" height="322" alt="image"
src="https://github.com/user-attachments/assets/284ee0c1-16bf-432b-b473-29ee048ed4cc"
/>
<img width="392" height="956" alt="image"
src="https://github.com/user-attachments/assets/e5eb1409-fa63-4dae-9439-86facbe41277"
/>

---------

Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
2026-10-06 11:37:26 +08:00
Joshen Lim 2538f7eb29 Fix unescaped SQL identifiers in row export (#51256)
## Context

Resolves https://github.com/supabase/supabase/issues/49977

Addresses an issue in `formatTableRowsToSQL` to use `ident` for schema,
table, and column name which will handle escaping of SQL identifiers.

Can verify fix by creating a table like `test"table`, then adding some
rows, and selecting either Copy as SQL or Export as SQL
2026-10-06 11:35:01 +08:00
claude[bot]andClaude b6d4239010 Update Supplemental Terms placeholder text (#51301)
<!-- ccr-slack-attribution -->
_Requested by **Nicole Kramer** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1790784371448999)_

## Problem

**Before:** The Supplemental Terms page
(`/legal/customer-resources/supplemental-terms`) says "Content coming
soon."

**After:** The page shows "Check here for any feature specific terms
that we may need to release, or clauses that allow for compliance with
geography specific laws that we may introduce."

## Solution

Replaces the placeholder body in
`apps/www/data/legal/customer-resources/supplemental-terms/v1.mdx` with
the supplied text, as a plain paragraph. Nothing else changes.

## Review instructions

1. Open the Vercel preview link for
`/legal/customer-resources/supplemental-terms`.
2. Confirm the page shows the new text instead of "Content coming soon."

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01K2vqszbsJiMJPABAnLMgaC


---
_Generated by [Claude
Code](https://claude.ai/code/session_01K2vqszbsJiMJPABAnLMgaC)_

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-06 03:20:55 +00:00
Joshen Lim be1ba651ed Add branching nav items to cmd k (#51255)
## Context

Adds a couple of branching nav items to Command K
- Create new branch
- Branch management
- Merge requests
- Github Connection (For branching)
- Branching feedback

Switch branch is still available, and only visible after a branch has
been created (status quo)

<img width="610" height="531" alt="image"
src="https://github.com/user-attachments/assets/3068184e-889d-44ed-8cf6-2afd59ffb109"
/>
2026-10-06 11:12:53 +08:00
Joshen Lim 642a02db49 Prevent enabling spend cap if org has projects with RRs (#51253)
## Context

Prevents organizations from enabling spend cap if the org has projects
with read replicas - We currently gate creation of read replicas to
ensure that orgs have spend caps disabled, but were missing the guard
for the other way around
<img width="662" height="378" alt="image"
src="https://github.com/user-attachments/assets/44ad036c-4c1b-48e8-beb7-f16f6170c9fb"
/>

## Other changes involved
- Refactored to use new `Sheet` and `Table` components in
`SpendCapSidePanel`
2026-10-06 11:12:35 +08:00
Pamela Chia 20d6f2197f chore(studio): remove privacy policy notice (#51299)
I removed the Studio Privacy Policy update notice that #50397 added on
2026-09-16, when Privacy Policy v4 took effect. It has been up for
almost three weeks, and the ToS v4 banner (#51109) goes out next. I did
the same in #44380, removing the March 2026 privacy notice after 15
days.

This is the exact inverse of #50397: the banner component and its test,
the banner ID, the dismissal local storage key, and the org-landing path
helper that only this notice used.

## To test

Tested on Vercel preview:
- [ ] In a fresh browser profile (no
`privacy-policy-update-2026-09-16-dismissed` key), open
`/organizations`: expect no Privacy Policy notice
- [ ] Open `/org/<slug>`: expect no Privacy Policy notice and the
project list renders normally
- [ ] Open a project's Logs page: expect the logs deprecation banner
behavior unchanged (only shows before its expiry)

## Linear
- fixes GROWTH-1322
2026-10-05 19:24:14 -07:00
claude[bot]andClaude a629c9c1ac Add hidden Supplemental Terms legal page (#51100)
<!-- ccr-slack-attribution -->
_Requested by **Nicole Kramer** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1790784371448999)_

## Problem

No page existed yet for the upcoming "Supplemental Terms" document.
Nicole Kramer (Commercial & Product Counsel) needs a stable, linkable
URL to reference from future Terms of Service / Enterprise SaaS
Subscription Agreement updates, before the legal content itself is
ready. The page needs to be reachable by direct URL but not surfaced in
the visible Legal Hub nav yet, matching the existing "hidden" precedent
used for `/enterprise-terms`.

## Solution

Added a new page at `/legal/customer-resources/supplemental-terms`:

- `apps/www/pages/legal/customer-resources/supplemental-terms.tsx` — a
page component mirroring the existing Data Processing Addendum page
(`apps/www/pages/legal/customer-resources/data-processing-addendum.tsx`):
`DefaultLayout` + `PageHeader` (h1 "Supplemental Terms") +
`LegalDocVersions` rendering a single MDX version.
- `apps/www/data/legal/customer-resources/supplemental-terms/v1.mdx` —
placeholder body content (`_Content coming soon._`), no frontmatter/h1,
following this repo's existing legal MDX convention (the h1 is rendered
by `PageHeader`, not the MDX itself). Nicole will fill in the actual
legal content later.

**On "hidden":** I investigated the actual codebase state before
implementing, since the two precedents named didn't turn out to work the
same way:
- `/enterprise-terms` is genuinely hidden — it is not linked anywhere in
`apps/www/pages/legal/index.tsx`'s Legal Hub listing, and its `NextSeo`
meta sets `noindex: true, nofollow: true`.
- The Data Processing Addendum and Subprocessor List pages, by contrast,
**are** linked in the visible Legal Hub listing
(`apps/www/pages/legal/index.tsx`, "Customer Legal Resources" section) —
they are not hidden today.

Given that, this PR mirrors the DPA/Subprocessor List *structural*
pattern (route under `/legal/customer-resources/`, page-component +
versioned-MDX content) since that's what "under Customer Legal
Resources" means structurally in this codebase, but mirrors
`enterprise-terms`' *hidden* mechanism: the new page's `NextSeo` meta
sets `noindex: true, nofollow: true`, and — importantly — **no entry was
added** to the `sections` array in `apps/www/pages/legal/index.tsx`, so
it does not appear in the visible Legal Hub or any nav. The page is
reachable only via its direct URL.

Terms of Service and the Enterprise SaaS Subscription Agreement pages
were not touched.

## Review instructions

1. Confirm `/legal/customer-resources/supplemental-terms` renders with
h1 "Supplemental Terms" and placeholder body text.
2. Confirm the page does **not** appear anywhere on `/legal` (the Legal
Hub listing).
3. Confirm `apps/www/pages/terms.tsx` /
`apps/www/pages/enterprise-terms.tsx` (and their MDX content) are
unchanged.

## Checklist

- [x] I have read CONTRIBUTING.md
- [ ] N/A — no docs topic edited (legal page content is a placeholder,
not docs content)

---

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01K2vqszbsJiMJPABAnLMgaC

---
_Generated by [Claude
Code](https://claude.ai/code/session_01K2vqszbsJiMJPABAnLMgaC)_

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-06 13:09:25 +11:00
Pamela Chia 81da60392e feat(www): add multigres alpha form to /database (#51298)
The Multigres private alpha request form only lives at
/go/multigres-early-access (#51053), and nothing on the product site
links to it. I added the same form to /database, the way /compute embeds
its waitlist form.

The new section sits at the bottom of the page, directly above the
closing "Start your project" CTA: the go page's hero copy, the alpha
caveats, and a "Learn about Multigres" link to multigres.com on the
left, the form on the right. Fields, disclaimer, and redirect are read
from the go page definition. The form posts `{ slug:
'multigres-early-access', formId: 'form' }`, so the server resolves the
existing CRM config and submissions land in the same database as the go
page.

**Note:** the section throws at build time if the go page or its form
section is removed, so retiring the go page means removing this section
in the same change.

## To test
Tested on Vercel preview:
- [ ] Open /database and scroll to the bottom: expect a "Private alpha /
Multigres on Supabase" section directly above "Build in a weekend, scale
to millions", with the email and organization slug form, the alpha
caveats, and the Privacy Policy disclaimer
- [ ] Click "Learn about Multigres": expect multigres.com to open in a
new tab
- [ ] Resize to a phone width: expect the text stacked above the form
card with no horizontal scroll
- [ ] Open /go/multigres-early-access: expect its page and form
unchanged
- [ ] After merge, submit a test request from supabase.com/database:
expect a redirect to /go/multigres-early-access/thank-you and a new row
in the Multigres requests database

## Linear
- fixes GROWTH-1321
2026-10-05 18:50:48 -07:00
Ignacio Dobronich 22cdd05492 fix: update disk maxSize in pricing page (#51295) 2026-10-05 22:46:23 -03:00