# Analyse de l'API C# SkydiveLogs - Architecture et Fonctionnement

## Vue d'ensemble

L'API **SkydiveLogs** est une application ASP.NET Core MVC développée avec une architecture modulaire propre, divisée en six projets distincts qui reposent sur une architecture en couches (Layered Architecture) :

### Structure du Projet
```
SkydiveLogs/Back/
├── skydiveLogs-api/              # Projet principal (Web API + Point d'entrée)
├── skydiveLogs-api.Domain/       # Modèles de domaine (Entités)
├── skydiveLogs-api.DomainBusiness/ # Couche business logique (Services)
├── skydiveLogs-api.DomainService/ # Couche d'accès aux données (Repositories)
├── skydiveLogs-api.Infrastructure/ # Implémentations des repositories
├── skydiveLogs-api.Ioc/          # Service d'injection de dépendances
└── skydiveLogs-api.sln           # Fichier de solution
```

## 1. Architecture des Couches

### 1.1 Architecture Clean/Modulaire

L'API suit le **pattern Clean Architecture** avec une séparation claire des responsabilités :

```
┌─────────────────────────────────────────────────────┐
│  skydiveLogs-api (Presentation Layer)                │
│  - Controllers                                       │
│  - Program.cs / Startup.cs                           │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.Ioc (Dependency Injection)          │
│  - Configuration IoC                                 │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.DomainBusiness (Business Layer)     │
│  - Services (Interfaces + Implémentations)           │
│  - Logique métier                                     │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.DomainService (Data Access Layer)   │
│  - Repositories (Interfaces)                         │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.Infrastructure (Implementation)     │
│  - Repositories implémentés                           │
│  - LiteDbProvider                                     │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.Domain (Domain Layer)               │
│  - Modèles de données (Entities)                     │
└─────────────────────────────────────────────────────┘
```

### 1.2 Injection de Dépendances (IocService)

Le projet **skydiveLogs-api.Ioc** gère toute l'injection de dépendances via la classe `IocService` :

#### Services Injectés
- **Aircraft**, **Gear**, **DropZone**, **Jump**, **JumpType**, **Tunnel**, **User** et leurs services
- **Stats** services (analytique)
- **CacheService** (singleton pour le cache)
- **IdentityService** (authentification)
- **Repositories** pour chaque entité
- **LiteDbProvider** (fournisseur de données LiteDB)

```csharp
services.AddScoped<IAircraftService, AircraftService>();
services.AddScoped<IGearService, GearService>();
services.AddScoped<IDropZoneService, DropZoneService>();
services.AddScoped<IJumpService, JumpService>();
// ... et ainsi de suite pour tous les services
```

## 2. Configuration de l'Application (Startup.cs)

### 2.1 Configuration de l'Application

Le fichier **Startup.cs** configure :

1. **Authentication JWT**
   - Validation du token JWT avec :
     - Vérification de l'émetteur (issuer)
     - Vérification de l'audience (audience)
     - Vérification de l'expiration (lifetime)
     - Validation de la clé de signature
   
2. **CORS**
   - Configuration pour autoriser la communication avec l'application front-end
   
3. **Initialisation de la Base de Données**
   - Vérification de l'existence du fichier LiteDB
   - Appel à `InitDbService.GenerateDb()` si le fichier n'existe pas
   - Appel à `InitDbService.Update()` si le fichier existe

### 2.2 Programme Principal (Program.cs)

```csharp
public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) 
    => WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
```

## 3. Architecture des Contrôleurs

Tous les contrôleurs héritent de la classe de base `Base` :

### 3.1 Classe Base

```csharp
[Route("api/[controller]")]
[ApiController]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class Base : ControllerBase { }
```

**Annotations importantes :**
- `Route("api/[controller]")` : Préfixe "api/" pour toutes les routes
- `ApiController` : Optimisations pour les API
- `Authorize` : Requêtes authentifiées via JWT

### 3.2 Structure Type des Contrôleurs

Chaque contrôleur suit le même pattern :

```csharp
public class XxxController : Base
{
    public XxxController(IxxxService xxxService, IMapper mapper)
    {
        _xxxService = xxxService;
        _mapper = mapper;
    }
    
    [HttpGet]
    public IEnumerable<XxxResp> Get() { ... }
    
    [HttpGet("{id}")]
    public XxxResp Get(int id) { ... }
    
    [HttpPost]
    public void Post([FromBody] XxxReq value) { ... }
    
    [HttpPut("{id}")]
    public void Put(int id, [FromBody] XxxReq value) { ... }
    
    [HttpDelete("{id}")]
    public void Delete(int id) { ... }
}
```

