Skip to content

Group V2 Requirements

DAEILLIM edited this page Dec 22, 2025 · 4 revisions

3️⃣ V2 모임 서비스 요구사항 확인

1. 🖼️ 이미지 정책(사전 업로드 방식)

핵심 내용 정리

  • 모임 이미지는 “사전 업로드 → imageKey로 등록” 방식입니다.
  • 업로드는 최대 3장, 변형은 440x240 / 100x100 WEBP 2종입니다.
  • pre-upload imageKey는 2시간 유효하며, 업로더만 사용할 수 있고, 사용 시 1회 소비됩니다.
  • 수정의 imageKeys는 “최종 상태”이며, null=변경 없음, []=전체 삭제, [..]=그대로 최종 반영(0번째 대표)입니다.
  • 모임 삭제는 DB 삭제 확정 후(커밋 후) 이미지 파일을 삭제합니다.

1. 모임 이미지는 “선 업로드 → 키(imageKey)로 등록” 방식입니다.

모임을 생성하거나 수정할 때 이미지를 바로 저장하지 않고, 먼저 이미지를 업로드해서 서버가 imageKey와 URL 세트를 발급합니다.
그 다음 모임 생성/수정 API에서는 imageKey 목록을 전달해서 해당 이미지를 모임에 연결합니다.

  1. 사용자는 이미지 업로드 요청을 먼저 수행한다.
  2. 서버는 업로드된 이미지마다 imageKey(고유 키) 를 발급한다.
  3. 모임 생성/수정에서는 업로드 결과로 받은 imageKey를 사용해 이미지를 확정 등록한다.

해당 정책의 목적은 “이미지 파일 업로드”와 “모임 데이터 저장”을 분리해서, 모임 생성/수정 시 데이터 정합성을 유지하고, 이미지 URL 규격을 서버가 보증하도록 하기 위함이에요.

2. 사전 업로드 API는 최대 3장까지 업로드할 수 있습니다.

사전 업로드 API(/api/v2/groups/images/upload)는 한 번 요청에 최대 3개 파일만 받습니다.
  • 0장: 허용(이미지 없이 업로드 요청을 보내면 실질적으로 결과는 빈 배열이에요.)
  • 1~3장: 정상 처리
  • 4장 이상: 오류

3. 업로드된 이미지는 서버가 2가지 규격으로 자동 생성합니다.

사용자가 올린 이미지 1장은 서버에서 다음 2개 변형(Variant)으로 만들어 저장합니다. 올린 이미지 형식은 모두 .webp로 변환되고, 원본 이미지에 대한 정보를 보관하지 않습니다.
  • 카드용 이미지: 440 x 240 (WEBP)
  • 썸네일 이미지: 100 x 100 (WEBP)

따라서 “모임 이미지 1장”은 내부적으로는 아래 2개의 URL을 갖고 있습니다.

  • url440x240
  • url100x100 이 URL은 클라이언트가 임의로 만들거나 조합하는 값이 아니라, 서버가 업로드 처리 과정에서 생성하고 보증하는 결과물입니다.

4. 사전 업로드 결과는 2시간 동안만 유효합니다.

사전 업로드로 발급된 imageKey는 2시간(TTL) 동안만 유효합니다.
2시간이 지나면 해당 imageKey로 모임 생성/수정에 사용할 수 없습니다(서버에서 찾을 수 없게 돼요.)
  • 유효기간 내에 모임 생성/수정 요청에서 사용해야 합니다.
  • 유효기간이 지나면 다시 업로드를 해야 합니다.

5. 업로드한 사람만 그 imageKey를 확정 등록(사용)할 수 있습니다.

사전 업로드로 발급된 imageKey는 업로더(uploaderId) 가 함께 저장됩니다.
만약 모임 생성/수정에서 imageKey를 사용하려고 할 때, 요청한 사용자와 업로더가 다르면 오류 처리됩니다.
따라서 다른 사람이 올린 imageKey를 가져다가 내 모임에 붙일 수 없습니다.

6. imageKey는 “한 번만” 모임 생성/수정에 소비(consumed)됩니다.

모임 생성/수정에서 imageKey를 사용할 때 서버는 Redis에서 그 값을 consume(가져오고 삭제해서 consume이에요!) 합니다.
  1. 같은 imageKey를 두 번 재사용할 수 없습니다.
  2. 모임 생성 요청에서 한 번 사용되면, 같은 imageKey로 또 다른 모임에 붙일 수 없습니다.
  3. 수정에서도 마찬가지로, “새로 추가되는 이미지”는 반드시 “아직 소비되지 않은 pre-upload imageKey”여야 합니다.

7. 모임 생성 시 이미지 정책

