- BOM 항목 추가/수정/삭제 시 섹션탭 즉시 반영 - 섹션 복제 시 UI 즉시 업데이트 (null vs undefined 이슈 해결) - 항목 수정 기능 추가 (useTemplateManagement) - 실시간 동기화 문서 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
8.9 KiB
코드 품질 및 일관성 검사 결과
검사 일자: 2025-11-07 검사자: Claude Code
📊 전체 요약
프로젝트: Next.js 15 + TypeScript + next-intl (다국어 지원) 언어: TypeScript/TSX 린트: ESLint 9 (Next.js config) 타입 체크: ✅ 통과 (에러 없음) 린트 상태: ⚠️ 12개 문제 (9 errors, 3 warnings)
🔴 Critical Issues (즉시 수정 필요)
1. src/lib/api/client.ts - Type 정의 누락 (5 errors)
문제:
RequestInit,Response,fetch,URL등 글로벌 타입이 인식되지 않음- 브라우저/Node.js 환경 타입 정의 누락
수정 방법:
// 파일 상단에 타입 선언 추가
/// <reference lib="dom" />
// 또는 tsconfig.json에서 lib 설정 확인
"lib": ["dom", "dom.iterable", "esnext"]
위치:
- src/lib/api/client.ts:50 -
token변수 선언 (case block) - src/lib/api/client.ts:70 -
RequestInit타입 미정의 - src/lib/api/client.ts:78 -
RequestInit타입 미정의 - src/lib/api/client.ts:88 -
fetch미정의 - src/lib/api/client.ts:139 -
Response타입 미정의
2. src/middleware.ts - 미사용 함수/변수 (2 errors)
문제 1: isProtectedRoute 함수 정의되었으나 사용되지 않음
// Line 161
function isProtectedRoute(pathname: string): boolean {
return AUTH_CONFIG.protectedRoutes.some(route =>
pathname.startsWith(route)
);
}
문제 2: URL 글로벌 타입 인식 안됨
// Line 231, 247
new URL(AUTH_CONFIG.redirects.afterLogin, request.url)
new URL('/login', request.url)
수정 방법:
isProtectedRoute함수 앞에_추가 (unused 규칙 준수) 또는 삭제- tsconfig.json lib 설정 확인
위치:
- src/middleware.ts:161 -
isProtectedRoute미사용 - src/middleware.ts:231 -
URL타입 미정의 - src/middleware.ts:247 -
URL타입 미정의
3. src/components/auth/LoginPage.tsx (2 issues)
Error: 미사용 변수 response
// Line 43
const response = await sanctumClient.login({
user_id: userId,
user_pwd: password,
});
// response 변수가 사용되지 않음
Warning: any 타입 사용
// Line 55
} catch (err: any) {
// any 대신 구체적인 타입 필요
}
수정 방법:
// Option 1: response 사용하지 않으면 제거
await sanctumClient.login({ user_id: userId, user_pwd: password });
// Option 2: 타입 개선
} catch (err: unknown) {
const error = err as { status?: number; message?: string };
// ...
}
위치:
- src/components/auth/LoginPage.tsx:43 -
response미사용 - src/components/auth/LoginPage.tsx:55 -
any타입 사용
🟡 Warnings (개선 권장)
4. src/lib/api/auth/token-storage.ts - any 타입 사용 (2 warnings)
위치: Line 30, 38
// Line 30, 38
} catch (e: any) {
// any 대신 unknown 사용 권장
}
개선 방법:
} catch (e: unknown) {
console.error('Token parse error:', e);
}
위치:
- src/lib/api/auth/token-storage.ts:30 -
any타입 사용 - src/lib/api/auth/token-storage.ts:38 -
any타입 사용
✅ 긍정적인 부분
-
TypeScript 타입 체크 통과 - 타입 시스템이 올바르게 작동 중
-
명확한 디렉토리 구조:
src/ ├── app/[locale]/ # Next.js 15 App Router ├── components/ # 재사용 컴포넌트 │ ├── ui/ # UI 컴포넌트 (shadcn/ui) │ └── auth/ # 인증 관련 ├── contexts/ # React Context ├── lib/ # 유틸리티/API │ ├── api/ │ │ └── auth/ # 인증 API 로직 │ └── validations/ # Zod 스키마 └── i18n/ # 다국어 설정 -
Zod 검증 사용 - 런타임 타입 안전성 확보
-
일관된 명명 규칙:
- 컴포넌트: PascalCase (
LoginPage.tsx) - 유틸: camelCase (
auth-config.ts) - 상수: UPPER_SNAKE_CASE (
AUTH_CONFIG)
- 컴포넌트: PascalCase (
🎯 스타일 일관성
✅ 긍정적 패턴
- Import 순서: 외부 라이브러리 → 내부 모듈 → 컴포넌트 순서 일관됨
- "use client" 지시자: 클라이언트 컴포넌트에 올바르게 적용
- 경로 별칭:
@/*패턴 일관되게 사용 - 함수형 컴포넌트: 모든 컴포넌트가 함수형으로 작성됨
⚠️ 개선 필요
-
하드코딩된 한글 텍스트:
// SignupPage.tsx:148 <p className="text-xs text-muted-foreground">회원가입</p> // 다국어 지원 누락 (LoginPage는 useTranslations 사용) -
인라인 스타일 사용:
// LoginPage.tsx:79 <div style={{ backgroundColor: '#3B82F6' }}> // Tailwind 클래스 사용 권장: bg-blue-500 -
주석 처리된 코드:
// SignupPage.tsx:448-521 // 대량의 주석 처리된 플랜 선택 UI (73줄) // 제거 또는 별도 파일로 분리 권장
🔧 추천 개선 사항
우선순위 1 (High) - 즉시 수정
- ✅ tsconfig.json lib 설정 확인 (DOM 타입 포함)
- ✅ any 타입 제거 →
unknown또는 구체적 타입으로 변경 - ✅ 미사용 변수 제거 (response, isProtectedRoute)
우선순위 2 (Medium) - 단기 개선
-
하드코딩 텍스트 다국어화:
// messages/ko.json에 추가 { "signup": { "title": "회원가입", "companyInfo": "회사 정보를 입력해주세요" } } -
인라인 스타일 → Tailwind 클래스:
// Before <div style={{ backgroundColor: '#3B82F6' }}> // After <div className="bg-blue-500"> -
주석 처리된 코드 정리:
- 필요 시 별도 브랜치로 보존
- 불필요하면 삭제
우선순위 3 (Low) - 장기 개선
-
에러 타입 정의:
// lib/api/types.ts export interface ApiError { status: number; message: string; errors?: Record<string, string[]>; code?: string; } -
ESLint 규칙 커스터마이징:
// .eslintrc.json 생성 { "extends": "next/core-web-vitals", "rules": { "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }] } }
📈 메트릭스
| 항목 | 상태 | 점수 |
|---|---|---|
| TypeScript 타입 체크 | ✅ 통과 | 100% |
| ESLint 오류 | ⚠️ 9개 | 65% |
| 코드 구조 | ✅ 우수 | 90% |
| 명명 규칙 | ✅ 일관됨 | 95% |
| 다국어 적용 | ⚠️ 부분적 | 75% |
| 스타일 일관성 | ✅ 양호 | 85% |
전체 코드 품질: 82/100 (양호)
🚀 빠른 수정 가이드
# 1. tsconfig.json 확인 (이미 올바르게 설정됨)
cat tsconfig.json | grep -A5 "lib"
# 2. ESLint 오류 확인
npm run lint
# 3. 자동 수정 가능한 항목 수정
npm run lint -- --fix
# 4. TypeScript 타입 체크
npx tsc --noEmit
📋 상세 에러 목록
ESLint Errors (9개)
-
src/components/auth/LoginPage.tsx:43:13
responseis assigned a value but never used- Rule:
@typescript-eslint/no-unused-vars
-
src/lib/api/client.ts:50:9
- Unexpected lexical declaration in case block
- Rule:
no-case-declarations
-
src/lib/api/client.ts:70:15
RequestInitis not defined- Rule:
no-undef
-
src/lib/api/client.ts:78:19
RequestInitis not defined- Rule:
no-undef
-
src/lib/api/client.ts:88:28
fetchis not defined- Rule:
no-undef
-
src/lib/api/client.ts:139:39
Responseis not defined- Rule:
no-undef
-
src/middleware.ts:161:10
isProtectedRouteis defined but never used- Rule:
@typescript-eslint/no-unused-vars
-
src/middleware.ts:231:40
URLis not defined- Rule:
no-undef
-
src/middleware.ts:247:21
URLis not defined- Rule:
no-undef
ESLint Warnings (3개)
-
src/components/auth/LoginPage.tsx:55:19
- Unexpected any. Specify a different type
- Rule:
@typescript-eslint/no-explicit-any
-
src/lib/api/auth/token-storage.ts:30:17
- Unexpected any. Specify a different type
- Rule:
@typescript-eslint/no-explicit-any
-
src/lib/api/auth/token-storage.ts:38:14
- Unexpected any. Specify a different type
- Rule:
@typescript-eslint/no-explicit-any
💡 결론
프로젝트는 전반적으로 양호한 품질을 유지하고 있으나, 위 9개 ESLint 오류를 수정하면 더욱 견고한 코드베이스가 될 것입니다.
주요 개선 포인트:
- 타입 정의 완성도 향상 (no-undef 에러 해결)
- any 타입 제거로 타입 안전성 강화
- 미사용 변수/함수 정리로 코드 가독성 향상
- 다국어 지원 일관성 개선
- 스타일 일관성 유지 (인라인 스타일 제거)