---
description: Phase 10 - Start a new feature, release or hotfix branch with worktree
agent: gitflow-start
model: haiku
---

# Phase 10: START - Demarrer une branche GitFlow (Worktree)

Tu es expert GitFlow. Cree une branche dans un **worktree separe** (par defaut).

> **INSTRUCTION CLAUDE:** Les blocs `AskUserQuestion({...})` ci-dessous sont des instructions pour utiliser le tool `AskUserQuestion` de maniere **interactive**. Tu DOIS executer le tool avec ces parametres pour obtenir la reponse de l'utilisateur AVANT de continuer. NE PAS afficher ce code - ATTENDRE la reponse.

**Argument:** `$ARGUMENTS` = `{type} {name} [--no-worktree]`

---

## ETAPE 1: Analyser le contexte

**IMPORTANT:** Avant toute question, collecter ces informations :

```bash
# 1. Branche courante
CURRENT_BRANCH=$(git branch --show-current)

# 2. Version actuelle (package.json, .csproj, VERSION, etc.)
VERSION=$(cat package.json 2>/dev/null | grep '"version"' | head -1 | sed 's/.*: "\(.*\)".*/\1/')
# Ou pour .NET: grep -oP '(?<=<Version>).*(?=</Version>)' *.csproj

# 3. Etat working directory
STATUS=$(git status --porcelain)

# 4. Commits develop vs main
DEVELOP_AHEAD=$(git rev-list --count origin/main..origin/develop 2>/dev/null || echo "0")
MAIN_AHEAD=$(git rev-list --count origin/develop..origin/main 2>/dev/null || echo "0")

# 5. Dernier tag
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "none")

# 6. Branches existantes
EXISTING_FEATURES=$(git branch -r | grep 'feature/' | wc -l)
EXISTING_RELEASES=$(git branch -r | grep 'release/' | wc -l)
EXISTING_HOTFIXES=$(git branch -r | grep 'hotfix/' | wc -l)

# 7. Compter les migrations sur develop (pour releases)
MIGRATIONS_ON_DEVELOP=$(find . -path "*/Migrations/*.cs" -not -name "*Designer*" -not -name "*ModelSnapshot*" 2>/dev/null | wc -l)
```

---

## ETAPE 2: Afficher le contexte

```
================================================================================
                         GITFLOW START - CONTEXTE
================================================================================

REPOSITORY
  Branche: {CURRENT_BRANCH} | Version: {VERSION} | Tag: {LAST_TAG}
  Working dir: {clean|dirty avec N fichiers}

SYNCHRONISATION
  develop → main: {DEVELOP_AHEAD} commits en avance
  main → develop: {MAIN_AHEAD} commits en avance
  {Si DEVELOP_AHEAD > 0: "Une release est recommandee"}
  {Si MAIN_AHEAD > 0: "⚠️ ATTENTION: main contient des commits absents de develop!"}

BRANCHES ACTIVES
  Features: {N} | Releases: {N} | Hotfixes: {N}

EF CORE (si projet .NET)
  Migrations sur develop: {MIGRATIONS_ON_DEVELOP}

================================================================================
```

---

## ETAPE 3: Questions dynamiques selon contexte

### Si `$ARGUMENTS` fourni → Parser et executer directement

```
$ARGUMENTS = "feature add-user-auth"
→ TYPE = "feature", NAME = "add-user-auth"
→ Sauter les questions, executer directement
```

### Si PAS d'arguments → Questionnaire dynamique

**Construire les options selon le contexte:**

```javascript
// Logique de construction des options
options = []

// Feature: toujours disponible depuis develop
if (CURRENT_BRANCH === 'develop' || canSwitchTo('develop')) {
  options.push({
    label: "feature",
    description: "Nouvelle fonctionnalite (depuis develop)"
  })
}

// Release: proposer SI develop a des commits ahead de main
if (DEVELOP_AHEAD > 0) {
  // Calculer les versions possibles
  const [major, minor, patch] = VERSION.split('.').map(Number)
  options.push({
    label: `release v${major}.${minor + 1}.0`,
    description: `Release minor - ${DEVELOP_AHEAD} commits a publier (Recommande)`
  })
  options.push({
    label: `release v${major + 1}.0.0`,
    description: "Release major - Changements breaking"
  })
}

// Hotfix: toujours disponible, mais mettre en avant si sur main ou si urgent
if (CURRENT_BRANCH === 'main') {
  options.unshift({
    label: "hotfix",
    description: "Correction urgente (depuis main) - PRIORITAIRE"
  })
} else {
  options.push({
    label: "hotfix",
    description: "Correction urgente (depuis main)"
  })
}
```

**AskUserQuestion avec options dynamiques:**

```javascript
AskUserQuestion({
  questions: [{
    question: "Quel type de branche voulez-vous creer ?",
    header: "Type",
    options: options,  // Options construites dynamiquement
    multiSelect: false
  }]
})
```

---

## ETAPE 4: Question de suivi selon le type

### Si FEATURE selectionne:

```javascript
AskUserQuestion({
  questions: [{
    question: "Decrivez la feature (utilisé pour le nom de branche)",
    header: "Feature",
    options: [
      { label: "add-", description: "Ajouter une nouvelle fonctionnalite" },
      { label: "update-", description: "Ameliorer une fonctionnalite existante" },
      { label: "refactor-", description: "Refactoring de code" }
    ],
    multiSelect: false
  }]
})
// Puis demander le nom complet en texte libre
```

### Si RELEASE selectionne:

**Etape A: Verifier l'etat de main**

```javascript
// Si main contient des commits absents de develop (main corrompu/divergent)
if (MAIN_AHEAD > 0) {
  AskUserQuestion({
    questions: [{
      question: `⚠️ ATTENTION: main contient ${MAIN_AHEAD} commits absents de develop. Comment proceder ?`,
      header: "Main",
      options: [
        { label: "Reset main", description: "Cette release remettra main en sync avec develop (Recommande)" },
        { label: "Analyser d'abord", description: "Voir les commits divergents avant de decider" },
        { label: "Continuer normalement", description: "Ignorer la divergence (non recommande)" }
      ],
      multiSelect: false
    }]
  })
}

// Si "Analyser d'abord" → Afficher les commits divergents:
// git log origin/develop..origin/main --oneline
```

**Etape B: Gestion des migrations EF Core**

```javascript
// Si projet .NET avec plusieurs migrations
if (MIGRATIONS_ON_DEVELOP > 3) {
  AskUserQuestion({
    questions: [{
      question: `Il y a ${MIGRATIONS_ON_DEVELOP} migrations sur develop. Voulez-vous les consolider ?`,
      header: "Migrations",
      options: [
        { label: "Consolider", description: "Squash en 1 migration propre (Recommande pour releases)" },
        { label: "Garder separees", description: "Conserver l'historique des migrations" }
      ],
      multiSelect: false
    }]
  })
}

// Si "Consolider" → Executer le processus de squash:
// 1. Backup de la branche actuelle
// 2. dotnet ef migrations list → sauvegarder la liste
// 3. dotnet ef database drop (si DB locale de dev)
// 4. Supprimer tous les fichiers Migrations/
// 5. dotnet ef migrations add InitialCreate_v{version}
// 6. Commit avec message descriptif
```

**Etape C: Confirmer la version**

```javascript
const [major, minor, patch] = VERSION.split('.').map(Number)

AskUserQuestion({
  questions: [{
    question: "Confirmer la version de release",
    header: "Version",
    options: [
      { label: `${major}.${minor + 1}.0`, description: "Minor - Nouvelles fonctionnalites (Recommande)" },
      { label: `${major}.${minor}.${patch + 1}`, description: "Patch - Corrections uniquement" },
      { label: `${major + 1}.0.0`, description: "Major - Changements breaking" }
    ],
    multiSelect: false
  }]
})
```

### Si HOTFIX selectionne:

**⚠️ NOTE VERSIONING:** La version sera automatiquement incrementee (PATCH) lors du `/gitflow:11-finish`.
Exemple: `1.7.1` → `1.7.2`. Pas besoin de faire `npm version patch` manuellement.

```javascript
AskUserQuestion({
  questions: [{
    question: "Decrivez le hotfix (utilisé pour le nom de branche)",
    header: "Hotfix",
    options: [
      { label: "fix-", description: "Correction de bug" },
      { label: "security-", description: "Correction de securite" },
      { label: "revert-", description: "Annuler un changement" }
    ],
    multiSelect: false
  }]
})
// Puis demander le nom complet en texte libre
```

---

## ETAPE 5: Verifications pre-creation

