Metal from Europe — carte interactive des groupes de metal européens (frontend statique + API Node.js + PostgreSQL/PostGIS + geocoder)
Le trigger bands_set_geom (migration 002) faisait `NEW.updated_at := now()` sans condition. Or upsert_bands exécute un `ON CONFLICT DO UPDATE` sans clause WHERE : Postgres déclenche donc le trigger pour chaque ligne vue, même quand aucune valeur ne change. get_bands_to_enrich filtrant sur `updated_at > crawled_at + 1 min`, la table entière redevenait « à enrichir » après chaque crawl — le crawler repartait indéfiniment chercher des pages inchangées sur Metal Archives. La migration 016 ne bumpe plus updated_at que sur changement réel de la ligne. La 017 introduit alors le signal manquant : quand MA modifie un groupe sur un champ visible seulement sur sa page (line-up, albums), le listing ne montre aucun diff. Le crawler capture donc l'horodatage "modified" affiché par MA lui-même et lève enrich_pending quand ce texte change — une fois par modification, sans boucle. Autres correctifs : - claim_job_trigger() réclamait n'importe quel trigger en attente. Le crawler raflait donc les 'geocoder_enqueue', qu'il ne sait pas exécuter, et les refermait en « job_type inconnu » — selon lequel des deux daemons interrogeait la table en premier. Borné aux CRAWLER_JOB_TYPES. - run_enrich sautait la politesse après un échec, via un `continue` placé avant le sleep. Un échec de get_html étant le plus souvent un 403/429, c'était le pire moment pour enchaîner sans délai. - FlareSolverrError n'était rattrapée nulle part : un blip réseau ou un crash du Chrome headless faisait perdre le run entier. - La boucle du scheduler n'isolait aucune exception : une panne DB transitoire tuait le process, que restart: unless-stopped relançait en crash-loop. - recover_stuck_runs() referme au démarrage les runs laissés en 'running' par une instance tuée brutalement. - full_crawl publie sa progression et respire entre deux pays. 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
test 4