📥모임 생성 요청(POST /api/v2/groups/create)에서 images가 있을 경우
  • 각 이미지 항목은 imageKey가 반드시 필요합니다.
  • sortOrder는 선택으로 프론트가 보내면 그 값을 사용합니다. 만약, 안 보내면 서버가 요청 순서대로 0(대표이미지)부터 부여합니다.
  • 또한 생성 시 이미지도 최대 3장까지 등록 가능합니다.

8. 모임 수정 시 이미지 정책(핵심)

모임 수정에서 이미지 필드는 imageKeys: List 형태로 받습니다. 해당 리스트는 “부분 수정용”이 아니라 최종 상태(final state)를 의미합니다.
수정 요청의 imageKeys가 의미하는 바는 다음과 같습니다.
  • 이 리스트에 포함된 imageKey들만 모임에 포함됩니다.
  • 리스트에 없는 기존 이미지는 삭제됩니다.
  • 리스트에 있고 기존에 없던 imageKey는 신규 이미지로 추가됩니다.(사전 업로드가 필요합니다.)
  • 리스트의 순서가 최종 표시 순서가 됩니다.(0번이 대표 이미지)

8-1) 수정 요청에서 imageKeys가 null이면?

  • 이미지 변경 없음: 기존 이미지 상태를 유지합니다.

8-2) 수정 요청에서 imageKeys가 빈 리스트([])이면?

  • 이미지 전체 삭제: 모임에 연결된 이미지가 모두 제거됩니다.

8-3) 수정 요청에서 imageKeys가 1~3개이면?

  • 해당 키 목록이 곧 “최종 이미지 목록 + 최종 순서”가 됩니다.(0번째가 대표 이미지에요.)

8-4) 수정에서 중복 imageKey는 금지

  • imageKeys 안에 동일한 key가 중복되면 오류 처리합니다.

8-5) 수정에서 최대 3장 제한

  • imageKeys는 최대 3개까지만 허용됩니다.

9. 정렬(sortOrder) 정책: “0번이 대표”

모임 이미지의 대표(썸네일/대표 노출)는 항상 sortOrder = 0 을 의미합니다.
  • 이미지가 3장이면 sortOrder는 0,1,2로 관리됩니다.
  • 수정에서 넘어온 imageKeys의 리스트 순서대로 0.. 재부여 됩니다.

10. 모임 삭제 시 이미지 파일도 같이 삭제됩니다.(커밋 이후)

모임을 “하드 삭제”하면 DB 데이터 삭제 후, 트랜잭션 커밋이 끝난 다음 S3 파일(URL 기반) 을 삭제합니다.
  1. DB가 먼저 삭제 확정
  2. 그 다음 이미지 파일 삭제 수행
  3. 만약 파일 삭제가 실패하더라도 DB는 이미 삭제된 상태일 수 있습니다. → (추후 재시도(outbox) 확장 포인트 고려 중)

2. 👥 모임 상태 · 참가 · 정원 · 역할 정책

핵심 내용 정리

  • 모임은 RECRUITING / FULL / CLOSED / CANCELLED / FINISHED 5가지 상태를 가집니다.
  • 참가 가능 여부는 모집중(RECRUITING) + 남은 자리 있음 조건으로 판단합니다.
  • HOST는 참가·탈퇴가 불가능하며, 수정·삭제 권한을 가집니다.
  • 참가자 수는 ATTEND 상태만 집계합니다.
  • FULL 상태는 자동 전환/복귀되며, CANCELLED·FINISHED는 최종 상태입니다.

1. 모임 상태(Group Status)의 종류와 의미

모임 상태 설명
RECRUITING 모집 중 상태이며, 기본 상태입니다. 참가가 가능합니다.
FULL 최대 인원에 도달한 상태입니다.
참가자는 더 받을 수 없지만, 탈퇴가 발생하면 다시 RECRUITING으로 돌아갈 수 있습니다.
CLOSED 모집이 종료된 상태입니다.
참가 및 재참가는 모두 불가능합니다
CANCELLED 모임이 취소된 상태입니다.
더 이상 수정·참가·재개가 불가능합니다.
FINISHED 모임이 종료된 상태입니다.
더 이상 수정·참가가 불가능합니다.

모임 생성 직후 상태는 항상 RECRUITING 입니다.

2. 모임 상태 전이(변경) 규칙

모임 상태는 정해진 방향으로만 변경할 수 있습니다.

모임 상태 변경 가능한 상태
RECRUITING FULL, CLOSED, CANCELLED, FINISHED
FULL RECRUITING, CLOSED, CANCELLED, FINISHED
CLOSED CANCELLED, FINISHED
CANCELLED 모임 상태 변경 불가
FINISHED 모임 상태 변경 불가

위 규칙을 벗어난 상태 변경 요청은 모두 오류 처리됩니다.

3. 참가 가능 여부 판단 기준

모임에 참가 버튼이 활성화되는 조건은 다음 두 가지를 모두 만족해야 합니다.

  1. 모임 상태가 RECRUITING
  2. 현재 참가 인원 < 최대 인원

아래 모임 상태에서는 참가가 불가능합니다.

  • FULL
  • CLOSED
  • CANCELLED
  • FINISHED

반드시 “모집중 + 남은 자리 있음” 상태에서만 참가가 가능합니다.

4. 모임 참가자 역할(Role) 정책

모임 참가자는 다음 역할 중 하나를 가집니다.

모임 참가자 역할 설명
HOST 모임 생성자
모임 수정 및 삭제 권한 보유
참가(ATTEND) 및 탈퇴(LEFT) 불가
MEMBER 일반 참가자
MANAGER (현재는 확장 예정 역할)

HOST는 모임 생성 시 자동으로 부여됩니다.

5. 모임 참가자 상태(User Status)

모임 참가자는 아래 상태 중 하나를 가집니다.

  • ATTEND: 현재 참가 중
  • LEFT: 자발적 탈퇴
  • KICKED: 강제 퇴장
  • BANNED: 영구 차단

참가자 수 집계에는 ATTEND 상태만 포함됩니다.

6. 모임 참가(attend) 정책

📌 참가 기본 조건

  1. 로그인 사용자만 가능
  2. HOST는 참가 불가
  3. 모임 상태는 반드시 RECRUITING이어야 합니다.

📌 기존 참가 이력에 따른 처리

  1. ATTEND → 오류 (이미 참가 중)
  2. LEFT / KICKED → 재참가 허용
  3. BANNED → 참가 불가 (오류)
  4. 기존 이력 없음 → 신규 참가자로 생성

📌재참여하는 경우

  • 상태는 ATTEND로 변경(joinedAt은 새로 기록됩니다.)

7. 정원(maxParticipants) 정책

참가 또는 재참가 처리 후, ATTEND 상태 참가자 수를 기준으로 정원을 체크합니다.
참가자 수가 최대 인원을 초과하면 전체 요청은 오류 처리되며 롤백됩니다.

📌 자동 상태 변경

  • 참가자 수 == 최대 인원 → FULL로 자동 전환
  • FULL 상태에서 탈퇴 발생 → RECRUITING으로 자동 복귀

8. 모임 탈퇴(left) 정책

HOST는 탈퇴할 수 없습니다.
ATTEND 상태일 때만 탈퇴가 가능합니다.

탈퇴 처리 결과

  • 상태는 LEFT로 변경(leftAt(탈퇴 시각)이 기록됩니다.)

9. 참가자 수 계산 기준

참가자 수(participantCount)는 항상 ATTEND 상태만 기준으로 계산합니다.
LEFT, KICKED, BANNED 상태는 참가자 수에 포함되지 않습니다.

10. 모임 상세 조회 시 참가자 노출 정책

HOST가 조회할 경우

  • 모든 참가자 상태(ATTEND / LEFT / KICKED / BANNED) 확인 가능
  • 탈퇴 시각(leftAt) 포함

일반 사용자 또는 비로그인

  • ATTEND 상태 참가자만 노출
  • 탈퇴·강퇴 정보는 노출되지 않음

11. 모임 수정 제한 정책

아래 경우에는 모임 수정이 불가능합니다.

  • 모임이 삭제된 경우
  • 모임 상태가 CANCELLED 또는 FINISHED인 경우

12. 모임 삭제 정책(Hard Delete)

모임 삭제는 HOST만 가능합니다. 삭제 순서는 다음과 같습니다.

  1. 참가자 정보 삭제
  2. 태그 연결 삭제
  3. 이미지 삭제 (variants → images)
  4. 모임 엔티티 삭제
  5. 트랜잭션 커밋 이후 이미지 파일(S3) 삭제

3. 📝 모임 생성 정책 (입력값 검증 · 쿨다운 · 기본 동작)

핵심 내용 정리

  • 모임 생성은 로그인한 사용자만 가능하며, 생성자는 자동으로 HOST가 됩니다.
  • 모임 생성에는 5초 쿨다운이 적용됩니다.
  • 제목·설명·위치·시간·정원은 필수 또는 조건부 필수입니다.
  • 태그는 최대 10개까지 가능하며, 중복은 허용되지 않습니다.
  • 이미지는 사전 업로드된 imageKey를 통해 최대 3장까지 등록할 수 있습니다.

1. 모임 생성 기본 조건

  1. 모임 생성은 다음 조건을 만족해야 가능합니다.
  2. 로그인한 사용자만 모임을 생성할 수 있습니다.
  3. 비로그인 사용자는 모임 생성이 불가능합니다.
  4. 모임 생성 요청 시, 요청 사용자는 자동으로 해당 모임의 HOST가 됩니다.
  5. HOST는 생성과 동시에 모임에 참가자로 등록됩니다.

