the-tip-top-backend/API-DOCUMENTATION.md
2025-11-17 23:47:54 +01:00

19 KiB

📚 Documentation complète des API - The Tip Top

Base URL: http://localhost:4000

Version: 1.0.0


🔓 1. ROUTES PUBLIQUES (3 endpoints)

1.1 Health Check

GET /

Description: Vérifier que l'API est en ligne

Réponse:

{
  "message": "✅ API The Tip Top en ligne et opérationnelle -branche dev-  !"
}

1.2 Database Check

GET /db-check

Description: Vérifier la connexion à la base de données

Réponse:

{
  "message": "✅ DB connectée branche dev",
  "time": "2025-11-08T14:55:40.560Z"
}

1.3 Métriques Prometheus

GET /metrics

Description: Récupérer les métriques de performance (format Prometheus)

Réponse: Format texte Prometheus


🔐 2. AUTHENTIFICATION (5 endpoints)

2.1 Inscription

POST /api/auth/register
Content-Type: application/json

Body:

{
  "email": "user@example.com",
  "password": "Password123",
  "confirmPassword": "Password123",
  "firstName": "John",
  "lastName": "Doe",
  "phone": "0612345678",          // optionnel
  "address": "1 rue de Paris",    // optionnel
  "city": "Paris",                // optionnel
  "postalCode": "75001"           // optionnel
}

Validation:

  • Email: format email valide
  • Password: min 8 caractères, 1 majuscule, 1 minuscule, 1 chiffre
  • confirmPassword: doit correspondre au password
  • firstName/lastName: min 2 caractères, max 100
  • phone: format français (optionnel)
  • postalCode: 5 chiffres (optionnel)

Réponse:

{
  "success": true,
  "message": "Inscription réussie. Veuillez vérifier votre email pour activer votre compte.",
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "role": "CLIENT"
  }
}

2.2 Connexion

POST /api/auth/login
Content-Type: application/json

Body:

{
  "email": "user@example.com",
  "password": "Password123"
}

Réponse:

{
  "success": true,
  "message": "Connexion réussie",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "role": "CLIENT",
    "isVerified": false
  }
}

Note: Le token JWT expire après 7 jours


2.3 Vérification Email

GET /api/auth/verify-email/:token

Paramètres URL:

  • token: Token de vérification reçu par email

Exemple:

GET /api/auth/verify-email/a1b2c3d4e5f6...

Réponse:

{
  "success": true,
  "message": "Email vérifié avec succès! Vous pouvez maintenant vous connecter."
}

2.4 Mot de passe oublié

POST /api/auth/forgot-password
Content-Type: application/json

Body:

{
  "email": "user@example.com"
}

Réponse:

{
  "success": true,
  "message": "Si cet email existe, un lien de réinitialisation a été envoyé."
}

2.5 Réinitialiser mot de passe

POST /api/auth/reset-password
Content-Type: application/json

Body:

{
  "token": "reset-token-from-email",
  "password": "NewPassword123",
  "confirmPassword": "NewPassword123"
}

Réponse:

{
  "success": true,
  "message": "Mot de passe réinitialisé avec succès. Vous pouvez maintenant vous connecter."
}

2.6 Déconnexion (Bonus)

POST /api/auth/logout
Authorization: Bearer {token}

Réponse:

{
  "success": true,
  "message": "Déconnexion réussie"
}

2.7 Profil utilisateur connecté (Bonus)

GET /api/auth/me
Authorization: Bearer {token}

Réponse:

{
  "success": true,
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "phone": "0612345678",
    "address": "1 rue de Paris",
    "city": "Paris",
    "postalCode": "75001",
    "role": "CLIENT",
    "isVerified": true,
    "createdAt": "2025-11-08T14:08:57.237Z"
  }
}

👤 3. UTILISATEUR (4 endpoints) - 🔒 Auth requise

Toutes les routes nécessitent: Authorization: Bearer {token}

3.1 Récupérer son profil

