---
description: Phase 3 - Smart commit with EF Core migration validation
agent: gitflow-commit
model: sonnet
args: [message]
---

# Phase 3: COMMIT - Migration-aware commits

You are an expert in GitFlow and EF Core. Manage commits with validation of .NET migrations.

> **CLAUDE INSTRUCTION:** The `AskUserQuestion({...})` blocks below are instructions for using the `AskUserQuestion` tool **interactively**. You MUST execute the tool with these parameters to get the user's response BEFORE continuing. DO NOT display this code - WAIT for the response.

**Argument:** `$ARGUMENTS` = commit message (optional, generated if absent)

---

## ETAPE 0: GARDE-FOUS PRE-COMMIT

> **PROTECTION:** Verifications de securite AVANT toute operation de commit.

### 0.1 Protection des branches

```bash
CURRENT=$(git rev-parse --abbrev-ref HEAD)

# ═══════════════════════════════════════════════════════════════
# BLOCAGE: Commit direct sur main
# ═══════════════════════════════════════════════════════════════
if [[ "$CURRENT" == "main" ]]; then
  echo ""
  echo "╔══════════════════════════════════════════════════════════════════════════════╗"
  echo "║  ⛔ COMMIT BLOQUE - BRANCHE PROTEGEE                                          ║"
  echo "╠══════════════════════════════════════════════════════════════════════════════╣"
  echo "║  Vous etes sur 'main' - les commits directs ne sont pas autorises.           ║"
  echo "║                                                                              ║"
  echo "║  GitFlow interdit les commits directs sur main car:                          ║"
  echo "║  - main represente le code en production                                     ║"
  echo "║  - Les changements doivent passer par release ou hotfix                      ║"
  echo "║                                                                              ║"
  echo "║  ALTERNATIVES:                                                               ║"
  echo "║  → Correction urgente?   /gitflow:10-start hotfix <nom>                      ║"
  echo "║  → Nouvelle release?     /gitflow:10-start release                           ║"
  echo "╚══════════════════════════════════════════════════════════════════════════════╝"
  echo ""
  exit 1
fi

# ═══════════════════════════════════════════════════════════════
# AVERTISSEMENT: Commit direct sur develop
# ═══════════════════════════════════════════════════════════════
if [[ "$CURRENT" == "develop" ]]; then
  echo ""
  echo "╔══════════════════════════════════════════════════════════════════════════════╗"
  echo "║  ⚠️  ATTENTION - COMMIT SUR DEVELOP                                           ║"
  echo "╠══════════════════════════════════════════════════════════════════════════════╣"
  echo "║  Vous etes sur 'develop' - les commits directs sont deconseilles.            ║"
  echo "║                                                                              ║"
  echo "║  GitFlow recommande de passer par des branches feature car:                  ║"
  echo "║  - Permet la review avant integration                                        ║"
  echo "║  - Isole les changements en cours                                            ║"
  echo "║  - Facilite le rollback si necessaire                                        ║"
  echo "║                                                                              ║"
  echo "║  ALTERNATIVE RECOMMANDEE:                                                    ║"
  echo "║  → /gitflow:10-start feature <nom>                                           ║"
  echo "╚══════════════════════════════════════════════════════════════════════════════╝"
  echo ""
fi
```

**Si sur develop, demander confirmation:**
```javascript
if (CURRENT === "develop") {
  AskUserQuestion({
    questions: [{
      question: "Voulez-vous vraiment committer directement sur develop ?",
      header: "Confirm",
      options: [
        { label: "Non, creer une feature", description: "Recommande - /gitflow:10-start feature" },
        { label: "Oui, commit direct", description: "Non recommande - bypass GitFlow" }
      ],
      multiSelect: false
    }]
  })

  if (response === "Non, creer une feature") {
    // Executer le processus RESCUE TO FEATURE
    // Voir section 0.1.1 ci-dessous pour les details
    executeRescueToFeature()
  }
}
```

### 0.1.1 RESCUE TO FEATURE - Sauvetage des modifications develop vers feature

> **CLAUDE INSTRUCTION:** Cette section est executee quand l'utilisateur choisit "Non, creer une feature".
> Elle analyse l'etat de develop et sauve TOUT le travail vers une feature branch.

**ETAPE R1: Analyser l'etat complet de develop**

```bash
# Fetch pour avoir les infos a jour
git fetch origin --quiet 2>/dev/null

# Etat du working directory
STAGED=$(git diff --cached --name-only | wc -l)
MODIFIED=$(git diff --name-only | wc -l)
UNTRACKED=$(git ls-files --others --exclude-standard | wc -l)

# Determiner si dirty
if [ "$STAGED" -gt 0 ] || [ "$MODIFIED" -gt 0 ] || [ "$UNTRACKED" -gt 0 ]; then
  HAS_CHANGES="true"
else
  HAS_CHANGES="false"
fi

# Commits locaux non pushes
LOCAL_COMMITS=$(git rev-list --count origin/develop..HEAD 2>/dev/null || echo "0")

# Commits distants non recuperes
REMOTE_COMMITS=$(git rev-list --count HEAD..origin/develop 2>/dev/null || echo "0")

# Determiner l'etat de synchronisation
if [ "$LOCAL_COMMITS" -eq 0 ] && [ "$REMOTE_COMMITS" -eq 0 ]; then
  SYNC_STATE="SYNCED"
elif [ "$LOCAL_COMMITS" -gt 0 ] && [ "$REMOTE_COMMITS" -eq 0 ]; then
  SYNC_STATE="AHEAD"
elif [ "$LOCAL_COMMITS" -eq 0 ] && [ "$REMOTE_COMMITS" -gt 0 ]; then
  SYNC_STATE="BEHIND"
else
  SYNC_STATE="DIVERGED"
fi

echo ""
echo "=============================================================================="
echo "                    ANALYSE DE DEVELOP"
echo "=============================================================================="
echo ""
echo "Working directory: $HAS_CHANGES"
echo "  - Fichiers stages: $STAGED"
echo "  - Fichiers modifies: $MODIFIED"
echo "  - Fichiers non suivis: $UNTRACKED"
echo ""
echo "Commits locaux (non pushes): $LOCAL_COMMITS"
echo "Commits distants (a recuperer): $REMOTE_COMMITS"
echo "Etat de synchronisation: $SYNC_STATE"
echo ""

# Afficher les commits locaux si present
if [ "$LOCAL_COMMITS" -gt 0 ]; then
  echo "COMMITS LOCAUX:"
  echo "------------------------------------------------------------------------------"
  git log origin/develop..HEAD --oneline
  echo "------------------------------------------------------------------------------"
fi

# Afficher les commits distants si present
if [ "$REMOTE_COMMITS" -gt 0 ]; then
  echo ""
  echo "COMMITS DISTANTS A RECUPERER:"
  echo "------------------------------------------------------------------------------"
  git log HEAD..origin/develop --oneline
  echo "------------------------------------------------------------------------------"
fi

echo "=============================================================================="
```

**ETAPE R2: Traitement selon le cas detecte**

```javascript
// CAS 1: CLEAN - Rien a sauver
if (HAS_CHANGES === "false" && LOCAL_COMMITS === 0 && SYNC_STATE === "SYNCED") {
  console.log("")
  console.log("==============================================================================")
  console.log("                    DEVELOP EST PROPRE")
  console.log("==============================================================================")
  console.log("")
  console.log("Aucune modification detectee sur develop.")
  console.log("Vous pouvez creer une feature directement.")
  console.log("")
  console.log("PROCHAINE ETAPE:")
  console.log("  /gitflow:10-start feature <nom>")
  console.log("")
  console.log("==============================================================================")
  exit(0)
}

// CAS 2-9: Il y a quelque chose a sauver - Demander le nom de la feature
```

**Generer un nom suggere depuis les commits (si applicable):**

