Skip to content

Refactor/query optimization readability #244#276

Draft
IENFI wants to merge 25 commits into
devfrom
refactor/query-optimization-readability-#244
Draft

Refactor/query optimization readability #244#276
IENFI wants to merge 25 commits into
devfrom
refactor/query-optimization-readability-#244

Conversation

@IENFI

@IENFI IENFI commented Mar 22, 2026

Copy link
Copy Markdown
Collaborator

요약 (연관 이슈 번호 포함)

  • 디비 조회 최소화 #244
  • 가독성 개선 #273
  • 현재까지 그룹 활동 로그, 지도 게시글 조회, 미디어 업로드/조회, 휴지통 크론 등 백엔드 조회 경로를 정리하면서 불필요한 쿼리와 중복 로직을 줄이고, 문서화와 가독성을 함께 개선했습니다.

작업 내용 + 스크린샷

  • 그룹 활동 로그 조회에서 actor/user 최소 컬럼 조회 적용, 페이지 사이즈 상한 추가, 불필요한 actor 정렬 제거
  • getGroupActivities를 단계별 private 함수로 분리하고 JSDoc 보강
  • 지도 게시글 조회에서 LOCATION 블록 조회를 N+1 방식에서 배치 조회 방식으로 변경
  • 휴지통 영구 삭제 크론의 Postgres 날짜 비교 오류 수정
  • 미디어 업로드 개수 제한을 공용 상수로 통일하고 presign DTO/서비스에 상한 적용
  • createPresignedUploads에서 presign URL 생성 성공 후 PENDING 메타데이터를 저장하도록 순서 조정
  • completeUploads에도 S3 설정 검증 추가
  • MediaController의 중복 인증 체크 제거
  • feed/auth/user/group 일부 서비스의 JSDoc 및 내부 구조 정리

실제 걸린 시간

  • 일주일

작업하며 고민했던 점(선택)

  • presign 단계에서 PENDING row를 언제 저장할지 고민했습니다. 실패한 presign 요청의 DB 흔적을 남기지 않기 위해 “URL 생성 성공 후 저장”으로 정리했습니다.
  • 업로드 제한은 presign과 게시글 저장 단계가 서로 어긋나지 않도록 같은 상수 기준으로 맞췄습니다.
  • 조회 최적화는 과도한 미세 최적화보다, 실제 병목이 보이는 N+1 제거와 가독성 개선을 우선했습니다.

테스트 실행 여부

  • 👍 네, 테스트했어요.
  • 🙅 아니요, 필요하지 않아요.
  • 🤯 아니요, 하지만 테스트가 필요해요.

리뷰 참고사항(선택)

  • 기능 추가보다는 조회 경로 최적화, 정책 일관성 정리, 문서화 비중이 큰 PR입니다.
  • feed/auth/user 관련 JSDoc/구조 정리 커밋도 함께 포함되어 있습니다.
  • 실제 동작 변경 포인트는 그룹 활동 조회, 지도 조회, 미디어 presign/complete, 휴지통 크론입니다.
  • 추가 리팩터링/정리 커밋이 더 들어갈 수 있음

시각 자료(이미지/영상, 있다면)(선택)

@IENFI IENFI requested a review from H-sooyeon March 22, 2026 10:41
@IENFI IENFI self-assigned this Mar 22, 2026
@IENFI IENFI added 🛠️ BE 백엔드 작업 🔨refactor 리팩토링 작업(클린코드/성능 개선 등) labels Mar 22, 2026

@H-sooyeon H-sooyeon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

고생하셨습니다!
궁금한점들 코멘트로 달아놨어요.

Comment thread backend/src/modules/auth/auth.service.ts
Comment on lines +37 to +43
/**
* OAuth 식별자(provider + providerId)로 사용자를 조회하고 없으면 생성한다.
* 소프트 삭제된 사용자는 복구한 뒤 최신 프로필 정보로 갱신한다.
*
* @param params OAuth 사용자 정보
* @returns 기존 또는 신규 생성된 사용자 엔티티
*/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

소프트 삭제된 사용자는 복구한 뒤 최신 프로필 정보로 갱신한다.

복구할 때 삭제되기 전의 데이터는 모두 초기화되는게 맞겠죠?
전에 그 이슈가 있어서 수정했다고 얘기해주셨던 것 같긴 한데, 기억이 가물해서 여쭤봐요!

Comment on lines +95 to +97
throw new BadRequestException(
`files must be at most ${MAX_MEDIA_PRESIGN_BATCH_SIZE}.`,
);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

이전에 에러 메시지를 한글로 바꾸셨었는데, 영어로 바꾸는걸까요?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

미디어 업로드 개수 제한은 공동 작성에선 업로드시(웹소켓으로 서로에게 전달되니), 개인 작성에선 저장시 제한 이벤트를 확인하는걸까요?

혹은 둘 다 저장 버튼 클릭시 발생하는 이벤트라면 공동작성에서 브로드캐스트로 이미지 개수 제한 안내를 보내는걸까요?

IENFI added 23 commits April 11, 2026 00:41
- AuthService의 public/private 메서드에 JSDoc 추가
- OAuth 로그인, 코드 교환, 토큰 재발급/폐기 흐름 설명 보강
- @param, @returns, @throws 태그를 메서드 시그니처에 맞게 명시
- 동작 변경 없이 문서화만 반영
- UserService의 공개 API 및 내부 유틸 메서드에 JSDoc 추가
- 아카이브 조회, 월 커버 후보/수정, 기록일 조회 로직 설명 보강
- @param, @returns, @throws 태그를 메서드별로 명확히 기재
- 비즈니스 로직 변경 없이 주석/문서만 수정
- 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 동작 기준으로 정리
@IENFI IENFI force-pushed the refactor/query-optimization-readability-#244 branch from c23ae8b to c273f9e Compare April 10, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠️ BE 백엔드 작업 🔨refactor 리팩토링 작업(클린코드/성능 개선 등)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants