Commit Graph
8 Commits
Author SHA1 Message Date
Ali Waseem 61078d2617 chore(studio): add jsx-a11y ESLint ratchet rules for statically-detectable a11y issues (#47582)
## Summary
- Follow-up to the axe-core accessibility audit (FE-3781), which found
1,733 failing elements across 126 Studio surfaces deduplicating to 12
root-cause families. A subset of those (missing accessible names/labels,
invalid/redundant ARIA, empty headings/anchors) is statically detectable
— this adds ESLint coverage for it instead of relying solely on the
runtime axe-core CI gate.
- Adds 13 `jsx-a11y` rules to `apps/studio/eslint.config.cjs` at
`'warn'`: `aria-props`, `aria-proptypes`, `role-supports-aria-props`,
`anchor-has-content`, `control-has-associated-label`
(`controlComponents: ['Button', 'Switch']`),
`label-has-associated-control` (`labelComponents: ['Label']`,
`controlComponents: ['Input', 'Switch']`), `aria-role`,
`no-redundant-roles`, `no-aria-hidden-on-focusable`,
`tabindex-no-positive`, `anchor-is-valid`, `heading-has-content`,
`no-distracting-elements`.
- Wires all 13 into the existing `lint:ratchet` script and initializes
their baselines in `apps/studio/.github/eslint-rule-baselines.json`, so
any *new* violation fails `studio-lint-ratchet.yml` while the
pre-existing ones (mostly `control-has-associated-label`: 274,
`label-has-associated-control`: 37) are tracked and shrink over time via
the weekly baseline-decrease cron.

Resolves
[FE-3795](https://linear.app/supabase/issue/FE-3795/add-jsx-a11y-eslint-ratchet-rules-for-statically-detectable-a11y).

## Test plan
- [x] `pnpm --filter studio run lint:ratchet` passes (exit 0, no
regressions)
- [x] Spot-checked several flagged instances against source to confirm
true positives (e.g. an unlabeled save/cancel icon-button pair in
`AIAssistantChatSelector.tsx`, an empty `<h3>` in `PITRForm.tsx`)
- [x] CI (`studio-lint-ratchet.yml`, typecheck.yml lint step) green on
this PR

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

* **Bug Fixes**
* Expanded Studio’s accessibility linting to cover additional ARIA prop
validation, label/control relationships, anchor/heading validity,
role/ARIA correctness, and focus/tab behavior (including distracting
markup).
* Updated accessibility lint baselines so tracked violations remain
accurate as rules expand.
* **New Features**
* Enhanced the Studio lint “ratchet” workflow to load ratchet rule IDs
from an external `rules-file` instead of a long inline command.
* **Tests**
* Added an integration test to verify rule IDs are read from the
`rules-file`.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-03 20:33:12 +00:00
e81c714aae refactor(studio): lazy self-hosted admin client + enforce in API routes (from #46424) (#47104)
Extracted from the TanStack Start migration (#46424) to shrink that PR.

The self-hosted storage/auth API routes each constructed a module-scope
admin client (`createClient(process.env.SUPABASE_URL!,
process.env.SUPABASE_SERVICE_KEY!)`). Those env vars only exist on
self-hosted, so eager module-scope construction is wasteful on platform
and fragile on any runtime that evaluates an API module before its route
is hit (constructing with `undefined` credentials throws on import).

**Changed:**
- Add `lib/api/self-hosted-admin.ts` — `selfHostedSupabaseAdmin`, a
`Proxy` that defers `createClient(...)` until first property access
(inside a handler, i.e. on self-hosted where the vars are set).
- Swap **all 17** storage/auth/vector-bucket handlers from module-scope
`createClient(...)` to `import { selfHostedSupabaseAdmin as supabase }`.
- **Enforce it:** add an eslint `no-restricted-syntax` rule banning
module-scope `createClient` in `pages/api/**` + `routes/**` (now that
every flagged handler is lazy). The same eslint config block also
carries an analytics-SQL boundary rule — 0 violations on master.

Behaviour is unchanged (the client is still built lazily inside the
handler). This is also the change that makes those routes safe under
TanStack's single-handler module evaluation.

## To test
- Self-hosted Studio: storage buckets/objects, vector buckets, and auth
users operations work as before.

## Verification
studio lint (0 errors, both rules active) ✓ · studio typecheck ✓.


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

## Summary by CodeRabbit

* **Refactor**
* Standardized self-hosted Supabase admin client usage across platform
authentication and storage endpoints, removing per-route client setup.
* Improved reliability by lazily creating the admin client only when
first used.
* **Chores / Tooling**
* Updated ESLint rules to prevent module-scope Supabase client creation
in API routes and to enforce safe analytics SQL access patterns.

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

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-06-22 13:37:15 +00:00
Charis da1eb8b65f chore(logs): lock the analytics SQL wire boundary (#46485)
## 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?

Refactor / chore — lints the analytics SQL wire boundary and tightens
internal API surface. Final PR in the safe-analytics-sql series (stacked
on #46476).

## What is the current behavior?

After PRs 1–10, every analytics SQL call site routes through
`executeAnalyticsSql`, but nothing prevents a future caller from
regressing by calling
`post('/platform/projects/{ref}/analytics/endpoints/logs.all', …)`
directly. `safe-analytics-sql.ts` also exports `rawSql` and
`LogSqlFragmentSeparator`, neither of which has external consumers —
`rawSql` in particular is a cast-to-brand escape hatch that should not
be reachable from outside the file. The safe-sql-execution skill
documents only the pg-meta (Postgres) side of the model.

## What is the new behavior?

- Adds an ESLint `no-restricted-syntax` rule in
`apps/studio/eslint.config.cjs` that fails on direct `post()` / `get()`
calls against
`/platform/projects/{ref}/analytics/endpoints/logs.all{,.otel}` outside
the `executeAnalyticsSql` wrapper.
- Un-exports `rawSql` and `LogSqlFragmentSeparator` from
`safe-analytics-sql.ts`; updates the `SafeLogSqlFragment` docstring
accordingly.
- Adds an "Analytics SQL" section to
`.claude/skills/safe-sql-execution/SKILL.md` covering the disjoint
`SafeLogSqlFragment` brand, the helpers, the wire boundary, and the new
lint.

## Additional context

Resolves FE-2949
2026-05-29 13:36:22 +00:00
Danny White cca4e52dd0 refactor(ui-patterns): Standardise TanStack sort headers (#44212)
## What kind of change does this PR introduce?

Component update.

## What is the current behaviour?

TanStack tables in the repo are split between the shared `TableHeadSort`
primitive and the older Studio-local `DataTableColumnHeader` helper,
which makes the sorting UI and integration path inconsistent.

If you were to just use `DataTableColumnHeader` in `ui-patterns/Table`,
you’d get a very different visual result to the `TableHeadSort` UI you
see in most other tables.

## What is the new behaviour?

Adds a shared `TanStackTableHeadSort` adapter in `ui-patterns/Table`,
backed by the existing `TableHeadSort` primitive, and switches the
webhook table plus the design-system TanStack demo to that canonical
path. `DataTableColumnHeader` stays as a deprecated wrapper for now,
Studio gets a lint guard to block new imports of it, and the table docs
now point TanStack tables at the shared adapter explicitly.

## To test

Check out column sorting on the Platform Webhook endpoint deliveries
table.
2026-03-30 21:48:52 +11:00
Ali Waseem c57c341244 chore: add ratchet rules to stop nesting components (#42962)
## 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 changes required for this React Doctor need more thought that I can
hammer with AI. Just need to stop this from happening in the future with
Ratchet rules
2026-02-18 10:09:08 -07:00
Ali Waseem 2dd75cbfdd chore: Update aria-controls and aria-expanded for components (#42961)
## 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?

- React Doctor fixes for aria controls and aria expanded
- Updated eslint to include the role
2026-02-18 16:41:10 +00:00
Ali Waseem 1890624a1a fix: add missing keys to studio (#42957)
## 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?

Cleanup from React Doctor! Components missing keys
2026-02-18 09:05:22 -07:00
Ivan Vasilov 56d40fe0b2 chore: Migrate eslint for all apps to use flat config (#39486)
* Use the "eslint" command instead of built-in next lint since it's getting obsolete.

* Bump all deps to support eslint 9+.

* Convert the rules in eslint-config-supabase to be flat-config compatible.

* Migrate all apps to use the new eslint config rules.

* Fix all errors found in the new setup.

* Fix the no default exports ignores.

* Scan all files for linting in studio.

* Fix all lint errors.

* Make the reportUnusedDisableDirectives a warning.
2025-10-15 16:35:24 +02:00