아카이브 월별 조회 API에 무한스크롤 지원 추가#297
Open
IENFI wants to merge 56 commits into
Open
Conversation
- `User` 엔티티의 OAuth 식별자 제약을 활성 사용자 기준으로 변경 - 탈퇴한 계정과 재가입 계정이 공존할 수 있는 구조를 반영
- users 테이블의 OAuth 유니크 제약을 활성 사용자 기준 partial unique index로 전환 - 탈퇴 계정과 재가입 계정이 공존할 수 있도록 provider_id 기준 제약 구조 변경
- OAuth 로그인 시 soft-deleted 사용자 조회 및 recover 흐름 제거 - 동일 OAuth 식별자로 재로그인해도 기존 탈퇴 계정을 복원하지 않도록 변경 - active user만 기존 계정으로 간주하고 없으면 새 사용자 생성
- OAuth 로그인 시 active user는 기존 계정으로 갱신되는 케이스 추가 - 탈퇴 계정은 복구하지 않고 새 사용자로 생성되는 케이스 추가
- 테스트 파일에서 jest 전역 타입을 인식할 수 있도록 compilerOptions.types 설정 추가 - describe, it, expect, jest 관련 에디터 경고가 발생하지 않도록 정리
- 회원 탈퇴 시 refresh token 정리를 위해 RefreshToken 엔티티를 모듈에 등록 - 마이페이지 서비스에서 refresh token 리포지토리를 사용할 수 있도록 의존성 구성 반영
- 회원 탈퇴 성공 시 해당 사용자의 refresh token을 일괄 revoke 하도록 변경 - 탈퇴 이후 기존 세션으로 토큰 재발급이 되지 않도록 정리
- 회원 탈퇴 시 사용자 soft delete와 refresh token revoke가 함께 수행되는 케이스 추가 - 이미 삭제된 사용자 처리 시 refresh token 정리가 실행되지 않는 케이스 검증
- 회원 탈퇴 시 소유 그룹 조회를 위해 Group 엔티티를 모듈에 등록 - 마이페이지 서비스에서 그룹 소유 여부를 확인할 수 있도록 DI 구성 반영
- 회원 탈퇴 전에 사용자가 소유한 그룹이 있는지 먼저 조회하도록 변경 - 소유 그룹이 있으면 그룹 이름을 포함한 안내 메시지와 함께 탈퇴를 차단 - owner 그룹이 없을 때만 기존 탈퇴 및 refresh token revoke 로직 수행
- 소유 그룹이 없을 때 정상 탈퇴되는 케이스 검증 - owner 그룹이 있으면 탈퇴가 차단되고 후속 정리가 실행되지 않는 케이스 추가
- 회원 탈퇴 시 공유 글의 share token revoke, refresh token revoke, user soft delete를 한 트랜잭션으로 처리 - 관련 탈퇴 흐름 테스트를 보강해 revoke 동작을 검증
- 그룹 나가기 시 groups.owner_id 대신 group_members.role 기준으로 관리자 여부를 확인하도록 변경 - 관리자인 사용자가 그룹을 나가려는 경우 관리자 그룹 여부를 검사하도록 로직 정리 - owner_id와 실제 그룹 권한 간 불일치로 인해 관리자가 그대로 탈퇴되는 문제를 완화
- 그룹 나가기 전 관리자 수 조회를 count 조건에서 query builder 기반 조회로 변경 - users.deleted_at IS NULL 조건을 추가해 탈퇴 유저를 관리자 수 산정에서 제외 - 유일한 관리자 판단 시 soft delete 상태의 사용자까지 고려하도록 정리
- 그룹 나가기 처리에서 별도 그룹 존재 조회를 제거하고 멤버 삭제 결과로 실패 여부를 판단 - 같은 그룹의 active 관리자 멤버 row에 pessimistic write lock을 적용 - 관리자 수 확인과 멤버 삭제를 하나의 트랜잭션으로 묶어 유일한 관리자 이탈을 방지
- group_members에 deleted_at 컬럼을 추가해 탈퇴한 멤버를 soft delete로 관리 - 기존 group_id, user_id unique constraint를 제거 - active 멤버만 유니크하도록 partial unique index 추가
- 마이그레이션 이름을 인자로 받도록 db:mig:gen 스크립트 수정 - 이름 없이 실행할 경우 잘못된 파일이 생성되지 않도록 사용법 안내 후 종료 - 테스트 환경 마이그레이션 생성 스크립트에도 동일한 검증 적용
- 그룹 설정 DTO에서 ownerUserId 필드 제거 - 그룹 설정 조회 시 owner relation 로드를 제거하고 응답에서 ownerUserId 제외 - 프론트 그룹 설정 타입과 mock 데이터를 변경된 응답 구조에 맞게 수정
- 그룹 삭제 권한 확인 기준을 최초 생성자 owner에서 active ADMIN 멤버로 변경 - ownerId와 그룹 내 관리자 권한 간의 정책 불일치를 제거 - 그룹 최상위 권한 판단을 group_members.role 기준으로 일원화 Co-authored-by: Copilot <copilot@github.com>
- 멤버 추방 시 owner 기준 방장 확인을 제거하고 ADMIN 멤버 추방을 차단하도록 변경 - 멤버 추방을 soft delete로 처리하고 target membership row에 pessimistic lock 적용 - 권한 변경 시 active ADMIN row와 target membership row를 트랜잭션에서 잠그도록 변경 - 유일한 ADMIN을 non-ADMIN으로 변경하지 못하도록 방어 로직 추가 - 그룹 나가기 시 active ADMIN row와 본인 membership row를 잠그고 현재 membership id 기준으로 soft delete - 그룹 내 프로필 수정 시 profileMediaId null 요청을 변경 없음으로 오인하지 않도록 undefined 기준으로 검사
- 멤버 추방 API endpoint를 렌더 시점의 deleteMember 상태값으로 생성하던 문제 수정 - 삭제 버튼 클릭 시점의 member 정보를 mutate 변수로 전달해 정확한 userId로 요청하도록 변경 - 추방 성공 처리에서도 상태값 대신 mutation variables를 사용해 제거 대상 정보를 참조
- 그룹 정보 수정 시 사용하지 않는 owner relation 로드를 제거 - owner 기준 권한 판단 제거 이후 남은 불필요한 관계 조회 정리
- 초대 링크 조회 시 멤버 수 계산에 active user 조건 추가 - group_members의 soft delete 기본 필터와 별도로 users.deleted_at IS NULL 조건을 반영 Co-authored-by: Copilot <copilot@github.com>
- .env.example에 ADMIN_KEY 예시 값을 추가 - 공지사항 관리자 키 용도와 보안 주석을 함께 정리
- 그룹 역할 우선순위 상수를 공용 유틸로 추출 - 관리자 승격 후보 선택 유틸을 추가해 역할 및 가입 순서 기준을 재사용 가능하게 정리 - 그룹 권한 가드가 동일한 우선순위 유틸을 사용하도록 변경
- 회원 탈퇴 트랜잭션에서 사용자 row를 잠그고 탈퇴 가능 여부를 먼저 확인하도록 변경 - 그룹 멤버십을 순회하며 비관리자 탈퇴, 공동 관리자 탈퇴, 유일 관리자 그룹 삭제, 관리자 양도 후 탈퇴를 처리하도록 추가 - share token revoke, refresh token revoke, user soft delete 전에 그룹 멤버십 정리가 함께 수행되도록 정리
- 유일한 관리자이자 유일한 멤버인 그룹 삭제 케이스를 검증 - 다른 멤버에게 관리자 권한을 양도한 뒤 탈퇴하는 케이스를 검증 - 공동 관리자 존재 시 단순 멤버십 삭제와 이미 탈퇴한 사용자 예외 케이스를 검증
- 회원 탈퇴 시 그룹별 멤버십 정리 분기를 private helper 메서드로 분리 - withdraw 본문이 전체 탈퇴 흐름만 드러나도록 그룹 삭제, 관리자 양도, 멤버십 삭제 로직을 정리 - 기존 동작은 유지하면서 탈퇴 로직의 가독성과 책임 분리를 개선
- GroupService에 transaction manager를 받는 deleteGroup helper를 추가 - 기존 그룹 삭제 API가 공용 helper를 통해 삭제를 수행하도록 정리 - 회원 탈퇴 시 빈 그룹 삭제도 동일한 그룹 삭제 helper를 재사용하도록 변경 - 마이페이지 모듈과 테스트 코드를 GroupService 주입 구조에 맞게 동기화
- draft 무효화와 draft media 정리를 공용 cleanup service로 추출 - 그룹 삭제 시 해당 그룹의 active draft를 일괄 무효화하고 draft snapshot을 갱신하도록 변경 - 그룹 나가기, 멤버 추방, VIEWER 강등, 회원 탈퇴 시 해당 사용자가 owner인 그룹 draft를 무효화하도록 추가 - draft invalidation 시 websocket 알림과 in-memory presence/lock 상태도 함께 정리되도록 보강
- 회원 탈퇴 트랜잭션에서 user_month_covers를 userId 기준으로 삭제하도록 추가 - 개인 포스트 삭제 이후 stale 상태로 남을 수 있는 월별 커버 설정 데이터를 함께 정리 - 마이페이지 탈퇴 테스트에 개인 월별 커버 삭제 호출 검증을 추가
- MediaService에 참조 없는 READY 미디어 자산 정리 cron 작업을 추가 - post, draft, 프로필, 그룹 커버, 월별 커버에서 참조되지 않는 asset만 orphan으로 판별하도록 구현 - orphan asset은 S3 원본 삭제 후 media_assets row도 함께 삭제하도록 정리 - media 모듈에 orphan 판별용 엔티티 의존성을 추가
- transaction-aware media cleanup helper 추가 - 삭제 흐름에서 수집한 candidate mediaIds 기준으로 active 참조 여부 확인 후 media_assets 정리 - 커밋 이후 S3 원본 삭제 처리 - 그룹 삭제, 회원 탈퇴, draft invalidation 경로에 미디어 정리 연결 - 기존 orphan sweep cron은 안전망으로 유지
Co-authored-by: Copilot <copilot@github.com>
- Group 엔티티에서 owner relation을 제거 - 그룹 생성 시 owner 컬럼 저장 없이 첫 멤버를 ADMIN으로 등록하도록 변경 - owner 기준 그룹 모델에서 group_members 기반 권한 구조로 일관되게 정리
- post e2e 테스트의 그룹 생성 fixture에서 owner relation 주입을 제거 - 그룹 정리 로직을 owner 기준 삭제 대신 테스트 그룹 이름 기준 삭제로 변경 - Group 엔티티 구조 변경 이후 발생하던 타입 및 lint 오류를 정리
- 자동 마이그레이션 생성 시 불필요한 스키마 변경이 섞이지 않도록 엔티티 정의를 현재 DB 구조에 가깝게 조정 Co-authored-by: Copilot <copilot@github.com>
- groups 테이블의 owner_id foreign key constraint를 제거 - groups.owner_id 컬럼을 삭제하도록 마이그레이션 추가 - down 마이그레이션에서 owner_id 컬럼과 foreign key를 복구하도록 구성
- 공용 인증 Unauthorized 예외를 추가하고 401 응답에 세부 error.code를 담도록 정리 - 마이페이지 프로필 조회 시 사용자 없음 케이스를 USER_NOT_FOUND 코드로 구분 - 인증 코드 교환, refresh token 만료/재사용/세션 무효화 케이스도 각각 별도 401 코드로 분리
- auth error code를 refresh 대상과 terminal 세션 종료 대상으로 구분하도록 프론트 분기 추가 - USER_NOT_FOUND 같은 terminal 401에서는 refresh를 반복하지 않고 바로 로그아웃하도록 변경 - /api/auth/session 재호출 루프를 줄이기 위해 401 처리 조건을 세분화
- 회원 탈퇴 중 ADMIN 멤버십 정리 시 VIEWER를 관리자 이관 후보에서 제외 - 이관 가능한 ADMIN/EDITOR가 없으면 그룹을 삭제하도록 분기 - VIEWER를 ADMIN으로 승격시키던 흐름을 제거
- 프로필 수정 시 사용자 레코드 락 조회 및 기존 profileImageId 확인 - 프로필 이미지 교체 및 null 삭제 시 이전 이미지 orphan 정리 - 개인 프로필 이미지 삭제 요청 null 입력 허용 및 DTO 정합성 반영
- 프로필 이미지 교체 시 이전 이미지 정리 검증 - 프로필 이미지 null 삭제 시 이전 이미지 정리 검증 - 닉네임만 변경하는 경우 미디어 정리 미발생 검증
- 미디어 삭제 후보 예약을 위한 delete_requested_at, delete_retry_count, last_delete_error 컬럼 추가 - 요청 경로에서 orphan 판정 대신 삭제 후보 표시만 수행하는 구조로 전환 - 백그라운드 큐에서 참조 재확인 후 S3 병렬 삭제 및 성공 건 DB 최종 삭제 수행 - 삭제 실패 시 재시도 횟수와 마지막 오류 기록 유지 - orphan 정리 및 재시도 cron을 삭제 예약 기반 흐름으로 재구성
- 회원 탈퇴, 프로필 수정, 그룹 삭제, 그룹 멤버 정리 흐름의 미디어 정리 반환값을 후보 ID 기반으로 통일 - draft invalidation 결과 구조를 mediaDeletionCandidateIds 중심으로 정리 - 요청 완료 후 실제 삭제 대신 백그라운드 삭제 큐 적재 호출로 변경
- 미디어 삭제 후보 표시, orphan 삭제, 재참조 복구, 삭제 실패 재시도 메타 기록 검증 - 프로필 수정 및 회원 탈퇴 흐름의 삭제 후보 기반 미디어 정리 동작 검증 - 기존 미디어 정리 호출부 변경에 따른 반환값 구조와 후속 호출 정합성 검증
- 그룹 멤버 추방 시 멤버십 프로필 이미지를 삭제 후보로 함께 수집 - 그룹 나가기 시 멤버십 프로필 이미지를 삭제 후보로 함께 수집 - draft invalidation 결과와 프로필 이미지 후보를 합쳐 백그라운드 삭제 큐로 전달
- 그룹 멤버 추방 시 프로필 이미지가 삭제 후보에 포함되는지 검증 - 그룹 나가기 시 프로필 이미지가 삭제 후보에 포함되는지 검증 - draft invalidation 후보와 프로필 이미지 후보가 함께 전달되는지 검증
- 그룹 월별 아카이브 조회에 allYears, cursor, limit 쿼리 지원 추가 - 전체 연도 기준 월 카드 목록을 커서 기반으로 페이지네이션하도록 분기 추가 - 기존 getMonthlyArchive 내부 월별 조회 로직을 공통 메서드로 정리 - 월 단위 nextCursor 계산을 공통 유틸로 분리 - 기존 연도별 조회 동작은 유지
- month cursor 인코딩/디코딩 동작 검증 - 잘못된 cursor 입력을 무시하는 동작 검증 - 첫 페이지 및 다음 페이지 계산 로직 검증
- 사용자 월별 아카이브 조회에 allYears, cursor, limit 쿼리 지원 추가 - 전체 연도 기준 월 카드 목록을 커서 기반으로 페이지네이션하도록 분기 추가 - 기존 getMonthlyArchive 내부 월별 조회 로직을 공통 메서드로 정리 - 사용자 월별 아카이브 페이지 응답 DTO를 추가 - 기존 연도별 조회 동작은 유지
6 tasks
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.
요약 (연관 이슈 번호 포함)
그룹/개인 월별 아카이브 조회 API에 전체 기간 기준 무한스크롤 조회를 추가했습니다.
기존 연도별 조회는 유지하면서,
allYears,cursor,limit파라미터를 통해월 카드 단위로 다음 페이지를 불러올 수 있도록 백엔드를 확장했습니다.
작업 내용 + 스크린샷
items,nextCursor구조 적용getMonthlyArchive내부 로직을 공통 메서드로 정리해 재사용 가능하게 분리실제 걸린 시간
작업하며 고민했던 점(선택)
월 카드단위로 잡아야 해서, 포스트 커서가 아닌 월 커서를 별도로 두었습니다.테스트 실행 여부
리뷰 참고사항(선택)
feat/user-withdrawal-and-group-leave-#285브랜치에서 이어서 진행했습니다.8005878이후 커밋부터 확인해주시면 됩니다. (뒤의 세 개)시각 자료(이미지/영상, 있다면)(선택)
없음