mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 10:55:06 +03:00
842609fffbcbca542e855a4676fbcd48cb2030db
19528
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
842609fffb |
copy(studio): rename 'Trash' to 'Deleted files' in the Storage UI
Renamed every user-facing occurrence: the Files sub-tab label, the bucket detail page's link button, the empty state, error subject, and the retention copy. Internal naming (Trash/ folder, component names, hooks, query keys, route path) is left as-is — only the displayed text changed. Also updates the demo script and implementation notes to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiUEvmC84bRsteqsWXHY2p |
||
|
|
c79c915e54 |
polish(studio): preview pane header, timeline spacing, bucket Trash link
- Preview pane: when Versions is available, the Details/Versions tabs move into the header row alongside the close icon instead of sitting below it; added horizontal gap between the tabs. - Version timeline: more vertical breathing room between entries. - Bucket detail page: add a Trash button next to Policies/Edit bucket, deep-linking to Files > Trash pre-filtered to the viewed bucket. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiUEvmC84bRsteqsWXHY2p |
||
|
|
d9b8820a96 |
feat(studio): fold storage retention into Storage Size, add platform restore points
Usage page: remove the standalone Card-based Storage Size section and fold the retention breakdown into the existing Storage Size attribute. The chart now stacks live objects / object versions / snapshots via the standard UsageBarChart attributes, and the breakdown renders in the right column through `additionalInfo`, matching every other section's layout and styling. splitStorageSizeByRetention attributes the reported daily total across the three segments without changing the total (unit tested). Database backups: reframe a backup as an environment-wide restore point rather than a database-only one. A backup restores Postgres — and Auth users plus Storage metadata with it, since those live in Postgres — but not object bytes, which is exactly what produces rows referencing files that no longer exist. So: - Per-row coverage chips across Database / Storage / Config, with the storage gap surfaced rather than implied - A coverage notice naming which buckets aren't protected and linking to the fix - Restore dialog offers 'into a new preview branch' as the default, since branching is a copy-on-write platform primitive: verify a restore point before promoting it, instead of destructively restoring over production. In-place restore remains available and still uses the existing backup-restore mutation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiUEvmC84bRsteqsWXHY2p |
||
|
|
c1512f7f7f |
fix(studio): restore vertical gap in Snapshots and Trash pages
PageSectionContent is a plain div, so a gap-y-* className has no effect without flex flex-col — same pattern already used by StorageSettings, VectorBuckets, and AnalyticsBuckets. Snapshots.tsx and Trash.tsx were missing the flex flex-col, so the gap between the toolbar and the table/empty-state was silently not applied. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiUEvmC84bRsteqsWXHY2p |
||
|
|
a2761e82a6 |
refactor(studio): Snapshots/Trash as Files sub-tabs + unit inputs
- Move Snapshots and Trash out of the Storage sidebar (which lists bucket *types*: Files/Analytics/Vectors) into tabs under Files, at /storage/files/snapshots and /storage/files/trash — they're recovery views over file buckets, not a separate bucket type. Tabs added in StorageBucketsLayout; sidebar items reverted in StorageMenuV2. - Use the design-system 'Input with unit' pattern (InputGroup + InputGroupAddon/InputGroupText) for the lifecycle day inputs in the bucket data-protection section. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiUEvmC84bRsteqsWXHY2p |
||
|
|
b1184b3a99 |
feat(studio): Storage Snapshots & Versioning demo (mock data)
Implements the five Claude Design mockups as real Studio components behind a single prototype flag (STORAGE_PROTECTION_ENABLED), wired to an in-memory mock data layer since no platform API exists yet: - Data protection section in create/edit bucket modals (versioning + snapshots toggles + lifecycle policies) - Snapshots: new bucket-scoped nav page with Pre-backup/Manual triggers, take snapshot, and restore-with-diff - Versions tab in the storage explorer preview pane (restore an older version) - Storage size retention breakdown on the org usage page (live / versions / snapshots, retained-data callout, per-bucket table) - Trash: new bucket-scoped nav page for soft-deletes with held-by-snapshot state Adds mock query/mutation hooks under data/storage/protection, Snapshots + Trash nav items, and new pages/routes (+ TANSTACK_MIGRATION entries). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiUEvmC84bRsteqsWXHY2p |
||
|
|
8d4d3b57e0 |
feat(studio): add tanstack variant to the studio docker image (#48091)
Makes the self-hosted Docker image buildable with the TanStack/Vite
build alongside the existing Next one. The Dockerfile's new
`STUDIO_FRAMEWORK` build arg (default: `next`) selects which framework
lands in the image — the same variable `scripts/dispatch.js` keys on
everywhere else, so `--build-arg STUDIO_FRAMEWORK=tanstack` is the
docker spelling of the existing switch. Both flavors assemble a
normalized `/srv` tree, so a single production stage serves either with
the same CMD (`node apps/studio/server.js`), port 3000, and healthcheck.
Unlike Next's self-contained standalone output, the Vite SSR bundle
externalizes studio's dependencies and resolves them from `node_modules`
at request time, so the tanstack runtime tree is a prod-only `pnpm
deploy` plus the built `dist/`. The boot smoke test runs a second time
against that pruned tree, so a runtime import that's missing from
`dependencies` fails the image build instead of 500ing the deployed
container — which is exactly how this PR caught four packages
misclassified as devDependencies (`braintrust` +
`@smithy/property-provider` via the AI routes, `libpg-query` via the
parse-query API route, `@radix-ui/react-use-escape-keydown` via the
Queues panel; split into its own commit).
**Changed:**
- `apps/studio/Dockerfile`: `ARG STUDIO_FRAMEWORK` selects `build-next`
/ `build-tanstack` stages via `FROM build-${STUDIO_FRAMEWORK}`; both
normalize into one production layout
- `apps/studio/package.json`: moved the four runtime-imported packages
from devDependencies to dependencies (versions unchanged)
- `apps/studio/vite.config.ts`: pinned `preview.host` to `127.0.0.1` —
the prerender step boots `vite preview` and crawls its resolved URL, and
the default `localhost` host lets the server bind the IPv6 loopback
while the crawler fetches `127.0.0.1`, which ECONNREFUSEDs the whole
build inside BuildKit containers
- `.github/workflows/studio-docker-build.yml`: builds the tanstack image
as a second step (reuses the first build's layer cache; job name
unchanged)
**Added:**
- `build:studio:docker:tanstack` root script
Note: the tanstack image is ~2.0GB vs ~1.2GB for Next (externalized
`node_modules`); shrinking it via file tracing is a follow-up. Nothing
self-hosters pull changes until a tanstack-built image is published —
this makes it buildable and CI-checked.
## To test
- `pnpm build:studio:docker` then run the image against a stack —
behavior unchanged (healthcheck `/api/platform/profile` 200, `/` 307s to
`/project/default`)
- `pnpm build:studio:docker:tanstack` then run that image with the same
env — same healthcheck, redirect, and data endpoints (projects, pg-meta)
respond 200; browser loads Project Overview / Table Editor with no
requests leaving the container
- Both verified locally against the CLI stack (`host.docker.internal`
env, container reports `healthy`)
- Vercel + e2e checks on this PR exercise the `preview.host` change on
their runners
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added TanStack-based Studio build support with a framework-selectable
Docker image.
- Added a local build command for the TanStack Studio Docker image.
- **Build & Deployment**
- Updated the Studio Docker build workflow to also publish a
TanStack-tagged Studio image when relevant.
- **Bug Fixes**
- Improved `vite preview` behavior in containers by binding to IPv4
loopback.
- Standardized the Studio container runtime port to `3000`.
- **Chores**
- Updated Studio runtime packages to support the TanStack build.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
|
||
|
|
74a57861b3 |
chore(studio): remove region limitation for vector buckets (#48248)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Remove the region limitation on vector buckets ## What is the current behavior? Currently vector buckets are limited to a subset of Supabase regions ## What is the new behavior? All supabase regions now have access to vector buckets ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Vector buckets are now available based solely on platform enablement, without region-based restrictions. * **Bug Fixes** * Removed the region limitation message and related region availability checks from the Storage Vectors page. * Updated vector bucket upgrade behavior to reflect platform availability more consistently. * **Tests** * Updated coverage to reflect the simplified platform-based availability behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
99fd5d0117 |
fix: Refactor some suspicious Valtio uses (#48141)
This PR is partly driven by changes in https://github.com/supabase/supabase/pull/48102. Claude identified code smells of Valtio state which are not bugs at the moment, but we should address in case their usage changes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved AI assistant message updates to prevent unexpected state changes. * Fixed table editing behavior to preserve shared data and prevent accidental in-place mutations. * Improved consent handling by preventing SDK internals from being altered by state management. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6cff728742 |
feat(studio): polish Connect sheet mode selector and steps (#48266)
## What kind of change does this PR introduce? UI polish for the Connect sheet: clearer mode selection, wider sheet layout, and step/content chrome across Direct, Server, MCP, and shadcn flows. ## What is the current behavior? - Connect modes use a weak selected state and an awkward grid layout. - The sheet can jump width below the `lg` breakpoint when switching modes. - Direct connection chrome is noisy (reset in a footer, Title Case / mono pooler labels, mismatched copy-button sizes). - Several steps use admonitions or extra tips that repeat footer guidance. - Case-sensitive import of `InlineLink` breaks Linux/Vercel builds. ## What is the new behavior? ### Mode selector and sheet - Stronger selected/hover treatment; comfortable single row that wraps via `@container`. - Empty odd slots use a sunk placeholder cell. - Sheet uses `size="lg"` with `max-w-4xl` and `w-full min-w-0` so width stays stable when switching modes. ### Steps chrome - “Follow these steps” header with a copy-prompt action for coding agents. - Optional steps labelled `(optional)`. - Shared `CodeBlock` for install snippets; MCP feature groups preselect all except Storage. - Server / shadcn tips folded into footers; IPv4 add-on admonition is responsive with an inline Learn more link and a single Enable action. ### Direct connection - Connection string and connection parameters stay one step (same credentials, two formats). - Reset database password lives in the string card title row beside Shared/Dedicated pooler. - Card titles use sans + sentence case (`Shared pooler`, `Connection parameters`); `.env` stays mono. - Icon-only copy buttons match CodeBlock square sizing; row actions sit slightly closer to the right edge (`pr-2`). - Shared pooler toggle copy clarified. | Before | After | | --- | --- | | <img width="390" height="763" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/adca3cc5-94f8-47e5-a4a2-2831790f430a" /> | <img width="390" height="763" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/f03afe58-e654-435e-a821-835f6243ca95" /> | | <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/79f08620-7e1e-4246-a70f-801606c0f499" /> | <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/fb45e851-955e-46c2-90f1-afecb93d6ac4" /> | | <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/eda36d21-bba7-46ab-ad48-134acf93b471" /> | <img width="1718" height="1323" alt="API Keys Settings Chisel Toolshed Supabase" src="https://github.com/user-attachments/assets/b7b728c6-fc92-46a7-8e3f-2f182c56ece7" /> | ### Test plan - [ ] Open **Connect** and confirm mode cells select/hover clearly; narrow the sheet and confirm wrap + stable width. - [ ] Direct: switch Direct / Transaction / Session; confirm pooler title, reset in title row, parameters table, and percent-encode note. - [ ] Toggle IPv4 shared pooler on Transaction; confirm string updates and admonition/Learn more behaviour when on IPv4-only paths. - [ ] Server: `.env` Copy all / row copy sizing; install command copy. - [ ] MCP / shadcn / Framework: steps still resolve and copy prompt still builds a useful agent prompt. - [ ] Spot-check light/dark and a Linux/Vercel build (InlineLink import casing). |
||
|
|
2a17985a1c |
fix: Skip to main content link should be visible when focused (#48303)
## Problem #47694 introduced a _Skip to main content_ link allowing keyboard users to jump to the main section without having to tab through all the navigation elements. However, this link is completely invisible which means sighted users will not see what is actually focused. ## Solution The best practice for such links is to make them visible on focus. For instance on https://tetralogical.com: <img width="1556" height="305" alt="image" src="https://github.com/user-attachments/assets/e36f6d73-98b0-46ca-b464-72540a482b5f" /> Here's what it looks like on Studio: <img width="1835" height="335" alt="image" src="https://github.com/user-attachments/assets/71623306-587a-48aa-b955-43d3368f6073" /> ## How to test - Make sure your browser allows to tab to links (https://www.articulatesupport.com/article/How-to-Enable-Tab-Key-Navigation-on-a-Mac) - Open https://studio-staging-git-gildasgarcia-fe-3805-add-ski-cf6824-supabase.vercel.app and sign in - Once the Studio is loaded, verify the button isn't be visible - Press _Tab_: the button should be visible. - Press _Enter_, then press _Tab: the organizations search input should be focused |
||
|
|
69570a357d |
fix(studio): route vercel deploy-button params to create despite marketplace source (#48258)
## What kind of change does this PR introduce? Bug fix for the Vercel Deploy Button → Studio handoff. ## What is the current behavior? Vercel sometimes opens our install popup with `source=marketplace` while still sending Deploy Button params (`currentProjectId`, `external-id`). We trust `source` alone, so users are routed to choose-project (connect) instead of create — which is why create never gets reached in the Deploy Button flow. ## What is the new behavior? - When both Deploy Button signals (`currentProjectId` + `externalId`) are present, route to create even if Vercel sent `source=marketplace` / `external` - Hide Skip (and related empty-state copy) on choose-project when those signals are present, so Deploy Button users can't continue without linking ## Additional context Stacked on #48230. Test plan: - [ ] Unit tests for `resolveVercelInstallSource` / `hasVercelDeployButtonSignals` pass - [ ] Deploy Button flow with mislabeled `source=marketplace` + both params → lands on create after org install/continue - [ ] Genuine marketplace install (no `currentProjectId`/`external-id`) → still lands on choose-project with Skip available - [ ] If choose-project is opened with both Deploy Button params, Skip is hidden <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved Vercel installation handling for Deploy Button workflows, ensuring the correct setup path is selected. - Added clearer project-connection guidance when no projects are available (including conditional skip copy). - **Bug Fixes** - Prevented Deploy Button installations from incorrectly offering a skip option. - Preserved the skip-and-connect-later guidance for other Vercel installation flows. - Improved recognition of Deploy Button installations even when the reported Vercel source differs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
2f0a582198 |
chore: remove triplit link (#48286)
## 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? Blog update ## What is the current behavior? Triplit link goes to triplit.dev which is no longer registered/active ## What is the new behavior? No more triplit.dev link <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated the blog post’s opening paragraph by removing the hyperlink from the “Triplit” text. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8c092185ae |
feat: paused project restore window copy and backup downloads (#48279)
Shows the restore deadline as a date on the paused-project screens, and offers backup downloads while a paused project is still restorable (previously only after the restore window ended). Depends on a backend change — keep as draft until that is live. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Extended the paused-project restore window from 90 days to up to 1 year. * Added clearer, downloadable options for database backups and storage objects while a project is paused. * Paused-project screens now show an “available until” date when applicable (and updated resume guidance). * **Documentation** * Updated platform and troubleshooting guides to reflect the new 1-year restore window and post-window recovery limitations. * **Bug Fixes** * Standardized restore-window wording across the pause confirmation and paused-state UI. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
075caf314e | chore: refactor database advisors and database wrapper federated content (#48199) | ||
|
|
cea246d195 |
Fix: improve accessibility for icon buttons (Table Editor menu) (#47639)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix (accessibility improvement) ## What is the current behavior? Icon-only buttons do not have explicit accessible names for screen readers or tooltips. ## What is the new behavior? All icon-only buttons now have explicit accessible names using visually hidden text (sr-only), ensuring proper screen reader support. ## Additional context Tooltip text is preserved or added for visual users. No visual changes were introduced. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Accessibility Improvements** * Updated table editor action controls with clearer, context-aware `aria-label`s (e.g., “Add new column”, “More options for …”, “New table”). * **UI Refinements** * Added hover tooltips to key table editor actions, including add-column, more-options dropdown triggers, and create-new-table button, improving discoverability and guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a06eb5f26f |
[FE-3724] feat(studio): add enable cleanup button to cron jobs page (#48200)
Adds a standalone **Enable cleanup** button to the Cron Jobs page header so users can schedule the daily `delete-job-run-details` cleanup job proactively — previously this was only reachable inside the conditional "table too big" overflow dialog. Addresses [FE-3724](https://linear.app/supabase/issue/FE-3724/enable-pg-cron-cleanup-job-from-ui-and-api) (the UI half; the Management API half needs platform-side work). **Added:** - `Enable cleanup` button in the cron jobs header (left of Refresh), hidden while the existence check loads and whenever a `delete-job-run-details` job already exists - Confirmation dialog with a retention-period select (defaults to 7 days), live SQL preview, and telemetry (`cron_job_cleanup_enable_button_clicked` with `origin` + `retentionInterval`) - Component tests (MSW) for visibility gating and the schedule/cancel flows - E2E regression test for the full schedule → delete → button-reappears cycle **Fixed:** - Name-based `useCronJobQuery` lookup: the `queryFn` dropped the `name` param, and a not-found job returned `undefined` (rejected by react-query v5) — now passes `name` through and returns `CronJob | null` - Cache invalidation gaps: create/delete now invalidate the whole cron-jobs prefix (list, count, job details), so the footer count updates after create/delete and the button reappears after the cleanup job is deleted. The schedule mutation deliberately invalidates only the existence check + count (see inline comment) - Pre-existing e2e leak: the cleanup-workflow test left `delete-job-run-details` scheduled; it now cleans up after itself ## Screenshots | Header button | Dialog | | --- | --- | | <img width="890" height="325" alt="Screenshot 2026-07-22 at 9 44 40 PM" src="https://github.com/user-attachments/assets/966cd640-d8a6-4c8f-92e7-73151bf4de9c" /> | <img width="512" height="461" alt="fe3724-dialog" src="https://github.com/user-attachments/assets/6be1785f-cc7e-4048-a648-9ef260b0949f" /> | ## To test - Go to a project's Integrations → Cron → Jobs with pg_cron enabled and no `delete-job-run-details` job → the `Enable cleanup` button shows next to Refresh - Open the dialog, switch retention intervals → the SQL preview updates; confirm → success toast, the job appears in the grid (`0 12 * * *`), and the button disappears without a reload - Delete the `delete-job-run-details` job from the grid → the button reappears without a reload - Create then delete any other job → the footer `Total: N jobs` count updates both ways without a reload - Regression: with the high-query-cost banner forced (or via the e2e), the overflow dialog's "Schedule cleanup job" step still shows its success state — the dialog must not close mid-flow <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Added an **Enable cleanup** action to the Cron Jobs tab header, including a retention selector and SQL preview. * Enabling schedules the daily cleanup, shows a success toast, updates the grid, and hides the enable button; **Cancel** closes the dialog without scheduling. * **Bug Fixes** * Improved cron job lookup to work by name when needed. * Refreshed related cron job data more reliably after scheduling and deletion. * **Telemetry** * Added an event for cleanup enable button clicks. * **Tests** * Added component and Playwright coverage for enable/cancel/schedule/delete and cleanup banner flows. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
223a10d1bb |
Add query filter for Database Connections (#48242)
## Context Adds a way to filter against the query string in Database Connections <img width="682" height="161" alt="image" src="https://github.com/user-attachments/assets/1ba6d678-553a-4a1a-9da9-412532c626df" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a free-text search filter for database activity sessions. * Search works alongside existing state, role, and application filters. * Filter option counts now reflect the current search results. * **Bug Fixes** * Improved filter reset behavior to reliably clear search along with all other selections. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b2b150fa3c |
feat(pipelines): Add UI selector for choosing which tables to skip copy of (#47808)
## Summary Adds initial-copy scoping to Pipelines in Studio. Users can copy all existing rows, skip all initial copies, copy only selected publication tables, or skip selected table copies. All publication tables continue streaming new changes regardless of the initial-copy policy. The policy now round-trips through create, edit, validation, and the generated Management API contract. Initial-copy estimates and table-restart confirmations use the same scope. Edit requests also preserve redacted credentials and pipeline settings that Studio does not own. This completes the Studio layer of the [ETL API change](https://github.com/supabase/etl/pull/897) and [Management API change](https://github.com/supabase/platform/pull/35479). ## Screenshots ### Selector <img width="1153" height="465" alt="image" src="https://github.com/user-attachments/assets/bf615e82-ee61-4222-979d-a8695a957e82" /> ### Select certain tables only <img width="1153" height="465" alt="image" src="https://github.com/user-attachments/assets/28adaa24-f239-4d1d-8fb8-fdb1988320cd" /> ### Confirm copy costs As the final step before the pipeline is created: <img width="597" height="619" alt="image" src="https://github.com/user-attachments/assets/a660bd87-bfb8-41c5-8099-4cdbdef943bf" /> ### Policy-aware initial-copy estimate #### Copy no table is selected <img width="407" height="464" alt="image" src="https://github.com/user-attachments/assets/99d859ec-2ec3-452a-ab69-11924a8db260" /> #### Some tables are selected <img width="407" height="464" alt="image" src="https://github.com/user-attachments/assets/e68aedf4-66bc-4372-98ef-0dd7fecef324" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added configurable “initial table copy” policies (copy/skip all and copy/skip selected) during replication setup, including table-picker behavior, pruning of stale selections, and updated restart/cost estimates. - **Bug Fixes** - Improved restart flows to consistently use `schema.table` identity and simplified “errored tables” targeting to match error-state tables. - Reduced unnecessary loading by gating publication/table fetches to when panels are visible; improved validation/toast handling when publication tables are unavailable. - **Tests** - Added/expanded coverage for destination form submission, table-copy selection, restart/cost dialogs, and copy-estimate summarization. - **Style** - Refreshed warning/label text for clearer configuration and confirmation messaging. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Victor Farazdagi <simple.square@gmail.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
a1df468edd |
Add keyboard shortcut to live mode (#48280)
## Context As per PR title - there's already a keyboard shortcut mapping for the live mode toggle that was originally present in `UnifiedLogs`, so this reuses that. Opting for a more explicit tooltip copy as well as "Live" doesn't really explain what it does <img width="257" height="82" alt="image" src="https://github.com/user-attachments/assets/2159eef3-6291-4fdc-93ca-da706c8688f0" /> <img width="195" height="101" alt="image" src="https://github.com/user-attachments/assets/0d5d211c-af66-406d-9cff-7de7b15f0892" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added keyboard shortcut support for toggling live updates in database connections. * Added shortcut guidance to the Live/Pause control. * Resuming live updates now refreshes activity immediately and updates the displayed timestamp. * **Bug Fixes** * Improved live-refresh controls and messaging to clearly reflect the refresh cadence. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6c6a721cb7 |
fix(pg-meta): scope remaining O(catalog) introspection queries behind pgMetaScopedIntrospection (#48148)
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix (performance), follow-up to #47894, plus regression-guard tests. ## What is the current behavior? #47894 scoped the Table Editor and entity-definition introspection queries, but four more `@supabase/pg-meta` query families still do O(catalog) work per request. On a production project with a very large catalog (hundreds of schemas, ~465K `pg_constraint` rows) they run 5 to 55 seconds each, trip the 58s `statement_timeout`, and spill sorts to temp files. During a recent "DB CPU > 85%" incident on such a project, 24 of 27 active backends were running these queries concurrently. 1. **`tables.retrieve()` (single-table lookup by name+schema or id)**: the `tables`/`columns` CTEs scan the whole catalog (`pg_class`, `pg_constraint`, `pg_index`, all of `pg_attribute`, per-table sizes) and the one-table predicate is applied only on the outer select. Same bug class #47894 fixed for the OID-based table editor query; this sibling path never got the treatment. It accounted for 94 of the 96 statement-timeout cancellations in the incident. 2. **Types listing**: the `t_enums` and `t_attributes` subqueries aggregate the entire `pg_enum` and every composite relation before the wrapper's schema filter applies. 3. **Table privileges**: `aclexplode` + double `pg_roles` join + GROUP BY over every relation in the database; schema/OID filters applied only after aggregation, in both `list()` and `retrieve()`. 4. **Row counts**: `getTableRowsCountSql` treats `reltuples = -1` (never-analyzed table) as "small table, run exact count(*)". A freshly bulk-loaded multi-million-row table times out on every Table Editor pagination render. Two Studio-side amplifiers turned one slow query into a sustained load storm: - `useTableQuery` (behind `tables.retrieve()`) mounts once per visible foreign-key grid cell via `ForeignKeyFormatter`, so a single Table Editor view fires ~20 concurrent copies against the FK target table. A timed-out query caches nothing, and TanStack retries errored no-data queries on every observer mount by default, so scrolling kept re-issuing the 58s scan. - `useTableApiAccessQuery` fetched table privileges for the entire database and filtered down to one schema client-side. ## What is the new behavior? **pg-meta (all behind the existing `pgMetaScopedIntrospection` flag, same rollout mechanism as #47894; `scoped: false` keeps serving the current SQL):** - `tables.retrieve()`: the identifier is resolved to a scalar `targetOid` init-plan and pushed into the base scan, primary-key, relationships (both FK directions kept: `conrelid` or `confrelid`) and columns CTEs. A materialized `target` CTE was deliberately avoided: it acts as an optimization barrier and forces the very seq scans being removed. - Types: filter `pg_type`/`pg_namespace` first, then compute enums/attributes per surviving row via correlated index-scan subqueries (`pg_enum(enumtypid, enumsortorder)`, `pg_attribute(attrelid, attnum)`). - Table privileges: schema/OID predicates injected into the base WHERE before `aclexplode`/GROUP BY for `list()` and `retrieve()`. - Row counts: `reltuples = -1` is treated as "unknown" and gated on physical size via `pg_relation_size` (a cheap stat call; `relpages` is equally stale pre-vacuum). At or below `THRESHOLD_ESTIMATE_BYTES` (~10MB, derived from `THRESHOLD_COUNT` at a conservative ~200 bytes/row) the exact count runs as before: fast by construction, and it avoids bogus estimates since Postgres floors never-vacuumed heaps at 10 pages, so an empty table would otherwise report ~2K estimated rows. Above the gate the count routes through the EXPLAIN-based `pg_temp.count_estimate`, or returns `-1`/`is_estimate = true` in read-only contexts where the temp function cannot be created. The scoped branch embeds the estimated select via `literal()` instead of legacy's apostrophe-only escaping, so it stays correct under `standard_conforming_strings = off`. `enforceExactCount` unchanged. **Studio:** - The flag decision is contained in the data layer instead of prop-drilled: a small imperative accessor (`apps/studio/data/scoped-introspection.ts`) is hydrated from `useFlag` via a one-line `useSyncScopedIntrospection()` call in `DefaultLayout`, and the query functions read it internally when building the pg-meta SQL. `DefaultLayout` is shared by both the Next and TanStack router trees; hydrating from `_app.tsx` alone would leave TanStack-served pages permanently unscoped since `routes/__root.tsx` mounts its own flag provider. Cold loads cannot race the flag: the query functions await a readiness promise that resolves only after the sync hook has hydrated the accessor with a loaded flag store (immediately on self-hosted where flags are disabled; a 5s safety net armed lazily on the first `ready()` call - not at module import, which would let the timer expire before a project page ever mounts - bounds genuine ConfigCat outages). No component threading, no query-key changes (remaining tradeoff, documented in the module: a mid-session flag flip can serve stale-keyed caches until refetch, fine for a session-stable rollout flag). #47894's existing threading is left as-is and gets deleted together with the flag in the cleanup PR. Also fixes the previously-missing `scoped` pass-through in `getTableRowsCount`. - Flag-independent hardening: `useTableQuery` now sets `retryOnMount: false`, `refetchOnWindowFocus: false` and `staleTime: 5min`. Errored (timed-out) queries no longer refire on every grid cell remount, while stale successful metadata still revalidates on mount after `staleTime`. - `useTableApiAccessQuery` now passes `includedSchemas: [schemaName]`; the client-side filter stays as a safety net. - The rows-count query is `enabled`-gated on the permission check settling, so a transiently-false `canSQLAdminWrite` can no longer cache a read-only `-1` count for a writable user (read replicas short-circuit synchronously as before). **Regression guards (extending the #47894 infrastructure):** - Execution-based scoped-vs-legacy equivalence tests for all four queries: both variants run against the test database and are compared with raw `toEqual` - no normalization, ids included (types across 6 option combos, privileges incl. multi-grantee + PUBLIC, `tables.retrieve` for both identifier branches, row counts for every case where the two paths must agree). Two documented exceptions where only the LEGACY side is sorted, because a de-normalized diagnostic run proved legacy emits genuinely plan-dependent order there (an adversarial-FK fixture shows it is neither oid, name, nor creation order): the `types.list` outer row order (scoped adds `order by t.oid`; legacy has no ORDER BY) and the `tables.retrieve` relationships array (scoped orders by `constraint_name` + column-name tie-breakers - a composite two-column FK expands to 4 entries sharing one constraint_name). Everything else (privileges via `aclexplode` over the same relacl, columns by `ordinal_position`, primary keys by `indkey` order, enums by `enumsortorder`) is byte-identical between the two paths with no test-side help. The one intentional value divergence, never-analyzed tables above the size gate where legacy's exact count is the timeout bug itself, is asserted explicitly as a divergence. - Plan-guard budgets for every scoped query against the stress catalog (extended with 200 enums + 200 composite types). Residual seq scans are justified in-budget: `pg_constraint` max 2 (no index on `confrelid`), `pg_attrdef` max 1, `pg_authid` max 2 (scales with role count, not schema count). - Legacy templates carry a FROZEN do-not-edit marker (they must keep matching production behavior until the flag cleanup deletes them); the ordinary test suite runs against the legacy default, so behavioral drift there fails regular tests. ### Validation - pg-meta: typecheck clean; the affected suites (types, table-privileges, tables, rows-count, catalog-plan-guard) pass in full. - Cross-version: the scoped-vs-legacy equivalence and rows-count behavioral suites were validated on PostgreSQL 14, 15, and 17 (identical results on all three). Two version-marginal planner choices surfaced on 17 (`pg_type` / `pg_class` seq scan vs full-index bitmap for per-schema listings, both structurally unavoidable without an index leading on the namespace column) and are carried as justified plan-guard budget entries. A full 468-test suite run sequentially: 452 passed, 16 failures verified environmental (13 timeouts in an untouched file that passes 27/27 in isolation on the marathon-run cluster, 3 cluster-global role collisions from container reuse). - Studio: `pnpm --filter studio typecheck` clean; 39/39 tests across the touched data hooks; eslint clean on touched files. ### Rollout Same staged ConfigCat rollout as #47894 via `pgMetaScopedIntrospection` (user-email targeting first, then percentage, then 100%). The `useTableQuery` hardening and the API-access schema scoping ship unflagged (behavior-safe). Gate before percentage rollout: functionally verify the FK popover/selector UX under the new `staleTime`/`retryOnMount` settings (a just-edited FK target must not look stale anywhere Studio does not already refetch on save). Once fully rolled out, the legacy templates and flag get deleted together with #47894's in one cleanup PR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
ddd0f3e8d8 |
feat(www): update Grafana Cloud blog post authors (#48284)
## 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? Content update — updates the author byline on an existing blog post (`apps/www`). ## What is the current behavior? The "Observability for every Supabase project with Grafana Cloud" post lists a single author (`raminder_singh`). ## What is the new behavior? Updates the byline to the three authors credited in the source doc: Alex Hall, Matt Linkous, and Raminder Singh. - Adds a new `authors.json` entry for `alex_hall` (GitHub `alexhall`, Engineering) - `matt_linkous` and `raminder_singh` already existed - Updates the post frontmatter: `author: alex_hall, matt_linkous, raminder_singh` ## Additional context - Source doc: [Notion](https://app.notion.com/p/supabase/Blog-Post-Grafana-Cloud-Partner-drop-3455004b775f8108935feefecd87623f) - Follow-up to #47716 (the original post, already merged) - Pre-flight: Prettier passes; `authors.json` is valid JSON <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated the Grafana Cloud observability blog post to credit all contributing authors. * Added an author profile for Alex Hall, including their role and profile details. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4b24cf028a |
chore(claude): improve CLAUDE.md files and skill triggering (#48261)
Improves the repo's agent guidance: distills the always-required `studio-best-practices` skill into `apps/studio/CLAUDE.md`, tunes every skill description for reliable triggering, and mechanically enforces the generated-files rule. Grounded in Anthropic's official CLAUDE.md guidance (see justifications below). ## The main change: Studio CLAUDE.md gets a Code style section **Why:** `studio-best-practices` was a skill that instructed agents to *always* load it before any Studio code work. Anthropic's guidance draws the line as: sometimes-relevant guidance → skill (loaded on demand); always-relevant guidance → CLAUDE.md. A skill that must always load has failed the test for being a skill — it costs a tool-call round trip and, worse, silently does nothing in sessions that forget to load it. Since `apps/studio/CLAUDE.md` is lazy-loaded only when an agent touches Studio files, inlining is properly scoped: non-Studio sessions never pay for it. **Why not verbatim:** the skill was 175 lines, mostly ❌/✅ worked examples teaching practices models already know. Inlining it whole would push the file past the ~200-line point where Anthropic warns rules start getting lost. Instead each section was distilled to the rule it exists to enforce — e.g. the loading/error/success section kept its code block because the *shape* (early returns at top level, flat `&&` chains inline) is the prescription, and prose loses it. **The framing that makes the generic rules earn their place:** models default to matching surrounding code, and not all existing Studio code follows these practices. The section opens with "older Studio code predates some of these conventions — follow them rather than mirroring nearby legacy patterns," which converts otherwise-redundant React advice into an explicit instruction to break from local precedent. One rule was added that the old skill lacked: `useEffect` is for external-system sync only (~364 Studio files contain effects, many in patterns we don't want copied). **Changed:** - `apps/studio/CLAUDE.md` — new Code style section (84 lines total, within budget); skills table no longer mandates a pre-load - `.claude/CLAUDE.md` — dropped `pnpm install` from commands (guessable; Anthropic's test: "would removing this cause mistakes?") **Removed:** - `.claude/skills/studio-best-practices/` — fully absorbed; its cross-references to other skills were already covered by the skills routing table ## Skill description tuning Descriptions are the only signal an agent sees before deciding to load a skill, and the observed failure mode is under-triggering on tasks that don't name the skill. Nine descriptions reworded: front-loaded matchable keywords, added incidental-trigger cases (e.g. a new feature that adds copy is a `copywriting` moment), and disambiguated overlaps (`vitest` is now the API reference deferring to `studio-testing` for strategy). The `safe-sql-execution` rewrite was additionally validated with skill-creator's trigger-eval loop against 20 realistic queries: held-out test accuracy 54% → 71%, with zero false triggers across all iterations. (`vitest` shows under `.agents/` because `.claude/skills/vitest` symlinks there.) ## Generated-files enforcement **Added:** `permissions.deny` rules in `.claude/settings.json` for the six generated-file globs the root CLAUDE.md already lists. CLAUDE.md prose is advisory; permission rules are mechanical and also gate sandboxed Bash writes. (Verified live: the rule blocked an unintended regeneration of `database-types.ts` during testing.) ## To test - CI: prettier + typos checks pass (docs-only + settings change, no app code) - In a fresh Claude Code session in the repo: ask it to edit `apps/studio/routeTree.gen.ts` — should be denied by the new permission rule - Ask it to do any Studio UI task — it should pick up the Code style rules from `apps/studio/CLAUDE.md` without loading a best-practices skill <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated development guidance for testing, copywriting, SQL safety, telemetry, queries, error handling, and toolbar reviews. * Restructured Vitest references into clearer tables and improved formatting across several guides. * Added Studio code-style conventions and clarified when task-specific guidance should be applied. * Removed outdated Studio best-practices guidance. * **Chores** * Added safeguards preventing edits to generated and protected files. * Simplified the documented development command sequence. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
7f42765070 |
Joshen/fe 3983 no way to create a new project in vercel integration when (#48230)
## Context For the Vercel integration flow (e.g "Deploy with Vercel" button on GH) If an organization has no projects, there currently isn't a way to create a project and connect it in the same session - users can only hit "Skip". This addresses that by directing users to the /deploy-button/new-project route in this scenario <img width="505" height="539" alt="image" src="https://github.com/user-attachments/assets/6cc85030-42c7-4e58-b4b3-cb8ac0f5da9e" /> ## Other changes involved - Also separates `ProjectLinker` into smaller components - preference for avoiding declaration of components within a component ## To test I'm not sure if this can be tested on staging to be honest, but otherwise we can give it a go on production after the changes are through, as this doesn't change any existing logic to the usual "Connect project" flow I did try clicking the "Deploy with Vercel" button on a repo, and just changing the URL to the staging URL at the Supabase step - seems to work <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary * **UI Improvements** * Streamlined the Vercel/GitHub project-linking step while keeping the same create/connect/skip flow, including the searchable project picker, branding/status indicators, and the feature-flagged “create new project” option. * On the Vercel choose-project step, the default selection now reflects the current project context. * **Bug Fixes / Tests** * Improved Vercel install routing query handling to preserve deploy-button configuration when present, with updated automated test coverage. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com> |
||
|
|
d0e781a960 |
Allow users to continue with org if integration installed (#48231)
## Context For the Vercel integration, if the source is marketplace, currently selecting an organization that already has the integration installed prevents the user from proceeding. <img width="267" height="172" alt="image" src="https://github.com/user-attachments/assets/ba3aafa0-f753-4797-89cd-a7f1e16bbdb2" /> Whereas users should just be able to proceed and select a project from within the organization <img width="435" height="226" alt="image" src="https://github.com/user-attachments/assets/e659bc20-6980-4ef2-af5c-8612af99668b" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Enhanced the Vercel integration installation flow with dynamic primary button text (“Continue” vs “Install integration”) based on installation status. * **Bug Fixes** * Updated the install button so it no longer disables when the selected organization already has the Vercel marketplace integration installed. * Removed the “already installed” warning from the main render path. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com> |
||
|
|
e0ecaadc21 |
docs: make AI tools section agent-first (#48167)
## 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? This PR reworks the `/guides/ai-tools` docs section to be agent-first. The overview now leads with the fastest path to a working setup (the plugin install command), a "What's supported?" card grid showing which coding agents and IDEs work via Plugin and/or MCP (with each product's own tagline, not a generated sentence), and a concepts glossary — instead of a plain four-item list. The sidebar "AI Tools" widget, shown on every guides page, now links to this hub ("Connect your AI agent") instead of opening a ChatGPT/Claude chat frontend. Closes DOCS-1201. ## What is the current behavior? - The `/guides/ai-tools` overview is a plain four-item bullet list with no getting-started path, compatibility info, or concepts explanation. - The sidebar "AI Tools" widget offers "Copy as Markdown", "Ask ChatGPT", and "Ask Claude" — the latter two send you to a chat frontend instead of agent setup. ## What is the new behavior? - `ai-tools.mdx`: intro → plugin install callout → "What's supported?" card grid (`<ContentListings id="ai-tools-supported-agents" />`, icon + tagline + Plugin/MCP badge per agent) → "Key concepts" glossary → "Building AI into your app?" (also converted to `ContentListings`). - New `data/content-listings/ai-tools.data.ts` builds the card grid from the existing `PLUGIN_CLIENTS`/`MCP_CLIENT_DATA` client lists (no new hand-maintained data) — fixing two latent bugs found along the way: GitHub Copilot was keyed differently between the two sources (would have produced duplicate cards), and Windsurf has no upstream docs URL (would have been silently dropped). - New opt-in `badgePosition` field on `ContentListingItem` so the badge renders under the title for the agent grid, without changing the one other existing badge usage (self-hosting's "Official" tag, still inline). - `plugins.mdx`/`mcp.mdx`/`ai-skills.mdx` each get a one-line "Quick start" lead-in so they stand alone via the `.md` content-negotiation route. - `GuidesSidebar.tsx` + `telemetry-constants.ts`: Added "Connect your AI agent" → `/guides/ai-tools`, and the `ask_ai_clicked` event with `agent_setup_clicked`. - Accessibility fix (from review): the "Not supported" indicator now exposes an `sr-only` label instead of being fully `aria-hidden`. ## Additional context - Worktree: `~/GitHub/supabase/supabase-worktrees/nikrichers/docs-1201-make-guidesai-tools-agent-first-and-replace-chat-frontend` - **Open question — Windsurf card**: `windsurf.com` now redirects to a Devin Desktop page (Cognition acquired Windsurf in 2025), but Supabase's own `MCP_CLIENT_DATA` still targets Windsurf's distinct config path (`~/.codeium/windsurf/mcp_config.json`), so the card is still labeled "Windsurf" with its pre-acquisition tagline ("The first agentic IDE. Tomorrow's editor, today."). Needs a follow-up decision on whether to relabel/merge/drop this card once Devin Desktop's MCP support (if any) is confirmed. - Follow-up (not in this PR): deeper IA rework of the ai-tools section belongs to the broader agent-first audit; `content/guides/resources/glossary.mdx` has no MCP/Agent Skills/Plugin/Prompts entries yet — this PR's "Key concepts" is currently the only definition of these terms site-wide. - Verification: | Check | Result | | --- | --- | | Lint (`lint:mdx`, `eslint`), `typecheck`, `test:local lib/content-listings.test.ts` | Pass — 13/13 tests, 0 errors | | `build:guides-markdown` | Pass — card grid flattens cleanly to markdown | | Playwright: broken icon requests, light + dark theme, PR preview | Pass — 0 in either theme | | `/guides/self-hosting` "Official" badge (existing `ContentListings` usage) | Pass — unaffected by the new `badgePosition` opt-in | ### Before & After #### [`/guides/ai-tools`](https://supabase.com/docs/guides/ai-tools) Also shows the sidebar change (right rail): "Ask ChatGPT" / "Ask Claude" → "Connect your AI agent". | [Before](https://supabase.com/docs/guides/ai-tools) | [After](https://docs-git-nikrichers-docs-1201-make-guidesai-too-7c7493-supabase.vercel.app/docs/guides/ai-tools) | | --- | --- | |  |  | Sub-pages each just add a one-line "Quick start" callout under the intro (no other layout change): [plugins](https://supabase.com/docs/guides/ai-tools/plugins) ([preview](https://docs-git-nikrichers-docs-1201-make-guidesai-too-7c7493-supabase.vercel.app/docs/guides/ai-tools/plugins)) · [mcp](https://supabase.com/docs/guides/ai-tools/mcp) ([preview](https://docs-git-nikrichers-docs-1201-make-guidesai-too-7c7493-supabase.vercel.app/docs/guides/ai-tools/mcp)) · [ai-skills](https://supabase.com/docs/guides/ai-tools/ai-skills) ([preview](https://docs-git-nikrichers-docs-1201-make-guidesai-too-7c7493-supabase.vercel.app/docs/guides/ai-tools/ai-skills)). ### Test plan - [x] `/guides/ai-tools` renders callout → card grid → concepts → Building AI into your app, in order - [x] Card grid: one card per agent (no duplicate Copilot), Windsurf present, icons clean in both themes, taglines shown, badges below title - [x] Sidebar shows "Connect your AI agent"; self-hosting's "Official" badge unaffected - [x] `.md` route still serves clean markdown; no lingering `ask_ai_clicked`, ChatGPT/Claude icon, or `SupportedAgentsTable` references --------- Co-authored-by: Nik Richers <nik@validmind.ai> |
||
|
|
f653600517 |
fix(studio): make failed Postgres upgrade banner dismissible (#48260)
- The failed-upgrade banner reflects the API's last-known upgrade status, which stays "Failed" indefinitely even after a project is restored, so it never went away - A hard refresh didn't help, since this isn't client-cached state - Adds a dismiss action, scoped to the attempt's `initiated_at` so a future failed upgrade still shows the banner Fixes FE-3964 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a dismiss control to project upgrade failure notifications. * Dismissed notifications remain hidden for the current project until a new upgrade failure occurs. * Contact support remains available alongside the dismiss option. * **Bug Fixes** * Improved upgrade failure banner behavior by persisting dismissal state across page visits. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b6e574e5cd |
fix(www): stop on-demand mdx events from winning the events marquee (#48264)
## 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 — the [events index](https://supabase.com/events) was featuring the TRAE webinar in its marquee days after the event happened, instead of the next genuinely upcoming event (the Dublin meetup), and counting it toward the "Webinar" filter chip alongside actually-upcoming webinars. ## What is the current behavior? `getMdxEvents()` in `lib/events.ts` only excludes past events by comparing dates against the start of today in UTC. It doesn't check `onDemand` at all. The TRAE event's timestamp (`2026-07-22T19:00:00.000-07:00`) converts to `2026-07-23T02:00:00Z`, which is still "today or later" by that UTC cutoff — so even though the event already happened and flipped to `onDemand: true`, it kept getting returned as an "upcoming" event. Since the events marquee (`featuredEvent`) just picks the earliest-dated event from that pool, TRAE kept winning over the actually-upcoming Dublin meetup, and it kept counting toward the "Webinar" filter chip. ## What is the new behavior? `getMdxEvents()` now excludes any event with `onDemand: true` outright, regardless of how its date converts across timezones — on-demand events belong solely in the on-demand bucket (`getOnDemandMdxEvents`), not the upcoming/marquee pool. Verified locally: the "Webinar" filter chip count on `/events` drops to 0 with this in place (previously counted TRAE), while the TRAE event's card in the on-demand list still correctly shows its "Webinar" tag and "Supabase Live" line, matching the other on-demand webinars (Perplexity, Datadog) — only its bucket assignment changed, not its labeling. ## Additional context Couldn't verify the marquee itself locally since the Luma events API returns a 500 in local dev (missing credentials, pre-existing/unrelated to this change). Confirmed independently via the production Luma API that the Dublin meetup (`2026-07-28T17:00:00Z`) is genuinely the next chronological event, so it will naturally take over the marquee once this ships — no hardcoding needed. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * On-demand events are no longer shown in the upcoming events list. * Upcoming events continue to be filtered by their relevant date, while on-demand event listings remain unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8252b69b6a |
feat(www): convert TRAE webinar page to on-demand (#48225)
## 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 — converts the TRAE webinar event page to its on-demand version and adds a small template enhancement to support a custom type label. ## What is the current behavior? The [TRAE webinar page](https://supabase.com/events/supabase-trae-high-quality-apps) is set up as a live, upcoming event: `onDemand: false`, a registration CTA linking out to GoToWebinar, and copy written in the future tense ("What we'll cover"). The shared event page template (`pages/events/[slug].tsx`) always renders the raw `type` frontmatter value (e.g. "WEBINAR") as the label at the top of the page, with no way to override it. ## What is the new behavior? - Flips `onDemand` to `true` and swaps the `main_cta` from the GoToWebinar registration link to a `#recording` anchor labeled "Watch the recording", matching the pattern used for the Bolt and Perplexity webinars once they went on-demand. - Adds a `video-container` iframe placeholder (`id="recording"`) below the intro copy. The `src` is intentionally left empty with a `TODO` comment — neither the Bolt nor Perplexity on-demand pages expose the recording URL in frontmatter, it's a hardcoded YouTube embed URL in the MDX body, so this needs the real embed URL dropped in before merging. - Replaces the "What we'll cover" section with updated "Key Takeaways" copy and a closing line ("We hope you enjoy the recording!"). - Adds an optional `type_label` frontmatter field to the event page template. When set, it renders in place of the raw `type` value at the top of the page; when unset, behavior is unchanged for every other event page. Used here to show "Supabase Live" instead of "WEBINAR". ## Additional context Verified locally in preview: - TRAE event page renders correctly with the new CTA, video placeholder, updated copy, and "SUPABASE LIVE" label. - Other event pages (e.g. `enterprise-innovation-with-bolt`) are unaffected and still show their original type label, confirming the `type_label` change is backward compatible. Still needed before merging: the actual recording embed URL in the iframe `src`. |
||
|
|
312d05af4b |
fix(www): changelog frontmatter (#48249)
## 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? Security/bug fix ## What is the current behavior? The changelog entry parser exposes all YAML frontmatter fields parsed by `matter()` directly to the client via Next.js props. This includes private fields like `internal:` (escalation teams, notes) and `reviewers:`, which get serialized into the page's `__NEXT_DATA__` and are visible in View Source even if never rendered. ## What is the new behavior? - Added `PUBLIC_FRONTMATTER_KEYS` constant that explicitly allowlists only the fields safe to expose to the browser - Added `toPublicFrontmatter()` function that filters frontmatter down to the allowlist, dropping `internal:`, `reviewers:`, and any other private keys - Updated `parseChangelogEntryFile()` to apply the allowlist before returning frontmatter to callers - Added comprehensive unit tests covering both the filtering logic and the integration with the parser This uses an allowlist approach rather than a denylist, so new private fields added upstream won't silently leak to clients. ## Additional context The allowlist is kept in sync with `ChangelogEntryFrontmatter` in `changelog-repo.ts` per the code comment. Tests verify that: - Only allowlisted keys are present in the returned frontmatter - Private fields like `internal` and `reviewers` are never exposed - Public fields flow through untouched - Undefined values are omitted from the result https://claude.ai/code/session_017uSmnCLsskFYR7YH8DKGkr <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a shared changelog title renderer that safely displays titles as inline Markdown. * Added plain-text title extraction for consistent headings and SEO metadata. * **Bug Fixes** * Prevented private/internal changelog frontmatter (including reviewer metadata) from being exposed to browser-rendered pages. * Ensured featured and non-featured changelog timelines stay consistent even when some entries fail to serialize. * Improved the changelog detail not-found behavior to revalidate instead of caching 404s indefinitely. * **Tests** * Added coverage for public frontmatter allowlisting, date normalization (`publish_date`/sorting), and `sortDate` consistency across YAML variations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Lukas Bernert <lukas@bernert.at> |
||
|
|
7781ee0d04 |
fix(studio): correct realtime settings UI limits to match backend (#48253)
Realtime settings validation in Studio didn't match the backend's actual limits: - \`max_presence_events_per_second\` allowed up to 10000 (backend caps at 5000), - \`max_payload_size_in_kb\` allowed up to 3000 (backend caps at 10000) - \`max_events_per_second\` allowed up to 10000 (backend caps at 50000). Updated the Zod schema limits in both branches of the form's discriminated union to match. Fixes FE-3991 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Increased the allowed limits for realtime event throughput, presence events, and payload size settings. * Administrators can now configure higher-capacity realtime workloads, including payloads up to 10,000 KB. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e6ad56101f |
fix: MFA list Added on value uses last_challenged_at instead of created_at (#48252)
Fixes FE-3985. `TOTPFactors` was displaying `updated_at` (which mirrors `last_challenged_at`) for "Added on" instead of `created_at`. |
||
|
|
3effea71aa |
feat(www): add Grafana Cloud partner drop blog post (#47716)
## 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? Launch blog post - Grafana! ## What is the current behavior? Nonexistent 😆 ## What is the new behavior? Adds the "Observability for every Supabase project with Grafana Cloud" partner drop post, announcing the one-click Grafana Cloud integration. - Post: [`apps/www/_blog/2026-07-23-observability-for-every-supabase-project-with-grafana-cloud.mdx`](https://github.com/supabase/supabase/blob/blog/grafana-cloud-partner-drop/apps/www/_blog/2026-07-23-observability-for-every-supabase-project-with-grafana-cloud.mdx) - Images: `apps/www/public/images/blog/observability-for-every-supabase-project-with-grafana-cloud/` (og + thumb) - Author: `raminder_singh` · Date: 2026-07-23 · Category: product - Includes the YouTube walkthrough embed and UTM-tagged dashboard links <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a blog post announcing one-click Grafana Cloud observability integration for Supabase projects. * Highlights include preconfigured authentication, metric scraping, and dashboards available on all plans, including free. * Documents dashboard portability, Metrics API usage, setup instructions, and upcoming log support. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4272aba4b1 | fix: Update Grafana Cloud integration guides (#47776) | ||
|
|
8108528682 |
Fix: Update the auth user field in the Logs page (#48237)
- Fix the user filter to work with `edge_logs`. - Update the `auth_user` field to be derived from other log attributes. - Removed filtering for `postgres_logs` since it didn't really filter by user actions, only by user id mentions. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved unified logs user filtering to rely only on exact attribution identifiers from authentication and edge log sources, removing partial message-based matching. - Updated unified logs user identification by deriving `auth_user` from authentication actor IDs or edge JWT subject values. - Refined “user filter reachability” logic to consider only attributable log types (auth and edge). - **Tests** - Adjusted unified logs query tests to match the updated attribution routing and reachability outcomes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
efc0ad3fce |
fix: fix migration dialog does not show the correct content in some edge cases (#48239)
## Problem When two projects have migrations with the same version but different content, the details panel does not update the content and shows the first loaded migration one. ## Solution This is because the CodeEditor does not react to content only changes. Settings its `key` ensures it does. Unfortunately, we can't unit test that the CodeEditor content changes correctly. ## How to test - create two projects and push a migration with the same version but different content on them - open the _Database/Migrations_ page for the first project - click the _View migration SQL_ and ensure its content matches the migration for this project - select the other project using the top bar - click the _View migration SQL_ and ensure its content matches the migration for this project <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved migration SQL display when switching between migrations or projects. * Ensured the code editor consistently refreshes with the currently selected migration’s statements. * Improved type safety for the migration search input. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d900c09e8a |
chore(studio): grafana-cloud slug (#48238)
Use `grafana-cloud` slug for the partner integration. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Grafana Cloud to the featured integrations in the marketplace. * Added light and dark themed artwork for the Grafana Cloud featured integration. * **Improvements** * Updated the OAuth “installed” detection to include Grafana Cloud alongside Grafana. * Included Grafana Cloud in the set of official partners for the partner-only filter. * **Tests** * Expanded marketplace integration fixtures to cover Grafana Cloud scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7c20cc574c |
feat(www): new changelog sync (#47880)
## What kind of change does this PR introduce? Sync changelog from private supabase/changelog. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Changelog entries now come from the structured changelog repository. * Added filters for change type, product stage, and self-hosted impact. * Updated badge UI for affected products and change types with filter links. * Changelog detail sidebar now shows lifecycle stage, sunset dates, and self-hosted impact (when available). * **Improvements** * Product category discovery and filtering now use affected products. * Discussion links show only when legacy discussion data is present. * RSS feeds and generated changelog markdown now use the updated metadata. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
fbf7ce44ef |
[FE-3544] fix(studio): role impersonation for truncated cell loads (#48215)
Loading a truncated cell's full value from the inline grid editors or the row side-panel editors called `getCellValue` without `roleImpersonationState`, so the fetch ran with full DB privileges instead of the role selected in **View as role** — leaking values RLS would deny. Same class of bug #46442 fixed for row copy/export; the mutation already accepted the state, these call sites just weren't passing it. **Changed:** - Pass `roleImpersonationState` into `getCellValue` in all 4 truncated-cell loaders (inline grid Text/Json editors + row side-panel Text/Json editors), mirroring the existing `Header.tsx` pattern **Added:** - MSW component test on the row side-panel `TextEditor` asserting the cell-value SQL is wrapped with `set local role` when impersonation is active, and not wrapped when it isn't ## To test Note: if the impersonated role can't select the row at all (e.g. force RLS with no policy), the main grid correctly shows 0 rows under **View as role**, so the "Load full value" button is never reachable — you can't exercise this path that way. Use a row the role *can* see and verify the request is role-wrapped: - Create a table with a text value long enough to be truncated in the grid (>16KB), with RLS enabled and an anon-visible row: ```sql create table public.secrets (id int primary key, secret text); alter table public.secrets enable row level security; alter table public.secrets force row level security; create policy "anon can read" on public.secrets for select to anon using (true); insert into public.secrets values (1, repeat('a', 20000)); ``` - In the Table Editor, set **View as role → anon** — the row should be visible with the `secret` cell truncated - With the network tab open, load the full value via each path: double-click the cell (inline editor) and the row side panel's expand editor → "Load full text data" (a `jsonb` column exercises the two JSON editor paths the same way) - The `pg-meta` query request body should start with `set_config('role', 'anon', true)` + anon JWT claims before the `select secret …`. Before this fix it was a bare unwrapped `select secret from public.secrets where id = 1;` - Drop the policy and confirm the grid shows 0 records under anon (denial still applies at the grid level); switch back to the default role and confirm the full value still loads normally with no wrapper Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
3121841863 |
[FE-2271] fix: correct stale email confirmation dashboard paths (#48228)
Users were getting AI-generated troubleshooting steps pointing at **Authentication → Settings → Sign up → "Enable email confirmations"** — a dashboard path that no longer exists (FE-2271). The guidance comes from external LLMs trained on stale supabase.com content: two 2022 blog tutorials contain that exact phrasing. The real toggle is **Authentication → Sign In / Providers → User Signups → "Confirm email"**. **Changed:** - Updated the Flutter chat and Angular Trello blog tutorials to point at the current toggle location (and removed screenshots of the old UI) - Repointed the legacy `/project/:ref/auth/settings` redirect from `/auth/users` to `/auth/providers`, so anyone following stale instructions lands on the page that actually has the auth config ## To test - Visit `/project/<ref>/auth/settings` in Studio — it should redirect to `/project/<ref>/auth/providers` (verified locally on both the redirect and the existing `redirects.shared.test.ts` suite) - Check the two blog posts render correctly and the dashboard deep link opens Sign In / Providers <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Updated authentication settings redirects so project settings pages now open the correct sign-in and provider configuration page. - **Documentation** - Updated Flutter and Angular tutorial instructions for disabling email confirmation. - Added current navigation guidance and clarified where to turn off the **Confirm email** option. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
e3fdfc9c15 |
docs(telemetry): make the Logs Explorer docs ClickHouse-focused (#47914)
Makes the Logs Explorer query docs ClickHouse-focused. The Logs Explorer runs on ClickHouse (default since June 2026): a single `logs` table tagged by `source`, with nested fields in a `log_attributes` map. This rewrites `## Querying with the Logs Explorer` to document only that model: - ClickHouse query mechanics (`log_attributes['...']` access, `toInt32OrZero`, `count()`), with example queries and the "don't guess keys" guidance - The old BigQuery `cross join unnest(metadata)` section (timestamp/unnesting/examples) is removed; a short note flags that BigQuery is deprecated - Best practices and the field reference reworded for ClickHouse No dead anchors: the only repo reference to an `#unnesting-arrays` anchor points at `advanced-log-filtering`, which is untouched. Supersedes the earlier two-engine version on this branch. Skill side (agent-skills#112) already points here as the single source for log querying. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated Logs Explorer guides to use ClickHouse as the default query engine. * Added guidance for querying the unified `logs` table and accessing structured fields. * Added examples for filtering errors, SQLSTATE codes, numeric values, and regular expressions. * Documented how to discover available log fields and clarified MCP log-query behavior. * Updated best practices and field references to reflect the current log structure. * **Chores** * Added SQLSTATE and substring terms to the documentation spelling allow-list. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
52030a88fe |
chore(studio): proper grafana light-mode image (#48232)
Use a real light-mode grafana dashboard rather than an inverted dark mode one. <img width="888" height="287" alt="Screenshot 2026-07-23 at 09 45 45" src="https://github.com/user-attachments/assets/f37a6950-19eb-4edc-b59d-fd48681874dd" /> |
||
|
|
63e2eb3ca6 |
Joshen/fe 3971 blocked by visualization (#48187)
## Context Improving the "blocked by" visualisation for database connections - to accommodate the situation whereby there might be a chain of blocked process. Intention is so that users can identify whats the root process that's blocking everything - and from there decide if they want to terminate the process or not. Also brings `ActivityRow` out into its separate file since `Activity` is getting big <img width="473" height="299" alt="image" src="https://github.com/user-attachments/assets/21d0d223-5dbd-49d5-877c-815c78cb7482" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Streamlined the database activity view by separating the single-row rendering into its own component, keeping the same end-user experience (status badge, query/“No query”, duration warnings, blocking details, PID copy, and actions). * Kept “Terminate” behind confirmation prompts and preserved role-based restrictions for when termination is available. * **Improvements** * Standardized how activity durations are calculated and how status badges are styled for consistent display. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b76d04d6a0 |
fix: read FGA permissions from openapi spec x-fga-permissions extension (#48181)
## 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? Follow up to https://github.com/supabase/platform/pull/35940, which moved FGA permissions off security and onto the `x-fga-permissions` extension. This updates the docs reference component to read from the new field. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * API documentation now supports displaying fine-grained access permissions for endpoints. * Endpoint security details are presented more consistently using the documented permissions configuration. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3bca21b3f8 |
chore(a11y): convert leftover focus recipes to focus-ring (#48219)
## What kind of change does this PR introduce? Accessibility cleanup (DEPR-628). ## What is the current behavior? Leftover call sites still use ad-hoc focus recipes (`ring-foreground-muted`, `outline-brand`, Dialog/Sheet `focus:` rings, etc.) instead of the shared utilities from #41575. ## What is the new behavior? Converts those leftovers across `packages/ui`, Studio, www, docs, and design-system to `focus-ring`, preferring `focus-visible`. Keeps documented exceptions (`group-focus-visible`, InputGroup `:has()`). ## To test Tab through controls (keyboard only). Expect a consistent offset ring on `:focus-visible`, not a green/brand/custom stack, and no ring animation. ### www (marketing) Preview: https://zone-www-dot-com-git-danny-depr-628-focus-ring-fbccf9-supabase.vercel.app - Global nav on `/`: Product, Developers, Solutions dropdowns; logo; hamburger + mobile menu - `/features`: view toggles and feature cards - `/company`: card links - `/changelog`: timeline / entry links - `/partners/catalog`: grid/list toggle and partner cards - `/pricing`: compute section expand control - Product / Modules / Solutions sticky navs on product pages (e.g. `/database`, `/storage`) - `/state-of-startups`: TwoOptionToggle if present ### docs Preview: https://docs-git-danny-depr-628-focus-ring-long-tail-supabase.vercel.app - Any guide page: top nav dropdowns and items - Narrow viewport: hamburger, then mobile menu links + close - Guide with PromptPanel / tabs: tab to prompt actions and tab list ### studio (dashboard) Preview: https://studio-staging-git-danny-depr-628-focus-ring-long-tail-supabase.vercel.app - Project home: Connect section tiles; drag-handle focus on sortable sections - Integrations marketplace (`/project/<ref>/integrations`): featured cards, list/grid toggle, list rows - Auth (`/project/<ref>/auth/oauth-apps`, `/project/<ref>/auth/providers`): open create/edit sheet, tab to close (X) - Database policies (`/project/<ref>/database/policies`): open policy editor sheet, tab to close - Storage policies (`/project/<ref>/storage/files/policies`): bucket section links; policy modal close - Query performance (`/project/<ref>/observability/query-performance`): info icon buttons on metrics - Replication pipeline detail (if available): slot lag / status info icons - Support (`/support/new`): attachment add/remove controls - Table editor: spreadsheet import preview checkboxes; row text/JSON editor TwoOptionToggle - Any Dialog/Sheet/toast close (X): ring on keyboard focus only, not mouse click ### design-system Preview: https://design-system-git-danny-depr-628-focus-ring-long-tail-supabase.vercel.app - Colour palette swatches (keyboard focus) - Form patterns sidepanel example: avatar / focusable control in the example ## Additional context - Linear: [DEPR-628](https://linear.app/supabase/issue/DEPR-628) - Follow-ups: form-group CSS (DEPR-629), Storage columns selection (DEPR-630), ESLint rule (DEPR-632) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Accessibility & Usability** * Standardized keyboard focus indicators across navigation, dialogs, forms, buttons, toggles, links, and tooltips using a consolidated focus style. * Improved toggle controls to use proper button semantics (instead of clickable text), including `aria-pressed`/disabled handling and better keyboard navigation. * **Visual Updates** * Harmonized hover/focus ring visuals across the design system, Studio, documentation, and marketing pages while preserving existing layout and interaction behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0bef8e7d90 |
test(sql-editor): e2e coverage + delete jsdom test + merge Results.utils tests (Steps 5-6) (#48217)
## Summary Steps 5 and 6 of the SQL editor test refactor plan (the final two steps). **Step 5** — extends `e2e/studio/features/sql-editor.spec.ts` (real browser, zero mocks) with cases that need the real Monaco editor / full app render: - destructive-query warning modal: confirm actually re-runs the forced query (previously only `Cancel` was exercised) - debug button opens the AI Assistant with the query error pre-filled Deletes `apps/studio/tests/components/SQLEditor/SQLEditor.test.tsx` — its logic-level cases are now covered mock-free by the Step 4 hook tests, and its integration cases by e2e. Deleting rather than narrowing is the honest consequence of "no mocking": every remaining assertion it could make in jsdom requires a Monaco mock. **Step 6** — merges `apps/studio/tests/components/SQLEditor/Results.utils.test.ts` (`formatClipboardValue`/`formatCellValue`) into the colocated `apps/studio/components/interfaces/SQLEditor/UtilityPanel/Results.utils.test.ts` (`formatResults`/`convertResultsToMarkdown`/`convertResultsToJSON`/`getResultsHeaders`/`isLargeValue`/`convertResultsToCSV`) — both tested disjoint exports of the same source file. Deletes the `tests/` copy. This is the last step in the plan. ## Test plan - [x] `pnpm --filter studio typecheck` — no new errors in changed files - [x] `npx prettier --check` on all changed files - [x] Ran the new/changed e2e cases locally end-to-end against a live local stack — both pass - [x] `cd apps/studio && npx vitest run components/interfaces/SQLEditor/UtilityPanel/Results.utils.test.ts` — 42/42 passing after the merge <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added end-to-end coverage for destructive SQL query warning modal flow before forced execution. * Added end-to-end coverage for the AI Assistant debug flow when SQL execution fails. * Expanded unit test coverage for SQL editor results formatting utilities (clipboard and cell value formatting). * Removed the prior SQLEditor unit test suite and the older results-formatting unit tests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e4f75bf74c | chore(studio): update copywriting on integrations pages (#48197) | ||
|
|
ec260a594d |
docs(billing): clarify top-ups do not apply to outstanding invoices (#48220)
### Summary This PR clarifies that credit top-ups apply only to future invoices and cannot be used to pay or adjust outstanding invoices. It updates the Credits FAQ, Billing FAQ, and credit top-up modal with consistent wording. ### Testing #### Credits FAQ https://docs-git-kanishk-billing-2726-update-billing-fa-bd77f2-supabase.vercel.app/docs/guides/platform/credits#credit-faq #### Billing FAQ https://docs-git-kanishk-billing-2726-update-billing-fa-bd77f2-supabase.vercel.app/docs/guides/platform/billing-faq#payments-and-billing-cycle #### Credit Top Up Modal <img width="544" height="473" alt="Screenshot 2026-07-23 at 1 17 30 AM" src="https://github.com/user-attachments/assets/5d016398-7b46-455d-8bf1-a5767d10bc48" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added FAQ guidance explaining that credit top-ups apply only to future invoices and cannot pay or adjust outstanding invoices. * **Billing Updates** * Clarified that credits are granted based on the pre-tax payment amount. * Confirmed that credits are non-refundable and do not expire. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6f6badae51 |
fix(eslint): promote require-explicit-tabindex to error (#48170)
## What kind of change does this PR introduce? Accessibility / lint hardening (Safari keyboard focus). ## What is the current behavior? `supabase/require-explicit-tabindex` is `'warn'`. Studio’s ratchet was at 0 but the rule was still ratcheted; www / docs / design-system still had raw `<button>` / `role="button"` call sites without an explicit `tabIndex`. [DEPR-627](https://linear.app/supabase/issue/DEPR-627) · follow-up to #47984 / #48040 ## What is the new behavior? - Shared config: `'supabase/require-explicit-tabindex': 'error'` - Swept www / docs / design-system (+ Studio test fixtures the ratchet skipped) - Removed the rule from the Studio ratchet + baselines ## To test Prefer **Safari**. This PR only adds explicit `tabIndex` to raw `<button>` / `role="button"` call sites — not links, and not controls that already go through `Button` from `ui`. ### Marketing (`www`) ([staging link](https://zone-www-dot-com-git-danny-depr-627-promote-req-7ae43c-supabase.vercel.app/)) - [x] Homepage frameworks / dashboard feature tabs — Tab through each tab button - [x] Product pages (e.g. `/auth`, `/database`) — section tab switchers - [x] Narrow viewport — open the hamburger; Tab through menu buttons - [x] `/partners/catalog` — filter / view controls - [x] Blog view toggle (list ↔ grid) ### Docs ([staging link](https://docs-git-danny-depr-627-promote-require-explici-25e46d-supabase.vercel.app/)) - [x] **Desktop (≥ lg):** top-right **⋯ menu** (hamburger icon) — opens a dropdown that includes Theme. Not a separate theme button. - [x] **Mobile (< lg):** top-right **hamburger** opens the sheet; close (X) is the raw button we tagged. Theme inside the sheet uses `ThemeToggle` / `DropdownMenuTrigger` from `ui` (already supposed to set `tabIndex`). - [x] **Code blocks** — copy / language controls - [x] **Is this helpful?** — X / check are `Button` from `ui` (should already Tab). After voting **while signed in**, the follow-up “What went well?” / “How can we improve?” text button is the raw one we tagged. - [x] **AI Tools → Copy as Markdown** (right rail on a guide) — this is the only GuidesSidebar control this PR changed. “On this page” TOC items are **links**, not covered by this lint. - [x] **Reference docs** (e.g. JS client reference) — section headers that expand/collapse in the left nav (`Collapsible.Trigger`) - [x] **Troubleshooting index** — type in the search field, then Tab to the **clear (X)** control ### Dashboard (`studio`) No production UI changes in this PR (tests + lint config only). Quick Safari smoke that prior tabindex work still holds: - [x] Project sidebar — Tab through primary nav links - [x] Settings → General — Tab through inputs / buttons - [x] Storage → Files — Tab a bucket row / file actions |
||
|
|
08c4f64c42 |
test(sql-editor): add mock-free hook tests (Step 4) (#48214)
## What Step 4 of the SQL editor testability plan: **mock-free hook tests** for the extracted SQL editor hooks, built on the Step 3 renderHook harness (`tests/lib/sql-editor-test-utils.tsx`) — in-memory editor port + real valtio stores + MSW. **Zero `vi.mock`.** | File | Tests | Covers | |------|-------|--------| | `useSqlEditorExecution.test.tsx` | 8 | destructive-query gating (`potentialIssues` vs. forced run), auto-limit suffixing, connection-string → `x-connection-encrypted` header, `onSuccess`/`onError` session-store writes, error-line highlight, diff-open short-circuit | | `useSqlEditorAi.test.tsx` | 7 | one-shot diff-request drain (empty vs. non-empty editor), drain-exactly-once across remounts, accept/discard diff, `onDebug` opening the assistant chat + debug prompt | | `usePrettifyQuery.test.tsx` | 2 | in-place format + write-back, diff-open no-op | | `useSnippetIdentity.test.tsx` | 2 | generated identity + store-driven loading state | | `useSnippetTitleGenerator.test.tsx` | 2 | untitled-snippet naming via the title endpoint | Every test exercises real dependencies at the seam where they're real: network via MSW, stores used real and reset per test, Monaco via the in-memory editor port. ## Test plan - [x] `pnpm test:studio -- SQLEditor` → **286/286 passing** (21 new tests included) - [x] `pnpm --filter studio typecheck` clean - [x] Confirmed zero `vi.mock` in the new files <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added comprehensive automated coverage for SQL query formatting, snippet identity, and AI-generated titles. * Added coverage for AI-assisted SQL editing, including diff acceptance, rejection, debugging, and request handling. * Added coverage for query execution, result persistence, safety checks, replica selection, error highlighting, and diff-state behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |