fromis_9/docs/code-review.md
caadiq 1c9b30b783 에러 유틸리티 함수를 모든 라우트에 적용
utils/error.js에 정의된 헬퍼 함수들(badRequest, unauthorized, notFound,
conflict, serverError)을 전체 라우트 파일에 적용하여 에러 응답 처리 일관성 확보

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 11:24:42 +09:00

4.5 KiB

코드 리뷰 결과

작성일: 2025-01-23 범위: app 폴더 제외한 backend, frontend, docker 설정

잘 된 점

백엔드 구조

  • Fastify 플러그인 패턴을 적절히 활용
  • 서비스/라우트 계층 분리가 명확함
  • withTransaction 유틸리티로 트랜잭션 처리 일관성 확보
  • N+1 쿼리 최적화 적용 (getAlbumsWithTracks)

캐싱

  • Redis 캐시 유틸리티(utils/cache.js)가 깔끔하게 구현됨
  • TTL 상수화로 관리 용이
  • 캐시 키 생성 헬퍼 함수 제공

프론트엔드

  • API 클라이언트의 에러 처리와 인증 토큰 관리가 잘 구현됨
  • PC/Mobile 분리 구조 적용
  • Zustand를 활용한 상태 관리

개선 필요 사항

1. 보안 (우선순위: 높음) 완료

1.1 JWT Secret 하드코딩 완료

파일: backend/src/config/index.js

기본값을 제거하고 서버 시작 시 필수 환경변수 검증 로직을 추가함.

2. Docker 설정 (우선순위: 중간)

2.1 Meilisearch 버전

현재 v1.6 사용 중. 최신 버전으로 업데이트 권장. latest로 변경 완료 (v1.33.1)

2.2 리소스 제한 없음

redis:
  # ... 기존 설정
  deploy:
    resources:
      limits:
        memory: 256M

meilisearch:
  # ... 기존 설정
  deploy:
    resources:
      limits:
        memory: 512M

2.3 프로덕션 Dockerfile

현재 개발용 Dockerfile만 활성화됨. 배포 시 주석 해제 또는 multi-stage build 적용 필요.


3. 백엔드 코드 (우선순위: 중간)

3.1 에러 유틸리티 미활용 완료

모든 라우트 파일에 에러 유틸리티(utils/error.js) 적용 완료.

  • badRequest, unauthorized, notFound, conflict, serverError 함수 사용

3.2 SELECT * 사용

파일: services/album.js:16-19

// 현재
'SELECT * FROM albums WHERE folder_name = ? OR title = ?'

// 권장
'SELECT id, title, folder_name, album_type, album_type_short, release_date, cover_original_url, cover_medium_url, cover_thumb_url, description FROM albums WHERE folder_name = ? OR title = ?'

3.3 앨범 삭제 시 관련 데이터 누락 완료

파일: services/album.js

앨범 삭제 시 관련 테이블(photos, teasers, photo_members) 및 S3 파일도 함께 삭제하도록 개선됨.

4. 프론트엔드 코드 (우선순위: 낮음)

4.1 App.jsx 라우트 분리

현재 194줄로 너무 큼. 라우트 분리 권장.

src/
├── routes/
│   ├── index.jsx      # 라우트 통합
│   ├── pc.jsx         # PC 라우트
│   ├── mobile.jsx     # Mobile 라우트
│   └── admin.jsx      # Admin 라우트
└── App.jsx            # 간소화

4.2 레거시 export 정리

파일: api/client.js:147-155

// 삭제 대상 (마이그레이션 완료 후)
export const get = api.get;
export const post = api.post;
export const put = api.put;
export const del = api.del;
export const authGet = authApi.get;
export const authPost = authApi.post;
export const authPut = authApi.put;
export const authDel = authApi.del;

4.3 개발 도구 미설정

파일: frontend/package.json

{
  "scripts": {
    "lint": "eslint src --ext .js,.jsx",
    "lint:fix": "eslint src --ext .js,.jsx --fix",
    "test": "vitest",
    "test:coverage": "vitest --coverage"
  },
  "devDependencies": {
    "eslint": "^8.57.0",
    "eslint-plugin-react": "^7.34.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "vitest": "^1.6.0"
  }
}

5. 문서 (우선순위: 낮음)

5.1 migration.md 파일 누락

CLAUDE.mdREADME.md에서 docs/migration.md를 참조하지만 실제 파일이 없음.

5.2 환경별 설정 문서화

개발/스테이징/프로덕션 환경별 설정 가이드 필요.


개선 우선순위 요약

순위 항목 파일 상태
1 JWT Secret 기본값 제거 config/index.js 완료
2 앨범 삭제 시 관련 테이블 정리 services/album.js 완료
3 에러 유틸리티 통일 라우트 파일들 완료
4 App.jsx 라우트 분리 App.jsx 미완료
5 레거시 export 정리 api/client.js 미완료
6 Meilisearch 버전 업데이트 docker-compose.yml 완료
7 테스트 코드 작성 전체 미완료

참고

  • 이 문서는 app 폴더를 제외한 코드 리뷰 결과입니다.
  • 보안 관련 항목은 가능한 빨리 적용을 권장합니다.