adminAuth.js était le fichier le moins couvert du dépôt — 52 % de score de mutation, 22 mutants sans aucune couverture — alors qu'il porte JWT, bcrypt et le verrouillage de compte. seedAdminUser, recordLoginAttempt, markLoginSuccess et writeAuditLog n'avaient aucun test direct. writeAuditLog était le plus gênant : il peut cesser d'enregistrer sans qu'aucune action admin n'échoue et sans qu'aucun test ne rougisse, et un journal d'audit muet ne se remarque que le jour où on en a besoin. Mesuré après coup : adminAuth.js passe de 52,31 % à 84,29 %, les mutants sans couverture de 22 à 1, et le score global de 82,20 % à 88,85 %. Le job Python de la CI n'installait que ruff, pytest et pip-audit : psycopg2, beautifulsoup4, lxml et hypothesis manquaient, et il aurait échoué dès la collecte — ce que personne n'a jamais vu, faute de runner enregistré. Il part désormais de requirements-dev.txt, et lance aussi la suite du crawler, qui n'était pas exécutée du tout. requirements-dev.txt épinglait psycopg2-binary==2.9.9, sans roue pour Python >= 3.13 : la suite entière s'arrêtait dès la collecte sur un poste par ailleurs sain. Épinglages assouplis en bornes basses. Corrige enfin le commentaire de a11y.test.js, qui renvoyait à « l'audit Lighthouse manuel du README de la CI » pour justifier deux règles désactivées. Cet audit n'existe pas : README-CI.md documente le test e2e de l'admin, qui couvre bien le contraste mais UNIQUEMENT pour le dashboard. Pour le site public, ces règles ne sont vérifiées nulle part. La couverture n'a pas changé, seule sa description était fausse. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| .githooks | ||
| apps | ||
| infra | ||
| libs | ||
| scripts | ||
| .gitignore | ||
| docker-compose.dev.yml | ||
| docker-compose.test.yml | ||
| docker-compose.yml | ||
| eslint.config.js | ||
| jsconfig.json | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.js | ||
| pyproject.toml | ||
| README-CI.md | ||
| README.md | ||
| requirements-dev.txt | ||
| stryker.config.json | ||
| stryker.full.config.json | ||
| vitest.config.js | ||
| vitest.integration.config.js | ||
| vitest.mutation.config.js | ||
| vitest.mutation.full.config.js | ||
Stack metalfrom.eu
Carte des groupes de metal européens, données issues de Metal Archives (avec accord du propriétaire du site source).
Services
| Service | Rôle |
|---|---|
web |
Site public (carte Leaflet) |
admin |
Back-office (nginx + reverse-proxy vers l'API) |
api |
API Fastify (public + routes admin), migrations DB |
crawler |
Scraping incrémental/complet de Metal Archives via FlareSolverr |
flaresolverr |
Contournement Cloudflare (Chrome headless) pour le crawler |
geocoder-enqueue |
Peuple band_locations depuis bands.location_text |
geocoder-worker |
Géocodage Geoapify |
groq-worker |
Désambiguïsation LLM (Groq) des lieux non géocodés |
crawler et flaresolverr ne tournent qu'en dev pour l'instant : ils sont
absents de docker-compose.yml. La prod partage la même base, alimentée depuis
l'environnement de dev.
Déploiement
docker-compose.yml: productiondocker-compose.dev.yml: environnement de dev (branchedev, auto-déployé via webhook Forgejo → Coolify)
Base PostgreSQL + PostGIS gérée séparément par Coolify. Variables d'env : voir
infra/.env.example.
Qualité
Le déploiement se déclenche sur webhook à chaque push : rien ne s'interpose
entre git push et la mise en ligne. La porte de qualité est donc locale,
et doit être installée une fois par clone :
npm install
npm run hooks:install
| Commande | Portée |
|---|---|
npm run check |
lint + types + tests JS + ruff + pytest (~6 s) |
npm run test:e2e |
parcours Playwright du dashboard admin (~22 s) |
npm run test:integration:full |
SQL validé contre un vrai PostgreSQL+PostGIS (exige Docker) |
npm run check:full |
tout ci-dessus + mutation + audits de dépendances |
Le hook pre-push lance check puis test:e2e. .forgejo/workflows/ci.yml
existe mais reste inerte tant qu'aucun runner Forgejo n'est enregistré.
Outillage Python de test : pip install -r requirements-dev.txt.