diff --git a/PyroFetes/README.md b/PyroFetes/README.md new file mode 100644 index 00000000..a6063b32 --- /dev/null +++ b/PyroFetes/README.md @@ -0,0 +1,300 @@ +# 🎆 Pyrofêtes — Backend + +> API REST de gestion des entrepôts et produits pyrotechniques, développée avec **C#**, **ASP.NET Core** et **FastEndpoints**. + +--- + +## 🛠️ Stack technique + +| Technologie | Rôle | +|---|---| +| [C# / .NET 8](https://dotnet.microsoft.com/) | Langage et runtime principal | +| [ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/) | Framework web | +| [FastEndpoints](https://fast-endpoints.com/) | Bibliothèque d'endpoints REST performants | +| Entity Framework Core | ORM pour l'accès à la base de données | +| SQL Server | Base de données relationnelle | +| JWT Bearer | Authentification par token | + +--- + +## 📁 Structure du projet + +``` +Pyrofetes.API/ +│ +├── Models/ # Entités de la base de données (EF Core) +│ +├── DTO/ # Objets de transfert de données +│ ├── Brand/ +│ │ ├── Request/ +│ │ │ ├── CreateBrandDto.cs +│ │ │ └── UpdateBrandDto.cs +│ │ └── Response/ +│ │ └── GetBrandDto.cs +│ ├── Classification/ +│ ├── Color/ +│ ├── Effect/ +│ ├── Login/ +│ ├── Material/ +│ ├── Movement/ +│ ├── Product/ +│ ├── ProductCategory/ +│ ├── ProductColor/ +│ ├── ProductEffect/ +│ ├── ProductSupplierPrice/ +│ ├── ProductWarehouse/ +│ ├── Refrresh/ # Token refresh +│ ├── Supplier/ +│ └── Warehouse/ +│ +├── Endpoints/ # Endpoints FastEndpoints (CRUD par domaine) +│ ├── Brand/ +│ │ ├── CreateBrandEndpoint.cs +│ │ ├── DeleteBrandEndpoint.cs +│ │ ├── GetAllBrandsEndpoint.cs +│ │ ├── GetBrandEndpoint.cs +│ │ └── UpdateBrandEndpoint.cs +│ ├── Classification/ +│ ├── Color/ +│ ├── Effect/ +│ ├── Login/ +│ ├── Material/ +│ ├── Movement/ +│ ├── Product/ +│ ├── ProductCategory/ +│ ├── Refresh/ # Refresh token JWT +│ ├── Supplier/ +│ └── Warehouse/ +│ +├── Data/ # Contexte Entity Framework Core +│ └── AppDbContext.cs +│ +├── Migrations/ # Migrations EF Core +├── appsettings.json # Configuration production +├── appsettings.Development.json # Configuration développement +└── Program.cs # Point d'entrée et configuration des services +``` + +--- + +## 🚀 Installation et lancement + +### Prérequis + +- [.NET SDK](https://dotnet.microsoft.com/download) >= 8.0 +- SQL Server en cours d'exécution (local ou distant) +- [Entity Framework CLI](https://learn.microsoft.com/en-us/ef/core/cli/dotnet) + +```bash +dotnet tool install --global dotnet-ef +``` + +### Installation + +```bash +# Cloner le dépôt +git clone https://github.com/votre-org/pyrofetes-backend.git +cd pyrofetes-backend +``` + +### Configuration + +Editer `appsettings.Development.json` : + +```json +{ + "ConnectionStrings": { + "DefaultConnection": "Server=localhost,1433;Database=PyrofetesDb;User Id=sa;Password=VotreMotDePasse;TrustServerCertificate=True;" + }, + "JwtSettings": { + "SecretKey": "votre-cle-secrete-minimum-32-caracteres", + "Issuer": "PyrofetesAPI", + "Audience": "PyrofetesFrontend", + "ExpirationMinutes": 60, + "RefreshTokenExpirationDays": 7 + } +} +``` + +### Migrations et base de données + +```bash +# Créer la base de données et appliquer les migrations +dotnet ef database update +``` + +### Lancement + +```bash +dotnet run +``` + +L'API sera disponible sur [http://localhost:5000](http://localhost:5000) +La documentation Swagger sera accessible sur [http://localhost:5000/swagger](http://localhost:5000/swagger) + +--- + +## ⚙️ Configuration FastEndpoints + CORS + +Dans `Program.cs` : + +```csharp +builder.Services.AddCors(options => +{ + options.AddPolicy("AllowAngular", policy => + policy.WithOrigins("http://localhost:4200") + .AllowAnyHeader() + .AllowAnyMethod()); +}); + +builder.Services.AddFastEndpoints(); +builder.Services.AddJWTBearerAuth("votre-cle-secrete"); + +var app = builder.Build(); + +app.UseCors("AllowAngular"); +app.UseAuthentication(); +app.UseAuthorization(); +app.UseFastEndpoints(); +app.Run(); +``` + +### Anatomie d'un endpoint + +Chaque endpoint suit le pattern **Request → Handler → Response** de FastEndpoints : + +```csharp +// Endpoints/Brand/GetAllBrandsEndpoint.cs +public class GetAllBrandsEndpoint : EndpointWithoutRequest> +{ + private readonly AppDbContext _db; + + public GetAllBrandsEndpoint(AppDbContext db) => _db = db; + + public override void Configure() + { + Get("/api/brands"); + Roles("Admin", "User"); + } + + public override async Task HandleAsync(CancellationToken ct) + { + var brands = await _db.Brands + .Select(b => new GetBrandDto { Id = b.Id, Name = b.Name }) + .ToListAsync(ct); + + await SendOkAsync(brands, ct); + } +} +``` + +### Pattern DTO + +``` +DTO/ +└── Brand/ + ├── Request/ + │ ├── CreateBrandDto.cs ← payload entrant (POST) + │ └── UpdateBrandDto.cs ← payload entrant (PUT) + └── Response/ + └── GetBrandDto.cs ← payload sortant (GET) +``` + +--- + +## 📡 Endpoints API + +> Tous les endpoints (sauf `/api/auth/*` et `/api/auth/refresh`) requièrent un header `Authorization: Bearer `. + +### Authentification + +| Méthode | Route | Description | Auth | +|---|---|---|---| +| `POST` | `/api/auth/login` | Connexion, retourne JWT + refresh token | ❌ | +| `POST` | `/api/auth/refresh` | Renouvellement du JWT via refresh token | ❌ | + +### Marques (Brand) + +| Méthode | Route | Description | +|---|---|---| +| `GET` | `/api/brands` | Liste toutes les marques | +| `GET` | `/api/brands/{id}` | Détail d'une marque | +| `POST` | `/api/brands` | Créer une marque | +| `PUT` | `/api/brands/{id}` | Modifier une marque | +| `DELETE` | `/api/brands/{id}` | Supprimer une marque | + +### Produits (Product) + +| Méthode | Route | Description | +|---|---|---| +| `GET` | `/api/products` | Liste tous les produits | +| `GET` | `/api/products/{id}` | Détail d'un produit | +| `POST` | `/api/products` | Créer un produit | +| `PUT` | `/api/products/{id}` | Modifier un produit | +| `DELETE` | `/api/products/{id}` | Supprimer un produit | + +### Entrepôts (Warehouse) + +| Méthode | Route | Description | +|---|---|---| +| `GET` | `/api/warehouses` | Liste tous les entrepôts | +| `GET` | `/api/warehouses/{id}` | Détail d'un entrepôt | +| `POST` | `/api/warehouses` | Créer un entrepôt | +| `PUT` | `/api/warehouses/{id}` | Modifier un entrepôt | +| `DELETE` | `/api/warehouses/{id}` | Supprimer un entrepôt | + +### Fournisseurs (Supplier) + +| Méthode | Route | Description | +|---|---|---| +| `GET` | `/api/suppliers` | Liste tous les fournisseurs | +| `GET` | `/api/suppliers/{id}` | Détail d'un fournisseur | +| `POST` | `/api/suppliers` | Créer un fournisseur | +| `PUT` | `/api/suppliers/{id}` | Modifier un fournisseur | +| `DELETE` | `/api/suppliers/{id}` | Supprimer un fournisseur | + +### Autres domaines disponibles + +| Domaine | Préfixe route | +|---|---| +| Classifications | `/api/classifications` | +| Couleurs | `/api/colors` | +| Effets | `/api/effects` | +| Matériaux | `/api/materials` | +| Mouvements de stock | `/api/movements` | +| Catégories produit | `/api/product-categories` | +| Couleurs produit | `/api/product-colors` | +| Effets produit | `/api/product-effects` | +| Prix fournisseur produit | `/api/product-supplier-prices` | + +--- + +## 🔐 Authentification JWT + +### Flux d'authentification + +``` +Client (Angular) API (FastEndpoints) + │ │ + │── POST /api/auth/login ──▶│ + │ │ Vérifie credentials + │◀── { token, refreshToken }│ + │ │ + │── GET /api/... ──────────▶│ + │ Authorization: Bearer │ Valide le JWT + │◀── 200 OK ────────────────│ + │ │ + │── POST /api/auth/refresh ▶│ (token expiré) + │◀── { newToken } ──────────│ +``` + +### Header requis + +``` +Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... +``` +--- + +## 📄 Licence + +Ce projet est à usage interne — © Pyrofêtes. Tous droits réservés. \ No newline at end of file