# Guide de Contribution - TREK

Merci de contribuer au projet TREK ! Ce document explique comment contribuer efficacement.

## 📋 Table des matières

- [Prérequis](#prérequis)
- [Setup environnement local](#setup-environnement-local)
- [Documentation API (Swagger/OpenAPI)](#-documentation-api-swaggeropenapi)
- [Standards de code](#standards-de-code)
- [Security](#security)
- [Workflow Git](#workflow-git)
- [Commits](#commits)
- [Pull Requests](#pull-requests)
- [Tests](#tests)

---

## 🛠️ Prérequis

### Outils requis

- **Git** >= 2.30
- **Java** 17 (backend)
- **Node.js** >= 20 (frontend)
- **Maven** (inclus via wrapper `mvnw`)
- **npm** (inclus avec Node.js)
- **Podman** >= 4.0 (optionnel, pour tests locaux)

### Vérifier les versions

```bash
java -version    # openjdk 17.x.x
node -v          # v20.x.x
npm -v           # 10.x.x
git --version    # git version 2.x.x
```

---

## 🚀 Setup environnement local

### 1. Démarrage rapide (recommandé)

Le projet utilise **Task** (go-task) pour gérer l'environnement de développement.

#### Installation de Task

```bash
# Linux / macOS (script officiel)
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin

# Vérifier l'installation
task --version
```

> 📖 Plus d'options: https://taskfile.dev/installation

#### Commandes disponibles

```bash
# Démarrer l'environnement complet (full stack)
task start

# Démarrer uniquement les services backend (pour dev frontend local)
task dev:front         # Lance DB + Backend + Keycloak (sans frontend)

# Arrêter tous les services
task stop

# Redémarrer
task restart

# Voir les logs (temps réel)
task logs              # Tous les services
task logs:backend      # Backend uniquement
task logs:frontend     # Frontend uniquement
task logs:database     # Database uniquement

# Vérifier le statut des conteneurs
task status

# Rebuild les services
task build             # Tous
task build:backend     # Backend uniquement
task build:frontend    # Frontend uniquement

# Accès à la base de données
task db:shell          # Shell PostgreSQL interactif
task db:reset          # Reset DB (⚠️ SUPPRIME LES DONNÉES)

# Nettoyer complètement (⚠️ SUPPRIME TOUT)
task clean

# Lister toutes les commandes
task --list
```

#### Développement Local (Recommandé)

Pour un développement optimal avec rechargement rapide, lancez backend et frontend **en local** :

**Quick start (dev complet)** :
```bash
# Terminal 1 : Lancer uniquement les services (DB + Keycloak)
task dev

# Terminal 2 : Backend local avec Spring DevTools
cd backend
./mvnw spring-boot:run -Dspring-boot.run.profiles=local

# Terminal 3 : Frontend local avec Vite HMR
cd frontend
npm run dev
```

**Résultat** :
- Frontend sur http://localhost:5173 (HMR <100ms)
- Backend sur http://localhost:8080 (auto-restart ~5-10s)

---

#### Développement Frontend uniquement

Si tu travailles uniquement sur le frontend, voir **[frontend/DEV.md](./frontend/DEV.md)**.

```bash
task dev:front          # Lance DB + Backend + Keycloak
cd frontend && npm run dev
```

#### Développement Backend uniquement

Si tu travailles uniquement sur le backend, voir **[backend/DEV.md](./backend/DEV.md)**.

```bash
task dev:back           # Lance DB + Keycloak
cd backend && ./mvnw spring-boot:run -Dspring-boot.run.profiles=local
```

#### Points d'accès après `task start`

- **Frontend**: http://localhost:8081
- **Backend**: http://localhost:8080
- **Database**: localhost:5432

#### Documentation API

- **Swagger UI**: http://localhost:8080/swagger-ui.html
- **OpenAPI JSON**: http://localhost:8080/v3/api-docs
- **OpenAPI YAML**: http://localhost:8080/v3/api-docs.yaml

---

## 📚 Documentation API (Swagger/OpenAPI)

Le projet utilise **SpringDoc OpenAPI** pour générer automatiquement la documentation de l'API REST.

### Accéder à la documentation

Une fois le backend démarré (`task start` ou `./mvnw spring-boot:run`), la documentation est accessible via :

- **Interface interactive Swagger UI** : http://localhost:8080/swagger-ui.html
  - Permet de visualiser tous les endpoints
  - Tester les requêtes directement depuis le navigateur
  - Voir les schémas de données (DTOs, entités)

- **Spécification OpenAPI JSON** : http://localhost:8080/v3/api-docs
  - Format JSON pour outils d'automatisation (Postman, Insomnia, etc.)

- **Spécification OpenAPI YAML** : http://localhost:8080/v3/api-docs.yaml
  - Format YAML pour documentation ou génération de clients

### Documenter un nouvel endpoint

Lors de l'ajout d'un nouveau endpoint REST, suivez ces conventions :

#### 1. Ajouter `@Tag` au contrôleur (si nouveau)

```java
@RestController
@RequestMapping("/api/users")
@Tag(name = "Users", description = "API de gestion des utilisateurs")
public class UserController {
    // ...
}
```

#### 2. Documenter chaque endpoint avec `@Operation`

```java
@Operation(
    summary = "Récupérer tous les utilisateurs",
    description = "Retourne la liste complète de tous les utilisateurs du système"
)
@ApiResponses(value = {
    @ApiResponse(responseCode = "200", description = "Liste récupérée avec succès"),
    @ApiResponse(responseCode = "403", description = "Accès refusé")
})
@GetMapping
public ResponseEntity<List<UserDto>> getAllUsers() {
    // ...
}
```

#### 3. Documenter les paramètres avec `@Parameter`

```java
@GetMapping("/{id}")
public ResponseEntity<UserDto> getUserById(
    @Parameter(description = "ID de l'utilisateur à récupérer")
    @PathVariable Long id
) {
    // ...
}
```

#### 4. Conserver la Javadoc

**Important** : Gardez toujours la Javadoc standard Java en plus des annotations OpenAPI :

```java
/**
 * Get user by ID.
 *
 * @param id the user ID
 * @return the user DTO
 */
@Operation(summary = "Récupérer un utilisateur par ID")
@GetMapping("/{id}")
public ResponseEntity<UserDto> getUserById(@PathVariable Long id) {
    // ...
}
```

**Pourquoi ?**
- La Javadoc est visible dans l'IDE lors du développement
- Les annotations OpenAPI alimentent Swagger UI pour les utilisateurs de l'API
- Les deux sont complémentaires

### Configuration SpringDoc

La configuration OpenAPI se trouve dans :
- **Fichier** : `backend/src/main/java/com/junia/trek/backend/config/OpenApiConfig.java`
- **Dépendance** : `springdoc-openapi-starter-webmvc-ui` dans `backend/pom.xml`

Pour personnaliser la documentation (titre, description, contact, serveurs), modifier la classe `OpenApiConfig`.

### Bonnes pratiques

1. **Descriptions en français** : Pour faciliter la compréhension par l'équipe
2. **Codes HTTP précis** : Documenter tous les codes de retour possibles (200, 201, 400, 404, 500)
3. **Exemples de requêtes** : Utiliser `@Schema(example = "...")` sur les DTOs si nécessaire
4. **Grouper logiquement** : Utiliser `@Tag` pour organiser les endpoints par domaine métier
5. **Tester via Swagger UI** : Après modification, vérifier que l'endpoint fonctionne depuis l'interface

### Ressources

- [SpringDoc Documentation](https://springdoc.org/)
- [OpenAPI Specification](https://swagger.io/specification/)
- [Swagger UI Guide](https://swagger.io/tools/swagger-ui/)

---

### 2. Backend (standalone)

```bash
cd backend

# Build
./mvnw clean install

# Lancer
./mvnw spring-boot:run

# L'API démarre sur http://localhost:8080
```

### 3. Frontend (standalone)

```bash
cd frontend

# Installer les dépendances
npm install

# Lancer le dev server
npm run dev

# Le frontend démarre sur http://localhost:5173
```

### 4. Hooks Git (important)

```bash
# À la racine du projet
npm install

# Les pre-commit hooks sont maintenant actifs
```

---

## 📐 Standards de code

### Backend (Java)

**Style Guide**: [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)

#### Règles principales

- **Indentation**: 4 espaces
- **Ligne max**: 100 caractères
- **Naming**:
  - Classes: `PascalCase`
  - Méthodes/variables: `camelCase`
  - Constantes: `UPPER_SNAKE_CASE`
  - Packages: `lowercase`

#### Vérifier le style

```bash
cd backend

# Check style
./mvnw checkstyle:check

# Format automatiquement
./mvnw fmt:format
```

#### Exemple de code conforme

```java
package com.junia.trek.service;

import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class UserService {

    private static final int MAX_USERS = 100;

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}
```

---

### Frontend (TypeScript/React)

**Style Guide**: Airbnb ESLint + Prettier + TypeScript

#### Règles principales

- **Indentation**: 2 espaces
- **Quotes**: Single quotes `'`
- **Semicolons**: Oui (`;` requis)
- **Trailing commas**: ES5
- **Print width**: 100 caractères max

#### Vérifier le style

```bash
cd frontend

# Lint
npm run lint

# Lint + fix auto
npm run lint:fix

# Format automatiquement
npm run format
```

#### Exemple de code conforme

```typescript
import { useState, useEffect } from 'react';

interface User {
  id: number;
  name: string;
  email: string;
}

export function UserList() {
  const [users, setUsers] = useState<User[]>([]);

  useEffect(() => {
    fetchUsers().then((data) => setUsers(data));
  }, []);

  return (
    <div className="user-list">
      {users.map((user) => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
}
```

---

### Général (tous fichiers)

**EditorConfig** est configuré pour:

- **Charset**: UTF-8
- **End of line**: LF (Unix)
- **Final newline**: Oui
- **Trailing whitespace**: Supprimé

Ton IDE devrait détecter automatiquement `.editorconfig`.

---

## 🌿 Workflow Git

### Branches

```
main                  # Production (protégée)
  └─ dev              # Développement (protégée)
       ├─ feat/login  # Features
       ├─ fix/bug-123 # Bugfixes
       └─ docs/readme # Documentation
```

#### Conventions de nommage

- `feat/description` - Nouvelle fonctionnalité
- `fix/description` - Correction de bug
- `refactor/description` - Refactoring
- `docs/description` - Documentation
- `test/description` - Tests
- `chore/description` - Maintenance

**Exemples**:

```bash
feat/user-authentication
fix/login-button-alignment
docs/api-endpoints
```

---

### Workflow standard

```bash
# 1. Update dev
git checkout dev
git pull origin dev

# 2. Créer une branche
git checkout -b feat/ma-feature

# 3. Coder...
# Faire des commits fréquents

# 4. Push
git push origin feat/ma-feature

# 5. Créer une Pull Request sur GitHub
#    feat/ma-feature → dev
```

---

### Garder ta branche à jour

```bash
# Sur ta branche feature
git checkout feat/ma-feature

# Récupérer les derniers changements
git fetch origin
git rebase origin/dev

# Si conflits, résoudre puis:
git rebase --continue

# Force push (ta branche seulement)
git push origin feat/ma-feature --force-with-lease
```

---

## 🔐 Security

### Secrets Detection avec GitLeaks

Le projet utilise [GitLeaks](https://github.com/gitleaks/gitleaks) pour empêcher les secrets (API keys, mots de passe, tokens) d'être commités dans le dépôt.

#### Pre-commit Hook

GitLeaks s'exécute **automatiquement avant chaque commit** :

```bash
git commit -m "feat: add feature"
🔐 Scanning for secrets...
# Si secrets détectés : commit bloqué ❌
# Si aucun secret : commit réussi ✅
```

#### Si GitLeaks bloque votre commit

**⚠️ NE PAS bypasser le check sauf en cas de faux positif avéré.**

**Étapes à suivre :**

1. **Identifier le secret détecté** (GitLeaks affiche le fichier et la ligne)

2. **Supprimer le secret** de vos fichiers stagés

3. **Utiliser des variables d'environnement** à la place :

   ```java
   // ❌ Mauvais : secret hardcodé
   String apiKey = "sk_live_abc123";

   // ✅ Bon : variable d'environnement
   String apiKey = System.getenv("API_KEY");
   ```

   ```typescript
   // ❌ Mauvais : secret hardcodé
   const token = "ghp_abc123def456";

   // ✅ Bon : variable d'environnement
   const token = import.meta.env.VITE_API_TOKEN;
   ```

4. **Secrets de développement** : utiliser `compose.yml` ou `.env` (non commité)

#### Bypass en cas de faux positif

**Uniquement si GitLeaks détecte à tort une chaîne comme un secret :**

```bash
# Option 1 : Skip GitLeaks pour ce commit (déconseillé)
GITLEAKS_ENABLE=false git commit -m "your message"

# Option 2 : Skip tous les hooks (déconseillé)
git commit --no-verify -m "your message"
```

⚠️ **Attention** : N'utilisez jamais ces commandes pour commit de vrais secrets !

#### CI/CD

GitLeaks s'exécute également dans **GitHub Actions** sur chaque push/PR vers `main` et `dev`.

Si le workflow échoue, vérifiez les logs de l'action `Secrets Detection (GitLeaks)`.

### Dependency Vulnerability Scanning avec Trivy

Le projet utilise [Trivy](https://github.com/aquasecurity/trivy) pour détecter les vulnérabilités (CVE) dans les dépendances backend (Maven) et frontend (npm).

#### Scan automatique en CI/CD

Trivy s'exécute **automatiquement dans GitHub Actions** sur chaque push/PR vers `main` et `dev`.

Le scan vérifie:
- ✅ **Backend**: Dépendances Maven (`pom.xml`)
- ✅ **Frontend**: Dépendances npm (`package-lock.json`)

Seules les vulnérabilités **HIGH** et **CRITICAL** sont signalées.

#### Si Trivy détecte des vulnérabilités

1. **Consulter les logs** du workflow GitHub Actions (`Dependency Vulnerability Scanning`)

2. **Identifier la dépendance vulnérable** et le CVE associé

3. **Mettre à jour la dépendance** vers une version corrigée:

   ```bash
   # Backend (Maven)
   cd backend
   ./mvnw versions:display-dependency-updates
   # Puis mettre à jour manuellement dans pom.xml

   # Frontend (npm)
   cd frontend
   npm audit fix
   # Ou mettre à jour manuellement dans package.json si npm audit fix ne suffit pas
   ```

4. **Tester localement** avec Trivy avant de push:

   ```bash
   # Scan backend
   docker run --rm -v "$(pwd):/project" aquasec/trivy:latest fs --scanners vuln --severity HIGH,CRITICAL /project/backend

   # Scan frontend
   docker run --rm -v "$(pwd):/project" aquasec/trivy:latest fs --scanners vuln --severity HIGH,CRITICAL /project/frontend
   ```

### Dynamic Application Security Testing (DAST) avec OWASP ZAP

Le projet utilise [OWASP ZAP](https://www.zaproxy.org/) (Zed Attack Proxy) pour effectuer des tests de sécurité dynamiques sur l'application en cours d'exécution. Contrairement aux scans statiques (GitLeaks, Trivy), ZAP teste l'application **comme un attaquant le ferait**, en envoyant des requêtes HTTP et en analysant les réponses.

#### Qu'est-ce que ZAP détecte ?

ZAP peut identifier des vulnérabilités telles que :
- 🔓 **Injection SQL** - Failles permettant l'exécution de requêtes SQL malveillantes
- 🔓 **Cross-Site Scripting (XSS)** - Injection de scripts JavaScript malveillants
- 🔓 **Headers de sécurité manquants** - X-Frame-Options, CSP, HSTS, etc.
- 🔓 **Exposition d'informations sensibles** - Stack traces, chemins de fichiers, etc.
- 🔓 **CSRF (Cross-Site Request Forgery)** - Absence de tokens anti-CSRF
- 🔓 **Configuration TLS/SSL faible** - Protocoles ou chiffrements obsolètes
- 🔓 **Divulgation de versions** - Exposition de versions de frameworks/serveurs
- 🔓 **Clickjacking** - Absence de protection contre l'embedding iframe

#### Scan automatique en CI/CD

ZAP s'exécute **automatiquement dans GitHub Actions** à deux moments :

##### 1. Baseline Scan (rapide - 2-5 minutes)

- **Quand** : Sur chaque push/PR vers `main` et `dev`
- **Type** : Scan passif uniquement (pas d'attaques actives)
- **Cibles** : Frontend (port 8081) et Backend (port 8080)
- **Workflow** : `.github/workflows/security.yml` → job `dast-baseline`
- **Reports** : Téléchargeables dans les artifacts GitHub Actions
  - `zap-baseline-frontend-report` (HTML)
  - `zap-baseline-backend-report` (HTML)

**Fonctionnement** : ZAP explore (spider) l'application et analyse passivement toutes les requêtes/réponses pour détecter des failles évidentes sans envoyer de payloads malveillants.

##### 2. Full Scan (complet - 15-45 minutes)

- **Quand** : Tous les lundis à 03:00 UTC (planifié)
- **Type** : Scan actif (envoie des payloads malveillants pour tester les vulnérabilités)
- **Cibles** : Frontend et Backend
- **Workflow** : `.github/workflows/security.yml` → job `dast-full-scheduled`
- **Reports** : Téléchargeables dans les artifacts GitHub Actions
  - `zap-full-frontend-report` (HTML)
  - `zap-full-backend-report` (HTML)

**Fonctionnement** : ZAP explore l'application puis lance des attaques contrôlées (injection SQL, XSS, etc.) pour identifier les vulnérabilités exploitables.

#### Scans locaux avec ZAP

Avant de push, tu peux lancer ZAP localement pour détecter les problèmes de sécurité :

##### Prérequis

```bash
# Démarrer tous les services + ZAP
podman-compose --profile security up -d

# Attendre que tout soit prêt (30 secondes)
```

##### Baseline Scan (recommandé pour développement)

```bash
# Scan rapide passif (2-3 minutes)
./zap/baseline-scan-daemon.sh

# Les rapports sont générés dans ./zap/
ls -l zap/baseline-*-report.html
```

Ouvre les rapports HTML dans ton navigateur pour voir les résultats détaillés.

##### Full Scan (optionnel - pour tests approfondis)

```bash
# Scan complet avec attaques actives (15-30 minutes)
./zap/full-scan-daemon.sh

# Reports dans ./zap/
ls -l zap/full-*-report.html
```

⚠️ **Attention** : Le full scan peut générer beaucoup de logs dans l'application et prendre du temps.

#### Si ZAP détecte des vulnérabilités

Les rapports ZAP classent les alertes par niveau de risque :

| Niveau       | Priorité | Action                                      |
| ------------ | -------- | ------------------------------------------- |
| 🔴 **High**  | Critique | **Corriger immédiatement** avant merge      |
| 🟠 **Medium**| Élevée   | Corriger dans le sprint actuel              |
| 🟡 **Low**   | Moyenne  | Planifier correction                        |
| 🟢 **Info**  | Info     | Amélioration suggérée (non bloquant)        |

##### Étapes pour corriger une vulnérabilité

1. **Télécharger le rapport HTML** depuis les artifacts GitHub Actions ou ouvrir le rapport local

2. **Identifier la vulnérabilité** :
   - Nom de l'alerte (ex: "Missing X-Frame-Options Header")
   - URL affectée
   - Description de la faille
   - Solution suggérée par ZAP

3. **Consulter la documentation** :
   - [OWASP Top 10](https://owasp.org/www-project-top-ten/)
   - [ZAP Alert Details](https://www.zaproxy.org/docs/alerts/)

4. **Appliquer le fix** selon le type de vulnérabilité :

   **Exemple 1 : Headers de sécurité manquants (Frontend - Nginx)**

   ```nginx
   # frontend/nginx.conf
   server {
       # Ajouter les headers de sécurité
       add_header X-Frame-Options "DENY" always;
       add_header X-Content-Type-Options "nosniff" always;
       add_header X-XSS-Protection "1; mode=block" always;
       add_header Referrer-Policy "strict-origin-when-cross-origin" always;
       add_header Content-Security-Policy "default-src 'self'" always;
       
       # ... reste de la config
   }
   ```

   **Exemple 2 : Headers de sécurité manquants (Backend - Spring Boot)**

   ```java
   // backend/.../config/SecurityConfig.java
   @Configuration
   @EnableWebSecurity
   public class SecurityConfig {
       
       @Bean
       public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
           http.headers(headers -> headers
               .frameOptions(HeadersConfigurer.FrameOptionsConfig::deny)
               .contentTypeOptions(Customizer.withDefaults())
               .xssProtection(Customizer.withDefaults())
               .contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self'"))
           );
           return http.build();
       }
   }
   ```

   **Exemple 3 : Protection XSS (Backend - Input Validation)**

   ```java
   // ❌ Mauvais : Pas de validation
   @PostMapping("/user")
   public User createUser(@RequestBody User user) {
       return userService.save(user);
   }

   // ✅ Bon : Validation + sanitization
   @PostMapping("/user")
   public User createUser(@Valid @RequestBody UserDTO userDTO) {
       // Spring valide automatiquement avec @Valid
       return userService.save(userDTO.toEntity());
   }
   ```

   **Exemple 4 : CSRF Protection (Frontend - Axios)**

   ```typescript
   // frontend/src/api/client.ts
   import axios from 'axios';

   const apiClient = axios.create({
     baseURL: import.meta.env.VITE_API_URL,
     withCredentials: true, // Envoyer les cookies CSRF
   });

   // Interceptor pour ajouter le token CSRF
   apiClient.interceptors.request.use((config) => {
     const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
     if (csrfToken) {
       config.headers['X-CSRF-TOKEN'] = csrfToken;
     }
     return config;
   });
   ```

5. **Tester localement** :

   ```bash
   # Rebuild et redémarrer les services
   podman-compose down
   podman-compose build
   podman-compose --profile security up -d
   
   # Relancer le scan ZAP
   ./zap/baseline-scan-daemon.sh
   
   # Vérifier que la vulnérabilité n'apparaît plus
   ```

6. **Commit et push** :

   ```bash
   git add .
   git commit -m "fix(security): add missing security headers to nginx config"
   git push origin feat/ma-feature
   ```

#### Personnaliser les règles ZAP

Tu peux configurer quelles alertes ZAP doit ignorer ou signaler différemment :

**Fichier** : `.zap/rules.tsv`

```tsv
# Format: scanId  threshold  [IGNORE|WARN|FAIL]

# Ignorer les warnings sur les timestamps
10096  OFF  IGNORE

# Traiter les headers manquants comme warnings (pas d'échec)
10021  DEFAULT  WARN
10020  DEFAULT  WARN
```

Consulte `.zap/README.md` pour la liste complète des scan IDs.

#### Bonnes pratiques DAST

1. **Lancer ZAP localement** avant de push des changements de sécurité
2. **Corriger les alertes High/Medium** avant de merger une PR
3. **Ne pas bypasser les scans ZAP** en CI/CD
4. **Tester les corrections** avec un nouveau scan ZAP
5. **Documenter les faux positifs** dans `.zap/rules.tsv` si nécessaire
6. **Consulter les rapports hebdomadaires** (full scan) pour suivre l'évolution

#### Ressources ZAP

- [OWASP ZAP Documentation](https://www.zaproxy.org/docs/)
- [ZAP Getting Started Guide](https://www.zaproxy.org/getting-started/)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [ZAP Alert Reference](https://www.zaproxy.org/docs/alerts/)

---

### Container Image Vulnerability Scanning avec Trivy

Le projet utilise [Trivy](https://github.com/aquasecurity/trivy) pour scanner les images Docker et détecter les vulnérabilités dans les layers système (OS packages, libraries).

#### Scan automatique en CI/CD

Trivy scanne **automatiquement les images Docker** à deux moments :

##### 1. Scan lors du build (blocage)

Dans le workflow de build, les images sont scannées **avant publication** :

- **Quand** : Après le build, avant le push vers GitHub Container Registry
- **Blocage** : Si des vulnérabilités HIGH ou CRITICAL sont détectées, le workflow échoue et les images ne sont PAS publiées
- **Images scannées** :
  - ✅ `trek-backend:local` (Eclipse Temurin 17 + Alpine)
  - ✅ `trek-frontend:local` (Nginx + Alpine)

##### 2. Scan planifié hebdomadaire (monitoring)

Un scan automatique s'exécute **tous les lundis à 2h00 UTC** pour surveiller les images publiées :

- **Quand** : Cron hebdomadaire (`0 2 * * 1`)
- **Mode** : Monitoring uniquement (ne bloque pas)
- **Images scannées** :
  - ✅ `ghcr.io/kentopac/trek-backend:latest`
  - ✅ `ghcr.io/kentopac/trek-frontend:latest`
- **Objectif** : Détecter les nouvelles CVE apparues depuis la publication

Ce scan permet de détecter les vulnérabilités découvertes **après** la publication des images

#### Si Trivy détecte des vulnérabilités dans une image

1. **Consulter les logs** du workflow GitHub Actions :
   - `Build and validate Docker images` (scan lors du build)
   - `Security Scanning` > `Scheduled Container Image Scan` (scan hebdomadaire)

2. **Télécharger les rapports HTML** depuis les artifacts du workflow :
   - `trivy-backend-image-report` et `trivy-frontend-image-report` (build)
   - `trivy-backend-image-report-scheduled` et `trivy-frontend-image-report-scheduled` (cron)

3. **Identifier la vulnérabilité** :
   - CVE number (ex: CVE-2024-1234)
   - Package affecté (ex: `libssl1.1`)
   - Version vulnérable et version fixée

4. **Corriger la vulnérabilité** :

   ```bash
   # Si vulnérabilité dans l'image de base
   # → Mettre à jour la version de l'image de base dans le Dockerfile

   # Backend: backend/Dockerfile
   FROM docker.io/library/eclipse-temurin:17-jre-alpine
   # Vérifier s'il existe une version plus récente

   # Frontend: frontend/Dockerfile
   FROM docker.io/library/nginx:alpine
   # Vérifier s'il existe une version plus récente
   ```

5. **Rebuild et tester localement** :

   ```bash
   # Rebuild l'image
   docker compose build backend
   # ou
   docker compose build frontend

   # Test local (nécessite Trivy installé)
   trivy image trek-backend:local
   trivy image trek-frontend:local
   ```

#### Conseils pour réduire les vulnérabilités

- **Utiliser des images de base récentes** : Mises à jour régulières des images Alpine, Eclipse Temurin, Nginx
- **Multi-stage builds** : Réduire la surface d'attaque en n'incluant que le nécessaire dans l'image finale
- **Rebuild régulier** : Même sans changement de code, rebuilder périodiquement pour obtenir les derniers patches de sécurité

---

## 💬 Commits

### Format: Conventional Commits

```
<type>(<scope>): <description courte>

[body optionnel - explication détaillée]

[footer optionnel - refs issues, breaking changes]
```

#### Types obligatoires

| Type       | Usage                                    |
| ---------- | ---------------------------------------- |
| `feat`     | Nouvelle fonctionnalité                  |
| `fix`      | Correction de bug                        |
| `docs`     | Documentation uniquement                 |
| `style`    | Formatting (pas de changement de code)   |
| `refactor` | Refactoring (ni feat ni fix)             |
| `test`     | Ajout/modification de tests              |
| `chore`    | Maintenance (dependencies, config, etc.) |
| `ci`       | CI/CD (GitHub Actions)                   |
| `perf`     | Amélioration de performance              |
| `revert`   | Revert d'un commit précédent             |

#### Scopes suggérés

- `backend` - Code backend
- `frontend` - Code frontend
- `k8s` - Manifests Kubernetes
- `ci` - Workflows GitHub Actions
- `docs` - Documentation

#### Exemples valides

```bash
feat(backend): add JWT authentication endpoint
fix(frontend): correct button alignment on mobile screens
docs: update README with new API documentation
style(backend): format code with google-java-format
refactor(frontend): extract UserCard component
test(backend): add unit tests for UserService
chore(deps): update Spring Boot to 3.4.1
ci: add security scan workflow
```

#### ❌ Exemples invalides

```bash
# Trop vague
fix: fix bug

# Pas de type
add user login

# Majuscule au début
Feat: add login

# Point à la fin
feat: add login.
```

---

### Commits atomiques

**Principe**: Un commit = une modification logique.

**✅ Bon**:

```bash
git commit -m "feat(backend): add User entity"
git commit -m "feat(backend): add UserRepository"
git commit -m "feat(backend): add UserService with CRUD operations"
git commit -m "test(backend): add UserService unit tests"
```

**❌ Mauvais**:

```bash
git commit -m "feat(backend): add complete user management system"
# Trop gros, difficile à review
```

---

### Commitizen (helper interactif)

Pour faciliter l'écriture de commits conformes, utilisez **Commitizen** :

```bash
# Ajouter des fichiers
git add .

# Lancer le helper interactif
npm run commit
# Ou: npx cz

# Suivre le menu:
# 1. Choisir le type (feat, fix, chore, etc.)
# 2. Choisir le scope (backend, frontend, ci, etc.)
# 3. Écrire la description courte
# 4. [Optionnel] Description longue
# 5. [Optionnel] Breaking changes, issues liées
```

**Avantages** :

- Pas besoin de mémoriser les types
- Garantit un format correct
- Plus rapide qu'écrire manuellement

**Alternative classique** (si tu préfères) :

```bash
git commit -m "feat(backend): add user authentication"
```

Les deux méthodes fonctionnent et sont validées par commitlint.

---

### Pre-commit hooks

Les hooks Git vérifient **automatiquement** avant chaque commit:

1. ✅ Code formaté (Java + TypeScript)
2. ✅ Pas de lint errors
3. ✅ Message de commit conforme

**Si bloqué**:

```bash
# Voir les erreurs
git commit -m "feat: my feature"
# > Checkstyle errors found
# > Fix them with: ./mvnw fmt:format

# Corriger
cd backend && ./mvnw fmt:format

# Retry
git add .
git commit -m "feat(backend): my feature"
```

**Bypass (urgence uniquement)**:

```bash
git commit --no-verify -m "hotfix: critical bug"
# ⚠️ À utiliser seulement en cas d'urgence absolue
```

---

## 🔀 Pull Requests

### Avant de créer une PR

```bash
# 1. Tests passent
cd backend && ./mvnw test
cd frontend && npm test

# 2. Build fonctionne
cd backend && ./mvnw clean package
cd frontend && npm run build

# 3. Lint clean
cd backend && ./mvnw checkstyle:check
cd frontend && npm run lint

# 4. Branche à jour
git fetch origin
git rebase origin/dev
```

---

### Créer la PR

1. **Push ta branche**
2. **Aller sur GitHub** → https://github.com/KentoPAC/TREK
3. **"Compare & pull request"**
4. **Remplir le template**:
   - Description claire
   - Type de changement
   - Checklist complète
   - Screenshots si UI

---

### Review process

- **Au moins 1 approbation** requise
- **CI checks** doivent passer (build + lint + tests)
- **Pas de conflits** avec dev
- **Répondre aux commentaires** de review
- Une fois approuvée → **merge**

---

## ✅ Tests

### Backend

```bash
cd backend

# Tous les tests
./mvnw test

# Tests d'une classe spécifique
./mvnw test -Dtest=UserServiceTest

# Avec coverage
./mvnw test jacoco:report
# Report: target/site/jacoco/index.html
```

#### Écrire des tests

```java
@SpringBootTest
class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    void testGetAllUsers() {
        List<User> users = userService.getAllUsers();
        assertNotNull(users);
        assertTrue(users.size() > 0);
    }
}
```

---

### Frontend

```bash
cd frontend

# Tous les tests
npm test

# Avec coverage
npm run test:coverage
```

#### Écrire des tests

```typescript
import { render, screen } from '@testing-library/react'
import { UserList } from './UserList'

describe('UserList', () => {
  it('renders user list', () => {
    render(<UserList />)
    expect(screen.getByText('Users')).toBeInTheDocument()
  })
})
```

---

## 🐛 Debugging

### Backend

```bash
# Lancer en mode debug
./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"

# Attacher ton IDE sur port 5005
```

### Frontend

```bash
# Dev server avec sourcemaps
npm run dev

# Utiliser les DevTools du navigateur
```

---

## 📚 Ressources

- [Spring Boot Docs](https://spring.io/projects/spring-boot)
- [React Docs](https://react.dev/)
- [TypeScript Docs](https://www.typescriptlang.org/docs/)
- [Conventional Commits](https://www.conventionalcommits.org/)
- [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)

---
