mcpField
S
supabase-sql

supabase-sql

github.com/scientiacapital数据与数据库2878 次安装3 周前更新
代码仓库

关于 supabase-sql

用于清理和格式化 SQL 迁移文件,便于粘贴到 Supabase SQL Editor 的 Skill。重点处理幂等语句、正确的 service role RLS 策略及依赖说明。

主要功能

  1. 01修正 SQL 注释与格式
  2. 02为策略、触发器和索引添加幂等性
  3. 03修正 service role 的 RLS 策略
  4. 04移除未使用的枚举与冗余内容
  5. 05记录迁移依赖

适用场景

  1. 01准备供 Supabase SQL Editor 使用的迁移
  2. 02确保策略与触发器可重复执行
  3. 03检查 service role 访问规则
  4. 04记录所需表与函数

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/scientiacapital/skills --skill supabase-sql

安装后在 Claude Code 中输入/supabase-sql确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

config.json
reference/
function-patterns.md
rls-patterns.md

详细介绍

清理并格式化 SQL 迁移文件,以便直接粘贴到 Supabase SQL Editor。确保幂等性、正确的 RLS 策略(尤其是服务角色模式)、格式统一,并记录依赖项。

<quick_start> 清理任意 SQL 迁移文件:

  1. 修正拼写错误(注释中的 - 改为 -- )
  2. 添加幂等性(IF NOT EXISTS、DROP ... IF EXISTS)
  3. 修正 RLS 策略(服务角色应使用 TO service_role,而不是 JWT 检查)
  4. 移除无用代码(未使用的枚举)
  5. 统一大小写(NOW()、TIMESTAMPTZ)
  6. 在末尾添加依赖项注释
DROP POLICY IF EXISTS "Policy name" ON table_name;
CREATE POLICY "Policy name" ON table_name ...

</quick_start>

<success_criteria> SQL 清理成功的标准:

  • 所有策略和触发器在 CREATE 前都使用 DROP ... IF EXISTS
  • 服务角色策略使用 TO service_role(而不是 JWT 检查)
  • 索引使用 IF NOT EXISTS
  • 不保留未使用的枚举
  • 在迁移文件末尾列出依赖项
  • SQL 可在 Supabase SQL Editor 中无错误运行 </success_criteria>

<core_patterns> 清理 SQL 迁移文件,以便直接粘贴到 Supabase SQL Editor。

清理检查清单

逐项检查:

  1. 修正拼写错误 - 常见问题:注释行使用 - 而不是 --
  2. 添加幂等性 - 索引使用 IF NOT EXISTS,策略和触发器前使用 DROP ... IF EXISTS
  3. 移除无用代码 - 创建后从未使用的枚举(通常优先使用 TEXT + CHECK)
  4. 修正 RLS 策略 - 服务角色必须使用 TO service_role,而不是 JWT 检查
  5. 统一大小写 - 使用 NOW(),而不是 now();使用 TIMESTAMPTZ,而不是 timestamptz
  6. 移除冗余内容 - 冗长的 RAISE NOTICE 代码块、重复注释、文件路径标题
  7. 验证依赖项 - 在末尾列出必需的表

输出格式

-- ============================================
-- Migration Name
-- Created: YYYY-MM-DD
-- Purpose: One-line description
-- ============================================

-- ============================================
-- Table Name
-- ============================================

CREATE TABLE IF NOT EXISTS ...

-- ============================================
-- Indexes
-- ============================================

CREATE INDEX IF NOT EXISTS ...

-- ============================================
-- Row Level Security
-- ============================================

ALTER TABLE ... ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "..." ON ...;
CREATE POLICY "..." ON ...

-- ============================================
-- Functions
-- ============================================

CREATE OR REPLACE FUNCTION ...

-- ============================================
-- Triggers
-- ============================================

DROP TRIGGER IF EXISTS ... ON ...;
CREATE TRIGGER ...

常见修正

服务角色的 RLS 策略
-- WRONG (doesn't work reliably)
CREATE POLICY "Service role access" ON my_table
    FOR ALL
    USING (auth.jwt() ->> 'role' = 'service_role');

-- CORRECT
CREATE POLICY "Service role access" ON my_table
    FOR ALL
    TO service_role
    USING (true)
    WITH CHECK (true);
幂等策略
-- Always drop before create
DROP POLICY IF EXISTS "Policy name" ON table_name;
CREATE POLICY "Policy name" ON table_name ...
幂等触发器
DROP TRIGGER IF EXISTS trigger_name ON table_name;
CREATE TRIGGER trigger_name ...
未使用的枚举

如果看到创建了枚举,但表使用的是 TEXT CHECK (...),请移除该枚举:

-- DELETE THIS - never used
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'my_enum') THEN
        CREATE TYPE my_enum AS ENUM ('a', 'b', 'c');
    END IF;
END$$;

-- Table actually uses TEXT with CHECK (keep this)
status TEXT NOT NULL CHECK (status IN ('a', 'b', 'c'))

依赖项部分

如果引用了表,务必以依赖项说明作为结尾:

-- Dependencies: businesses, call_logs, subscription_plans
-- Requires function: update_updated_at_column()

参考文件

  • reference/rls-patterns.md - Supabase 常见 RLS 策略模式
  • reference/function-patterns.md - 触发器函数、原子操作

写入结果旁文件

最后一步,将结果写入 ~/.claude/skill-analytics/last-outcome-supabase-sql.json:

{"ts":"[UTC ISO8601]","skill":"supabase-sql","version":"1.0.0","variant":"default",
 "status":"[success|partial|error]","runtime_ms":[estimated ms from start],
 "metrics":{"migrations_written":[n],"tables_modified":[n],"rls_policies_created":[n]},
 "error":null,"session_id":"[YYYY-MM-DD]"}

如果某些阶段失败但仍生成了结果,请使用状态 "partial"。仅当未生成任何输出时,才使用 "error"。

评论

支持 Markdown