Skip to content

feat(user): GraphQL Input 전수 class-validator DTO 도입#98

Merged
chanwoo7 merged 4 commits into
developfrom
refactor/user-graphql-input-dto
May 23, 2026
Merged

feat(user): GraphQL Input 전수 class-validator DTO 도입#98
chanwoo7 merged 4 commits into
developfrom
refactor/user-graphql-input-dto

Conversation

@chanwoo7
Copy link
Copy Markdown
Member

Summary

  • User 도메인의 모든 GraphQL Input 13종을 class + class-validator DTO 로 전환
    • 페이지네이션 6종 (UserPaginationInput 베이스 상속)
    • 프로필 4종 (CompleteOnboarding / UpdateMyProfile / UpdateMyProfileImage / CreateProfileImageUploadUrl)
    • 리뷰 작성 3종 (WriteReview / WriteReviewMedia / CreateReviewMediaUploadUrl)
  • 별점 0.5 단위 검증을 위한 IsRatingValid 커스텀 validator 추가
  • 7개 User Resolver 가 신규 DTO class 를 @Args 타입으로 사용. ValidationPipe 가 정식 검증
  • 4개 User Service 의 수동 검증 코드 제거 (offset/limit, rating, content 길이, profileImageUrl 길이 등). 도메인 invariant(미디어 카운트·필드 미수정 등)는 service 에 유지
  • 구 interface 정의가 있던 types/user-input.type.ts, user-order-input.type.ts, user-review-input.type.ts 삭제. MyWishlistInput-output 파일에서 분리해 정상 위치로 이동

배경 / Plan 연결

FE 영향

정상 입력 시 응답은 동일합니다. 잘못된 형식에 대해서는:

  • 기존: 일부는 Service BadRequestException 으로 단건 응답, 일부는 무검증 통과 후 다른 에러
  • 변경: ValidationPipe 가 일관 처리. GraphQL 에러 extensions.code === BAD_REQUEST 로 표준화. 다중 위반은 다건 응답 가능

룰별 메시지 본문은 기존 한국어 문구를 유지하도록 데코레이터 message 옵션에 명시했습니다.

Test plan

  • 로컬 yarn lint 통과
  • 로컬 yarn test 996/996 통과 (이전 950 + 신규 46)
  • 로컬 yarn dto:check 통과 (19/46 DTO 매핑, errors 0)
  • npx tsc --noEmit 통과
  • CI: lint / type-check / test:cov 통과
  • CI: codecov/patch target 80% 통과

chanwoo7 added 2 commits May 24, 2026 03:15
A-2 검증 전략 P0-3 단계 3 (User Input 전수).

- UserPaginationInput 베이스 + 6종 페이지네이션 DTO (Orders/Reviews/
  Wishlist/Notifications/SearchHistories/RecentViewedProducts)
- 프로필 DTO 4종 (CompleteOnboarding / UpdateMyProfile /
  UpdateMyProfileImage / CreateProfileImageUploadUrl). 닉네임 길이·
  정규식, 전화번호 형식, 생년월일 범위 등 SDL 로 표현 불가한 룰 적용
- 리뷰 작성 DTO 3종 (WriteReview / WriteReviewMedia /
  CreateReviewMediaUploadUrl). 별점 0.5 단위 검증을 위해
  IsRatingValid 커스텀 validator 추가
- 단위 테스트 동반 (validate() 결과 직접 검증)
A-2 검증 전략 P0-3 단계 3 (User Input 전수) — 적용편.

- User Resolver 7종이 신규 DTO class 를 @Args 타입으로 사용.
  GraphQL ValidationPipe 가 정식 검증 수행.
- user-{order,wishlist,recent-view,review}.service: offset/limit 수동
  검증 제거 (DTO 가 처리)
- user-review.service: rating · content 길이 수동 검증 제거 (DTO 가
  처리). validateMedia(이미지 10 / 영상 1) invariant 만 잔존.
- user-profile.service: profileImageUrl 의 길이/공백 수동 검증 제거
  (DTO 가 처리). Name 빈 문자열 reject 는 service 에 방어 코드로 유지.
- types/user-{input,order-input,review-input}.type.ts 삭제 (interface
  →  class 마이그레이션 완료, 더 이상 사용처 없음)
- user-wishlist-output.type.ts 에 잘못 위치해 있던 MyWishlistInput 제거
- spec 정리: DTO 레이어로 이전된 검증 케이스(15+) 제거. service spec
  은 도메인 분기에 집중.

FE 영향: 정상 입력은 응답 동일. 잘못된 형식은 ValidationPipe 가
GraphQL BAD_REQUEST 로 일관 응답 (메시지 본문은 기존 한국어 그대로
유지하도록 룰별 message 옵션 명시).
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7b0093c4-9c5f-41c8-b4ac-0c28fc024721

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/user-graphql-input-dto

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 23, 2026

Coverage report

St.
Category Percentage Covered / Total
🟢 Statements 96.82% 3016/3115
🟢 Branches 86.1% 1685/1957
🟢 Functions 93.49% 632/676
🟢 Lines 97.13% 2745/2826

Test suite run success

1002 tests passing in 97 suites.

Report generated by 🧪jest coverage report action from 82b92ec

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 71b0915f98

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +28 to +30
@IsString()
@Length(20, 1000)
content!: string;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Trim review content before enforcing length constraints

WriteReviewInput.content is validated with @Length(20, 1000) on the raw string, but UserReviewService.writeReview persists input.content.trim(). This means inputs like 'a'.repeat(10) + ' ' (or all-whitespace 20 chars) now pass DTO validation and are saved as content shorter than 20 (or empty), which violates the previous business rule and allows effectively blank/too-short reviews into production data.

Useful? React with 👍 / 👎.

chanwoo7 added 2 commits May 24, 2026 03:29
complete-onboarding / update-my-profile / update-my-profile-image
DTO 의 @Transform 콜백에서 string 이 아닌 입력(null · 숫자) 분기가
미검사로 남아 branches 임계 86% 미달(85.94%) 원인. 다음 3 케이스 추가:

- name 이 null → IsOptional 흡수 후 통과 (Transform 비-string 경로)
- name 이 숫자 → IsString 거절 (Transform 통과 후 validator 가 처리)
- profileImageUrl 이 null/숫자 → IsString 거절

DTO 입력 파일 전체 branches 100% 달성. 전체 86.1% 로 임계 회복.
push 전에 lint / tsc / dto:check / test:cov(커버리지 임계 포함) 를
일괄 검증해 CI 사이클 소모를 사전 차단한다.

- package.json scripts: validate = lint && tsc && dto:check && test:cov
- .husky/pre-push: yarn validate 호출
- README: 명령 표에 validate / dto:check 추가
- 긴급 우회: git push --no-verify
- testcontainers 의존성상 Docker 가 동작 중이어야 함
@codecov
Copy link
Copy Markdown

codecov Bot commented May 23, 2026

Codecov Report

❌ Patch coverage is 97.97980% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...s/user/resolvers/user-profile-mutation.resolver.ts 80.00% 0 Missing and 1 partial ⚠️
.../user/resolvers/user-recent-view-query.resolver.ts 50.00% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@chanwoo7 chanwoo7 merged commit ca09fcc into develop May 23, 2026
9 checks passed
@chanwoo7 chanwoo7 deleted the refactor/user-graphql-input-dto branch May 23, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant