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

  • 유저

스크린샷 2025-04-27 19 41 30

  • 유저-앨범

스크린샷 2025-04-27 19 41 37

  • 앨범

스크린샷 2025-04-27 19 41 48

  • 사진

스크린샷 2025-04-27 19 41 55

  • 장소

스크린샷 2025-04-27 19 42 00


API 명세

모든 헤더에는 access token이 필수로 들어갑니다. 토큰 관련 명세는 유저 도메인 테크스펙에 명시했으므로 본 테크스펙에서는 생략합니다.

  • 메인페이지
    • 전체 앨범 목록 월별 조회
      • endpoint : /api/album/monthly?yearMonth={yearmonth}
      • 구현 상세 :
        • request param : yearMonth(yyyy-mm)
          • 최초 요청시에는 null로 요청합니다. 이후 요청 시 응답으로 받은 nextYearMonth를 yearMonth로 요청합니다.
        • 처리로직 :
          1. 최초 메인페이지 로딩 시 자동으로 요청한다.
          2. 최초 요청 시 yearmonth를 null로 요청한다.
          3. 쿼리파라미터가 null일 시 LocalDateTime.now() 기준의 yyyy-mm으로 조회를 시작한다.
            1. 유저 토큰 기반의 userId와 yearMonth를 사용하여 앨범 이름, 생성일을 조회한다.
            2. 해당 앨범의 썸네일 id를 사용하여 썸네일 주소를 조회한다.
            3. 각 앨범별 유저를 검색하여 해당 유저들의 닉네임과 썸네일 주소를 조회한다.
          4. 조회한 결과(앨범 id, 앨범 이름, 생성일, 썸네일 URL, 멤버 프로필이미지) 응답으로 반환한다.
    • 앨범 요약조회
      • endpoint : /api/album/{albumId}/summary
      • 구현상세
        • request param : albumId(앨범의 고유 아이디)
        • 처리로직
          1. 메인페이지에서 특정 앨범의 썸네일을 클릭할 시 요청한다.
          2. 해당 앨범의 장소 id를 확인하여 같은 장소 id의 사진을 조회한다.
            • 장소를 조회하지는 않는다.
          3. 같은 장소id를 가진 사진 중 quality_score가 가장 높은 사진의 URL과 위도, 경도를 조회한다.
          4. 조회한 결과(사진 id, quality score가 가장 높은 사진의 url, 위도, 경도)를 응답으로 반환한다.
  • 앨범 CRUD
    • 앨범 상세조회 및 검토 항목 처리 로직
      • endpoint
        • 상세조회 : /api/album/{albumId}
        • 사진복구(PUT) : /api/album/{albumId}/picture
        • 사진삭제(DELETE) : /api/album/{albumId}/picture
      • 구현상세
        • request param : albumId(앨범의 고유 아이디)
        • request body : pictureId(삭제, 복구시)
        • 처리로직
          1. 앨범의 고유 아이디로 앨범의 고유 아이디에 해당하는 모든 사진을 응답으로 반환한다.
            • 응답에 포함항목 : 앨범 타이틀, 사진정보
              • 사진정보 : 사진 아이디, 사진 URL, 위도, 고도, 태그, 중복여부, 흔들림여부, 사진찍은일시
          2. 중복여부(isDuplicated), 흔들림여부(isShaky)가 true인 사진들은 별도의 검토 항목에 들어가게 된다.
          3. 검토 항목에서 사진을 삭제할 수도 있고, 복원을 선택할 수도 있다.
            1. 만약 사진을 삭제한다면, deletedAt을 해당 시간의 timestamp로 변경한다.
            2. 만약 사진을 복원한다면, isDuplicated와 isShaky를 false로 변경한다.
          4. 검토항목이 아니어도 모든 사진은 삭제할 수 있으며, 삭제 시 deletedAt을 해당 시간의 timestamp로 변경한다.
  • 앨범 내 공동작업자 로직
    • 앨범 내 공동작업자 초대
      • endpoint
        • 앨범 초대 링크 생성 : /api/album/{albumId}/invite/link
        • 앨범 초대 수락 : /api/album/{albumId}/invite
      • 구현 상세
        • request body : invite token(초대 수락 시)
        • 처리로직
          1. 앨범의 초대 링크 생성 버튼을 클릭하면 링크 생성 api가 호출된다.

          2. 토큰 형태는 JWT이며, 앨범 아이디와 초대일, 만료일을 서버 비밀키로 서명한 토큰을 생성한다.

          3. 생성된 토큰은 다음과 같은 링크 양식으로 변환하여 응답으로 반환한다.

            "https://ongi.com/invite?token=eyJhbGciOiJIsInR5...&albumId=123"
            
          4. 사용자가 해당 링크를 클릭하면 /api/album/{albumId}/invite 를 요청한다.

          5. 이때 param의 albumId와 token의 albumId가 일치하지 않는다면 403 오류를 반환한다.

          6. 일치한다면 access token기반의 userId를 앨범의 공동작업자로 추가한다.

          7. 초대 수락 성공 응답을 반환한다.

    • 앨범 내 공동작업자 삭제
      • endpoint : /api/album/{albumId}/members/{userId}
      • 구현 상세
        • request param : userId, albumId
        • 처리 로직
          1. 앨범 소유자가 해당 API를 호출한다.
          2. 서버는 access token 기반 userId로 요청자가 앨범의 소유자인지 확인한다.
          3. 만약 요청자가 OWNER가 아니거나, 본인을 삭제하려고 하면 403 에러를 반환한다.
          4. 삭제할 userId가 해당 앨범의 공동작업자인지 검증한다.
          5. 검증에 성공하면 UserAlbum 매핑 테이블에서 해당 유저를 삭제한다.
          6. 공동작업자 삭제 성공 응답을 반환한다.
    • 앨범 내 공동작업자 소유권 위임
      • endpoint : /api/album/{albumId}/owner
      • 구현 상세
        • request param : albumId
        • request body : newOrderId
        • 처리 로직
          1. 앨범 소유자가 소유권 변경 API를 호출한다.
          2. 서버는 access token 기반 userId로 요청자가 해당 앨범의 OWNER인지 검증한다.
          3. 요청 body로 전달된 newOwnerId가 해당 앨범의 공동작업자인지 확인한다.
          4. 만약 요청자가 OWNER가 아니거나, newOwnerId가 공동작업자가 아니면 각각 403, 404 에러를 반환한다.
          5. 검증에 성공하면 UserAlbum 테이블에서:
            • 기존 OWNER의 role을 NORMAL로 변경
            • newOwnerId의 role을 OWNER로 변경
          6. 소유권 이전 성공 응답을 반환한다.