```bash
# ═══════════════════════════════════════════════════════════════
# FONCTION DE NORMALISATION DES NOMS
# ═══════════════════════════════════════════════════════════════
normalize_name() {
  local input="$1"
  local max_length="${2:-50}"

  # 1. Convertir en minuscules
  local result=$(echo "$input" | tr '[:upper:]' '[:lower:]')

  # 2. Supprimer les accents (francais)
  result=$(echo "$result" | sed 'y/àâäéèêëïîôùûüçÀÂÄÉÈÊËÏÎÔÙÛÜÇ/aaaeeeeiioouucaaaeeeeiioouuc/')

  # 3. Remplacer les espaces, underscores et caracteres speciaux par des tirets
  result=$(echo "$result" | sed 's/[ _:()]/-/g')

  # 4. Supprimer les caracteres non autorises (garder uniquement a-z, 0-9, -)
  result=$(echo "$result" | sed 's/[^a-z0-9-]//g')

  # 5. Supprimer les tirets multiples
  result=$(echo "$result" | sed 's/--*/-/g')

  # 6. Supprimer les tirets en debut/fin
  result=$(echo "$result" | sed 's/^-//;s/-$//')

  # 7. Tronquer a la longueur max
  result=$(echo "$result" | cut -c1-$max_length)

  # 8. Supprimer le tiret final apres troncature
  result=$(echo "$result" | sed 's/-$//')

  echo "$result"
}

# Si des commits locaux existent, extraire un nom suggere du premier commit
if [ "$LOCAL_COMMITS" -gt 0 ]; then
  FIRST_COMMIT_MSG=$(git log -1 --format='%s' origin/develop..HEAD)
  # Normaliser avec la fonction
  SUGGESTED_NAME=$(normalize_name "$FIRST_COMMIT_MSG" 40)
  echo "Nom suggere: $SUGGESTED_NAME"
fi
```

**Demander la description de la feature:**

> **NOTE:** Le prefix `feature/` reste TOUJOURS en anglais.
> Seule la partie descriptive utilise la langue configuree.

```javascript
// Lire la config de langue depuis .claude/gitflow/config.json
const langConfig = readConfig()?.language || { code: "en" }
const isEnglish = langConfig.code === "en"

// Construire les options selon qu'on a un nom suggere ou non
const options = []

if (SUGGESTED_NAME && SUGGESTED_NAME.length > 0) {
  options.push({ label: SUGGESTED_NAME, description: "Genere depuis vos commits (Recommande)" })
}

// Suggestions de verbes d'action selon la langue
// Le prefix de branche "feature/" ne change PAS
if (isEnglish) {
  options.push({ label: "add-", description: "Add a new feature → feature/add-..." })
  options.push({ label: "update-", description: "Update existing → feature/update-..." })
  options.push({ label: "fix-", description: "Fix a bug → feature/fix-..." })
  options.push({ label: "refactor-", description: "Refactor code → feature/refactor-..." })
} else {
  options.push({ label: "ajouter-", description: "Nouvelle fonctionnalite → feature/ajouter-..." })
  options.push({ label: "modifier-", description: "Modifier existant → feature/modifier-..." })
  options.push({ label: "corriger-", description: "Corriger un bug → feature/corriger-..." })
  options.push({ label: "refactorer-", description: "Refactorer du code → feature/refactorer-..." })
}

AskUserQuestion({
  questions: [{
    question: isEnglish
      ? "Describe the feature (branch will be feature/your-description)"
      : "Decrivez la feature (branche sera feature/votre-description)",
    header: "Feature",
    options: options,
    multiSelect: false
  }]
})

// Le nom fourni par l'utilisateur (via option ou "Other")
RAW_FEATURE_NAME = response
```

**Normaliser le nom saisi par l'utilisateur:**

```bash
# ═══════════════════════════════════════════════════════════════
# NORMALISATION OBLIGATOIRE DU NOM DE FEATURE
# ═══════════════════════════════════════════════════════════════
# Le nom saisi par l'utilisateur peut contenir:
# - Des accents (e, a, etc.)
# - Des espaces
# - Des majuscules
# - Des caracteres speciaux
#
# Exemples de normalisation:
# "Ajouter l'authentification" → "ajouter-lauthentification"
# "Fix bug dans le Login !!" → "fix-bug-dans-le-login"
# "Améliorer performance API" → "ameliorer-performance-api"
# ═══════════════════════════════════════════════════════════════

FEATURE_NAME=$(normalize_name "$RAW_FEATURE_NAME" 50)
FEATURE_BRANCH="feature/${FEATURE_NAME}"

# Afficher la normalisation si differente
if [ "$RAW_FEATURE_NAME" != "$FEATURE_NAME" ]; then
  echo ""
  echo "Nom normalise: '$RAW_FEATURE_NAME' → '$FEATURE_NAME'"
fi
```

**ETAPE R3: Confirmer si cas complexe (divergence ou rebase necessaire)**

```javascript
// Si divergence ou rebase necessaire, demander confirmation
if (SYNC_STATE === "DIVERGED" || (LOCAL_COMMITS > 0 && REMOTE_COMMITS > 0)) {
  AskUserQuestion({
    questions: [{
      question: "Situation complexe detectee. Comment proceder ?",
      header: "Strategy",
      options: [
        { label: "Rebase (Recommande)", description: "Rejouer vos commits sur origin/develop a jour" },
        { label: "Sauvegarder uniquement", description: "Creer la feature sans rebase (vous devrez rebase plus tard)" },
        { label: "Annuler", description: "Ne rien faire, je gere manuellement" }
      ],
      multiSelect: false
    }]
  })

  if (response === "Annuler") {
    console.log("Operation annulee.")
    exit(0)
  }

  STRATEGY = response
}
```

**ETAPE R4: Executer le rescue**

```bash
echo ""
echo "=== RESCUE EN COURS ==="
echo ""

# Point de restauration (toujours creer un backup)
RESCUE_TAG="rescue/develop-$(date +%Y%m%d-%H%M%S)"
git tag "${RESCUE_TAG}" HEAD
echo "[1/N] Point de restauration cree: ${RESCUE_TAG}"

# ═══════════════════════════════════════════════════════════════
# EXECUTION SELON LE CAS
# ═══════════════════════════════════════════════════════════════

STEP=2

# Si modifications non committees: stash
if [ "$HAS_CHANGES" = "true" ]; then
  git stash push -m "gitflow-rescue: WIP pour ${FEATURE_BRANCH}" --include-untracked
  echo "[$STEP/N] Modifications sauvegardees (stash)"
  STASHED="true"
  STEP=$((STEP + 1))
fi

# Si commits locaux: creer branche puis reset develop
if [ "$LOCAL_COMMITS" -gt 0 ]; then
  # Creer la feature branch a partir de HEAD actuel (avec les commits)
  git branch "${FEATURE_BRANCH}"
  echo "[$STEP/N] Branche ${FEATURE_BRANCH} creee avec ${LOCAL_COMMITS} commits"
  STEP=$((STEP + 1))

  # Reset develop a origin/develop
  git reset --hard origin/develop
  echo "[$STEP/N] develop reset a origin/develop"
  STEP=$((STEP + 1))

  # Checkout la feature
  git checkout "${FEATURE_BRANCH}"
  echo "[$STEP/N] Bascule sur ${FEATURE_BRANCH}"
  STEP=$((STEP + 1))

  # Si behind ET strategie rebase: rebaser sur develop a jour
  if [ "$REMOTE_COMMITS" -gt 0 ] && [ "$STRATEGY" = "Rebase (Recommande)" ]; then
    echo "[$STEP/N] Rebase en cours..."
    if git rebase origin/develop; then
      echo "    Rebase reussi"
    else
      echo ""
      echo "=============================================================================="
      echo "                    CONFLITS DE REBASE DETECTES"
      echo "=============================================================================="
      echo ""
      echo "Des conflits ont ete detectes lors du rebase."
      echo ""
      echo "RESOLUTION:"
      echo "  1. Resolvez les conflits dans les fichiers marques"
      echo "  2. git add <fichiers resolus>"
      echo "  3. git rebase --continue"
      echo ""
      echo "OU pour annuler:"
      echo "  git rebase --abort"
      echo ""
      echo "Point de restauration: ${RESCUE_TAG}"
      echo "  Restaurer: git checkout develop && git reset --hard ${RESCUE_TAG}"
      echo ""
      echo "=============================================================================="
      exit 1
    fi
    STEP=$((STEP + 1))
  fi

else
  # Pas de commits locaux: simple checkout -b
  # Si behind: pull d'abord
  if [ "$REMOTE_COMMITS" -gt 0 ]; then
    git pull origin develop --ff-only
    echo "[$STEP/N] develop synchronise avec origin"
    STEP=$((STEP + 1))
  fi

  git checkout -b "${FEATURE_BRANCH}"
  echo "[$STEP/N] Branche ${FEATURE_BRANCH} creee"
  STEP=$((STEP + 1))
fi

# Restaurer le stash si applicable
if [ "$STASHED" = "true" ]; then
  git stash pop
  echo "[$STEP/N] Modifications restaurees"
fi

# ═══════════════════════════════════════════════════════════════
# AFFICHER LE RESULTAT
# ═══════════════════════════════════════════════════════════════

echo ""
echo "=============================================================================="
echo "                    RESCUE REUSSI"
echo "=============================================================================="
echo ""
echo "Feature creee: ${FEATURE_BRANCH}"
if [ "$LOCAL_COMMITS" -gt 0 ]; then
  echo "Commits deplaces: ${LOCAL_COMMITS}"
fi
if [ "$STASHED" = "true" ]; then
  echo "Modifications restaurees: $(git status --short | wc -l) fichiers"
fi
echo ""
echo "develop: Propre et synchronise avec origin"
echo "${FEATURE_BRANCH}: Contient tout votre travail"
echo ""
echo "PROCHAINES ETAPES:"
echo "  /gitflow:3-commit       -> Committer vos modifications"
echo "  /gitflow:7-pull-request -> Creer une PR quand pret"
echo ""
echo "Point de restauration: ${RESCUE_TAG}"
echo "  En cas de probleme: git checkout develop && git reset --hard ${RESCUE_TAG}"
echo ""
echo "=============================================================================="
```