GET /api/users/profile
Authorization: Bearer {token}

Réponse:

{
  "success": true,
  "data": {
    "id": "uuid",
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "phone": "0612345678",
    "address": "1 rue de Paris",
    "city": "Paris",
    "postalCode": "75001",
    "role": "CLIENT",
    "isVerified": true,
    "createdAt": "2025-11-08T14:08:57.237Z"
  }
}

3.2 Modifier son profil

PUT /api/users/profile
Authorization: Bearer {token}
Content-Type: application/json

Body: (tous les champs sont optionnels)

{
  "firstName": "John",
  "lastName": "Doe",
  "phone": "0612345678",
  "address": "2 rue de Lyon",
  "city": "Lyon",
  "postalCode": "69001"
}

Réponse:

{
  "success": true,
  "message": "Profil mis à jour avec succès",
  "data": {
    "id": "uuid",
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "phone": "0612345678",
    "address": "2 rue de Lyon",
    "city": "Lyon",
    "postalCode": "69001",
    "role": "CLIENT"
  }
}

3.3 Changer son mot de passe

POST /api/users/change-password
Authorization: Bearer {token}
Content-Type: application/json

Body:

{
  "currentPassword": "OldPassword123",
  "newPassword": "NewPassword123",
  "confirmPassword": "NewPassword123"
}

Réponse:

{
  "success": true,
  "message": "Mot de passe modifié avec succès"
}

3.4 Supprimer son compte (Bonus)

DELETE /api/users/account
Authorization: Bearer {token}

Réponse:

{
  "success": true,
  "message": "Compte supprimé avec succès"
}

🎮 4. JEU (3 endpoints) - 🔒 Auth requise

Toutes les routes nécessitent: Authorization: Bearer {token}

4.1 Jouer et obtenir un ticket gagnant

POST /api/game/play
Authorization: Bearer {token}
Content-Type: application/json

Rôle requis: CLIENT uniquement

Body:

{
  "ticketCode": "ABC-DEFG-HIJK"
}

Réponse:

{
  "success": true,
  "message": "🎉 Félicitations! Vous avez gagné!",
  "data": {
    "ticket": {
      "id": "uuid",
      "code": "ABC-DEFG-HIJK",
      "status": "PENDING",
      "played_at": "2025-11-08T15:30:00.000Z"
    },
    "prize": {
      "id": "uuid",
      "type": "PHYSICAL",
      "name": "Infuseur à thé",
      "description": "Infuseur de qualité premium",
      "value": "39.00"
    }
  }
}

Erreurs possibles:

  • 400: "Ce code a déjà été utilisé"
  • 400: "Le jeu n'est pas actif pour le moment"
  • 500: "Aucun prix disponible"

4.2 Récupérer mes tickets

GET /api/game/my-tickets?page=1&limit=10&status=PENDING
Authorization: Bearer {token}

Query Parameters:

  • page: Numéro de page (défaut: 1)
  • limit: Tickets par page (défaut: 10)
  • status: Filtrer par statut (optionnel)
    • PENDING: En attente de validation
    • VALIDATED: Validé
    • REJECTED: Rejeté
    • CLAIMED: Récupéré

Réponse:

{
  "success": true,
  "data": {
    "tickets": [
      {
        "id": "uuid",
        "code": "ABC-DEFG-HIJK",
        "status": "PENDING",
        "playedAt": "2025-11-08T15:30:00.000Z",
        "claimedAt": null,
        "validatedAt": null,
        "rejectionReason": null,
        "prize": {
          "id": "uuid",
          "type": "PHYSICAL",
          "name": "Infuseur à thé",
          "description": "Infuseur de qualité premium",
          "value": "39.00"
        }
      }
    ],
    "pagination": {
      "total": 5,
      "page": 1,
      "limit": 10,
      "totalPages": 1
    }
  }
}

4.3 Détails d'un ticket par ID (Bonus)

GET /api/game/my-tickets/:id
Authorization: Bearer {token}

Exemple:

GET /api/game/my-tickets/550e8400-e29b-41d4-a716-446655440000

Réponse:

{
  "success": true,
  "data": {
    "id": "uuid",
    "code": "ABC-DEFG-HIJK",
    "status": "PENDING",
    "playedAt": "2025-11-08T15:30:00.000Z",
    "claimedAt": null,
    "validatedAt": null,
    "rejectionReason": null,
    "prize": {
      "id": "uuid",
      "type": "PHYSICAL",
      "name": "Infuseur à thé",
      "description": "Infuseur de qualité premium",
      "value": "39.00"
    }
  }
}

4.4 Détails d'un ticket par code

GET /api/game/ticket/:code
Authorization: Bearer {token}

Exemple:

GET /api/game/ticket/ABC-DEFG-HIJK

Réponse: Identique à 4.3


👔 5. EMPLOYÉ (4 endpoints) - 🔒 Rôle EMPLOYEE ou ADMIN requis

Toutes les routes nécessitent:

  • Authorization: Bearer {token}
  • Rôle: EMPLOYEE ou ADMIN

5.1 Liste des tickets en attente

GET /api/employee/pending-tickets?page=1&limit=10
Authorization: Bearer {token}

Query Parameters:

  • page: Numéro de page (défaut: 1)
  • limit: Tickets par page (défaut: 10)

Réponse:

{
  "success": true,
  "data": {
    "tickets": [
      {
        "id": "uuid",
        "code": "ABC-DEFG-HIJK",
        "status": "PENDING",
        "playedAt": "2025-11-08T15:30:00.000Z",
        "user": {
          "id": "uuid",
          "email": "user@example.com",
          "firstName": "John",
          "lastName": "Doe"
        },
        "prize": {
          "id": "uuid",
          "name": "Infuseur à thé",
          "type": "PHYSICAL",
          "value": "39.00"
        }
      }
    ],
    "pagination": {
      "total": 25,
      "page": 1,
      "limit": 10,
      "totalPages": 3
    }
  }
}

5.2 Valider ou rejeter un ticket

POST /api/employee/validate-ticket
Authorization: Bearer {token}
Content-Type: application/json

Body:

{
  "ticketId": "uuid",
  "action": "validate",        // ou "reject"
  "rejectionReason": "Ticket non conforme"  // requis si action = "reject"
}

Réponse:

{
  "success": true,
  "message": "Ticket validé avec succès",
  "data": {
    "id": "uuid",
    "code": "ABC-DEFG-HIJK",
    "status": "VALIDATED",
    "validatedAt": "2025-11-08T16:00:00.000Z"
  }
}

5.3 Rechercher un ticket (Bonus)

GET /api/employee/search-ticket?code=ABC-DEFG-HIJK
Authorization: Bearer {token}

Query Parameters:

  • code: Code du ticket à rechercher

Réponse:

{
  "success": true,
  "data": {
    "id": "uuid",
    "code": "ABC-DEFG-HIJK",
    "status": "PENDING",
    "playedAt": "2025-11-08T15:30:00.000Z",
    "user": {
      "email": "user@example.com",
      "firstName": "John",
      "lastName": "Doe"
    },
    "prize": {
      "name": "Infuseur à thé",
      "type": "PHYSICAL"
    }
  }
}

5.4 Statistiques employé (Bonus)

GET /api/employee/stats
Authorization: Bearer {token}

Réponse:

{
  "success": true,
  "data": {
    "validatedToday": 15,
    "rejectedToday": 3,
    "pendingTotal": 42
  }
}

👑 6. ADMIN (11 endpoints) - 🔒 Rôle ADMIN requis

Toutes les routes nécessitent:

  • Authorization: Bearer {token}
  • Rôle: ADMIN

6.1 Statistiques globales

GET /api/admin/statistics
Authorization: Bearer {token}

Réponse:

