Skip to content

대규모 백엔드 리팩토링 진행#249

Merged
kubrickcode merged 12 commits intomainfrom
develop/shlee/refactor
Nov 26, 2025
Merged

대규모 백엔드 리팩토링 진행#249
kubrickcode merged 12 commits intomainfrom
develop/shlee/refactor

Conversation

@kubrickcode
Copy link
Owner

No description provided.

백엔드 모듈 구조 개선 작업:
- content, exchange-rate, item, user 모듈을 도메인별 서브디렉토리로 재구성
- Resolver에서 비즈니스 로직을 Service Layer로 분리 (9개 서비스 생성)
- DTO, Object, Resolver, Service 파일을 각 도메인 디렉토리로 정리
- Resolver 메서드 순서 규칙 추가 (constructor → @query@mutation → @ResolveField)
- ESLint 설정 추가하여 Resolver 메서드 정렬 자동화

주요 변경사항:
- content 모듈: 8개 서브디렉토리로 분리 (category, content, duration, group, item, reward, see-more-reward, wage)
- item 모듈: auction-item, market-item 서브디렉토리로 분리
- 새로 생성된 서비스: ContentService, GroupService, ItemService, RewardService, SeeMoreRewardService, GoldExchangeRateService, AuctionItemService, MarketItemService
- Resolver LOC 평균 50-70% 감소
- 전체 테스트 통과 (101/101)

fix #224
- InputType 클래스명을 Action-First 패턴으로 변경 (예: ContentCreateInput → CreateContentInput)
- Boolean 필드에서 이중 "is" 접두사 제거 (includeIsBound → includeBound, includeIsSeeMore → includeSeeMore)
- 모든 nullable 필드에 설명 추가

fix #225
전역 ValidationPipe를 적용하고 모든 InputType에 class-validator 데코레이터를 추가하여 입력 데이터 검증을 자동화

- class-validator 및 class-transformer 의존성 추가
- 25개 InputType에 타입, 범위, 구조 검증 데코레이터 적용
- GraphQL 호환 ValidationPipe 설정 (optional 필드 처리)
- 비즈니스 규칙 검증 자동화 (레벨 1-1700, 시간 형식, ID 양수 등)

fix #226
- OrderByArg에 class-validator 데코레이터 추가 (@IsString, @isin)
- contentList query에 orderBy 파라미터 적용 (OrderByArg[] 배열 타입)
- ContentService에 buildOrderBy 메서드 구현 (다중 필드 정렬 지원)
- 기본 정렬 로직 유지 (contentCategory > level > id)

fix #227
모든 Mutation Result 타입에서 중복되던 ok 필드 정의를 MutationResult 기반 클래스로 통합하여 일관성 확보

- common/dto/mutation-result.dto.ts 생성 (ok 필드만 포함)
- 9개 Result 타입이 MutationResult 상속하도록 변경

fix #229
Service 계층이 GraphQL Context에 직접 의존하여 테스트 작성이 어렵고 재사용성이 낮았던 문제 해결

- UserContentService, UserGoldExchangeRateService에서 @Inject(CONTEXT) 제거
- userId를 명시적 파라미터로 받도록 메서드 시그니처 변경
- Resolver에서 @currentuser() 데코레이터로 userId 추출 후 Service에 전달
- ContentWageService, ItemService 등 downstream services도 userId 전파하도록 업데이트
- ContextType 정의 파일 제거

이를 통해 Service 계층의 테스트 가능성과 재사용성이 향상되고, GraphQL 이외의 컨텍스트(REST API, CLI 등)에서도 Service를 사용할 수 있게 됨

fix #230
CommonModule이 Config와 Prisma 두 가지 역할을 담당하여 단일 책임 원칙 위반
- CommonModule: PrismaService export/provider 제거, Config 전담
- AuthModule: PrismaModule 직접 import 추가
- 기존 다른 모듈들은 이미 PrismaModule 직접 import 중
any 타입과 as 타입 단언을 제거하고 제네릭 헬퍼 함수로 중복 코드 제거
- any[] → Prisma.XxxGetPayload 타입으로 교체
- as number[] → spread 연산자로 교체
- 4개 private 메서드 → 2개 제네릭 헬퍼 함수로 통합
- types, utils 파일 분리로 관심사 분리

fix #232
- auth.controller logout: callback 기반에서 Promise로 변경하여 에러 전파
- console.service seed: try-catch 에러 삼킴 제거로 CLI 실패 코드 반환

fix #233
- UserContentService: getUserOverride 제네릭 헬퍼로 4개 메서드의 반복 패턴 통합
- UserContentService: getItemPrice 중복 DB 쿼리 제거 (2회→1회)
- ContentWageService: calculateContentWageData로 80% 중복 로직 통합
- ContentWageService: Promise.all로 병렬 처리 개선
- 공통 상수 DEFAULT_CONTENT_ORDER_BY 추출 (ContentService, GroupService)
- 매직 넘버 SECONDS_PER_HOUR 상수화

fix #235
lodash 의존성을 es-toolkit으로 전환하여 번들 크기를 줄이고 타입 안전성을 개선

주요 변경사항:
- lodash(70KB) 제거 → es-toolkit(~16KB) 도입
- keyBy, groupBy, orderBy, sum, sumBy 함수 활용
- 순차 async for-of 루프를 Promise.all + sum으로 병렬화하여 성능 개선
- any 타입을 제네릭으로 대체하여 타입 안전성 강화
- if-else 조건 분기를 nullish coalescing으로 간소화

fix #247
@kubrickcode
Copy link
Owner Author

/gemini review

@gemini-code-assist
Copy link

Summary of Changes

Hello @kubrickcode, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 백엔드 아키텍처, 특히 content 모듈과 GraphQL API에 대한 광범위한 리팩토링을 수행합니다. 주요 목표는 기존의 거대한 리졸버와 서비스를 더 작고, 도메인에 특화된 단위로 분할하여 코드 구성, 유지보수성 및 테스트 용이성을 향상시키는 것입니다. 또한, class-validator를 통한 GraphQL DTO에 대한 강력한 입력 유효성 검사를 도입하고, 새로운 ESLint 규칙으로 코드 스타일을 강화하며, 보다 일반화된 DataLoader 구현으로 데이터 로딩 메커니즘을 개선합니다.

Highlights

  • 백엔드 모듈 재구성: 주로 content 모듈에 대한 대규모 리팩토링이 진행되어, 기존의 단일 쿼리/뮤테이션 파일들이 더 작고 목적에 맞는 서비스 및 리졸버로 분리되고 하위 디렉토리로 재구성되었습니다. 이는 코드의 응집도를 높이고 유지보수성을 향상시킵니다.
  • GraphQL 스키마 및 DTO 개선: schema.graphql 파일이 대폭 변경되어 입력 타입 이름이 변경되고(예: ContentCreateInput -> CreateContentInput), 필드 설명이 추가되었으며, 새로운 커스텀 시급 계산 관련 타입들이 도입되었습니다. 또한, class-validatorclass-transformer를 활용한 GraphQL DTO 유효성 검사 로직이 추가되어 데이터 무결성을 강화했습니다.
  • 의존성 및 코드 품질 관리: package.jsonpnpm-lock.yamlclass-transformer, class-validator, es-toolkit과 같은 새로운 의존성이 추가되었고, lodash가 제거되었습니다. eslint.config.js에는 리졸버 파일을 무시하고 NestJS GraphQL 리졸버에 특화된 perfectionist 정렬 규칙을 적용하는 설정이 추가되어 코드 스타일을 일관되게 유지합니다.
  • DataLoader 및 사용자 컨텍스트 처리 개선: DataLoaderService가 일반적인 createUniqueLoadercreateManyLoader 유틸리티를 사용하도록 리팩토링되어 재사용성과 코드 중복을 줄였습니다. 또한, UserContentServiceUserGoldExchangeRateService에서 CONTEXT 주입 대신 userId를 명시적으로 전달하도록 변경하여 테스트 용이성과 코드 명확성을 높였습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이 PR은 백엔드 코드베이스에 대한 대규모 리팩토링을 포함하고 있으며, 전반적인 코드 품질, 구조, 유지보수성을 크게 향상시켰습니다. 주요 개선 사항은 다음과 같습니다:

  • 도메인 중심의 모듈 및 파일 구조로 재구성하여 NestJS 프레임워크 가이드라인을 잘 따르고 있습니다.
  • GraphQL 스키마의 타입 네이밍을 일관성 있게 변경하고, 필드에 대한 설명을 추가하여 API 명세가 매우 명확해졌습니다.
  • 서비스 로직을 GraphQL 컨텍스트에서 분리하여 테스트 용이성과 재사용성을 높였습니다.
  • class-validator를 도입하여 DTO에 대한 유효성 검사를 강화했습니다.
  • lodashes-toolkit으로 대체하고, 중복 코드를 줄이는 등 전반적인 코드 클린업이 이루어졌습니다.
  • 새로운 ESLint 규칙을 추가하여 코드 스타일 가이드를 강제하는 점도 훌륭합니다.

전체적으로 매우 인상적인 리팩토링이며, 프로젝트의 장기적인 건강에 큰 도움이 될 것입니다. 한 가지 스타일 가이드 관련 제안 사항을 리뷰 코멘트로 남겼으니 확인 부탁드립니다.

@kubrickcode kubrickcode merged commit 35c88c7 into main Nov 26, 2025
7 checks passed
@kubrickcode kubrickcode deleted the develop/shlee/refactor branch November 26, 2025 10:05
@kubrickcode
Copy link
Owner Author

🎉 This PR is included in version 0.6.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant