supabase-sql

v2026.09.24

Clean and format SQL migrations for Supabase - idempotency, RLS policies, formatting, schema fixes. Use when: fix this SQL, clean migration, RLS policy, Supabase schema, format postgres, prepare for SQL Editor, idempotent migration.

GitHub
安装命令
npx skhub add scientiacapital/supabase-sql
Markdown
SKILL.md
<objective> Clean and format SQL migrations for direct paste into Supabase SQL Editor. Ensures idempotency, proper RLS policies (especially service role patterns), standardized formatting, and dependency documentation. </objective>

<quick_start> Clean any SQL migration:

  1. Fix typos (- → -- for comments)
  2. Add idempotency (IF NOT EXISTS, DROP ... IF EXISTS)
  3. Fix RLS policies (service role uses TO service_role, not JWT checks)
  4. Remove dead code (unused enums)
  5. Standardize casing (NOW(), TIMESTAMPTZ)
  6. Add dependencies comment at end
DROP POLICY IF EXISTS "Policy name" ON table_name;
CREATE POLICY "Policy name" ON table_name ...

</quick_start>

<success_criteria> SQL cleanup is successful when:

  • All policies and triggers use DROP ... IF EXISTS before CREATE
  • Service role policies use TO service_role (not JWT checks)
  • Indexes use IF NOT EXISTS
  • No unused enums remain
  • Dependencies listed at end of migration
  • SQL runs without errors in Supabase SQL Editor </success_criteria>

<core_patterns> Clean SQL migrations for direct paste into Supabase SQL Editor.

Cleanup Checklist

Run through each item:

  1. Fix typos - Common: - instead of -- on comment lines
  2. Add idempotency - IF NOT EXISTS on indexes, DROP ... IF EXISTS before policies/triggers
  3. Remove dead code - Enums created but never used (TEXT + CHECK often preferred)
  4. Fix RLS policies - Service role must use TO service_role, not JWT checks
  5. Standardize casing - NOW() not now(), TIMESTAMPTZ not timestamptz
  6. Remove clutter - Verbose RAISE NOTICE blocks, redundant comments, file path headers
  7. Validate dependencies - List required tables at end

Output Format

-- ============================================
-- 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 ...

Common Fixes

RLS Policy for Service Role

-- 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);

Idempotent Policies

-- Always drop before create
DROP POLICY IF EXISTS "Policy name" ON table_name;
CREATE POLICY "Policy name" ON table_name ...

Idempotent Triggers

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

Unused Enums

If you see enum created but table uses TEXT CHECK (...) instead, remove the enum:

-- 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 Section

Always end with dependencies note if tables are referenced:

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

Reference Files

  • reference/rls-patterns.md - Common RLS policy patterns for Supabase
  • reference/function-patterns.md - Trigger functions, atomic operations

Emit Outcome Sidecar

As the final step, write to ~/.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]"}

Use status "partial" if some stages failed but results were produced. Use "error" only if no output was generated.

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

未指定

源路径

active/supabase-sql-skill

默认分支

main

最新提交

9e03af3

Tree SHA

5b28287