Commit graph

3 commits

Author SHA1 Message Date
Nicolas FRYDER
fcb20e2e11 perf(api): compression des réponses, et troncature de la carte enfin signalée
Le site public charge l'intégralité du corpus une seconde après l'ouverture de
la page (loadAllHeatPoints), pour la heatmap et la recherche. Rien ne
compressait dans la chaîne — ni Fastify, ni Traefik. Ce n'était donc pas un
risque théorique mais la facture de chaque visiteur, à chaque visite.

Mesuré sur 100 000 groupes avec des données réalistes, en-tête Accept-Encoding
d'un vrai navigateur : 21,5 Mo deviennent 1,9 Mo.

gzip est préféré à brotli, contre l'intuition : br sort 2,3 Mo là où gzip fait
1,9 Mo. La qualité brotli par défaut est réglée pour la vitesse, et sur ce JSON
très répétitif elle perd sur les deux tableaux à la fois — taille ET CPU. Seuil
à 1 Ko, en dessous duquel compresser coûte plus que ça ne rapporte.

/api/clusters plafonnait par ailleurs sa réponse à 2000 groupes ou 1000
clusters sans le dire, ni côté API ni côté client : dans une zone dense, des
groupes disparaissaient de la carte sans aucun signal. La réponse porte
désormais `truncated` et `limit`, et l'interface affiche un avertissement
invitant à zoomer. Clé de traduction ajoutée dans les 21 langues, la
convention du fichier étant une couverture complète.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 14:35:12 +02:00
a7d7bc94de feat(admin): dashboard admin complet (auth forte, API, monitoring)
Nouveau service apps/admin (admin.metalfrom.eu / admin.dev.metalfrom.eu) :
- Frontend statique vanilla JS/CSS reprenant le design system du site
  (login, dashboard stats, table bands éditable, queue d'enrichissement,
  historique crawl_run, logs live, checkpoints, journal d'audit)
- nginx reverse-proxy /admin/api/* et /admin/auth/* vers le service api
  interne (same-origin côté navigateur, pas de CORS cross-site nécessaire
  pour le cookie de session)

apps/api :
- Nouvelle auth dédiée au dashboard, séparée du token BM_IMPORT_TOKEN
  existant : login bcrypt + session JWT en cookie httpOnly/secure/
  sameSite=strict, rate-limit + lockout après 5 échecs/15min, seeding
  du compte admin via env vars (jamais de mot de passe en clair en DB
  ou en git)
- Routes /admin/api/* : stats, queue (breakdown priorité identique au
  crawler Python), bands (recherche/tri/pagination/édition + audit log),
  crawl-runs, crawl-checkpoints, logs, audit-log
- trustProxy activé (Traefik + nginx en amont)

apps/crawler :
- log_event() écrit dans la nouvelle table crawl_log (run start/finish/
  erreurs) pour que le dashboard affiche les logs sans exposer le socket
  Docker (choix délibéré : pas de docker.sock monté, accès DB only)

migration 006_admin_dashboard.sql : admin_users, admin_login_attempts,
admin_audit_log, crawl_log

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 22:15:13 +02:00
d4e1bf2e15 chore: initial commit — snapshot VPS 2026-06-27
- apps/api      : API REST Node.js/Fastify + PostgreSQL/PostGIS
- apps/geocoder : Worker Python géocodage Nominatim
- apps/worker   : Scraper Python Metal-Archives
- apps/web      : Frontend statique Leaflet/clustering/heatmap
- infra/        : docker-compose + init.sql

Déployé via Coolify + Traefik sur VPS OVH.
2026-06-27 08:53:39 +00:00