Back to list
rdimascio

implement-crud

by rdimascio

Production-ready Claude Code plugins for Supabase database, auth, storage, realtime, and edge functions

0🍴 0📅 Dec 17, 2025

SKILL.md


name: implement-crud description: Implement complete CRUD (Create, Read, Update, Delete) operations for Supabase tables with proper error handling, validation, and RLS. Triggers when user requests data operations, API endpoints, or database interactions. allowed-tools: Read, Write, Edit, Glob, Grep

CRUD Implementation Skill

Implement comprehensive CRUD operations for Supabase tables with best practices.

Purpose

Generate production-ready CRUD operations including queries, mutations, error handling, type safety, and RLS-aware implementations.

When to Use

  • User requests CRUD functionality
  • Needs API endpoints for data operations
  • Asks for database interaction code
  • Wants to implement data management features
  • Requests type-safe database operations

Instructions

  1. Analyze Requirements

    • Identify target table and columns
    • Understand relationships and foreign keys
    • Check RLS policies on table
    • Determine validation rules
    • Identify required permissions
  2. Implement Read Operations

    • Single record fetch by ID
    • List with filtering and pagination
    • Search functionality
    • Include related data with joins
    • Handle not found cases
  3. Implement Create Operations

    • Input validation
    • Required field checks
    • Foreign key validation
    • Return created record with ID
    • Handle duplicate key errors
  4. Implement Update Operations

    • Partial update support
    • Optimistic locking if needed
    • Validate ownership via RLS
    • Return updated record
    • Handle not found cases
  5. Implement Delete Operations

    • Soft delete vs hard delete
    • Cascade handling
    • Validate ownership
    • Return success confirmation
    • Handle foreign key violations
  6. Add Error Handling

    • Wrap operations in try-catch
    • Provide meaningful error messages
    • Handle common Postgres errors
    • Return structured error responses
    • Log errors appropriately

Examples

TypeScript Implementation

import { createClient } from '@supabase/supabase-js'
import type { Database } from './database.types'

const supabase = createClient<Database>(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_ANON_KEY!
)

// READ: Get single post by ID
export async function getPost(id: string) {
  const { data, error } = await supabase
    .from('posts')
    .select(`
      *,
      author:profiles!author_id(*),
      comments(count)
    `)
    .eq('id', id)
    .single()

  if (error) {
    throw new Error(`Failed to fetch post: ${error.message}`)
  }

  return data
}

// READ: List posts with pagination
export async function listPosts(options: {
  page?: number
  perPage?: number
  published?: boolean
}) {
  const { page = 1, perPage = 20, published } = options
  const start = (page - 1) * perPage
  const end = start + perPage - 1

  let query = supabase
    .from('posts')
    .select('*, author:profiles!author_id(username)', { count: 'exact' })

  if (published !== undefined) {
    query = query.eq('published', published)
  }

  const { data, error, count } = await query
    .order('created_at', { ascending: false })
    .range(start, end)

  if (error) {
    throw new Error(`Failed to list posts: ${error.message}`)
  }

  return {
    data,
    pagination: {
      page,
      perPage,
      total: count,
      totalPages: Math.ceil((count || 0) / perPage)
    }
  }
}

// CREATE: Insert new post
export async function createPost(input: {
  title: string
  content: string
  authorId: string
  published?: boolean
}) {
  const { data, error } = await supabase
    .from('posts')
    .insert({
      title: input.title,
      content: input.content,
      author_id: input.authorId,
      published: input.published ?? false,
      slug: generateSlug(input.title)
    })
    .select()
    .single()

  if (error) {
    if (error.code === '23505') {
      throw new Error('A post with this title already exists')
    }
    throw new Error(`Failed to create post: ${error.message}`)
  }

  return data
}

// UPDATE: Update existing post
export async function updatePost(
  id: string,
  updates: {
    title?: string
    content?: string
    published?: boolean
  }
) {
  const { data, error } = await supabase
    .from('posts')
    .update(updates)
    .eq('id', id)
    .select()
    .single()

  if (error) {
    if (error.code === 'PGRST116') {
      throw new Error('Post not found or access denied')
    }
    throw new Error(`Failed to update post: ${error.message}`)
  }

  return data
}

// DELETE: Remove post
export async function deletePost(id: string) {
  const { error } = await supabase
    .from('posts')
    .delete()
    .eq('id', id)

  if (error) {
    if (error.code === 'PGRST116') {
      throw new Error('Post not found or access denied')
    }
    throw new Error(`Failed to delete post: ${error.message}`)
  }

  return { success: true }
}

function generateSlug(title: string): string {
  return title
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-|-$/g, '')
}

Output Format

Provide:

  1. Complete CRUD function implementations
  2. Proper TypeScript types
  3. Error handling for all cases
  4. Usage examples
  5. Testing recommendations

Score

Total Score

60/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新

+5
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon