36 KiB
🗺️ Roadmap Application Legacy BricoLoc
Objectif : Créer une réplique simplifiée mais fidèle de l'architecture monolithique existante de BricoLoc (2013-2025) pour démontrer les problématiques techniques et architecturales.
Durée : 2 semaines (Semaines 3-4 du projet global)
Effort : 40 heures
Stack technique : Node.js, Express.js, EJS, SQLite, Sessions
<EFBFBD> État d'Avancement
Dernière mise à jour : 28 Octobre 2025
| Phase | Statut | Progression | Temps estimé |
|---|---|---|---|
| Jour 1 - Setup Initial | ✅ Complété | 100% | 4h |
| Jour 2 - Authentification | ✅ Complété | 100% | 4h |
| Jour 3 - Catalogue | ✅ Complété | 100% | 4h |
| Jour 4 - Réservations | 🔲 Non commencé | 0% | 4h |
| Jour 5 - Administration | 🔲 Non commencé | 0% | 4h |
| Jour 6 - UI/UX | 🔲 Non commencé | 0% | 4h |
| Jour 7 - Gestion Stocks | 🔲 Non commencé | 0% | 4h |
| Jour 8 - Calendrier | 🔲 Non commencé | 0% | 4h |
| Jour 9 - Features Secondaires | 🔲 Non commencé | 0% | 4h |
| Jour 10 - Tests & Docs | 🔲 Non commencé | 0% | 4h |
Progression globale : 🟩🟩🟩🟩🟩🟩⬜⬜⬜⬜ 30% (3/10 jours complétés)
✅ Ce qui est fait (Jours 1-3)
Jour 1 - Infrastructure :
- ✅ Structure complète du projet (16 fichiers créés)
- ✅ Configuration package.json et dépendances installées
- ✅ Base de données SQLite initialisée (6 tables)
- ✅ Scripts d'initialisation et de seeding fonctionnels
- ✅ Templates EJS de base (layout, index, partials/messages)
- ✅ CSS legacy old-school
- ✅ Module database.js avec fonctions utilitaires
- ✅ 2 utilisateurs de test créés (admin + standard)
Jour 2 - Authentification :
- ✅ Routes :
/login,/register,/logout - ✅ Templates :
login.ejs,register.ejs - ✅ Logique d'authentification avec sessions
- ✅ Middleware
requireAuth - ✅ Bugs intentionnels : mot de passe en clair, pas de CSRF, validation email
Jour 3 - Catalogue :
- ✅ 20 outils créés avec catégories, marques, descriptions
- ✅ 10 entrepôts dans différentes villes
- ✅ 12 catégories d'outils
- ✅ Stocks générés pour chaque outil/entrepôt
- ✅ Routes GET
/outilset GET/outils/:id - ✅ Filtres : catégorie, recherche, prix min/max
- ✅ Templates
outils.ejsetoutil-detail.ejs - ✅ CSS complet pour grille d'outils et fiches détail
- ✅ Partials header/footer réutilisables
- ✅ Bugs intentionnels : SQL injection (BUG-003), N+1 queries (BUG-012), pas de pagination DB (BUG-011), logique dans templates (BUG-017)
🎯 Prochaine étape (Jour 4)
Implémenter le système de réservations :
- Routes :
/login,/register,/logout - Templates :
login.ejs,register.ejs - Logique d'authentification avec sessions
- Middleware
requireAuth - Bugs intentionnels : mot de passe en clair, pas de CSRF, validation email
<EFBFBD>📋 Contexte et Objectifs
Système Actuel BricoLoc (Architecture Complète)
Architecture technique historique :
- Frontend : Java Spring Framework 5, Tomcat 8.5, services web SOAP
- Backend : Java EE 6 (EJB, JPA), WebLogic Server 12c R1
- Base de données : Oracle 11g R2 (bricolocDB), MySQL 5 (cache)
- Écosystème SI :
- ERP SAP Business One 9.X
- Comparateur de prix SaaS (API REST)
- Batch Java de synchronisation CSV nocturne
- Client lourd C# pour gestion stocks entrepôts
- Power BI pour analytics
- Outils Python d'analyse
- Problèmes identifiés :
- "Grande boule de boue" (monolithe chaotique)
- Logique métier éparpillée (backend, PL/SQL, frontend)
- Accès direct à la DB depuis le frontend (contournement du backend)
- Tables avec >150 colonnes
- Dérives architecturales depuis 2013
- Bugs et problèmes de performance
- Incohérences majeures sur la gestion des stocks
Périmètre de la Réplique Legacy (Phase 1)
🎯 Focus : Application web B2C uniquement (MVP en 2 semaines)
Créer une application Node.js/Express qui :
- ✅ Reproduit les fonctionnalités principales (catalogue, réservations, admin)
- ✅ Intègre intentionnellement les anti-patterns et bugs typiques
- ✅ Démontre les limites d'une architecture monolithique mal maintenue
- ✅ Sert de point de comparaison avec l'application moderne
Ce qui EST inclus (Phase 1) :
- ✅ Application web B2C (frontend + backend monolithique)
- ✅ Authentification et gestion utilisateurs
- ✅ Catalogue d'outils avec filtres
- ✅ Système de réservations
- ✅ Gestion des stocks (simplifiée)
- ✅ Interface admin (CRUD outils, stocks)
- ✅ Architecture monolithique avec bugs intentionnels
Ce qui N'EST PAS inclus (Extensions futures) :
- ⏸️ Backend séparé avec services SOAP/REST
- ⏸️ Cache MySQL séparé
- ⏸️ Procédures PL/SQL (logique dans la DB)
- ⏸️ Intégration ERP (SAP Business One simulé)
- ⏸️ Comparateur de prix externe (API)
- ⏸️ Batch de synchronisation CSV/Java
- ⏸️ Client lourd C# pour stocks entrepôts
- ⏸️ Power BI / Analytics dashboard
- ⏸️ Vraie intégration Stripe (paiement)
- ⏸️ Chat support temps réel
Simplifications acceptées :
- Node.js au lieu de Java (plus accessible pour la démo)
- SQLite au lieu d'Oracle (simplicité de déploiement)
- Monolithe unique au lieu de frontend/backend séparés
- Pas de services SOAP (architecture simplifiée)
- Pas de cache MySQL séparé (inutile pour la démo)
🎯 Fonctionnalités à Implémenter
Périmètre Fonctionnel (MVP)
| Module | Fonctionnalités | Priorité |
|---|---|---|
| Authentification | Inscription, Connexion, Sessions | 🔴 Critique |
| Catalogue | Liste des outils, Détails outil, Filtres basiques | 🔴 Critique |
| Réservations | Créer réservation, Voir mes réservations, Annuler | 🔴 Critique |
| Administration | CRUD outils, Gestion stocks, Liste réservations | 🟠 Important |
| Chat Support | Simulacre de chat (messages statiques) | 🟢 Nice-to-have |
User Stories (7 US Principales)
US-L01 : Inscription Utilisateur
En tant que visiteur
Je veux créer un compte
Afin de pouvoir réserver des outils
Critères d'acceptation :
- ✅ Formulaire avec email, mot de passe, nom, prénom
- ❌ BUG : Pas de validation format email
- ❌ BUG : Mot de passe stocké en clair dans la DB
- ❌ BUG : Pas de confirmation de mot de passe
- ✅ Redirection vers
/loginaprès inscription
US-L02 : Connexion Utilisateur
En tant que utilisateur enregistré
Je veux me connecter
Afin de accéder à mon espace client
Critères d'acceptation :
- ✅ Formulaire avec email et mot de passe
- ✅ Session persistante (cookie)
- ❌ BUG : Pas de protection CSRF
- ❌ BUG : Messages d'erreur trop détaillés (fuite d'info)
- ✅ Redirection vers
/outilsaprès connexion
US-L03 : Consulter le Catalogue
En tant que visiteur ou utilisateur
Je veux voir la liste des outils disponibles
Afin de choisir un outil à louer
Critères d'acceptation :
- ✅ Liste paginée des outils (20 par page)
- ✅ Filtres : catégorie, prix min/max, disponibilité
- ❌ BUG : Pas de pagination côté serveur (tout chargé en mémoire)
- ❌ BUG : Requête SQL vulnérable aux injections (filtres)
- ✅ Affichage : nom, prix/jour, catégorie, image
US-L04 : Consulter Détails d'un Outil
En tant que visiteur ou utilisateur
Je veux voir les détails d'un outil
Afin de décider si je veux le réserver
Critères d'acceptation :
- ✅ Description complète, prix, caractéristiques
- ✅ Images de l'outil
- ✅ Calendrier de disponibilité (si connecté)
- ❌ BUG : Calendrier n'affiche pas toutes les réservations (bug de calcul de dates)
- ❌ BUG : Prix affiché peut être incohérent avec le calcul final
US-L05 : Créer une Réservation
En tant que utilisateur connecté
Je veux réserver un outil pour des dates précises
Afin de l'utiliser pour mon projet
Critères d'acceptation :
- ✅ Formulaire : date début, date fin, entrepôt de retrait
- ✅ Calcul automatique du prix total
- ❌ BUG : Pas de vérification de disponibilité réelle (race condition)
- ❌ BUG : Double-booking possible
- ❌ BUG : Prix calculé côté client (manipulable)
- ✅ Confirmation de réservation affichée
US-L06 : Voir Mes Réservations
En tant que utilisateur connecté
Je veux voir l'historique de mes réservations
Afin de suivre mes locations en cours et passées
Critères d'acceptation :
- ✅ Liste des réservations (en cours, passées, annulées)
- ✅ Détails : outil, dates, prix, statut, entrepôt
- ✅ Bouton "Annuler" (si réservation à venir)
- ❌ BUG : Annulation ne libère pas le stock immédiatement
- ❌ BUG : Dates affichées avec timezone incorrect
US-L07 : Administration des Outils (Admin)
En tant qu' administrateur
Je veux gérer le catalogue d'outils
Afin de maintenir l'inventaire à jour
Critères d'acceptation :
- ✅ CRUD complet : Créer, Modifier, Supprimer des outils
- ✅ Gestion des stocks par entrepôt
- ✅ Upload d'images
- ❌ BUG : Pas de vérification des permissions (n'importe qui peut devenir admin)
- ❌ BUG : Suppression d'outil ne vérifie pas les réservations actives
- ❌ BUG : Interface admin accessible via URL directe sans authentification forte
🏗️ Architecture Technique Détaillée
Stack Technique
Runtime: Node.js 20+
Framework Web: Express.js 4.x
Template Engine: EJS (Embedded JavaScript)
Base de données: SQLite 3
Gestion de sessions: express-session + SQLite store
Upload fichiers: multer
Sécurité: AUCUNE (volontairement)
Tests: AUCUN (volontairement)
Structure du Projet
apps/legacy-app/
├── src/
│ ├── server.js # Point d'entrée, TOUT le code backend
│ ├── database.js # Connexion SQLite + requêtes
│ ├── views/ # Templates EJS
│ │ ├── layout.ejs # Layout principal
│ │ ├── index.ejs # Page d'accueil
│ │ ├── login.ejs # Connexion
│ │ ├── register.ejs # Inscription
│ │ ├── outils.ejs # Liste des outils
│ │ ├── outil-detail.ejs # Détails d'un outil
│ │ ├── reservations.ejs # Mes réservations
│ │ ├── nouvelle-reservation.ejs # Formulaire réservation
│ │ ├── admin/
│ │ │ ├── dashboard.ejs # Dashboard admin
│ │ │ ├── outils.ejs # Gestion outils
│ │ │ ├── stocks.ejs # Gestion stocks
│ │ │ └── reservations.ejs # Liste réservations
│ │ └── partials/
│ │ ├── header.ejs
│ │ ├── footer.ejs
│ │ └── messages.ejs # Flash messages
│ ├── public/ # Assets statiques
│ │ ├── css/
│ │ │ └── styles.css # CSS global (minimal, old-school)
│ │ ├── js/
│ │ │ └── main.js # JavaScript client (jQuery style)
│ │ └── images/
│ │ ├── logo.png
│ │ └── outils/ # Images des outils
│ └── uploads/ # Uploads dynamiques
├── docs/
│ ├── ROADMAP_LEGACY.md # Ce fichier
│ ├── BUGS.md # Liste exhaustive des bugs
│ └── ARCHITECTURE.md # Schéma de l'architecture
├── data/
│ ├── bricoloc.db # Base SQLite
│ └── seeds/
│ ├── entrepots.sql
│ ├── categories.sql
│ ├── outils.sql
│ └── users.sql
├── package.json
└── README.md
Modèle de Données (SQLite)
Table users
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL UNIQUE,
password TEXT NOT NULL, -- ❌ En clair !
nom TEXT NOT NULL,
prenom TEXT NOT NULL,
telephone TEXT,
adresse TEXT,
code_postal TEXT,
ville TEXT,
is_admin INTEGER DEFAULT 0, -- ❌ Pas de gestion de rôles
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
Table categories
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nom TEXT NOT NULL,
description TEXT,
slug TEXT UNIQUE
);
Table entrepots
CREATE TABLE entrepots (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nom TEXT NOT NULL,
ville TEXT NOT NULL,
code_postal TEXT,
adresse TEXT,
telephone TEXT,
email TEXT
);
Table outils
CREATE TABLE outils (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nom TEXT NOT NULL,
description TEXT,
categorie_id INTEGER,
prix_jour REAL NOT NULL,
caution REAL,
marque TEXT,
modele TEXT,
annee INTEGER,
poids REAL,
dimensions TEXT,
puissance TEXT,
image_url TEXT,
restrictions_pro INTEGER DEFAULT 0,
livraison_possible INTEGER DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (categorie_id) REFERENCES categories(id)
);
Table stocks (Anti-pattern : données dénormalisées)
CREATE TABLE stocks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
outil_id INTEGER NOT NULL,
entrepot_id INTEGER NOT NULL,
quantite_totale INTEGER NOT NULL,
quantite_disponible INTEGER NOT NULL, -- ❌ Calculé manuellement, source de bugs
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (outil_id) REFERENCES outils(id),
FOREIGN KEY (entrepot_id) REFERENCES entrepots(id)
);
Table reservations
CREATE TABLE reservations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
outil_id INTEGER NOT NULL,
entrepot_id INTEGER NOT NULL,
date_debut DATE NOT NULL,
date_fin DATE NOT NULL,
prix_total REAL NOT NULL, -- ❌ Calculé côté client
statut TEXT DEFAULT 'en_attente', -- en_attente, confirmee, annulee, terminee
mode_paiement TEXT, -- en_ligne, entrepot
paiement_effectue INTEGER DEFAULT 0,
notes TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (outil_id) REFERENCES outils(id),
FOREIGN KEY (entrepot_id) REFERENCES entrepots(id)
);
🐛 Bugs et Anti-Patterns Intentionnels
Liste des 15+ Bugs à Implémenter
| ID | Catégorie | Description | Impact | Fichier |
|---|---|---|---|---|
| BUG-001 | Sécurité | Mot de passe en clair dans DB | 🔴 Critique | database.js |
| BUG-002 | Sécurité | Pas de protection CSRF | 🔴 Critique | server.js |
| BUG-003 | Sécurité | SQL Injection sur filtres | 🔴 Critique | server.js (route /outils) |
| BUG-004 | Sécurité | Admin accessible sans auth forte | 🔴 Critique | server.js (middleware) |
| BUG-005 | Sécurité | Upload fichiers non sécurisé | 🟠 Élevé | server.js (multer) |
| BUG-006 | Validation | Pas de validation format email | 🟠 Élevé | server.js (POST /register) |
| BUG-007 | Validation | Prix calculé côté client | 🔴 Critique | nouvelle-reservation.ejs |
| BUG-008 | Logique | Race condition sur réservations | 🔴 Critique | server.js (POST /reservations) |
| BUG-009 | Logique | Double-booking possible | 🔴 Critique | server.js (vérification dispo) |
| BUG-010 | Logique | Annulation ne libère pas le stock | 🟠 Élevé | server.js (DELETE /reservations/:id) |
| BUG-011 | Performance | Pas de pagination DB | 🟠 Élevé | server.js (GET /outils) |
| BUG-012 | Performance | Requêtes N+1 | 🟠 Élevé | server.js (boucles imbriquées) |
| BUG-013 | UX | Messages d'erreur trop détaillés | 🟡 Moyen | login.ejs |
| BUG-014 | UX | Dates avec timezone incorrect | 🟡 Moyen | reservations.ejs |
| BUG-015 | Code | Code dupliqué partout | 🟠 Élevé | server.js (>1000 lignes) |
| BUG-016 | Code | Pas de gestion d'erreurs try/catch | 🟠 Élevé | server.js (global) |
| BUG-017 | Architecture | Logique métier dans les vues EJS | 🔴 Critique | outils.ejs, reservations.ejs |
| BUG-018 | Architecture | Tout dans un seul fichier | 🔴 Critique | server.js (monolithe) |
Documentation complète : Voir BUGS.md
📅 Planning Détaillé (2 Semaines)
Semaine 3 : Backend + Fonctionnalités Principales (20h)
✅ Jour 1 (Lundi) - Setup Initial (4h) - COMPLÉTÉ
Tâches :
-
✅ Initialiser le projet Node.js
cd apps/legacy-app npm init -y npm install express ejs express-session sqlite3 multer express-flash connect-sqlite3 -
✅ Créer la structure de fichiers
mkdir -p src/views/{admin,partials} src/public/{css,js,images/outils} src/uploads data/seeds docs -
✅ Configurer
server.js(fichier principal monolithique)- ✅ Setup Express + EJS
- ✅ Configuration sessions (cookie-based, pas de JWT)
- ✅ Middleware basique (body-parser, static)
- BUG-002 : Pas de helmet, pas de CSRF protection
-
✅ Créer
database.js- ✅ Connexion SQLite
- ✅ Fonctions utilitaires (query, run, all)
- ✅ BUG-001 : Fonction
createUser()stocke mot de passe en clair
-
✅ Créer le schéma de base de données
npm run db:init # Script créé et fonctionnel npm run db:seed # 2 utilisateurs de test créés
Livrables :
- ✅ Serveur Express structure créée (server.js placeholder)
- ✅ Base SQLite initialisée avec schéma complet (6 tables)
- ✅ Structure de fichiers complète (16 fichiers créés)
- ✅ Templates EJS : layout.ejs, index.ejs, partials/messages.ejs
- ✅ CSS legacy old-school (styles.css)
- ✅ Scripts d'initialisation DB fonctionnels
Statut : ✅ JOUR 1 COMPLÉTÉ - Structure complète opérationnelle
Prochaine étape : Jour 2 - Implémenter l'authentification complète (routes + logique)
✅ Jour 2 (Mardi) - Authentification (4h) - COMPLÉTÉ
User Stories : US-L01, US-L02
Tâches :
-
✅ Créer les routes d'authentification
// server.js app.get('/login', (req, res) => { ... }); app.post('/login', (req, res) => { ... }); app.get('/register', (req, res) => { ... }); app.post('/register', (req, res) => { ... }); app.get('/logout', (req, res) => { ... }); -
✅ Créer les templates EJS
- ✅
views/login.ejs: formulaire de connexion avec layout complet - ✅
views/register.ejs: formulaire d'inscription avec tous les champs - ✅
views/layout.ejs: layout principal (déjà créé) - ✅
views/index.ejs: mise à jour avec layout complet - ✅ Navigation dynamique selon statut login
- ✅
-
✅ Implémenter la logique d'authentification
- ✅ Vérification email/password (en clair)
- ✅ Création de session (stockage user_id dans SQLite store)
- ✅ BUG-006 : Pas de validation format email
- ✅ BUG-013 : Messages d'erreur détaillés ("Email introuvable" vs "Mot de passe incorrect")
-
✅ Créer le middleware d'authentification
function requireAuth(req, res, next) { if (!req.session.userId) { return res.redirect('/login'); } next(); } // ❌ BUG-004 : Pas de middleware requireAdmin séparé
Livrables :
- ✅ Inscription fonctionnelle (avec bugs intentionnels)
- ✅ Connexion fonctionnelle (avec bugs intentionnels)
- ✅ Sessions persistantes avec SQLite store
- ✅ Logout qui détruit la session
- ✅ Menu de navigation dynamique (connecté/non connecté)
- ✅ Lien "Administration" visible pour les admins
Tests manuels effectués :
- ✅ Créer un compte test@test.com → ✅ Inscrit correctement
- ✅ Se connecter avec admin@bricoloc.fr → ✅ Session créée
- ✅ Vérifier menu admin → ✅ Lien "Administration" visible
- ✅ Vérifier DB → ✅ Mot de passe en clair confirmé (BUG-001)
- ✅ Session persiste entre les requêtes → ✅ Cookie valide 7 jours
Statut : ✅ JOUR 2 COMPLÉTÉ - Authentification fonctionnelle avec bugs intentionnels
Prochaine étape : Jour 3 - Implémenter le catalogue d'outils avec filtres
🔲 Jour 3 (Mercredi) - Catalogue d'outils (4h) - À FAIRE
Statut : ⏸️ À FAIRE - Prochaine étape du développement
🔲 Jour 3 (Mercredi) - Catalogue (4h) - NON COMMENCÉ
User Stories : US-L03, US-L04
Tâches :
-
🔲 Seeder les données de test
sqlite3 data/bricoloc.db < data/seeds/entrepots.sql sqlite3 data/bricoloc.db < data/seeds/categories.sql sqlite3 data/bricoloc.db < data/seeds/outils.sql -
✅ Créer les routes catalogue
app.get('/outils', (req, res) => { ... }); // Liste app.get('/outils/:id', (req, res) => { ... }); // Détails -
✅ Implémenter la liste des outils
- Query SQL avec JOIN categories
- Filtres : catégorie, prix min/max, disponibilité
- BUG-003 : SQL Injection via paramètres de filtre
- BUG-011 : Pas de pagination, tout chargé en mémoire
- BUG-012 : Requête N+1 pour les stocks
-
✅ Créer les templates
views/outils.ejs: grille d'outilsviews/outil-detail.ejs: fiche détaillée- BUG-017 : Calculs de disponibilité dans le template EJS
-
✅ CSS basique old-school
public/css/styles.css: styles années 2010- Pas de responsive design
- Tables pour layout (anti-pattern)
Livrables :
- ✅ Page catalogue fonctionnelle
- ✅ Page détail outil avec images
- ✅ Filtres fonctionnels (mais vulnérables)
Tests manuels :
- Injecter SQL dans filtre catégorie :
?categorie=1' OR '1'='1→ ✅ Fonctionne - Charger 500+ outils → ✅ Lenteur visible
Jour 4 (Jeudi) - Réservations (4h)
User Stories : US-L05, US-L06
Tâches :
-
✅ Créer les routes réservations
app.get('/outils/:id/reserver', requireAuth, (req, res) => { ... }); app.post('/reservations', requireAuth, (req, res) => { ... }); app.get('/mes-reservations', requireAuth, (req, res) => { ... }); app.post('/reservations/:id/annuler', requireAuth, (req, res) => { ... }); -
✅ Implémenter la création de réservation
- Formulaire : dates, entrepôt
- BUG-007 : Prix total calculé côté client (JavaScript)
- BUG-008 : Pas de transaction SQL (race condition)
- BUG-009 : Vérification de disponibilité incomplète
-
✅ Implémenter la liste des réservations
- Query avec JOIN outils, entrepots
- BUG-012 : Requête N+1 encore
- BUG-014 : Dates affichées avec mauvais timezone
-
✅ Implémenter l'annulation
- Update statut = 'annulee'
- BUG-010 : Ne met pas à jour
stocks.quantite_disponible
-
✅ Créer les templates
views/nouvelle-reservation.ejs: formulaire avec calendrierviews/reservations.ejs: liste des réservations
Livrables :
- ✅ Réservation fonctionnelle
- ✅ Historique des réservations
- ✅ Annulation fonctionnelle (mais buguée)
Tests manuels :
- Créer 2 réservations simultanées pour le même outil → ✅ Double-booking
- Annuler une réservation → ✅ Stock pas libéré
- Modifier le prix total dans le formulaire (DevTools) → ✅ Accepté
Jour 5 (Vendredi) - Administration Basique (4h)
User Stories : US-L07 (partiel)
Tâches :
-
✅ Créer les routes admin
app.get('/admin', requireAuth, (req, res) => { ... }); app.get('/admin/outils', requireAuth, (req, res) => { ... }); app.post('/admin/outils', requireAuth, (req, res) => { ... }); app.post('/admin/outils/:id/supprimer', requireAuth, (req, res) => { ... }); -
✅ Implémenter CRUD outils
- Formulaire création/édition
- Upload d'image (multer)
- BUG-005 : Pas de validation du type de fichier
- BUG-004 : Pas de vérification
is_admin
-
✅ Créer les templates admin
views/admin/dashboard.ejs: page d'accueil adminviews/admin/outils.ejs: gestion des outils
-
✅ Seed un utilisateur admin
INSERT INTO users (email, password, nom, prenom, is_admin) VALUES ('admin@bricoloc.fr', 'admin123', 'Admin', 'BricoLoc', 1);
Livrables :
- ✅ Interface admin accessible (sans protection)
- ✅ CRUD outils fonctionnel
- ✅ Upload d'images fonctionnel (non sécurisé)
Tests manuels :
- Accéder à
/adminsans être admin → ✅ Accès autorisé - Uploader un fichier
.php→ ✅ Accepté - Supprimer un outil avec réservations actives → ✅ Pas de vérification
Semaine 4 : Frontend, Gestion Stocks, Finitions (20h)
Jour 6 (Lundi) - Amélioration UI/UX (4h)
Tâches :
-
✅ Créer le CSS "old-school"
/* public/css/styles.css */ body { font-family: Arial, sans-serif; background: #f0f0f0; } table { width: 100%; border-collapse: collapse; } /* ❌ Pas de responsive, pas de flexbox/grid */ -
✅ Ajouter JavaScript côté client (jQuery-style)
// public/js/main.js $(document).ready(function() { // Calcul prix réservation (BUG-007) $('#date_debut, #date_fin').change(function() { var prixJour = parseFloat($('#prix_jour').val()); var nbJours = calculerNbJours(); $('#prix_total').val(prixJour * nbJours); // ❌ Manipulable }); }); -
✅ Améliorer les templates existants
- Ajouter flash messages (succès, erreurs)
- Menu de navigation avec état connecté/déconnecté
- Breadcrumb basique
-
✅ Créer la page d'accueil
views/index.ejs: landing page simple- Liste des catégories populaires
- Section "Comment ça marche"
Livrables :
- ✅ Interface utilisateur basique mais complète
- ✅ Page d'accueil informative
- ✅ Navigation cohérente
Jour 7 (Mardi) - Gestion Stocks (4h)
User Stories : US-L07 (complet)
Tâches :
-
✅ Créer les routes gestion stocks
app.get('/admin/stocks', requireAuth, (req, res) => { ... }); app.post('/admin/stocks/:id/update', requireAuth, (req, res) => { ... }); -
✅ Implémenter la logique de stocks
- Affichage stocks par entrepôt
- Modification manuelle des quantités
- BUG-010 : Incohérence avec les réservations actives
-
✅ Créer le template
views/admin/stocks.ejs: tableau de gestion- Formulaire de modification en ligne
-
✅ Implémenter la vérification de disponibilité
function checkAvailability(outilId, dateDebut, dateFin, entrepotId) { // ❌ BUG-009 : Logique incomplète, ne vérifie pas toutes les conditions const query = ` SELECT quantite_disponible FROM stocks WHERE outil_id = ? AND entrepot_id = ? `; // Ne prend pas en compte les réservations en conflit }
Livrables :
- ✅ Interface de gestion des stocks
- ✅ Mise à jour manuelle des quantités
- ✅ Vérification de disponibilité (buguée)
Jour 8 (Mercredi) - Calendrier Disponibilités (4h)
Tâches :
-
✅ Implémenter le calendrier sur la page détail outil
- Affichage des dates déjà réservées
- Sélection de plage de dates
- BUG-014 : Problèmes de timezone
-
✅ Ajouter bibliothèque de calendrier (ex: flatpickr)
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css"> <script src="https://cdn.jsdelivr.net/npm/flatpickr"></script> -
✅ JavaScript pour bloquer les dates indisponibles
flatpickr("#date_debut", { disable: reservedDates, // ❌ BUG : Liste incomplète minDate: "today" }); -
✅ Améliorer le formulaire de réservation
- Sélection entrepôt
- Calcul prix dynamique (côté client, BUG-007)
- Récapitulatif avant validation
Livrables :
- ✅ Calendrier de réservation fonctionnel
- ✅ Expérience utilisateur améliorée
- ✅ Bugs de dates documentés
Jour 9 (Jeudi) - Features Secondaires (4h)
Tâches :
-
✅ Implémenter la recherche d'outils
app.get('/recherche', (req, res) => { const q = req.query.q; // ❌ BUG-003 : SQL Injection possible const query = `SELECT * FROM outils WHERE nom LIKE '%${q}%'`; }); -
✅ Ajouter pagination (côté client seulement)
// ❌ BUG-011 : Tout chargé en mémoire puis paginé en JS const allOutils = await db.all('SELECT * FROM outils'); res.render('outils', { outils: allOutils }); // Pas de LIMIT -
✅ Créer une page "Mes informations"
- Affichage des données utilisateur
- Formulaire de modification (non fonctionnel)
-
✅ Ajouter un simulacre de chat support
- Messages statiques prédéfinis
- Formulaire de contact (ne fait rien)
Livrables :
- ✅ Recherche fonctionnelle (vulnérable)
- ✅ Pagination côté client
- ✅ Pages secondaires complètes
Jour 10 (Vendredi) - Tests Manuels & Documentation (4h)
Tâches :
-
✅ Tests manuels exhaustifs
- Parcourir tous les scénarios utilisateur
- Reproduire tous les bugs identifiés
- Documenter les comportements anormaux
-
✅ Rédiger
docs/BUGS.md- Liste exhaustive des 18+ bugs
- Instructions de reproduction
- Captures d'écran si nécessaire
- Explications des impacts
-
✅ Rédiger
docs/ARCHITECTURE.md- Schéma de l'architecture monolithique
- Flux de données
- Points de friction identifiés
-
✅ Mettre à jour
README.md- Instructions d'installation
- Commandes de lancement
- Comptes de test (admin + utilisateur standard)
- Liste des fonctionnalités
-
✅ Créer un seed complet
npm run seed # Script qui remplit la DB avec données de test
Livrables :
- ✅ Application testée manuellement
- ✅ Documentation complète (BUGS.md, ARCHITECTURE.md)
- ✅ README.md à jour
- ✅ Données de test complètes
📊 Métriques Cibles (Application Legacy)
Métriques de Qualité (Volontairement Basses)
| Métrique | Cible | Méthode de Mesure |
|---|---|---|
| Lighthouse Performance | < 60 | Chrome DevTools |
| Lighthouse Best Practices | < 70 | Chrome DevTools |
| Lighthouse SEO | < 80 | Chrome DevTools |
| Tests Coverage | 0% | Aucun test |
| Complexité Cyclomatique | > 20 | ESLint plugin |
| Code Duplication | > 30% | jscpd |
| Lignes de code (server.js) | > 1000 | wc -l |
| Nombre de bugs identifiés | > 15 | Documentation manuelle |
| Time to Interactive (TTI) | > 5s | Lighthouse |
Métriques Fonctionnelles (Succès)
| Métrique | Cible |
|---|---|
| User Stories implémentées | 7/7 |
| Fonctionnalités principales | 100% |
| Pages créées | 12+ |
| Templates EJS | 15+ |
| Routes Express | 20+ |
🎯 Critères de Succès
Critères de Complétion
- ✅ 7 User Stories complètement implémentées et fonctionnelles
- ✅ 18+ bugs identifiés, implémentés et documentés
- ✅ Application déployable localement sans erreur
- ✅ Documentation complète (BUGS.md, ARCHITECTURE.md, README.md)
- ✅ Données de test (seed complet avec 50+ outils, 10 entrepôts, 5 utilisateurs)
- ✅ UI old-school mais cohérente et navigable
Critères de Qualité (Intentionnellement Bas)
- ✅ Aucun test automatisé
- ✅ Fichier monolithique server.js > 1000 lignes
- ✅ Vulnérabilités de sécurité multiples
- ✅ Performance médiocre (temps de chargement > 3s)
- ✅ Code legacy authentique (duplication, pas de patterns)
🚀 Démarrage Rapide
Installation
cd apps/legacy-app
npm install
Initialisation de la base de données
npm run db:init # Crée le schéma
npm run db:seed # Remplit avec données de test
Lancement du serveur
npm start # Production
npm run dev # Développement (nodemon)
Accès à l'application
- URL :
http://localhost:3000 - Compte admin :
admin@bricoloc.fr/admin123 - Compte utilisateur :
jean.dupont@email.fr/password123
📚 Ressources et Références
Technologies Utilisées
- Express.js Documentation
- EJS Documentation
- SQLite Documentation
- Multer (File Upload)
- express-session
Inspiration Architecture Legacy
- Article : Big Ball of Mud
- Article : Monolith to Microservices
- Vidéo : Legacy Code Patterns
🔮 Extensions Futures (Phases 2-3)
Ces fonctionnalités reproduisent plus fidèlement l'écosystème SI complet de BricoLoc.
Elles peuvent être ajoutées après la Phase 1 pour enrichir la démo.
Phase 2 : Backend Séparé & Intégrations (Optionnel - +20h)
Objectif : Reproduire l'architecture frontend/backend séparée avec services SOAP/REST
| Extension | Description | Effort | Priorité |
|---|---|---|---|
| Backend API séparé | Extraire la logique métier dans un service Node.js séparé (SOAP ou REST) | 8h | 🟠 Moyenne |
| Cache MySQL | Ajouter une base MySQL pour cache (photos, docs) | 3h | 🟢 Basse |
| Procédures SQL | Migrer une partie de la logique en procédures stockées SQLite | 4h | 🟡 Moyenne |
| Batch de synchronisation | Script Node.js simulant la synchro CSV nocturne des stocks | 5h | 🟠 Moyenne |
Valeur ajoutée :
- Démontre les problèmes de couplage frontend/backend
- Illustre la complexité des services web SOAP legacy
- Montre les difficultés de synchronisation de données
Phase 3 : Écosystème Complet (Optionnel - +30h)
Objectif : Simuler l'intégration avec les systèmes externes (ERP, comparateur, analytics)
| Extension | Description | Effort | Priorité |
|---|---|---|---|
| Mock ERP (SAP B1) | API REST simulant l'ERP avec données de stocks | 6h | 🟢 Basse |
| Comparateur de prix | Service externe (API) pour comparaison prix outils | 5h | 🟢 Basse |
| Client lourd stocks | Application Electron (ou CLI) pour gestion stocks entrepôts | 8h | 🟡 Moyenne |
| Dashboard Analytics | Page simple avec graphiques (Chart.js) simulant Power BI | 4h | 🟢 Basse |
| Vraie intégration Stripe | Paiement fonctionnel avec webhooks | 4h | 🟠 Moyenne |
| Chat temps réel | Socket.io pour chat support en temps réel | 3h | 🟢 Basse |
Valeur ajoutée :
- Reproduit la complexité d'un SI avec multiples systèmes
- Démontre les problèmes d'intégration et de cohérence des données
- Illustre les dépendances entre systèmes legacy
Roadmap d'Extensions (Si Temps Disponible)
gantt
title Extensions Legacy (Optionnel)
dateFormat YYYY-MM-DD
section Phase 1 (MVP)
App Web B2C :done, phase1, 2025-10-28, 2w
section Phase 2
Backend API séparé :crit, phase2a, after phase1, 8d
Cache MySQL :phase2b, after phase1, 3d
Procédures SQL :phase2c, after phase2a, 4d
Batch synchronisation :phase2d, after phase2b, 5d
section Phase 3
Mock ERP :phase3a, after phase2, 6d
Comparateur de prix :phase3b, after phase2, 5d
Client lourd stocks :phase3c, after phase3a, 8d
Dashboard Analytics :phase3d, after phase3b, 4d
Stripe intégration :phase3e, after phase3c, 4d
Chat temps réel :phase3f, after phase3d, 3d
Décision : Phase 1 uniquement pour ce projet (2 semaines).
Phases 2-3 documentées pour référence future.
🔄 Prochaines Étapes
Après complétion de l'application Legacy (Semaine 4) :
- Semaine 5 : Démarrage Application Moderne (Setup Next.js + Supabase)
- Semaine 6 : Auth Service (Clean Architecture)
- Semaine 7-8 : Catalogue & Inventory Services
- Semaine 9 : Reservation & Payment Services
- Semaine 10 : Comparaison et Présentation
Dernière mise à jour : Octobre 2025
Prochaine révision : Fin Semaine 4
Statut : 🔵 En cours de planification