Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Translates natural language data model descriptions into production-ready Supabase migrations. Generates CREATE TABLE statements, Row Level Security policies, indexes, and TypeScript types. Triggered when the user asks to design a database schema, create tables, set up Supabase, or generate a migration. Shows full SQL for review before applying anything.
.claude/skills/0xjitsu-supabase-schema/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 23% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -6% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 17% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 79% | 0% |
Natural language to production-ready Supabase migration pipeline.
Activate this skill when the user:
A natural language description of the data model. Examples:
Read the user's description and extract:
Present a summary table before generating SQL:
| Entity | Key Attributes | Relationships | |--------|---------------|---------------| | users | email, name, avatar_url | has_many posts, has_many comments | | posts | title, body, status | belongs_to user, has_many comments |
Generate SQL with appropriate Postgres types:
sql-- Enable required extensions CREATE EXTENSION IF NOT EXISTS "pgcrypto"; CREATE TABLE public.users ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), email text UNIQUE NOT NULL, full_name text, avatar_url text, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() );
Type selection rules:
uuid with gen_random_uuid() default — never serial/bigserialtimestamptz — never timestamp without timezonetext — never varchar unless a hard length limit is requiredjsonb — never jsonCHECK constraints over Postgres ENUM types (easier to migrate)numeric(12,2) or bigint (cents) — never float/doubletext with CHECK (status IN ('draft', 'published', 'archived'))Enable RLS on every table and generate default policies:
sqlALTER TABLE public.posts ENABLE ROW LEVEL SECURITY; -- Users can read all published posts CREATE POLICY "Public posts are viewable by everyone" ON public.posts FOR SELECT USING (status = 'published'); -- Users can CRUD their own posts CREATE POLICY "Users can manage their own posts" ON public.posts FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
Default RLS rules:
sql-- Foreign key indexes (Postgres does NOT auto-index FK columns) CREATE INDEX idx_posts_user_id ON public.posts (user_id); CREATE INDEX idx_comments_post_id ON public.comments (post_id); -- Common query pattern indexes CREATE INDEX idx_posts_status ON public.posts (status) WHERE status = 'published'; CREATE INDEX idx_posts_created_at ON public.posts (created_at DESC);
Index rules:
DESC indexes for timestamp orderingjsonb and full-text search columnssqlCREATE OR REPLACE FUNCTION public.handle_updated_at() RETURNS trigger AS $$ BEGIN NEW.updated_at = now(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Apply to all tables with updated_at CREATE TRIGGER set_updated_at BEFORE UPDATE ON public.users FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();
Use Supabase MCP to generate types:
generate_typescript_types with the project IDsrc/types/database.tsSafety protocol — ALWAYS follow this sequence:
apply_migration with a descriptive namelist_tables after applicationNever auto-apply without confirmation. This is a hard rule.
Before presenting the migration, verify:
id uuid PRIMARY KEY DEFAULT gen_random_uuid()created_at timestamptz NOT NULL DEFAULT now()updated_at timestamptz NOT NULL DEFAULT now()ON DELETE behavior is specified (CASCADE or SET NULL)CHECK constraintshandle_updated_at trigger is applied to all tablesUser: "I need a schema for a task management app with projects, tasks, and team members"
Agent output:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-22 | pass→pass | 15,524 | 12,399 | -20% | 1 | 1 | 0% | 2,898 | 3,738 | +29% | 0 | 0 | — |
case-01 | fail→pass | 14,106 | 13,269 | -6% | 1 | 1 | 0% | 3,473 | 4,688 | +35% | 0 | 0 | — |
case-02 | fail→pass | 24,914 | 24,159 | -3% | 1 | 1 | 0% | 6,214 | 7,634 | +23% | 0 | 0 | — |
case-03 | fail→pass | 23,816 | 16,270 | -32% | 1 | 1 | 0% | 5,556 | 5,246 | -6% | 0 | 0 | — |
case-04 | fail→pass | 17,650 | 16,997 | -4% | 1 | 1 | 0% | 3,865 | 4,510 | +17% | 0 | 0 | — |
case-05 | fail→fail | 15,573 | 14,436 | -7% | 1 | 1 | 0% | 3,569 | 4,664 | +31% | 0 | 0 | — |
case-06 | pass→pass | 17,185 | 11,010 | -36% | 1 | 1 | 0% | 3,611 | 3,698 | +2% | 0 | 0 | — |
case-07 | fail→pass | 12,533 | 12,024 | -4% | 1 | 1 | 0% | 2,302 | 4,122 | +79% | 0 | 0 | — |
case-08 | fail→pass | 13,738 | 28,641 | +108% | 1 | 1 | 0% | 2,927 | 4,160 | +42% | 0 | 0 | — |
case-09 | fail→pass | 13,000 | 9,449 | -27% | 1 | 1 | 0% | 2,726 | 3,816 | +40% | 0 | 0 | — |
case-10 | pass→pass | 39,718 | 16,499 | -58% | 1 | 1 | 0% | 4,086 | 5,401 | +32% | 0 | 0 | — |
case-11 | fail→fail | 5,828 | 4,710 | -19% | 1 | 1 | 0% | 1,142 | 2,347 | +106% | 0 | 0 | — |
case-12 | fail→fail | 12,213 | 17,858 | +46% | 1 | 1 | 0% | 2,713 | 3,610 | +33% | 0 | 0 | — |
case-13 | fail→pass | 15,770 | 13,945 | -12% | 1 | 1 | 0% | 3,576 | 4,788 | +34% | 0 | 0 | — |
case-14 | pass→pass | 17,502 | 12,220 | -30% | 1 | 1 | 0% | 2,837 | 3,874 | +37% | 0 | 0 | — |
case-15 | pass→pass | 10,807 | 6,352 | -41% | 1 | 1 | 0% | 2,019 | 2,542 | +26% | 0 | 0 | — |
case-16 | fail→pass | 17,968 | 11,038 | -39% | 1 | 1 | 0% | 2,020 | 3,808 | +89% | 0 | 0 | — |
case-17 | fail→pass | 10,162 | 13,130 | +29% | 1 | 1 | 0% | 2,330 | 4,708 | +102% | 0 | 0 | — |
case-18 | pass→pass | 9,802 | 9,099 | -7% | 1 | 1 | 0% | 2,332 | 3,534 | +52% | 0 | 0 | — |
case-19 | fail→pass | 16,495 | 9,088 | -45% | 1 | 1 | 0% | 3,569 | 3,569 | 0% | 0 | 0 | — |
case-20 | pass→pass | 12,825 | 8,865 | -31% | 1 | 1 | 0% | 2,511 | 3,115 | +24% | 0 | 0 | — |
case-21 | pass→pass | 10,700 | 26,654 | +149% | 1 | 1 | 0% | 2,287 | 2,889 | +26% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +50 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/3/2026 | +23% |
Other measured skills in the registry, with their headline benchmark lift.