Files
gh-tiboxtibo-custom-claude-…/commands/toduba-rollback.md
2025-11-30 09:01:56 +08:00

10 KiB
Raw Permalink Blame History

allowed-tools, argument-hint, description
allowed-tools argument-hint description
Bash
Read
Write
Glob
Grep
[--last] [--steps <n>] [--to <commit>] [--dry-run] [--force] Sistema di rollback con snapshot automatici per annullare modifiche

Toduba Rollback - Sistema di Rollback Intelligente ↩️

Obiettivo

Fornire un sistema di rollback sicuro e intelligente per annullare modifiche, con snapshot automatici prima di ogni operazione significativa.

Argomenti

  • --last: Rollback ultima operazione (default)
  • --steps <n>: Rollback di N operazioni
  • --to <commit>: Rollback a specific commit
  • --dry-run: Mostra cosa verrebbe rollbackato senza farlo
  • --force: Skip conferme di sicurezza
  • --list: Mostra snapshot disponibili

Argomenti ricevuti: $ARGUMENTS

Sistema di Snapshot

Auto-Snapshot Before Changes

# Automaticamente creato da orchestrator prima di modifiche
create_snapshot() {
  local snapshot_id="toduba-$(date +%Y%m%d-%H%M%S)"
  local snapshot_dir=".toduba/snapshots/$snapshot_id"

  mkdir -p "$snapshot_dir"

  # Save current state
  echo "📸 Creating snapshot: $snapshot_id"

  # 1. Git state
  git diff > "$snapshot_dir/uncommitted.diff"
  git status --porcelain > "$snapshot_dir/status.txt"
  git rev-parse HEAD > "$snapshot_dir/last_commit.txt"

  # 2. File list
  find . -type f -not -path "./.git/*" -not -path "./node_modules/*" \
    > "$snapshot_dir/files.txt"

  # 3. Metadata
  cat > "$snapshot_dir/metadata.json" <<EOF
{
  "id": "$snapshot_id",
  "timestamp": "$(date -Iseconds)",
  "description": "$1",
  "files_count": $(wc -l < "$snapshot_dir/files.txt"),
  "uncommitted_changes": $(git status --porcelain | wc -l),
  "user": "$(git config user.name)",
  "operation": "$2"
}
EOF

  # 4. Create restore point
  tar czf "$snapshot_dir/backup.tar.gz" \
    --exclude=".git" \
    --exclude="node_modules" \
    --exclude=".toduba/snapshots" \
    .

  echo "✅ Snapshot created: $snapshot_id"
  return 0
}

Processo di Rollback

Fase 1: Identificazione Snapshot

identify_rollback_target() {
  local target=""

  if [[ "$ARGUMENTS" == *"--last"* ]] || [ -z "$ARGUMENTS" ]; then
    # Get last snapshot
    target=$(ls -t .toduba/snapshots | head -1)
    echo "🎯 Target: Last operation ($target)"

  elif [[ "$ARGUMENTS" == *"--steps"* ]]; then
    # Get N snapshots back
    local steps=$(echo "$ARGUMENTS" | grep -oP '(?<=--steps )\d+')
    target=$(ls -t .toduba/snapshots | sed -n "${steps}p")
    echo "🎯 Target: $steps steps back ($target)"

  elif [[ "$ARGUMENTS" == *"--to"* ]]; then
    # Rollback to specific commit
    local commit=$(echo "$ARGUMENTS" | grep -oP '(?<=--to )\w+')
    echo "🎯 Target: Git commit $commit"
    git_rollback=true
  fi

  if [ -z "$target" ] && [ "$git_rollback" != true ]; then
    echo "❌ No valid rollback target found"
    exit 1
  fi

  ROLLBACK_TARGET="$target"
}

Fase 2: Pre-Rollback Analysis

