Questions Présentation Flashcards
Pourquoi avez-vous choisi d’utiliser une architecture monorepo pour ce projet?
L’architecture monorepo nous a permis de centraliser le code frontend et backend dans un seul dépôt, facilitant ainsi la gestion des versions, le partage de types entre frontend et backend, et simplifiant le processus de déploiement. Cette approche était idéale pour notre équipe de 4 personnes travaillant simultanément sur différentes parties de l’application.
Comment avez-vous sécurisé les variables d’environnement dans votre projet?
Nous avons utilisé des fichiers .env pour stocker les variables sensibles (identifiants de base de données, clés d’API pour Cloudinary), avec des fichiers .env.sample pour partager la structure sans les valeurs. Ces fichiers .env étaient exclus du dépôt Git via .gitignore pour éviter la divulgation d’informations sensibles.
Comment avez-vous pris en compte l’accessibilité dans vos maquettes?
Nous avons suivi les standards RGAA en veillant à maintenir des contrastes suffisants entre le texte et l’arrière-plan, dimensionné les éléments cliquables avec une taille minimale de 44px, défini une hiérarchie claire des titres, et prévu des alternatives textuelles pour les éléments visuels. L’approche mobile-first nous a également aidés à créer une interface accessible sur tous les appareils.
Comment avez-vous organisé l’enchaînement des maquettes?
Nous avons réalisé un schéma d’enchaînement des interfaces qui modélise le parcours utilisateur à travers l’application. Cela nous a permis de visualiser l’expérience globale et d’identifier les points où nous devions optimiser les interactions, notamment pour le processus d’inscription, de connexion, et d’échange de points contre des lots.
Quelles techniques avez-vous utilisées pour rendre vos interfaces responsives?
J’ai adopté une approche mobile-first avec CSS Grid pour structurer les contenus. J’ai défini des points de rupture à 768px et 1024px avec des media queries pour adapter la mise en page (passage de 1 à 2 puis 3 colonnes). J’ai également utilisé des unités relatives (rem, vh, vw) plutôt que des pixels fixes pour garantir l’adaptabilité sur tous les appareils.
Comment avez-vous structuré vos composants React pour les rendre réutilisables?
J’ai créé des composants modulaires comme GameCard qui acceptent des props pour personnaliser leur contenu et comportement. Cette approche a permis de réutiliser le même composant dans différents contextes (liste des jeux publique, interface admin) tout en maintenant une cohérence visuelle et fonctionnelle.
Expliquez comment vous avez implémenté le système de recherche dynamique des jeux.
J’ai utilisé useState pour gérer la valeur de l’input et useEffect pour appliquer le filtrage en temps réel. À chaque frappe de l’utilisateur, la fonction de filtrage compare le nom du jeu avec la valeur entrée (sans distinction de casse). J’ai également ajouté des messages contextuels aléatoires pour améliorer l’expérience utilisateur en cas de recherche sans résultat.
Comment avez-vous géré l’authentification et les sessions utilisateur?
Nous avons implémenté un système d’authentification JWT avec stockage du token dans un cookie sécurisé (httpOnly, SameSite=Lax). Côté client, nous avons utilisé un contexte React (AuthContext) pour gérer l’état d’authentification et les informations utilisateur à travers toute l’application, avec des middlewares côté serveur pour vérifier les tokens et les permissions.
Pourquoi avoir choisi MySQL pour ce projet plutôt qu’une base NoSQL?
MySQL était parfaitement adapté à notre modèle de données où les relations entre entités (utilisateurs, jeux, lots) étaient clairement définies. Les besoins de l’application en termes de requêtes complexes (comme obtenir les jeux favoris d’un utilisateur, ou les lots acquis) bénéficiaient de la structure relationnelle et de la rigueur du langage SQL pour garantir l’intégrité des données.
Comment avez-vous modélisé les relations many-to-many dans votre base de données?
Pour les relations many-to-many comme celle entre utilisateurs et jeux (favoris), nous avons créé des tables de jonction (favorite, prize_acquired) qui stockent les ID des deux entités reliées. Cette approche respecte les principes de normalisation et nous permet d’effectuer des requêtes efficaces.
Comment avez-vous prévenu les risques d’injection SQL dans vos requêtes?
J’ai systématiquement utilisé des requêtes paramétrées avec le symbole “?” comme placeholder, en passant séparément les valeurs à insérer. Cette méthode assure que les entrées utilisateur sont correctement échappées par le driver MySQL et ne peuvent pas être interprétées comme du code SQL malveillant.
Expliquez comment vous avez structuré vos repositories pour les accès aux données.
J’ai adopté le pattern Repository pour encapsuler toute la logique d’accès aux données. Chaque entité (Game, Prize, User) dispose de son propre repository avec des méthodes CRUD standards et des méthodes spécifiques (findAllAvailable, toggleBan…). Cette structure nous a permis de centraliser les accès à la base de données et de réutiliser facilement les requêtes communes.
Comment avez-vous géré les opérations sensibles comme le bannissement d’utilisateurs?
J’ai implémenté des contrôleurs spécifiques pour ces actions (toggleBan, toggleAdmin) avec des vérifications d’autorisation via middleware. Les opérations sont encapsulées dans des transactions pour garantir l’intégrité des données. J’ai également ajouté des modales de confirmation côté client pour éviter les actions accidentelles.
Comment avez-vous structuré vos tests unitaires pour les composants métier?
J’ai suivi le pattern AAA (Arrange-Act-Assert) en utilisant Jest pour mes tests. Chaque test isole une fonctionnalité spécifique avec des mocks pour simuler les dépendances. Les tests couvrent les cas nominaux et les cas d’erreur, vérifiant notamment les réponses HTTP appropriées (204 pour succès sans contenu, 404 pour ressource non trouvée, etc.).
Quels ont été les défis techniques les plus importants de ce projet et comment les avez-vous surmontés?
La gestion des images avec Cloudinary a été un défi initial, notamment pour comprendre le flux d’upload et la récupération des URLs sécurisées. J’ai résolu ce problème en élaborant une fonction d’upload réutilisable et bien documentée. La mise en place d’un système d’authentification robuste a également été complexe, mais l’utilisation de JWT et la séparation claire des responsabilités dans les middlewares nous ont permis d’obtenir un résultat sécurisé.
Si vous deviez refaire ce projet, que changeriez-vous dans votre approche ou vos choix techniques?
J’ajouterais davantage de tests d’intégration pour couvrir les interactions entre les composants. J’explorerais également TypeScript plus en profondeur pour renforcer le typage, notamment au niveau des interfaces entre le front et le back. Enfin, j’implémenterais un système de cache pour optimiser les performances, particulièrement pour les données fréquemment consultées comme la liste des jeux.