⬅️ Flèches / Télécommande / Espace ➡️
Slide 0
🎓

Présentation Titre Professionnel

Bonjour à tous, je m'appelle Guns Bruno
et aujourd'hui je me présente à vous dans le cadre du titre professionnel de niveau 6
Concepteur Développeur d'Application,
aboutissement de ma formation professionnelle au sein de SEM Numérica.

Slide 1

Les 11 Compétences CDA

💼
Slide 2

FailDaily 📱

😅

Réseau social mobile pour partager vos petites galères du quotidien
de manière drôle et bienveillante

✍️ Publier
  • Texte + photo (optionnel)
  • Mode anonyme ou visible
  • Catégories variées
💬 Réagir
  • 💪 Courage
  • 😂 Rire
  • ❤️ Empathie
  • 🤝 Support
🏆 Gamification
  • Points & niveaux
  • Badges à débloquer
🛡️ Sécurité
  • Modération active
  • Accord parental (mineurs)
  • Ambiance bienveillante

PWA mobile • Angular + Ionic • Node.js • MySQL

Slide 3
Compétence 5

📋 Phase 1 : CONCEPTION

Analyser les besoins 📝

FONCTIONNALITÉS PRINCIPALES : ✓ Inscription avec email + vérification ✓ Publier un "fail" (texte + photo optionnelle) ✓ Choisir : anonyme OU visible ✓ 4 types de réactions positives (courage, rire, empathie, support) ✓ Système de points et badges ✓ Commentaires d'encouragement uniquement ✓ Modération pour protéger la communauté
Slide 4
Compétence 5

Créer les maquettes 🎨

📱 FailDaily - Inscription
Créer un compte
Déjà un compte ? Se connecter
📱 FailDaily - Connexion
Bon retour ! 👋
Mot de passe oublié ?
Pas de compte ? S'inscrire
Slide 4B
Compétence 5

Maquettes : Liste et Création de Fails 📋

📱 FailDaily
@pseudo123 Travail
Café renversé sur mon patron
J'ai renversé mon café pendant la réunion...
[Photo du café]
💪 12 😂 45 ❤️ 8 🤝 23
Anonyme Transport
Raté mon train ce matin
🏠 📋 🏆 👤
➕ Créer un Fail
📸 + Ajouter une photo
🏠 📋 🏆 👤
Slide 4C
Compétence 5

Maquettes : Badges et Profil 🏆

🏆 Mes Badges
🌟 Niveau 5
920 pts
BADGES DÉBLOQUÉS :
🔥
💪
🎯
BADGES À VENIR :
🔒
🔒
🔒
🏠 📋 🏆 👤
👤 Mon Profil
👤
@pseudo123
📊 STATISTIQUES
Fails: 23
Réactions: 456
Points: 920
Niveau: 5
MES FAILS
• Café renversé
💪12 😂45
• Raté train
💪8 😂12
🏠 📋 🏆 👤
Slide 5
Compétence 6

Architecture 3-tiers 🏗️

📱
FRONTEND
Angular + Ionic
Interface utilisateur • Navigation
Requêtes HTTP (API REST)
⚙️
BACKEND
Node.js + Express
Logique métier • Authentification
Requêtes SQL
💾
BASE DE DONNÉES
MySQL
Stockage • Persistance
Slide 6
Compétence 7

Concevoir la base de données 🗄️

