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>
43 lines
1.8 KiB
JSON
43 lines
1.8 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 .",
|
|
"lint:fix": "eslint . --fix",
|
|
"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 qualité lancée avant chaque push (~30s). Les tests de mutation et les audits de dépendances en sont exclus : trop lents / dépendants du réseau. Lancer `npm run check:full` avant une release.",
|
|
"check": "npm run lint && npm run lint:py && npm run typecheck && npm run test && npm run test:py",
|
|
"check:full": "npm run check && npm run audit:js && npm run audit:py && npm run test:mutation:full",
|
|
"hooks:install": "git config core.hooksPath .githooks"
|
|
},
|
|
"devDependencies": {
|
|
"@eslint/js": "^9.17.0",
|
|
"@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",
|
|
"typescript": "^5.7.2",
|
|
"vitest": "^2.1.8"
|
|
}
|
|
}
|