---

### 0.2 Verification synchronisation

```bash
# Verifier si la branche est a jour avec le remote
git fetch origin --quiet 2>/dev/null

BEHIND=$(git rev-list --count HEAD..origin/$CURRENT 2>/dev/null || echo "0")

if [ "$BEHIND" -gt 0 ]; then
  echo ""
  echo "┌──────────────────────────────────────────────────────────────────────────────┐"
  echo "│  ⚠️  BRANCHE EN RETARD                                                        │"
  echo "├──────────────────────────────────────────────────────────────────────────────┤"
  echo "│  Votre branche est $BEHIND commits en retard par rapport au remote.          │"
  echo "│                                                                              │"
  echo "│  RECOMMANDATION:                                                             │"
  echo "│  → Synchronisez d'abord: git pull --rebase origin $CURRENT                   │"
  echo "│  → Ou utilisez: /gitflow:13-sync                                             │"
  echo "└──────────────────────────────────────────────────────────────────────────────┘"
  echo ""
fi
```

**Si en retard, demander synchronisation:**
```javascript
if (BEHIND > 0) {
  AskUserQuestion({
    questions: [{
      question: `Votre branche est ${BEHIND} commits en retard. Synchroniser ?`,
      header: "Sync",
      options: [
        { label: "Oui, synchroniser", description: "git pull --rebase (Recommande)" },
        { label: "Non, continuer", description: "Commit sans sync (risque de conflit au push)" }
      ],
      multiSelect: false
    }]
  })

  if (response === "Oui, synchroniser") {
    // Executer git pull --rebase
    result = exec("git pull --rebase origin " + CURRENT)
    if (result.exitCode !== 0) {
      console.log("Conflits detectes. Resolvez-les puis relancez /gitflow:3-commit")
      exit(1)
    }
  }
}
```

