Files
pn-new-crm/eslint.config.mjs
Matt 52342ee45d feat(uat-batch-4): a11y form primitives + click-to-preview + EOI empty-state + lint guards
- FieldError primitive (role=alert, aria-live) — used by Wave 3
  form-error UX work.
- FieldLabel primitive (Label + Info-tooltip slot) — foundational for
  the platform-wide admin-settings tooltip audit.
- ESLint guard against em-dash in user-facing JSX text inside
  src/components + src/app (warning, not error; 111 existing instances
  flagged for follow-up sweep).
- FileGrid card body becomes click-to-preview button (was hidden under
  a kebab); aria-label per row; kebab keeps Download/Rename/Delete.
- DocumentList: title cell on rows with signedFileId opens
  FilePreviewDialog; kebab gains Download action (was missing
  per UAT). Single FilePreviewDialog instance lifted to the parent.
- DocumentList type extended with signedFileId.
- EOI empty state: third ghost button "Mark signed without file"
  wired to existing MarkExternallySignedDialog (parity with
  reservation tab).
- Watcher empty-state padding fix on document-detail.

tsc clean. 1419/1419 vitest. lint clean on touched files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 17:20:13 +02:00

84 lines
3.3 KiB
JavaScript

import nextCoreWebVitals from 'eslint-config-next/core-web-vitals';
import prettier from 'eslint-config-prettier/flat';
const eslintConfig = [
...nextCoreWebVitals,
prettier,
{
// Scope the typescript-eslint rule overrides to TS/TSX files. Without
// the `files` filter, eslint flat-config attempts to apply these
// rules to every walked file (including root-level JS / mjs / json
// configs) and fails because the typescript-eslint plugin only
// registers itself for TS/TSX. Surfaced 2026-05-14 when CI's
// `pnpm lint` command ran across the whole repo root.
files: ['**/*.ts', '**/*.tsx'],
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
// React Compiler safety rules shipped with eslint-config-next@16 /
// react-hooks@7. Triage status (2026-05-13 sweep):
// purity, set-state-in-render, immutability, refs,
// set-state-in-effect — promoted to error after the cleanup
// sweep (Wave 3 of the 2026-05-12 audit). All hits migrated to
// either useQuery, render-phase derivation, key-based remount,
// or a justified eslint-disable for canonical setState-on-
// subscription patterns. New regressions block CI.
// incompatible-library — informational only ("Compiler
// skipped this file because of a non-Compiler-safe import").
// No action needed; silenced to keep `pnpm lint` output
// actionable.
'react-hooks/purity': 'error',
'react-hooks/set-state-in-render': 'error',
'react-hooks/immutability': 'error',
'react-hooks/refs': 'error',
'react-hooks/set-state-in-effect': 'error',
'react-hooks/incompatible-library': 'off',
},
},
{
// User-facing copy in src/components and src/app should never use
// em-dashes (—) in JSX text. The user reads em-dashes as a
// tell-tale "AI-generated" marker; we prefer periods, commas, or
// simple hyphens. Code comments / audit-log strings / templates
// outside these directories are exempt.
files: ['src/components/**/*.tsx', 'src/app/**/*.tsx'],
rules: {
'no-restricted-syntax': [
'warn',
{
selector: "JSXText[value=/\\u2014/]",
message:
'No em-dash in user-facing JSX text. Use period, comma, or hyphen instead.',
},
],
},
},
{
// Tests assert response shape via expect() — narrowing every
// `res.json()` to a structural type adds boilerplate without catching
// bugs. Allow `any` casts at JSON boundaries in test files. Also
// relax unused-vars to warn (destructured-but-unused helpers are
// common in setup/teardown patterns).
files: ['tests/**/*.ts', 'tests/**/*.tsx'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
},
},
{
ignores: [
'client-portal/**',
'next-env.d.ts',
// Agent worktree artifacts — not part of the canonical tree.
'.claude/**',
// Build output + Next generated types
'.next/**',
'dist/**',
// Other sub-projects with their own toolchains
'website/**',
],
},
];
export default eslintConfig;