From d155da7e2b8e44b3a809ca10b741b70df7c2e5d3 Mon Sep 17 00:00:00 2001 From: chanwoo7 Date: Thu, 4 Jun 2026 04:04:28 +0900 Subject: [PATCH] =?UTF-8?q?refactor(lint):=20import/no-cycle=20=ED=99=9C?= =?UTF-8?q?=EC=84=B1=ED=99=94=20+=20common/global=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=EA=B2=BD=EA=B3=84=20ESLint=20=EA=B0=95=EC=A0=9C=20(P2-3=20?= =?UTF-8?q?=EC=BD=94=EC=96=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - import/no-cycle 활성화 (현재 위반 0건, 순환참조 회귀 방지) - no-restricted-imports 로 CLAUDE.md 의존성 방향 룰 강제: - common → features/global/prisma 의존 금지 (common → 무의존) - common/utils → DI(Injectable/Inject)·ConfigService·Prisma 의존 금지 (DI 없는 값 클래스 HttpException 류는 허용 — finding 5) - global → features/prisma 의존 금지 (global → common, config) - 신규 의존성 없음 (eslint-plugin-import 기존 설치). 기존 코드 위반 0건. --- eslint.config.mjs | 88 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/eslint.config.mjs b/eslint.config.mjs index ea71621..7c71a76 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -59,6 +59,8 @@ export default defineConfig( alphabetize: { order: 'asc', caseInsensitive: true }, }, ], + // 순환 참조 금지 (P2-3). 현재 위반 0건 — 회귀 방지용. + 'import/no-cycle': ['error', { ignoreExternal: true }], }, settings: { 'import/resolver': { @@ -67,6 +69,92 @@ export default defineConfig( }, }, + // 모듈 경계 강화 (P2-3) — CLAUDE.md 의존성 방향 룰을 ESLint 로 강제. + // common 은 features/global/prisma 에 의존 금지 (common → 무의존). + { + files: ['src/common/**/*.ts'], + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: [ + '@/features', + '@/features/**', + '@/global', + '@/global/**', + '@/prisma', + '@/prisma/**', + ], + message: + 'common 은 features/global/prisma 에 의존하면 안 됩니다 (common → 무의존).', + }, + ], + }, + ], + }, + }, + + // common/utils 는 순수 함수 — DI(Injectable/Inject)·ConfigService·Prisma 의존 금지. + // (DI 없는 값 클래스인 HttpException 류는 허용) + { + files: ['src/common/utils/**/*.ts'], + rules: { + 'no-restricted-imports': [ + 'error', + { + paths: [ + { + name: '@nestjs/common', + importNames: ['Injectable', 'Inject'], + message: + 'common/utils 는 DI-free 순수 함수만 (Injectable/Inject 금지).', + }, + { + name: '@nestjs/config', + message: + 'common/utils 는 ConfigService 등 런타임 서비스에 의존하면 안 됩니다.', + }, + ], + patterns: [ + { + group: [ + '@/features', + '@/features/**', + '@/global', + '@/global/**', + '@/prisma', + '@/prisma/**', + ], + message: + 'common 은 features/global/prisma 에 의존하면 안 됩니다 (common → 무의존).', + }, + ], + }, + ], + }, + }, + + // global 은 features/prisma 에 의존 금지 (global → common, config). + { + files: ['src/global/**/*.ts'], + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['@/features', '@/features/**', '@/prisma', '@/prisma/**'], + message: + 'global 은 features/prisma 에 의존하면 안 됩니다 (global → common, config).', + }, + ], + }, + ], + }, + }, + // 테스트 파일에 대한 특별 규칙 { files: ['**/*.spec.ts', '**/*.test.ts'],