---
description: Populate database with test or initial data
agent: efcore-db-seed
model: haiku
---

# EF Core Database Seed

Inserts test or initial data into the database using EF Core HasData() or Seeder classes.

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

---

## RÈGLES DE CONFORMITÉ (OBLIGATOIRE)

> **INTERDIT - Violations CLAUDE.md:**
> - ❌ Scripts SQL (.sql files) dans le repository
> - ❌ Utilisation de `sqlcmd` avec SQL brut
> - ❌ `migrationBuilder.Sql()` avec INSERT statements
>
> **OBLIGATOIRE - Méthodes autorisées:**
> - ✅ `HasData()` dans les configurations EF Core
> - ✅ Classes `IDataSeeder` exécutées au démarrage
> - ✅ Migrations EF Core avec données typées
>
> **Contact support:** support@atlshub.ch

---

## STEP 0: Verification environnement et connexion

> **Include:** `_env-check.md` (etapes 0.1 a 0.5)

### 0.1 Detecter et afficher l'environnement

```bash
# Scanner les fichiers appsettings
API_DIR=$(find . -type d -name "*.Api" | head -1)
[ -z "$API_DIR" ] && API_DIR="src/SmartStack.Api"

# Selectionner l'environnement
ENV_FLAG="${1#--env=}"
if [ -n "$ENV_FLAG" ] && [ "$ENV_FLAG" != "$1" ]; then
  SELECTED_ENV="appsettings.${ENV_FLAG}.json"
elif [ -f "$API_DIR/appsettings.Local.json" ]; then
  SELECTED_ENV="appsettings.Local.json"
else
  echo "ERROR: Aucun fichier appsettings trouve"
  exit 1
fi

# Extraire connection string
CONNECTION_STRING=$(powershell -Command "
  \$json = Get-Content '$API_DIR/$SELECTED_ENV' | ConvertFrom-Json
  \$json.ConnectionStrings.DefaultConnection
")

DATABASE_NAME=$(echo "$CONNECTION_STRING" | grep -oP 'Database=\K[^;]+')
SERVER_NAME=$(echo "$CONNECTION_STRING" | grep -oP 'Server=\K[^;]+')

# Protection Production
if [[ "$SELECTED_ENV" == *"Production"* ]]; then
  echo "BLOQUE: Seed interdit en environnement Production"
  exit 1
fi
```

### 0.2 Afficher le resume

```
================================================================================
                         EF CORE - DATABASE SEED
================================================================================

ENVIRONNEMENT: {SELECTED_ENV}

BASE DE DONNEES CIBLE:
  Server:   {SERVER_NAME}
  Database: {DATABASE_NAME}

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

---

## STEP 1: Detect available seeding methods

```bash
# Search for COMPLIANT seed methods only
SEED_METHODS=""

# 1. DbSeeder or DataSeeder class
if grep -rq "class.*Seeder\|class.*Seed\|IDataSeeder" . --include="*.cs" 2>/dev/null; then
  SEED_METHODS="$SEED_METHODS seeder-class"
fi

# 2. HasData() in configurations (RECOMMENDED)
if grep -rq "\.HasData(" . --include="*.cs" 2>/dev/null; then
  SEED_METHODS="$SEED_METHODS hasdata"
fi

# 3. --seed argument in Program.cs
if grep -q "\-\-seed" ./Program.cs 2>/dev/null; then
  SEED_METHODS="$SEED_METHODS cli-argument"
fi

# WARNING: Detect forbidden SQL scripts
if [ -f "./scripts/seed.sql" ] || [ -f "./Data/seed.sql" ]; then
  echo "⚠️  WARNING: SQL seed scripts detected - FORBIDDEN by CLAUDE.md"
  echo "   Please migrate to HasData() in EF Core configurations"
  echo "   Contact: support@atlshub.ch"
fi
```

---

## STEP 2: Display options

```
================================================================================
                         EF CORE - DATABASE SEED
================================================================================

DETECTED METHODS:
```

**If methods found:**

```javascript
// Build options dynamically - ONLY COMPLIANT METHODS
options = []

if (SEED_METHODS.includes("hasdata")) {
  options.push({
    label: "HasData (Recommended)",
    description: "Data seeded via EF Core migrations - compliant"
  })
}

if (SEED_METHODS.includes("seeder-class")) {
  options.push({
    label: "Seeder Class",
    description: "Execute DbSeeder/DataSeeder class at startup"
  })
}

