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>
This commit is contained in:
78
eslint.config.mjs
Normal file
78
eslint.config.mjs
Normal file
@@ -0,0 +1,78 @@
|
||||
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,
|
||||
);
|
||||
Reference in New Issue
Block a user