BE 테크스펙(Album) - 100-hours-a-week/5-yeosa-wiki GitHub Wiki
배경 (Background)
- 앨범 생성, 조회, 수정, 삭제 기능을 정의하고 앨범 내 공동작업자 관련 기능을 정의합니다.
- 결과 1 : 서비스 메인페이지 구현
- 결과 2 : 앨범 CRUD 기능 구현
- 결과 3 : 앨범 내 공동작업자 조회, 초대 및 소유권 이양 기능 구현
목표가 아닌 것 (Non-goals) (Optional)
- 앨범 나가기(초대받은 후 앨범에 더이상 접근하지 않는 기능)은 mvp에서는 구현하지 않습니다.
설계 및 기술 자료 (Architecture and Technical Documentation)
관련 ERD
- 유저
- 유저-앨범
- 앨범
- 사진
- 장소
API 명세
모든 헤더에는 access token이 필수로 들어갑니다. 토큰 관련 명세는 유저 도메인 테크스펙에 명시했으므로 본 테크스펙에서는 생략합니다.
- 메인페이지
- 전체 앨범 목록 월별 조회
- endpoint :
/api/album/monthly?yearMonth={yearmonth}
- 구현 상세 :
- request param : yearMonth(yyyy-mm)
- 최초 요청시에는 null로 요청합니다. 이후 요청 시 응답으로 받은 nextYearMonth를 yearMonth로 요청합니다.
- 처리로직 :
- 최초 메인페이지 로딩 시 자동으로 요청한다.
- 최초 요청 시 yearmonth를 null로 요청한다.
- 쿼리파라미터가 null일 시 LocalDateTime.now() 기준의 yyyy-mm으로 조회를 시작한다.
- 유저 토큰 기반의 userId와 yearMonth를 사용하여 앨범 이름, 생성일을 조회한다.
- 해당 앨범의 썸네일 id를 사용하여 썸네일 주소를 조회한다.
- 각 앨범별 유저를 검색하여 해당 유저들의 닉네임과 썸네일 주소를 조회한다.
- 조회한 결과(앨범 id, 앨범 이름, 생성일, 썸네일 URL, 멤버 프로필이미지) 응답으로 반환한다.
- request param : yearMonth(yyyy-mm)
- endpoint :
- 앨범 요약조회
- endpoint :
/api/album/{albumId}/summary
- 구현상세
- request param : albumId(앨범의 고유 아이디)
- 처리로직
- 메인페이지에서 특정 앨범의 썸네일을 클릭할 시 요청한다.
- 해당 앨범의 장소 id를 확인하여 같은 장소 id의 사진을 조회한다.
- 장소를 조회하지는 않는다.
- 같은 장소id를 가진 사진 중 quality_score가 가장 높은 사진의 URL과 위도, 경도를 조회한다.
- 조회한 결과(사진 id, quality score가 가장 높은 사진의 url, 위도, 경도)를 응답으로 반환한다.
- endpoint :
- 전체 앨범 목록 월별 조회
- 앨범 CRUD
- 앨범 상세조회 및 검토 항목 처리 로직
- endpoint
- 상세조회 :
/api/album/{albumId}
- 사진복구(PUT) :
/api/album/{albumId}/picture
- 사진삭제(DELETE) :
/api/album/{albumId}/picture
- 상세조회 :
- 구현상세
- request param : albumId(앨범의 고유 아이디)
- request body : pictureId(삭제, 복구시)
- 처리로직
- 앨범의 고유 아이디로 앨범의 고유 아이디에 해당하는 모든 사진을 응답으로 반환한다.
- 응답에 포함항목 : 앨범 타이틀, 사진정보
- 사진정보 : 사진 아이디, 사진 URL, 위도, 고도, 태그, 중복여부, 흔들림여부, 사진찍은일시
- 응답에 포함항목 : 앨범 타이틀, 사진정보
- 중복여부(isDuplicated), 흔들림여부(isShaky)가 true인 사진들은 별도의 검토 항목에 들어가게 된다.
- 검토 항목에서 사진을 삭제할 수도 있고, 복원을 선택할 수도 있다.
- 만약 사진을 삭제한다면, deletedAt을 해당 시간의 timestamp로 변경한다.
- 만약 사진을 복원한다면, isDuplicated와 isShaky를 false로 변경한다.
- 검토항목이 아니어도 모든 사진은 삭제할 수 있으며, 삭제 시 deletedAt을 해당 시간의 timestamp로 변경한다.
- 앨범의 고유 아이디로 앨범의 고유 아이디에 해당하는 모든 사진을 응답으로 반환한다.
- endpoint
- 앨범 상세조회 및 검토 항목 처리 로직
- 앨범 내 공동작업자 로직
- 앨범 내 공동작업자 초대
- endpoint
- 앨범 초대 링크 생성 :
/api/album/{albumId}/invite/link
- 앨범 초대 수락 :
/api/album/{albumId}/invite
- 앨범 초대 링크 생성 :
- 구현 상세
- request body : invite token(초대 수락 시)
- 처리로직
-
앨범의 초대 링크 생성 버튼을 클릭하면 링크 생성 api가 호출된다.
-
토큰 형태는 JWT이며, 앨범 아이디와 초대일, 만료일을 서버 비밀키로 서명한 토큰을 생성한다.
-
생성된 토큰은 다음과 같은 링크 양식으로 변환하여 응답으로 반환한다.
"https://ongi.com/invite?token=eyJhbGciOiJIsInR5...&albumId=123"
-
사용자가 해당 링크를 클릭하면
/api/album/{albumId}/invite
를 요청한다. -
이때 param의 albumId와 token의 albumId가 일치하지 않는다면 403 오류를 반환한다.
-
일치한다면 access token기반의 userId를 앨범의 공동작업자로 추가한다.
-
초대 수락 성공 응답을 반환한다.
-
- endpoint
- 앨범 내 공동작업자 삭제
- endpoint :
/api/album/{albumId}/members/{userId}
- 구현 상세
- request param : userId, albumId
- 처리 로직
- 앨범 소유자가 해당 API를 호출한다.
- 서버는 access token 기반 userId로 요청자가 앨범의 소유자인지 확인한다.
- 만약 요청자가 OWNER가 아니거나, 본인을 삭제하려고 하면 403 에러를 반환한다.
- 삭제할 userId가 해당 앨범의 공동작업자인지 검증한다.
- 검증에 성공하면 UserAlbum 매핑 테이블에서 해당 유저를 삭제한다.
- 공동작업자 삭제 성공 응답을 반환한다.
- endpoint :
- 앨범 내 공동작업자 소유권 위임
- endpoint :
/api/album/{albumId}/owner
- 구현 상세
- request param : albumId
- request body : newOrderId
- 처리 로직
- 앨범 소유자가 소유권 변경 API를 호출한다.
- 서버는 access token 기반 userId로 요청자가 해당 앨범의 OWNER인지 검증한다.
- 요청 body로 전달된 newOwnerId가 해당 앨범의 공동작업자인지 확인한다.
- 만약 요청자가 OWNER가 아니거나, newOwnerId가 공동작업자가 아니면 각각 403, 404 에러를 반환한다.
- 검증에 성공하면 UserAlbum 테이블에서:
- 기존 OWNER의 role을 NORMAL로 변경
- newOwnerId의 role을 OWNER로 변경
- 소유권 이전 성공 응답을 반환한다.
- endpoint :
- 앨범 내 공동작업자 초대