| Check | Commande | Action si echec |
|-------|----------|-----------------|
| Working tree clean | `git status --porcelain` | Proposer stash ou commit |
| Branche n'existe pas | `git branch --list {branch}` | Erreur avec suggestion |
| Base a jour | `git fetch origin` | Fetch automatique |

**Si working directory dirty:**

```javascript
AskUserQuestion({
  questions: [{
    question: "Working directory non propre. Que faire ?",
    header: "Action",
    options: [
      { label: "Stash", description: "git stash - Sauvegarder temporairement" },
      { label: "Commit", description: "Lancer /gitflow:3-commit d'abord" },
      { label: "Continuer", description: "Ignorer (non recommande)" }
    ],
    multiSelect: false
  }]
})
```

---

## ETAPE 6: Creer la branche

### Detecter le mode worktree

```bash
# Lire la config GitFlow
CONFIG_FILE=".claude/gitflow/config.json"
if [ -f "$CONFIG_FILE" ]; then
  WORKTREE_MODE=$(grep -o '"mode": *"[^"]*"' "$CONFIG_FILE" | head -1 | cut -d'"' -f4)
  # Default to adjacent if not specified
  WORKTREE_MODE=${WORKTREE_MODE:-adjacent}
else
  WORKTREE_MODE="adjacent"
fi
```

### Mode Worktree - Organized (v1.3)

**Si `worktrees.mode` = "organized"** (structure 01-Main, 02-Develop, etc.)

```bash
# Paths relatifs au projet parent (on est dans 02-Develop)
PROJECT_ROOT=".."

git fetch origin

# Feature (depuis develop)
WORKTREE_PATH="${PROJECT_ROOT}/features/{name}"
mkdir -p "${PROJECT_ROOT}/features"
git worktree add -b feature/{name} "$WORKTREE_PATH" origin/develop

# Release (depuis develop)
WORKTREE_PATH="${PROJECT_ROOT}/releases/v{version}"
mkdir -p "${PROJECT_ROOT}/releases"
git worktree add -b release/v{version} "$WORKTREE_PATH" origin/develop

# Hotfix (depuis main)
WORKTREE_PATH="${PROJECT_ROOT}/hotfixes/{name}"
mkdir -p "${PROJECT_ROOT}/hotfixes"
git worktree add -b hotfix/{name} "$WORKTREE_PATH" origin/main
```

**Structure resultante (Organized):**
```
{project}/
├── 01-Main/
├── 02-Develop/          ← Current
├── features/
│   └── {name}/          ← NEW
├── releases/
└── hotfixes/
```

### Mode Worktree - Adjacent (Legacy v1.2)

**Si `worktrees.mode` = "adjacent"** (structure ../worktrees/)

```bash
WORKTREE_BASE="../worktrees"

# Creer le repertoire parent et le sous-repertoire du type
mkdir -p "${WORKTREE_BASE}/features"
mkdir -p "${WORKTREE_BASE}/releases"
mkdir -p "${WORKTREE_BASE}/hotfixes"

git fetch origin

# Feature (depuis develop)
WORKTREE_PATH="${WORKTREE_BASE}/features/{name}"
git worktree add -b feature/{name} "$WORKTREE_PATH" origin/develop

# Release (depuis develop)
WORKTREE_PATH="${WORKTREE_BASE}/releases/v{version}"
git worktree add -b release/v{version} "$WORKTREE_PATH" origin/develop

# Hotfix (depuis main)
WORKTREE_PATH="${WORKTREE_BASE}/hotfixes/{name}"
git worktree add -b hotfix/{name} "$WORKTREE_PATH" origin/main
```

**Structure resultante (Adjacent):**
```
parent/
├── repo/                ← Current
└── worktrees/
    └── features/
        └── {name}/      ← NEW
```

### Mode --no-worktree

```bash
# Feature
git checkout develop && git pull origin develop
git checkout -b feature/{name}

# Release
git checkout develop && git pull origin develop
git checkout -b release/v{version}

# Hotfix
git checkout main && git pull origin main
git checkout -b hotfix/{name}
```

---

## ETAPE 6.5: Configuration AUTOMATIQUE appsettings.Local.json (Projets .NET)

> **AUTOMATIQUE:** Cette etape s'execute sans intervention utilisateur pour garantir
> l'isolation des bases de donnees entre worktrees.

### 6.5.1: Detecter les projets .NET