-- Table qui stocke tous les fails partagés CREATE TABLE fails ( id -- Numéro unique du fail user_id -- Qui l'a posté title -- Le titre (ex: "Raté mon train") description -- L'histoire complète category -- Catégorie (travail, amour, etc.) image_url -- Photo (si l'utilisateur en a mis une) is_anonyme -- Anonyme ? (oui/non) created_at -- Date de publication ) -- Exemple de fail stocké : id: "abc123" user_id: "user456" title: "Café renversé sur mon patron" description: "J'ai renversé mon café..." category: "travail" is_anonyme: false (visible)
Slide 6B
Compétence 7

Schéma relationnel de la base de données 📊

👥 USERS
🔑 id
email
password_hash
username
birthdate
points
level
📝 FAILS
🔑 id
🔗 user_id
title
description
category
is_anonyme
status
💗 REACTIONS
🔑 id
🔗 fail_id
🔗 user_id
reaction_type
💬 COMMENTS
🔑 id
🔗 fail_id
🔗 user_id
content
⚖️ MODERATION
🔑 id
🔗 fail_id
🔗 moderator_id
status
🏆 BADGES
🔑 id
name
description
icon
points_required
⭐ USER_BADGES
🔑 id
🔗 user_id
🔗 badge_id
earned_at
👪 PARENTAL_CONSENTS
🔑 id
🔗 user_id
parent_email
status
1:* 1:* 1:* 1:* 1:* 1:*

📌 Légende : 🔑 Clé primaire  |  🔗 Clé étrangère  |  1:* Un-à-plusieurs  |  ━━━ Relation  |  - - - Relation optionnelle

Slide 7
Compétence 1

🛠️ Phase 2 : MISE EN PLACE

Installer l'environnement de travail 💻

# Outils installés : ✓ Node.js (v20) → Pour faire fonctionner le backend ✓ MySQL (v8) → Pour la base de données ✓ Visual Studio Code → Mon éditeur de code ✓ Git → Pour sauvegarder mon travail ✓ Docker → Pour emballer l'application # Vérifier les versions : node --version # v20.10.0 npm --version # 10.2.3 mysql --version # 8.0.35
Slide 8
Compétence 4

Gérer le projet avec Git 📦

# Historique de mes sauvegardes (commits) : ✅ "Ajout système d'authentification" ✅ "Création formulaire publication fail" ✅ "Ajout système de réactions" ✅ "Correction bug anonymat" ✅ "Ajout système de badges" # Exemple de sauvegarde : git add . git commit -m "✅ FIX: Cache admin" git push origin main
Slide 9
Compétence 8

💻 Phase 3 : DÉVELOPPEMENT

Développer l'accès aux données (Node.js + MySQL) 🔌

// Route pour récupérer les fails router.get('/fails', async (req, res) => { const query = ` SELECT f.id, f.title, u.username, COUNT(r.id) as reactions FROM fails f LEFT JOIN users u ON f.user_id = u.id LEFT JOIN reactions r ON f.id = r.fail_id WHERE f.status = 'approved' GROUP BY f.id LIMIT 50 `; const [fails] = await pool.execute(query); res.json({ success: true, data: fails }); }); // ✅ Résultat : { "success": true, "data": [ { "id": 42, "title": "Café renversé", "username": "pseudo123", "reactions": 88 } ] }
📱 FailDaily - Fil d'actualité
@pseudo123 Travail
Café renversé sur mon patron 😅
J'ai renversé mon café sur la chemise de mon patron...
💪 12 😂 45 ❤️ 8 🤝 23
Anonyme Transport
Raté mon train ce matin 🚂
Réveil en retard, course folle...
💪 5 😂 12
🏠 📋 🏆 👤
Slide 10
Compétence 3

Logique métier : Points ⚙️

// Donner des points pour une réaction async function givePoints(failId, reactionType) { // Règle : chaque réaction = points différents const POINTS = { 'courage': 5, 'laugh': 3, 'empathy': 2, 'support': 3 }; const pointsToAdd = POINTS[reactionType]; // Ajouter les points à l'utilisateur await pool.execute(` UPDATE users SET points = points + ? WHERE id = ? `, [pointsToAdd, userId]); // Vérifier si badge débloqué checkBadges(userId); }
🏆 Badges & Progression
Niveau 5 🌟
920 / 1200 points
🎖️ Badges débloqués
🔥
💪
🎯
🔒 Prochains badges
🏆
👑
💎
🏠 📋 🏆 👤
Slide 11A
Compétence 2

Interface utilisateur (Angular) 🎨

// Composant pour afficher un fail export class FailCardComponent { @Input() fail: Fail; // Données du fail // Fonction appelée au clic sur réaction async react(type: string) { // Appeler l'API pour ajouter la réaction await this.failService.addReaction( this.fail.id, type ); // Afficher message de confirmation this.toastCtrl.create({ message: '✅ Réaction envoyée !', duration: 2000 }).then(toast => toast.present()); } } <!-- Template HTML --> <div class="fail-card"> <h3>{{ fail.title }}</h3> <p>{{ fail.description }}</p> <div class="reactions"> <button (click)="react('courage')">💪</button> <button (click)="react('laugh')">😂</button> <button (click)="react('empathy')">❤️</button> </div> </div>
➕ Publier un Fail
+ Ajouter une photo
🏠 📋 🏆 👤
Slide 11B
Compétence 10

Modération des fails 🛡️

📊 Dashboard Admin

1,245
Utilisateurs
523
Fails publiés
12
En attente
8,431
Réactions

🔍 File de modération

Fail #142 - Travail
"J'ai oublié ma présentation..."
Fail #143 - Transport
"Raté mon bus pour l'examen..."
// Vérifier si l'utilisateur est admin function requireAdmin(req, res, next) { const [user] = await pool.execute(` SELECT role FROM users WHERE id = ? `, [req.user.id]); if (user[0].role !== 'admin') { return res.status(403).json({ error: 'Accès refusé' }); } next(); // OK, continuer } // Route pour modérer un fail router.post('/admin/moderate/:id', requireAdmin, // Vérifier admin d'abord async (req, res) => { const { id } = req.params; const { action } = req.body; // 'approved' ou 'rejected' await pool.execute(` UPDATE fails SET status = ? WHERE id = ? `, [action, id]); res.json({ success: true }); } );
Slide 12
Compétence 9

✅ Phase 4 : VALIDATION

Tests unitaires + intégration (Jest) 🧪

// TEST 1 : Bloquer enfant <13 ans test('Refuser inscription -13 ans', async () => { const enfant = { email: 'enfant@test.com', birthdate: '2015-01-01' // 10 ans }; const res = await request(app) .post('/api/auth/register') .send(enfant); expect(res.status).toBe(403); expect(res.body.error).toContain('13 ans'); }); // ✅ RÉSULTAT : PASS // TEST 2 : Système de points test('Attribution de points', async () => { const fail = await createFail(userId); await addReaction(fail.id, 'courage'); const user = await getUser(userId); expect(user.points).toBe(5); // +5 pts }); // ✅ RÉSULTAT : PASS // TEST 3 : Modération test('Rejeter un fail', async () => { const fail = await createFail(userId); await moderateFail(fail.id, 'rejected'); const result = await getFail(fail.id); expect(result.status).toBe('rejected'); }); // ✅ RÉSULTAT : PASS

📊 Résultats des tests

✅ Test 1 : Protection mineurs
Enfant -13 ans → Refusé ✓
✅ Test 2 : Points réactions
Courage → +5 points ✓
✅ Test 3 : Modération
Fail rejeté → Status updated ✓
127 / 127
Tests réussis ✅
Slide 13
Compétence 10

Documenter le projet 📚

# GUIDE D'INSTALLATION ## 1. Préparer le serveur - Installer Node.js version 18+ - Installer MySQL 8.0 ## 2. Installer les dépendances cd backend npm install ## 3. Configurer la base de données DB_HOST=localhost DB_USER=root DB_PASSWORD=votreMotDePasse DB_NAME=faildaily ## 4. Lancer l'application npm run dev ## 5. Vérifier ✓ Backend : http://localhost:3000 ✓ Base de données connectée
Slide 14
Compétence 11

Mettre en production (Docker) 🚀

# Fichier docker-compose.yml services: database: image: mysql:8.0 environment: MYSQL_DATABASE: faildaily MYSQL_PASSWORD: motdepasse123 backend: build: ./backend-api ports: - "3000:3000" frontend: build: ./frontend ports: - "80:80" # Une seule commande pour tout démarrer : docker-compose up -d
Slide 15
🎯

CONCLUSION

Ce que j'ai appris :

  • Concevoir avant de coder (besoins, architecture, BDD)
  • Organiser mon travail (Git, méthodologie)
  • Développer les 3 couches (données, logique, interface)
  • Tester pour garantir la qualité
  • Déployer en production de façon professionnelle
  • Résultat final :

    Une application complète, testée et déployée,
    utilisable par de vraies personnes !

    Merci de votre attention ! 😊