Files
app/eslint.config.mjs
BOHA 519edce373 fix: 2026-06-09 full-codebase audit hardening
Validation: shared NaN-guarded Zod coercion helpers in schemas/common.ts replace
the raw number|string transform idiom across every schema (the root-cause NaN bug
class); emailOrEmpty + lenient isoDateString/timeString.

Security: roles privilege-escalation closed; refresh-token family revocation on
reuse; TOTP uses config params; read endpoints permission-guarded; received-invoices
gross VAT on all paths; orders-pdf custom-items authz.

Concurrency: $queryRaw SELECT...FOR UPDATE locks in ascending-id order (warehouse
confirm/cancel, attendance lockUserRow); uniqueness checks moved into create
transactions (TOCTOU -> 409); deterministic id tiebreak on second-precision
timestamp ordering (plan resolveCell/resolveGrid, warehouse FIFO).

Frontend: Rules-of-Hooks fixed across ~14 pages + PlanCellModal; UTC-date persisted
fields; dashboard invalidation gaps; stale-closure confirm bugs.

Tooling/tests: ESLint flat config (react-hooks/rules-of-hooks = error) + Prettier;
tsconfig.test.json so tsc -b type-checks the tests; removed 3 dead deps; npm audit
fix (8 -> 3). Suite 195 -> 247 (happy-path auth, FIFO oldest-first, flakiness fixes),
isolated on app_test via .env.test with a hard-throw setup guard.

Gates: tsc 0 | build 0 | vitest 247/247 | eslint 0 errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 06:45:26 +02:00

79 lines
2.3 KiB
JavaScript

import js from "@eslint/js";
import tseslint from "typescript-eslint";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import globals from "globals";
import prettier from "eslint-config-prettier";
export default tseslint.config(
{
ignores: [
"dist/**",
"dist-client/**",
"node_modules/**",
"prisma/migrations/**",
"src/admin/bones/**",
"*.config.js",
"*.config.mjs",
"*.config.ts",
".claude/**",
],
},
js.configs.recommended,
...tseslint.configs.recommended,
{
// Server + shared code
files: ["src/**/*.{ts,tsx}", "scripts/**/*.ts", "prisma/seed.ts"],
languageOptions: {
globals: { ...globals.node, ...globals.browser },
},
rules: {
// TS already resolves identifiers — `no-undef` only false-positives on
// global types/ambient names in .ts files.
"no-undef": "off",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": [
"warn",
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
],
"@typescript-eslint/no-require-imports": "warn",
"no-empty": ["warn", { allowEmptyCatch: false }],
// Intentional control-character regexes (NUL/path-traversal guards,
// combining-marks stripping) — not a defect here.
"no-control-regex": "off",
// Stylistic / advisory — surface as warnings, don't fail the lint gate.
"no-useless-escape": "warn",
"no-useless-assignment": "warn",
"preserve-caught-error": "warn",
"prefer-const": "warn",
},
},
{
// Frontend React code
files: ["src/admin/**/*.{ts,tsx}", "src/**/*.tsx"],
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
},
},
{
// Plain Node helper scripts (.js/.mjs/.cjs in scripts/)
files: ["scripts/**/*.{js,mjs,cjs}"],
languageOptions: { globals: { ...globals.node } },
rules: { "no-undef": "off" },
},
{
// Tests
files: ["src/__tests__/**/*.ts"],
languageOptions: { globals: { ...globals.node } },
rules: {
"@typescript-eslint/no-explicit-any": "off",
},
},
prettier,
);