Skip to content
crud-skill logo

CRUD Skill

crud-skill

Implement Create, Read, Update, Delete operations for todo tasks. Use when building data management functionality.

SKILL.md

Full skill instructions

CRUD Skill

Purpose

Implement robust CRUD operations for todo task management.

Instructions

Service Layer Pattern

from typing import Optional, List
from datetime import datetime

class TodoService:
    """Service layer for todo task operations."""
    
    def __init__(self, database):
        self.db = database
    
    # CREATE
    def create_task(self, task_data: dict) -> dict:
        """Create a new task with auto-generated metadata."""
        now = datetime.now().isoformat()
        task_data['created_at'] = now
        task_data['updated_at'] = now
        task_data['status'] = task_data.get('status', 'pending')
        
        task_id = self.db.insert(task_data)
        task_data['id'] = task_id
        return task_data
    
    # READ
    def get_task(self, task_id: int) -> Optional[dict]:
        """Get a single task by ID."""
        return self.db.get(task_id)
    
    def get_all_tasks(self) -> List[dict]:
        """Get all tasks."""
        return self.db.get_all()
    
    def get_tasks_by_status(self, status: str) -> List[dict]:
        """Get tasks filtered by status."""
        return self.db.search(self.db.query.status == status)
    
    # UPDATE
    def update_task(self, task_id: int, updates: dict) -> Optional[dict]:
        """Update a task and return updated version."""
        updates['updated_at'] = datetime.now().isoformat()
        success = self.db.update(task_id, updates)
        if success:
            return self.get_task(task_id)
        return None
    
    def complete_task(self, task_id: int) -> Optional[dict]:
        """Mark a task as complete."""
        return self.update_task(task_id, {
            'status': 'completed',
            'completed_at': datetime.now().isoformat()
        })
    
    def uncomplete_task(self, task_id: int) -> Optional[dict]:
        """Mark a task as pending (uncomplete)."""
        return self.update_task(task_id, {
            'status': 'pending',
            'completed_at': None
        })
    
    def toggle_complete(self, task_id: int) -> Optional[dict]:
        """Toggle task completion status."""
        task = self.get_task(task_id)
        if not task:
            return None
        if task['status'] == 'completed':
            return self.uncomplete_task(task_id)
        return self.complete_task(task_id)
    
    # DELETE
    def delete_task(self, task_id: int) -> bool:
        """Delete a task by ID."""
        return self.db.delete(task_id)
    
    def delete_completed(self) -> int:
        """Delete all completed tasks. Returns count deleted."""
        completed = self.get_tasks_by_status('completed')
        count = 0
        for task in completed:
            if self.delete_task(task['id']):
                count += 1
        return count

Validation Before Operations

def create_task(self, task_data: dict) -> dict:
    """Create with validation."""
    # Validate required fields
    if not task_data.get('title'):
        raise ValueError("Title is required")
    
    # Validate title length
    if len(task_data['title']) > 200:
        raise ValueError("Title must be 200 characters or less")
    
    # Validate priority
    valid_priorities = ['low', 'medium', 'high', 'urgent']
    priority = task_data.get('priority', 'medium')
    if priority not in valid_priorities:
        raise ValueError(f"Priority must be one of: {valid_priorities}")
    
    # Proceed with creation
    return self._do_create(task_data)

Error Handling Pattern

from typing import Union

class TaskResult:
    """Result wrapper for operations."""
    def __init__(self, success: bool, data=None, error: str = None):
        self.success = success
        self.data = data
        self.error = error

def safe_create_task(self, task_data: dict) -> TaskResult:
    """Create task with error handling."""
    try:
        task = self.create_task(task_data)
        return TaskResult(True, data=task)
    except ValueError as e:
        return TaskResult(False, error=str(e))
    except Exception as e:
        return TaskResult(False, error=f"Unexpected error: {e}")

Common Operations

Batch Operations

def create_many(self, tasks: List[dict]) -> List[dict]:
    """Create multiple tasks."""
    return [self.create_task(t) for t in tasks]

def delete_many(self, task_ids: List[int]) -> int:
    """Delete multiple tasks by ID."""
    return sum(1 for id in task_ids if self.delete_task(id))

Existence Checks

def task_exists(self, task_id: int) -> bool:
    """Check if task exists."""
    return self.get_task(task_id) is not None

def get_task_or_raise(self, task_id: int) -> dict:
    """Get task or raise error if not found."""
    task = self.get_task(task_id)
    if not task:
        raise ValueError(f"Task {task_id} not found")
    return task

Best Practices

  • Always validate input before operations
  • Update updated_at on every modification
  • Return the modified object after updates
  • Use result objects for error handling
  • Keep operations atomic and focused
  • Log important operations for debugging