Aller au contenu

EPIDOCS — Erreurs courantes

Frontend

Page blanche après déploiement

Symptôme : L'application affiche une page blanche ou une erreur 500.

Cause : Les variables NEXT_PUBLIC_* ne sont pas injectées au build time.

Solution :

# Vérifier que les variables sont dans le .env sur le VPS
ssh root@VPS_IP
cat /root/projects/epidocs/epidocs-frontend/.env

# Les variables NEXT_PUBLIC_* doivent être présentes AVANT le build Docker
# Si elles manquent, les ajouter et reconstruire l'image

Warning

Les variables NEXT_PUBLIC_* sont injectées au build time, pas au runtime. Un simple restart du conteneur ne suffit pas — il faut rebuild l'image Docker.


Boucle de redirection /auth

Symptôme : L'utilisateur est redirigé en boucle vers /auth après connexion.

Cause possible 1 : Le cookie auth_token est bloqué par le navigateur (Domain invalide).

Solution :

# Vérifier dans les DevTools > Application > Cookies
# Si le cookie n'apparaît pas, c'est un problème de Domain
# Le backend doit configurer AUTH_COOKIE_DOMAIN = None en dev
# ou AUTH_COOKIE_DOMAIN = ".epitools.bj" en prod

Cause possible 2 : Le proxy Next.js ne lit pas correctement les cookies.

Solution : Vérifier que src/proxy.js utilise bien request.cookies.get() et non cookies() de next/headers.


Erreur 503 sur toutes les requêtes API

Symptôme : Toutes les requêtes API retournent 503, y compris /auth/sign_in.

Cause : Le mode maintenance est activé côté backend et les routes d'auth ne sont pas exemptées.

Solution :

# Se connecter directement au backend pour désactiver la maintenance
curl -X PUT http://127.0.0.1:7010/admin/system-status \
  -H "Cookie: auth_token=VOTRE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"is_active": true}'

Danger

Si les routes d'auth sont bloquées par la maintenance, aucun admin ne peut se connecter. Corriger le middleware backend pour exempter /auth/sign_in et /auth/callback.


"Mode maintenance" affiché alors que le système est actif

Symptôme : Le dashboard admin affiche "MODE MAINTENANCE" même quand is_active: true.

Cause : Le backend retourne les données en camelCase (isActive) mais le frontend lit en snake_case (is_active).

Solution : Vérifier que normalizeStatusData() dans systemStatusService.js gère bien les deux formats :

is_active: data.is_active ?? data.isActive

Résultats de recherche étudiants vides

Symptôme : La recherche d'étudiants dans le wizard de génération ne retourne aucun résultat malgré des étudiants existants.

Cause : Le backend retourne { students: [...] } mais le code frontend cherche data.results.

Solution : Vérifier que le code utilise bien :

const students = studentsData?.students || studentsData?.results || [];

Erreur 500 sur GET /documents/available-document-types

Symptôme : 'User' object has no attribute 'section' dans les logs backend.

Cause : Un admin appelle cette route qui tente d'accéder à request.user.section, mais les admins n'ont pas d'attribut section.

Solution : Passer ?studentEmail=xxx ou ?classe=PGE1 comme query param pour que le backend utilise la section de l'étudiant ou de la classe au lieu de celle de l'utilisateur connecté.


Backend

TypeError sur PUT /admin/system-status

Symptôme : TypeError: '<=' not supported between instances of 'str' and 'datetime.datetime'

Cause : Les champs scheduled_start et scheduled_end sont stockés comme strings mais comparés avec timezone.now() (datetime).

Solution : Parser les dates avec parse_datetime() avant la comparaison dans la vue backend.


Génération en lot timeout

Symptôme : La requête POST /documents/admin/batch-generate timeout pour les grandes classes.

Cause : La génération de nombreux PDFs prend du temps. Le timeout par défaut d'Axios est trop court.

Solution : Le frontend utilise déjà un timeout de 300 secondes (5 minutes). Si ce n'est pas suffisant :

# Vérifier côté Nginx
# /etc/nginx/sites-available/epidocs
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;

Symptôme : Le login réussit (200 OK) mais le cookie n'est pas stocké dans le navigateur.

Cause : Le Set-Cookie du backend a un attribut Domain incompatible avec le frontend.

Solution :

  • Dev : AUTH_COOKIE_DOMAIN = None dans les settings Django
  • Prod : AUTH_COOKIE_DOMAIN = ".epitools.bj" (domaine racine avec point)