---
name: debug-backend
description: Diagnose and auto-fix SmartStack .NET backend failures
group: DEBUG
allowed-tools: [Read, Edit, Write, Glob, Grep, Bash]  # Bash: diagnostic commands
---

# Skill: Debug Backend — .NET + EF Core + Kestrel

## Contexte

Tu opères dans le worktree d'un projet SmartStack client. Le backend est un projet
.NET 10 avec structure Clean 4 layers (Domain / Application / Infrastructure / Api).
Le dev-runner du Studio spawn `dotnet run --no-build --no-launch-profile --urls http://localhost:{port}`.

## Plan d'exécution

### Étape 1 — Build

```bash
cd src/{AppCode}.Api
dotnet build --nologo --verbosity normal
```

**Analyser la sortie** :
- **Exit 0 + "Build succeeded"** → passer à l'étape 2
- **Exit ≠ 0 + "Build FAILED"** → parser les erreurs MSBuild (lignes `error CS####`), identifier le fichier+ligne, corriger, relancer

**Erreurs de build courantes** :
| Erreur | Cause | Fix |
|--------|-------|-----|
| `CS0246: The type or namespace name 'X' could not be found` | Using manquant / référence projet absente | Ajouter `using` ou `<ProjectReference>` dans .csproj |
| `CS0117: 'X' does not contain a definition for 'Y'` | Propriété renommée / version lib différente | Vérifier l'API du package, adapter l'appel |
| `MSB3026: Impossible de copier ... locked by ...` | Process .Api.exe orphelin | `Get-Process | Where-Object Name -like '*{AppCode}.Api*' | Stop-Process -Force` |
| `NETSDK1045: .NET SDK 10 is required` | SDK incorrect | `dotnet --list-sdks` pour vérifier, installer .NET 10 |

### Étape 2 — Run + health check

```bash
dotnet run --no-build --no-launch-profile --urls http://localhost:5142 --project src/{AppCode}.Api
```

En parallèle dans un autre terminal :
```bash
# Attendre 10s puis tester
curl -fsS http://localhost:5142/health || curl -fsS http://localhost:5142/
```

**Erreurs de runtime courantes** :

| Symptôme dans logs | Cause | Fix |
|--------------------|-------|-----|
| `System.InvalidOperationException: The endpoint Http is missing the required 'Url' parameter` | `Kestrel:Endpoints:Http` sans `Url` dans appsettings.json | Ajouter `"Url": "http://localhost:5142"` ou **supprimer** la section `Kestrel:Endpoints` (le --urls CLI suffit) |
| `Microsoft.Data.SqlClient.SqlException: A network-related ... error` | SQL Server pas lancé | `Get-Service MSSQL* | Where Status -eq Running` — démarrer via `Start-Service MSSQLSERVER` |
| `Microsoft.Data.SqlClient.SqlException: Login failed` | ConnectionString invalide | Vérifier `ConnectionStrings:DefaultConnection` dans appsettings.Development.json |
| `System.InvalidOperationException: No migrations configuration ...` | Migration EF Core absente | `dotnet ef migrations add Initial --project src/{AppCode}.Infrastructure --startup-project src/{AppCode}.Api` |
| `The migration '...' has already been applied` | DB désynchronisée | **⚠ DESTRUCTIF**: `dotnet ef database drop --force` détruit les données locales. NE PAS exécuter sans confirmation utilisateur explicite. Alternative non-destructive: `dotnet ef migrations list --startup-project src/{AppCode}.Api` pour voir l'état, puis `dotnet ef database update 0 --startup-project src/{AppCode}.Api` pour revenir à l'état vide, puis `dotnet ef database update` |
| `Unhandled exception. System.Reflection.TargetInvocationException` | DI container — service manquant | Chercher `AddScoped`/`AddSingleton` manquant dans `Program.cs` ou `DependencyInjection.cs` |
| `JwtBearer Authentication was not configured` | Jwt.Secret vide | Vérifier `Jwt:Secret` dans appsettings.json |
| `Application started. Press Ctrl+C to shut down.` + `/health` retourne ECONNREFUSED | Backend écoute ailleurs | Chercher `Now listening on:` pour voir le vrai port |

### Étape 3 — Vérifier

**3a. L'endpoint /health répond ?**
```bash
curl -I http://localhost:5142/health
```

- HTTP 200 / 204 / 404 → passer à 3b
- ECONNREFUSED → backend mort, reboucler sur étape 2

**3b. La DB répond via l'API ?** (critical — port binding OK ≠ app fonctionnelle)
```bash
# L'endpoint /health de SmartStack doit inclure un check DB. Vérifier le corps:
curl -fsS http://localhost:5142/health
# Attendu: {"status":"Healthy", ...} ou équivalent incluant une entrée DB
```

Si `/health` retourne 200 mais que la clé `database`/`db`/`sqlServer` est absente ou `Unhealthy` :
- ConnectionString incorrecte → vérifier `appsettings.Development.json`
- SQL Server en panne → `Get-Service MSSQL* | Where Status -eq Running`
- Permissions DB manquantes → user de la connection string n'a pas accès à la DB

**3c. L'API de navigation répond ?** (requis pour que le frontend charge)
```bash
# Sans token JWT, attendre 401. Avec token valide, attendre JSON.
curl -I http://localhost:5142/api/navigation/menu
# 401 → OK (endpoint existe, auth requise)
# 404 → routing cassé, controllers pas mappés
# 500 → exception à investiguer (seed non lancé ? DB vide ?)
```

## Fichiers clés à vérifier

```
src/{AppCode}.Api/
├── Program.cs                     # 4 calls SmartStack : AddSmartStack, InitializeSmartStackAsync, UseSmartStack, MapSmartStack
├── appsettings.json               # ConnectionStrings, Jwt, Kestrel (⚠ pas d'Endpoints:Url vide)
├── appsettings.Development.json   # Overrides dev
└── Properties/launchSettings.json # applicationUrl (ignoré par --no-launch-profile mais reste une référence)

src/{AppCode}.Infrastructure/
└── Migrations/                    # Doit contenir au moins une migration Initial
```

## Validation finale

Avant de dire "fixé" :
1. `dotnet build --nologo` → exit 0, 0 errors
2. `dotnet run --no-build --no-launch-profile --urls http://localhost:5142` tourne
3. `curl http://localhost:5142/health` → HTTP 2xx/4xx (pas 0)
4. Pas de stack trace dans les 50 dernières lignes de stdout

Si un fix modifie le schéma DB, suggérer à l'utilisateur de créer une migration EF Core.