### 0.3 Verification working directory

```bash
# Verifier s'il y a des fichiers a committer
STAGED=$(git diff --cached --name-only | wc -l)
MODIFIED=$(git diff --name-only | wc -l)
UNTRACKED=$(git ls-files --others --exclude-standard | wc -l)

if [ "$STAGED" -eq 0 ] && [ "$MODIFIED" -eq 0 ] && [ "$UNTRACKED" -eq 0 ]; then
  echo ""
  echo "✅ Rien a committer - working directory propre"
  echo ""
  exit 0
fi

# Afficher resume
echo ""
echo "FICHIERS DETECTES:"
echo "  Staged:    $STAGED"
echo "  Modified:  $MODIFIED"
echo "  Untracked: $UNTRACKED"
echo ""
```

---

## Workflow

### 1. Analyze files

- Staged files
- Modified files not staged
- Untracked files
- Detect migration files in each category

### 2. Validate migrations

A valid EF Core migration = **3 files** :
- `{Timestamp}_{Name}.cs` - Main migration
- `{Timestamp}_{Name}.Designer.cs` - Metadata
- `{Context}ModelSnapshot.cs` - Model state

**Checks:**
- All 3 files are present
- Build compiles (`dotnet build`)
- No ModelSnapshot conflicts with develop

### 3. ⚠️ SAFETY CHECK - Destructive operations

**BLOCKING** - Scan migrations for dangerous operations :

```bash
# Patterns to detect in migration .cs files
grep -n "DropTable\|DropColumn\|DropIndex\|DropForeignKey\|DeleteData" {migration}.cs
grep -n "migrationBuilder.Sql" {migration}.cs | grep -i "DELETE\|DROP\|TRUNCATE"
```

**If detected :**

```
╔══════════════════════════════════════════════════════════╗
║  ⛔ DESTRUCTIVE OPERATIONS DETECTED                       ║
╠══════════════════════════════════════════════════════════╣
║  File: {migration}.cs                                    ║
║  Line {X}: DropTable("Users")                            ║
║  Line {Y}: DropColumn("Email", "Customers")              ║
╠══════════════════════════════════════════════════════════╣
║  RISKS:                                                  ║
║  - Irreversible data loss                                ║
║  - Verify that you have a BACKUP                         ║
╚══════════════════════════════════════════════════════════╝
```

**Actions:**
1. Display detailed alert (file, line, operation)
2. Request explicit confirmation: "Do you confirm? (yes/no)"
3. If "no" → Cancel commit
4. If "yes" → Log in [.claude/gitflow/logs/](.claude/gitflow/logs/)`dangerous-migrations.json`
5. Continue commit

**Dangerous patterns:**

| Pattern | Risk | Level |
|---------|------|-------|
| `DropTable` | Delete entire table | CRITICAL |
| `DropColumn` | Data loss in column | CRITICAL |
| `DeleteData` | Delete rows | CRITICAL |
| `DropForeignKey` | Break integrity | HIGH |
| `DropIndex` | Performance impact | MEDIUM |
| `Sql("DELETE...")` | Raw destructive SQL | CRITICAL |
| `Sql("DROP...")` | Raw destructive SQL | CRITICAL |
| `Sql("TRUNCATE...")` | Empty table | CRITICAL |

### 4. Classify commit

| Files | Type | Prefix |
|-------|------|--------|
| Migrations only | migration | `db(migrations):` |
| Migrations + code | mixed | `feat:` or `fix:` |
| Code without migration | code | Based on branch type |
| Config/docs | chore | `chore:` |

### 5. Generate message (if absent)