## 4. Entités de Domaine (skydiveLogs-api.Domain)

### 4.1 Entités Principales

#### **Jump** (Saut de parachutisme)
```csharp
public class Jump
{
    public Aircraft Aircraft { get; set; }
    public int DeployAltitude { get; set; }
    public DropZone DropZone { get; set; }
    public int ExitAltitude { get; set; }
    public Gear Gear { get; set; }
    public int Id { get; set; }
    public bool IsSpecial { get; set; }
    public DateTime JumpDate { get; set; }
    public JumpType JumpType { get; set; }
    public string Notes { get; set; }
    public User User { get; set; }
    public bool WithCutaway { get; set; }
}
```

**Autres entités :**
- **Aircraft** : Données des aéronefs
- **User** : Utilisateurs (avec authentification)
- **DropZone** : Zones de parachute (parachute drops)
- **Gear** : Équipement
- **JumpType** : Types de sauts
- **Tunnel** : Données de tunnels
- **TunnelFlight** : Vols de tunnel
- **CacheType** : Types de cache

#### **User** (avec authentification)
```csharp
public class User
{
    public string Email { get; set; }
    public string FirstName { get; set; }
    public int Id { get; set; }
    public bool IsAdmin { get; set; }
    public string Language { get; set; }
    public string LastName { get; set; }
    public string Login { get; set; }
    public string Password { get; set; }
}
```

### 4.2 Modèles de Statistiques

Des entités dédiées pour les statistiques :
- `Statistic` - Statistiques générales
- `StatsByAircraft` - Statistiques par aéronef
- `StatsByDz` - Statistiques par zone de parachute
- `StatsByGear` - Statistiques par équipement
- `StatsByJumpType` - Statistiques par type de saut
- `StatsByYear` - Statistiques par année
- `StatsByYearByJumpType` - Statistiques croisées année/type
- `StatsForLastMonthByDz` - Statistiques du dernier mois
- `StatsForLastYearByDz` - Statistiques de l'année dernière

## 5. Services de Business Logic (skydiveLogs-api.DomainBusiness)

### 5.1 Services Disponibles

Chaque service implémente une interface dans `Interfaces` :

#### Services CRUD
- `AircraftService` - Gestion des aéronefs
- `DropZoneService` - Gestion des zones de parachute
- `GearService` - Gestion de l'équipement
- `JumpService` - Gestion des sauts (principal)
- `JumpTypeService` - Gestion des types de sauts
- `TunnelService` - Gestion des tunnels
- `TunnelFlightService` - Gestion des vols de tunnel
- `UserImageService` - Gestion des images utilisateurs
- `UserService` - Gestion des utilisateurs

#### Services de Cache
- `CacheService` - Gestion du cache
- `IdentityService` - Gestion de l'identité/authentification

#### Services d'Initialisation
- `InitDbService` - Initialisation de la base de données

#### Services Statistiques
- `StatsService` - Statistiques générales
- `StatsByAircraftService` - Par aéronef
- `StatsByDzService` - Par zone de parachute
- `StatsByGearService` - Par équipement
- `StatsByJumpTypeService` - Par type de saut
- `StatsByYearService` - Par année
- `StatsByYearByJumpTypeService` - Croisé année/type
- `StatsForLastMonthByDzService` - Dernier mois
- `StatsForLastMonthByJumpTypeService` - Dernier mois
- `StatsForLastYearByDzService` - Dernière année
- `StatsForLastYearByJumpTypeService` - Dernière année

### 5.2 Implémentations de Services (ex: JumpService)

Les services implémentent la logique métier et utilisent les repositories :

```csharp
public class JumpService : IJumpService
{
    private readonly IJumpRepository _jumpRepository;
    private readonly IMapper _mapper;
    
    public void AddNewJump(...) { ... }
    public void DeleteJumpById(int id) { ... }
    public IEnumerable<Jump> GetAllJumps() { ... }
    public Jump GetJumpById(int id) { ... }
    public Jump GetJumpByUserAndDate(...) { ... }
    public int GetJumpCount() { ... }
    public IEnumerable<Jump> GetJumpsByIndexes(...) { ... }
    public Jump UpdateJump(int id, Jump jump) { ... }
}
```

## 6. Répositories (skydiveLogs-api.DomainService et Infrastructure)

### 6.1 Couche DomainService

Contient uniquement les interfaces `IxxxRepository` qui définissent le contrat d'accès aux données.

### 6.2 Couche Infrastructure

Implémente concrètement les repositories avec **LiteDB** (base de données fichier NoSQL) :

