chore(ci+logs): eslint в CI, npm audit, logger с уровнями, retention error_logs

Шаги 1.6 и 1.7 плана production-готовности:
- eslint flat-config (баг-ловушки, легаси warn), lint блокирующий в pr-check
- npm audit --audit-level=high в CI (отчёт)
- фикс реального бага: условный useRef в TaskTitleInline
- server/utils/logger.ts (LOG_LEVEL/LOG_FORMAT) в 5 горячих местах
- error_logs retention 30 дней (worker), redactSensitive в captureErrorLog
- 0 errors lint, vitest 96/96
This commit is contained in:
2026-09-08 00:11:38 +03:00
parent 6eaca79cc6
commit abd5d4b65f
14 changed files with 1579 additions and 19 deletions

100
eslint.config.js Normal file
View File

@@ -0,0 +1,100 @@
// Базовый flat-config ESLint: только правила, ловящие реальные баги, без стилистики.
// Существующие легаси-проблемы — warn (не блокируют CI), критичные — error.
import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
import reactHooks from "eslint-plugin-react-hooks";
export default tseslint.config(
{
ignores: [
"dist/**",
"node_modules/**",
"client-di2/dist/**",
"client-di2/node_modules/**",
"mobile/**",
"tmp/**",
"uploads/**",
"attached_assets/**",
"apps/**",
"traccar/**",
"**/*.config.*",
// seed-файлы кастомных JS-страниц исполняются в sandbox с глобальным ctx — это не Node-модули
"server/page-seeds/**",
"server/documents/worker/node_modules/**",
"server/documents/worker/dist/**",
],
},
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ["**/*.{ts,tsx,js,mjs,cjs}"],
languageOptions: {
globals: {
...globals.node,
...globals.browser,
},
},
plugins: {
"react-hooks": reactHooks,
},
rules: {
// Критичное: нарушение правил хуков — реальные баги рендера
"react-hooks/rules-of-hooks": "error",
// Пропущенные зависимости — частый источник багов, но в легаси много: warn
"react-hooks/exhaustive-deps": "warn",
// Неиспользуемые переменные: warn, игнор префикса _ и catch-параметров
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
ignoreRestSiblings: true,
},
],
// Сравнения: только строгие ==/!= на null разрешены
eqeqeq: ["warn", "always", { null: "ignore" }],
// console.* осознанно используется на сервере и в воркерах
"no-console": "off",
// Легаси-уровень warn: реальные мелочи, но не блокируем CI на старом коде
"prefer-const": "warn",
"@typescript-eslint/no-unused-expressions": "warn",
"no-useless-escape": "warn",
"no-empty": ["warn", { allowEmptyCatch: true }],
// В проекте много any и require-импортов — не блокируем на легаси
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-require-imports": "off",
"@typescript-eslint/no-empty-object-type": "off",
},
},
{
// Service worker: своё глобальное окружение (clients, self, caches и т.д.)
files: ["client/public/sw.js", "**/sw.js"],
languageOptions: {
globals: {
...globals.serviceworker,
},
},
},
{
// no-undef в TS/TSX избыточен — типы проверяет tsc
files: ["**/*.{ts,tsx,mts,cts}"],
rules: {
"no-undef": "off",
},
},
{
// Тесты и скрипты могут использовать нестандартные глобалы
files: ["tests/**", "scripts/**"],
rules: {
"@typescript-eslint/no-unused-vars": "off",
},
},
);