Loading...
Automated database migration management with rollback capabilities, validation, and multi-environment support
{
"hookConfig": {
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/database-migration-runner.sh",
"matchers": [
"write",
"edit"
]
}
}
},
"scriptContent": "#!/usr/bin/env bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\nif [ -z \"$FILE_PATH\" ]; then\n exit 0\nfi\n\n# Check if it's a migration-related file\nif [[ \"$FILE_PATH\" == *migration* ]] || [[ \"$FILE_PATH\" == *schema* ]] || [[ \"$FILE_PATH\" == *.sql ]]; then\n echo \"🗃️ Database migration file detected: $FILE_PATH\" >&2\n \n # Check for common migration frameworks\n if [ -f \"package.json\" ] && (grep -q \"knex\" package.json || grep -q \"sequelize\" package.json || grep -q \"typeorm\" package.json); then\n echo \"📦 Node.js migration framework detected\" >&2\n \n # Knex migrations\n if command -v npx &> /dev/null && npx knex --version &> /dev/null 2>&1; then\n echo \"🔧 Running Knex migration status check...\" >&2\n MIGRATION_STATUS=$(npx knex migrate:status 2>/dev/null || echo \"No pending migrations\")\n echo \"📊 Migration Status: $MIGRATION_STATUS\" >&2\n \n # Check for pending migrations\n if echo \"$MIGRATION_STATUS\" | grep -q \"pending\"; then\n echo \"⚠️ Pending migrations detected. Run 'npx knex migrate:latest' to apply them\" >&2\n else\n echo \"✅ All migrations are up to date\" >&2\n fi\n \n # Sequelize migrations\n elif command -v npx &> /dev/null && npx sequelize-cli --version &> /dev/null 2>&1; then\n echo \"🔧 Sequelize CLI detected\" >&2\n echo \"💡 Run 'npx sequelize-cli db:migrate:status' to check migration status\" >&2\n \n # TypeORM migrations\n elif command -v npx &> /dev/null && npx typeorm --version &> /dev/null 2>&1; then\n echo \"🔧 TypeORM detected\" >&2\n echo \"💡 Run 'npx typeorm migration:show' to check migration status\" >&2\n fi\n \n # Django migrations\n elif [ -f \"manage.py\" ]; then\n echo \"🐍 Django project detected\" >&2\n if command -v python &> /dev/null; then\n echo \"🔧 Checking Django migration status...\" >&2\n python manage.py showmigrations --plan 2>/dev/null | tail -5 | head -3 || echo \"💡 Run 'python manage.py showmigrations' to check status\" >&2\n fi\n \n # Rails migrations\n elif [ -f \"Gemfile\" ] && grep -q \"rails\" Gemfile; then\n echo \"💎 Rails project detected\" >&2\n if command -v bundle &> /dev/null; then\n echo \"🔧 Checking Rails migration status...\" >&2\n bundle exec rails db:migrate:status 2>/dev/null | tail -5 || echo \"💡 Run 'rails db:migrate:status' to check status\" >&2\n fi\n \n # Raw SQL files\n elif [[ \"$FILE_PATH\" == *.sql ]]; then\n echo \"📜 Raw SQL migration file detected\" >&2\n \n # Check file size and complexity\n if [ -f \"$FILE_PATH\" ]; then\n LINE_COUNT=$(wc -l < \"$FILE_PATH\" 2>/dev/null || echo \"0\")\n echo \"📊 SQL file contains $LINE_COUNT lines\" >&2\n \n # Check for potentially destructive operations\n if grep -i \"DROP\\|DELETE\\|TRUNCATE\" \"$FILE_PATH\" >/dev/null 2>&1; then\n echo \"⚠️ WARNING: Potentially destructive SQL operations detected (DROP/DELETE/TRUNCATE)\" >&2\n echo \"💡 Consider creating a backup before executing this migration\" >&2\n fi\n \n # Check for common patterns\n if grep -i \"CREATE TABLE\\|ALTER TABLE\\|CREATE INDEX\" \"$FILE_PATH\" >/dev/null 2>&1; then\n echo \"🏗️ Schema modification statements detected\" >&2\n fi\n \n if grep -i \"INSERT\\|UPDATE\" \"$FILE_PATH\" >/dev/null 2>&1; then\n echo \"📝 Data modification statements detected\" >&2\n fi\n fi\n fi\n \n # General migration best practices reminder\n echo \"📋 Migration Best Practices:\" >&2\n echo \" • Always backup database before running migrations\" >&2\n echo \" • Test migrations on development/staging first\" >&2\n echo \" • Ensure migrations are reversible when possible\" >&2\n echo \" • Use transactions for atomic operations\" >&2\n \nelse\n echo \"File $FILE_PATH is not a migration file, skipping analysis\" >&2\nfi\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/database-migration-runner.sh",
"matchers": [
"write",
"edit"
]
}
}
}#!/usr/bin/env bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Check if it's a migration-related file
if [[ "$FILE_PATH" == *migration* ]] || [[ "$FILE_PATH" == *schema* ]] || [[ "$FILE_PATH" == *.sql ]]; then
echo "🗃️ Database migration file detected: $FILE_PATH" >&2
# Check for common migration frameworks
if [ -f "package.json" ] && (grep -q "knex" package.json || grep -q "sequelize" package.json || grep -q "typeorm" package.json); then
echo "📦 Node.js migration framework detected" >&2
# Knex migrations
if command -v npx &> /dev/null && npx knex --version &> /dev/null 2>&1; then
echo "🔧 Running Knex migration status check..." >&2
MIGRATION_STATUS=$(npx knex migrate:status 2>/dev/null || echo "No pending migrations")
echo "📊 Migration Status: $MIGRATION_STATUS" >&2
# Check for pending migrations
if echo "$MIGRATION_STATUS" | grep -q "pending"; then
echo "⚠️ Pending migrations detected. Run 'npx knex migrate:latest' to apply them" >&2
else
echo "✅ All migrations are up to date" >&2
fi
# Sequelize migrations
elif command -v npx &> /dev/null && npx sequelize-cli --version &> /dev/null 2>&1; then
echo "🔧 Sequelize CLI detected" >&2
echo "💡 Run 'npx sequelize-cli db:migrate:status' to check migration status" >&2
# TypeORM migrations
elif command -v npx &> /dev/null && npx typeorm --version &> /dev/null 2>&1; then
echo "🔧 TypeORM detected" >&2
echo "💡 Run 'npx typeorm migration:show' to check migration status" >&2
fi
# Django migrations
elif [ -f "manage.py" ]; then
echo "🐍 Django project detected" >&2
if command -v python &> /dev/null; then
echo "🔧 Checking Django migration status..." >&2
python manage.py showmigrations --plan 2>/dev/null | tail -5 | head -3 || echo "💡 Run 'python manage.py showmigrations' to check status" >&2
fi
# Rails migrations
elif [ -f "Gemfile" ] && grep -q "rails" Gemfile; then
echo "💎 Rails project detected" >&2
if command -v bundle &> /dev/null; then
echo "🔧 Checking Rails migration status..." >&2
bundle exec rails db:migrate:status 2>/dev/null | tail -5 || echo "💡 Run 'rails db:migrate:status' to check status" >&2
fi
# Raw SQL files
elif [[ "$FILE_PATH" == *.sql ]]; then
echo "📜 Raw SQL migration file detected" >&2
# Check file size and complexity
if [ -f "$FILE_PATH" ]; then
LINE_COUNT=$(wc -l < "$FILE_PATH" 2>/dev/null || echo "0")
echo "📊 SQL file contains $LINE_COUNT lines" >&2
# Check for potentially destructive operations
if grep -i "DROP\|DELETE\|TRUNCATE" "$FILE_PATH" >/dev/null 2>&1; then
echo "⚠️ WARNING: Potentially destructive SQL operations detected (DROP/DELETE/TRUNCATE)" >&2
echo "💡 Consider creating a backup before executing this migration" >&2
fi
# Check for common patterns
if grep -i "CREATE TABLE\|ALTER TABLE\|CREATE INDEX" "$FILE_PATH" >/dev/null 2>&1; then
echo "🏗️ Schema modification statements detected" >&2
fi
if grep -i "INSERT\|UPDATE" "$FILE_PATH" >/dev/null 2>&1; then
echo "📝 Data modification statements detected" >&2
fi
fi
fi
# General migration best practices reminder
echo "📋 Migration Best Practices:" >&2
echo " • Always backup database before running migrations" >&2
echo " • Test migrations on development/staging first" >&2
echo " • Ensure migrations are reversible when possible" >&2
echo " • Use transactions for atomic operations" >&2
else
echo "File $FILE_PATH is not a migration file, skipping analysis" >&2
fi
exit 0Hook detects migration file but framework check fails
Verify package.json contains knex, sequelize, or typeorm dependency. Run npm install to ensure frameworks are installed. Check npx command availability and node_modules/.bin in PATH.
Knex migration status shows no pending despite new files
Run npx knex migrate:list to verify migration discovery. Check migration file naming follows timestamp pattern. Ensure knexfile.js configuration points to correct migrations directory.
PostToolUse hook triggers on non-migration SQL files
Refine file path pattern matching to exclude seed/query files. Add migration directory check: [[ $FILE_PATH == *migrations/* ]]. Update matchers to prevent false positives.
Destructive operation warning for safe rollback scripts
Hook warns on DROP/DELETE/TRUNCATE in any context. Add migration safety comments to suppress warnings. Consider splitting destructive down migrations into separate reviewed files.
Django migration detection fails in virtual environment
Activate virtualenv before hook runs: source venv/bin/activate in shell config. Use absolute python path from which python. Ensure manage.py is executable and in project root.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters