metalfrom.eu/package.json
Nicolas Fryder 7b53d47d71
Some checks are pending
CI / javascript (push) Waiting to run
CI / python (push) Waiting to run
CI / mutation (push) Waiting to run
feat: intégration SQL sur PostgreSQL réel + boutons de crawl conscients du crawler
1. Suite d'intégration SQL (npm run test:integration:full)

Ferme le dernier angle mort : la SÉMANTIQUE du SQL. Le parseur de grammaire ne
voyait pas un nom de colonne inexistant, un type incompatible ou une fonction
PostGIS mal appelée — soit exactement la classe de bugs qui n'apparaissait
qu'en production.

Technique : chaque requête émise par l'application passe par `PREPARE`.
Postgres l'analyse et la planifie entièrement — colonnes, types, opérateurs
jsonb, fonctions PostGIS — SANS l'exécuter ni nécessiter de données. Rapide, et
ça couvre aussi les requêtes que le parseur JS ne sait pas lire :
jsonb_build_object, `jsonb - text[]`, `raw ? 'clé'`, make_interval, l'opérateur
spatial && et l'agrégation en grille des clusters.

Les migrations réelles sont appliquées dans l'ordre réel : une migration
invalide échoue ici, plus au redémarrage du conteneur en production.

54 tests. Exige Docker, donc HORS de `check` et du hook pre-push — la boucle
de développement reste à 6 s. Base jetable en tmpfs (fsync off).

Deux témoins vérifient que le détecteur n'est pas inopérant : une colonne
inexistante et un type incompatible doivent être rejetés.

2. Les boutons de crawl ne mentent plus

La production ne déploie pas le service crawler (docker-compose.yml ne le
contient pas). Les boutons « Crawl incrémental », « Enrichir » et « Crawl
complet » y créaient des demandes que personne ne consommait, avec un libellé
promettant une exécution « sous ~1 min ».

Ils s'appuient désormais sur le battement de cœur : pas de crawler vivant,
boutons désactivés et raison affichée. « Alimenter le géocodage » reste actif,
puisqu'il est traité par le geocoder.

Je n'ai PAS ajouté le crawler au compose de production : ce serait déclencher
du crawl depuis la prod, décision qui n'est pas la mienne.

Régression évitée au passage : re-rendre le bloc de traitements effaçait le
message de retour (« Demande #77 enregistrée »), puisque loadPilotage() est
rappelé après un clic réussi. L'état des boutons est donc mis à jour sans
reconstruire le DOM. Détecté par un test existant.

Correctif : la suite d'intégration était happée par le glob de vitest.config.js
et allongeait `check` de 6 à 22 s en exigeant Docker.

Tests : 580 JS + 54 intégration, 63 Python, 89 Playwright

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 20:53:35 +02:00

58 lines
3.5 KiB
JSON

{
"name": "metalfromeu",
"version": "0.0.1",
"private": true,
"type": "module",
"description": "Monorepo metalfrom.eu — outillage qualité (lint, types, tests). Chaque app garde son propre runtime.",
"workspaces": [
"apps/api"
],
"scripts": {
"lint": "eslint . --cache --cache-location node_modules/.cache/eslint/",
"lint:fix": "eslint . --fix --cache --cache-location node_modules/.cache/eslint/",
"typecheck": "tsc -p jsconfig.json",
"test": "vitest run",
"test:watch": "vitest",
"test:cov": "vitest run --coverage",
"test:mutation": "stryker run",
"test:mutation:full": "stryker run stryker.full.config.json",
"lint:py": "ruff check .",
"lint:py:fix": "ruff check . --fix",
"test:py": "npm run test:py:geocoder && npm run test:py:crawler",
"test:py:geocoder": "cd apps/geocoder && python -m pytest tests -q",
"test:py:crawler": "cd apps/crawler && python -m pytest tests -q",
"audit:js": "npm audit --audit-level=high",
"audit:py": "pip-audit -r apps/api/../crawler/requirements.txt -r apps/geocoder/requirements.txt",
"_comment_check": "`check` = la porte de qualite lancee avant chaque push. Les cinq verifications tournent en parallele (voir scripts/check.mjs). Mutation et audits de dependances en sont exclus : trop lents / dependants du reseau — voir `check:full`.",
"check": "node scripts/check.mjs",
"check:full": "npm run check && npm run test:e2e && npm run audit:js && npm run audit:py && npm run test:mutation:full",
"hooks:install": "git config core.hooksPath .githooks",
"_comment_cache": "lint et typecheck utilisent un cache dans node_modules/.cache : `check` tourne des dizaines de fois par jour, refaire l'analyse complete de fichiers inchanges a chaque fois n'apporte rien. Les caches sont invalides par mtime+contenu ; `npm run check:clean` les purge.",
"check:clean": "node -e \"require('fs').rmSync('node_modules/.cache',{recursive:true,force:true})\"",
"check:sequential": "node scripts/check.mjs --sequential",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:install": "playwright install chromium",
"_comment_e2e": "Les parcours Playwright (~22 s) ne sont PAS dans `check` : celui-ci tourne des dizaines de fois par jour et doit rester sous 10 s. Ils sont lances par le hook pre-push, granularite correcte pour ce cout. `npm run test:e2e:install` recupere Chromium sur un clone neuf.",
"test:integration": "vitest run --config vitest.integration.config.js",
"test:integration:up": "docker compose -f docker-compose.test.yml up -d --wait",
"test:integration:down": "docker compose -f docker-compose.test.yml down -v",
"test:integration:full": "npm run test:integration:up && npm run test:integration && npm run test:integration:down",
"_comment_integration": "Suite d'integration : valide le SQL contre un vrai PostgreSQL+PostGIS via PREPARE (colonnes, types, PostGIS). Exige Docker, donc HORS de `check` et du hook pre-push. A lancer avant une release ou apres avoir touche une requete."
},
"devDependencies": {
"@axe-core/playwright": "^4.13.0",
"@eslint/js": "^9.17.0",
"@playwright/test": "^1.62.1",
"@stryker-mutator/core": "^8.7.1",
"@stryker-mutator/vitest-runner": "^8.7.1",
"@vitest/coverage-v8": "^2.1.8",
"axe-core": "^4.10.2",
"eslint": "^9.17.0",
"globals": "^15.14.0",
"jsdom": "^25.0.1",
"node-sql-parser": "^5.4.0",
"typescript": "^5.7.2",
"vitest": "^2.1.8"
}
}