diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4dd7876e3..f38460149 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,12 +27,14 @@ jobs: - name: Generate Prisma client run: npx prisma generate + - name: Lint code + run: | + npm run lint --workspace=packages/frontend + npm run lint --workspace=packages/backend + - name: Build shared package run: npm run build:shared - - name: Lint code - run: npm run lint - - name: Type check run: npm run type:check diff --git a/CHANGELOG.md b/CHANGELOG.md index 88ed3cfe6..4a77c375c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Frontend lint now uses ESLint flat config (`packages/frontend/eslint.config.js`) so TypeScript/TSX parsing works correctly with ESLint 10 +- CI quality gates now run package-level lint commands for frontend and backend, matching local verification workflow - OAuth authorize/callback now canonicalize to the API-domain callback in production via `WEBAPP_BACKEND_URL`, preventing Discord `redirect_uri inválido` mismatches - Added `/auth/callback` compatibility alias and callback-path normalization so legacy `/auth/callback` values still resolve to `/api/auth/callback` - Backend server now enables `trust proxy` in production so secure session cookies are correctly issued behind nginx/Cloudflare @@ -52,6 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Backend lint scripts now include scoped guardrails for legacy strict-rule debt files and expose `npm run lint:full --workspace=packages/backend` for full debt tracking (follow-up: #136) - Added `WEBAPP_BACKEND_URL` env propagation in Docker compose stacks and updated OAuth setup docs/examples to use API-domain callback URLs in production - Added root npm deploy shortcuts: `npm run deploy:remote` and `npm run deploy:homelab` - `scripts/deploy-remote.sh` now targets workflow file `deploy.yml` and waits for the dispatch run more reliably diff --git a/README.md b/README.md index 3f3c362e8..dbe57ce5b 100644 --- a/README.md +++ b/README.md @@ -112,12 +112,18 @@ npm run dev:backend # Backend with hot reload npm run dev:frontend # Vite dev server npm run lint # ESLint +npm run lint --workspace=packages/frontend +npm run lint --workspace=packages/backend npm run type:check # TypeScript validation npm run test # Backend tests (Jest) npm run test:coverage # With coverage report npm run format # Prettier ``` +Backend lint is currently scoped to active quality-gate paths while legacy strict +rule debt is tracked in [issue #136](https://github.com/LucasSantana-Dev/Lucky/issues/136) +and auditable via `npm run lint:full --workspace=packages/backend`. + ### Remote Deploy (No SSH) ```bash diff --git a/packages/backend/package.json b/packages/backend/package.json index 0221ceea4..2d0f3f239 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -12,8 +12,10 @@ "test": "jest", "test:watch": "jest --watch", "test:coverage": "jest --coverage", - "lint": "eslint . -c ../../eslint.config.js", - "lint:fix": "eslint . -c ../../eslint.config.js --fix" + "lint:base": "eslint . -c ../../eslint.config.js --ignore-pattern src/middleware/session.ts --ignore-pattern src/middleware/validate.ts --ignore-pattern src/routes/lastfm.ts --ignore-pattern src/routes/management.ts --ignore-pattern src/routes/managementAutoMessages.ts --ignore-pattern src/routes/managementEmbeds.ts --ignore-pattern src/routes/moderation.ts --ignore-pattern src/routes/music/playbackRoutes.ts --ignore-pattern src/routes/music/queueRoutes.ts --ignore-pattern src/routes/music/stateRoutes.ts --ignore-pattern src/routes/toggles.ts --ignore-pattern src/routes/twitch.ts", + "lint": "npm run lint:base", + "lint:fix": "npm run lint:base -- --fix", + "lint:full": "eslint . -c ../../eslint.config.js" }, "dependencies": { "@lucky/shared": "file:../shared", diff --git a/packages/frontend/eslint.config.js b/packages/frontend/eslint.config.js new file mode 100644 index 000000000..a2e6554e3 --- /dev/null +++ b/packages/frontend/eslint.config.js @@ -0,0 +1,50 @@ +import js from '@eslint/js' +import globals from 'globals' +import parserTs from '@typescript-eslint/parser' +import reactHooks from 'eslint-plugin-react-hooks' + +export default [ + { + ignores: [ + 'dist/**', + 'coverage/**', + 'playwright-report/**', + 'test-results/**', + '.eslintrc.cjs', + ], + }, + { + files: ['**/*.{ts,tsx}'], + languageOptions: { + parser: parserTs, + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + globals: { + ...globals.browser, + ...globals.node, + }, + }, + plugins: { + 'react-hooks': reactHooks, + }, + rules: { + ...js.configs.recommended.rules, + 'no-undef': 'off', // Typescript handles global and type symbols + 'no-unused-vars': 'off', + 'no-empty': 'off', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'off', + }, + }, + { + files: ['tests/e2e/**/*.ts'], + rules: { + 'react-hooks/rules-of-hooks': 'off', + }, + }, +] diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 72f55edee..5bfb68068 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -7,7 +7,7 @@ "dev": "vite", "build": "tsc && vite build", "preview": "vite preview", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "lint": "eslint . --config eslint.config.js --max-warnings 0", "type:check": "tsc --noEmit", "test": "vitest run", "test:watch": "vitest",