# Fichier: python_cheats/cheatsheets/sonarqube.txt
# Cheatsheet SonarQube - Guide Complet pour Débutants


[OK] QU'EST-CE QUE SONARQUBE ? (POUR DÉBUTANTS ABSOLUS)

# === ANALOGIE SIMPLE ===

# Imaginez que votre code est comme une maison en construction:
# - Vous écrivez du code (construisez la maison)
# - Le code peut avoir des problèmes invisibles (fissures, mauvais câblage)
# - Ces problèmes peuvent causer des bugs plus tard

# SonarQube = Inspecteur en bâtiment automatique pour votre code
# Il inspecte votre code et vous dit:
# [OK] "Ce code est dangereux, il peut crasher" (Bugs)
# [OK] "Ce code a une faille de sécurité" (Vulnerabilities)
# [OK] "Ce code fonctionne mais sera difficile à modifier" (Code Smells)
# [OK] "Seulement 60% de votre code est testé" (Coverage)

# === POURQUOI UTILISER SONARQUBE ? ===

# Sans SonarQube:
# [X] Bugs découverts en production
# [X] Failles de sécurité exploitées
# [X] Code difficile à maintenir
# [X] Équipe perd du temps sur code legacy
# [X] Pas de standard de qualité

# Avec SonarQube:
# [OK] Bugs détectés avant production
# [OK] Failles de sécurité identifiées tôt
# [OK] Code maintenable et lisible
# [OK] Équipe plus productive
# [OK] Standards de qualité appliqués automatiquement

# === WORKFLOW VISUEL COMPLET ===

# ÉTAPE 1: Sans SonarQube (situation avant)
# Développeur écrit code -> Commit -> Production
#                                    v
#                            Bug découvert par utilisateurs [CRYING_FACE]

# ÉTAPE 2: Avec SonarQube (situation après)
# Développeur écrit code -> SonarQube analyse -> Bugs détectés -> Correction
#                                                                  v
# Commit -> Production sans bugs -> Utilisateurs contents [SMILING_FACE_WITH_SMILING_EYES]

# === EXEMPLE CONCRET ===

# Imaginez ce code Python:
def calculate_average(numbers):
    total = 0
    for num in numbers:
        total = total + num
    return total / len(numbers)  # [X] Bug potentiel!

# SonarQube vous dira:
# "[ATTENTION] Bug: Division by zero possible si numbers est vide"
# "[IDEE] Suggestion: Vérifier que len(numbers) > 0"

# Code corrigé:
def calculate_average(numbers):
    if not numbers:  # [OK] Protection ajoutée
        return 0
    total = 0
    for num in numbers:
        total = total + num
    return total / len(numbers)

# === COMMENT ÇA MARCHE ? ===

# 1. VOUS ÉCRIVEZ DU CODE
# mon_projet/
#   src/
#     main.py
#     utils.py

# 2. VOUS LANCEZ SONARQUBE
# Terminal: sonar-scanner

# 3. SONARQUBE ANALYSE VOTRE CODE
# Il lit chaque fichier .py
# Il cherche des problèmes connus
# Il compte vos tests
# Il mesure la complexité

# 4. VOUS VOYEZ LES RÉSULTATS
# Dans votre navigateur: http://localhost:9000
# Dashboard avec:
# - 5 bugs trouvés
# - 2 vulnérabilités de sécurité
# - 23 code smells
# - Coverage: 65%

# 5. VOUS CORRIGEZ LES PROBLÈMES
# Vous ouvrez le fichier problématique
# Vous corrigez selon les suggestions
# Vous relancez l'analyse

# 6. QUALITÉ AMÉLIORÉE !
# - 0 bugs
# - 0 vulnérabilités
# - 10 code smells (en progrès)
# - Coverage: 75%

# === VOCABULAIRE DE BASE (EXPLIQUÉ SIMPLEMENT) ===

# [BUG] BUG
# Quoi: Erreur dans le code qui peut causer un crash
# Exemple: Division par zéro, accès à un élément inexistant
# Gravité: DOIT être corrigé
# Analogie: Fil électrique mal branché

# [VERROUILLE] VULNERABILITY (Vulnérabilité)
# Quoi: Faille de sécurité exploitable par un attaquant
# Exemple: Injection SQL, mot de passe en clair
# Gravité: DOIT être corrigé immédiatement
# Analogie: Porte d'entrée sans serrure

# [NETTOYAGE] CODE SMELL
# Quoi: Code qui fonctionne MAIS difficile à maintenir
# Exemple: Fonction trop longue, code dupliqué
# Gravité: Devrait être corrigé (mais pas urgent)
# Analogie: Désordre dans une pièce (fonctionne mais pénible)

# [TEST] COVERAGE (Couverture de tests)
# Quoi: Pourcentage de code testé automatiquement
# Exemple: 75% = 3/4 de votre code a des tests
# Objectif: Minimum 80%
# Analogie: Combien de pièces de la maison avez-vous inspectées?

# [SYNC] DUPLICATION
# Quoi: Code copié-collé plusieurs fois
# Exemple: Même fonction répétée dans 3 fichiers
# Problème: Si vous corrigez un bug, vous devez le faire 3 fois!
# Analogie: Photocopies d'un document - difficile de tous les mettre à jour

# [SORTIE] QUALITY GATE (Porte de Qualité)
# Quoi: Ensemble de règles que le code doit respecter
# Exemple: "Coverage > 80% ET Bugs = 0"
# Résultat: PASS (vert [OK]) ou FAIL (rouge [X])
# Analogie: Contrôle technique de voiture - passe ou ne passe pas

# [MESURE] TECHNICAL DEBT (Dette Technique)
# Quoi: Temps nécessaire pour corriger tous les problèmes
# Exemple: "2 jours 5 heures de dette"
# Problème: Plus c'est élevé, plus c'est difficile de modifier le code
# Analogie: Désordre accumulé - plus il y en a, plus c'est long à ranger

# === PREMIER CONTACT AVEC SONARQUBE ===

# Imaginez que vous ouvrez SonarQube pour la première fois.
# Vous verrez un DASHBOARD (tableau de bord) avec des chiffres:

# ┌─────────────────────────────────────────┐
# │  MON PROJET                              │
# ├─────────────────────────────────────────┤
# │  Reliability (Fiabilité)         * C   │
# │  -> 12 Bugs                               │
# ├─────────────────────────────────────────┤
# │  Security (Sécurité)             * B   │
# │  -> 3 Vulnerabilities                     │
# ├─────────────────────────────────────────┤
# │  Maintainability                 * A   │
# │  -> 45 Code Smells                        │
# ├─────────────────────────────────────────┤
# │  Coverage (Tests)               [GRAPHIQUE] 68%  │
# │  -> 2,340 lignes testées sur 3,441        │
# ├─────────────────────────────────────────┤
# │  Duplications                   [GRAPHIQUE] 4.2% │
# │  -> 145 lignes dupliquées                 │
# └─────────────────────────────────────────┘

# Comment lire ce tableau:
# - * A = EXCELLENT (meilleur score)
# - * B = BON
# - * C = MOYEN (à améliorer)
# - * D = MAUVAIS
# - * E = TRÈS MAUVAIS (urgent!)

# Que faire?
# 1. Cliquez sur "12 Bugs" -> Voir la liste des bugs
# 2. Cliquez sur un bug -> Voir le code problématique
# 3. Lisez l'explication -> Comprendre le problème
# 4. Corrigez le code -> Appliquer la solution
# 5. Re-analysez -> Vérifier l'amélioration


[OK] INTRODUCTION À SONARQUBE

# Qu'est-ce que SonarQube ?
# SonarQube est une plateforme open-source d'inspection continue de la qualité du code
# Il détecte automatiquement les bugs, vulnérabilités et code smells dans 30+ langages

# Concepts clés
# - Qualité du Code: Mesure de la maintenabilité et fiabilité
# - Dette Technique: Effort nécessaire pour corriger les problèmes
# - Code Smell: Code fonctionnel mais difficile à maintenir
# - Bug: Erreur qui peut causer un dysfonctionnement
# - Vulnérabilité: Faille de sécurité potentielle
# - Hotspot de Sécurité: Code sensible nécessitant une revue manuelle

# Éditions disponibles
# - Community Edition (gratuite): Langages de base
# - Developer Edition: Analyse de branches, pull requests
# - Enterprise Edition: Portfolio, gouvernance
# - Data Center Edition: Haute disponibilité

# === POUR QUI EST SONARQUBE ? ===

# [PERSONNE][CODE] Développeurs débutants
# Pourquoi: Apprendre les bonnes pratiques automatiquement
# Bénéfice: SonarQube est comme un mentor qui vous guide

# [PERSONNE][CODE] Développeurs expérimentés
# Pourquoi: Maintenir la qualité sur gros projets
# Bénéfice: Détection automatique des problèmes qu'on pourrait manquer

# [UTILISATEURS] Équipes
# Pourquoi: Standard de qualité commun
# Bénéfice: Tout le monde suit les mêmes règles

# [ENTREPRISE] Entreprises
# Pourquoi: Gouvernance et conformité
# Bénéfice: Audit de qualité sur tous les projets

# === PREMIÈRE UTILISATION - TUTORIEL PAS À PAS ===

# Vous êtes développeur Python et vous venez de finir votre premier projet.
# Votre chef vous demande: "Installe SonarQube pour vérifier la qualité"
# Vous ne savez pas ce que c'est. Suivez ce guide!

# ÉTAPE 1: Comprendre ce que vous allez faire
# ─────────────────────────────────────────
# Vous allez:
# 1. Installer SonarQube (le serveur qui fait l'analyse)
# 2. Installer Scanner (l'outil qui envoie votre code au serveur)
# 3. Créer un "projet" dans SonarQube (comme créer un dossier)
# 4. Lancer l'analyse (SonarQube va lire votre code)
# 5. Voir les résultats dans votre navigateur

# ÉTAPE 2: Installation (version simple avec Docker)
# ──────────────────────────────────────────────────
# Ouvrez votre terminal et tapez:

# Lancer SonarQube (comme démarrer une application)
docker run -d --name sonarqube -p 9000:9000 sonarqube:lts-community

# Explication:
# - docker run: Lance un conteneur (comme une mini-machine virtuelle)
# - -d: En arrière-plan (vous pouvez continuer à utiliser votre terminal)
# - --name sonarqube: Donne un nom au conteneur
# - -p 9000:9000: Rend SonarQube accessible sur http://localhost:9000
# - sonarqube:lts-community: Version gratuite et stable de SonarQube

# Attendez 2-3 minutes que SonarQube démarre
# Vérifiez qu'il est prêt:
curl http://localhost:9000/api/system/status
# Vous devriez voir: {"status":"UP"}

# ÉTAPE 3: Ouvrir SonarQube dans votre navigateur
# ────────────────────────────────────────────────
# Ouvrez: http://localhost:9000
# Vous verrez une page de connexion

# Login par défaut:
# Utilisateur: admin
# Mot de passe: admin

# [ATTENTION] IMPORTANT: Après connexion, SonarQube vous demandera de changer le mot de passe
# Choisissez un nouveau mot de passe (ex: MonMotDePasse123!)

# ÉTAPE 4: Créer votre premier projet
# ────────────────────────────────────
# Dans l'interface SonarQube:
# 1. Cliquez sur "Create Project" (gros bouton bleu)
# 2. Choisissez "Manually" (manuellement)
# 3. Project key: mon-premier-projet (nom technique, pas d'espaces)
# 4. Display name: Mon Premier Projet (nom affiché)
# 5. Cliquez "Set Up"

# ÉTAPE 5: Obtenir un token d'authentification
# ─────────────────────────────────────────────
# SonarQube va vous demander comment vous voulez analyser votre projet
# 1. Choisissez "Locally" (sur votre machine)
# 2. Générez un token:
#    - Token name: mon-token-test
#    - Cliquez "Generate"
#    - Copiez le token (ressemble à: squ_a1b2c3d4e5f6...)
#    - [ATTENTION] IMPORTANT: Sauvegardez-le, vous ne le verrez qu'une fois!

# ÉTAPE 6: Installer SonarQube Scanner
# ─────────────────────────────────────
# Le scanner est l'outil qui va analyser votre code

# Mac:
brew install sonar-scanner

# Linux (Ubuntu/Debian):
# Télécharger
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip
# Décompresser
unzip sonar-scanner-cli-*.zip
# Installer
sudo mv sonar-scanner-* /opt/sonar-scanner
# Ajouter au PATH
echo 'export PATH=$PATH:/opt/sonar-scanner/bin' >> ~/.bashrc
source ~/.bashrc

# Windows (avec Chocolatey):
choco install sonar-scanner

# Vérifier l'installation:
sonar-scanner --version
# Vous devriez voir: SonarScanner 5.0.1...

# ÉTAPE 7: Préparer votre projet pour l'analyse
# ──────────────────────────────────────────────
# Allez dans le dossier de votre projet:
cd /chemin/vers/mon_projet

# Structure typique d'un projet Python:
# mon_projet/
#   src/
#     main.py
#     utils.py
#   tests/
#     test_main.py
#   requirements.txt

# Créez un fichier de configuration:
nano sonar-project.properties

# Copiez-collez cette configuration de base:
# (Remplacez mon-premier-projet par votre project key)

sonar.projectKey=mon-premier-projet
sonar.projectName=Mon Premier Projet
sonar.projectVersion=1.0
sonar.sources=src
sonar.tests=tests
sonar.sourceEncoding=UTF-8
sonar.python.version=3.11
sonar.exclusions=**/venv/**,**/__pycache__/**

# Explication de chaque ligne:
# - projectKey: Identifiant unique (doit correspondre à ce que vous avez créé)
# - projectName: Nom affiché dans l'interface
# - projectVersion: Version de votre application (1.0 pour commencer)
# - sources: Où se trouve votre code (dossier src)
# - tests: Où se trouvent vos tests (dossier tests)
# - sourceEncoding: Encodage des fichiers (UTF-8 standard)
# - python.version: Votre version Python
# - exclusions: Fichiers à ignorer (environnements virtuels, cache)

# ÉTAPE 8: Lancer votre première analyse!
# ────────────────────────────────────────
# Dans votre terminal (dans le dossier du projet):

sonar-scanner -Dsonar.token=VOTRE_TOKEN_ICI

# [ATTENTION] Remplacez VOTRE_TOKEN_ICI par le token que vous avez copié à l'étape 5
# Exemple:
sonar-scanner -Dsonar.token=squ_a1b2c3d4e5f6g7h8i9j0

# Vous verrez des messages défiler dans le terminal:
# INFO: Scanner configuration file: ...
# INFO: Project root configuration file: sonar-project.properties
# INFO: Analyzing on SonarQube server 10.3
# INFO: Base dir: /chemin/vers/mon_projet
# INFO: Working dir: /chemin/vers/mon_projet/.scannerwork
# INFO: Source paths: src
# INFO: Test paths: tests
# INFO: Sensor Python Sensor [python]
# INFO: Python version: 3.11
# INFO: Sensor Python Sensor [python] (done) | time=1234ms
# ...
# INFO: ANALYSIS SUCCESSFUL
# INFO: Task total time: 12.345 s

# Si vous voyez "ANALYSIS SUCCESSFUL" -> Bravo! [BRAVO]

# ÉTAPE 9: Voir les résultats
# ───────────────────────────
# Retournez dans votre navigateur: http://localhost:9000
# Cliquez sur votre projet "Mon Premier Projet"

# Vous verrez votre premier dashboard!
# Prenons un exemple de ce que vous pourriez voir:

# ┌─────────────────────────────────────────────────┐
# │  MON PREMIER PROJET                             │
# │  Last analysis: aujourd'hui à 14h32             │
# ├─────────────────────────────────────────────────┤
# │                                                 │
# │  Reliability              * C                  │
# │  8 Bugs                                         │
# │  5 min debt                                     │
# │                                                 │
# │  Security                 * A                  │
# │  0 Vulnerabilities                              │
# │                                                 │
# │  Security Review          * A                  │
# │  0 Security Hotspots                            │
# │                                                 │
# │  Maintainability          * A                  │
# │  23 Code Smells                                 │
# │  1h 30min debt                                  │
# │                                                 │
# │  Coverage                 [GRAPHIQUE] 45.2%              │
# │  Duplication              [GRAPHIQUE] 3.7%               │
# │                                                 │
# │  Lines of Code            [NOTE] 1,234              │
# └─────────────────────────────────────────────────┘

# ÉTAPE 10: Explorer votre premier bug
# ─────────────────────────────────────
# Dans le dashboard, cliquez sur "8 Bugs"
# Vous verrez une liste comme:

# ┌────────────────────────────────────────────────────┐
# │  Bug                                   | Severity   │
# ├────────────────────────────────────────────────────┤
# │  [BUG] "calculate" may be null here       | MAJOR      │
# │  [FICHIER] src/utils.py:42                                 │
# ├────────────────────────────────────────────────────┤
# │  [BUG] Remove this "return" statement     | MINOR      │
# │  [FICHIER] src/main.py:156                                 │
# └────────────────────────────────────────────────────┘

# Cliquez sur le premier bug pour voir les détails:

# ╔═══════════════════════════════════════════════════╗
# ║  Bug: "calculate" may be null here                 ║
# ║  Type: Bug                                         ║
# ║  Severity: MAJOR                                   ║
# ║  Effort: 5 minutes                                 ║
# ╠═══════════════════════════════════════════════════╣
# ║  Description:                                      ║
# ║  The variable "calculate" may be null when used.   ║
# ║  This will cause a NullPointerException.           ║
# ║                                                    ║
# ║  File: src/utils.py                                ║
# ║  Line: 42                                          ║
# ║                                                    ║
# ║  Code:                                             ║
# ║  39 | def process_data(data):                      ║
# ║  40 |     result = None                            ║
# ║  41 |     if data:                                 ║
# ║-> 42 |         result = calculate(data)             ║
# ║  43 |     return result.value  [X] Problème ici!   ║
# ║                                                    ║
# ║  Solution suggérée:                                ║
# ║  Vérifiez que result n'est pas None avant de       ║
# ║  l'utiliser.                                       ║
# ╚═══════════════════════════════════════════════════╝

# ÉTAPE 11: Corriger le bug
# ──────────────────────────
# Ouvrez le fichier src/utils.py:

# Code AVANT (avec bug):
def process_data(data):
    result = None
    if data:
        result = calculate(data)
    return result.value  # [X] Crash si result est None!

# Code APRÈS (corrigé):
def process_data(data):
    result = None
    if data:
        result = calculate(data)
    
    # [OK] Vérification ajoutée
    if result is None:
        return None
    return result.value

# ÉTAPE 12: Re-lancer l'analyse
# ──────────────────────────────
# Sauvegardez votre fichier, puis dans le terminal:

sonar-scanner -Dsonar.token=VOTRE_TOKEN_ICI

# Attendez la fin de l'analyse...
# Retournez sur http://localhost:9000

# Votre dashboard est mis à jour:
# - Bugs: 8 -> 7 (un de moins!)
# - Vous voyez l'amélioration dans l'historique

# [BRAVO] FÉLICITATIONS!
# Vous venez de:
# [OK] Installer SonarQube
# [OK] Créer votre premier projet
# [OK] Lancer votre première analyse
# [OK] Comprendre les résultats
# [OK] Corriger votre premier bug
# [OK] Améliorer la qualité de votre code!

# === PROCHAINES ÉTAPES ===

# Maintenant que vous avez compris les bases:
# 1. Corrigez les autres bugs un par un
# 2. Explorez les Code Smells (cliquez dessus)
# 3. Ajoutez des tests pour augmenter le Coverage
# 4. Configurez l'intégration avec Git (section CI/CD plus bas)
# 5. Définissez une Quality Gate pour votre équipe


[OK] CONCEPTS FONDAMENTAUX EXPLIQUÉS EN DÉTAIL

# === 1. LES TROIS TYPES D'ISSUES ===

# [BUG] BUG - Explication détaillée
# ─────────────────────────────

# Définition simple:
# Un bug est une erreur dans votre code qui peut causer un dysfonctionnement

# Exemple 1: Division par zéro
# [X] Code problématique:
def moyenne(nombres):
    total = sum(nombres)
    return total / len(nombres)  # Crash si nombres est vide!

# Utilisation:
moyenne([])  # [X] ERREUR: ZeroDivisionError

# [OK] Code corrigé:
def moyenne(nombres):
    if not nombres:  # Vérification ajoutée
        return 0
    total = sum(nombres)
    return total / len(nombres)

# Utilisation:
moyenne([])  # [OK] OK: retourne 0

# Exemple 2: Accès à un index inexistant
# [X] Code problématique:
def premier_element(liste):
    return liste[0]  # Crash si liste vide!

# [OK] Code corrigé:
def premier_element(liste):
    if not liste:
        return None
    return liste[0]

# Exemple 3: Variable non initialisée
# [X] Code problématique:
def calculer_prix(quantite):
    if quantite > 10:
        prix = 100
    # Si quantite <= 10, prix n'existe pas!
    return prix * quantite  # [X] Erreur possible

# [OK] Code corrigé:
def calculer_prix(quantite):
    prix = 120  # Initialisé par défaut
    if quantite > 10:
        prix = 100
    return prix * quantite

# Pourquoi c'est grave?
# -> Votre application peut crasher en production
# -> Les utilisateurs perdent leurs données
# -> Votre réputation est affectée

# [VERROUILLE] VULNERABILITY - Explication détaillée
# ────────────────────────────────────────

# Définition simple:
# Une faille de sécurité qu'un attaquant peut exploiter

# Exemple 1: SQL Injection
# [X] Code dangereux:
def get_user(username):
    query = f"SELECT * FROM users WHERE name = '{username}'"
    cursor.execute(query)
    
# Attaque possible:
# username = "admin' OR '1'='1"
# Query devient: SELECT * FROM users WHERE name = 'admin' OR '1'='1'
# -> Retourne TOUS les utilisateurs! [!]

# [OK] Code sécurisé:
def get_user(username):
    query = "SELECT * FROM users WHERE name = %s"
    cursor.execute(query, (username,))  # Paramètre escapé automatiquement

# Exemple 2: Mot de passe en clair
# [X] Code dangereux:
password = "MonMotDePasse123"  # En dur dans le code!
db_password = "root"           # Visible par tous!

# [OK] Code sécurisé:
import os
password = os.environ.get("APP_PASSWORD")  # Variable d'environnement
db_password = os.environ.get("DB_PASSWORD")

# Exemple 3: XSS (Cross-Site Scripting)
# [X] Code dangereux (Flask):
from flask import request
@app.route('/hello')
def hello():
    name = request.args.get('name')
    return f"<h1>Hello {name}</h1>"  # [X] Injection possible!

# Attaque possible:
# URL: /hello?name=<script>alert('Hacké!')</script>
# -> Script exécuté dans le navigateur!

# [OK] Code sécurisé:
from flask import request, escape
@app.route('/hello')
def hello():
    name = request.args.get('name')
    return f"<h1>Hello {escape(name)}</h1>"  # [OK] Échappé

# Pourquoi c'est grave?
# -> Vos données peuvent être volées
# -> Votre site peut être piraté
# -> Amendes RGPD (jusqu'à 4% du CA!)
# -> Poursuites judiciaires possibles

# [NETTOYAGE] CODE SMELL - Explication détaillée
# ──────────────────────────────────────

# Définition simple:
# Code qui fonctionne MAIS sera difficile à maintenir plus tard

# Exemple 1: Fonction trop longue
# [X] Code smell:
def traiter_commande(commande):
    # 200 lignes de code ici...
    # Impossible de comprendre ce que ça fait!
    # Difficile de tester
    # Difficile de modifier
    pass

# [OK] Code propre:
def traiter_commande(commande):
    valider_commande(commande)
    calculer_total(commande)
    appliquer_reduction(commande)
    envoyer_confirmation(commande)

# Chaque fonction fait UNE chose et est facile à comprendre

# Exemple 2: Code dupliqué
# [X] Code smell:
def calculer_prix_produit_a(quantite):
    prix_unitaire = 10
    if quantite > 100:
        reduction = 0.1
    else:
        reduction = 0
    return prix_unitaire * quantite * (1 - reduction)

def calculer_prix_produit_b(quantite):
    prix_unitaire = 20
    if quantite > 100:
        reduction = 0.1
    else:
        reduction = 0
    return prix_unitaire * quantite * (1 - reduction)

# [OK] Code propre (mutualisé):
def calculer_prix(prix_unitaire, quantite):
    reduction = 0.1 if quantite > 100 else 0
    return prix_unitaire * quantite * (1 - reduction)

def calculer_prix_produit_a(quantite):
    return calculer_prix(10, quantite)

def calculer_prix_produit_b(quantite):
    return calculer_prix(20, quantite)

# Exemple 3: Variables mal nommées
# [X] Code smell:
def f(x, y):
    z = x * y
    if z > 1000:
        z = z * 0.9
    return z

# Que fait cette fonction? [REFLEXION] Impossible à dire!

# [OK] Code propre:
def calculer_prix_avec_reduction(prix_unitaire, quantite):
    prix_total = prix_unitaire * quantite
    if prix_total > 1000:
        prix_total = prix_total * 0.9  # 10% de réduction
    return prix_total

# Maintenant c'est clair!

# Pourquoi c'est un problème?
# -> Le prochain développeur perd du temps à comprendre
# -> Les bugs sont plus difficiles à trouver
# -> Les modifications prennent plus de temps
# -> Le code devient "legacy" rapidement

# === 2. COVERAGE (COUVERTURE DE TESTS) ===

# Qu'est-ce que c'est?
# ────────────────────
# Le Coverage mesure quel pourcentage de votre code est testé automatiquement

# Exemple concret:
# Vous avez ce code:

def diviser(a, b):
    if b == 0:
        return None
    return a / b

# Vous avez ce test:
def test_diviser():
    assert diviser(10, 2) == 5  # Teste seulement le cas normal

# Coverage: 66% (2 lignes sur 3 testées)
# Ligne non testée: "if b == 0:" et "return None"

# Test complet:
def test_diviser():
    assert diviser(10, 2) == 5      # Cas normal
    assert diviser(10, 0) is None   # Cas division par zéro

# Coverage: 100% (toutes les lignes testées)

# Visualisation du Coverage:
# ─────────────────────────

# Dans SonarQube, les lignes sont colorées:
# [OK] VERT: Ligne testée
# [X] ROUGE: Ligne NON testée
# [JAUNE] JAUNE: Ligne partiellement testée (if avec un seul cas testé)

# Exemple visuel:
# 1 | def calculer_remise(prix, code):
# 2 |     if code == "VIP":              [OK] Testée
# 3 |         return prix * 0.8          [OK] Testée
# 4 |     elif code == "NORMAL":         [X] NON testée
# 5 |         return prix * 0.9          [X] NON testée
# 6 |     return prix                    [OK] Testée

# Coverage: 50% (3 lignes sur 6)

# Pourquoi c'est important?
# ─────────────────────────
# [X] Sans tests (Coverage 0%):
# - Vous modifiez du code
# - Vous cassez quelque chose sans le savoir
# - Bug découvert en production
# - Panique! [!]

# [OK] Avec tests (Coverage 80%+):
# - Vous modifiez du code
# - Les tests s'exécutent automatiquement
# - Si quelque chose casse, vous le savez immédiatement
# - Vous corrigez avant production
# - Tranquillité d'esprit [SMILING_FACE_WITH_SMILING_EYES]

# Objectif réaliste:
# - Nouveau code: 80% minimum
# - Code legacy: 60-70% acceptable
# - Code critique: 90%+ recommandé

# === 3. QUALITY GATE (PORTE DE QUALITÉ) ===

# Analogie du monde réel:
# ──────────────────────
# Imaginez un contrôle technique de voiture:
# - [OK] Freins OK
# - [OK] Feux OK
# - [X] Pneus usés -> REFUSÉ

# C'est pareil avec Quality Gate:
# - [OK] Coverage >= 80%
# - [OK] Bugs = 0
# - [X] Duplications > 5% -> REFUSÉ

# Exemple concret:
# ───────────────

# Votre Quality Gate "Strict Production":
# ┌────────────────────────────────────────┐
# │  Condition                | Seuil      │
# ├────────────────────────────────────────┤
# │  New Coverage             | >= 80%     │
# │  New Bugs                 | = 0        │
# │  New Vulnerabilities      | = 0        │
# │  New Code Smells          | <= 5       │
# │  New Duplications         | <= 3%      │
# └────────────────────────────────────────┘

# Vous lancez une analyse, résultats:
# - New Coverage: 75% [X] (moins que 80%)
# - New Bugs: 0 [OK]
# - New Vulnerabilities: 0 [OK]
# - New Code Smells: 3 [OK]
# - New Duplications: 2% [OK]

# Quality Gate: [X] FAILED (à cause du coverage)
# -> Vous NE POUVEZ PAS déployer en production
# -> Vous devez ajouter des tests pour atteindre 80%

# Après avoir ajouté des tests:
# - New Coverage: 82% [OK]

# Quality Gate: [OK] PASSED
# -> Vous pouvez déployer en production!

# Pourquoi c'est puissant?
# ───────────────────────
# Sans Quality Gate:
# - Développeur: "J'ai fini, je déploie"
# - 5 bugs en production
# - Clients mécontents

# Avec Quality Gate:
# - Développeur: "J'ai fini, je déploie"
# - Quality Gate: [X] STOP! 3 bugs détectés
# - Développeur corrige les bugs
# - Quality Gate: [OK] OK, tu peux déployer
# - 0 bugs en production
# - Clients contents

# === 4. TECHNICAL DEBT (DETTE TECHNIQUE) ===

# Analogie du monde réel:
# ──────────────────────
# Vous avez une maison:
# - Petit trou dans le toit: 30 minutes pour réparer
# - Vous ignorez le problème
# - Le trou s'agrandit
# - L'eau s'infiltre
# - Moisissure apparaît
# - Maintenant: 3 jours et 5000€ pour réparer!

# C'est pareil avec le code:
# - Petit code smell: 10 minutes pour corriger
# - Vous l'ignorez
# - Vous ajoutez du code autour
# - Le code smell se propage
# - Maintenant: 2 jours pour refactoriser!

# Comment SonarQube calcule la dette:
# ──────────────────────────────────

# Pour chaque issue, SonarQube estime le temps de correction:
# - Bug simple: 5 minutes
# - Bug complexe: 30 minutes
# - Code smell simple: 5 minutes
# - Code smell complexe: 1 heure
# - Vulnérabilité: 30 minutes

# Exemple:
# Votre projet a:
# - 5 bugs simples: 5 × 5min = 25min
# - 2 bugs complexes: 2 × 30min = 1h
# - 30 code smells: 30 × 5min = 2h30
# Total: 3h 55min de dette technique

# SonarQube affiche:
# "Technical Debt: 3h 55min"
# "Technical Debt Ratio: 2.5%"

# Le ratio se calcule:
# Ratio = Dette / Temps de développement du projet
# Si votre projet = 160h de développement:
# Ratio = 3h55 / 160h = 2.5%

# Interprétation du ratio:
# - <= 5%: [OK] Excellent
# - 5-10%: [ATTENTION] Attention
# - 10-20%: [X] Problématique
# - > 20%: [ALERTE] Critique!

# === 5. NEW CODE vs OVERALL CODE ===

# Concept du "Fix the Water Leak":
# ───────────────────────────────

# Imaginez un bateau qui prend l'eau:
# Option 1: Écoper l'eau (corriger tout l'ancien code)
# -> Épuisant, prend des mois, décourageant

# Option 2: Boucher le trou (assurer que le nouveau code est propre)
# -> Puis écoper progressivement
# -> Réaliste et motivant!

# SonarQube applique cette philosophie:
# - Overall Code: Tout le code (ancien + nouveau)
# - New Code: Seulement le code ajouté/modifié récemment

# Exemple concret:
# ───────────────

# Votre projet legacy (1 an):
# - 10,000 lignes
# - 50 bugs
# - Coverage: 30%
# - Situation: [!] Catastrophique!

# Vous ajoutez une nouvelle fonctionnalité (100 lignes):
# New Code:
# - 0 bugs [OK]
# - Coverage: 85% [OK]
# - Pas de duplication [OK]

# Overall Code (après):
# - 10,100 lignes
# - 50 bugs (inchangé)
# - Coverage: 31% (légère amélioration)

# Quality Gate focus sur New Code:
# [OK] PASSED car votre nouveau code est propre!

# Après 6 mois avec cette approche:
# - Nouveau code: Toujours propre (80%+ coverage, 0 bugs)
# - Ancien code: Progressivement amélioré quand vous le touchez
# - Moral de l'équipe: [OK] Excellent!
# - Situation globale: En constante amélioration [HAUSSE]

# === 6. RATINGS (NOTES A à E) ===

# Comment SonarQube note votre code:
# ─────────────────────────────────

# Pour chaque catégorie (Reliability, Security, Maintainability),
# SonarQube compte les issues et leur sévérité:

# RELIABILITY (Fiabilité - Bugs):
# ─────────────────────────────
# * A: 0 bugs
# * B: au moins 1 bug MINOR
# * C: au moins 1 bug MAJOR
# * D: au moins 1 bug CRITICAL
# * E: au moins 1 bug BLOCKER

# Exemple 1:
# Votre code: 5 bugs MINOR, 0 autres
# Rating: B (car au moins 1 MINOR)

# Exemple 2:
# Votre code: 3 bugs MINOR, 1 bug MAJOR
# Rating: C (car au moins 1 MAJOR, peu importe les MINOR)

# Exemple 3:
# Votre code: 0 bugs
# Rating: A (perfection!)

# SECURITY (Sécurité - Vulnerabilities):
# ────────────────────────────────────
# Même logique que Reliability
# * A: 0 vulnérabilités
# * B: au moins 1 MINOR
# * C: au moins 1 MAJOR
# * D: au moins 1 CRITICAL
# * E: au moins 1 BLOCKER

# MAINTAINABILITY (Maintenabilité - Technical Debt Ratio):
# ───────────────────────────────────────────────────────
# Basé sur le ratio dette/temps de développement:
# * A: <= 5%
# * B: 6-10%
# * C: 11-20%
# * D: 21-50%
# * E: > 50%

# Exemple:
# Projet de 100h de développement
# Dette technique: 8h
# Ratio: 8/100 = 8%
# Rating: B

# Objectif pour un projet professionnel:
# ───────────────────────────────────
# [OK] Reliability: A (0 bugs)
# [OK] Security: A (0 vulnérabilités)
# [OK] Maintainability: A ou B (< 10% dette)
# [OK] Coverage: 80%+
# [OK] Duplications: < 3%


[OK] INSTALLATION SONARQUBE (GUIDE DÉTAILLÉ POUR DÉBUTANTS)

# === COMPRENDRE L'ARCHITECTURE AVANT D'INSTALLER ===

# SonarQube a 3 composants principaux:

# 1⃣ SERVEUR SONARQUBE
# Quoi: L'application web qui analyse et stocke les résultats
# Où: Sur votre machine ou un serveur
# Analogie: C'est comme un site web que vous hébergez

# 2⃣ BASE DE DONNÉES
# Quoi: Stocke tous les résultats d'analyses
# Où: Sur le même serveur que SonarQube
# Options: PostgreSQL (recommandé), H2 (développement seulement)
# Analogie: C'est comme un classeur qui garde tous vos documents

# 3⃣ SCANNER
# Quoi: Programme qui lit votre code et l'envoie au serveur
# Où: Sur votre machine de développement
# Analogie: C'est comme un scanner de documents qui numérise vos papiers

# Schéma visuel:
# ┌─────────────────┐
# │  Votre Machine  │
# │                 │
# │  [DOSSIER] Votre Code  │
# │       v         │
# │  [RECHERCHE] Scanner     │────envoie───->  ┌─────────────────┐
# │                 │                │  Serveur        │
# └─────────────────┘                │  SonarQube      │
#                                    │       v         │
#                                    │  [SAUVEGARDE] Base de     │
#                                    │     données     │
#                                    │       v         │
#                                    │  [GRAPHIQUE] Dashboard   │
#                                    │  (navigateur)   │
#                                    └─────────────────┘

# === MÉTHODE 1: INSTALLATION AVEC DOCKER (LA PLUS SIMPLE) ===

# Pourquoi Docker?
# [OK] Installation en 1 commande
# [OK] Pas besoin d'installer Java
# [OK] Pas besoin de configurer PostgreSQL manuellement
# [OK] Facile à supprimer après (propre)
# [X] Nécessite Docker installé

# ÉTAPE 1: Installer Docker (si pas déjà fait)
# ────────────────────────────────────────────

# Mac:
# Télécharger Docker Desktop: https://www.docker.com/products/docker-desktop

# Windows:
# Télécharger Docker Desktop: https://www.docker.com/products/docker-desktop

# Linux (Ubuntu/Debian):
sudo apt update
sudo apt install docker.io
sudo systemctl start docker
sudo systemctl enable docker

# Vérifier que Docker fonctionne:
docker --version
# Vous devriez voir: Docker version 24.0.x

# ÉTAPE 2: Lancer SonarQube (version simple H2)
# ──────────────────────────────────────────────

# [ATTENTION] NOTE: Cette version utilise H2 (base temporaire)
# OK pour: Tester, apprendre, développement
# PAS OK pour: Production, usage en équipe

docker run -d \
  --name sonarqube \
  -p 9000:9000 \
  sonarqube:lts-community

# Explication de chaque partie:
# - docker run: Lance un conteneur
# - -d: Détaché (tourne en arrière-plan)
# - --name sonarqube: Nom du conteneur (pour le retrouver facilement)
# - -p 9000:9000: Port (votre machine:conteneur)
# - sonarqube:lts-community: Image à utiliser (version gratuite stable)

# Attendez 2-3 minutes que SonarQube démarre
# Suivez les logs pour voir la progression:
docker logs -f sonarqube

# Vous verrez défiler:
# SonarQube is operational  <- Attendez ce message!

# Appuyez sur Ctrl+C pour quitter les logs

# Vérifier que SonarQube est prêt:
curl http://localhost:9000/api/system/status
# Résultat attendu: {"status":"UP"}

# ÉTAPE 3: Lancer SonarQube avec PostgreSQL (RECOMMANDÉ)
# ───────────────────────────────────────────────────────

# Pourquoi PostgreSQL?
# [OK] Base de données persistante (données conservées)
# [OK] Performance meilleure
# [OK] OK pour production
# [OK] Recommandé par SonarQube

# Créer un fichier docker-compose.yml:
nano docker-compose.yml

# Coller ce contenu:

# Java (OpenJDK 17 recommandé)
java -version                           # Vérifier version

# Ubuntu/Debian
sudo apt update
sudo apt install openjdk-17-jdk

# CentOS/RHEL
sudo yum install java-17-openjdk

# Mac
brew install openjdk@17

# Base de données (optionnel, H2 incluse par défaut)
# PostgreSQL (recommandé), Oracle, SQL Server

# === TÉLÉCHARGEMENT ===

# Télécharger depuis https://www.sonarqube.org/downloads/
wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-10.3.0.82913.zip

# Ou version LTS
wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.9.3.79811.zip

# Décompresser
unzip sonarqube-*.zip
cd sonarqube-*

# === CONFIGURATION DE BASE ===

# Structure des dossiers
sonarqube/
├── bin/          # Scripts de démarrage
│   ├── linux-x86-64/
│   ├── macosx-universal-64/
│   └── windows-x86-64/
├── conf/         # Fichiers de configuration
├── data/         # Données (H2, Elasticsearch)
├── extensions/   # Plugins
├── lib/          # Bibliothèques
├── logs/         # Logs
└── web/          # Interface web

# Éditer la configuration
nano conf/sonar.properties

# Configuration minimale
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube
sonar.web.host=0.0.0.0
sonar.web.port=9000

# === DÉMARRAGE ===

# Linux
./bin/linux-x86-64/sonar.sh start
./bin/linux-x86-64/sonar.sh status
./bin/linux-x86-64/sonar.sh stop
./bin/linux-x86-64/sonar.sh restart

# Mac
./bin/macosx-universal-64/sonar.sh start

# Windows
bin\windows-x86-64\StartSonar.bat

# Logs
tail -f logs/sonar.log
tail -f logs/web.log
tail -f logs/ce.log        # Compute Engine
tail -f logs/es.log        # Elasticsearch

# Accéder à l'interface
# http://localhost:9000
# Login par défaut: admin / admin
# Changez le mot de passe immédiatement!

# === INSTALLATION AVEC DOCKER ===

# Docker simple (avec H2, non recommandé pour production)
docker run -d --name sonarqube -p 9000:9000 sonarqube:lts-community

# Avec PostgreSQL
docker-compose.yml:
version: "3"
services:
  sonarqube:
    image: sonarqube:lts-community
    depends_on:
      - db
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: sonar
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
    ports:
      - "9000:9000"
  db:
    image: postgres:14
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar
      POSTGRES_DB: sonar
    volumes:
      - postgresql:/var/lib/postgresql
      - postgresql_data:/var/lib/postgresql/data

volumes:
  sonarqube_data:
  sonarqube_extensions:
  sonarqube_logs:
  postgresql:
  postgresql_data:

# Démarrer
docker-compose up -d

# Arrêter
docker-compose down


[OK] CONFIGURATION POSTGRESQL (RECOMMANDÉ)

# Installer PostgreSQL
sudo apt install postgresql postgresql-contrib

# Se connecter à PostgreSQL
sudo -u postgres psql

# Créer base et utilisateur
CREATE DATABASE sonarqube;
CREATE USER sonar WITH ENCRYPTED PASSWORD 'sonar';
GRANT ALL PRIVILEGES ON DATABASE sonarqube TO sonar;
ALTER DATABASE sonarqube OWNER TO sonar;
\q

# Éditer postgresql.conf (optionnel)
# max_connections = 300
# shared_buffers = 256MB

# Redémarrer PostgreSQL
sudo systemctl restart postgresql

# Configuration dans sonar.properties
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube


[OK] SONARQUBE SCANNER - INSTALLATION

# === SCANNER CLI (LIGNE DE COMMANDE) ===

# Télécharger
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip

# Décompresser
unzip sonar-scanner-cli-*.zip
sudo mv sonar-scanner-* /opt/sonar-scanner

# Ajouter au PATH
export PATH=$PATH:/opt/sonar-scanner/bin

# Rendre permanent (ajoutez à ~/.bashrc ou ~/.zshrc)
echo 'export PATH=$PATH:/opt/sonar-scanner/bin' >> ~/.bashrc
source ~/.bashrc

# Vérifier installation
sonar-scanner --version

# Configuration globale
nano /opt/sonar-scanner/conf/sonar-scanner.properties

# Configuration de base
sonar.host.url=http://localhost:9000
sonar.sourceEncoding=UTF-8

# === INSTALLATION AVEC HOMEBREW (MAC) ===
brew install sonar-scanner

# === INSTALLATION AVEC CHOCOLATEY (WINDOWS) ===
choco install sonar-scanner

# === INSTALLATION AVEC NPM ===
npm install -g sonarqube-scanner


[OK] PREMIERS PAS - ANALYSER UN PROJET

# === CRÉER UN TOKEN D'AUTHENTIFICATION ===

# 1. Aller sur http://localhost:9000
# 2. Se connecter (admin/admin)
# 3. Mon Compte > Sécurité > Générer un Token
# 4. Nom: "my-project-token"
# 5. Type: User Token ou Project Analysis Token
# 6. Copier le token (visible une seule fois!)

# Exemple de token: squ_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8

# === CRÉER UN PROJET ===

# Interface web
# 1. Projects > Create Project
# 2. Manually > Project key: "my-project"
# 3. Display name: "My Project"
# 4. Suivre les instructions

# === FICHIER sonar-project.properties ===

# Créer à la racine du projet
nano sonar-project.properties

# Configuration minimale
sonar.projectKey=my-project
sonar.projectName=My Project
sonar.projectVersion=1.0
sonar.sources=.
sonar.sourceEncoding=UTF-8

# Configuration complète
sonar.projectKey=my-awesome-project
sonar.projectName=My Awesome Project
sonar.projectVersion=1.0.0
sonar.sources=src
sonar.tests=tests
sonar.sourceEncoding=UTF-8
sonar.exclusions=**/migrations/**,**/tests/**,**/__pycache__/**
sonar.test.exclusions=**/tests/**
sonar.python.version=3.11

# === LANCER L'ANALYSE ===

# Avec token dans la commande
sonar-scanner \
  -Dsonar.projectKey=my-project \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.token=squ_votre_token_ici

# Avec fichier sonar-project.properties
sonar-scanner -Dsonar.token=squ_votre_token_ici

# Avec login/password (déprécié)
sonar-scanner \
  -Dsonar.projectKey=my-project \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=admin \
  -Dsonar.password=admin

# Logs détaillés
sonar-scanner -X -Dsonar.token=squ_votre_token_ici

# === VOIR LES RÉSULTATS ===
# Aller sur http://localhost:9000/dashboard?id=my-project


[OK] CONFIGURATION PROJET PYTHON

# sonar-project.properties pour Python
sonar.projectKey=python-project
sonar.projectName=Python Project
sonar.projectVersion=1.0
sonar.sources=src
sonar.tests=tests
sonar.sourceEncoding=UTF-8

# Version Python
sonar.python.version=3.11

# Coverage (pytest-cov)
sonar.python.coverage.reportPaths=coverage.xml

# Exclusions
sonar.exclusions=**/migrations/**,**/venv/**,**/__pycache__/**,**/node_modules/**
sonar.test.exclusions=**/tests/**,**/*_test.py,**/test_*.py

