Aide-mémoire — EPIDOCS API
Référence rapide pour le backend Django de EPIDOCS.
Accès rapides
Ports et conteneurs
| Service |
Port hôte |
Port conteneur |
Image |
| API (Gunicorn) |
127.0.0.1:7010 |
8000 |
ghcr.io/epitechafrik/epidocs-api:deploy |
| PostgreSQL 16 |
non exposé |
5432 |
postgres:16 |
Chemins VPS
/root/projects/mydocs/epidocs-api/
Commandes essentielles
Vérification santé
curl -o /dev/null -s -w "%{http_code}" http://127.0.0.1:7010/
# 200 = OK
Logs
cd /root/projects/mydocs/epidocs-api
# Logs applicatifs
docker compose logs -f web --tail 100
docker compose logs web --tail 500 | grep -i "error\|exception\|traceback"
# Logs Django (fichier dans conteneur)
docker compose exec web cat /epidocs/logs/file.log | tail -50
# Logs PostgreSQL
docker compose logs -f db --tail 50
Base de données
# Vérifier la connectivité PostgreSQL
docker compose exec web python manage.py shell -c \
"from django.db import connection; connection.cursor().execute('SELECT 1'); print('OK')"
# Migrations en attente
docker compose exec web python manage.py showmigrations | grep "\[ \]"
# Backup PostgreSQL
docker compose exec db pg_dump -U postgres epidocs_db > backup_$(date +%Y%m%d).sql
docker compose exec db pg_dump -U postgres -Fc epidocs_db > backup_$(date +%Y%m%d).dump
# Backup media (templates Word + documents générés)
tar czf media_backup_$(date +%Y%m%d).tar.gz media/
Diagnostics utiles
# Étudiants par classe
docker compose exec web python manage.py shell -c "
from apps.student.models import Student
from django.db.models import Count
stats = Student.objects.filter(account_suspended=0).values('section').annotate(count=Count('login')).order_by('section')
for s in stats: print(f\"{s['section']}: {s['count']} étudiants\")"
# Sessions actives
docker compose exec web python manage.py shell -c "
from apps.user.models import UserSession
from django.utils import timezone
active = UserSession.objects.filter(is_valid=True, expires_at__gt=timezone.now())
print(f'{active.count()} sessions actives')"
# Mode maintenance
docker compose exec web python manage.py shell -c "
from apps.user.models import SystemStatus
s = SystemStatus.objects.first()
print(f'Maintenance: {s.is_maintenance}' if s else 'Pas de SystemStatus')"
# Templates documents
docker compose exec web ls -la /epidocs/media/modeles/
# Espace disque media
du -sh /root/projects/mydocs/epidocs-api/media/
Rollback
cd /root/projects/mydocs/epidocs-api
# Lister les images disponibles
docker images ghcr.io/epitechafrik/epidocs-api --format "table {{.Tag}}\t{{.CreatedAt}}"
# Modifier le tag dans docker-compose.yml puis :
docker compose pull web
docker compose up -d --no-deps web
Pipelines CI/CD
gh run list --repo EpitechAfrik/epidocs-api
gh run view RUN_ID --repo EpitechAfrik/epidocs-api --log-failed
Stack résumée
| Composant |
Technologie |
| Framework |
Django 5 + Django REST Framework |
| BDD |
PostgreSQL 16 |
| Auth |
JWT cookie HttpOnly + Azure AD (MSAL) |
| PDF |
docxtpl + LibreOffice |
| QR Codes |
qrcode + Pillow |
| WSGI |
Gunicorn (3 workers, timeout 120s) |
| Stockage |
Local media/ ou Cloudinary |
Volumes Docker
| Volume |
Usage |
epidocs-api_postgres_data (externe) |
Données PostgreSQL |
./media (bind mount) |
Templates Word + documents |
static_data |
Fichiers statiques Django |
Variables d'environnement clés
Ne jamais commiter les secrets
Les .env sont sur le VPS uniquement.
| Variable |
Description |
SECRET_KEY |
Secret Django |
POSTGRES_PASSWORD |
Mot de passe PostgreSQL |
JWT_SECRET_KEY |
Secret JWT |
JWT_COOKIE_DOMAIN |
.epitools.bj |
AZURE_CLIENT_ID / AZURE_CLIENT_SECRET / AZURE_TENANT_ID |
Azure AD SSO |
RESEND_API_KEY |
Token API Resend (emails) |
ALLOWED_HOSTS |
api.mydocs.epitools.bj,localhost |
Routes API principales
| Route |
Description |
/auth/sign_in |
Connexion |
/auth/callback |
Callback Azure AD |
/auth/me |
Utilisateur courant |
/student/auth/me |
Étudiant courant |
/documents/generate-document |
Génération PDF |
/documents/admin/batch-generate |
Génération PDF en lot |
/student/upload-csv/ |
Import étudiants CSV |
/admin/system-status |
Mode maintenance |
/admin/audit-logs |
Journal d'audit |
/integrations/v1/docs |
Doc live de l'API Zeno (ReDoc) |
/integrations/v1/documents/generate |
Génération de doc par un service (clé API) |
Intégration Zeno (clés API)
API service-à-service authentifiée par header Authorization: Api-Key <clé>. Doc live : /integrations/v1/docs.
# Créer un compte de service + clé (la clé s'affiche UNE seule fois)
docker compose exec web python manage.py create_service_account zeno --description "Backend Zeno"
# Lister les comptes de service et l'état de leurs clés
docker compose exec db psql -U postgres -d epidocs_db -c \
"SELECT s.name, k.prefix, k.is_active, k.last_used_at, k.revoked_at
FROM integrations_serviceaccount s
JOIN integrations_serviceapikey k ON k.service_id = s.id ORDER BY s.name;"
# Audit des actions d'un service (génération + téléchargement)
docker compose exec db psql -U postgres -d epidocs_db -c \
"SELECT action, actor_email, target_id, ip_address, timestamp
FROM user_auditlog WHERE actor_role='service' ORDER BY timestamp DESC LIMIT 20;"
# Tester une clé (attendu: 400 = auth OK, 401 = clé invalide)
curl -s -o /dev/null -w "%{http_code}\n" -X POST \
http://127.0.0.1:7010/integrations/v1/documents/generate \
-H "Authorization: Api-Key LA_CLE" -H "Content-Type: application/json" -d '{}'
Révocation / rotation d'une clé : depuis le dashboard (super-admin) ou via POST /integrations/v1/admin/keys/:id/revoke (ou /rotate).