```csharp
public class JumpRepository : IJumpRepository
{
    private readonly IDataProvider _dataProvider;
    private readonly IRepository<Jump> _jumpCollection;
    
    // Implémentation concrète
}
```

**LiteDbProvider** est utilisé comme fournisseur de données pour l'accès au fichier LiteDB.

## 7. Gestion des Données (Data)

### 7.1 Structure du Folder Data

```
skydiveLogs-api/Data/
├── Aircraft/
├── DropZone/
├── FavoriteDropZone/
├── Gear/
├── Image/
├── Jump/
├── JumpType/
├── StatsByAircraft/
├── StatsByDz/
├── StatsByGear/
├── StatsByJumpType/
├── StatsByYear/
├── StatsByYearByJumpType/
├── StatsForLastMonthByDz/
├── StatsForLastMonthByJumpType/
├── StatsForLastYearByDz/
├── StatsForLastYearByJumpType/
├── Tunnel/
├── TunnelFlight/
└── User/
```

Chaque dossier correspond à une collection LiteDB.

### 7.2 Contrats de Données (DataContract)

Les fichiers `DataContract` contiennent les DTOs (Data Transfer Objects) :

#### Requête (Req)
- `AircraftReq`, `DropZoneReq`, `GearReq`, `JumpReq`, `JumpTypeReq`
- `UserReq`, `TunnelFlightReq`, `ImageReq`

#### Réponse (Resp)
- `AircraftResp`, `AircraftSimpleResp`, `DropZoneResp`, `DropZoneSimpleResp`
- `GearResp`, `JumpResp`, `JumpListResp`, `JumpTypeResp`
- `UserResp`, `TunnelResp`, `TunnelFlightResp`, `ImageResp`
- `StatisticResp`, `StatisticForChartResp`
- `SimpleSummaryResp`

#### Statistiques
- `StatsForLastMonthByDzResp`
- `StatsForLastYearByDzResp`

## 8. Mappage avec AutoMapper

### 8.1 Configuration AutoMapper

Le fichier **Mapper** contient le profile d'AutoMapper pour mapper entre :
- Domain entities (Aircraft, User, Jump, etc.)
- DTOs (AircraftResp, UserResp, JumpResp, etc.)

```csharp
public class ModelProfile : Profile
{
    public ModelProfile()
    {
        // Configuration des mappages
        CreateMap<User, UserResp>();
        CreateMap<Aircraft, AircraftResp>();
        CreateMap<Jump, JumpResp>();
        // ... etc
    }
}
```

### 8.2 Utilisation dans les Contrôleurs

```csharp
public JumpListResp Get()
{
    var tmp = _jumpService.GetAllJumps();
    var result = new JumpListResp
    {
        Rows = _mapper.Map<IEnumerable<JumpResp>>(tmp),
        Count = tmp.Count()
    };
    return result;
}
```

## 9. Authentification JWT

### 9.1 Configuration JWT (Startup.cs)

```csharp
var jwtSection = Configuration.GetSection("JWT");
services.Configure<JwtSettings>(jwtSection);

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.SaveToken = true;
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = jwtSettings.Issuer,
            ValidAudience = jwtSettings.Issuer,
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(jwtSettings.Passphrase))
        };
    });
```

### 9.2 Token Generation (UserController)

```csharp
private string CreateToken(UserResp foundUser)
{
    var key = new SymmetricSecurityKey(
        Encoding.UTF8.GetBytes(_jwtConf.Passphrase));
    var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: _jwtConf.Issuer,
        audience: _jwtConf.Issuer,
        expires: DateTime.Now.AddDays(1),
        signingCredentials: credentials,
        claims: new Claim[]
        {
            new Claim(ClaimTypes.Name, foundUser.Login),
            new Claim(ClaimTypes.UserData, foundUser.Id.ToString()),
            new Claim(ClaimTypes.Email, foundUser.Email),
            new Claim(ClaimTypes.Role, foundUser.Roles),
            new Claim("Language", foundUser.Language ?? "")
        });

    return new JwtSecurityTokenHandler().WriteToken(token);
}
```

## 10. Endpoints API Disponibles

### 10.1 Routes par Contrôleur

#### `/api/Jump`
- `GET /api/Jump` - Liste tous les sauts
- `GET /api/Jump/{id}` - Get par ID
- `GET /api/Jump/{beginJumpIndex}/{endJumpIndex}` - Pagination
- `POST /api/Jump` - Créer un saut
- `PUT /api/Jump/{id}` - Mettre à jour
- `DELETE /api/Jump/{id}` - Supprimer

#### `/api/User`
- `GET /api/User/AlwaysLogin` - Vérification connexion
- `POST /api/User/Authenticate` - Authentification
- `POST /api/User` - Créer un utilisateur