# Inclure seulement certains fichiers
sonar.inclusions=**/*.py

# Ignorer duplications dans certains fichiers
sonar.cpd.exclusions=**/migrations/**,**/tests/**

# === GÉNÉRER COVERAGE ===

# Avec pytest-cov
pip install pytest pytest-cov

# Générer rapport XML
pytest --cov=src --cov-report=xml

# Générer rapport HTML
pytest --cov=src --cov-report=html

# Coverage.py direct
coverage run -m pytest
coverage xml

# Lancer analyse avec coverage
sonar-scanner -Dsonar.token=squ_votre_token_ici


[OK] CONFIGURATION PROJET JAVASCRIPT/TYPESCRIPT

# sonar-project.properties
sonar.projectKey=js-project
sonar.projectName=JavaScript Project
sonar.sources=src
sonar.tests=tests
sonar.sourceEncoding=UTF-8

# JavaScript/TypeScript
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.typescript.lcov.reportPaths=coverage/lcov.info

# Node modules
sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/**

# === AVEC NPM/YARN ===

# Installer scanner
npm install --save-dev sonarqube-scanner

# package.json
{
  "scripts": {
    "sonar": "sonar-scanner"
  }
}

# Lancer
npm run sonar

# === COVERAGE AVEC JEST ===

# package.json
{
  "jest": {
    "collectCoverage": true,
    "coverageReporters": ["lcov", "text"]
  }
}

# Générer coverage
npm test -- --coverage

# Analyser
sonar-scanner -Dsonar.token=squ_votre_token_ici


[OK] CONFIGURATION PROJET JAVA

# sonar-project.properties
sonar.projectKey=java-project
sonar.projectName=Java Project
sonar.sources=src/main/java
sonar.tests=src/test/java
sonar.java.binaries=target/classes
sonar.java.test.binaries=target/test-classes
sonar.java.libraries=target/dependency/*.jar

# JaCoCo coverage
sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml

# === AVEC MAVEN ===

# pom.xml
<properties>
  <sonar.host.url>http://localhost:9000</sonar.host.url>
</properties>

# Analyser
mvn clean verify sonar:sonar \
  -Dsonar.token=squ_votre_token_ici

# === AVEC GRADLE ===

# build.gradle
plugins {
  id "org.sonarqube" version "4.4.1.3373"
}

sonarqube {
  properties {
    property "sonar.projectKey", "java-project"
    property "sonar.host.url", "http://localhost:9000"
  }
}

# Analyser
./gradlew sonarqube \
  -Dsonar.token=squ_votre_token_ici


[OK] COMPRENDRE LES RÉSULTATS

# === DASHBOARD PROJET ===

# Métriques principales
# - Reliability: Bugs (A à E)
# - Security: Vulnérabilités (A à E)
# - Security Review: Hotspots (A à E)
# - Maintainability: Code Smells (A à E)
# - Coverage: % de code testé
# - Duplications: % de code dupliqué

# === RATING GRADES ===

# A = Excellent (0-5 issues)
# B = Bon (6-10 issues)
# C = Moyen (11-15 issues)
# D = Pauvre (16-20 issues)
# E = Très pauvre (21+ issues)

# Dette technique
# - Minutes/heures pour corriger les issues
# - Ratio: Dette / Temps de développement

# === TYPES D'ISSUES ===

# Bug (Reliability)
# - Erreur dans le code
# - Peut causer un crash ou comportement incorrect
# - Exemple: Division par zéro, null pointer

# Vulnérabilité (Security)
# - Faille de sécurité
# - Peut être exploitée par un attaquant
# - Exemple: Injection SQL, XSS

# Code Smell (Maintainability)
# - Code fonctionnel mais difficile à maintenir
# - Augmente la dette technique
# - Exemple: Fonction trop longue, code dupliqué

# Security Hotspot
# - Code sensible nécessitant une revue
# - Pas forcément une vulnérabilité
# - Exemple: Gestion de mots de passe, authentification

# === SÉVÉRITÉ ===

# BLOCKER: Doit être corrigé immédiatement
# CRITICAL: Haute priorité
# MAJOR: Priorité moyenne
# MINOR: Basse priorité
# INFO: Information


[OK] GÉRER LES ISSUES

# === FILTRER LES ISSUES ===

# Par type
# Projects > Issues > Type: Bug/Vulnerability/Code Smell

# Par sévérité
# Severity: Blocker/Critical/Major/Minor/Info

# Par status
# Status: Open/Confirmed/Reopened/Resolved/Closed

# Par assigné
# Assigned to: Me/Unassigned/Specific user

# Par date
# Creation Date: Last week/Last month/Custom

# Par règle
# Rule: Specific rule

# Par tag
# Tags: convention/error-prone/security

# === ACTIONS SUR LES ISSUES ===

# Assigner
# Cliquer sur issue > Assign > Choisir utilisateur

# Confirmer
# Cliquer sur issue > Confirm
# Indique que l'issue est réelle

# Résoudre
# Cliquer sur issue > Resolve
# - Fixed: Corrigé
# - False Positive: Faux positif
# - Won't Fix: Ne sera pas corrigé

# Réouvrir
# Cliquer sur issue > Reopen

# Commenter
# Cliquer sur issue > Add comment

# Changer sévérité (admin)
# Cliquer sur issue > Change severity

# === BULK OPERATIONS ===

# Sélectionner plusieurs issues
# Checkbox > Bulk Change
# - Assign
# - Set Severity
# - Resolve
# - Add Tags


[OK] QUALITY GATES (PORTES DE QUALITÉ)

# === QU'EST-CE QU'UNE QUALITY GATE ? ===

# Ensemble de conditions que le code doit respecter
# Détermine si le code peut être déployé (Pass/Fail)

# Quality Gate par défaut: "Sonar way"
# - Coverage sur nouveau code >= 80%
# - Duplications sur nouveau code <= 3%
# - Maintainability Rating sur nouveau code >= A
# - Reliability Rating sur nouveau code >= A
# - Security Rating sur nouveau code >= A
# - Security Hotspots Reviewed >= 100%

# === CRÉER UNE QUALITY GATE ===

# Administration > Quality Gates > Create

# Nom: "Strict Quality Gate"

# Conditions possibles:
# - Coverage: % de couverture de tests
# - Duplicated Lines: % de lignes dupliquées
# - Maintainability Rating: A à E
# - Reliability Rating: A à E
# - Security Rating: A à E
# - Security Hotspots Reviewed: % hotspots revus
# - New Bugs: Nombre de nouveaux bugs
# - New Vulnerabilities: Nouvelles vulnérabilités
# - New Code Smells: Nouveaux code smells

# Exemple de conditions strictes:
# Coverage on New Code >= 90%
# Duplicated Lines on New Code <= 2%
# Maintainability Rating on New Code = A
# Reliability Rating on New Code = A
# Security Rating on New Code = A
# New Bugs = 0
# New Vulnerabilities = 0

# === APPLIQUER UNE QUALITY GATE ===

# À un projet
# Project Settings > Quality Gate > Select gate

# Par défaut (tous nouveaux projets)
# Administration > Quality Gates > Set as Default

# === VÉRIFIER STATUS QUALITY GATE ===

# Dans le dashboard projet
# Status: Passed [OK] ou Failed [X]

# En ligne de commande
sonar-scanner -Dsonar.qualitygate.wait=true

# Retourne exit code 0 si passed, 1 si failed


[OK] RÈGLES (RULES)

# === EXPLORER LES RÈGLES ===

# Quality Profiles > Rules
# Plus de 5000 règles disponibles

# Filtrer par:
# - Language: Python, Java, JavaScript...
# - Type: Bug, Vulnerability, Code Smell
# - Severity: Blocker, Critical, Major...
# - Status: Beta, Deprecated, Ready
# - Tag: convention, error-prone, security...

# === DÉTAILS D'UNE RÈGLE ===

# Cliquer sur une règle pour voir:
# - Description complète
# - Exemple de code non-conforme
# - Exemple de code conforme
# - Exceptions
# - Références (CWE, CERT, OWASP)

# === ACTIVER/DÉSACTIVER UNE RÈGLE ===

# Quality Profiles > Select profile
# Rules > Search rule
# Activate / Deactivate

# === CHANGER LA SÉVÉRITÉ ===

# Dans le quality profile
# Rules > Select rule > Change severity

# === CRÉER UNE RÈGLE CUSTOM ===

# Community Edition: Non disponible
# Developer Edition+: Custom rules disponibles

# Règles XPath (Python, XML)
# Rules > Create
# - Key: custom-rule-1
# - Name: My Custom Rule
# - Type: Code Smell
# - Severity: Major
# - XPath expression


[OK] QUALITY PROFILES

# === QU'EST-CE QU'UN QUALITY PROFILE ? ===

# Collection de règles activées pour un langage
# Détermine quelles règles sont appliquées lors de l'analyse

# Profiles par défaut:
# - Sonar way (recommandé)
# - Sonar way Recommended (moins strict)

# === CRÉER UN QUALITY PROFILE ===

# Quality Profiles > Create

# Nom: "My Python Profile"
# Langage: Python
# Parent: Sonar way (hérite des règles)

# === PERSONNALISER UN PROFILE ===

# Quality Profiles > Select profile

# Activer/désactiver règles
# Rules > Filter > Activate/Deactivate

# Changer sévérités
# Rules > Select rule > Change severity

# Copier un profile
# Actions > Copy

# Comparer deux profiles
# Actions > Compare > Select profile

# === APPLIQUER UN PROFILE ===

# À un projet
# Project Settings > Quality Profiles > Select profile

# Par défaut (tous projets)
# Quality Profiles > Set as Default

# === VERSIONNER UN PROFILE ===

# Quality Profiles > Select profile
# Changelog: Voir historique des modifications

# Backup/Restore
# Actions > Backup
# Télécharge fichier XML

# Restore
# Create > Restore Profile > Upload XML


[OK] INTÉGRATION CI/CD

# === GITHUB ACTIONS ===

# .github/workflows/sonar.yml
name: SonarQube Analysis

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  sonarqube:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0  # Important pour l'analyse

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          pip install pytest pytest-cov

      - name: Run tests with coverage
        run: pytest --cov=src --cov-report=xml

      - name: SonarQube Scan
        uses: sonarsource/sonarqube-scan-action@master
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}

      - name: SonarQube Quality Gate Check
        uses: sonarsource/sonarqube-quality-gate-action@master
        timeout-minutes: 5
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

# Secrets à configurer:
# - SONAR_TOKEN: Token d'authentification
# - SONAR_HOST_URL: URL SonarQube (ex: http://sonar.example.com)

# === GITLAB CI ===

# .gitlab-ci.yml
sonarqube-check:
  stage: test
  image: 
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""]
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script:
    - sonar-scanner
  only:
    - main
    - merge_requests

# Variables CI/CD à configurer:
# - SONAR_TOKEN
# - SONAR_HOST_URL

# === JENKINS ===

# Jenkinsfile
pipeline {
    agent any
    
    environment {
        SONAR_TOKEN = credentials('sonar-token')
    }
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        
        stage('Test') {
            steps {
                sh 'pytest --cov=src --cov-report=xml'
            }
        }
        
        stage('SonarQube Analysis') {
            steps {
                script {
                    def scannerHome = tool 'SonarScanner'
                    withSonarQubeEnv('SonarQube') {
                        sh "${scannerHome}/bin/sonar-scanner"
                    }
                }
            }
        }
        
        stage('Quality Gate') {
            steps {
                timeout(time: 5, unit: 'MINUTES') {
                    waitForQualityGate abortPipeline: true
                }
            }
        }
    }
}

# === AZURE DEVOPS ===

# azure-pipelines.yml
trigger:
  - main
  - develop

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.11'

- script: |
    pip install -r requirements.txt
    pytest --cov=src --cov-report=xml
  displayName: 'Run tests'

- task: SonarQubePrepare@5
  inputs:
    SonarQube: 'SonarQube-Connection'
    scannerMode: 'CLI'
    configMode: 'file'

- task: SonarQubeAnalyze@5

- task: SonarQubePublish@5
  inputs:
    pollingTimeoutSec: '300'


[OK] PULL REQUEST DECORATION

# === CONFIGURATION GITHUB ===

# Administration > Configuration > DevOps Platform Integrations
# GitHub > Add Configuration

# Configuration:
# - GitHub API URL: https://api.github.com
# - GitHub App ID: [votre app ID]
# - Private Key: [votre clé privée]

# Créer GitHub App:
# 1. GitHub > Settings > Developer settings > GitHub Apps
# 2. New GitHub App
# 3. Permissions:
#    - Checks: Read & Write
#    - Pull requests: Read & Write
#    - Contents: Read
# 4. Générer private key
# 5. Installer l'app sur votre organisation

# Dans le projet:
# Project Settings > Pull Request Decoration
# Configuration name: [votre config GitHub]
# Repository identifier: username/repo

# === CONFIGURATION GITLAB ===

# Administration > Configuration > DevOps Platform Integrations
# GitLab > Add Configuration

# Configuration:
# - GitLab API URL: https://gitlab.com/api/v4
# - Personal Access Token: [votre token]

# Token permissions:
# - api
# - read_user
# - write_repository

# Dans le projet:
# Project Settings > Pull Request Decoration
# Configuration name: [votre config GitLab]
# Project ID: [ID projet GitLab]

# === CONFIGURATION BITBUCKET ===

# Administration > Configuration > DevOps Platform Integrations
# Bitbucket > Add Configuration

# Suivre les mêmes étapes que GitHub

# === RÉSULTAT ===

# Dans les Pull Requests:
# - Commentaire automatique avec résumé
# - Status check (Pass/Fail)
# - Badges pour chaque métrique
# - Lien vers le dashboard SonarQube


[OK] BRANCHES & PULL REQUESTS (DEVELOPER EDITION+)

# === ANALYSE DE BRANCHES ===

# Analyser une branche
sonar-scanner \
  -Dsonar.branch.name=feature/new-feature \
  -Dsonar.token=squ_votre_token_ici

# Analyser main/master
sonar-scanner \
  -Dsonar.branch.name=main \
  -Dsonar.token=squ_votre_token_ici

# Voir les branches
# Project > Branches

# Comparer branches
# Branches > Select branch > Compare to another branch

# Supprimer une branche
# Branches > Delete branch

# === ANALYSE DE PULL REQUEST ===

# Analyser un PR
sonar-scanner \
  -Dsonar.pullrequest.key=123 \
  -Dsonar.pullrequest.branch=feature/new-feature \
  -Dsonar.pullrequest.base=main \
  -Dsonar.token=squ_votre_token_ici

# Automatique avec CI/CD
# GitHub Actions détecte automatiquement les PRs

# Résultats dans le PR
# - Commentaire avec métriques
# - Issues détectées dans le nouveau code
# - Status check Pass/Fail


[OK] ADMINISTRATION

# === GESTION DES UTILISATEURS ===

# Créer utilisateur
# Administration > Security > Users > Create User

# Groupes
# Administration > Security > Groups > Create Group

# Permissions:
# - Administer System: Administration globale
# - Administer Quality Profiles: Gérer quality profiles
# - Administer Quality Gates: Gérer quality gates
# - Create Projects: Créer projets
# - Browse: Voir projets publics
# - See Source Code: Voir code source

# Permissions par projet
# Project Settings > Permissions
# - Administer: Admin projet
# - Execute Analysis: Lancer analyse
# - Browse: Voir projet
# - See Source Code: Voir code

# === AUTHENTIFICATION ===

# LDAP
# Administration > Configuration > Security > LDAP

# SAML
# Administration > Configuration > Security > SAML

# GitHub OAuth
# Administration > Configuration > Security > GitHub

# GitLab OAuth
# Administration > Configuration > Security > GitLab

# === TOKENS ===

# User Tokens (par utilisateur)
# Mon Compte > Security > Generate Token

# Project Analysis Tokens (par projet)
# Project Settings > Analysis Method > Generate Token

# Global Analysis Tokens (admin)
# Administration > Security > Tokens > Generate Token

# === PLUGINS ===

# Installer plugin
# Administration > Marketplace > Plugins

# Plugins populaires:
# - Python: Inclus par défaut
# - Java: Inclus par défaut
# - JavaScript/TypeScript: Inclus par défaut
# - C/C++: Commercial
# - C#: Commercial
# - PHP: Commercial
# - Go: Commercial

# Installer manuellement
# 1. Télécharger .jar
# 2. Copier dans extensions/plugins/
# 3. Redémarrer SonarQube

# === MAINTENANCE ===

# Backup
# Base de données: pg_dump
# Extensions: Copier extensions/
# Configuration: Copier conf/

# Mise à jour
# 1. Backup
# 2. Télécharger nouvelle version
# 3. Arrêter SonarQube
# 4. Remplacer binaires
# 5. Démarrer SonarQube
# 6. Suivre migration

# Logs de maintenance
# Administration > System > System Info
# Administration > System > Update Center

# Nettoyage base de données
# Administration > Projects > Management
# Bulk delete inactive projects

# Purge snapshots anciens (automatique)
# Par défaut: conserve 30 jours d'historique


[OK] MÉTRIQUES DÉTAILLÉES

# === RELIABILITY (FIABILITÉ) ===

# Bugs
# - Erreurs dans le code
# - Peuvent causer des crashes

# Rating Calculation:
# A: 0 bugs
# B: au moins 1 bug mineur
# C: au moins 1 bug majeur
# D: au moins 1 bug critique
# E: au moins 1 bug bloquant

# Métriques associées:
# - Bugs: Nombre total de bugs
# - New Bugs: Nouveaux bugs
# - Reliability Remediation Effort: Temps pour corriger

# === SECURITY (SÉCURITÉ) ===

# Vulnérabilités
# - Failles de sécurité
# - Peuvent être exploitées

# Rating Calculation:
# A: 0 vulnérabilités
# B: au moins 1 vulnérabilité mineure
# C: au moins 1 vulnérabilité majeure
# D: au moins 1 vulnérabilité critique
# E: au moins 1 vulnérabilité bloquante

# Security Hotspots
# - Code sensible à revoir
# - Nécessite validation manuelle

# Métriques associées:
# - Vulnerabilities: Nombre de vulnérabilités
# - New Vulnerabilities: Nouvelles vulnérabilités
# - Security Hotspots: Nombre de hotspots
# - Security Hotspots Reviewed: % hotspots revus
# - Security Review Rating: Note globale

# === MAINTAINABILITY (MAINTENABILITÉ) ===

# Code Smells
# - Code difficile à maintenir
# - Augmente dette technique

# Technical Debt
# - Temps nécessaire pour corriger
# - Exprimé en jours/heures/minutes

# Rating Calculation (ratio dette/temps dev):
# A: <= 5%
# B: 6-10%
# C: 11-20%
# D: 21-50%
# E: > 50%

# Métriques associées:
# - Code Smells: Nombre de code smells
# - New Code Smells: Nouveaux code smells
# - Technical Debt: Dette totale
# - Technical Debt Ratio: Ratio dette/dev
# - Sqale Rating: Note maintenabilité

# === COVERAGE (COUVERTURE) ===

# Coverage
# - % de code testé par tests unitaires
# - Basé sur lignes couvertes

# Métriques associées:
# - Coverage: % couverture globale
# - New Coverage: Couverture nouveau code
# - Line Coverage: % lignes couvertes
# - Branch Coverage: % branches couvertes
# - Lines to Cover: Lignes à couvrir
# - Uncovered Lines: Lignes non couvertes
# - Conditions to Cover: Conditions à couvrir
# - Uncovered Conditions: Conditions non couvertes

# === DUPLICATIONS (DUPLICATIONS) ===

# Duplicated Code
# - Code copié-collé
# - Difficile à maintenir

# Métriques associées:
# - Duplicated Lines: Nombre de lignes dupliquées
# - Duplicated Lines Density: % lignes dupliquées
# - Duplicated Blocks: Nombre de blocs dupliqués
# - Duplicated Files: Nombre de fichiers avec duplications

# === SIZE (TAILLE) ===

# Métriques de taille
# - Lines: Lignes totales
# - Lines of Code: Lignes de code (hors commentaires)
# - Statements: Instructions
# - Functions: Nombre de fonctions
# - Classes: Nombre de classes
# - Files: Nombre de fichiers
# - Directories: Nombre de répertoires
# - Comment Lines: Lignes de commentaires
# - Comment Lines Density: % commentaires

# === COMPLEXITY (COMPLEXITÉ) ===

# Cyclomatic Complexity
# - Nombre de chemins d'exécution
# - Plus c'est haut, plus c'est complexe

# Métriques associées:
# - Complexity: Complexité totale
# - Cognitive Complexity: Complexité cognitive
# - Complexity per Function: Complexité moyenne
# - Complexity per File: Complexité par fichier


[OK] NEW CODE PERIOD (PÉRIODE NOUVEAU CODE)

# === QU'EST-CE QUE NEW CODE ? ===

# SonarQube distingue:
# - Overall Code: Tout le code
# - New Code: Code ajouté/modifié récemment

# Quality Gate s'applique principalement au New Code
# Focus sur "ne pas dégrader la qualité"

# === DÉFINIR NEW CODE PERIOD ===

# Administration > Configuration > New Code

# Options disponibles:

# 1. Previous version (recommandé)
# - Depuis la dernière version release
# - Basé sur sonar.projectVersion

# 2. Number of days
# - Depuis X jours
# - Exemple: 30 derniers jours

# 3. Specific analysis
# - Depuis une analyse spécifique
# - Basé sur date d'analyse

# 4. Reference branch (Developer Edition+)
# - Depuis une branche de référence
# - Exemple: différence avec main

# === PAR PROJET ===

# Project Settings > New Code
# Override global setting

# Exemple avec versions:
sonar-scanner \
  -Dsonar.projectVersion=1.2.0 \
  -Dsonar.token=squ_votre_token_ici

# Chaque nouvelle version réinitialise New Code Period

# === VISUALISER NEW CODE ===

# Dashboard projet:
# - Onglet "Overall" vs "New Code"
# - Métriques séparées

# Issues:
# - Filter: New Code = Yes


[OK] PORTFOLIOS & APPLICATIONS (ENTERPRISE+)

# === PORTFOLIOS ===

# Grouper plusieurs projets
# Vue d'ensemble de la qualité

# Créer portfolio
# Administration > Portfolios > Create

# Ajouter projets
# Portfolio > Edit > Add Projects

# Métriques agrégées:
# - Reliability Rating
# - Security Rating
# - Maintainability Rating
# - Coverage
# - Duplications

# Sous-portfolios
# Portfolio > Edit > Add Sub-Portfolio

# === APPLICATIONS ===

# Grouper projets d'une même application
# Analyse comme un seul projet

# Créer application
# Administration > Applications > Create

# Ajouter projets/branches
# Application > Edit > Add Projects

# Avantages:
# - Quality Gate global
# - Métriques consolidées
# - Vue unifiée

# === GOVERNANCE ===

# Rapports PDF
# Portfolio > Generate PDF Report

# Alertes qualité
# Portfolio > Quality Gate Status

# Suivi dans le temps
# Portfolio > Activity


[OK] SECURITY REPORTS (DEVELOPER EDITION+)

# === OWASP TOP 10 ===

# Rapport des vulnérabilités OWASP
# Security Reports > OWASP Top 10

# Catégories:
# - A1: Injection
# - A2: Broken Authentication
# - A3: Sensitive Data Exposure
# - A4: XML External Entities (XXE)
# - A5: Broken Access Control
# - A6: Security Misconfiguration
# - A7: Cross-Site Scripting (XSS)
# - A8: Insecure Deserialization
# - A9: Using Components with Known Vulnerabilities
# - A10: Insufficient Logging & Monitoring

# === SANS TOP 25 ===

# Rapport des erreurs logicielles dangereuses
# Security Reports > SANS Top 25

# === CWE (COMMON WEAKNESS ENUMERATION) ===

# Classification des faiblesses logicielles
# Security Reports > CWE

# Exemples:
# - CWE-79: Cross-site Scripting
# - CWE-89: SQL Injection
# - CWE-20: Improper Input Validation
# - CWE-78: OS Command Injection
# - CWE-190: Integer Overflow

# === SONARQUBE SECURITY CATEGORIES ===

# Security Reports > SonarQube Security Categories

# Catégories:
# - SQL Injection
# - Command Injection
# - Path Traversal
# - LDAP Injection
# - XPath Injection
# - Expression Language Injection
# - Code Injection
# - Cross-Site Scripting (XSS)
# - Log Injection
# - HTTP Response Splitting
# - Open Redirect
# - XML External Entity (XXE)
# - Insecure Configuration
# - Object Injection
# - SSRF (Server-Side Request Forgery)
# - Weak Cryptography
# - Encryption of Sensitive Data
# - Traceability


[OK] WEBHOOKS

# === CRÉER UN WEBHOOK ===

# Project Settings > Webhooks > Create

# Configuration:
# - Name: "Slack Notification"
# - URL: https://hooks.slack.com/services/...
# - Secret: (optionnel, pour validation)

# Événements:
# - Project Analysis
# - Quality Gate Status

# === PAYLOAD ===

# Format JSON envoyé:
{
  "serverUrl": "http://localhost:9000",
  "taskId": "AXouyxDPizdp4B1A",
  "status": "SUCCESS",
  "analysedAt": "2023-11-20T10:15:30+0000",
  "revision": "abc123",
  "changedAt": "2023-11-20T10:15:30+0000",
  "project": {
    "key": "my-project",
    "name": "My Project",
    "url": "http://localhost:9000/dashboard?id=my-project"
  },
  "branch": {
    "name": "main",
    "type": "LONG",
    "isMain": true,
    "url": "http://localhost:9000/dashboard?id=my-project"
  },
  "qualityGate": {
    "name": "Sonar way",
    "status": "OK",
    "conditions": [
      {
        "metric": "new_coverage",
        "operator": "LESS_THAN",
        "value": "85",
        "status": "OK",
        "errorThreshold": "80"
      }
    ]
  }
}

# === EXEMPLES D'INTÉGRATION ===

# Slack
# Utiliser Incoming Webhooks
# Parser le payload et formater message

# Microsoft Teams
# Utiliser Incoming Webhook Connector
# Format adaptif cards

# Discord
# Utiliser Webhook Discord
# Parser et formater embed

# Email (via service externe)
# Zapier, Make, n8n
# Déclencher email sur webhook

# Jira (créer ticket si QG fail)
# Script qui appelle API Jira


[OK] API REST

# === AUTHENTIFICATION ===

# Basic Auth (token)
curl -u squ_votre_token_ici: \
  http://localhost:9000/api/system/status

# Bearer Token (header)
curl -H "Authorization: Bearer squ_votre_token_ici" \
  http://localhost:9000/api/system/status

# === ENDPOINTS PRINCIPAUX ===

# System Info
curl -u token: http://localhost:9000/api/system/info

# Status
curl -u token: http://localhost:9000/api/system/status

# Liste des projets
curl -u token: http://localhost:9000/api/projects/search

# Détails d'un projet
curl -u token: "http://localhost:9000/api/projects/search?projects=my-project"

# Métriques d'un projet
curl -u token: "http://localhost:9000/api/measures/component?component=my-project&metricKeys=bugs,vulnerabilities,code_smells,coverage"

# Issues d'un projet
curl -u token: "http://localhost:9000/api/issues/search?componentKeys=my-project&resolved=false"

# Quality Gate status
curl -u token: "http://localhost:9000/api/qualitygates/project_status?projectKey=my-project"

# Utilisateurs
curl -u token: http://localhost:9000/api/users/search

# Règles
curl -u token: "http://localhost:9000/api/rules/search?languages=py"

# Quality Profiles
curl -u token: http://localhost:9000/api/qualityprofiles/search

# Quality Gates
curl -u token: http://localhost:9000/api/qualitygates/list

# === CRÉER/MODIFIER ===

# Créer projet
curl -u token: -X POST \
  "http://localhost:9000/api/projects/create?project=new-project&name=New+Project"

# Supprimer projet
curl -u token: -X POST \
  "http://localhost:9000/api/projects/delete?project=my-project"

# Créer utilisateur
curl -u token: -X POST \
  "http://localhost:9000/api/users/create?login=john&name=John+Doe&email=john@example.com&password=secret"

# Assigner permission
curl -u token: -X POST \
  "http://localhost:9000/api/permissions/add_user?projectKey=my-project&login=john&permission=user"

# === EXEMPLES PYTHON ===

import requests

# Configuration
SONAR_URL = "http://localhost:9000"
SONAR_TOKEN = "squ_votre_token_ici"
headers = {"Authorization": f"Bearer {SONAR_TOKEN}"}

# Get project metrics
def get_project_metrics(project_key):
    url = f"{SONAR_URL}/api/measures/component"
    params = {
        "component": project_key,
        "metricKeys": "bugs,vulnerabilities,code_smells,coverage"
    }
    response = requests.get(url, headers=headers, params=params)
    return response.json()

# Get issues
def get_project_issues(project_key):
    url = f"{SONAR_URL}/api/issues/search"
    params = {
        "componentKeys": project_key,
        "resolved": "false"
    }
    response = requests.get(url, headers=headers, params=params)
    return response.json()

# Check Quality Gate
def check_quality_gate(project_key):
    url = f"{SONAR_URL}/api/qualitygates/project_status"
    params = {"projectKey": project_key}
    response = requests.get(url, headers=headers, params=params)
    data = response.json()
    return data["projectStatus"]["status"]

# Usage
metrics = get_project_metrics("my-project")
issues = get_project_issues("my-project")
qg_status = check_quality_gate("my-project")

print(f"Quality Gate: {qg_status}")
print(f"Bugs: {metrics['component']['measures'][0]['value']}")


[OK] OPTIMISATION & PERFORMANCE

# === PERFORMANCE SCANNER ===

# Exclure fichiers inutiles
sonar.exclusions=**/node_modules/**,**/venv/**,**/build/**,**/dist/**,**/*.min.js