2. 모임 생성 쿨다운(Cooldown) 정책

  1. 모임 생성에는 연속 생성 방지를 위한 쿨다운 정책이 적용됩니다.
  2. 동일 사용자는 5초에 1번만 모임을 생성할 수 있습니다.
  3. 쿨다운 시간 내에 다시 생성 요청을 하면 오류가 발생합니다.
  4. 쿨다운 남은 시간(초 단위)이 함께 전달됩니다.

📌 예시

  • A 사용자가 12:00:00에 모임 생성
  • 12:00:05 이전에 다시 생성 요청 → 실패
  • 12:00:05 이후 요청 → 성공

📌 보장 정책 모임 생성 트랜잭션이 실패(롤백) 되면, 쿨다운도 함께 해제됩니다.

3. 모임 생성 시 필수 입력 항목

모임 생성 시 다음 항목은 반드시 입력되어야 합니다.

  • 제목(title)
  • 위치(location)
  • 시작 시간(startTime)
  • 설명(description)
  • 최대 인원(maxParticipants)

위 항목 중 하나라도 누락되면 모임 생성은 실패합니다.

4. 모임 생성에 필요한 입력 값 정책

제목(title)

  • 필수 입력 값입니다.
  • 공백만 입력하는 것은 허용되지 않습니다.
  • 최대 길이는 50자입니다.
  • 앞뒤 공백은 제거(trim) 후 저장됩니다.

설명(description)

  • 필수 입력 값입니다.
  • 공백만 입력하는 것은 허용되지 않습니다.
  • 최대 길이는 300자입니다.
  • 앞뒤 공백은 제거(trim) 후 저장됩니다.

위치(location / locationDetail)

  • location(기본 위치)은 필수 입력입니다.
  • locationDetail(상세 위치)는 선택 입력입니다.
  • location은 공백이거나 비어 있을 수 없습니다.

📌 예시

  • location: “서울 강남구”
  • locationDetail: “강남역 3번 출구 앞”

시간(startTime / endTime)

  • startTime은 필수 입력입니다.
  • startTime은 현재 시각 이후(또는 현재) 여야 합니다.
  • endTime은 선택 입력입니다.

📌 시간 검증 규칙

  • endTime이 존재하는 경우: 반드시 startTime < endTime 이어야 합니다.
  • endTime이 없는 경우: 단일 시점 모임으로 처리됩니다. 시간 조건을 만족하지 않으면 모임 생성은 실패합니다.

최대 인원(maxParticipants)

  • 필수 입력 값입니다.
  • 최소 인원: 2명
  • 최대 인원: 12명 2명 미만 또는 12명 초과일 경우 오류 처리됩니다.

태그(tags) 정책

  • 태그는 선택 입력입니다.
  • 최대 10개까지 등록할 수 있습니다.
  • 공백이거나 빈 문자열 태그는 무시됩니다.
  • 동일한 태그가 중복되면 오류 처리됩니다.

📌 태그 처리 방식

  • 기존에 존재하는 태그는 재사용됩니다.
  • 존재하지 않는 태그는 새로 생성됩니다.

모임 생성 시 이미지 처리 정책

  • 이미지는 선택 입력입니다.
  • 최대 3장까지 등록 가능합니다.
  • 이미지는 반드시 사전 업로드된 imageKey를 통해 등록해야 합니다.
  • imageKey가 유효하지 않거나, 업로더가 다르면 오류 처리됩니다.
  • 이미지 정책의 상세 내용은 「🖼️ 이미지 정책(사전 업로드 방식)」을 따릅니다.

5. 모임 생성 완료 시 기본 동작

모임이 정상적으로 생성되면 다음 상태가 됩니다.

  • 모임 상태: RECRUITING
  • 생성자(HOST): 자동 참가 상태(ATTEND)
  • 생성 시각(createdAt), 수정 시각(updatedAt) 기록

4. 🔍 모임 목록 조회 정책 (검색 · 필터 · 커서 페이징)

핵심 내용 정리

  • 모임 목록 조회는 커서 기반 페이징 방식입니다.
  • 기본 필터는 ACTIVE이며, 상태 기준으로 노출 범위가 결정됩니다.
  • 키워드 검색은 제목·위치·설명을 대상으로 합니다.
  • 목록에서는 대표 이미지 최대 3장과 태그만 요약 노출합니다.
  • 참가 가능 여부(joinable)와 남은 자리(remainingSeats)는 서버에서 계산합니다.

1. 모임 목록 조회 기본 개요

모임 목록 조회 API는 다음 목적을 가집니다.

  • 전체 모임 목록 조회
  • 키워드 기반 검색
  • 상태 기반 필터링
  • 무한 스크롤을 위한 커서 기반 페이징 지원

기본적으로 삭제된 모임은 목록에 노출되지 않습니다.