#### `/api/Aircraft`
- `GET /api/Aircraft` - Liste
- `GET /api/Aircraft/{id}` - Get
- `GET /api/Aircraft/GetSimple` - Liste simplifiée
- `POST /api/Aircraft` - Créer
- `PUT /api/Aircraft/{id}` - Mettre à jour
- `DELETE /api/Aircraft/{id}` - Supprimer

#### `/api/DropZone`
- `GET /api/DropZone` - Liste
- `GET /api/DropZone/{id}` - Get
- `GET /api/DropZone/GetSimple` - Liste simplifiée
- `POST /api/DropZone` - Créer
- `PUT /api/DropZone/{id}` - Mettre à jour
- `DELETE /api/DropZone/{id}` - Supprimer
- `PUT /api/DropZone/AddToFavorite/{id}` - Ajouter aux favoris
- `PUT /api/DropZone/RemoveToFavorite/{id}` - Retirer des favoris

#### `/api/Gear`
- `GET /api/Gear` - Liste
- `GET /api/Gear/{id}` - Get
- `POST /api/Gear` - Créer
- `PUT /api/Gear/{id}` - Mettre à jour
- `DELETE /api/Gear/{id}` - Supprimer

#### `/api/JumpType`
- `GET /api/JumpType` - Liste
- `GET /api/JumpType/tunnel` - Types pour tunnel
- `GET /api/JumpType/{id}` - Get
- `POST /api/JumpType` - Créer
- `PUT /api/JumpType/{id}` - Mettre à jour
- `DELETE /api/JumpType/{id}` - Supprimer

#### `/api/Tunnel`
- `GET /api/Tunnel` - Liste
- `GET /api/Tunnel/{id}` - Get

#### `/api/TunnelFlight`
- Routes pour gestion des vols tunnel

#### `/api/Image`
- `GET /api/Image` - Liste
- `GET /api/Image/{id}` - Get
- `POST /api/Image` - Créer
- `PUT /api/Image/{id}` - Mettre à jour
- `DELETE /api/Image/{id}` - Supprimer

#### `/api/Stats`
- `GET /api/Stats/ByAircraft` - Stats par aéronef
- `GET /api/Stats/ByDz` - Stats par zone
- `GET /api/Stats/ByGear` - Stats par équipement
- `GET /api/Stats/ByJumpType` - Stats par type
- `GET /api/Stats/ByYear` - Stats par année
- `GET /api/Stats/ByYearByJumpType` - Stats croisées
- `GET /api/Stats/ForLastMonth` - Stats du mois dernier
- `GET /api/Stats/ForLastYear` - Stats de l'année dernière
- `GET /api/Stats/Simple` - Résumé simple
- `GET /api/Stats/Reset` - Réinitialiser les stats

## 11. Gestion de Configuration

### 11.1 Fichiers appsettings

Les configurations sont stockées dans :
- `appsettings.json` - Configuration par défaut
- `appsettings.Development.json` - Configuration de développement
- `appsettings.Release.json` - Configuration de production

### 11.2 Sections de Configuration

- **JWT** - Configuration JWT (issuer, passphrase)
- **Cors** - Configuration CORS (frontUrl)
- **ConnectionStrings** - Connexion LiteDB (Filename)

## 12. Initialisation de la Base de Données

Le fichier `CheckAndInitDb` dans `Startup.cs` s'assure que :
1. Le fichier LiteDB existe
2. Si non, `InitDbService.GenerateDb()` crée la structure
3. Si oui, `InitDbService.Update()` met à jour la structure

## 13. Bonnes Pratiques Observées

### 13.1 Séparation des Responsabilités
- Les contrôleurs ne font que manipuler les requêtes/réponses
- La logique métier est dans les services
- L'accès aux données est dans les repositories

### 13.2 Sécurité
- Authentification JWT
- Autorisation par rôle (admin flag)
- Validation des tokens
- HSTS en production

### 13.3 Gestion des Erreurs
- Développement avec `UseDeveloperExceptionPage()`
- Production avec HSTS
- Gestion des erreurs via services

### 13.4 Performance
- Pagination des listes (par index)
- Cache avec `CacheService`
- AutoMapper pour éviter le code répétitif

## 14. Conclusion

L'API **SkydiveLogs** est une application C# robuste et bien structurée, utilisant :
- **ASP.NET Core MVC** avec API
- **LiteDB** comme base de données fichier
- **JWT** pour l'authentification
- **AutoMapper** pour le mappage
- **Injection de dépendances** via `IocService`

L'architecture en couches assure une maintenabilité et une extensibilité optimales pour une application de journalisation de parachutisme.