# Désactiver analyses inutiles
sonar.cpd.exclusions=**/generated/**        # Pas de duplication check
sonar.coverage.exclusions=**/tests/**       # Pas de coverage check

# Utiliser cache
sonar-scanner -Dsonar.scanner.cache.enabled=true

# Augmenter mémoire scanner
export SONAR_SCANNER_OPTS="-Xmx2048m"

# === PERFORMANCE SERVEUR ===

# conf/sonar.properties

# Mémoire Elasticsearch
sonar.search.javaOpts=-Xms512m -Xmx512m

# Mémoire Web Server
sonar.web.javaOpts=-Xmx512m -Xms128m

# Mémoire Compute Engine
sonar.ce.javaOpts=-Xmx512m -Xms128m

# Threads Compute Engine
sonar.ce.workerCount=2

# === OPTIMISATION BASE DE DONNÉES ===

# PostgreSQL: postgresql.conf
shared_buffers = 512MB
effective_cache_size = 2GB
work_mem = 16MB
maintenance_work_mem = 256MB
max_connections = 300

# Index (automatiques, mais vérifier)
# pg_stat_user_indexes

# Vacuum régulier (automatique)
# Ou manuel: VACUUM ANALYZE;

# === NETTOYAGE ===

# Purger projets inactifs
# Administration > Projects > Management
# Bulk Delete

# Nettoyer anciennes analyses
# Par défaut: 30 jours conservés
# Administration > Configuration > Housekeeping

# Nettoyer logs
cd $SONARQUBE_HOME
find logs/ -name "*.log" -mtime +30 -delete

# === MONITORING ===

# System Info
# Administration > System > System Info

# Métriques importantes:
# - CPU Usage
# - Memory Usage
# - Database Connectivity
# - Elasticsearch Status
# - Compute Engine Tasks

# Logs à surveiller
tail -f logs/web.log          # Requêtes web
tail -f logs/ce.log           # Analyses
tail -f logs/es.log           # Elasticsearch

# Prometheus/Grafana
# Plugin: sonar-prometheus-exporter
# Exposer métriques sur /api/monitoring/metrics


[OK] BEST PRACTICES (BONNES PRATIQUES)

# === ORGANISATION DES PROJETS ===

# 1. Nommage cohérent
# Utiliser un schéma: team-project-component
# Exemples:
# - backend-api-user-service
# - frontend-web-dashboard
# - mobile-ios-app

# 2. Un projet par composant
# [OK] Séparer front/back
# [OK] Séparer microservices
# [X] Mono-repo avec tout mélangé

# 3. Utiliser des tags
# Project Settings > Project Information > Tags
# Exemples: backend, frontend, mobile, critical

# === QUALITY GATES ===

# 1. Focus sur New Code
# [OK] New Coverage >= 80%
# [OK] New Duplications <= 3%
# [OK] New Maintainability Rating = A

# 2. Seuils réalistes
# [X] Coverage globale >= 80% (trop strict pour code legacy)
# [OK] Coverage nouveau code >= 80% (réaliste)

# 3. Stricte en production
# Development: Permissive
# Staging: Medium
# Production: Strict

# === GESTION DES ISSUES ===

# 1. Résoudre rapidement
# Blocker: Immédiatement
# Critical: Dans la journée
# Major: Dans la semaine

# 2. Ne pas tout marquer "Won't Fix"
# Utiliser avec parcimonie
# Documenter pourquoi

# 3. False Positive
# Utiliser pour vrais faux positifs
# Considérer désactiver la règle si trop de FP

# === SECURITY ===

# 1. Review tous les Security Hotspots
# Ne pas ignorer
# Marquer comme "Safe" ou "Fixed"

# 2. Activer Security Reports
# OWASP Top 10
# SANS Top 25

# 3. Pipenv/Poetry security checks
pipenv check
poetry audit

# === COVERAGE ===

# 1. Cible réaliste
# New Code: 80%+
# Overall: 70%+ (bon)

# 2. Ignorer certains fichiers
sonar.coverage.exclusions=**/tests/**,**/migrations/**,**/__init__.py

# 3. Tester ce qui compte
# [OK] Logique métier
# [OK] Fonctions critiques
# [X] Getters/setters simples

# === CI/CD INTEGRATION ===

# 1. Quality Gate obligatoire
# Fail le build si QG failed

# 2. Analyser toutes les branches
# Main + branches de dev

# 3. PR Decoration
# Feedback immédiat dans PR

# === MAINTENANCE ===

# 1. Mises à jour régulières
# Suivre versions LTS
# Tester avant production

# 2. Monitoring
# Surveiller performances
# Logs régulièrement

# 3. Backup
# Base de données quotidien
# Configuration versionnée


[OK] DÉPANNAGE (TROUBLESHOOTING)

# === SCANNER NE SE LANCE PAS ===

# Problème: Java not found
# Solution:
which java
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk

# Problème: Permission denied
# Solution:
chmod +x /opt/sonar-scanner/bin/sonar-scanner

# Problème: Out of memory
# Solution:
export SONAR_SCANNER_OPTS="-Xmx2048m"

# === CONNEXION SERVEUR ÉCHOUE ===

# Problème: Connection refused
# Solution: Vérifier que SonarQube est démarré
curl http://localhost:9000/api/system/status

# Vérifier logs
tail -f logs/sonar.log

# Problème: 401 Unauthorized
# Solution: Vérifier token
sonar-scanner \
  -Dsonar.token=squ_votre_nouveau_token \
  -X

# === ANALYSE ÉCHOUE ===

# Problème: Project key invalid
# Solution: Utiliser seulement lettres, chiffres, - _ .
sonar.projectKey=my-project-123

# Problème: Quality Gate failed
# Solution: Ce n'est pas une erreur, c'est le résultat
# Corriger les issues détectées

# Problème: Coverage not found
# Solution: Vérifier chemin du rapport
sonar.python.coverage.reportPaths=coverage.xml
# Générer coverage avant scan
pytest --cov=src --cov-report=xml

# === SONARQUBE NE DÉMARRE PAS ===

# Problème: Port 9000 déjà utilisé
# Solution: Changer port
nano conf/sonar.properties
sonar.web.port=9001

# Problème: Elasticsearch failed
# Solution: Vérifier mémoire disponible
free -h
# Augmenter si nécessaire
sonar.search.javaOpts=-Xms512m -Xmx512m

# Problème: Database connection failed
# Solution: Vérifier PostgreSQL
sudo systemctl status postgresql
# Vérifier credentials dans sonar.properties

