---
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]`

**FLUX D'EXECUTION:**
```
AVEC arguments:     ETAPE 1 → ETAPE 5 → ETAPE 6 → ETAPE 7 → ETAPE 8
SANS arguments:     ETAPE 1 → ETAPE 2 → ETAPE 3 → ETAPE 4 → ETAPE 5 → ETAPE 6 → ETAPE 7 → ETAPE 8
                                                            ↑
                                                   TOUJOURS OBLIGATOIRE
```

---

## 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 aller aux verifications

```
$ARGUMENTS = "feature add-user-auth"
→ TYPE = "feature", NAME = "add-user-auth"
→ Sauter les questions (ETAPES 3-4), aller directement a ETAPE 5 (verifications)
```

**IMPORTANT:** Meme avec des arguments, tu DOIS executer l'ETAPE 5 (verifications) avant de creer la branche.

### 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:

**Lire la configuration de langue:**

```bash
# ═══════════════════════════════════════════════════════════════
# CONFIGURATION DE LANGUE
# ═══════════════════════════════════════════════════════════════
CONFIG_FILE=".claude/gitflow/config.json"
LANG_CODE="en"
if [ -f "$CONFIG_FILE" ]; then
  LANG_CODE=$(grep -oP '"code":\s*"\K[^"]+' "$CONFIG_FILE" 2>/dev/null | head -1)
  LANG_CODE=${LANG_CODE:-en}
fi
echo "Langue configuree: $LANG_CODE"
```

**Demander la description selon la langue configuree:**

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

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

// Suggestions de verbes d'action selon la langue
// Le prefix de branche "feature/" ne change PAS
const featureOptions = isEnglish ? [
  { label: "add-", description: "Add a new feature → feature/add-..." },
  { label: "update-", description: "Update existing → feature/update-..." },
  { label: "fix-", description: "Fix a bug → feature/fix-..." },
  { label: "refactor-", description: "Refactor code → feature/refactor-..." },
  { label: "improve-", description: "Improve perf/UX → feature/improve-..." }
] : [
  { label: "ajouter-", description: "Nouvelle fonctionnalite → feature/ajouter-..." },
  { label: "modifier-", description: "Modifier existant → feature/modifier-..." },
  { label: "corriger-", description: "Corriger un bug → feature/corriger-..." },
  { label: "refactorer-", description: "Refactorer du code → feature/refactorer-..." },
  { label: "ameliorer-", description: "Ameliorer perf/UX → feature/ameliorer-..." }
]

AskUserQuestion({
  questions: [{
    question: isEnglish
      ? "Describe the feature (branch will be feature/your-description)"
      : "Decrivez la feature (branche sera feature/votre-description)",
    header: "Feature",
    options: featureOptions,
    multiSelect: false
  }]
})
// L'utilisateur complete via "Other" pour le nom complet
```

**Normaliser le nom saisi:**

```bash
# ═══════════════════════════════════════════════════════════════
# FONCTION DE NORMALISATION DES NOMS DE BRANCHES
# ═══════════════════════════════════════════════════════════════
normalize_branch_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 et autres)
  result=$(echo "$result" | sed 'y/àâäéèêëïîôùûüçœæÀÂÄÉÈÊËÏÎÔÙÛÜÇŒÆ/aaaeeeeiioouucoaAAaEeeeIIOOuucoa/')

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

  # 4. Supprimer les caracteres non autorises
  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"
}

# Normaliser le nom fourni par l'utilisateur
RAW_NAME="$USER_INPUT"
FEATURE_NAME=$(normalize_branch_name "$RAW_NAME" 50)

# Afficher si normalisation appliquee
if [ "$RAW_NAME" != "$FEATURE_NAME" ]; then
  echo ""
  echo "┌──────────────────────────────────────────────────────────────────────────────┐"
  echo "│  ℹ️  NOM NORMALISE                                                            │"
  echo "├──────────────────────────────────────────────────────────────────────────────┤"
  echo "│  Saisi:      $RAW_NAME"
  echo "│  Normalise:  $FEATURE_NAME"
  echo "├──────────────────────────────────────────────────────────────────────────────┤"
  echo "│  Raisons possibles:                                                          │"
  echo "│  - Accents supprimes (e→e, a→a)                                              │"
  echo "│  - Espaces remplaces par tirets                                              │"
  echo "│  - Caracteres speciaux supprimes                                             │"
  echo "│  - Majuscules converties en minuscules                                       │"
  echo "└──────────────────────────────────────────────────────────────────────────────┘"
fi

BRANCH_NAME="feature/$FEATURE_NAME"
echo "Branche: $BRANCH_NAME"
```

**Exemples de normalisation:**

| Entree utilisateur | Resultat normalise |
|--------------------|-------------------|
| "Ajouter l'authentification" | `ajouter-lauthentification` |
| "Add User Auth !!" | `add-user-auth` |
| "Améliorer_Performance_API" | `ameliorer-performance-api` |
| "fix: Bug dans le login" | `fix-bug-dans-le-login` |
| "FEATURE majuscules" | `feature-majuscules` |

### 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.

**Demander la description selon la langue configuree:**

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

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

// Suggestions selon la langue (prefix hotfix/ ne change pas)
const hotfixOptions = isEnglish ? [
  { label: "fix-", description: "Bug fix → hotfix/fix-..." },
  { label: "security-", description: "Security fix → hotfix/security-..." },
  { label: "revert-", description: "Revert a change → hotfix/revert-..." },
  { label: "patch-", description: "Quick patch → hotfix/patch-..." }
] : [
  { label: "corriger-", description: "Correction bug → hotfix/corriger-..." },
  { label: "securite-", description: "Correction securite → hotfix/securite-..." },
  { label: "annuler-", description: "Annuler changement → hotfix/annuler-..." },
  { label: "patch-", description: "Correctif rapide → hotfix/patch-..." }
]

AskUserQuestion({
  questions: [{
    question: isEnglish
      ? "Describe the hotfix (branch will be hotfix/your-description)"
      : "Decrivez le hotfix (branche sera hotfix/votre-description)",
    header: "Hotfix",
    options: hotfixOptions,
    multiSelect: false
  }]
})
```

**Normaliser le nom (meme fonction que feature):**

```bash
# Utiliser la meme fonction normalize_branch_name definie plus haut
RAW_NAME="$USER_INPUT"
HOTFIX_NAME=$(normalize_branch_name "$RAW_NAME" 50)

if [ "$RAW_NAME" != "$HOTFIX_NAME" ]; then
  echo "Nom normalise: '$RAW_NAME' → '$HOTFIX_NAME'"
fi

BRANCH_NAME="hotfix/$HOTFIX_NAME"
echo "Branche: $BRANCH_NAME"
```

---

## ETAPE 5: Verifications pre-creation

> **OBLIGATOIRE:** Cette etape doit TOUJOURS etre executee, meme quand des arguments sont fournis via `$ARGUMENTS`. Ne JAMAIS sauter cette etape.

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

### 5.1 Verifier que la branche SPECIFIQUE n'existe pas

**IMPORTANT:** Cette verification doit etre faite sur la branche EXACTE demandee, pas sur le nombre total de branches.

```bash
# Construire le nom complet de la branche
BRANCH_FULL_NAME="${TYPE}/${NAME}"  # ex: feature/add-user-auth

# Fetch pour avoir les branches remote a jour
git fetch origin --quiet

# Verifier si la branche existe en LOCAL
LOCAL_EXISTS=$(git branch --list "$BRANCH_FULL_NAME")

# Verifier si la branche existe en REMOTE
REMOTE_EXISTS=$(git branch -r --list "origin/$BRANCH_FULL_NAME")

# Si la branche existe deja
if [ -n "$LOCAL_EXISTS" ] || [ -n "$REMOTE_EXISTS" ]; then
  echo ""
  echo "ERROR: La branche '$BRANCH_FULL_NAME' existe deja!"
  echo ""

  if [ -n "$LOCAL_EXISTS" ]; then
    echo "  - Existe en LOCAL"
  fi
  if [ -n "$REMOTE_EXISTS" ]; then
    echo "  - Existe en REMOTE (origin)"
  fi

  echo ""
  echo "Options:"
  echo "  1. Choisir un autre nom"
  echo "  2. Supprimer la branche existante: git branch -D $BRANCH_FULL_NAME"
  echo "  3. Continuer sur la branche existante: git checkout $BRANCH_FULL_NAME"
  echo ""

  # Proposer a l'utilisateur
  AskUserQuestion({
    questions: [{
      question: "La branche '$BRANCH_FULL_NAME' existe deja. Que faire ?",
      header: "Conflit",
      options: [
        { label: "Autre nom", description: "Choisir un nom different" },
        { label: "Checkout", description: "Basculer sur la branche existante" },
        { label: "Supprimer", description: "Supprimer et recreer (ATTENTION: perte de donnees)" }
      ],
      multiSelect: false
    }]
  })

  # Actions selon choix:
  # - "Autre nom" -> Retourner a ETAPE 4 pour redemander le nom
  # - "Checkout" -> git checkout $BRANCH_FULL_NAME && exit
  # - "Supprimer" -> git branch -D $BRANCH_FULL_NAME && git push origin --delete $BRANCH_FULL_NAME 2>/dev/null
fi

