fromis_9/docs/refactoring.md
caadiq a62cf7142b refactor(backend): 21단계 검색 페이징 최적화 - 중복 slice 제거
- services/meilisearch: 내부 SEARCH_LIMIT(1000)과 페이징 파라미터 분리
- services/meilisearch: 기본 limit을 100으로 변경
- routes/schedules: handleSearch에서 중복 slice 제거, 직접 offset/limit 전달

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:04:07 +09:00

9.6 KiB

Backend Refactoring Plan

백엔드 코드 품질 개선을 위한 리팩토링 계획서

완료된 작업

1단계: 설정 통합 (config 정리) 완료

  • 카테고리 ID 상수 통합 (CATEGORY_IDS)

수정된 파일:

  • src/config/index.js - CATEGORY_IDS 상수 추가
  • src/routes/admin/youtube.js - config에서 import
  • src/routes/admin/x.js - config에서 import
  • src/routes/schedules/index.js - 하드코딩된 2, 3, 8 → 상수로 변경

2단계: N+1 쿼리 최적화 완료

  • 앨범 목록 조회 시 트랙 한 번에 조회로 변경
  • 스케줄 멤버 조회 - 이미 최적화됨 (확인 완료)

수정된 파일:

  • src/routes/albums/index.js - GET /api/albums에서 트랙 조회 최적화

3단계: 서비스 레이어 분리 완료

  • src/services/album.js 생성
  • src/services/schedule.js 생성
  • 라우트에서 서비스 호출로 변경

4단계: 에러 처리 통일 완료

  • 에러 응답 유틸리티 생성 (src/utils/error.js)
  • reply.status()reply.code() 통일

5단계: 중복 코드 제거 완료

  • 스케줄러 상태 업데이트 로직 통합 (handleSyncResult 함수)
  • youtube/index.js 하드코딩된 카테고리 ID → config 사용

추가 작업 목록

6단계: 매직 넘버 config 이동 완료

  • 이미지 크기/품질 설정 (services/image.js)
  • X 기본 사용자명 (routes/admin/x.js, routes/schedules/index.js, services/schedule.js)
  • Meilisearch 최소 점수 (services/meilisearch/index.js)

수정된 파일:

  • src/config/index.js - image, x, meilisearch.minScore 추가
  • src/services/image.js - config에서 이미지 크기/품질 참조
  • src/services/meilisearch/index.js - config에서 minScore 참조
  • src/routes/admin/x.js - config에서 defaultUsername 참조
  • src/routes/schedules/index.js - config에서 defaultUsername 참조
  • src/services/schedule.js - config에서 defaultUsername 참조

7단계: 순차 쿼리 → 병렬 처리 완료

  • services/album.js getAlbumDetails - tracks, teasers, photos 병렬 조회
  • routes/albums/photos.js - 멤버 INSERT 배치 처리

수정된 파일:

  • src/services/album.js - Promise.all로 3개 쿼리 병렬 실행
  • src/routes/albums/photos.js - for loop → VALUES ? 배치 INSERT

8단계: meilisearch 카테고리 ID 상수화 완료

  • services/meilisearch/index.js - 하드코딩된 2, 3 → CATEGORY_IDS 사용

수정된 파일:

  • src/services/meilisearch/index.js - CATEGORY_IDS.YOUTUBE, CATEGORY_IDS.X 사용

9단계: 응답 형식 통일 완료

  • routes/schedules/suggestions.js - {success, message}{error} 또는 {message} 형식으로 통일

수정된 파일:

  • src/routes/schedules/suggestions.js - 응답 형식 통일

10단계: 로거 통일 완료

  • src/utils/logger.js 생성
  • 모든 console.error/log → logger 또는 fastify.log 사용

수정된 파일:

  • src/utils/logger.js - 로거 유틸리티 생성 (createLogger)
  • src/services/image.js - logger 사용
  • src/services/meilisearch/index.js - logger 사용
  • src/services/suggestions/index.js - logger 사용
  • src/services/suggestions/morpheme.js - logger 사용
  • src/routes/albums/photos.js - fastify.log 사용
  • src/routes/schedules/index.js - fastify.log 사용
  • src/routes/schedules/suggestions.js - fastify.log 사용

11단계: 대형 핸들러 분리 완료

  • routes/albums/index.js POST/PUT/DELETE → 서비스 함수로 분리
  • routes/albums/photos.js POST - SSE 스트리밍으로 인해 분리 보류

수정된 파일:

  • src/services/album.js - createAlbum, updateAlbum, deleteAlbum, insertTracks 추가
  • src/routes/albums/index.js - 서비스 함수 호출로 변경 (80줄 감소)

12단계: 트랜잭션 헬퍼 추상화 완료

  • src/utils/transaction.js 생성 - withTransaction 함수
  • 반복되는 트랜잭션 패턴 추상화 적용

수정된 파일:

  • src/utils/transaction.js - 트랜잭션 헬퍼 유틸리티 생성
  • src/services/album.js - createAlbum, updateAlbum, deleteAlbum에 withTransaction 적용
  • src/routes/albums/photos.js - DELETE 핸들러에 withTransaction 적용
  • src/routes/albums/teasers.js - DELETE 핸들러에 withTransaction 적용

13단계: Swagger/OpenAPI 문서화 개선 완료

  • src/schemas/index.js 생성 - 공통 스키마 정의
  • src/app.js - Swagger components에 스키마 등록
  • 태그 추가 (admin/youtube, admin/x, admin/bots)

