Files
supabase/apps/studio
Douglas J Hunley eea39cc316 fix(studio): register pitr_archiving_stale in the advisor lintInfoMap (#48044)
## Summary
Studio's Advisor UI reads lint metadata from a fixed `lintInfoMap`, not
from the API response. A lint name missing from that map shows a blank
title, no icon, no filter checkbox, and no remediation link. This PR
adds a `pitr_archiving_stale` entry to `lintInfoMap`, copied from the
existing `pitr_not_enabled` entry, so the new lint renders correctly in
the Advisor UI.

## Dependencies

> [!WARNING]
>
[supabase/platform#35862](https://github.com/supabase/platform/pull/35862)
defines the `pitr_archiving_stale` lint. Until it merges, the API never
sends this lint name, so the Advisor grid and the public
`/v1/projects/{ref}/advisors/security` response never show the new row
-- but the Security Rules page
(`/project/<ref>/advisors/rules/security`) renders one row per
`lintInfoMap` entry regardless of the API, so this PR's new row appears
there immediately, before the backend lint exists. See Details for what
that means in the gap between merges.

---

<details>
<summary>Details</summary>

- A lint name missing from `lintInfoMap` has these effects:
- The grid row shows a blank title and no icon. There is no fallback to
the API's own `title`.
- The row has no filter checkbox. Filter options come from
`lintInfoMap`, not from the API.
- The row has no lint-specific remediation link. The "Learn more" link
falls back to the generic database-linter page.
  - The row does not appear in the Advisor Rules enable/disable list.
- The new `pitr_archiving_stale` entry copies the existing
`pitr_not_enabled` entry's `link`, `docsLink`, and `category`, and uses
a new `title` matching
[supabase/platform#35862](https://github.com/supabase/platform/pull/35862)'s
lint definition verbatim. Its `name` also matches that lint definition
exactly.
- **Known gap, until the backend PR merges:** `AdvisorRules`
(`components/interfaces/Advisors/AdvisorRules.tsx`) filters
`lintInfoMap` by `category` alone, with no dependency on the API
returning the lint -- so this entry makes a "PITR archiving may be
broken" row appear on the Security Rules page for every project right
away, ahead of the backend lint actually existing. From that row, a user
can open `CreateRuleSheet` and submit a disable rule, which `POST`s
`lint_name: 'pitr_archiving_stale'` to the notification-exceptions
endpoint. That name is not yet in the generated
`CreateNotificationExceptionsBody` enum
(`packages/api-types/types/platform.d.ts`), so the request either errors
or stores an exception keyed to a lint name nothing will ever match,
until api-types regenerates after the backend PR ships. This window
closes on its own once
[supabase/platform#35862](https://github.com/supabase/platform/pull/35862)
merges; accepted as a short-lived tradeoff rather than gating this PR on
merge order or adding code to hide the row until then.
- The docs anchor (`#point-in-time-recovery`) explains what PITR and
WAL-G archiving are. It does not explain how to fix a stale or broken
archive. That content does not exist yet in either pull request.
INDATA-1149 tracks this as a follow-up.
- `packages/api-types/types/platform.d.ts` is a generated file. This
repo's own CLAUDE.md says never to hand-edit it. The file does not list
`pitr_archiving_stale` yet, because it regenerates only after the
backend lint ships and `pnpm api:codegen` runs. Until then,
`LintInfo['name']` stays a plain `string`. If someone misspells the new
entry's `name`, the code still compiles and the tests still pass. At
runtime, the icon and docs link fall back silently instead of failing a
build. Once
[supabase/platform#35862](https://github.com/supabase/platform/pull/35862)
merges and api-types regenerates, `LintInfo['name']` must tighten to the
generated `LINT_TYPES` union. This closes the gap for every lint entry,
not only this one.

</details>

---

<details>
<summary>Testing</summary>

- `pnpm --filter=studio test Linter.utils.test.tsx` (17 passed,
including a test that asserts the `pitr_archiving_stale` entry's shape)
- `pnpm typecheck --filter=studio` (clean)
- `pnpm exec eslint` on the touched files (clean; the `pnpm lint
--filter=studio` turbo wrapper itself errors on this machine with an
unrelated JSON-parse failure -- a tool-invocation issue, not a lint
finding)
- `prettier --check` on the touched files
- The `docsLink` assertion
(`toContain('/guides/platform/backups#point-in-time-recovery')`) is
domain-agnostic by construction, so it holds regardless of which
`NEXT_PUBLIC_DOCS_URL` value is set -- no test in this file overrides
that variable, this is a property of the assertion's own shape, not a
scenario the suite exercises

</details>

---

<details>
<summary>Misc</summary>

- Part of INDATA-979
- Changelog:
[supabase/changelog#192](https://github.com/supabase/changelog/pull/192)

</details>
2026-08-31 15:28:37 -04:00
..

Supabase Studio

A dashboard for managing your self-hosted Supabase project, and used on our hosted platform. Built with:

What's included

Studio is designed to work with existing deployments - either the local hosted, docker setup, or our CLI. It is not intended for managing the deployment and administration of projects - that's out of scope.

As such, the features exposed on Studio for existing deployments are limited to those which manage your database:

  • Table & SQL editors
    • Saved queries are unavailable
  • Database management
    • Policies, roles, extensions, replication
  • API documentation

Managing Project Settings

Project settings are managed outside of the Dashboard. If you use docker compose, you should manage the settings in your docker-compose file. If you're deploying Supabase to your own cloud, you should store your secrets and env vars in a vault or secrets manager.

How to contribute?

  • Branch from master and name your branches with the following structure
    • {type}/{branch_name}
      • Type: chore | fix | feature
      • The branch name is arbitrary — just make sure it summarizes the work.
  • When you send a PR to master, it will automatically tag members of the frontend team for review.
  • Review the main contributing guide to help test your feature before sending a PR.
  • The Dashboard is under active development. You should run git pull frequently to make sure you're up to date.

Developer Quickstart

Note

Supabase internal use: To develop on Studio locally with the backend services, see the instructions in the internal infrastructure repo.

# You'll need to be on Node v22
# in /studio

## For external contributors
pnpm install # install dependencies
pnpm run dev # start dev server

## For internal contributors
## First clone the private supabase/platform repo and follow instructions for setting up mise
mise studio  # Run from supabase/platform alongside `mise infra`

## For all
pnpm run test # run tests
pnpm run test -- --watch # run tests in watch mode

Running within a self-hosted environment

Follow the self-hosting guide to get started.

cd ..
cd docker
docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up

Once you've got that set up, update .env in the studio folder with the corresponding values.

POSTGRES_PASSWORD=
SUPABASE_ANON_KEY=
SUPABASE_SERVICE_KEY=

Then run the following commands to install dependencies and start the dashboard.

npm install
npm run dev

If you would like to configure different defaults for "Default Organization" and "Default Project", you will need to update the .env in the studio folder with the corresponding values.

DEFAULT_ORGANIZATION_NAME=
DEFAULT_PROJECT_NAME=