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.
| 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:
Other measured skills in the registry, with their headline benchmark lift.