From 2121b86a8e4c0fb077d70deb78b20611d2f336f4 Mon Sep 17 00:00:00 2001 From: Arthur Bassi Date: Fri, 12 Jun 2026 11:40:01 -0300 Subject: [PATCH] chore: add eslint, prettier, husky and commitlint tooling --- .cursor/rules/seahaven-admin.mdc | 52 +++++++++++++++++++++++++++ .husky/commit-msg | 1 + .husky/pre-commit | 1 + .prettierignore | 13 +++++++ .prettierrc | 15 ++++++++ commitlint.config.js | 1 + eslint.config.js | 62 ++++++++++++++++++++++++++++++++ 7 files changed, 145 insertions(+) create mode 100644 .cursor/rules/seahaven-admin.mdc create mode 100644 .husky/commit-msg create mode 100644 .husky/pre-commit create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 commitlint.config.js create mode 100644 eslint.config.js diff --git a/.cursor/rules/seahaven-admin.mdc b/.cursor/rules/seahaven-admin.mdc new file mode 100644 index 00000000..fcf3114f --- /dev/null +++ b/.cursor/rules/seahaven-admin.mdc @@ -0,0 +1,52 @@ +--- +description: SeaHaven Admin — arquitetura IrisLoan, convenções de rebuild seletivo +alwaysApply: true +--- + +# SeaHaven Admin — convenções IrisLoan + +## Stack + +- Vite SPA + React Router 7, TypeScript strict, Tailwind v4 + MUI +- HTTP: Ky com `credentials: "include"` (cookies httpOnly) +- Server state: TanStack Query; forms: React Hook Form + Zod +- **Não usar** em código novo: Next.js, Redux, axios, `apiUtil.js`, `tokenUtility.js` + +## Estrutura alvo (`src/`) + +``` +api/ domain// app/ infra/query-key/ lib/ hooks/ +components/ui|common|layout/ config/menu.ts providers/ main.tsx +``` + +- Alias `@/` para imports; arquivos novos em **kebab-case** (`use-debounce.ts`, `query-key.ts`) +- `pages/` é **somente referência** de endpoints e regras de negócio — deletar após entrega em `domain/` + `app/` + +## HTTP e auth + +- Centralizar paths em `api/api-paths.ts` e respostas em `api/handle-api-response.ts` +- Auth via AuthProvider + cookies; não criar slices Redux para sessão + +## Estado e dados + +- Cache e mutations: React Query + `infra/query-key/query-key.ts` +- Defaults do client em `lib/query/query-client.ts` + +## Forms e UI + +- Schemas Zod em `domain//schemas/`; views finas em `app/` +- Tailwind utilitário + componentes MUI; **não** importar `site.css` em código novo + +## Fluxo ao implementar feature + +1. Consultar legado em `pages//` (endpoints, campos, regras) +2. Criar `domain//` (schemas, hooks, use-cases) +3. View fina em `app/` + rota em `app/routes.tsx` +4. Deletar `pages//` quando a feature nova estiver pronta + +## Tooling + +- ESLint strict só em `.ts/.tsx` da arquitetura nova; legado em `pages/` ignorado +- Commits: Conventional Commits (`feat(scope): subject`) + +Referência: `docs/ARCHITECTURE_PLAN.md` diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100644 index 00000000..a78cc751 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1 @@ +npx commitlint --edit $1 diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..2312dc58 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..27f10fea --- /dev/null +++ b/.prettierignore @@ -0,0 +1,13 @@ +dist +build +node_modules +coverage +package-lock.json +*.tsbuildinfo + +# Legacy — format incrementally when touched (lint-staged) +src/pages/** +src/**/*.js +src/**/*.jsx +src/**/*.css +!src/styles/globals.css \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..2661d464 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,15 @@ +{ + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "printWidth": 100, + "tabWidth": 2, + "overrides": [ + { + "files": "*.mdc", + "options": { + "parser": "markdown" + } + } + ] +} diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 00000000..fa584fb6 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1 @@ +export default { extends: ["@commitlint/config-conventional"] }; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..c4ea4a39 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,62 @@ +import js from "@eslint/js"; +import eslintConfigPrettier from "eslint-config-prettier"; +import pluginReactHooks from "eslint-plugin-react-hooks"; +import pluginReactRefresh from "eslint-plugin-react-refresh"; +import globals from "globals"; +import tseslint from "typescript-eslint"; + +const legacyIgnores = [ + "src/pages/**", + "src/app/store.js", + "src/app/slices/**", + "src/lib/queryClient.js", + "src/hooks/**", + "src/components/**", + "src/constants/**", + "src/layouts/**", + "src/**/*.js", + "src/**/*.jsx", +]; + +export default tseslint.config( + { + ignores: ["dist/**", "build/**", "node_modules/**", "coverage/**", ...legacyIgnores], + }, + js.configs.recommended, + ...tseslint.configs.recommended, + eslintConfigPrettier, + { + files: [ + "src/{api,domain,app,lib,providers,infra,config,hooks,components/auth}/**/*.{ts,tsx}", + "src/**/*.{ts,tsx}", + "vite.config.ts", + ], + languageOptions: { + ecmaVersion: "latest", + sourceType: "module", + globals: globals.browser, + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + plugins: { + "react-hooks": pluginReactHooks, + "react-refresh": pluginReactRefresh, + }, + rules: { + ...pluginReactHooks.configs.recommended.rules, + "react-hooks/set-state-in-effect": "off", + "react-hooks/exhaustive-deps": "warn", + "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], + "@typescript-eslint/no-explicit-any": "warn", + }, + }, + { + files: ["vite.config.ts", "scripts/**/*.{js,mjs}"], + languageOptions: { + globals: globals.node, + }, + }, +);