analyze_rollback_impact() {
  echo ""
  echo "📊 Rollback Impact Analysis"
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━"

  local snapshot_dir=".toduba/snapshots/$ROLLBACK_TARGET"

  if [ -f "$snapshot_dir/metadata.json" ]; then
    # Parse metadata
    local timestamp=$(jq -r '.timestamp' "$snapshot_dir/metadata.json")
    local description=$(jq -r '.description' "$snapshot_dir/metadata.json")
    local files_count=$(jq -r '.files_count' "$snapshot_dir/metadata.json")

    echo "📅 Snapshot: $ROLLBACK_TARGET"
    echo "🕒 Created: $timestamp"
    echo "📝 Description: $description"
    echo "📁 Files: $files_count"
  fi

  # Current vs Target comparison
  echo ""
  echo "Changes to be reverted:"
  echo "━━━━━━━━━━━━━━━━━━━━━━"

  # Show file differences
  git diff --stat HEAD "$(cat $snapshot_dir/last_commit.txt 2>/dev/null)"

  # Count changes
  local added=$(git diff --numstat HEAD "$(cat $snapshot_dir/last_commit.txt)" | wc -l)
  local modified=$(git status --porcelain | grep "^ M" | wc -l)
  local deleted=$(git status --porcelain | grep "^ D" | wc -l)

  echo ""
  echo "Summary:"
  echo "   Added: $added files"
  echo "  ✏️ Modified: $modified files"
  echo "  ❌ Deleted: $deleted files"

  if [[ "$ARGUMENTS" == *"--dry-run"* ]]; then
    echo ""
    echo "🔍 DRY RUN MODE - No changes will be made"
    exit 0
  fi
}

Fase 3: Safety Checks

perform_safety_checks() {
  echo ""
  echo "🔒 Safety Checks"
  echo "━━━━━━━━━━━━━━━━━━━"

  # Check 1: Uncommitted changes
  if [ -n "$(git status --porcelain)" ]; then
    echo "⚠️  Warning: You have uncommitted changes"

    if [[ "$ARGUMENTS" != *"--force"* ]]; then
      read -p "Create backup before rollback? (Y/n): " backup_choice
      if [ "$backup_choice" != "n" ]; then
        create_snapshot "Pre-rollback backup" "manual"
      fi
    fi
  fi

  # Check 2: Running processes
  if pgrep -f "npm run dev" > /dev/null; then
    echo "⚠️  Warning: Development server is running"
    echo "   It will be stopped during rollback"
  fi

  # Check 3: Database state
  if [ -f ".toduba/db-version.txt" ]; then
    echo "⚠️  Warning: Database migrations may need reverting"
  fi

  # Final confirmation
  if [[ "$ARGUMENTS" != *"--force"* ]]; then
    echo ""
    echo "⚠️  This action cannot be undone (except by another rollback)"
    read -p "Proceed with rollback? (y/N): " confirm
    if [ "$confirm" != "y" ]; then
      echo "❌ Rollback cancelled"
      exit 0
    fi
  fi
}

Fase 4: Execute Rollback

execute_rollback() {
  echo ""
  echo "🔄 Executing Rollback"
  echo "━━━━━━━━━━━━━━━━━━━━━"

  local snapshot_dir=".toduba/snapshots/$ROLLBACK_TARGET"

  # Stop any running processes
  echo "📦 Stopping running processes..."
  pkill -f "npm run dev" 2>/dev/null || true
  pkill -f "npm start" 2>/dev/null || true

  # Git rollback if specified
  if [ "$git_rollback" = true ]; then
    echo "📝 Rolling back to commit: $commit"
    git reset --hard "$commit"
  else
    # File system rollback
    echo "📁 Restoring files from snapshot..."

    # Create safety backup
    mv . .toduba/pre_rollback_$(date +%s) 2>/dev/null || true

    # Extract snapshot
    tar xzf "$snapshot_dir/backup.tar.gz" -C .

    # Restore git state
    if [ -f "$snapshot_dir/uncommitted.diff" ]; then
      git apply "$snapshot_dir/uncommitted.diff" 2>/dev/null || true
    fi
  fi

  # Post-rollback tasks
  post_rollback_tasks
}

