{
 "openapi": "3.0.3",
 "info": {
  "title": "API Jury Rouge",
  "version": "1.0.0",
  "description": "Analyse et correction de travaux écrits. Traitement en mémoire, aucun document conservé. Décision de note : correcteur humain."
 },
 "servers": [
  {
   "url": "https://juryrouge.fr/api"
  }
 ],
 "components": {
  "securitySchemes": {
   "codeAcces": {
    "type": "apiKey",
    "in": "header",
    "name": "X-Jury-Key"
   }
  }
 },
 "paths": {
  "/health": {
   "get": {
    "summary": "État du service",
    "responses": {
     "200": {
      "description": "OK"
     }
    }
   }
  },
  "/modes": {
   "get": {
    "summary": "Modes de correction",
    "responses": {
     "200": {
      "description": "neutre, dur, bienveillant"
     }
    }
   }
  },
  "/grilles": {
   "get": {
    "summary": "Grilles de la bibliothèque",
    "responses": {
     "200": {
      "description": "Liste des grilles"
     }
    }
   }
  },
  "/solde": {
   "get": {
    "summary": "Solde d'un code à crédits",
    "security": [
     {
      "codeAcces": []
     }
    ],
    "responses": {
     "200": {
      "description": "Crédits restants, expiration, taille maximale"
     },
     "401": {
      "description": "Code invalide"
     }
    }
   }
  },
  "/grille-import": {
   "post": {
    "summary": "Importer une grille (Word, CSV, JSON, texte) ou proposer une grille à valider à partir d'un référentiel",
    "security": [
     {
      "codeAcces": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "filename"
        ],
        "properties": {
         "filename": {
          "type": "string",
          "description": "Nom du fichier, extension .docx, .pdf ou .txt"
         },
         "data_b64": {
          "type": "string",
          "description": "Contenu du fichier encodé en base64"
         },
         "texte": {
          "type": "string",
          "description": "Alternative : grille collée en texte"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Objet grille"
     },
     "422": {
      "description": "Aucun critère chiffré reconnu"
     },
     "401": {
      "description": "Code d'accès absent ou invalide"
     },
     "402": {
      "description": "Crédits épuisés, code expiré ou document trop long (codes à crédits)"
     },
     "415": {
      "description": "Format non accepté"
     },
     "429": {
      "description": "Trop de requêtes (40 par minute et par IP)"
     }
    }
   }
  },
  "/analyse": {
   "post": {
    "summary": "Analyse complète (similarité, IA, références, correction sur grille)",
    "security": [
     {
      "codeAcces": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "filename",
         "data_b64"
        ],
        "properties": {
         "filename": {
          "type": "string",
          "description": "Nom du fichier, extension .docx, .pdf ou .txt"
         },
         "data_b64": {
          "type": "string",
          "description": "Contenu du fichier encodé en base64"
         },
         "grille_id": {
          "type": "string"
         },
         "grille": {
          "type": "object"
         },
         "mode": {
          "type": "string",
          "enum": [
           "neutre",
           "dur",
           "bienveillant"
          ]
         },
         "externe": {
          "type": "boolean",
          "default": false,
          "description": "Recherche sur bases externes (Wikipédia FR, HAL, Crossref, OpenAlex, Google Livres). Désactivée par défaut."
         },
         "lot": {
          "type": "string"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Rapport d'analyse"
     },
     "400": {
      "description": "Analyse impossible (texte insuffisant)"
     },
     "401": {
      "description": "Code d'accès absent ou invalide"
     },
     "402": {
      "description": "Crédits épuisés, code expiré ou document trop long (codes à crédits)"
     },
     "415": {
      "description": "Format non accepté"
     },
     "429": {
      "description": "Trop de requêtes (40 par minute et par IP)"
     }
    }
   }
  },
  "/plagiat": {
   "post": {
    "summary": "Similarité et indice IA seuls",
    "security": [
     {
      "codeAcces": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "filename",
         "data_b64"
        ],
        "properties": {
         "filename": {
          "type": "string",
          "description": "Nom du fichier, extension .docx, .pdf ou .txt"
         },
         "data_b64": {
          "type": "string",
          "description": "Contenu du fichier encodé en base64"
         },
         "externe": {
          "type": "boolean",
          "default": false
         },
         "refs": {
          "type": "boolean",
          "default": false
         },
         "lot": {
          "type": "string"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Rapport de similarité"
     },
     "400": {
      "description": "Analyse impossible"
     },
     "401": {
      "description": "Code d'accès absent ou invalide"
     },
     "402": {
      "description": "Crédits épuisés, code expiré ou document trop long (codes à crédits)"
     },
     "415": {
      "description": "Format non accepté"
     },
     "429": {
      "description": "Trop de requêtes (40 par minute et par IP)"
     }
    }
   }
  }
 }
}