Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Semaine 3

Objectif

Pour cette séance, votre objectif est de pouvoir utiliser toutes les fonctionalités du front https://csharp.nouvet.fr/front3

Pour que ce frontend fonctionne avec votre backend vous devrez implémenter le même protocole de communication.

La liste des modèles de donnée ainsi que la liste des routes se trouve à la fin de cette page.

Prérequis

Pour que la communication puisse se faire, il y a 2 pré requis:

  • le backend doit être en cours d’exécution avec le port 5000
  • vous devez autoriser les requêtes CORS pour l’URL du frontend Doc CORS

Pour changer le port de votre backend, vous pouvez le faire dans le fichier Properties/launchSettings.json.

Gitignore

Je vous invite à ajouter ce fichier .gitignore dans votre projet.

https://github.com/microsoft/dotnet/blob/main/.gitignore

Il vous permettra de ne pas commiter les fichiers de build, les fichiers de configuration, les fichiers de log, etc.

Records

Je vous demanderais d’utiliser des records pour les DTO (Data Transfer Object). Doc Record

Un DTO est un objet qui est transmis entre le frontend et le backend ou l’inverse.

Dans votre cas, cela inclut tout les modèle sauf ceux qui sont stocké en base de données comme User et Progression.

Retour d’erreur

Vous devrez retourner des ErrorResponse en cas d’erreur.

public record ErrorResponse(string Message, string Code);

Vous trouverez les code associés dans les détails de chaque endpoint.

**Errors:**
- `404` - `USER_NOT_FOUND` - User not found

Ici on retourne un code 404 et un message d’erreur avec le code USER_NOT_FOUND.

Dans le code ca ressemblerait à ceci:

return NotFound(new ErrorResponse("User not found", "USER_NOT_FOUND"));

Le front s’attend à certains codes d’erreur et vous devrez les retourner avec les codes exacts.

Controller Game

Vous devrez créer un controller GameController qui sera chargé de gérer les interactions avec le jeu.

En plus du controlleur de jeu vous ajouterez une table Progression dans la BDD pour stocker les données du jeu.

Pour les champs de la classe Progression, regardez le modèle de données Progression en bas de page.

Le controleur devra pouvoir:

  • Récupérer la progression d’un utilisateur
  • Initialiser la progression d’un utilisateur
  • Augmenter le score d’un utilisateur
  • Récupérer le coût d’un reset
  • Reset le score d’un utilisateur et incrementer le multiplicateur
  • Récupérer le score le plus haut en base de données

Ordre d’implémentation

Dans l’ordre, voici les endpoints que vous devrez implémenter:

  • Register
  • Login
  • Get User Progression
  • Initialize Progression
  • Click
  • Get Reset Cost
  • Reset Progression
  • Get User by ID
  • Get Best Score
  • Get All Users
  • Delete User
  • Update User
  • Get All Admin Users
  • Search Users

Game Design

Le jeu est un jeu de clicker.

L’utilisateur clique sur un bouton pour augmenter son score.

Le score est augmenté de 1 a chaque clic.

Quand l’utilisateur à assez de point, il peut reset son score et le multiplicateur augmente de 1.

Voici la formule pour calculer le coût d’un reset:

private int CalculateResetCost(int multiplier)
{
        // Exponential cost: 100 * (1.5^(multiplier-1))
        double baseCost = 100.0;
        double growthFactor = 1.5;
        double cost = baseCost * Math.Pow(growthFactor, multiplier - 1);
        return (int)Math.Floor(cost);
}

Contrainte et rôle des utilisateurs

Quand un utilisateur s’inscrit, il aura par défaut le rôle User.

Sauf si aucun utilisateur Admin n’existe en base de données, alors le nouvel utilisateur sera automatiquement Admin.

Le pseudo doit être unique en base de données.

Validation des données

Vous utiliserez les annotations de data annotation pour valider les données du UserPass et du UserUpdate.

Vous implémenterez les règles suivantes:

  • Le mot de passe doit être d’au moins 4 caractères et comporter uniquement des lettres, des chiffres et les caractères spéciaux &^!@#.
  • Le pseudo doit être d’au moins 3 caractères alphanumériques.
  • Les longueurs maximales sont de 20 caractères pour le pseudo et le mot de passe.
  • Le champ sont marqués comme obligatoires.

Vous trouverez des exemples de validation dans la documentation sur les data annotations.

Game Server API Documentation

Les champs commence par une minuscules ici, mettez les bien en PascalCase dans votre code.

Base URL: http://localhost:5000/api


User Endpoints

Get User by ID

GET /api/User/{id}

Returns: UserPublic

Errors:

  • 404 - USER_NOT_FOUND - User not found

Login

POST /api/User/Login

Body: UserPass

Returns: UserPublic

Errors:

  • 404 - USER_NOT_FOUND - User not found
  • 401 - INVALID_PASSWORD - Invalid password

Register

POST /api/User/Register

Body: UserPass

Returns: UserPublic

Errors:

  • 400 - USERNAME_EXISTS - Username already exists
  • 400 - REGISTRATION_FAILED - Registration failed

Update User

PUT /api/User/{id}

Body: UserUpdate

Returns: User (full user object)

Errors:

  • 404 - USER_NOT_FOUND - User not found

Delete User

DELETE /api/User/{id}

Returns: true

Errors:

  • 404 - USER_NOT_FOUND - User not found

Note: Deletes user’s progression automatically (cascade)


Get All Users

GET /api/User/All

Returns: UserPublic[]


Get All Admin Users

GET /api/User/AllAdmin

Returns: UserPublic[]


Search Users

GET /api/User/Search/{name}

Returns: UserPublic[]


Game Endpoints

Click

GET /api/Game/Click/{userId}

Returns:

{
  "count": "integer",
  "multiplier": "integer"
}

Errors:

  • 400 - NO_PROGRESSION - User does not have a progression

Get Progression

GET /api/Game/Progression/{userId}

Returns: Progression

Errors:

  • 400 - NO_PROGRESSION - User does not have a progression

Initialize Progression

GET /api/Game/Initialize/{userId}

Returns: Progression

Errors:

  • 400 - PROGRESSION_EXISTS - User already has a progression
  • 400 - INITIALIZATION_FAILED - Failed to initialize progression

Reset Progression

POST /api/Game/Reset/{userId}

Body: {}

Returns: Progression

Errors:

  • 400 - NO_PROGRESSION - User does not have a progression
  • 400 - INSUFFICIENT_CLICKS - Not enough clicks to reset

Note: Resets count to 0, increments multiplier by 1, updates best score if current is higher

Cost Formula: 100 * (1.5^(multiplier-1))


Get Reset Cost

GET /api/Game/ResetCost/{userId}

Returns:

{
  "cost": "integer",
}

Errors:

  • 400 - NO_PROGRESSION - User does not have a progression

Get Best Score

GET /api/Game/BestScore

Returns:

{
  "userId": "integer",
  "bestScore": "integer"
}

Errors:

  • 404 - NO_PROGRESSIONS - No progressions found

Error Codes Reference

CodeStatusDescription
USER_NOT_FOUND404User not found
INVALID_PASSWORD401Invalid password
USERNAME_EXISTS400Username already taken
REGISTRATION_FAILED400Registration failed
NO_PROGRESSION400User has no progression
PROGRESSION_EXISTS400Progression already exists
INITIALIZATION_FAILED400Failed to initialize
INSUFFICIENT_CLICKS400Not enough clicks to reset
NO_PROGRESSIONS404No progressions found

Data Models

User

{
  "id": "integer",
  "username": "string",
  "password": "string",
  "role": "integer"  // 0 = Admin, 1 = User
}

UserPass

{
  "username": "string",
  "password": "string"
}

UserPublic

{
  "id": "integer",
  "username": "string",
  "role": "integer"  // 0 = Admin, 1 = User
}

UserUpdate

{
  "username": "string",
  "password": "string",
  "role": "integer"
}

Progression

{
  "id": "integer",
  "userId": "integer",
  "count": "integer",
  "multiplier": "integer",
  "bestScore": "integer"
}

ErrorResponse

{
  "message": "string",
  "code": "string"
}