From bd134c464623a3b58727bcd8c9706caf70943cf3 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Jun 2026 00:01:53 +0200 Subject: [PATCH] feature: sweep flotte (propagation libs copy-first model/monitoring/requestPromise/influxdb, config eslint/lintstaged/husky, migration TS, avancement conformite migrations Vite) --- .husky/.gitignore | 1 + .husky/commit-msg | 9 +++ .husky/post-merge | 7 +++ .lintstagedrc | 2 +- eslint.config.js | 146 +++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 .husky/.gitignore create mode 100755 .husky/commit-msg create mode 100755 .husky/post-merge diff --git a/.husky/.gitignore b/.husky/.gitignore new file mode 100644 index 0000000..31354ec --- /dev/null +++ b/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..7bba098 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,9 @@ + +if [ -z "$(cat "$1" | grep -E '(^fix:)|(^feature:)|(^up$)|^Merge branch .+$')" ] ; then + echo "" + echo respecte le format de commit ❤ + echo " fix: xxx" + echo " feature: xxx" + echo "" + exit 1 +fi diff --git a/.husky/post-merge b/.husky/post-merge new file mode 100755 index 0000000..6b297ba --- /dev/null +++ b/.husky/post-merge @@ -0,0 +1,7 @@ + +if git diff --name-only HEAD@{1} HEAD | grep package-lock.json ; then + echo "📦 package-lock.json changed. Running npm ci to update your dependencies..." + npm ci +else + echo "📦 no need to update dependencies" +fi diff --git a/.lintstagedrc b/.lintstagedrc index 326ac1a..2a86acc 100644 --- a/.lintstagedrc +++ b/.lintstagedrc @@ -3,7 +3,7 @@ "*.ts": ["eslint --fix", "prettier --write"], "*.css": ["prettier --write"], "*.jsx": ["prettier --write"], - "*.html.twig": ["twig-cs-fixer lint --fix"], + "*.tsx": ["prettier --write"], "*.php": ["php-cs-fixer fix --config .php-cs-fixer.php"], "Dockerfile": ["hadolint --ignore DL3002 --ignore DL3003 --ignore DL3008 --ignore DL3013 --ignore DL3016 --ignore DL3022"], "*.md": ["markdownlint --fix"], diff --git a/eslint.config.js b/eslint.config.js index d1d1c83..dbb6574 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -69,6 +69,142 @@ export default [ 'sonarjs/publicly-writable-directories': 0, 'sonarjs/file-permissions': 0, 'sonarjs/no-empty-test-file': 0, + // les // FIXME sont legitimes (WIP), comme todo-tag deja desactive + 'sonarjs/fixme-tag': 0, + // le stack utilise AppError {err: error} pour la cause, pas le cause natif ; rethrow AppError partout + 'preserve-caught-error': 0, + // force .then/.finally -> await, reecrit des chaines qui marchent + 'unicorn/prefer-await': 0, + // ordre declarations vs early-return, opinionne + 'unicorn/no-declarations-before-early-exit': 0, + // this.x sans declarer le membre ; classes Container/Model en style dynamique + 'unicorn/no-undeclared-class-members': 0, + // FAUX POSITIF sur parseInt(String(x),10) ; Math.trunc casserait le parsing de string + 'unicorn/prefer-math-trunc': 0, + // idiome de coercion volontaire + 'unicorn/no-useless-template-literals': 0, + // style + 'unicorn/prefer-else-if': 0, + // style + 'unicorn/no-unreadable-for-of-expression': 0, + // ternaire imbrique, comme no-nested-ternary + 'sonarjs/no-nested-conditional': 0, + // style a=b=c + 'sonarjs/no-nested-assignment': 0, + // style (await x).y + 'unicorn/no-await-expression-member': 0, + // style + 'unicorn/max-nested-calls': 0, + // map(fn) intentionnel + 'unicorn/no-array-callback-reference': 0, + // style + 'unicorn/prefer-includes-over-repeated-comparisons': 0, + // style + 'unicorn/prefer-unicode-code-point-escapes': 0, + // style + 'unicorn/prefer-minimal-ternary': 0, + // style + 'unicorn/no-duplicate-loops': 0, + // style + 'unicorn/prefer-iterator-to-array': 0, + // style + 'unicorn/prefer-early-return': 0, + // style + 'unicorn/no-immediate-mutation': 0, + // garde mutation, style + 'unicorn/no-array-sort': 0, + // style + 'unicorn/prefer-short-arrow-method': 0, + // style + 'sonarjs/use-type-alias': 0, + // style + 'unicorn/prefer-url-href': 0, + // style + 'unicorn/no-array-from-fill': 0, + // style + 'unicorn/no-unnecessary-global-this': 0, + // style + 'unicorn/no-unreadable-array-destructuring': 0, + // style + 'unicorn/no-nested-ternary': 0, + // style + 'unicorn/no-negated-comparison': 0, + // style + 'unicorn/consistent-class-member-order': 0, + // style + 'sonarjs/no-inverted-boolean-check': 0, + // style + 'unicorn/prefer-private-class-fields': 0, + // style + 'unicorn/no-useless-else': 0, + // style + 'sonarjs/void-use': 0, + // niche + 'unicorn/prefer-number-is-safe-integer': 0, + // niche + 'unicorn/prefer-math-min-max': 0, + // garde mutation, style + 'unicorn/no-array-reverse': 0, + // style + 'unicorn/logical-assignment-operators': 0, + // style + 'unicorn/prefer-simple-sort-comparator': 0, + // style + 'unicorn/prefer-continue': 0, + // style + 'unicorn/prefer-array-from-map': 0, + // style + 'unicorn/prefer-add-event-listener': 0, + // style + 'unicorn/prefer-module': 0, + // style + 'unicorn/prefer-hoisting-branch-code': 0, + // style + 'unicorn/prefer-array-flat-map': 0, + // style + 'unicorn/no-useless-recursion': 0, + // style + 'unicorn/no-unused-array-method-return': 0, + // style + 'unicorn/no-new-array': 0, + // style + 'unicorn/consistent-existence-index-check': 0, + // VET non-garde + 'sonarjs/no-unenclosed-multiline-block': 0, + // VET non-garde + 'unicorn/no-return-array-push': 0, + // VET non-garde + 'unicorn/no-subtraction-comparison': 0, + // VET non-garde + 'promise/always-return': 0, + // VET non-garde + 'sonarjs/no-redundant-assignments': 0, + // fire sur les assertions exactes de montants/prix dans les tests (calculs deterministes) = bruit + 'sonarjs/no-floating-point-equality': 0, + // faux positif sur slugify vendore (valeurs de remplacement = map ASCII + delimiteur, pas d input user) + 'unicorn/no-unsafe-string-replacement': 0, + // continue en boucle imbriquee = normal/lisible, pas d extraction forcee en fonction + 'unicorn/no-break-in-nested-loop': 0, + // naming is/has/can opinionne, comme prevent-abbreviations deja desactive + 'unicorn/consistent-boolean-name': 0, + // les // TODO sont legitimes, cf expiring-todo-comments deja desactive + 'sonarjs/todo-tag': 0, + // lookup dynamique du schema dans model.ts (this.modeldata[entity].columns[property]) = volontaire + 'unicorn/no-computed-property-existence-check': 0, + // famille regex sonar deja desactivee (slow-regex/regex-complexity/concise-regex) ; faux positifs sur regex lineaires + 'sonarjs/super-linear-regex': 0, + // parseFloat != Number : choix volontaire dans les validators model.ts (arrondi), Number casse en NaN + 'unicorn/prefer-number-coercion': 0, + // Uint8Array#toBase64() = API Node 22+ trop recente, btoa/toString('base64') marche partout + 'unicorn/prefer-uint8array-base64': 0, + // init de module volontaire (monitoring startQueue, client influxdb) + 'unicorn/no-top-level-side-effects': 0, + // etat module mute depuis les fonctions (timeout/queue/bans monitoring) = pattern singleton debounce + 'unicorn/no-top-level-assignment-in-function': 0, + // errorToObject.test.ts teste justement l'assignation de .cause/.stack + 'unicorn/no-error-property-assignment': 0, + // smoke/setup tests (e2e, translations should load) sans assertion = volontaire, cf no-empty-test-file + 'sonarjs/assertions-in-tests': 0, 'import-x/no-named-as-default-member': 0, 'import-x/no-unresolved': [ 'error', @@ -228,14 +364,17 @@ export default [ 'no-constant-binary-expression': 'error', 'no-undef-init': 'error', 'no-label-var': 'error', - 'init-declarations': ['error', 'always'], + // desactive : conflit direct avec no-useless-assignment sur les vars assignees en branches/try/boucle + // (toute init y est "inutile" donc flaggee, mais init-declarations l'exige). on garde no-useless-assignment. + 'init-declarations': 0, 'wrap-iife': ['error', 'inside'], yoda: 'error', 'vars-on-top': 'error', 'prefer-regex-literals': 'error', 'prefer-promise-reject-errors': 'error', 'promise/catch-or-return': ['error', { terminationMethod: ['catch', 'finally'] }], - 'no-warning-comments': 'error', + // les // TODO/FIXME sont legitimes (WIP), comme sonarjs/todo-tag deja desactive + 'no-warning-comments': 0, 'no-void': 'error', 'no-useless-return': 'error', 'no-useless-concat': 'error', @@ -271,7 +410,8 @@ export default [ ], 'no-eval': 'error', 'no-constant-condition': ['error', { checkLoops: false }], - 'no-eq-null': 'error', + // convention volontaire : == null = check idiomatique null+undefined (cf ESLINT_FLOTTE.md), ~400 usages flotte + 'no-eq-null': 0, 'no-else-return': 'error', 'no-unused-vars': 0, 'no-console': 0,