Created
March 10, 2026 18:39
-
-
Save vedovelli/743c83acb3c4924e481cff3f037e72bd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Você é um arquiteto de software especializado em React SPAs modernas. Preciso que você crie um | |
| plano completo de instalação e configuração de uma SPA com a seguinte arquitetura. O plano deve | |
| incluir: (1) comandos de instalação, (2) conteúdo de cada arquivo de configuração, (3) explicação | |
| da função de cada elemento, e (4) QA gates com Git hooks. | |
| --- | |
| ## STACK TÉCNICA | |
| ### Runtime & Build | |
| - **Node.js** ≥ 24 | |
| - **pnpm** como package manager (usar `packageManager` field no package.json) | |
| - **Vite 8** como bundler com Rolldown | |
| - **TypeScript 5.9+** com configuração strict máxima | |
| ### Framework & UI | |
| - **React 19** com React Compiler (babel-plugin-react-compiler) | |
| - **TanStack Router** com file-based routing e auto code splitting | |
| - **TanStack Query** para server state management | |
| - **TanStack Form** com **Valibot** para validação de formulários | |
| - **TanStack Table** para tabelas de dados | |
| - **TanStack Virtual** para virtualização de listas | |
| - **Tailwind CSS v4** via @tailwindcss/vite plugin | |
| - **CVA (cva@1.0.0-beta.4)** com **tailwind-merge** para component variants | |
| - **Base UI (@base-ui/react)** como primitivos de UI acessíveis | |
| - **Lucide React** para ícones | |
| - **Motion** para animações | |
| - **Sonner** para toast notifications | |
| - **cmdk** para command palette | |
| ### Utilitários | |
| - **ts-pattern** para pattern matching (OBRIGATÓRIO em vez de switch/if-else chains) | |
| - **Remeda** para utility functions funcionais | |
| - **date-fns** para manipulação de datas | |
| - **nanoid** para IDs únicos | |
| - **Immer** para imutabilidade | |
| - **Zustand** para estado global do cliente (mínimo, preferir TanStack Query) | |
| ### Testing (3 camadas) | |
| - **Vitest 4** como test runner com 3 projetos: | |
| - `unit`: testes unitários (`*.spec.ts(x)`) | |
| - `browser`: testes de componente com Playwright (`*.browser.spec.ts(x)`) | |
| - `integration`: testes de integração (`*.integration.spec.ts(x)`) | |
| - **Testing Library** (React + DOM + user-event) | |
| - **MSW 2** para mock de APIs em testes de integração | |
| - **jsdom** como ambiente padrão para testes unitários | |
| - **@vitest/browser-playwright** para browser tests | |
| - **@vitest/coverage-v8** para cobertura de código | |
| ### Linting & Formatting (alta velocidade) | |
| - **oxlint** como linter principal (Rust-based, extremamente rápido) | |
| - **oxfmt** como formatter (Rust-based) | |
| - **ESLint 10** apenas para regras que oxlint não cobre: | |
| - **eslint-plugin-boundaries** para enforcement de arquitetura modular | |
| - **typescript-eslint** para regras TypeScript avançadas | |
| - **eslint-plugin-oxlint** para desabilitar regras duplicadas | |
| - **markdownlint-cli2** para documentação | |
| ### DevTools (só em dev) | |
| - **@tanstack/devtools-vite** (injetado condicionalmente) | |
| - **@tanstack/react-devtools**, **react-query-devtools**, **react-form-devtools**, **react-router-devtools** | |
| - **react-scan** para detectar re-renders desnecessários | |
| ### Git Hooks | |
| - **Husky 9** para Git hooks | |
| --- | |
| ## ESTRUTURA DE DIRETÓRIOS | |
| ```text | |
| src/ | |
| ├── core/ # Utilitários core, API client, query keys, hooks compartilhados | |
| │ ├── api.ts # API client (fetch wrapper) | |
| │ ├── keys.ts # Query key factory (@lukemorales/query-key-factory) | |
| │ ├── queries.ts # Query options centralizadas | |
| │ ├── hooks.ts # Hooks reutilizáveis | |
| │ ├── i18n.ts # Provider e config de i18n | |
| │ ├── storage.ts # Utilitários de localStorage | |
| │ └── locales/ # Catálogos de tradução por idioma | |
| ├── ui/ # Design system (componentes reutilizáveis sem lógica de negócio) | |
| │ ├── Button.tsx | |
| │ ├── Form.tsx | |
| │ ├── variants.ts # Configuração CVA com tailwind-merge | |
| │ └── ... | |
| ├── pattern/ # Componentes compostos de nível mais alto (usam ui/) | |
| ├── layouts/ # Componentes de layout puros | |
| ├── features/ # Lógica de negócio por domínio | |
| │ └── {domain}/ | |
| │ ├── pages/ | |
| │ ├── components/ | |
| │ ├── hooks/ # Mutations do domínio | |
| │ ├── types/ | |
| │ └── schemas/ # Schemas Valibot | |
| ├── routes/ # File-based routing (TanStack Router) | |
| │ ├── __root.tsx | |
| │ ├── _auth/ # Grupo de rotas autenticadas | |
| │ └── ... | |
| ├── mocks/ # MSW handlers e setup | |
| │ ├── handlers/ | |
| │ └── setup-specs.ts | |
| └── main.tsx # Entry point | |
| ``` | |
| --- | |
| ## PATH ALIASES (tsconfig.json + vite resolve) | |
| ```json | |
| { | |
| "@*": ["./src/*"], | |
| "@core/*": ["./src/core/*"], | |
| "@features/*": ["./src/features/*"], | |
| "@layouts/*": ["./src/layouts/*"], | |
| "@pattern/*": ["./src/pattern/*"], | |
| "@routes/*": ["./src/routes/*"], | |
| "@ui/*": ["./src/ui/*"], | |
| "@mocks/*": ["./src/mocks/*"] | |
| } | |
| ``` | |
| --- | |
| ## TSCONFIG.JSON — CONFIGURAÇÃO STRICT MÁXIMA | |
| ```json | |
| { | |
| "include": ["**/*.ts", "**/*.tsx"], | |
| "exclude": ["node_modules", "dist", "build"], | |
| "compilerOptions": { | |
| "target": "ES2024", | |
| "module": "ESNext", | |
| "lib": ["ES2024", "DOM", "DOM.Iterable"], | |
| "jsx": "react-jsx", | |
| "types": ["vite/client", "vitest/globals", "msw"], | |
| "allowJs": true, | |
| "moduleResolution": "bundler", | |
| "esModuleInterop": true, | |
| "isolatedModules": true, | |
| "verbatimModuleSyntax": true, | |
| "allowImportingTsExtensions": true, | |
| "baseUrl": ".", | |
| "paths": { | |
| "@*": ["./src/*"], | |
| "@core/*": ["./src/core/*"], | |
| "@features/*": ["./src/features/*"], | |
| "@mocks/*": ["./src/mocks/*"], | |
| "@layouts/*": ["./src/layouts/*"], | |
| "@pattern/*": ["./src/pattern/*"], | |
| "@routes/*": ["./src/routes/*"], | |
| "@ui/*": ["./src/ui/*"] | |
| }, | |
| "sourceMap": true, | |
| "declaration": false, | |
| "skipLibCheck": true, | |
| "noEmit": true, | |
| "erasableSyntaxOnly": true, | |
| "strict": true, | |
| "noImplicitAny": true, | |
| "noImplicitOverride": true, | |
| "noImplicitReturns": true, | |
| "noPropertyAccessFromIndexSignature": true, | |
| "noUncheckedIndexedAccess": true, | |
| "noUncheckedSideEffectImports": true, | |
| "noUnusedLocals": true, | |
| "noUnusedParameters": true, | |
| "allowUnusedLabels": false, | |
| "allowUnreachableCode": false, | |
| "noFallthroughCasesInSwitch": true, | |
| "forceConsistentCasingInFileNames": true | |
| } | |
| } | |
| ``` | |
| --- | |
| ## OXLINT CONFIGURAÇÃO (.oxlintrc.json) | |
| Plugins habilitados: unicorn, typescript, oxc, react, react-perf, import, vitest | |
| Categorias em nível "error": correctness, perf, restriction, suspicious, pedantic | |
| Regras importantes: | |
| - `eslint/max-depth`: máximo 3 | |
| - `eslint/max-nested-callbacks`: máximo 3 | |
| - `import/consistent-type-specifier-style`: "prefer-inline" | |
| - `typescript/array-type`: "array" (não `Array<T>`) | |
| - Relaxar regras em arquivos de teste (`*.spec.ts`) | |
| Forneça o conteúdo completo do `.oxlintrc.json` com os seguintes overrides: | |
| - Arquivos gerais `**/*.{js,ts,tsx}`: permitir async/await, optional chaining, rest/spread | |
| - Arquivos TS `**/*.{ts,tsx}`: max-depth 3, max-nested-callbacks 3, inline type imports | |
| - Arquivos JSX `**/*.{jsx,tsx}`: permitir stateless multi-comp, permitir constant-only exports | |
| - Arquivos de teste `**/*.spec.{ts,tsx}`: relaxar regras de console, any, non-null assertion, etc. | |
| - Arquivos de mock `**/mocks/**`: permitir parent imports relativos | |
| --- | |
| ## ESLINT — APENAS PARA BOUNDARIES | |
| ESLint 10 configurado APENAS para eslint-plugin-boundaries que enforça regras de importação: | |
| | Camada | Pode importar de | | |
| | ---------- | ------------------------------------------------ | | |
| | core | core, mocks | | |
| | ui | ui | | |
| | layout | core, ui, layout | | |
| | pattern | core, ui, pattern | | |
| | features | core, ui, pattern, components, features | | |
| | components | core, ui, pattern, components, features | | |
| | routes | core, ui, pattern, layout, features, components | | |
| | mocks | core, mocks, features | | |
| Usar eslint-plugin-oxlint para desabilitar regras que oxlint já cobre. | |
| Forneça o conteúdo completo do `eslint.config.js` com: | |
| - Ignores para dist, routeTree.gen.ts, specs, mocks, locales | |
| - typescript-eslint recommended | |
| - boundaries plugin com todas as regras acima | |
| - oxlint integration | |
| --- | |
| ## VITE CONFIG | |
| Plugins (em ordem): | |
| 1. `@tanstack/devtools-vite` (apenas em dev) | |
| 2. `@tanstack/router-plugin/vite` com `autoCodeSplitting: true` | |
| 3. `@vitejs/plugin-react` com babel plugins: lingui-macro + react-compiler | |
| 4. `@tailwindcss/vite` | |
| 5. `@lingui/vite-plugin` | |
| 6. `rollup-license-plugin` | |
| 7. `rollup-plugin-visualizer` (condicional via env var) | |
| Build config: | |
| - Code splitting: separar react e react-dom em chunk "react" | |
| - Drop console e debugger em produção | |
| - Nomear chunks: `lazy-[name]-[hash].js` | |
| Feature flags via `define`: | |
| ```js | |
| __APP_VERSION__: git short SHA | |
| __APP_ENV__: mode (development/production) | |
| __FEATURE_FLAG_*__: boolean flags de env vars | |
| ``` | |
| Forneça o conteúdo completo do `vite.config.ts`. | |
| --- | |
| ## VITEST CONFIG | |
| 3 projetos de teste no mesmo config: | |
| - **unit**: `src/**/*.spec.ts(x)` excluindo integration e browser | |
| - **integration**: `src/**/*.integration.spec.ts(x)` com timeout 15s | |
| - **browser**: config separado (`vitest.browser.config.ts`) com Playwright | |
| Coverage excluindo: `*.d.ts`, types, specs, config, generated, routes, mocks, entry points | |
| Forneça o conteúdo completo do `vite.config.ts` (seção test) e do `vitest.browser.config.ts`. | |
| --- | |
| ## GIT HOOKS (Husky) | |
| ### Pre-commit | |
| ```bash | |
| pnpm fmt # oxfmt auto-format | |
| pnpm lint:docs:fix # markdownlint auto-fix | |
| ``` | |
| ### Pre-push | |
| ```bash | |
| pnpm lint # oxlint + ESLint (ambos devem passar) | |
| pnpm build # build de produção deve compilar | |
| ``` | |
| Forneça os arquivos `.husky/pre-commit` e `.husky/pre-push` completos com verificação de exit code. | |
| --- | |
| ## SCRIPTS DO PACKAGE.JSON | |
| ```json | |
| { | |
| "dev": "vite --port 3000", | |
| "build": "vite build", | |
| "serve": "vite preview", | |
| "check": "pnpm fmt && pnpm lint:oxlint:fix", | |
| "fmt": "oxfmt", | |
| "fmt:ci": "oxfmt --check", | |
| "lint": "oxlint && eslint", | |
| "lint:oxlint:fix": "oxlint --fix", | |
| "lint:ts": "tsc --noEmit", | |
| "lint:docs": "markdownlint-cli2 'docs/**/*.md'", | |
| "lint:docs:fix": "markdownlint-cli2 --fix 'docs/**/*.md'", | |
| "test": "pnpm test:unit && pnpm test:browser:headless && pnpm test:integration", | |
| "test:unit": "vitest run --project unit", | |
| "test:unit:watch": "vitest --project unit", | |
| "test:integration": "vitest run --project integration", | |
| "test:integration:watch": "vitest --project integration", | |
| "test:browser": "vitest --config=vitest.browser.config.ts", | |
| "test:browser:headless": "vitest run --config=vitest.browser.config.ts --browser.headless", | |
| "test:watch": "vitest", | |
| "i18n:extract": "lingui extract", | |
| "i18n:compile": "lingui compile", | |
| "prepare": "husky", | |
| "build:stats": "VITE_BUNDLE_STATS=true vite build", | |
| "bump": "pnpx npm-check-updates --upgrade && pnpm i && pnpm audit", | |
| "bump:check": "pnpx npm-check-updates" | |
| } | |
| ``` | |
| --- | |
| ## QA GATES (checklist obrigatório antes de considerar qualquer tarefa completa) | |
| ```text | |
| ✅ pnpm fmt → Formatting (oxfmt) | |
| ✅ pnpm lint → oxlint + ESLint boundaries | |
| ✅ pnpm lint:ts → TypeScript strict compilation | |
| ✅ pnpm test → Todas as 3 camadas de teste | |
| ✅ pnpm build → Build de produção | |
| ``` | |
| --- | |
| ## CONVENÇÕES OBRIGATÓRIAS | |
| 1. **`type` em vez de `interface`** para todas as definições de tipo | |
| 2. **Inline type imports**: `import { type Foo }` não `import type { Foo }` | |
| 3. **Named exports apenas** — sem default exports | |
| 4. **Sem barrel exports** (index.ts re-exportando) — imports diretos sempre | |
| 5. **ts-pattern** obrigatório para qualquer lógica condicional com 3+ branches, sempre com `.returnType<T>()` | |
| 6. **Sem useCallback/useMemo** para otimização — React Compiler cuida disso | |
| 7. **TanStack Query** para todo estado de servidor — nunca useEffect para fetch | |
| 8. **Path aliases** em todos os imports — nunca caminhos relativos com `../` | |
| ### ts-pattern — Padrão obrigatório | |
| ```typescript | |
| // SEMPRE usar .returnType<T>() para declarar o tipo de retorno | |
| const getStatus = (status: string) => { | |
| return match(status) | |
| .returnType<BadgeVariant>() | |
| .with("pending", () => "orange") | |
| .with("active", "granted", () => "success") | |
| .otherwise(() => "indigo") | |
| } | |
| // Usar .exhaustive() quando todos os casos devem ser cobertos | |
| // Usar .otherwise() quando há um fallback padrão | |
| ``` | |
| --- | |
| ## ENTREGÁVEL ESPERADO | |
| Gere o plano completo com: | |
| 1. Comandos de instalação agrupados por categoria (dependencies, devDependencies) | |
| 2. Conteúdo completo de cada arquivo de configuração (tsconfig, vite, oxlint, eslint, lingui, vitest) | |
| 3. Arquivo de setup de testes (`setup-specs.ts`) | |
| 4. Estrutura de diretórios com arquivos iniciais | |
| 5. Um componente exemplo usando a stack completa (route + query + form + ui com CVA) | |
| 6. Documentação em markdown explicando cada decisão arquitetural | |
| 7. Git hooks configurados e testáveis | |
| 8. Arquivo `vite-env.d.ts` com declarações de feature flags |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment