Paillasse/portail/public/openapi/v1.yaml
Adam Belkacemi ecf3dfb21d ajoute l'API publique /api/v1 (bloc B, premier chantier)
Catalogue en lecture seule (labs, banque de quiz officielle, cours) -
choix d'Adam pour la première version, zéro donnée d'élève. Laravel
Sanctum, un jeton Bearer par développeur créé depuis /jetons-api (un
prof), portée catalogue:lire seulement. Quota par jeton (pas par
compte ni par IP) dans Redis via un limiteur nommé, 60 requêtes/minute.
Documentation : spécification OpenAPI 3.0 et page publique /api/docs.

Désactive /sanctum/csrf-cookie (config/sanctum.php) : l'API est en
jeton Bearer seulement, jamais en cookie de SPA.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-14 01:23:23 +02:00

175 lines
4.8 KiB
YAML

openapi: 3.0.3
info:
title: Syllabus — API publique
version: "1.0"
description: >
Catalogue en lecture seule (labs, banque de quiz officielle, cours).
Aucune donnée d'élève. Jeton créé depuis /jetons-api (compte prof).
contact:
email: adam@belkacemi.me
servers:
- url: https://syllabuslab.fr/api/v1
security:
- bearerAuth: []
paths:
/labs:
get:
summary: Liste des labs du catalogue
operationId: listerLabs
tags: [Labs]
responses:
"200":
description: Liste des labs
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Lab"
/labs/{identifiant}:
get:
summary: Détail d'un lab
operationId: lireLab
tags: [Labs]
parameters:
- $ref: "#/components/parameters/IdentifiantLab"
responses:
"200":
description: Le lab
content:
application/json:
schema:
type: object
properties:
data:
$ref: "#/components/schemas/Lab"
"404":
description: Lab introuvable
/quiz:
get:
summary: Liste des quiz de la banque officielle
operationId: listerQuiz
tags: [Quiz]
responses:
"200":
description: Liste des quiz (métadonnées seulement, jamais les questions)
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Quiz"
/quiz/{id}:
get:
summary: Détail d'un quiz (métadonnées)
operationId: lireQuiz
tags: [Quiz]
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"200":
description: Le quiz
content:
application/json:
schema:
type: object
properties:
data:
$ref: "#/components/schemas/Quiz"
"404":
description: Quiz introuvable ou non partagé
/cours:
get:
summary: Liste des cours du catalogue
operationId: listerCours
tags: [Cours]
responses:
"200":
description: Liste des cours (sans le contenu complet)
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/CoursResume"
/cours/{identifiant}:
get:
summary: Détail d'un cours, avec son contenu
operationId: lireCours
tags: [Cours]
parameters:
- name: identifiant
in: path
required: true
schema:
type: string
example: 08-deux-lan-routeur
responses:
"200":
description: Le cours
content:
application/json:
schema:
type: object
properties:
data:
$ref: "#/components/schemas/Cours"
"404":
description: Cours introuvable
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: Jeton créé depuis /jetons-api. 60 requêtes par minute et par jeton.
parameters:
IdentifiantLab:
name: identifiant
in: path
required: true
schema:
type: string
example: 08-deux-lan-routeur
schemas:
Lab:
type: object
properties:
identifiant: { type: string, example: 08-deux-lan-routeur }
titre: { type: string, example: Deux LAN et un routeur }
niveau: { type: string, nullable: true, example: decouverte }
duree_min: { type: integer, nullable: true, example: 45 }
competences:
type: array
items: { type: string }
example: [adressage-ipv4, routage-statique]
Quiz:
type: object
properties:
id: { type: integer, example: 7 }
titre: { type: string, example: Un serveur web et son client }
theme: { type: string, nullable: true, example: SRV }
questions_count: { type: integer, example: 6 }
CoursResume:
type: object
properties:
identifiant: { type: string, example: 08-deux-lan-routeur }
titre: { type: string, example: Deux LAN et un routeur }
Cours:
allOf:
- $ref: "#/components/schemas/CoursResume"
- type: object
properties:
contenu_markdown: { type: string }