2. 페이징 방식: 커서(cursor) 기반

모임 목록 조회는 페이지 번호 방식이 아닌 커서 기반 페이징을 사용합니다.

  • cursor는 마지막으로 조회한 모임의 groupId 입니다.
  • 최신 모임이 먼저 노출되며, groupId 내림차순 기준입니다.
  • 다음 페이지가 있는 경우에만 nextCursor가 내려옵니다.

📌 동작 방식

  1. 첫 요청: cursor 없이 요청
  2. 서버는 size + 1 만큼 조회
  3. size 초과 여부로 다음 페이지 존재 여부 판단
  4. 다음 페이지가 있으면 마지막 요소의 groupId를 nextCursor로 반환

3. 페이지 크기(size) 정책

  • 기본 size 값은 20입니다.
  • 최소 size는 1, 최대 size는 50입니다. size가 범위를 벗어나면 서버에서 자동 보정됩니다.

4. 기본 필터(GroupListFilter) 정책

모임 목록 조회에는 filter 파라미터가 존재합니다.

필터 설명
ACTIVE 현재 사용자에게 노출되는 모임
포함 상태: RECRUITING, FULL, CLOSED
ARCHIVED 종료된 모임 목록
포함 상태: CANCELLED, FINISHED
ALL 상태 제한 없이 전체 모임 조회

filter가 명시되지 않으면 기본값은 ACTIVE입니다.

5. includeStatuses / excludeStatuses 정책

목록 조회 시 상태 필터를 직접 지정할 수 있습니다.

  • includeStatuses가 있으면 filter의 기본 include 규칙을 무시하고 includeStatuses만 사용합니다.
  • excludeStatuses가 있으면 해당 상태는 조회 결과에서 제외됩니다.

📌 충돌 처리 규칙

  • include와 exclude에 동일한 상태가 있을 경우 exclude가 우선되며, 해당 상태는 제외됩니다.

📌 주의

  • filter=ALL 인 경우에는 기본 상태 강제가 적용되지 않습니다.('기본 노출 규칙'을 무시하고 전체를 다 보여줘요.)

6. 키워드 검색(keyword) 정책

키워드 검색은 선택 조건입니다.

검색 대상 필드

  • 모임 제목(title)
  • 모임 위치(location)
  • 모임 상세 위치(locationDetail)
  • 모임 설명(description)

검색 방식

  • 대소문자 구분 없음
  • 부분 일치 검색

키워드가 공백이거나 비어 있으면 검색 조건은 적용되지 않습니다.

7. 목록 노출 이미지 정책

모임 목록에서는 이미지 전체 정보를 내려주지 않습니다.

  • 대표 이미지 기준으로 최대 3장까지만 노출됩니다.
  • 이미지 규격은 CARD_440_240 만 사용됩니다.
  • 이미지가 없는 경우 빈 배열이 내려옵니다.

이미지의 정렬 순서는 모임 이미지의 sortOrder 기준입니다.

8. 목록 노출 태그 정책

  • 모임에 연결된 태그 이름만 문자열 배열로 노출됩니다.
  • 태그 개수 제한은 없습니다.
  • 태그 자체의 상세 정보(ID 등)는 노출하지 않습니다.

9. 참가자 수 및 남은 자리 계산 정책

목록에서 사용되는 값들은 서버에서 계산됩니다.

  • participantCount: ATTEND 상태 참가자 수
  • remainingSeats: maxParticipants - participantCount (0 미만이면 0)
  • joinable
    • 아래 조건을 만족하면 true
      • 모임 상태가 RECRUITING
      • remainingSeats > 0

프론트에서는 별도의 계산을 하지 않아도 됩니다.

10. 삭제된 모임 노출 정책

softDelete 또는 hardDelete된 모임은 목록에 노출되지 않습니다.
deletedAt이 존재하는 모임은 항상 조회 대상에서 제외됩니다.

5. 📄 모임 수정 정책 상세 (부분 수정 · 불변 조건 · 이미지/태그 연계)

핵심 내용 정리

  • 모임 수정은 HOST만 가능합니다.
  • 수정 요청은 “부분 수정”이지만, 각 필드는 최종 상태 기준으로 반영됩니다.
  • CANCELLED·FINISHED 상태의 모임은 수정할 수 없습니다.
  • 태그·이미지는 null과 []의 의미가 명확히 다릅니다.
  • 이미지 수정은 최종 imageKeys 리스트 기준으로 동작합니다.

1. 모임 수정 기본 조건

모임 수정은 다음 조건을 만족해야 가능합니다.

  • 로그인한 사용자만 수정 요청 가능합니다.
  • 요청 사용자는 반드시 해당 모임의 HOST여야 합니다.
  • 모임이 삭제되지 않은 상태여야 합니다.
  • 모임 상태가 CANCELLED 또는 FINISHED가 아니어야 합니다.

