---
name: step-03-create
description: Create consolidated migration with MCP naming
next_step: step-04-validate.md
---

# Step 3: Create Consolidated Migration

## YOUR TASK:

Generate a new consolidated migration capturing all branch changes.

**MANDATORY:** Use MCP for naming. NEVER hardcode.

**Previous step:** `step-02-fetch.md`

---

## EXECUTION SEQUENCE:

### 1. Build Description

```bash
# Extract feature name from branch
FEATURE_NAME=$(echo "$CURRENT_BRANCH" | sed 's|.*/||' | sed 's/-/ /g' | \
  awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2))}1' | \
  tr -d ' ')

DESCRIPTION="${FEATURE_NAME}Consolidated"

echo "Description: $DESCRIPTION"
```

### 2. Call MCP for Migration Name (MANDATORY)

```javascript
// DESCRIPTION = from above (e.g., "UserAuthConsolidated")
// DBCONTEXT_TYPE = "core" or "extensions" (from detect_dbcontext)

const result = await mcp__smartstack__suggest_migration({
  description: DESCRIPTION,
  context: DBCONTEXT_TYPE    // NEVER hardcode!
});

// Result example: core_v1.7.0_001_UserAuthConsolidated
MIGRATION_NAME = result.migrationName;
```

**FORBIDDEN:**
- Manual name calculation
- Hardcoding context

### 3. Create Migration

```bash
echo ""
echo "Creating migration: $MIGRATION_NAME"
echo "Context: $DBCONTEXT"
echo ""

dotnet ef migrations add "$MIGRATION_NAME" \
  --context "$DBCONTEXT" \
  --project "$INFRA_PROJECT" \
  --startup-project "$STARTUP_PROJECT" \
  -o Persistence/Migrations \
  --verbose
```

### 4. Verify Files Created

```bash
MIGRATION_FILE="$MIGRATIONS_DIR/${MIGRATION_NAME}.cs"
DESIGNER_FILE="$MIGRATIONS_DIR/${MIGRATION_NAME}.Designer.cs"

if [ ! -f "$MIGRATION_FILE" ]; then
  echo "ERROR: Migration file not created"

  # Restore backup
  cp "$BACKUP_DIR"/*.cs "$MIGRATIONS_DIR/"
  echo "Restored from backup"
  exit 1
fi

echo ""
echo "Migration created:"
echo "  $MIGRATION_FILE"
echo "  $DESIGNER_FILE"
```

### 5. Inject SQL Objects (Functions, Views, SP)

EF Core does NOT generate DDL for TVF, views, and stored procedures.
SQL source scripts are in `Persistence/SqlObjects/` (Embedded Resources).
After a rebase-snapshot, they must be re-injected into the consolidated migration.

```bash
# Check if SqlObjects folder exists with .sql files
SQL_OBJECTS_DIR="$INFRA_PROJECT_DIR/Persistence/SqlObjects"
SQL_FILES=$(find "$SQL_OBJECTS_DIR" -name "*.sql" 2>/dev/null | wc -l)

if [ "$SQL_FILES" -gt 0 ]; then
  echo ""
  echo "Found $SQL_FILES SQL object(s) in SqlObjects/"
  echo "Injecting SqlObjectHelper.ApplyAll(migrationBuilder) into migration..."

  # Validate migration file path before sed operations
  if [ ! -f "$MIGRATION_FILE" ]; then
    echo "ERROR: Migration file not found: $MIGRATION_FILE"
    exit 1
  fi
  if ! echo "$MIGRATION_FILE" | grep -qE '\.cs$'; then
    echo "ERROR: Invalid migration file path (not .cs): $MIGRATION_FILE"
    exit 1
  fi

  # Add using directive if not present
  if ! grep -q "using SmartStack.Infrastructure.Persistence.SqlObjects;" "$MIGRATION_FILE"; then
    sed -i '1s/^/using SmartStack.Infrastructure.Persistence.SqlObjects;\n/' "$MIGRATION_FILE"
  fi

  # Add SqlObjectHelper.ApplyAll at the end of Up() method
  sed -i '/protected override void Up/,/^        }/ {
    /^        }/ i\
\            // Apply SQL objects (TVF, Views, SP) from embedded resources\
\            SqlObjectHelper.ApplyAll(migrationBuilder);
  }' "$MIGRATION_FILE"

  # Verify injection succeeded (fallback to manual step if sed pattern didn't match)
  if ! grep -q "SqlObjectHelper.ApplyAll" "$MIGRATION_FILE"; then
    echo "WARNING: Automatic injection failed (indentation pattern may differ)"
    echo ""
    echo "MANUAL STEP REQUIRED: Add these lines inside the Up() method before the closing brace:"
    echo '    using SmartStack.Infrastructure.Persistence.SqlObjects;'
    echo '    ...'
    echo '    SqlObjectHelper.ApplyAll(migrationBuilder);'
    echo ""
    echo "File: $MIGRATION_FILE"
  else
    echo "  SqlObjectHelper.ApplyAll(migrationBuilder) injected"
  fi
  find "$SQL_OBJECTS_DIR" -name "*.sql" -exec basename {} \; | while read f; do
    echo "  - $f"
  done
else
  echo ""
  echo "No SQL objects found in SqlObjects/ - skipping injection"
fi
```

---

## STATE OUTPUT:

| Variable | Description |
|----------|-------------|
| `{migration_name}` | Name from MCP |
| `{migration_file}` | Path to .cs file |

---

## SUCCESS CRITERIA:

- MCP called successfully
- Migration files created

## NEXT STEP:

→ `step-04-validate.md`