# === PERFORMANCE LENTE ===

# Problème: Analyse très lente
# Solution: Exclure fichiers inutiles
sonar.exclusions=**/node_modules/**,**/venv/**

# Augmenter mémoire
export SONAR_SCANNER_OPTS="-Xmx4096m"

# Problème: Interface web lente
# Solution: Vérifier mémoire serveur
# Administration > System > System Info

# Augmenter mémoire dans sonar.properties
sonar.web.javaOpts=-Xmx1024m -Xms256m

# === ISSUES BIZARRES ===

# Problème: Issues sur fichiers exclus
# Solution: Vérifier patterns exclusion
sonar.exclusions=**/migrations/**
# Pas: sonar.exclusions=migrations/**

# Problème: False positives
# Solution: Marquer comme False Positive
# Ou désactiver règle dans Quality Profile

# Problème: Règle ne s'applique pas
# Solution: Vérifier Quality Profile actif
# Project Settings > Quality Profiles

# === LOGS UTILES ===

# Tous les logs
tail -f logs/*.log

# Erreurs uniquement
grep ERROR logs/sonar.log

# Warnings
grep WARN logs/sonar.log

# Analyser logs web
tail -f logs/web.log | grep -i error

# Compute Engine (analyses)
tail -f logs/ce.log


[OK] EXEMPLES DE CONFIGURATIONS COMPLÈTES

# === PROJET DJANGO ===

# sonar-project.properties
sonar.projectKey=django-project
sonar.projectName=Django Project
sonar.projectVersion=1.0.0

sonar.sources=myapp
sonar.tests=myapp/tests
sonar.sourceEncoding=UTF-8

# Python
sonar.python.version=3.11
sonar.python.coverage.reportPaths=coverage.xml

# Exclusions
sonar.exclusions=**/migrations/**,**/venv/**,**/staticfiles/**,**/media/**
sonar.test.exclusions=**/tests/**

# === PROJET FLASK ===

# sonar-project.properties
sonar.projectKey=flask-api
sonar.projectName=Flask API
sonar.sources=app
sonar.tests=tests
sonar.python.coverage.reportPaths=coverage.xml
sonar.exclusions=**/venv/**,**/__pycache__/**

# === PROJET FASTAPI ===

# sonar-project.properties
sonar.projectKey=fastapi-service
sonar.projectName=FastAPI Service
sonar.sources=src
sonar.tests=tests
sonar.python.coverage.reportPaths=coverage.xml
sonar.exclusions=**/venv/**,**/alembic/**

# === PROJET REACT ===

# sonar-project.properties
sonar.projectKey=react-app
sonar.projectName=React App
sonar.sources=src
sonar.tests=src
sonar.test.inclusions=**/*.test.js,**/*.test.jsx
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.exclusions=**/node_modules/**,**/build/**,**/coverage/**

# === PROJET VUE.JS ===

# sonar-project.properties
sonar.projectKey=vue-app
sonar.projectName=Vue App
sonar.sources=src
sonar.tests=tests
sonar.test.inclusions=**/*.spec.js
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.exclusions=**/node_modules/**,**/dist/**

# === PROJET ANGULAR ===

# sonar-project.properties
sonar.projectKey=angular-app
sonar.projectName=Angular App
sonar.sources=src
sonar.tests=src
sonar.test.inclusions=**/*.spec.ts
sonar.typescript.lcov.reportPaths=coverage/lcov.info
sonar.exclusions=**/node_modules/**,**/dist/**,**/e2e/**

# === PROJET SPRING BOOT ===

# pom.xml (pas de sonar-project.properties nécessaire)
<properties>
  <sonar.projectKey>spring-boot-app</sonar.projectKey>
  <sonar.projectName>Spring Boot App</sonar.projectName>
  <sonar.host.url>http://localhost:9000</sonar.host.url>
  <sonar.coverage.jacoco.xmlReportPaths>
    ${project.build.directory}/site/jacoco/jacoco.xml
  </sonar.coverage.jacoco.xmlReportPaths>
</properties>


[OK] SCRIPTS UTILES

# === SCRIPT ANALYSE COMPLÈTE (BASH) ===

#!/bin/bash
# analyze.sh - Script complet d'analyse SonarQube

set -e

PROJECT_KEY="my-project"
SONAR_HOST="http://localhost:9000"
SONAR_TOKEN="squ_votre_token_ici"

echo "[TEST] Running tests with coverage..."
pytest --cov=src --cov-report=xml --cov-report=html

echo "[GRAPHIQUE] Running SonarQube analysis..."
sonar-scanner \
  -Dsonar.projectKey=$PROJECT_KEY \
  -Dsonar.host.url=$SONAR_HOST \
  -Dsonar.token=$SONAR_TOKEN \
  -Dsonar.qualitygate.wait=true

echo "[OK] Analysis complete!"
echo "[HAUSSE] View results: $SONAR_HOST/dashboard?id=$PROJECT_KEY"

# === SCRIPT VÉRIFICATION QUALITY GATE (PYTHON) ===

#!/usr/bin/env python3
# check_qg.py - Vérifier Quality Gate

import requests
import sys
import time

SONAR_URL = "http://localhost:9000"
SONAR_TOKEN = "squ_votre_token_ici"
PROJECT_KEY = "my-project"

headers = {"Authorization": f"Bearer {SONAR_TOKEN}"}

def get_quality_gate_status():
    url = f"{SONAR_URL}/api/qualitygates/project_status"
    params = {"projectKey": PROJECT_KEY}
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()
    data = response.json()
    return data["projectStatus"]

def main():
    print(f"[RECHERCHE] Checking Quality Gate for {PROJECT_KEY}...")
    
    # Attendre un peu que l'analyse soit traitée
    time.sleep(5)
    
    status = get_quality_gate_status()
    
    print(f"\n[GRAPHIQUE] Quality Gate: {status['status']}")
    
    if status['status'] == 'ERROR':
        print("\n[X] Quality Gate FAILED")
        print("\nFailing conditions:")
        for condition in status['conditions']:
            if condition['status'] == 'ERROR':
                print(f"  - {condition['metricKey']}: {condition['actualValue']} "
                      f"(threshold: {condition['errorThreshold']})")
        sys.exit(1)
    else:
        print("\n[OK] Quality Gate PASSED")
        sys.exit(0)

if __name__ == "__main__":
    main()

# === SCRIPT EXPORT MÉTRIQUES (PYTHON) ===

#!/usr/bin/env python3
# export_metrics.py - Exporter métriques en CSV

import requests
import csv

SONAR_URL = "http://localhost:9000"
SONAR_TOKEN = "squ_votre_token_ici"
PROJECT_KEY = "my-project"

headers = {"Authorization": f"Bearer {SONAR_TOKEN}"}

def get_metrics():
    url = f"{SONAR_URL}/api/measures/component"
    params = {
        "component": PROJECT_KEY,
        "metricKeys": "bugs,vulnerabilities,code_smells,coverage,duplicated_lines_density"
    }
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()
    return response.json()

def main():
    data = get_metrics()
    measures = data['component']['measures']
    
    with open('metrics.csv', 'w', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(['Metric', 'Value'])
        for measure in measures:
            writer.writerow([measure['metric'], measure.get('value', 'N/A')])
    
    print("[OK] Metrics exported to metrics.csv")

if __name__ == "__main__":
    main()


[OK] RESSOURCES & DOCUMENTATION COMPLÈTE

# === DOCUMENTATION OFFICIELLE ===

# Site principal SonarQube
https://www.sonarqube.org/
# Description: Page d'accueil, téléchargements, présentation

# Documentation complète
https://docs.sonarqube.org/latest/
# Description: Guide complet, tutoriels, références API
# Sections importantes:
# - Setup and Upgrade: Installation et mise à jour
# - User Guide: Guide utilisateur
# - Analyzing Source Code: Comment analyser
# - Extend: Plugins et extensions
# - Instance Administration: Administration serveur

# Documentation par version
https://docs.sonarqube.org/9.9/  # Version 9.9 LTS
https://docs.sonarqube.org/10.3/ # Version 10.3 Latest

# === COMMUNITY & SUPPORT ===

# Forum communautaire (TRÈS ACTIF)
https://community.sonarsource.com/
# Description: Posez vos questions, cherchez des réponses
# Catégories:
# - Get Help: Aide pour problèmes
# - SonarQube: Questions spécifiques SonarQube
# - SonarCloud: Version cloud
# - Languages: Questions par langage
# - DevOps: Intégration CI/CD

# Stack Overflow
https://stackoverflow.com/questions/tagged/sonarqube
# Tag: [sonarqube]
# Plus de 15,000 questions répondues

# GitHub Issues (bugs et feature requests)
https://github.com/SonarSource/sonarqube/issues
# Signaler bugs
# Demander nouvelles fonctionnalités
# Voir roadmap

# === RÈGLES PAR LANGAGE ===

# Base de données de règles complète
https://rules.sonarsource.com/
# Pour chaque langage:
# - Description détaillée de chaque règle
# - Exemples de code non-conforme
# - Exemples de code conforme
# - Références (CERT, CWE, OWASP)

# Exemples de langages:
https://rules.sonarsource.com/python/     # Python
https://rules.sonarsource.com/javascript/ # JavaScript
https://rules.sonarsource.com/java/       # Java
https://rules.sonarsource.com/typescript/ # TypeScript
https://rules.sonarsource.com/php/        # PHP
https://rules.sonarsource.com/csharp/     # C#
https://rules.sonarsource.com/go/         # Go
https://rules.sonarsource.com/kotlin/     # Kotlin

# === BLOG & ACTUALITÉS ===

# Blog officiel SonarSource
https://blog.sonarsource.com/
# Articles sur:
# - Nouvelles fonctionnalités
# - Bonnes pratiques
# - Études de cas
# - Sécurité
# - Clean Code

# Articles recommandés pour débutants:
# - "Clean as You Code" methodology
# - "What is Technical Debt?"
# - "Security Hotspots vs Vulnerabilities"
# - "Understanding Quality Gates"

# Twitter/X
https://twitter.com/SonarSource
# Actualités en temps réel
# Annonces de versions

# LinkedIn
https://www.linkedin.com/company/sonarsource/
# Articles professionnels
# Témoignages d'entreprises

# === FORMATIONS & CERTIFICATIONS ===

# SonarQube University (GRATUIT!)
https://www.sonarsource.com/learn/
# Cours en ligne gratuits:
# - Clean Code with SonarQube (2h)
# - Security with SonarQube (1.5h)
# - SonarQube Administration (3h)
# Certificats à l'issue de chaque cours

# Webinars réguliers
https://www.sonarsource.com/resources/webinars/
# Webinars mensuels sur:
# - Nouvelles fonctionnalités
# - Études de cas
# - Best practices
# Replay disponibles

# YouTube Channel
https://www.youtube.com/c/Sonarsource
# Tutoriels vidéo
# Présentations de conférences
# Démonstrations de fonctionnalités

# === PLUGINS & EXTENSIONS ===

# Marketplace officiel
# Dans SonarQube: Administration > Marketplace
# Ou en ligne: https://docs.sonarqube.org/latest/instance-administration/marketplace/

# Plugins populaires (Community Edition):
# - Checkstyle Plugin
# - PMD Plugin
# - FindBugs Plugin
# - Git Plugin
# - GitHub Plugin
# - GitLab Plugin

# Plugins commerciaux (Developer/Enterprise):
# - C/C++ Analyzer
# - C# Analyzer
# - Visual Basic Analyzer
# - PL/SQL Analyzer
# - ABAP Analyzer
# - COBOL Analyzer

# === INTÉGRATIONS IDE ===

# SonarLint (Plugin IDE - GRATUIT)
https://www.sonarlint.org/

# Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=SonarSource.sonarlint-vscode
# Installation: Chercher "SonarLint" dans extensions

# IntelliJ IDEA
https://plugins.jetbrains.com/plugin/7973-sonarlint
# Installation: Settings > Plugins > Marketplace > "SonarLint"

# Eclipse
https://marketplace.eclipse.org/content/sonarlint
# Installation: Help > Eclipse Marketplace > "SonarLint"

# Visual Studio
https://marketplace.visualstudio.com/items?itemName=SonarSource.SonarLintforVisualStudio2022

# Avantages SonarLint:
# [OK] Détection en temps réel pendant que vous codez
# [OK] Pas besoin de lancer analyse complète
# [OK] Feedback immédiat
# [OK] Connexion à SonarQube pour synchro règles

# === OUTILS CLI ===

# SonarScanner CLI
https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/
# Outil principal pour analyser projets

# SonarScanner for Maven
https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-maven/
# Intégration Maven
# pom.xml configuration

# SonarScanner for Gradle
https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-gradle/
# Intégration Gradle
# build.gradle configuration

# SonarScanner for .NET
https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-msbuild/
# Pour projets C#/.NET

# SonarScanner for Azure DevOps
https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-azure-devops/
# Extension Azure Pipelines

# === API REST DOCUMENTATION ===

# Documentation API complète
https://VOTRE_SONARQUBE/web_api
# Accédez depuis votre instance
# Liste TOUS les endpoints disponibles

# API Web Service Documentation
https://docs.sonarqube.org/latest/extend/web-api/
# Guide d'utilisation de l'API

# Endpoints principaux:
# /api/authentication/        - Authentification
# /api/ce/                   - Compute Engine (analyses)
# /api/components/           - Projets et composants
# /api/issues/               - Issues (bugs, vulnerabilities)
# /api/measures/             - Métriques
# /api/projects/             - Gestion projets
# /api/qualitygates/         - Quality Gates
# /api/qualityprofiles/      - Quality Profiles
# /api/rules/                - Règles
# /api/system/               - Informations système
# /api/users/                - Gestion utilisateurs
# /api/webhooks/             - Webhooks

# === LIVRES & EBOOKS ===

# "Clean Code" de Robert C. Martin
# ISBN: 978-0132350884
# Le livre de référence sur le code propre
# Philosophie derrière SonarQube

# "SonarQube in Action" de G. Ann Campbell & Patroklos P. Papapetrou
# ISBN: 978-1617290954
# Guide complet SonarQube
# (Note: Version un peu ancienne mais concepts toujours valables)

# "Continuous Inspection: How to Measure Maintainability"
# eBook gratuit par SonarSource
# Téléchargeable sur: https://www.sonarsource.com/learn/

# === CONFÉRENCES & ÉVÉNEMENTS ===

# SonarSource Events
https://www.sonarsource.com/company/events/
# - Webinars mensuels
# - Workshops
# - Conférences

# Présence aux conférences tech:
# - Devoxx
# - JavaOne
# - QCon
# - DevOps Days
# - AWS re:Invent

# Meetups locaux
https://www.meetup.com/topics/sonarqube/
# Groupes locaux d'utilisateurs SonarQube

# === COMPARAISONS & ALTERNATIVES ===

# Articles de comparaison:
# "SonarQube vs SonarCloud"
# "SonarQube vs CodeClimate"
# "SonarQube vs Coverity"
# "Static Analysis Tools Comparison"

# Site de comparaison:
https://www.g2.com/products/sonarqube/competitors/alternatives
# Reviews et comparaisons utilisateurs

# === SÉCURITÉ & CVE ===

# Security Advisories SonarQube
https://www.sonarsource.com/products/sonarqube/security/
# Vulnérabilités connues
# Patches de sécurité

# CVE Database pour SonarQube
https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=sonarqube
# Vulnérabilités CVE répertoriées

# === CONTRIBUTIONS & DÉVELOPPEMENT ===

# Contribuer à SonarQube
https://github.com/SonarSource/sonarqube/blob/master/CONTRIBUTING.md
# Guidelines pour contribuer
# Comment soumettre pull requests

# Développer des plugins
https://docs.sonarqube.org/latest/extend/developing-plugin/
# Guide pour créer plugins custom

# Plugin API Javadoc
https://javadocs.sonarsource.org/
# Documentation Java pour développeurs plugins


[OK] CONFIGURATIONS AVANCÉES PAR CAS D'USAGE

# === CONFIGURATION MULTI-PROJETS (MONOREPO) ===

# Cas d'usage: Vous avez un monorepo avec plusieurs projets
# Structure:
# monorepo/
# ├── backend-api/
# ├── backend-worker/
# ├── frontend-web/
# ├── frontend-mobile/
# └── shared-lib/

# OPTION 1: Un projet SonarQube par composant (RECOMMANDÉ)
# ─────────────────────────────────────────────────────────

# Avantages:
# [OK] Quality Gate indépendant par composant
# [OK] Équipes différentes peuvent avoir des standards différents
# [OK] Plus facile à gérer
# [OK] Permissions granulaires

# Configuration:
# Créer sonar-project.properties dans chaque dossier:

# backend-api/sonar-project.properties
sonar.projectKey=monorepo-backend-api
sonar.projectName=Backend API
sonar.sources=src
sonar.tests=tests
sonar.python.coverage.reportPaths=coverage.xml
sonar.exclusions=**/migrations/**

# backend-worker/sonar-project.properties
sonar.projectKey=monorepo-backend-worker
sonar.projectName=Backend Worker
sonar.sources=src
sonar.tests=tests
sonar.python.coverage.reportPaths=coverage.xml

# frontend-web/sonar-project.properties
sonar.projectKey=monorepo-frontend-web
sonar.projectName=Frontend Web
sonar.sources=src
sonar.tests=src
sonar.test.inclusions=**/*.test.js
sonar.javascript.lcov.reportPaths=coverage/lcov.info

# Script d'analyse pour tous les projets:
#!/bin/bash
# analyze-all.sh

PROJECTS=("backend-api" "backend-worker" "frontend-web" "frontend-mobile" "shared-lib")

for project in "${PROJECTS[@]}"; do
  echo "[GRAPHIQUE] Analyzing $project..."
  cd $project
  sonar-scanner -Dsonar.token=$SONAR_TOKEN
  cd ..
done

echo "[OK] All projects analyzed!"

# OPTION 2: Projet unique avec modules (Developer Edition+)
# ──────────────────────────────────────────────────────────

# Avantages:
# [OK] Vue unifiée de tout le monorepo
# [OK] Quality Gate global
# [OK] Métriques agrégées

# Inconvénients:
# [X] Nécessite Developer Edition
# [X] Moins flexible

# Configuration sonar-project.properties à la racine:
sonar.projectKey=monorepo
sonar.projectName=Complete Monorepo
sonar.modules=backend-api,backend-worker,frontend-web

# Module backend-api
backend-api.sonar.projectName=Backend API
backend-api.sonar.sources=backend-api/src
backend-api.sonar.tests=backend-api/tests
backend-api.sonar.python.coverage.reportPaths=backend-api/coverage.xml

# Module backend-worker
backend-worker.sonar.projectName=Backend Worker
backend-worker.sonar.sources=backend-worker/src
backend-worker.sonar.tests=backend-worker/tests
backend-worker.sonar.python.coverage.reportPaths=backend-worker/coverage.xml

