# Rapport: Hardening Production Semaine 1 - veza-backend-api

**Date**: 2025-12-15  
**Objectif**: Transformer veza-backend-api en service exploitable sereinement la 1ère semaine de prod  
**Approche**: Améliorations incrémentales, testées, directement actionnables

---

## Résumé Exécutif

### ✅ Livrables Complétés

1. **Alerting Prometheus** - 8 alertes critiques configurées
2. **Runbooks** - 3 runbooks incident-ready (DB down, circuit breaker, upload stuck)
3. **Contrat Erreurs** - Test de contrat ajouté, endpoints critiques standardisés
4. **Load Tests** - Script k6 reproductible avec seuils définis

### 📊 État Actuel

- **Alertes**: ✅ Configurées et documentées
- **Runbooks**: ✅ Prêts pour incidents
- **Tests**: ✅ Contrat erreurs + load tests
- **Documentation**: ✅ Complète et actionnable

---

## 1. Alerting Prometheus

### Fichiers Créés

- `ops/prometheus/alerts.yml` - Règles d'alerte Prometheus
- `ops/prometheus/README.md` - Documentation activation et configuration

### Alertes Configurées

#### Critiques (Critical)

1. **VezaCircuitBreakerOpen**
   - **Condition**: Circuit breaker OPEN > 5 minutes
   - **Métrique**: `veza_circuit_breaker_state == 2`
   - **Action**: Vérifier service externe (OAuth/Stream), consulter runbook

2. **VezaDBPoolExhausted**
   - **Condition**: Taux d'attente DB pool > 0.1/s pendant 2 min
   - **Métrique**: `rate(veza_db_pool_wait_count_total[5m]) > 0.1`
   - **Action**: Vérifier DB, connexions bloquantes, consulter runbook

3. **VezaHigh5xxAbsolute**
   - **Condition**: > 10 erreurs 5xx/seconde pendant 2 min
   - **Métrique**: `sum(rate(veza_gin_http_requests_total{status=~"5.."}[5m])) > 10`
   - **Action**: Investigation immédiate, vérifier logs

4. **VezaReadinessFailed**
   - **Condition**: Service down (up == 0) > 1 min
   - **Métrique**: `up{job="veza-backend-api"} == 0`
   - **Action**: Redémarrer service, vérifier health

#### Warnings

5. **VezaDBPoolHighUsage**
   - **Condition**: DB pool > 80% (20/25 connexions) pendant 5 min
   - **Métrique**: `veza_db_pool_open_connections > 20`
   - **Action**: Surveiller, vérifier requêtes lentes

6. **VezaHigh5xxRate**
   - **Condition**: Taux erreurs 5xx > 5% pendant 5 min
   - **Métrique**: `(sum(rate(5xx)) / sum(rate(all))) > 0.05`
   - **Action**: Investigation, vérifier logs

7. **VezaHighLatencyCriticalEndpoints**
   - **Condition**: Latence P95 > 1s sur endpoints critiques pendant 5 min
   - **Métrique**: `histogram_quantile(0.95, veza_gin_http_request_duration_seconds) > 1.0`
   - **Action**: Vérifier performance, DB, dépendances

8. **VezaHealthDegraded**
   - **Condition**: Service en mode dégradé > 10 min
   - **Métrique**: `veza_health_check_status < 1`
   - **Action**: Vérifier services optionnels (Redis/RabbitMQ)

### Activation

Voir `ops/prometheus/README.md` pour instructions détaillées.

**Résumé**:
1. Copier `alerts.yml` dans `/etc/prometheus/rules/`
2. Ajouter dans `prometheus.yml`: `rule_files: ["/etc/prometheus/rules/veza-backend-api.yml"]`
3. Redémarrer Prometheus
4. Vérifier: `http://localhost:9090/alerts`

---

## 2. Runbooks

### Fichiers Créés

- `docs/runbooks/db_down.md` - Runbook DB down / pool exhausted
- `docs/runbooks/circuit_breaker_open.md` - Runbook circuit breaker open
- `docs/runbooks/upload_stuck.md` - Runbook upload stuck in "uploading"

### Structure des Runbooks

Chaque runbook suit le format:
1. **Signal** - Alertes/symptômes déclencheurs
2. **Hypothèses** - Causes possibles
3. **Vérifications** - Commandes de diagnostic
4. **Actions Correctives** - Solutions par scénario
5. **Post-Mortem Notes** - Template pour documentation post-incident

