# Brainstorming Session - Portfolio Gamifié **Date** : 26 janvier 2026 **Facilitatrice** : Mary (Business Analyst) **Techniques utilisées** : Role Playing, SCAMPER, What If Scenarios, Yes And Building **Stack technique** : PHP 8+ / MariaDB / TailwindCSS / Swup.js / Konva.js / vis.js **Langues** : Français (défaut) + Anglais --- ## Executive Summary | Élément | Détail | |---------|--------| | **Sujet** | Amélioration portfolio - Fonctionnalités techniques et visuelles | | **Objectif** | Exploration large | | **Idées initiales** | Carousel témoignages, Compétences cliquables → projets | | **Total idées générées** | 40+ | ### Concept Central Retenu > **Portfolio = Aventure narrative immersive** avec quête principale "Trouver le développeur", chemins multiples à choix, progression gamifiée, et expérience unique par visiteur. --- ## Insights - Role Playing (3 Perspectives) ### Perspective Recruteur Pressé | Besoin | Insight | |--------|---------| | Se démarquer | Design non-conventionnel, éléments surprenants | | Infos rapides | Compétences visibles immédiatement | | Preuves concrètes | Lien direct compétences → projets | | Teasing efficace | Previews projets sans tout révéler | ### Perspective Client Potentiel | Besoin | Insight | |--------|---------| | Confiance technique | Détails techniques par projet | | Process de travail | Section "Comment je travaille" | | Confiance humaine | Ton authentique, touche personnelle | | Personnalité | À propos qui va au-delà du CV | ### Perspective Développeur Pair | Besoin | Insight | |--------|---------| | Impressionner | Animations/interactions avancées | | Valeur ajoutée | Opinions sur les technos, contenu régulier | | Mémorable | Élément signature unique et challengeant | | Dialogue | Interaction qui donne envie de discuter | --- ## SCAMPER - Idées Générées ### S - Substitute (Substituer) | Élément actuel | Substitution | |----------------|--------------| | Textes classiques | Narrateur (toi) qui guide la visite comme une aventure | | Images statiques | Animations SVG + entrées animées pour les projets | | Navigation standard | Navigation gamifiée : carte interactive accessible via icône | | Formulaire contact | "Objectif final" avec célébration à la complétion | | Contenu bonus | Easter eggs cachés avec récompense globale | ### C - Combine (Combiner) | Combinaison | Résultat | |-------------|----------| | À propos + Timeline | Section "Mon parcours" narrative | | Gamification + Navigation | Système de progression global sur tout le site | | Compétences + Projets | Compétences cliquables → projets liés | ### A - Adapt (Adapter) | Inspiration | Adaptation portfolio | |-------------|---------------------| | Zelda BOTW - Quêtes | Objectifs de découverte à accomplir | | Zelda BOTW - Dialogues PNJ | Témoignages sous forme de dialogues interactifs | | Portfolios fluides | Transitions de page animées seamless | ### M - Modify/Magnify (Amplifier) | Élément | Amplification | |---------|---------------| | Compétences | Arbre de compétences RPG évoluant avec chaque projet | | Progression skill | Avant/après projet = niveau qui monte + description | | Transitions | Animation "changement de zone" immersive (élément signature) | | Storytelling | Intrigue parallèle au métier de développeur | | Micro-interactions | Éléments cliquables cachés + easter eggs | ### P - Put to other uses (Autres usages) | Usage | Implémentation | |-------|----------------| | Ressource code | Section snippets/templates réutilisables | | Networking | Multi-points de contact facilités | ### E - Eliminate (Éliminer) | À éliminer | Alternative | |------------|-------------| | Navigation classique (menu burger) | Carte interactive + narrateur guide | | Informations redondantes | Chaque info à un seul endroit stratégique | | Footer classique | Intégrer les liens dans l'expérience | ### R - Reverse/Rearrange (Inverser) | Inversion | Effet | |-----------|-------| | Héros mystérieux au départ | Intrigue dès l'arrivée | | Révélation progressive | Chaque section dévoile une facette | | Pas de page "À propos" classique | L'histoire se construit au fil de l'exploration | --- ## What If Scenarios - Concepts Avancés ### Quête Principale | Concept | Implémentation | |---------|----------------| | Quête principale | "Trouver le développeur" = fil rouge | | Climax narratif | Le visiteur te "trouve" enfin | | Récompense | Dialogue avec toi = formulaire de contact | ### Double Entrée (Visiteurs Pressés) | Chemin | Expérience | |--------|------------| | **Aventurier** | "Partir à l'aventure" → Expérience complète | | **Pressé** | "Je cherche..." + éléments loufoques → Roadmap complétée | ### Expérience Unique & Viralité | Concept | Implémentation | |---------|----------------| | Parcours multiples | 2-3 choix binaires = 4-8 parcours différents | | Même destination | Toutes les fins → Contact développeur | | Rejouabilité | Chemins différents pour chaque visiteur | --- ## Yes And Building - Affinements ### Système de Challenges | Type | Description | |------|-------------| | Challenge obligatoire | 1 puzzle facile pour accéder au contact | | Easter eggs | Challenges cachés plus complexes | | Récompenses | Snippets de code, anecdotes cachées | | Aide | Système d'indices → réponse si bloqué | ### Dialogues PNJ (Témoignages) | Élément | Implémentation | |---------|----------------| | Format | Avatar + bulle de dialogue style Zelda | | Interaction | Clic pour "parler" → typewriter effect | | Personnalités | Mentor sage, collègue sarcastique, client enthousiaste | | Variété | 3-4 textes aléatoires par PNJ, même sens | ### Sauvegarde & Réengagement | Fonctionnalité | Implémentation | |----------------|----------------| | Sauvegarde locale | LocalStorage JS (transparent) | | Sauvegarde cloud | Email optionnel (multi-device) | | Rappel narratif | Email après X jours : "Ta quête t'attend..." | --- ## Architecture Narrative Proposée ``` ┌─────────────────────────────────────────────────────────────┐ │ ARRIVÉE SUR LE SITE │ └─────────────────────────────────────────────────────────────┘ │ ┌───────────────┴───────────────┐ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ "Partir à │ │ "Je n'ai pas │ │ l'aventure" │ │ le temps..." │ └─────────────────┘ └─────────────────┘ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Intro narrative │ │ Roadmap │ │ Héros mystérieux│ │ "Partie sauvée" │ └─────────────────┘ └─────────────────┘ │ │ ▼ │ ┌─────────────────┐ │ │ CHOIX 1 │ │ │ Chemin A ou B │ │ └─────────────────┘ │ │ │ │ ▼ ▼ │ ┌───────┐ ┌───────┐ │ │Projets│ │Skills │ │ │ │ │Tree │ │ └───────┘ └───────┘ │ │ │ │ └───┬───┘ │ ▼ │ ┌─────────────────┐ │ │ Parcours/ │ │ │ Timeline │◄──────────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ │ Témoignages │ │ (Dialogues PNJ) │ └─────────────────┘ │ ▼ ┌─────────────────┐ │ CHALLENGE │ │ (Puzzle facile) │ └─────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ "TU M'AS TROUVÉ !" │ │ Dialogue avec le dev = Contact │ │ + Célébration finale │ └─────────────────────────────────────────────────────────┘ ``` --- ## Catégorisation des Idées ### Opportunités Immédiates (Quick Wins) *Implémentables rapidement avec impact fort* | # | Idée | Effort | |---|------|--------| | 1 | Compétences cliquables → projets | Faible | | 2 | Carousel témoignages style dialogue | Faible | | 3 | Transitions de page animées | Moyen | | 4 | Fusion À propos + Timeline | Faible | | 5 | Multi-points de contact | Faible | ### Innovations Futures (Phase 2) *Demandent plus de développement mais réalisables* | # | Idée | Effort | |---|------|--------| | 1 | Narrateur-guide avec textes d'accompagnement | Moyen | | 2 | Double entrée (Aventure vs Mode pressé) | Moyen | | 3 | Carte interactive comme navigation | Élevé | | 4 | Arbre de compétences visuel | Élevé | | 5 | Barre de progression exploration | Moyen | | 6 | Sauvegarde LocalStorage | Faible | ### Moonshots (Phase 3) *Ambitieux, différenciants* | # | Idée | Effort | |---|------|--------| | 1 | Chemins multiples à choix (4-8 parcours) | Élevé | | 2 | Quête principale "Trouver le dev" | Élevé | | 3 | Challenge/puzzle obligatoire | Moyen | | 4 | Easter eggs avec récompenses | Moyen | | 5 | Système de rappel email narratif | Moyen | | 6 | Textes PNJ aléatoires + personnalités | Moyen | --- ## Plan d'Action Recommandé ### Phase 1 : Fondations | # | Action | Priorité | |---|--------|----------| | 1 | Implémenter transitions de page seamless | Haute | | 2 | Créer composant compétences cliquables → projets | Haute | | 3 | Refondre carousel témoignages en style dialogue | Haute | | 4 | Fusionner À propos et Timeline | Haute | | 5 | Concevoir la carte interactive (maquette) | Moyenne | ### Phase 2 : Gamification Light | # | Action | Priorité | |---|--------|----------| | 1 | Ajouter narrateur-guide | Haute | | 2 | Créer double entrée (Aventure / Pressé) | Haute | | 3 | Implémenter barre de progression | Moyenne | | 4 | Système de sauvegarde LocalStorage | Moyenne | | 5 | Arbre de compétences visuel | Moyenne | ### Phase 3 : Expérience Complète | # | Action | Priorité | |---|--------|----------| | 1 | Système de choix narratifs | Haute | | 2 | Challenge/puzzle principal | Moyenne | | 3 | Easter eggs et récompenses | Basse | | 4 | Personnalités PNJ + textes aléatoires | Basse | | 5 | Système de rappel email | Basse | --- ## Stack Technique Validée ### Architecture Globale ``` ┌─────────────────────────────────────────────────────────────┐ │ BACKEND │ ├─────────────────────────────────────────────────────────────┤ │ PHP 8+ Routing, templates, logique │ │ MariaDB Données, i18n, progression │ │ PDO Connexion sécurisée BDD │ │ Custom i18n Helper __('key') + cache │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ FRONTEND │ ├─────────────────────────────────────────────────────────────┤ │ TailwindCSS Styling + animations CSS │ │ Swup.js ~5kb Transitions pages seamless │ │ Konva.js ~150kb Carte interactive / minimap │ │ vis.js Network ~150kb Skill tree interactif │ │ GSAP ~60kb Animations avancées (optionnel) │ │ JS Vanilla Logique, localStorage, events │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ INTERNATIONALISATION │ ├─────────────────────────────────────────────────────────────┤ │ Langues FR (défaut) + EN │ │ Stockage Table MariaDB `translations` │ │ Détection URL (/en/...) ou cookie/session │ │ Fallback FR si clé manquante en EN │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ ASSETS │ ├─────────────────────────────────────────────────────────────┤ │ Images WebP optimisées │ │ Icônes SVG inline ou sprite │ │ Fonts Variable fonts (perf) │ └─────────────────────────────────────────────────────────────┘ ``` ### Librairies JS - Détail | Librairie | Version | Poids (gzip) | Usage | |-----------|---------|--------------|-------| | [Swup.js](https://swup.js.org/) | 4.x | ~2kb | Transitions de page seamless | | [Konva.js](https://konvajs.org/) | 9.x | ~50kb | Carte interactive, minimap | | [vis.js Network](https://visjs.github.io/vis-network/) | 9.x | ~50kb | Skill tree interactif | | [GSAP](https://greensock.com/gsap/) | 3.x | ~25kb | Animations complexes (optionnel) | | **Total estimé** | | **~100-125kb** | | ### Routing i18n | URL | Langue | Page | |-----|--------|------| | `/` | FR (défaut) | Accueil | | `/en` | EN | Accueil | | `/projets` | FR | Projets | | `/en/projects` | EN | Projets | | `/competences` | FR | Skills | | `/en/skills` | EN | Skills | | `/a-propos` | FR | À propos | | `/en/about` | EN | About | | `/contact` | FR | Contact | | `/en/contact` | EN | Contact | --- ## Schéma Base de Données MariaDB ### Diagramme Relationnel ``` ┌──────────────────┐ ┌──────────────────┐ │ projects │ │ skills │ ├──────────────────┤ ├──────────────────┤ │ id │ │ id │ │ slug │ │ slug │ │ title_key (i18n) │ │ name_key (i18n) │ │ description_key │ │ icon │ │ image │ │ max_level │ │ url │ │ category │ │ github_url │ └────────┬─────────┘ │ date_completed │ │ │ is_featured │ │ └────────┬─────────┘ │ │ │ │ ┌───────────────────┴───────────────────┐ │ │ skill_project │ │ ├───────────────────────────────────────┤ └────┤ skill_id │ │ project_id │ │ level_before │ │ level_after │ └───────────────────────────────────────┘ ┌──────────────────┐ ┌──────────────────┐ │ testimonials │ │ narrator_texts │ ├──────────────────┤ ├──────────────────┤ │ id │ │ id │ │ name │ │ context │ │ role │ │ text_key (i18n) │ │ company │ │ variant │ │ avatar │ └──────────────────┘ │ text_key (i18n) │ │ personality │ ┌──────────────────┐ │ project_id (FK) │ │ easter_eggs │ └──────────────────┘ ├──────────────────┤ │ id │ ┌──────────────────┐ │ location │ │ translations │ │ trigger_type │ ├──────────────────┤ │ reward_type │ │ id │ │ reward_key (i18n)│ │ lang (fr/en) │ └──────────────────┘ │ key_name │ │ value │ ┌──────────────────┐ └──────────────────┘ │ user_progress │ ├──────────────────┤ │ id │ │ session_id │ │ email (nullable) │ │ progress_json │ │ last_visited │ └──────────────────┘ ``` ### Tables Détaillées #### Table `translations` (i18n) ```sql CREATE TABLE translations ( id INT AUTO_INCREMENT PRIMARY KEY, lang VARCHAR(5) NOT NULL, -- 'fr', 'en' key_name VARCHAR(255) NOT NULL, -- 'hero.title', 'nav.projects' value TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY unique_translation (lang, key_name), INDEX idx_lang (lang) ); ``` #### Table `projects` ```sql CREATE TABLE projects ( id INT AUTO_INCREMENT PRIMARY KEY, slug VARCHAR(100) NOT NULL UNIQUE, title_key VARCHAR(255) NOT NULL, -- Clé i18n description_key VARCHAR(255) NOT NULL, -- Clé i18n short_description_key VARCHAR(255), -- Clé i18n (teaser) image VARCHAR(255), url VARCHAR(255), github_url VARCHAR(255), date_completed DATE, is_featured BOOLEAN DEFAULT FALSE, display_order INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` #### Table `skills` ```sql CREATE TABLE skills ( id INT AUTO_INCREMENT PRIMARY KEY, slug VARCHAR(100) NOT NULL UNIQUE, name_key VARCHAR(255) NOT NULL, -- Clé i18n description_key VARCHAR(255), -- Clé i18n icon VARCHAR(100), -- Nom icône ou chemin SVG category ENUM('frontend', 'backend', 'tools', 'soft') NOT NULL, max_level INT DEFAULT 5, display_order INT DEFAULT 0 ); ``` #### Table `skill_project` (liaison + progression) ```sql CREATE TABLE skill_project ( id INT AUTO_INCREMENT PRIMARY KEY, skill_id INT NOT NULL, project_id INT NOT NULL, level_before INT DEFAULT 0, level_after INT NOT NULL, level_description_key VARCHAR(255), -- Clé i18n FOREIGN KEY (skill_id) REFERENCES skills(id) ON DELETE CASCADE, FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE, UNIQUE KEY unique_skill_project (skill_id, project_id) ); ``` #### Table `testimonials` ```sql CREATE TABLE testimonials ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, role VARCHAR(100), company VARCHAR(100), avatar VARCHAR(255), text_key VARCHAR(255) NOT NULL, -- Clé i18n personality ENUM('sage', 'sarcastique', 'enthousiaste', 'professionnel') DEFAULT 'professionnel', project_id INT, display_order INT DEFAULT 0, is_active BOOLEAN DEFAULT TRUE, FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE SET NULL ); ``` #### Table `narrator_texts` ```sql CREATE TABLE narrator_texts ( id INT AUTO_INCREMENT PRIMARY KEY, context VARCHAR(100) NOT NULL, -- 'intro', 'transition_projects', 'hint' text_key VARCHAR(255) NOT NULL, -- Clé i18n variant INT DEFAULT 1, -- Pour textes aléatoires INDEX idx_context (context) ); ``` #### Table `easter_eggs` ```sql CREATE TABLE easter_eggs ( id INT AUTO_INCREMENT PRIMARY KEY, slug VARCHAR(100) NOT NULL UNIQUE, location VARCHAR(100) NOT NULL, -- 'header-logo', 'footer-secret' trigger_type ENUM('click', 'hover', 'konami', 'scroll') NOT NULL, reward_type ENUM('snippet', 'anecdote', 'image', 'badge') NOT NULL, reward_key VARCHAR(255) NOT NULL, -- Clé i18n ou chemin fichier difficulty ENUM('easy', 'medium', 'hard') DEFAULT 'medium', is_active BOOLEAN DEFAULT TRUE ); ``` #### Table `user_progress` ```sql CREATE TABLE user_progress ( id INT AUTO_INCREMENT PRIMARY KEY, session_id VARCHAR(100) NOT NULL UNIQUE, email VARCHAR(255), -- Optionnel pour sauvegarde cloud progress_json JSON NOT NULL, -- État complet de la progression current_path VARCHAR(50), -- Chemin narratif choisi completion_percent INT DEFAULT 0, easter_eggs_found JSON, -- Liste des IDs trouvés last_visited TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, reminder_sent BOOLEAN DEFAULT FALSE, INDEX idx_email (email) ); ``` ### Helper PHP i18n ```php BDD $cacheFile = __DIR__ . "/../cache/translations_{$lang}.php"; if (file_exists($cacheFile) && filemtime($cacheFile) > time() - 3600) { return include $cacheFile; } // Charger depuis MariaDB $pdo = getDbConnection(); $stmt = $pdo->prepare("SELECT key_name, value FROM translations WHERE lang = ?"); $stmt->execute([$lang]); $translations = []; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $translations[$row['key_name']] = $row['value']; } // Sauvegarder en cache file_put_contents($cacheFile, '