{ "extends": [ "next/core-web-vitals", "plugin:import/recommended", "plugin:import/typescript" ], "ignorePatterns": [ "lib/types/generated/**", "**/*.test.ts", "**/*.test.tsx", "eslint-rules/**" ], "overrides": [ { "files": [ "app/**/page.*", "app/**/layout.*", "app/**/loading.*", "app/**/error.*", "app/**/not-found.*", "app/**/global-error.*", "app/**/template.*", "app/**/default.*" ], "rules": { "import/no-default-export": "error", "no-restricted-syntax": "error" } }, { "files": [ "lib/presenters/**/*.ts", "lib/presenters/**/*.tsx", "lib/view-models/**/*.ts", "lib/view-models/**/*.tsx" ], "rules": { "gridpilot-rules/presenter-contract": "error" } }, { "files": [ "lib/builders/view-models/*.ts", "lib/builders/view-models/*.tsx" ], "rules": { "gridpilot-rules/view-model-builder-contract": "error", "gridpilot-rules/view-model-builder-implements": "error" } }, { "files": [ "lib/builders/view-data/*.ts", "lib/builders/view-data/*.tsx" ], "rules": { "gridpilot-rules/filename-matches-export": "error", "gridpilot-rules/single-export-per-file": "error", "gridpilot-rules/view-data-builder-contract": "error", "gridpilot-rules/view-data-builder-implements": "error", "gridpilot-rules/view-data-builder-imports": "error" } }, { "files": [ "lib/builders/**/*.ts", "lib/builders/**/*.tsx" ], "rules": { "gridpilot-rules/no-page-dtos-directory": "error" } }, { "files": [ "lib/mutations/**/*.ts" ], "rules": { "gridpilot-rules/clean-error-handling": "error", "gridpilot-rules/filename-service-match": "error", "gridpilot-rules/mutation-contract": "error", "gridpilot-rules/mutation-must-map-errors": "error", "gridpilot-rules/mutation-must-use-builders": "error" } }, { "files": [ "templates/**/*.tsx" ], "rules": { "gridpilot-rules/component-no-data-manipulation": "error", "gridpilot-rules/no-hardcoded-routes": "error", "gridpilot-rules/no-raw-html-in-app": "error", "gridpilot-rules/template-no-async-render": "error", "gridpilot-rules/template-no-direct-mutations": "error", "gridpilot-rules/template-no-external-state": "error", "gridpilot-rules/template-no-global-objects": "error", "gridpilot-rules/template-no-mutation-props": "error", "gridpilot-rules/template-no-side-effects": "error", "gridpilot-rules/template-no-unsafe-html": "error" } }, { "files": [ "components/**/*.tsx" ], "rules": { "gridpilot-rules/component-no-data-manipulation": "error", "gridpilot-rules/no-raw-html-in-app": "error" } }, { "files": [ "app/**/page.tsx", "app/**/layout.tsx" ], "rules": { "@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-unused-vars": "error", "gridpilot-rules/component-classification": "error", "gridpilot-rules/no-console": "error", "gridpilot-rules/no-direct-process-env": "error", "gridpilot-rules/no-hardcoded-routes": "error", "gridpilot-rules/no-hardcoded-search-params": "error", "gridpilot-rules/no-index-files": "error", "gridpilot-rules/no-next-cookies-in-pages": "error", "gridpilot-rules/no-raw-html-in-app": "error", "gridpilot-rules/rsc-no-container-manager": "error", "gridpilot-rules/rsc-no-container-manager-calls": "error", "gridpilot-rules/rsc-no-di": "error", "gridpilot-rules/rsc-no-display-objects": "error", "gridpilot-rules/rsc-no-intl": "error", "gridpilot-rules/rsc-no-local-helpers": "error", "gridpilot-rules/rsc-no-object-construction": "error", "gridpilot-rules/rsc-no-page-data-fetcher": "error", "gridpilot-rules/rsc-no-presenters": "error", "gridpilot-rules/rsc-no-sorting-filtering": "error", "gridpilot-rules/rsc-no-unsafe-services": "error", "gridpilot-rules/rsc-no-view-models": "error", "import/no-default-export": "error", "no-restricted-syntax": "error", "react-hooks/exhaustive-deps": "error", "react-hooks/rules-of-hooks": "error", "react/no-unescaped-entities": "error" } }, { "files": [ "lib/services/**/*.ts", "lib/page-queries/**/*.ts", "lib/mutations/**/*.ts", "middleware.ts", "lib/mutations/auth/types/*.ts" ], "rules": { "gridpilot-rules/clean-error-handling": "error", "gridpilot-rules/no-direct-process-env": "error" } }, { "files": [ "lib/display-objects/**/*.ts", "lib/display-objects/**/*.tsx" ], "rules": { "gridpilot-rules/display-no-business-logic": "error", "gridpilot-rules/display-no-domain-models": "error", "gridpilot-rules/filename-display-match": "error", "gridpilot-rules/model-no-domain-in-display": "error" } }, { "files": [ "lib/page-queries/**/*.ts" ], "rules": { "gridpilot-rules/clean-error-handling": "error", "gridpilot-rules/filename-matches-export": "error", "gridpilot-rules/no-hardcoded-routes": "error", "gridpilot-rules/no-hardcoded-search-params": "error", "gridpilot-rules/page-query-contract": "error", "gridpilot-rules/page-query-execute": "error", "gridpilot-rules/page-query-filename": "error", "gridpilot-rules/page-query-must-use-builders": "error", "gridpilot-rules/page-query-no-null-returns": "error", "gridpilot-rules/page-query-return-type": "error", "gridpilot-rules/single-export-per-file": "error" } }, { "files": [ "templates/**/*.ts", "templates/**/*.tsx" ], "rules": { "gridpilot-rules/view-data-location": "error" } }, { "files": [ "lib/view-data/**/*.ts", "lib/view-data/**/*.tsx" ], "rules": { "gridpilot-rules/view-data-implements": "error" } }, { "files": [ "lib/view-models/**/*.ts", "lib/view-models/**/*.tsx" ], "rules": { "gridpilot-rules/view-model-implements": "error", "gridpilot-rules/view-model-taxonomy": "error" } }, { "files": [ "lib/services/**/*.ts" ], "rules": { "gridpilot-rules/filename-service-match": "error", "gridpilot-rules/services-implement-contract": "error", "gridpilot-rules/services-must-be-pure": "error", "gridpilot-rules/services-must-return-result": "error", "gridpilot-rules/services-no-external-api": "error" } }, { "files": [ "app/**/*.tsx", "app/**/*.ts" ], "rules": { "gridpilot-rules/client-only-must-have-directive": "error", "gridpilot-rules/client-only-no-server-code": "error", "gridpilot-rules/no-use-mutation-in-client": "error", "gridpilot-rules/server-actions-interface": "error", "gridpilot-rules/server-actions-must-use-mutations": "error", "gridpilot-rules/server-actions-return-result": "error" } }, { "files": [ "lib/write-boundaries/**/*.ts" ], "rules": { "gridpilot-rules/write-boundary-must-use-repository": "error", "gridpilot-rules/write-boundary-no-direct-mutations": "error" } }, { "files": [ "lib/domain/**/*.ts", "lib/models/**/*.ts" ], "rules": { "gridpilot-rules/model-no-display-in-domain": "error" } }, { "files": [ "lib/**/*.ts", "lib/**/*.tsx" ], "rules": { "gridpilot-rules/lib-no-next-imports": "error" } }, { "files": [ "app/onboarding/**/*.ts", "app/onboarding/**/*.tsx", "lib/auth/RouteGuard.ts", "lib/auth/AuthFlowRouter.ts", "middleware.ts" ], "rules": { "gridpilot-rules/no-console": "error" } }, { "files": [ "app/**/*.tsx", "app/**/*.ts" ], "rules": { "gridpilot-rules/component-classification": "error", "gridpilot-rules/no-hardcoded-routes": "error", "gridpilot-rules/no-nextjs-imports-in-ui": "error", "gridpilot-rules/no-raw-html-in-app": "error" } }, { "files": [ "app/**/actions.ts", "app/**/actions/*.ts" ], "rules": { "gridpilot-rules/no-hardcoded-routes": "error", "gridpilot-rules/server-actions-interface": "error", "gridpilot-rules/server-actions-return-result": "error" } }, { "files": [ "ui/**/*.tsx", "ui/**/*.ts" ], "rules": { "gridpilot-rules/component-classification": "error", "gridpilot-rules/no-nextjs-imports-in-ui": "error", "gridpilot-rules/ui-element-purity": "error" } }, { "files": [ "components/**/*.tsx", "components/**/*.ts" ], "rules": { "gridpilot-rules/component-classification": "error", "gridpilot-rules/no-hardcoded-routes": "error", "gridpilot-rules/no-nextjs-imports-in-ui": "error", "gridpilot-rules/no-raw-html-in-app": "error", "no-restricted-imports": "error" } }, { "files": [ "components/mockups/**/*.tsx" ], "rules": { "gridpilot-rules/no-raw-html-in-app": "error" } }, { "files": [ "lib/services/**/*.ts" ], "rules": { "gridpilot-rules/no-hardcoded-routes": "error", "gridpilot-rules/service-function-format": "error", "gridpilot-rules/services-implement-contract": "error", "gridpilot-rules/services-must-be-pure": "error", "gridpilot-rules/services-no-external-api": "error" } }, { "files": [ "lib/mutations/**/*.ts" ], "rules": { "gridpilot-rules/no-hardcoded-routes": "error" } } ], "plugins": [ "boundaries", "import", "@typescript-eslint", "unused-imports", "gridpilot-rules" ], "root": true, "rules": { "@next/next/no-img-element": "error", "@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-unused-vars": [ "error", { "argsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_", "varsIgnorePattern": "^_" } ], "boundaries/element-types": [ 2, { "default": "disallow", "rules": [ { "allow": [ "website" ], "from": [ "website" ] } ] } ], "gridpilot-rules/no-index-files": "error", "import/no-default-export": "error", "import/no-named-as-default-member": "error", "no-restricted-syntax": "error", "react-hooks/exhaustive-deps": "error", "react-hooks/rules-of-hooks": "error", "react/no-unescaped-entities": "error", "unused-imports/no-unused-imports": "error", "unused-imports/no-unused-vars": "error" }, "settings": { "boundaries/elements": [ { "pattern": [ "**/*" ], "type": "website" } ], "import/resolver": { "typescript": {} } } }