### Runbook: DB Down

**Scénarios couverts**:
- DB PostgreSQL down
- DB pool saturé (> 20/25 connexions)
- Réseau/connectivité
- Requêtes bloquantes

**Actions clés**:
- Redémarrer PostgreSQL
- Identifier et tuer requêtes bloquantes
- Vérifier espace disque/mémoire
- Augmenter pool temporairement (si nécessaire)

### Runbook: Circuit Breaker Open

**Scénarios couverts**:
- Service externe down (OAuth, Stream)
- Service externe lent (timeouts)
- Problème réseau
- Configuration circuit breaker

**Actions clés**:
- Identifier circuit breaker affecté
- Tester service externe directement
- Vérifier métriques (échecs consécutifs, requêtes rejetées)
- Forcer réouverture (si service confirmé OK)

### Runbook: Upload Stuck

**Scénarios couverts**:
- Job worker down
- Queue bloquée (RabbitMQ)
- Storage problème (fichier manquant, permissions)
- Processing échoué silencieusement
- Timeout processing

**Actions clés**:
- Vérifier statut upload en DB
- Redémarrer job worker
- Vérifier queue RabbitMQ
- Forcer re-processing si nécessaire

---

## 3. Contrat Erreurs Unifié

### Fichiers Créés

- `internal/handlers/error_contract_test.go` - Test de contrat pour format erreurs

### Test de Contrat

Le test `TestErrorContract` vérifie que les endpoints critiques retournent des erreurs au format standardisé:

```json
{
  "success": false,
  "error": {
    "code": 2000,
    "message": "error message",
    "timestamp": "2025-12-15T10:00:00Z",
    "request_id": "...",
    "details": [...]
  }
}
```

### Endpoints Testés

- ✅ BitrateHandler - Validation erreurs
- ✅ BitrateHandler - Unauthorized
- ✅ PlaybackAnalyticsHandler - Not Found
- ✅ Validation errors avec détails

### État Standardisation

**Endpoints standardisés** (utilisent `RespondWithAppError`):
- ✅ `/api/v1/tracks/:id/bitrate/adapt` - BitrateHandler
- ✅ `/api/v1/playback/analytics/*` - PlaybackAnalyticsHandler
- ✅ `/health`, `/readyz`, `/live` - HealthHandler

**Endpoints partiellement standardisés**:
- ⚠️ `/api/v1/auth/*` - Utilise `response.Error()` (format similaire mais non AppError)
  - **Impact**: Format compatible mais pas de code d'erreur standardisé
  - **Action**: Documenté comme acceptable pour l'instant (conversion future possible)

### Exécution

```bash
go test ./internal/handlers -run TestErrorContract -v
```

**Résultat**: ✅ Tous les tests passent

---

## 4. Micro Load Test

### Fichiers Créés

- `scripts/loadtest/k6_load_test.js` - Script k6 pour load testing
- `scripts/loadtest/README.md` - Documentation utilisation

### Configuration

**Stages** (par défaut):
- Ramp-up: 0 → 10 VUs en 30s
- Stabilité: 10 VUs pendant 1m
- Ramp-down: 10 → 0 VUs en 30s

**Endpoints testés**:
1. `GET /health` - Health check
2. `GET /readyz` - Readiness check
3. `POST /api/v1/auth/login` - Auth endpoint (credentials invalides)
4. `GET /api/v1/tracks` - Track list

### Seuils Attendus

- **HTTP Request Duration**: P95 < 500ms, P99 < 1s
- **Error Rate**: < 5%
- **Health Check**: P95 < 100ms
- **Readyz Check**: P95 < 200ms

### Utilisation

```bash
# Test basique
k6 run scripts/loadtest/k6_load_test.js

# Avec URL personnalisée
BASE_URL=http://staging.example.com:8080 k6 run scripts/loadtest/k6_load_test.js

# Avec token auth
AUTH_TOKEN=your_token k6 run scripts/loadtest/k6_load_test.js
```

### Résultats

Le script génère:
- **stdout**: Résumé textuel
- `scripts/loadtest/k6_summary.json`: Résultats détaillés JSON

### Détection Régressions

**Signaux d'alerte**:
- Latence P95 > 500ms → Performance dégradée
- Error rate > 5% → Problèmes stabilité
- Health check > 100ms → Problème DB/dépendances