post_rollback_tasks() {
  echo ""
  echo "🔧 Post-Rollback Tasks"
  echo "━━━━━━━━━━━━━━━━━━━━━"

  # Reinstall dependencies if package.json changed
  if git diff HEAD~1 HEAD --name-only | grep -q "package.json"; then
    echo "📦 Reinstalling dependencies..."
    npm install
  fi

  # Run migrations if needed
  if [ -f ".toduba/run-migrations.sh" ]; then
    echo "🗄️ Running database migrations..."
    ./.toduba/run-migrations.sh
  fi

  # Clear caches
  echo "🧹 Clearing caches..."
  rm -rf .cache/ dist/ build/ 2>/dev/null || true

  # Rebuild if needed
  if [ -f "package.json" ] && grep -q '"build"' package.json; then
    echo "🔨 Rebuilding project..."
    npm run build
  fi
}

Fase 5: Rollback Report

## 📋 Rollback Report

**Timestamp**: [DATE TIME]
**Rollback Type**: [snapshot/git]
**Target**: [SNAPSHOT_ID or COMMIT]

### ✅ Actions Completed
- [x] Stopped running processes
- [x] Created safety backup
- [x] Restored files from snapshot
- [x] Applied uncommitted changes
- [x] Reinstalled dependencies
- [x] Cleared caches
- [x] Rebuilt project

### 📊 Statistics
- Files restored: 156
- Dependencies updated: 3
- Cache cleared: 12MB
- Time taken: 45 seconds

### ⚠️ Manual Actions Required
1. Restart development server: `npm run dev`
2. Check database state if applicable
3. Verify application functionality
4. Review restored code changes

### 🔄 Rollback History

toduba-20241031-143022 ← CURRENT toduba-20241031-140515 toduba-20241031-134208 toduba-20241031-125633


### 💡 Next Steps
- Test application thoroughly
- If issues persist, rollback further: `/toduba-rollback --steps 2`
- To undo this rollback: `/toduba-rollback --last`

Snapshot Management

List Available Snapshots

list_snapshots() {
  echo "📸 Available Snapshots"
  echo "━━━━━━━━━━━━━━━━━━━━━━━"

  for snapshot in .toduba/snapshots/*/metadata.json; do
    if [ -f "$snapshot" ]; then
      local id=$(jq -r '.id' "$snapshot")
      local time=$(jq -r '.timestamp' "$snapshot")
      local desc=$(jq -r '.description' "$snapshot")
      local size=$(du -sh "$(dirname "$snapshot")" | cut -f1)

      printf "%-25s %s  %6s  %s\n" "$id" "$time" "$size" "$desc"
    fi
  done

  echo ""
  echo "Total: $(ls -1 .toduba/snapshots | wc -l) snapshots"
  echo "Disk usage: $(du -sh .toduba/snapshots | cut -f1)"
}

Auto-Cleanup Old Snapshots

cleanup_old_snapshots() {
  # Keep only last 20 snapshots or 7 days
  local max_age=7  # days
  local max_count=20

  echo "🧹 Cleaning old snapshots..."

  # Delete by age
  find .toduba/snapshots -type d -mtime +$max_age -exec rm -rf {} \;

  # Delete by count
  ls -t .toduba/snapshots | tail -n +$((max_count + 1)) | \
    xargs -I {} rm -rf ".toduba/snapshots/{}"

  echo "✅ Cleanup complete"
}

Integration with Orchestrator

The orchestrator automatically creates snapshots before:

  • Major refactoring
  • Database migrations
  • Dependency updates
  • Bulk file operations
  • Deployment preparations
// In orchestrator work package
if (taskComplexity === 'high' || modifiedFiles > 10) {
  await createSnapshot(`Pre-${taskName}`, taskName);
}

Error Recovery

handle_rollback_error() {
  echo "❌ Rollback failed!"
  echo ""
  echo "Emergency recovery options:"
  echo "1. Check .toduba/pre_rollback_* for backup"
  echo "2. Use git history: git reflog"
  echo "3. Restore from .toduba/snapshots manually"
  echo "4. Contact support with error details"

  # Save error log
  echo "$1" > .toduba/rollback_error.log
  exit 1
}