> **CLAUDE INSTRUCTION - REDACTION EXPERTE DES COMMITS**
>
> Chaque message de commit doit etre **auto-explicatif** et repondre a 3 questions:
> 1. **Quel probleme existait?** (justifie le changement)
> 2. **Quelle solution?** (explique l'approche technique)
> 3. **Quel gain?** (motive l'adoption)

#### 5.1 Format standard - Commit simple

```
{type}({scope}): {resume impact en 50 chars max}

{Pour chaque modification significative, UN PARAGRAPHE structure:}

**{NOM_CHANGEMENT}**
Resout le probleme ou {description situation problematique}.
Implemente {solution technique} qui permet desormais de {capacite gagnee}.
```

#### 5.2 Format expert - Commit multi-changements

```
{type}({scope}): {verbe d'impact} {objet} pour {objectif}

**{CHANGEMENT_1}**
PROBLEME: {Quel dysfonctionnement/manque existait?}
SOLUTION: {Quelle approche technique adoptee?}
IMPACT: {Qu'est-ce que l'utilisateur/developpeur gagne?}

**{CHANGEMENT_2}**
Avant: {etat problematique}.
Apres: {nouvel etat ameliore}.
Technique: {approche utilisee}.

Fichiers: {liste fichiers principaux avec leur role}

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
```

#### 5.3 Regles de redaction

| Principe | Application |
|----------|-------------|
| **Atomicite** | 1 commit = 1 intention logique |
| **Contexte** | Le "pourquoi" AVANT le "quoi" |
| **Impact** | Toujours mentionner le benefice utilisateur |
| **Autonomie** | Chaque paragraphe comprehensible seul |
| **Concision** | Maximum d'info, minimum de mots |

#### 5.4 Verbes d'impact (preferer)

| Eviter | Utiliser |
|--------|----------|
| "Ajout de..." | "Implemente X pour Y" |
| "Modification de..." | "Optimise X qui permet Y" |
| "Correction de..." | "Resout X cause par Y" |
| "Mise a jour..." | "Ameliore X en Y" |

#### 5.5 Templates par type

**Migration:**
```
db(migrations): {action} {description}

**MIGRATION: {MigrationName}**
PROBLEME: {Pourquoi cette migration est necessaire}
SOLUTION: {Tables/colonnes ajoutees/modifiees}
IMPACT: {Nouvelles capacites pour l'application}

Tables: {CREATE|ALTER|DROP} {tables}
Context: {DbContext}
```

**Feature:**
```
feat({scope}): {description impact}

**{NOM_FEATURE}**
PROBLEME: {Manque ou limitation actuelle}
SOLUTION: {Implementation technique choisie}
IMPACT: {Benefice utilisateur concret}

Fichiers cles:
- {path/file1.ext}: {role en 5 mots}
- {path/file2.ext}: {role en 5 mots}
```

**Fix:**
```
fix({scope}): resout {symptome} dans {contexte}

**{NOM_BUG}**
SYMPTOME: {Ce que l'utilisateur observait}
CAUSE: {Origine technique du probleme}
CORRECTION: {Comment le fix resout le probleme}
VERIFICATION: {Comment confirmer que c'est corrige}
```

**Mixed (code + migrations):**
```
feat({scope}): {description}

**{FEATURE}**
{Paragraphe explicatif}

**MIGRATIONS INCLUSES**
- {MigrationName}: {ce qu'elle apporte}

Fichiers: {liste}
```

### 6. Execute commit

- Add missing migration files if necessary
- Verify one last time
- Commit with message

### 7. Post-commit

- Verify no migration files are left uncommitted
- Display summary

### 8. Automatic push (based on config)

Read config: `.claude/gitflow/config.json` → `workflow.push.afterCommit`

**Worktree detection:**
```bash
# If git-common-dir != .git → it's a worktree
COMMON_DIR=$(git rev-parse --git-common-dir 2>/dev/null)
if [[ "$COMMON_DIR" != ".git" && "$COMMON_DIR" != "." ]]; then
  IS_WORKTREE=true
fi
```

**Push logic:**

| Config `afterCommit` | Worktree | Action |
|---------------------|----------|--------|
| `worktree` | Yes | Automatic push |
| `worktree` | No | Ask user |
| `always` | - | Automatic push |
| `ask` | - | Ask user |
| `never` | - | Do not push |

**If user is asked:**
```
AskUserQuestion({
  questions: [{
    question: "Do you want to push this commit?",
    header: "Push",
    options: [
      { label: "Yes, push now", description: "git push origin <branch>" },
      { label: "No, later", description: "Local commit only" }
    ],
    multiSelect: false
  }]
})
```

**Execute push:**
```bash
git push origin $(git branch --show-current)
```

**Push error handling:**
- If remote not configured → Skip with message
- If rebase necessary → Warn and suggest:
  ```
  /gitflow:4-plan rebase
  ```
- If branch protected → Warn (PR required)

---

## Common errors

| Error | Solution |
|-------|----------|
| ModelSnapshot missing | Add the file |
| Designer missing | Add the file |
| Build fails | `dotnet ef migrations remove` + fix |
| Conflict detected | Rebase first |
| **Destructive operation** | Confirm or modify migration |

---

## Resume

**Afficher un resume apres le commit:**

```
═══════════════════════════════════════════════════════════════════════════════
                         COMMIT CRÉÉ
═══════════════════════════════════════════════════════════════════════════════

COMMIT DETAILS
───────────────────────────────────────────────────────────────────────────────
  • Branche:   {branch_name}
  • Hash:      {commit_hash_short}
  • Message:   {commit_message}
  • Fichiers:  {N} fichiers modifiés

FICHIERS INCLUS
───────────────────────────────────────────────────────────────────────────────
  {type_icon} {file_1}
  {type_icon} {file_2}
  {type_icon} {file_3}
  ... ({N} fichiers au total)

WORKFLOW STATUT
───────────────────────────────────────────────────────────────────────────────
  ✓ Fichiers stagés
  ✓ Validations EF Core passées (si applicable)
  ✓ Commit créé localement
  ✓ Push vers origin/{branch} (si auto-push activé)

═══════════════════════════════════════════════════════════════════════════════
                         PROCHAINES ÉTAPES
═══════════════════════════════════════════════════════════════════════════════

1. Continuer à développer et committer:
   /gitflow:3-commit

2. Quand prêt, créer une Pull Request:
   /gitflow:7-pull-request {branch_name}

═══════════════════════════════════════════════════════════════════════════════
```

**Si des migrations EF Core sont incluses:**

```
═══════════════════════════════════════════════════════════════════════════════
                         COMMIT AVEC MIGRATIONS
═══════════════════════════════════════════════════════════════════════════════

COMMIT DETAILS
───────────────────────────────────────────────────────────────────────────────
  • Branche:   {branch_name}
  • Hash:      {commit_hash_short}
  • Message:   {commit_message}
  • Fichiers:  {N} fichiers modifiés

MIGRATIONS EF CORE INCLUSES
───────────────────────────────────────────────────────────────────────────────
  ✓ {timestamp}_{MigrationName}.cs
  ✓ {timestamp}_{MigrationName}.Designer.cs
  ✓ {Context}ModelSnapshot.cs (updated)

VALIDATIONS
───────────────────────────────────────────────────────────────────────────────
  ✓ Les 3 fichiers de migration sont présents
  ✓ Build vérifié
  ✓ Pas d'opérations destructives détectées

WORKFLOW STATUT
───────────────────────────────────────────────────────────────────────────────
  ✓ Fichiers stagés
  ✓ Validations EF Core passées
  ✓ Commit créé localement
  ✓ Push vers origin/{branch}

═══════════════════════════════════════════════════════════════════════════════
                         PROCHAINES ÉTAPES
═══════════════════════════════════════════════════════════════════════════════

1. Appliquer la migration en local:
   /efcore:db-deploy

2. Continuer à développer ou créer une PR:
   /gitflow:7-pull-request {branch_name}

═══════════════════════════════════════════════════════════════════════════════
```

---

## Modes

| Command | Action |
|---------|--------|
| `/gitflow:3-commit {msg}` | Commit with message |
| `/gitflow:3-commit` | Auto generate message |
| `/gitflow:3-commit --validate` | Validate without commit |
| `/gitflow:3-commit --dry-run` | Simulation |
