EPIDOCS — Frontend
Description
EPIDOCS est un système de gestion documentaire pour les étudiants d'EPITECH Bénin. Le frontend fournit deux interfaces distinctes : un portail étudiant (demande de documents, suivi, réclamations) et un dashboard administrateur (gestion des modèles, génération de documents, maintenance système).
Fonctionnalités principales
Portail étudiant
- Demande de documents : certificats de scolarité, lettres de recommandation, etc.
- Suivi de demande : timeline visuelle avec tracking par code unique
- Réclamations : soumission et suivi des réclamations
- Gestion de compte : sessions actives, demandes de modification d'informations
- Annonces : bandeaux d'annonces ciblés par classe
Dashboard administrateur
- Modèles de documents : upload, extraction d'attributs, activation/désactivation
- Gestion des étudiants : recherche, suspension, migration entre classes
- Génération de documents : génération individuelle (wizard 3 étapes) et en lot par classe
- Statistiques : tableau de bord avec métriques d'utilisation
- Historique : consultation de l'historique documentaire par étudiant
Fonctionnalités superadmin
- Mode maintenance : activation/désactivation avec redirection automatique des étudiants
- Maintenance planifiée : programmation avec date de début/fin
- Annonces : création et gestion de bandeaux d'information
- Analytics : métriques détaillées par période
- Logs d'audit : traçabilité des actions administratives
- Sauvegarde : export/import de la base de données
Architecture
Stack technique
| Composant |
Technologie |
Version |
| Framework |
Next.js (App Router) |
16.1.0 |
| Runtime |
Node.js |
20 (Alpine) |
| UI |
React |
19.0.0 |
| Composants |
Chakra UI |
2.8.2 |
| Styling |
Tailwind CSS |
3.4.1 |
| HTTP |
Axios |
1.7.3 |
| Formulaires |
React Hook Form |
7.62.0 |
| Data fetching |
TanStack React Query |
5.90.21 |
| Animations |
Framer Motion |
11.3.12 |
| Gestionnaire de paquets |
pnpm |
10.18.3 |
| Conteneur |
Docker (node:20-alpine) |
— |
Structure des dossiers
src/
├── app/
│ ├── admin/ # Dashboard administrateur
│ │ ├── components/ # Navbar, Sidebar
│ │ ├── admins/ # Gestion des admins
│ │ ├── analytics/ # Analytics (superadmin)
│ │ ├── announcements/ # Annonces (superadmin)
│ │ ├── audit-logs/ # Logs d'audit (superadmin)
│ │ ├── backup/ # Sauvegarde BDD (superadmin)
│ │ ├── batch-generate/ # Génération en lot
│ │ ├── dashboard/ # Statistiques
│ │ ├── documents/ # Historique documents
│ │ ├── generate-document/ # Génération unitaire
│ │ ├── info-requests/ # Demandes de modification
│ │ ├── migration/ # Migration étudiants
│ │ ├── models/ # Modèles de documents
│ │ ├── pending/ # Étudiants en attente
│ │ ├── students/ # Gestion étudiants
│ │ ├── system-status/ # Maintenance (superadmin)
│ │ └── layout.js
│ │
│ ├── student/ # Portail étudiant
│ │ ├── components/ # Navbar, Profile, Banners
│ │ ├── historiques/ # Historique documents
│ │ ├── mes-demandes/ # Demandes de modification
│ │ ├── reclamations/ # Réclamations
│ │ ├── sessions/ # Gestion sessions
│ │ └── layout.js
│ │
│ ├── auth/ # Authentification OAuth
│ ├── maintenance/ # Page maintenance
│ └── documents/tracking/ # Suivi public par code
│
├── services/ # Couche API (Axios)
│ ├── axios.js # Instance + intercepteurs
│ ├── auth/authServices.js # Auth (login, logout, sessions)
│ ├── admin/adminServices.js # Opérations admin
│ ├── admin/announcementService.js
│ ├── admin/systemStatusService.js
│ └── students/index.js # Opérations étudiant
│
├── context/ # React Context
│ ├── userContext.js # Auth + user state
│ └── sidebarContext.js # Sidebar state
│
├── middlewares/ # Helpers côté client
│ ├── protectedRoute.js # Route protégée par droits
│ └── isAuthorizedShow.js # Affichage conditionnel
│
├── components/ # Composants partagés
├── utils/ # Utilitaires (storage, dates)
├── constant/ # Constantes (couleurs)
└── proxy.js # Middleware Next.js (auth guard)
Rôles et permissions
| Droit |
Superadmin |
Admin |
Étudiant |
| Gestion modèles |
oui |
oui |
non |
| Génération unitaire |
oui |
oui |
non |
| Génération en lot |
oui |
non |
non |
| Migration étudiants |
oui |
non |
non |
| Mode maintenance |
oui |
non |
non |
| Annonces |
oui |
non |
non |
| Analytics / Audit |
oui |
non |
non |
| Sauvegarde BDD |
oui |
non |
non |
| Demande de documents |
non |
non |
oui |
| Réclamations |
non |
non |
oui |
Diagrammes
Architecture globale
graph TB
User[Utilisateur / Navigateur]
Nginx["Nginx<br/>Reverse proxy + TLS"]
Frontend["Frontend Next.js<br/>:3000"]
Backend["Backend Django<br/>API REST"]
DB["Base de données"]
Azure["Microsoft Azure AD<br/>(OAuth SSO)"]
User --> Nginx
Nginx --> Frontend
Frontend --> Backend
Backend --> DB
Frontend --> Azure
Backend --> Azure
Flux d'authentification
sequenceDiagram
participant User as Utilisateur
participant FE as Frontend Next.js
participant Azure as Microsoft OAuth
participant BE as Backend Django
participant Cookie as Cookie auth_token
User->>FE: Clic "Connexion Microsoft"
FE->>Azure: Redirect OAuth
Azure->>FE: Callback /auth/callback?code=XXX
FE->>BE: POST /auth/sign_in {code, session_state}
BE->>Azure: Validation du token
BE->>Cookie: Set auth_token (HttpOnly)
BE-->>FE: {user, role, rights}
FE->>FE: Stockage user dans localStorage
FE->>FE: Redirection selon rôle (admin/student)
Flux de génération de document
sequenceDiagram
participant Admin as Admin (Frontend)
participant API as Backend API
participant PDF as Moteur PDF
Admin->>API: GET /documents/available-document-types?studentEmail=xxx
API-->>Admin: {documents: {allowed_documents: [...]}}
Admin->>API: POST /documents/admin/generate-for-student<br/>{studentEmail, docId}
API->>PDF: Génération du PDF
PDF-->>API: Blob PDF
API-->>Admin: Content-Type: application/pdf
Admin->>Admin: Téléchargement automatique
Flux de génération en lot
sequenceDiagram
participant Admin as Superadmin
participant API as Backend API
participant PDF as Moteur PDF
Admin->>API: POST /documents/admin/batch-generate<br/>{classe: "PGE1", doc_id: "certificat_scolarite"}
API->>PDF: Génération N PDFs
PDF-->>API: ZIP contenant tous les PDFs
API-->>Admin: Content-Type: application/zip<br/>X-Batch-Total: 45<br/>X-Batch-Generated: 43<br/>X-Batch-Errors: 2
Admin->>Admin: Téléchargement ZIP + résumé
Docker
Dockerfile
Image multi-stage basée sur node:20-alpine avec pnpm. Les variables NEXT_PUBLIC_* sont injectées au build via ARG.
- Stage builder : installation des dépendances + build Next.js
- Stage runner : copie du build optimisé, exécution en production
docker-compose.prod.yml
services:
frontend:
image: ghcr.io/epitechafrik/epidocs-frontend:latest
container_name: epidocs_frontend_container
restart: unless-stopped
ports:
- "127.0.0.1:7012:3000"
env_file:
- .env
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
- NEXT_PUBLIC_WEB_URL=${NEXT_PUBLIC_WEB_URL}
networks:
- epidocs-network
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
epidocs-network:
driver: bridge
Points importants :
- Le port est bindé sur
127.0.0.1 uniquement (accessible via Nginx seulement)
- Le healthcheck utilise
wget (pas de curl sur Alpine par défaut)
- Logging limité à 30 Mo (3 fichiers de 10 Mo)
- Réseau bridge dédié
epidocs-network
Routes de l'application
Routes publiques (sans authentification)
| Route |
Description |
/auth |
Page de connexion Microsoft OAuth |
/auth/callback |
Callback OAuth |
/noaccount |
Page "aucun compte" |
/register |
Inscription étudiant en attente |
/desactivated |
Compte désactivé |
/documents/tracking/:id |
Suivi public d'un document |
/maintenance |
Page de maintenance |
/unauthorized |
Accès non autorisé |
Routes admin (role: admin ou superadmin)
| Route |
Description |
/admin |
Dashboard principal |
/admin/models |
Gestion des modèles de documents |
/admin/students |
Gestion des étudiants |
/admin/pending |
Validation des inscriptions |
/admin/migration |
Migration de classe |
/admin/info-requests |
Demandes de modification |
/admin/dashboard |
Statistiques |
/admin/documents |
Historique documentaire |
/admin/admins |
Gestion des admins |
/admin/generate-document |
Génération unitaire |
/admin/batch-generate |
Génération en lot (superadmin) |
/admin/system-status |
Mode maintenance (superadmin) |
/admin/announcements |
Annonces (superadmin) |
/admin/analytics |
Analytics (superadmin) |
/admin/audit-logs |
Logs d'audit (superadmin) |
/admin/backup |
Sauvegarde BDD (superadmin) |
Routes étudiant (role: student)
| Route |
Description |
/student |
Page principale + profil |
/student/historiques |
Historique des demandes |
/student/mes-demandes |
Demandes de modification |
/student/reclamations |
Réclamations |
/student/sessions |
Sessions actives |
Intercepteurs Axios
L'instance Axios (src/services/axios.js) gère automatiquement :
- Requêtes :
Content-Type: application/json par défaut, withCredentials: true
- Erreur 401 : redirection vers
/auth (sauf si déjà sur la page auth)
- Erreur 503 : mode maintenance — redirige les étudiants vers
/maintenance, les admins/superadmins ne sont pas redirigés
Variables d'environnement
| Variable |
Description |
Exemple |
NEXT_PUBLIC_WEB_URL |
URL publique du frontend |
https://mydocs.epitools.bj |
NEXT_PUBLIC_API_URL |
URL publique du backend API |
https://api-mydocs.epitools.bj |
NODE_ENV |
Mode d'exécution |
production |
Variables NEXT_PUBLIC_*
Les variables préfixées par NEXT_PUBLIC_ sont exposées au navigateur. Ne jamais y mettre de secrets. Ces variables sont injectées au build time (pas au runtime), donc un changement nécessite un rebuild de l'image Docker.
Pipeline CI/CD
Déclencheurs
- Push sur
main ou develop
- Pull request vers
main
- Dispatch manuel
Jobs
graph LR
CI["CI<br/>Lint + Build"] --> Docker["Build Docker<br/>Push GHCR"]
Docker --> Deploy["Déploiement<br/>SCP + SSH"]
Deploy --> Health["Health Check"]
- CI : checkout → setup pnpm → install → lint → build → upload artifact
- Build Docker : build image multi-stage → push
ghcr.io/epitechafrik/epidocs-frontend:latest
- Deploy : SCP du
docker-compose.prod.yml + .env → SSH pour pull et restart conteneur
- Health check : vérification que le conteneur répond sur le port 3000
Secrets GitHub nécessaires
| Secret |
Description |
NEXT_PUBLIC_API_URL |
URL du backend |
NEXT_PUBLIC_WEB_URL |
URL du frontend |
SSH_PRIVATE_KEY |
Clé SSH pour accès au VPS |
VPS_IP |
Adresse IP du VPS |
VPS_USER |
Utilisateur SSH (root) |
ENV_FILE |
Contenu complet du fichier .env |
GITHUB_TOKEN |
Token GHCR (auto-fourni) |
Rollback
Procédure
# 1. Lister les images disponibles
docker images ghcr.io/epitechafrik/epidocs-frontend --format "table {{.Tag}}\t{{.CreatedAt}}"
# 2. Modifier le tag dans docker-compose.prod.yml
# image: ghcr.io/epitechafrik/epidocs-frontend:sha-XXXXXXX
# 3. Redéployer
cd /root/projects/epidocs/epidocs-frontend
docker compose -f docker-compose.prod.yml down
docker compose -f docker-compose.prod.yml up -d
# 4. Vérifier
docker ps | grep epidocs_frontend
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:7012
Après le rollback
- Investiguer la cause sur
main
- Pousser un correctif
- Le pipeline redéploiera automatiquement