위 조건 중 하나라도 만족하지 않으면 수정 요청은 실패합니다.

2. 모임 수정은 “부분 수정” 방식입니다.

모임 수정 요청은 모든 필드를 한 번에 보내지 않아도 됩니다.

  • 요청에 포함된 필드만 수정됩니다.
  • 요청에 포함되지 않은 필드는 기존 값이 유지됩니다.

📌 단, 각 필드는 최종 상태로 반영되며, 서버가 유효성 검사를 수행합니다.

3. 수정 불가 조건 (공통 가드)

아래 조건에 해당하면 모임 수정은 불가능합니다.

  • 모임이 이미 삭제된 경우
  • 모임 상태가 CANCELLED
  • 모임 상태가 FINISHED

이 경우 모든 수정 요청은 오류 처리됩니다.

4. 제목(title) 수정 정책

  • 요청에 title이 포함된 경우에만 수정됩니다.
  • 공백만 있는 값은 허용되지 않습니다.
  • 최대 길이는 50자입니다.
  • 앞뒤 공백은 제거(trim) 후 저장됩니다.

5. 설명(description) 수정 정책

요청에 description이 포함된 경우에만 수정됩니다.

  • 공백만 있는 값은 허용되지 않습니다.
  • 최대 길이는 300자입니다.
  • 앞뒤 공백은 제거(trim) 후 저장됩니다.

6. 위치(location / locationDetail) 수정 정책

위치 정보는 부분 수정이 가능합니다.

  • location 또는 locationDetail 중 하나라도 요청에 포함되면
  • 서버는 최종 주소 객체를 새로 구성합니다.

📌 동작 방식

  • location이 없고 locationDetail만 요청된 경우: 기존 location 유지 + locationDetail 변경
  • location만 요청된 경우: location 변경 + 기존 locationDetail 유지

location은 반드시 값이 있어야 하며, 공백은 허용되지 않습니다.

7. 시간(startTime / endTime) 수정 정책

시간 정보는 단일 수정 또는 동시 수정이 가능합니다.

  • startTime만 수정 가능
  • endTime만 수정 가능
  • startTime + endTime 동시 수정 가능

📌 공통 검증 규칙

  • startTime은 null이 될 수 없습니다.
  • endTime이 존재하는 경우 반드시 startTime < endTime 조건을 만족해야 합니다.

조건을 만족하지 않으면 수정 요청은 실패합니다.

8. 최대 인원(maxParticipants) 수정 정책

  • maxParticipants가 요청에 포함된 경우에만 수정됩니다.
  • 현재 ATTEND 상태 참가자 수보다 작아질 수 없습니다.

📌 예시

  • 현재 참가자 5명
  • maxParticipants를 4로 수정 요청 → 오류
  • maxParticipants를 6 이상으로 수정 → 정상

9. 모임 상태(status) 수정 정책

status는 요청에 포함된 경우에만 변경됩니다.

  • 상태 변경은 정해진 상태 전이 규칙을 따릅니다.
  • 허용되지 않은 상태 전이는 오류 처리됩니다.

(상태 전이 규칙은 「👥 모임 상태 · 참가 · 정원 · 역할 정책」을 따릅니다.)

10. 태그(tags) 수정 정책

태그 수정은 최종 상태 기준 교체 방식입니다.

tags = null: 태그 변경 없음

tags = []: 모든 태그 삭제

tags = ["A", "B"]: 기존 태그 전체 제거 후 A, B로 재구성

📌 태그 검증 규칙

  • 최대 10개까지 허용
  • 중복 태그는 허용되지 않음
  • 공백 또는 빈 문자열 태그는 무시됨

11. 이미지(imageKeys) 수정 정책

이미지 수정은 최종 상태 리스트 방식으로 처리됩니다.

  • imageKeys = null: 이미지 변경 없음
  • imageKeys = []: 이미지 전체 삭제
  • imageKeys = ["k1", "k2"]: k1, k2만 남기고 순서대로 정렬 (0번 대표)

📌 이미지 정책 요약

  • 최대 3장까지 허용
  • 중복 imageKey 허용 안 됨
  • 신규 imageKey는 반드시 사전 업로드된 값이어야 함
  • 기존 이미지 중 리스트에 없는 것은 삭제됨

(상세 규칙은 「🖼️ 이미지 정책」을 따릅니다.)

12. 수정 완료 후 처리

모임 수정이 성공하면 다음 정보가 갱신됩니다.

  • updatedAt 변경
  • 수정된 필드만 반영
  • 이미지/태그는 최종 상태 기준으로 재조회하여 응답

6. 🧩 예외 · 에러 정책 (주요 실패 시나리오 정리)

