Module de Communication : Annonces Étudiants

Retour à l'organigramme
SQLite / backend/server.js

Structure de la table "Annonces"

  • Ciblage : Le champ classe_cible permet de définir si l'annonce est destinée à une classe spécifique (ex: MMI-A1) ou à tout le monde ("Toutes").
  • Liaisons (Foreign Keys) : L'annonce est liée à l'enseignant qui l'a créée (auteur_id) et potentiellement à une Situation d'Apprentissage (sae_id).
  • Suppression en cascade : Si une SAE ou un enseignant est supprimé de la base, l'option ON DELETE CASCADE nettoiera automatiquement les annonces obsolètes.
/* Initialisation SQLite (server.js) */
CREATE TABLE IF NOT EXISTS Annonces (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    auteur_id INTEGER NOT NULL,
    message TEXT NOT NULL,
    classe_cible TEXT NOT NULL,
    sae_id INTEGER,
    date_creation TEXT NOT NULL,
    
    /* Relations fortes */
    FOREIGN KEY (auteur_id) REFERENCES Comptes(id) ON DELETE CASCADE,
    FOREIGN KEY (sae_id) REFERENCES SAE(id) ON DELETE CASCADE
);
Node.js / backend/server.js

Récupération et Filtrage (Route GET)

  • Isolation des données : Le serveur ne renvoie jamais toutes les annonces à un étudiant. Il vérifie d'abord sa classe dans la base de données via son token JWT.
  • Logique de condition (WHERE) : La requête SQL ne sélectionne que les annonces dont la classe_cible correspond à celle de l'étudiant, ou celles marquées "Toutes".
  • Enrichissement (JOIN) : La requête récupère simultanément le nom de l'auteur et le nom de la SAE associée via des jointures. Le LEFT JOIN sur la SAE empêche la requête d'échouer si l'annonce n'a pas de SAE liée.
app.get('/api/annonces', verifierToken, async (req, res) => {
    try {
        // ... (Logique admin / enseignant)
        
        // Logique Étudiant : Récupération de sa classe
        const userDb = await db.get('SELECT classe FROM Comptes WHERE id = ?', [req.user.id]);
        
        // Requête complexe avec jointures et filtre de classe
        const rows = await db.all(`
            SELECT Annonces.*, Comptes.nom, Comptes.prenom, SAE.nom AS sae_nom 
            FROM Annonces 
            JOIN Comptes ON Annonces.auteur_id = Comptes.id 
            LEFT JOIN SAE ON Annonces.sae_id = SAE.id 
            WHERE Annonces.classe_cible = ? OR Annonces.classe_cible = 'Toutes' 
            ORDER BY Annonces.id DESC
        `, [userDb.classe]);
        
        return res.json(rows);
        
    } catch (error) { /* ... */ }
});
React / frontend/src/App.jsx

Intégration au Tableau de bord

  • Rendu Conditionnel : Le bloc d'annonces n'apparaît sur le tableau de bord que si le tableau annonces contient des éléments (annonces.length > 0).
  • Bouton d'accès rapide : Si l'enseignant a lié l'annonce à une SAE (ann.sae_id est défini), un bouton "Voir SAE" est généré dynamiquement.
  • Navigation fluide : Un clic sur ce bouton déclenche la fonction openSaeDetails() qui bascule l'interface directement sur la SAE sans recharger la page.
{/* Extrait de App.jsx - Affichage Conditionnel */}
{token && role !== 'admin' && vueActuelle === 'dashboard' && annonces.length > 0 && (
  

Annonces récentes

{annonces.map(ann => (
{ann.prenom} {ann.nom} {ann.classe_cible} {formatDateTime(ann.date_creation)}

{ann.message}

{/* Bouton conditionnel si une SAE est liée */} {ann.sae_id && ( )}
))}
)}