import tseslint from 'typescript-eslint'; import angular from 'angular-eslint'; /** * ESLint now owns only the rules that are NOT dependency-graph shaped: no `any`, and * template accessibility. The architecture's **boundary** rules — bounded-context * direction (herregistratie → registratie → shared, auth/brief/beheer → shared; shared * depends on nothing), `domain/` framework-freedom, `contracts/` purity, `ui ↛ * infrastructure`, and ApiClient confinement — moved to **dependency-cruiser** (WP-38, * `.dependency-cruiser.base.js` + one thin per-app config, WP-67): one declarative source * (per app) that also emits the architecture graph * (`npm run dep:graph`) and is enforced by `npm run dep:check` (in CI). That replaced the * per-context `no-restricted-imports` blocks that had to be hand-copied (and had left * `herregistratie` uncovered). */ export default [ // A disable directive that no rule needs any more is a lint failure, repo-wide (no // `files` key, so this applies everywhere — ESLint 9 flat config rule). This forces // every later file split in the readable-codebase arc (RD-02) to delete its own // `max-lines` exemption instead of leaving it as permanent debt. { linterOptions: { reportUnusedDisableDirectives: 'error' }, }, { ignores: [ 'dist/**', 'node_modules/**', 'storybook-static*/**', '.angular/**', 'coverage/**', 'backend/**', // Generated client — owns its own /* eslint-disable */ header. 'libs/shared/src/infrastructure/api-client.ts', ], }, { files: ['{apps,libs}/**/*.ts'], languageOptions: { parser: tseslint.parser, parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, }, plugins: { '@typescript-eslint': tseslint.plugin }, rules: { '@typescript-eslint/no-explicit-any': 'error' }, // This repo has no .html files — every template is inline. This processor // extracts each component's template string into a virtual `*.html` file, // which the template-a11y block below (`files: ['{apps,libs}/**/*.html']`) then lints. processor: angular.processInlineTemplates, }, // Template a11y (WP-17): the official angular-eslint accessibility bundle // (alt-text, label-has-associated-control, click/mouse-events-have-key-events, // interactive-supports-focus, valid-aria, no-autofocus, and more) linting the // virtual `.html` files the processor above extracts from inline templates. ...angular.configs.templateAccessibility.map((c) => ({ ...c, files: ['{apps,libs}/**/*.html'], })), // The dashboard refactor proved a page can be 42 lines. This rule holds the rest of // the app to that budget: 250 is reachable, not a style-guide default. The glob must // include `section` and `step` — the dashboard refactor's own file kinds — or every // file this arc creates escapes the guard. Each exemption below names its reason and // the ticket that removes it, so the list is a dated to-do, not silent debt. { files: ['{apps,libs}/**/*.{page,component,section,step}.ts'], rules: { 'max-lines': ['error', { max: 250, skipBlankLines: true, skipComments: true }], }, }, ];