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_aton every modification - Return the modified object after updates
- Use result objects for error handling
- Keep operations atomic and focused
- Log important operations for debugging
