> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snakysec.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 07 restore redis bullmq

# Runbook 07 — Récupération Redis / BullMQ après crash

## 1. Quand activer

| Scénario                                               | Activer ?                          |
| ------------------------------------------------------ | ---------------------------------- |
| Container `mssp-redis` crashed, jobs en attente perdus | **OUI** (re-trigger)               |
| Redis OOM (out of memory), restart du container        | **OUI**                            |
| Volume `redis-data` corrompu                           | **OUI** (effacer + restart à vide) |
| Ralentissements applicatifs sans crash                 | **NON** (debug Redis, pas DR)      |

## 2. Objectifs

* **RPO** : N/A (jobs idempotents, pas de "données" à backuper sur Redis)
* **RTO cible** : 30 minutes
* **Garantie** : aucun audit perdu, aucun rapport à régénérer manuellement

## 3. Pourquoi pas de backup Redis

Redis ne contient que des **jobs BullMQ en cours d'exécution** + cache de
sessions ephemerals. Toutes les données métier persistent dans Postgres :

* Trigger audit : `audit_runs.status = QUEUED` côté Postgres → re-tractable
* Worker chain : lit depuis `platform_audit_log`, idempotent par seq
* Worker import : queue interne reconstruite par re-trigger
* Sessions NextAuth : re-login requis (utilisateurs reconnectent)

Tous les workers BullMQ sont conçus **idempotents** (cf. ADR
[004-cursor-pagination.md](../../adr/) et patterns dans
[platform/src/jobs/](../../../platform/src/jobs/)).

## 4. Procédure

### 4.1 Stop redis + workers

```bash theme={null}
cd /opt/mssp/app/platform
docker compose -f compose/_common.yml -f compose/app.prod.yml stop \
  worker-chain worker-digest worker-retention worker-scheduler \
  worker-import worker-deadline worker-regression worker-permission-expiry
make redis-down
```

### 4.2 Cleanup volume si corruption

```bash theme={null}
# Cas crash sans corruption : skip cette étape
# Cas corruption (AOF illisible, error logs Redis) :
docker run --rm \
  -v platform_redis-data:/data \
  alpine sh -c "rm -rf /data/* /data/.[!.]* 2>/dev/null || true"
```

### 4.3 Redémarrage Redis

```bash theme={null}
make redis-up
sleep 5

# Vérifier healthy
docker exec mssp-redis redis-cli -a "${REDIS_PASSWORD}" ping
# attendu : PONG
```

### 4.4 Redémarrage workers (consume queue)

```bash theme={null}
docker compose -f compose/_common.yml -f compose/app.prod.yml up -d \
  worker-chain worker-digest worker-retention worker-scheduler \
  worker-import worker-deadline worker-regression worker-permission-expiry

sleep 10
docker compose ps | grep worker
# tous les workers : Up + healthy
```

### 4.5 Re-trigger des audits orphelins

Identifier les `audit_runs` en `QUEUED` ou `RUNNING` qui n'ont pas progressé
depuis le crash :

```bash theme={null}
docker exec mssp-postgres psql -U mssp -d mssp_platform <<'EOF'
SELECT id, "clientId", framework, "productArea", status, "triggeredAt"
FROM audit_runs
WHERE status IN ('QUEUED', 'RUNNING')
  AND "triggeredAt" < NOW() - INTERVAL '30 minutes';
EOF
```

Pour chaque run orphelin, re-trigger via l'API admin :

```bash theme={null}
# UI : navigate to /clients/<slug>/audits, click "Re-run"
# Ou CLI :
curl -X POST https://snakysec.com/api/v1/audits/trigger \
  -H "Authorization: Bearer ${MSSP_ADMIN_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"clientId": "...", "framework": "cis", "productArea": "entra"}'
```

### 4.6 Re-trigger des digests / KPI snapshots manqués

Si le crash a duré >24h, certains workers cron ont sauté leur fenêtre. Forcer
le rattrapage :

```bash theme={null}
# Worker digest mensuel
docker exec mssp-worker-digest npm run worker:digest:trigger

# Worker KPI snapshot
docker exec mssp-worker-regression npm run worker:kpi:trigger
```

## 5. Validation

```bash theme={null}
# Workers consomment la queue
docker compose -f compose/_common.yml -f compose/app.prod.yml logs --tail=50 \
  worker-chain worker-import

# Aucun job stuck en RUNNING > 30 min
docker exec mssp-postgres psql -U mssp -d mssp_platform -c \
  "SELECT id, status, \"triggeredAt\" FROM audit_runs \
   WHERE status = 'RUNNING' AND \"triggeredAt\" < NOW() - INTERVAL '30 minutes';"
```

## 6. Communication client

Aucune en cas standard. Si un client signale un audit "stuck" qu'on a re-triggé,
réponse type :

```
Le run d'audit a été interrompu suite à un incident technique de notre service
de queue de jobs. Il a été automatiquement relancé. Vous devriez voir le
résultat dans les prochaines 15 minutes. Aucune donnée n'a été perdue.
```

| Version | Date       | Auteur             |
| ------- | ---------- | ------------------ |
| 1.0     | 2026-04-26 | Nicolas Schiffgens |
