Setup complet de l'infrastructure projet : - Frontend Nuxt 4 (SSR, TypeScript, i18n, Pinia, TailwindCSS) - Backend Laravel 12 API-only avec middleware X-API-Key et CORS - Design tokens (sky-dark, sky-accent, sky-text) et polices (Merriweather, Inter) - Documentation planning et implementation artifacts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
27 KiB
27 KiB
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 | 4.x | ~2kb | Transitions de page seamless |
| Konva.js | 9.x | ~50kb | Carte interactive, minimap |
| vis.js Network | 9.x | ~50kb | Skill tree interactif |
| 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)
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
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
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)
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
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
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
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
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
// includes/i18n.php
function __($key, $lang = null) {
global $translations_cache;
$lang = $lang ?? $_SESSION['lang'] ?? 'fr';
// Cache check
if (!isset($translations_cache[$lang])) {
// Load from DB or file cache
$translations_cache[$lang] = loadTranslations($lang);
}
return $translations_cache[$lang][$key] ?? $key;
}
function loadTranslations($lang) {
// Priorité : cache fichier > 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, '<?php return ' . var_export($translations, true) . ';');
return $translations;
}
Questions Ouvertes pour la Suite
- Design carte interactive : Quel style visuel ? (minimaliste, illustré, isométrique...)
- Contenu narrateur : Quel ton exact ? Tutoiement confirmé ?
- Challenge principal : Quel type de puzzle ? (code, logique, exploration...)
- Easter eggs : Combien ? Quelles récompenses concrètes ?
- Métriques : Comment mesurer le succès de la gamification ?
Prochaines Étapes Recommandées
| # | Action | Agent suggéré | Priorité |
|---|---|---|---|
| 1 | Créer le schéma BDD MariaDB | Dev | Haute |
| 2 | Configurer i18n (helper + table translations) | Dev | Haute |
| 3 | Intégrer Swup.js pour transitions seamless | Dev | Haute |
| 4 | Maquettes/Wireframes de l'expérience | UX Expert | Haute |
| 5 | Prototype carte interactive avec Konva.js | Dev | Moyenne |
| 6 | Prototype skill tree avec vis.js | Dev | Moyenne |
| 7 | Rédaction des textes du narrateur (FR + EN) | Analyst/PO | Moyenne |
| 8 | Créer les stories techniques par phase | PM | Moyenne |
Réflexion Session
Ce qui a bien fonctionné
- Role Playing pour identifier les vrais besoins des visiteurs
- SCAMPER pour structurer l'exploration systématique
- What If pour pousser les concepts audacieux
- Yes And pour affiner et rester pragmatique
- Discussion stack technique pour garder le projet réalisable
Principes clés dégagés
- Immersion avant tout - Pas de navigation classique
- Respect du temps - Double entrée Aventure/Pressé
- Expérience unique - Chemins multiples, textes aléatoires
- Gamification subtile - Progression discrète, pas un jeu vidéo
- Contact = récompense narrative - Pas une corvée
- Stack évolutive - MariaDB pour faciliter les évolutions futures
- International dès le départ - FR + EN intégrés dans l'architecture
Document généré lors de la session de brainstorming du 2026-01-26 Facilitatrice : Mary (Business Analyst) - BMAD Method