핵심 내용 정리

  • 모든 실패는 명확한 원인과 메시지를 가진 에러로 응답됩니다.
  • 인증·권한·상태·입력값·정합성 오류를 구분합니다.
  • 서버 오류가 아닌 경우, 대부분은 사용자 행동에 따른 예측 가능한 실패입니다.
  • 실패한 요청은 부분 반영 없이 전체 롤백됩니다.

1. 공통 에러 처리 원칙

모임 서비스의 에러 처리는 다음 원칙을 따릅니다.

  • 유효성 검증 실패는 즉시 요청을 중단합니다.
  • 하나의 요청에서 오류가 발생하면 아무 변경도 반영되지 않습니다.
  • 클라이언트는 에러 메시지를 기준으로 사용자에게 안내합니다.
  • 서버 내부 오류(500)는 예외적인 경우에만 발생해야 합니다.

2. 인증(Authentication) 관련 오류

다음 경우 요청은 실패합니다.

로그인하지 않은 사용자가 다음 요청 시도를 하는 경우 해당 요청은 거부됩니다.

  • 모임 생성
  • 모임 수정
  • 모임 삭제
  • 모임 참가 / 탈퇴

사용자는 “로그인이 필요합니다”와 유사한 메시지를 받습니다.

3. 권한(Authorization) 관련 오류

다음 경우 요청은 실패합니다.

HOST가 아닌 사용자인 경우

  • 모임 수정 요청
  • 모임 삭제 요청

HOST 사용자인 경우

  • 자기 모임에 참가(attend)하려는 경우
  • 자기 모임에서 탈퇴(left)하려는 경우

📌 결과

요청은 거부됩니다.

“권한이 없습니다” 또는 “허용되지 않은 요청”와 유사한 메시지가 반환됩니다.

4. 모임 상태(Status) 관련 오류

다음 상태에서는 특정 요청이 실패합니다.

📌 참가 실패 케이스

  • 모임 상태가 RECRUITING이 아닌 경우
    • FULL
    • CLOSED
    • CANCELLED
    • FINISHED

📌 수정 실패 케이스

  • 모임 상태가 CANCELLED 또는 FINISHED인 경우

📌 상태 변경 실패 케이스

  • 허용되지 않은 상태 전이 요청

5. 참가(attend) 관련 오류

다음 경우 모임 참가 요청은 실패합니다.

  • 이미 ATTEND 상태인 경우
  • BANNED 상태인 경우
  • 정원이 초과된 경우
  • HOST가 참가하려는 경우

📌 결과

  • 참가 처리되지 않음
  • 참가자 수 증가 없음
  • 상태 변경 없음

6. 탈퇴(left) 관련 오류

다음 경우 모임 탈퇴 요청은 실패합니다.

  • HOST가 탈퇴하려는 경우
  • ATTEND 상태가 아닌 경우
    • LEFT
    • KICKED
    • BANNED

📌 결과

  • 탈퇴 처리되지 않음
  • 상태 변경 없음

7. 정원(maxParticipants) 관련 오류

다음 경우 요청은 실패합니다.

모임 생성 시

  • 2명 미만
  • 12명 초과

모임 수정 시

  • 현재 ATTEND 참가자 수보다 작은 값으로 수정 요청한 경우

📌 결과

요청은 전체 실패 처리됩니다.

8. 이미지(imageKey) 관련 오류

다음 경우 이미지 처리 요청은 실패합니다.

  • imageKey가 존재하지 않는 경우
  • imageKey가 이미 소비(consumed)된 경우
  • imageKey 업로더와 요청 사용자가 다른 경우
  • 이미지 개수가 3장을 초과한 경우
  • 수정 요청에서 중복 imageKey가 포함된 경우

📌 결과

  • 이미지 등록/수정 전체 실패
  • 기존 이미지 상태 유지

9. 태그(tags) 관련 오류

다음 경우 태그 요청은 실패합니다.

  • 태그 개수가 10개를 초과한 경우
  • 중복된 태그가 포함된 경우

📌 결과

  • 태그 변경 전체 실패
  • 기존 태그 상태 유지

10. 시간(startTime / endTime) 관련 오류

다음 경우 요청은 실패합니다.

  • startTime이 null인 경우
  • startTime이 현재 시각 이전인 경우
  • endTime이 startTime보다 같거나 빠른 경우

📌 결과

  • 모임 생성 또는 수정 실패

11. 쿨다운(Cooldown) 관련 오류

다음 경우 모임 생성 요청은 실패합니다.

  • 동일 사용자가 쿨다운 시간(5초) 이내에 다시 생성 요청한 경우

📌 결과

  • 생성 실패
  • 남은 쿨다운 시간이 함께 전달됨

12. 데이터 정합성 보장 정책

하나의 요청에서 여러 변경이 발생하더라도, 중간에 오류가 발생하면 모든 변경은 롤백됩니다.

📌 예시

  • 이미지 등록 중 오류 발생: 태그, 모임 정보, 이미지 모두 저장되지 않음