# Module frontend-web
frontend-web.sonar.projectName=Frontend Web
frontend-web.sonar.sources=frontend-web/src
frontend-web.sonar.tests=frontend-web/src
frontend-web.sonar.test.inclusions=**/*.test.js
frontend-web.sonar.javascript.lcov.reportPaths=frontend-web/coverage/lcov.info

# OPTION 3: Application (Enterprise Edition)
# ───────────────────────────────────────────

# Grouper plusieurs projets en une Application
# Configuration dans l'interface SonarQube:
# Administration > Applications > Create

# Ajouter les projets:
# - monorepo-backend-api
# - monorepo-backend-worker
# - monorepo-frontend-web

# Avantages:
# [OK] Vue unifiée sans perdre l'indépendance des projets
# [OK] Quality Gate global de l'application
# [OK] Flexibilité maximale

# === CONFIGURATION PAR ENVIRONNEMENT ===

# DEV (Développement)
# ───────────────────
# Quality Gate: Permissif
# Focus: Apprentissage, feedback rapide

# sonar-project.properties
sonar.projectKey=myapp-dev
sonar.qualitygate=Development
sonar.coverage.exclusions=**/tests/**,**/mocks/**

# Quality Gate "Development":
# - New Coverage >= 50%
# - New Bugs <= 10
# - New Vulnerabilities <= 5
# - New Code Smells <= 50

# STAGING (Pré-production)
# ────────────────────────
# Quality Gate: Medium
# Focus: Préparation production

# sonar-project.properties
sonar.projectKey=myapp-staging
sonar.qualitygate=Staging
sonar.coverage.exclusions=**/tests/**

# Quality Gate "Staging":
# - New Coverage >= 70%
# - New Bugs <= 3
# - New Vulnerabilities <= 1
# - New Code Smells <= 20
# - New Duplications <= 5%

# PRODUCTION
# ──────────
# Quality Gate: Strict
# Focus: Zéro compromis

# sonar-project.properties
sonar.projectKey=myapp-prod
sonar.qualitygate=Production-Strict

# Quality Gate "Production-Strict":
# - New Coverage >= 80%
# - New Bugs = 0
# - New Vulnerabilities = 0
# - New Code Smells <= 5
# - New Duplications <= 3%
# - New Security Hotspots Reviewed = 100%

# Script pour analyser selon l'environnement:
#!/bin/bash
# analyze-env.sh

ENV=$1  # dev, staging, prod

if [ "$ENV" == "dev" ]; then
  PROJECT_KEY="myapp-dev"
  QG="Development"
elif [ "$ENV" == "staging" ]; then
  PROJECT_KEY="myapp-staging"
  QG="Staging"
elif [ "$ENV" == "prod" ]; then
  PROJECT_KEY="myapp-prod"
  QG="Production-Strict"
else
  echo "Usage: ./analyze-env.sh [dev|staging|prod]"
  exit 1
fi

sonar-scanner \
  -Dsonar.projectKey=$PROJECT_KEY \
  -Dsonar.qualitygate=$QG \
  -Dsonar.token=$SONAR_TOKEN

# === CONFIGURATION MICROSERVICES ===

# Architecture microservices typique:
# - 10+ services indépendants
# - Équipes différentes par service
# - Criticité variable

# STRATÉGIE 1: Tags pour catégoriser
# ───────────────────────────────────

# Dans chaque projet, ajouter tags:
# Project Settings > Project Information > Tags

# Tags recommandés:
# - Équipe: team-payment, team-shipping, team-user
# - Criticité: critical, important, standard
# - Type: microservice, library, frontend
# - Techno: python, java, nodejs

# Exemple:
# user-service: [team-user, critical, microservice, python]
# payment-service: [team-payment, critical, microservice, java]
# email-service: [team-notification, standard, microservice, python]

# Filtrage dans Projects:
# Filter by tags: critical
# -> Voir seulement services critiques

# STRATÉGIE 2: Nommage cohérent
# ──────────────────────────────

# Convention: [équipe]-[type]-[nom]
# Exemples:
# - payment-service-api
# - payment-service-worker
# - payment-lib-common
# - shipping-service-api
# - shipping-service-tracker
# - user-service-api
# - user-service-auth

# Avantages:
# [OK] Facile de voir ce qui appartient à qui
# [OK] Recherche simplifiée
# [OK] Automatisation facilitée

# STRATÉGIE 3: Quality Gates par criticité
# ─────────────────────────────────────────

# Quality Gate "Critical Services":
# - New Coverage >= 90%
# - New Bugs = 0
# - New Vulnerabilities = 0
# - New Security Hotspots Reviewed = 100%

# Quality Gate "Standard Services":
# - New Coverage >= 80%
# - New Bugs = 0
# - New Vulnerabilities = 0
# - New Security Hotspots Reviewed = 100%

# Quality Gate "Non-Critical Services":
# - New Coverage >= 70%
# - New Bugs <= 1
# - New Vulnerabilities = 0

# Appliquer dans chaque projet:
# Project Settings > Quality Gate > Select appropriate gate

# === CONFIGURATION ÉQUIPES DISTRIBUÉES ===

# Cas d'usage: Équipes sur différents fuseaux horaires
# Problème: Analyses lentes bloquent les équipes

# SOLUTION 1: Compute Engine Workers multiples
# ─────────────────────────────────────────────

# conf/sonar.properties
sonar.ce.workerCount=4  # 4 analyses en parallèle (au lieu de 1)

# Recommandation:
# - Petit projet (<100 projets): workerCount=1
# - Moyen projet (100-500): workerCount=2-4
# - Gros projet (>500): workerCount=4-8

# SOLUTION 2: Analyses incrémentales (Developer Edition+)
# ────────────────────────────────────────────────────────

# Analyser seulement fichiers modifiés dans PR
# Gain de temps: 80-90% plus rapide

# GitHub Actions:
- name: SonarQube PR Analysis
  uses: sonarsource/sonarqube-scan-action@master
  env:
    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
  with:
    args: >
      -Dsonar.pullrequest.key=${{ github.event.pull_request.number }}
      -Dsonar.pullrequest.branch=${{ github.head_ref }}
      -Dsonar.pullrequest.base=${{ github.base_ref }}

# SOLUTION 3: Cache Scanner
# ─────────────────────────

# Activer cache pour accélérer analyses répétées:
sonar-scanner \
  -Dsonar.scanner.cache.enabled=true \
  -Dsonar.scanner.cache.path=.sonar/cache

# CI/CD: Partager cache entre builds:
# GitHub Actions:
- uses: actions/cache@v3
  with:
    path: .sonar/cache
    key: ${{ runner.os }}-sonar-cache

# === CONFIGURATION HAUTE DISPONIBILITÉ ===

# Data Center Edition seulement
# Pour: SonarQube critique, ne peut pas tomber

# Architecture:
# ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
# │   SonarQube │  │   SonarQube │  │   SonarQube │
# │   Node 1    │  │   Node 2    │  │   Node 3    │
# └──────┬──────┘  └──────┬──────┘  └──────┬──────┘
#        │                │                │
#        └────────────────┴────────────────┘
#                         │
#                  ┌──────┴──────┐
#                  │  PostgreSQL │
#                  │   Cluster   │
#                  └─────────────┘

# Configuration node 1:
# conf/sonar.properties
sonar.cluster.enabled=true
sonar.cluster.node.type=application
sonar.cluster.node.name=node1
sonar.cluster.hosts=node1:9003,node2:9003,node3:9003

# Configuration node 2:
sonar.cluster.enabled=true
sonar.cluster.node.type=application
sonar.cluster.node.name=node2
sonar.cluster.hosts=node1:9003,node2:9003,node3:9003

# Load Balancer devant (HAProxy, Nginx):
upstream sonarqube {
    server node1:9000;
    server node2:9000;
    server node3:9000;
}

# === CONFIGURATION POUR GRANDS PROJETS ===

# Projet avec 1M+ lignes de code
# Problème: Analyses très lentes

# SOLUTION 1: Exclure intelligemment
# ──────────────────────────────────

sonar.exclusions=\
  **/node_modules/**,\
  **/vendor/**,\
  **/dist/**,\
  **/build/**,\
  **/*.min.js,\
  **/*.min.css,\
  **/generated/**,\
  **/migrations/**,\
  **/tests/fixtures/**,\
  **/__snapshots__/**,\
  **/coverage/**,\
  **/.venv/**,\
  **/venv/**

# SOLUTION 2: Désactiver analyses inutiles
# ─────────────────────────────────────────

# Pas de duplication check sur generated code:
sonar.cpd.exclusions=**/generated/**,**/migrations/**

# Pas de coverage sur tests:
sonar.coverage.exclusions=**/tests/**,**/*_test.py

# SOLUTION 3: Augmenter mémoire
# ──────────────────────────────

# Scanner:
export SONAR_SCANNER_OPTS="-Xmx4096m"

# Server (conf/sonar.properties):
sonar.web.javaOpts=-Xmx2048m -Xms512m
sonar.ce.javaOpts=-Xmx4096m -Xms1024m
sonar.search.javaOpts=-Xms2048m -Xmx2048m

# SOLUTION 4: Analyse par modules
# ────────────────────────────────

# Au lieu d'analyser tout d'un coup:
# Analyser module par module
# Combiner avec Application (Enterprise)

# Module 1:
cd module1
sonar-scanner -Dsonar.projectKey=project-module1

# Module 2:
cd ../module2
sonar-scanner -Dsonar.projectKey=project-module2

# Puis grouper en Application dans l'interface


[OK] PATTERNS & ANTI-PATTERNS

# === PATTERNS (BONNES PRATIQUES) ===

# PATTERN 1: "Clean as You Code"
# ───────────────────────────────
# [OK] Faire: Focus sur nouveau code uniquement
# [OK] Quality Gate strict sur New Code
# [OK] Améliorer ancien code progressivement

# Configuration:
# New Code Period: Previous version
# Quality Gate focus: New Code metrics

# Résultat:
# -> Qualité s'améliore constamment
# -> Équipe motivée (objectifs atteignables)
# -> Pas de "big bang refactoring"

# PATTERN 2: "Shift Left"
# ───────────────────────
# [OK] Faire: Détecter problèmes le plus tôt possible
# [OK] SonarLint dans IDE (temps réel)
# [OK] Analyse dans PR (avant merge)
# [OK] Quality Gate bloquant

# Workflow:
# 1. Développeur écrit code
# 2. SonarLint détecte -> Corrige immédiatement
# 3. Commit -> PR créée
# 4. SonarQube analyse PR -> Decoration
# 5. Code review + SonarQube check
# 6. Quality Gate PASS -> Merge autorisé

# Résultat:
# -> Bugs détectés en minutes (pas en jours)
# -> Coût de correction minimal
# -> Production stable

# PATTERN 3: "Defense in Depth"
# ──────────────────────────────
# [OK] Faire: Plusieurs niveaux de vérification
# [OK] SonarLint (IDE)
# [OK] Pre-commit hooks
# [OK] SonarQube (CI/CD)
# [OK] Security Hotspots review

# Exemple pre-commit hook:
#!/bin/bash
# .git/hooks/pre-commit

echo "[RECHERCHE] Running SonarLint..."
# Lancer SonarLint en CLI si disponible
# Ou rappel à l'utilisateur de vérifier

echo "[TEST] Running tests..."
pytest

echo "[OK] Pre-commit checks passed!"

# PATTERN 4: "Metrics-Driven Development"
# ───────────────────────────────────────
# [OK] Faire: Suivre métriques dans le temps
# [OK] Dashboard visible par tous
# [OK] Objectifs clairs et mesurables
# [OK] Célébrer améliorations

# Exemple objectifs trimestriels:
# Q1: Coverage New Code 70% -> 75%
# Q2: Coverage New Code 75% -> 80%
# Q3: Technical Debt -20%
# Q4: Coverage Overall 60% -> 65%

# PATTERN 5: "Graduated Quality Gates"
# ────────────────────────────────────
# [OK] Faire: Augmenter exigences progressivement
# [OK] Mois 1-3: Quality Gate "Starter"
# [OK] Mois 4-6: Quality Gate "Intermediate"
# [OK] Mois 7+: Quality Gate "Strict"

# Starter:
# - New Coverage >= 50%
# - New Bugs <= 5

# Intermediate:
# - New Coverage >= 70%
# - New Bugs <= 1

# Strict:
# - New Coverage >= 80%
# - New Bugs = 0

# === ANTI-PATTERNS (À ÉVITER!) ===

# ANTI-PATTERN 1: "Big Bang Refactoring"
# ──────────────────────────────────────
# [X] Éviter: Essayer de tout corriger d'un coup
# [X] "On va prendre 2 mois pour corriger tous les bugs"
# [X] Bloquer toutes les features

# Pourquoi c'est mauvais:
# -> Équipe découragée (objectif inatteignable)
# -> Business bloqué (pas de nouvelles features)
# -> Risque de régressions énorme
# -> Souvent abandonné à mi-chemin

# [OK] Alternative: "Clean as You Code"
# -> Focus nouveau code
# -> Ancien code amélioré progressivement

# ANTI-PATTERN 2: "Quality Gate Cosmétique"
# ─────────────────────────────────────────
# [X] Éviter: Quality Gate qui ne bloque jamais
# [X] Coverage >= 10% (trop facile!)
# [X] Bugs <= 100 (beaucoup trop!)

# Pourquoi c'est mauvais:
# -> Aucune amélioration réelle
# -> Faux sentiment de sécurité
# -> SonarQube devient inutile

# [OK] Alternative: Quality Gates réalistes mais exigeants
# -> New Coverage >= 80%
# -> New Bugs = 0

# ANTI-PATTERN 3: "Ignorer les Issues"
# ────────────────────────────────────
# [X] Éviter: Marquer tout en "Won't Fix"
# [X] "On n'a pas le temps"
# [X] "Ce n'est pas important"

# Pourquoi c'est mauvais:
# -> Dette technique s'accumule
# -> Métriques deviennent inexactes
# -> Culture du "c'est pas grave"

# [OK] Alternative: Gérer les issues correctement
# -> Corriger les critiques immédiatement
# -> Planifier correction des autres
# -> "Won't Fix" seulement si vraiment faux positif

# ANTI-PATTERN 4: "Quality Gate en Production Seulement"
# ───────────────────────────────────────────────────────
# [X] Éviter: Pas de vérification en dev/staging
# [X] Seulement avant production
# [X] Découverte tardive des problèmes


[OK] EXEMPLES COMPLETS PAR LANGAGE

# === PROJET PYTHON DJANGO ===

# Structure du projet:
django_project/
├── myapp/
│   ├── __init__.py
│   ├── models.py
│   ├── views.py
│   ├── urls.py
│   └── tests/
│       ├── __init__.py
│       ├── test_models.py
│       └── test_views.py
├── myproject/
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── requirements.txt
├── requirements-dev.txt
├── .gitignore
└── sonar-project.properties

# Configuration complète sonar-project.properties:
sonar.projectKey=django-myapp
sonar.projectName=Django MyApp
sonar.projectVersion=1.0.0
sonar.sourceEncoding=UTF-8

# Chemins source et tests
sonar.sources=myapp,myproject
sonar.tests=myapp/tests

# Python version
sonar.python.version=3.11

# Coverage
sonar.python.coverage.reportPaths=coverage.xml

# Exclusions
sonar.exclusions=\
  **/migrations/**,\
  **/settings.py,\
  **/wsgi.py,\
  **/asgi.py,\
  **/__pycache__/**,\
  **/venv/**,\
  **/.venv/**,\
  **/staticfiles/**,\
  **/media/**

# Test exclusions
sonar.test.exclusions=**/tests/**

# Coverage exclusions (pas besoin de coverage sur les tests eux-mêmes)
sonar.coverage.exclusions=\
  **/tests/**,\
  **/migrations/**,\
  **/settings.py,\
  **/manage.py

# Duplication exclusions
sonar.cpd.exclusions=**/migrations/**

# Script de test avec coverage:
# test.sh
#!/bin/bash
set -e

echo "[TEST] Running tests with coverage..."
pytest \
  --cov=myapp \
  --cov=myproject \
  --cov-report=xml \
  --cov-report=html \
  --cov-report=term-missing

echo "[GRAPHIQUE] Running SonarQube analysis..."
sonar-scanner -Dsonar.token=$SONAR_TOKEN

echo "[OK] Done!"

# Configuration GitHub Actions:
# .github/workflows/sonarqube.yml
name: SonarQube Analysis

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  sonarqube:
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:14
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: testdb
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
    
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0  # Important pour SonarQube
      
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
      
      - name: Install dependencies
        run: |
          pip install --upgrade pip
          pip install -r requirements.txt
          pip install -r requirements-dev.txt
      
      - name: Run tests with coverage
        env:
          DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
        run: |
          pytest \
            --cov=myapp \
            --cov=myproject \
            --cov-report=xml \
            --cov-report=term
      
      - name: SonarQube Scan
        uses: sonarsource/sonarqube-scan-action@master
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
      
      - name: Quality Gate Check
        uses: sonarsource/sonarqube-quality-gate-action@master
        timeout-minutes: 5
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

# Exemple de test avec couverture:
# myapp/tests/test_views.py
import pytest
from django.test import Client
from django.urls import reverse
from myapp.models import Article

@pytest.mark.django_db
class TestArticleViews:
    def test_article_list_view(self):
        """Test que la liste d'articles s'affiche correctement"""
        client = Client()
        response = client.get(reverse('article_list'))
        assert response.status_code == 200
        assert 'articles' in response.context
    
    def test_article_detail_view(self):
        """Test que le détail d'un article s'affiche"""
        article = Article.objects.create(
            title="Test Article",
            content="Test content"
        )
        client = Client()
        response = client.get(reverse('article_detail', args=[article.id]))
        assert response.status_code == 200
        assert response.context['article'] == article
    
    def test_article_create_view(self):
        """Test la création d'un article"""
        client = Client()
        data = {
            'title': 'New Article',
            'content': 'New content'
        }
        response = client.post(reverse('article_create'), data)
        assert response.status_code == 302  # Redirect après création
        assert Article.objects.filter(title='New Article').exists()


# === PROJET PYTHON FLASK API ===

# Structure:
flask_api/
├── app/
│   ├── __init__.py
│   ├── models.py
│   ├── routes.py
│   └── utils.py
├── tests/
│   ├── __init__.py
│   ├── conftest.py
│   ├── test_routes.py
│   └── test_models.py
├── config.py
├── run.py
├── requirements.txt
└── sonar-project.properties

# sonar-project.properties:
sonar.projectKey=flask-api
sonar.projectName=Flask API
sonar.projectVersion=1.0.0

sonar.sources=app
sonar.tests=tests

sonar.python.version=3.11
sonar.python.coverage.reportPaths=coverage.xml

sonar.exclusions=\
  **/venv/**,\
  **/.venv/**,\
  **/__pycache__/**,\
  **/migrations/**

sonar.test.exclusions=**/tests/**
sonar.coverage.exclusions=**/tests/**,**/conftest.py

# Exemple de code avec problèmes détectés par SonarQube:

# [X] AVANT (avec issues):
# app/routes.py
from flask import request, jsonify
from app import app, db
from app.models import User

@app.route('/api/users/<user_id>', methods=['GET'])
def get_user(user_id):
    # [X] SQL Injection possible!
    query = f"SELECT * FROM users WHERE id = {user_id}"
    result = db.engine.execute(query)
    
    # [X] Pas de gestion d'erreur
    user = result.fetchone()
    
    # [X] Retourne données sensibles
    return jsonify({
        'id': user.id,
        'username': user.username,
        'email': user.email,
        'password': user.password  # [X] Mot de passe exposé!
    })

@app.route('/api/users', methods=['POST'])
def create_user():
    data = request.json
    
    # [X] Pas de validation
    user = User(
        username=data['username'],
        email=data['email'],
        password=data['password']  # [X] Pas de hash!
    )
    db.session.add(user)
    db.session.commit()
    
    return jsonify({'id': user.id}), 201

# Issues détectées par SonarQube:
# 1. Critical Vulnerability: SQL Injection (line 7)
# 2. Major Bug: Uncaught exception possible (line 11)
# 3. Blocker Vulnerability: Password in clear text (line 18)
# 4. Critical Vulnerability: Storing unencrypted password (line 28)
# 5. Major Code Smell: No input validation (line 24)

# [OK] APRÈS (corrigé):
# app/routes.py
from flask import request, jsonify, abort
from werkzeug.security import generate_password_hash
from app import app, db
from app.models import User
from marshmallow import Schema, fields, ValidationError

# Schéma de validation
class UserSchema(Schema):
    username = fields.Str(required=True, validate=lambda x: len(x) >= 3)
    email = fields.Email(required=True)
    password = fields.Str(required=True, validate=lambda x: len(x) >= 8)

user_schema = UserSchema()

@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    """Récupérer un utilisateur par ID"""
    # [OK] ORM (pas de SQL injection)
    user = User.query.get(user_id)
    
    # [OK] Gestion d'erreur
    if user is None:
        abort(404, description="User not found")
    
    # [OK] Seulement données publiques
    return jsonify({
        'id': user.id,
        'username': user.username,
        'email': user.email
        # Pas de mot de passe!
    })

@app.route('/api/users', methods=['POST'])
def create_user():
    """Créer un nouvel utilisateur"""
    # [OK] Validation des données
    try:
        data = user_schema.load(request.json)
    except ValidationError as err:
        return jsonify({'errors': err.messages}), 400
    
    # [OK] Vérifier unicité email
    if User.query.filter_by(email=data['email']).first():
        return jsonify({'error': 'Email already exists'}), 409
    
    # [OK] Hash du mot de passe
    user = User(
        username=data['username'],
        email=data['email'],
        password=generate_password_hash(data['password'])
    )
    
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': 'Database error'}), 500
    
    return jsonify({'id': user.id}), 201

# Tests correspondants:
# tests/test_routes.py
import pytest
from app import app, db
from app.models import User

@pytest.fixture
def client():
    app.config['TESTING'] = True
    with app.test_client() as client:
        with app.app_context():
            db.create_all()
            yield client
            db.drop_all()

