# Exploitation

## Localisation

Application et PostgreSQL chez **Greenshift**, centre de données aux **Pays-Bas** (colocation Iron Mountain, sans accès logique). Les sauvegardes et les journaux restent au même endroit. La communication commerciale annonce un hébergement européen, jamais français.

## Environnements

| Environnement | Composition |
| --- | --- |
| Local | PostgreSQL en conteneur, API et dashboard en développement, extension en rechargement à chaud |
| Recette | Copie réduite de la production, données synthétiques, cible des restaurations d'essai |
| Production | Instance unique Hono + dashboard statique, PostgreSQL managé |

La promotion se fait par image de conteneur étiquetée. Les migrations Drizzle s'appliquent au démarrage, avant d'accepter du trafic.

## Sauvegardes

Sauvegarde quotidienne incluse dans l'offre Greenshift, rétention de sept jours.

Une sauvegarde qui n'a jamais été restaurée n'est pas une sauvegarde. Restauration d'essai **trimestrielle** sur la recette, jamais par-dessus la base de travail :

```bash
pnpm db:restore-drill
```

Le script dump la base `DATABASE_URL`, la restaure dans `circuy_restore_drill`, vérifie la présence du schéma, puis détruit cette base temporaire.

## Rétention des événements

Tâche **mensuelle** : supprimer les événements de plus de treize mois.

```bash
pnpm --filter @circuy/api purge-events
```

## Journaux

JSON sur la sortie standard, collectés par l'hébergeur. Ils ne contiennent jamais d'adresse IP, de jeton, ni de contenu de parcours.

Exemple : `{"level":"info","msg":"listening","port":8787}`

## Alertes qui réveillent un humain

- indisponibilité des endpoints publics de lecture (`/health`, manifeste) ;
- échec d'une sauvegarde ;
- taux d'erreur serveur supérieur à 1 % sur cinq minutes.

Tout le reste se consulte, rien d'autre ne déclenche. Une alerte sans action immédiate apprend à ignorer les alertes.
