Aller au contenu

EPIDOCS API — Erreurs courantes

Erreurs d'authentification

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_DOMAIN est 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 :

  1. Vérifier la variable CALLBACK_URL dans le .env
  2. Vérifier que cette URL est enregistrée dans Azure Portal → App Registrations → Redirect URIs
  3. 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 :

  1. Le document a été généré avant l'upload du template EN (voir cas ci-dessus)
  2. Le campus de l'étudiant a un CampusDocumentType sans modele_en
  3. 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 :

  1. Template manquant : le fichier .docx n'existe pas dans media/modeles/
  2. LibreOffice crash : la conversion DOCX → PDF échoue
  3. 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 :

  1. Ouvrir le fichier .docx et vérifier les placeholders
  2. Vérifier que l'attribut existe dans apps/document_type/utils.pyprepare_attributes()
  3. 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 :

docker compose exec web python manage.py migrate

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 :

# Trouver le processus qui utilise le port
lsof -i :7010

# Arrêter l'ancien conteneur
docker stop epidocs_api && docker rm epidocs_api