{"openapi":"3.1.0","info":{"title":"Moyeo API","description":"CMC Moyeo MVP server API","version":"v1"},"servers":[{"url":"https://3-35-119-70.sslip.io","description":"Generated server url"}],"tags":[{"name":"My place","description":"마이페이지 내 장소 관리 API"},{"name":"Meeting","description":"모임 생성, 초대 코드 조회, 회원·게스트 참여 API"},{"name":"Feedback","description":"사용자 피드백 API"},{"name":"Time","description":"서버 시간 조회 API"},{"name":"Auth","description":"소셜 로그인 및 현재 사용자 조회 API"},{"name":"Member","description":"현재 사용자 정보 API"},{"name":"Development Auth","description":"local 및 dev 프로필에서만 제공되는 테스트 계정 인증 API"},{"name":"Departure place","description":"출발지 통합 검색 API"}],"paths":{"/api/users/me/onboarding":{"put":{"tags":["Member"],"summary":"최초 닉네임 등록","description":"소셜 가입 직후 기본 닉네임이 없는 사용자의 닉네임을 최초 1회 등록합니다.\n같은 닉네임으로 다시 요청하면 성공하며, 다른 닉네임으로 변경하는 기능은 별도 API로 제공합니다.\n","operationId":"completeOnboarding","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteOnboardingRequest"}}},"required":true},"responses":{"200":{"description":"닉네임 등록 성공 또는 같은 요청 재시도 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"400":{"description":"닉네임 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"409":{"description":"이미 다른 닉네임으로 온보딩 완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"ONBOARDING_ALREADY_COMPLETED","status":409}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/{meetingId}/cover-image":{"put":{"tags":["Meeting"],"summary":"모임 커버 사진 교체","description":"임시 MVP 정책상 방장만 최대 10MB, 13MP이고 한 변이 8,000px 이하인 JPEG/PNG 커버 사진을 교체할 수 있습니다. 성공 응답의 coverImageUrl은 새로 저장된 이미지의 상대 조회 경로입니다. 프론트는 기존 <img src>를 이 값에 API 서버 주소를 붙인 URL로 교체합니다.","operationId":"replaceCoverImage","parameters":[{"name":"meetingId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"coverImage":{"type":"string","format":"binary"}},"required":["coverImage"]}}}},"responses":{"200":{"description":"커버 사진 교체 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeetingCoverResponse"}}}},"413":{"description":"커버 파일 10MB, 원본 이미지 13MP 또는 한 변 8,000px 제한 초과","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeetingCoverResponse"}}}},"415":{"description":"JPEG 또는 PNG가 아닌 커버 파일","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeetingCoverResponse"}}}},"403":{"description":"방장 권한 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeetingCoverResponse"}}}},"503":{"description":"커버 이미지 저장소 일시 이용 불가","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeetingCoverResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Meeting"],"summary":"모임 커버 사진 삭제","description":"임시 MVP 정책상 방장만 모임 커버 사진을 삭제할 수 있습니다.","operationId":"deleteCoverImage","parameters":[{"name":"meetingId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"커버 사진 삭제 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}},"403":{"description":"방장 권한 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}},"404":{"description":"삭제할 커버 사진 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings":{"post":{"tags":["Meeting"],"summary":"커버 사진을 포함한 모임 생성","description":"**출발지 이름 공통 안내**\n장소 조율이 포함된 `SCHEDULE_AND_PLACE` 또는 `PLACE_ONLY` 모임에서는 `departure`를 입력합니다.\n이때 `departure.name`은 선택 입력(nullable)이며, 생략하면 장소 현황 응답에서 `departure.address`를 표시합니다.\n\n커버 사진은 선택 사항입니다. 사진이 없어도 이 multipart API로 모임을 생성할 수 있습니다.\n이때 `coverImage` 파트만 생략합니다. `request`는 문자열이 아니라\n`application/json` 타입의 Blob 파트여야 합니다.\n\n`request`에는 모임 설정과 방장의 후보 날짜·가능 일정·출발지를 선택한 플로우에 맞게\n모두 담습니다. 성공 시 `meetingId`, `inviteCode`를 반환합니다.\n\n`FormData` 요청에서 `Content-Type` 헤더는 직접 설정하지 마세요. 브라우저 또는 curl이\nmultipart boundary를 자동으로 추가합니다.\n\n```javascript\nconst formData = new FormData();\nformData.append(\n  \"request\",\n  new Blob([JSON.stringify(requestBody)], { type: \"application/json\" })\n);\nif (coverImageFile) {\n  formData.append(\"coverImage\", coverImageFile);\n}\n\nawait fetch(\"/api/meetings\", {\n  method: \"POST\",\n  headers: { Authorization: \"Bearer {accessToken}\" },\n  body: formData\n});\n```\n","operationId":"createMeetingWithCover","requestBody":{"content":{"application/json":{"examples":{"SCHEDULE_ONLY_DATE_ONLY_NO_DEADLINE":{"description":"마감 기한 없이 답변을 받는 날짜 선택 모임입니다.\n\n- `noDeadline`을 `true`로 보냅니다.\n- `deadlineMinutes`는 보내지 않거나 `null`로 보냅니다.\n- `DATE_ONLY`이므로 `availableStartTime`, `availableEndTime`, `scheduleResponse`는 보내지 않습니다.\n","value":{"name":"여유롭게 날짜 정하기","description":"마감 없이 가능한 날짜를 받아요.","maxParticipants":4,"planningType":"SCHEDULE_ONLY","scheduleInputType":"DATE_ONLY","scheduleCandidateDates":["2026-07-10","2026-07-11"],"noDeadline":true}},"SCHEDULE_AND_PLACE_DATE_AND_TIME":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY`\n- `PLACE_ONLY`\n- `SCHEDULE_AND_PLACE` ← 이 예시\n\n**허용 `scheduleInputType`**\n- `DATE_ONLY`\n- `DATE_AND_TIME` ← 이 예시\n\n**조건부 입력**\n- `scheduleInputType=DATE_AND_TIME`: `availableStartTime`, `availableEndTime` 필수\n- `scheduleInputType=DATE_ONLY`: 시간 필드 미전송\n\n","value":{"name":"토요일 저녁 모임","description":"오랜만에 같이 저녁 먹어요.","maxParticipants":6,"planningType":"SCHEDULE_AND_PLACE","scheduleInputType":"DATE_AND_TIME","availableStartTime":"17:00","availableEndTime":"23:00","scheduleCandidateDates":["2026-07-10","2026-07-11"],"scheduleResponse":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]},"departure":{"name":"회사","address":"서울 강남구 테헤란로 123","latitude":37.498095,"longitude":127.02761,"transportationMode":"PUBLIC_TRANSIT"},"deadlineMinutes":1440}},"SCHEDULE_AND_PLACE_DATE_ONLY":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY`\n- `PLACE_ONLY`\n- `SCHEDULE_AND_PLACE` ← 이 예시\n\n**허용 `scheduleInputType`**\n- `DATE_ONLY` ← 이 예시\n- `DATE_AND_TIME`\n\n공통 시간대는 보내지 않습니다.\n","value":{"name":"주말 모임 정하기","description":"가능한 날짜와 장소를 정해요.","maxParticipants":6,"planningType":"SCHEDULE_AND_PLACE","scheduleInputType":"DATE_ONLY","scheduleCandidateDates":["2026-07-10","2026-07-11"],"departure":{"address":"서울 강남구 테헤란로 123","latitude":37.498095,"longitude":127.02761,"transportationMode":"PUBLIC_TRANSIT"},"deadlineMinutes":1440}},"SCHEDULE_ONLY_DATE_AND_TIME":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY` ← 이 예시\n- `PLACE_ONLY`\n- `SCHEDULE_AND_PLACE`\n\n**허용 `scheduleInputType`**\n- `DATE_ONLY`\n- `DATE_AND_TIME` ← 이 예시\n\n장소 관련 필드는 보내지 않습니다.\n","value":{"name":"저녁 일정 정하기","description":"가능한 날짜와 시간을 정해요.","maxParticipants":4,"planningType":"SCHEDULE_ONLY","scheduleInputType":"DATE_AND_TIME","availableStartTime":"17:00","availableEndTime":"23:00","scheduleCandidateDates":["2026-07-10","2026-07-11"],"scheduleResponse":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]},"deadlineMinutes":180}},"SCHEDULE_ONLY_DATE_ONLY":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY` ← 이 예시\n- `PLACE_ONLY`\n- `SCHEDULE_AND_PLACE`\n\n**허용 `scheduleInputType`**\n- `DATE_ONLY` ← 이 예시\n- `DATE_AND_TIME`\n\n장소 추천 전략과 출발지 필드는 보내지 않습니다.\n","value":{"name":"주말 일정 정하기","description":"가능한 날짜를 정해요.","maxParticipants":4,"planningType":"SCHEDULE_ONLY","scheduleInputType":"DATE_ONLY","scheduleCandidateDates":["2026-07-10","2026-07-11"],"deadlineMinutes":180}},"PLACE_ONLY":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY`\n- `PLACE_ONLY` ← 이 예시\n- `SCHEDULE_AND_PLACE`\n\n**`scheduleInputType`**\n- `PLACE_ONLY`에서는 보내지 않습니다.\n\n**출발지 표시 이름**\n- `departure.name`은 선택 입력입니다. 생략하면 장소 현황 응답에서 `departure.address`를 표시합니다.\n\n","value":{"name":"카페 장소 정하기","description":"만날 장소를 정해요.","maxParticipants":8,"planningType":"PLACE_ONLY","departure":{"address":"서울 강남구 테헤란로 123","latitude":37.498095,"longitude":127.02761,"transportationMode":"PUBLIC_TRANSIT"},"deadlineMinutes":720}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"request":{"$ref":"#/components/schemas/CreateMeetingRequest"},"coverImage":{"type":"string","format":"binary","description":"선택 JPEG 또는 PNG 파일. 최대 10MB, 13MP이고 한 변은 8,000px 이하여야 합니다. 사진이 없으면 이 파트를 생략합니다."}},"required":["request"]},"examples":{"SCHEDULE_ONLY_DATE_ONLY_NO_DEADLINE":{"description":"마감 기한 없이 답변을 받는 날짜 선택 모임입니다.\n\n- `request.noDeadline`를 `true`로 보냅니다.\n- `request.deadlineMinutes`는 보내지 않거나 `null`로 보냅니다.\n- `coverImage`는 선택 파일 파트이므로 필요할 때만 추가합니다.\n","value":{"request":{"name":"여유롭게 날짜 정하기","description":"마감 없이 가능한 날짜를 받아요.","maxParticipants":4,"planningType":"SCHEDULE_ONLY","scheduleInputType":"DATE_ONLY","scheduleCandidateDates":["2026-07-10","2026-07-11"],"noDeadline":true}}},"SCHEDULE_AND_PLACE_DATE_AND_TIME":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY`\n- `PLACE_ONLY`\n- `SCHEDULE_AND_PLACE` ← 이 예시\n\n**허용 `scheduleInputType`**\n- `DATE_ONLY`\n- `DATE_AND_TIME` ← 이 예시\n\n**조건부 `request` JSON 입력**\n- `scheduleInputType=DATE_AND_TIME`: `availableStartTime`, `availableEndTime` 필수\n- `scheduleInputType=DATE_ONLY`: 시간 필드 미전송\n\n`coverImage`는 선택 파일 파트이며, 사진이 없으면 생략합니다.\n","value":{"request":{"name":"토요일 저녁 모임","description":"오랜만에 같이 저녁 먹어요.","maxParticipants":6,"planningType":"SCHEDULE_AND_PLACE","scheduleInputType":"DATE_AND_TIME","availableStartTime":"17:00","availableEndTime":"23:00","scheduleCandidateDates":["2026-07-10","2026-07-11"],"scheduleResponse":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]},"departure":{"name":"회사","address":"서울 강남구 테헤란로 123","latitude":37.498095,"longitude":127.02761,"transportationMode":"PUBLIC_TRANSIT"},"deadlineMinutes":1440}}},"SCHEDULE_AND_PLACE_DATE_ONLY":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY`\n- `PLACE_ONLY`\n- `SCHEDULE_AND_PLACE` ← 이 예시\n\n**허용 `scheduleInputType`**\n- `DATE_ONLY` ← 이 예시\n- `DATE_AND_TIME`\n\n공통 시간대는 보내지 않고 `coverImage`는 선택 사항입니다.\n","value":{"request":{"name":"주말 모임 정하기","description":"가능한 날짜와 장소를 정해요.","maxParticipants":6,"planningType":"SCHEDULE_AND_PLACE","scheduleInputType":"DATE_ONLY","scheduleCandidateDates":["2026-07-10","2026-07-11"],"departure":{"name":"회사","address":"서울 강남구 테헤란로 123","latitude":37.498095,"longitude":127.02761,"transportationMode":"PUBLIC_TRANSIT"},"deadlineMinutes":1440}}},"SCHEDULE_ONLY_DATE_AND_TIME":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY` ← 이 예시\n- `PLACE_ONLY`\n- `SCHEDULE_AND_PLACE`\n\n**허용 `scheduleInputType`**\n- `DATE_ONLY`\n- `DATE_AND_TIME` ← 이 예시\n\n장소 관련 필드는 보내지 않고 `coverImage`는 선택 사항입니다.\n","value":{"request":{"name":"저녁 일정 정하기","description":"가능한 날짜와 시간을 정해요.","maxParticipants":4,"planningType":"SCHEDULE_ONLY","scheduleInputType":"DATE_AND_TIME","availableStartTime":"17:00","availableEndTime":"23:00","scheduleCandidateDates":["2026-07-10","2026-07-11"],"scheduleResponse":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]},"deadlineMinutes":180}}},"SCHEDULE_ONLY_DATE_ONLY":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY` ← 이 예시\n- `PLACE_ONLY`\n- `SCHEDULE_AND_PLACE`\n\n**허용 `scheduleInputType`**\n- `DATE_ONLY` ← 이 예시\n- `DATE_AND_TIME`\n\n장소 추천 전략과 출발지 필드는 보내지 않습니다.\n`coverImage`는 선택 파일 파트이며, 사진이 없으면 생략합니다.\n","value":{"request":{"name":"주말 일정 정하기","description":"가능한 날짜를 정해요.","maxParticipants":4,"planningType":"SCHEDULE_ONLY","scheduleInputType":"DATE_ONLY","scheduleCandidateDates":["2026-07-10","2026-07-11"],"deadlineMinutes":180}}},"PLACE_ONLY":{"description":"**허용 `planningType`**\n- `SCHEDULE_ONLY`\n- `PLACE_ONLY` ← 이 예시\n- `SCHEDULE_AND_PLACE`\n\n**`scheduleInputType`**\n- `PLACE_ONLY`에서는 보내지 않습니다.\n\n**출발지 표시 이름**\n- `departure.name`은 선택 입력입니다. 생략하면 장소 현황 응답에서 `departure.address`를 표시합니다.\n\n`coverImage`는 선택 파일 파트이며, 사진이 없으면 생략합니다.\n","value":{"request":{"name":"카페 장소 정하기","description":"만날 장소를 정해요.","maxParticipants":8,"planningType":"PLACE_ONLY","departure":{"address":"서울 강남구 테헤란로 123","latitude":37.498095,"longitude":127.02761,"transportationMode":"PUBLIC_TRANSIT"},"deadlineMinutes":720}}}},"encoding":{"request":{"contentType":"application/json"}}}}},"responses":{"201":{"description":"모임 생성 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateMeetingResponse"}}}},"400":{"description":"request JSON 형식 검증 실패 또는 선택한 모임 플로우와 방장 참여 입력의 불일치","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"examples":{"요청 형식 검증 실패":{"description":"요청 형식 검증 실패","value":{"code":"COMMON_VALIDATION_FAILED","status":400}},"모임 플로우와 방장 참여 입력 불일치":{"description":"모임 플로우와 방장 참여 입력 불일치","value":{"code":"INVALID_MEETING_PARTICIPATION_INPUT","status":400}},"지원하지 않는 출발지 지역":{"description":"지원하지 않는 출발지 지역","value":{"code":"UNSUPPORTED_DEPARTURE_REGION","status":400}}}}}},"413":{"description":"커버 파일 10MB, 원본 이미지 13MP 또는 한 변 8,000px 제한 초과","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateMeetingResponse"}}}},"415":{"description":"JPEG 또는 PNG가 아닌 커버 파일","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateMeetingResponse"}}}},"503":{"description":"커버 이미지 저장소 일시 이용 불가","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateMeetingResponse"}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/{meetingId}/schedule-confirmation":{"post":{"tags":["Meeting"],"summary":"일정 확정","description":"방장만 실행할 수 있습니다. 일정과 장소가 모두 확정되면 모임이 최종 확정됩니다.","operationId":"confirmSchedule","parameters":[{"name":"meetingId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmScheduleRequest"}}},"required":true},"responses":{"200":{"description":"OK","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeetingConfirmationResponse"}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/{meetingId}/place-confirmation":{"post":{"tags":["Meeting"],"summary":"장소 확정","description":"방장만 실행할 수 있습니다. 일정과 장소가 모두 확정되면 모임이 최종 확정됩니다.","operationId":"confirmPlace","parameters":[{"name":"meetingId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmPlaceRequest"}}},"required":true},"responses":{"200":{"description":"OK","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeetingConfirmationResponse"}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/invitations/{inviteCode}/members":{"post":{"tags":["Meeting"],"summary":"로그인 회원 모임 참여","description":"**출발지 이름 공통 안내**\n장소 조율이 포함된 `SCHEDULE_AND_PLACE` 또는 `PLACE_ONLY` 모임에서는 `departure`를 입력합니다.\n\n모임 생성 응답의 inviteCode를 경로 변수에 넣어 현재 로그인한 서비스 사용자를 모임 참여자로 생성합니다.<br>\n회원 기본 닉네임과 다른 모임 안 표시 닉네임을 입력할 수 있습니다.\n일정 조율 모임은 scheduleInputType에 맞춰 scheduleResponse.availableDates 또는 scheduleResponse.availableTimeRanges를 입력하고,\n장소 조율 모임은 departure를 함께 입력해야 합니다.\n로그인 회원은 Bearer Access Token으로 식별하므로 참여 비밀번호를 입력하지 않습니다.\n생성에 사용한 방장 토큰이 아니라 참여할 다른 회원의 Access Token을 사용해야 합니다.\n","operationId":"joinMember","parameters":[{"name":"inviteCode","in":"path","description":"모임 생성 응답의 inviteCode 값입니다.","required":true,"schema":{"type":"string"},"example":"ABCD234567"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberJoinRequest"},"examples":{"SCHEDULE_AND_PLACE_DATE_AND_TIME":{"description":"모임 생성의 SCHEDULE_AND_PLACE_DATE_AND_TIME 예시와 연결됩니다. 생성에 사용한 방장 토큰이 아닌 참여 회원의 Bearer Access Token을 설정하고, 초대 조회로 받은 모임장 선택 시간대 안에서만 가능한 날짜·시간대를 선택합니다.","value":{"nickname":"민지일","scheduleResponse":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]},"departure":{"name":"집","address":"서울 마포구 월드컵북로 1","latitude":37.5665,"longitude":126.978,"transportationMode":"CAR"}}},"SCHEDULE_AND_PLACE_DATE_ONLY":{"description":"날짜와 장소를 함께 정하는 모임입니다. 방장이 만든 후보 날짜 중 가능한 날짜와 출발지를 입력합니다.","value":{"nickname":"민지이","scheduleResponse":{"availableDates":["2026-07-10","2026-07-11"]},"departure":{"name":"학교","address":"서울 성동구 왕십리로 222","latitude":37.561,"longitude":127.0365,"transportationMode":"PUBLIC_TRANSIT"}}},"SCHEDULE_ONLY_DATE_ONLY":{"description":"날짜만 정하는 일정 모임입니다. 방장이 만든 후보 날짜 중 가능한 날짜만 입력합니다.","value":{"nickname":"민지","scheduleResponse":{"availableDates":["2026-07-10","2026-07-11"]}}},"SCHEDULE_ONLY_DATE_AND_TIME":{"description":"일정과 시간을 정하는 일정 모임입니다. 방장이 만든 후보 날짜 안에서 가능한 시간대를 입력합니다.","value":{"nickname":"민지시간","scheduleResponse":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]}}},"PLACE_ONLY":{"description":"모임 생성의 PLACE_ONLY 예시와 연결됩니다. 출발지만 입력하고 scheduleResponse는 포함하지 않습니다. departure.name은 선택 입력이며 생략하면 출발지 주소가 표시됩니다.","value":{"nickname":"민지","departure":{"address":"서울 마포구 월드컵북로 1","latitude":37.5665,"longitude":126.978,"transportationMode":"CAR"}}}}}},"required":true},"responses":{"201":{"description":"로그인 회원 모임 참여 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ParticipantJoinResponse"}}}},"400":{"description":"요청 형식 검증 실패 또는 모임 설정과 참여 입력의 불일치","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"examples":{"요청 형식 검증 실패":{"description":"요청 형식 검증 실패","value":{"code":"COMMON_VALIDATION_FAILED","status":400}},"모임 설정과 참여 입력 불일치":{"description":"모임 설정과 참여 입력 불일치","value":{"code":"INVALID_MEETING_PARTICIPATION_INPUT","status":400}},"지원하지 않는 출발지 지역":{"description":"지원하지 않는 출발지 지역","value":{"code":"UNSUPPORTED_DEPARTURE_REGION","status":400}}}}}},"401":{"description":"Access Token 없음, 만료 또는 유효하지 않음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"404":{"description":"초대 코드에 해당하는 모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"MEETING_INVITATION_NOT_FOUND","status":404}}}},"409":{"description":"회원 중복 참여, 모임 인원 초과 또는 참여 마감","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"examples":{"이미 참여한 회원":{"description":"이미 참여한 회원","value":{"code":"DUPLICATE_MEETING_PARTICIPANT_MEMBER","status":409}},"모임 인원 초과":{"description":"모임 인원 초과","value":{"code":"MEETING_PARTICIPANT_LIMIT_EXCEEDED","status":409}},"모임 참여 마감":{"description":"모임 참여 마감","value":{"code":"MEETING_PARTICIPATION_CLOSED","status":409}}}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/invitations/{inviteCode}/guests":{"post":{"tags":["Meeting"],"summary":"게스트 모임 참여","description":"**출발지 이름 공통 안내**\n장소 조율이 포함된 `SCHEDULE_AND_PLACE` 또는 `PLACE_ONLY` 모임에서는 `departure`를 입력합니다.\n\n모임 생성 응답의 inviteCode를 경로 변수에 넣어, 해당 모임에 게스트 참여자를 생성합니다.<br>\n닉네임, 비밀번호와 모임 유형에 맞는 일정 또는 출발지 정보를 한 번에 저장합니다.\n일정 조율 모임은 scheduleInputType에 맞춰 scheduleResponse.availableDates 또는 scheduleResponse.availableTimeRanges를 입력하고,\n장소 조율 모임은 departure를 필수로 입력해야 합니다.\n게스트 참여에는 Bearer Access Token을 사용하지 않습니다.\n게스트 재입장/수정 인증은 정책 확정 후 함께 보완할 예정입니다.\n","operationId":"joinGuest","parameters":[{"name":"inviteCode","in":"path","description":"모임 생성 응답의 inviteCode 값입니다.","required":true,"schema":{"type":"string"},"example":"ABCD234567"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestJoinRequest"},"examples":{"SCHEDULE_AND_PLACE_DATE_AND_TIME":{"description":"모임 생성의 SCHEDULE_AND_PLACE_DATE_AND_TIME 예시와 연결됩니다. 초대 조회로 받은 모임장 선택 시간대 안에서만 가능한 날짜·시간대를 선택합니다.","value":{"nickname":"민지친구","password":"1234","scheduleResponse":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]},"departure":{"name":"회사","address":"서울 강남구 테헤란로 123","latitude":37.498095,"longitude":127.02761,"transportationMode":"PUBLIC_TRANSIT"}}},"SCHEDULE_AND_PLACE_DATE_ONLY":{"description":"날짜와 장소를 함께 정하는 모임입니다. 방장이 만든 후보 날짜 중 가능한 날짜와 출발지를 입력합니다.","value":{"nickname":"민지친구","password":"1234","scheduleResponse":{"availableDates":["2026-07-10","2026-07-11"]},"departure":{"name":"집","address":"서울 마포구 월드컵북로 1","latitude":37.5665,"longitude":126.978,"transportationMode":"CAR"}}},"SCHEDULE_ONLY_DATE_ONLY":{"description":"날짜만 정하는 일정 모임입니다. 방장이 만든 후보 날짜 중 가능한 날짜만 입력합니다.","value":{"nickname":"민지친구","password":"1234","scheduleResponse":{"availableDates":["2026-07-10","2026-07-11"]}}},"SCHEDULE_ONLY_DATE_AND_TIME":{"description":"일정과 시간을 정하는 일정 모임입니다. 방장이 만든 후보 날짜 안에서 가능한 시간대를 입력합니다.","value":{"nickname":"민지친구","password":"1234","scheduleResponse":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]}}},"PLACE_ONLY":{"description":"모임 생성의 PLACE_ONLY 예시와 연결됩니다. 출발지만 입력하고 scheduleResponse는 포함하지 않습니다. departure.name은 선택 입력이며 생략하면 출발지 주소가 표시됩니다.","value":{"nickname":"민지친구","password":"1234","departure":{"address":"서울 강남구 테헤란로 123","latitude":37.498095,"longitude":127.02761,"transportationMode":"PUBLIC_TRANSIT"}}}}}},"required":true},"responses":{"201":{"description":"게스트 참여 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ParticipantJoinResponse"}}}},"400":{"description":"요청 형식 검증 실패 또는 모임 설정과 참여 입력의 불일치","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"examples":{"요청 형식 검증 실패":{"description":"요청 형식 검증 실패","value":{"code":"COMMON_VALIDATION_FAILED","status":400}},"모임 설정과 참여 입력 불일치":{"description":"모임 설정과 참여 입력 불일치","value":{"code":"INVALID_MEETING_PARTICIPATION_INPUT","status":400}},"지원하지 않는 출발지 지역":{"description":"지원하지 않는 출발지 지역","value":{"code":"UNSUPPORTED_DEPARTURE_REGION","status":400}}}}}},"404":{"description":"초대 코드에 해당하는 모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"MEETING_INVITATION_NOT_FOUND","status":404}}}},"409":{"description":"닉네임 중복, 모임 인원 초과 또는 참여 마감","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"examples":{"모임 참여 마감":{"description":"모임 참여 마감","value":{"code":"MEETING_PARTICIPATION_CLOSED","status":409}},"모임 인원 초과":{"description":"모임 인원 초과","value":{"code":"MEETING_PARTICIPANT_LIMIT_EXCEEDED","status":409}},"모임 안 닉네임 중복":{"description":"모임 안 닉네임 중복","value":{"code":"DUPLICATE_MEETING_PARTICIPANT_NICKNAME","status":409}}}}}}}}},"/api/meetings/invitations/{inviteCode}/guests/entry":{"post":{"tags":["Meeting"],"summary":"게스트 참여 진입 분기","description":"게스트 참여 요청 전에 호출하는 공개 분기 API입니다. Bearer Access Token은 사용하지 않습니다.\n\n- `NEW_GUEST`: 해당 모임에서 게스트 닉네임이 미사용입니다. 신규 게스트 참여 입력 플로우로 이동합니다.\n- `EXISTING_GUEST`: 해당 닉네임의 게스트가 있고 비밀번호가 일치합니다. 모임 현황 플로우로 이동합니다.\n- 이미 사용 중인 닉네임의 비밀번호가 일치하지 않으면 `DUPLICATE_MEETING_PARTICIPANT_NICKNAME`을 반환합니다. 비밀번호 불일치 여부는 별도 오류로 노출하지 않습니다.\n","operationId":"checkGuestEntry","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestEntryRequest"},"examples":{"GUEST_ENTRY":{"description":"모임 안에서 사용할 게스트 닉네임과 숫자 4자리 비밀번호를 입력합니다.","value":{"nickname":"민지","password":"1234"}}}}},"required":true},"responses":{"200":{"description":"게스트 참여 진입 분기 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"examples":{"NEW_GUEST":{"description":"신규 게스트 참여 입력 플로우로 이동합니다.","value":{"entryType":"NEW_GUEST"}},"EXISTING_GUEST":{"description":"기존 게스트로 확인되었습니다. 모임 현황 플로우로 이동합니다.","value":{"entryType":"EXISTING_GUEST"}}}}}},"400":{"description":"유효하지 않은 닉네임 또는 비밀번호","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuestEntryResponse"}}}},"404":{"description":"초대 코드에 해당하는 모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GuestEntryResponse"}}}},"409":{"description":"이미 사용 중인 게스트 닉네임","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"DUPLICATE_MEETING_PARTICIPANT_NICKNAME","status":409}}}}}}},"/api/me/places":{"get":{"tags":["My place"],"summary":"내 장소 목록 조회","description":"현재 로그인한 회원이 저장한 장소만 조회합니다.\n\n- 정렬: `createdAt` 내림차순이며, 저장 시각이 같으면 `id` 내림차순\n- 중복: 같은 위치나 같은 별칭이 여러 번 저장되어 있으면 각각 반환\n- 개수: 현재 저장 및 조회 개수 제한 없음\n- 빈 목록: 오류가 아니라 `{ \"places\": [] }` 반환\n","operationId":"findAll","responses":{"200":{"description":"내 장소 목록 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/SavedPlaceListResponse"}}}},"401":{"description":"Access Token 없음, 만료 또는 유효하지 않음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["My place"],"summary":"내 장소 저장","description":"출발지 통합 검색에서 사용자가 선택한 결과를 내 장소로 저장합니다.\n\n**요청 구성 방법**\n1. `POST /api/departure-places/searches`로 장소를 검색합니다.\n2. 응답의 `results`에서 사용자가 하나를 선택합니다.\n3. 선택 결과의 필드를 그대로 복사하고 사용자가 입력한 `alias`를 추가합니다.\n\n`type`은 원본 검색 결과가 지하철역(`STATION`), 주소(`ADDRESS`), 일반 장소(`PLACE`) 중\n무엇인지 보존합니다. 저장·수정·삭제 권한에는 영향을 주지 않습니다.\n\n동일한 위치, 주소, 표시명 또는 별칭의 중복 저장을 허용하며 현재 저장 개수 제한은 없습니다.\n저장된 위치 스냅샷은 변경하지 않고, 이후 수정 API에서는 별칭만 변경할 수 있습니다.\n\n**장소 용도**\n- `category`에는 `HOME`, `WORK`, `OTHER` 중 하나를 보낼 수 있습니다.\n- `category`를 생략하면 서버가 `OTHER`로 저장합니다.\n","operationId":"save","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavePlaceRequest"},"examples":{"WORK":{"description":"WORK","value":{"alias":"회사","category":"WORK","type":"PLACE","displayName":"강남파이낸스센터","address":"서울 강남구 테헤란로 152","roadAddress":"서울 강남구 테헤란로 152","jibunAddress":"서울 강남구 역삼동 737","latitude":37.500028,"longitude":127.036502}}}}},"required":true},"responses":{"201":{"description":"내 장소 저장 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/SavedPlaceResponse"}}}},"400":{"description":"요청값 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"Access Token 없음, 만료 또는 유효하지 않음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/feedbacks":{"get":{"tags":["Feedback"],"summary":"내 피드백 이력 조회","description":"현재 로그인한 회원이 제출한 피드백만 최신 제출 순으로 반환합니다. 제출 이력이 없으면 빈 배열을 반환합니다.","operationId":"findMyFeedbacks","responses":{"200":{"description":"피드백 이력 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/FeedbackListResponse"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/FeedbackListResponse"}}}},"403":{"description":"닉네임 온보딩 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/FeedbackListResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Feedback"],"summary":"피드백 제출","description":"현재 로그인한 회원의 사용자 식별자와 함께 피드백을 저장합니다. 사용자 식별자는 요청 본문으로 받지 않습니다.","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeedbackRequest"}}},"required":true},"responses":{"201":{"description":"피드백 제출 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/FeedbackResponse"}}}},"400":{"description":"피드백 내용 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"403":{"description":"닉네임 온보딩 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/departure-places/searches":{"post":{"tags":["Departure place"],"summary":"출발지 통합 검색","description":"인증:\n- Access Token: 선택 — 회원 검색 시 사용\n- inviteCode: 조건부 필수 — Access Token이 없는 게스트에게 필수\n- 둘 다 전달: Access Token 우선, inviteCode 무시\n- 잘못된 Access Token: 401, inviteCode 방식으로 fallback하지 않음\n\n통합 이유:\n- 회원과 게스트의 검색 요청·응답 및 카카오 검색 로직이 동일함\n- 인증 수단만 서버에서 분기해 하나의 API로 제공함\n\n검색:\n- 정확히 `~역`: 지하철역 우선 검색 후 결과가 없으면 일반 장소 검색\n- 도로명·지번 주소형(`번지` 포함): 주소 우선 검색 후 결과가 없으면 일반 장소 검색\n- 단독 지명·지하 주소 및 그 외: 일반 장소 검색\n- 결과 좌표: WGS84 위도·경도 포함\n","operationId":"search","parameters":[{"name":"inviteCode","in":"query","description":"회원: 선택(전달해도 무시) / 게스트: 필수인 모임 초대코드","required":false,"schema":{"type":"string"},"example":"ABCD234567"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeparturePlaceSearchRequest"},"examples":{"STATION":{"description":"STATION","value":{"keyword":"서울역"}},"ADDRESS":{"description":"ADDRESS","value":{"keyword":"서울 강남구 테헤란로 152"}},"PLACE":{"description":"PLACE","value":{"keyword":"스타벅스 강남역점"}}}}},"required":true},"responses":{"200":{"description":"출발지 통합 검색 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeparturePlaceSearchResponse"}}}},"400":{"description":"검색어 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"Access Token과 초대코드가 모두 없거나, 전달한 Access Token이 유효하지 않음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"404":{"description":"게스트 요청의 초대코드에 해당하는 모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"MEETING_INVITATION_NOT_FOUND","status":404}}}},"503":{"description":"출발지 검색 서비스 또는 카카오 REST API 키를 사용할 수 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"DEPARTURE_PLACE_SEARCH_UNAVAILABLE","status":503}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]},{}]}},"/api/auth/refresh":{"post":{"tags":["Auth"],"summary":"로그인 연장","description":"저장된 갱신 토큰으로 새 Access Token과 갱신 토큰을 발급합니다.","operationId":"refresh","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenRequest"}}},"required":true},"responses":{"200":{"description":"로그인 연장 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"갱신 토큰 요청값 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"갱신 토큰이 없거나 만료 또는 무효화됨","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}}}}},"/api/auth/logout":{"post":{"tags":["Auth"],"summary":"현재 기기 로그아웃","description":"현재 기기에 저장된 갱신 토큰과 Access Token을 즉시 무효화합니다. 다른 기기의 로그인은 유지됩니다.","operationId":"logout","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenRequest"}}},"required":true},"responses":{"204":{"description":"현재 기기 로그아웃 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}},"400":{"description":"갱신 토큰 요청값 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"갱신 토큰이 없거나 만료 또는 무효화됨","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}}}}},"/api/auth/kakao":{"post":{"tags":["Auth"],"summary":"카카오 로그인","description":"프론트엔드가 카카오 GET 콜백의 state를 검증한 뒤 일회용 code와 콜백 환경 식별자를 전달합니다.\nredirectTarget은 local, dev, prod 중 서버에 등록된 값만 허용하며 URI 자체는 전달하지 않습니다.\n서버가 카카오와 code를 교환하고 회원번호를 확인한 뒤 Moyeo Access Token을 발급합니다.\n최초 로그인도 즉시 가입 처리하며 nickname은 null, onboardingCompleted는 false로 반환합니다.\n","operationId":"loginKakao","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KakaoLoginRequest"}}},"required":true},"responses":{"200":{"description":"카카오 로그인 및 Access Token 발급 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"code 요청값 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"code가 유효하지 않거나 만료 또는 재사용됨","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"SOCIAL_LOGIN_FAILED","status":401}}}},"503":{"description":"카카오 로그인 서비스의 일시적 장애 또는 서버 설정 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"SOCIAL_LOGIN_UNAVAILABLE","status":503}}}}}}},"/api/auth/kakao/native":{"post":{"tags":["Auth"],"summary":"카카오 네이티브 SDK 로그인","description":"네이티브 앱이 카카오 SDK로 발급받은 Access Token을 전달합니다.\n서버는 토큰으로 카카오 사용자 정보를 조회해 회원번호를 확인한 뒤 Moyeo Access Token을 발급합니다.\n카카오 Access Token은 로그인 요청 처리 후 저장하지 않습니다.\n브라우저 로그인은 별도 `POST /api/auth/kakao` API를 사용합니다.\n","operationId":"loginKakaoNative","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KakaoNativeLoginRequest"}}},"required":true},"responses":{"200":{"description":"카카오 네이티브 SDK 로그인 및 Access Token 발급 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"accessToken 요청값 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"카카오 Access Token이 유효하지 않거나 만료됨","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"SOCIAL_LOGIN_FAILED","status":401}}}},"503":{"description":"카카오 로그인 서비스의 일시적 장애 또는 서버 설정 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"SOCIAL_LOGIN_UNAVAILABLE","status":503}}}}}}},"/api/auth/dev/tokens":{"post":{"tags":["Development Auth"],"summary":"개발 테스트 계정 Access Token 일괄 발급","description":"local 및 dev 프로필에서만 노출됩니다. 요청 본문 없이 테스트 사용자 1과 2의 Access Token을 함께 반환합니다.","operationId":"issueTokens","responses":{"200":{"description":"두 테스트 계정의 Access Token 발급 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DevAuthTokensResponse"}}}}}}},"/api/auth/apple":{"post":{"tags":["Auth"],"summary":"Apple 로그인","description":"프론트가 Apple GET 콜백에서 받은 일회용 code, 로그인 요청 전에 만든 nonce, 콜백 환경 식별자를 전달합니다.\nredirectTarget은 dev 또는 prod만 허용하며 URI 자체는 전달하지 않습니다.\n서버가 Apple과 code를 교환하고 사용자 정보를 검증한 뒤 Moyeo Access Token을 발급합니다.\n최초 로그인도 즉시 가입 처리되며 nickname은 null, onboardingCompleted는 false로 반환됩니다.\n","operationId":"loginApple","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppleLoginRequest"}}},"required":true},"responses":{"200":{"description":"Apple 로그인 및 Access Token 발급 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"code 또는 nonce 요청값 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"code가 유효하지 않거나 만료·재사용됐거나 Apple 응답 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"SOCIAL_LOGIN_FAILED","status":401}}}},"503":{"description":"Apple 로그인 서비스의 일시적 장애 또는 서버 설정 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"SOCIAL_LOGIN_UNAVAILABLE","status":503}}}}}}},"/api/auth/apple/native":{"post":{"tags":["Auth"],"summary":"Apple 네이티브 SDK 로그인","description":"네이티브 앱이 Apple SDK에서 받은 identityToken, authorizationCode, nonce를 전달합니다. 서버는 App ID audience와 nonce, 두 identity token의 동일한 sub를 검증한 뒤 Access Token을 발급합니다.","operationId":"loginAppleNative","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppleNativeLoginRequest"}}},"required":true},"responses":{"200":{"description":"Apple 네이티브 SDK 로그인 및 Access Token 발급 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"identityToken, authorizationCode 또는 nonce 요청값 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Apple identity token 또는 authorization code 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"503":{"description":"Apple 로그인 서비스 설정 미완료 또는 일시적 장애","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}}}}},"/api/users/me/profile-color":{"patch":{"tags":["Member"],"summary":"기본 프로필 색상 수정","description":"현재 회원의 기본 프로필 색상을 GRAY, RED, PURPLE, ORANGE 중 하나로 변경합니다. 현재는 색상 프로필만 지원합니다.","operationId":"updateProfileColor","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileColorRequest"}}},"required":true},"responses":{"200":{"description":"기본 프로필 색상 수정 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"400":{"description":"지원하지 않는 색상 또는 요청 본문 오류","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"403":{"description":"최초 닉네임 온보딩이 완료되지 않은 사용자입니다.","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/users/me/nickname":{"patch":{"tags":["Member"],"summary":"기본 닉네임 수정","description":"현재 사용자의 기본 닉네임을 수정합니다.\n모임 안에서 이미 사용 중인 방장·회원 참여자 닉네임은 변경하지 않습니다.\n","operationId":"updateNickname","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNicknameRequest"}}},"required":true},"responses":{"200":{"description":"기본 닉네임 수정 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"400":{"description":"닉네임 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"403":{"description":"최초 닉네임 온보딩이 완료되지 않은 사용자입니다. 먼저 PUT /api/users/me/onboarding으로 기본 닉네임을 등록해야 합니다.","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/{meetingId}/participants/me/nickname":{"patch":{"tags":["Meeting"],"summary":"모임 내 본인 닉네임 수정","description":"방장 또는 로그인 회원이 해당 모임에서 표시되는 본인 닉네임만 수정합니다. 기본 프로필 닉네임은 변경하지 않으며, 회원·방장 닉네임 중복은 허용됩니다.","operationId":"updateMeetingParticipantNickname","parameters":[{"name":"meetingId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMeetingParticipantNicknameRequest"}}},"required":true},"responses":{"200":{"description":"모임 내 닉네임 수정 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeetingParticipantNicknameResponse"}}}},"400":{"description":"닉네임 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}},"404":{"description":"모임 또는 본인 참여 정보 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"examples":{"MEETING_NOT_FOUND":{"description":"MEETING_NOT_FOUND","value":{"code":"MEETING_NOT_FOUND","status":404}},"MEETING_PARTICIPANT_NOT_FOUND":{"description":"MEETING_PARTICIPANT_NOT_FOUND","value":{"code":"MEETING_PARTICIPANT_NOT_FOUND","status":404}}}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/invitations/{inviteCode}/members/me/participation/schedule-response":{"patch":{"tags":["Meeting"],"summary":"내 일정 참여 응답 수정","description":"로그인한 방장 또는 회원의 일정 가능 응답 전체를 교체합니다. DATE_ONLY는 availableDates만, DATE_AND_TIME은 availableTimeRanges만 보냅니다. 일정 조율이 없는 모임에서는 수정할 수 없습니다.","operationId":"updateMyScheduleResponse","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponseRequest"},"examples":{"DATE_ONLY":{"description":"기존 후보 날짜 중 가능한 날짜만 다시 선택합니다.","value":{"availableDates":["2026-07-10","2026-07-12"]}},"DATE_AND_TIME":{"description":"초대 조회로 받은 모임장 선택 시간대 안에서 가능한 시간대를 다시 선택합니다.","value":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]}}}}},"required":true},"responses":{"200":{"description":"내 일정 참여 응답 수정 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"400":{"description":"모임 유형과 맞지 않거나 유효하지 않은 일정 응답","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"403":{"description":"닉네임 온보딩 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"examples":{"ONBOARDING_REQUIRED":{"description":"ONBOARDING_REQUIRED","value":{"code":"ONBOARDING_REQUIRED","status":403}}}}}},"404":{"description":"초대 코드 또는 본인 참여 정보 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"409":{"description":"마감 또는 확정된 모임","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/invitations/{inviteCode}/members/me/participation/departure":{"patch":{"tags":["Meeting"],"summary":"내 출발지 참여 응답 수정","description":"로그인한 방장 또는 회원의 출발지와 교통수단 응답 전체를 교체합니다. 장소 조율이 없는 모임에서는 수정할 수 없습니다.","operationId":"updateMyDeparture","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepartureRequest"}}},"required":true},"responses":{"200":{"description":"내 출발지 참여 응답 수정 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"400":{"description":"모임 유형과 맞지 않거나 유효하지 않은 출발지 응답","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"examples":{"지원하지 않는 출발지 지역":{"description":"지원하지 않는 출발지 지역","value":{"code":"UNSUPPORTED_DEPARTURE_REGION","status":400}}}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"403":{"description":"닉네임 온보딩 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"examples":{"ONBOARDING_REQUIRED":{"description":"ONBOARDING_REQUIRED","value":{"code":"ONBOARDING_REQUIRED","status":403}}}}}},"404":{"description":"초대 코드 또는 본인 참여 정보 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"409":{"description":"마감 또는 확정된 모임","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/invitations/{inviteCode}/guests/{nickname}/participation/schedule-response":{"patch":{"tags":["Meeting"],"summary":"게스트 일정 참여 응답 수정","description":"초대 코드와 게스트 닉네임으로 대상을 식별한 뒤, 일정 응답 전체를 교체합니다.","operationId":"updateGuestScheduleResponse","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}},{"name":"nickname","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponseRequest"},"examples":{"DATE_ONLY":{"description":"DATE_ONLY","value":{"availableDates":["2026-07-10","2026-07-12"]}},"DATE_AND_TIME":{"description":"DATE_AND_TIME","value":{"availableTimeRanges":[{"candidateDate":"2026-07-10","startTime":"18:00","endTime":"20:00"}]}}}}},"required":true},"responses":{"200":{"description":"게스트 일정 참여 응답 수정 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"400":{"description":"유효하지 않은 일정 응답","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"404":{"description":"초대 코드 또는 게스트 참여 정보 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"409":{"description":"마감 또는 확정된 모임","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}}}}},"/api/meetings/invitations/{inviteCode}/guests/{nickname}/participation/departure":{"patch":{"tags":["Meeting"],"summary":"게스트 출발지 참여 응답 수정","description":"초대 코드와 게스트 닉네임으로 대상을 식별한 뒤, 출발지와 교통수단 응답을 교체합니다.","operationId":"updateGuestDeparture","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}},{"name":"nickname","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepartureRequest"},"example":{"name":"회사","address":"서울 마포구 월드컵북로 120","latitude":37.5665,"longitude":126.978,"transportationMode":"PUBLIC_TRANSIT"}}},"required":true},"responses":{"200":{"description":"게스트 출발지 참여 응답 수정 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"400":{"description":"유효하지 않은 출발지 응답","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"examples":{"지원하지 않는 출발지 지역":{"description":"지원하지 않는 출발지 지역","value":{"code":"UNSUPPORTED_DEPARTURE_REGION","status":400}}}}}},"404":{"description":"초대 코드 또는 게스트 참여 정보 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"409":{"description":"마감 또는 확정된 모임","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}}}}},"/api/me/places/{savedPlaceId}":{"delete":{"tags":["My place"],"summary":"내 장소 삭제","description":"현재 로그인한 회원이 소유한 저장 장소를 삭제하고 본문 없이 `204 No Content`를 반환합니다.\n검색 이력이나 모임 참여자에 이미 저장된 출발지 스냅샷은 함께 삭제되지 않습니다.\n다른 회원의 장소 ID도 존재 여부를 노출하지 않고 `SAVED_PLACE_NOT_FOUND`로 응답합니다.\n","operationId":"delete","parameters":[{"name":"savedPlaceId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"내 장소 삭제 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}},"401":{"description":"Access Token 없음, 만료 또는 유효하지 않음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"404":{"description":"본인 소유의 저장 장소가 아님 또는 장소 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"SAVED_PLACE_NOT_FOUND","status":404}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["My place"],"summary":"내 장소 별칭 수정","description":"현재 로그인한 회원이 소유한 저장 장소의 `alias`만 수정합니다.\n\n`type`, `displayName`, 주소, 위도·경도 등 선택 당시의 위치 스냅샷은 변경되지 않습니다.\n위치 자체를 바꾸려면 기존 장소를 삭제하고 새로운 검색 결과를 저장해야 합니다.\n다른 회원의 장소 ID도 존재 여부를 노출하지 않고 `SAVED_PLACE_NOT_FOUND`로 응답합니다.\n","operationId":"rename","parameters":[{"name":"savedPlaceId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenameSavedPlaceRequest"},"example":{"alias":"새 회사"}}},"required":true},"responses":{"200":{"description":"내 장소 별칭 수정 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/SavedPlaceResponse"}}}},"400":{"description":"요청값 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"Access Token 없음, 만료 또는 유효하지 않음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"404":{"description":"본인 소유의 저장 장소가 아님 또는 장소 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"SAVED_PLACE_NOT_FOUND","status":404}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/health":{"get":{"tags":["health-controller"],"operationId":"health","responses":{"200":{"description":"OK","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}}}},"/api/users/me":{"get":{"tags":["Member"],"summary":"마이페이지 조회","description":"현재 회원의 기본 닉네임, 프로필 색상, 저장 출발지 목록을 함께 반환합니다. 출발지 목록은 GET /api/me/places와 같은 데이터를 마이페이지 화면용으로 복제해 반환하며, 피드백 이력은 포함하지 않습니다.","operationId":"getMyPage","responses":{"200":{"description":"마이페이지 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyPageResponse"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyPageResponse"}}}},"403":{"description":"최초 닉네임 온보딩이 완료되지 않은 사용자입니다.","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Member"],"summary":"회원 탈퇴","description":"현재 회원을 탈퇴 처리하고 본인이 생성한 모든 모임과 개인 소유 데이터를 삭제합니다.\n별도 소셜 로그인 없이 저장된 연결 정보로 Apple 토큰 철회 또는 Kakao 연결 해제를 완료합니다.\n방장인 모임은 참여자·일정 후보·일정 가능 정보·모임 출발지 검색 이력·커버 이미지까지 삭제합니다.\n다른 회원이 생성한 모임에서는 본인의 참여 행과 일정·출발지 정보를 모두 삭제합니다.\n따라서 탈퇴 회원은 해당 모임의 참여자 목록, 인원 수, 일정 및 장소 계산에 포함되지 않습니다.\n닉네임 온보딩을 완료하지 않은 회원도 탈퇴할 수 있습니다.\n","operationId":"withdraw","responses":{"204":{"description":"소셜 연결 해제 및 회원 탈퇴 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"503":{"description":"소셜 연결 해제를 완료할 수 없음. 로컬 계정은 유지됩니다.","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"SOCIAL_LOGIN_UNAVAILABLE","status":503}}}},"500":{"description":"활성 계정의 소셜 연결 정보가 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_INTERNAL_SERVER_ERROR","status":500}}}}},"security":[{"bearerAuth":[]}]}},"/api/time":{"get":{"tags":["Time"],"summary":"서버 현재 시간 조회","description":"서버의 현재 시간을 UTC 기준 ISO-8601 형식으로 반환합니다. 클라이언트의 날짜 및 시간 판단 기준을 서버와 동기화할 때 사용합니다.","operationId":"getServerTime","responses":{"200":{"description":"서버 현재 시간 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ServerTimeResponse"}}}}}}},"/api/meetings/{meetingId}":{"get":{"tags":["Meeting"],"summary":"내 모임 상세 조회","description":"로그인 회원이 방장 또는 회원 참여자로 속한 모임의 상세 정보를 반환합니다. 참여자 목록의 isMe로 현재 사용자를 표시합니다.","operationId":"getMyMeetingDetail","parameters":[{"name":"meetingId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"내 모임 상세 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyMeetingDetailResponse"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyMeetingDetailResponse"}}}},"403":{"description":"닉네임 온보딩 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyMeetingDetailResponse"}}}},"404":{"description":"참여 중인 모임을 찾을 수 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyMeetingDetailResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Meeting"],"summary":"방장 모임 삭제","description":"방장은 진행 중·확정 모임을 포함해 자신이 생성한 모임을 삭제할 수 있습니다. 참여자, 일정 응답·후보, 모임 출발지 검색 이력과 커버 이미지도 함께 삭제합니다.","operationId":"deleteMeeting","parameters":[{"name":"meetingId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"모임 삭제 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"403":{"description":"닉네임 온보딩 미완료 또는 방장이 아님","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"examples":{"ONBOARDING_REQUIRED":{"description":"ONBOARDING_REQUIRED","value":{"code":"ONBOARDING_REQUIRED","status":403}},"MEETING_DELETION_FORBIDDEN":{"description":"MEETING_DELETION_FORBIDDEN","value":{"code":"MEETING_DELETION_FORBIDDEN","status":403}}}}}},"404":{"description":"모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"MEETING_NOT_FOUND","status":404}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/me":{"get":{"tags":["Meeting"],"summary":"내 모임 홈 목록","description":"로그인 회원이 방장 또는 회원 참여자로 속한 진행 중 및 확정 모임을 반환합니다.","operationId":"getMyMeetings","responses":{"200":{"description":"OK","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyMeetingListResponse"}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/invitations/{inviteCode}":{"get":{"tags":["Meeting"],"summary":"초대 코드로 모임 조회","description":"초대 링크 진입 화면에서 사용할 모임 정보를 조회합니다.<br>\n참여 가능 여부와 마감/정원 초과 안내 문구를 함께 반환합니다.\n로그인한 사용자는 선택적으로 `Authorization: Bearer {accessToken}` 헤더를 보내면\n이미 참여한 모임인지도 확인할 수 있습니다. 닉네임 온보딩 전 사용자도 조회할 수 있으며,\n헤더 없이 호출하면 기존 공개 조회와 동일하게 동작합니다.\n모임장 프로필 이미지는 아직 사용자 프로필 정책이 확정되지 않아 응답에 포함하지 않았고, 프로필 정책 확정 후 협의하여 확장할 예정입니다.\n진행상황 확인 버튼은 추후 VIEW-01 모임 현황 API와 연결됩니다.\n","operationId":"getInvitation","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"초대 코드 모임 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeetingInvitationResponse"},"examples":{"DATE_AND_TIME":{"description":"참여자가 날짜별 모임장 선택 시간대 안에서 가능한 시간을 선택하는 모임입니다.","value":{"meetingId":152,"name":"일정 조율","description":"일정을 조율합니다.","coverImageUrl":null,"maxParticipants":6,"planningType":"SCHEDULE_ONLY","status":"PLANNING","scheduleMode":"VOTE","scheduleInputType":"DATE_AND_TIME","scheduleCandidateDates":[{"candidateDate":"2026-08-02","availableTimeRanges":[{"startTime":"06:00:00","endTime":"12:00:00"}]}],"placeMode":"NONE","placeRecommendationStrategy":null,"deadlineAt":"2026-08-03T07:42:11","participantCount":1,"hostNickname":"모모링","participationStatus":{"canJoin":true,"reason":"AVAILABLE","message":null}}}}}}},"404":{"description":"초대 코드에 해당하는 모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"MEETING_INVITATION_NOT_FOUND","status":404}}}}}}},"/api/meetings/invitations/{inviteCode}/view":{"get":{"tags":["Meeting"],"summary":"모임 현황 조회","description":"확정 전 모임 상세 화면에서 표시할 기본 현황을 조회합니다.<br>\n로그인 없이 열람할 수 있으며, 참여 인원과 마감까지 남은 시간, 참여자 목록을 반환합니다.\n","operationId":"getMeetingView","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"모임 현황 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MeetingViewResponse"}}}},"404":{"description":"초대 코드에 해당하는 모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"MEETING_INVITATION_NOT_FOUND","status":404}}}}}}},"/api/meetings/invitations/{inviteCode}/view/schedules":{"get":{"tags":["Meeting"],"summary":"일정 조율 현황 조회","description":"확정 전 모임 상세 화면의 일정 조율 현황을 조회합니다.<br>\n저장된 참여자 가능 시간 슬롯을 집계해 1명 이상 참여 가능한 후보를 가능 인원순으로 최대 5개 반환합니다.\nsort는 LONGEST_MEETING 또는 EARLIEST_DATE를 사용할 수 있으며, 생략하면 EARLIEST_DATE로 정렬합니다.\n","operationId":"getScheduleView","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"EARLIEST_DATE"}}],"responses":{"200":{"description":"일정 조율 현황 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScheduleViewResponse"}}}},"400":{"description":"지원하지 않는 정렬 방식","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_INVALID_REQUEST","status":400}}}},"404":{"description":"초대 코드에 해당하는 모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"MEETING_INVITATION_NOT_FOUND","status":404}}}}}}},"/api/meetings/invitations/{inviteCode}/view/places":{"get":{"tags":["Meeting"],"summary":"장소 조율 현황 조회","description":"확정 전 모임 상세 화면의 장소 조율 현황을 조회합니다.<br>\n정원 미달 시 참여자 출발지 좌표와 상권 카탈로그를 이용한 직선거리 기반 미리보기를 반환합니다.<br>\n정원이 찬 뒤 최초 조회에서는 카카오 실제 이동시간으로 추천을 계산해 저장하며, 이후 조회는 저장된 평균·최대 이동시간 추천을 반환합니다.\n","operationId":"getPlaceView","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"장소 조율 현황 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceViewResponse"}}}},"503":{"description":"정원 충족 후 최초 실제 이동시간 계산 중 카카오 경로 조회 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceViewResponse"}}}},"404":{"description":"초대 코드에 해당하는 모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"MEETING_INVITATION_NOT_FOUND","status":404}}}}}}},"/api/meetings/invitations/{inviteCode}/members/me/participation":{"get":{"tags":["Meeting"],"summary":"내 모임 참여 응답 조회","description":"로그인한 방장 또는 회원이 수정 화면에 표시할 본인의 일정 가능 응답과 출발지 응답을 조회합니다. 게스트 참여자는 지원하지 않습니다.","operationId":"getMyParticipation","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"내 참여 응답 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"403":{"description":"닉네임 온보딩 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"examples":{"ONBOARDING_REQUIRED":{"description":"ONBOARDING_REQUIRED","value":{"code":"ONBOARDING_REQUIRED","status":403}}}}}},"404":{"description":"초대 코드 또는 본인 참여 정보 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/invitations/{inviteCode}/guests/{nickname}/participation":{"get":{"tags":["Meeting"],"summary":"게스트 모임 참여 응답 조회","description":"초대 코드와 게스트 닉네임으로 식별한 게스트의 일정 가능 응답과 출발지 응답을 조회합니다. 현재 게스트 참여 응답 수정 API와 동일하게 비밀번호나 토큰을 다시 확인하지 않습니다.","operationId":"getGuestParticipation","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}},{"name":"nickname","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"게스트 참여 응답 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}},"404":{"description":"초대 코드 또는 게스트 참여 정보 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyParticipationResponse"}}}}}}},"/api/meetings/invitations/{inviteCode}/cover-image":{"get":{"tags":["Meeting"],"summary":"초대 링크 모임 커버 사진 조회","description":"초대 조회·모임 조회 응답의 coverImageUrl을 그대로 사용해 <img src>에 넣는 이미지 바이너리 API입니다. 상대 경로이므로 프론트 API 서버 주소를 앞에 붙입니다. v 쿼리는 브라우저 캐시 갱신 전용이며 변경하거나 제거하지 않습니다. 응답은 1년 immutable 캐시 정책을 사용합니다.","operationId":"getCoverImage","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}},{"name":"v","in":"query","description":"브라우저 캐시를 구분하는 응답 전용 버전값","required":false,"schema":{"type":"string"},"example":"15v9zq"}],"responses":{"200":{"description":"커버 사진 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"모임 또는 커버 사진 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"503":{"description":"커버 이미지 저장소 일시 이용 불가","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}}}},"/api/departure-places/reverse-geocodes":{"get":{"tags":["Departure place"],"summary":"좌표로 출발지 주소 조회","description":"WGS84 위도와 경도를 카카오 Local로 변환해 도로명주소와 지번주소를 반환합니다.\n\n인증은 출발지 통합 검색과 같습니다.\n- Access Token을 보낸 회원은 inviteCode 없이 요청할 수 있습니다.\n- Access Token이 없으면 유효한 모임 inviteCode가 필요합니다.\n- 도로명주소는 카카오 결과에 없을 수 있으며, 이때 null입니다.\n- 주소를 찾지 못하면 두 주소 필드가 모두 null인 200 응답을 반환합니다.\n","operationId":"reverseGeocode","parameters":[{"name":"inviteCode","in":"query","description":"회원은 선택이며 게스트는 유효한 모임 초대코드가 필요합니다.","required":false,"schema":{"type":"string"},"example":"ABCD234567"},{"name":"latitude","in":"query","description":"WGS84 위도","required":true,"schema":{"type":"number","maximum":90.0,"minimum":-90.0},"example":37.5665},{"name":"longitude","in":"query","description":"WGS84 경도","required":true,"schema":{"type":"number","maximum":180.0,"minimum":-180.0},"example":126.978}],"responses":{"200":{"description":"주소 변환 성공 또는 해당 좌표의 주소 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReverseGeocodingResponse"}}}},"400":{"description":"좌표 검증 실패","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"COMMON_VALIDATION_FAILED","status":400}}}},"401":{"description":"Access Token과 inviteCode가 모두 없거나 Access Token이 유효하지 않음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"404":{"description":"게스트 요청의 inviteCode에 해당하는 모임 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"MEETING_INVITATION_NOT_FOUND","status":404}}}},"503":{"description":"카카오 Local API를 사용할 수 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"REVERSE_GEOCODING_UNAVAILABLE","status":503}}}},"403":{"description":"닉네임 온보딩 미완료","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"ONBOARDING_REQUIRED","status":403}}}}},"security":[{"bearerAuth":[]}]}},"/api/auth/me":{"get":{"tags":["Auth"],"summary":"현재 사용자 조회","description":"`Authorization: Bearer {accessToken}` 헤더로 현재 로그인 사용자를 조회합니다.","operationId":"me","responses":{"200":{"description":"현재 사용자 조회 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"401":{"description":"Access Token 없음, 만료 또는 유효하지 않음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"*/*":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/{meetingId}/participation":{"delete":{"tags":["Meeting"],"summary":"회원 모임 나가기","description":"로그인 회원 참여자(MEMBER)는 상태와 무관하게 본인 참여를 취소할 수 있습니다. 참여자 행과 일정 응답·출발지 정보는 hard delete됩니다. 방장은 이 API 대신 모임 삭제를 사용합니다.","operationId":"leaveMeeting","parameters":[{"name":"meetingId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"모임 나가기 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}},"401":{"description":"인증 필요","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"example":{"code":"AUTHENTICATION_REQUIRED","status":401}}}},"403":{"description":"닉네임 온보딩 미완료 또는 방장 참여자","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"examples":{"ONBOARDING_REQUIRED":{"description":"ONBOARDING_REQUIRED","value":{"code":"ONBOARDING_REQUIRED","status":403}},"MEETING_PARTICIPANT_LEAVE_FORBIDDEN":{"description":"MEETING_PARTICIPANT_LEAVE_FORBIDDEN","value":{"code":"MEETING_PARTICIPANT_LEAVE_FORBIDDEN","status":403}}}}}},"404":{"description":"모임 또는 본인 참여 정보 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"examples":{"MEETING_NOT_FOUND":{"description":"MEETING_NOT_FOUND","value":{"code":"MEETING_NOT_FOUND","status":404}},"MEETING_PARTICIPANT_NOT_FOUND":{"description":"MEETING_PARTICIPANT_NOT_FOUND","value":{"code":"MEETING_PARTICIPANT_NOT_FOUND","status":404}}}}}}},"security":[{"bearerAuth":[]}]}},"/api/meetings/invitations/{inviteCode}/guests/{nickname}":{"delete":{"tags":["Meeting"],"summary":"게스트 모임 나가기","description":"게스트 닉네임으로 해당 모임의 GUEST 참여를 취소합니다. 비밀번호나 Access JWT는 다시 입력하지 않습니다.<br>\n현재 MVP 임시 정책으로, 초대 코드를 아는 사람은 해당 모임의 게스트 닉네임을 지정해 나가기 요청을 할 수 있습니다.\n참여자 행과 일정 응답·출발지 정보는 hard delete되며, 최대 참여 인원도 함께 하나 감소합니다.\n","operationId":"leaveGuest","parameters":[{"name":"inviteCode","in":"path","required":true,"schema":{"type":"string"}},{"name":"nickname","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"게스트 모임 나가기 성공","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}}},"404":{"description":"초대 코드 또는 게스트 참여 정보 없음","headers":{"X-Trace-Id":{"description":"요청 추적 ID입니다. 서버 로그 조회 시 사용합니다.","schema":{"type":"string","format":"uuid"}}},"content":{"application/problem+json":{"examples":{"MEETING_INVITATION_NOT_FOUND":{"description":"MEETING_INVITATION_NOT_FOUND","value":{"code":"MEETING_INVITATION_NOT_FOUND","status":404}},"MEETING_PARTICIPANT_NOT_FOUND":{"description":"MEETING_PARTICIPANT_NOT_FOUND","value":{"code":"MEETING_PARTICIPANT_NOT_FOUND","status":404}}}}}}}}}},"components":{"schemas":{"CompleteOnboardingRequest":{"type":"object","description":"최초 닉네임 등록 요청","properties":{"nickname":{"type":"string","description":"사용자 기본 닉네임. 한글 또는 영문 2~10자이며 전역 고유값이 아닙니다.","example":"모여","maxLength":10,"minLength":2,"pattern":"^[가-힣A-Za-z]{2,10}$"}},"required":["nickname"]},"AuthUserResponse":{"type":"object","description":"인증 사용자 응답","properties":{"id":{"type":"integer","format":"int64","description":"서버에서 사용자를 식별하는 ID","example":1},"nickname":{"type":["string","null"],"description":"사용자 기본 닉네임. 최초 소셜 가입 후 온보딩 전에는 null입니다.","example":"moyeo1"},"profile":{"$ref":"#/components/schemas/ProfileResponse","description":"회원 프로필 표시 정보"},"onboardingCompleted":{"type":"boolean","description":"닉네임 등록을 완료했는지 여부","example":true}}},"ProfileResponse":{"type":"object","description":"회원 프로필 표시 정보입니다. 현재는 기본 색상만 지원합니다.","properties":{"type":{"type":"string","description":"프로필 종류","enum":["COLOR"],"example":"COLOR"},"color":{"type":"string","description":"기본 프로필 색상","enum":["GRAY","RED","PURPLE","ORANGE"],"example":"PURPLE"}}},"MeetingCoverResponse":{"type":"object","description":"모임 커버 이미지 수정 응답","properties":{"coverImageUrl":{"type":"string","description":"교체 후 새로 저장된 커버 이미지를 <img src>에 표시할 상대 API 경로입니다. 기존 화면의 src를 이 값으로 교체하면 새 캐시 버전의 이미지를 받습니다.","example":"/api/meetings/invitations/ABCD234567/cover-image?v=15v9zq"}}},"CreateMeetingRequest":{"type":"object","description":"필수 JSON 파트. FormData 문자열이 아닌 application/json Blob으로 전송합니다.","properties":{"name":{"type":"string","description":"모임 카드와 초대 화면에 표시할 이름입니다.","example":"토요일 저녁 모임","maxLength":15,"minLength":1},"description":{"type":"string","description":"모임에 대한 간단한 설명입니다. 선택 입력이며 비워둘 수 있습니다.","example":"오랜만에 같이 저녁 먹어요.","maxLength":100,"minLength":0},"maxParticipants":{"type":"integer","format":"int32","description":"필수 입력인 최대 참여 인원입니다. 방장을 포함합니다.","example":6,"maximum":20,"minimum":2},"planningType":{"type":"string","description":"모임 생성 FAB에서 선택한 생성 유형입니다.\n<ul>\n  <li>SCHEDULE_ONLY: 일정만 정하기. 날짜만 또는 날짜와 시간을 받는 조율(VOTE) 방식입니다.</li>\n  <li>PLACE_ONLY: 장소만 정하기. 장소는 중간지점 추천(RECOMMEND) 대상으로 생성합니다.</li>\n  <li>SCHEDULE_AND_PLACE: 일정과 장소 둘 다 정하기. 일정 조율(VOTE)과 중간지점 장소 추천(RECOMMEND)을 함께 저장합니다.</li>\n</ul>\n장소 추천 전략은 서버가 결정하며, 생성 요청에서 받지 않습니다.\n확정 일정/확정 장소 직접 입력(FIXED)은 이번 MVP 생성 요청에서 받지 않으며, 추후 회의에서 재검토합니다.\n","enum":["SCHEDULE_ONLY","PLACE_ONLY","SCHEDULE_AND_PLACE"],"example":"SCHEDULE_AND_PLACE"},"scheduleInputType":{"type":"string","description":"일정을 정하는 모임에서 선택한 입력 유형입니다. PLACE_ONLY에서는 보내지 않습니다.","enum":["DATE_ONLY","DATE_AND_TIME"],"example":"DATE_AND_TIME"},"availableStartTime":{"type":"string","description":"DATE_AND_TIME일 때 모든 후보 날짜에 공통으로 적용할 시작 시간입니다. 1시간 단위로 입력하며 DATE_ONLY와 PLACE_ONLY에서는 보내지 않습니다.","example":"18:00"},"availableEndTime":{"type":"string","description":"DATE_AND_TIME일 때 모든 후보 날짜에 공통으로 적용할 종료 시간입니다. 시작 시간보다 뒤여야 하고 1시간 단위이며 DATE_ONLY와 PLACE_ONLY에서는 보내지 않습니다.","example":"22:00"},"scheduleCandidateDates":{"type":"array","description":"방장이 정한 일정 후보 날짜입니다. 일정 조율 모임에서 필수이며 최대 21개까지 보낼 수 있습니다. PLACE_ONLY에서는 보내지 않습니다.","items":{"type":"string","format":"date"},"maxItems":21,"maxLength":21,"minItems":0},"scheduleResponse":{"$ref":"#/components/schemas/ScheduleResponseRequest","description":"방장의 일정 응답입니다. DATE_AND_TIME에서 availableTimeRanges를 보내고 DATE_ONLY에서는 생략합니다."},"departure":{"$ref":"#/components/schemas/DepartureRequest","description":"방장의 출발지와 이동수단입니다. 장소 조율 모임에서 필수입니다."},"deadlineMinutes":{"type":"integer","format":"int32","description":"noDeadline가 false이거나 생략된 경우 필수입니다. 생성 요청 처리 시점부터 마감까지 남은 시간(분)이며, 10분 단위로 최소 10분, 최대 7일 23시간입니다. noDeadline가 true이면 생략하거나 null로 보냅니다.","example":1440,"maximum":11460,"minimum":10},"noDeadline":{"type":"boolean","default":false,"description":"true이면 참여/응답 마감 없이 모임을 생성합니다. 이 경우 deadlineMinutes는 생략하거나 null로 보냅니다. 생략하거나 false이면 deadlineMinutes가 필요합니다.","example":false}},"required":["maxParticipants","name","planningType"]},"DepartureRequest":{"type":"object","description":"참여자 출발지와 이동수단","properties":{"name":{"type":["string","null"],"description":"출발지 표시 이름입니다. 선택 입력(nullable)이며, 생략하면 조회 응답에서는 출발지 주소를 표시합니다.","example":"회사","maxLength":30,"minLength":0},"address":{"type":"string","description":"출발지 주소입니다. 현재 MVP에서는 서울특별시 또는 경기도 주소만 허용합니다.","example":"서울 강남구 테헤란로 123","maxLength":255,"minLength":0},"latitude":{"type":"number","description":"출발지 위도입니다. 검색 후보를 선택한 경우 응답 좌표를 경도와 함께 보냅니다.","example":37.498095,"maximum":90.0,"minimum":-90.0},"longitude":{"type":"number","description":"출발지 경도입니다. 검색 후보를 선택한 경우 응답 좌표를 위도와 함께 보냅니다.","example":127.02761,"maximum":180.0,"minimum":-180.0},"transportationMode":{"type":"string","description":"이동수단입니다.\n<ul>\n  <li>PUBLIC_TRANSIT: 대중교통</li>\n  <li>CAR: 자동차</li>\n</ul>\n","enum":["PUBLIC_TRANSIT","CAR"],"example":"PUBLIC_TRANSIT"}},"required":["address","transportationMode"]},"ScheduleAvailabilityRequest":{"type":"object","description":"가능한 일정 슬롯","properties":{"candidateDate":{"type":"string","format":"date","description":"모임장이 설정한 일정 후보 날짜 중 하나입니다.","example":"2026-07-10"},"startTime":{"type":"string","description":"가능 시간 시작입니다. 1시간 단위로 입력합니다.","example":"18:00"},"endTime":{"type":"string","description":"가능 시간 종료입니다. 1시간 단위로 입력합니다.","example":"19:00"}},"required":["candidateDate","endTime","startTime"]},"ScheduleResponseRequest":{"type":"object","description":"일정 참여 응답","properties":{"availableDates":{"type":"array","description":"날짜만 조율할 때 선택한 가능한 날짜 목록입니다.","example":["2026-07-10","2026-07-11"],"items":{"type":"string","format":"date"}},"availableTimeRanges":{"type":"array","description":"날짜와 시간을 조율할 때 선택한 가능한 시간 범위 목록입니다.","items":{"$ref":"#/components/schemas/ScheduleAvailabilityRequest"}}}},"CreateMeetingResponse":{"type":"object","description":"모임과 방장 참여를 함께 저장한 성공 응답입니다.","properties":{"meetingId":{"type":"integer","format":"int64","description":"생성된 모임 식별자입니다.","example":1},"inviteCode":{"type":"string","description":"초대 코드입니다.","example":"ABCD234567"}}},"ConfirmScheduleRequest":{"type":"object","description":"일정 확정 요청","properties":{"scheduleDate":{"type":"string","format":"date","description":"생성 시 등록한 후보 날짜 중 선택할 날짜","example":"2026-07-10"},"startTime":{"type":"string","description":"DATE_AND_TIME에서만 필수. DATE_ONLY에서는 생략","example":"18:00:00"},"endTime":{"type":"string","description":"DATE_AND_TIME에서만 필수. DATE_ONLY에서는 생략","example":"20:00:00"}},"required":["scheduleDate"]},"MeetingConfirmationResponse":{"type":"object","description":"일정 또는 장소 확정 결과","properties":{"meetingId":{"type":"integer","format":"int64","description":"모임 ID"},"status":{"type":"string","description":"현재 모임 상태","enum":["PLANNING","CONFIRMED"]},"confirmedAt":{"type":["string","null"],"format":"date-time","description":"일정과 장소가 모두 확정된 최종 확정 시각. 아직 한 항목만 확정됐으면 null입니다."},"scheduleDate":{"type":["string","null"],"format":"date","description":"확정 일정 날짜. 아직 일정 확정 전이면 null입니다."},"startTime":{"type":["string","null"],"description":"확정 시작 시간. DATE_ONLY면 null입니다."},"endTime":{"type":["string","null"],"description":"확정 종료 시간. DATE_ONLY면 null입니다."},"placeName":{"type":["string","null"],"description":"확정 장소명. 아직 장소 확정 전이면 null입니다."}}},"ConfirmPlaceRequest":{"type":"object","description":"장소 확정 요청","properties":{"commercialAreaCode":{"type":"string","description":"장소 추천 또는 실제 이동시간 추천 응답의 areaCode","example":"1001491"}},"required":["commercialAreaCode"]},"MemberJoinRequest":{"type":"object","description":"로그인 회원 참여자 생성과 참여 상세 정보 저장 요청","properties":{"nickname":{"type":"string","description":"모임 안에서 사용할 표시 닉네임입니다. 회원 기본 닉네임과 다르게 입력할 수 있습니다.","example":"member","maxLength":10,"minLength":2,"pattern":"^[가-힣A-Za-z]{2,10}$"},"scheduleResponse":{"$ref":"#/components/schemas/ScheduleResponseRequest","description":"참여자의 일정 응답입니다. 일정 조율 모임에서 필수입니다."},"departure":{"$ref":"#/components/schemas/DepartureRequest","description":"참여자 출발지와 이동수단입니다. 장소 조율 모임에서 필수입니다."}},"required":["nickname"]},"ParticipantJoinResponse":{"type":"object","description":"모임 참여 응답","properties":{"meetingId":{"type":"integer","format":"int64","description":"참여한 모임 ID","example":1},"participantId":{"type":"integer","format":"int64","description":"서버에서 생성한 모임 참여자 ID","example":2},"userId":{"type":["integer","null"],"format":"int64","description":"연결된 서비스 사용자 ID입니다. 게스트 참여자는 null입니다.","example":42},"nickname":{"type":"string","description":"모임 안에서 사용할 표시 닉네임","example":"member1"},"participantType":{"type":"string","description":"참여자 타입입니다.\n<ul>\n  <li>HOST: 방장</li>\n  <li>MEMBER: 로그인 회원 참여자</li>\n  <li>GUEST: 게스트 참여자</li>\n</ul>\n","enum":["HOST","MEMBER","GUEST"],"example":"MEMBER"}}},"GuestJoinRequest":{"type":"object","description":"게스트 모임 참여 요청입니다.\n게스트 참여자 생성과 참여 상세 정보 저장을 한 번에 처리합니다.\n일정 조율 모임은 scheduleResponse를, 장소 조율 모임은 departure를 함께 입력해야 합니다.\n","properties":{"nickname":{"type":"string","description":"모임 안에서 사용할 표시 닉네임입니다. 같은 모임 안에서는 중복될 수 없습니다.","example":"guest","maxLength":10,"minLength":2,"pattern":"^[가-힣A-Za-z]{2,10}$"},"password":{"type":"string","description":"게스트 참여 비밀번호입니다.\n현재는 참여 정보에 해시로 저장하며, 게스트 재입장/수정 검증 정책은 아직 구현하지 않았습니다.\n","example":"1234","maxLength":4,"minLength":4,"pattern":"^[0-9]{4}$"},"scheduleResponse":{"$ref":"#/components/schemas/ScheduleResponseRequest","description":"참여자의 일정 응답입니다. 일정 조율 모임에서 필수입니다."},"departure":{"$ref":"#/components/schemas/DepartureRequest","description":"참여자 출발지와 이동수단입니다. 장소 조율 모임에서 필수입니다."}},"required":["nickname","password"]},"GuestEntryRequest":{"type":"object","description":"게스트 참여 진입 분기 요청입니다.","properties":{"nickname":{"type":"string","description":"모임 안에서 사용할 게스트 닉네임","example":"guest","maxLength":10,"minLength":2,"pattern":"^[가-힣A-Za-z]{2,10}$"},"password":{"type":"string","description":"게스트 참여 비밀번호","example":"1234","maxLength":4,"minLength":4,"pattern":"^[0-9]{4}$"}},"required":["nickname","password"]},"GuestEntryResponse":{"type":"object","description":"게스트 참여 진입 분기 응답","properties":{"entryType":{"type":"string","description":"NEW_GUEST는 신규 참여 입력으로, EXISTING_GUEST는 모임 현황으로 이동합니다.","enum":["NEW_GUEST","EXISTING_GUEST"]}}},"SavePlaceRequest":{"type":"object","description":"내 장소 저장 요청입니다.\n\n`POST /api/departure-places/searches` 응답의 `results` 중 사용자가 선택한 항목에서\n`type`, `displayName`, `address`, `roadAddress`, `jibunAddress`, `latitude`, `longitude`를\n그대로 복사하고, 사용자가 입력한 `alias`를 추가해 전송합니다.\n\n서버는 선택 당시의 검색 결과를 회원 소유 스냅샷으로 저장합니다. 같은 검색 결과나\n같은 별칭을 여러 번 저장할 수 있으며 현재 저장 개수 제한은 없습니다.\n","properties":{"alias":{"type":"string","description":"회원이 지정한 장소 별칭","example":"회사","maxLength":30,"minLength":0},"category":{"type":["string","null"],"description":"회원이 지정한 장소 용도입니다. 프론트엔드는 이 값으로 아이콘을 표시합니다. 생략하면 서버가 `OTHER`로 저장합니다.","enum":["HOME","WORK","OTHER"],"example":"WORK"},"type":{"type":"string","description":"출발지 검색 응답의 결과 유형을 그대로 전달합니다.\n- `STATION`: 지하철역 검색 결과\n- `ADDRESS`: 도로명주소 또는 지번주소 검색 결과\n- `PLACE`: 상호·시설 등 일반 장소 검색 결과\n\n저장 장소의 원본 분류를 보존하는 값이며, 별칭 수정이나 삭제 권한에는 영향을 주지 않습니다.\n","enum":["STATION","ADDRESS","PLACE"],"example":"PLACE"},"displayName":{"type":"string","description":"출발지 검색 응답의 `displayName`을 그대로 전달합니다. 카카오 검색 결과에서 화면에 표시한 원본 장소명입니다.","example":"강남파이낸스센터","maxLength":255,"minLength":0},"address":{"type":"string","description":"출발지 검색 응답의 `address`를 그대로 전달합니다. 도로명주소가 있으면 도로명주소가 대표 주소로 제공됩니다.","example":"서울 강남구 테헤란로 152","maxLength":255,"minLength":0},"roadAddress":{"type":["string","null"],"description":"출발지 검색 응답의 `roadAddress`를 그대로 전달합니다. 검색 결과에 도로명주소가 없으면 생략하거나 null로 전달합니다.","maxLength":255,"minLength":0},"jibunAddress":{"type":["string","null"],"description":"출발지 검색 응답의 `jibunAddress`를 그대로 전달합니다. 검색 결과에 지번주소가 없으면 생략하거나 null로 전달합니다.","maxLength":255,"minLength":0},"latitude":{"type":"number","description":"출발지 검색 응답의 WGS84 `latitude`를 그대로 전달합니다. -90 이상 90 이하이며 소수점 이하는 최대 15자리입니다.","example":37.500028,"maximum":90.0,"minimum":-90.0},"longitude":{"type":"number","description":"출발지 검색 응답의 WGS84 `longitude`를 그대로 전달합니다. -180 이상 180 이하이며 소수점 이하는 최대 15자리입니다.","example":127.036502,"maximum":180.0,"minimum":-180.0}},"required":["address","alias","displayName","latitude","longitude","type"]},"SavedPlaceResponse":{"type":"object","description":"회원이 저장한 장소 스냅샷입니다. `alias`만 수정할 수 있으며 검색 결과에서 가져온 나머지 위치 정보는 생성 후 변경되지 않습니다.","properties":{"id":{"type":"integer","format":"int64","description":"저장 장소 ID","example":1},"alias":{"type":"string","description":"회원이 지정한 장소 별칭","example":"회사"},"type":{"type":"string","description":"원본 검색 결과 유형입니다. `STATION`은 지하철역, `ADDRESS`는 도로명·지번주소, `PLACE`는 상호·시설 등 일반 장소를 의미합니다.","enum":["STATION","ADDRESS","PLACE"],"example":"PLACE"},"category":{"type":"string","description":"회원이 지정한 장소 용도입니다. 프론트엔드는 이 값으로 아이콘을 표시합니다.","enum":["HOME","WORK","OTHER"],"example":"WORK"},"displayName":{"type":"string","description":"검색 결과의 원본 표시명","example":"강남파이낸스센터"},"address":{"type":"string","description":"대표 주소","example":"서울 강남구 테헤란로 152"},"roadAddress":{"type":["string","null"],"description":"도로명주소. 없으면 null입니다."},"jibunAddress":{"type":["string","null"],"description":"지번주소. 없으면 null입니다."},"latitude":{"type":"number","description":"WGS84 위도","example":37.500028},"longitude":{"type":"number","description":"WGS84 경도","example":127.036502}}},"CreateFeedbackRequest":{"type":"object","description":"사용자 피드백 등록 요청입니다. 내용 최대 1,000자는 임시 MVP 제한입니다.","properties":{"content":{"type":"string","description":"서비스에 전달할 의견입니다. 최대 1,000자는 임시 MVP 제한입니다.","example":"일정 후보를 복사하는 기능이 있으면 좋겠어요.","maxLength":1000,"minLength":0}},"required":["content"]},"FeedbackResponse":{"type":"object","description":"사용자가 제출한 피드백입니다.","properties":{"id":{"type":"integer","format":"int64","description":"피드백 ID","example":1},"content":{"type":"string","description":"제출 내용","example":"일정 후보를 복사하는 기능이 있으면 좋겠어요."},"createdAt":{"type":"string","format":"date-time","description":"제출 시각","example":"2026-08-02T14:30:00"}}},"DeparturePlaceSearchRequest":{"type":"object","description":"출발지 통합 검색 요청","properties":{"keyword":{"type":"string","description":"역명, 도로명·지번 주소 또는 일반 장소명","example":"서울역","maxLength":100,"minLength":0}},"required":["keyword"]},"DeparturePlaceSearchResponse":{"type":"object","description":"출발지 통합 검색 응답. 선택 후보의 WGS84 위도와 경도를 포함합니다.","properties":{"results":{"type":"array","description":"검색 결과 목록","items":{"$ref":"#/components/schemas/Result"}}}},"Result":{"type":"object","description":"출발지 선택 후보","properties":{"type":{"type":"string","description":"검색 결과 유형","enum":["STATION","ADDRESS","PLACE"],"example":"STATION"},"displayName":{"type":"string","description":"검색 목록에 표시할 장소명 또는 주소 표시명입니다. 최종 출발지 name은 사용자가 별도로 입력합니다.","example":"서울역 1호선"},"address":{"type":"string","description":"선택 시 출발지 주소로 사용할 대표 주소입니다. 도로명주소를 우선합니다.","example":"서울 중구 세종대로 지하 2"},"roadAddress":{"type":["string","null"],"description":"도로명주소. 없으면 null입니다."},"jibunAddress":{"type":["string","null"],"description":"지번주소. 없으면 null입니다."},"latitude":{"type":"number","description":"선택 후보의 WGS84 위도입니다.","example":37.5546788388674},"longitude":{"type":"number","description":"선택 후보의 WGS84 경도입니다.","example":126.970606917394}}},"RefreshTokenRequest":{"type":"object","properties":{"refreshToken":{"type":"string","minLength":1}},"required":["refreshToken"]},"AuthResponse":{"type":"object","description":"인증 성공 응답","properties":{"accessToken":{"type":"string","description":"API 인증에 사용할 Access Token. 보호된 API 호출 시 Authorization 헤더에 넣습니다.","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."},"refreshToken":{"type":"string","description":"30일 자동 로그인에 사용할 갱신 토큰입니다. 클라이언트의 안전한 저장소에만 보관하고, 갱신 또는 로그아웃 요청에만 전송합니다.","example":"mGk7bM0s0O6XqzR4a2GfRk6vJ3YwQ2KpT8xD1cL9eHs"},"tokenType":{"type":"string","description":"토큰 타입. Authorization 헤더에는 `Bearer {accessToken}` 형태로 사용합니다.","example":"Bearer"},"user":{"$ref":"#/components/schemas/AuthUserResponse","description":"회원가입 또는 로그인에 성공한 사용자 정보"}}},"KakaoLoginRequest":{"type":"object","description":"카카오 로그인 요청","properties":{"code":{"type":"string","description":"카카오 콜백으로 전달된 일회용 인가 코드","example":"abc123...","maxLength":4096,"minLength":0},"redirectTarget":{"type":"string","description":"서버에 등록된 카카오 콜백 환경","enum":["local","dev","prod"],"example":"dev"}},"required":["code","redirectTarget"]},"KakaoNativeLoginRequest":{"type":"object","description":"카카오 네이티브 SDK 로그인 요청","properties":{"accessToken":{"type":"string","description":"카카오 네이티브 SDK가 발급한 Access Token. 서버는 사용자 식별 후 저장하지 않습니다.","example":"kakao-access-token","maxLength":4096,"minLength":0}},"required":["accessToken"]},"DevAuthTokensResponse":{"type":"object","description":"개발 테스트 계정 2개의 Access Token 발급 응답","properties":{"userOne":{"$ref":"#/components/schemas/AuthResponse","description":"테스트 사용자 1의 인증 응답"},"userTwo":{"$ref":"#/components/schemas/AuthResponse","description":"테스트 사용자 2의 인증 응답"}}},"AppleLoginRequest":{"type":"object","description":"Apple 로그인 요청","properties":{"code":{"type":"string","description":"Apple이 프론트 콜백에 전달한 일회용 로그인 코드","example":"c123...","maxLength":4096,"minLength":0},"nonce":{"type":"string","description":"프론트가 Apple 로그인 요청 전에 생성한 nonce 원문","example":"YpV5...","maxLength":255,"minLength":0},"redirectTarget":{"type":"string","description":"서버에 등록된 Apple 콜백 환경. local은 Apple 웹 로그인에서 지원하지 않습니다.","enum":["dev","prod"],"example":"dev"}},"required":["code","nonce","redirectTarget"]},"AppleNativeLoginRequest":{"type":"object","description":"Apple 네이티브 SDK 로그인 요청","properties":{"identityToken":{"type":"string","description":"Apple 네이티브 SDK가 발급한 identity token","example":"eyJraWQiOi...","maxLength":8192,"minLength":0},"authorizationCode":{"type":"string","description":"Apple 네이티브 SDK가 발급한 일회용 authorization code","example":"c123...","maxLength":4096,"minLength":0},"nonce":{"type":"string","description":"프론트가 native Apple 로그인 요청 전에 생성해 SDK에 전달한 nonce 원문","example":"YpV5...","maxLength":255,"minLength":0}},"required":["authorizationCode","identityToken","nonce"]},"UpdateProfileColorRequest":{"type":"object","properties":{"color":{"type":"string","description":"선택할 기본 프로필 색상","enum":["GRAY","RED","PURPLE","ORANGE"],"example":"PURPLE"}},"required":["color"]},"UpdateNicknameRequest":{"type":"object","description":"기본 닉네임 수정 요청","properties":{"nickname":{"type":"string","description":"사용자 기본 닉네임입니다. 한글 또는 영문 2~10자이며, 모임 안에서 사용하는 참여자 닉네임은 변경하지 않습니다.","example":"모여","maxLength":10,"minLength":2,"pattern":"^[가-힣A-Za-z]{2,10}$"}},"required":["nickname"]},"UpdateMeetingParticipantNicknameRequest":{"type":"object","description":"모임 내 본인 닉네임 수정 요청","properties":{"nickname":{"type":"string","description":"해당 모임에서만 표시하는 닉네임입니다. 한글 또는 영문 2~10자이며, 기본 프로필 닉네임은 변경하지 않습니다.","example":"모여","maxLength":10,"minLength":2,"pattern":"^[가-힣A-Za-z]{2,10}$"}},"required":["nickname"]},"MeetingParticipantNicknameResponse":{"type":"object","description":"모임 내 닉네임 수정 응답","properties":{"meetingId":{"type":"integer","format":"int64","description":"모임 ID","example":1},"participantId":{"type":"integer","format":"int64","description":"수정된 참여자 ID","example":10},"userId":{"type":["integer","null"],"format":"int64","description":"연결된 서비스 사용자 ID입니다. 게스트 참여자는 null입니다.","example":42},"nickname":{"type":"string","description":"수정된 모임 내 닉네임","example":"모여"}}},"Departure":{"type":"object","properties":{"name":{"type":["string","null"],"description":"출발지 표시 이름입니다. 입력하지 않았다면 null입니다.","example":"회사"},"address":{"type":"string","description":"출발지 주소","example":"서울 강남구 테헤란로 123"},"latitude":{"type":["number","null"],"description":"출발지 위도","example":37.498095},"longitude":{"type":["number","null"],"description":"출발지 경도","example":127.02761},"transportationMode":{"type":"string","description":"이동 수단","enum":["PUBLIC_TRANSIT","CAR"],"example":"PUBLIC_TRANSIT"}}},"MyParticipationResponse":{"type":"object","description":"방장, 회원 또는 게스트의 모임 참여 응답","properties":{"meetingId":{"type":"integer","format":"int64","description":"모임 ID","example":17},"participantType":{"type":"string","description":"현재 사용자의 모임 역할","enum":["HOST","MEMBER","GUEST"]},"scheduleInputType":{"type":"string","description":"일정 입력 유형","enum":["DATE_ONLY","DATE_AND_TIME","NONE"]},"scheduleResponse":{"type":"null","$ref":"#/components/schemas/ScheduleResponse","description":"본인의 일정 응답입니다. DATE_ONLY에서는 availableDates만 사용하고 availableTimeRanges는 빈 배열입니다. DATE_AND_TIME에서는 availableTimeRanges만 사용하고 availableDates는 빈 배열입니다. 일정 조율이 없는 모임(NONE)에서는 null입니다."},"departure":{"type":"null","$ref":"#/components/schemas/Departure","description":"본인의 출발지와 교통수단 응답입니다. 장소 조율 모임에서는 값이 있으며, 장소 조율이 없는 모임에서는 null입니다."}}},"ScheduleAvailability":{"type":"object","properties":{"candidateDate":{"type":"string","format":"date","description":"모임 후보 날짜","example":"2026-07-10"},"startTime":{"type":"string","description":"가능 시작 시간","example":"18:00"},"endTime":{"type":"string","description":"가능 종료 시간","example":"20:00"}}},"ScheduleResponse":{"type":"object","properties":{"availableDates":{"type":"array","description":"DATE_ONLY 모임에서 선택한 후보 날짜 목록입니다. DATE_AND_TIME 모임에서는 빈 배열입니다.","example":["2026-07-10","2026-07-12"],"items":{"type":"string","format":"date"}},"availableTimeRanges":{"type":"array","description":"DATE_AND_TIME 모임에서 선택한 가능 시간 범위 목록입니다. DATE_ONLY 모임에서는 빈 배열입니다.","items":{"$ref":"#/components/schemas/ScheduleAvailability"}}}},"RenameSavedPlaceRequest":{"type":"object","description":"내 장소 별칭 수정 요청","properties":{"alias":{"type":"string","description":"새 장소 별칭","example":"새 회사","maxLength":30,"minLength":0}},"required":["alias"]},"MyPageResponse":{"type":"object","description":"마이페이지 조회 응답입니다. 회원 기본 정보와 저장 출발지 목록을 함께 반환합니다.","properties":{"nickname":{"type":"string","description":"회원 기본 닉네임","example":"모여"},"profile":{"$ref":"#/components/schemas/ProfileResponse","description":"회원 프로필 표시 정보"},"places":{"type":"array","description":"저장 일시 최신순 출발지 목록","items":{"$ref":"#/components/schemas/SavedPlaceResponse"}}}},"ServerTimeResponse":{"type":"object","description":"서버 현재 시각 응답","properties":{"serverTime":{"type":"string","format":"date-time","description":"서버가 UTC 기준으로 반환한 현재 시각(ISO-8601)","example":"2026-07-17T02:30:45.123Z"}}},"MyMeetingDetailResponse":{"type":"object","description":"로그인 회원의 모임 상세","properties":{"meetingId":{"type":"integer","format":"int64","description":"모임 ID","example":17},"name":{"type":"string","description":"모임명","example":"주말 저녁 모임"},"description":{"type":["string","null"],"description":"모임 설명. 입력하지 않은 경우 null입니다."},"coverImageUrl":{"type":["string","null"],"description":"커버 이미지 조회 API 경로. 없으면 null입니다."},"hostNickname":{"type":"string","description":"모임장 닉네임","example":"moyeo1"},"confirmedScheduleDate":{"type":["string","null"],"format":"date","description":"확정 일정 날짜. 일정이 아직 확정되지 않았거나 장소 전용 모임이면 null입니다."},"confirmedStartTime":{"type":["string","null"],"description":"확정 시작 시간. 일정이 아직 확정되지 않았거나 DATE_ONLY 또는 장소 전용 모임이면 null입니다."},"confirmedEndTime":{"type":["string","null"],"description":"확정 종료 시간. 일정이 아직 확정되지 않았거나 DATE_ONLY 또는 장소 전용 모임이면 null입니다."},"confirmedPlaceName":{"type":["string","null"],"description":"확정 장소명. 장소가 아직 확정되지 않았거나 일정 전용 모임이면 null입니다."},"participants":{"type":"array","description":"참여자 목록","items":{"$ref":"#/components/schemas/Participant"}}}},"Participant":{"type":"object","description":"모임 참여자","properties":{"participantId":{"type":"integer","format":"int64","description":"참여자 ID","example":31},"userId":{"type":["integer","null"],"format":"int64","description":"연결된 서비스 사용자 ID입니다. 게스트 참여자는 null입니다.","example":42},"nickname":{"type":"string","description":"모임 안에서 사용하는 닉네임","example":"moyeo1"},"participantType":{"type":"string","description":"참여자 유형","enum":["HOST","MEMBER","GUEST"]},"isMe":{"type":"boolean","description":"현재 로그인한 사용자 여부","example":true}}},"Item":{"type":"object","description":"홈 모임 카드","properties":{"meetingId":{"type":"integer","format":"int64","description":"모임 ID","example":17},"inviteCode":{"type":"string","description":"모임 초대 코드. 모임 현황 조회 API 경로에 사용합니다.","example":"ABCD234567"},"name":{"type":"string","description":"모임명","example":"주말 저녁 모임"},"coverImageUrl":{"type":["string","null"],"description":"커버 이미지 조회 API 경로. 없으면 null입니다."},"hostNickname":{"type":"string","description":"모임장 닉네임","example":"moyeo1"},"role":{"type":"string","description":"나의 역할","enum":["HOST","MEMBER"]},"participantCount":{"type":"integer","format":"int32","description":"현재 참여 인원","example":2},"maxParticipants":{"type":"integer","format":"int32","description":"최대 참여 인원","example":6},"deadlineStatus":{"type":"string","description":"참여·응답 마감 상태","enum":["OPEN","CLOSED","NO_DEADLINE"]},"deadlineAt":{"type":["string","null"],"format":"date-time","description":"마감 시각. 마감이 없으면 null입니다.","example":"2026-07-29 13:54:43"},"confirmedScheduleDate":{"type":["string","null"],"format":"date","description":"확정 일정 날짜. 미확정 또는 장소 전용 모임이면 null입니다."},"confirmedStartTime":{"type":["string","null"],"description":"확정 시작 시간. DATE_ONLY 또는 장소 전용 모임이면 null입니다."},"confirmedEndTime":{"type":["string","null"],"description":"확정 종료 시간. DATE_ONLY 또는 장소 전용 모임이면 null입니다."},"confirmedPlaceName":{"type":["string","null"],"description":"확정 장소명. 미확정 또는 일정 전용 모임이면 null입니다."}}},"MyMeetingListResponse":{"type":"object","description":"로그인 회원의 홈 모임 목록","properties":{"planningMeetings":{"type":"array","description":"아직 최종 확정되지 않은 모임 목록","items":{"$ref":"#/components/schemas/Item"}},"confirmedMeetings":{"type":"array","description":"최종 확정된 모임 목록","items":{"$ref":"#/components/schemas/Item"}}}},"MeetingInvitationResponse":{"type":"object","description":"초대 코드 모임 조회 응답","properties":{"meetingId":{"type":"integer","format":"int64","description":"서버에서 모임을 식별하는 ID","example":1},"name":{"type":"string","description":"초대 링크 진입 화면에 표시할 모임 이름","example":"주말 저녁 모임"},"description":{"type":["string","null"],"description":"초대 링크 진입 화면에 표시할 모임 설명. 입력하지 않은 경우 null입니다.","example":"오랜만에 같이 저녁 먹어요."},"coverImageUrl":{"type":["string","null"],"description":"이미 저장된 커버 이미지를 <img src>에 표시할 때 쓰는 상대 API 경로입니다. API 서버 주소를 앞에 붙여 사용하며, v 값은 캐시 갱신용이므로 변경하지 않습니다. 커버가 없으면 null입니다.","example":"/api/meetings/invitations/ABCD234567/cover-image?v=15v9zq"},"maxParticipants":{"type":"integer","format":"int32","description":"최대 참여 인원. 방장을 포함합니다.","example":6},"planningType":{"type":"string","description":"모임 생성 유형입니다.\n<ul>\n  <li>SCHEDULE_ONLY: 일정만 정하기</li>\n  <li>PLACE_ONLY: 장소만 정하기</li>\n  <li>SCHEDULE_AND_PLACE: 일정과 장소 모두 정하기</li>\n</ul>\n","enum":["SCHEDULE_ONLY","PLACE_ONLY","SCHEDULE_AND_PLACE"],"example":"SCHEDULE_AND_PLACE"},"status":{"type":"string","description":"모임의 최종 확정 상태입니다. PLANNING은 아직 최종 확정 전, CONFIRMED는 필요한 일정·장소 선택이 모두 확정된 상태입니다.","enum":["PLANNING","CONFIRMED"],"example":"PLANNING"},"scheduleMode":{"type":"string","description":"일정 설정 방식입니다.\n<ul>\n  <li>VOTE: 일정 조율</li>\n  <li>NONE: 일정 없음</li>\n</ul>\n현재 MVP 생성 API에서는 FIXED 직접 입력을 받지 않습니다.\n","enum":["VOTE","NONE"],"example":"VOTE"},"scheduleInputType":{"type":"string","description":"일정 참여 입력 유형입니다.","enum":["DATE_ONLY","DATE_AND_TIME","NONE"],"example":"DATE_AND_TIME"},"scheduleCandidateDates":{"type":"array","description":"일정 후보 목록입니다. DATE_AND_TIME이면 모임장이 방 생성 때 선택한 시간 범위만 포함합니다. 시간이 없는 후보 날짜는 반환하지 않습니다. DATE_ONLY에서는 시간 범위가 빈 배열입니다.","example":[{"candidateDate":"2026-07-10","availableTimeRanges":[{"startTime":"18:00","endTime":"20:00"}]}],"items":{"$ref":"#/components/schemas/ScheduleCandidateResponse"}},"placeMode":{"type":"string","description":"장소 설정 방식입니다.\n<ul>\n  <li>RECOMMEND: 장소 추천/확정 플로우에서 장소를 정함</li>\n  <li>NONE: 장소 없음</li>\n</ul>\n현재 MVP 생성 API에서는 FIXED 직접 입력을 받지 않습니다.\n","enum":["RECOMMEND","NONE"],"example":"RECOMMEND"},"placeRecommendationStrategy":{"type":["string","null"],"description":"생성 시 선택한 장소 추천 방식입니다. placeMode=RECOMMEND가 아니면 null입니다.\n1차 MVP에서는 생성 후 변경하지 않으며, 생성 시점에는 추천 결과나 확정 장소를 만들지 않습니다.\n<ul>\n  <li>MIDDLE_POINT: 참여자 출발지를 기준으로 추후 중간지점 추천 진행</li>\n  <li>RANDOM: 추후 랜덤 방식으로 장소 추천 진행</li>\n</ul>\n","enum":["MIDDLE_POINT","RANDOM"],"example":"MIDDLE_POINT"},"deadlineAt":{"type":["string","null"],"format":"date-time","description":"서버가 계산한 모임 참여/응답 마감 일시입니다. 마감 없는 모임에서는 null입니다.","example":"2026-07-01T18:00:00"},"participantCount":{"type":"integer","format":"int64","description":"현재 참여 인원. 방장을 포함합니다.","example":1},"hostNickname":{"type":"string","description":"방장으로 표시할 닉네임","example":"moyeo1"},"participationStatus":{"$ref":"#/components/schemas/ParticipationStatusResponse","description":"초대 링크 진입 시점의 참여 가능 상태. 참여하기 버튼 활성화와 안내 문구에 사용합니다."}}},"ParticipationStatusResponse":{"type":"object","description":"초대 진입 참여 가능 상태","properties":{"canJoin":{"type":"boolean","description":"현재 참여하기 버튼을 활성화할 수 있는지 여부","example":true},"reason":{"type":"string","description":"참여 가능/불가 사유 코드입니다.\n<ul>\n  <li>AVAILABLE: 참여 가능</li>\n  <li>ALREADY_JOINED: 로그인한 사용자가 이미 참여함</li>\n  <li>MEETING_CONFIRMED: 모임이 최종 확정됨</li>\n  <li>DEADLINE_PASSED: 참여 기한 지남</li>\n  <li>PARTICIPANT_LIMIT_EXCEEDED: 정원 초과</li>\n</ul>\n로그인한 사용자가 이미 참여한 경우 `ALREADY_JOINED`를 우선 반환합니다.\n그렇지 않고 모임이 확정되었으면 `MEETING_CONFIRMED`를 반환합니다.\n이후 기한과 정원이 모두 막힌 경우 기한 초과를 우선 반환합니다.\n","enum":["AVAILABLE","ALREADY_JOINED","MEETING_CONFIRMED","DEADLINE_PASSED","PARTICIPANT_LIMIT_EXCEEDED"],"example":"AVAILABLE"},"message":{"type":["string","null"],"description":"참여 불가 시 화면에 표시할 안내 문구. 참여 가능하면 null입니다.","example":"기한이 지난 모임이에요. 아쉽지만 현재는 더 이상 참여할 수 없어요."}}},"ScheduleAvailabilityResponse":{"type":"object","properties":{"startTime":{"type":"string","description":"선택 가능 시작 시간","example":"18:00"},"endTime":{"type":"string","description":"선택 가능 종료 시간","example":"20:00"}}},"ScheduleCandidateResponse":{"type":"object","properties":{"candidateDate":{"type":"string","format":"date","description":"모임 후보 날짜","example":"2026-07-10"},"availableTimeRanges":{"type":"array","description":"DATE_AND_TIME 모임에서 참여자가 선택할 수 있는 모임장 선택 시간 범위입니다. DATE_ONLY에서는 빈 배열입니다.","items":{"$ref":"#/components/schemas/ScheduleAvailabilityResponse"}}}},"MeetingViewResponse":{"type":"object","description":"모임 현황 조회 응답","properties":{"meetingId":{"type":"integer","format":"int64","description":"모임 ID","example":1},"name":{"type":"string","description":"모임명","example":"주말 저녁 모임"},"description":{"type":["string","null"],"description":"모임 설명. 입력하지 않은 경우 null입니다.","example":"오랜만에 같이 저녁 먹어요."},"coverImageUrl":{"type":["string","null"],"description":"이미 저장된 커버 이미지를 <img src>에 표시할 때 쓰는 상대 API 경로입니다. API 서버 주소를 앞에 붙여 사용하며, v 값은 캐시 갱신용이므로 변경하지 않습니다. 커버가 없으면 null입니다.","example":"/api/meetings/invitations/ABCD234567/cover-image?v=15v9zq"},"planningType":{"type":"string","description":"모임 생성 유형","enum":["SCHEDULE_ONLY","PLACE_ONLY","SCHEDULE_AND_PLACE"],"example":"SCHEDULE_AND_PLACE"},"meetingConfirmed":{"type":"boolean","description":"모임의 최종 확정 여부입니다. 일정과 장소 조율이 모두 필요한 모임은 두 항목이 모두 확정된 경우에만 true입니다.","example":false},"scheduleMode":{"type":"string","description":"일정 설정 방식입니다. 현재 MVP에서는 일정 조율 모임이면 VOTE, 일정 조율이 없으면 NONE을 반환합니다.","enum":["VOTE","NONE"],"example":"VOTE"},"scheduleInputType":{"type":"string","description":"일정 참여 입력 유형입니다.","enum":["DATE_ONLY","DATE_AND_TIME","NONE"],"example":"DATE_AND_TIME"},"placeMode":{"type":"string","description":"장소 설정 방식입니다. 현재 MVP에서는 장소 조율 모임이면 RECOMMEND, 장소 조율이 없으면 NONE을 반환합니다.","enum":["RECOMMEND","NONE"],"example":"RECOMMEND"},"placeRecommendationStrategy":{"type":["string","null"],"description":"장소 추천 방식입니다. placeMode가 RECOMMEND가 아닌 경우 null입니다.","enum":["MIDDLE_POINT","RANDOM"],"example":"MIDDLE_POINT"},"maxParticipants":{"type":"integer","format":"int32","description":"최대 참여 인원. 방장을 포함합니다.","example":6},"participantCount":{"type":"integer","format":"int64","description":"현재 참여 인원. 방장을 포함합니다.","example":3},"deadlineAt":{"type":["string","null"],"format":"date-time","description":"모임 참여/응답 마감 일시입니다. 마감 없는 모임에서는 null입니다.","example":"2026-07-12T18:00:00"},"remainingMinutes":{"type":["integer","null"],"format":"int64","description":"현재 서버 시간 기준 마감까지 남은 분입니다. 이미 마감된 경우 0이며, 마감 없는 모임에서는 null입니다.","example":360},"confirmedScheduleDate":{"type":["string","null"],"format":"date","description":"확정 일정 날짜. 일정이 아직 확정되지 않았거나 장소 전용 모임이면 null입니다."},"confirmedStartTime":{"type":["string","null"],"description":"확정 시작 시간. 일정이 아직 확정되지 않았거나 DATE_ONLY 또는 장소 전용 모임이면 null입니다."},"confirmedEndTime":{"type":["string","null"],"description":"확정 종료 시간. 일정이 아직 확정되지 않았거나 DATE_ONLY 또는 장소 전용 모임이면 null입니다."},"confirmedPlaceName":{"type":["string","null"],"description":"확정 장소명. 장소가 아직 확정되지 않았거나 일정 전용 모임이면 null입니다."},"participants":{"type":"array","description":"참여자 목록. 방장이 먼저 오고 이후 참여 순서로 정렬됩니다.","items":{"$ref":"#/components/schemas/ParticipantResponse"}}}},"ParticipantResponse":{"type":"object","description":"모임 참여자","properties":{"participantId":{"type":"integer","format":"int64","description":"모임 참여자 ID","example":1},"userId":{"type":["integer","null"],"format":"int64","description":"연결된 서비스 사용자 ID입니다. 게스트 참여자는 null입니다.","example":42},"nickname":{"type":"string","description":"모임 안에서 표시할 닉네임","example":"moyeo1"},"participantType":{"type":"string","description":"참여자 유형","enum":["HOST","MEMBER","GUEST"],"example":"HOST"},"withdrawn":{"type":"boolean","description":"연결된 서비스 사용자의 탈퇴 여부. 게스트는 항상 false입니다.","example":false}}},"AvailabilityStatusResponse":{"type":"object","description":"일정 응답 현황 블록","properties":{"candidateDate":{"type":"string","format":"date"},"startTime":{"type":"string"},"endTime":{"type":"string"},"availableParticipantCount":{"type":"integer","format":"int64"}}},"AvailableParticipantResponse":{"type":"object","description":"일정 후보 참여 가능자","properties":{"participantId":{"type":"integer","format":"int64"},"userId":{"type":["integer","null"],"format":"int64","description":"연결된 서비스 사용자 ID입니다. 게스트 참여자는 null입니다.","example":42},"nickname":{"type":"string"}}},"CandidateResponse":{"type":"object","description":"일정 후보","properties":{"candidateDate":{"type":"string","format":"date","description":"후보 날짜","example":"2026-07-12"},"startTime":{"type":["string","null"],"description":"시작 시간. DATE_ONLY에서는 null입니다.","example":"18:00"},"endTime":{"type":["string","null"],"description":"종료 시간. DATE_ONLY에서는 null입니다.","example":"19:00"},"availableParticipantCount":{"type":"integer","format":"int64","description":"해당 날짜 또는 시간에 참여 가능한 인원 수","example":3},"availableParticipants":{"type":"array","description":"해당 후보 시간에 가능한 참여자 목록입니다. 링크로 조회한 비로그인 사용자에게도 공개됩니다.","items":{"$ref":"#/components/schemas/AvailableParticipantResponse"}}}},"ScheduleViewResponse":{"type":"object","description":"일정 조율 현황 조회 응답","properties":{"meetingId":{"type":"integer","format":"int64","description":"모임 ID","example":1},"scheduleInputType":{"type":"string","description":"일정 참여 입력 유형","enum":["DATE_ONLY","DATE_AND_TIME","NONE"],"example":"DATE_AND_TIME"},"scheduleConfirmed":{"type":"boolean","description":"일정의 확정 여부입니다. 확정 일정이 선택되면 true입니다.","example":false},"sort":{"type":"string","description":"적용된 정렬 방식","enum":["LONGEST_MEETING","EARLIEST_DATE"],"example":"EARLIEST_DATE"},"participantCount":{"type":"integer","format":"int64","description":"현재 참여 인원. 방장을 포함합니다.","example":4},"candidates":{"type":"array","description":"최대 참여 가능 인원의 일정 후보 목록입니다. 해당 후보들을 정렬 방식에 따라 최대 5개 반환합니다.","items":{"$ref":"#/components/schemas/CandidateResponse"}},"availabilityStatuses":{"type":"array","description":"일정 응답 현황 블록입니다. DATE_ONLY는 날짜별 블록이며 시작·종료 시간은 null입니다. DATE_AND_TIME은 같은 가능 참여자 집합의 연속 1시간 슬롯을 합쳐 반환합니다. 클라이언트는 availableParticipantCount / participantCount 비율로 화면 색상을 표시합니다.","items":{"$ref":"#/components/schemas/AvailabilityStatusResponse"}}}},"CoordinateResponse":{"type":"object","description":"좌표","properties":{"latitude":{"type":"number","description":"위도","example":37.5344715},"longitude":{"type":"number","description":"경도","example":126.9726696}}},"ParticipantDepartureResponse":{"type":"object","description":"참여자 출발지 정보","properties":{"participantId":{"type":"integer","format":"int64","description":"모임 참여자 ID","example":1},"userId":{"type":["integer","null"],"format":"int64","description":"연결된 서비스 사용자 ID입니다. 게스트 참여자는 null입니다.","example":42},"nickname":{"type":"string","description":"모임 안에서 표시할 닉네임","example":"moyeo1"},"participantType":{"type":"string","description":"참여자 유형","enum":["HOST","MEMBER","GUEST"],"example":"HOST"},"withdrawn":{"type":"boolean","description":"연결된 서비스 사용자의 탈퇴 여부. 게스트는 항상 false입니다.","example":false},"departureName":{"type":"string","description":"출발지 표시 이름입니다. 요청에서 name을 생략하면 출발지 주소를 반환합니다.","example":"회사"},"departureAddress":{"type":["string","null"],"description":"출발지 주소. 입력하지 않았으면 null입니다.","example":"서울 강남구 테헤란로 123"},"transportationMode":{"type":["string","null"],"description":"이동 수단입니다. 입력하지 않았으면 null입니다.","enum":["PUBLIC_TRANSIT","CAR"],"example":"PUBLIC_TRANSIT"}}},"PlaceViewResponse":{"type":"object","description":"장소 조율 현황 조회 응답","properties":{"meetingId":{"type":"integer","format":"int64","description":"모임 ID","example":1},"placeConfirmed":{"type":"boolean","description":"장소의 확정 여부입니다. 확정 장소가 선택되면 true입니다.","example":false},"placeRecommendationStrategy":{"type":["string","null"],"description":"장소 추천 방식입니다. 장소 조율 모임이 아니면 null입니다.","enum":["MIDDLE_POINT","RANDOM"],"example":"MIDDLE_POINT"},"recommendationBasis":{"type":["string","null"],"description":"추천 산출 방식입니다. MIDDLE_POINT는 좌표가 있으면 STRAIGHT_LINE_PREVIEW를, 좌표가 하나도 없으면 COORDINATES_PENDING을 반환합니다. RANDOM은 RANDOM_CATALOG_PREVIEW를 반환하고, 장소 조율 모임이 아니면 null입니다.","enum":["STRAIGHT_LINE_PREVIEW","COORDINATES_PENDING","RANDOM_CATALOG_PREVIEW"],"example":"STRAIGHT_LINE_PREVIEW"},"center":{"type":["object","null"],"$ref":"#/components/schemas/CoordinateResponse","description":"참여자 출발지 좌표의 단순 평균 지점입니다. MIDDLE_POINT에서 출발지가 하나 이상 있을 때만 반환하고, RANDOM 또는 장소 조율 모임이 아니면 null입니다."},"participantCount":{"type":"integer","format":"int64","description":"현재 참여 인원. 방장을 포함합니다.","example":4},"participants":{"type":"array","description":"참여자별 출발지 정보","items":{"$ref":"#/components/schemas/ParticipantDepartureResponse"}},"recommendations":{"type":"array","description":"추천 상권 목록. MIDDLE_POINT는 예비 후보를 최대 3개, RANDOM은 최대 5개 반환하며 추천이 없으면 빈 배열입니다.","items":{"$ref":"#/components/schemas/RecommendationResponse"}}}},"RecommendationResponse":{"type":"object","description":"추천 상권","properties":{"rank":{"type":"integer","format":"int32","description":"추천 순위","example":1},"areaCode":{"type":"string","description":"상권 코드","example":"1001491"},"areaName":{"type":"string","description":"상권명","example":"삼각지역"},"categoryName":{"type":"string","description":"상권 분류명","enum":["발달상권","관광특구"],"example":"관광특구"},"latitude":{"type":"number","description":"상권 중심 위도","example":37.5344715},"longitude":{"type":"number","description":"상권 중심 경도","example":126.9726696},"guName":{"type":"string","description":"자치구명","example":"용산구"},"dongName":{"type":"string","description":"행정동명","example":"한강로동"},"averageStraightDistanceMeters":{"type":["integer","null"],"format":"int64","description":"참여자 출발지에서 상권까지의 평균 직선거리 미터. 랜덤 추천이면 null입니다.","example":3200},"averageTravelTimeSeconds":{"type":["integer","null"],"format":"int64","description":"정원이 찬 뒤 최초 조회에서 저장한 참여자 평균 실제 이동시간(초)입니다. 직선거리 미리보기에서는 null입니다.","example":1200},"maxTravelTimeSeconds":{"type":["integer","null"],"format":"int64","description":"정원이 찬 뒤 최초 조회에서 저장한 참여자 최대 실제 이동시간(초)입니다. 직선거리 미리보기에서는 null입니다.","example":1800},"station":{"type":["object","null"],"$ref":"#/components/schemas/StationResponse","description":"상권과 매핑된 지하철역 정보입니다. 매핑이 없으면 null입니다. 거리·좌표는 노출하지 않습니다."}}},"StationResponse":{"type":"object","description":"상권과 매핑된 지하철역과 호선","properties":{"name":{"type":"string","description":"지하철역명","example":"강남역"},"lineNames":{"type":"array","description":"해당 역의 호선명 목록","example":["2호선","신분당선"],"items":{"type":"string"}}}},"SavedPlaceListResponse":{"type":"object","description":"내 장소 목록 응답입니다. 현재 저장 개수 제한은 없으며, `places`는 저장 일시가 최신인 항목부터 정렬됩니다.","properties":{"places":{"type":"array","description":"최근 저장순 장소 목록","items":{"$ref":"#/components/schemas/SavedPlaceResponse"}}}},"FeedbackListResponse":{"type":"object","description":"내 피드백 제출 이력 응답입니다.","properties":{"feedbacks":{"type":"array","description":"최신 제출 순 피드백 목록","items":{"$ref":"#/components/schemas/FeedbackResponse"}}}},"ReverseGeocodingResponse":{"type":"object","description":"좌표에 해당하는 주소 정보입니다. 카카오가 해당 주소를 제공하지 않으면 각 필드는 null입니다.","properties":{"roadAddress":{"type":["string","null"],"description":"도로명주소. 해당 좌표에 도로명주소가 없으면 null입니다.","example":"서울 중구 세종대로 110"},"jibunAddress":{"type":["string","null"],"description":"지번주소. 해당 좌표에 지번주소가 없으면 null입니다.","example":"서울 중구 태평로1가 31"},"isSupportedRegion":{"type":"boolean","description":"도로명주소 또는 지번주소 중 하나라도 서울특별시 또는 경기도이면 true입니다. 주소가 모두 없거나 지역을 판정할 수 없으면 false입니다.","example":true}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}}