# 🔍 AUDIT DE PRODUCTION - RollerLogic

**Date:** 30 janvier 2026  
**Version:** v1.3.11  
**État:** Analyse complète pour mise en production

---

## 📋 TABLE DES MATIÈRES

1. [🔴 CRITIQUE - Problèmes bloquants](#-critique---problèmes-bloquants)
2. [🟠 SÉCURITÉ - Risques à corriger](#-sécurité---risques-à-corriger)
3. [🔵 OPTIONNEL - Améliorations recommandées](#-optionnel---améliorations-recommandées)
4. [✅ Points positifs](#-points-positifs)
5. [📝 Résumé des actions prioritaires](#-résumé-des-actions-prioritaires)

---

## 🔴 CRITIQUE - Problèmes bloquants

### 1. ❌ Pas de tests automatisés

**Problème:** Aucun fichier de test trouvé (`.test.ts`, `.spec.ts`)

**Impact:**

- Impossible de valider les changements avant déploiement
- Risque élevé de régression lors des mises à jour
- Pas de garantie sur le bon fonctionnement des fonctionnalités critiques (paiements, authentification)

**Solution:**

```bash
# Installer les dépendances de test
npm install --save-dev vitest @vitest/ui supertest @types/supertest

# Créer au minimum des tests pour :
# - routes/webhook-routes.ts (paiements Stripe)
# - routes/auth-routes.ts (authentification)
# - routes/payments-routes.ts (checkout Stripe)
# - server/crypto-utils.ts (hashage, validation)
```

**Fichiers de test prioritaires:**

- `rollerlogic-api/src/routes/__tests__/webhook-routes.test.ts`
- `rollerlogic-api/src/routes/__tests__/auth-routes.test.ts`
- `rollerlogic-api/src/routes/__tests__/payments-routes.test.ts`
- `rollerlogic-api/src/server/__tests__/crypto-utils.test.ts`

---

### 2. ❌ Mot de passe base de données exposé dans docs/deployment/ovh-deployment.md

**Fichier:** [docs/deployment/ovh-deployment.md](../../deployment/ovh-deployment.md)

**Problème:** Le mot de passe DB est écrit en clair dans le fichier de documentation :

```markdown
Password: (store as Docker secret) ---> (voir .env local)
```

**Impact:**

- **CRITIQUE** : Mot de passe compromis si le repo devient public
- Accès direct à la base de données de production

**Solution IMMÉDIATE:**

```bash
# 1. Supprimer le mot de passe du fichier
# 2. Changer le mot de passe de la base de données sur OVH CloudDB
# 3. Mettre à jour le secret Docker :
echo "NOUVEAU_MOT_DE_PASSE" | docker secret create rollerlogic_db_password_v2 -
# 4. Mettre à jour rollerlogic-stack.yml pour utiliser le nouveau secret
```

**Fichier à modifier:**

```markdown
# docs/deployment/ovh-deployment.md ligne 37

- Password: (store as Docker secret) ---> (voir .env local)

* Password: (store as Docker secret - see internal password manager)
```

---

### 3. ⚠️ Pas de stratégie de backup base de données

**Problème:** Aucune sauvegarde automatique configurée pour la base MySQL

**Impact:**

- Perte de données en cas de crash ou corruption de la DB
- Impossibilité de restaurer les données utilisateurs (progression, achats, wallets)

**Solution:**

```bash
# Créer un script de backup journalier
# fichier: backup-db.sh
#!/bin/bash
DATE=$(date +%Y-%m-%d_%H-%M-%S)
mysqldump -h gb9434-001.eu.clouddb.ovh.net \
  -P 35670 \
  -u Taaazzz \
  -p'$DB_PASSWORD' \
  RollerLogic \
  | gzip > /backups/rollerlogic_${DATE}.sql.gz

# Garder seulement les 7 derniers jours
find /backups -name "rollerlogic_*.sql.gz" -mtime +7 -delete
```

**Cron à ajouter:**

```cron
0 3 * * * /root/backup-db.sh >> /var/log/backup-db.log 2>&1
```

---

### 4. ⚠️ Transactions non utilisées dans les webhooks Stripe

**Fichier:** [webhook-routes.ts](rollerlogic-api/src/routes/webhook-routes.ts#L100-L230)

**Problème:** Les opérations de paiement ne sont pas atomiques. Si une erreur survient pendant l'insertion des avatars ou ball skins, le wallet peut être débité sans que l'utilisateur reçoive ses items.

**Exemple problématique:**

```typescript
// Ligne 131-142 : wallet débité
await db.execute(
  `UPDATE wallets SET hints = hints + ?, ...`,
  [cashPack.items.hints, ...]
);

// Ligne 155 : Si cette requête échoue, le wallet est quand même débité !
await db.execute(
  `INSERT IGNORE INTO user_avatar_packs (...)`,
  [metaUserId, packId, sessionId]
);
```

**Solution:**

```typescript
// Utiliser des transactions MySQL
const connection = await db.getConnection();
try {
  await connection.beginTransaction();

  // Toutes les opérations ici
  await connection.execute(`UPDATE wallets ...`);
  await connection.execute(`INSERT INTO user_avatar_packs ...`);

  await connection.commit();
} catch (error) {
  await connection.rollback();
  throw error;
} finally {
  connection.release();
}
```

---

### 5. ⚠️ window.prompt() utilisé pour actions critiques

**Fichier:** [action-handler.ts](rollerlogic-mobile/src/managers/action-handler.ts#L273)

**Problème:** `window.prompt()` est utilisé pour l'action "réinitialiser la progression", ce qui n'est pas fiable :

- Peut être bloqué par les navigateurs
- UX très pauvre sur mobile
- Pas de validation du code saisi

**Solution:**

```typescript
// Remplacer par une modale personnalisée
// Créer partials/modals/confirm-reset-modal.ts
export function showConfirmResetModal(
  onConfirm: () => void,
  onCancel: () => void,
): void {
  // Modal avec input type="text" pour saisir "RESET"
  // Boutons Confirmer/Annuler
  // Validation : input === "RESET" (insensible à la casse)
}
```

---

## 🟠 SÉCURITÉ - Risques à corriger

### 6. 🔐 Pas de protection CSRF

**Problème:** Aucun token CSRF implémenté sur les routes de mutations (POST/PUT/DELETE)

**Impact:**

- Attaques Cross-Site Request Forgery possibles
- Un attaquant peut forcer un utilisateur connecté à faire des actions (achats, changements de profil)

**Solution:**

```bash
npm install @fastify/csrf-protection
```

```typescript
// server.ts
import csrfProtection from "@fastify/csrf-protection";

await app.register(csrfProtection, {
  cookieOpts: {
    signed: true,
    sameSite: "strict",
    httpOnly: true,
  },
});
```

**Routes à protéger:**

- POST `/auth/register`, `/auth/login`
- POST `/payments/stripe/checkout-*`
- PUT `/profile/update`
- POST `/profile/delete-account`

---

### 7. 🔐 Pas de helmet pour les headers de sécurité

**Problème:** Aucun header de sécurité HTTP standard (X-Frame-Options, X-Content-Type-Options, etc.)

**Impact:**

- Clickjacking possible
- XSS facilité
- MIME sniffing attacks

**Solution:**

```bash
npm install @fastify/helmet
```

```typescript
// server.ts
import helmet from "@fastify/helmet";

await app.register(helmet, {
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      scriptSrc: ["'self'"],
      imgSrc: ["'self'", "data:", "https:"],
      connectSrc: ["'self'", "https://api.rollerlogic.com"],
    },
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true,
  },
});
```

---

### 8. 🔐 Console.error au lieu de logger dans webhook-routes.ts

**Fichier:** [webhook-routes.ts](rollerlogic-api/src/routes/webhook-routes.ts)

**Problème:** 4 occurrences de `console.error()` au lieu d'utiliser le logger Fastify :

- Ligne 142 : `console.error("Erreur mise à jour wallet:", error);`
- Ligne 179 : `console.error("Erreur insertion avatars:", error);`
- Ligne 212 : `console.error("Erreur insertion ball skins:", error);`
- Ligne 226 : `console.error("Erreur insertion challenge pack:", error);`

**Impact:**

- Les erreurs ne sont pas trackées dans les logs structurés
- Impossible de monitorer les erreurs de paiement en production

**Solution:**

```typescript
// Remplacer tous les console.error par :
request.log.error(
  { err: error, userId: metaUserId, packType },
  "payment_processing_error",
);
```

---

### 9. 🔐 Rate limiting incomplet

**Problème:** Rate limiting uniquement sur quelques routes :

- ✅ `/auth/*` routes (10/min)
- ✅ `/profile/update` (10/min)
- ✅ `/profile/check-display-name` (30/min)
- ❌ `/payments/stripe/checkout-*` (pas de limite)
- ❌ `/webhook/stripe` (pas de limite, mais webhook signé)
- ❌ `/stats/*` (pas de limite)

**Impact:**

- Abus possibles sur les endpoints de création de checkout Stripe
- Potentielles attaques DDoS sur les endpoints non protégés

**Solution:**

```typescript
// server.ts - Ajouter rate limiting global par défaut
await app.register(rateLimit, {
  global: true,
  max: 100, // 100 requêtes
  timeWindow: "1 minute",
  skipOnError: false,
});

// Puis override spécifiques :
// - auth : 10/min (déjà fait)
// - payments : 20/min (à ajouter)
// - stats : 50/min (à ajouter)
```

---

### 10. 🔐 Validation input incomplète

**Fichier:** [profile-routes.ts](rollerlogic-api/src/routes/profile-routes.ts)

**Problème:** Seul le `displayName` et `motto` sont validés avec `hasHtmlOrDangerousChars()`. D'autres champs manquent de validation :

- `email` : pas de validation de format regex
- `avatar` : pas de validation de la valeur (peut être n'importe quelle string)
- `accent` : pas de validation (peut être n'importe quelle string)
- `title` : pas de validation

**Solution:**

```typescript
// Ajouter des validateurs
function isValidEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

function isValidAvatarId(avatarId: string): boolean {
  return /^[a-zA-Z0-9_-]{1,50}$/.test(avatarId);
}

function isValidAccent(accent: string): boolean {
  return /^#[0-9a-fA-F]{6}$/.test(accent); // hex color
}

// Utiliser dans les schemas Fastify
schema: {
  body: {
    type: 'object',
    properties: {
      email: { type: 'string', format: 'email' },
      avatar: { type: 'string', pattern: '^[a-zA-Z0-9_-]{1,50}$' },
      accent: { type: 'string', pattern: '^#[0-9a-fA-F]{6}$' }
    }
  }
}
```

---

### 11. 🔐 Secrets Docker non versionnés

**Problème:** Les secrets Docker sont référencés mais pas de documentation sur comment les créer/régénérer

**Solution:** Créer un script de gestion des secrets :

```bash
# scripts/setup-secrets.sh
#!/bin/bash
echo "🔐 Configuration des secrets Docker Swarm"

# JWT Secret
openssl rand -base64 32 | docker secret create rollerlogic_jwt_secret_v2 -

# Stripe Secret Key
echo "$STRIPE_SECRET_KEY" | docker secret create stripe_secret_key_rollerlogic_v2 -

# Stripe Webhook Secret
echo "$STRIPE_WEBHOOK_SECRET" | docker secret create stripe_webhook_secret_rollerlogic_v2 -

# DB Password
echo "$DB_PASSWORD" | docker secret create rollerlogic_db_password_v2 -

# SMTP Password
echo "$SMTP_PASSWORD" | docker secret create smtp_pass_v3 -

echo "✅ Secrets créés avec succès"
```

---

## 🔵 OPTIONNEL - Améliorations recommandées

### 12. 📊 Monitoring et alerting manquant

**Problème:** Aucun système de monitoring/alerting configuré

**Recommandation:**

```bash
# Option 1 : Prometheus + Grafana
# Ajouter prom-client pour exposer des métriques
npm install prom-client

# Option 2 : Sentry pour error tracking
npm install @sentry/node @sentry/fastify

# Option 3 : Datadog, New Relic, ou équivalent
```

**Métriques à suivre:**

- Temps de réponse API (p50, p95, p99)
- Taux d'erreur par endpoint
- Nombre de paiements réussis/échoués
- Nombre d'utilisateurs actifs (DAU/MAU)
- Taux d'échec authentification
- Usage DB (connexions pool, slow queries)

---

### 13. 📊 Logs non centralisés

**Problème:** Les logs sont uniquement dans Docker stdout, pas de solution centralisée

**Recommandation:**

```bash
# Option 1 : Loki + Grafana
# docker-compose.yml
loki:
  image: grafana/loki:latest
  ports:
    - "3100:3100"

# Option 2 : ELK Stack (Elasticsearch, Logstash, Kibana)
# Option 3 : Cloudwatch Logs (AWS) ou équivalent OVH
```

---

### 14. 🚀 Pas de CI/CD automatisé

**Problème:** Déploiement manuel (build, push, deploy)

**Recommandation:**

```yaml
# .github/workflows/deploy.yml
name: Deploy to OVH

on:
  push:
    tags:
      - "v*"

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build Docker image
        run: docker build -t ghcr.io/taaazzz-prog/rollerlogic-api:${{ github.ref_name }} .

      - name: Push to registry
        run: docker push ghcr.io/taaazzz-prog/rollerlogic-api:${{ github.ref_name }}

      - name: Deploy to OVH
        run: |
          ssh taaazzz@51.75.55.185 "
            docker stack deploy -c rollerlogic-stack.yml rollerlogic
          "
```

---

### 15. 📝 Documentation API manquante

**Problème:** Pas de Swagger/OpenAPI pour documenter l'API

**Recommandation:**

```bash
npm install @fastify/swagger @fastify/swagger-ui
```

```typescript
// server.ts
import swagger from "@fastify/swagger";
import swaggerUi from "@fastify/swagger-ui";

await app.register(swagger, {
  openapi: {
    info: {
      title: "RollerLogic API",
      version: "1.3.11",
    },
    servers: [{ url: "https://api.rollerlogic.com" }],
  },
});

await app.register(swaggerUi, {
  routePrefix: "/docs",
});

// Accessible à https://api.rollerlogic.com/docs
```

---

### 16. 🔄 Pas de healthcheck détaillé

**Problème:** Le healthcheck actuel vérifie juste que l'API répond, pas l'état de la DB

**Fichier:** [health-routes.ts](rollerlogic-api/src/routes/health-routes.ts)

**Recommandation:**

```typescript
// Ajouter un endpoint /health/detailed
app.get("/health/detailed", async (request, reply) => {
  const checks = {
    api: "ok",
    database: "unknown",
    stripe: "unknown",
    smtp: "unknown",
  };

  try {
    await db.execute("SELECT 1");
    checks.database = "ok";
  } catch {
    checks.database = "error";
  }

  // Test Stripe API
  try {
    await stripe.balance.retrieve();
    checks.stripe = "ok";
  } catch {
    checks.stripe = "error";
  }

  // Test SMTP (optionnel)
  if (mailer) {
    try {
      await mailer.verify();
      checks.smtp = "ok";
    } catch {
      checks.smtp = "error";
    }
  }

  const allOk = Object.values(checks).every((v) => v === "ok");
  reply.code(allOk ? 200 : 503);
  return checks;
});
```

---

### 17. 🧹 TODOs et FIXMEs dans le code

**Problème:** Il peut y avoir des TODOs/FIXMEs oubliés (non vérifié exhaustivement)

**Recommandation:**

```bash
# Rechercher tous les TODOs
grep -r "TODO\|FIXME\|XXX\|HACK" rollerlogic-api/src rollerlogic-mobile/src

# Les traiter avant la mise en production
```

---

### 18. 📱 localStorage sans fallback

**Fichier:** Multiple fichiers dans [rollerlogic-mobile/src](rollerlogic-mobile/src)

**Problème:** `localStorage` peut être désactivé (mode privé Safari/Firefox)

**Recommandation:**

```typescript
// core/storage.ts - Créer un wrapper avec fallback
const storage = {
  getItem(key: string): string | null {
    try {
      return localStorage.getItem(key);
    } catch {
      return sessionStorage.getItem(key);
    }
  },
  setItem(key: string, value: string): void {
    try {
      localStorage.setItem(key, value);
    } catch {
      sessionStorage.setItem(key, value);
    }
  },
  removeItem(key: string): void {
    try {
      localStorage.removeItem(key);
    } catch {
      sessionStorage.removeItem(key);
    }
  },
};

export default storage;
```

---

### 19. 🔒 Rotation des secrets

**Problème:** Pas de procédure de rotation des secrets (JWT, Stripe, DB password)

**Recommandation:**

```markdown
# SECURITY.md - Procédure de rotation des secrets

## JWT Secret

1. Générer nouveau secret : `openssl rand -base64 32`
2. Créer nouveau secret Docker : `echo "NEW_SECRET" | docker secret create rollerlogic_jwt_secret_v2 -`
3. Mettre à jour stack.yml
4. Redéployer : `docker stack deploy -c rollerlogic-stack.yml rollerlogic`
5. Attendre 24h (TTL tokens)
6. Supprimer ancien secret : `docker secret rm rollerlogic_jwt_secret`

## Stripe Webhook Secret

1. Créer nouveau webhook dans Stripe Dashboard
2. Copier nouveau secret
3. Créer nouveau secret Docker
4. Mettre à jour stack.yml
5. Redéployer
6. Supprimer ancien webhook Stripe
7. Supprimer ancien secret Docker

Rotation recommandée : tous les 90 jours
```

---

### 20. 📈 Pas de limite sur la taille des uploads

**Problème:** Pas de limite explicite sur la taille des body (JSON)

**Recommandation:**

```typescript
// server.ts
const app = fastify({
  logger: {
    level: isProd ? "info" : "debug",
  },
  bodyLimit: 1024 * 1024, // 1 MB max
  trustProxy: true,
});
```

---

### 21. 🌐 CORS peut être plus restrictif

**Fichier:** [server.ts](rollerlogic-api/src/server.ts)

**Problème:** CORS configuré avec `origin: true` (accepte toutes les origines avec credentials)

**Recommandation:**

```typescript
// server.ts
await app.register(cors, {
  origin: [
    "https://rollerlogic.com",
    "https://www.rollerlogic.com",
    "capacitor://localhost", // Mobile Capacitor
    "ionic://localhost", // Mobile Ionic
  ],
  credentials: true,
  methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Authorization"],
});
```

---

### 22. 🎯 Pas de limite sur les connexions DB

**Fichier:** [config.ts](rollerlogic-api/src/config.ts#L123)

**Problème:** Pool DB configuré avec `DB_POOL_SIZE` (défaut: 10), mais pas de limite de connexions par utilisateur

**Recommandation:**

```typescript
// db.ts
export const initDb = (config: AppConfig["db"]) => {
  const pool = mysql.createPool({
    host: config.host,
    port: config.port,
    user: config.user,
    password: config.password,
    database: config.database,
    connectionLimit: config.poolSize,
    queueLimit: 50, // Limite queue des requêtes
    waitForConnections: true,
    enableKeepAlive: true,
    keepAliveInitialDelay: 10000,
  });

  return pool;
};
```

---

### 23. 🔄 Pas de gestion des migrations DB

**Problème:** Les migrations sont faites avec `ensureSchema()`, `ensureAdminColumn()`, etc., mais pas de système de versioning

**Recommandation:**

```bash
npm install mysql2-migrations
```

```typescript
// migrations/001_create_users.sql
CREATE TABLE IF NOT EXISTS users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  email VARCHAR(255) NOT NULL UNIQUE,
  ...
);

// migrations/002_add_admin_column.sql
ALTER TABLE users ADD COLUMN is_admin BOOLEAN DEFAULT FALSE;

// migrations/003_create_avatars.sql
...
```

```typescript
// server.ts
import { migrate } from "mysql2-migrations";

await migrate({
  connection: db,
  migrationsPath: "./migrations",
});
```

---

## ✅ Points positifs

### Ce qui est bien fait :

1. ✅ **Argon2 pour les mots de passe** - Excellent choix (meilleur que bcrypt)
2. ✅ **Rate limiting sur auth/profile** - Protège contre le bruteforce
3. ✅ **JWT avec refresh tokens** - Bonne architecture d'authentification
4. ✅ **Prepared statements SQL** - Protection contre l'injection SQL
5. ✅ **Validation XSS basique** - `hasHtmlOrDangerousChars()` sur les inputs critiques
6. ✅ **Docker multi-stage** - Image optimisée, user non-root
7. ✅ **Stripe webhooks signés** - Sécurité paiements
8. ✅ **HTTPS avec Let's Encrypt** - Chiffrement en production
9. ✅ **Secrets via Docker secrets** - Pas de secrets hardcodés (sauf dans doc)
10. ✅ **Logger structuré Pino** - Logs JSON parsables
11. ✅ **Architecture découplée** - Routes, services, utils bien séparés
12. ✅ **Traefik reverse proxy** - Routing HTTPS automatique

---

## 📝 Résumé des actions prioritaires

### 🔴 Actions IMMÉDIATES (avant mise en production)

| #   | Action                                           | Temps estimé | Priorité |
| --- | ------------------------------------------------ | ------------ | -------- |
| 2   | Supprimer mot de passe DB du README + le changer | 10 min       | 🔴🔴🔴   |
| 4   | Ajouter transactions atomiques dans webhooks     | 2h           | 🔴🔴     |
| 3   | Configurer backup DB automatique                 | 1h           | 🔴🔴     |
| 8   | Remplacer console.error par logger               | 30 min       | 🔴       |
| 5   | Remplacer window.prompt() par modal              | 2h           | 🔴       |

### 🟠 Actions IMPORTANTES (semaine 1-2)

| #   | Action                                 | Temps estimé | Priorité |
| --- | -------------------------------------- | ------------ | -------- |
| 6   | Ajouter protection CSRF                | 3h           | 🟠🟠     |
| 7   | Installer @fastify/helmet              | 2h           | 🟠🟠     |
| 9   | Étendre rate limiting à tous endpoints | 1h           | 🟠🟠     |
| 10  | Améliorer validation inputs            | 3h           | 🟠       |
| 11  | Documenter procédure secrets           | 1h           | 🟠       |

### 🔵 Actions RECOMMANDÉES (mois 1-2)

| #   | Action                                    | Temps estimé | Priorité |
| --- | ----------------------------------------- | ------------ | -------- |
| 1   | Écrire tests unitaires/intégration        | 2-3 jours    | 🔵🔵🔵   |
| 12  | Configurer monitoring (Sentry/Prometheus) | 1 jour       | 🔵🔵     |
| 13  | Centraliser les logs (Loki/ELK)           | 1 jour       | 🔵🔵     |
| 14  | Setup CI/CD automatisé                    | 1 jour       | 🔵       |
| 15  | Générer documentation API (Swagger)       | 4h           | 🔵       |
| 16  | Healthcheck détaillé                      | 2h           | 🔵       |
| 21  | Restreindre CORS origins                  | 30 min       | 🔵       |

---

## 🎯 Score de production readiness

| Catégorie          | Score | Commentaire                                                                     |
| ------------------ | ----- | ------------------------------------------------------------------------------- |
| **Sécurité**       | 6/10  | Bonnes bases (Argon2, JWT, HTTPS) mais manque CSRF, Helmet, validation complète |
| **Fiabilité**      | 4/10  | Pas de tests, pas de backup, transactions atomiques manquantes                  |
| **Monitoring**     | 3/10  | Logs basiques OK, mais pas de métriques, alerting, ou log centralisé            |
| **Performance**    | 7/10  | Architecture correcte, rate limiting partiel, pool DB configuré                 |
| **Maintenabilité** | 6/10  | Code propre et organisé, mais manque tests et documentation API                 |

**Score global : 5.2/10** ⚠️

### Recommandation finale :

🔴 **NE PAS mettre en production sans :**

1. Supprimer le mot de passe DB exposé + le changer
2. Ajouter transactions atomiques webhooks
3. Configurer backup DB
4. Remplacer console.error par logger

🟠 **Mettre en production avec vigilance si :**

- Les 4 points critiques ci-dessus sont corrigés
- CSRF et Helmet sont ajoutés dans les 7 jours
- Monitoring de base (Sentry) est en place

🟢 **Production stable possible après :**

- Tests unitaires sur fonctions critiques (auth, payments)
- Rate limiting global
- Backup testé et automatisé
- Monitoring + alerting opérationnels

---

**Prochaines étapes suggérées :**

1. Créer un ticket/issue pour chaque point critique (1-5)
2. Planifier sprint "sécurité" pour points 6-11
3. Roadmap Q1 2026 pour points 12-23
4. Revoir cet audit tous les 3 mois

---

_Document généré par GitHub Copilot - Audit du 30 janvier 2026_