수정된 파일:

  • src/schemas/index.js - JSON Schema 정의 (Error, Success, Album, Schedule 등)
  • src/app.js - Swagger 설정에 스키마 컴포넌트 추가

14단계: 입력 검증 강화 (JSON Schema) 완료

  • 라우트에 params, querystring, body, response 스키마 추가
  • 상세 description 추가로 API 문서 품질 향상

수정된 파일:

  • src/routes/albums/index.js - GET/POST/PUT/DELETE 스키마 추가
  • src/routes/schedules/index.js - 검색/조회/삭제 스키마 추가
  • src/routes/admin/youtube.js - 영상 조회/일정 등록/수정 스키마 추가
  • src/routes/admin/x.js - 게시글 조회/일정 등록 스키마 추가
  • src/routes/admin/bots.js - 봇 관리 스키마 추가

15단계: 스키마 파일 분리 완료

  • 단일 스키마 파일을 도메인별로 분리
  • Re-export 패턴으로 기존 import 호환성 유지

생성된 파일:

  • src/schemas/common.js - 공통 스키마 (errorResponse, successResponse, paginationQuery, idParam)
  • src/schemas/album.js - 앨범 관련 스키마
  • src/schemas/schedule.js - 일정 관련 스키마
  • src/schemas/admin.js - 관리자 API 스키마 (YouTube, X)
  • src/schemas/member.js - 멤버 스키마
  • src/schemas/auth.js - 인증 스키마
  • src/schemas/index.js - 모든 스키마 re-export

16단계: 에러 처리 일관성 완료

  • 모든 라우트에 try/catch 적용
  • 에러 응답 패턴 통일

수정된 파일:

  • src/routes/schedules/index.js - 모든 핸들러에 try/catch 추가

17단계: 중복 코드 제거 (멤버 조회) 완료

  • 멤버 조회 로직을 서비스로 분리
  • 앨범 존재 확인 로직 통합

생성된 파일:

  • src/services/member.js - getAllMembers, getMemberByName, getMemberBasicByName

수정된 파일:

  • src/services/album.js - getAlbumByName, getAlbumById 추가
  • src/routes/members/index.js - 서비스 호출로 변경 (약 50줄 감소)
  • src/routes/albums/index.js - 서비스 호출로 변경

18단계: 이미지 처리 최적화 완료

  • 이미지 메타데이터 중복 처리 제거
  • processImage에서 메타데이터 함께 반환
  • sharp 인스턴스 재사용 (clone() 사용)

수정된 파일:

  • src/services/image.js - processImage 함수 개선, uploadAlbumPhoto 중복 조회 제거

19단계: Redis 캐시 확대 완료

  • 캐시 유틸리티 생성 (src/utils/cache.js)
  • 멤버 목록 캐싱 (10분 TTL)
  • 멤버 수정 시 캐시 무효화
  • 일정 상세 조회 - X 프로필이 별도 캐시 사용하므로 보류

생성된 파일:

  • src/utils/cache.js - getOrSet, invalidate, invalidatePattern, cacheKeys

수정된 파일:

  • src/services/member.js - getAllMembers에 캐시 적용, invalidateMemberCache 추가
  • src/routes/members/index.js - Redis 캐시 사용, 수정 시 캐시 무효화

20단계: 서비스 레이어 확대 완료

  • schedules 라우트의 DB 쿼리를 서비스로 분리
  • 일관된 서비스 패턴 적용

수정된 파일:

  • src/services/schedule.js - getCategories, getScheduleDetail 함수 추가
  • src/routes/schedules/index.js - 서비스 호출로 변경 (약 70줄 감소)

21단계: 검색 페이징 최적화 완료

  • 라우트에서 중복 slice 제거
  • 내부 검색 한도와 페이징 파라미터 분리
  • searchSchedules에 offset/limit 직접 전달

수정된 파일:

  • src/services/meilisearch/index.js - SEARCH_LIMIT 분리, 기본 limit 100으로 변경
  • src/routes/schedules/index.js - handleSearch에서 중복 slice 제거

진행 상황

단계 작업 상태
1단계 설정 통합 완료
2단계 N+1 쿼리 최적화 완료
3단계 서비스 레이어 분리 완료
4단계 에러 처리 통일 완료
5단계 중복 코드 제거 완료
6단계 매직 넘버 config 이동 완료
7단계 순차→병렬 쿼리 완료
8단계 meilisearch 카테고리 ID 완료
9단계 응답 형식 통일 완료
10단계 로거 통일 완료
11단계 대형 핸들러 분리 완료
12단계 트랜잭션 헬퍼 추상화 완료
13단계 Swagger/OpenAPI 문서화 완료
14단계 입력 검증 강화 (JSON Schema) 완료
15단계 스키마 파일 분리 완료
16단계 에러 처리 일관성 완료
17단계 중복 코드 제거 (멤버 조회) 완료
18단계 이미지 처리 최적화 완료
19단계 Redis 캐시 확대 완료
20단계 서비스 레이어 확대 완료
21단계 검색 페이징 최적화 완료

참고사항

  • 각 단계별로 커밋 후 다음 단계 진행
  • 기존 API 응답 형식은 유지
  • 프론트엔드 수정 불필요하도록 진행
  • API 문서는 /docs에서 확인 가능 (Scalar API Reference)