def test_get_user_success(client):
    """Test récupération utilisateur existant"""
    user = User(username='testuser', email='test@example.com', password='hashed')
    db.session.add(user)
    db.session.commit()
    
    response = client.get(f'/api/users/{user.id}')
    assert response.status_code == 200
    data = response.get_json()
    assert data['username'] == 'testuser'
    assert 'password' not in data  # Vérifier que password n'est pas exposé

def test_get_user_not_found(client):
    """Test récupération utilisateur inexistant"""
    response = client.get('/api/users/999')
    assert response.status_code == 404

def test_create_user_success(client):
    """Test création utilisateur valide"""
    data = {
        'username': 'newuser',
        'email': 'new@example.com',
        'password': 'SecurePass123!'
    }
    response = client.post('/api/users', json=data)
    assert response.status_code == 201
    assert User.query.filter_by(email='new@example.com').first() is not None

def test_create_user_invalid_email(client):
    """Test création avec email invalide"""
    data = {
        'username': 'newuser',
        'email': 'invalid-email',
        'password': 'SecurePass123!'
    }
    response = client.post('/api/users', json=data)
    assert response.status_code == 400

def test_create_user_duplicate_email(client):
    """Test création avec email existant"""
    user = User(username='existing', email='exist@example.com', password='hashed')
    db.session.add(user)
    db.session.commit()
    
    data = {
        'username': 'newuser',
        'email': 'exist@example.com',
        'password': 'SecurePass123!'
    }
    response = client.post('/api/users', json=data)
    assert response.status_code == 409


# === PROJET REACT / JAVASCRIPT ===

# Structure:
react_app/
├── public/
│   └── index.html
├── src/
│   ├── components/
│   │   ├── Header.js
│   │   ├── Footer.js
│   │   └── UserList.js
│   ├── services/
│   │   └── api.js
│   ├── utils/
│   │   └── validators.js
│   ├── App.js
│   └── index.js
├── src/__tests__/
│   ├── components/
│   │   └── UserList.test.js
│   └── utils/
│       └── validators.test.js
├── package.json
└── sonar-project.properties

# sonar-project.properties:
sonar.projectKey=react-app
sonar.projectName=React App
sonar.projectVersion=1.0.0

sonar.sources=src
sonar.tests=src
sonar.test.inclusions=**/*.test.js,**/*.test.jsx,**/*.spec.js

sonar.javascript.lcov.reportPaths=coverage/lcov.info

sonar.exclusions=\
  **/node_modules/**,\
  **/build/**,\
  **/dist/**,\
  **/coverage/**,\
  **/*.test.js,\
  **/*.spec.js

sonar.sourceEncoding=UTF-8

# package.json (configuration Jest):
{
  "name": "react-app",
  "version": "1.0.0",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "test:coverage": "react-scripts test --coverage --watchAll=false",
    "sonar": "sonar-scanner"
  },
  "jest": {
    "collectCoverageFrom": [
      "src/**/*.{js,jsx}",
      "!src/index.js",
      "!src/**/*.test.{js,jsx}",
      "!src/**/*.spec.{js,jsx}"
    ],
    "coverageReporters": ["lcov", "text", "html"],
    "coverageThreshold": {
      "global": {
        "branches": 80,
        "functions": 80,
        "lines": 80,
        "statements": 80
      }
    }
  }
}

# Exemple de code avec problèmes:

# [X] AVANT (avec issues):
// src/components/UserList.js
import React, { useState, useEffect } from 'react';

function UserList() {
  const [users, setUsers] = useState([]);
  
  useEffect(() => {
    // [X] Fetch sans gestion d'erreur
    fetch('https://api.example.com/users')
      .then(res => res.json())
      .then(data => setUsers(data));
  }, []);
  
  // [X] Pas de vérification si users existe
  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map(user => (
          // [X] Pas de key unique
          <li>
            {/* [X] XSS possible si user.name contient HTML */}
            <div dangerouslySetInnerHTML={{__html: user.name}} />
          </li>
        ))}
      </ul>
    </div>
  );
}

export default UserList;

# Issues détectées:
# 1. Major Bug: Unhandled promise rejection (line 7)
# 2. Critical Vulnerability: XSS vulnerability (line 19)
# 3. Major Bug: Missing key prop (line 16)
# 4. Minor Code Smell: Map may be undefined (line 15)

# [OK] APRÈS (corrigé):
// src/components/UserList.js
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';

function UserList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    // [OK] Gestion d'erreur complète
    const fetchUsers = async () => {
      try {
        setLoading(true);
        const response = await fetch('https://api.example.com/users');
        
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const data = await response.json();
        setUsers(data);
        setError(null);
      } catch (err) {
        console.error('Error fetching users:', err);
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };
    
    fetchUsers();
  }, []);
  
  // [OK] Affichage conditionnel
  if (loading) {
    return <div>Loading...</div>;
  }
  
  if (error) {
    return <div>Error: {error}</div>;
  }
  
  // [OK] Vérification si users existe et n'est pas vide
  if (!users || users.length === 0) {
    return <div>No users found.</div>;
  }
  
  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map(user => (
          // [OK] Key unique
          <li key={user.id}>
            {/* [OK] Texte échappé automatiquement */}
            <div>{user.name}</div>
            <div>{user.email}</div>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default UserList;

# Tests correspondants:
// src/__tests__/components/UserList.test.js
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import UserList from '../../components/UserList';

// Mock fetch
global.fetch = jest.fn();

describe('UserList', () => {
  beforeEach(() => {
    fetch.mockClear();
  });
  
  it('affiche loading pendant le chargement', () => {
    fetch.mockImplementation(() => new Promise(() => {})); // Ne résout jamais
    
    render(<UserList />);
    expect(screen.getByText('Loading...')).toBeInTheDocument();
  });
  
  it('affiche les utilisateurs après chargement réussi', async () => {
    const mockUsers = [
      { id: 1, name: 'John Doe', email: 'john@example.com' },
      { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
    ];
    
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => mockUsers
    });
    
    render(<UserList />);
    
    await waitFor(() => {
      expect(screen.getByText('John Doe')).toBeInTheDocument();
      expect(screen.getByText('Jane Smith')).toBeInTheDocument();
    });
  });
  
  it('affiche un message d\'erreur en cas d\'échec', async () => {
    fetch.mockRejectedValueOnce(new Error('Network error'));
    
    render(<UserList />);
    
    await waitFor(() => {
      expect(screen.getByText(/Error: Network error/i)).toBeInTheDocument();
    });
  });
  
  it('affiche un message si aucun utilisateur', async () => {
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => []
    });
    
    render(<UserList />);
    
    await waitFor(() => {
      expect(screen.getByText('No users found.')).toBeInTheDocument();
    });
  });
});

# Script pour lancer tests et analyse:
# analyze.sh
#!/bin/bash
set -e

echo "[TEST] Running tests with coverage..."
npm run test:coverage

echo "[GRAPHIQUE] Running SonarQube analysis..."
npm run sonar

echo "[OK] Done!"


[OK] SCÉNARIOS RÉELS ET RÉSOLUTIONS

# === SCÉNARIO 1: Projet Legacy avec 50+ Bugs ===

# SITUATION:
# - Projet Python de 3 ans
# - 15,000 lignes de code
# - 53 bugs détectés
# - 247 code smells
# - Coverage: 35%
# - Équipe découragée

# PROBLÈME:
# Chef de projet: "Il faut tout corriger avant de continuer!"
# Développeurs: "Impossible, ça prendrait 3 mois!"

# SOLUTION: Approche "Clean as You Code"
# ─────────────────────────────────────────

# ÉTAPE 1: Accepter la situation actuelle
# Ne PAS essayer de tout corriger d'un coup

# ÉTAPE 2: Configurer New Code Period
# Administration > Configuration > New Code
# Choisir: "Previous version"

# ÉTAPE 3: Quality Gate focus sur New Code
# Quality Gate "Legacy Improvement":
sonar.qualitygate.name=Legacy-Improvement

# Conditions:
# New Coverage >= 70% (au lieu de 80%)
# New Bugs = 0
# New Vulnerabilities = 0
# New Code Smells <= 10
# New Duplications <= 5%

# Ne PAS mettre de conditions sur Overall Code!

# ÉTAPE 4: Exclure code legacy vraiment problématique
# sonar-project.properties
sonar.exclusions=\
  **/old_deprecated_module/**,\
  **/legacy/**

# ÉTAPE 5: Planifier amélioration progressive
# Règle: Chaque fois qu'on touche à un vieux fichier, on l'améliore

# Exemple:
# Semaine 1: Correction bug dans user_service.py
# -> En profiter pour:
#   - Ajouter tests (coverage 35% -> 75% pour ce fichier)
#   - Corriger 3 code smells dans ce fichier
#   - Renommer variables mal nommées

# ÉTAPE 6: Célébrer les progrès
# Après 3 mois:
# - Overall bugs: 53 -> 48 (-10%)
# - Overall coverage: 35% -> 42% (+20%)
# - New code: TOUJOURS propre (Quality Gate pass)
# - Équipe motivée!

# Après 12 mois:
# - Overall bugs: 53 -> 15 (-70%)
# - Overall coverage: 35% -> 65% (+85%)
# - Dette technique: -60%


# === SCÉNARIO 2: Quality Gate Bloque Déploiement Urgent ===

# SITUATION:
# - Vendredi 17h
# - Bug critique en production
# - Fix prêt et testé
# - Quality Gate: FAILED (Coverage 75%, besoin 80%)
# - Client attend le fix

# PROBLÈME:
# Développeur: "Je dois déployer maintenant!"
# Quality Gate: "[X] FAILED"

# MAUVAISE SOLUTION [X]:
# - Désactiver Quality Gate temporairement
# - "On corrigera plus tard"
# - Spoiler: On ne corrige jamais

# BONNE SOLUTION [OK]:
# ─────────────────

# OPTION 1: Ajouter tests rapidement (15 minutes)
# Le fix est simple, les tests aussi

# Avant (75% coverage):
def fix_calculation_bug(amount):
    if amount < 0:
        return 0
    return amount * 1.2

# Tests existants (insuffisants):
def test_fix_positive():
    assert fix_calculation_bug(100) == 120

# Ajouter tests manquants:
def test_fix_negative():
    assert fix_calculation_bug(-10) == 0

def test_fix_zero():
    assert fix_calculation_bug(0) == 0

def test_fix_decimal():
    assert fix_calculation_bug(10.5) == 12.6

# Re-lancer analyse: Coverage 75% -> 85% [OK]

# OPTION 2: Hotfix Exception (procédure)
# Si vraiment pas le temps:

# 1. Documenter la décision
# Git commit message:
git commit -m "HOTFIX: Critical calculation bug

Issue: Production calculator returning wrong values
Impact: All users affected
Fix: Added validation for negative values

Quality Gate: Bypassed for emergency
Reason: Production down, client waiting
TODO: Add missing tests on Monday (ticket #1234)

Approved by: [Manager Name]
"

# 2. Créer ticket immédiatement
# Jira/GitHub: "Add tests for hotfix #1234"
# Priority: HIGH
# Assigné: Vous-même
# Deadline: Lundi

# 3. Déployer avec bypass manuel
# (Nécessite permissions admin)

# 4. Lundi matin: Ajouter tests et re-déployer
# Fermer le ticket seulement après Quality Gate PASS


# === SCÉNARIO 3: Faux Positifs en Masse ===

# SITUATION:
# - Nouveau projet Python
# - 30 "bugs" détectés
# - Développeur les examine: 20 sont des faux positifs!
# - Frustration: "SonarQube est nul!"

# EXEMPLE de faux positif courant:

# Code:
def process_data(data: Optional[List[str]]) -> str:
    if data is None:
        return ""
    
    result = []
    for item in data:
        result.append(item.upper())  # [X] SonarQube: "item may be None"
    
    return " ".join(result)

# SonarQube dit: "item may be None" -> FAUX POSITIF
# Raison: data est une List[str], donc item ne peut pas être None

# MAUVAISE SOLUTION [X]:
# - Marquer tout en "Won't Fix"
# - Ignorer SonarQube
# - Se plaindre dans Slack

# BONNE SOLUTION [OK]:
# ─────────────────

# SOLUTION 1: Améliorer le code (rendre intentions claires)
def process_data(data: Optional[List[str]]) -> str:
    if data is None:
        return ""
    
    # [OK] Filtrer None explicitement (même si pas nécessaire)
    # Cela rend le code plus robuste ET SonarQube comprend
    filtered_data = [item for item in data if item is not None]
    result = [item.upper() for item in filtered_data]
    
    return " ".join(result)

# SOLUTION 2: Désactiver la règle pour ce cas
# Si vraiment faux positif récurrent:

# Quality Profiles > Python > Règle concernée
# Désactiver OU Changer sévérité OU Paramètres

# SOLUTION 3: Commentaire spécial (inline)
def process_data(data: Optional[List[str]]) -> str:
    if data is None:
        return ""
    
    result = []
    for item in data:
        result.append(item.upper())  # NOSONAR - item cannot be None here
    
    return " ".join(result)

# Note: Utiliser NOSONAR avec parcimonie!
# Documenter POURQUOI c'est un faux positif


# === SCÉNARIO 4: Coverage Impossible à Atteindre ===

# SITUATION:
# - Quality Gate: Coverage >= 80%
# - Votre code: 78%
# - Les 2% manquants: Code impossible à tester

# EXEMPLE:

# Code impossible à tester directement:
import sys

def main():
    # Configuration en fonction de l'OS
    if sys.platform == 'win32':
        config = WindowsConfig()  # [X] Impossible de tester sous Linux!
    else:
        config = UnixConfig()
    
    app = Application(config)
    app.run()

if __name__ == '__main__':
    main()  # [X] Pas couvert par tests (point d'entrée)

# PROBLÈME:
# - 5 lignes non couvertes
# - Coverage global: 78%
# - Besoin: 80%

# MAUVAISE SOLUTION [X]:
# - Baisser le seuil à 78%
# - "C'est bon, 78% c'est suffisant"

# BONNE SOLUTION [OK]:
# ─────────────────

# SOLUTION 1: Exclure le code non testable
# sonar-project.properties
sonar.coverage.exclusions=\
  **/main.py,\
  **/__main__.py,\
  **/wsgi.py,\
  **/asgi.py

# SOLUTION 2: Refactoriser pour rendre testable
# Avant (non testable):
def main():
    if sys.platform == 'win32':
        config = WindowsConfig()
    else:
        config = UnixConfig()
    
    app = Application(config)
    app.run()

# Après (testable):
def get_config(platform: str) -> Config:
    """Retourne config selon platform"""
    if platform == 'win32':
        return WindowsConfig()
    return UnixConfig()

def create_app(config: Config) -> Application:
    """Crée application avec config"""
    return Application(config)

def main():
    """Point d'entrée (minimal, non testé)"""
    config = get_config(sys.platform)
    app = create_app

[OK] PROBLÈMES D'INSTALLATION

# === PROBLÈME 1: SonarQube ne démarre pas ===

# SYMPTÔMES:
# - Docker container s'arrête immédiatement
# - Ou message: "SonarQube failed to start"
# - Logs montrent erreurs

# DIAGNOSTIC:
docker logs sonarqube

# OU si installation native:
tail -f $SONARQUBE_HOME/logs/sonar.log

# CAUSES COURANTES ET SOLUTIONS:

# Cause 1: Pas assez de mémoire
# ─────────────────────────────
# Erreur dans logs:
# "There is insufficient memory for the Java Runtime Environment"

# Solution:
# Docker:
docker run -d \
  --name sonarqube \
  -p 9000:9000 \
  -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true \
  -m 4g \
  sonarqube:lts-community

# Installation native:
# Éditer conf/sonar.properties
sonar.web.javaOpts=-Xmx512m -Xms128m
sonar.ce.javaOpts=-Xmx512m -Xms128m
sonar.search.javaOpts=-Xms512m -Xmx512m

# Cause 2: Port 9000 déjà utilisé
# ───────────────────────────────
# Erreur: "Address already in use"

# Vérifier quel processus utilise le port:
# Linux/Mac:
lsof -i :9000
# Ou
sudo netstat -tulpn | grep :9000

# Windows:
netstat -ano | findstr :9000

# Solutions:
# A) Tuer le processus qui utilise le port
kill -9 [PID]

# B) Changer le port SonarQube
# conf/sonar.properties:
sonar.web.port=9001

# Docker:
docker run -d --name sonarqube -p 9001:9000 sonarqube:lts-community

# Cause 3: Problème de base de données
# ────────────────────────────────────
# Erreur: "Unable to connect to database"

# Vérifier que PostgreSQL est démarré:
sudo systemctl status postgresql

# Démarrer si nécessaire:
sudo systemctl start postgresql

# Tester connexion:
psql -U sonar -d sonarqube -h localhost

# Si erreur "password authentication failed":
# Réinitialiser mot de passe PostgreSQL:
sudo -u postgres psql
ALTER USER sonar WITH PASSWORD 'nouveauMotDePasse';
\q

# Mettre à jour conf/sonar.properties:
sonar.jdbc.password=nouveauMotDePasse

# Cause 4: Elasticsearch bootstrap checks failed
# ───────────────────────────────────────────────
# Erreur: "max virtual memory areas vm.max_map_count [65530] is too low"

# Solution Linux:
sudo sysctl -w vm.max_map_count=262144

# Rendre permanent:
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf

# Docker:
# Sur l'hôte:
sudo sysctl -w vm.max_map_count=262144

# Ou désactiver checks (DEV seulement!):
docker run -d \
  --name sonarqube \
  -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true \
  sonarqube:lts-community

# Cause 5: Permissions fichiers
# ─────────────────────────────
# Erreur: "Permission denied" dans logs

# Donner permissions:
sudo chown -R 1000:1000 $SONARQUBE_HOME/data
sudo chown -R 1000:1000 $SONARQUBE_HOME/logs
sudo chown -R 1000:1000 $SONARQUBE_HOME/extensions

# Docker volumes:
docker run -d \
  --name sonarqube \
  --user $(id -u):$(id -g) \
  -v sonarqube_data:/opt/sonarqube/data \
  sonarqube:lts-community


# === PROBLÈME 2: Interface web inaccessible ===

# SYMPTÔMES:
# - http://localhost:9000 -> "Connection refused"
# - Ou page blanche
# - Ou "502 Bad Gateway"

# DIAGNOSTIC:

# Vérifier que SonarQube tourne:
docker ps
# Ou
ps aux | grep sonar

# Vérifier logs:
docker logs sonarqube
# Chercher: "SonarQube is operational"

# Vérifier status API:
curl http://localhost:9000/api/system/status

# SOLUTIONS:

# Solution 1: Attendre que SonarQube soit complètement démarré
# Premier démarrage: 2-5 minutes
# Démarrages suivants: 30-60 secondes

# Suivre les logs:
docker logs -f sonarqube

# Attendre ce message:
# "SonarQube is operational"

# Solution 2: Vérifier la configuration réseau
# Docker:
docker inspect sonarqube | grep IPAddress

# Tester avec IP Docker:
curl http://172.17.0.2:9000/api/system/status

# Solution 3: Problème de firewall
# Linux:
sudo ufw allow 9000/tcp

# Windows:
# Panneau de configuration > Pare-feu Windows
# Règle entrante pour port 9000

# Solution 4: Logs web.log montrent erreurs
tail -f logs/web.log

# Si "OutOfMemoryError":
# Augmenter mémoire (voir Cause 1 ci-dessus)


# === PROBLÈME 3: Base de données corrompue ===

# SYMPTÔMES:
# - SonarQube démarre mais crash rapidement
# - Erreurs SQL dans logs
# - "Database is not up-to-date"

# DIAGNOSTIC:
# Logs montrent:
# "ERROR web[][o.s.s.p.Platform] Background initialization failed. Stopping SonarQube"

# SOLUTION 1: Réinitialiser base de données (PERTE DE DONNÉES!)
# ──────────────────────────────────────────────────────────────

# Sauvegarder d'abord (si possible):
pg_dump -U sonar sonarqube > backup.sql

# Supprimer et recréer:
sudo -u postgres psql
DROP DATABASE sonarqube;
CREATE DATABASE sonarqube;
GRANT ALL PRIVILEGES ON DATABASE sonarqube TO sonar;
\q

# Redémarrer SonarQube (réinitialisera la DB):
docker restart sonarqube

# SOLUTION 2: Migration de version échouée
# ────────────────────────────────────────

# Si mise à jour SonarQube a échoué:
# 1. Restaurer ancienne version
# 2. Restaurer backup DB
# 3. Lire notes de migration: https://docs.sonarqube.org/latest/setup/upgrading/

# Restaurer backup:
psql -U sonar sonarqube < backup.sql