7. 🔐 권한 · 보안 정책 정리 (HOST / MEMBER / 비로그인 행동 기준)

핵심 내용 정리

  • 모든 모임 관련 행동은 사용자 역할(HOST / MEMBER / 비로그인) 기준으로 제한됩니다.
  • 인증(Authentication)과 권한(Authorization)은 명확히 구분됩니다.
  • 서버는 항상 권한을 우선 검증하며, 프론트 요청을 전적으로 신뢰하지 않습니다.
  • “보여줄 수 있음”과 “행동할 수 있음”은 별개의 개념입니다.

1. 인증(Authentication) 기본 정책

모임 서비스는 다음 인증 원칙을 따릅니다.

  • 로그인 여부는 서버 기준으로 판단합니다.
  • 로그인하지 않은 사용자는 조회만 가능하며, 변경을 수반하는 모든 요청은 제한됩니다.
  • 인증 정보가 없거나 만료된 경우 요청은 즉시 거부됩니다.

📌 인증이 필요한 기능

  • 모임 생성
  • 모임 수정
  • 모임 삭제
  • 모임 참가 / 탈퇴
  • 내 모임 목록 조회

2. 사용자 유형(User Type) 정의

모임 서비스에서 사용자는 다음 3가지 유형으로 구분됩니다.

  1. 비로그인 사용자
  2. 일반 로그인 사용자
  3. HOST (모임 생성자)

HOST는 “로그인 사용자”의 특수한 역할이며,특정 모임에 대해서만 HOST 권한을 가집니다.

3. 비로그인 사용자 권한 정책

비로그인 사용자는 다음 행동만 가능합니다.

✅가능한 행동

  • 모임 목록 조회
  • 모임 상세 조회

❌ 불가능한 행동

  • 모임 생성
  • 모임 수정
  • 모임 삭제
  • 모임 참가
  • 모임 탈퇴
  • 내 모임 목록 조회

📌 비로그인 사용자는 읽기 전용(Read-only) 사용자입니다.

4. 일반 로그인 사용자(MEMBER) 권한 정책

일반 로그인 사용자는 다음 행동이 가능합니다.

✅ 가능한 행동

  • 모임 목록 조회
  • 모임 상세 조회
  • 모임 참가 (조건 충족 시)
  • 모임 탈퇴 (ATTEND 상태일 때)
  • 내 모임 목록 조회

❌ 불가능한 행동

  • 타인의 모임 수정
  • 타인의 모임 삭제
  • HOST 권한이 필요한 관리 기능

📌 로그인 사용자라도, HOST가 아닌 모임에 대해서는 관리 권한이 없습니다.

5. HOST 권한 정책

HOST는 자신이 생성한 모임에 대해 다음 권한을 가집니다.

✅ 가능한 행동

  • 모임 수정
  • 모임 삭제
  • 모임 상태 변경
  • 참가자 전체 조회

❌ 불가능한 행동

  • 자기 모임에 참가
  • 자기 모임에서 탈퇴

📌 HOST는 “관리자”이며, 참가자 개념과 분리됩니다.

6. 행동별 권한 요약 표

행동 비로그인 로그인 HOST
모임 목록 조회
모임 상세 조회
모임 생성
모임 참가
모임 탈퇴
모임 수정
모임 삭제
참가자 전체 조회
내 모임 목록 조회

7. 권한 검증 우선순위 정책

서버는 요청 처리 시 다음 순서로 검증합니다.

  1. 인증 여부 확인
  2. 요청 대상 모임 존재 여부 확인
  3. 삭제 여부 확인
  4. 권한(HOST / MEMBER) 확인
  5. 상태(Status) 검증
  6. 비즈니스 로직 수행

📌 권한이 없는 요청은 비즈니스 로직 실행 전 즉시 차단됩니다.

8. 보안 관점 정책

  • 클라이언트에서 전달하는 role 정보는 신뢰하지 않습니다.
  • 모든 권한 판단은 서버의 데이터 기준으로 수행합니다.
  • URL 조작, ID 추측 등을 통한 접근은 모두 차단됩니다.
  • 모임 ID는 내부 식별자이며, 권한 검증 없이 정보가 노출되지 않습니다.

9. “노출 가능”과 “행동 가능”의 분리 원칙

다음 원칙을 반드시 지킵니다.

  • 버튼이 보인다고 해서 행동이 허용되는 것은 아닙니다.
  • 서버는 항상 최종 권한 판단자입니다.
  • 프론트엔드는 UX 개선을 위한 보조 수단일 뿐입니다.

📌 예시

  • 참가 버튼이 보이더라도, 서버 조건을 만족하지 않으면 참가 실패 가능
  • 수정 버튼이 숨겨져 있어도, 서버는 권한 검증을 수행함

Clone this wiki locally