openapi: 3.0.3
info:
  title: Cercle Projet 2025 - API
  description: |
    Spécification OpenAPI générée automatiquement à partir des fichiers de routes du projet.
    Ce document couvre les endpoints en lecture (GET) existants pour Questions, Leçons, Chapitres, Langages,
    Articles, et les endpoints d'authentification/profil. Il inclut des schémas de réponses génériques.
  version: '1.0.0'
servers:
  - url: https://api.codequest.quentin-montreuil.fr/
    description: Serveur de production
  - url: http://localhost:3000
    description: Serveur local
tags:
  - name: Auth
    description: Endpoints d'authentification
  - name: Profil
    description: Données liées au profil connecté
  - name: Questions
    description: Gestion des questions et réponses (GET-only pour l'instant)
  - name: Lecons
    description: Leçons et relations (chapitre, badges, questions, progression)
  - name: Chapitres
    description: Chapitres, leurs leçons, badges et langages
  - name: Langages
    description: Langages disponibles
  - name: Articles
    description: Articles publics
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
    Pagination:
      type: object
      properties:
        page:
          type: integer
          example: 1
        limit:
          type: integer
          example: 20
        total:
          type: integer
          example: 123
    Utilisateur:
      type: object
      properties:
        id:
          type: integer
          example: 42
        pseudo:
          type: string
          example: "mathy"
        email:
          type: string
          format: email
          example: "user@example.com"
    AuthCredentials:
      type: object
      properties:
        email:
          type: string
          format: email
        password:
          type: string
    AuthResponse:
      type: object
      properties:
        token:
          type: string
          example: "eyJhbGciOi..."
        user:
          $ref: '#/components/schemas/Utilisateur'
    Question:
      type: object
      properties:
        id:
          type: integer
          example: 1
        texte:
          type: string
          example: "Quel est le type primitif de... ?"
        leconId:
          type: integer
    Reponse:
      type: object
      properties:
        id:
          type: integer
        texte:
          type: string
        correct:
          type: boolean
    Lecon:
      type: object
      properties:
        id:
          type: integer
        titre:
          type: string
        description:
          type: string
        chapitreId:
          type: integer
    Chapitre:
      type: object
      properties:
        id:
          type: integer
        titre:
          type: string
        description:
          type: string
    Badge:
      type: object
      properties:
        id:
          type: integer
        nom:
          type: string
    Langage:
      type: object
      properties:
        id:
          type: integer
        nom:
          type: string
    Article:
      type: object
      properties:
        id:
          type: integer
        titre:
          type: string
        contenu:
          type: string

paths:
  /api/auth/register:
    post:
      tags: [Auth]
      summary: Enregistrer un nouvel utilisateur
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AuthCredentials'
      responses:
        '201':
          description: Utilisateur créé
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Utilisateur'
        '400':
          description: Requête invalide
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/auth/login:
    post:
      tags: [Auth]
      summary: Connexion (retourne token)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AuthCredentials'
      responses:
        '200':
          description: Authentification réussie
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '401':
          description: Identifiants invalides

  /api/auth/me:
    get:
      tags: [Auth]
      summary: Récupérer l'utilisateur courant (JWT requis)
      security:
        - bearerAuth: []
      responses:
        '200':
          description: Utilisateur connecté
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Utilisateur'
        '401':
          description: Non authentifié

  /api/profil:
    get:
      tags: [Profil]
      summary: Récupérer l'ensemble des données du profil connecté
      security:
        - bearerAuth: []
      responses:
        '200':
          description: Données du profil
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    $ref: '#/components/schemas/Utilisateur'
                  stats:
                    type: object
        '401':
          description: Non authentifié

  /api/questions:
    get:
      tags: [Questions]
      summary: Lister les questions (optionnellement avec leurs réponses)
      parameters:
        - in: query
          name: withAnswers
          schema:
            type: boolean
          description: Inclure les réponses associées
        - in: query
          name: page
          schema:
            type: integer
        - in: query
          name: limit
          schema:
            type: integer
      responses:
        '200':
          description: Liste de questions
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Question'
                  meta:
                    $ref: '#/components/schemas/Pagination'

  /api/questions/{id}:
    get:
      tags: [Questions]
      summary: Récupérer une question par id
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
        - in: query
          name: withAnswers
          schema:
            type: boolean
      responses:
        '200':
          description: Question trouvée
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Question'
        '404':
          description: Non trouvée

  /api/questions/{id}/answers:
    get:
      tags: [Questions]
      summary: Récupérer les réponses d'une question
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Liste des réponses
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Reponse'

  /api/lecons:
    get:
      tags: [Lecons]
      summary: Lister les leçons
      parameters:
        - in: query
          name: page
          schema:
            type: integer
        - in: query
          name: limit
          schema:
            type: integer
      responses:
        '200':
          description: Liste de leçons
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Lecon'
                  meta:
                    $ref: '#/components/schemas/Pagination'

  /api/lecons/{leconId}:
    get:
      tags: [Lecons]
      summary: Détails d'une leçon
      parameters:
        - in: path
          name: leconId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Leçon trouvée
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Lecon'
        '404':
          description: Non trouvée

  /api/lecons/{leconId}/chapitre:
    get:
      tags: [Lecons]
      summary: Récupérer le chapitre parent d'une leçon
      parameters:
        - in: path
          name: leconId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Chapitre
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Chapitre'

  /api/lecons/{leconId}/badges:
    get:
      tags: [Lecons]
      summary: Badges associés à la leçon (via chapitre)
      parameters:
        - in: path
          name: leconId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Liste de badges
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Badge'

  /api/lecons/{leconId}/questions:
    get:
      tags: [Lecons]
      summary: Lister les questions d'une leçon
      parameters:
        - in: path
          name: leconId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Liste des questions
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Question'

  /api/lecons/{leconId}/questions/{questionId}:
    get:
      tags: [Lecons]
      summary: Récupérer une question précise d'une leçon
      parameters:
        - in: path
          name: leconId
          required: true
          schema:
            type: integer
        - in: path
          name: questionId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Question
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Question'
        '404':
          description: Non trouvée ou n'appartient pas à la leçon

  /api/lecons/{leconId}/progression/{utilisateurId}:
    get:
      tags: [Lecons]
      summary: Progression d'un utilisateur pour une leçon
      parameters:
        - in: path
          name: leconId
          required: true
          schema:
            type: integer
        - in: path
          name: utilisateurId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Progression de l'utilisateur
          content:
            application/json:
              schema:
                type: object
                properties:
                  completed:
                    type: boolean
                  progress:
                    type: number

  /api/chapitres:
    get:
      tags: [Chapitres]
      summary: Lister les chapitres
      responses:
        '200':
          description: Liste des chapitres
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Chapitre'

  /api/chapitres/{chapitreId}:
    get:
      tags: [Chapitres]
      summary: Détails d'un chapitre
      parameters:
        - in: path
          name: chapitreId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Chapitre
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Chapitre'

  /api/chapitres/{chapitreId}/lecons:
    get:
      tags: [Chapitres]
      summary: Leçons d'un chapitre
      parameters:
        - in: path
          name: chapitreId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Liste de leçons
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Lecon'

  /api/chapitres/{chapitreId}/badges:
    get:
      tags: [Chapitres]
      summary: Badges d'un chapitre
      parameters:
        - in: path
          name: chapitreId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Liste de badges
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Badge'

  /api/chapitres/{chapitreId}/langages:
    get:
      tags: [Chapitres]
      summary: Langages associés à un chapitre
      parameters:
        - in: path
          name: chapitreId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Liste de langages
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Langage'

  /api/chapitres/{chapitreId}/progression/{utilisateurId}:
    get:
      tags: [Chapitres]
      summary: Progression d'un utilisateur pour un chapitre
      parameters:
        - in: path
          name: chapitreId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Progression
          content:
            application/json:
              schema:
                type: object
                properties:
                  completedCount:
                    type: integer
                  totalCount:
                    type: integer

  /api/chapitres/{chapitreId}/progression:
    post:
      tags: [Chapitres]
      summary: Créer ou récupérer la progression du chapitre pour l'utilisateur authentifié
      security:
        - bearerAuth: []
      parameters:
        - in: path
          name: chapitreId
          required: true
          schema:
            type: integer
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                statut:
                  type: string
                  example: commence
                score:
                  type: number
                  example: 0
                tentatives:
                  type: integer
                  example: 1
      responses:
        '201':
          description: Progression créée
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                  meta:
                    type: object
                    properties:
                      created:
                        type: boolean
                  error:
                    type: string
        '200':
          description: Progression déjà existante
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                  meta:
                    type: object
                    properties:
                      created:
                        type: boolean
                  error:
                    type: string
        '400':
          description: Requête invalide
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Non authentifié
        '404':
          description: Chapitre ou utilisateur introuvable

  /api/langages:
    get:
      tags: [Langages]
      summary: Lister les langages
      responses:
        '200':
          description: Liste des langages
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Langage'

  /api/langages/{langageId}:
    get:
      tags: [Langages]
      summary: Détails d'un langage
      parameters:
        - in: path
          name: langageId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Langage
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Langage'

  /api/langages/{langageId}/chapitres:
    get:
      tags: [Langages]
      summary: Lister les chapitres d'un langage
      parameters:
        - in: path
          name: langageId
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Liste de chapitres
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Chapitre'
                  meta:
                    $ref: '#/components/schemas/Pagination'

  /api/articles:
    get:
      tags: [Articles]
      summary: Lister les articles
      responses:
        '200':
          description: Liste d'articles
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Article'

  /api/articles/{id}:
    get:
      tags: [Articles]
      summary: Récupérer un article
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Article
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Article'
        '404':
          description: Non trouvé

  /api/exemple:
    get:
      tags: [Chapitres]
      summary: Endpoint d'exemple (fichier de routes présent mais vide)
      responses:
        '204':
          description: Aucun contenu (route vide dans le projet)

  # NOTE: le mapping des préfixes (/api/...) dépend de la façon dont vous montez les routers dans index.js

components_examples: {}

# Fin du fichier OpenAPI
