vps-health-api/CLAUDE.md
le king fu 39a55fad93 docs: sync CLAUDE.md with real Coolify mounts and manual deploy trigger
Persistent Storages replace the documented (never-existing) per-file
bind-mounts; agents-map.json check path corrected to /data/defenseurs/;
app has no Forgejo Source so post-merge deploy is a manual API trigger.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 20:47:17 -04:00

4.2 KiB

VPS Health API

API sante minimaliste pour le VPS. ~127 lignes, Node 22 + HTTP natif.

Endpoints

  • GET /health — CPU, memoire, disque, uptime, logto ({status, responseTimeMs, error?})
  • GET /defenseurs — contenu de status.json (rapports defenseurs)
  • GET /reports/scans?date=YYYY-MM-DD — agrege les rapports defenseur-<agent>_<date>*.json du jour, format { date, count, reports: Report[] }. Filtre isScanReport (exclut defenseur-auto_*.json). Date validee par regex (path traversal bloque). Consommateur : defenseur-auto workstation cron (remplace le pre-rsync SSH). Exemple : curl -H "Authorization: Bearer $TOKEN" "https://health.lacompagniemaximus.com/reports/scans?date=2026-05-07".
  • GET /defenseurs/findings?project=X — findings detailles du Defenseur correspondant. Query params : project=<name> (obligatoire, lookup via agents-map.json), category=<deps|secrets|code|acces|infra> (optionnel, exact match), severity=<CRITICAL|HIGH|MEDIUM|LOW|INFO> (optionnel, threshold inclusif vers le haut). Sans severity -> MEDIUM+HIGH+CRITICAL (cache LOW+INFO). severity=LOW -> LOW+MEDIUM+HIGH+CRITICAL (cache toujours INFO, asymetrie volontaire). severity=INFO -> INFO uniquement (opt-in explicite). Reponses : 200 { agent, project, timestamp, findings[] } si report present (sans champ status) ; 200 { findings: [], status: "no_data" } si pas de report ; 400 sans project ou param invalide ; 404 projet inconnu ; 500 si agents-map.json corrompu. Consommateurs : admin dashboard Vercel (drill-down), futur skill /analyse-vulnerabilite. Exemple : curl -H "Authorization: Bearer $TOKEN" "https://health.lacompagniemaximus.com/defenseurs/findings?project=la-suite-booking&severity=HIGH".

Auth

  • Bearer token via env HEALTH_TOKEN
  • Fail-closed : si HEALTH_TOKEN non configure, toutes les requetes sont refusees
  • Coolify : HEALTH_TOKEN doit etre is_runtime=true, is_buildtime=false. Buildtime fait fuiter le secret en clair dans application_deployment_queues.logs. Voir la-compagnie-maximus/docs/coolify-ops.md section "Secrets en buildtime".

Config

  • Port : 3001 (env PORT)
  • LOGTO_HEALTH_URL : URL du .well-known/openid-configuration (default auth.lacompagniemaximus.com)
  • REPORTS_DIR : dossier lu par /reports/scans et /defenseurs/findings (default /data/defenseurs/reports)
  • DEFENSEURS_AGENTS_MAP_PATH : snapshot project->agent ecrit par le Sergent (default /data/defenseurs/agents-map.json)
  • Montages Coolify (Persistent Storages, UI seulement — aucun endpoint API) :
    • /data/defenseurs (host) -> /data/defenseurs : status.json + agents-map.json, ecrits directement la par le Sergent. /home/defenseur/defenseurs/status.json est un leurre obsolete lu par personne.
    • /home/defenseur/defenseurs/reports (host) -> /data/defenseurs/reports : rapports de scan (+ sous-dir archive/). Pose le 2026-07-15 (issue #10).

Deploy

Pas d'auto-deploy : l'app Coolify n'a pas de Source Forgejo (source_id=null, migration trackee dans la-compagnie-maximus#133). Apres un merge sur main, trigger manuel :

curl -H "Authorization: Bearer $(cat ~/.coolify-token)" \
  "https://coolify.lacompagniemaximus.com/api/v1/deploy?uuid=u8000gsg044wsk0oo0w884ok&force=true"

(ou bouton Redeploy dans l'UI Coolify.)

Tests

  • npm test (vitest) — couvre /defenseurs/findings (14 cas : auth, validation, filtres severity/category, asymetrie INFO, scan clean vs no_data, JSON corrompu)
  • Runtime reste 0-dep ; vitest en devDep uniquement

Gotchas

  • Pas d'Express — HTTP natif Node.js uniquement
  • Le status.json et agents-map.json sont ecrits par le Sergent defenseurs, pas par cette API (read-only)
  • agents-map.json doit etre present sur le VPS avant le deploy : verifier via ssh ubuntu@vps 'ls /data/defenseurs/agents-map.json' (PAS /home/defenseur/..., leurre obsolete). Sinon /defenseurs/findings retourne 500.
  • Coolify ignore silencieusement -v dans custom_docker_run_options — les volumes passent par les Persistent Storages (UI seulement). Details dans la-compagnie-maximus/docs/coolify-ops.md.
  • Severity threshold est asymetrique : ?severity=LOW retourne LOW+MEDIUM+HIGH+CRITICAL mais cache INFO. INFO est seulement accessible via ?severity=INFO explicite (cache le bruit par defaut).