{"id":14968771,"url":"https://github.com/supabase/splinter","last_synced_at":"2025-04-05T11:06:53.936Z","repository":{"id":229893447,"uuid":"754797230","full_name":"supabase/splinter","owner":"supabase","description":"Supabase Postgres Linter: Performance and Security Advisors","archived":false,"fork":false,"pushed_at":"2025-02-26T00:29:56.000Z","size":981,"stargazers_count":117,"open_issues_count":5,"forks_count":15,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-04-02T00:36:37.032Z","etag":null,"topics":["linter","postgres","supabase"],"latest_commit_sha":null,"homepage":"https://supabase.github.io/splinter/","language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/supabase.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["supabase"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2024-02-08T19:32:56.000Z","updated_at":"2025-03-26T03:13:53.000Z","dependencies_parsed_at":"2024-05-15T11:50:17.897Z","dependency_job_id":null,"html_url":"https://github.com/supabase/splinter","commit_stats":{"total_commits":91,"total_committers":6,"mean_commits":"15.166666666666666","dds":0.08791208791208793,"last_synced_commit":"95f050cc7fbfaf0ea0d04e3b5fc9cd805c1b3713"},"previous_names":["supabase/splinter"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supabase%2Fsplinter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supabase%2Fsplinter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supabase%2Fsplinter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supabase%2Fsplinter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/supabase","download_url":"https://codeload.github.com/supabase/splinter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247325693,"owners_count":20920714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linter","postgres","supabase"],"created_at":"2024-09-24T13:40:31.880Z","updated_at":"2025-04-05T11:06:53.892Z","avatar_url":"https://github.com/supabase.png","language":"PLpgSQL","funding_links":["https://github.com/sponsors/supabase"],"categories":[],"sub_categories":[],"readme":"# splinter (Supabase Postgres LINTER)\n\n\u003cimg src=\"https://github.com/supabase/splinter/assets/12958657/3683c310-c9f6-4b05-ae3a-c51c03d3ff0f\" height=\"250\"\u003e\n\n\u003cp\u003e\n\u003ca href=\"\"\u003e\u003cimg src=\"https://img.shields.io/badge/postgresql-15+-blue.svg\" alt=\"PostgreSQL version\" height=\"18\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/supabase/splinter/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/pypi/l/markdown-subtemplate.svg\" alt=\"License\" height=\"18\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/supabase/splinter/actions\"\u003e\u003cimg src=\"https://github.com/supabase/splinter/actions/workflows/test.yml/badge.svg\" alt=\"tests\" height=\"18\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n**Documentation**: \u003ca href=\"https://supabase.github.io/splinter\" target=\"_blank\"\u003ehttps://supabase.github.io/splinter\u003c/a\u003e\n\n**Source Code**: \u003ca href=\"https://github.com/supabase/splinter\" target=\"_blank\"\u003ehttps://github.com/supabase/splinter\u003c/a\u003e\n\n---\n\nSplinter maintains a set of lints for Supabase projects. It uses SQL queries to identify common database schema issues. Some lints are general purpose for Postgres projects while others are specific to Supabase features storing their data in Postgres e.g. auth and storage.\n\n## Usage\n\nIf you are only interested in linting a project, a single query containing the latest version of all lints is availble in splinter.sql in the repo root.\n\n## Lint Interface\n\nEach lint creates a view that returns a common interface. The interface is:\n\n- name (text) not null -- Name of the lint\n- title (text) not null -- Human readable title of the lint\n- level (text) not null -- The level of issue. One of ERROR/WARN/INFO\n- facing (text) not null -- Is it an internal (to supabase) or an external (user centric)  lint. One of INTERNAL/EXTERNAL\n- categories (text[]) not null -- Relevant tags for the issue. Any/All of SECURITY/PERFORMANCE (list may grow)\n- description (text) not null -- This is a description of the lint and why its an issue\n- detail (text) not null -- A text description of the issue that includes references to the specific table/column/constraint/whatever that fails the lint\n- remediation (text) optional -- A reference to documentation to describe the issue and how to resolve it\n- metadata (jsonb) optional -- Lint specific information, for example referenced entities, or entity types\n- cache_key (text) not null -- A short, uniquely identifiable string that users can add to an exclusion list to avoid repeatedly seeing the same lint failures. It should identify the releavnt table/column/constraint. The string should be prefixed with the lint name. For example a lint named \"unindexed_foreign_key\" might have a unique key \"unindexed_foreign_key_public_user_created_by_id\"\n\n## Deploying to supabase/supabase\n\nTo deploy lints to Supabase prod, open a PR against `supabase/supabase` updating [the lint query](https://github.com/supabase/supabase/blob/76d10d789fcd1b3e02a62d67d2d8edce78f81903/apps/studio/data/lint/lint-query.ts#L6)\n\nIf the update includes a new lint, update [getHumanReadableTitle](https://github.com/supabase/supabase/blob/76d10d789fcd1b3e02a62d67d2d8edce78f81903/apps/studio/components/interfaces/Reports/ReportLints.utils.tsx#L9) and [LINT_TYPES](https://github.com/supabase/supabase/blob/76d10d789fcd1b3e02a62d67d2d8edce78f81903/apps/studio/data/lint/lint-query.ts#L694).\n\n[Example PR](https://github.com/supabase/supabase/pull/22682)\n\n\n## Development\n\nSupabase PostgreSQL 15+\n\nSetup:\n\n```sh\ngit clone https://github.com/supabase/splinter.git\ncd splinter\n```\n\n## Tests\n\nAll lints tests with a true positive example.\n\nTo run the test suite:\n\n```sh\ndocker rmi -f dockerfiles-test \u0026\u0026 SUPABASE_VERSION=15.1.1.13 docker-compose -f dockerfiles/docker-compose.yml run --rm test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupabase%2Fsplinter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsupabase%2Fsplinter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupabase%2Fsplinter/lists"}