{
  "success": true,
  "data": {
    "users": {
      "total": 1500,
      "clients": 1450,
      "employees": 45,
      "admins": 5,
      "verifiedEmails": 1200
    },
    "tickets": {
      "total": 5000,
      "pending": 150,
      "validated": 4500,
      "rejected": 200,
      "claimed": 3800
    },
    "prizes": {
      "total": 10,
      "active": 8,
      "totalStock": 2500,
      "distributed": 4500
    }
  }
}

6.2 Liste de tous les prix

GET /api/admin/prizes
Authorization: Bearer {token}

Réponse:

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "type": "PHYSICAL",
      "name": "Infuseur à thé",
      "description": "Infuseur de qualité premium",
      "value": "39.00",
      "probability": 0.60,
      "stock": 500,
      "initialStock": 1000,
      "isActive": true,
      "createdAt": "2025-01-01T00:00:00.000Z"
    }
  ]
}

6.3 Créer un nouveau prix

POST /api/admin/prizes
Authorization: Bearer {token}
Content-Type: application/json

Body:

{
  "type": "PHYSICAL",           // ou "DISCOUNT"
  "name": "Coffret découverte",
  "description": "Assortiment de thés premium",
  "value": "69.00",
  "probability": 0.15,
  "stock": 200
}

Réponse:

{
  "success": true,
  "message": "Prix créé avec succès",
  "data": {
    "id": "uuid",
    "type": "PHYSICAL",
    "name": "Coffret découverte",
    "description": "Assortiment de thés premium",
    "value": "69.00",
    "probability": 0.15,
    "stock": 200,
    "initialStock": 200,
    "isActive": true
  }
}

6.4 Modifier un prix

PUT /api/admin/prizes/:id
Authorization: Bearer {token}
Content-Type: application/json

Body: (tous les champs sont optionnels)

{
  "name": "Nouveau nom",
  "description": "Nouvelle description",
  "value": "79.00",
  "probability": 0.20,
  "stock": 250,
  "isActive": false
}

Réponse:

{
  "success": true,
  "message": "Prix mis à jour avec succès",
  "data": {
    "id": "uuid",
    "name": "Nouveau nom",
    "description": "Nouvelle description",
    "value": "79.00",
    "probability": 0.20,
    "stock": 250,
    "isActive": false
  }
}

6.5 Supprimer (désactiver) un prix

DELETE /api/admin/prizes/:id
Authorization: Bearer {token}

Réponse:

{
  "success": true,
  "message": "Prix désactivé avec succès"
}

Note: Le prix n'est pas supprimé physiquement, il est marqué comme isActive: false


6.6 Liste paginée des utilisateurs

GET /api/admin/users?page=1&limit=20&role=CLIENT
Authorization: Bearer {token}

Query Parameters:

  • page: Numéro de page (défaut: 1)
  • limit: Utilisateurs par page (défaut: 20)
  • role: Filtrer par rôle (optionnel): CLIENT, EMPLOYEE, ADMIN

Réponse:

{
  "success": true,
  "data": {
    "users": [
      {
        "id": "uuid",
        "email": "user@example.com",
        "firstName": "John",
        "lastName": "Doe",
        "role": "CLIENT",
        "isVerified": true,
        "createdAt": "2025-11-08T14:08:57.237Z"
      }
    ],
    "pagination": {
      "total": 1500,
      "page": 1,
      "limit": 20,
      "totalPages": 75
    }
  }
}

6.7 Créer un nouvel employé

POST /api/admin/employees
Authorization: Bearer {token}
Content-Type: application/json

Body:

{
  "email": "employee@thetiptop.com",
  "password": "TempPassword123",
  "firstName": "Marie",
  "lastName": "Dupont"
}

Réponse:

{
  "success": true,
  "message": "Employé créé avec succès",
  "data": {
    "id": "uuid",
    "email": "employee@thetiptop.com",
    "firstName": "Marie",
    "lastName": "Dupont",
    "role": "EMPLOYEE"
  }
}

