metalfrom.eu/infra/.env.example
Nicolas Fryder 60074fb015
Some checks are pending
CI / javascript (push) Waiting to run
CI / python (push) Waiting to run
CI / mutation (push) Waiting to run
feat(qualité): outillage de test complet, CI locale, annulation réelle des runs
Le dépôt n'avait aucun test, aucun linter, aucune vérification de types.

Outillage
- ESLint 9 (flat config) sur api + les deux frontends, Ruff sur le Python
- tsc --checkJs sur l'API (pas de TypeScript, juste la vérification)
- Vitest : 401 tests JS ; pytest : 43 tests Python
- Tests de mutation (Stryker), deux profils : logique pure et API complète
- Hook pre-push `npm run check` (~17 s) — le déploiement Coolify est sur webhook,
  c'est donc la seule porte de qualité avant la mise en ligne
- Workflow Forgejo Actions prêt (inerte tant qu'aucun runner n'est enregistré)

Sécurité
- Injection SQL authentifiée dans resolve-conflict : `field` était interpolé
  dans le SET sans allowlist
- timingSafeEqual levait sur un jeton multi-octets (500 au lieu de 401)
- setErrorHandler écrasait tous les 4xx en 500
- .env.example : ADMIN_JWT_SECRET et ADMIN_SEED_* n'étaient documentés nulle part
  alors que leur absence casse toute connexion admin

Annulation réelle des crawl_run (migration 014)
- L'API posait status='error' sans que le crawler en sache rien : le process
  continuait, et son UPDATE final ne matchait plus (run réussi affiché en erreur)
- Protocole coopératif : drapeau cancel_requested lu à chaque lot, le crawler
  écrit lui-même status='cancelled'

Cohérence géographique (migration 014)
- Le trigger 013 supprimait les band_locations sans purger le point dénormalisé
- L'édition admin de lat/lon n'atteignait jamais band_locations : la carte
  ignorait la correction. Override step_order = -1, dans une transaction

Corrections
- limit/offset NaN → 500 au lieu de 400
- OPTIONS sans `return reply` (Fastify poursuivait le cycle de vie)
- listen() sans catch, cast ::text en dur sur les colonnes numériques
- /admin/api/logs ne renvoyait pas sa pagination
- a11y : sélecteur de langue annoncé comme liste vide (role=option manquant)

Nettoyage
- apps/web/quizz-site supprimé (sans rapport avec le projet)
- Code mort : openModal(), LANG_NAMES, double import, variables inutilisées
- .dockerignore ajoutés ; node_modules racine n'était pas gitignoré

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 10:05:40 +02:00

49 lines
1.8 KiB
Text

# ------------------------------------------------------------------
# Base de données (gérée séparément par Coolify, standalone)
# ------------------------------------------------------------------
DATABASE_URL=postgresql://bm:PASSWORD@HOST:5432/bm
# ------------------------------------------------------------------
# API — authentification
# ------------------------------------------------------------------
# Jeton Bearer des endpoints d'import machine-à-machine (/admin/import).
BM_IMPORT_TOKEN=
# OBLIGATOIRE : secret de signature des sessions du dashboard admin.
# Minimum 32 caractères, sinon TOUTE connexion admin échoue en 500.
# openssl rand -hex 32
ADMIN_JWT_SECRET=
# Compte admin créé au démarrage s'il n'existe pas (les deux sont requis,
# sinon aucun compte n'est créé et le dashboard est inaccessible).
# Générer le hash :
# node -e "console.log(require('bcryptjs').hashSync(process.argv[1],12))" 'mon-mot-de-passe'
ADMIN_SEED_USERNAME=
ADMIN_SEED_PASSWORD_HASH=
# Origines autorisées en CORS, séparées par des virgules.
# dev : https://dev.metalfrom.eu
# prod : https://metalfrom.eu,https://www.metalfrom.eu
CORS_ORIGINS=
# ------------------------------------------------------------------
# Géocodage
# ------------------------------------------------------------------
# Fournisseur de géocodage (pipeline actuel).
GEOAPIFY_API_KEY=
# Désambiguïsation LLM des lieux que Geoapify ne résout pas.
GROQ_API_KEY=
# ------------------------------------------------------------------
# pgAdmin
# ------------------------------------------------------------------
PGADMIN_EMAIL=
PGADMIN_PASSWORD=
# ------------------------------------------------------------------
# Divers
# ------------------------------------------------------------------
TZ=Europe/Paris
PUID=1001
PGID=1001