echo "OK Branche '$BRANCH_FULL_NAME' disponible"
```

### 5.2 Verifier working directory

**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

**IMPORTANT:** Toujours detecter la structure EXISTANTE en priorite, avant de lire la config.

```bash
# ═══════════════════════════════════════════════════════════════
# ETAPE 1: Detection automatique basee sur la structure des dossiers
# ═══════════════════════════════════════════════════════════════

# Verifier si on est dans une structure "organized" (01-Main, 02-Develop, features/, etc.)
# Ces dossiers sont a la racine du projet parent (..)
if [ -d "../features" ] && [ -d "../releases" ] && [ -d "../hotfixes" ]; then
  # Structure organized detectee
  WORKTREE_MODE="organized"
  echo "[AUTO-DETECT] Structure organized detectee (../features/, ../releases/, ../hotfixes/)"
elif [ -d "../01-Main" ] && [ -d "../02-Develop" ]; then
  # Structure organized detectee via les prefixes numerotes
  WORKTREE_MODE="organized"
  echo "[AUTO-DETECT] Structure organized detectee (../01-Main/, ../02-Develop/)"
elif [ -d "../worktrees" ]; then
  # Structure adjacent/legacy detectee
  WORKTREE_MODE="adjacent"
  echo "[AUTO-DETECT] Structure adjacent detectee (../worktrees/)"
else
  # ═══════════════════════════════════════════════════════════════
  # ETAPE 2: Fallback sur la config GitFlow si structure non detectee
  # ═══════════════════════════════════════════════════════════════
  CONFIG_FILE=".claude/gitflow/config.json"
  if [ -f "$CONFIG_FILE" ]; then
    WORKTREE_MODE=$(grep -o '"mode": *"[^"]*"' "$CONFIG_FILE" | head -1 | cut -d'"' -f4)
    WORKTREE_MODE=${WORKTREE_MODE:-adjacent}
    echo "[CONFIG] Mode lu depuis config.json: $WORKTREE_MODE"
  else
    # Default: adjacent si rien n'est detecte
    WORKTREE_MODE="adjacent"
    echo "[DEFAULT] Aucune structure detectee, mode par defaut: adjacent"
  fi
fi

echo "WORKTREE_MODE=$WORKTREE_MODE"
```

### 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

**Afficher un resume adapte au TYPE de branche creee:**

### Si FEATURE:

```
================================================================================
                         FEATURE CREEE
================================================================================

BRANCHE:  feature/{name}
BASE:     develop
CIBLE:    develop
WORKTREE: ../features/{name}/

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

1. Naviguer vers le worktree:
   cd ../features/{name}
   # ou dans VSCode:
   code ../features/{name}

2. Faire vos modifications et committer:
   /gitflow:3-commit

3. Creer une Pull Request (feature/{name} → develop):
   /gitflow:7-pull-request feature/{name}

4. Apres merge de la PR, nettoyer:
   /gitflow:11-finish feature/{name}
   Cela va:
     ✓ Supprimer la branche feature/{name}
     ✓ Nettoyer le worktree

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

### Si RELEASE:

```
================================================================================
                         RELEASE CREEE
================================================================================

BRANCHE:  release/v{version}
BASE:     develop
CIBLE:    main + develop (merge back)
VERSION:  v{version}
WORKTREE: ../releases/v{version}/

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

1. Naviguer vers le worktree:
   cd ../releases/v{version}
   # ou dans VSCode:
   code ../releases/v{version}

2. Creer une Pull Request (release/v{version} → main):
   /gitflow:7-pull-request release/v{version}

3. Apres merge de la PR, finaliser:
   /gitflow:11-finish release/v{version}
   Cela va:
     ✓ Creer le tag v{version}
     ✓ Merger main → develop (merge back)
     ✓ Incrementer la version sur develop ({version} → {next_minor})
     ✓ Nettoyer le worktree

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

### Si HOTFIX:

```
================================================================================
                         HOTFIX CREE
================================================================================

BRANCHE:  hotfix/{name}
BASE:     main
CIBLE:    main + develop (merge back)
WORKTREE: ../hotfixes/{name}/

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

1. Naviguer vers le worktree:
   cd ../hotfixes/{name}
   # ou dans VSCode:
   code ../hotfixes/{name}

2. Faire vos corrections et committer:
   /gitflow:3-commit

3. Creer une Pull Request (hotfix/{name} → main):
   /gitflow:7-pull-request hotfix/{name}

4. Apres merge de la PR, finaliser:
   /gitflow:11-finish hotfix/{name}
   Cela va:
     ✓ Incrementer la version PATCH ({current} → {current+patch})
     ✓ Creer le tag v{new_version}
     ✓ Merger main → develop (merge back)
     ✓ Nettoyer le worktree

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

---

## 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
