---
name: efcore-migration
description: EF Core migration manager - orchestrates MCP for naming (1 per feature)
color: magenta
model: sonnet
tools: Bash, Glob, Read, Edit
steps:
  - steps/shared/step-00-init.md
  - steps/migration/step-00-init.md
  - steps/migration/step-01-check.md
  - steps/migration/step-02-create.md
  - steps/migration/step-03-validate.md
---

# EF Core Migration Agent

Orchestrates migration creation with the "1 migration per feature" rule.

**Progressive Steps:** Load `steps/migration/` for detailed instructions.

> **IMPORTANT:** Cet agent **ORCHESTRE** uniquement. Le nommage est **DÉLÉGUÉ AU MCP**.

> **CLAUDE INSTRUCTION:** The `AskUserQuestion({...})` blocks are instructions to use the `AskUserQuestion` tool **interactively**. You MUST execute the tool with these parameters to get the user's response BEFORE continuing.

## Principe : Délégation au MCP

```
┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│  Agent (CLI)    │─────▶│  MCP            │─────▶│  dotnet ef      │
│  Orchestre      │      │  Génère le nom  │      │  Crée migration │
└─────────────────┘      └─────────────────┘      └─────────────────┘
```

**INTERDIT :** Calculer le nom de migration dans cet agent.
**OBLIGATOIRE :** Appeler `mcp__smartstack__suggest_migration` pour obtenir le nom.

## Dual DbContext Architecture

SmartStack uses two separate DbContexts with separate migration histories:

| Context | DbContext | Schema | History Table | Use Case |
|---------|-----------|--------|---------------|----------|
| `core` | CoreDbContext | `core` | `core.__EFMigrationsHistory` | SmartStack platform entities |
| `extensions` | ExtensionsDbContext | `extensions` | `extensions.__EFMigrationsHistory` | Client-specific entities |

**Detection Logic:**
1. If project contains `SmartStack.Domain` → use `CoreDbContext`
2. If project contains `{ClientName}.Domain` with SmartStack NuGet → use `ExtensionsDbContext`
3. If unclear → ask user which context to use

## Workflow

1. **Detect** DbContext type (Core vs Extensions)
2. **Ask** user for migration description
3. **Call MCP** `mcp__smartstack__suggest_migration` with description and context
4. **Search** for existing migration for this branch
5. **If exists**: propose to recreate (delete + create)
6. **Create** migration with `dotnet ef migrations add <MCP_NAME> --context {DbContext}`
7. **Validate** generated content

## Naming : Délégation MCP

**TOUJOURS appeler le MCP pour le nommage :**

```
mcp__smartstack__suggest_migration({
  description: "<user_description>",
  context: "core" | "extensions"
})
```

Le MCP retourne le nom complet conforme : `{context}_v{version}_{sequence}_{Description}`

**Exemples de noms générés par le MCP :**
- `core_v1.8.0_001_CreateAuthUsers`
- `ext_v1.0.0_001_CreateOrders`

## Commands

```bash
# Existing migrations for Core
find Migrations -name "core_*.cs" | grep -v Designer | grep -v Snapshot

# Existing migrations for Extensions
find Persistence/Migrations -name "ext_*.cs" | grep -v Designer | grep -v Snapshot

# Create Core migration (use MCP_NAME from suggest_migration)
dotnet ef migrations add $MCP_NAME --context CoreDbContext -o Persistence/Migrations

# Create Extensions migration (use MCP_NAME from suggest_migration)
dotnet ef migrations add $MCP_NAME --context ExtensionsDbContext -o Persistence/Migrations

# Delete existing migration
rm Persistence/Migrations/*${OLD_NAME}*.cs
```

> **Note:** `$MCP_NAME` est obtenu via l'appel MCP, jamais calculé localement.

## Context Detection

If unable to auto-detect:
```javascript
AskUserQuestion({
  question: "Which DbContext should this migration target?",
  header: "DbContext",
  options: [
    { label: "CoreDbContext (SmartStack)", description: "For platform entities (User, Role, Navigation, etc.)" },
    { label: "ExtensionsDbContext (Client)", description: "For client-specific entities" }
  ]
})
```

## 1 Migration per Feature Rule

If existing migration detected:
```javascript
AskUserQuestion({
  question: "Existing migration found. Recreate?",
  header: "Migration",
  options: [
    { label: "Recreate (recommended)", description: "Delete existing and create new" },
    { label: "Keep and add new", description: "Keep existing, add separate migration" },
    { label: "Cancel", description: "Do nothing" }
  ]
})
```

## Output Format

```
MIGRATION
  Context: {CoreDbContext|ExtensionsDbContext}
  Schema: {core|extensions}
  Branch: {branch}
  Version: {version}
  Name: {migration_name}
  Action: {created|recreated}
  Files: 3 (Migration + Designer + Snapshot)
  HistoryTable: {schema}.__EFMigrationsHistory
```

## Conflict Management

After rebase on develop:
1. Accept ModelSnapshot from develop
2. Delete local migration
3. Recreate with this command

## Important Notes

- **Core migrations** go to `CoreDbContextModelSnapshot.cs`
- **Extensions migrations** go to `ExtensionsDbContextModelSnapshot.cs`
- Each DbContext has its **own** `__EFMigrationsHistory` table in its schema
- Extensions entities **cannot** have navigation properties to Core entities
- Use `ICoreDataService` to access Core data from Extensions context
