Refactor/query optimization readability #244#276
Draft
IENFI wants to merge 25 commits into
Draft
Conversation
H-sooyeon
reviewed
Mar 31, 2026
H-sooyeon
left a comment
Collaborator
There was a problem hiding this comment.
고생하셨습니다!
궁금한점들 코멘트로 달아놨어요.
Comment on lines
+37
to
+43
| /** | ||
| * OAuth 식별자(provider + providerId)로 사용자를 조회하고 없으면 생성한다. | ||
| * 소프트 삭제된 사용자는 복구한 뒤 최신 프로필 정보로 갱신한다. | ||
| * | ||
| * @param params OAuth 사용자 정보 | ||
| * @returns 기존 또는 신규 생성된 사용자 엔티티 | ||
| */ |
Collaborator
There was a problem hiding this comment.
소프트 삭제된 사용자는 복구한 뒤 최신 프로필 정보로 갱신한다.
복구할 때 삭제되기 전의 데이터는 모두 초기화되는게 맞겠죠?
전에 그 이슈가 있어서 수정했다고 얘기해주셨던 것 같긴 한데, 기억이 가물해서 여쭤봐요!
Comment on lines
+95
to
+97
| throw new BadRequestException( | ||
| `files must be at most ${MAX_MEDIA_PRESIGN_BATCH_SIZE}.`, | ||
| ); |
Collaborator
There was a problem hiding this comment.
이전에 에러 메시지를 한글로 바꾸셨었는데, 영어로 바꾸는걸까요?
Collaborator
There was a problem hiding this comment.
미디어 업로드 개수 제한은 공동 작성에선 업로드시(웹소켓으로 서로에게 전달되니), 개인 작성에선 저장시 제한 이벤트를 확인하는걸까요?
혹은 둘 다 저장 버튼 클릭시 발생하는 이벤트라면 공동작성에서 브로드캐스트로 이미지 개수 제한 안내를 보내는걸까요?
- FeedQueryService의 책임(피드 조회용 read query) 설명 추가 - getFeedForUser 입력값(userId, query)과 반환값(cards, warnings) 문서화 - date/tz 유효성 실패 시 BadRequestException 가능성 명시
- FeedQueryService 클래스 및 getFeedForUser 메서드 JSDoc 추가 - dayRange 입력/출력 계약과 예외 조건 문서화 - dayRange 사용 권장 패턴을 @remarks로 명시 (`eventAt >= from AND eventAt < to`) - buildFeedCards 파라미터/반환 구조 설명 추가
- buildFeedCards를 오케스트레이션 중심으로 정리하고 로더/매핑 함수로 분리 - postBlock 조회를 3회(LOCATION, TIME, preview)에서 1회로 통합 후 메모리 분기 처리 - contributor 기반 group pair를 dedupe해 groupMember 조회 조건 중복 제거 - group member key/매핑 처리 정리로 코드 가독성 개선 - 비즈니스 동작은 유지하고 내부 구조와 조회 경로만 개선
- contributor 기반 groupId:userId 수집을 Set으로 dedupe 처리 - groupMemberRepo 조회를 2회에서 1회로 통합 - 단일 조회 결과로 contributor 프로필 메타와 requester 그룹 role을 함께 구성 - 기존 피드 응답 동작은 유지하고 중복 조회/조건만 제거
- feed.helpers.ts 내부 함수 전반에 JSDoc(@param/@returns) 추가
- getGroupActivities의 actor 조회 쿼리에 select를 추가해 필요한 필드만 로드하도록 변경 - 불필요한 user 컬럼(email, provider, settings 등) 로딩을 제거해 쿼리 페이로드와 직렬화 비용 줄임
- `getGroupActivities`에 limit 정규화 추가 - 기본 20, 최소 1, 최대 50 적용 - 과도한 `limit` 요청으로 인한 DB 부하 증가 방지 - 로그 조회 후 actor/member 후속 조회 fan-out 비용 제한
- `getGroupActivities`의 actor 조회에서 `createdAt ASC` 정렬 제거 - 동일 로그의 actor는 생성 시점이 거의 같아 정렬 이점이 작음 - 불필요한 정렬 비용을 줄임
- `getGroupActivities`를 오케스트레이션 중심으로 축소 - 로그 페이지 조회, actor 조회, 멤버 프로필 조회, actor 매핑, 응답 변환, nextCursor 생성 로직을 private 메서드로 분리 - 내부 보조 타입(`GroupMemberProfile`, `ActivityLogPage`) 추가 - 동작/응답 구조는 유지하고 코드 탐색성과 유지보수성을 개선
- `getGroupActivities`에서 분리한 private 함수들에 JSDoc 추가 - 각 함수의 역할, 입력(`@param`), 반환값(`@returns`)을 명시 - 데이터 흐름(로그 조회 → actor 조회 → 멤버 병합 → 응답 변환) 이해도를 개선
- 게시글 목록 변환 루프 내부의 `PostBlock(LOCATION)` 개별 조회 제거 - `postIds` 기준 `LOCATION` 블록을 한 번에 조회하도록 변경 - `postId -> placeName` 맵으로 변환해 응답 아이템 조립 시 재사용 - N+1 패턴(1 + N 쿼리)을 배치 조회(1 + 1)로 줄여 DB round-trip과 응답 지연을 완화
- `LOCATION` 블록 조회 결과를 raw value 맵이 아니라 `postId -> placeDisplay` 맵으로 바로 변환 - `postBlock` 조회 시 `postId`, `value`만 선택해 필요한 컬럼만 로드 - 응답 조립 단계에서 `placeName` 계산 로직을 제거해 매핑 흐름을 단순화
- soft-deleted 게시글 영구 삭제 조건에서 MySQL식 `INTERVAL 30 DAY` 사용 제거
- `DateTime.now().minus({ days: 30 })`로 cutoff 시각을 계산해 쿼리 파라미터로 전달
- `MediaController`에서 `requesterId` 존재 여부를 확인하는 중복 로직 제거 - `JwtAuthGuard`를 신뢰하고 `user.sub`를 직접 사용하도록 정리 - 불필요해진 `UnauthorizedException` import 제거
- 게시글 이미지 개수 제한을 공용 상수로 분리 - presign DTO에 최대 업로드 개수 제한 추가 - `createPresignedUploads`에 배치 크기 상한 검증 추가 - 게시글 검증과 presign 요청 제한을 같은 기준으로 맞춰 정책 일관성 강화
- `MediaPresignRequestDto.files` 설명에 최대 업로드 개수 명시 - presign 요청 예시 payload 추가 - 업로드 제한 정책을 API 문서에서 바로 확인할 수 있도록 개선
- `createPresignedUploads`에서 presign URL 생성 후 `PENDING` 자산을 저장하도록 순서 변경 - presign 생성 중 실패한 요청이 불필요한 `PENDING` row를 남기지 않도록 정리
- `completeUploads` 시작 시 `ensureS3Config()` 호출 추가
- `cleanupPendingAssets`에서 S3 삭제 결과를 자산별로 확인하도록 변경 - 스토리지 삭제에 성공한 자산만 `media_assets`에서 삭제 - `NotFound`/`NoSuchKey`는 이미 삭제된 상태로 간주해 DB 정리 허용
- findOneByOrFail 대신 명시적으로 사용자 존재 여부를 확인하도록 수정 - 사용자 미존재 시 NotFoundException과 일관된 메시지를 반환하도록 정리
- 현재 구현과 맞지 않는 회원 탈퇴 설계 주석을 제거 - withdraw 메서드 설명을 실제 soft delete 동작 기준으로 정리
c23ae8b to
c273f9e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
요약 (연관 이슈 번호 포함)
작업 내용 + 스크린샷
getGroupActivities를 단계별 private 함수로 분리하고 JSDoc 보강LOCATION블록 조회를 N+1 방식에서 배치 조회 방식으로 변경createPresignedUploads에서 presign URL 생성 성공 후 PENDING 메타데이터를 저장하도록 순서 조정completeUploads에도 S3 설정 검증 추가MediaController의 중복 인증 체크 제거실제 걸린 시간
작업하며 고민했던 점(선택)
PENDINGrow를 언제 저장할지 고민했습니다. 실패한 presign 요청의 DB 흔적을 남기지 않기 위해 “URL 생성 성공 후 저장”으로 정리했습니다.테스트 실행 여부
리뷰 참고사항(선택)
시각 자료(이미지/영상, 있다면)(선택)