Dix-huit migrations, zéro CHECK. crawl_run.status, job_triggers.job_type et band_locations.geocode_status étaient du texte libre dont les valeurs admises ne vivaient que dans des commentaires. C'est le dénominateur commun de plusieurs bugs de ce dépôt : un statut 'error' que plus personne n'écrivait mais qu'un bouton d'admin ciblait encore, des lignes 'processing' qu'aucune requête ne reprenait, un job_type réclamé par le mauvais daemon. Une faute de frappe écrivait une ligne durablement invisible, sans jamais rien faire échouer. Vérifié contre PostgreSQL : 'runnning' et le job_type 'geocode' sont désormais rejetés, les valeurs légitimes passent. Les contraintes restent NOT VALID de façon assumée — cette migration tourne au démarrage de chaque conteneur API, et une seule ligne héritée hors domaine empêcherait l'API de démarrer. Le but est d'arrêter la dérive, pas de réécrire le passé. Retire geocode_queue, vestige du pipeline Nominatim que plus aucune ligne de code ne référence. Ajoute enfin une purge de rétention sur crawl_log, admin_audit_log et admin_login_attempts, qui grossissaient sans fin — alors que la migration 015 avait explicitement conçu service_health pour éviter « une table qui grossit ». Elle est appelée par migrate.js au démarrage, seul point d'accroche périodique disponible, et volontairement tolérante : ce nettoyage ne doit jamais empêcher l'API de démarrer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| .githooks | ||
| apps | ||
| infra | ||
| 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.