[OK] PROBLÈMES D'ANALYSE

# === PROBLÈME 4: Scanner ne trouve pas les fichiers ===

# SYMPTÔMES:
# - Analyse se termine sans erreur
# - Mais 0 fichiers analysés
# - Dashboard vide ou "No data"

# DIAGNOSTIC:
# Logs du scanner montrent:
# "0 files indexed"
# "0 source files to be analyzed"

# CAUSES ET SOLUTIONS:

# Cause 1: Mauvais chemin sources
# ───────────────────────────────
# sonar-project.properties incorrect:
sonar.sources=source  # [X] Dossier n'existe pas!

# Vérifier structure:
ls -la
# Vous voyez:
# drwxr-xr-x  src/

# Corriger:
sonar.sources=src  # [OK] Bon chemin

# Cause 2: Patterns d'exclusion trop larges
# ─────────────────────────────────────────
sonar.exclusions=**/*  # [X] Exclut TOUT!

# Corriger:
sonar.exclusions=**/node_modules/**,**/venv/**

# Cause 3: Exécution dans mauvais dossier
# ───────────────────────────────────────
# Vous êtes dans:
pwd
# /home/user/projects

# Mais projet dans:
# /home/user/projects/mon-projet/

# Solution:
cd mon-projet
sonar-scanner

# Cause 4: Fichiers pas reconnus comme code
# ─────────────────────────────────────────
# Extensions non standard:
# - .py.bak
# - .js.old
# - .txt (contenant code Python)

# Solution: Forcer reconnaissance
sonar.sources=.
sonar.inclusions=**/*.py,**/*.js,**/*.txt

# Ou renommer fichiers avec bonnes extensions


# === PROBLÈME 5: "Insufficient privileges" ===

# SYMPTÔMES:
# - Erreur: "Insufficient privileges"
# - Ou "You're not authorized to execute any SonarQube analysis"

# DIAGNOSTIC:
# L'utilisateur/token n'a pas les bonnes permissions

# SOLUTIONS:

# Solution 1: Vérifier token
# ─────────────────────────
# Token expiré ou révoqué?
# Mon Compte > Sécurité > Tokens
# Vérifier que token existe et est actif

# Générer nouveau token si nécessaire
# Mettre à jour dans CI/CD

# Solution 2: Permissions projet
# ──────────────────────────────
# L'utilisateur doit avoir permission "Execute Analysis"

# Aller dans:
# Project Settings > Permissions
# Vérifier que votre utilisateur/groupe a "Execute Analysis"

# Ou donner à tous les utilisateurs authentifiés:
# Anyone -> Execute Analysis: [OK]

# Solution 3: "Force Authentication" activé
# ────────────────────────────────────────
# Administration > Configuration > Security > Force user authentication

# Si activé, tous les appels doivent être authentifiés
# Utiliser token dans toutes les commandes:
sonar-scanner -Dsonar.token=VOTRE_TOKEN

# Solution 4: Token dans mauvais format
# ─────────────────────────────────────
# Token doit être passé via -Dsonar.token=
# PAS via -Dsonar.login= (déprécié)

# [X] Ancien (déprécié):
sonar-scanner -Dsonar.login=admin -Dsonar.password=admin

# [OK] Nouveau:
sonar-scanner -Dsonar.token=squ_xxxxx


# === PROBLÈME 6: Coverage non détecté ===

# SYMPTÔMES:
# - Vous avez des tests
# - Tests passent
# - Coverage généré
# - Mais SonarQube montre 0% coverage

# DIAGNOSTIC:
# Logs scanner montrent:
# "Sensor Python Coverage [python]"
# "Coverage report doesn't exist: coverage.xml"

# CAUSES ET SOLUTIONS:

# Cause 1: Rapport coverage non généré
# ────────────────────────────────────
# Vérifier que fichier existe:
ls -la coverage.xml
# Si absent: tests n'ont pas généré coverage

# Solution Python:
pytest --cov=src --cov-report=xml

# Solution JavaScript (Jest):
npm test -- --coverage

# Solution Java (Maven):
mvn clean test jacoco:report

# Cause 2: Mauvais chemin dans config
# ───────────────────────────────────
# sonar-project.properties:
sonar.python.coverage.reportPaths=coverage.xml

# Mais fichier est dans:
# tests/coverage.xml

# Corriger:
sonar.python.coverage.reportPaths=tests/coverage.xml

# Ou chemin relatif:
sonar.python.coverage.reportPaths=./coverage.xml

# Cause 3: Format coverage incompatible
# ─────────────────────────────────────
# SonarQube attend format XML (Cobertura)

# Vérifier format:
head -n 5 coverage.xml

# Doit commencer par:
# <?xml version="1.0" ?>
# <coverage version="..." ...>

# Générer bon format:
# Python (pytest-cov génère Cobertura):
pytest --cov=src --cov-report=xml

# JavaScript (Jest avec config):
# jest.config.js:
module.exports = {
  coverageReporters: ['lcov', 'text']
};

# Cause 4: Chemins absolus vs relatifs
# ────────────────────────────────────
# Coverage contient chemins absolus:
# /home/user/project/src/main.py

# Mais SonarQube attend chemins relatifs:
# src/main.py

# Solution Python (pytest-cov):
pytest --cov=src --cov-report=xml --cov-report=term

# Vérifier dans coverage.xml que chemins sont relatifs

# Si chemins absolus, utiliser:
sonar.projectBaseDir=/home/user/project

# Cause 5: Fichiers sources déplacés
# ──────────────────────────────────
# Coverage généré avant restructuration
# Chemins dans coverage.xml ne correspondent plus

# Solution: Regénérer coverage APRÈS restructuration
rm -rf .coverage coverage.xml htmlcov/
pytest --cov=src --cov-report=xml


# === PROBLÈME 7: Analyse très lente ===

# SYMPTÔMES:
# - Analyse prend 30+ minutes
# - CI/CD timeout
# - Compute Engine queue longue

# DIAGNOSTIC:
# Combien de fichiers analysés?
# Logs montrent:
# "12,456 source files to be analyzed"
# "Processing time: 1847s"

# SOLUTIONS:

# Solution 1: Exclure fichiers inutiles
# ─────────────────────────────────────
sonar.exclusions=\
  **/node_modules/**,\
  **/vendor/**,\
  **/dist/**,\
  **/build/**,\
  **/*.min.js,\
  **/*.min.css,\
  **/migrations/**,\
  **/generated/**,\
  **/__pycache__/**,\
  **/venv/**,\
  **/.venv/**

# Solution 2: Désactiver analyses inutiles
# ────────────────────────────────────────
# Pas de check duplication sur code généré:
sonar.cpd.exclusions=**/generated/**,**/migrations/**

# Pas de coverage sur tests:
sonar.coverage.exclusions=**/tests/**

# Solution 3: Augmenter mémoire scanner
# ─────────────────────────────────────
export SONAR_SCANNER_OPTS="-Xmx4096m"

# CI/CD (GitHub Actions):
- name: SonarQube Scan
  env:
    SONAR_SCANNER_OPTS: "-Xmx4096m"
  run: sonar-scanner

# Solution 4: Analyse incrémentale (Developer Edition+)
# ──────────────────────────────────────────────────────
# Analyser seulement fichiers modifiés dans PR:
sonar-scanner \
  -Dsonar.pullrequest.key=123 \
  -Dsonar.pullrequest.branch=feature \
  -Dsonar.pullrequest.base=main

# Solution 5: Scanner cache
# ────────────────────────
sonar-scanner -Dsonar.scanner.cache.enabled=true

# CI/CD: Cacher entre builds
# GitHub Actions:
- uses: actions/cache@v3
  with:
    path: .sonar/cache
    key: ${{ runner.os }}-sonar

# Solution 6: Compute Engine workers (Server)
# ───────────────────────────────────────────
# Si plusieurs projets en queue:
# conf/sonar.properties:
sonar.ce.workerCount=4  # Au lieu de 1


# === PROBLÈME 8: Quality Gate toujours FAILED ===

# SYMPTÔMES:
# - Vous corrigez issues
# - Re-analysez
# - Quality Gate: toujours FAILED

# DIAGNOSTIC:
# Voir POURQUOI failed:
# Dashboard > Quality Gate > Voir détails

# Exemple:
# "New Coverage is 75% (required >= 80%)" [X]

# SOLUTIONS:

# Solution 1: Mauvaise Quality Gate appliquée
# ───────────────────────────────────────────
# Vérifier quelle QG est utilisée:
# Project Settings > Quality Gate

# Si "Sonar way" est trop strict pour projet legacy:
# Créer QG custom moins strict:
# Administration > Quality Gates > Create

# "Legacy-Friendly":
# - New Coverage >= 60% (au lieu de 80%)
# - New Bugs <= 3 (au lieu de 0)

# Appliquer au projet:
# Project Settings > Quality Gate > Legacy-Friendly

# Solution 2: Conditions sur Overall Code
# ───────────────────────────────────────
# Quality Gate a condition:
# "Overall Coverage >= 80%"

# Projet legacy: 45% coverage
# Impossible à atteindre rapidement!

# Modifier QG pour focus sur New Code:
# Quality Gates > Edit > Supprimer condition Overall
# Ajouter: "New Coverage >= 80%"

# Solution 3: New Code Period mal configuré
# ────────────────────────────────────────
# Si New Code Period = "30 jours"
# Mais pas de commit depuis 40 jours
# -> Aucun "New Code" -> QG peut échouer bizarrement

# Vérifier:
# Project Settings > New Code

# Changer en: "Previous version"
# Chaque analyse avec nouvelle version = nouveau New Code Period

# Solution 4: Coverage non pris en compte
# ───────────────────────────────────────
# QG dit: "New Coverage is 0%"
# Mais vous avez des tests!

# -> Voir "PROBLÈME 6: Coverage non détecté" ci-dessus

# Solution 5: Bugs/Vulnerabilities cachés
# ───────────────────────────────────────
# QG: "New Vulnerabilities is 2 (required = 0)"
# Vous dites: "Mais j'ai tout corrigé!"

# -> Issues marquées "Won't Fix" comptent encore!
# -> Issues "Confirmed" comptent encore!

# Solution: Résoudre correctement
# Issues > Sélectionner > Resolve as "Fixed"


[OK] PROBLÈMES DE PERMISSIONS

# === PROBLÈME 9: Utilisateur ne voit pas projet ===

# SYMPTÔMES:
# - Admin voit projet
# - Utilisateur normal: "No projects"

# DIAGNOSTIC:
# Projet est privé et utilisateur n'a pas accès

# SOLUTIONS:

# Solution 1: Rendre projet public
# ────────────────────────────────
# Project Settings > Permissions
# "Public" -> [OK]

# [ATTENTION] Attention: Tout le monde peut voir le code!

# Solution 2: Donner accès spécifique
# ──────────────────────────────────
# Project Settings > Permissions
# Grant access to:
# - Utilisateur spécifique
# - Ou groupe

# Permissions:
# - Browse: Voir projet [OK]
# - See Source Code: Voir code [OK]

# Solution 3: Template de permissions
# ───────────────────────────────────
# Pour appliquer à plusieurs projets:
# Administration > Security > Permission Templates
# Create template
# Appliquer aux projets


# === PROBLÈME 10: Token révoqué automatiquement ===

# SYMPTÔMES:
# - CI/CD fonctionnait hier
# - Aujourd'hui: "401 Unauthorized"
# - Token révoqué

# CAUSES:

# Cause 1: Token expiré
# ────────────────────
# Tokens peuvent avoir expiration

# Vérifier:
# Mon Compte > Sécurité > Tokens
# Voir date expiration

# Solution: Générer nouveau token
# Copy/paste dans CI/CD secrets

# Cause 2: Utilisateur désactivé
# ─────────────────────────────
# Si utilisateur propriétaire du token est désactivé
# Token révoqué automatiquement

# Solution:
# Administration > Security > Users
# Réactiver utilisateur

# Cause 3: Token révoqué manuellement
# ──────────────────────────────────
# Admin a révoqué token (sécurité)

# Solution:
# Générer nouveau token
# Utiliser "Project Analysis Token" (plus sécurisé)


[OK] PROBLÈMES DE PERFORMANCE

# === PROBLÈME 11: SonarQube serveur très lent ===

# SYMPTÔMES:
# - Interface web très lente
# - Analyses prennent des heures
# - Compute Engine queue longue

# DIAGNOSTIC:

# Vérifier ressources:
# Administration > System > System Info

# Regarder:
# - CPU Usage
# - Memory Usage
# - Database Pool

# SOLUTIONS:

# Solution 1: Pas assez de RAM
# ───────────────────────────
# System Info montre:
# Memory Usage: 95%+ (presque plein)

# Augmenter RAM allouée:
# conf/sonar.properties:
sonar.web.javaOpts=-Xmx2048m -Xms512m
sonar.ce.javaOpts=-Xmx4096m -Xms1024m
sonar.search.javaOpts=-Xms2048m -Xmx2048m

# Docker:
docker run -d \
  --name sonarqube \
  -m 8g \
  sonarqube:lts-community

# Solution 2: Base de données lente
# ─────────────────────────────────
# PostgreSQL mal configuré

# postgresql.conf:
shared_buffers = 512MB
effective_cache_size = 2GB
work_mem = 32MB
maintenance_work_mem = 512MB
max_connections = 300

# Redémarrer PostgreSQL:
sudo systemctl restart postgresql

# Solution 3: Trop de projets inactifs
# ────────────────────────────────────
# 500+ projets non analysés depuis 6+ mois

# Nettoyer:
# Administration > Projects > Management
# Filter: Last analysis > 6 months ago
# Bulk delete

# Solution 4: Elasticsearch problèmes
# ───────────────────────────────────
# Logs/es.log montre erreurs

# Réindexer:
# Administration > System > Search Indexes
# "Trigger full reindex"

# Solution 5: Compute Engine saturé
# ─────────────────────────────────
# Queue avec 20+ analyses en attente

# Augmenter workers:
# conf/sonar.properties:
sonar.ce.workerCount=4

# [ATTENTION] Augmente utilisation CPU/RAM


# === PROBLÈME 12: Base de données pleine ===

# SYMPTÔMES:
# - Erreur: "No space left on device"
# - DB PostgreSQL atteint limite

# DIAGNOSTIC:
# Vérifier taille:
sudo -u postgres psql
SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size 
FROM pg_database;

# SOLUTIONS:

# Solution 1: Purger anciennes analyses
# ─────────────────────────────────────
# Administration > Configuration > Housekeeping
# Changer: "Keep only analyses more recent than 30 days"
# -> "Keep only analyses more recent than 7 days"

# Trigger manuel:
# Administration > System > Backup
# "Purge analysis history"

# Solution 2: Nettoyer projets inutiles
# ─────────────────────────────────────
# Supprimer projets non utilisés
# Administration > Projects > Management
# Delete inactive projects

# Solution 3: Vacuum PostgreSQL
# ─────────────────────────────
sudo -u postgres psql sonarqube
VACUUM FULL;
ANALYZE;

# Solution 4: Augmenter espace disque
# ──────────────────────────────────
# Redimensionner partition
# Ou ajouter disque


[OK] PROBLÈMES RÉSEAU & INTÉGRATION

# === PROBLÈME 13: GitHub/GitLab integration ne fonctionne pas ===

# SYMPTÔMES:
# - Pas de commentaire dans PR
# - Pas de status check
# - PR Decoration absente

# DIAGNOSTIC:
# Administration > Configuration > DevOps Platform Integrations
# Vérifier configuration

# SOLUTIONS:

# Solution 1: GitHub App mal configurée
# ─────────────────────────────────────
# Vérifier permissions GitHub App:
# - Checks: Read & Write [OK]
# - Pull Requests: Read & Write [OK]
# - Contents: Read [OK]

# Vérifier installation:
# GitHub > Organization > Settings > GitHub Apps
# App installée sur bons repos?

# Solution 2: Project binding manquant
# ────────────────────────────────────
# Dans SonarQube:
# Project Settings > Pull Request Decoration
# Configuration name: [sélectionner GitHub config]
# Repository identifier: owner/repo

# Solution 3: Token expiré
# ───────────────────────
# GitHub App Private Key expiré ou révoqué

# Générer nouvelle clé:
# GitHub App > General > Private keys > Generate

# Mettre à jour dans SonarQube:
# Administration > Configuration > GitHub

# Solution 4: Webhook GitLab non configuré
# ────────────────────────────────────────
# GitLab: Project > Settings > Webhooks
# URL: https://sonarqube.example.com/api/webhooks/gitlab
# Trigger: Merge Request events [OK]

# Solution 5: Firewall bloque requêtes
# ────────────────────────────────────
# SonarQube ne peut pas atteindre GitHub/GitLab

# Tester connexion depuis serveur SonarQube:
curl -I https://api.github.com
curl -I https://gitlab.com

# Si timeout: Configurer proxy ou ouvrir firewall


# === PROBLÈME 14: Scanner ne peut pas contacter serveur ===

# SYMPTÔMES:
# - Erreur: "Failed to connect to http://localhost:9000"
# - Ou "Connection refused"
# - Ou "Connection timeout"

# DIAGNOSTIC:
# Tester connexion manuelle:
curl http://localhost:9000/api/system/status

# SOLUTIONS:

# Solution 1: Mauvaise URL
# ───────────────────────
# sonar-project.properties ou commande:
sonar.host.url=http://localhost:9000  # [X] Si server distant

# Corriger:
sonar.host.url=https://sonarqube.votreentreprise.com

# Solution 2: HTTPS sans certificat valide
# ────────────────────────────────────────
# Erreur: "SSL certificate problem"

# Solution temporaire (DEV seulement!):
sonar-scanner \
  -Dsonar.scanner.skip.jreProvisioning=true \
  -Djavax.net.ssl.trustStore=NONE

# Solution permanente:
# Installer certificat CA dans truststore Java

# Solution 3: Proxy non configuré
# ───────────────────────────────
# Entreprise avec proxy obligatoire

# Configuration proxy:
export HTTP_PROXY=http://proxy.entreprise.com:8080
export HTTPS_PROXY=http://proxy.entreprise.com:8080

# Ou sonar-scanner.properties:
sonar.scanner.proxyHost=proxy.entreprise.com
sonar.scanner.proxyPort=8080
sonar.scanner.proxyUser=username
sonar.scanner.proxyPassword=password

# Solution 4: VPN déconnecté
# ─────────────────────────
# Si SonarQube sur réseau privé

# Vérifier VPN actif
# Se reconnecter si nécessaire


[OK] PROBLÈMES SPÉCIFIQUES PAR LANGAGE

# === PYTHON: Module not found ===

# SYMPTÔMES:
# - Analyse Python réussit
# - Mais beaucoup de faux positifs "Module not found"

# Exemple:
# from myapp.utils import helper  # [X] "Module 'myapp' not found"

# SOLUTION:
# SonarQube n'installe pas les dépendances

# Installer dépendances avant analyse:
pip install -r requirements.txt
sonar-scanner

# Ou en CI/CD:
- name: Install dependencies
  run: pip install -r requirements.txt

- name: SonarQube Scan
  run: sonar-scanner

# === JAVASCRIPT: TypeScript errors ===

# SYMPTÔMES:
# - Erreurs TypeScript bloquent analyse
# - "error TS2304: Cannot find name 'X'"

# SOLUTION:
# Installer dépendances TypeScript:
npm install
# Ou
yarn install

# Puis analyser:
sonar-scanner

# Si problèmes persistent:
# Exclure fichiers de définitions:
sonar.exclusions=**/*.d.ts

# === JAVA: Missing JaCoCo report ===

# SYMPTÔMES:
# - Tests exécutés
# - Mais coverage = 0%

# SOLUTION:
# Configurer JaCoCo dans pom.xml:
<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.10</version>
  <executions>
    <execution>
      <goals>
        <goal>prepare-agent</goal>
      </goals>
    </execution>
    <execution>
      <id>report</id>
      <phase>test</phase>
      <goals>
        <goal>report</goal>
      </goals>
    </execution>
  </executions>
</plugin>

# Exécuter:
mvn clean test jacoco:report
mvn sonar:sonar


[OK] CHECKLIST DÉPANNAGE RAPIDE

# Problème: SonarQube ne démarre pas
[ ] Vérifier logs: docker logs sonarqube
[ ] Vérifier mémoire disponible: free -h
[ ] Vérifier port disponible: lsof -i :9000
[ ] Vérifier PostgreSQL actif: systemctl status postgresql
[ ] Vérifier vm.max_map_count >= 262144

# Problème: Analyse échoue
[ ] Vérifier token valide: