EPIDOCS API — Erreurs courantes¶
Erreurs d'authentification¶
Cookie auth_token non envoyé / session invalide¶
Symptôme : L'API retourne 401 Unauthorized alors que l'utilisateur vient de se connecter.
Cause : Le cookie auth_token n'est pas envoyé par le navigateur (problème CORS / SameSite), ou la session a expiré.
Solution :
# Vérifier les sessions actives dans la base
docker compose exec web python manage.py shell -c "
from apps.user.models import UserSession
sessions = UserSession.objects.filter(is_valid=True)
for s in sessions:
print(f'{s.user or s.student} - expires: {s.expires_at} - valid: {s.is_valid}')
"
- En production : vérifier que
JWT_COOKIE_DOMAINest bien défini (ex:.epitools.bj) - En dev : vérifier que le frontend envoie
credentials: 'include'dans les requêtes fetch
Azure AD callback échoue¶
Symptôme : Après la connexion Microsoft, le callback retourne une erreur ou redirige en boucle.
Cause : CALLBACK_URL ne correspond pas à l'URL enregistrée dans l'App Registration Azure.
Solution :
- Vérifier la variable
CALLBACK_URLdans le.env - Vérifier que cette URL est enregistrée dans Azure Portal → App Registrations → Redirect URIs
- S'assurer que le tenant ID est correct (
AZURE_TENANT_ID)
Erreurs de génération de documents¶
La version EN n'est pas générée pour un document existant¶
Symptôme : L'étudiant clique "générer" après l'ajout du support multilingue, le document s'affiche comme "terminé" mais X-Has-En retourne false — seule la version FR est disponible.
Cause : Le document avait déjà été généré avant l'ajout du modele_en sur le DocumentType. L'entrée GenDocumentHistory existe avec remote_url_en = NULL. L'API détecte le document existant et le retourne sans vérifier si un template EN est maintenant disponible.
Solution : Depuis la version 621602b, ce cas est géré automatiquement. Lors d'une nouvelle demande de génération, si modele_en est disponible mais remote_url_en est NULL, la version EN est générée et sauvegardée sans toucher au document FR ni au tracking code. Il suffit que l'étudiant reclique "générer".
Pour forcer la mise à jour manuellement :
docker compose exec web python manage.py shell -c "
from apps.document_type.models import GenDocumentHistory, DocumentType
from apps.document_type.utils import generate_en_for_existing
# Trouver les documents sans EN pour un doc_id donné
doc_id = 'certificat_scolarite'
doc = DocumentType.objects.get(doc_id=doc_id)
if not doc.modele_en:
print('Pas de template EN configuré pour ce document')
else:
histories = GenDocumentHistory.objects.filter(doc_id=doc_id, remote_url_en__isnull=True)
print(f'{histories.count()} documents à mettre à jour')
for h in histories:
ok = generate_en_for_existing(h, doc.modele_en.path)
print(f'{h.tracking_code_id}: {\"OK\" if ok else \"ERREUR\"}')
"
X-Has-En: false alors que le template EN est configuré¶
Symptôme : Le frontend n'affiche pas le bouton de téléchargement EN malgré un modele_en uploadé sur le DocumentType.
Causes possibles :
- Le document a été généré avant l'upload du template EN (voir cas ci-dessus)
- Le campus de l'étudiant a un
CampusDocumentTypesansmodele_en - La génération EN a échoué silencieusement (voir logs)
Solution :
# Vérifier les logs de génération EN
docker compose logs web --tail 200 | grep -i "EN PDF\|generating EN\|EN version"
# Vérifier le campus override
docker compose exec web python manage.py shell -c "
from apps.campus.models import CampusDocumentType
from apps.student.models import Student
email = 'etudiant@epitech.bj'
s = Student.objects.get(login=email)
if s.campus:
override = CampusDocumentType.objects.filter(campus=s.campus, document_type__doc_id='certificat_scolarite').first()
if override:
print(f'Campus override: modele_en={override.modele_en}')
else:
print('Pas de campus override — template global utilisé')
"
Erreur lors de la génération du document (500)¶
Symptôme : L'API retourne une erreur 500 lors de la génération.
Causes possibles :
- Template manquant : le fichier
.docxn'existe pas dansmedia/modeles/ - LibreOffice crash : la conversion DOCX → PDF échoue
- Attribut manquant : le template contient un placeholder
{{attribut}}que le code ne connaît pas
Solution :
# Vérifier que le template existe
docker compose exec web ls -la /epidocs/media/modeles/
# Vérifier les logs de génération
docker compose logs web --tail 100 | grep -i "erreur\|error\|generation"
# Vérifier que LibreOffice fonctionne
docker compose exec web libreoffice --version
Impossible de trouver la valeur de l'attribut xxx¶
Symptôme : Erreur lors de la génération, un attribut du template Word n'est pas reconnu.
Cause : Le fichier .docx contient un placeholder {{xxx}} qui n'est pas défini dans prepare_attributes() ni dans les champs du modèle Student.
Solution :
- Ouvrir le fichier
.docxet vérifier les placeholders - Vérifier que l'attribut existe dans
apps/document_type/utils.py→prepare_attributes() - Si c'est un champ étudiant, vérifier qu'il existe dans le modèle
Student
'User' object has no attribute 'section'¶
Symptôme : Un admin appelle /documents/available-document-types sans query param.
Cause : L'admin (modèle User) n'a pas d'attribut section, contrairement aux étudiants.
Solution : L'admin doit passer ?studentEmail=xxx ou ?classe=PGE1 en paramètre.
Erreurs de base de données¶
OperationalError: could not connect to server¶
Symptôme : L'API ne démarre pas, erreur de connexion PostgreSQL.
Cause : Le conteneur db n'est pas prêt ou POSTGRES_HOST est mal configuré.
Solution :
# Vérifier que le conteneur db tourne
docker compose ps
# Vérifier la connectivité
docker compose exec web python -c "
import psycopg2
conn = psycopg2.connect(host='db', dbname='epidocs_db', user='postgres', password='CHANGE_ME')
print('OK')
conn.close()
"
# Vérifier les logs du conteneur db
docker compose logs db --tail 20
relation "xxx" does not exist¶
Symptôme : Erreur au démarrage ou lors d'une requête API.
Cause : Les migrations n'ont pas été appliquées.
Solution :
Erreurs de mode maintenance¶
Les étudiants ne peuvent plus accéder après désactivation du mode maintenance¶
Symptôme : Le mode maintenance est désactivé mais les étudiants reçoivent toujours une erreur 503.
Cause : La fenêtre de maintenance planifiée (scheduled_start / scheduled_end) est toujours active.
Solution :
# Vérifier l'état du système
docker compose exec web python manage.py shell -c "
from apps.user.models import SystemStatus
s = SystemStatus.objects.first()
if s:
print(f'Maintenance: {s.is_maintenance}')
print(f'Scheduled: {s.scheduled_start} → {s.scheduled_end}')
"
Mettre à jour via l'API : PUT /admin/system-status avec is_maintenance: false et scheduled_start: null, scheduled_end: null.
Erreurs de déploiement¶
Volume PostgreSQL introuvable¶
Symptôme : docker compose up échoue avec une erreur sur le volume externe.
Cause : Le volume epidocs-api_postgres_data n'existe pas sur le VPS.
Solution :
# Créer le volume
docker volume create epidocs-api_postgres_data
# Vérifier
docker volume inspect epidocs-api_postgres_data
Attention
Ne jamais supprimer ce volume en production ! Il contient toutes les données de la base.
Port 7010 déjà utilisé¶
Symptôme : docker compose up échoue car le port est déjà occupé.
Solution :