mcpField
S
supabase-admin

supabase-admin

github.com/curiositech数据与数据库257189 次安装2 天前更新
代码仓库

关于 supabase-admin

supabase-admin 是面向使用 Supabase 的开发者的数据库管理技能,涵盖生产应用中的模式设计、RLS、迁移和性能优化。它还提供 Supabase 身份验证相关 SQL 模式及 RLS 问题排查方法。

主要功能

  1. 01设计与排查 RLS 策略
  2. 02规划数据库迁移和模式变更
  3. 03处理身份验证相关 SQL 模式
  4. 04优化查询与索引性能
  5. 05诊断 RLS 可见性问题

适用场景

  1. 01保护用户数据访问
  2. 02为应用部署数据库模式变更
  3. 03排查查询结果为空的问题

安装

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

$npx skills add https://github.com/curiositech/some_claude_skills --skill supabase-admin

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

包含的文件

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

.claude-plugin/
plugin.json
references/
rls-patterns.md
social-schema.md

详细介绍

Supabase 管理专家

掌握 Supabase 架构设计、行级安全策略、迁移和生产应用的性能优化。

适用场景

✅ 以下情况请使用此技能:

  • 行级安全(RLS)策略设计与调试
  • 数据库迁移和架构变更
  • Auth 集成(触发器、创建个人资料)
  • 查询性能优化
  • Supabase 专用 SQL 模式(auth.uid()、auth.jwt())

❌ 以下情况请勿使用:

  • Supabase Auth UI 配置 → 请参阅 Supabase 控制台文档
  • Edge Functions → 请使用 cloudflare-worker-dev 技能
  • 不涉及 Supabase 的通用 PostgreSQL → 请使用标准 SQL 资源
  • 客户端 Supabase SDK 用法 → 请参阅 Supabase JS 文档

核心能力

1. 行级安全(RLS)

始终为用户表启用 RLS:

ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;

策略模式:

-- Public read, authenticated write
CREATE POLICY "Public read" ON posts FOR SELECT USING (true);
CREATE POLICY "Owners can write" ON posts FOR INSERT
  WITH CHECK (auth.uid() = user_id);

-- Owner-only access
CREATE POLICY "Users own their data" ON profiles
  FOR ALL USING (auth.uid() = id);

-- Role-based access
CREATE POLICY "Admins can do anything" ON content
  FOR ALL USING (
    EXISTS (
      SELECT 1 FROM profiles
      WHERE profiles.id = auth.uid()
      AND profiles.role = 'admin'
    )
  );

性能关键:为 auth.uid() 列创建索引:

-- 100x performance improvement for RLS policies
CREATE INDEX idx_posts_user_id ON posts(user_id);
CREATE INDEX idx_profiles_id ON profiles(id);

JWT 函数的子查询优化:

-- BAD: JWT parsed for every row
CREATE POLICY "slow" ON posts FOR SELECT
  USING (user_id = auth.uid());

-- GOOD: JWT parsed once via subquery
CREATE POLICY "fast" ON posts FOR SELECT
  USING (user_id = (SELECT auth.uid()));
2. 迁移最佳实践

文件命名约定:

supabase/migrations/
├── 001_initial_schema.sql
├── 002_add_profiles_trigger.sql
├── 003_forum_tables.sql
└── 004_add_rls_policies.sql

迁移模板:

-- Migration: 005_feature_name
-- Description: What this migration does
-- Author: name
-- Date: YYYY-MM-DD

-- Up migration
BEGIN;

-- Your DDL here
CREATE TABLE ...;
ALTER TABLE ...;
CREATE POLICY ...;

COMMIT;

-- Down migration (as comment for reference)
-- DROP TABLE ...;
-- DROP POLICY ...;

安全迁移模式:

-- Add column with default (no table lock)
ALTER TABLE users ADD COLUMN status text DEFAULT 'active';

-- Add NOT NULL constraint safely
ALTER TABLE users ADD COLUMN email text;
UPDATE users SET email = '[email protected]' WHERE email IS NULL;
ALTER TABLE users ALTER COLUMN email SET NOT NULL;

-- Create index concurrently (no lock)
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
3. Auth 集成

注册时自动创建个人资料:

-- Function to create profile
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO public.profiles (id, email, display_name)
  VALUES (
    NEW.id,
    NEW.email,
    COALESCE(NEW.raw_user_meta_data->>'display_name', split_part(NEW.email, '@', 1))
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- Trigger on auth.users
CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();

在策略中检查 Auth 状态:

-- Authenticated users only
CREATE POLICY "Authenticated access" ON data
  FOR SELECT USING (auth.role() = 'authenticated');

-- Get current user's ID
SELECT auth.uid();

-- Get current user's JWT claims
SELECT auth.jwt();
4. 常见架构模式

带默认值的时间戳:

CREATE TABLE posts (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE,
  content text NOT NULL,
  created_at timestamptz DEFAULT now(),
  updated_at timestamptz DEFAULT now()
);

-- Auto-update updated_at
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = now();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER update_posts_updated_at
  BEFORE UPDATE ON posts
  FOR EACH ROW EXECUTE FUNCTION update_updated_at();

软删除模式:

ALTER TABLE posts ADD COLUMN deleted_at timestamptz;

CREATE POLICY "Hide deleted" ON posts
  FOR SELECT USING (deleted_at IS NULL);

全文搜索:

-- Add search vector column
ALTER TABLE posts ADD COLUMN search_vector tsvector;

-- Create GIN index
CREATE INDEX idx_posts_search ON posts USING GIN(search_vector);

-- Update function
CREATE OR REPLACE FUNCTION posts_search_update()
RETURNS TRIGGER AS $$
BEGIN
  NEW.search_vector := to_tsvector('english', COALESCE(NEW.title, '') || ' ' || COALESCE(NEW.content, ''));
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Search query
SELECT * FROM posts
WHERE search_vector @@ plainto_tsquery('english', 'search terms');
5. RLS 问题调试

常见问题:结果为空,且没有错误

-- Check if RLS is enabled
SELECT tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public';

-- List all policies
SELECT * FROM pg_policies WHERE tablename = 'your_table';

-- Test as specific role
SET ROLE anon;
SELECT * FROM your_table LIMIT 1;
RESET ROLE;

-- Test with specific user
SET request.jwt.claims TO '{"sub": "user-uuid-here"}';
SELECT * FROM your_table;

诊断查询:

-- Check what the current user can see
SELECT
  auth.uid() as current_user,
  auth.role() as current_role,
  (SELECT count(*) FROM your_table) as visible_rows;

快速参考

任务命令
启用 RLSALTER TABLE t ENABLE ROW LEVEL SECURITY;
创建策略CREATE POLICY "name" ON t FOR action USING (condition);
删除策略DROP POLICY "name" ON t;
检查策略SELECT * FROM pg_policies WHERE tablename = 't';
当前用户SELECT auth.uid();
为所有者强制启用 RLSALTER TABLE t FORCE ROW LEVEL SECURITY;

参考资料

详细指南请参阅 /references/:

  • rls-patterns.md - 高级 RLS 策略模式
  • migration-checklist.md - 部署前检查清单
  • performance-tuning.md - 查询和索引优化
  • social-schema.md - 社交功能的架构模式

评论

支持 Markdown