Référence de l'API
Chaque route servie par l'API Learnio, qui peut l'appeler, et comment fonctionnent la connexion, les permissions, les erreurs et la pagination.
Pour le pack Full Stack
URL de base et format des réponses
Chaque route est servie sous le préfixe /api. En local, l'URL de base est http://localhost:8000/api. Sur un serveur, c'est l'adresse de votre API suivie de /api, la même valeur que les deux frontends lisent dans NEXT_PUBLIC_API_BASE_URL (Variables d'environnement).
L'API sert deux publics qui ne partagent jamais de jeton. Les étudiants utilisent les routes sous /api/users/<area> et /api/shop, listées dans les sections étudiantes ci-dessous. Le tableau de bord admin utilise toutes les autres routes, y compris /api/users lui-même et /api/users/<username>, qui gèrent les comptes étudiants.
Les corps de requête sont en JSON, sauf pour l'envoi de fichiers. Chaque réponse arrive dans la même enveloppe :
{
"success": true,
"data": { },
"message": ""
}data contient le résultat. message est une courte phrase que certaines écritures renseignent, traduite dans la langue de la requête, et vide sinon. Le health check n'exige pas de jeton et montre l'enveloppe :
curl http://localhost:8000/api/health{"success":true,"data":{"status":"ok"},"message":""}Il répond 503 tant que la base de données est injoignable ou ne contient aucune table : un load balancer peut donc l'utiliser comme sonde de disponibilité.
Erreurs
Une requête qui échoue répond avec le statut HTTP correspondant et la même enveloppe, avec success: false, data: null et, pour la validation, les problèmes par champ, indexés par le nom du champ (un champ d'un objet imbriqué par son chemin pointé) :
curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"not-an-email","password":"x"}'{
"success": false,
"data": null,
"message": "Enter a valid email address (example@domain.com).",
"errors": {
"email": ["Enter a valid email address (example@domain.com)."]
}
}| Statut | Quand |
|---|---|
400 | Un champ n'a pas passé la validation, une valeur de requête est inutilisable, ou le corps contient un champ que la route n'accepte pas. Les champs inconnus sont refusés, pas ignorés. |
401 | Le jeton est absent, expiré ou appartient à l'autre public. Aussi une connexion qui échoue, que l'e-mail n'ait pas de compte ou que le mot de passe soit faux. |
403 | Les rôles de l'administrateur n'accordent pas la permission de la route, ou un compte formateur a accédé à autre chose que ses propres cours. |
404 | Aucun enregistrement de ce type. |
409 | L'écriture entre en conflit avec un enregistrement existant, comme un e-mail ou un slug déjà utilisé. |
429 | Trop de tentatives depuis une même adresse sur une route de connexion, d'inscription ou de mot de passe. L'en-tête Retry-After indique combien de secondes attendre. |
500 | Un échec inattendu. Le message reste générique et les détails vont dans le journal de l'API. |
Les écritures réussies répondent 201 pour POST et 200 pour les autres méthodes.
Pagination et tri
Les listes ont deux formes, une par public. Les routes étudiantes répondent dans la forme que lit le site étudiant ; les routes admin répondent dans la forme que lit le tableau de bord.
| Listes étudiantes et publiques | Listes admin | |
|---|---|---|
| Page | page, à partir de 1 | page, à partir de 1 |
| Taille de page | page_count (cours, blog, inscriptions, avis) ou per_page (formateurs). Par défaut, les cours suivent le paramètre courses_per_page, les inscriptions 100. | page_count, 15 par défaut (10 pour les administrateurs). Les commandes utilisent limit. |
| Tri | Cours uniquement : sort_by et sort_dir (asc ou desc) | sort et order (asc ou desc). Les commandes utilisent sort_by et sort_order. |
| Ordre par défaut | Cours par date de mise à jour décroissante, blog par date de publication décroissante | Par date de mise à jour décroissante, avec id pour départager. Les catégories et les formateurs conservent leur ordre défini manuellement. |
| Réponse | data, current_page, last_page, per_page, total, from, to, plus les liens de page | data, page, limit, total, totalPages |
Une page contient au plus 100 lignes : une taille plus grande est lue comme 100, et une taille absente ou illisible revient à la valeur par défaut de la liste. Il en va de même pour page, qui revient à 1.
sort n'accepte que les colonnes autorisées par chaque liste. Une clé inconnue se replie sur l'ordre par défaut au lieu d'échouer : un ancien favori se charge donc toujours.
La liste publique des cours se trie par id, price, discount_percentage, rating, duration, level, language, created_at ou updated_at, et se filtre par title, category_id, instructor_id et type (live ou recorded).
Langue
Envoyez la langue du lecteur dans l'en-tête Accept-Language. L'API parle les langues listées dans back-end/src/i18n/locales.ts, en et ar à la livraison. Elle lit la première étiquette, donc ar-SA est de l'arabe, et une requête qui ne nomme aucune langue prise en charge reçoit une réponse dans la langue du paramètre default_locale. Il n'y a pas de paramètre de requête pour la langue.
- Les messages d'erreur et le
messaged'une écriture réussie sont traduits. - Le texte enregistré dans les deux langues, comme les titres et descriptions des cours, est renvoyé sous la forme
{ "en": "...", "ar": "..." }et le client choisit l'une des deux. - Quelques routes étudiantes ne répondent que dans la langue demandée : la liste des inscriptions, le contenu d'un cours et la recherche.
- Le paiement prend la langue dans son corps (
locale, l'une des langues prises en charge), pour que le reçu corresponde à la page sur laquelle l'étudiant a acheté.
Authentification
Les étudiants et les administrateurs se connectent sur des endpoints différents, sur des tables différentes, et reçoivent des jetons que seules leurs propres routes acceptent.
| Public | Connexion | Jeton dans la réponse | Accepté sur |
|---|---|---|---|
| Étudiant | POST /api/users/auth/login | data.token, avec data.user | Routes étudiantes |
| Admin | POST /api/auth/login | data.access_token, avec data.admin (rôles et permissions) | Routes admin |
- Les deux sont des JWT signés avec
JWT_SECRET. Envoyez-les sous la formeAuthorization: Bearer <token>. - Un jeton dure
JWT_EXPIRATION,7dpar défaut (Variables d'environnement). La connexion administrateur renvoie la même valeur dansexpires_in. - Il n'y a pas d'endpoint de rafraîchissement. Quand un jeton expire, la requête suivante répond
401et le client se reconnecte. - La déconnexion (
POST /api/users/auth/logout) indique seulement au client d'abandonner son jeton. Rien n'est révoqué sur le serveur : un jeton reste donc valide jusqu'à son expiration. - Un jeton étudiant est refusé sur les routes admin et un jeton admin sur les routes étudiantes, bien que les deux utilisent le même secret.
- Une connexion qui échoue répond
401avec un seul message, que l'e-mail n'ait pas de compte ou que le mot de passe soit faux : le formulaire ne permet donc pas de savoir qui a un compte. - Les routes de connexion, d'inscription et de mot de passe acceptent 10 tentatives par minute depuis une même adresse, comptées par route. Au-delà, elles répondent
429avec un en-têteRetry-After. Le compte est gardé dans la mémoire de l'API : il repart de zéro au redémarrage et chaque instance a le sien.
Se connecter avec le Super Admin des données de démonstration
Terminalcurl -X POST http://localhost:8000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"admin@learnio.com","password":"Admin@123"}'Réponse{ "success": true, "data": { "access_token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "Bearer", "expires_in": "7d", "admin": { "id": 1, "email": "admin@learnio.com", "instructor_id": null, "roles": [{ "id": 1, "name": "Super Admin", "guard_name": "web" }], "permissions": ["admins.view", "admins.create", "..."] } }, "message": "Signed in successfully." }Appeler une route protégée avec le jeton
Terminalcurl "http://localhost:8000/api/courses?page=1&page_count=5" \ -H "Authorization: Bearer <access_token>"Résultat attendu: Les cinq premiers cours, dans la forme des listes admin.
Se connecter avec l'étudiant des données de démonstration
Les données d'exemple contiennent aussi un étudiant,
demo@learnio.comavec le mot de passeDemo@123:Terminalcurl -X POST http://localhost:8000/api/users/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"demo@learnio.com","password":"Demo@123"}'Transmettez ensuite
data.tokende la même manière, par exemple àGET /api/users/enrollments.
Changez les mots de passe de démonstration
Les comptes des données d'exemple utilisent des mots de passe publiés : Admin@123 pour le Super Admin, admin123 pour le reste du personnel et Demo@123 pour l'étudiant de démonstration. Changez-les, ou partez de tables vides, avant la mise en ligne d'un site.
Permissions
Chaque route admin vérifie d'abord le jeton, puis la permission qu'elle nomme. Les permissions sont nommées <module>.<action>, et un administrateur détient toutes les permissions de tous ses rôles. Quand une route en nomme plusieurs, n'importe laquelle suffit. Dans les tableaux admin ci-dessous, un nom de permission dans la colonne Qui peut l'appeler désigne un administrateur dont les rôles l'accordent.
Relancer le seeder crée les rôles manquants et laisse les permissions des rôles existants telles quelles : les modifications faites dans le tableau de bord sont conservées. Super Admin fait exception : il reçoit toute permission qu'il n'a pas encore.
| Module | Permissions |
|---|---|
| Administrateurs | admins.view, admins.create, admins.edit, admins.delete, admins.assign_roles |
| Rôles | roles.view, roles.create, roles.edit, roles.delete, roles.assign_permissions |
| Paramètres | settings.view, settings.edit |
| Étudiants | students.view, students.create, students.update, students.delete, students.restore, students.verify |
| Catégories | categories.view, categories.create, categories.edit, categories.delete, categories.restore |
| Cours | courses.view, courses.create, courses.edit, courses.delete, courses.restore |
| Programme | curriculum.view, curriculum.create, curriculum.edit, curriculum.delete |
| Formateurs | instructors.view, instructors.create, instructors.edit, instructors.delete, instructors.restore |
| Inscriptions | enrollments.view, enrollments.create, enrollments.edit, enrollments.delete |
| Commandes | orders.view, orders.create, orders.edit, orders.delete |
| Avis | reviews.view, reviews.edit, reviews.delete, reviews.restore |
| Cours en direct | live_sessions.view, live_sessions.create, live_sessions.edit, live_sessions.delete |
| Devoirs | assignments.view, assignments.create, assignments.edit, assignments.delete |
| Blog | blog.view, blog.create, blog.edit, blog.delete, blog.restore |
| Assistant IA | ai_chat.use, ai_chat.view_models |
Chaque permission de lecture se termine par .view, et aucune autre : le rôle Viewer des données de démonstration est construit à partir de cette règle. Les rôles créés par les données d'exemple :
| Rôle | Accorde |
|---|---|
| Super Admin | Tout |
| Admin | Tout sauf roles.*, admins.* et settings.edit |
| Manager | Cours, programme, catégories, formateurs, inscriptions et commandes sans suppression, plus students.view, reviews.view et reviews.edit |
| Editor | blog.*, reviews.view, reviews.edit, categories.view, courses.view, instructors.view |
| Viewer | Toutes les permissions .view |
| Formateur | Cours en direct, devoirs et programme, courses.view, courses.create, courses.edit, ainsi que la lecture des étudiants, des inscriptions et des avis |
Un compte admin lié à un formateur porte un instructor_id dans sa réponse de connexion, et il est limité à ses propres cours en plus de ses permissions : les listes n'affichent que ces cours et leurs étudiants, et une écriture en dehors répond 403.
Quand les rôles d'un administrateur changent, le tableau de bord en est informé par le socket /auth (événement permissions-updated) pour rafraîchir GET /api/auth/me. Ce socket n'accepte que des jetons d'administrateur.
Catalogue public
Aucun jeton nécessaire. Ce sont les routes qu'appellent les pages publiques du site étudiant.
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/health | N'importe qui | Vérification de disponibilité |
GET | /api/users/courses | N'importe qui | Liste les cours publics publiés, paginés (page_count, le paramètre courses_per_page par défaut), avec filtres et tri |
GET | /api/users/courses/categories | N'importe qui | Les catégories qui contiennent au moins un cours public, avec leur nombre de cours |
GET | /api/users/courses/:slug | N'importe qui | Un cours public publié avec ses sections et ses leçons. Un brouillon répond 404. Seules les leçons d'aperçu gratuit contiennent leur contenu et leur vidéo. |
GET | /api/users/courses/:slug/reviews | N'importe qui | Les avis publiés du cours, du plus récemment mis à jour au plus ancien, paginés (page_count, 5 par défaut) |
GET | /api/users/Instructors | N'importe qui | Annuaire des formateurs, paginé (per_page, 8 par défaut), filtrable par specialty |
GET | /api/users/Instructors/:username | N'importe qui | Un formateur avec ses cours publics |
GET | /api/users/blog | N'importe qui | Les articles publiés, du plus récent au plus ancien, paginés (page_count, 9 par défaut), filtrables par tag |
GET | /api/users/blog/tags | N'importe qui | Chaque tag utilisé, avec le nombre d'articles qui le portent |
GET | /api/users/blog/:slug | N'importe qui | Un article publié |
GET | /api/users/platform/figures | N'importe qui | Les chiffres de la page d'accueil : étudiants, cours, formateurs, pays et satisfaction |
GET | /api/categories | N'importe qui | Liste des catégories, paginée, avec search, is_active, parent_id, has_courses |
GET | /api/categories/roots | N'importe qui | Catégories de premier niveau |
GET | /api/categories/slug/:slug | N'importe qui | Une catégorie par slug |
GET | /api/categories/:id | N'importe qui | Une catégorie par identifiant |
GET | /api/helpers/countries | N'importe qui | Les pays pour un champ de sélection, dans la langue de la requête |
GET | /api/shop/payment-methods | N'importe qui | Les moyens de paiement que le paiement doit proposer, et lesquels sont hébergés |
Le I majuscule de /api/users/Instructors correspond au chemin qu'appelle le site étudiant ; la correspondance n'est pas sensible à la casse.
Inscription et connexion des étudiants
Le site étudiant utilise les routes sous /api/users/auth. L'inscription connecte immédiatement l'étudiant et envoie par e-mail un lien de confirmation ; un compte non confirmé peut quand même naviguer et acheter.
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
POST | /api/users/auth/register | N'importe qui | Crée le compte (first_name, last_name, email, password de 8 caractères ou plus, phone facultatif) et connecte l'étudiant. data.verification_email_sent indique si l'e-mail est parti. |
POST | /api/users/auth/login | N'importe qui | Connecte avec email et password, répond token et user |
POST | /api/users/auth/logout | N'importe qui | Rien à révoquer ; permet au client d'effacer son jeton |
POST | /api/users/auth/resend | N'importe qui | Renvoie le lien de confirmation par e-mail à email |
POST | /api/users/auth/verify-email | N'importe qui | Confirme l'adresse avec le token du lien (valable 24 heures) |
POST | /api/users/auth/forgot-password | N'importe qui | Envoie un lien de réinitialisation par e-mail à email (valable 1 heure) |
POST | /api/users/auth/reset-password | N'importe qui | Définit un nouveau password avec le token du lien |
GET | /api/users/auth/me | Étudiant | L'étudiant connecté |
resend et forgot-password répondent de la même façon que l'adresse ait un compte ou non : on ne peut donc pas s'en servir pour savoir qui est inscrit. La connexion, l'inscription, resend, forgot-password et reset-password sont limitées en nombre de tentatives (Authentification).
Un second ensemble de routes étudiantes sous /api/students/auth fonctionne sur les mêmes comptes et répond aussi token et user. Le site étudiant ne l'utilise pas ; préférez /api/users/auth.
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
POST | /api/students/auth/register | N'importe qui | Crée un compte étudiant et le connecte, sans e-mail de confirmation |
POST | /api/students/auth/login | N'importe qui | Connecte l'étudiant |
GET | /api/students/auth/me | Étudiant | Le profil de l'étudiant connecté |
PATCH | /api/students/auth/me | Étudiant | Met à jour le nom, l'e-mail ou le téléphone |
PATCH | /api/students/auth/me/password | Étudiant | Change le mot de passe |
POST | /api/students/auth/forgot-password | N'importe qui | Envoie un lien de réinitialisation à email, en répondant de la même façon que l'adresse ait un compte ou non |
POST | /api/students/auth/reset-password | N'importe qui | Définit un nouveau mot de passe avec un jeton de réinitialisation |
Profil, cours et progression de l'étudiant
Chaque route ici exige un jeton étudiant. Les cours et les leçons sont désignés par leur code, pas par leur identifiant numérique.
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/users/profile | Étudiant | L'étudiant connecté |
PATCH | /api/users/profile | Étudiant | Met à jour first_name, last_name, email ou phone |
PATCH | /api/users/profile/password | Étudiant | Change le mot de passe (l'actuel et un nouveau de 8 caractères ou plus) |
GET | /api/users/dashboard/overview | Étudiant | Tout ce qu'affiche l'écran d'accueil du tableau de bord, en un seul appel |
GET | /api/users/dashboard/kpis | Étudiant | Les chiffres clés de l'étudiant |
GET | /api/users/dashboard/radar | Étudiant | Le graphique des compétences, issu du paramètre dashboard_radar_metrics |
GET | /api/users/enrollments | Étudiant | Les cours de l'étudiant, paginés (page_count, 100 par défaut), filtrables par type, search et status |
GET | /api/users/enrollments/courses/:code | Étudiant | Le contenu complet d'un cours détenu, avec le statut de chaque leçon et la progression |
PATCH | /api/users/enrollments/courses/:code | Étudiant | Enregistre la dernière leçon ouverte (last_accessed_lesson_id) |
POST | /api/users/enrollments/lessons/:lessonCode/complete | Étudiant | Marque une leçon comme terminée et met à jour la progression du cours |
GET | /api/users/enrollments/lessons/:lessonCode/note | Étudiant | La note de l'étudiant sur une leçon |
PUT | /api/users/enrollments/lessons/:lessonCode/note | Étudiant | Enregistre la note (body) |
GET | /api/users/search | Étudiant | Recherche globale (q, limit par type) : les cours de l'étudiant, le catalogue, les formateurs et plus encore |
GET | /api/users/courses/:courseId/review | Étudiant | L'avis de l'étudiant lui-même sur le cours, ou null s'il n'en a pas |
PUT | /api/users/courses/:courseId/review | Étudiant | Écrit ou remplace l'avis de l'étudiant : rating de 1 à 5, et comment facultatif de 2 000 caractères au plus |
DELETE | /api/users/courses/:courseId/review | Étudiant | Retire l'avis de l'étudiant |
Les routes d'avis prennent l'identifiant numérique du cours, et chaque étudiant a un avis par cours. Seul un étudiant inscrit au cours peut en écrire un ; une inscription annulée répond 403.
- Un avis est
publishedaussitôt, oupendingjusqu'à ce qu'un modérateur l'approuve quand le paramètrereviews_require_approvalvauttrue. Modifier un avis masqué par un modérateur le renvoie àpending. - Un avis supprimé par un modérateur revient avec
status: removedet ne peut plus être modifié ni retiré (403). - Chaque écriture recalcule la note et le nombre d'avis du cours, ainsi que ceux de son formateur.
- Un nouvel avis, et une modification en attente d'approbation, notifient le personnel qui détient
reviews.view.
Quiz, devoirs et calendrier
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/users/quizzes?course_id= | Étudiant | Les quiz d'un cours que l'étudiant détient |
GET | /api/users/quizzes/:id | Étudiant | Un quiz avec ses questions, sans les réponses |
GET | /api/users/quizzes/:id/attempts | Étudiant | Les tentatives précédentes de l'étudiant |
POST | /api/users/quizzes/:id/attempts | Étudiant | Soumet answers (identifiant de question vers les identifiants des options choisies) et renvoie le score |
GET | /api/users/dashboard/calendar | Étudiant | Les cours et les échéances de devoirs entre from et to (dates ISO, 7 jours par défaut, 92 au maximum) |
POST | /api/users/dashboard/calendar/assignments/:id/submit | Étudiant | Rend un devoir (body) |
DELETE | /api/users/dashboard/calendar/assignments/:id/submit | Étudiant | Retire une soumission |
Les routes du calendrier pour les cours en direct sont décrites dans Cours en direct.
Messages et notifications des étudiants
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/users/conversations | Étudiant | Les conversations de l'étudiant avec ses formateurs |
POST | /api/users/conversations | Étudiant | Ouvre, ou renvoie, la conversation avec le formateur de course_id |
GET | /api/users/conversations/:id/messages | Étudiant | Les messages d'une conversation |
POST | /api/users/conversations/:id/messages | Étudiant | Envoie un message : body, une image (attachment_url, attachment_name, attachment_type), ou les deux |
PATCH | /api/users/conversations/:id/read | Étudiant | Marque la conversation comme lue |
PATCH | /api/users/conversations/:id/unread | Étudiant | La marque comme non lue |
GET | /api/users/notifications | Étudiant | Les notifications de l'étudiant |
PATCH | /api/users/notifications/:id/read | Étudiant | En marque une comme lue |
PATCH | /api/users/notifications/read-all | Étudiant | Les marque toutes comme lues |
DELETE | /api/users/notifications/:id | Étudiant | En supprime une |
Les nouvelles notifications sont aussi envoyées via Socket.IO, sur le namespace /notifications à l'adresse de l'API sans /api. Transmettez le jeton comme auth.token dans le handshake et écoutez notification:created. Les administrateurs utilisent le même socket avec leur propre jeton.
Paiement et règlements
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/shop/payment-methods | N'importe qui | Les methods que propose le paiement et celles qui sont hosted |
POST | /api/shop/checkout | Étudiant | Achète course_id, ou jusqu'à 50 course_ids en un seul débit, avec payment_method (card ou paypal) et locale |
POST | /api/shop/orders/:reference/settle | Étudiant | Finalise un paiement hébergé au retour de l'acheteur. Nécessaire pour PayPal ; sans effet pour Stripe. |
GET | /api/shop/orders | Étudiant | Les commandes de l'étudiant |
POST | /api/webhooks/payments/stripe | Stripe, signé | Règle, fait échouer ou rembourse les commandes à partir des événements de Stripe |
POST | /api/webhooks/payments/paypal | PayPal, signé | Règle, fait échouer ou rembourse les commandes à partir des événements de PayPal |
Quand le paiement répond avec redirect_url, envoyez-y l'acheteur et considérez la commande comme pending : la place est attribuée quand le webhook du prestataire confirme le paiement, pas au retour. Chaque webhook vérifie la signature du prestataire et répond 401 si elle ne correspond pas. Les événements ne sont appliqués qu'une fois, quel que soit le nombre de nouvelles tentatives du prestataire.
Un cours gratuit (prix 0) passe par la même route et n'atteint jamais de processeur de paiement : il fonctionne sans aucune clé de paiement. La commande est enregistrée comme paid avec gateway: "free" et redirect_url: null, la place est attribuée aussitôt, et l'étudiant reçoit l'e-mail d'inscription sans reçu. Les commandes gratuites comptent comme des inscriptions, pas comme des ventes : elles sont exclues du panier moyen.
Configuration des prestataires et de leurs abonnements aux webhooks : Paiements.
Connexion admin et comptes du personnel
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
POST | /api/auth/login | N'importe qui | Connecte un administrateur, répond access_token, les rôles et les permissions. Limité en nombre de tentatives. |
GET | /api/auth/me | Tout administrateur connecté | L'administrateur connecté avec ses rôles et permissions |
GET | /api/admins | admins.view | Liste du personnel, filtrable par email, name, phone, role_id |
GET | /api/admins/statistics | admins.view | Effectifs du personnel |
GET | /api/admins/:id | admins.view | Un administrateur |
POST | /api/admins | admins.create | Crée un administrateur |
PATCH | /api/admins/:id | admins.edit | Met à jour un administrateur |
PATCH | /api/admins/:id/roles | admins.assign_roles | Remplace les rôles de l'administrateur (role_ids) |
DELETE | /api/admins/:id | admins.delete | Supprime un administrateur |
PATCH | /api/admins/profile | Tout administrateur connecté | Met à jour le nom, les coordonnées et la photo de l'administrateur connecté |
PATCH | /api/admins/profile/password | Tout administrateur connecté | Change le mot de passe de l'administrateur connecté |
Une adresse e-mail appartient à un seul administrateur, même supprimé : créer un administrateur, ou changer un e-mail pour une adresse déjà utilisée, répond 409.
Rôles
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/roles | roles.view | Les rôles, paginés quand page est envoyé, filtrables par name, guard_name, created_from, created_to |
GET | /api/roles/statistics | roles.view | Nombre de rôles |
GET | /api/roles/select | roles.view | Tous les rôles, pour un sélecteur |
GET | /api/roles/permissions | roles.view | Toutes les permissions, regroupées par module |
GET | /api/roles/:id | roles.view | Un rôle avec ses permissions |
POST | /api/roles | roles.create | Crée un rôle (name) |
PUT | /api/roles/:id | roles.edit | Renomme un rôle |
POST | /api/roles/:id/permissions | roles.assign_permissions | Remplace les permissions du rôle par permissions, une liste de noms |
DELETE | /api/roles/:id | roles.delete | Supprime un rôle |
Étudiants
Les comptes étudiants sont désignés par username. La suppression d'un compte est une suppression logique, réversible.
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/users | students.view | Les étudiants, avec search, email, phone, country_id, username, first_name, last_name, from_date, to_date, verified |
GET | /api/users/statistic | students.view | Nombre d'étudiants |
GET | /api/users/:username | students.view | Un étudiant |
POST | /api/users | students.create | Crée un étudiant |
PATCH | /api/users/:username | students.update | Met à jour un étudiant |
PATCH | /api/users/:username/change-password | students.update | Définit le mot de passe d'un étudiant |
POST | /api/users/:username/resend-verification-email | students.update | Renvoie le lien de confirmation. data.sent vaut false et data.simulated vaut true quand aucun fournisseur d'e-mail n'est défini et que le lien est allé dans le journal. 409 si l'adresse est déjà confirmée, 429 quand elle en a reçu trop, 503 quand le fournisseur a refusé. |
POST | /api/users/:username/make-verified | students.verify | Marque l'e-mail comme confirmé |
POST | /api/users/:username/make-unverified | students.verify | Marque l'e-mail comme non confirmé |
DELETE | /api/users/:username | students.delete | Déplace l'étudiant dans la corbeille |
GET | /api/users/deleted | students.view, students.delete ou students.restore | Les étudiants supprimés |
GET | /api/users/deleted/:username | students.view, students.delete ou students.restore | Un étudiant supprimé |
POST | /api/users/deleted/:username/restore | students.restore | Restaure un étudiant supprimé |
Formateurs
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/instructors | instructors.view | Les formateurs, avec search, specialty, status, is_featured |
GET | /api/instructors/statistic | instructors.view | Nombre de formateurs |
GET | /api/instructors/username/:username | instructors.view | Un formateur par nom d'utilisateur |
GET | /api/instructors/:id | instructors.view | Un formateur |
POST | /api/instructors | instructors.create | Crée un formateur |
PATCH | /api/instructors/:id | instructors.edit | Met à jour un formateur |
DELETE | /api/instructors/:id | instructors.delete | Déplace un formateur dans la corbeille |
GET | /api/instructors/deleted | instructors.view, instructors.delete ou instructors.restore | Les formateurs supprimés |
POST | /api/instructors/deleted/:id/restore | instructors.restore | En restaure un |
Un compte formateur écrit à ses étudiants via ces routes, qui répondent 403 pour un administrateur non lié à un formateur :
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/conversations | Compte formateur | Les conversations du formateur |
GET | /api/conversations/with/:userId | Compte formateur | Les cours que le formateur partage avec un étudiant, pour démarrer une conversation à partir de l'un d'eux |
POST | /api/conversations | Compte formateur | Ouvre, ou renvoie, une conversation avec user_id, éventuellement au sujet de course_id |
GET | /api/conversations/:id/messages | Compte formateur | Les messages d'une conversation |
POST | /api/conversations/:id/messages | Compte formateur | Envoie un message |
PATCH | /api/conversations/:id/read | Compte formateur | La marque comme lue |
PATCH | /api/conversations/:id/unread | Compte formateur | La marque comme non lue |
Catégories
Les lectures sont ouvertes à tous et listées dans le Catalogue public. Les écritures exigent une permission :
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/categories/statistic | categories.view | Nombre de catégories |
POST | /api/categories | categories.create | Crée une catégorie |
PATCH | /api/categories/:id | categories.edit | Met à jour une catégorie |
DELETE | /api/categories/:id | categories.delete | Déplace une catégorie dans la corbeille |
GET | /api/categories/deleted | categories.delete ou categories.restore | Les catégories supprimées |
POST | /api/categories/deleted/:id/restore | categories.restore | En restaure un |
Cours
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/courses | courses.view | Les cours, avec search, category_id, instructor_id, status, type, is_public, is_featured |
GET | /api/courses/statistic | courses.view | Nombre de cours |
GET | /api/courses/slug/:slug | courses.view | Un cours par slug |
GET | /api/courses/:id | courses.view | Un cours |
POST | /api/courses | courses.create | Crée un cours |
PATCH | /api/courses/:id | courses.edit | Met à jour un cours |
DELETE | /api/courses/:id | courses.delete | Déplace un cours dans la corbeille |
GET | /api/courses/deleted | courses.delete ou courses.restore | Les cours supprimés |
POST | /api/courses/deleted/:id/restore | courses.restore | En restaure un |
Programme : sections, leçons et ressources
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/courses/:courseId/sections | curriculum.view | Les sections d'un cours |
POST | /api/courses/:courseId/sections | curriculum.create | Ajoute une section |
POST | /api/courses/:courseId/sections/reorder | curriculum.edit | Définit l'ordre des sections à partir de ids |
GET | /api/sections/:id | curriculum.view | Une section |
PATCH | /api/sections/:id | curriculum.edit | Met à jour une section |
DELETE | /api/sections/:id | curriculum.delete | Supprime une section |
GET | /api/sections/:sectionId/lessons | curriculum.view | Les leçons d'une section |
POST | /api/sections/:sectionId/lessons | curriculum.create | Ajoute une leçon |
POST | /api/sections/:sectionId/lessons/reorder | curriculum.edit | Définit l'ordre des leçons à partir de ids |
GET | /api/lessons/:id | curriculum.view | Une leçon |
PATCH | /api/lessons/:id | curriculum.edit | Met à jour une leçon |
DELETE | /api/lessons/:id | curriculum.delete | Supprime une leçon |
GET | /api/lessons/:lessonId/resources | curriculum.view | Les ressources téléchargeables d'une leçon |
POST | /api/lessons/:lessonId/resources | curriculum.edit | Joint une ressource |
PATCH | /api/lesson-resources/:id | curriculum.edit | Met à jour une ressource |
DELETE | /api/lesson-resources/:id | curriculum.edit | Retire une ressource |
Quiz et devoirs
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/quizzes?course_id= | courses.view | Les quiz d'un cours (course_id est obligatoire) |
GET | /api/quizzes/:id | courses.view | Un quiz avec ses questions et ses réponses |
POST | /api/quizzes | courses.create | Crée un quiz |
PATCH | /api/quizzes/:id | courses.edit | Met à jour un quiz |
DELETE | /api/quizzes/:id | courses.delete | Supprime un quiz |
POST | /api/quizzes/:id/questions | courses.edit | Ajoute une question |
PATCH | /api/quizzes/:id/questions/:questionId | courses.edit | Met à jour une question |
DELETE | /api/quizzes/:id/questions/:questionId | courses.edit | Supprime une question |
GET | /api/assignments | assignments.view | Les devoirs, avec search, course_id, lesson_id, status, from, to |
GET | /api/assignments/:id | assignments.view | Un devoir |
GET | /api/assignments/:id/submissions | assignments.view | Les soumissions en attente de correction |
PATCH | /api/assignments/submissions/:submissionId/grade | assignments.edit | Corrige une soumission |
POST | /api/assignments | assignments.create | Crée un devoir |
PATCH | /api/assignments/:id | assignments.edit | Met à jour un devoir |
DELETE | /api/assignments/:id | assignments.delete | Supprime un devoir |
Inscriptions et commandes
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/enrollments | enrollments.view | Les inscriptions, avec search, course_id, user_id, status, date_from, date_to |
GET | /api/enrollments/statistic | enrollments.view | Nombre d'inscriptions |
GET | /api/enrollments/:id | enrollments.view | Une inscription |
POST | /api/enrollments | enrollments.create | Inscrit un étudiant manuellement |
PATCH | /api/enrollments/:id | enrollments.edit | Met à jour une inscription |
DELETE | /api/enrollments/:id | enrollments.delete | Retire une inscription |
GET | /api/orders | orders.view | Commandes, avec search, status, payment_method, course_id, user_id, date_from, date_to, page, limit, sort_by, sort_order |
GET | /api/orders/revenue | orders.view | Revenus entre date_from et date_to. Le panier moyen exclut les commandes gratuites. |
GET | /api/orders/revenue/series | orders.view | Le chiffre d'affaires quotidien des derniers days jours (30 par défaut, 365 au maximum) |
GET | /api/orders/:id | orders.view | Une commande |
POST | /api/orders | orders.create | Enregistre une place payée par un autre moyen |
PATCH | /api/orders/:id | orders.edit | Met à jour une commande |
DELETE | /api/orders/:id | orders.delete | Supprime une commande |
Le status d'une commande est pending, paid, failed ou refunded. Son gateway nomme le processeur qui a encaissé le paiement, demo pour le simulateur intégré, ou free pour un cours qui ne coûtait rien.
Avis
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/course-reviews | reviews.view | Les avis, avec search, course_id, user_id, rating, status |
GET | /api/course-reviews/statistic | reviews.view | Nombre d'avis |
GET | /api/course-reviews/:id | reviews.view | Un avis |
PATCH | /api/course-reviews/:id | reviews.edit | Modère un avis : status vaut published, pending ou hidden |
DELETE | /api/course-reviews/:id | reviews.delete | Déplace un avis dans la corbeille |
GET | /api/course-reviews/deleted | reviews.delete ou reviews.restore | Les avis supprimés |
POST | /api/course-reviews/deleted/:id/restore | reviews.restore | En restaure un |
Les étudiants écrivent leurs propres avis via les routes étudiant, et la page du cours lit ceux qui sont publiés dans le Catalogue public. Chaque décision de modération recalcule la note du cours et celle du formateur.
Blog
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/blog | blog.view | Les articles de tous statuts, avec search, category_slug, status, tag |
GET | /api/blog/statistic | blog.view | Nombre d'articles |
GET | /api/blog/slug/:slug | blog.view | Un article par slug |
GET | /api/blog/:id | blog.view | Un article |
POST | /api/blog | blog.create | Crée un article |
PATCH | /api/blog/:id | blog.edit | Met à jour un article |
DELETE | /api/blog/:id | blog.delete | Déplace un article dans la corbeille |
GET | /api/blog/deleted | blog.delete ou blog.restore | Les articles supprimés |
POST | /api/blog/deleted/:id/restore | blog.restore | En restaure un |
Paramètres
Les paramètres de la plateforme sont enregistrés sous forme de paires clé-valeur et désignés par key.
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/settings | settings.view | Les paramètres, avec search, category, type |
GET | /api/settings/:key | settings.view | Un paramètre |
PATCH | /api/settings/:key | settings.edit | Modifie la valeur d'un paramètre |
DELETE | /api/settings/:key | settings.edit | Supprime un paramètre |
Le seeder crée ces six paramètres, et chacun est lu par l'API ou par le tableau de bord de l'étudiant :
| Clé | Valeur initiale | Rôle |
|---|---|---|
site_name | Learnio | Le nom du produit écrit dans chaque e-mail que l'API envoie |
default_locale | en | La langue utilisée quand une requête ne nomme aucune langue prise en charge. Une valeur qui n'est pas une langue prise en charge est refusée avec 400. |
support_email | support@learnio.com | L'adresse de réponse de chaque e-mail, pour qu'une réponse parvienne à une personne |
courses_per_page | 12 | La taille de page du catalogue public quand la requête n'en fixe aucune (de 1 à 100) |
reviews_require_approval | false | À true, l'avis d'un étudiant attend avec le statut pending jusqu'à ce qu'un modérateur le publie |
dashboard_radar_metrics | Une table JSON de métrique à score | Le graphique des compétences du tableau de bord de l'étudiant |
Une modification s'applique à la requête ou à l'e-mail suivant, sans redémarrage. Relancer le seeder ajoute un paramètre manquant, mais n'écrase jamais une valeur déjà enregistrée.
Envoi de médias
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
POST | /api/helpers/upload | Tout administrateur connecté, ou un étudiant | Envoie un fichier vers le bucket de médias et répond avec ses adresses |
Envoyez du multipart/form-data avec le fichier dans file, jusqu'à 150 Mo, et éventuellement path (le dossier, uploads par défaut), for (un préréglage de taille d'image) et type (video pour ignorer le traitement d'image). Les images sont redimensionnées en plusieurs versions ; les vidéos (mp4, webm, mov, m4v) sont enregistrées telles quelles. Cette route a besoin des paramètres du bucket décrits dans Stockage des médias.
La route demande un jeton d'administrateur ou d'étudiant, vérifié avant la lecture du fichier. path doit être l'un des dossiers listés dans back-end/src/modules/helpers/upload/upload-folders.constants.ts ; tout autre répond 400. Un administrateur peut téléverser dans uploads, admins/profile, admins/profiles, users/profiles, blog, categories, courses, instructors, messages et ai-chat. Un étudiant ne peut téléverser que dans messages, pour les images qu'il joint à une conversation. Un nouvel écran qui téléverse dans son propre dossier demande d'ajouter ce dossier à la liste.
curl -X POST http://localhost:8000/api/helpers/upload \
-H "Authorization: Bearer <access_token>" \
-F "file=@cover.jpg" -F "path=courses"Notifications, recherche et statistiques
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/notifications | Tout administrateur connecté | Les notifications de l'administrateur connecté et le nombre de non lues |
PATCH | /api/notifications/read-all | Tout administrateur connecté | Les marque toutes comme lues, répond avec tout le flux |
PATCH | /api/notifications/:id/read | Tout administrateur connecté | En marque une comme lue, répond avec tout le flux |
DELETE | /api/notifications/:id | Tout administrateur connecté | En supprime une, répond avec tout le flux |
GET | /api/search | Tout administrateur connecté | Recherche globale (q, limit par type). Seuls les types autorisés par les permissions de l'administrateur sont recherchés. |
GET | /api/statistics/trends | courses.view | Les chiffres de chaque carte de statistiques, en un seul appel |
GET | /api/statistics/overview | courses.view | La vue d'ensemble de l'accueil du tableau de bord, sur days jours, avec limit lignes par liste |
Un administrateur ne lit et ne modifie que ses propres notifications : les routes prennent l'administrateur dans le jeton. L'API en écrit une pour chacun de ces événements, à chaque administrateur qui détient la permission demandée par l'écran lié :
| Type | Quand | Qui la reçoit |
|---|---|---|
enrollment_created | Un étudiant reçoit une place, par un achat, un cours gratuit ou le personnel | enrollments.view |
course_completed | Un étudiant termine un cours | enrollments.view |
course_review_submitted | Un étudiant laisse un avis, ou modifie un avis en attente d'approbation | reviews.view |
course_published | Un cours est publié | courses.view |
student_registered | Un étudiant crée un compte | students.view |
Un compte administrateur lié à un formateur n'est informé que des cours de ce formateur, et pas des nouvelles inscriptions de comptes. Chaque notification est aussi poussée par le socket /notifications dès son enregistrement.
Cours en direct
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Les routes des cours en direct : la planification des sessions, et les jetons d'accès que reçoivent les étudiants et les hôtes pour une salle Jitsi Meet.
Certificats
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Les routes des certificats : comment un étudiant en réclame un pour un cours terminé, et l'adresse publique de vérification.
Assistant IA
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Les routes de l'assistant IA : la diffusion en streaming d'une réponse, la liste des modèles et les sessions de conversation enregistrées.
Historique des conversations de l'assistant
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Enregistrer, lister et renommer les conversations de l'assistant.
Serveur MCP
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Le module MCP qui expose les données du tableau de bord comme outils pour l'assistant.
Routes du mode démo
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Les routes qu'utilise une démo publique : l'interrupteur de démo et les comptes par visiteur.
Passerelles de paiement personnalisées
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Comment la couche de paiement est construite : les interfaces de passerelle et de webhook, le webhook du simulateur, et l'ajout d'un prestataire.