if (SEED_METHODS.includes("cli-argument")) {
  options.push({
    label: "CLI --seed",
    description: "Launch app with --seed argument"
  })
}

AskUserQuestion({
  questions: [{
    question: "Which seeding method to use?",
    header: "Seed",
    options: options,
    multiSelect: false
  }]
})
```

**If no method found:**

```
⚠️  No seeding method detected

SOLUTION RECOMMANDÉE - HasData():
────────────────────────────────────────────────────────────────────────────────
Ajoutez HasData() dans vos fichiers *Configuration.cs :

public class UserConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.HasData(new User
        {
            Id = Guid.Parse("7f3c9a2e-8d1b-4e5f-a6c8-9b4d2f7e1a3c"), // Random GUID
            Name = "Admin",
            Email = "admin@example.com",
            CreatedAt = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc)
        });
    }
}
────────────────────────────────────────────────────────────────────────────────

Puis créez une migration:
  dotnet ef migrations add SeedInitialData

ALTERNATIVE - Seeder Class:
────────────────────────────────────────────────────────────────────────────────
public interface IDataSeeder
{
    Task SeedAsync(CancellationToken ct = default);
}

public class DatabaseSeeder : IDataSeeder
{
    private readonly ApplicationDbContext _context;

    public async Task SeedAsync(CancellationToken ct = default)
    {
        if (!await _context.Users.AnyAsync(ct))
        {
            _context.Users.Add(new User { ... });
            await _context.SaveChangesAsync(ct);
        }
    }
}
────────────────────────────────────────────────────────────────────────────────

❌ INTERDIT: Création de scripts SQL (.sql files)
   Contact: support@atlshub.ch
```

---

## STEP 3: Execute seeding

### Option A: HasData (via migrations)

```bash
# Les données sont déjà dans les migrations
# Simplement appliquer les migrations
STARTUP_PROJECT=$(find . -name "*.Api.csproj" -o -name "*Web.csproj" | head -1)
INFRA_PROJECT=$(find . -name "*Infrastructure.csproj" | head -1)

dotnet ef database update \
  --project "$INFRA_PROJECT" \
  --startup-project "$STARTUP_PROJECT"

echo "✓ HasData() seed applied via migrations"
```

### Option B: Seeder Class

```bash
# Detect startup project
STARTUP_PROJECT=$(find . -name "*.csproj" -exec grep -l "Microsoft.AspNetCore" {} \; | head -1)

# Execute with seed option
dotnet run --project "$STARTUP_PROJECT" -- --seed

echo "✓ Seeder class executed"
```

### Option C: CLI --seed

```bash
STARTUP_PROJECT=$(find . -name "*.csproj" -exec grep -l "Microsoft.AspNetCore" {} \; | head -1)
dotnet run --project "$STARTUP_PROJECT" -- --seed
```

---

## STEP 4: Verification

```bash
# Verify seeding via EF Core context
STARTUP_PROJECT=$(find . -name "*.csproj" -exec grep -l "Microsoft.AspNetCore" {} \; | head -1)

# Run verification endpoint or check via application
echo "Verification: Launch application and check data"
echo "  dotnet run --project $STARTUP_PROJECT"
echo ""
echo "Or check via EF Core:"
echo "  dotnet ef dbcontext info"
```

---

## STEP 5: Summary

```
================================================================================
                         SEEDING COMPLETE
================================================================================

METHOD:      {method used}
COMPLIANT:   ✓ EF Core native (no raw SQL)

✓ Database populated successfully

NEXT COMMANDS:
  /efcore:db-status  → Check status
  dotnet run         → Launch application

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

---

## Migration de scripts SQL existants

Si vous avez des scripts SQL legacy, migrez-les vers HasData():

```
AVANT (INTERDIT):
────────────────────────────────────────────────────────────────────────────────
-- scripts/seed.sql
INSERT INTO Users (Id, Name, Email) VALUES (1, 'Admin', 'admin@test.com');
────────────────────────────────────────────────────────────────────────────────

APRÈS (CORRECT):
────────────────────────────────────────────────────────────────────────────────
// UserConfiguration.cs
builder.HasData(new User
{
    Id = Guid.Parse("7f3c9a2e-8d1b-4e5f-a6c8-9b4d2f7e1a3c"),
    Name = "Admin",
    Email = "admin@test.com"
});
────────────────────────────────────────────────────────────────────────────────

Puis: dotnet ef migrations add MigrateSeedData
```

---

## Support

> **Questions ou problèmes avec le seeding EF Core?**
>
> 📧 **support@atlshub.ch**
