Test updates by AI

This commit is contained in:
2026-03-24 22:11:58 +01:00
parent 0ebdbca549
commit 8f0cb650c7
11 changed files with 708 additions and 44 deletions
+571
View File
@@ -0,0 +1,571 @@
# 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.