From 87572f5b1f68f786a0c7c4d46190bcd1593c0552 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Tue, 13 Jan 2026 12:49:23 +0100 Subject: [PATCH] website refactor --- apps/website/.eslintrc.json | 63 +++++++++++++++++++-- apps/website/eslint-rules/index.js | 3 + apps/website/eslint-rules/no-index-files.js | 45 +++++++++++++++ 3 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 apps/website/eslint-rules/no-index-files.js diff --git a/apps/website/.eslintrc.json b/apps/website/.eslintrc.json index db6c26f94..647647e15 100644 --- a/apps/website/.eslintrc.json +++ b/apps/website/.eslintrc.json @@ -88,7 +88,8 @@ "gridpilot-rules/template-no-global-objects": "error", "gridpilot-rules/template-no-mutation-props": "error", "gridpilot-rules/template-no-unsafe-html": "error", - "gridpilot-rules/component-no-data-manipulation": "error" + "gridpilot-rules/component-no-data-manipulation": "error", + "gridpilot-rules/no-hardcoded-routes": "error" } }, { @@ -144,7 +145,9 @@ "gridpilot-rules/page-query-must-use-builders": "error", "gridpilot-rules/single-export-per-file": "error", "gridpilot-rules/filename-matches-export": "error", - "gridpilot-rules/clean-error-handling": "error" + "gridpilot-rules/clean-error-handling": "error", + "gridpilot-rules/no-hardcoded-routes": "error", + "gridpilot-rules/no-hardcoded-search-params": "error" } }, { @@ -217,6 +220,48 @@ "gridpilot-rules/lib-no-next-imports": "error" } }, + { + "files": [ + "app/**/*.tsx", + "app/**/*.ts" + ], + "rules": { + "gridpilot-rules/no-raw-html-in-app": "error", + "gridpilot-rules/no-nextjs-imports-in-ui": "error", + "gridpilot-rules/no-hardcoded-routes": "error" + } + }, + { + "files": [ + "app/**/actions.ts", + "app/**/actions/*.ts" + ], + "rules": { + "gridpilot-rules/no-hardcoded-routes": "error" + } + }, + { + "files": [ + "ui/**/*.tsx", + "ui/**/*.ts" + ], + "rules": { + "gridpilot-rules/ui-element-purity": "error", + "gridpilot-rules/no-nextjs-imports-in-ui": "error", + "gridpilot-rules/component-classification": "warn" + } + }, + { + "files": [ + "components/**/*.tsx", + "components/**/*.ts" + ], + "rules": { + "gridpilot-rules/no-nextjs-imports-in-ui": "error", + "gridpilot-rules/component-classification": "warn", + "gridpilot-rules/no-hardcoded-routes": "error" + } + }, { "files": [ "lib/services/**/*.ts" @@ -226,7 +271,16 @@ "gridpilot-rules/services-must-be-marked": "error", "gridpilot-rules/services-must-be-pure": "error", "gridpilot-rules/services-no-external-api": "error", - "gridpilot-rules/services-no-instantiation": "error" + "gridpilot-rules/services-implement-contract": "error", + "gridpilot-rules/no-hardcoded-routes": "error" + } + }, + { + "files": [ + "lib/mutations/**/*.ts" + ], + "rules": { + "gridpilot-rules/no-hardcoded-routes": "error" } } ], @@ -265,7 +319,8 @@ "react-hooks/rules-of-hooks": "error", "react/no-unescaped-entities": "error", "unused-imports/no-unused-imports": "off", - "unused-imports/no-unused-vars": "off" + "unused-imports/no-unused-vars": "off", + "gridpilot-rules/no-index-files": "error" }, "settings": { "boundaries/elements": [ diff --git a/apps/website/eslint-rules/index.js b/apps/website/eslint-rules/index.js index 7ed952df3..7b75d7356 100644 --- a/apps/website/eslint-rules/index.js +++ b/apps/website/eslint-rules/index.js @@ -148,6 +148,9 @@ module.exports = { // Route Configuration Rules 'no-hardcoded-routes': require('./no-hardcoded-routes'), 'no-hardcoded-search-params': require('./no-hardcoded-search-params'), + + // Architecture Rules + 'no-index-files': require('./no-index-files'), }, // Configurations for different use cases diff --git a/apps/website/eslint-rules/no-index-files.js b/apps/website/eslint-rules/no-index-files.js new file mode 100644 index 000000000..52252cf40 --- /dev/null +++ b/apps/website/eslint-rules/no-index-files.js @@ -0,0 +1,45 @@ +/** + * @file no-index-files.js + * Bans index.ts/index.tsx files - they hide dependencies and make code harder to navigate + */ + +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'Ban index.ts/index.tsx files - use explicit imports instead', + category: 'Best Practices', + recommended: true, + }, + fixable: null, + schema: [], + messages: { + indexFile: 'Index files are banned. Use explicit imports and barrel exports. Example: Instead of "import { foo } from "./", use "import { foo } from "./foo" and export from "./foo" explicitly.', + }, + }, + + create(context) { + const filename = context.getFilename(); + + // Check if file is named index.ts or index.tsx + const isIndexFile = /(^|\/|\\)index\.(ts|tsx)$/.test(filename); + + // Allow index files in root directories that are required by framework + const allowedPaths = [ + 'apps/website/app/index.ts', // Next.js app router entry + 'apps/website/pages/index.tsx', // Next.js pages router entry + 'apps/website/src/index.ts', // Common entry point + 'apps/website/index.ts', // Root entry + ]; + + if (isIndexFile && !allowedPaths.some(path => filename.endsWith(path))) { + context.report({ + node: null, // Report on the file level + loc: { line: 1, column: 0 }, + messageId: 'indexFile', + }); + } + + return {}; + }, +};