**Actions si seuils dépassés**:
1. Vérifier logs application
2. Vérifier métriques Prometheus
3. Vérifier ressources système
4. Consulter runbooks

---

## Utilisation en Production

### Semaine 1 - Checklist Quotidienne

#### Matin (9h)

- [ ] Vérifier alertes Prometheus: `http://prometheus:9090/alerts`
- [ ] Vérifier métriques clés:
  - `veza_db_pool_open_connections` < 20
  - `veza_circuit_breaker_state == 0` (closed)
  - `rate(veza_gin_http_requests_total{status=~"5.."}[5m]) < 0.05`
- [ ] Vérifier logs erreurs: `grep -i error /var/log/veza-backend-api/*.log | tail -20`

#### Après-midi (14h)

- [ ] Re-vérifier alertes
- [ ] Vérifier latence: `histogram_quantile(0.95, veza_gin_http_request_duration_seconds)`
- [ ] Run load test (optionnel): `k6 run scripts/loadtest/k6_load_test.js`

#### Soir (18h)

- [ ] Résumé incidents de la journée
- [ ] Documenter dans runbooks si nouveaux patterns

### En Cas d'Incident

1. **Identifier alerte déclenchée** → Consulter runbook correspondant
2. **Suivre runbook** → Signal → Hypothèses → Vérifications → Actions
3. **Documenter** → Post-mortem notes dans runbook
4. **Ajuster** → Alertes/seuils si nécessaire

### Intégration CI/CD

**Optionnel**: Ajouter load test dans pipeline

```yaml
# .github/workflows/load-test.yml
- name: Run load tests
  run: |
    k6 run scripts/loadtest/k6_load_test.js
  env:
    BASE_URL: http://staging.example.com:8080
```

---

## Améliorations Futures (Non-Bloquantes)

### Court Terme (Semaine 2-4)

1. **Convertir `internal/core/auth/handler.go`** vers `RespondWithAppError`
   - Impact: Standardisation complète
   - Effort: 2-3h

2. **Ajouter métriques upload processing**
   - Alerte: Uploads stuck > 10 min
   - Effort: 1-2h

3. **Dashboard Grafana**
   - Visualisation métriques clés
   - Effort: 2-3h

### Moyen Terme (Mois 2-3)

1. **Tests d'intégration end-to-end**
   - Scénarios utilisateur complets
   - Effort: 1 semaine

2. **Chaos Engineering**
   - Tests résilience (DB down, dépendances down)
   - Effort: 2-3 jours

3. **Performance profiling**
   - Identifier bottlenecks
   - Effort: 1 semaine

---

## Fichiers Modifiés/Créés

### Nouveaux Fichiers

```
ops/prometheus/
  ├── alerts.yml
  └── README.md

docs/runbooks/
  ├── db_down.md
  ├── circuit_breaker_open.md
  └── upload_stuck.md

scripts/loadtest/
  ├── k6_load_test.js
  └── README.md

internal/handlers/
  └── error_contract_test.go

docs/
  └── PROD_WEEK1_HARDENING_REPORT.md (ce fichier)
```

### Fichiers Modifiés

Aucun fichier de code modifié (approche non-invasive).

---

## Validation

### Tests Exécutés

```bash
# Test contrat erreurs
go test ./internal/handlers -run TestErrorContract -v
# ✅ PASS

# Load test (exemple)
k6 run scripts/loadtest/k6_load_test.js
# ✅ Seuils respectés
```

### Vérifications Manuelles

- [x] Alertes Prometheus syntaxiquement correctes
- [x] Runbooks complets et actionnables
- [x] Load test exécutable et reproductible
- [x] Test contrat erreurs passe

---

## Conclusion

Le module **veza-backend-api** est maintenant **prêt pour la semaine 1 de production** avec:

✅ **Alerting** - 8 alertes critiques configurées  
✅ **Runbooks** - 3 runbooks incident-ready  
✅ **Tests** - Contrat erreurs + load tests  
✅ **Documentation** - Complète et actionnable

**Prochaines étapes**:
1. Activer alertes Prometheus en staging/prod
2. Former équipe sur runbooks
3. Monitorer métriques première semaine
4. Ajuster seuils selon observations réelles

**Support**: Consulter runbooks en cas d'incident, ajuster alertes selon besoins.

---

**Date de création**: 2025-12-15  
**Auteur**: SRE Team  
**Version**: 1.0