6.8 Modifier un utilisateur

PUT /api/admin/users/:id
Authorization: Bearer {token}
Content-Type: application/json

Body: (tous les champs sont optionnels)

{
  "role": "EMPLOYEE",           // CLIENT, EMPLOYEE, ADMIN
  "isVerified": true,
  "firstName": "Jean",
  "lastName": "Martin"
}

Réponse:

{
  "success": true,
  "message": "Utilisateur mis à jour avec succès",
  "data": {
    "id": "uuid",
    "email": "user@example.com",
    "firstName": "Jean",
    "lastName": "Martin",
    "role": "EMPLOYEE",
    "isVerified": true
  }
}

6.9 Supprimer un utilisateur

DELETE /api/admin/users/:id
Authorization: Bearer {token}

Réponse:

{
  "success": true,
  "message": "Utilisateur supprimé avec succès"
}

Note: Suppression physique de l'utilisateur et de tous ses tickets (cascade)


6.10 Liste paginée de tous les tickets

GET /api/admin/tickets?page=1&limit=20&status=PENDING&userId=uuid
Authorization: Bearer {token}

Query Parameters:

  • page: Numéro de page (défaut: 1)
  • limit: Tickets par page (défaut: 20)
  • status: Filtrer par statut (optionnel)
  • userId: Filtrer par utilisateur (optionnel)

Réponse:

{
  "success": true,
  "data": {
    "tickets": [
      {
        "id": "uuid",
        "code": "ABC-DEFG-HIJK",
        "status": "PENDING",
        "playedAt": "2025-11-08T15:30:00.000Z",
        "validatedAt": null,
        "claimedAt": null,
        "user": {
          "id": "uuid",
          "email": "user@example.com",
          "firstName": "John",
          "lastName": "Doe"
        },
        "prize": {
          "id": "uuid",
          "name": "Infuseur à thé",
          "type": "PHYSICAL",
          "value": "39.00"
        }
      }
    ],
    "pagination": {
      "total": 5000,
      "page": 1,
      "limit": 20,
      "totalPages": 250
    }
  }
}

📋 RÉCAPITULATIF

Par catégorie

Catégorie Nombre d'endpoints Auth requise Rôle requis
Publiques 3 Non -
Authentification 7 ⚠️ Partiel -
Utilisateur 4 Oui Tous
Jeu 4 Oui CLIENT (play)
Employé 4 Oui EMPLOYEE, ADMIN
Admin 11 Oui ADMIN
TOTAL 33

🔑 Authentification

Headers requis pour routes protégées

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

Format des erreurs

{
  "success": false,
  "error": "Message d'erreur descriptif"
}

Codes d'erreur HTTP

  • 200: Succès
  • 201: Créé avec succès
  • 400: Erreur de validation / Bad Request
  • 401: Non authentifié / Token invalide
  • 403: Accès refusé / Permissions insuffisantes
  • 404: Ressource non trouvée
  • 500: Erreur serveur

👥 Comptes de test

CLIENT

Email: test-client@test.com
Password: Test1234
Rôle: CLIENT

EMPLOYEE

Email: employee@test.com
Password: Employee1234
Rôle: EMPLOYEE

ADMIN

Email: admin@test.com
Password: Admin1234
Rôle: ADMIN

🚀 Exemples Postman

Collection de base

  1. Créer une nouvelle collection "The Tip Top API"

  2. Variables d'environnement:

    • base_url: http://localhost:4000
    • token: (sera défini automatiquement après login)
  3. Script de test automatique (dans l'onglet Tests de la requête Login):

    if (pm.response.code === 200) {
        var jsonData = pm.response.json();
        pm.environment.set("token", jsonData.token);
    }
    
  4. Authorization globale:

    • Type: Bearer Token
    • Token: {{token}}

Documentation générée le: 2025-11-08

Serveur: http://localhost:4000

Contact: support@thetiptop.com