```bash
cd "${WORKTREE_PATH}"

# Chercher tous les fichiers appsettings.json (peut y en avoir plusieurs)
APPSETTINGS_FILES=$(find . -name "appsettings.json" -not -path "*/bin/*" -not -path "*/obj/*" 2>/dev/null)

if [ -z "$APPSETTINGS_FILES" ]; then
  echo "Pas de projet .NET detecte (aucun appsettings.json)"
  # Continuer sans configuration
fi
```

### 6.5.2: Generer le nom de base de donnees UNIQUE

**Convention de nommage:**

| Type de branche | Pattern DB | Exemple |
|-----------------|------------|---------|
| develop | `{ProjectName}_Dev` | `SmartStack_Dev` |
| feature/* | `{ProjectName}_feat_{name}` | `SmartStack_feat_add_user_auth` |
| hotfix/* | `{ProjectName}_fix_{name}` | `SmartStack_fix_login_bug` |
| release/* | `{ProjectName}_rel_{version}` | `SmartStack_rel_1_3_0` |

```bash
# Extraire le nom de projet depuis le .csproj ou le dossier
PROJECT_NAME=$(basename "$(find . -name "*.Api.csproj" -o -name "*.Web.csproj" | head -1)" .csproj 2>/dev/null)
if [ -z "$PROJECT_NAME" ]; then
  PROJECT_NAME=$(basename "$(pwd)" | sed 's/[^a-zA-Z0-9]/_/g')
fi

# Normaliser le nom de branche pour SQL Server (pas de caracteres speciaux)
BRANCH_SAFE=$(echo "${BRANCH_NAME}" | sed 's/[\/\-]/_/g' | sed 's/[^a-zA-Z0-9_]//g')

# Generer le nom de DB selon le type
case "$TYPE" in
  feature)
    DB_NAME="${PROJECT_NAME}_feat_${BRANCH_SAFE}"
    ;;
  hotfix)
    DB_NAME="${PROJECT_NAME}_fix_${BRANCH_SAFE}"
    ;;
  release)
    VERSION_SAFE=$(echo "${VERSION}" | sed 's/\./_/g')
    DB_NAME="${PROJECT_NAME}_rel_${VERSION_SAFE}"
    ;;
  *)
    DB_NAME="${PROJECT_NAME}_Dev"
    ;;
esac

# Limiter a 128 caracteres (limite SQL Server)
DB_NAME=$(echo "$DB_NAME" | cut -c1-128)

echo "Database name: $DB_NAME"
```

### 6.5.3: Lire la configuration depuis gitflow/config.json

```bash
# Lire les parametres de connexion depuis la section "database" du config GitFlow
CONFIG_FILE=".claude/gitflow/config.json"

if [ -f "$CONFIG_FILE" ]; then
  # Verifier si la creation automatique est activee
  DB_ENABLED=$(grep -oP '"database"[^}]*"enabled":\s*\K(true|false)' "$CONFIG_FILE" 2>/dev/null || echo "true")

  if [ "$DB_ENABLED" = "false" ]; then
    echo "  [SKIP] Database auto-config desactive dans config.json"
    # Sortir de l'etape 6.5 sans creer appsettings.Local.json
    SKIP_DB_CONFIG=true
  fi

  # Extraire les valeurs de la section "database"
  DB_SERVER=$(grep -oP '"database"[^}]*"server":\s*"\K[^"]+' "$CONFIG_FILE" 2>/dev/null || echo "localhost")
  DB_AUTH=$(grep -oP '"database"[^}]*"authType":\s*"\K[^"]+' "$CONFIG_FILE" 2>/dev/null || echo "windows")
  DB_USER=$(grep -oP '"database"[^}]*"username":\s*"\K[^"]+' "$CONFIG_FILE" 2>/dev/null || echo "")
  DB_PASS=$(grep -oP '"database"[^}]*"password":\s*"\K[^"]+' "$CONFIG_FILE" 2>/dev/null || echo "")
  DB_PREFIX=$(grep -oP '"database"[^}]*"namePrefix":\s*"\K[^"]+' "$CONFIG_FILE" 2>/dev/null || echo "")

  # Utiliser le prefix configure si present
  if [ -n "$DB_PREFIX" ]; then
    PROJECT_NAME="$DB_PREFIX"
  fi
else
  # Valeurs par defaut si pas de config
  DB_SERVER="localhost"
  DB_AUTH="windows"
  DB_ENABLED="true"
fi
```

### 6.5.4: Creer appsettings.Local.json pour CHAQUE projet

```bash
for APPSETTINGS in $APPSETTINGS_FILES; do
  DIR=$(dirname "$APPSETTINGS")
  LOCAL_FILE="${DIR}/appsettings.Local.json"

  # Ne pas ecraser si existe deja
  if [ -f "$LOCAL_FILE" ]; then
    echo "  [SKIP] $LOCAL_FILE existe deja"
    continue
  fi

  # Copier le fichier original comme base
  cp "$APPSETTINGS" "$LOCAL_FILE"

  # Construire la connection string
  if [ "$DB_AUTH" = "windows" ]; then
    CONNECTION_STRING="Server=${DB_SERVER};Database=${DB_NAME};Trusted_Connection=true;TrustServerCertificate=true;MultipleActiveResultSets=true"
  else
    CONNECTION_STRING="Server=${DB_SERVER};Database=${DB_NAME};User Id=${DB_USER};Password=${DB_PASS};TrustServerCertificate=true;MultipleActiveResultSets=true"
  fi

  # Mettre a jour la connection string dans le fichier JSON
  # Utiliser sed pour remplacer la valeur existante
  sed -i 's|"DefaultConnection":\s*"[^"]*"|"DefaultConnection": "'"$CONNECTION_STRING"'"|g' "$LOCAL_FILE"

  # Si pas de ConnectionStrings, ajouter le bloc
  if ! grep -q '"ConnectionStrings"' "$LOCAL_FILE"; then
    # Ajouter apres la premiere accolade ouvrante
    sed -i '1a\  "ConnectionStrings": {\n    "DefaultConnection": "'"$CONNECTION_STRING"'"\n  },' "$LOCAL_FILE"
  fi

  echo "  [OK] $LOCAL_FILE cree avec DB: $DB_NAME"
done
```

### 6.5.5: Assurer .gitignore

```bash
# S'assurer que appsettings.Local.json est ignore
GITIGNORE=$(find . -name ".gitignore" -not -path "*/bin/*" | head -1)

if [ -n "$GITIGNORE" ]; then
  if ! grep -q "appsettings.Local.json" "$GITIGNORE" 2>/dev/null; then
    echo "" >> "$GITIGNORE"
    echo "# Local settings per worktree (ne pas committer)" >> "$GITIGNORE"
    echo "appsettings.Local.json" >> "$GITIGNORE"
    echo "appsettings.*.Local.json" >> "$GITIGNORE"
    echo "  [OK] .gitignore mis a jour"
  fi
fi
```

### 6.5.6: Afficher resume

```
================================================================================
                    CONFIGURATION LOCALE AUTOMATIQUE
================================================================================

WORKTREE:   {WORKTREE_PATH}
BRANCHE:    {BRANCH_NAME}
TYPE:       {feature|hotfix|release}

BASE DE DONNEES:
  Server:   {DB_SERVER}
  Database: {DB_NAME}
  Auth:     {Windows|SQL}

FICHIERS CREES:
  ✓ src/SmartStack.Api/appsettings.Local.json
  {autres fichiers si plusieurs projets}

ISOLATION GARANTIE:
  ✓ Cette branche utilise sa propre DB
  ✓ Pas de conflit avec develop ou autres features
  ✓ Fichier ignore par git (credentials securises)

================================================================================
PROCHAINE ETAPE:
  /efcore:db-deploy  → Creer et deployer la base de donnees
================================================================================
```

### 6.5.7: Configuration GitFlow pour DB (optionnel)

**Pour pre-configurer les parametres de connexion, ajouter dans `.claude/gitflow/config.json`:**

```json
{
  "database": {
    "server": "localhost",
    "authType": "windows",
    "username": "",
    "password": "",
    "namePrefix": "SmartStack"
  }
}
```

| Parametre | Description | Defaut |
|-----------|-------------|--------|
| `server` | Serveur SQL Server | `localhost` |
| `authType` | `windows` ou `sql` | `windows` |
| `username` | User SQL (si sql auth) | - |
| `password` | Password SQL (si sql auth) | - |
| `namePrefix` | Prefixe des noms de DB | Nom du projet |

---

## ETAPE 7: Actions post-creation

**Release uniquement** - Bump version :
```bash
npm version {version} --no-git-tag-version
git add package.json package-lock.json
git commit -m "chore: bump version to {version}"
```

**Push branche:**
```bash
git push -u origin {branch}
```

---

## ETAPE 8: Resume et prochaines etapes

```
================================================================================
                         BRANCHE CREEE
================================================================================

TYPE:     {feature|release|hotfix}
BRANCHE:  {branch_name}
BASE:     {develop|main}
CIBLE:    {develop|main+develop}
VERSION:  {version} (si release)

WORKTREE:
  - Organized mode: ../{type}s/{name}/ (ex: ../features/add-user/)
  - Adjacent mode:  ../worktrees/{type}s/{name}/
  - No worktree:    meme repertoire

================================================================================
PROCHAINES ETAPES
================================================================================

1. Naviguer vers le worktree:
   - Organized: cd "../{type}s/{name}" ou code "../{type}s/{name}"
   - Adjacent:  cd "../worktrees/{type}s/{name}"

2. Faire vos modifications
3. /gitflow:3-commit
4. /gitflow:7-pull-request
5. /gitflow:11-finish (apres merge PR)

================================================================================
```

---

## Exemples

| Commande | Resultat |
|----------|----------|
| `/gitflow:10-start` | Mode interactif avec contexte |
| `/gitflow:10-start feature user-auth` | `feature/user-auth` direct |
| `/gitflow:10-start release` | Propose versions basees sur actuelle |
| `/gitflow:10-start hotfix login-fix` | `hotfix/login-fix` direct |
| `/gitflow:10-start feature test --no-worktree` | Sans worktree |

---

## Cas speciaux

### Develop tres en avance de main (> 10 commits)

```
⚠️  ATTENTION: develop a {N} commits en avance de main.
    Une release est fortement recommandee avant de creer une nouvelle feature.

    Voulez-vous:
    1. Creer une release d'abord (Recommande)
    2. Continuer avec la feature quand meme
```

### Release en cours

```
⚠️  Une release est deja en cours: release/v1.2.0

    Voulez-vous:
    1. Continuer sur la release existante
    2. Creer une nouvelle release (rare)
```

### Hotfix urgent depuis n'importe quelle branche

```
Si hotfix selectionne depuis une branche != main:
→ Stash automatique des changements
→ Checkout main
→ Creer hotfix
→ Message: "Vos changements ont ete stash. Recuperez-les avec 'git stash pop' apres le hotfix."
```

### Main divergent (commits absents de develop)

**Situation:** main contient des commits qui ne sont pas sur develop (ex: hotfix mal merge, commit direct sur main)

**Detection:**
```bash
MAIN_AHEAD=$(git rev-list --count origin/develop..origin/main 2>/dev/null || echo "0")
```

**Si utilisateur choisit "Reset main":**
```bash
# Pendant la release, au moment du finish:
# 1. Merge develop → release (normal)
# 2. Au lieu de merge release → main, faire un reset:
git checkout main
git reset --hard release/v{version}
git push --force-with-lease origin main
# 3. Puis merge release → develop (normal)
```

**Note:** This operation is logged in [.claude/gitflow/logs/](.claude/gitflow/logs/)`main-resets.json`

### Consolidation des migrations EF Core

**Situation:** Plusieurs migrations accumulees sur develop (> 3)

**Avantages de consolider:**
- 1 seule migration = schema propre
- Pas de conflits ModelSnapshot lors des merges
- Deploy plus rapide en production

**Processus si utilisateur choisit "Consolider":**

```bash
# 1. S'assurer d'etre sur la branche release
cd "${WORKTREE_PATH}"

# 2. Sauvegarder la liste des migrations
dotnet ef migrations list > migrations-backup.txt

# 3. Identifier le DbContext
CONTEXT=$(grep -l "DbContext" **/*.cs | head -1)

# 4. Supprimer toutes les migrations
rm -rf Migrations/

# 5. Creer une migration consolidee
dotnet ef migrations add InitialCreate_v{version} --context {DbContext}

# 6. Verifier que le build passe
dotnet build

# 7. Commit la consolidation
git add -A
git commit -m "db(migrations): consolidate migrations for v{version}

Merged migrations:
$(cat migrations-backup.txt)

Single migration: InitialCreate_v{version}"

rm migrations-backup.txt
```

**⚠️ IMPORTANT:**
- Ceci est uniquement pour les releases (pas features/hotfixes)
- La DB de production doit etre synchronisee avec les migrations AVANT la consolidation
- Apres consolidation, les environnements de dev doivent recreer leur DB locale
