From 28d2029418b0bbd5db1f4a3daf5aae9f9e229300 Mon Sep 17 00:00:00 2001 From: yongin1212 Date: Wed, 21 Oct 2026 19:50:10 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=A7=80=EB=8F=84=20=EC=A7=80=EC=97=AD=20=EC=A7=91=EA=B3=84=20?= =?UTF-8?q?=EB=B0=8F=20=ED=81=B4=EB=9F=AC=EC=8A=A4=ED=84=B0=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=20=EC=B6=94=EA=B0=80=20(#1820)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api/1820-admin-place-map.md | 166 +++++++++++++ .../dto/place/map/AdminPlaceMapRequest.java | 22 ++ .../dto/place/map/AdminPlaceMapResponse.java | 32 +++ .../place/lookup/AdminPlaceMapController.java | 98 ++++++++ .../place/map/AdminPlaceMapClusterToken.java | 93 ++++++++ .../place/map/AdminPlaceMapCondition.java | 39 +++ .../place/map/AdminPlaceMapProperties.java | 12 + .../place/map/AdminPlaceMapQueryService.java | 116 +++++++++ .../domain/exception/AdminErrorCode.java | 3 + .../place/AdminPlaceMapQueryRepository.java | 171 +++++++++++++ src/main/resources/application.yaml | 5 + .../admin/AdminMapPlaceControllerTest.java | 34 +++ .../lookup/AdminPlaceMapControllerTest.java | 73 ++++++ .../map/AdminPlaceMapClusterTokenTest.java | 50 ++++ .../place/map/AdminPlaceMapConditionTest.java | 31 +++ .../map/AdminPlaceMapQueryServiceTest.java | 114 +++++++++ ...ryRepositoryPostgreSqlIntegrationTest.java | 224 ++++++++++++++++++ .../resources/openapi-baseline/admin.json | 2 +- .../resources/openapi-baseline/openapi.json | 2 +- 19 files changed, 1285 insertions(+), 2 deletions(-) create mode 100644 docs/api/1820-admin-place-map.md create mode 100644 src/main/java/com/typenull/pingdom/moderation/api/dto/place/map/AdminPlaceMapRequest.java create mode 100644 src/main/java/com/typenull/pingdom/moderation/api/dto/place/map/AdminPlaceMapResponse.java create mode 100644 src/main/java/com/typenull/pingdom/moderation/api/place/lookup/AdminPlaceMapController.java create mode 100644 src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapClusterToken.java create mode 100644 src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapCondition.java create mode 100644 src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapProperties.java create mode 100644 src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapQueryService.java create mode 100644 src/main/java/com/typenull/pingdom/place/infrastructure/persistence/place/AdminPlaceMapQueryRepository.java create mode 100644 src/test/java/com/typenull/pingdom/moderation/api/place/lookup/AdminPlaceMapControllerTest.java create mode 100644 src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapClusterTokenTest.java create mode 100644 src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapConditionTest.java create mode 100644 src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapQueryServiceTest.java create mode 100644 src/test/java/com/typenull/pingdom/place/infrastructure/persistence/place/AdminPlaceMapQueryRepositoryPostgreSqlIntegrationTest.java diff --git a/docs/api/1820-admin-place-map.md b/docs/api/1820-admin-place-map.md new file mode 100644 index 000000000..6a1ba2819 --- /dev/null +++ b/docs/api/1820-admin-place-map.md @@ -0,0 +1,166 @@ +# 관리자 장소 지도 API 계약 (#1820) + +프론트 전달용 v1. 관리자 목록의 페이지와 독립적으로 지도 영역을 조회한다. +기존 공개 지도 API와 관리자 목록·상세 API는 변경하지 않는다. + +## 인증 및 공통 규칙 + +- 기존 관리자 JWT/세션 인증 및 `@AdminOnly` 권한 정책을 사용한다. +- 성공 응답은 DTO 직접 반환. 오류는 기존 `{ "message": "...", "code": "..." }` 형식이다. +- 좌표는 WGS84 경도/위도, 화면 크기는 device pixel이 아닌 CSS pixel이다. +- 목록의 page/limit/sortParam을 지도 요청에 전달하지 않는다. +- 숫자 ID는 기존 API와 동일한 JSON number다. + +## 1. 지도 조회 + +`GET /admin/places/map` + +| 파라미터 | 필수 | 규칙/기본값 | +|---|---|---| +| west, south, east, north | O | 유한한 숫자. 경도 -180~180, 위도 -85.05112878~85.05112878. west < east, south < north. 날짜변경선 횡단 미지원 | +| zoom | O | 정수 0~20 | +| width, height | O | 각각 정수 64~8192 CSS px | +| keyword | X | trim 후 최대 100자. 기본 빈 문자열. 기존 목록처럼 장소명·영문명·주소 부분 검색, 숫자는 등록자 ID 검색도 적용 | +| category | X | 기존 관리자 목록과 동일한 카테고리 별칭 정규화. 알 수 없는 값은 OTHER로 정규화 | +| discoveryStatus | X | VISIBLE / HIDDEN. 생략하면 모두 포함 | +| operatingStatus | X | OPERATING / TEMPORARILY_CLOSED / PERMANENTLY_CLOSED. 생략하면 모두 포함 | + +유효한 좌표와 PostGIS location이 있는 장소만 지도 대상으로 삼는다. 물리 삭제된 장소는 제외된다. +location과 위경도는 일치해야 하며 불일치 레코드는 제외한다. 지역 전체 수는 좌표 유무와 무관하게 +유효 지역 코드가 연결된 장소를 포함한다. 필터는 지역·공간·그룹 내부 목록에 동일하게 적용된다. + +```http +GET /admin/places/map?west=128.50&south=35.80&east=128.70&north=35.95&zoom=13&width=1200&height=800&category=CAFE +``` + +### 표현 및 집계 + +| zoom | mode | 표현 | +|---|---|---| +| 0~8 | SIDO | 시·도 전체 수 + 지역 미연결 장소의 공간 그룹/마커 | +| 9~11 | SIGUNGU | 시·군·구 전체 수 + 지역 미연결 장소의 공간 그룹/마커 | +| 12~20 | SPATIAL | 공간 그룹과 단일 장소 마커 | + +프론트는 zoom으로 응답 구조를 추정하지 않고 mode 및 각 배열을 사용한다. 모든 배열은 항상 존재한다. +지역은 **현재 화면 안에 해당 필터의 장소가 한 개 이상 있는 경우** 선택한다. 행정 경계 교차 판정은 +현재 경계 데이터가 없어 제공하지 않는다. regions.bounds는 해당 지역의 필터 적용 후 유효 좌표 장소 범위이며 +행정 경계가 아니다(`boundsSource=PLACE_EXTENT`). 표시 좌표는 현재 화면 안에 있는 동일 필터 장소의 평균이므로 화면 밖으로 나가지 않는다. 확대 bounds는 지역 전체 장소 범위를 유지한다. +지역 코드 미연결 장소는 clusters/markers로 별도 표시하여 조용히 누락시키지 않는다. + +- regions[].count: REGION 범위, 동일 필터의 지역 전체 장소 수. 좌표 없는 장소도 지역 코드가 있으면 포함. +- viewportPlaceCount: 현재 화면 안 동일 필터·유효 좌표 장소 수. 지역 전체 수와 합산하지 않는다. +- clusters[].count: VIEWPORT 범위, 현재 요청 영역과 해당 격자의 교집합 장소 수. +- 단일 장소는 마커, 2개 이상은 그룹. 공간 그룹과 마커 사이에 중복이 없다. +- 지역 모드에서는 지역 집계와 미연결 장소의 공간 결과 사이에 중복이 없다. +- 지역 없는 장소, 좌표 없는 장소는 기존 관리자 목록에서 계속 관리할 수 있다. + +### 응답 예시: 공간 혼합 + +```json +{ + "mode": "SPATIAL", + "zoom": 13, + "regions": [], + "clusters": [{ + "clusterKey": "v1:filterHash:resolution:x:y", + "clusterId": "opaque-token", + "count": 24, + "latitude": 35.871, + "longitude": 128.601, + "bounds": {"west":128.600,"south":35.870,"east":128.603,"north":35.873}, + "countScope": "VIEWPORT", + "action": "EXPAND", "nextZoom": 14 + }], + "markers": [{ + "id":1820,"name":"예시 카페","latitude":35.875,"longitude":128.610, + "category":"CAFE","discoveryStatus":"HIDDEN","operatingStatus":"OPERATING" + }], + "viewportPlaceCount": 25, + "complete": true, + "incompleteReason": null, + "recoveryAction": null +} +``` + +### 응답 예시: 지역 집계 + +```json +{ + "mode":"SIGUNGU", + "zoom":10, + "regions":[{ + "regionLevel":"SIGUNGU","regionCode":"27260","name":"대구광역시 수성구", + "count":320,"countScope":"REGION","latitude":35.858,"longitude":128.631, + "bounds":{"west":128.60,"south":35.80,"east":128.76,"north":35.90}, + "boundsSource":"PLACE_EXTENT","action":"EXPAND","nextZoom":12 + }], + "clusters":[],"markers":[],"viewportPlaceCount":120, + "complete":true,"incompleteReason":null,"recoveryAction":null +} +``` + +정상 0건: 해당 zoom의 mode, 배열은 모두 [], viewportPlaceCount=0, complete=true. + +### 표시량 및 탐색 + +- regions + clusters + markers 합계 초기 서버 상한은 200개이며 `admin.place-map.max-items`(환경변수 `ADMIN_PLACE_MAP_MAX_ITEMS`, 허용 4~2000)로 조정한다. 작은 화면은 CSS 면적에 따라 더 낮은 공간 표시 예산을 사용한다. +- 고정 Web Mercator 원점·zoom별 기본 64 CSS px 격자 사용. 화면 이동으로 원점은 변하지 않는다. +- 상한 초과 시 격자 크기를 2배씩 키워 재집계하며, 임의 LIMIT 결과를 전체처럼 반환하지 않는다. +- 지역 수 자체가 상한을 초과하면 전체 요청 영역을 SPATIAL로 전환한다. +- 유한한 재집계 한도 초과 시 배열을 비우고 complete=false, + incompleteReason=RESULT_BUDGET_EXCEEDED, recoveryAction=ZOOM_IN을 반환한다. +- EXPAND: bounds로 fitBounds한 뒤 zoom이 nextZoom보다 작으면 nextZoom까지 확대한다. SIDO의 nextZoom은 9, SIGUNGU는 12, 공간 그룹은 현재 zoom+1이다. 반드시 현재 단계보다 확대한다. bounds가 점 또는 선이면 지도 SDK의 padding/minimum span을 적용한다. +- clusterKey: 필터·미연결 범위·격자 해상도·셀 좌표로 결정되는 표시용 키. 같은 필터/해상도/셀은 지도 이동과 토큰 재발급에도 동일하다. 필터나 재집계 해상도가 바뀌면 변경된다. clusterId는 만료되는 목록 조회 토큰으로 표시 키로 사용하지 않는다. +- LIST: nextZoom=null. 그룹 내부 장소 목록을 연다. 같은 좌표의 그룹 또는 zoom=20 그룹은 LIST다. +- 지도 이동/필터 변경 시 이전 요청 취소 + 요청 순번 검사로 늦은 응답을 버린다. + +## 2. 그룹 내부 장소 목록 + +`GET /admin/places/map/clusters/{clusterId}/places?page=1&limit=20` + +- page: 기본 1, 1~1000000. limit: 기본 20, 1~100. 범위 밖은 400. +- ID 오름차순. 목록 항목은 위 markers와 동일한 최소 필드다. +- 필터는 다시 받지 않는다. 토큰에 원래 필터·요청 영역·고정 격자·집계 정책 v1을 결합한다. +- 토큰은 서버 서명으로 변조를 방지하며 5분간 유효하다. 권한은 매 요청 재검사한다. +- 그룹 구성/표시 필드 변경을 지문으로 감지하면 409로 거부한다. 다른 그룹으로 자동 해석하지 않는다. +- 토큰은 동일 셀이라도 조회 영역·필터가 다르면 별도 탐색 문맥이다. 클라이언트에서 분해/영속 저장하지 않는다. +- 페이지 요청마다 같은 그룹인지 검증한다. 데이터 스냅샷 저장 기능은 제공하지 않는다. + +```json +{ + "places":[{"id":1820,"name":"예시 카페","latitude":35.875,"longitude":128.610, + "category":"CAFE","discoveryStatus":"HIDDEN","operatingStatus":"OPERATING"}], + "page":1,"limit":20,"totalCount":24,"totalPages":2,"hasNext":true +} +``` + +장소 클릭 시 기존 `GET /admin/places/{id}`를 호출한다. + +## 오류 및 최신성 + +| HTTP | code | 프론트 처리 | +|---|---|---| +| 400 | ADMIN_PLACE_MAP_INVALID_REQUEST | 경계·크기·zoom·페이지·필터 입력 확인. 바인딩/Validation 오류는 기존 공통 오류 코드 적용 | +| 401 / 403 | 기존 인증/관리자 권한 오류 코드 | 기존 로그인/권한 처리 | +| 409 | ADMIN_PLACE_MAP_CLUSTER_INVALID | 토큰 변조·만료·그룹 변경·정책 버전 변경. 지도 재조회 후 다시 선택 | +| 503 | ADMIN_PLACE_MAP_QUERY_TIMEOUT | 잠시 후 사용자 재조회. 자동 무한 재시도 금지 | + +v1은 응답/지역 집계 캐시와 사전 집계를 사용하지 않는다. HTTP Cache-Control: no-store. +변경 커밋 후 다음 조회에 반영되며 응답 내 여러 SQL은 동일 REPEATABLE_READ 스냅샷을 사용한다. +그룹 토큰의 5분 유효기간은 응답 캐시 TTL이 아니다. SQL statement timeout은 쿼리당 3초의 중단 기준이며 전체 API 응답시간 보장이 아니다. 전체 서버 응답시간은 기존 Actuator `http.server.requests`의 지도/그룹 URI 템플릿별 timer로 별도 측정한다(응답 직렬화 포함, 네트워크 왕복 제외). 대구 전체·밀집 영역의 실제 데이터 결과를 기준으로 상한과 확대 정책을 조정한다. +실제 대구 데이터의 실행 계획·응답 시간은 운영 승인 데이터로 별도 측정해야 하며 200개는 성능 보장값이 아니다. + +## 프론트 구현 순서 + +1. 지도 idle(이동·확대 완료) 이벤트를 debounce하고 경계/zoom/크기/필터로 요청한다. +2. 최신 요청 응답의 regions, clusters, markers를 모두 표시한다. +3. 지역 및 EXPAND 그룹은 확대, LIST 그룹은 페이지 목록, 마커는 기존 상세를 연다. +4. 필터 변경 시 이전 그룹 목록/토큰을 폐기한다. 409는 지도 재조회, complete=false는 확대 안내한다. + +## 구현 검증 기록 + +- 전체 단위 테스트 1,455개 통과 후 최종 변경 관련 단위/공개 지도 회귀 19개, PostGIS 7개, 실제 인증 경로 2개 통과. +- 대구 범위를 사용하는 가상 장소 10,000건: HTTP dispatch·응답 직렬화 포함 약 347ms, 공간 집계 SQL 실행 약 74ms, 120개 그룹으로 10,000건 누락 없이 표현. +- 동일 건물 30건 그룹 유지·페이지 조회·변경 후 409, 화면 밖 장소를 포함한 지역 전체 수와 화면 안 대표 좌표, 고정 격자/표시 키 안정성을 확인했다. +- 위 수치는 로컬 단일 실행·가상 데이터이며 운영 대구 실데이터나 p95 보장값이 아니다. 초기 상한 200과 zoom 경계는 유지한다. +- 변경 전 HEAD의 생성 OpenAPI와 비교해 기존 경로/스키마 변경이 없음을 확인하고 신규 두 경로와 지도 전용 스키마만 baseline에 추가했다. diff --git a/src/main/java/com/typenull/pingdom/moderation/api/dto/place/map/AdminPlaceMapRequest.java b/src/main/java/com/typenull/pingdom/moderation/api/dto/place/map/AdminPlaceMapRequest.java new file mode 100644 index 000000000..7e85f9895 --- /dev/null +++ b/src/main/java/com/typenull/pingdom/moderation/api/dto/place/map/AdminPlaceMapRequest.java @@ -0,0 +1,22 @@ +package com.typenull.pingdom.moderation.api.dto.place.map; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Size; +import io.swagger.v3.oas.annotations.media.Schema; +import com.typenull.pingdom.place.domain.place.discovery.PlaceDiscoveryStatus; +import com.typenull.pingdom.place.domain.place.operating.PlaceOperatingStatus; + +@Schema(description = "지도 경계 WGS84, CSS pixel 크기. 날짜변경선 횡단은 지원하지 않습니다.") +public record AdminPlaceMapRequest( + @Schema(minimum = "-180", maximum = "180", example = "128.5") @NotNull Double west, + @Schema(minimum = "-85.05112878", maximum = "85.05112878", example = "35.8") @NotNull Double south, + @Schema(minimum = "-180", maximum = "180", example = "128.7") @NotNull Double east, + @Schema(minimum = "-85.05112878", maximum = "85.05112878", example = "35.95") @NotNull Double north, + @NotNull @Min(0) @Max(20) Integer zoom, + @NotNull @Min(64) @Max(8192) Integer width, + @NotNull @Min(64) @Max(8192) Integer height, + @Size(max = 100) String keyword, @Size(max = 100) String category, + PlaceDiscoveryStatus discoveryStatus, PlaceOperatingStatus operatingStatus +) {} diff --git a/src/main/java/com/typenull/pingdom/moderation/api/dto/place/map/AdminPlaceMapResponse.java b/src/main/java/com/typenull/pingdom/moderation/api/dto/place/map/AdminPlaceMapResponse.java new file mode 100644 index 000000000..fe854d68a --- /dev/null +++ b/src/main/java/com/typenull/pingdom/moderation/api/dto/place/map/AdminPlaceMapResponse.java @@ -0,0 +1,32 @@ +package com.typenull.pingdom.moderation.api.dto.place.map; + +import java.util.List; +import io.swagger.v3.oas.annotations.media.Schema; + +/** 지역 전체 집계와 viewport 공간 집계는 서로 합산하지 않는다. */ +@Schema(description = "관리자 지도. 지역 전체 count와 viewportPlaceCount는 별도 범위이며 합산하지 않습니다.") +public record AdminPlaceMapResponse( + @Schema(allowableValues = {"SIDO", "SIGUNGU", "SPATIAL"}) String mode, int zoom, List regions, List clusters, List markers, + @Schema(description = "현재 화면 안의 동일 필터·유효 좌표 장소 수. 지역 전체 count와 합산하지 않습니다.") long viewportPlaceCount, + @Schema(description = "모든 표시 대상을 누락 없이 표현했는지 여부") boolean complete, + @Schema(nullable = true, allowableValues = {"RESULT_BUDGET_EXCEEDED"}) String incompleteReason, + @Schema(nullable = true, allowableValues = {"ZOOM_IN"}) String recoveryAction +) { + @Schema(name = "AdminPlaceMapBounds") + public record Bounds(double west, double south, double east, double north) {} + @Schema(name = "AdminPlaceMapRegion") + public record Region(String regionLevel, String regionCode, String name, long count, + String countScope, double latitude, double longitude, Bounds bounds, + @Schema(allowableValues = {"PLACE_EXTENT"}) String boundsSource, + @Schema(allowableValues = {"EXPAND"}) String action, int nextZoom) {} + @Schema(name = "AdminPlaceMapCluster") + public record Cluster(String clusterKey, String clusterId, long count, double latitude, double longitude, + Bounds bounds, String countScope, + @Schema(allowableValues = {"EXPAND", "LIST"}) String action, Integer nextZoom) {} + @Schema(name = "AdminPlaceMapMarker") + public record Marker(long id, String name, double latitude, double longitude, String category, + String discoveryStatus, String operatingStatus) {} + @Schema(name = "AdminPlaceMapGroupPage") + public record GroupPage(List places, int page, int limit, long totalCount, + long totalPages, boolean hasNext) {} +} diff --git a/src/main/java/com/typenull/pingdom/moderation/api/place/lookup/AdminPlaceMapController.java b/src/main/java/com/typenull/pingdom/moderation/api/place/lookup/AdminPlaceMapController.java new file mode 100644 index 000000000..75c2c1154 --- /dev/null +++ b/src/main/java/com/typenull/pingdom/moderation/api/place/lookup/AdminPlaceMapController.java @@ -0,0 +1,98 @@ +package com.typenull.pingdom.moderation.api.place.lookup; + +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapRequest; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse.GroupPage; +import com.typenull.pingdom.moderation.application.query.place.map.AdminPlaceMapQueryService; +import com.typenull.pingdom.shared.config.swagger.ApiAudience; +import com.typenull.pingdom.shared.config.swagger.SwaggerTagCatalog; +import com.typenull.pingdom.shared.security.annotation.AdminOnly; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.http.CacheControl; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(value = "/admin/places/map", produces = "application/json") +@RequiredArgsConstructor +@AdminOnly +@ApiAudience(ApiAudience.Group.ADMIN) +@Tag(name = SwaggerTagCatalog.PLACE_LOOKUP) +public class AdminPlaceMapController { + private final AdminPlaceMapQueryService service; + + @GetMapping + @Operation(summary = "관리자 지도 지역 집계 및 공간 그룹 조회", description = "zoom 0~8 SIDO, 9~11 SIGUNGU, 12~20 SPATIAL. " + + "지역은 화면 안 장소 기준으로 선택하며 count는 동일 필터의 지역 전체 수입니다. " + + "bounds는 행정 경계가 아닌 PLACE_EXTENT입니다. 지역 미연결 장소는 공간 그룹/마커로 반환합니다. " + + "viewportPlaceCount와 지역 count는 합산하지 않습니다. 초기 상한 200개(설정 가능)이며 초과 시 재집계합니다. EXPAND는 nextZoom 이상 확대합니다. clusterKey는 표시용 고정 키입니다. " + + "안전 한도 초과는 complete=false, RESULT_BUDGET_EXCEEDED, ZOOM_IN으로 안내합니다. " + + "정상 0건은 빈 배열, viewportPlaceCount=0, complete=true입니다.") + @ApiResponses({@ApiResponse(responseCode = "200", description = "지역/공간 혼합 또는 빈 결과", + content = @Content(schema = @Schema(implementation = AdminPlaceMapResponse.class), examples = { + @ExampleObject(name = "spatial", summary = "공간 그룹과 개별 장소", value = """ + {"mode":"SPATIAL","zoom":13,"regions":[], + "clusters":[{"clusterKey":"v1:filterHash:resolution:x:y","clusterId":"opaque-token","count":24,"latitude":35.871,"longitude":128.601, + "bounds":{"west":128.600,"south":35.870,"east":128.603,"north":35.873}, + "countScope":"VIEWPORT","action":"EXPAND","nextZoom":14}], + "markers":[{"id":1820,"name":"예시 카페","latitude":35.875,"longitude":128.610, + "category":"CAFE","discoveryStatus":"HIDDEN","operatingStatus":"OPERATING"}], + "viewportPlaceCount":25,"complete":true,"incompleteReason":null,"recoveryAction":null} + """), + @ExampleObject(name = "regional", summary = "지역 전체 수와 화면 내 수 구분", value = """ + {"mode":"SIGUNGU","zoom":10, + "regions":[{"regionLevel":"SIGUNGU","regionCode":"27260","name":"대구광역시 수성구", + "count":320,"countScope":"REGION","latitude":35.858,"longitude":128.631, + "bounds":{"west":128.60,"south":35.80,"east":128.76,"north":35.90}, + "boundsSource":"PLACE_EXTENT","action":"EXPAND","nextZoom":12}], + "clusters":[],"markers":[],"viewportPlaceCount":120,"complete":true, + "incompleteReason":null,"recoveryAction":null} + """), + @ExampleObject(name = "empty", summary = "정상 0건", value = """ + {"mode":"SPATIAL","zoom":13,"regions":[],"clusters":[],"markers":[], + "viewportPlaceCount":0,"complete":true,"incompleteReason":null,"recoveryAction":null} + """) + })), + @ApiResponse(responseCode = "400", description = "잘못된 경계·zoom·크기·필터", + content = @Content(examples = @ExampleObject(value = """ + {"message":"관리자 지도 조회 조건이 올바르지 않습니다.","code":"ADMIN_PLACE_MAP_INVALID_REQUEST"} + """))), + @ApiResponse(responseCode = "401", description = "인증 필요"), + @ApiResponse(responseCode = "403", description = "관리자 권한 필요"), + @ApiResponse(responseCode = "503", description = "ADMIN_PLACE_MAP_QUERY_TIMEOUT")}) + public ResponseEntity find(@Valid @ModelAttribute @ParameterObject AdminPlaceMapRequest request) { + return ResponseEntity.ok().cacheControl(CacheControl.noStore()).body(service.find(request)); + } + + @GetMapping("/clusters/{clusterId}/places") + @Operation(summary = "관리자 지도 그룹 내부 장소 조회", description = "원래 필터·영역·격자를 유지한 ID 오름차순 페이지. " + + "page 1~1000000, limit 1~100. 토큰은 5분 유효하며 변조·만료·그룹 변경·정책 버전 변경은 409. " + + "409 발생 시 지도 재조회 후 그룹을 다시 선택합니다. 각 요청에서 관리자 권한을 재검사합니다.") + @ApiResponses({@ApiResponse(responseCode = "200", description = "그룹 내부 장소 페이지"), + @ApiResponse(responseCode = "400", description = "잘못된 페이지"), + @ApiResponse(responseCode = "401", description = "인증 필요"), + @ApiResponse(responseCode = "403", description = "관리자 권한 필요"), + @ApiResponse(responseCode = "409", description = "ADMIN_PLACE_MAP_CLUSTER_INVALID: 지도 재조회 필요", + content = @Content(examples = @ExampleObject(value = """ + {"message":"지도 그룹이 만료되었거나 변경되었습니다. 지도를 다시 조회해주세요.","code":"ADMIN_PLACE_MAP_CLUSTER_INVALID"} + """))), + @ApiResponse(responseCode = "503", description = "ADMIN_PLACE_MAP_QUERY_TIMEOUT")}) + public ResponseEntity groupPlaces(@PathVariable String clusterId, + @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "20") int limit) { + return ResponseEntity.ok().cacheControl(CacheControl.noStore()).body(service.groupPlaces(clusterId, page, limit)); + } +} diff --git a/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapClusterToken.java b/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapClusterToken.java new file mode 100644 index 000000000..daee83222 --- /dev/null +++ b/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapClusterToken.java @@ -0,0 +1,93 @@ +package com.typenull.pingdom.moderation.application.query.place.map; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.typenull.pingdom.moderation.domain.exception.AdminErrorCode; +import com.typenull.pingdom.moderation.domain.exception.AdminException; +import com.typenull.pingdom.shared.security.jwt.JwtProperties; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.time.Clock; +import java.util.Base64; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** Access/Refresh JWT와 구별되는 목적별 HMAC 토큰. 저장소 없이 다중 인스턴스에서 검증한다. */ +@Component +public class AdminPlaceMapClusterToken { + private static final Base64.Encoder ENCODER = Base64.getUrlEncoder().withoutPadding(); + private static final Base64.Decoder DECODER = Base64.getUrlDecoder(); + private final ObjectMapper mapper; + private final byte[] key; + private final Clock clock; + + @Autowired + public AdminPlaceMapClusterToken(ObjectMapper mapper, JwtProperties properties) { + this(mapper, properties, Clock.systemUTC()); + } + + AdminPlaceMapClusterToken(ObjectMapper mapper, JwtProperties properties, Clock clock) { + this.mapper = mapper; + this.clock = clock; + this.key = properties.secret().getBytes(StandardCharsets.UTF_8); + } + + public String issue(AdminPlaceMapCondition condition, double cellSize, long x, long y, + boolean unknownOnly, String fingerprint) { + var payload = new Payload(1, clock.instant().getEpochSecond() + 300, + condition, cellSize, x, y, unknownOnly, fingerprint); + try { + String body = ENCODER.encodeToString(mapper.writeValueAsBytes(payload)); + return body + "." + ENCODER.encodeToString(sign(body)); + } catch (java.io.IOException e) { + throw new IllegalStateException("관리자 지도 그룹 토큰 직렬화 실패", e); + } + } + + /** 표시 키는 필터·고정 격자만 사용한다. 화면 이동, 토큰 발급 시각, 멤버 수는 포함하지 않는다. */ + public String displayKey(AdminPlaceMapCondition c, double cell, long x, long y, boolean unknownOnly) { + try { + String scope = c.keyword().toLowerCase(java.util.Locale.ROOT) + "\n" + c.category() + "\n" + + c.discoveryStatus() + "\n" + c.operatingStatus() + "\n" + unknownOnly; + String hash = java.util.HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256") + .digest(scope.getBytes(StandardCharsets.UTF_8))); + return "v1:" + hash + ":" + Double.toHexString(cell) + ":" + x + ":" + y; + } catch (java.security.NoSuchAlgorithmException e) { + throw new IllegalStateException(e); + } + } + + public Payload read(String token) { + try { + if (token == null || token.length() > 4096) throw invalid(); + String[] parts = token.split("\\.", -1); + if (parts.length != 2 || !MessageDigest.isEqual(sign(parts[0]), DECODER.decode(parts[1]))) throw invalid(); + Payload p = mapper.readValue(DECODER.decode(parts[0]), Payload.class); + if (p.version() != 1 || p.expiresAt() <= clock.instant().getEpochSecond() + || p.condition() == null || !Double.isFinite(p.cellSize()) || p.cellSize() <= 0 + || p.fingerprint() == null) throw invalid(); + p.condition().validate(); + return p; + } catch (java.io.IOException | IllegalArgumentException | AdminException e) { + throw invalid(); + } + } + + private byte[] sign(String body) { + try { + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(key, "HmacSHA256")); + return mac.doFinal(("admin-place-map:v1:" + body).getBytes(StandardCharsets.UTF_8)); + } catch (java.security.GeneralSecurityException e) { + throw new IllegalStateException("관리자 지도 그룹 토큰 서명 실패", e); + } + } + + private AdminException invalid() { + return new AdminException(AdminErrorCode.ADMIN_PLACE_MAP_CLUSTER_INVALID); + } + + public record Payload(int version, long expiresAt, AdminPlaceMapCondition condition, + double cellSize, long x, long y, boolean unknownOnly, String fingerprint) {} +} diff --git a/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapCondition.java b/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapCondition.java new file mode 100644 index 000000000..3d65d537f --- /dev/null +++ b/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapCondition.java @@ -0,0 +1,39 @@ +package com.typenull.pingdom.moderation.application.query.place.map; + +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapRequest; +import com.typenull.pingdom.moderation.domain.exception.AdminErrorCode; +import com.typenull.pingdom.moderation.domain.exception.AdminException; +import com.typenull.pingdom.place.domain.place.category.PlaceCategoryPolicy; +import com.typenull.pingdom.place.domain.place.discovery.PlaceDiscoveryStatus; +import com.typenull.pingdom.place.domain.place.operating.PlaceOperatingStatus; + +/** 토큰에도 원래 조회 조건을 담아 후속 페이지에서 필터와 영역이 바뀌지 않게 한다. */ +public record AdminPlaceMapCondition(double west, double south, double east, double north, + String keyword, String category, + PlaceDiscoveryStatus discoveryStatus, PlaceOperatingStatus operatingStatus) { + public static final double MAX_LATITUDE = 85.05112878; + + public static AdminPlaceMapCondition from(AdminPlaceMapRequest r) { + if (r.west() == null || r.south() == null || r.east() == null || r.north() == null + || r.zoom() == null || r.zoom() < 0 || r.zoom() > 20 + || r.width() == null || r.width() < 64 || r.width() > 8192 + || r.height() == null || r.height() < 64 || r.height() > 8192 + || (r.keyword() != null && r.keyword().length() > 100) + || (r.category() != null && r.category().length() > 100)) { + throw new AdminException(AdminErrorCode.ADMIN_PLACE_MAP_INVALID_REQUEST); + } + var condition = new AdminPlaceMapCondition(r.west(), r.south(), r.east(), r.north(), + r.keyword() == null ? "" : r.keyword().trim(), PlaceCategoryPolicy.normalize(r.category()), + r.discoveryStatus(), r.operatingStatus()); + condition.validate(); + return condition; + } + + public void validate() { + if (!Double.isFinite(west) || !Double.isFinite(south) || !Double.isFinite(east) || !Double.isFinite(north) + || west < -180 || east > 180 || south < -MAX_LATITUDE || north > MAX_LATITUDE + || west >= east || south >= north || keyword == null || keyword.length() > 100) { + throw new AdminException(AdminErrorCode.ADMIN_PLACE_MAP_INVALID_REQUEST); + } + } +} diff --git a/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapProperties.java b/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapProperties.java new file mode 100644 index 000000000..8c147b403 --- /dev/null +++ b/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapProperties.java @@ -0,0 +1,12 @@ +package com.typenull.pingdom.moderation.application.query.place.map; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.bind.DefaultValue; +import org.springframework.validation.annotation.Validated; + +/** 표시 상한의 초기값은 200이며 데이터 측정 후 설정으로 조정한다. */ +@Validated +@ConfigurationProperties("admin.place-map") +public record AdminPlaceMapProperties(@DefaultValue("200") @Min(4) @Max(2000) int maxItems) {} diff --git a/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapQueryService.java b/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapQueryService.java new file mode 100644 index 000000000..93ee60488 --- /dev/null +++ b/src/main/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapQueryService.java @@ -0,0 +1,116 @@ +package com.typenull.pingdom.moderation.application.query.place.map; + +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapRequest; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse.Cluster; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse.GroupPage; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse.Region; +import com.typenull.pingdom.moderation.domain.exception.AdminErrorCode; +import com.typenull.pingdom.moderation.domain.exception.AdminException; +import com.typenull.pingdom.place.infrastructure.persistence.place.AdminPlaceMapQueryRepository; +import com.typenull.pingdom.place.infrastructure.persistence.place.AdminPlaceMapQueryRepository.Cell; +import java.util.ArrayList; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.dao.QueryTimeoutException; +import org.springframework.dao.DataAccessException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; + +/** 지역 count와 viewport count를 분리하고 제한 초과 시 격자를 넓혀 재집계한다. */ +@Service +@RequiredArgsConstructor +public class AdminPlaceMapQueryService { + private static final double WORLD_METERS = 40075016.68557849; + private final AdminPlaceMapQueryRepository repository; + private final AdminPlaceMapClusterToken tokens; + private final AdminPlaceMapProperties properties; + + // 집계 후 마커/그룹 검증 사이의 동시 변경으로 응답 내 개수가 어긋나지 않도록 동일 스냅샷을 사용한다. + @Transactional(readOnly = true, isolation = Isolation.REPEATABLE_READ) + public AdminPlaceMapResponse find(AdminPlaceMapRequest request) { + var condition = AdminPlaceMapCondition.from(request); + int maxItems = properties.maxItems(); + try { + repository.setQueryTimeout(); + long viewportCount = repository.countViewport(condition); + String mode = request.zoom() <= 8 ? "SIDO" : request.zoom() <= 11 ? "SIGUNGU" : "SPATIAL"; + if (viewportCount == 0) return response(mode, request.zoom(), List.of(), List.of(), List.of(), 0); + List regions = "SPATIAL".equals(mode) ? List.of() : repository.findRegions(condition, mode, maxItems + 1); + // 지역만으로 예산을 소진하면 전체 viewport를 공간 모드로 바꿔 누락 없이 묶는다. + if (regions.size() >= maxItems) { + regions = List.of(); + mode = "SPATIAL"; + } + boolean unknownOnly = !"SPATIAL".equals(mode); + int screenBudget = Math.max(4, Math.min(maxItems, (int) ((long) request.width() * request.height() / (64 * 64)))); + int budget = Math.max(1, Math.min(maxItems - regions.size(), screenBudget)); + double cellSize = WORLD_METERS / Math.scalb(1d, request.zoom()) / 4d; + List cells = List.of(); + // 최대 세계 크기의 두 배 셀까지 유한하게 재집계한다. LIMIT은 초과 감지용이며 결과 절단용이 아니다. + for (int attempt = 0; attempt < 24; attempt++) { + cells = repository.findCells(condition, cellSize, unknownOnly, budget + 1); + if (cells.size() <= budget) break; + cellSize *= 2; + } + if (cells.size() > budget) { + return new AdminPlaceMapResponse(mode, request.zoom(), List.of(), List.of(), List.of(), + viewportCount, false, "RESULT_BUDGET_EXCEEDED", "ZOOM_IN"); + } + var clusters = new ArrayList(); + var singleIds = new ArrayList(); + for (Cell cell : cells) { + if (cell.count() == 1) { + singleIds.add(cell.singleId()); + } else { + boolean sameCoordinate = cell.bounds().west() == cell.bounds().east() + && cell.bounds().south() == cell.bounds().north(); + String token = tokens.issue(condition, cellSize, cell.x(), cell.y(), unknownOnly, cell.fingerprint()); + clusters.add(new Cluster(tokens.displayKey(condition, cellSize, cell.x(), cell.y(), unknownOnly), token, cell.count(), cell.latitude(), cell.longitude(), cell.bounds(), + "VIEWPORT", request.zoom() == 20 || sameCoordinate ? "LIST" : "EXPAND", + request.zoom() == 20 || sameCoordinate ? null : request.zoom() + 1)); + } + } + return response(mode, request.zoom(), regions, clusters, repository.markers(singleIds), viewportCount); + } catch (DataAccessException e) { + throw queryFailure(e); + } + } + + @Transactional(readOnly = true, isolation = Isolation.REPEATABLE_READ) + public GroupPage groupPlaces(String token, int page, int limit) { + if (page < 1 || page > 1000000 || limit < 1 || limit > 100) { + throw new AdminException(AdminErrorCode.ADMIN_PLACE_MAP_INVALID_REQUEST); + } + var p = tokens.read(token); + try { + repository.setQueryTimeout(); + var state = repository.groupState(p.condition(), p.cellSize(), p.x(), p.y(), p.unknownOnly()); + if (state.count() < 2 || !p.fingerprint().equals(state.fingerprint())) { + throw new AdminException(AdminErrorCode.ADMIN_PLACE_MAP_CLUSTER_INVALID); + } + long pages = (state.count() + limit - 1) / limit; + var places = repository.groupPlaces(p.condition(), p.cellSize(), p.x(), p.y(), p.unknownOnly(), page, limit); + return new GroupPage(places, page, limit, state.count(), pages, page < pages); + } catch (DataAccessException e) { + throw queryFailure(e); + } + } + + private RuntimeException queryFailure(DataAccessException exception) { + // PostgreSQL 57014는 드라이버 설정에 따라 QueryTimeoutException 이외의 예외로도 변환된다. + for (Throwable cause = exception; cause != null; cause = cause.getCause()) { + if (cause instanceof QueryTimeoutException + || cause instanceof java.sql.SQLException sql && "57014".equals(sql.getSQLState())) { + return new AdminException(AdminErrorCode.ADMIN_PLACE_MAP_QUERY_TIMEOUT, exception); + } + } + return exception; + } + + private AdminPlaceMapResponse response(String mode, int zoom, List regions, List clusters, + List markers, long total) { + return new AdminPlaceMapResponse(mode, zoom, regions, clusters, markers, total, true, null, null); + } +} diff --git a/src/main/java/com/typenull/pingdom/moderation/domain/exception/AdminErrorCode.java b/src/main/java/com/typenull/pingdom/moderation/domain/exception/AdminErrorCode.java index d2136f396..3c29d60f2 100644 --- a/src/main/java/com/typenull/pingdom/moderation/domain/exception/AdminErrorCode.java +++ b/src/main/java/com/typenull/pingdom/moderation/domain/exception/AdminErrorCode.java @@ -8,6 +8,9 @@ @Getter @RequiredArgsConstructor public enum AdminErrorCode implements ErrorCode { + ADMIN_PLACE_MAP_INVALID_REQUEST(HttpStatus.BAD_REQUEST, "관리자 지도 조회 조건이 올바르지 않습니다."), + ADMIN_PLACE_MAP_CLUSTER_INVALID(HttpStatus.CONFLICT, "지도 그룹이 만료되었거나 변경되었습니다. 지도를 다시 조회해주세요."), + ADMIN_PLACE_MAP_QUERY_TIMEOUT(HttpStatus.SERVICE_UNAVAILABLE, "지도 조회 시간이 초과되었습니다. 잠시 후 다시 조회해주세요."), ADMIN_ROLE_ASSIGNMENT_INVALID(HttpStatus.BAD_REQUEST, "관리자 역할 할당 요청이 올바르지 않습니다."), ADMIN_PERMISSION_REQUIRED(HttpStatus.FORBIDDEN, "요청을 처리할 관리자 권한이 없습니다."), ADMIN_ROLE_ASSIGNMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "관리자 역할 할당을 찾을 수 없습니다."), diff --git a/src/main/java/com/typenull/pingdom/place/infrastructure/persistence/place/AdminPlaceMapQueryRepository.java b/src/main/java/com/typenull/pingdom/place/infrastructure/persistence/place/AdminPlaceMapQueryRepository.java new file mode 100644 index 000000000..a4728607d --- /dev/null +++ b/src/main/java/com/typenull/pingdom/place/infrastructure/persistence/place/AdminPlaceMapQueryRepository.java @@ -0,0 +1,171 @@ +package com.typenull.pingdom.place.infrastructure.persistence.place; + +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse.Bounds; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse.Marker; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse.Region; +import com.typenull.pingdom.moderation.application.query.place.map.AdminPlaceMapCondition; +import com.typenull.pingdom.place.domain.place.category.PlaceCategoryPolicy; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Collection; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.stereotype.Repository; + +/** + * 기존 viewport와 같은 PostGIS bbox/SQL 집계를 관리자 범위로 적용한다. + * 공개 전용 VISIBLE/OPERATING 조건은 복사하지 않는다. 전체 장소를 JVM에 적재하지 않는다. + */ +@Repository +@RequiredArgsConstructor +public class AdminPlaceMapQueryRepository { + private final NamedParameterJdbcTemplate jdbc; + + private static final String FILTER = """ + (CAST(:keyword AS text) = '' + OR LOWER(mp.place_name) LIKE LOWER(CONCAT('%', :keyword, '%')) + OR LOWER(mp.english_name) LIKE LOWER(CONCAT('%', :keyword, '%')) + OR LOWER(mp.address) LIKE LOWER(CONCAT('%', :keyword, '%')) + OR mp.user_id = :numericKeyword) + AND (:hasCategory = false OR LOWER(TRIM(mp.category)) IN (:aliases)) + AND (CAST(:discovery AS text) IS NULL OR mp.discovery_status = :discovery) + AND (CAST(:operating AS text) IS NULL OR mp.operating_status = :operating) + """; + // 숫자 좌표와 인덱스 좌표의 불일치를 제외하고 Mercator 변환의 정의역을 보장한다. + private static final String VALID = """ + mp.latitude BETWEEN -85.05112878 AND 85.05112878 + AND mp.longitude BETWEEN -180 AND 180 + AND mp.location IS NOT NULL AND NOT ST_IsEmpty(mp.location) + AND ST_X(mp.location) = mp.longitude AND ST_Y(mp.location) = mp.latitude + """; + private static final String VIEWPORT = """ + mp.location && ST_MakeEnvelope(:west, :south, :east, :north, 4326) + """; + private static final String UNKNOWN_REGION = """ + AND NOT EXISTS (SELECT 1 FROM place_administrative_region r WHERE r.region_code = mp.region_code) + """; + // 두 독립 64-bit 지문으로 구성/필드 변경을 감지한다. 토큰 서명과는 별개의 변경 검사용 값이다. + private static final String FINGERPRINT = """ + CONCAT(COUNT(*), ':', bit_xor(hashtextextended(ROW(map_place_id, place_name, category, + latitude, longitude, discovery_status, operating_status, region_code)::text, 0)), ':', + bit_xor(hashtextextended(ROW(map_place_id, place_name, category, + latitude, longitude, discovery_status, operating_status, region_code)::text, 1))) + """; + private static final String CELL = """ + FLOOR(ST_X(ST_Transform(location, 3857)) / :cell) = :gridX + AND FLOOR(ST_Y(ST_Transform(location, 3857)) / :cell) = :gridY + """; + + public void setQueryTimeout() { + // SET LOCAL에 해당한다. 현재 트랜잭션 종료 시 커넥션의 기존 설정으로 복원된다. + jdbc.getJdbcTemplate().execute("SELECT set_config('statement_timeout', '3000', true)"); + } + + public long countViewport(AdminPlaceMapCondition c) { + return jdbc.queryForObject("SELECT COUNT(*) FROM map_place mp WHERE " + FILTER + " AND " + VALID + + " AND " + VIEWPORT, params(c), Long.class); + } + + public List findRegions(AdminPlaceMapCondition c, String level, int limit) { + boolean sido = "SIDO".equals(level); + String code = sido ? "LEFT(r.region_code, 2)" : "r.region_code"; + String name = sido ? "r.sido" : "r.region_name"; + // 선택은 viewport 내 장소 기준, count는 선택한 지역 전체의 동일 필터 기준이다. + String sql = """ + WITH selected AS ( + SELECT DISTINCT %s AS code + FROM map_place mp JOIN place_administrative_region r ON r.region_code = mp.region_code + WHERE %s AND %s AND %s + ) + SELECT %s AS code, MIN(%s) AS name, COUNT(*) AS place_count, + AVG(CASE WHEN %s THEN mp.latitude END) AS latitude, + AVG(CASE WHEN %s THEN mp.longitude END) AS longitude, + MIN(CASE WHEN %s THEN mp.longitude END) AS west, + MIN(CASE WHEN %s THEN mp.latitude END) AS south, + MAX(CASE WHEN %s THEN mp.longitude END) AS east, + MAX(CASE WHEN %s THEN mp.latitude END) AS north + FROM map_place mp JOIN place_administrative_region r ON r.region_code = mp.region_code + JOIN selected s ON s.code = %s + WHERE %s + GROUP BY %s ORDER BY code LIMIT :limit + """.formatted(code, FILTER, VALID, VIEWPORT, code, name, + (VALID + " AND " + VIEWPORT), (VALID + " AND " + VIEWPORT), VALID, VALID, VALID, VALID, code, FILTER, code); + return jdbc.query(sql, params(c).addValue("limit", limit), (rs, row) -> new Region(level, + rs.getString("code"), rs.getString("name"), rs.getLong("place_count"), "REGION", + rs.getDouble("latitude"), rs.getDouble("longitude"), bounds(rs), "PLACE_EXTENT", "EXPAND", sido ? 9 : 12)); + } + + private String points(boolean unknownOnly) { + // MATERIALIZED는 유효성 검증 전 ST_Transform이 실행되는 planner 재배치를 막는다. + return "WITH points AS MATERIALIZED (SELECT mp.* FROM map_place mp WHERE " + FILTER + + " AND " + VALID + " AND " + VIEWPORT + (unknownOnly ? UNKNOWN_REGION : "") + ") "; + } + + public List findCells(AdminPlaceMapCondition c, double cellSize, boolean unknownOnly, int limit) { + String sql = points(unknownOnly) + """ + SELECT FLOOR(ST_X(ST_Transform(location, 3857)) / :cell)::bigint AS grid_x, + FLOOR(ST_Y(ST_Transform(location, 3857)) / :cell)::bigint AS grid_y, + COUNT(*) AS place_count, MIN(map_place_id) AS single_id, + AVG(latitude) AS latitude, AVG(longitude) AS longitude, + MIN(longitude) AS west, MIN(latitude) AS south, + MAX(longitude) AS east, MAX(latitude) AS north, + """ + FINGERPRINT + " AS fingerprint FROM points GROUP BY grid_x, grid_y ORDER BY grid_y, grid_x LIMIT :limit"; + return jdbc.query(sql, params(c).addValue("cell", cellSize).addValue("limit", limit), + (rs, row) -> new Cell(rs.getLong("grid_x"), rs.getLong("grid_y"), rs.getLong("place_count"), + rs.getLong("single_id"), rs.getDouble("latitude"), rs.getDouble("longitude"), + bounds(rs), rs.getString("fingerprint"))); + } + + public GroupState groupState(AdminPlaceMapCondition c, double cell, long x, long y, boolean unknownOnly) { + return jdbc.queryForObject(points(unknownOnly) + "SELECT COUNT(*) AS place_count, " + FINGERPRINT + + " AS fingerprint FROM points WHERE " + CELL, + cellParams(c, cell, x, y), (rs, row) -> new GroupState(rs.getLong("place_count"), rs.getString("fingerprint"))); + } + + public List groupPlaces(AdminPlaceMapCondition c, double cell, long x, long y, + boolean unknownOnly, int page, int limit) { + return jdbc.query(points(unknownOnly) + "SELECT * FROM points WHERE " + CELL + + " ORDER BY map_place_id LIMIT :limit OFFSET :offset", + cellParams(c, cell, x, y).addValue("limit", limit).addValue("offset", (long) (page - 1) * limit), + (rs, row) -> marker(rs)); + } + + public List markers(Collection ids) { + if (ids.isEmpty()) return List.of(); + return jdbc.query("SELECT * FROM map_place WHERE map_place_id IN (:ids) ORDER BY map_place_id", + new MapSqlParameterSource("ids", ids), (rs, row) -> marker(rs)); + } + + private MapSqlParameterSource cellParams(AdminPlaceMapCondition c, double cell, long x, long y) { + return params(c).addValue("cell", cell).addValue("gridX", x).addValue("gridY", y); + } + + private MapSqlParameterSource params(AdminPlaceMapCondition c) { + Long numeric = null; + try { numeric = Long.valueOf(c.keyword()); } catch (NumberFormatException ignored) { /* 일반 문자열 검색 */ } + var aliases = PlaceCategoryPolicy.normalizedAliases(c.category()); + return new MapSqlParameterSource() + .addValue("west", c.west()).addValue("south", c.south()).addValue("east", c.east()).addValue("north", c.north()) + .addValue("keyword", c.keyword()).addValue("numericKeyword", numeric, Types.BIGINT) + .addValue("hasCategory", c.category() != null).addValue("aliases", aliases.isEmpty() ? List.of("") : aliases) + .addValue("discovery", c.discoveryStatus() == null ? null : c.discoveryStatus().name(), Types.VARCHAR) + .addValue("operating", c.operatingStatus() == null ? null : c.operatingStatus().name(), Types.VARCHAR); + } + + private static Bounds bounds(ResultSet rs) throws SQLException { + return new Bounds(rs.getDouble("west"), rs.getDouble("south"), rs.getDouble("east"), rs.getDouble("north")); + } + + private static Marker marker(ResultSet rs) throws SQLException { + return new Marker(rs.getLong("map_place_id"), rs.getString("place_name"), rs.getDouble("latitude"), + rs.getDouble("longitude"), PlaceCategoryPolicy.canonicalOrNull(rs.getString("category")), + rs.getString("discovery_status"), rs.getString("operating_status")); + } + + public record Cell(long x, long y, long count, long singleId, double latitude, double longitude, + Bounds bounds, String fingerprint) {} + public record GroupState(long count, String fingerprint) {} +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 02e29b2a0..9cd548067 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -463,3 +463,8 @@ verification: cleanup-enabled: true cleanup-delay: PT24H cleanup-initial-delay: PT1H + +# 관리자 지도 표시 상한. 쿼리 timeout과 별개이며 실측 후 조정한다. +admin: + place-map: + max-items: ${ADMIN_PLACE_MAP_MAX_ITEMS:200} diff --git a/src/test/java/com/typenull/pingdom/integration/admin/AdminMapPlaceControllerTest.java b/src/test/java/com/typenull/pingdom/integration/admin/AdminMapPlaceControllerTest.java index e4973d86a..c17a6ae18 100644 --- a/src/test/java/com/typenull/pingdom/integration/admin/AdminMapPlaceControllerTest.java +++ b/src/test/java/com/typenull/pingdom/integration/admin/AdminMapPlaceControllerTest.java @@ -3156,6 +3156,40 @@ void rebuildsPlaceSimilaritySnapshot() throws Exception { assertEquals(1L, placeSimilaritySnapshotRepository.count()); } + /** 신규 지도/그룹 경로도 실제 Security 체인의 인증과 관리자 권한 검사를 거친다. */ + @Test + void adminMapRequiresAuthenticationAndAdminRole() throws Exception { + mockMvc.perform(get("/admin/places/map")) + .andExpect(status().isUnauthorized()); + mockMvc.perform(get("/admin/places/map/clusters/token/places")) + .andExpect(status().isUnauthorized()); + String token = createUserAndLogin("mapUser" + ADMIN_SEQUENCE.incrementAndGet(), UserRole.USER); + mockMvc.perform(get("/admin/places/map") + .param("west", "128.5").param("south", "35.8").param("east", "128.7") + .param("north", "35.95").param("zoom", "13").param("width", "1200").param("height", "800") + .header(HttpHeaders.AUTHORIZATION, "Bearer " + token)) + .andExpect(status().isForbidden()); + mockMvc.perform(get("/admin/places/map/clusters/token/places") + .header(HttpHeaders.AUTHORIZATION, "Bearer " + token)) + .andExpect(status().isForbidden()); + } + + /** H2 환경에서도 관리자 인증 후 요청 검증은 PostGIS SQL보다 먼저 수행된다. */ + @Test + void adminMapValidatesBeforeExecutingSpatialSql() throws Exception { + String token = createAdminAndLogin(); + mockMvc.perform(get("/admin/places/map") + .param("west", "129").param("south", "35.8").param("east", "128") + .param("north", "35.95").param("zoom", "13").param("width", "1200").param("height", "800") + .header(HttpHeaders.AUTHORIZATION, "Bearer " + token)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.code").value("ADMIN_PLACE_MAP_INVALID_REQUEST")); + mockMvc.perform(get("/admin/places/map/clusters/expired/places") + .header(HttpHeaders.AUTHORIZATION, "Bearer " + token)) + .andExpect(status().isConflict()) + .andExpect(jsonPath("$.code").value("ADMIN_PLACE_MAP_CLUSTER_INVALID")); + } + /** 증가하는 이름의 관리자 계정을 생성하고 실제 로그인 API로 access token을 발급받음. */ private String createAdminAndLogin() throws Exception { String username = "adminPlaceTester" + ADMIN_SEQUENCE.incrementAndGet(); diff --git a/src/test/java/com/typenull/pingdom/moderation/api/place/lookup/AdminPlaceMapControllerTest.java b/src/test/java/com/typenull/pingdom/moderation/api/place/lookup/AdminPlaceMapControllerTest.java new file mode 100644 index 000000000..64cfc637a --- /dev/null +++ b/src/test/java/com/typenull/pingdom/moderation/api/place/lookup/AdminPlaceMapControllerTest.java @@ -0,0 +1,73 @@ +package com.typenull.pingdom.moderation.api.place.lookup; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapRequest; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse; +import com.typenull.pingdom.moderation.application.query.place.map.AdminPlaceMapQueryService; +import com.typenull.pingdom.moderation.domain.exception.AdminErrorCode; +import com.typenull.pingdom.moderation.domain.exception.AdminException; +import com.typenull.pingdom.shared.exception.handler.GlobalExceptionHandler; +import com.typenull.pingdom.shared.observability.AuthMetrics; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +class AdminPlaceMapControllerTest { + private final AdminPlaceMapQueryService service = mock(AdminPlaceMapQueryService.class); + private MockMvc mvc; + + @BeforeEach + void setup() { + mvc = MockMvcBuilders.standaloneSetup(new AdminPlaceMapController(service)) + .setControllerAdvice(new GlobalExceptionHandler(mock(AuthMetrics.class))).build(); + } + + private MockHttpServletRequestBuilder request() { + return get("/admin/places/map").param("west","128.5").param("south","35.8") + .param("east","128.7").param("north","35.95").param("zoom","13") + .param("width","1200").param("height","800"); + } + + @Test + void bindsMapParametersAndReturnsNoStoreEmptyResponse() throws Exception { + when(service.find(any())).thenReturn(new AdminPlaceMapResponse("SPATIAL",13,List.of(),List.of(),List.of(),0,true,null,null)); + mvc.perform(request().param("discoveryStatus","HIDDEN").param("category","CAFE")) + .andExpect(status().isOk()).andExpect(header().string("Cache-Control","no-store")) + .andExpect(jsonPath("$.mode").value("SPATIAL")).andExpect(jsonPath("$.regions").isArray()) + .andExpect(jsonPath("$.clusters").isArray()).andExpect(jsonPath("$.markers").isArray()) + .andExpect(jsonPath("$.viewportPlaceCount").value(0)).andExpect(jsonPath("$.complete").value(true)); + verify(service).find(argThat(r -> r.zoom()==13 && r.width()==1200 && r.category().equals("CAFE") + && r.discoveryStatus().name().equals("HIDDEN"))); + } + + @Test + void missingRequiredInputAndInvalidEnumsAreBadRequests() throws Exception { + mvc.perform(get("/admin/places/map")).andExpect(status().isBadRequest()); + mvc.perform(request().param("discoveryStatus","UNKNOWN")).andExpect(status().isBadRequest()); + verifyNoInteractions(service); + } + + @Test + void rejectsUnboundedSizeBeforeServiceInvocation() throws Exception { + mvc.perform(get("/admin/places/map").param("west","128.5").param("south","35.8") + .param("east","128.7").param("north","35.95").param("zoom","13") + .param("width","999999").param("height","800")) + .andExpect(status().isBadRequest()); + verifyNoInteractions(service); + } + + @Test + void expiredGroupUsesExistingGlobalErrorShape() throws Exception { + when(service.groupPlaces("expired",1,20)).thenThrow(new AdminException(AdminErrorCode.ADMIN_PLACE_MAP_CLUSTER_INVALID)); + mvc.perform(get("/admin/places/map/clusters/expired/places")) + .andExpect(status().isConflict()).andExpect(jsonPath("$.code").value("ADMIN_PLACE_MAP_CLUSTER_INVALID")) + .andExpect(jsonPath("$.message").isString()); + } +} diff --git a/src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapClusterTokenTest.java b/src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapClusterTokenTest.java new file mode 100644 index 000000000..eead8cd61 --- /dev/null +++ b/src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapClusterTokenTest.java @@ -0,0 +1,50 @@ +package com.typenull.pingdom.moderation.application.query.place.map; + +import static org.assertj.core.api.Assertions.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.typenull.pingdom.moderation.domain.exception.AdminException; +import com.typenull.pingdom.shared.security.jwt.JwtProperties; +import com.typenull.pingdom.place.domain.place.discovery.PlaceDiscoveryStatus; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneOffset; +import org.junit.jupiter.api.Test; + +class AdminPlaceMapClusterTokenTest { + private final JwtProperties properties = new JwtProperties("s".repeat(64), 60, 600); + private final Clock clock = Clock.fixed(Instant.parse("2026-10-21T00:00:00Z"), ZoneOffset.UTC); + private final AdminPlaceMapCondition condition = new AdminPlaceMapCondition(128, 35, 129, 36, + "카페", "CAFE", PlaceDiscoveryStatus.HIDDEN, null); + + @Test + void signedTokenPreservesOriginalFilterViewportAndResolution() { + var tokens = new AdminPlaceMapClusterToken(new ObjectMapper(), properties, clock); + var payload = tokens.read(tokens.issue(condition, 100, 13, 24, true, "fingerprint")); + assertThat(payload.condition()).isEqualTo(condition); + assertThat(payload.cellSize()).isEqualTo(100); + assertThat(payload.unknownOnly()).isTrue(); + assertThat(payload.expiresAt()).isEqualTo(clock.instant().getEpochSecond() + 300); + } + + @Test + void rejectsTamperingExpiredAndWrongPurposeTokens() { + var tokens = new AdminPlaceMapClusterToken(new ObjectMapper(), properties, clock); + String token = tokens.issue(condition, 100, 13, 24, false, "fingerprint"); + assertThatThrownBy(() -> tokens.read("a" + token)).isInstanceOf(AdminException.class); + assertThatThrownBy(() -> tokens.read("a.b.c")).isInstanceOf(AdminException.class); + assertThatThrownBy(() -> tokens.read("x".repeat(4097))).isInstanceOf(AdminException.class); + var expired = new AdminPlaceMapClusterToken(new ObjectMapper(), properties, Clock.offset(clock, java.time.Duration.ofSeconds(300))); + assertThatThrownBy(() -> expired.read(token)).isInstanceOf(AdminException.class); + } + @Test + void displayKeyStaysStableAcrossPanAndTokenRenewalButChangesWithResolutionOrFilter() { + var tokens = new AdminPlaceMapClusterToken(new ObjectMapper(), properties, clock); + var shifted = new AdminPlaceMapCondition(127,34,130,37,"카페","CAFE",PlaceDiscoveryStatus.HIDDEN,null); + String key = tokens.displayKey(condition,100,13,24,false); + assertThat(tokens.displayKey(shifted,100,13,24,false)).isEqualTo(key); + assertThat(tokens.displayKey(condition,200,13,24,false)).isNotEqualTo(key); + assertThat(tokens.displayKey(condition,100,13,24,true)).isNotEqualTo(key); + } + +} diff --git a/src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapConditionTest.java b/src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapConditionTest.java new file mode 100644 index 000000000..44611c974 --- /dev/null +++ b/src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapConditionTest.java @@ -0,0 +1,31 @@ +package com.typenull.pingdom.moderation.application.query.place.map; + +import static org.assertj.core.api.Assertions.*; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapRequest; +import com.typenull.pingdom.moderation.domain.exception.AdminException; +import org.junit.jupiter.api.Test; + +class AdminPlaceMapConditionTest { + @Test + void rejectsInvalidBoundsNonFiniteValuesZoomAndUnboundedClientSize() { + for (double[] box : new double[][] {{129,35,128,36}, {128,36,129,35}, {128,35,Double.NaN,36}, + {128,35,Double.POSITIVE_INFINITY,36}, {-181,35,129,36}, {128,-90,129,36}}) { + assertThatThrownBy(() -> AdminPlaceMapCondition.from(new AdminPlaceMapRequest( + box[0], box[1], box[2], box[3], 14, 1200, 800, null, null, null, null))) + .isInstanceOf(AdminException.class); + } + assertThatThrownBy(() -> AdminPlaceMapCondition.from(new AdminPlaceMapRequest( + 128d,35d,129d,36d,21,1200,800,null,null,null,null))).isInstanceOf(AdminException.class); + assertThatThrownBy(() -> AdminPlaceMapCondition.from(new AdminPlaceMapRequest( + 128d,35d,129d,36d,14,9000,800,null,null,null,null))).isInstanceOf(AdminException.class); + } + + @Test + void matchesExistingCategoryNormalizationAndKeepsAllStatusesByDefault() { + var c = AdminPlaceMapCondition.from(new AdminPlaceMapRequest(128d,35d,129d,36d,14,1200,800," 카페 ","커피",null,null)); + assertThat(c.keyword()).isEqualTo("카페"); + assertThat(c.category()).isEqualTo("CAFE"); + assertThat(c.discoveryStatus()).isNull(); + assertThat(c.operatingStatus()).isNull(); + } +} diff --git a/src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapQueryServiceTest.java b/src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapQueryServiceTest.java new file mode 100644 index 000000000..f608ea8a2 --- /dev/null +++ b/src/test/java/com/typenull/pingdom/moderation/application/query/place/map/AdminPlaceMapQueryServiceTest.java @@ -0,0 +1,114 @@ +package com.typenull.pingdom.moderation.application.query.place.map; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapRequest; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse.*; +import com.typenull.pingdom.moderation.domain.exception.AdminException; +import com.typenull.pingdom.place.infrastructure.persistence.place.AdminPlaceMapQueryRepository; +import com.typenull.pingdom.place.infrastructure.persistence.place.AdminPlaceMapQueryRepository.Cell; +import com.typenull.pingdom.place.infrastructure.persistence.place.AdminPlaceMapQueryRepository.GroupState; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.dao.QueryTimeoutException; + +class AdminPlaceMapQueryServiceTest { + private final AdminPlaceMapQueryRepository repository = mock(AdminPlaceMapQueryRepository.class); + private final AdminPlaceMapClusterToken tokens = mock(AdminPlaceMapClusterToken.class); + private final AdminPlaceMapQueryService service = new AdminPlaceMapQueryService(repository, tokens, new AdminPlaceMapProperties(200)); + private final Bounds bounds = new Bounds(128.6, 35.87, 128.6, 35.87); + + private AdminPlaceMapRequest request(int zoom) { + return new AdminPlaceMapRequest(128.5, 35.8, 128.7, 35.95, zoom, 1200, 800, null, null, null, null); + } + + @BeforeEach + void setUp() { when(repository.countViewport(any())).thenReturn(25L); } + + @Test + void reclustersInsteadOfSilentlyTruncatingAndPreservesMixedResults() { + var excess = java.util.Collections.nCopies(201, new Cell(1, 1, 2, 1, 35.87, 128.6, bounds, "a")); + var group = new Cell(1, 1, 24, 1, 35.87, 128.6, bounds, "fingerprint"); + var single = new Cell(2, 2, 1, 25, 35.88, 128.61, bounds, "single"); + when(repository.findCells(any(), anyDouble(), eq(false), anyInt())).thenReturn(excess, List.of(group, single)); + when(tokens.issue(any(), anyDouble(), eq(1L), eq(1L), eq(false), eq("fingerprint"))).thenReturn("token"); + when(repository.markers(List.of(25L))).thenReturn(List.of(new Marker(25, "카페", 35.88, 128.61, "CAFE", "HIDDEN", "OPERATING"))); + var response = service.find(request(14)); + assertThat(response.complete()).isTrue(); + assertThat(response.clusters()).singleElement().satisfies(c -> { + assertThat(c.count()).isEqualTo(24); + assertThat(c.action()).isEqualTo("LIST"); + }); + assertThat(response.markers()).hasSize(1); + assertThat(response.viewportPlaceCount()).isEqualTo(25); + var sizes = org.mockito.ArgumentCaptor.forClass(Double.class); + verify(repository, times(2)).findCells(any(), sizes.capture(), eq(false), anyInt()); + assertThat(sizes.getAllValues().get(1)).isEqualTo(sizes.getAllValues().get(0) * 2); + } + + @Test + void regionalTotalsAreNotAddedToViewportAndUnknownRegionsUseSpatialFallback() { + var region = new Region("SIGUNGU", "27260", "수성구", 320, "REGION", 35.87, 128.6, bounds, "PLACE_EXTENT", "EXPAND", 12); + when(repository.findRegions(any(), eq("SIGUNGU"), anyInt())).thenReturn(List.of(region)); + when(repository.findCells(any(), anyDouble(), eq(true), anyInt())).thenReturn(List.of()); + when(repository.markers(List.of())).thenReturn(List.of()); + var response = service.find(request(10)); + assertThat(response.regions()).containsExactly(region); + assertThat(response.viewportPlaceCount()).isEqualTo(25); + verify(repository).findCells(any(), anyDouble(), eq(true), anyInt()); + } + + @Test + void boundedReaggregationReturnsExplicitFailureWithoutPartialArrays() { + when(repository.findCells(any(), anyDouble(), anyBoolean(), anyInt())).thenReturn( + java.util.Collections.nCopies(201, new Cell(1, 1, 2, 1, 35.87, 128.6, bounds, "a"))); + var response = service.find(request(20)); + assertThat(response.complete()).isFalse(); + assertThat(response.clusters()).isEmpty(); + assertThat(response.incompleteReason()).isEqualTo("RESULT_BUDGET_EXCEEDED"); + verify(repository, times(24)).findCells(any(), anyDouble(), anyBoolean(), anyInt()); + verifyNoInteractions(tokens); + } + + @Test + void changedGroupRejectsLatePageRequest() { + var condition = AdminPlaceMapCondition.from(request(20)); + when(tokens.read("token")).thenReturn(new AdminPlaceMapClusterToken.Payload(1, 9999999999L, condition, 100, 1, 1, false, "old")); + when(repository.groupState(condition, 100, 1, 1, false)).thenReturn(new GroupState(24, "changed")); + assertThatThrownBy(() -> service.groupPlaces("token", 1, 20)).isInstanceOf(AdminException.class) + .hasMessageContaining("변경"); + verify(repository, never()).groupPlaces(any(), anyDouble(), anyLong(), anyLong(), anyBoolean(), anyInt(), anyInt()); + } + + @Test + void stableGroupUsesOriginalConditionAndIdPagination() { + var condition = AdminPlaceMapCondition.from(request(20)); + when(tokens.read("token")).thenReturn(new AdminPlaceMapClusterToken.Payload(1, 9999999999L, condition, 100, 1, 1, false, "same")); + when(repository.groupState(condition, 100, 1, 1, false)).thenReturn(new GroupState(24, "same")); + when(repository.groupPlaces(condition, 100, 1, 1, false, 2, 20)).thenReturn(List.of()); + var result = service.groupPlaces("token", 2, 20); + assertThat(result.totalPages()).isEqualTo(2); + assertThat(result.hasNext()).isFalse(); + verify(repository).groupPlaces(condition, 100, 1, 1, false, 2, 20); + } + + @Test + void queryTimeoutUsesDomainError() { + when(repository.countViewport(any())).thenThrow(new QueryTimeoutException("cancel")); + assertThatThrownBy(() -> service.find(request(14))).isInstanceOf(AdminException.class).hasMessageContaining("초과"); + } + + @Test + void emptyViewportKeepsModeAndReturnsEmptyArrays() { + when(repository.countViewport(any())).thenReturn(0L); + var result = service.find(request(7)); + assertThat(result.mode()).isEqualTo("SIDO"); + assertThat(result.regions()).isEmpty(); + assertThat(result.clusters()).isEmpty(); + assertThat(result.markers()).isEmpty(); + assertThat(result.complete()).isTrue(); + } +} diff --git a/src/test/java/com/typenull/pingdom/place/infrastructure/persistence/place/AdminPlaceMapQueryRepositoryPostgreSqlIntegrationTest.java b/src/test/java/com/typenull/pingdom/place/infrastructure/persistence/place/AdminPlaceMapQueryRepositoryPostgreSqlIntegrationTest.java new file mode 100644 index 000000000..7ef14549d --- /dev/null +++ b/src/test/java/com/typenull/pingdom/place/infrastructure/persistence/place/AdminPlaceMapQueryRepositoryPostgreSqlIntegrationTest.java @@ -0,0 +1,224 @@ +package com.typenull.pingdom.place.infrastructure.persistence.place; + +import static org.assertj.core.api.Assertions.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapRequest; +import com.typenull.pingdom.moderation.application.query.place.map.AdminPlaceMapClusterToken; +import com.typenull.pingdom.moderation.application.query.place.map.AdminPlaceMapCondition; +import com.typenull.pingdom.moderation.application.query.place.map.AdminPlaceMapQueryService; +import com.typenull.pingdom.moderation.domain.exception.AdminException; +import com.typenull.pingdom.place.domain.place.discovery.PlaceDiscoveryStatus; +import com.typenull.pingdom.shared.security.jwt.JwtProperties; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.support.TransactionTemplate; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +/** 실제 PostGIS에서 SQL 집계·변경 검증을 실행한다. 애플리케이션 전체 부트스트랩과 분리된 저장소 계약 테스트. */ +@Tag("postgres-integration") +@Testcontainers +class AdminPlaceMapQueryRepositoryPostgreSqlIntegrationTest { + @Container + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>( + DockerImageName.parse("postgis/postgis:16-3.4").asCompatibleSubstituteFor("postgres")); + private JdbcTemplate jdbc; + private AdminPlaceMapQueryRepository repository; + private AdminPlaceMapQueryService service; + private TransactionTemplate tx; + private RecordingJdbc recording; + + @BeforeEach + void setup() { + var ds = new DriverManagerDataSource(POSTGRES.getJdbcUrl(), POSTGRES.getUsername(), POSTGRES.getPassword()); + jdbc = new JdbcTemplate(ds); + jdbc.execute("CREATE EXTENSION IF NOT EXISTS postgis"); + jdbc.execute("DROP TABLE IF EXISTS map_place, place_administrative_region"); + jdbc.execute(""" + CREATE TABLE map_place (map_place_id bigint PRIMARY KEY, place_name text, english_name text, + address text, category text, user_id bigint, latitude double precision, longitude double precision, + location geometry(Point,4326), discovery_status text, operating_status text, region_code varchar(5)) + """); + jdbc.execute("CREATE INDEX idx_test_map_location ON map_place USING gist(location)"); + jdbc.execute("CREATE TABLE place_administrative_region (region_code varchar(5) PRIMARY KEY, sido text, region_name text)"); + jdbc.update("INSERT INTO place_administrative_region VALUES ('27260', '대구광역시', '대구광역시 수성구')"); + recording = new RecordingJdbc(ds); + repository = new AdminPlaceMapQueryRepository(recording); + service = new AdminPlaceMapQueryService(repository, new AdminPlaceMapClusterToken(new ObjectMapper(), + new JwtProperties("test-map-".repeat(8), 60, 600)), + new com.typenull.pingdom.moderation.application.query.place.map.AdminPlaceMapProperties(200)); + tx = new TransactionTemplate(new DataSourceTransactionManager(ds)); + tx.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ); + tx.setReadOnly(true); + } + + private void place(long id, double lon, double lat, String region, String visibility) { + jdbc.update(""" + INSERT INTO map_place VALUES (?, '카페', 'cafe', '대구 수성구', 'coffee', 7, ?, ?, + ST_SetSRID(ST_MakePoint(?, ?),4326), ?, 'OPERATING', ?) + """, id, lat, lon, lon, lat, visibility, region); + } + + private AdminPlaceMapRequest request(int zoom, PlaceDiscoveryStatus status) { + return new AdminPlaceMapRequest(128.5,35.8,128.7,35.95,zoom,1200,800,null,null,status,null); + } + + @Test + void regionCountsWholeRegionIncludingUnlocatedWhileUnknownRegionsRemainVisible() { + place(1,128.6,35.87,"27260","VISIBLE"); + place(2,128.9,35.87,"27260","HIDDEN"); // 화면 밖이지만 지역 전체 수에 포함 + place(3,128.61,35.88,null,"HIDDEN"); + place(4,128.62,35.89,"99999","VISIBLE"); + jdbc.update("INSERT INTO map_place(map_place_id,place_name,region_code,discovery_status,operating_status) VALUES (5,'좌표없음','27260','HIDDEN','OPERATING')"); + var response = tx.execute(s -> service.find(request(10,null))); + assertThat(response.viewportPlaceCount()).isEqualTo(3); + assertThat(response.regions()).singleElement().satisfies(r -> { + assertThat(r.count()).isEqualTo(3); + assertThat(r.bounds().east()).isEqualTo(128.9); + assertThat(r.boundsSource()).isEqualTo("PLACE_EXTENT"); + assertThat(r.longitude()).isEqualTo(128.6); + assertThat(r.latitude()).isEqualTo(35.87); + assertThat(r.nextZoom()).isEqualTo(12); + }); + long spatial = response.clusters().stream().mapToLong(c -> c.count()).sum() + response.markers().size(); + assertThat(spatial).isEqualTo(2); + var sido = tx.execute(s -> service.find(request(7, null))); + assertThat(sido.regions()).singleElement().satisfies(r -> assertThat(r.regionCode()).isEqualTo("27")); + } + + @Test + void filtersIncludeHiddenAndClosedByDefaultAndMatchCategoryAliasesAndRegistrantId() { + place(1,128.6,35.87,null,"HIDDEN"); + place(2,128.61,35.88,null,"VISIBLE"); + jdbc.update("UPDATE map_place SET operating_status='PERMANENTLY_CLOSED' WHERE map_place_id=1"); + var hidden = new AdminPlaceMapRequest(128.5,35.8,128.7,35.95,14,1200,800,"7","커피",PlaceDiscoveryStatus.HIDDEN,null); + var response = tx.execute(s -> service.find(hidden)); + assertThat(response.viewportPlaceCount()).isEqualTo(1); + assertThat(response.markers()).singleElement().satisfies(m -> { + assertThat(m.id()).isEqualTo(1); + assertThat(m.category()).isEqualTo("CAFE"); + assertThat(m.operatingStatus()).isEqualTo("PERMANENTLY_CLOSED"); + }); + } + + @Test + void colocatedPlacesRemainGroupedAndPagesRejectChangedMembership() { + for (int i=1;i<=30;i++) place(i,128.6,35.87,null,"HIDDEN"); + var response = tx.execute(s -> service.find(request(20,null))); + var group = response.clusters().getFirst(); + assertThat(group.count()).isEqualTo(30); + assertThat(group.action()).isEqualTo("LIST"); + var page = tx.execute(s -> service.groupPlaces(group.clusterId(),2,20)); + assertThat(page.places()).hasSize(10); + assertThat(page.places().getFirst().id()).isEqualTo(21); + assertThat(page.totalCount()).isEqualTo(30); + jdbc.update("UPDATE map_place SET longitude=128.61, location=ST_SetSRID(ST_MakePoint(128.61,latitude),4326) WHERE map_place_id=30"); + assertThatThrownBy(() -> tx.execute(s -> service.groupPlaces(group.clusterId(),1,20))) + .isInstanceOf(AdminException.class).hasMessageContaining("변경"); + } + + @Test + void denseResultReaggregatesWithoutLossAndPanKeepsGridOrigin() { + jdbc.update(""" + INSERT INTO map_place + SELECT i,'카페','cafe','대구','CAFE',7,35.81+(i%%100)*0.001, + 128.51+(i/100)*0.001, + ST_SetSRID(ST_MakePoint(128.51+(i/100)*0.001,35.81+(i%%100)*0.001),4326), + 'HIDDEN','OPERATING',NULL + FROM generate_series(1,10000) i + """.replace("%%", "%")); + var mvc = org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup( + new com.typenull.pingdom.moderation.api.place.lookup.AdminPlaceMapController(service)).build(); + long started = System.nanoTime(); + var response = tx.execute(s -> { + try { + var http = mvc.perform(org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get("/admin/places/map") + .param("west","128.2").param("south","35.5").param("east","128.95").param("north","36.4") + .param("zoom","20").param("width","1200").param("height","800")).andReturn(); + assertThat(http.getResponse().getStatus()).isEqualTo(200); + return new ObjectMapper().readValue(http.getResponse().getContentAsByteArray(), + com.typenull.pingdom.moderation.api.dto.place.map.AdminPlaceMapResponse.class); + } catch (Exception e) { throw new RuntimeException(e); } + }); + System.out.println("ADMIN_MAP_DAEGU_SYNTHETIC_10000_HTTP total_ms=" + (System.nanoTime()-started)/1_000_000.0 + + " clusters="+response.clusters().size()+" markers="+response.markers().size()); + jdbc.execute("ANALYZE map_place"); + String measuredSql = recording.spatialSql; + var measuredParams = recording.spatialParams; + var plan = tx.execute(s -> recording.query("EXPLAIN (ANALYZE, BUFFERS) " + measuredSql, + measuredParams, (rs, row) -> rs.getString(1))); + System.out.println("ADMIN_MAP_ACTUAL_CLUSTER_PLAN\n"+String.join("\n",plan)); + assertThat(response.complete()).isTrue(); + assertThat(response.clusters().size()+response.markers().size()).isLessThanOrEqualTo(200); + assertThat(response.clusters().stream().mapToLong(c->c.count()).sum()+response.markers().size()).isEqualTo(10000); + var c = AdminPlaceMapCondition.from(request(14,null)); + var shifted = new AdminPlaceMapCondition(128.49,35.79,128.71,35.96,"",null,null,null); + var before = tx.execute(s -> repository.findCells(c,1000,false,201)); + var after = tx.execute(s -> repository.findCells(shifted,1000,false,201)); + assertThat(before.stream().map(x -> List.of(x.x(),x.y())).toList()) + .isEqualTo(after.stream().map(x -> List.of(x.x(),x.y())).toList()); + } + + @Test + void excludesInvalidOrInconsistentCoordinatesAndHandlesEmptyViewport() { + place(1,128.6,35.87,null,"VISIBLE"); + jdbc.update("UPDATE map_place SET longitude=129 WHERE map_place_id=1"); + var response = tx.execute(s -> service.find(request(14,null))); + assertThat(response.viewportPlaceCount()).isZero(); + assertThat(response.markers()).isEmpty(); + } + + @Test + void groupFingerprintChangesForMetadataAndFilterStatusUpdates() { + place(1,128.6,35.87,null,"HIDDEN"); + place(2,128.6,35.87,null,"HIDDEN"); + var response = tx.execute(s -> service.find(request(20,PlaceDiscoveryStatus.HIDDEN))); + String token = response.clusters().getFirst().clusterId(); + jdbc.update("UPDATE map_place SET place_name='변경된 이름' WHERE map_place_id=1"); + assertThatThrownBy(() -> tx.execute(s -> service.groupPlaces(token,1,20))).isInstanceOf(AdminException.class); + var fresh = tx.execute(s -> service.find(request(20,PlaceDiscoveryStatus.HIDDEN))); + String next = fresh.clusters().getFirst().clusterId(); + jdbc.update("UPDATE map_place SET discovery_status='VISIBLE' WHERE map_place_id=1"); + assertThatThrownBy(() -> tx.execute(s -> service.groupPlaces(next,1,20))).isInstanceOf(AdminException.class); + } + @Test + void postgresStatementTimeoutIsTranslatedIntoPublicDomainError() { + var slow = new AdminPlaceMapQueryRepository(recording) { + @Override + public long countViewport(AdminPlaceMapCondition condition) { + return jdbc.queryForObject("SELECT 1 FROM pg_sleep(4)", Long.class); + } + }; + var slowService = new AdminPlaceMapQueryService(slow, new AdminPlaceMapClusterToken(new ObjectMapper(), + new JwtProperties("test-map-".repeat(8),60,600)), + new com.typenull.pingdom.moderation.application.query.place.map.AdminPlaceMapProperties(200)); + assertThatThrownBy(() -> tx.execute(s -> slowService.find(request(14,null)))) + .isInstanceOf(AdminException.class).hasMessageContaining("초과"); + } + + private static class RecordingJdbc extends NamedParameterJdbcTemplate { + String spatialSql; + org.springframework.jdbc.core.namedparam.SqlParameterSource spatialParams; + RecordingJdbc(javax.sql.DataSource ds) { super(ds); } + @Override + public List query(String sql, org.springframework.jdbc.core.namedparam.SqlParameterSource params, + org.springframework.jdbc.core.RowMapper mapper) { + if (sql.contains("AS grid_x") && !sql.startsWith("EXPLAIN")) { + spatialSql = sql; + spatialParams = params; + } + return super.query(sql, params, mapper); + } + } + +} diff --git a/src/test/resources/openapi-baseline/admin.json b/src/test/resources/openapi-baseline/admin.json index 0860b39d6..5b838c27c 100644 --- a/src/test/resources/openapi-baseline/admin.json +++ b/src/test/resources/openapi-baseline/admin.json @@ -1 +1 @@ -{"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://127.0.0.1:64060","description":"Generated server url"}],"tags":[{"name":"대시보드","description":"운영 현황, 최근 활동 및 처리 대기 항목"},{"name":"회원·권한","description":"회원 제재 및 관리자 역할 관리"},{"name":"사업자 관리","description":"사업자 심사 및 연결 장소 관리"},{"name":"장소 등록 심사","description":"장소 등록 신청과 증빙 확인 및 심사"},{"name":"장소 조회","description":"운영 대상 장소 목록 및 상세 조회"},{"name":"장소 정보·품질","description":"장소 정보 보정, 근거 검토 및 노출 상태 관리"},{"name":"중복·추천 관리","description":"중복 장소 검토·병합 및 추천 운영"},{"name":"제보·재검증","description":"장소 정보 제보 심사 및 재검증 요청 관리"},{"name":"행사·운영 공지","description":"행사 발행 및 운영 공지 관리"},{"name":"리뷰 삭제 심사","description":"장소 리뷰 삭제 요청 확인 및 심사"},{"name":"커뮤니티 관리","description":"게시글과 댓글 운영 조회"},{"name":"신고·이의신청","description":"신고 및 이의신청 검토·처리, 신고 콘텐츠 삭제"},{"name":"신뢰 점수","description":"신뢰 점수·이상 징후 및 개입 규칙 관리"},{"name":"방문 인증·스카우트","description":"방문 보고 심사 및 스카우트 자격 관리"},{"name":"예약","description":"예약 및 처리 이력 조회"},{"name":"Verified Boost","description":"Verified Boost 상품 등록 및 활성 상태 관리"},{"name":"알림·발송 이력","description":"운영 알림 확인 및 발송 이력 조회"},{"name":"감사·개인정보 처리 이력","description":"관리자 작업 감사 및 개인정보 처리 이력 조회"},{"name":"Outbox·스토리지 운영","description":"Outbox 재처리 및 스토리지 고아 객체 관리"}],"paths":{"/admin/trust-score/intervention-rules/{ruleId}":{"put":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 수정","description":"관리자가 Trust Score 개입 규칙 내용을 수정합니다.","operationId":"updateRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/places":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 연결 장소 및 운영 품질 조회","operationId":"listPlaces_1","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOwnerPlaceResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 장소 연결 변경","description":"현재 연결 장소를 요청의 placeIds 전체로 교체합니다. 빈 목록은 모든 장소 연결을 해제합니다. Merchant Owner 승인과는 별도 요청 및 별도 트랜잭션입니다.","operationId":"replacePlaces","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/places/{placeId}/quality":{"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 장소 운영 품질 지표 변경","operationId":"updateOperationalQuality","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceQualityUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/onboarding":{"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 온보딩 완료도 변경","operationId":"updateOnboarding","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOnboardingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/{reportId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 심사","operationId":"review","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/corrections/{correctionId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 정정 심사","operationId":"reviewCorrection","parameters":[{"name":"correctionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionReviewRequest"}}},"required":true},"responses":{"200":{"description":"제보 정정 심사 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionResponse"}}}},"400":{"description":"심사 요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"제보 정정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"이미 심사된 정정 또는 활성 제보 충돌","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관리자 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products":{"get":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 목록 조회","operationId":"list_1","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 생성","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}/deactivate":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 비활성화","operationId":"deactivate","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}/activate":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 활성화","operationId":"activate","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/roles":{"get":{"tags":["회원·권한"],"summary":"관리자 역할 이력 조회","operationId":"list_2","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"대상 관리자 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["회원·권한"],"summary":"관리자 역할 부여","operationId":"assign","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentRequest"}}},"required":true},"responses":{"400":{"description":"역할 할당 요청 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"이미 활성 역할이 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"부여 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"대상 관리자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}/interventions/evaluate":{"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 수동 평가","description":"관리자가 신고자의 현재 Trust Score 정책에 활성 개입 규칙을 수동 평가합니다.","operationId":"evaluateReporter","parameters":[{"name":"reporterUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionEvaluationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules":{"get":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 목록 조회","description":"관리자가 Trust Score 개입 규칙 목록을 우선순위 순서로 조회합니다.","operationId":"listRules","parameters":[{"name":"enabledOnly","in":"query","description":"활성화된 규칙만 조회할지 여부","required":false,"schema":{"type":"boolean","default":false},"example":false}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 생성","description":"관리자가 Trust Score 개입 규칙을 생성합니다.","operationId":"createRule","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleRequest"}}},"required":true},"responses":{"200":{"description":"Trust Score 개입 규칙 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"},"example":{"id":1,"ruleName":"low trust temporary restriction","triggerType":"FALSE_REPORT_COUNT","actionType":"TEMPORARY_RESTRICT","enabled":true,"minTrustScore":0,"maxTrustScore":60,"minSubmittedCount":3,"minFalseReportCount":3,"durationDays":7,"priority":10,"reason":"허위 신고 누적 사용자 제한"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/batch/recalculate":{"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 일괄 재계산","operationId":"recalculateTrustScores","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreBatchResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/suspend":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 정지","operationId":"suspend","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/revoke":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 회수","operationId":"revoke","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/suspend":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 정지","operationId":"suspendEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/revoke":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 회수","operationId":"revokeEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/grant":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 부여","operationId":"grantEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityGrantRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/approve":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 승인","operationId":"approve","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"Scout 프로필 승인 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"409":{"description":"현재 프로필 상태에서 승인 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"403":{"description":"Scout 심사 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-field-reports/{reportId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 현장 제보 심사","operationId":"review_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"현장 제보 심사 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"409":{"description":"이미 심사된 현장 제보","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"400":{"description":"심사 요청 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"404":{"description":"현장 제보를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/{id}/decline":{"post":{"tags":["신고·이의신청"],"summary":"신고 거절 처리","description":"관리자가 신고를 거절 처리합니다.","operationId":"declineReport","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"신고 거절 성공","content":{"*/*":{"example":{"reportId":1,"status":"DECLINED","reportedUserId":5,"banned":false,"processedAt":"2026-05-07T21:00:00"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"example":{"message":"이미 처리된 신고입니다.","code":"REPORT_ALREADY_PROCESSED"}}}},"404":{"description":"신고 내역 없음","content":{"*/*":{"example":{"message":"신고 내역을 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/{id}/accept":{"post":{"tags":["신고·이의신청"],"summary":"신고 수락 처리","description":"관리자가 신고를 수락하고 대상 사용자를 제재하며 신고 대상 게시글을 숨김 처리합니다.","operationId":"acceptReport","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"신고 수락 성공","content":{"*/*":{"example":{"reportId":1,"status":"ACCEPTED","reportedUserId":5,"banned":true,"processedAt":"2026-05-07T21:00:00"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"example":{"message":"이미 처리된 신고입니다.","code":"REPORT_ALREADY_PROCESSED"}}}},"404":{"description":"신고 내역 없음","content":{"*/*":{"example":{"message":"신고 내역을 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals/{id}/reject":{"post":{"tags":["신고·이의신청"],"summary":"신고 이의제기 반려","operationId":"reject_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals/{id}/approve":{"post":{"tags":["신고·이의신청"],"summary":"신고 이의제기 승인","operationId":"approve_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{postId}/reports/decline":{"post":{"tags":["신고·이의신청"],"summary":"게시글 단위 신고 일괄 거절","description":"관리자가 게시글에 연결된 PENDING 신고를 모두 거절합니다. 게시글 공개 상태와 대상 사용자 제재 상태는 변경하지 않습니다.","operationId":"declinePostReports","parameters":[{"name":"postId","in":"path","description":"신고를 일괄 거절할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"200":{"description":"게시글 신고 일괄 거절 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"},"example":{"postId":10,"status":"DECLINED","processedReportCount":3,"visibilityStatus":"ACTIVE","hiddenAt":null,"hiddenReason":null,"processedAt":"2026-05-21T10:15:30"}}}},"409":{"description":"처리할 PENDING 신고 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{postId}/reports/accept":{"post":{"tags":["신고·이의신청"],"summary":"게시글 단위 신고 일괄 수락","description":"관리자가 게시글에 연결된 PENDING 신고를 모두 수락하고 게시글 숨김 및 대상 사용자 제재를 처리합니다.","operationId":"acceptPostReports","parameters":[{"name":"postId","in":"path","description":"신고를 일괄 수락할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"게시글 신고 일괄 수락 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"},"example":{"postId":10,"status":"ACCEPTED","processedReportCount":3,"visibilityStatus":"AUTO_HIDDEN","hiddenAt":"2026-05-21T10:15:30","hiddenReason":"REPORT_BULK_ACCEPTED","processedAt":"2026-05-21T10:15:30"}}}},"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"409":{"description":"처리할 PENDING 신고 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report/refresh":{"post":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 리포트 생성 시작","description":"DB와 S3를 백그라운드에서 비교해 Redis에 리포트 결과를 저장합니다. 생성된 리포트는 GET report API로 페이지 조회합니다.","operationId":"refreshS3OrphanReport","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReportStatus"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 생성","description":"관리자가 상점 운영 상태 공지를 생성합니다.","operationId":"createNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices/{noticeId}/cancel":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 취소","description":"관리자가 예약 또는 활성 운영 상태 공지를 취소합니다.","operationId":"cancelNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCancelRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests":{"get":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 목록 조회","operationId":"list_7","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 생성","operationId":"create_1","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/reminders":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 리마인드 발행","operationId":"remind","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/complete":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 완료","operationId":"complete","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/cancel":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 취소","operationId":"cancel","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/information-evidence":{"get":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 목록 조회","description":"관리자가 장소 정보 출처와 증빙 메타데이터를 확인합니다.","operationId":"getPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 조회할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceResponse"}}}},"200":{"description":"장소 정보 증빙 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 등록","description":"관리자가 장소 정보 출처와 증빙 메타데이터를 등록합니다.","operationId":"createPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 등록할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceCreateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"200":{"description":"장소 정보 증빙 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-snapshots/resync":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 추천 snapshot 재동기화","description":"관리자가 모든 장소 추천 snapshot을 현재 데이터 기준으로 다시 동기화합니다.","operationId":"resyncRecommendationSnapshots","responses":{"200":{"description":"추천 snapshot 재동기화 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationSnapshotResyncResponse"},"example":{"placeCount":12,"synchronizedSnapshotCount":12,"deletedSnapshotCount":1,"synchronizedSimilaritySnapshotCount":24,"deletedSimilaritySnapshotCount":2,"synchronizedVersionSnapshotCount":3,"deletedVersionSnapshotCount":0,"message":"장소 추천 snapshot 재동기화를 완료했습니다."}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 병합","description":"관리자가 중복 장소의 참조 데이터를 대상 장소로 옮기고 원본 장소를 병합합니다.","operationId":"mergePlaces","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge-histories/{historyId}/restore":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 장소 병합 복구","description":"관리자가 저장된 장소 병합 이력을 기준으로 복구합니다.","operationId":"restoreMerge","parameters":[{"name":"historyId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceMergeRestoreResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/reject":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 거절","operationId":"rejectDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateDecisionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/merge":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 확정 중복 장소 병합","operationId":"mergeDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateMergeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/confirm":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 확정","operationId":"confirmDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateDecisionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests/{deletionRequestId}/review":{"post":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 심사","operationId":"review_2","parameters":[{"name":"deletionRequestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceReviewDeletionRequestReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-operating-notices/expire":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 만료 처리","description":"만료 시간이 지난 운영 상태 공지를 일괄 만료 처리합니다.","operationId":"expireDueNotices","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}/review":{"post":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 검토","operationId":"reviewReport","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}/disputes/{disputeId}/review":{"post":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 반박 검토","operationId":"reviewDispute","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"disputeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events":{"get":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 목록 조회","operationId":"listEvents","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":20}},{"name":"keyword","in":"query","required":false,"schema":{"type":"string"}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"eventType","in":"query","required":false,"schema":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]}},{"name":"publicationStatus","in":"query","required":false,"schema":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]}},{"name":"scheduleStatus","in":"query","required":false,"schema":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 등록","description":"장소와 연결된 기간형 이벤트를 초안으로 등록합니다.","operationId":"createEvent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventRequest"}}},"required":true},"responses":{"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"이벤트 초안 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}/publish":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 공개","description":"종료되지 않은 초안 이벤트를 앱 탐색에 공개합니다.","operationId":"publishEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventActionRequest"}}},"required":true},"responses":{"200":{"description":"이벤트 공개 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"409":{"description":"공개할 수 없는 상태 또는 기간","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}/cancel":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 취소","description":"초안 또는 공개된 기간형 이벤트를 취소하고 앱 탐색에서 제외합니다.","operationId":"cancelEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventActionRequest"}}},"required":true},"responses":{"409":{"description":"이미 취소된 이벤트","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 취소 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"404":{"description":"이벤트를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/outbox-events/{eventId}/retry":{"post":{"tags":["Outbox·스토리지 운영"],"summary":"관리자 Outbox 이벤트 재처리","description":"장애 원인과 중복 처리 안전성을 확인한 뒤 최종 실패 이벤트를 재처리 대상으로 전환합니다.","operationId":"retry","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventRetryRequest"}}},"required":true},"responses":{"403":{"description":"Outbox 복구 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"재처리 사유 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"재처리 불가 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"재처리 예약 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventItem"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/reject":{"post":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 반려","operationId":"reject_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/approve":{"post":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 승인","description":"NEW_PLACE 승인 시 장소 생성, Merchant Owner 연결과 신청의 COMPLETED 전이가 하나의 트랜잭션으로 완료됩니다. 신청자의 추가 완료 요청은 필요하지 않습니다.","operationId":"approve_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/revoke":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 권한 회수","operationId":"revoke_1","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/reject":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 반려","operationId":"reject_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/approve":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 승인","description":"승인 사유만 처리합니다. 장소 연결은 변경하지 않으며, 승인 후 연결이 필요하면 PUT /admin/merchant-owners/{userId}/places로 전체 장소 목록을 별도 요청해야 합니다. 승인과 장소 연결은 별도 트랜잭션입니다.","operationId":"approve_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}/decline":{"post":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 반려","description":"반려는 신고 상태만 변경하고 대상 노출 상태를 바꾸지 않습니다.","operationId":"decline","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"신고 반려 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportActionResponse"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"커뮤니티 신고를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}/accept":{"post":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 수락","description":"수락한 신고 대상 글 또는 댓글을 숨깁니다.","operationId":"accept","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"커뮤니티 신고 또는 대상 콘텐츠를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"신고 수락 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportActionResponse"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/ban/{userId}":{"post":{"tags":["회원·권한"],"summary":"사용자 밴 처리","description":"관리자가 특정 사용자를 밴 처리합니다. expiresAt 또는 durationDays를 전달하면 기간 밴으로, 둘 다 비우면 영구 밴으로 처리합니다.","operationId":"banUser","parameters":[{"name":"userId","in":"path","description":"밴 처리할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BanRequest"}}}},"responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"밴 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BanResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/ban/{userId}/release":{"post":{"tags":["회원·권한"],"summary":"사용자 밴 해제","description":"관리자가 영구 밴 또는 기간 밴 상태의 사용자를 명시적으로 해제합니다.","operationId":"unbanUser","parameters":[{"name":"userId","in":"path","description":"밴 해제할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnbanRequest"}}}},"responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"409":{"description":"제재 중인 사용자가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"제재 중인 사용자가 아닙니다.","code":"USER_NOT_BANNED"}}}},"200":{"description":"밴 해제 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UnbanResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}/enable":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 활성화","description":"관리자가 Trust Score 개입 규칙을 활성화합니다.","operationId":"enableRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleToggleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}/disable":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 비활성화","description":"관리자가 Trust Score 개입 규칙을 비활성화합니다.","operationId":"disableRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleToggleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/anomalies/{anomalyId}/resolve":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 이상치 해결 처리","description":"관리자가 Trust Score 이상치를 해결 처리하고 감사 로그를 남깁니다.","operationId":"resolveAnomaly","parameters":[{"name":"anomalyId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyResolveRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices/{noticeId}":{"patch":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 수정","description":"관리자가 상점 운영 상태 공지 내용을 수정합니다.","operationId":"updateNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/tourist-info":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 관광 정보 수정","description":"관리자가 장소의 영문명, 관광객용 요약, 관광 카테고리를 수정합니다.","operationId":"updatePlaceTouristInfo","parameters":[{"name":"id","in":"path","description":"관광 정보를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceTouristInfoUpdateRequest"}}},"required":true},"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"reason":"수정 사유는 필수입니다."}}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"장소 관광 정보 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceTouristInfoUpdateResponse"},"example":{"placeId":1,"englishName":"Jinju Castle","touristSummary":"A historic fortress overlooking the Nam River.","touristCategories":["K_POP","CAFE","POP_UP"],"message":"장소 관광 정보를 수정했습니다."}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/operating-status":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 운영 상태 확인","description":"관리자가 확인한 장소 운영 상태를 기록하고 최신 확인 시각을 서버 시간으로 갱신합니다. 비운영 장소는 앱 장소 조회와 추천에서 숨겨집니다.","operationId":"updatePlaceOperatingStatus","parameters":[{"name":"id","in":"path","description":"운영 상태를 확인할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"200":{"description":"장소 운영 상태 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/operating-schedule":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 영업시간 일정 수정","description":"관리자가 요일별 정규 영업시간과 특정 날짜 휴무·대체 영업시간을 전체 교체합니다. 수동 운영 상태는 변경하지 않습니다.","operationId":"updatePlaceOperatingSchedule","parameters":[{"name":"id","in":"path","description":"영업시간 일정을 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingScheduleUpdateRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"장소 영업시간 일정 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingScheduleUpdateResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/kakao-place-id":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 Kakao place id 수정","description":"관리자가 장소에 연결된 Kakao place id를 재연결하거나 해제합니다.","operationId":"updatePlaceKakaoPlaceId","parameters":[{"name":"id","in":"path","description":"Kakao place id를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceKakaoPlaceIdUpdateRequest"}}},"required":true},"responses":{"409":{"description":"이미 다른 장소에 연결된 Kakao place id","content":{"*/*":{"example":{"message":"이미 다른 장소에 연결된 Kakao place id입니다.","code":"PLACE_KAKAO_PLACE_ID_CONFLICT"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"kakaoPlaceId":"카카오 장소 ID는 50자 이하여야 합니다."}}}}},"200":{"description":"Kakao place id 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceKakaoPlaceIdUpdateResponse"},"example":{"placeId":1,"kakaoPlaceId":"27414316","message":"장소 Kakao place id를 수정했습니다."}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/information-evidence/{evidenceId}/review":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 검토","description":"관리자가 장소 정보 증빙을 승인 또는 반려하고 장소 정보 검증 요약 상태를 갱신합니다.","operationId":"reviewPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 검토할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"evidenceId","in":"path","description":"증빙 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceReviewRequest"}}},"required":true},"responses":{"200":{"description":"장소 정보 증빙 검토 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"404":{"description":"장소 또는 증빙을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/geocoding":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 주소·좌표 보정","description":"관리자가 대표 주소, 정규화 주소와 좌표를 함께 보정하며 출처는 ADMIN으로 기록합니다.","operationId":"updatePlaceGeocoding","parameters":[{"name":"id","in":"path","description":"주소와 좌표를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceGeocodingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceGeocodingUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/discovery-status":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 탐색 노출 상태 수정","description":"관리자가 장소를 공개 탐색, 자동완성, 북마크 목록, 추천 후보에 노출할지 제어합니다.","operationId":"updatePlaceDiscoveryStatus","parameters":[{"name":"id","in":"path","description":"탐색 노출 상태를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"200":{"description":"장소 탐색 노출 상태 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/coordinates":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 좌표 수정","description":"관리자가 잘못 등록된 장소의 위도와 경도를 수정합니다.","operationId":"updatePlaceCoordinates","parameters":[{"name":"id","in":"path","description":"좌표를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceCoordinateUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"장소 좌표 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceCoordinateUpdateResponse"},"example":{"placeId":1,"latitude":35.1796,"longitude":128.1076,"message":"장소 좌표를 수정했습니다."}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"latitude":"위도는 90.0 이하여야 합니다."}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/basic-information":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 기본 정보 수정","description":"관리자가 장소명과 표준 카테고리를 수정하고 변경 사유를 감사 로그에 남깁니다.","operationId":"updatePlaceBasicInformation","parameters":[{"name":"id","in":"path","description":"기본 정보를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"200":{"description":"장소 기본 정보 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-traffic":{"patch":{"tags":["중복·추천 관리"],"summary":"관리자 추천 버전 트래픽 비율 수정","description":"관리자가 추천 버전별 traffic percentage를 수정하고 즉시 반영합니다.","operationId":"updateRecommendationTraffic","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}":{"get":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 상세 조회","operationId":"getEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventListItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 수정","description":"초안 상태의 기간형 이벤트 정보와 연결 장소를 수정합니다.","operationId":"updateEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventRequest"}}},"required":true},"responses":{"404":{"description":"이벤트 또는 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"409":{"description":"초안이 아닌 이벤트 수정 시도","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/{notificationId}/read":{"patch":{"tags":["알림·발송 이력"],"summary":"관리자 알림 읽음 처리","description":"관리자가 운영 확인이 필요한 인앱 알림을 읽음 상태로 변경합니다.","operationId":"markAsRead","parameters":[{"name":"notificationId","in":"path","description":"알림 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"알림을 찾을 수 없음","content":{"*/*":{"example":{"message":"알림을 찾을 수 없습니다.","code":"NOTIFICATION_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"알림 읽음 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationReadResponse"},"example":{"notificationId":1,"read":true,"message":"알림을 읽음 처리했습니다."}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/read":{"patch":{"tags":["알림·발송 이력"],"summary":"관리자 전체 알림 읽음 처리","description":"관리자가 모든 미확인 인앱 알림을 읽음 상태로 변경합니다.","operationId":"markAllAsRead","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"전체 알림 읽음 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationReadAllResponse"},"example":{"updatedCount":3,"message":"전체 알림을 읽음 처리했습니다."}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports":{"get":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 목록 조회","operationId":"list","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/corrections":{"get":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 정정 목록 조회","operationId":"listCorrections","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}":{"get":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 상세 조회","operationId":"get","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/sanctions":{"get":{"tags":["회원·권한"],"summary":"사용자 제재 이력 조회","description":"관리자가 특정 사용자의 제재 변경 이력을 페이지 단위로 조회합니다. 제재 이력이 없으면 500이 아니라 빈 histories 배열과 페이지 메타데이터를 반환합니다.","operationId":"listUserSanctionHistories","parameters":[{"name":"userId","in":"path","description":"조회할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"banType","in":"query","description":"제재 유형 필터","required":false,"schema":{"type":"string","enum":["PERMANENT","TEMPORARY"]},"example":"TEMPORARY"},{"name":"action","in":"query","description":"처리 상태 필터","required":false,"schema":{"type":"string","enum":["APPLIED","RELEASED","EXPIRED"]},"example":"APPLIED"},{"name":"from","in":"query","description":"처리 시각 시작 필터","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"처리 시각 종료 필터","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"}],"responses":{"200":{"description":"사용자 제재 이력 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminUserSanctionHistoryResponse"},"example":{"histories":[],"page":1,"limit":5,"totalCount":0,"totalPages":1,"hasNext":false}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"400":{"description":"조회 기간 필터 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"제재 이력 조회 종료 시각은 시작 시각보다 이후여야 합니다.","code":"INVALID_SANCTION_FILTER_PERIOD"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/sanction":{"get":{"tags":["회원·권한"],"summary":"사용자 제재 상태 조회","description":"관리자가 특정 사용자의 현재 제재 상태를 조회합니다. 만료된 기간 밴은 현재 제재로 보지 않습니다.","operationId":"getUserSanctionStatus","parameters":[{"name":"userId","in":"path","description":"조회할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminUserSanctionStatusResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/role-targets":{"get":{"tags":["회원·권한"],"summary":"관리자 역할 부여 대상 사용자 검색","description":"관리자 역할 API에 전달할 수 있는 관리자 계정만 username 부분 일치로 검색합니다. 사용자 공통 표시 이름은 제공되지 않아 username만 검색하며, 빈 keyword는 전체 대상 조회로 처리합니다. page는 1부터 시작하고 limit은 1~100으로 보정됩니다. 이메일과 전화번호는 반환하지 않습니다.","operationId":"search","parameters":[{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기(1~100)","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"username 부분 일치 검색어. 비어 있으면 전체 역할 부여 대상을 조회합니다.","required":false,"schema":{"type":"string"},"example":"operator"}],"responses":{"200":{"description":"검색 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentTargetSearchResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/banned":{"get":{"tags":["회원·권한"],"summary":"밴 유저 목록 조회","description":"관리자가 현재 밴 처리된 사용자 목록을 페이지 단위로 조회합니다. keyword는 숫자만 입력하면 userId 정확히 일치로 검색하고, 그 외에는 username 부분 일치로 검색합니다. counts는 현재 밴 중인 사용자 기준이며, keyword 검색어가 있으면 검색 결과 기준으로 계산됩니다. 기간 필터는 from과 to를 사용합니다. limit 값은 내부적으로 1~100 범위로 보정됩니다.","operationId":"listBannedUsers","parameters":[{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"숫자만 입력하면 userId 정확히 일치, 그 외에는 username 부분 일치 검색","required":false,"schema":{"type":"string"},"example":"blockedUser01"},{"name":"banType","in":"query","description":"밴 유형","required":false,"schema":{"type":"string","enum":["PERMANENT","TEMPORARY"]},"example":"PERMANENT"},{"name":"from","in":"query","description":"밴 처리 시작 시각 이상","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"밴 처리 종료 시각 이하","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"sortBy","in":"query","description":"정렬 기준","required":false,"schema":{"type":"string","default":"BANNED_AT","enum":["BANNED_AT","EXPIRES_AT","USER_ID"]},"example":"BANNED_AT"},{"name":"sortDirection","in":"query","description":"정렬 방향","required":false,"schema":{"type":"string","default":"DESC","enum":["ASC","DESC"]},"example":"DESC"}],"responses":{"200":{"description":"밴 유저 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminBannedUserResponse"},"example":{"users":[{"userId":7,"username":"blockedUser01","banned":true,"banType":"PERMANENT","bannedAt":"2026-06-07T13:30:00","banExpiresAt":null}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false,"counts":{"total":1,"permanent":1,"temporary":0}}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/banned/{userId}":{"get":{"tags":["회원·권한"],"summary":"밴 유저 상세 조회","description":"관리자가 특정 밴 유저의 상세 정보를 조회합니다.","operationId":"getBannedUser","parameters":[{"name":"userId","in":"path","description":"조회할 밴 유저 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"404":{"description":"밴 유저를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"밴 유저 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminBannedUserDetailResponse"},"example":{"userId":7,"username":"blockedUser01","email":"blockedUser01@example.com","birthYear":1998,"language":"ko","country":"KR","role":"USER","banned":true,"bannedAt":"2026-06-07T13:30:00","banType":"PERMANENT","banExpiresAt":null,"banReason":"반복적인 신고 누적","createdAt":"2026-06-01T10:00:00"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}":{"get":{"tags":["신뢰 점수"],"summary":"신고자 신뢰 등급과 점수 근거 조회","description":"관리자가 신고자의 신뢰 점수, 등급, 신고 처리 통계 기반 점수 근거를 조회합니다.","operationId":"getTrustScore","parameters":[{"name":"reporterUserId","in":"path","description":"신고자 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"200":{"description":"신뢰 등급과 점수 근거 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreResponse"},"example":{"reporterUserId":7,"reporterUsername":"pingdom_user","trustScore":80,"trustGrade":"HIGH","restricted":false,"restrictedUntil":null,"restrictionReason":null,"evidence":{"submittedCount":12,"acceptedCount":8,"declinedCount":4,"falseReportCount":3,"acceptanceRate":66.67,"baseScore":100,"acceptedScoreBonus":40,"falseReportScorePenalty":60}}}}},"404":{"description":"신고자 Trust Score 정책을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"신고자 Trust Score 정책을 찾을 수 없습니다.","code":"TRUST_SCORE_REPORTER_POLICY_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}/history":{"get":{"tags":["신뢰 점수"],"summary":"신고자 Trust Score 변경 이력 조회","operationId":"listTrustScoreHistory","parameters":[{"name":"reporterUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreChangeHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/anomalies":{"get":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 이상치 목록 조회","description":"관리자가 Trust Score 이상치 목록을 조회합니다. page는 1 이상, limit은 1~100 범위로 보정됩니다.","operationId":"listAnomalies","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"reporterUserId","in":"query","description":"신고자 사용자 ID 필터","required":false,"schema":{"type":"integer","format":"int64"},"example":12},{"name":"unresolvedOnly","in":"query","description":"미해결 이상치만 조회할지 여부","required":false,"schema":{"type":"boolean","default":false},"example":true}],"responses":{"200":{"description":"Trust Score 이상치 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 목록 조회","operationId":"list_3","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACTIVE","SUSPENDED","REVOKED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfilePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 및 활동 자격 상세 조회","operationId":"get_1","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-field-reports":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 현장 제보 목록 조회","operationId":"list_4","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/s3/orphan-objects":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"S3 orphan 객체 dry-run 리포트","description":"DB에 등록된 게시글 원본/썸네일 S3 key와 S3 객체 목록을 비교해 DB에서 사용 중이지 않은 객체를 조회합니다. 실제 삭제는 수행하지 않습니다.","operationId":"reportOrphanObjects","parameters":[{"name":"prefix","in":"query","description":"조회할 S3 key prefix","required":false,"schema":{"type":"string","default":"map/"},"example":"map/"},{"name":"limit","in":"query","description":"최대 스캔 객체 수. 1~10000 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1000},"example":1000}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminS3OrphanObjectReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reservations":{"get":{"tags":["예약"],"summary":"관리자 예약 기록 목록 조회","operationId":"list_5","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"merchantOwnerUserId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"touristUserId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"reservationFrom","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"reservationTo","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReservationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reservations/{reservationId}":{"get":{"tags":["예약"],"summary":"관리자 예약 기록 상세 조회","operationId":"get_2","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/reported-users":{"get":{"tags":["신고·이의신청"],"summary":"관리자 신고 유저 목록 조회","description":"관리자가 PENDING 상태의 신고 유저 목록을 조회합니다. limit 값은 내부적으로 1~100 범위로 보정됩니다.","operationId":"getReportedUsers","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"검색 키워드. 신고자 이름, 신고 사유, 신고받은 유저 ID로 검색합니다.","required":false,"schema":{"type":"string","default":""},"example":"욕설"}],"responses":{"200":{"description":"신고 유저 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReportedUsersResponse"},"example":{"users":[{"reportId":12,"reporterUserId":3,"reporterUsername":"reporter01","reportedImageId":101,"reportedUserId":55,"reason":"욕설"}],"page":1,"limit":20,"totalCount":123,"totalPages":7,"hasNext":true}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/reported-users/{id}":{"get":{"tags":["신고·이의신청"],"summary":"관리자 신고 유저 상세 조회","description":"관리자가 신고 상세 정보를 조회합니다.","operationId":"getReportedUser","parameters":[{"name":"id","in":"path","description":"조회할 신고 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":12}],"responses":{"200":{"description":"신고 유저 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReportedUsersItem"},"example":{"reportId":12,"reporterUserId":3,"reporterUsername":"reporter01","reportedImageId":101,"reportedUserId":55,"reason":"욕설"}}}},"404":{"description":"신고를 찾을 수 없음","content":{"*/*":{"example":{"message":"신고를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals":{"get":{"tags":["신고·이의신청"],"summary":"신고 이의제기 목록 조회","operationId":"list_6","parameters":[{"name":"status","in":"query","description":"이의제기 상태","required":false,"schema":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]}},{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/privacy-processing-histories":{"get":{"tags":["감사·개인정보 처리 이력"],"summary":"개인정보 처리 이력 조회","description":"관리자가 개인정보 export, 탈퇴, 익명화, 삭제 처리 이력을 페이지 단위로 조회합니다.","operationId":"listHistories","parameters":[{"name":"subjectUserId","in":"query","description":"처리 대상 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"actorUserId","in":"query","description":"처리 수행 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"action","in":"query","description":"처리 유형","required":false,"schema":{"type":"string","enum":["EXPORT_REQUESTED","WITHDRAWAL_REQUESTED","ANONYMIZED","DELETED"]},"example":"EXPORT_REQUESTED"},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-31T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PrivacyProcessingHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 삭제 후보 리포트 생성","description":"최근 생성된 S3 고아 파일 리포트의 삭제 후보를 페이지 단위로 조회합니다. 이 API는 S3/DB 전체 스캔이나 실제 삭제를 수행하지 않습니다.","operationId":"createS3OrphanReport","parameters":[{"name":"reportId","in":"query","description":"조회할 리포트 ID. 생략하면 최근 생성된 리포트를 조회합니다.","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReport"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report/status":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 리포트 생성 상태 조회","description":"리포트 생성 작업의 RUNNING/COMPLETED/FAILED 상태와 집계 정보를 조회합니다.","operationId":"getS3OrphanReportStatus","parameters":[{"name":"reportId","in":"query","description":"조회할 리포트 ID. 생략하면 최근 생성된 리포트를 조회합니다.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReportStatus"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places":{"get":{"tags":["장소 조회"],"summary":"관리자 장소 목록 조회","description":"관리자가 등록된 장소 목록을 페이지 단위로 조회합니다.","operationId":"listPlaces","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"sortParam","in":"query","description":"장소 정렬 기준. LATEST, OLDEST, LEVEL_DESC만 지원합니다.","required":false,"schema":{"type":"string","enum":["LATEST","OLDEST","LEVEL_DESC"]},"example":"LATEST"},{"name":"keyword","in":"query","description":"장소 검색 키워드. 장소명, 등록자 ID, 주소로 검색합니다.","required":false,"schema":{"type":"string","default":""},"example":"용인"},{"name":"category","in":"query","description":"일반 장소 카테고리 필터. 입력값을 표준 카테고리로 정규화한 뒤 AdminMapPlaceItem.category와 정확히 비교합니다. touristCategories와는 별도 기준입니다.","required":false,"schema":{"type":"string","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"example":"CAFE"}],"responses":{"200":{"description":"장소 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceResponse"},"examples":{"categoryFilteredResult":{"summary":"카테고리 필터 조회 결과","description":"categoryFilteredResult","value":{"places":[{"id":1,"name":"진주성","address":"경상남도 진주시 남강로 626","discoveryStatus":"VISIBLE","category":"CULTURAL_HERITAGE","categoryName":"문화재","touristCategories":["EXHIBITION"],"latitude":35.1894,"longitude":128.0789,"userId":3,"registrant":"placeRegistrar","level":5,"placeGrowth":{"photoCount":10,"level":5,"currentLevelMinPhotoCount":10,"nextLevelMinPhotoCount":16,"progressPercent":0}}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}},"emptyResult":{"summary":"카테고리 필터 결과 없음","description":"emptyResult","value":{"places":[],"page":1,"limit":20,"totalCount":0,"totalPages":1,"hasNext":false}}}}}},"400":{"description":"지원하지 않는 장소 정렬 기준","content":{"*/*":{"example":{"message":"장소 목록은 LATEST 또는 OLDEST 정렬만 지원합니다.","code":"UNSUPPORTED_PLACE_SORT_PARAM"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}":{"get":{"tags":["장소 조회"],"summary":"관리자 장소 상세 조회","description":"관리자가 특정 장소의 기본 정보와 연결된 게시글 목록을 조회합니다.","operationId":"getPlace","parameters":[{"name":"id","in":"path","description":"조회할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"sortParam","in":"query","description":"게시글 정렬 기준","required":false,"schema":{"type":"string","default":"LATEST","enum":["LATEST","OLDEST","MOST_LIKED"]},"example":"LATEST"},{"name":"keyword","in":"query","description":"게시글 검색","required":false,"schema":{"type":"string","default":""},"example":"용인"}],"responses":{"200":{"description":"장소 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDetailResponse"},"example":{"id":1,"name":"진주성","imageUrl":"https://example.com/places/1/representative.jpg","address":"경상남도 진주시 남강로 626","discoveryStatus":"VISIBLE","category":"CULTURAL_HERITAGE","categoryName":"문화재","latitude":35.1894,"longitude":128.0789,"userId":3,"username":"placeOwner","sortParam":"LATEST","postCount":1,"level":5,"placeGrowth":{"photoCount":10,"hiddenPhotoCount":1,"level":5,"currentLevelMinPhotoCount":10,"nextLevelMinPhotoCount":16,"progressPercent":0},"posts":[{"id":10,"imageUrl":"https://example.com/image.jpg","title":"야경 사진","description":"남강 야경입니다.","userId":3,"username":"pingdom_user","createdAt":"2026-05-28T12:00:00","likeCount":5,"visibilityStatus":"HIDDEN","hiddenReason":"ADMIN_HIDDEN"}]}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendations/{requestId}/explanation":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 설명 조회","description":"관리자가 추천 응답 requestId의 후보 source, score, ranking, feature log 정보를 조회합니다.","operationId":"getRecommendationExplanation","parameters":[{"name":"requestId","in":"path","description":"추천 응답 requestId","required":true,"schema":{"type":"string"},"example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}],"responses":{"200":{"description":"추천 설명 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationExplanationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-metrics":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 성과 조회","description":"관리자가 장소별 추천 노출, 클릭, CTR 지표를 조회합니다.","operationId":"listRecommendationMetrics","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"sortBy","in":"query","description":"추천 성과 정렬 기준","required":false,"schema":{"type":"string","enum":["SMOOTHED_CTR","RAW_CTR","BOOKMARK_CONVERSION","LIKE_CONVERSION","TOTAL_CONVERSION","EXPOSURE","CLICK","UPDATED_AT"]},"example":"SMOOTHED_CTR"},{"name":"keyword","in":"query","description":"장소 검색 키워드","required":false,"schema":{"type":"string","default":""},"example":"진주"},{"name":"recommendationVersion","in":"query","description":"추천 버전 필터","required":false,"schema":{"type":"string","default":""},"example":"place-rec-v1"},{"name":"days","in":"query","description":"최근 N일 기준 필터","required":false,"schema":{"type":"integer","format":"int32"},"example":7}],"responses":{"200":{"description":"추천 성과 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricsResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-metrics/compare":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 버전 성과 비교","description":"관리자가 두 추천 버전의 CTR, 전환율, 노출 지표를 같은 조건에서 비교합니다.","operationId":"compareRecommendationMetrics","parameters":[{"name":"baselineVersion","in":"query","description":"기준 추천 버전","required":true,"schema":{"type":"string"},"example":"place-rec-v1"},{"name":"targetVersion","in":"query","description":"비교 대상 추천 버전","required":true,"schema":{"type":"string"},"example":"place-rec-v2"},{"name":"keyword","in":"query","description":"장소 검색 키워드","required":false,"schema":{"type":"string","default":""},"example":"진주"},{"name":"days","in":"query","description":"최근 N일 기준 필터","required":false,"schema":{"type":"integer","format":"int32"},"example":7}],"responses":{"200":{"description":"추천 버전 성과 비교 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricsCompareResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge-histories":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 장소 병합 이력 조회","description":"관리자가 최근 장소 병합 이력을 조회합니다.","operationId":"listMergeHistories","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceMergeHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicates":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 목록 조회","description":"관리자가 병합 대상이 될 수 있는 중복 장소 그룹을 조회합니다.","operationId":"listDuplicatePlaces","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicates/{id}":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 상세 조회","description":"관리자가 특정 장소의 중복 후보 목록을 조회합니다.","operationId":"getDuplicatePlace","parameters":[{"name":"id","in":"path","description":"중복 후보를 확인할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 조회","operationId":"listDuplicateCandidates","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","default":"PENDING","enum":["PENDING","CONFIRMED","REJECTED","MERGED"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 상세 조회","operationId":"getDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests":{"get":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 목록 조회","operationId":"list_8","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests/{deletionRequestId}":{"get":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 상세 조회","operationId":"get_3","parameters":[{"name":"deletionRequestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports":{"get":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 목록 조회","operationId":"list_9","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}":{"get":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 상세 조회","operationId":"get_4","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/outbox-events":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"관리자 Outbox 이벤트 조회","description":"운영자가 Outbox 이벤트의 상태와 실패 원인을 조회합니다. 민감한 payload와 deduplication key는 반환하지 않습니다.","operationId":"list_10","parameters":[{"name":"status","in":"query","description":"처리 상태","required":false,"schema":{"type":"string","enum":["PENDING","PROCESSING","RETRY","SUCCEEDED","FAILED"]},"example":"FAILED"},{"name":"eventType","in":"query","description":"이벤트 유형","required":false,"schema":{"type":"string","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"example":"EMAIL_VERIFICATION_REQUESTED"},{"name":"aggregateType","in":"query","description":"aggregate 유형","required":false,"schema":{"type":"string"},"example":"USER"},{"name":"aggregateId","in":"query","description":"aggregate ID","required":false,"schema":{"type":"string"},"example":10},{"name":"from","in":"query","description":"생성 시각 조회 시작","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"생성 시각 조회 종료","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"400":{"description":"조회 기간 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Outbox 복구 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 알림 목록 조회","description":"인증된 관리자가 자신에게 전달된 운영 알림을 유형, 읽음 상태, 기간 조건으로 조회합니다. 알림 token은 report:{reportId}, place:{placeId}, sanction:{sanctionId} 형식을 사용합니다.","operationId":"listNotifications","parameters":[{"name":"type","in":"query","description":"관리자 알림 유형: ADMIN_REPORT_RECEIVED, ADMIN_REPORT_PROCESSED, ADMIN_DUPLICATE_PLACE_DETECTED, ADMIN_USER_SANCTION","required":false,"schema":{"type":"string","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"example":"ADMIN_REPORT_RECEIVED"},{"name":"read","in":"query","description":"읽음 여부","required":false,"schema":{"type":"boolean"},"example":false},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-31T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"관리자 알림 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationResponse"},"example":{"notifications":[{"notificationId":1,"userId":10,"type":"ADMIN_REPORT_RECEIVED","title":"신고 접수 알림","body":"신고 ID 30 접수가 게시글 ID 12에 등록되었습니다.","token":"report:30","read":false,"createdAt":"2026-07-21T15:30:00"}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}}}},"400":{"description":"조회 기간 오류","content":{"*/*":{"example":{"message":"알림 조회 종료 시각은 시작 시각보다 이후여야 합니다.","code":"INVALID_NOTIFICATION_FILTER_PERIOD"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/unread-count":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 미확인 알림 개수 조회","description":"관리자가 아직 읽음 처리하지 않은 인앱 알림 개수를 조회합니다.","operationId":"countUnread","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"미확인 알림 개수 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationUnreadCountResponse"},"example":{"unreadCount":3}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notification-deliveries":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 알림 발송 결과 조회","description":"관리자가 사용자, 채널, 상태, 알림 유형, 기간 조건으로 알림 발송 결과를 페이지 단위로 조회합니다.","operationId":"listDeliveries","parameters":[{"name":"userId","in":"query","description":"수신 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":10},{"name":"channel","in":"query","description":"발송 채널","required":false,"schema":{"type":"string","enum":["FCM","EMAIL"]},"example":"FCM"},{"name":"status","in":"query","description":"발송 상태","required":false,"schema":{"type":"string","enum":["SUCCEEDED","FAILED","RETRY_SCHEDULED","FINAL_FAILED"]},"example":"SUCCEEDED"},{"name":"notificationType","in":"query","description":"인앱 알림 유형","required":false,"schema":{"type":"string","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"example":"NEW_LIKE"},{"name":"outboxEventType","in":"query","description":"Outbox 이벤트 유형","required":false,"schema":{"type":"string","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"example":"EMAIL_VERIFICATION_REQUESTED"},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationDeliveryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 목록 조회","description":"keyword는 장소명과 신청자 username을 부분 일치로 검색합니다. NEW_PLACE는 신청 장소명, EXISTING_PLACE_CLAIM은 대상 기존 장소명을 검색합니다. submittedFrom·submittedTo는 신청 제출 시각(Asia/Seoul 기준 LocalDateTime)을 포함 경계로 필터링하며, DRAFT는 제출 시각이 없어 기간 필터에서 제외됩니다. 한쪽 기간 경계만 전달할 수 있고 종료 시각이 시작 시각보다 빠르면 400을 반환합니다. 빈 keyword는 검색 조건을 적용하지 않습니다.","operationId":"list_11","parameters":[{"name":"status","in":"query","description":"반복 전달 가능한 신청 상태 필터","required":false,"style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]}}},{"name":"applicationType","in":"query","required":false,"schema":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]}},{"name":"keyword","in":"query","description":"장소명 또는 신청자 username 부분 일치 검색어. 공백 또는 빈 값은 미적용","required":false,"schema":{"type":"string"},"example":"서울"},{"name":"submittedFrom","in":"query","description":"신청 제출 시각 시작 경계(포함)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-01T00:00:00"},{"name":"submittedTo","in":"query","description":"신청 제출 시각 종료 경계(포함)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-30T23:59:59"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 상세 조회","operationId":"get_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/attachments":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 첨부파일 목록 조회","operationId":"listAttachments","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationAttachmentResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/attachments/{attachmentId}/content":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 첨부파일 다운로드","operationId":"attachmentContent","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"attachmentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 신청 목록 조회","operationId":"list_12","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfilePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 신청 상세 조회","operationId":"get_6","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/summary":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 요약 조회","description":"전체 장소, 게시글, 처리 대기 신고, 현재 밴 사용자 수와 운영 지표를 조회합니다. 등록 변화 지표는 서버 기준 오늘 00시부터 현재까지와 오늘을 포함한 최근 7일을 제공합니다. 중복 장소는 이름·주소 기준 후보 그룹 수, 밴 만료 예정 사용자는 현재 시각부터 7일 이내의 임시 밴 사용자 수, 위치 정보 누락 장소는 location이 없는 장소 수를 의미합니다.","operationId":"getSummary","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"대시보드 요약 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardSummaryResponse"},"example":{"placeCount":44,"postCount":58,"pendingReportCount":5,"bannedUserCount":6,"operationalMetrics":{"today":{"period":"TODAY","startedAt":"2026-07-21T00:00:00","endedAt":"2026-07-21T15:30:00","placeRegistrationCount":3,"postRegistrationCount":7},"last7Days":{"period":"LAST_7_DAYS","startedAt":"2026-07-15T00:00:00","endedAt":"2026-07-21T15:30:00","placeRegistrationCount":12,"postRegistrationCount":31},"duplicatePlaceGroupCount":2,"expiringBannedUserCount":4,"missingLocationPlaceCount":1,"expiringBanUntil":"2026-07-28T15:30:00","collectedAt":"2026-07-21T15:30:00"}}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/recent-activities":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 최근 운영 활동 조회","description":"최근 장소 등록, 게시글 등록, 신고 처리, 사용자 밴 및 밴 해제 내역을 조회합니다. limit 값은 내부적으로 1~50 범위로 보정됩니다.","operationId":"getRecentActivities","parameters":[{"name":"limit","in":"query","description":"조회할 최대 개수. 1~50 범위로 보정됩니다.","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","default":10},"example":10}],"responses":{"200":{"description":"최근 운영 활동 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardRecentActivitiesResponse"},"example":{"places":[{"placeId":10,"name":"핑덤 카페","address":"서울특별시 중구 세종대로 110","userId":3,"registrant":"pingdom_user","createdAt":"2026-07-21T15:30:00"}],"posts":[{"postId":22,"title":"야경이 좋은 장소","userId":3,"username":"pingdom_user","placeId":10,"placeName":"핑덤 카페","createdAt":"2026-07-21T15:30:00"}],"reports":[{"reportId":30,"reportedImageId":22,"title":"야경이 좋은 장소","status":"ACCEPTED","processedAt":"2026-07-21T16:00:00","createdAt":"2026-07-21T15:40:00"}],"userSanctions":[{"sanctionId":40,"targetUserId":5,"targetUsername":"reported_user","action":"APPLIED","banType":"PERMANENT","reason":"부적절한 게시글입니다.","processedAt":"2026-07-21T16:00:00"}]}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/pending-items":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 처리 필요 항목 조회","description":"우선 처리해야 하는 PENDING 신고와 통합 사업자·장소 신청 목록을 조회합니다. 통합 신청은 navigationPath로 관리자 심사 상세 화면 이동 경로를 제공합니다. limit 값은 내부적으로 1~50 범위로 보정됩니다.","operationId":"getPendingItems","parameters":[{"name":"limit","in":"query","description":"조회할 최대 개수. 1~50 범위로 보정됩니다.","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","default":10},"example":10}],"responses":{"200":{"description":"처리 필요 항목 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardPendingItemsResponse"},"example":{"items":[{"type":"POST_REPORT","targetId":30,"reportId":30,"postId":22,"title":"야경이 좋은 장소","status":"PENDING","createdAt":"2026-07-21T15:40:00","navigationPath":null}],"totalCount":1}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 글 목록 조회","description":"숨김 글을 포함해 카테고리와 숨김 상태로 조회합니다.","operationId":"findPosts","parameters":[{"name":"categoryId","in":"query","required":false,"schema":{"type":"string"}},{"name":"hidden","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityPostPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 글 상세 조회","description":"숨김 여부와 연결 장소를 포함해 조회합니다.","operationId":"findPost","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"커뮤니티 글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityPostResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}/comments":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 댓글 목록 조회","description":"숨김 댓글을 포함해 숨김 상태로 조회합니다.","operationId":"findComments","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"hidden","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"댓글 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityCommentPageResponse"}}}},"404":{"description":"커뮤니티 글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}/comments/{commentId}":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 댓글 상세 조회","operationId":"findComment","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityCommentResponse"}}}},"404":{"description":"커뮤니티 글 또는 댓글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports":{"get":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 목록 조회","operationId":"list_13","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]}},{"name":"targetType","in":"query","required":false,"schema":{"type":"string","enum":["POST","COMMENT"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}":{"get":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 상세 조회","operationId":"get_7","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"신고 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportResponse"},"examples":{"POST":{"summary":"글 신고: postId와 targetId가 동일","description":"POST","value":{"reportId":1,"targetType":"POST","targetId":101,"postId":101,"targetHidden":false,"reporterUserId":10,"reason":"SPAM","description":"글 신고","status":"PENDING","createdAt":"2026-09-17T10:00:00","processedByAdminUserId":null,"processedAt":null}},"COMMENT":{"summary":"댓글 신고: postId는 원문 글, targetId는 댓글","description":"COMMENT","value":{"reportId":2,"targetType":"COMMENT","targetId":202,"postId":101,"targetHidden":false,"reporterUserId":10,"reason":"ABUSE","description":"댓글 신고","status":"PENDING","createdAt":"2026-09-17T10:00:00","processedByAdminUserId":null,"processedAt":null}}}}}},"404":{"description":"커뮤니티 신고를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/audit-logs":{"get":{"tags":["감사·개인정보 처리 이력"],"summary":"관리자 감사 로그 조회","description":"관리자가 actor, action, target, 기간 조건으로 운영 감사 로그를 페이지 단위로 조회합니다.","operationId":"listAuditLogs","parameters":[{"name":"actorUserId","in":"query","description":"작업 관리자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"action","in":"query","description":"작업 유형","required":false,"schema":{"type":"string","enum":["ADMIN_ROLE_ASSIGNED","ADMIN_ROLE_REVOKED","USER_BAN_APPLIED","USER_BAN_RELEASED","REPORT_ACCEPTED","REPORT_DECLINED","COMMUNITY_REPORT_ACCEPTED","COMMUNITY_REPORT_DECLINED","POST_DELETED","POST_HIDDEN","POST_RESTORED","APPEAL_APPROVED","APPEAL_REJECTED","PLACE_DELETED","PLACE_BASIC_INFORMATION_UPDATED","PLACE_KAKAO_PLACE_ID_UPDATED","PLACE_GEOCODING_UPDATED","PLACE_TOURIST_INFO_UPDATED","PLACE_INFORMATION_EVIDENCE_UPDATED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_INFORMATION_REVERIFICATION_COMPLETED","PLACE_INFORMATION_REVERIFICATION_CANCELED","PLACE_INFORMATION_REVERIFICATION_EXPIRED","VISITOR_VERIFICATION_REPORT_REVIEWED","VISITOR_VERIFICATION_REPORT_CORRECTION_REVIEWED","SCOUT_FIELD_REPORT_REVIEWED","SCOUT_PROFILE_REVIEWED","SCOUT_ACTIVITY_ELIGIBILITY_REVIEWED","PLACE_DISCOVERY_STATUS_UPDATED","PLACE_OPERATING_STATUS_UPDATED","PLACE_OPERATING_SCHEDULE_UPDATED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_EVENT_CREATED","PLACE_EVENT_UPDATED","PLACE_EVENT_PUBLISHED","PLACE_EVENT_CANCELLED","PLACE_RECOMMENDATION_TRAFFIC_UPDATED","PLACE_RECOMMENDATION_KILL_SWITCH_UPDATED","TRUST_SCORE_ANOMALY_RESOLVED","TRUST_SCORE_INTERVENTION_RULE_CREATED","TRUST_SCORE_INTERVENTION_RULE_UPDATED","TRUST_SCORE_INTERVENTION_RULE_ENABLED","TRUST_SCORE_INTERVENTION_RULE_DISABLED","TRUST_SCORE_INTERVENTION_EVALUATED","NOTIFICATION_READ","NOTIFICATION_READ_ALL","PLACE_DUPLICATE_CONFIRMED","PLACE_DUPLICATE_REJECTED","PLACE_MERGED","MERCHANT_OWNER_APPROVED","MERCHANT_OWNER_REJECTED","MERCHANT_OWNER_REVOKED","MERCHANT_OWNER_PLACES_UPDATED","MERCHANT_ONBOARDING_UPDATED","MERCHANT_OPERATIONAL_QUALITY_UPDATED","MERCHANT_VERIFICATION_REVIEWED","MERCHANT_VERIFICATION_VIEWED","MERCHANT_PLACE_CLAIM_ATTACHMENT_VIEWED","MERCHANT_PLACE_CLAIM_APPROVED","MERCHANT_PLACE_CLAIM_REJECTED","MERCHANT_PLACE_APPLICATION_APPROVED","MERCHANT_PLACE_APPLICATION_REJECTED","MERCHANT_PLACE_APPLICATION_VIEWED","MERCHANT_PLACE_APPLICATION_ATTACHMENT_VIEWED","OUTBOX_EVENT_RETRIED","AD_CREATED","AD_DELETED","RESERVATION_CONFIRMED","RESERVATION_REJECTED"]},"example":"USER_BAN_APPLIED"},{"name":"targetType","in":"query","description":"대상 유형","required":false,"schema":{"type":"string","enum":["USER","REPORT","COMMUNITY_REPORT","APPEAL","POST","PLACE","PLACE_DUPLICATE_CANDIDATE","PLACE_INFORMATION_EVIDENCE","PLACE_INFORMATION_REPORT","PLACE_INFORMATION_DISPUTE","PLACE_INFORMATION_REVERIFICATION","VISITOR_VERIFICATION_REPORT","VISITOR_VERIFICATION_REPORT_CORRECTION","SCOUT_FIELD_REPORT","SCOUT_PROFILE","SCOUT_ACTIVITY_ELIGIBILITY","PLACE_OPERATING_NOTICE","PLACE_EVENT","TRUST_SCORE_ANOMALY","TRUST_SCORE_INTERVENTION_RULE","NOTIFICATION","OUTBOX_EVENT","MERCHANT_OWNER","MERCHANT_VERIFICATION","MERCHANT_PLACE_CLAIM_ATTACHMENT","MERCHANT_PLACE_CLAIM","MERCHANT_PLACE_APPLICATION","MERCHANT_PLACE_APPLICATION_ATTACHMENT","AD","RESERVATION"]},"example":"USER"},{"name":"targetId","in":"query","description":"대상 ID","required":false,"schema":{"type":"string"},"example":7},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminAuditLogResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/roles/{role}":{"delete":{"tags":["회원·권한"],"summary":"관리자 역할 회수","operationId":"revoke_2","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"role","in":"path","required":true,"schema":{"type":"string","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentRevokeRequest"}}}},"responses":{"200":{"description":"회수 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}},"404":{"description":"활성 역할을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{id}/delete":{"delete":{"tags":["신고·이의신청"],"summary":"관리자 게시글 삭제","description":"관리자가 게시글을 강제로 삭제합니다. S3 객체 삭제는 DB 삭제 확정 후 Outbox로 비동기 처리됩니다.","operationId":"deletePost","parameters":[{"name":"id","in":"path","description":"삭제할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"example":{"message":"게시글을 찾을 수 없습니다.","code":"POST_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"204":{"description":"게시글 삭제 성공"}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans":{"delete":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 삭제","description":"완료된 리포트의 삭제 후보인지 확인하고, 삭제 직전 DB에서 사용 중인 키를 다시 제외한 뒤 S3 객체를 삭제합니다.","operationId":"deleteS3Orphans","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminS3OrphanDeleteRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanDeleteResult"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/delete":{"delete":{"tags":["장소 정보·품질"],"summary":"관리자 장소 삭제","description":"관리자가 장소를 강제로 삭제합니다.","operationId":"forceDeletePlace","parameters":[{"name":"id","in":"path","description":"강제 삭제할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":5}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"409":{"description":"연결된 기간형 이벤트가 있어 장소를 삭제할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"204":{"description":"장소 삭제 성공"},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}}},"components":{"schemas":{"AdminTrustScoreInterventionRuleRequest":{"required":["actionType","reason","ruleName","triggerType"],"type":"object","properties":{"ruleName":{"maxLength":100,"minLength":0,"type":"string","description":"규칙 이름","example":"low trust temporary restriction"},"triggerType":{"type":"string","description":"트리거 유형","example":"FALSE_REPORT_COUNT","enum":["TRUST_SCORE_RANGE","FALSE_REPORT_COUNT","ACCEPTANCE_RATE","ANOMALY_DETECTED"]},"actionType":{"type":"string","description":"액션 유형","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"minTrustScore":{"maximum":100,"minimum":0,"type":"integer","description":"최소 Trust Score","format":"int32","example":0},"maxTrustScore":{"maximum":100,"minimum":0,"type":"integer","description":"최대 Trust Score","format":"int32","example":60},"minSubmittedCount":{"minimum":0,"type":"integer","description":"최소 신고 수","format":"int64","example":3},"minFalseReportCount":{"minimum":0,"type":"integer","description":"최소 허위 신고 수","format":"int64","example":3},"durationDays":{"type":"integer","description":"임시 제한 기간 일수. TEMPORARY_RESTRICT일 때만 입력합니다.","format":"int32","example":7},"priority":{"minimum":0,"type":"integer","description":"우선순위. 낮을수록 먼저 적용됩니다.","format":"int32","example":10},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"개입 규칙 적용 사유","example":"허위 신고 누적 사용자 제한"}}},"AdminTrustScoreInterventionRuleItem":{"type":"object","properties":{"id":{"type":"integer","description":"개입 규칙 ID","format":"int64","example":1},"ruleName":{"type":"string","description":"규칙 이름","example":"low trust review"},"triggerType":{"type":"string","description":"트리거 유형","example":"FALSE_REPORT_COUNT","enum":["TRUST_SCORE_RANGE","FALSE_REPORT_COUNT","ACCEPTANCE_RATE","ANOMALY_DETECTED"]},"actionType":{"type":"string","description":"액션 유형","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"minTrustScore":{"type":"integer","description":"최소 Trust Score","format":"int32","example":0},"maxTrustScore":{"type":"integer","description":"최대 Trust Score","format":"int32","example":60},"minSubmittedCount":{"type":"integer","description":"최소 신고 수","format":"int64","example":3},"minFalseReportCount":{"type":"integer","description":"최소 허위 신고 수","format":"int64","example":3},"durationDays":{"type":"integer","description":"제한 기간 일수","format":"int32","example":7},"priority":{"type":"integer","description":"우선순위","format":"int32","example":10},"reason":{"type":"string","description":"적용 사유","example":"허위 신고 누적"},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}}},"MerchantOwnerPlaceUpdateRequest":{"type":"object","properties":{"placeIds":{"maxItems":100,"minItems":0,"uniqueItems":true,"type":"array","items":{"type":"integer","format":"int64"}},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerProfileResponse":{"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"businessName":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string","nullable":true},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]},"onboardingStatus":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"]},"onboardingCompletionRate":{"type":"integer","format":"int32"},"onboardingCompletedAt":{"type":"string","format":"date-time","nullable":true},"reviewedBy":{"type":"integer","format":"int64","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"reviewReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"placeIds":{"type":"array","items":{"type":"integer","format":"int64"}}},"description":"Merchant Owner 프로필 응답"},"MerchantOwnerPlaceQualityUpdateRequest":{"required":["noShowRate","reservationCancellationRate","reservationResponseRate","status"],"type":"object","properties":{"status":{"type":"string","enum":["UNMEASURED","HEALTHY","NEEDS_ATTENTION","AT_RISK"]},"reservationResponseRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"reservationCancellationRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"noShowRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"evaluatedAt":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerPlaceResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"operationalQualityStatus":{"type":"string","enum":["UNMEASURED","HEALTHY","NEEDS_ATTENTION","AT_RISK"]},"reservationResponseRate":{"type":"integer","format":"int32"},"reservationCancellationRate":{"type":"integer","format":"int32"},"noShowRate":{"type":"integer","format":"int32"},"qualityEvaluatedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"MerchantOnboardingUpdateRequest":{"required":["completionRate","status"],"type":"object","properties":{"status":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"]},"completionRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"completedAt":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"VisitorVerificationReportReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"VisitorVerificationReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"waitTimeMinutes":{"type":"integer","format":"int32"},"languageCode":{"type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"VisitorVerificationReportCorrectionReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"ErrorResponse":{"required":["message"],"type":"object","properties":{"message":{"type":"string","description":"에러 메시지","example":"유효하지 않은 토큰입니다."},"code":{"type":"string","description":"도메인 에러 코드. 일부 공통 검증 오류에서는 제공되지 않을 수 있습니다.","nullable":true,"example":"INVALID_TOKEN"}},"description":"에러 응답"},"VisitorVerificationReportCorrectionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"requesterUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"waitTimeMinutes":{"type":"integer","format":"int32"},"languageCode":{"type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]},"reportStatus":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"VerifiedBoostProductCreateRequest":{"required":["description","durationDays","name","priceAmount"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","example":"Verified Boost 7일"},"description":{"maxLength":500,"minLength":0,"type":"string","example":"검증된 장소의 추천 노출을 7일간 강화합니다."},"priceAmount":{"type":"integer","description":"KRW 기준 가격","format":"int64","example":30000},"durationDays":{"maximum":365,"minimum":1,"type":"integer","format":"int32","example":7}}},"VerifiedBoostProductResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"name":{"type":"string"},"description":{"type":"string"},"priceAmount":{"type":"integer","description":"KRW 기준 가격","format":"int64","example":30000},"durationDays":{"type":"integer","format":"int32","example":7},"status":{"type":"string","enum":["DRAFT","ACTIVE","INACTIVE"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminRoleAssignmentRequest":{"required":["role"],"type":"object","properties":{"role":{"type":"string","description":"할당할 관리자 역할","example":"CONTENT_MODERATOR","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"역할을 부여하거나 회수하는 사유","example":"장소 정보 검수 담당 배정"}},"description":"관리자 역할 할당 요청"},"AdminRoleAssignmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"adminUserId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"assignedByUserId":{"type":"integer","format":"int64"},"assignedAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time"},"permissions":{"type":"array","items":{"type":"string","enum":["ADMIN_ROLE_MANAGE","USER_READ","USER_SANCTION","PLACE_READ","PLACE_MODERATE","MERCHANT_REVIEW","REPORT_REVIEW","SCOUT_REVIEW","DASHBOARD_READ","AUDIT_READ","OUTBOX_RECOVERY"]}}},"description":"관리자 역할 할당 응답"},"AdminTrustScoreInterventionEvaluationResponse":{"type":"object","properties":{"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":12},"trustScore":{"type":"integer","description":"현재 Trust Score","format":"int32","example":40},"matchedRuleId":{"type":"integer","description":"매칭된 규칙 ID","format":"int64","example":1},"matchedRuleName":{"type":"string","description":"매칭된 규칙 이름","example":"low trust temporary restriction"},"actionType":{"type":"string","description":"적용 액션","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"restrictedUntil":{"type":"string","description":"제한 만료 시각","format":"date-time"},"message":{"type":"string","description":"처리 결과 메시지","example":"Trust Score 개입 규칙을 적용했습니다."}}},"AdminTrustScoreBatchResponse":{"type":"object","properties":{"processedCount":{"type":"integer","format":"int32"},"changedCount":{"type":"integer","format":"int32"}}},"ScoutProfileReviewRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutProfileResponse":{"required":["activityEligibilityStatus","createdAt","displayName","eligibilityReviewedAt","eligibilityReviewedByAdminUserId","eligibilityStatusReason","eligibleFrom","eligibleUntil","introduction","profileReviewedAt","profileReviewedByAdminUserId","profileStatus","profileStatusReason","updatedAt","userId"],"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"displayName":{"type":"string"},"introduction":{"type":"string","nullable":true},"profileStatus":{"type":"string","enum":["PENDING","ACTIVE","SUSPENDED","REVOKED"]},"profileReviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"profileReviewedAt":{"type":"string","format":"date-time","nullable":true},"profileStatusReason":{"type":"string","nullable":true},"activityEligibilityStatus":{"type":"string","enum":["PENDING","ELIGIBLE","SUSPENDED","EXPIRED","REVOKED"]},"eligibleFrom":{"type":"string","format":"date-time","nullable":true},"eligibleUntil":{"type":"string","format":"date-time","nullable":true},"eligibilityReviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"eligibilityReviewedAt":{"type":"string","format":"date-time","nullable":true},"eligibilityStatusReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Scout 프로필 및 활동 자격 응답"},"ScoutActivityEligibilityReviewRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutActivityEligibilityGrantRequest":{"required":["eligibleFrom"],"type":"object","properties":{"eligibleFrom":{"type":"string","format":"date-time"},"eligibleUntil":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutFieldReportReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutFieldReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"scoutUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","CROWD_LEVEL","SAFETY","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminReservationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"quantity":{"type":"integer","format":"int32"},"touristUserId":{"type":"integer","format":"int64"},"touristUsername":{"type":"string"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"merchantOwnerUsername":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"availabilityId":{"type":"integer","format":"int64"},"reservationStartsAt":{"type":"string","format":"date-time"},"reservationEndsAt":{"type":"string","format":"date-time"},"bookerName":{"type":"string"},"bookerPhone":{"type":"string"},"requestNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"confirmedAt":{"type":"string","format":"date-time"},"reviewedBy":{"type":"integer","format":"int64"},"reviewedAt":{"type":"string","format":"date-time"},"reviewReason":{"type":"string"},"rejectedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"canceledBy":{"type":"integer","format":"int64"},"statusHistory":{"type":"array","items":{"$ref":"#/components/schemas/AdminReservationStatusHistoryResponse"}}}},"AdminReservationStatusHistoryResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"changedBy":{"type":"integer","format":"int64"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}},"AdminReportAppealActionRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminReportAppealActionResponse":{"type":"object","properties":{"appealId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]},"processedAt":{"type":"string","format":"date-time"}}},"AdminPostReportBulkActionResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":10},"status":{"type":"string","description":"일괄 처리된 신고 상태","example":"ACCEPTED","enum":["PENDING","ACCEPTED","DECLINED","RESTORED"]},"processedReportCount":{"type":"integer","description":"처리된 신고 수","format":"int32","example":3},"visibilityStatus":{"type":"string","description":"게시글 공개 상태","example":"AUTO_HIDDEN","enum":["ACTIVE","AUTO_HIDDEN"]},"hiddenAt":{"type":"string","description":"게시글 숨김 처리 시각","format":"date-time"},"hiddenReason":{"type":"string","description":"게시글 숨김 사유","example":"REPORT_BULK_ACCEPTED"},"processedAt":{"type":"string","description":"신고 처리 시각","format":"date-time"}},"description":"관리자 게시글 단위 신고 일괄 처리 응답"},"S3OrphanReportStatus":{"type":"object","properties":{"reportId":{"type":"string"},"status":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"dbKeyCount":{"type":"integer","format":"int64"},"s3KeyCount":{"type":"integer","format":"int64"},"deleteCandidateCount":{"type":"integer","format":"int64"},"errorMessage":{"type":"string"}}},"PlaceOperatingNoticeCreateRequest":{"required":["expiresAt","message","noticeType","severity","startsAt"],"type":"object","properties":{"noticeType":{"type":"string","enum":["TEMPORARY_CLOSURE","HOURS_CHANGE","CROWDING","REOPENING","GENERAL"]},"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"message":{"maxLength":500,"minLength":0,"type":"string"},"startsAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}},"description":"상점 운영 상태 공지 생성 요청"},"PlaceOperatingNoticeResponse":{"required":["cancelReason","canceledAt","createdAt","expiredAt","expiresAt","id","message","noticeType","placeId","severity","startsAt","status","updatedAt","visibleNow"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"noticeType":{"type":"string","enum":["TEMPORARY_CLOSURE","HOURS_CHANGE","CROWDING","REOPENING","GENERAL"]},"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"status":{"type":"string","enum":["SCHEDULED","ACTIVE","EXPIRED","CANCELED"]},"message":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"expiredAt":{"type":"string","format":"date-time","nullable":true},"canceledAt":{"type":"string","format":"date-time","nullable":true},"cancelReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"visibleNow":{"type":"boolean"}},"description":"상점 운영 상태 공지 응답"},"PlaceOperatingNoticeCancelRequest":{"required":["cancelReason"],"type":"object","properties":{"cancelReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"상점 운영 상태 공지 취소 요청"},"PlaceInformationReverificationCreateRequest":{"required":["dueAt","reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"},"dueAt":{"type":"string","format":"date-time"}}},"PlaceInformationReverificationResponse":{"type":"object","properties":{"requestId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["REQUESTED","RESPONDED","COMPLETED","CANCELED","EXPIRED"]},"reason":{"type":"string"},"requestedAt":{"type":"string","format":"date-time"},"dueAt":{"type":"string","format":"date-time"},"lastRemindedAt":{"type":"string","format":"date-time"},"reminderCount":{"type":"integer","format":"int32"},"respondedAt":{"type":"string","format":"date-time"},"responseNote":{"type":"string"},"completedAt":{"type":"string","format":"date-time"}}},"AdminPlaceInformationEvidenceCreateRequest":{"required":["evidenceType","sourceType"],"type":"object","properties":{"sourceType":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"evidenceType":{"type":"string","enum":["EXTERNAL_PLACE_ID","BUSINESS_CLAIM","DOCUMENT","PHOTO","ADMIN_REVIEW","USER_VISIT","SYSTEM_SIGNAL"]},"externalReference":{"maxLength":100,"minLength":0,"type":"string","description":"외부 장소 ID, 사업자 등록 번호 등 외부 참조값","nullable":true},"referenceUrl":{"maxLength":500,"minLength":0,"type":"string","description":"증빙 URL","nullable":true},"description":{"maxLength":1000,"minLength":0,"type":"string","description":"관리자 메모 또는 증빙 설명","nullable":true},"submittedByUserId":{"type":"integer","description":"증빙 제출 사용자 ID. 미입력 시 관리자 ID를 사용","format":"int64","nullable":true}},"description":"관리자 장소 정보 증빙 등록 요청"},"AdminPlaceInformationEvidenceItem":{"type":"object","properties":{"evidenceId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"sourceType":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"evidenceType":{"type":"string","enum":["EXTERNAL_PLACE_ID","BUSINESS_CLAIM","DOCUMENT","PHOTO","ADMIN_REVIEW","USER_VISIT","SYSTEM_SIGNAL"]},"verificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"externalReference":{"type":"string","nullable":true},"referenceUrl":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"submittedByUserId":{"type":"integer","format":"int64","nullable":true},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"관리자 장소 정보 증빙 항목"},"AdminPlaceInformationEvidenceUpdateResponse":{"type":"object","properties":{"evidence":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceItem"},"message":{"type":"string"}},"description":"관리자 장소 정보 증빙 변경 응답"},"AdminPlaceRecommendationSnapshotResyncResponse":{"type":"object","properties":{"placeCount":{"type":"integer","format":"int64"},"synchronizedSnapshotCount":{"type":"integer","format":"int64"},"deletedSnapshotCount":{"type":"integer","format":"int64"},"synchronizedSimilaritySnapshotCount":{"type":"integer","format":"int64"},"deletedSimilaritySnapshotCount":{"type":"integer","format":"int64"},"synchronizedVersionSnapshotCount":{"type":"integer","format":"int64"},"deletedVersionSnapshotCount":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminMapPlaceMergeRequest":{"type":"object","properties":{"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"candidateId":{"type":"integer","format":"int64"}}},"AdminMapPlaceMergeResponse":{"type":"object","properties":{"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminPlaceMergeRestoreResponse":{"type":"object","properties":{"historyId":{"type":"integer","format":"int64"},"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminPlaceDuplicateDecisionRequest":{"required":["reviewNote"],"type":"object","properties":{"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminPlaceDuplicateCandidateResponse":{"type":"object","properties":{"candidateId":{"type":"integer","format":"int64"},"leftPlaceId":{"type":"integer","format":"int64"},"rightPlaceId":{"type":"integer","format":"int64"},"matchReason":{"type":"string"},"confidenceScore":{"type":"number"},"distanceMeters":{"type":"integer","format":"int32"},"status":{"type":"string"},"reviewedByAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"mergeHistoryId":{"type":"integer","format":"int64"},"detectedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminPlaceDuplicateMergeRequest":{"required":["targetPlaceId"],"type":"object","properties":{"targetPlaceId":{"type":"integer","format":"int64"}}},"PlaceReviewDeletionRequestReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminPlaceReviewDeletionRequestResponse":{"type":"object","properties":{"deletionRequestId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"requestReason":{"type":"string"},"requesterUserId":{"type":"integer","format":"int64"},"requestedAt":{"type":"string","format":"date-time"},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"reviewedAt":{"type":"string","format":"date-time"},"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reviewAuthorUserId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"reviewVisibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]},"reviewCreatedAt":{"type":"string","format":"date-time"}}},"PlaceReviewMediaResponse":{"type":"object","properties":{"reviewMediaId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"contentType":{"type":"string"}},"description":"리뷰에 연결된 검증 완료 사진"},"PlaceInformationReportReviewRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","description":"UNDER_REVIEW, ACCEPTED, REJECTED, RESOLVED만 허용","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"관리자 장소 정보 신고 검토 요청"},"PlaceInformationDisputeResponse":{"type":"object","properties":{"disputeId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"disputedByUserId":{"type":"integer","format":"int64"},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"장소 정보 반박 응답"},"PlaceInformationReportResponse":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"evidenceId":{"type":"integer","format":"int64","nullable":true},"reporterUserId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["NAME","ADDRESS","GEOLOCATION","OPERATING_STATUS","TOURIST_INFORMATION","SOURCE_EVIDENCE","MEDIA","OTHER"]},"reasonType":{"type":"string","enum":["INCORRECT","OUTDATED","MISSING","MISLEADING","DUPLICATE","CLOSED_OR_MOVED","SPAM_OR_ABUSE","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"status":{"type":"string","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"resolvedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"disputes":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}},"description":"장소 정보 신고 응답"},"PlaceInformationDisputeReviewRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","description":"ACCEPTED 또는 REJECTED만 허용","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"관리자 장소 정보 반박 검토 요청"},"AdminPlaceEventRequest":{"required":["endAt","eventType","placeId","reason","startAt","title"],"type":"object","properties":{"placeId":{"type":"integer","description":"행사 장소 ID","format":"int64","example":17},"title":{"maxLength":150,"minLength":0,"type":"string","description":"이벤트 제목","example":"진주 여름 빛 축제"},"description":{"maxLength":1000,"minLength":0,"type":"string","description":"이벤트 설명","example":"남강을 배경으로 열리는 야간 공연과 전시입니다."},"eventType":{"type":"string","description":"이벤트 유형","example":"EXHIBITION","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","description":"시작 시각","format":"date-time"},"endAt":{"type":"string","description":"종료 시각","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"관리자 변경 사유","example":"공식 일정 등록"}},"description":"관리자 기간형 이벤트 등록·수정 요청"},"AdminPlaceEventResponse":{"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"publicationStatus":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]},"message":{"type":"string"}},"description":"관리자 기간형 이벤트 응답"},"AdminPlaceEventActionRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"변경 사유","example":"운영 검토를 완료했습니다."}},"description":"관리자 이벤트 상태 변경 요청"},"AdminOutboxEventRetryRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"장애 원인 제거와 중복 처리 안전성을 확인한 재처리 사유","example":"외부 메일 공급자 장애 복구 확인"}},"description":"관리자 Outbox 이벤트 재처리 요청"},"AdminOutboxEventItem":{"type":"object","properties":{"eventId":{"type":"string","description":"이벤트 ID"},"eventType":{"type":"string","description":"이벤트 유형","example":"EMAIL_VERIFICATION_REQUESTED","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"aggregateType":{"type":"string","description":"aggregate 유형","example":"USER"},"aggregateId":{"type":"string","description":"aggregate ID","example":"10"},"status":{"type":"string","description":"처리 상태","example":"FAILED","enum":["PENDING","PROCESSING","RETRY","SUCCEEDED","FAILED"]},"attemptCount":{"type":"integer","description":"현재 재시도 주기의 실패 횟수","format":"int32","example":5},"nextAttemptAt":{"type":"string","description":"다음 처리 가능 시각","format":"date-time"},"processingStartedAt":{"type":"string","description":"처리 선점 시각","format":"date-time"},"processedAt":{"type":"string","description":"처리 완료 시각","format":"date-time"},"lastError":{"type":"string","description":"마지막 실패 원인"},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}},"description":"관리자 Outbox 이벤트 운영 조회 항목"},"MerchantPlaceApplicationReviewRequest":{"required":["reviewedVersion"],"type":"object","properties":{"reviewedVersion":{"type":"integer","format":"int64"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"BreakTime":{"required":["closesAt","opensAt"],"type":"object","properties":{"opensAt":{"$ref":"#/components/schemas/LocalTime"},"closesAt":{"$ref":"#/components/schemas/LocalTime"}}},"LocalTime":{"type":"object","properties":{"hour":{"type":"integer","format":"int32"},"minute":{"type":"integer","format":"int32"},"second":{"type":"integer","format":"int32"},"nano":{"type":"integer","format":"int32"}}},"MerchantPlaceApplicationAttachmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"fileId":{"type":"string"},"documentType":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"uploadedAt":{"type":"string","format":"date-time"},"retentionExpiresAt":{"type":"string","format":"date-time"},"displayOrder":{"type":"integer","format":"int32"}}},"MerchantPlaceApplicationNewPlaceResponse":{"type":"object","properties":{"placeName":{"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"description":{"type":"string"},"businessContactPhone":{"type":"string"},"applicantContactPhone":{"type":"string"},"tags":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["ENGLISH_SERVICE_AVAILABLE","ENGLISH_MENU_AVAILABLE","RESERVATION_AVAILABLE","RESERVATION_COUPON_AVAILABLE","GENERAL_COUPON_AVAILABLE","GOOD_AMBIENCE"]}},"timezone":{"type":"string"},"operatingDays":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegistrationOperatingDay"}}}},"MerchantPlaceApplicationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"merchantDisplayName":{"type":"string"},"merchantContactEmail":{"type":"string"},"merchantDescription":{"type":"string"},"merchantContactPhone":{"type":"string"},"newPlace":{"$ref":"#/components/schemas/MerchantPlaceApplicationNewPlaceResponse"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"type":"string"},"reviewReason":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"version":{"type":"integer","format":"int64"},"submissionVersion":{"type":"integer","format":"int64"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceApplicationAttachmentResponse"}}}},"PlaceRegistrationOperatingDay":{"required":["dayOfWeek","status"],"type":"object","properties":{"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"status":{"type":"string","enum":["OPEN","CLOSED","OPEN_24_HOURS"]},"opensAt":{"$ref":"#/components/schemas/LocalTime"},"closesAt":{"$ref":"#/components/schemas/LocalTime"},"breakTimes":{"type":"array","items":{"$ref":"#/components/schemas/BreakTime"}}}},"MerchantOwnerReviewRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminCommunityReportActionResponse":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"targetHidden":{"type":"boolean"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 처리 결과"},"BanRequest":{"type":"object","properties":{"reason":{"maxLength":255,"minLength":0,"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"expiresAt":{"type":"string","description":"기간 밴 종료 시각. 비우면 영구 밴으로 처리됩니다.","format":"date-time"},"durationDays":{"minimum":1,"type":"integer","description":"현재 시각부터 적용할 밴 기간(일). expiresAt과 동시에 사용할 수 없습니다.","format":"int64","example":7}},"description":"관리자 밴 처리 요청 정보"},"BanResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"밴 처리된 사용자 ID","format":"int64","example":7},"banned":{"type":"boolean","description":"밴 여부","example":true},"bannedAt":{"type":"string","description":"밴 처리 시각","format":"date-time"},"reason":{"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"banType":{"type":"string","description":"밴 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"}},"description":"관리자 밴 처리 응답"},"UnbanRequest":{"type":"object","properties":{"reason":{"maxLength":255,"minLength":0,"type":"string","description":"밴 해제 사유","example":"운영 검토 결과 해제"}},"description":"관리자 밴 해제 요청 정보"},"UnbanResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"밴 해제된 사용자 ID","format":"int64","example":7},"banned":{"type":"boolean","description":"현재 밴 여부","example":false},"releasedAt":{"type":"string","description":"밴 해제 처리 시각","format":"date-time"},"reason":{"type":"string","description":"밴 해제 사유","example":"운영 검토 결과 해제"}},"description":"관리자 밴 해제 응답"},"AdminTrustScoreInterventionRuleToggleResponse":{"type":"object","properties":{"ruleId":{"type":"integer","description":"개입 규칙 ID","format":"int64","example":1},"enabled":{"type":"boolean","description":"활성화 여부","example":false},"message":{"type":"string","description":"처리 결과 메시지","example":"Trust Score 개입 규칙을 비활성화했습니다."}}},"AdminTrustScoreAnomalyResolveRequest":{"required":["resolutionReason"],"type":"object","properties":{"resolutionReason":{"maxLength":500,"minLength":0,"type":"string","description":"이상치 해결 사유","example":"관리자 검토 후 정상 패턴으로 확인했습니다."}}},"AdminTrustScoreAnomalyItem":{"type":"object","properties":{"id":{"type":"integer","description":"Trust Score 이상치 ID","format":"int64","example":1},"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":12},"reporterUsername":{"type":"string","description":"신고자 username","example":"ping-user"},"anomalyType":{"type":"string","description":"이상치 유형","example":"FALSE_REPORT_SPIKE","enum":["RAPID_DROP","FALSE_REPORT_SPIKE","LOW_ACCEPTANCE_RATE","MANUAL_REVIEW"]},"severity":{"type":"string","description":"이상치 심각도","example":"HIGH","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"baselineScore":{"type":"integer","description":"기준 Trust Score","format":"int32","example":100},"observedScore":{"type":"integer","description":"감지 시점 Trust Score","format":"int32","example":40},"submittedCount":{"type":"integer","description":"전체 신고 수","format":"int64","example":5},"acceptedCount":{"type":"integer","description":"수락 신고 수","format":"int64","example":1},"declinedCount":{"type":"integer","description":"거절 신고 수","format":"int64","example":4},"falseReportCount":{"type":"integer","description":"허위 신고 수","format":"int64","example":4},"detectedAt":{"type":"string","description":"감지 시각","format":"date-time"},"resolvedAt":{"type":"string","description":"해결 시각","format":"date-time"},"resolutionReason":{"type":"string","description":"해결 사유","example":"관리자 검토 완료"}},"description":"이상치 목록"},"PlaceOperatingNoticeUpdateRequest":{"required":["message","severity"],"type":"object","properties":{"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"message":{"maxLength":500,"minLength":0,"type":"string"}},"description":"상점 운영 상태 공지 수정 요청"},"AdminMapPlaceTouristInfoUpdateRequest":{"required":["reason"],"type":"object","properties":{"englishName":{"maxLength":150,"minLength":0,"type":"string","description":"영문 장소명. 공백 또는 null이면 제거합니다.","nullable":true,"example":"Jinju Castle"},"touristSummary":{"maxLength":500,"minLength":0,"type":"string","description":"관광객용 장소 요약. 공백 또는 null이면 제거합니다.","nullable":true},"touristCategories":{"maxItems":9,"minItems":0,"uniqueItems":true,"type":"array","description":"관광 목적 카테고리 전체 목록. 생략하면 모두 제거합니다.","items":{"type":"string","description":"관광 목적 카테고리 전체 목록. 생략하면 모두 제거합니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"영문 정보와 관광 분류 최신화"}},"description":"관리자 장소 관광 정보 전체 교체 요청"},"AdminMapPlaceTouristInfoUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"message":{"type":"string"}}},"AdminMapPlaceOperatingStatusUpdateRequest":{"required":["operatingStatus","reason"],"type":"object","properties":{"operatingStatus":{"type":"string","description":"확인된 장소 운영 상태","example":"TEMPORARILY_CLOSED","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 확인 근거","example":"현장 확인 결과 임시 휴업"}},"description":"관리자 장소 운영 상태 확인 요청"},"AdminMapPlaceOperatingStatusUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","description":"운영 상태 최신 확인 시각","format":"date-time"},"message":{"type":"string"}}},"AdminMapPlaceOperatingExceptionRequest":{"required":["date"],"type":"object","properties":{"date":{"type":"string","format":"date","example":"2026-08-15"},"closed":{"type":"boolean","description":"true이면 종일 휴무이며 hours는 비워야 합니다.","example":true},"hours":{"uniqueItems":true,"type":"array","description":"대체 영업 시간대. closed가 false이면 하나 이상 필요합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingTimeRangeRequest"}}},"description":"관리자 특정 날짜 영업 예외"},"AdminMapPlaceOperatingScheduleUpdateRequest":{"required":["reason"],"type":"object","properties":{"regularHours":{"uniqueItems":true,"type":"array","description":"요일별 정규 영업 시간대. 생략하면 모두 제거합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceRegularOperatingHourRequest"}},"exceptions":{"uniqueItems":true,"type":"array","description":"특정 날짜의 휴무 또는 대체 영업 일정. 생략하면 모두 제거합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingExceptionRequest"}},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"광복절 휴무와 주말 영업시간 반영"}},"description":"관리자 장소 정규 영업시간과 예외 일정 전체 교체 요청"},"AdminMapPlaceOperatingTimeRangeRequest":{"required":["closesAt","opensAt"],"type":"object","properties":{"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"관리자 장소 운영 시간대"},"AdminMapPlaceRegularOperatingHourRequest":{"required":["closesAt","dayOfWeek","opensAt"],"type":"object","properties":{"dayOfWeek":{"type":"string","example":"MONDAY","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"관리자 요일별 정규 영업 시간대"},"AdminMapPlaceOperatingScheduleUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"exceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"message":{"type":"string"}}},"PlaceOperatingExceptionResponse":{"type":"object","properties":{"date":{"type":"string","format":"date","example":"2026-08-15"},"closed":{"type":"boolean","description":"true이면 종일 휴무이며 hours는 비어 있습니다."},"hours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingTimeRangeResponse"}}},"description":"특정 날짜의 휴무 또는 대체 영업 시간"},"PlaceOperatingTimeRangeResponse":{"type":"object","properties":{"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"하루 중 장소 운영 시간대"},"PlaceRegularOperatingHourResponse":{"type":"object","properties":{"dayOfWeek":{"type":"string","example":"MONDAY","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"요일별 정규 영업 시간대"},"AdminMapPlaceKakaoPlaceIdUpdateRequest":{"type":"object","properties":{"kakaoPlaceId":{"maxLength":50,"minLength":0,"type":"string"}}},"AdminMapPlaceKakaoPlaceIdUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"kakaoPlaceId":{"type":"string"},"message":{"type":"string"}}},"AdminPlaceInformationEvidenceReviewRequest":{"required":["verificationStatus"],"type":"object","properties":{"verificationStatus":{"type":"string","description":"관리자 검토 결과. ADMIN_VERIFIED 또는 REJECTED만 허용","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string","description":"검토 사유. REJECTED일 때 필수","nullable":true}},"description":"관리자 장소 정보 증빙 검토 요청"},"AdminMapPlaceGeocodingUpdateRequest":{"required":["address","latitude","longitude","reason"],"type":"object","properties":{"address":{"maxLength":255,"minLength":0,"type":"string"},"roadAddress":{"maxLength":255,"minLength":0,"type":"string"},"jibunAddress":{"maxLength":255,"minLength":0,"type":"string"},"postalCode":{"maxLength":20,"minLength":0,"type":"string"},"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminMapPlaceGeocodingUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"address":{"type":"string"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"message":{"type":"string"}}},"AdminMapPlaceDiscoveryStatusUpdateRequest":{"required":["discoveryStatus","reason"],"type":"object","properties":{"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"HIDDEN","enum":["VISIBLE","HIDDEN"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"중복 장소 검수 전 임시 숨김"}},"description":"관리자 장소 탐색 노출 상태 수정 요청"},"AdminMapPlaceDiscoveryStatusUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"HIDDEN","enum":["VISIBLE","HIDDEN"]},"message":{"type":"string"}},"description":"관리자 장소 탐색 노출 상태 수정 응답"},"AdminMapPlaceCoordinateUpdateRequest":{"required":["latitude","longitude"],"type":"object","properties":{"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"}}},"AdminMapPlaceCoordinateUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"message":{"type":"string"}}},"AdminMapPlaceBasicInformationUpdateRequest":{"required":["category","name","reason"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","description":"수정할 장소명","example":"진주성"},"category":{"type":"string","description":"수정할 표준 장소 카테고리","example":"CULTURAL_HERITAGE","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"장소명과 분류 오등록 정정"}},"description":"관리자 장소 기본 정보 수정 요청"},"AdminMapPlaceBasicInformationUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"modifiedAt":{"type":"string","description":"감사 로그에 기록된 기본 정보 수정 시각","format":"date-time"},"message":{"type":"string"}},"description":"관리자 장소 기본 정보 수정 응답"},"AdminPlaceRecommendationTrafficUpdateItem":{"required":["recommendationVersion"],"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v2"},"trafficPercentage":{"maximum":100,"minimum":0,"type":"integer","description":"트래픽 비율","format":"int32","example":30},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"fallbackVersion":{"type":"string","description":"비활성화된 추천 버전 요청 시 대체할 버전","nullable":true,"example":"place-rec-v1"}},"description":"수정할 추천 버전별 트래픽 비율 목록"},"AdminPlaceRecommendationTrafficUpdateRequest":{"required":["policies","reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"추천 정책 변경 사유","example":"추천 실험 v2 트래픽을 확대합니다."},"policies":{"type":"array","description":"수정할 추천 버전별 트래픽 비율 목록","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateItem"}}}},"AdminPlaceRecommendationTrafficPolicyItem":{"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v1"},"stage":{"type":"string","description":"추천 단계","example":"STABLE"},"trafficPercentage":{"type":"integer","description":"트래픽 비율","format":"int32","example":70},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"fallbackVersion":{"type":"string","description":"비활성화 시 fallback 추천 버전","nullable":true,"example":"place-rec-v1"}},"description":"현재 추천 버전별 트래픽 정책"},"AdminPlaceRecommendationTrafficUpdateResponse":{"type":"object","properties":{"defaultVersion":{"type":"string","description":"기본 추천 버전","example":"place-rec-v1"},"policies":{"type":"array","description":"현재 추천 버전별 트래픽 정책","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficPolicyItem"}},"message":{"type":"string","description":"수정 결과 메시지","example":"추천 버전 트래픽 비율을 수정했습니다."}}},"AdminNotificationReadResponse":{"type":"object","properties":{"notificationId":{"type":"integer","description":"읽음 처리된 알림 ID","format":"int64","example":1},"read":{"type":"boolean","description":"읽음 여부","example":true},"message":{"type":"string","description":"처리 메시지","example":"알림을 읽음 처리했습니다."}},"description":"관리자 알림 읽음 처리 응답"},"AdminNotificationReadAllResponse":{"type":"object","properties":{"updatedCount":{"type":"integer","description":"읽음 처리된 알림 개수","format":"int64","example":3},"message":{"type":"string","description":"처리 메시지","example":"전체 알림을 읽음 처리했습니다."}},"description":"관리자 전체 알림 읽음 처리 응답"},"VisitorVerificationReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/VisitorVerificationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"VisitorVerificationReportCorrectionPageResponse":{"type":"object","properties":{"corrections":{"type":"array","items":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"VerifiedBoostProductPageResponse":{"type":"object","properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminUserSanctionHistoryItem":{"type":"object","properties":{"historyId":{"type":"integer","description":"제재 이력 ID","format":"int64","example":1},"targetUserId":{"type":"integer","description":"대상 사용자 ID","format":"int64","example":7},"targetUsername":{"type":"string","description":"대상 사용자명","example":"blockedUser01"},"banType":{"type":"string","description":"제재 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"action":{"type":"string","description":"처리 상태","example":"APPLIED","enum":["APPLIED","RELEASED","EXPIRED"]},"reason":{"type":"string","description":"처리 사유","example":"반복적인 신고 누적"},"startedAt":{"type":"string","description":"제재 시작 시각","format":"date-time"},"endedAt":{"type":"string","description":"제재 종료 시각","format":"date-time"},"adminUserId":{"type":"integer","description":"처리 관리자 ID","format":"int64","example":1},"adminUsername":{"type":"string","description":"처리 관리자명","example":"admin"},"processedAt":{"type":"string","description":"처리 시각","format":"date-time"}},"description":"관리자 사용자 제재 이력 아이템"},"AdminUserSanctionHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/AdminUserSanctionHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 사용자 제재 이력 목록 응답"},"AdminUserSanctionStatusResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"banned":{"type":"boolean","description":"현재 제재 여부","example":true},"banType":{"type":"string","description":"제재 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"bannedAt":{"type":"string","description":"제재 시작 시각","format":"date-time"},"banExpiresAt":{"type":"string","description":"제재 종료 시각","format":"date-time"},"banReason":{"type":"string","description":"제재 사유","example":"반복적인 신고 누적"}},"description":"관리자 사용자 제재 상태 조회 응답"},"AdminRoleAssignmentTargetItem":{"type":"object","properties":{"userId":{"type":"integer","description":"역할 API에 전달할 사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"admin_operator"}},"description":"관리자 역할 부여 대상 사용자"},"AdminRoleAssignmentTargetSearchResponse":{"type":"object","properties":{"users":{"type":"array","description":"현재 페이지의 역할 부여 대상 사용자","items":{"$ref":"#/components/schemas/AdminRoleAssignmentTargetItem"}},"page":{"type":"integer","description":"현재 페이지 번호(1부터 시작)","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"검색 조건에 맞는 전체 사용자 수","format":"int64","example":12},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false}},"description":"관리자 역할 부여 대상 사용자 검색 응답"},"AdminBannedUserCounts":{"type":"object","properties":{"total":{"type":"integer","description":"현재 밴 중인 전체 사용자 수","format":"int64","example":12},"permanent":{"type":"integer","description":"현재 영구 밴 중인 사용자 수","format":"int64","example":7},"temporary":{"type":"integer","description":"현재 기간 밴 중인 사용자 수","format":"int64","example":5}},"description":"현재 밴 사용자 필터별 카운트"},"AdminBannedUserItem":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"banned":{"type":"boolean","description":"밴 처리 여부","example":true},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"bannedAt":{"type":"string","description":"밴 처리 시각","format":"date-time"},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"}},"description":"밴 유저 목록 아이템"},"AdminBannedUserResponse":{"type":"object","properties":{"users":{"type":"array","description":"현재 페이지의 밴 사용자 목록","items":{"$ref":"#/components/schemas/AdminBannedUserItem"}},"page":{"type":"integer","description":"현재 페이지 번호(1부터 시작)","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"조회 조건에 맞는 현재 밴 사용자 전체 수","format":"int64","example":12},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int64","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false},"counts":{"$ref":"#/components/schemas/AdminBannedUserCounts"}},"description":"밴 유저 목록 조회 응답"},"AdminBannedUserDetailResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"email":{"type":"string","description":"이메일","example":"blockedUser01@example.com"},"birthYear":{"type":"integer","description":"출생연도","format":"int32","example":1998},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"role":{"type":"string","description":"권한","example":"USER"},"banned":{"type":"boolean","description":"밴 여부","example":true},"bannedAt":{"type":"string","description":"밴 시각","format":"date-time"},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"},"banReason":{"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"createdAt":{"type":"string","description":"가입 시각","format":"date-time"}},"description":"밴 유저 상세 조회 응답"},"AdminTrustScoreEvidenceResponse":{"type":"object","properties":{"submittedCount":{"type":"integer","description":"신고 제출 수","format":"int64","example":12},"acceptedCount":{"type":"integer","description":"승인된 신고 수","format":"int64","example":8},"declinedCount":{"type":"integer","description":"반려된 신고 수","format":"int64","example":4},"falseReportCount":{"type":"integer","description":"허위 신고 수","format":"int64","example":3},"acceptanceRate":{"type":"number","description":"승인률","format":"double","example":66.67},"baseScore":{"type":"integer","description":"기본 점수","format":"int32","example":100},"acceptedScoreBonus":{"type":"integer","description":"승인 신고 가산점 합계","format":"int64","example":40},"falseReportScorePenalty":{"type":"integer","description":"허위 신고 감점 합계","format":"int64","example":60}},"description":"신뢰 점수 산정 근거"},"AdminTrustScoreResponse":{"type":"object","properties":{"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":7},"reporterUsername":{"type":"string","description":"신고자 username","example":"pingdom_user"},"trustScore":{"type":"integer","description":"신뢰 점수","format":"int32","example":80},"trustGrade":{"type":"string","description":"신뢰 등급","example":"HIGH","enum":["HIGH","NORMAL","LOW"]},"restricted":{"type":"boolean","description":"현재 신고 제한 여부","example":false},"restrictedUntil":{"type":"string","description":"신고 제한 종료 시각","format":"date-time","nullable":true},"restrictionReason":{"type":"string","description":"신고 제한 사유","nullable":true,"example":"FALSE_REPORT_THRESHOLD_EXCEEDED"},"evidence":{"$ref":"#/components/schemas/AdminTrustScoreEvidenceResponse"}},"description":"신고자 신뢰 등급 및 점수 근거 응답"},"AdminTrustScoreChangeHistoryItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"beforeScore":{"type":"integer","format":"int32"},"afterScore":{"type":"integer","format":"int32"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}},"AdminTrustScoreChangeHistoryResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminTrustScoreChangeHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminTrustScoreInterventionRuleResponse":{"type":"object","properties":{"rules":{"type":"array","description":"개입 규칙 목록","items":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"}}}},"AdminTrustScoreAnomalyResponse":{"type":"object","properties":{"anomalies":{"type":"array","description":"이상치 목록","items":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyItem"}},"page":{"type":"integer","description":"현재 페이지","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 개수","format":"int64","example":42},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":3}}},"ScoutProfilePageResponse":{"type":"object","properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/ScoutProfileResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 Scout 프로필 목록 응답"},"ScoutFieldReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminS3OrphanObjectReportResponse":{"type":"object","properties":{"prefix":{"type":"string"},"scanLimit":{"type":"integer","format":"int32"},"dryRun":{"type":"boolean"},"truncated":{"type":"boolean"},"dbKeyCount":{"type":"integer","format":"int64"},"s3ObjectCount":{"type":"integer","format":"int64"},"orphanObjectCount":{"type":"integer","format":"int64"},"orphanKeys":{"type":"array","items":{"type":"string"}}}},"AdminReservationPageResponse":{"type":"object","properties":{"reservations":{"type":"array","items":{"$ref":"#/components/schemas/AdminReservationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"ReportedUsersItem":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"reporterUsername":{"type":"string"},"reportedImageId":{"type":"integer","format":"int64"},"reportedUserId":{"type":"integer","format":"int64"},"reason":{"type":"string"}}},"ReportedUsersResponse":{"type":"object","properties":{"users":{"type":"array","items":{"$ref":"#/components/schemas/ReportedUsersItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminReportAppealItem":{"type":"object","properties":{"appealId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"appellantUserId":{"type":"integer","format":"int64"},"appellantUsername":{"type":"string"},"targetUserId":{"type":"integer","format":"int64"},"reason":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]},"adminUserId":{"type":"integer","format":"int64"},"adminReason":{"type":"string"},"processedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"AdminReportAppealResponse":{"type":"object","properties":{"appeals":{"type":"array","items":{"$ref":"#/components/schemas/AdminReportAppealItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PrivacyProcessingHistoryItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"subjectUserId":{"type":"integer","format":"int64"},"actorUserId":{"type":"integer","format":"int64"},"actorType":{"type":"string","enum":["USER","SYSTEM","ADMIN"]},"action":{"type":"string","enum":["EXPORT_REQUESTED","WITHDRAWAL_REQUESTED","ANONYMIZED","DELETED"]},"details":{"type":"string"},"requestId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"PrivacyProcessingHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/PrivacyProcessingHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"S3OrphanCandidate":{"type":"object","properties":{"key":{"type":"string"},"reason":{"type":"string"}}},"S3OrphanReport":{"type":"object","properties":{"reportId":{"type":"string"},"status":{"type":"string"},"errorMessage":{"type":"string"},"deleteCandidates":{"type":"array","items":{"$ref":"#/components/schemas/S3OrphanCandidate"}},"dbKeyCount":{"type":"integer","format":"int64"},"s3KeyCount":{"type":"integer","format":"int64"},"deleteCandidateCount":{"type":"integer","format":"int64"},"generatedAt":{"type":"string","format":"date-time"},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceItem":{"required":["level"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"category":{"type":"string","description":"일반 장소 카테고리. touristCategories와 별도 기준이며 미분류 장소는 null입니다.","nullable":true,"example":"OTHER","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"categoryName":{"type":"string","description":"화면 표시용 일반 장소 카테고리명. category가 없으면 미분류입니다.","example":"기타","enum":["음식점","음악","팝업","패션","뷰티","전시","카페","문화재","기타","미분류"]},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","description":"외국인 관광 관심사 분류. 일반 장소 category 필터와는 별도 기준입니다.","items":{"type":"string","description":"외국인 관광 관심사 분류. 일반 장소 category 필터와는 별도 기준입니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"level":{"minimum":0,"type":"integer","description":"장소 성장 레벨. 10 이상이면 관리자 지도에서 불꽃 마커로 표시할 수 있습니다.","format":"int32","example":5},"placeGrowth":{"$ref":"#/components/schemas/PlaceGrowthSnapshot"}}},"AdminMapPlaceResponse":{"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"minimum":1,"type":"integer","description":"전체 페이지 수. 조회 결과가 없어도 1을 반환합니다.","format":"int64","example":1},"hasNext":{"type":"boolean"}},"description":"관리자 장소 목록 조회 응답"},"PlaceGrowthSnapshot":{"type":"object","properties":{"photoCount":{"type":"integer","format":"int64"},"level":{"type":"integer","format":"int32"},"currentLevelMinPhotoCount":{"type":"integer","format":"int64"},"nextLevelMinPhotoCount":{"type":"integer","format":"int64"},"progressPercent":{"type":"integer","format":"int32"}}},"PlaceInformationReverificationListResponse":{"type":"object","properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDetailResponse":{"required":["imageUrl","level"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"imageUrl":{"type":"string","description":"장소 목록·상세에서 공통으로 사용하는 canonical 대표 이미지 URL입니다. 대표 이미지가 없으면 null입니다.","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"category":{"type":"string","description":"일반 장소 카테고리. touristCategories와 별도 기준이며 미분류 장소는 null입니다.","nullable":true,"example":"OTHER","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"categoryName":{"type":"string","description":"화면 표시용 일반 장소 카테고리명. category가 없으면 미분류입니다.","example":"기타","enum":["음식점","음악","팝업","패션","뷰티","전시","카페","문화재","기타","미분류"]},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","description":"외국인 관광 관심사 분류. 일반 장소 category와는 별도 기준입니다.","items":{"type":"string","description":"외국인 관광 관심사 분류. 일반 장소 category와는 별도 기준입니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"username":{"type":"string"},"sortParam":{"type":"string","enum":["LATEST","OLDEST","MOST_LIKED"]},"postCount":{"type":"integer","format":"int32"},"level":{"minimum":0,"type":"integer","description":"장소 성장 레벨. 10 이상이면 관리자 지도에서 불꽃 마커로 표시할 수 있습니다.","format":"int32","example":5},"placeGrowth":{"$ref":"#/components/schemas/AdminMapPlaceGrowthResponse"},"posts":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceImageItem"}}}},"AdminMapPlaceGrowthResponse":{"type":"object","properties":{"photoCount":{"type":"integer","description":"장소 성장에 반영된 노출 게시글 사진 수","format":"int64","example":10},"hiddenPhotoCount":{"type":"integer","description":"장소 성장에 반영되지 않는 숨김 게시글 사진 수","format":"int64","example":1},"level":{"type":"integer","format":"int32"},"currentLevelMinPhotoCount":{"type":"integer","format":"int64"},"nextLevelMinPhotoCount":{"type":"integer","format":"int64"},"progressPercent":{"type":"integer","format":"int32"}},"description":"관리자 장소 상세 성장 상태"},"AdminMapPlaceImageItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"thumbnailUrl":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"userId":{"type":"integer","format":"int64"},"username":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"likeCount":{"type":"integer","format":"int64"},"visibilityStatus":{"type":"string","description":"일반 사용자 기준 게시글 노출 상태","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"hiddenReason":{"type":"string","description":"게시글이 숨김 처리된 사유. 노출 중인 게시글은 null","nullable":true,"example":"ADMIN_HIDDEN"}}},"AdminPlaceInformationEvidenceResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"evidences":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceItem"}}},"description":"관리자 장소 정보 증빙 목록 응답"},"AdminPlaceRecommendationExplanationItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":1},"placeName":{"type":"string","description":"장소명","example":"진주성"},"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":21},"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v2"},"recommendationStage":{"type":"string","description":"추천 stage","example":"EXPERIMENT","enum":["STABLE","EXPERIMENTAL"]},"ranking":{"type":"integer","description":"노출 순위","format":"int32","example":1},"source":{"type":"string","description":"후보 소스","example":"PERSONALIZED","enum":["PERSONAL","POPULAR","FRESH","GEO","FALLBACK"]},"distanceMeters":{"type":"integer","description":"거리(m)","format":"int64","example":128},"geoScore":{"type":"number","description":"geo score","format":"double","example":0.91},"personalScore":{"type":"number","description":"personal score","format":"double","example":0.42},"qualityScore":{"type":"number","description":"quality score","format":"double","example":0.37},"engagementScore":{"type":"number","description":"engagement score","format":"double","example":0.25},"conversionScore":{"type":"number","description":"conversion score","format":"double","example":0.14},"explorationScore":{"type":"number","description":"exploration score","format":"double","example":0.08},"freshnessScore":{"type":"number","description":"freshness score","format":"double","example":0.19},"trustScore":{"type":"number","description":"검증 제보자 신뢰도 기반 score","format":"double","example":0.82},"contextScore":{"type":"number","description":"K-컬처 관심사와 현재 여행 맥락 기반 score","format":"double","example":0.25},"benefitScore":{"type":"number","description":"현재 이용 가능한 혜택 기반 boost","format":"double","example":0.05},"availabilityScore":{"type":"number","description":"예약 가능 시간 기반 boost","format":"double","example":0.05},"boostScore":{"type":"number","description":"Verified Boost 집행 기반 score","format":"double","example":0.08},"finalScore":{"type":"number","description":"최종 score","format":"double","example":0.74},"createdAt":{"type":"string","description":"로그 생성 시각","format":"date-time"}},"description":"관리자 추천 설명 항목"},"AdminPlaceRecommendationExplanationResponse":{"type":"object","properties":{"requestId":{"type":"string","description":"추천 요청 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"items":{"type":"array","description":"관리자 추천 설명 항목","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationExplanationItem"}}},"description":"관리자 추천 설명 조회 응답"},"AdminPlaceRecommendationMetricItem":{"type":"object","properties":{"id":{"type":"integer","description":"장소 ID","format":"int64","example":1},"name":{"type":"string","description":"장소명","example":"진주성"},"address":{"type":"string","description":"장소 주소","example":"경상남도 진주시 남강로 626"},"photoCount":{"type":"integer","description":"장소 사진 수","format":"int64","example":12},"exposureCount":{"type":"integer","description":"추천 노출 수","format":"int64","example":120},"clickCount":{"type":"integer","description":"추천 클릭 수","format":"int64","example":18},"rawCtr":{"type":"number","description":"원본 CTR","format":"double","example":0.15},"smoothedCtr":{"type":"number","description":"랭킹 기준 smoothed CTR","format":"double","example":0.13},"bookmarkConversionCount":{"type":"integer","description":"북마크 전환 수","format":"int64","example":4},"likeConversionCount":{"type":"integer","description":"좋아요 전환 수","format":"int64","example":6},"bookmarkConversionRate":{"type":"number","description":"북마크 전환율","format":"double","example":0.03},"likeConversionRate":{"type":"number","description":"좋아요 전환율","format":"double","example":0.05},"totalConversionRate":{"type":"number","description":"전체 전환율","format":"double","example":0.08},"snapshotUpdatedAt":{"type":"string","description":"추천 snapshot 최종 갱신 시각","format":"date-time"}},"description":"관리자 추천 성과 항목"},"AdminPlaceRecommendationMetricsResponse":{"type":"object","properties":{"metrics":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricItem"}},"sortBy":{"type":"string","enum":["SMOOTHED_CTR","RAW_CTR","BOOKMARK_CONVERSION","LIKE_CONVERSION","TOTAL_CONVERSION","EXPOSURE","CLICK","UPDATED_AT"]},"recommendationVersion":{"type":"string"},"days":{"type":"integer","format":"int32"},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}},"description":"관리자 추천 성과 목록 응답"},"AdminPlaceRecommendationMetricSummary":{"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v1"},"exposureCount":{"type":"integer","description":"추천 노출 수","format":"int64","example":120},"clickCount":{"type":"integer","description":"추천 클릭 수","format":"int64","example":18},"rawCtr":{"type":"number","description":"원본 CTR","format":"double","example":0.15},"smoothedCtr":{"type":"number","description":"smoothed CTR","format":"double","example":0.13},"bookmarkConversionCount":{"type":"integer","description":"북마크 전환 수","format":"int64","example":4},"likeConversionCount":{"type":"integer","description":"좋아요 전환 수","format":"int64","example":6},"bookmarkConversionRate":{"type":"number","description":"북마크 전환율","format":"double","example":0.03},"likeConversionRate":{"type":"number","description":"좋아요 전환율","format":"double","example":0.05},"totalConversionRate":{"type":"number","description":"전체 전환율","format":"double","example":0.08}},"description":"관리자 추천 성과 요약"},"AdminPlaceRecommendationMetricsCompareResponse":{"type":"object","properties":{"baselineVersion":{"type":"string","description":"기준 추천 버전","example":"place-rec-v1"},"targetVersion":{"type":"string","description":"비교 대상 추천 버전","example":"place-rec-v2"},"days":{"type":"integer","description":"최근 N일 기준 필터","format":"int32","example":7},"keyword":{"type":"string","description":"장소 검색 키워드","example":"진주"},"baseline":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"},"target":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"},"delta":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"}},"description":"관리자 추천 버전 성과 비교 응답"},"AdminPlaceMergeHistoryItem":{"type":"object","properties":{"historyId":{"type":"integer","format":"int64"},"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"adminUserId":{"type":"integer","format":"int64"},"restored":{"type":"boolean"},"mergedAt":{"type":"string","format":"date-time"},"restoredAt":{"type":"string","format":"date-time"}}},"AdminPlaceMergeHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMergeHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDuplicateGroupItem":{"type":"object","properties":{"representativePlaceId":{"type":"integer","format":"int64"},"duplicatePlaceIds":{"type":"array","items":{"type":"integer","format":"int64"}},"reasons":{"type":"array","items":{"type":"string"}}}},"AdminMapPlaceDuplicateResponse":{"type":"object","properties":{"groups":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateGroupItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDuplicateCandidateItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"kakaoPlaceId":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"photoCount":{"type":"integer","format":"int64"},"reason":{"type":"string"},"distanceMeters":{"type":"number","format":"double"}}},"AdminMapPlaceDuplicateDetailResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"kakaoPlaceId":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"photoCount":{"type":"integer","format":"int64"},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateCandidateItem"}}}},"AdminPlaceDuplicateCandidateListResponse":{"type":"object","properties":{"candidates":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminPlaceReviewDeletionRequestPageResponse":{"type":"object","properties":{"deletionRequests":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PlaceInformationReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"장소 정보 신고 페이지 응답"},"AdminPlaceEventListItem":{"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"placeAddress":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"publicationStatus":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminPlaceEventListResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceEventListItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminOutboxEventResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AdminOutboxEventItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 Outbox 이벤트 운영 조회 응답"},"AdminNotificationItem":{"type":"object","properties":{"notificationId":{"type":"integer","description":"알림 ID","format":"int64","example":1},"userId":{"type":"integer","description":"수신 관리자 ID","format":"int64","example":10},"type":{"type":"string","description":"관리자 알림 유형: ADMIN_REPORT_RECEIVED, ADMIN_REPORT_PROCESSED, ADMIN_DUPLICATE_PLACE_DETECTED, ADMIN_USER_SANCTION","example":"ADMIN_REPORT_RECEIVED","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"title":{"type":"string","description":"알림 제목","example":"신고 접수 알림"},"body":{"type":"string","description":"알림 내용","example":"신고 ID 30 접수가 게시글 ID 12에 등록되었습니다."},"token":{"type":"string","description":"관리 화면 연결 token. report:{reportId}, place:{placeId}, sanction:{sanctionId} 형식","example":"report:30"},"read":{"type":"boolean","description":"읽음 여부","example":false},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"}},"description":"관리자 알림 아이템"},"AdminNotificationResponse":{"type":"object","properties":{"notifications":{"type":"array","description":"관리자 알림 목록","items":{"$ref":"#/components/schemas/AdminNotificationItem"}},"page":{"type":"integer","description":"현재 페이지 번호","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 알림 개수","format":"int64","example":1},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false}},"description":"관리자 알림 목록 응답"},"AdminNotificationUnreadCountResponse":{"type":"object","properties":{"unreadCount":{"type":"integer","description":"미확인 알림 개수","format":"int64","example":3}},"description":"관리자 미확인 알림 개수 응답"},"AdminNotificationDeliveryItem":{"type":"object","properties":{"deliveryId":{"type":"integer","description":"발송 결과 ID","format":"int64","example":1},"channel":{"type":"string","description":"발송 채널","example":"FCM","enum":["FCM","EMAIL"]},"status":{"type":"string","description":"발송 상태","example":"SUCCEEDED","enum":["SUCCEEDED","FAILED","RETRY_SCHEDULED","FINAL_FAILED"]},"userId":{"type":"integer","description":"수신 사용자 ID","format":"int64","example":10},"notificationId":{"type":"integer","description":"인앱 알림 ID","format":"int64","example":100},"notificationType":{"type":"string","description":"인앱 알림 유형","example":"NEW_LIKE"},"outboxEventId":{"type":"string","description":"Outbox 이벤트 ID"},"outboxEventType":{"type":"string","description":"Outbox 이벤트 유형","example":"MAP_IMAGE_LIKED"},"providerMessageId":{"type":"string","description":"외부 발송 provider message id"},"providerErrorCode":{"type":"string","description":"외부 발송 provider error code"},"errorCode":{"type":"string","description":"내부 실패 분류 코드"},"failureReason":{"type":"string","description":"실패 사유"},"retryable":{"type":"boolean","description":"재시도 가능 여부","example":true},"attemptCount":{"type":"integer","description":"발송 시도 횟수","format":"int32","example":1},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}},"description":"관리자 알림 발송 결과 아이템"},"AdminNotificationDeliveryResponse":{"type":"object","properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/AdminNotificationDeliveryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 알림 발송 결과 목록 응답"},"AdminMerchantPlaceApplicationListItemResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"maskedBusinessRegistrationNumber":{"type":"string"},"merchantDisplayName":{"type":"string"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminMerchantPlaceApplicationPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationListItemResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMerchantPlaceApplicationAttachmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"documentType":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"uploadedAt":{"type":"string","format":"date-time"},"retentionExpiresAt":{"type":"string","format":"date-time"},"displayOrder":{"type":"integer","format":"int32"}}},"AdminMerchantPlaceApplicationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"businessRegistrationNumber":{"type":"string"},"merchantDisplayName":{"type":"string"},"merchantContactEmail":{"type":"string"},"merchantDescription":{"type":"string"},"merchantContactPhone":{"type":"string"},"newPlace":{"$ref":"#/components/schemas/MerchantPlaceApplicationNewPlaceResponse"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"type":"string"},"reviewReason":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"version":{"type":"integer","format":"int64"},"submissionVersion":{"type":"integer","format":"int64"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationAttachmentResponse"}}}},"MerchantOwnerProfilePageResponse":{"type":"object","properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminDashboardMetricWindowResponse":{"type":"object","properties":{"period":{"type":"string","description":"집계 기간 코드","example":"TODAY","enum":["TODAY","LAST_7_DAYS"]},"startedAt":{"type":"string","description":"집계 시작 시각","format":"date-time"},"endedAt":{"type":"string","description":"집계 종료 시각","format":"date-time"},"placeRegistrationCount":{"type":"integer","description":"기간 내 장소 등록 수","format":"int64","example":3},"postRegistrationCount":{"type":"integer","description":"기간 내 게시글 등록 수","format":"int64","example":7}},"description":"관리자 대시보드 기간별 운영 변화 지표"},"AdminDashboardOperationalMetricsResponse":{"type":"object","properties":{"today":{"$ref":"#/components/schemas/AdminDashboardMetricWindowResponse"},"last7Days":{"$ref":"#/components/schemas/AdminDashboardMetricWindowResponse"},"duplicatePlaceGroupCount":{"type":"integer","description":"중복 장소 후보 그룹 수","format":"int64","example":2},"expiringBannedUserCount":{"type":"integer","description":"7일 이내 임시 밴 만료 예정 사용자 수","format":"int64","example":4},"missingLocationPlaceCount":{"type":"integer","description":"location 좌표 정보가 누락된 장소 수","format":"int64","example":1},"expiringBanUntil":{"type":"string","description":"밴 만료 예정 집계 종료 시각","format":"date-time"},"collectedAt":{"type":"string","description":"지표 집계 기준 시각","format":"date-time"}},"description":"관리자 대시보드 추가 운영 지표"},"AdminDashboardSummaryResponse":{"type":"object","properties":{"placeCount":{"type":"integer","description":"전체 장소 수","format":"int64","example":44},"postCount":{"type":"integer","description":"전체 게시글 수","format":"int64","example":58},"pendingReportCount":{"type":"integer","description":"처리 대기 신고 수","format":"int64","example":5},"bannedUserCount":{"type":"integer","description":"현재 밴 사용자 수","format":"int64","example":6},"operationalMetrics":{"$ref":"#/components/schemas/AdminDashboardOperationalMetricsResponse"}},"description":"관리자 대시보드 전체 운영 현황 요약"},"AdminDashboardRecentActivitiesResponse":{"type":"object","properties":{"places":{"type":"array","description":"최근 장소 등록 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentPlaceItem"}},"posts":{"type":"array","description":"최근 게시글 등록 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentPostItem"}},"reports":{"type":"array","description":"최근 신고 처리 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentReportItem"}},"userSanctions":{"type":"array","description":"최근 사용자 밴 및 밴 해제 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentUserSanctionItem"}}},"description":"관리자 대시보드 최근 운영 활동"},"AdminDashboardRecentPlaceItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":10},"name":{"type":"string","description":"장소명","example":"핑덤 카페"},"address":{"type":"string","description":"주소","example":"서울특별시 중구 세종대로 110"},"userId":{"type":"integer","description":"등록 사용자 ID","format":"int64","example":3},"registrant":{"type":"string","description":"등록자명","example":"pingdom_user"},"createdAt":{"type":"string","description":"장소 등록일","format":"date-time"}},"description":"관리자 대시보드 최근 장소 등록 항목"},"AdminDashboardRecentPostItem":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":10},"title":{"type":"string","description":"게시글 제목","example":"야경이 좋은 장소"},"userId":{"type":"integer","description":"작성자 ID","format":"int64","example":3},"username":{"type":"string","description":"작성자명","example":"pingdom_user"},"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":7},"placeName":{"type":"string","description":"장소명","example":"핑덤 카페"},"createdAt":{"type":"string","description":"생성일","format":"date-time"}},"description":"관리자 대시보드 최근 게시글 등록 항목"},"AdminDashboardRecentReportItem":{"type":"object","properties":{"reportId":{"type":"integer","description":"신고 ID","format":"int64","example":10},"reportedImageId":{"type":"integer","description":"신고 대상 게시글 ID","format":"int64","example":22},"title":{"type":"string","description":"신고 대상 게시글 제목","example":"야경이 좋은 장소"},"status":{"type":"string","description":"신고 상태","example":"ACCEPTED","enum":["PENDING","ACCEPTED","DECLINED","RESTORED"]},"processedAt":{"type":"string","description":"처리일","format":"date-time"},"createdAt":{"type":"string","description":"신고 생성일","format":"date-time"}},"description":"관리자 대시보드 최근 신고 처리 항목"},"AdminDashboardRecentUserSanctionItem":{"type":"object","properties":{"sanctionId":{"type":"integer","description":"제재 이력 ID","format":"int64","example":10},"targetUserId":{"type":"integer","description":"대상 사용자 ID","format":"int64","example":5},"targetUsername":{"type":"string","description":"대상 사용자명","example":"reported_user"},"action":{"type":"string","description":"제재 처리 유형","example":"APPLIED","enum":["APPLIED","RELEASED","EXPIRED"]},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"reason":{"type":"string","description":"처리 사유","example":"부적절한 게시글입니다."},"processedAt":{"type":"string","description":"처리일","format":"date-time"}},"description":"관리자 대시보드 최근 사용자 제재 항목"},"AdminDashboardPendingItem":{"type":"object","properties":{"type":{"type":"string","description":"처리 필요 항목 유형","example":"POST_REPORT","enum":["POST_REPORT","MERCHANT_PLACE_APPLICATION","POST_REPORT","MERCHANT_PLACE_APPLICATION"]},"targetId":{"type":"integer","description":"처리 항목 ID. POST_REPORT에서는 신고 ID와 동일","format":"int64","example":30},"reportId":{"type":"integer","description":"신고 ID. 신고 처리 화면으로 이동할 때 사용","format":"int64","example":30},"postId":{"type":"integer","description":"신고 대상 게시글 ID. 게시글 상세 화면으로 이동할 때 사용","format":"int64","nullable":true,"example":22},"title":{"type":"string","description":"처리 대상 제목","example":"야경이 좋은 장소"},"status":{"type":"string","description":"처리 대상 상태","example":"PENDING"},"createdAt":{"type":"string","description":"생성일","format":"date-time"},"navigationPath":{"type":"string","description":"관리자 화면 이동 경로. 통합 신청 항목에서만 제공","nullable":true,"example":"/admin/merchant-place-applications/12"}},"description":"관리자 대시보드 처리 필요 항목"},"AdminDashboardPendingItemsResponse":{"type":"object","properties":{"items":{"type":"array","description":"처리 필요 항목","items":{"$ref":"#/components/schemas/AdminDashboardPendingItem"}},"totalCount":{"type":"integer","description":"필터링 전 전체 PENDING 처리 필요 항목 수","format":"int64","example":8}},"description":"관리자 대시보드 처리 필요 항목 목록"},"AdminCommunityPostItem":{"type":"object","properties":{"postId":{"type":"integer","format":"int64"},"categoryId":{"type":"string"},"title":{"type":"string"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 글 목록 항목"},"AdminCommunityPostPageResponse":{"type":"object","properties":{"posts":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityPostItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminCommunityPostResponse":{"type":"object","properties":{"postId":{"type":"integer","format":"int64"},"categoryId":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"places":{"type":"array","items":{"$ref":"#/components/schemas/Place"}}}},"Place":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"deleted":{"type":"boolean"}}},"AdminCommunityCommentItem":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"content":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 댓글 목록 항목"},"AdminCommunityCommentPageResponse":{"type":"object","properties":{"comments":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityCommentItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminCommunityCommentResponse":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"content":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"AdminCommunityReportItem":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"targetHidden":{"type":"boolean"},"reporterUserId":{"type":"integer","format":"int64"},"reason":{"type":"string","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"createdAt":{"type":"string","format":"date-time"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 목록 항목"},"AdminCommunityReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityReportItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 커뮤니티 신고 목록 응답"},"AdminCommunityReportResponse":{"required":["postId"],"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"postId":{"type":"integer","description":"원문 글 ID. POST는 targetId와 같고 COMMENT는 대상 댓글이 속한 글 ID입니다. 신고 대상과 댓글의 원문 관계는 DB 제약으로 보장되며, 숨김 여부와 관계없이 반환합니다.","format":"int64","example":101},"targetHidden":{"type":"boolean"},"reporterUserId":{"type":"integer","format":"int64"},"reason":{"type":"string","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"description":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"createdAt":{"type":"string","format":"date-time"},"processedByAdminUserId":{"type":"integer","format":"int64"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 상세 응답"},"AdminAuditLogItem":{"type":"object","properties":{"auditLogId":{"type":"integer","description":"감사 로그 ID","format":"int64","example":1},"actorUserId":{"type":"integer","description":"작업 관리자 ID","format":"int64","example":1},"actorUsername":{"type":"string","description":"작업 관리자명","example":"admin"},"action":{"type":"string","description":"작업 유형","example":"USER_BAN_APPLIED","enum":["ADMIN_ROLE_ASSIGNED","ADMIN_ROLE_REVOKED","USER_BAN_APPLIED","USER_BAN_RELEASED","REPORT_ACCEPTED","REPORT_DECLINED","COMMUNITY_REPORT_ACCEPTED","COMMUNITY_REPORT_DECLINED","POST_DELETED","POST_HIDDEN","POST_RESTORED","APPEAL_APPROVED","APPEAL_REJECTED","PLACE_DELETED","PLACE_BASIC_INFORMATION_UPDATED","PLACE_KAKAO_PLACE_ID_UPDATED","PLACE_GEOCODING_UPDATED","PLACE_TOURIST_INFO_UPDATED","PLACE_INFORMATION_EVIDENCE_UPDATED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_INFORMATION_REVERIFICATION_COMPLETED","PLACE_INFORMATION_REVERIFICATION_CANCELED","PLACE_INFORMATION_REVERIFICATION_EXPIRED","VISITOR_VERIFICATION_REPORT_REVIEWED","VISITOR_VERIFICATION_REPORT_CORRECTION_REVIEWED","SCOUT_FIELD_REPORT_REVIEWED","SCOUT_PROFILE_REVIEWED","SCOUT_ACTIVITY_ELIGIBILITY_REVIEWED","PLACE_DISCOVERY_STATUS_UPDATED","PLACE_OPERATING_STATUS_UPDATED","PLACE_OPERATING_SCHEDULE_UPDATED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_EVENT_CREATED","PLACE_EVENT_UPDATED","PLACE_EVENT_PUBLISHED","PLACE_EVENT_CANCELLED","PLACE_RECOMMENDATION_TRAFFIC_UPDATED","PLACE_RECOMMENDATION_KILL_SWITCH_UPDATED","TRUST_SCORE_ANOMALY_RESOLVED","TRUST_SCORE_INTERVENTION_RULE_CREATED","TRUST_SCORE_INTERVENTION_RULE_UPDATED","TRUST_SCORE_INTERVENTION_RULE_ENABLED","TRUST_SCORE_INTERVENTION_RULE_DISABLED","TRUST_SCORE_INTERVENTION_EVALUATED","NOTIFICATION_READ","NOTIFICATION_READ_ALL","PLACE_DUPLICATE_CONFIRMED","PLACE_DUPLICATE_REJECTED","PLACE_MERGED","MERCHANT_OWNER_APPROVED","MERCHANT_OWNER_REJECTED","MERCHANT_OWNER_REVOKED","MERCHANT_OWNER_PLACES_UPDATED","MERCHANT_ONBOARDING_UPDATED","MERCHANT_OPERATIONAL_QUALITY_UPDATED","MERCHANT_VERIFICATION_REVIEWED","MERCHANT_VERIFICATION_VIEWED","MERCHANT_PLACE_CLAIM_ATTACHMENT_VIEWED","MERCHANT_PLACE_CLAIM_APPROVED","MERCHANT_PLACE_CLAIM_REJECTED","MERCHANT_PLACE_APPLICATION_APPROVED","MERCHANT_PLACE_APPLICATION_REJECTED","MERCHANT_PLACE_APPLICATION_VIEWED","MERCHANT_PLACE_APPLICATION_ATTACHMENT_VIEWED","OUTBOX_EVENT_RETRIED","AD_CREATED","AD_DELETED","RESERVATION_CONFIRMED","RESERVATION_REJECTED"]},"targetType":{"type":"string","description":"대상 유형","example":"USER","enum":["USER","REPORT","COMMUNITY_REPORT","APPEAL","POST","PLACE","PLACE_DUPLICATE_CANDIDATE","PLACE_INFORMATION_EVIDENCE","PLACE_INFORMATION_REPORT","PLACE_INFORMATION_DISPUTE","PLACE_INFORMATION_REVERIFICATION","VISITOR_VERIFICATION_REPORT","VISITOR_VERIFICATION_REPORT_CORRECTION","SCOUT_FIELD_REPORT","SCOUT_PROFILE","SCOUT_ACTIVITY_ELIGIBILITY","PLACE_OPERATING_NOTICE","PLACE_EVENT","TRUST_SCORE_ANOMALY","TRUST_SCORE_INTERVENTION_RULE","NOTIFICATION","OUTBOX_EVENT","MERCHANT_OWNER","MERCHANT_VERIFICATION","MERCHANT_PLACE_CLAIM_ATTACHMENT","MERCHANT_PLACE_CLAIM","MERCHANT_PLACE_APPLICATION","MERCHANT_PLACE_APPLICATION_ATTACHMENT","AD","RESERVATION"]},"targetId":{"type":"string","description":"대상 ID","example":"7"},"reason":{"type":"string","description":"작업 사유","example":"반복적인 신고 누적"},"beforeState":{"type":"string","description":"작업 전 상태 JSON"},"afterState":{"type":"string","description":"작업 후 상태 JSON"},"requestId":{"type":"string","description":"요청 ID","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"createdAt":{"type":"string","description":"감사 로그 생성 시각","format":"date-time"}},"description":"관리자 감사 로그 아이템"},"AdminAuditLogResponse":{"type":"object","properties":{"auditLogs":{"type":"array","items":{"$ref":"#/components/schemas/AdminAuditLogItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 감사 로그 목록 응답"},"AdminRoleAssignmentRevokeRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"역할을 회수하는 사유","example":"담당 업무 변경"}},"description":"관리자 역할 회수 요청"},"AdminS3OrphanDeleteRequest":{"required":["reportId"],"type":"object","properties":{"reportId":{"type":"string"},"keys":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"confirmed":{"type":"boolean"}}},"S3OrphanDeleteFailure":{"type":"object","properties":{"key":{"type":"string"},"reason":{"type":"string"}}},"S3OrphanDeleteResult":{"type":"object","properties":{"requestedKeyCount":{"type":"integer","format":"int32"},"deletedKeyCount":{"type":"integer","format":"int32"},"failedKeyCount":{"type":"integer","format":"int32"},"deletedKeys":{"type":"array","items":{"type":"string"}},"failedKeys":{"type":"array","items":{"$ref":"#/components/schemas/S3OrphanDeleteFailure"}}}},"ValidationErrorResponse":{"required":["code","errors","message"],"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string","example":"VALIDATION_FAILED"},"errors":{"type":"object","additionalProperties":{"type":"string"}}},"description":"필드 검증 오류 응답"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}} \ No newline at end of file +{"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://127.0.0.1:64060","description":"Generated server url"}],"tags":[{"name":"대시보드","description":"운영 현황, 최근 활동 및 처리 대기 항목"},{"name":"회원·권한","description":"회원 제재 및 관리자 역할 관리"},{"name":"사업자 관리","description":"사업자 심사 및 연결 장소 관리"},{"name":"장소 등록 심사","description":"장소 등록 신청과 증빙 확인 및 심사"},{"name":"장소 조회","description":"운영 대상 장소 목록 및 상세 조회"},{"name":"장소 정보·품질","description":"장소 정보 보정, 근거 검토 및 노출 상태 관리"},{"name":"중복·추천 관리","description":"중복 장소 검토·병합 및 추천 운영"},{"name":"제보·재검증","description":"장소 정보 제보 심사 및 재검증 요청 관리"},{"name":"행사·운영 공지","description":"행사 발행 및 운영 공지 관리"},{"name":"리뷰 삭제 심사","description":"장소 리뷰 삭제 요청 확인 및 심사"},{"name":"커뮤니티 관리","description":"게시글과 댓글 운영 조회"},{"name":"신고·이의신청","description":"신고 및 이의신청 검토·처리, 신고 콘텐츠 삭제"},{"name":"신뢰 점수","description":"신뢰 점수·이상 징후 및 개입 규칙 관리"},{"name":"방문 인증·스카우트","description":"방문 보고 심사 및 스카우트 자격 관리"},{"name":"예약","description":"예약 및 처리 이력 조회"},{"name":"Verified Boost","description":"Verified Boost 상품 등록 및 활성 상태 관리"},{"name":"알림·발송 이력","description":"운영 알림 확인 및 발송 이력 조회"},{"name":"감사·개인정보 처리 이력","description":"관리자 작업 감사 및 개인정보 처리 이력 조회"},{"name":"Outbox·스토리지 운영","description":"Outbox 재처리 및 스토리지 고아 객체 관리"}],"paths":{"/admin/trust-score/intervention-rules/{ruleId}":{"put":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 수정","description":"관리자가 Trust Score 개입 규칙 내용을 수정합니다.","operationId":"updateRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/places":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 연결 장소 및 운영 품질 조회","operationId":"listPlaces_1","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOwnerPlaceResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 장소 연결 변경","description":"현재 연결 장소를 요청의 placeIds 전체로 교체합니다. 빈 목록은 모든 장소 연결을 해제합니다. Merchant Owner 승인과는 별도 요청 및 별도 트랜잭션입니다.","operationId":"replacePlaces","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/places/{placeId}/quality":{"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 장소 운영 품질 지표 변경","operationId":"updateOperationalQuality","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceQualityUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/onboarding":{"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 온보딩 완료도 변경","operationId":"updateOnboarding","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOnboardingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/{reportId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 심사","operationId":"review","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/corrections/{correctionId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 정정 심사","operationId":"reviewCorrection","parameters":[{"name":"correctionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionReviewRequest"}}},"required":true},"responses":{"200":{"description":"제보 정정 심사 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionResponse"}}}},"400":{"description":"심사 요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"제보 정정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"이미 심사된 정정 또는 활성 제보 충돌","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관리자 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products":{"get":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 목록 조회","operationId":"list_1","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 생성","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}/deactivate":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 비활성화","operationId":"deactivate","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}/activate":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 활성화","operationId":"activate","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/roles":{"get":{"tags":["회원·권한"],"summary":"관리자 역할 이력 조회","operationId":"list_2","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"대상 관리자 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["회원·권한"],"summary":"관리자 역할 부여","operationId":"assign","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentRequest"}}},"required":true},"responses":{"400":{"description":"역할 할당 요청 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"이미 활성 역할이 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"부여 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"대상 관리자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}/interventions/evaluate":{"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 수동 평가","description":"관리자가 신고자의 현재 Trust Score 정책에 활성 개입 규칙을 수동 평가합니다.","operationId":"evaluateReporter","parameters":[{"name":"reporterUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionEvaluationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules":{"get":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 목록 조회","description":"관리자가 Trust Score 개입 규칙 목록을 우선순위 순서로 조회합니다.","operationId":"listRules","parameters":[{"name":"enabledOnly","in":"query","description":"활성화된 규칙만 조회할지 여부","required":false,"schema":{"type":"boolean","default":false},"example":false}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 생성","description":"관리자가 Trust Score 개입 규칙을 생성합니다.","operationId":"createRule","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleRequest"}}},"required":true},"responses":{"200":{"description":"Trust Score 개입 규칙 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"},"example":{"id":1,"ruleName":"low trust temporary restriction","triggerType":"FALSE_REPORT_COUNT","actionType":"TEMPORARY_RESTRICT","enabled":true,"minTrustScore":0,"maxTrustScore":60,"minSubmittedCount":3,"minFalseReportCount":3,"durationDays":7,"priority":10,"reason":"허위 신고 누적 사용자 제한"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/batch/recalculate":{"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 일괄 재계산","operationId":"recalculateTrustScores","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreBatchResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/suspend":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 정지","operationId":"suspend","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/revoke":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 회수","operationId":"revoke","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/suspend":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 정지","operationId":"suspendEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/revoke":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 회수","operationId":"revokeEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/grant":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 부여","operationId":"grantEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityGrantRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/approve":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 승인","operationId":"approve","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"Scout 프로필 승인 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"409":{"description":"현재 프로필 상태에서 승인 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"403":{"description":"Scout 심사 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-field-reports/{reportId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 현장 제보 심사","operationId":"review_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"현장 제보 심사 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"409":{"description":"이미 심사된 현장 제보","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"400":{"description":"심사 요청 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"404":{"description":"현장 제보를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/{id}/decline":{"post":{"tags":["신고·이의신청"],"summary":"신고 거절 처리","description":"관리자가 신고를 거절 처리합니다.","operationId":"declineReport","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"신고 거절 성공","content":{"*/*":{"example":{"reportId":1,"status":"DECLINED","reportedUserId":5,"banned":false,"processedAt":"2026-05-07T21:00:00"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"example":{"message":"이미 처리된 신고입니다.","code":"REPORT_ALREADY_PROCESSED"}}}},"404":{"description":"신고 내역 없음","content":{"*/*":{"example":{"message":"신고 내역을 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/{id}/accept":{"post":{"tags":["신고·이의신청"],"summary":"신고 수락 처리","description":"관리자가 신고를 수락하고 대상 사용자를 제재하며 신고 대상 게시글을 숨김 처리합니다.","operationId":"acceptReport","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"신고 수락 성공","content":{"*/*":{"example":{"reportId":1,"status":"ACCEPTED","reportedUserId":5,"banned":true,"processedAt":"2026-05-07T21:00:00"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"example":{"message":"이미 처리된 신고입니다.","code":"REPORT_ALREADY_PROCESSED"}}}},"404":{"description":"신고 내역 없음","content":{"*/*":{"example":{"message":"신고 내역을 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals/{id}/reject":{"post":{"tags":["신고·이의신청"],"summary":"신고 이의제기 반려","operationId":"reject_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals/{id}/approve":{"post":{"tags":["신고·이의신청"],"summary":"신고 이의제기 승인","operationId":"approve_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{postId}/reports/decline":{"post":{"tags":["신고·이의신청"],"summary":"게시글 단위 신고 일괄 거절","description":"관리자가 게시글에 연결된 PENDING 신고를 모두 거절합니다. 게시글 공개 상태와 대상 사용자 제재 상태는 변경하지 않습니다.","operationId":"declinePostReports","parameters":[{"name":"postId","in":"path","description":"신고를 일괄 거절할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"200":{"description":"게시글 신고 일괄 거절 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"},"example":{"postId":10,"status":"DECLINED","processedReportCount":3,"visibilityStatus":"ACTIVE","hiddenAt":null,"hiddenReason":null,"processedAt":"2026-05-21T10:15:30"}}}},"409":{"description":"처리할 PENDING 신고 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{postId}/reports/accept":{"post":{"tags":["신고·이의신청"],"summary":"게시글 단위 신고 일괄 수락","description":"관리자가 게시글에 연결된 PENDING 신고를 모두 수락하고 게시글 숨김 및 대상 사용자 제재를 처리합니다.","operationId":"acceptPostReports","parameters":[{"name":"postId","in":"path","description":"신고를 일괄 수락할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"게시글 신고 일괄 수락 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"},"example":{"postId":10,"status":"ACCEPTED","processedReportCount":3,"visibilityStatus":"AUTO_HIDDEN","hiddenAt":"2026-05-21T10:15:30","hiddenReason":"REPORT_BULK_ACCEPTED","processedAt":"2026-05-21T10:15:30"}}}},"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"409":{"description":"처리할 PENDING 신고 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report/refresh":{"post":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 리포트 생성 시작","description":"DB와 S3를 백그라운드에서 비교해 Redis에 리포트 결과를 저장합니다. 생성된 리포트는 GET report API로 페이지 조회합니다.","operationId":"refreshS3OrphanReport","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReportStatus"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 생성","description":"관리자가 상점 운영 상태 공지를 생성합니다.","operationId":"createNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices/{noticeId}/cancel":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 취소","description":"관리자가 예약 또는 활성 운영 상태 공지를 취소합니다.","operationId":"cancelNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCancelRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests":{"get":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 목록 조회","operationId":"list_7","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 생성","operationId":"create_1","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/reminders":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 리마인드 발행","operationId":"remind","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/complete":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 완료","operationId":"complete","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/cancel":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 취소","operationId":"cancel","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/information-evidence":{"get":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 목록 조회","description":"관리자가 장소 정보 출처와 증빙 메타데이터를 확인합니다.","operationId":"getPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 조회할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceResponse"}}}},"200":{"description":"장소 정보 증빙 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 등록","description":"관리자가 장소 정보 출처와 증빙 메타데이터를 등록합니다.","operationId":"createPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 등록할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceCreateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"200":{"description":"장소 정보 증빙 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-snapshots/resync":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 추천 snapshot 재동기화","description":"관리자가 모든 장소 추천 snapshot을 현재 데이터 기준으로 다시 동기화합니다.","operationId":"resyncRecommendationSnapshots","responses":{"200":{"description":"추천 snapshot 재동기화 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationSnapshotResyncResponse"},"example":{"placeCount":12,"synchronizedSnapshotCount":12,"deletedSnapshotCount":1,"synchronizedSimilaritySnapshotCount":24,"deletedSimilaritySnapshotCount":2,"synchronizedVersionSnapshotCount":3,"deletedVersionSnapshotCount":0,"message":"장소 추천 snapshot 재동기화를 완료했습니다."}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 병합","description":"관리자가 중복 장소의 참조 데이터를 대상 장소로 옮기고 원본 장소를 병합합니다.","operationId":"mergePlaces","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge-histories/{historyId}/restore":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 장소 병합 복구","description":"관리자가 저장된 장소 병합 이력을 기준으로 복구합니다.","operationId":"restoreMerge","parameters":[{"name":"historyId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceMergeRestoreResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/reject":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 거절","operationId":"rejectDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateDecisionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/merge":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 확정 중복 장소 병합","operationId":"mergeDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateMergeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/confirm":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 확정","operationId":"confirmDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateDecisionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests/{deletionRequestId}/review":{"post":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 심사","operationId":"review_2","parameters":[{"name":"deletionRequestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceReviewDeletionRequestReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-operating-notices/expire":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 만료 처리","description":"만료 시간이 지난 운영 상태 공지를 일괄 만료 처리합니다.","operationId":"expireDueNotices","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}/review":{"post":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 검토","operationId":"reviewReport","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}/disputes/{disputeId}/review":{"post":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 반박 검토","operationId":"reviewDispute","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"disputeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events":{"get":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 목록 조회","operationId":"listEvents","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":20}},{"name":"keyword","in":"query","required":false,"schema":{"type":"string"}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"eventType","in":"query","required":false,"schema":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]}},{"name":"publicationStatus","in":"query","required":false,"schema":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]}},{"name":"scheduleStatus","in":"query","required":false,"schema":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 등록","description":"장소와 연결된 기간형 이벤트를 초안으로 등록합니다.","operationId":"createEvent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventRequest"}}},"required":true},"responses":{"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"이벤트 초안 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}/publish":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 공개","description":"종료되지 않은 초안 이벤트를 앱 탐색에 공개합니다.","operationId":"publishEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventActionRequest"}}},"required":true},"responses":{"200":{"description":"이벤트 공개 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"409":{"description":"공개할 수 없는 상태 또는 기간","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}/cancel":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 취소","description":"초안 또는 공개된 기간형 이벤트를 취소하고 앱 탐색에서 제외합니다.","operationId":"cancelEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventActionRequest"}}},"required":true},"responses":{"409":{"description":"이미 취소된 이벤트","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 취소 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"404":{"description":"이벤트를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/outbox-events/{eventId}/retry":{"post":{"tags":["Outbox·스토리지 운영"],"summary":"관리자 Outbox 이벤트 재처리","description":"장애 원인과 중복 처리 안전성을 확인한 뒤 최종 실패 이벤트를 재처리 대상으로 전환합니다.","operationId":"retry","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventRetryRequest"}}},"required":true},"responses":{"403":{"description":"Outbox 복구 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"재처리 사유 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"재처리 불가 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"재처리 예약 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventItem"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/reject":{"post":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 반려","operationId":"reject_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/approve":{"post":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 승인","description":"NEW_PLACE 승인 시 장소 생성, Merchant Owner 연결과 신청의 COMPLETED 전이가 하나의 트랜잭션으로 완료됩니다. 신청자의 추가 완료 요청은 필요하지 않습니다.","operationId":"approve_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/revoke":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 권한 회수","operationId":"revoke_1","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/reject":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 반려","operationId":"reject_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/approve":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 승인","description":"승인 사유만 처리합니다. 장소 연결은 변경하지 않으며, 승인 후 연결이 필요하면 PUT /admin/merchant-owners/{userId}/places로 전체 장소 목록을 별도 요청해야 합니다. 승인과 장소 연결은 별도 트랜잭션입니다.","operationId":"approve_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}/decline":{"post":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 반려","description":"반려는 신고 상태만 변경하고 대상 노출 상태를 바꾸지 않습니다.","operationId":"decline","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"신고 반려 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportActionResponse"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"커뮤니티 신고를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}/accept":{"post":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 수락","description":"수락한 신고 대상 글 또는 댓글을 숨깁니다.","operationId":"accept","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"커뮤니티 신고 또는 대상 콘텐츠를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"신고 수락 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportActionResponse"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/ban/{userId}":{"post":{"tags":["회원·권한"],"summary":"사용자 밴 처리","description":"관리자가 특정 사용자를 밴 처리합니다. expiresAt 또는 durationDays를 전달하면 기간 밴으로, 둘 다 비우면 영구 밴으로 처리합니다.","operationId":"banUser","parameters":[{"name":"userId","in":"path","description":"밴 처리할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BanRequest"}}}},"responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"밴 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BanResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/ban/{userId}/release":{"post":{"tags":["회원·권한"],"summary":"사용자 밴 해제","description":"관리자가 영구 밴 또는 기간 밴 상태의 사용자를 명시적으로 해제합니다.","operationId":"unbanUser","parameters":[{"name":"userId","in":"path","description":"밴 해제할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnbanRequest"}}}},"responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"409":{"description":"제재 중인 사용자가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"제재 중인 사용자가 아닙니다.","code":"USER_NOT_BANNED"}}}},"200":{"description":"밴 해제 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UnbanResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}/enable":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 활성화","description":"관리자가 Trust Score 개입 규칙을 활성화합니다.","operationId":"enableRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleToggleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}/disable":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 비활성화","description":"관리자가 Trust Score 개입 규칙을 비활성화합니다.","operationId":"disableRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleToggleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/anomalies/{anomalyId}/resolve":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 이상치 해결 처리","description":"관리자가 Trust Score 이상치를 해결 처리하고 감사 로그를 남깁니다.","operationId":"resolveAnomaly","parameters":[{"name":"anomalyId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyResolveRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices/{noticeId}":{"patch":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 수정","description":"관리자가 상점 운영 상태 공지 내용을 수정합니다.","operationId":"updateNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/tourist-info":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 관광 정보 수정","description":"관리자가 장소의 영문명, 관광객용 요약, 관광 카테고리를 수정합니다.","operationId":"updatePlaceTouristInfo","parameters":[{"name":"id","in":"path","description":"관광 정보를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceTouristInfoUpdateRequest"}}},"required":true},"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"reason":"수정 사유는 필수입니다."}}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"장소 관광 정보 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceTouristInfoUpdateResponse"},"example":{"placeId":1,"englishName":"Jinju Castle","touristSummary":"A historic fortress overlooking the Nam River.","touristCategories":["K_POP","CAFE","POP_UP"],"message":"장소 관광 정보를 수정했습니다."}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/operating-status":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 운영 상태 확인","description":"관리자가 확인한 장소 운영 상태를 기록하고 최신 확인 시각을 서버 시간으로 갱신합니다. 비운영 장소는 앱 장소 조회와 추천에서 숨겨집니다.","operationId":"updatePlaceOperatingStatus","parameters":[{"name":"id","in":"path","description":"운영 상태를 확인할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"200":{"description":"장소 운영 상태 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/operating-schedule":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 영업시간 일정 수정","description":"관리자가 요일별 정규 영업시간과 특정 날짜 휴무·대체 영업시간을 전체 교체합니다. 수동 운영 상태는 변경하지 않습니다.","operationId":"updatePlaceOperatingSchedule","parameters":[{"name":"id","in":"path","description":"영업시간 일정을 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingScheduleUpdateRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"장소 영업시간 일정 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingScheduleUpdateResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/kakao-place-id":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 Kakao place id 수정","description":"관리자가 장소에 연결된 Kakao place id를 재연결하거나 해제합니다.","operationId":"updatePlaceKakaoPlaceId","parameters":[{"name":"id","in":"path","description":"Kakao place id를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceKakaoPlaceIdUpdateRequest"}}},"required":true},"responses":{"409":{"description":"이미 다른 장소에 연결된 Kakao place id","content":{"*/*":{"example":{"message":"이미 다른 장소에 연결된 Kakao place id입니다.","code":"PLACE_KAKAO_PLACE_ID_CONFLICT"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"kakaoPlaceId":"카카오 장소 ID는 50자 이하여야 합니다."}}}}},"200":{"description":"Kakao place id 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceKakaoPlaceIdUpdateResponse"},"example":{"placeId":1,"kakaoPlaceId":"27414316","message":"장소 Kakao place id를 수정했습니다."}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/information-evidence/{evidenceId}/review":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 검토","description":"관리자가 장소 정보 증빙을 승인 또는 반려하고 장소 정보 검증 요약 상태를 갱신합니다.","operationId":"reviewPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 검토할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"evidenceId","in":"path","description":"증빙 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceReviewRequest"}}},"required":true},"responses":{"200":{"description":"장소 정보 증빙 검토 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"404":{"description":"장소 또는 증빙을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/geocoding":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 주소·좌표 보정","description":"관리자가 대표 주소, 정규화 주소와 좌표를 함께 보정하며 출처는 ADMIN으로 기록합니다.","operationId":"updatePlaceGeocoding","parameters":[{"name":"id","in":"path","description":"주소와 좌표를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceGeocodingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceGeocodingUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/discovery-status":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 탐색 노출 상태 수정","description":"관리자가 장소를 공개 탐색, 자동완성, 북마크 목록, 추천 후보에 노출할지 제어합니다.","operationId":"updatePlaceDiscoveryStatus","parameters":[{"name":"id","in":"path","description":"탐색 노출 상태를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"200":{"description":"장소 탐색 노출 상태 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/coordinates":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 좌표 수정","description":"관리자가 잘못 등록된 장소의 위도와 경도를 수정합니다.","operationId":"updatePlaceCoordinates","parameters":[{"name":"id","in":"path","description":"좌표를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceCoordinateUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"장소 좌표 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceCoordinateUpdateResponse"},"example":{"placeId":1,"latitude":35.1796,"longitude":128.1076,"message":"장소 좌표를 수정했습니다."}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"latitude":"위도는 90.0 이하여야 합니다."}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/basic-information":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 기본 정보 수정","description":"관리자가 장소명과 표준 카테고리를 수정하고 변경 사유를 감사 로그에 남깁니다.","operationId":"updatePlaceBasicInformation","parameters":[{"name":"id","in":"path","description":"기본 정보를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"200":{"description":"장소 기본 정보 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-traffic":{"patch":{"tags":["중복·추천 관리"],"summary":"관리자 추천 버전 트래픽 비율 수정","description":"관리자가 추천 버전별 traffic percentage를 수정하고 즉시 반영합니다.","operationId":"updateRecommendationTraffic","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}":{"get":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 상세 조회","operationId":"getEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventListItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 수정","description":"초안 상태의 기간형 이벤트 정보와 연결 장소를 수정합니다.","operationId":"updateEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventRequest"}}},"required":true},"responses":{"404":{"description":"이벤트 또는 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"409":{"description":"초안이 아닌 이벤트 수정 시도","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/{notificationId}/read":{"patch":{"tags":["알림·발송 이력"],"summary":"관리자 알림 읽음 처리","description":"관리자가 운영 확인이 필요한 인앱 알림을 읽음 상태로 변경합니다.","operationId":"markAsRead","parameters":[{"name":"notificationId","in":"path","description":"알림 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"알림을 찾을 수 없음","content":{"*/*":{"example":{"message":"알림을 찾을 수 없습니다.","code":"NOTIFICATION_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"알림 읽음 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationReadResponse"},"example":{"notificationId":1,"read":true,"message":"알림을 읽음 처리했습니다."}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/read":{"patch":{"tags":["알림·발송 이력"],"summary":"관리자 전체 알림 읽음 처리","description":"관리자가 모든 미확인 인앱 알림을 읽음 상태로 변경합니다.","operationId":"markAllAsRead","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"전체 알림 읽음 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationReadAllResponse"},"example":{"updatedCount":3,"message":"전체 알림을 읽음 처리했습니다."}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports":{"get":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 목록 조회","operationId":"list","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/corrections":{"get":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 정정 목록 조회","operationId":"listCorrections","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}":{"get":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 상세 조회","operationId":"get","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/sanctions":{"get":{"tags":["회원·권한"],"summary":"사용자 제재 이력 조회","description":"관리자가 특정 사용자의 제재 변경 이력을 페이지 단위로 조회합니다. 제재 이력이 없으면 500이 아니라 빈 histories 배열과 페이지 메타데이터를 반환합니다.","operationId":"listUserSanctionHistories","parameters":[{"name":"userId","in":"path","description":"조회할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"banType","in":"query","description":"제재 유형 필터","required":false,"schema":{"type":"string","enum":["PERMANENT","TEMPORARY"]},"example":"TEMPORARY"},{"name":"action","in":"query","description":"처리 상태 필터","required":false,"schema":{"type":"string","enum":["APPLIED","RELEASED","EXPIRED"]},"example":"APPLIED"},{"name":"from","in":"query","description":"처리 시각 시작 필터","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"처리 시각 종료 필터","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"}],"responses":{"200":{"description":"사용자 제재 이력 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminUserSanctionHistoryResponse"},"example":{"histories":[],"page":1,"limit":5,"totalCount":0,"totalPages":1,"hasNext":false}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"400":{"description":"조회 기간 필터 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"제재 이력 조회 종료 시각은 시작 시각보다 이후여야 합니다.","code":"INVALID_SANCTION_FILTER_PERIOD"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/sanction":{"get":{"tags":["회원·권한"],"summary":"사용자 제재 상태 조회","description":"관리자가 특정 사용자의 현재 제재 상태를 조회합니다. 만료된 기간 밴은 현재 제재로 보지 않습니다.","operationId":"getUserSanctionStatus","parameters":[{"name":"userId","in":"path","description":"조회할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminUserSanctionStatusResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/role-targets":{"get":{"tags":["회원·권한"],"summary":"관리자 역할 부여 대상 사용자 검색","description":"관리자 역할 API에 전달할 수 있는 관리자 계정만 username 부분 일치로 검색합니다. 사용자 공통 표시 이름은 제공되지 않아 username만 검색하며, 빈 keyword는 전체 대상 조회로 처리합니다. page는 1부터 시작하고 limit은 1~100으로 보정됩니다. 이메일과 전화번호는 반환하지 않습니다.","operationId":"search","parameters":[{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기(1~100)","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"username 부분 일치 검색어. 비어 있으면 전체 역할 부여 대상을 조회합니다.","required":false,"schema":{"type":"string"},"example":"operator"}],"responses":{"200":{"description":"검색 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentTargetSearchResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/banned":{"get":{"tags":["회원·권한"],"summary":"밴 유저 목록 조회","description":"관리자가 현재 밴 처리된 사용자 목록을 페이지 단위로 조회합니다. keyword는 숫자만 입력하면 userId 정확히 일치로 검색하고, 그 외에는 username 부분 일치로 검색합니다. counts는 현재 밴 중인 사용자 기준이며, keyword 검색어가 있으면 검색 결과 기준으로 계산됩니다. 기간 필터는 from과 to를 사용합니다. limit 값은 내부적으로 1~100 범위로 보정됩니다.","operationId":"listBannedUsers","parameters":[{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"숫자만 입력하면 userId 정확히 일치, 그 외에는 username 부분 일치 검색","required":false,"schema":{"type":"string"},"example":"blockedUser01"},{"name":"banType","in":"query","description":"밴 유형","required":false,"schema":{"type":"string","enum":["PERMANENT","TEMPORARY"]},"example":"PERMANENT"},{"name":"from","in":"query","description":"밴 처리 시작 시각 이상","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"밴 처리 종료 시각 이하","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"sortBy","in":"query","description":"정렬 기준","required":false,"schema":{"type":"string","default":"BANNED_AT","enum":["BANNED_AT","EXPIRES_AT","USER_ID"]},"example":"BANNED_AT"},{"name":"sortDirection","in":"query","description":"정렬 방향","required":false,"schema":{"type":"string","default":"DESC","enum":["ASC","DESC"]},"example":"DESC"}],"responses":{"200":{"description":"밴 유저 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminBannedUserResponse"},"example":{"users":[{"userId":7,"username":"blockedUser01","banned":true,"banType":"PERMANENT","bannedAt":"2026-06-07T13:30:00","banExpiresAt":null}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false,"counts":{"total":1,"permanent":1,"temporary":0}}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/banned/{userId}":{"get":{"tags":["회원·권한"],"summary":"밴 유저 상세 조회","description":"관리자가 특정 밴 유저의 상세 정보를 조회합니다.","operationId":"getBannedUser","parameters":[{"name":"userId","in":"path","description":"조회할 밴 유저 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"404":{"description":"밴 유저를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"밴 유저 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminBannedUserDetailResponse"},"example":{"userId":7,"username":"blockedUser01","email":"blockedUser01@example.com","birthYear":1998,"language":"ko","country":"KR","role":"USER","banned":true,"bannedAt":"2026-06-07T13:30:00","banType":"PERMANENT","banExpiresAt":null,"banReason":"반복적인 신고 누적","createdAt":"2026-06-01T10:00:00"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}":{"get":{"tags":["신뢰 점수"],"summary":"신고자 신뢰 등급과 점수 근거 조회","description":"관리자가 신고자의 신뢰 점수, 등급, 신고 처리 통계 기반 점수 근거를 조회합니다.","operationId":"getTrustScore","parameters":[{"name":"reporterUserId","in":"path","description":"신고자 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"200":{"description":"신뢰 등급과 점수 근거 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreResponse"},"example":{"reporterUserId":7,"reporterUsername":"pingdom_user","trustScore":80,"trustGrade":"HIGH","restricted":false,"restrictedUntil":null,"restrictionReason":null,"evidence":{"submittedCount":12,"acceptedCount":8,"declinedCount":4,"falseReportCount":3,"acceptanceRate":66.67,"baseScore":100,"acceptedScoreBonus":40,"falseReportScorePenalty":60}}}}},"404":{"description":"신고자 Trust Score 정책을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"신고자 Trust Score 정책을 찾을 수 없습니다.","code":"TRUST_SCORE_REPORTER_POLICY_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}/history":{"get":{"tags":["신뢰 점수"],"summary":"신고자 Trust Score 변경 이력 조회","operationId":"listTrustScoreHistory","parameters":[{"name":"reporterUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreChangeHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/anomalies":{"get":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 이상치 목록 조회","description":"관리자가 Trust Score 이상치 목록을 조회합니다. page는 1 이상, limit은 1~100 범위로 보정됩니다.","operationId":"listAnomalies","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"reporterUserId","in":"query","description":"신고자 사용자 ID 필터","required":false,"schema":{"type":"integer","format":"int64"},"example":12},{"name":"unresolvedOnly","in":"query","description":"미해결 이상치만 조회할지 여부","required":false,"schema":{"type":"boolean","default":false},"example":true}],"responses":{"200":{"description":"Trust Score 이상치 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 목록 조회","operationId":"list_3","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACTIVE","SUSPENDED","REVOKED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfilePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 및 활동 자격 상세 조회","operationId":"get_1","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-field-reports":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 현장 제보 목록 조회","operationId":"list_4","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/s3/orphan-objects":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"S3 orphan 객체 dry-run 리포트","description":"DB에 등록된 게시글 원본/썸네일 S3 key와 S3 객체 목록을 비교해 DB에서 사용 중이지 않은 객체를 조회합니다. 실제 삭제는 수행하지 않습니다.","operationId":"reportOrphanObjects","parameters":[{"name":"prefix","in":"query","description":"조회할 S3 key prefix","required":false,"schema":{"type":"string","default":"map/"},"example":"map/"},{"name":"limit","in":"query","description":"최대 스캔 객체 수. 1~10000 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1000},"example":1000}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminS3OrphanObjectReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reservations":{"get":{"tags":["예약"],"summary":"관리자 예약 기록 목록 조회","operationId":"list_5","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"merchantOwnerUserId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"touristUserId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"reservationFrom","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"reservationTo","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReservationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reservations/{reservationId}":{"get":{"tags":["예약"],"summary":"관리자 예약 기록 상세 조회","operationId":"get_2","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/reported-users":{"get":{"tags":["신고·이의신청"],"summary":"관리자 신고 유저 목록 조회","description":"관리자가 PENDING 상태의 신고 유저 목록을 조회합니다. limit 값은 내부적으로 1~100 범위로 보정됩니다.","operationId":"getReportedUsers","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"검색 키워드. 신고자 이름, 신고 사유, 신고받은 유저 ID로 검색합니다.","required":false,"schema":{"type":"string","default":""},"example":"욕설"}],"responses":{"200":{"description":"신고 유저 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReportedUsersResponse"},"example":{"users":[{"reportId":12,"reporterUserId":3,"reporterUsername":"reporter01","reportedImageId":101,"reportedUserId":55,"reason":"욕설"}],"page":1,"limit":20,"totalCount":123,"totalPages":7,"hasNext":true}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/reported-users/{id}":{"get":{"tags":["신고·이의신청"],"summary":"관리자 신고 유저 상세 조회","description":"관리자가 신고 상세 정보를 조회합니다.","operationId":"getReportedUser","parameters":[{"name":"id","in":"path","description":"조회할 신고 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":12}],"responses":{"200":{"description":"신고 유저 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReportedUsersItem"},"example":{"reportId":12,"reporterUserId":3,"reporterUsername":"reporter01","reportedImageId":101,"reportedUserId":55,"reason":"욕설"}}}},"404":{"description":"신고를 찾을 수 없음","content":{"*/*":{"example":{"message":"신고를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals":{"get":{"tags":["신고·이의신청"],"summary":"신고 이의제기 목록 조회","operationId":"list_6","parameters":[{"name":"status","in":"query","description":"이의제기 상태","required":false,"schema":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]}},{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/privacy-processing-histories":{"get":{"tags":["감사·개인정보 처리 이력"],"summary":"개인정보 처리 이력 조회","description":"관리자가 개인정보 export, 탈퇴, 익명화, 삭제 처리 이력을 페이지 단위로 조회합니다.","operationId":"listHistories","parameters":[{"name":"subjectUserId","in":"query","description":"처리 대상 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"actorUserId","in":"query","description":"처리 수행 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"action","in":"query","description":"처리 유형","required":false,"schema":{"type":"string","enum":["EXPORT_REQUESTED","WITHDRAWAL_REQUESTED","ANONYMIZED","DELETED"]},"example":"EXPORT_REQUESTED"},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-31T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PrivacyProcessingHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 삭제 후보 리포트 생성","description":"최근 생성된 S3 고아 파일 리포트의 삭제 후보를 페이지 단위로 조회합니다. 이 API는 S3/DB 전체 스캔이나 실제 삭제를 수행하지 않습니다.","operationId":"createS3OrphanReport","parameters":[{"name":"reportId","in":"query","description":"조회할 리포트 ID. 생략하면 최근 생성된 리포트를 조회합니다.","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReport"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report/status":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 리포트 생성 상태 조회","description":"리포트 생성 작업의 RUNNING/COMPLETED/FAILED 상태와 집계 정보를 조회합니다.","operationId":"getS3OrphanReportStatus","parameters":[{"name":"reportId","in":"query","description":"조회할 리포트 ID. 생략하면 최근 생성된 리포트를 조회합니다.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReportStatus"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places":{"get":{"tags":["장소 조회"],"summary":"관리자 장소 목록 조회","description":"관리자가 등록된 장소 목록을 페이지 단위로 조회합니다.","operationId":"listPlaces","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"sortParam","in":"query","description":"장소 정렬 기준. LATEST, OLDEST, LEVEL_DESC만 지원합니다.","required":false,"schema":{"type":"string","enum":["LATEST","OLDEST","LEVEL_DESC"]},"example":"LATEST"},{"name":"keyword","in":"query","description":"장소 검색 키워드. 장소명, 등록자 ID, 주소로 검색합니다.","required":false,"schema":{"type":"string","default":""},"example":"용인"},{"name":"category","in":"query","description":"일반 장소 카테고리 필터. 입력값을 표준 카테고리로 정규화한 뒤 AdminMapPlaceItem.category와 정확히 비교합니다. touristCategories와는 별도 기준입니다.","required":false,"schema":{"type":"string","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"example":"CAFE"}],"responses":{"200":{"description":"장소 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceResponse"},"examples":{"categoryFilteredResult":{"summary":"카테고리 필터 조회 결과","description":"categoryFilteredResult","value":{"places":[{"id":1,"name":"진주성","address":"경상남도 진주시 남강로 626","discoveryStatus":"VISIBLE","category":"CULTURAL_HERITAGE","categoryName":"문화재","touristCategories":["EXHIBITION"],"latitude":35.1894,"longitude":128.0789,"userId":3,"registrant":"placeRegistrar","level":5,"placeGrowth":{"photoCount":10,"level":5,"currentLevelMinPhotoCount":10,"nextLevelMinPhotoCount":16,"progressPercent":0}}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}},"emptyResult":{"summary":"카테고리 필터 결과 없음","description":"emptyResult","value":{"places":[],"page":1,"limit":20,"totalCount":0,"totalPages":1,"hasNext":false}}}}}},"400":{"description":"지원하지 않는 장소 정렬 기준","content":{"*/*":{"example":{"message":"장소 목록은 LATEST 또는 OLDEST 정렬만 지원합니다.","code":"UNSUPPORTED_PLACE_SORT_PARAM"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}":{"get":{"tags":["장소 조회"],"summary":"관리자 장소 상세 조회","description":"관리자가 특정 장소의 기본 정보와 연결된 게시글 목록을 조회합니다.","operationId":"getPlace","parameters":[{"name":"id","in":"path","description":"조회할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"sortParam","in":"query","description":"게시글 정렬 기준","required":false,"schema":{"type":"string","default":"LATEST","enum":["LATEST","OLDEST","MOST_LIKED"]},"example":"LATEST"},{"name":"keyword","in":"query","description":"게시글 검색","required":false,"schema":{"type":"string","default":""},"example":"용인"}],"responses":{"200":{"description":"장소 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDetailResponse"},"example":{"id":1,"name":"진주성","imageUrl":"https://example.com/places/1/representative.jpg","address":"경상남도 진주시 남강로 626","discoveryStatus":"VISIBLE","category":"CULTURAL_HERITAGE","categoryName":"문화재","latitude":35.1894,"longitude":128.0789,"userId":3,"username":"placeOwner","sortParam":"LATEST","postCount":1,"level":5,"placeGrowth":{"photoCount":10,"hiddenPhotoCount":1,"level":5,"currentLevelMinPhotoCount":10,"nextLevelMinPhotoCount":16,"progressPercent":0},"posts":[{"id":10,"imageUrl":"https://example.com/image.jpg","title":"야경 사진","description":"남강 야경입니다.","userId":3,"username":"pingdom_user","createdAt":"2026-05-28T12:00:00","likeCount":5,"visibilityStatus":"HIDDEN","hiddenReason":"ADMIN_HIDDEN"}]}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendations/{requestId}/explanation":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 설명 조회","description":"관리자가 추천 응답 requestId의 후보 source, score, ranking, feature log 정보를 조회합니다.","operationId":"getRecommendationExplanation","parameters":[{"name":"requestId","in":"path","description":"추천 응답 requestId","required":true,"schema":{"type":"string"},"example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}],"responses":{"200":{"description":"추천 설명 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationExplanationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-metrics":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 성과 조회","description":"관리자가 장소별 추천 노출, 클릭, CTR 지표를 조회합니다.","operationId":"listRecommendationMetrics","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"sortBy","in":"query","description":"추천 성과 정렬 기준","required":false,"schema":{"type":"string","enum":["SMOOTHED_CTR","RAW_CTR","BOOKMARK_CONVERSION","LIKE_CONVERSION","TOTAL_CONVERSION","EXPOSURE","CLICK","UPDATED_AT"]},"example":"SMOOTHED_CTR"},{"name":"keyword","in":"query","description":"장소 검색 키워드","required":false,"schema":{"type":"string","default":""},"example":"진주"},{"name":"recommendationVersion","in":"query","description":"추천 버전 필터","required":false,"schema":{"type":"string","default":""},"example":"place-rec-v1"},{"name":"days","in":"query","description":"최근 N일 기준 필터","required":false,"schema":{"type":"integer","format":"int32"},"example":7}],"responses":{"200":{"description":"추천 성과 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricsResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-metrics/compare":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 버전 성과 비교","description":"관리자가 두 추천 버전의 CTR, 전환율, 노출 지표를 같은 조건에서 비교합니다.","operationId":"compareRecommendationMetrics","parameters":[{"name":"baselineVersion","in":"query","description":"기준 추천 버전","required":true,"schema":{"type":"string"},"example":"place-rec-v1"},{"name":"targetVersion","in":"query","description":"비교 대상 추천 버전","required":true,"schema":{"type":"string"},"example":"place-rec-v2"},{"name":"keyword","in":"query","description":"장소 검색 키워드","required":false,"schema":{"type":"string","default":""},"example":"진주"},{"name":"days","in":"query","description":"최근 N일 기준 필터","required":false,"schema":{"type":"integer","format":"int32"},"example":7}],"responses":{"200":{"description":"추천 버전 성과 비교 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricsCompareResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge-histories":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 장소 병합 이력 조회","description":"관리자가 최근 장소 병합 이력을 조회합니다.","operationId":"listMergeHistories","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceMergeHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicates":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 목록 조회","description":"관리자가 병합 대상이 될 수 있는 중복 장소 그룹을 조회합니다.","operationId":"listDuplicatePlaces","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicates/{id}":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 상세 조회","description":"관리자가 특정 장소의 중복 후보 목록을 조회합니다.","operationId":"getDuplicatePlace","parameters":[{"name":"id","in":"path","description":"중복 후보를 확인할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 조회","operationId":"listDuplicateCandidates","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","default":"PENDING","enum":["PENDING","CONFIRMED","REJECTED","MERGED"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 상세 조회","operationId":"getDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests":{"get":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 목록 조회","operationId":"list_8","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests/{deletionRequestId}":{"get":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 상세 조회","operationId":"get_3","parameters":[{"name":"deletionRequestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports":{"get":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 목록 조회","operationId":"list_9","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}":{"get":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 상세 조회","operationId":"get_4","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/outbox-events":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"관리자 Outbox 이벤트 조회","description":"운영자가 Outbox 이벤트의 상태와 실패 원인을 조회합니다. 민감한 payload와 deduplication key는 반환하지 않습니다.","operationId":"list_10","parameters":[{"name":"status","in":"query","description":"처리 상태","required":false,"schema":{"type":"string","enum":["PENDING","PROCESSING","RETRY","SUCCEEDED","FAILED"]},"example":"FAILED"},{"name":"eventType","in":"query","description":"이벤트 유형","required":false,"schema":{"type":"string","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"example":"EMAIL_VERIFICATION_REQUESTED"},{"name":"aggregateType","in":"query","description":"aggregate 유형","required":false,"schema":{"type":"string"},"example":"USER"},{"name":"aggregateId","in":"query","description":"aggregate ID","required":false,"schema":{"type":"string"},"example":10},{"name":"from","in":"query","description":"생성 시각 조회 시작","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"생성 시각 조회 종료","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"400":{"description":"조회 기간 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Outbox 복구 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 알림 목록 조회","description":"인증된 관리자가 자신에게 전달된 운영 알림을 유형, 읽음 상태, 기간 조건으로 조회합니다. 알림 token은 report:{reportId}, place:{placeId}, sanction:{sanctionId} 형식을 사용합니다.","operationId":"listNotifications","parameters":[{"name":"type","in":"query","description":"관리자 알림 유형: ADMIN_REPORT_RECEIVED, ADMIN_REPORT_PROCESSED, ADMIN_DUPLICATE_PLACE_DETECTED, ADMIN_USER_SANCTION","required":false,"schema":{"type":"string","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"example":"ADMIN_REPORT_RECEIVED"},{"name":"read","in":"query","description":"읽음 여부","required":false,"schema":{"type":"boolean"},"example":false},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-31T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"관리자 알림 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationResponse"},"example":{"notifications":[{"notificationId":1,"userId":10,"type":"ADMIN_REPORT_RECEIVED","title":"신고 접수 알림","body":"신고 ID 30 접수가 게시글 ID 12에 등록되었습니다.","token":"report:30","read":false,"createdAt":"2026-07-21T15:30:00"}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}}}},"400":{"description":"조회 기간 오류","content":{"*/*":{"example":{"message":"알림 조회 종료 시각은 시작 시각보다 이후여야 합니다.","code":"INVALID_NOTIFICATION_FILTER_PERIOD"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/unread-count":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 미확인 알림 개수 조회","description":"관리자가 아직 읽음 처리하지 않은 인앱 알림 개수를 조회합니다.","operationId":"countUnread","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"미확인 알림 개수 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationUnreadCountResponse"},"example":{"unreadCount":3}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notification-deliveries":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 알림 발송 결과 조회","description":"관리자가 사용자, 채널, 상태, 알림 유형, 기간 조건으로 알림 발송 결과를 페이지 단위로 조회합니다.","operationId":"listDeliveries","parameters":[{"name":"userId","in":"query","description":"수신 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":10},{"name":"channel","in":"query","description":"발송 채널","required":false,"schema":{"type":"string","enum":["FCM","EMAIL"]},"example":"FCM"},{"name":"status","in":"query","description":"발송 상태","required":false,"schema":{"type":"string","enum":["SUCCEEDED","FAILED","RETRY_SCHEDULED","FINAL_FAILED"]},"example":"SUCCEEDED"},{"name":"notificationType","in":"query","description":"인앱 알림 유형","required":false,"schema":{"type":"string","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"example":"NEW_LIKE"},{"name":"outboxEventType","in":"query","description":"Outbox 이벤트 유형","required":false,"schema":{"type":"string","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"example":"EMAIL_VERIFICATION_REQUESTED"},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationDeliveryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 목록 조회","description":"keyword는 장소명과 신청자 username을 부분 일치로 검색합니다. NEW_PLACE는 신청 장소명, EXISTING_PLACE_CLAIM은 대상 기존 장소명을 검색합니다. submittedFrom·submittedTo는 신청 제출 시각(Asia/Seoul 기준 LocalDateTime)을 포함 경계로 필터링하며, DRAFT는 제출 시각이 없어 기간 필터에서 제외됩니다. 한쪽 기간 경계만 전달할 수 있고 종료 시각이 시작 시각보다 빠르면 400을 반환합니다. 빈 keyword는 검색 조건을 적용하지 않습니다.","operationId":"list_11","parameters":[{"name":"status","in":"query","description":"반복 전달 가능한 신청 상태 필터","required":false,"style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]}}},{"name":"applicationType","in":"query","required":false,"schema":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]}},{"name":"keyword","in":"query","description":"장소명 또는 신청자 username 부분 일치 검색어. 공백 또는 빈 값은 미적용","required":false,"schema":{"type":"string"},"example":"서울"},{"name":"submittedFrom","in":"query","description":"신청 제출 시각 시작 경계(포함)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-01T00:00:00"},{"name":"submittedTo","in":"query","description":"신청 제출 시각 종료 경계(포함)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-30T23:59:59"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 상세 조회","operationId":"get_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/attachments":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 첨부파일 목록 조회","operationId":"listAttachments","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationAttachmentResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/attachments/{attachmentId}/content":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 첨부파일 다운로드","operationId":"attachmentContent","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"attachmentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 신청 목록 조회","operationId":"list_12","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfilePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 신청 상세 조회","operationId":"get_6","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/summary":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 요약 조회","description":"전체 장소, 게시글, 처리 대기 신고, 현재 밴 사용자 수와 운영 지표를 조회합니다. 등록 변화 지표는 서버 기준 오늘 00시부터 현재까지와 오늘을 포함한 최근 7일을 제공합니다. 중복 장소는 이름·주소 기준 후보 그룹 수, 밴 만료 예정 사용자는 현재 시각부터 7일 이내의 임시 밴 사용자 수, 위치 정보 누락 장소는 location이 없는 장소 수를 의미합니다.","operationId":"getSummary","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"대시보드 요약 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardSummaryResponse"},"example":{"placeCount":44,"postCount":58,"pendingReportCount":5,"bannedUserCount":6,"operationalMetrics":{"today":{"period":"TODAY","startedAt":"2026-07-21T00:00:00","endedAt":"2026-07-21T15:30:00","placeRegistrationCount":3,"postRegistrationCount":7},"last7Days":{"period":"LAST_7_DAYS","startedAt":"2026-07-15T00:00:00","endedAt":"2026-07-21T15:30:00","placeRegistrationCount":12,"postRegistrationCount":31},"duplicatePlaceGroupCount":2,"expiringBannedUserCount":4,"missingLocationPlaceCount":1,"expiringBanUntil":"2026-07-28T15:30:00","collectedAt":"2026-07-21T15:30:00"}}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/recent-activities":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 최근 운영 활동 조회","description":"최근 장소 등록, 게시글 등록, 신고 처리, 사용자 밴 및 밴 해제 내역을 조회합니다. limit 값은 내부적으로 1~50 범위로 보정됩니다.","operationId":"getRecentActivities","parameters":[{"name":"limit","in":"query","description":"조회할 최대 개수. 1~50 범위로 보정됩니다.","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","default":10},"example":10}],"responses":{"200":{"description":"최근 운영 활동 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardRecentActivitiesResponse"},"example":{"places":[{"placeId":10,"name":"핑덤 카페","address":"서울특별시 중구 세종대로 110","userId":3,"registrant":"pingdom_user","createdAt":"2026-07-21T15:30:00"}],"posts":[{"postId":22,"title":"야경이 좋은 장소","userId":3,"username":"pingdom_user","placeId":10,"placeName":"핑덤 카페","createdAt":"2026-07-21T15:30:00"}],"reports":[{"reportId":30,"reportedImageId":22,"title":"야경이 좋은 장소","status":"ACCEPTED","processedAt":"2026-07-21T16:00:00","createdAt":"2026-07-21T15:40:00"}],"userSanctions":[{"sanctionId":40,"targetUserId":5,"targetUsername":"reported_user","action":"APPLIED","banType":"PERMANENT","reason":"부적절한 게시글입니다.","processedAt":"2026-07-21T16:00:00"}]}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/pending-items":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 처리 필요 항목 조회","description":"우선 처리해야 하는 PENDING 신고와 통합 사업자·장소 신청 목록을 조회합니다. 통합 신청은 navigationPath로 관리자 심사 상세 화면 이동 경로를 제공합니다. limit 값은 내부적으로 1~50 범위로 보정됩니다.","operationId":"getPendingItems","parameters":[{"name":"limit","in":"query","description":"조회할 최대 개수. 1~50 범위로 보정됩니다.","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","default":10},"example":10}],"responses":{"200":{"description":"처리 필요 항목 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardPendingItemsResponse"},"example":{"items":[{"type":"POST_REPORT","targetId":30,"reportId":30,"postId":22,"title":"야경이 좋은 장소","status":"PENDING","createdAt":"2026-07-21T15:40:00","navigationPath":null}],"totalCount":1}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 글 목록 조회","description":"숨김 글을 포함해 카테고리와 숨김 상태로 조회합니다.","operationId":"findPosts","parameters":[{"name":"categoryId","in":"query","required":false,"schema":{"type":"string"}},{"name":"hidden","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityPostPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 글 상세 조회","description":"숨김 여부와 연결 장소를 포함해 조회합니다.","operationId":"findPost","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"커뮤니티 글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityPostResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}/comments":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 댓글 목록 조회","description":"숨김 댓글을 포함해 숨김 상태로 조회합니다.","operationId":"findComments","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"hidden","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"댓글 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityCommentPageResponse"}}}},"404":{"description":"커뮤니티 글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}/comments/{commentId}":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 댓글 상세 조회","operationId":"findComment","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityCommentResponse"}}}},"404":{"description":"커뮤니티 글 또는 댓글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports":{"get":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 목록 조회","operationId":"list_13","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]}},{"name":"targetType","in":"query","required":false,"schema":{"type":"string","enum":["POST","COMMENT"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}":{"get":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 상세 조회","operationId":"get_7","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"신고 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportResponse"},"examples":{"POST":{"summary":"글 신고: postId와 targetId가 동일","description":"POST","value":{"reportId":1,"targetType":"POST","targetId":101,"postId":101,"targetHidden":false,"reporterUserId":10,"reason":"SPAM","description":"글 신고","status":"PENDING","createdAt":"2026-09-17T10:00:00","processedByAdminUserId":null,"processedAt":null}},"COMMENT":{"summary":"댓글 신고: postId는 원문 글, targetId는 댓글","description":"COMMENT","value":{"reportId":2,"targetType":"COMMENT","targetId":202,"postId":101,"targetHidden":false,"reporterUserId":10,"reason":"ABUSE","description":"댓글 신고","status":"PENDING","createdAt":"2026-09-17T10:00:00","processedByAdminUserId":null,"processedAt":null}}}}}},"404":{"description":"커뮤니티 신고를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/audit-logs":{"get":{"tags":["감사·개인정보 처리 이력"],"summary":"관리자 감사 로그 조회","description":"관리자가 actor, action, target, 기간 조건으로 운영 감사 로그를 페이지 단위로 조회합니다.","operationId":"listAuditLogs","parameters":[{"name":"actorUserId","in":"query","description":"작업 관리자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"action","in":"query","description":"작업 유형","required":false,"schema":{"type":"string","enum":["ADMIN_ROLE_ASSIGNED","ADMIN_ROLE_REVOKED","USER_BAN_APPLIED","USER_BAN_RELEASED","REPORT_ACCEPTED","REPORT_DECLINED","COMMUNITY_REPORT_ACCEPTED","COMMUNITY_REPORT_DECLINED","POST_DELETED","POST_HIDDEN","POST_RESTORED","APPEAL_APPROVED","APPEAL_REJECTED","PLACE_DELETED","PLACE_BASIC_INFORMATION_UPDATED","PLACE_KAKAO_PLACE_ID_UPDATED","PLACE_GEOCODING_UPDATED","PLACE_TOURIST_INFO_UPDATED","PLACE_INFORMATION_EVIDENCE_UPDATED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_INFORMATION_REVERIFICATION_COMPLETED","PLACE_INFORMATION_REVERIFICATION_CANCELED","PLACE_INFORMATION_REVERIFICATION_EXPIRED","VISITOR_VERIFICATION_REPORT_REVIEWED","VISITOR_VERIFICATION_REPORT_CORRECTION_REVIEWED","SCOUT_FIELD_REPORT_REVIEWED","SCOUT_PROFILE_REVIEWED","SCOUT_ACTIVITY_ELIGIBILITY_REVIEWED","PLACE_DISCOVERY_STATUS_UPDATED","PLACE_OPERATING_STATUS_UPDATED","PLACE_OPERATING_SCHEDULE_UPDATED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_EVENT_CREATED","PLACE_EVENT_UPDATED","PLACE_EVENT_PUBLISHED","PLACE_EVENT_CANCELLED","PLACE_RECOMMENDATION_TRAFFIC_UPDATED","PLACE_RECOMMENDATION_KILL_SWITCH_UPDATED","TRUST_SCORE_ANOMALY_RESOLVED","TRUST_SCORE_INTERVENTION_RULE_CREATED","TRUST_SCORE_INTERVENTION_RULE_UPDATED","TRUST_SCORE_INTERVENTION_RULE_ENABLED","TRUST_SCORE_INTERVENTION_RULE_DISABLED","TRUST_SCORE_INTERVENTION_EVALUATED","NOTIFICATION_READ","NOTIFICATION_READ_ALL","PLACE_DUPLICATE_CONFIRMED","PLACE_DUPLICATE_REJECTED","PLACE_MERGED","MERCHANT_OWNER_APPROVED","MERCHANT_OWNER_REJECTED","MERCHANT_OWNER_REVOKED","MERCHANT_OWNER_PLACES_UPDATED","MERCHANT_ONBOARDING_UPDATED","MERCHANT_OPERATIONAL_QUALITY_UPDATED","MERCHANT_VERIFICATION_REVIEWED","MERCHANT_VERIFICATION_VIEWED","MERCHANT_PLACE_CLAIM_ATTACHMENT_VIEWED","MERCHANT_PLACE_CLAIM_APPROVED","MERCHANT_PLACE_CLAIM_REJECTED","MERCHANT_PLACE_APPLICATION_APPROVED","MERCHANT_PLACE_APPLICATION_REJECTED","MERCHANT_PLACE_APPLICATION_VIEWED","MERCHANT_PLACE_APPLICATION_ATTACHMENT_VIEWED","OUTBOX_EVENT_RETRIED","AD_CREATED","AD_DELETED","RESERVATION_CONFIRMED","RESERVATION_REJECTED"]},"example":"USER_BAN_APPLIED"},{"name":"targetType","in":"query","description":"대상 유형","required":false,"schema":{"type":"string","enum":["USER","REPORT","COMMUNITY_REPORT","APPEAL","POST","PLACE","PLACE_DUPLICATE_CANDIDATE","PLACE_INFORMATION_EVIDENCE","PLACE_INFORMATION_REPORT","PLACE_INFORMATION_DISPUTE","PLACE_INFORMATION_REVERIFICATION","VISITOR_VERIFICATION_REPORT","VISITOR_VERIFICATION_REPORT_CORRECTION","SCOUT_FIELD_REPORT","SCOUT_PROFILE","SCOUT_ACTIVITY_ELIGIBILITY","PLACE_OPERATING_NOTICE","PLACE_EVENT","TRUST_SCORE_ANOMALY","TRUST_SCORE_INTERVENTION_RULE","NOTIFICATION","OUTBOX_EVENT","MERCHANT_OWNER","MERCHANT_VERIFICATION","MERCHANT_PLACE_CLAIM_ATTACHMENT","MERCHANT_PLACE_CLAIM","MERCHANT_PLACE_APPLICATION","MERCHANT_PLACE_APPLICATION_ATTACHMENT","AD","RESERVATION"]},"example":"USER"},{"name":"targetId","in":"query","description":"대상 ID","required":false,"schema":{"type":"string"},"example":7},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminAuditLogResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/roles/{role}":{"delete":{"tags":["회원·권한"],"summary":"관리자 역할 회수","operationId":"revoke_2","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"role","in":"path","required":true,"schema":{"type":"string","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentRevokeRequest"}}}},"responses":{"200":{"description":"회수 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}},"404":{"description":"활성 역할을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{id}/delete":{"delete":{"tags":["신고·이의신청"],"summary":"관리자 게시글 삭제","description":"관리자가 게시글을 강제로 삭제합니다. S3 객체 삭제는 DB 삭제 확정 후 Outbox로 비동기 처리됩니다.","operationId":"deletePost","parameters":[{"name":"id","in":"path","description":"삭제할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"example":{"message":"게시글을 찾을 수 없습니다.","code":"POST_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"204":{"description":"게시글 삭제 성공"}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans":{"delete":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 삭제","description":"완료된 리포트의 삭제 후보인지 확인하고, 삭제 직전 DB에서 사용 중인 키를 다시 제외한 뒤 S3 객체를 삭제합니다.","operationId":"deleteS3Orphans","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminS3OrphanDeleteRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanDeleteResult"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/delete":{"delete":{"tags":["장소 정보·품질"],"summary":"관리자 장소 삭제","description":"관리자가 장소를 강제로 삭제합니다.","operationId":"forceDeletePlace","parameters":[{"name":"id","in":"path","description":"강제 삭제할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":5}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"409":{"description":"연결된 기간형 이벤트가 있어 장소를 삭제할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"204":{"description":"장소 삭제 성공"},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/map":{"get":{"tags":["장소 조회"],"summary":"관리자 지도 지역 집계 및 공간 그룹 조회","description":"zoom 0~8 SIDO, 9~11 SIGUNGU, 12~20 SPATIAL. 지역은 화면 안 장소 기준으로 선택하며 count는 동일 필터의 지역 전체 수입니다. bounds는 행정 경계가 아닌 PLACE_EXTENT입니다. 지역 미연결 장소는 공간 그룹/마커로 반환합니다. viewportPlaceCount와 지역 count는 합산하지 않습니다. 초기 상한 200개(설정 가능)이며 초과 시 재집계합니다. EXPAND는 nextZoom 이상 확대합니다. clusterKey는 표시용 고정 키입니다. 안전 한도 초과는 complete=false, RESULT_BUDGET_EXCEEDED, ZOOM_IN으로 안내합니다. 정상 0건은 빈 배열, viewportPlaceCount=0, complete=true입니다.","operationId":"find","parameters":[{"name":"west","in":"query","required":true,"schema":{"maximum":180,"minimum":-180,"type":"string","example":128.5},"example":128.5},{"name":"south","in":"query","required":true,"schema":{"maximum":85.05112878,"minimum":-85.05112878,"type":"string","example":35.8},"example":35.8},{"name":"east","in":"query","required":true,"schema":{"maximum":180,"minimum":-180,"type":"string","example":128.7},"example":128.7},{"name":"north","in":"query","required":true,"schema":{"maximum":85.05112878,"minimum":-85.05112878,"type":"string","example":35.95},"example":35.95},{"name":"zoom","in":"query","required":true,"schema":{"maximum":20,"minimum":0,"type":"integer","format":"int32"}},{"name":"width","in":"query","required":true,"schema":{"maximum":8192,"minimum":64,"type":"integer","format":"int32"}},{"name":"height","in":"query","required":true,"schema":{"maximum":8192,"minimum":64,"type":"integer","format":"int32"}},{"name":"keyword","in":"query","required":false,"schema":{"maxLength":100,"minLength":0,"type":"string"}},{"name":"category","in":"query","required":false,"schema":{"maxLength":100,"minLength":0,"type":"string"}},{"name":"discoveryStatus","in":"query","required":false,"schema":{"type":"string","enum":["VISIBLE","HIDDEN"]}},{"name":"operatingStatus","in":"query","required":false,"schema":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]}}],"responses":{"503":{"description":"ADMIN_PLACE_MAP_QUERY_TIMEOUT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapResponse"}}}},"200":{"description":"지역/공간 혼합 또는 빈 결과","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapResponse"},"examples":{"spatial":{"summary":"공간 그룹과 개별 장소","description":"spatial","value":{"mode":"SPATIAL","zoom":13,"regions":[],"clusters":[{"clusterKey":"v1:filterHash:resolution:x:y","clusterId":"opaque-token","count":24,"latitude":35.871,"longitude":128.601,"bounds":{"west":128.6,"south":35.87,"east":128.603,"north":35.873},"countScope":"VIEWPORT","action":"EXPAND","nextZoom":14}],"markers":[{"id":1820,"name":"예시 카페","latitude":35.875,"longitude":128.61,"category":"CAFE","discoveryStatus":"HIDDEN","operatingStatus":"OPERATING"}],"viewportPlaceCount":25,"complete":true,"incompleteReason":null,"recoveryAction":null}},"regional":{"summary":"지역 전체 수와 화면 내 수 구분","description":"regional","value":{"mode":"SIGUNGU","zoom":10,"regions":[{"regionLevel":"SIGUNGU","regionCode":"27260","name":"대구광역시 수성구","count":320,"countScope":"REGION","latitude":35.858,"longitude":128.631,"bounds":{"west":128.6,"south":35.8,"east":128.76,"north":35.9},"boundsSource":"PLACE_EXTENT","action":"EXPAND","nextZoom":12}],"clusters":[],"markers":[],"viewportPlaceCount":120,"complete":true,"incompleteReason":null,"recoveryAction":null}},"empty":{"summary":"정상 0건","description":"empty","value":{"mode":"SPATIAL","zoom":13,"regions":[],"clusters":[],"markers":[],"viewportPlaceCount":0,"complete":true,"incompleteReason":null,"recoveryAction":null}}}}}},"400":{"description":"잘못된 경계·zoom·크기·필터","content":{"application/json":{"example":{"message":"관리자 지도 조회 조건이 올바르지 않습니다.","code":"ADMIN_PLACE_MAP_INVALID_REQUEST"}}}},"401":{"description":"인증 필요","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 필요","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/map/clusters/{clusterId}/places":{"get":{"tags":["장소 조회"],"summary":"관리자 지도 그룹 내부 장소 조회","description":"원래 필터·영역·격자를 유지한 ID 오름차순 페이지. page 1~1000000, limit 1~100. 토큰은 5분 유효하며 변조·만료·그룹 변경·정책 버전 변경은 409. 409 발생 시 지도 재조회 후 그룹을 다시 선택합니다. 각 요청에서 관리자 권한을 재검사합니다.","operationId":"groupPlaces","parameters":[{"name":"clusterId","in":"path","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"400":{"description":"잘못된 페이지","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapGroupPage"}}}},"503":{"description":"ADMIN_PLACE_MAP_QUERY_TIMEOUT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapGroupPage"}}}},"401":{"description":"인증 필요","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 필요","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"ADMIN_PLACE_MAP_CLUSTER_INVALID: 지도 재조회 필요","content":{"application/json":{"example":{"message":"지도 그룹이 만료되었거나 변경되었습니다. 지도를 다시 조회해주세요.","code":"ADMIN_PLACE_MAP_CLUSTER_INVALID"}}}},"200":{"description":"그룹 내부 장소 페이지","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapGroupPage"}}}}},"security":[{"bearerAuth":[]}]}}},"components":{"schemas":{"AdminTrustScoreInterventionRuleRequest":{"required":["actionType","reason","ruleName","triggerType"],"type":"object","properties":{"ruleName":{"maxLength":100,"minLength":0,"type":"string","description":"규칙 이름","example":"low trust temporary restriction"},"triggerType":{"type":"string","description":"트리거 유형","example":"FALSE_REPORT_COUNT","enum":["TRUST_SCORE_RANGE","FALSE_REPORT_COUNT","ACCEPTANCE_RATE","ANOMALY_DETECTED"]},"actionType":{"type":"string","description":"액션 유형","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"minTrustScore":{"maximum":100,"minimum":0,"type":"integer","description":"최소 Trust Score","format":"int32","example":0},"maxTrustScore":{"maximum":100,"minimum":0,"type":"integer","description":"최대 Trust Score","format":"int32","example":60},"minSubmittedCount":{"minimum":0,"type":"integer","description":"최소 신고 수","format":"int64","example":3},"minFalseReportCount":{"minimum":0,"type":"integer","description":"최소 허위 신고 수","format":"int64","example":3},"durationDays":{"type":"integer","description":"임시 제한 기간 일수. TEMPORARY_RESTRICT일 때만 입력합니다.","format":"int32","example":7},"priority":{"minimum":0,"type":"integer","description":"우선순위. 낮을수록 먼저 적용됩니다.","format":"int32","example":10},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"개입 규칙 적용 사유","example":"허위 신고 누적 사용자 제한"}}},"AdminTrustScoreInterventionRuleItem":{"type":"object","properties":{"id":{"type":"integer","description":"개입 규칙 ID","format":"int64","example":1},"ruleName":{"type":"string","description":"규칙 이름","example":"low trust review"},"triggerType":{"type":"string","description":"트리거 유형","example":"FALSE_REPORT_COUNT","enum":["TRUST_SCORE_RANGE","FALSE_REPORT_COUNT","ACCEPTANCE_RATE","ANOMALY_DETECTED"]},"actionType":{"type":"string","description":"액션 유형","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"minTrustScore":{"type":"integer","description":"최소 Trust Score","format":"int32","example":0},"maxTrustScore":{"type":"integer","description":"최대 Trust Score","format":"int32","example":60},"minSubmittedCount":{"type":"integer","description":"최소 신고 수","format":"int64","example":3},"minFalseReportCount":{"type":"integer","description":"최소 허위 신고 수","format":"int64","example":3},"durationDays":{"type":"integer","description":"제한 기간 일수","format":"int32","example":7},"priority":{"type":"integer","description":"우선순위","format":"int32","example":10},"reason":{"type":"string","description":"적용 사유","example":"허위 신고 누적"},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}}},"MerchantOwnerPlaceUpdateRequest":{"type":"object","properties":{"placeIds":{"maxItems":100,"minItems":0,"uniqueItems":true,"type":"array","items":{"type":"integer","format":"int64"}},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerProfileResponse":{"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"businessName":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string","nullable":true},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]},"onboardingStatus":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"]},"onboardingCompletionRate":{"type":"integer","format":"int32"},"onboardingCompletedAt":{"type":"string","format":"date-time","nullable":true},"reviewedBy":{"type":"integer","format":"int64","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"reviewReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"placeIds":{"type":"array","items":{"type":"integer","format":"int64"}}},"description":"Merchant Owner 프로필 응답"},"MerchantOwnerPlaceQualityUpdateRequest":{"required":["noShowRate","reservationCancellationRate","reservationResponseRate","status"],"type":"object","properties":{"status":{"type":"string","enum":["UNMEASURED","HEALTHY","NEEDS_ATTENTION","AT_RISK"]},"reservationResponseRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"reservationCancellationRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"noShowRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"evaluatedAt":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerPlaceResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"operationalQualityStatus":{"type":"string","enum":["UNMEASURED","HEALTHY","NEEDS_ATTENTION","AT_RISK"]},"reservationResponseRate":{"type":"integer","format":"int32"},"reservationCancellationRate":{"type":"integer","format":"int32"},"noShowRate":{"type":"integer","format":"int32"},"qualityEvaluatedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"MerchantOnboardingUpdateRequest":{"required":["completionRate","status"],"type":"object","properties":{"status":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"]},"completionRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"completedAt":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"VisitorVerificationReportReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"VisitorVerificationReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"waitTimeMinutes":{"type":"integer","format":"int32"},"languageCode":{"type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"VisitorVerificationReportCorrectionReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"ErrorResponse":{"required":["message"],"type":"object","properties":{"message":{"type":"string","description":"에러 메시지","example":"유효하지 않은 토큰입니다."},"code":{"type":"string","description":"도메인 에러 코드. 일부 공통 검증 오류에서는 제공되지 않을 수 있습니다.","nullable":true,"example":"INVALID_TOKEN"}},"description":"에러 응답"},"VisitorVerificationReportCorrectionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"requesterUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"waitTimeMinutes":{"type":"integer","format":"int32"},"languageCode":{"type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]},"reportStatus":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"VerifiedBoostProductCreateRequest":{"required":["description","durationDays","name","priceAmount"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","example":"Verified Boost 7일"},"description":{"maxLength":500,"minLength":0,"type":"string","example":"검증된 장소의 추천 노출을 7일간 강화합니다."},"priceAmount":{"type":"integer","description":"KRW 기준 가격","format":"int64","example":30000},"durationDays":{"maximum":365,"minimum":1,"type":"integer","format":"int32","example":7}}},"VerifiedBoostProductResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"name":{"type":"string"},"description":{"type":"string"},"priceAmount":{"type":"integer","description":"KRW 기준 가격","format":"int64","example":30000},"durationDays":{"type":"integer","format":"int32","example":7},"status":{"type":"string","enum":["DRAFT","ACTIVE","INACTIVE"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminRoleAssignmentRequest":{"required":["role"],"type":"object","properties":{"role":{"type":"string","description":"할당할 관리자 역할","example":"CONTENT_MODERATOR","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"역할을 부여하거나 회수하는 사유","example":"장소 정보 검수 담당 배정"}},"description":"관리자 역할 할당 요청"},"AdminRoleAssignmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"adminUserId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"assignedByUserId":{"type":"integer","format":"int64"},"assignedAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time"},"permissions":{"type":"array","items":{"type":"string","enum":["ADMIN_ROLE_MANAGE","USER_READ","USER_SANCTION","PLACE_READ","PLACE_MODERATE","MERCHANT_REVIEW","REPORT_REVIEW","SCOUT_REVIEW","DASHBOARD_READ","AUDIT_READ","OUTBOX_RECOVERY"]}}},"description":"관리자 역할 할당 응답"},"AdminTrustScoreInterventionEvaluationResponse":{"type":"object","properties":{"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":12},"trustScore":{"type":"integer","description":"현재 Trust Score","format":"int32","example":40},"matchedRuleId":{"type":"integer","description":"매칭된 규칙 ID","format":"int64","example":1},"matchedRuleName":{"type":"string","description":"매칭된 규칙 이름","example":"low trust temporary restriction"},"actionType":{"type":"string","description":"적용 액션","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"restrictedUntil":{"type":"string","description":"제한 만료 시각","format":"date-time"},"message":{"type":"string","description":"처리 결과 메시지","example":"Trust Score 개입 규칙을 적용했습니다."}}},"AdminTrustScoreBatchResponse":{"type":"object","properties":{"processedCount":{"type":"integer","format":"int32"},"changedCount":{"type":"integer","format":"int32"}}},"ScoutProfileReviewRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutProfileResponse":{"required":["activityEligibilityStatus","createdAt","displayName","eligibilityReviewedAt","eligibilityReviewedByAdminUserId","eligibilityStatusReason","eligibleFrom","eligibleUntil","introduction","profileReviewedAt","profileReviewedByAdminUserId","profileStatus","profileStatusReason","updatedAt","userId"],"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"displayName":{"type":"string"},"introduction":{"type":"string","nullable":true},"profileStatus":{"type":"string","enum":["PENDING","ACTIVE","SUSPENDED","REVOKED"]},"profileReviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"profileReviewedAt":{"type":"string","format":"date-time","nullable":true},"profileStatusReason":{"type":"string","nullable":true},"activityEligibilityStatus":{"type":"string","enum":["PENDING","ELIGIBLE","SUSPENDED","EXPIRED","REVOKED"]},"eligibleFrom":{"type":"string","format":"date-time","nullable":true},"eligibleUntil":{"type":"string","format":"date-time","nullable":true},"eligibilityReviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"eligibilityReviewedAt":{"type":"string","format":"date-time","nullable":true},"eligibilityStatusReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Scout 프로필 및 활동 자격 응답"},"ScoutActivityEligibilityReviewRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutActivityEligibilityGrantRequest":{"required":["eligibleFrom"],"type":"object","properties":{"eligibleFrom":{"type":"string","format":"date-time"},"eligibleUntil":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutFieldReportReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutFieldReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"scoutUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","CROWD_LEVEL","SAFETY","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminReservationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"quantity":{"type":"integer","format":"int32"},"touristUserId":{"type":"integer","format":"int64"},"touristUsername":{"type":"string"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"merchantOwnerUsername":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"availabilityId":{"type":"integer","format":"int64"},"reservationStartsAt":{"type":"string","format":"date-time"},"reservationEndsAt":{"type":"string","format":"date-time"},"bookerName":{"type":"string"},"bookerPhone":{"type":"string"},"requestNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"confirmedAt":{"type":"string","format":"date-time"},"reviewedBy":{"type":"integer","format":"int64"},"reviewedAt":{"type":"string","format":"date-time"},"reviewReason":{"type":"string"},"rejectedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"canceledBy":{"type":"integer","format":"int64"},"statusHistory":{"type":"array","items":{"$ref":"#/components/schemas/AdminReservationStatusHistoryResponse"}}}},"AdminReservationStatusHistoryResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"changedBy":{"type":"integer","format":"int64"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}},"AdminReportAppealActionRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminReportAppealActionResponse":{"type":"object","properties":{"appealId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]},"processedAt":{"type":"string","format":"date-time"}}},"AdminPostReportBulkActionResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":10},"status":{"type":"string","description":"일괄 처리된 신고 상태","example":"ACCEPTED","enum":["PENDING","ACCEPTED","DECLINED","RESTORED"]},"processedReportCount":{"type":"integer","description":"처리된 신고 수","format":"int32","example":3},"visibilityStatus":{"type":"string","description":"게시글 공개 상태","example":"AUTO_HIDDEN","enum":["ACTIVE","AUTO_HIDDEN"]},"hiddenAt":{"type":"string","description":"게시글 숨김 처리 시각","format":"date-time"},"hiddenReason":{"type":"string","description":"게시글 숨김 사유","example":"REPORT_BULK_ACCEPTED"},"processedAt":{"type":"string","description":"신고 처리 시각","format":"date-time"}},"description":"관리자 게시글 단위 신고 일괄 처리 응답"},"S3OrphanReportStatus":{"type":"object","properties":{"reportId":{"type":"string"},"status":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"dbKeyCount":{"type":"integer","format":"int64"},"s3KeyCount":{"type":"integer","format":"int64"},"deleteCandidateCount":{"type":"integer","format":"int64"},"errorMessage":{"type":"string"}}},"PlaceOperatingNoticeCreateRequest":{"required":["expiresAt","message","noticeType","severity","startsAt"],"type":"object","properties":{"noticeType":{"type":"string","enum":["TEMPORARY_CLOSURE","HOURS_CHANGE","CROWDING","REOPENING","GENERAL"]},"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"message":{"maxLength":500,"minLength":0,"type":"string"},"startsAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}},"description":"상점 운영 상태 공지 생성 요청"},"PlaceOperatingNoticeResponse":{"required":["cancelReason","canceledAt","createdAt","expiredAt","expiresAt","id","message","noticeType","placeId","severity","startsAt","status","updatedAt","visibleNow"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"noticeType":{"type":"string","enum":["TEMPORARY_CLOSURE","HOURS_CHANGE","CROWDING","REOPENING","GENERAL"]},"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"status":{"type":"string","enum":["SCHEDULED","ACTIVE","EXPIRED","CANCELED"]},"message":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"expiredAt":{"type":"string","format":"date-time","nullable":true},"canceledAt":{"type":"string","format":"date-time","nullable":true},"cancelReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"visibleNow":{"type":"boolean"}},"description":"상점 운영 상태 공지 응답"},"PlaceOperatingNoticeCancelRequest":{"required":["cancelReason"],"type":"object","properties":{"cancelReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"상점 운영 상태 공지 취소 요청"},"PlaceInformationReverificationCreateRequest":{"required":["dueAt","reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"},"dueAt":{"type":"string","format":"date-time"}}},"PlaceInformationReverificationResponse":{"type":"object","properties":{"requestId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["REQUESTED","RESPONDED","COMPLETED","CANCELED","EXPIRED"]},"reason":{"type":"string"},"requestedAt":{"type":"string","format":"date-time"},"dueAt":{"type":"string","format":"date-time"},"lastRemindedAt":{"type":"string","format":"date-time"},"reminderCount":{"type":"integer","format":"int32"},"respondedAt":{"type":"string","format":"date-time"},"responseNote":{"type":"string"},"completedAt":{"type":"string","format":"date-time"}}},"AdminPlaceInformationEvidenceCreateRequest":{"required":["evidenceType","sourceType"],"type":"object","properties":{"sourceType":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"evidenceType":{"type":"string","enum":["EXTERNAL_PLACE_ID","BUSINESS_CLAIM","DOCUMENT","PHOTO","ADMIN_REVIEW","USER_VISIT","SYSTEM_SIGNAL"]},"externalReference":{"maxLength":100,"minLength":0,"type":"string","description":"외부 장소 ID, 사업자 등록 번호 등 외부 참조값","nullable":true},"referenceUrl":{"maxLength":500,"minLength":0,"type":"string","description":"증빙 URL","nullable":true},"description":{"maxLength":1000,"minLength":0,"type":"string","description":"관리자 메모 또는 증빙 설명","nullable":true},"submittedByUserId":{"type":"integer","description":"증빙 제출 사용자 ID. 미입력 시 관리자 ID를 사용","format":"int64","nullable":true}},"description":"관리자 장소 정보 증빙 등록 요청"},"AdminPlaceInformationEvidenceItem":{"type":"object","properties":{"evidenceId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"sourceType":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"evidenceType":{"type":"string","enum":["EXTERNAL_PLACE_ID","BUSINESS_CLAIM","DOCUMENT","PHOTO","ADMIN_REVIEW","USER_VISIT","SYSTEM_SIGNAL"]},"verificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"externalReference":{"type":"string","nullable":true},"referenceUrl":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"submittedByUserId":{"type":"integer","format":"int64","nullable":true},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"관리자 장소 정보 증빙 항목"},"AdminPlaceInformationEvidenceUpdateResponse":{"type":"object","properties":{"evidence":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceItem"},"message":{"type":"string"}},"description":"관리자 장소 정보 증빙 변경 응답"},"AdminPlaceRecommendationSnapshotResyncResponse":{"type":"object","properties":{"placeCount":{"type":"integer","format":"int64"},"synchronizedSnapshotCount":{"type":"integer","format":"int64"},"deletedSnapshotCount":{"type":"integer","format":"int64"},"synchronizedSimilaritySnapshotCount":{"type":"integer","format":"int64"},"deletedSimilaritySnapshotCount":{"type":"integer","format":"int64"},"synchronizedVersionSnapshotCount":{"type":"integer","format":"int64"},"deletedVersionSnapshotCount":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminMapPlaceMergeRequest":{"type":"object","properties":{"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"candidateId":{"type":"integer","format":"int64"}}},"AdminMapPlaceMergeResponse":{"type":"object","properties":{"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminPlaceMergeRestoreResponse":{"type":"object","properties":{"historyId":{"type":"integer","format":"int64"},"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminPlaceDuplicateDecisionRequest":{"required":["reviewNote"],"type":"object","properties":{"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminPlaceDuplicateCandidateResponse":{"type":"object","properties":{"candidateId":{"type":"integer","format":"int64"},"leftPlaceId":{"type":"integer","format":"int64"},"rightPlaceId":{"type":"integer","format":"int64"},"matchReason":{"type":"string"},"confidenceScore":{"type":"number"},"distanceMeters":{"type":"integer","format":"int32"},"status":{"type":"string"},"reviewedByAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"mergeHistoryId":{"type":"integer","format":"int64"},"detectedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminPlaceDuplicateMergeRequest":{"required":["targetPlaceId"],"type":"object","properties":{"targetPlaceId":{"type":"integer","format":"int64"}}},"PlaceReviewDeletionRequestReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminPlaceReviewDeletionRequestResponse":{"type":"object","properties":{"deletionRequestId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"requestReason":{"type":"string"},"requesterUserId":{"type":"integer","format":"int64"},"requestedAt":{"type":"string","format":"date-time"},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"reviewedAt":{"type":"string","format":"date-time"},"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reviewAuthorUserId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"reviewVisibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]},"reviewCreatedAt":{"type":"string","format":"date-time"}}},"PlaceReviewMediaResponse":{"type":"object","properties":{"reviewMediaId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"contentType":{"type":"string"}},"description":"리뷰에 연결된 검증 완료 사진"},"PlaceInformationReportReviewRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","description":"UNDER_REVIEW, ACCEPTED, REJECTED, RESOLVED만 허용","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"관리자 장소 정보 신고 검토 요청"},"PlaceInformationDisputeResponse":{"type":"object","properties":{"disputeId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"disputedByUserId":{"type":"integer","format":"int64"},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"장소 정보 반박 응답"},"PlaceInformationReportResponse":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"evidenceId":{"type":"integer","format":"int64","nullable":true},"reporterUserId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["NAME","ADDRESS","GEOLOCATION","OPERATING_STATUS","TOURIST_INFORMATION","SOURCE_EVIDENCE","MEDIA","OTHER"]},"reasonType":{"type":"string","enum":["INCORRECT","OUTDATED","MISSING","MISLEADING","DUPLICATE","CLOSED_OR_MOVED","SPAM_OR_ABUSE","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"status":{"type":"string","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"resolvedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"disputes":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}},"description":"장소 정보 신고 응답"},"PlaceInformationDisputeReviewRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","description":"ACCEPTED 또는 REJECTED만 허용","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"관리자 장소 정보 반박 검토 요청"},"AdminPlaceEventRequest":{"required":["endAt","eventType","placeId","reason","startAt","title"],"type":"object","properties":{"placeId":{"type":"integer","description":"행사 장소 ID","format":"int64","example":17},"title":{"maxLength":150,"minLength":0,"type":"string","description":"이벤트 제목","example":"진주 여름 빛 축제"},"description":{"maxLength":1000,"minLength":0,"type":"string","description":"이벤트 설명","example":"남강을 배경으로 열리는 야간 공연과 전시입니다."},"eventType":{"type":"string","description":"이벤트 유형","example":"EXHIBITION","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","description":"시작 시각","format":"date-time"},"endAt":{"type":"string","description":"종료 시각","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"관리자 변경 사유","example":"공식 일정 등록"}},"description":"관리자 기간형 이벤트 등록·수정 요청"},"AdminPlaceEventResponse":{"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"publicationStatus":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]},"message":{"type":"string"}},"description":"관리자 기간형 이벤트 응답"},"AdminPlaceEventActionRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"변경 사유","example":"운영 검토를 완료했습니다."}},"description":"관리자 이벤트 상태 변경 요청"},"AdminOutboxEventRetryRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"장애 원인 제거와 중복 처리 안전성을 확인한 재처리 사유","example":"외부 메일 공급자 장애 복구 확인"}},"description":"관리자 Outbox 이벤트 재처리 요청"},"AdminOutboxEventItem":{"type":"object","properties":{"eventId":{"type":"string","description":"이벤트 ID"},"eventType":{"type":"string","description":"이벤트 유형","example":"EMAIL_VERIFICATION_REQUESTED","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"aggregateType":{"type":"string","description":"aggregate 유형","example":"USER"},"aggregateId":{"type":"string","description":"aggregate ID","example":"10"},"status":{"type":"string","description":"처리 상태","example":"FAILED","enum":["PENDING","PROCESSING","RETRY","SUCCEEDED","FAILED"]},"attemptCount":{"type":"integer","description":"현재 재시도 주기의 실패 횟수","format":"int32","example":5},"nextAttemptAt":{"type":"string","description":"다음 처리 가능 시각","format":"date-time"},"processingStartedAt":{"type":"string","description":"처리 선점 시각","format":"date-time"},"processedAt":{"type":"string","description":"처리 완료 시각","format":"date-time"},"lastError":{"type":"string","description":"마지막 실패 원인"},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}},"description":"관리자 Outbox 이벤트 운영 조회 항목"},"MerchantPlaceApplicationReviewRequest":{"required":["reviewedVersion"],"type":"object","properties":{"reviewedVersion":{"type":"integer","format":"int64"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"BreakTime":{"required":["closesAt","opensAt"],"type":"object","properties":{"opensAt":{"$ref":"#/components/schemas/LocalTime"},"closesAt":{"$ref":"#/components/schemas/LocalTime"}}},"LocalTime":{"type":"object","properties":{"hour":{"type":"integer","format":"int32"},"minute":{"type":"integer","format":"int32"},"second":{"type":"integer","format":"int32"},"nano":{"type":"integer","format":"int32"}}},"MerchantPlaceApplicationAttachmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"fileId":{"type":"string"},"documentType":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"uploadedAt":{"type":"string","format":"date-time"},"retentionExpiresAt":{"type":"string","format":"date-time"},"displayOrder":{"type":"integer","format":"int32"}}},"MerchantPlaceApplicationNewPlaceResponse":{"type":"object","properties":{"placeName":{"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"description":{"type":"string"},"businessContactPhone":{"type":"string"},"applicantContactPhone":{"type":"string"},"tags":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["ENGLISH_SERVICE_AVAILABLE","ENGLISH_MENU_AVAILABLE","RESERVATION_AVAILABLE","RESERVATION_COUPON_AVAILABLE","GENERAL_COUPON_AVAILABLE","GOOD_AMBIENCE"]}},"timezone":{"type":"string"},"operatingDays":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegistrationOperatingDay"}}}},"MerchantPlaceApplicationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"merchantDisplayName":{"type":"string"},"merchantContactEmail":{"type":"string"},"merchantDescription":{"type":"string"},"merchantContactPhone":{"type":"string"},"newPlace":{"$ref":"#/components/schemas/MerchantPlaceApplicationNewPlaceResponse"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"type":"string"},"reviewReason":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"version":{"type":"integer","format":"int64"},"submissionVersion":{"type":"integer","format":"int64"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceApplicationAttachmentResponse"}}}},"PlaceRegistrationOperatingDay":{"required":["dayOfWeek","status"],"type":"object","properties":{"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"status":{"type":"string","enum":["OPEN","CLOSED","OPEN_24_HOURS"]},"opensAt":{"$ref":"#/components/schemas/LocalTime"},"closesAt":{"$ref":"#/components/schemas/LocalTime"},"breakTimes":{"type":"array","items":{"$ref":"#/components/schemas/BreakTime"}}}},"MerchantOwnerReviewRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminCommunityReportActionResponse":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"targetHidden":{"type":"boolean"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 처리 결과"},"BanRequest":{"type":"object","properties":{"reason":{"maxLength":255,"minLength":0,"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"expiresAt":{"type":"string","description":"기간 밴 종료 시각. 비우면 영구 밴으로 처리됩니다.","format":"date-time"},"durationDays":{"minimum":1,"type":"integer","description":"현재 시각부터 적용할 밴 기간(일). expiresAt과 동시에 사용할 수 없습니다.","format":"int64","example":7}},"description":"관리자 밴 처리 요청 정보"},"BanResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"밴 처리된 사용자 ID","format":"int64","example":7},"banned":{"type":"boolean","description":"밴 여부","example":true},"bannedAt":{"type":"string","description":"밴 처리 시각","format":"date-time"},"reason":{"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"banType":{"type":"string","description":"밴 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"}},"description":"관리자 밴 처리 응답"},"UnbanRequest":{"type":"object","properties":{"reason":{"maxLength":255,"minLength":0,"type":"string","description":"밴 해제 사유","example":"운영 검토 결과 해제"}},"description":"관리자 밴 해제 요청 정보"},"UnbanResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"밴 해제된 사용자 ID","format":"int64","example":7},"banned":{"type":"boolean","description":"현재 밴 여부","example":false},"releasedAt":{"type":"string","description":"밴 해제 처리 시각","format":"date-time"},"reason":{"type":"string","description":"밴 해제 사유","example":"운영 검토 결과 해제"}},"description":"관리자 밴 해제 응답"},"AdminTrustScoreInterventionRuleToggleResponse":{"type":"object","properties":{"ruleId":{"type":"integer","description":"개입 규칙 ID","format":"int64","example":1},"enabled":{"type":"boolean","description":"활성화 여부","example":false},"message":{"type":"string","description":"처리 결과 메시지","example":"Trust Score 개입 규칙을 비활성화했습니다."}}},"AdminTrustScoreAnomalyResolveRequest":{"required":["resolutionReason"],"type":"object","properties":{"resolutionReason":{"maxLength":500,"minLength":0,"type":"string","description":"이상치 해결 사유","example":"관리자 검토 후 정상 패턴으로 확인했습니다."}}},"AdminTrustScoreAnomalyItem":{"type":"object","properties":{"id":{"type":"integer","description":"Trust Score 이상치 ID","format":"int64","example":1},"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":12},"reporterUsername":{"type":"string","description":"신고자 username","example":"ping-user"},"anomalyType":{"type":"string","description":"이상치 유형","example":"FALSE_REPORT_SPIKE","enum":["RAPID_DROP","FALSE_REPORT_SPIKE","LOW_ACCEPTANCE_RATE","MANUAL_REVIEW"]},"severity":{"type":"string","description":"이상치 심각도","example":"HIGH","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"baselineScore":{"type":"integer","description":"기준 Trust Score","format":"int32","example":100},"observedScore":{"type":"integer","description":"감지 시점 Trust Score","format":"int32","example":40},"submittedCount":{"type":"integer","description":"전체 신고 수","format":"int64","example":5},"acceptedCount":{"type":"integer","description":"수락 신고 수","format":"int64","example":1},"declinedCount":{"type":"integer","description":"거절 신고 수","format":"int64","example":4},"falseReportCount":{"type":"integer","description":"허위 신고 수","format":"int64","example":4},"detectedAt":{"type":"string","description":"감지 시각","format":"date-time"},"resolvedAt":{"type":"string","description":"해결 시각","format":"date-time"},"resolutionReason":{"type":"string","description":"해결 사유","example":"관리자 검토 완료"}},"description":"이상치 목록"},"PlaceOperatingNoticeUpdateRequest":{"required":["message","severity"],"type":"object","properties":{"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"message":{"maxLength":500,"minLength":0,"type":"string"}},"description":"상점 운영 상태 공지 수정 요청"},"AdminMapPlaceTouristInfoUpdateRequest":{"required":["reason"],"type":"object","properties":{"englishName":{"maxLength":150,"minLength":0,"type":"string","description":"영문 장소명. 공백 또는 null이면 제거합니다.","nullable":true,"example":"Jinju Castle"},"touristSummary":{"maxLength":500,"minLength":0,"type":"string","description":"관광객용 장소 요약. 공백 또는 null이면 제거합니다.","nullable":true},"touristCategories":{"maxItems":9,"minItems":0,"uniqueItems":true,"type":"array","description":"관광 목적 카테고리 전체 목록. 생략하면 모두 제거합니다.","items":{"type":"string","description":"관광 목적 카테고리 전체 목록. 생략하면 모두 제거합니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"영문 정보와 관광 분류 최신화"}},"description":"관리자 장소 관광 정보 전체 교체 요청"},"AdminMapPlaceTouristInfoUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"message":{"type":"string"}}},"AdminMapPlaceOperatingStatusUpdateRequest":{"required":["operatingStatus","reason"],"type":"object","properties":{"operatingStatus":{"type":"string","description":"확인된 장소 운영 상태","example":"TEMPORARILY_CLOSED","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 확인 근거","example":"현장 확인 결과 임시 휴업"}},"description":"관리자 장소 운영 상태 확인 요청"},"AdminMapPlaceOperatingStatusUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","description":"운영 상태 최신 확인 시각","format":"date-time"},"message":{"type":"string"}}},"AdminMapPlaceOperatingExceptionRequest":{"required":["date"],"type":"object","properties":{"date":{"type":"string","format":"date","example":"2026-08-15"},"closed":{"type":"boolean","description":"true이면 종일 휴무이며 hours는 비워야 합니다.","example":true},"hours":{"uniqueItems":true,"type":"array","description":"대체 영업 시간대. closed가 false이면 하나 이상 필요합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingTimeRangeRequest"}}},"description":"관리자 특정 날짜 영업 예외"},"AdminMapPlaceOperatingScheduleUpdateRequest":{"required":["reason"],"type":"object","properties":{"regularHours":{"uniqueItems":true,"type":"array","description":"요일별 정규 영업 시간대. 생략하면 모두 제거합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceRegularOperatingHourRequest"}},"exceptions":{"uniqueItems":true,"type":"array","description":"특정 날짜의 휴무 또는 대체 영업 일정. 생략하면 모두 제거합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingExceptionRequest"}},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"광복절 휴무와 주말 영업시간 반영"}},"description":"관리자 장소 정규 영업시간과 예외 일정 전체 교체 요청"},"AdminMapPlaceOperatingTimeRangeRequest":{"required":["closesAt","opensAt"],"type":"object","properties":{"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"관리자 장소 운영 시간대"},"AdminMapPlaceRegularOperatingHourRequest":{"required":["closesAt","dayOfWeek","opensAt"],"type":"object","properties":{"dayOfWeek":{"type":"string","example":"MONDAY","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"관리자 요일별 정규 영업 시간대"},"AdminMapPlaceOperatingScheduleUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"exceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"message":{"type":"string"}}},"PlaceOperatingExceptionResponse":{"type":"object","properties":{"date":{"type":"string","format":"date","example":"2026-08-15"},"closed":{"type":"boolean","description":"true이면 종일 휴무이며 hours는 비어 있습니다."},"hours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingTimeRangeResponse"}}},"description":"특정 날짜의 휴무 또는 대체 영업 시간"},"PlaceOperatingTimeRangeResponse":{"type":"object","properties":{"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"하루 중 장소 운영 시간대"},"PlaceRegularOperatingHourResponse":{"type":"object","properties":{"dayOfWeek":{"type":"string","example":"MONDAY","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"요일별 정규 영업 시간대"},"AdminMapPlaceKakaoPlaceIdUpdateRequest":{"type":"object","properties":{"kakaoPlaceId":{"maxLength":50,"minLength":0,"type":"string"}}},"AdminMapPlaceKakaoPlaceIdUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"kakaoPlaceId":{"type":"string"},"message":{"type":"string"}}},"AdminPlaceInformationEvidenceReviewRequest":{"required":["verificationStatus"],"type":"object","properties":{"verificationStatus":{"type":"string","description":"관리자 검토 결과. ADMIN_VERIFIED 또는 REJECTED만 허용","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string","description":"검토 사유. REJECTED일 때 필수","nullable":true}},"description":"관리자 장소 정보 증빙 검토 요청"},"AdminMapPlaceGeocodingUpdateRequest":{"required":["address","latitude","longitude","reason"],"type":"object","properties":{"address":{"maxLength":255,"minLength":0,"type":"string"},"roadAddress":{"maxLength":255,"minLength":0,"type":"string"},"jibunAddress":{"maxLength":255,"minLength":0,"type":"string"},"postalCode":{"maxLength":20,"minLength":0,"type":"string"},"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminMapPlaceGeocodingUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"address":{"type":"string"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"message":{"type":"string"}}},"AdminMapPlaceDiscoveryStatusUpdateRequest":{"required":["discoveryStatus","reason"],"type":"object","properties":{"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"HIDDEN","enum":["VISIBLE","HIDDEN"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"중복 장소 검수 전 임시 숨김"}},"description":"관리자 장소 탐색 노출 상태 수정 요청"},"AdminMapPlaceDiscoveryStatusUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"HIDDEN","enum":["VISIBLE","HIDDEN"]},"message":{"type":"string"}},"description":"관리자 장소 탐색 노출 상태 수정 응답"},"AdminMapPlaceCoordinateUpdateRequest":{"required":["latitude","longitude"],"type":"object","properties":{"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"}}},"AdminMapPlaceCoordinateUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"message":{"type":"string"}}},"AdminMapPlaceBasicInformationUpdateRequest":{"required":["category","name","reason"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","description":"수정할 장소명","example":"진주성"},"category":{"type":"string","description":"수정할 표준 장소 카테고리","example":"CULTURAL_HERITAGE","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"장소명과 분류 오등록 정정"}},"description":"관리자 장소 기본 정보 수정 요청"},"AdminMapPlaceBasicInformationUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"modifiedAt":{"type":"string","description":"감사 로그에 기록된 기본 정보 수정 시각","format":"date-time"},"message":{"type":"string"}},"description":"관리자 장소 기본 정보 수정 응답"},"AdminPlaceRecommendationTrafficUpdateItem":{"required":["recommendationVersion"],"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v2"},"trafficPercentage":{"maximum":100,"minimum":0,"type":"integer","description":"트래픽 비율","format":"int32","example":30},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"fallbackVersion":{"type":"string","description":"비활성화된 추천 버전 요청 시 대체할 버전","nullable":true,"example":"place-rec-v1"}},"description":"수정할 추천 버전별 트래픽 비율 목록"},"AdminPlaceRecommendationTrafficUpdateRequest":{"required":["policies","reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"추천 정책 변경 사유","example":"추천 실험 v2 트래픽을 확대합니다."},"policies":{"type":"array","description":"수정할 추천 버전별 트래픽 비율 목록","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateItem"}}}},"AdminPlaceRecommendationTrafficPolicyItem":{"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v1"},"stage":{"type":"string","description":"추천 단계","example":"STABLE"},"trafficPercentage":{"type":"integer","description":"트래픽 비율","format":"int32","example":70},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"fallbackVersion":{"type":"string","description":"비활성화 시 fallback 추천 버전","nullable":true,"example":"place-rec-v1"}},"description":"현재 추천 버전별 트래픽 정책"},"AdminPlaceRecommendationTrafficUpdateResponse":{"type":"object","properties":{"defaultVersion":{"type":"string","description":"기본 추천 버전","example":"place-rec-v1"},"policies":{"type":"array","description":"현재 추천 버전별 트래픽 정책","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficPolicyItem"}},"message":{"type":"string","description":"수정 결과 메시지","example":"추천 버전 트래픽 비율을 수정했습니다."}}},"AdminNotificationReadResponse":{"type":"object","properties":{"notificationId":{"type":"integer","description":"읽음 처리된 알림 ID","format":"int64","example":1},"read":{"type":"boolean","description":"읽음 여부","example":true},"message":{"type":"string","description":"처리 메시지","example":"알림을 읽음 처리했습니다."}},"description":"관리자 알림 읽음 처리 응답"},"AdminNotificationReadAllResponse":{"type":"object","properties":{"updatedCount":{"type":"integer","description":"읽음 처리된 알림 개수","format":"int64","example":3},"message":{"type":"string","description":"처리 메시지","example":"전체 알림을 읽음 처리했습니다."}},"description":"관리자 전체 알림 읽음 처리 응답"},"VisitorVerificationReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/VisitorVerificationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"VisitorVerificationReportCorrectionPageResponse":{"type":"object","properties":{"corrections":{"type":"array","items":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"VerifiedBoostProductPageResponse":{"type":"object","properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminUserSanctionHistoryItem":{"type":"object","properties":{"historyId":{"type":"integer","description":"제재 이력 ID","format":"int64","example":1},"targetUserId":{"type":"integer","description":"대상 사용자 ID","format":"int64","example":7},"targetUsername":{"type":"string","description":"대상 사용자명","example":"blockedUser01"},"banType":{"type":"string","description":"제재 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"action":{"type":"string","description":"처리 상태","example":"APPLIED","enum":["APPLIED","RELEASED","EXPIRED"]},"reason":{"type":"string","description":"처리 사유","example":"반복적인 신고 누적"},"startedAt":{"type":"string","description":"제재 시작 시각","format":"date-time"},"endedAt":{"type":"string","description":"제재 종료 시각","format":"date-time"},"adminUserId":{"type":"integer","description":"처리 관리자 ID","format":"int64","example":1},"adminUsername":{"type":"string","description":"처리 관리자명","example":"admin"},"processedAt":{"type":"string","description":"처리 시각","format":"date-time"}},"description":"관리자 사용자 제재 이력 아이템"},"AdminUserSanctionHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/AdminUserSanctionHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 사용자 제재 이력 목록 응답"},"AdminUserSanctionStatusResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"banned":{"type":"boolean","description":"현재 제재 여부","example":true},"banType":{"type":"string","description":"제재 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"bannedAt":{"type":"string","description":"제재 시작 시각","format":"date-time"},"banExpiresAt":{"type":"string","description":"제재 종료 시각","format":"date-time"},"banReason":{"type":"string","description":"제재 사유","example":"반복적인 신고 누적"}},"description":"관리자 사용자 제재 상태 조회 응답"},"AdminRoleAssignmentTargetItem":{"type":"object","properties":{"userId":{"type":"integer","description":"역할 API에 전달할 사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"admin_operator"}},"description":"관리자 역할 부여 대상 사용자"},"AdminRoleAssignmentTargetSearchResponse":{"type":"object","properties":{"users":{"type":"array","description":"현재 페이지의 역할 부여 대상 사용자","items":{"$ref":"#/components/schemas/AdminRoleAssignmentTargetItem"}},"page":{"type":"integer","description":"현재 페이지 번호(1부터 시작)","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"검색 조건에 맞는 전체 사용자 수","format":"int64","example":12},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false}},"description":"관리자 역할 부여 대상 사용자 검색 응답"},"AdminBannedUserCounts":{"type":"object","properties":{"total":{"type":"integer","description":"현재 밴 중인 전체 사용자 수","format":"int64","example":12},"permanent":{"type":"integer","description":"현재 영구 밴 중인 사용자 수","format":"int64","example":7},"temporary":{"type":"integer","description":"현재 기간 밴 중인 사용자 수","format":"int64","example":5}},"description":"현재 밴 사용자 필터별 카운트"},"AdminBannedUserItem":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"banned":{"type":"boolean","description":"밴 처리 여부","example":true},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"bannedAt":{"type":"string","description":"밴 처리 시각","format":"date-time"},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"}},"description":"밴 유저 목록 아이템"},"AdminBannedUserResponse":{"type":"object","properties":{"users":{"type":"array","description":"현재 페이지의 밴 사용자 목록","items":{"$ref":"#/components/schemas/AdminBannedUserItem"}},"page":{"type":"integer","description":"현재 페이지 번호(1부터 시작)","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"조회 조건에 맞는 현재 밴 사용자 전체 수","format":"int64","example":12},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int64","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false},"counts":{"$ref":"#/components/schemas/AdminBannedUserCounts"}},"description":"밴 유저 목록 조회 응답"},"AdminBannedUserDetailResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"email":{"type":"string","description":"이메일","example":"blockedUser01@example.com"},"birthYear":{"type":"integer","description":"출생연도","format":"int32","example":1998},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"role":{"type":"string","description":"권한","example":"USER"},"banned":{"type":"boolean","description":"밴 여부","example":true},"bannedAt":{"type":"string","description":"밴 시각","format":"date-time"},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"},"banReason":{"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"createdAt":{"type":"string","description":"가입 시각","format":"date-time"}},"description":"밴 유저 상세 조회 응답"},"AdminTrustScoreEvidenceResponse":{"type":"object","properties":{"submittedCount":{"type":"integer","description":"신고 제출 수","format":"int64","example":12},"acceptedCount":{"type":"integer","description":"승인된 신고 수","format":"int64","example":8},"declinedCount":{"type":"integer","description":"반려된 신고 수","format":"int64","example":4},"falseReportCount":{"type":"integer","description":"허위 신고 수","format":"int64","example":3},"acceptanceRate":{"type":"number","description":"승인률","format":"double","example":66.67},"baseScore":{"type":"integer","description":"기본 점수","format":"int32","example":100},"acceptedScoreBonus":{"type":"integer","description":"승인 신고 가산점 합계","format":"int64","example":40},"falseReportScorePenalty":{"type":"integer","description":"허위 신고 감점 합계","format":"int64","example":60}},"description":"신뢰 점수 산정 근거"},"AdminTrustScoreResponse":{"type":"object","properties":{"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":7},"reporterUsername":{"type":"string","description":"신고자 username","example":"pingdom_user"},"trustScore":{"type":"integer","description":"신뢰 점수","format":"int32","example":80},"trustGrade":{"type":"string","description":"신뢰 등급","example":"HIGH","enum":["HIGH","NORMAL","LOW"]},"restricted":{"type":"boolean","description":"현재 신고 제한 여부","example":false},"restrictedUntil":{"type":"string","description":"신고 제한 종료 시각","format":"date-time","nullable":true},"restrictionReason":{"type":"string","description":"신고 제한 사유","nullable":true,"example":"FALSE_REPORT_THRESHOLD_EXCEEDED"},"evidence":{"$ref":"#/components/schemas/AdminTrustScoreEvidenceResponse"}},"description":"신고자 신뢰 등급 및 점수 근거 응답"},"AdminTrustScoreChangeHistoryItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"beforeScore":{"type":"integer","format":"int32"},"afterScore":{"type":"integer","format":"int32"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}},"AdminTrustScoreChangeHistoryResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminTrustScoreChangeHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminTrustScoreInterventionRuleResponse":{"type":"object","properties":{"rules":{"type":"array","description":"개입 규칙 목록","items":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"}}}},"AdminTrustScoreAnomalyResponse":{"type":"object","properties":{"anomalies":{"type":"array","description":"이상치 목록","items":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyItem"}},"page":{"type":"integer","description":"현재 페이지","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 개수","format":"int64","example":42},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":3}}},"ScoutProfilePageResponse":{"type":"object","properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/ScoutProfileResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 Scout 프로필 목록 응답"},"ScoutFieldReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminS3OrphanObjectReportResponse":{"type":"object","properties":{"prefix":{"type":"string"},"scanLimit":{"type":"integer","format":"int32"},"dryRun":{"type":"boolean"},"truncated":{"type":"boolean"},"dbKeyCount":{"type":"integer","format":"int64"},"s3ObjectCount":{"type":"integer","format":"int64"},"orphanObjectCount":{"type":"integer","format":"int64"},"orphanKeys":{"type":"array","items":{"type":"string"}}}},"AdminReservationPageResponse":{"type":"object","properties":{"reservations":{"type":"array","items":{"$ref":"#/components/schemas/AdminReservationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"ReportedUsersItem":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"reporterUsername":{"type":"string"},"reportedImageId":{"type":"integer","format":"int64"},"reportedUserId":{"type":"integer","format":"int64"},"reason":{"type":"string"}}},"ReportedUsersResponse":{"type":"object","properties":{"users":{"type":"array","items":{"$ref":"#/components/schemas/ReportedUsersItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminReportAppealItem":{"type":"object","properties":{"appealId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"appellantUserId":{"type":"integer","format":"int64"},"appellantUsername":{"type":"string"},"targetUserId":{"type":"integer","format":"int64"},"reason":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]},"adminUserId":{"type":"integer","format":"int64"},"adminReason":{"type":"string"},"processedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"AdminReportAppealResponse":{"type":"object","properties":{"appeals":{"type":"array","items":{"$ref":"#/components/schemas/AdminReportAppealItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PrivacyProcessingHistoryItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"subjectUserId":{"type":"integer","format":"int64"},"actorUserId":{"type":"integer","format":"int64"},"actorType":{"type":"string","enum":["USER","SYSTEM","ADMIN"]},"action":{"type":"string","enum":["EXPORT_REQUESTED","WITHDRAWAL_REQUESTED","ANONYMIZED","DELETED"]},"details":{"type":"string"},"requestId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"PrivacyProcessingHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/PrivacyProcessingHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"S3OrphanCandidate":{"type":"object","properties":{"key":{"type":"string"},"reason":{"type":"string"}}},"S3OrphanReport":{"type":"object","properties":{"reportId":{"type":"string"},"status":{"type":"string"},"errorMessage":{"type":"string"},"deleteCandidates":{"type":"array","items":{"$ref":"#/components/schemas/S3OrphanCandidate"}},"dbKeyCount":{"type":"integer","format":"int64"},"s3KeyCount":{"type":"integer","format":"int64"},"deleteCandidateCount":{"type":"integer","format":"int64"},"generatedAt":{"type":"string","format":"date-time"},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceItem":{"required":["level"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"category":{"type":"string","description":"일반 장소 카테고리. touristCategories와 별도 기준이며 미분류 장소는 null입니다.","nullable":true,"example":"OTHER","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"categoryName":{"type":"string","description":"화면 표시용 일반 장소 카테고리명. category가 없으면 미분류입니다.","example":"기타","enum":["음식점","음악","팝업","패션","뷰티","전시","카페","문화재","기타","미분류"]},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","description":"외국인 관광 관심사 분류. 일반 장소 category 필터와는 별도 기준입니다.","items":{"type":"string","description":"외국인 관광 관심사 분류. 일반 장소 category 필터와는 별도 기준입니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"level":{"minimum":0,"type":"integer","description":"장소 성장 레벨. 10 이상이면 관리자 지도에서 불꽃 마커로 표시할 수 있습니다.","format":"int32","example":5},"placeGrowth":{"$ref":"#/components/schemas/PlaceGrowthSnapshot"}}},"AdminMapPlaceResponse":{"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"minimum":1,"type":"integer","description":"전체 페이지 수. 조회 결과가 없어도 1을 반환합니다.","format":"int64","example":1},"hasNext":{"type":"boolean"}},"description":"관리자 장소 목록 조회 응답"},"PlaceGrowthSnapshot":{"type":"object","properties":{"photoCount":{"type":"integer","format":"int64"},"level":{"type":"integer","format":"int32"},"currentLevelMinPhotoCount":{"type":"integer","format":"int64"},"nextLevelMinPhotoCount":{"type":"integer","format":"int64"},"progressPercent":{"type":"integer","format":"int32"}}},"PlaceInformationReverificationListResponse":{"type":"object","properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDetailResponse":{"required":["imageUrl","level"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"imageUrl":{"type":"string","description":"장소 목록·상세에서 공통으로 사용하는 canonical 대표 이미지 URL입니다. 대표 이미지가 없으면 null입니다.","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"category":{"type":"string","description":"일반 장소 카테고리. touristCategories와 별도 기준이며 미분류 장소는 null입니다.","nullable":true,"example":"OTHER","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"categoryName":{"type":"string","description":"화면 표시용 일반 장소 카테고리명. category가 없으면 미분류입니다.","example":"기타","enum":["음식점","음악","팝업","패션","뷰티","전시","카페","문화재","기타","미분류"]},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","description":"외국인 관광 관심사 분류. 일반 장소 category와는 별도 기준입니다.","items":{"type":"string","description":"외국인 관광 관심사 분류. 일반 장소 category와는 별도 기준입니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"username":{"type":"string"},"sortParam":{"type":"string","enum":["LATEST","OLDEST","MOST_LIKED"]},"postCount":{"type":"integer","format":"int32"},"level":{"minimum":0,"type":"integer","description":"장소 성장 레벨. 10 이상이면 관리자 지도에서 불꽃 마커로 표시할 수 있습니다.","format":"int32","example":5},"placeGrowth":{"$ref":"#/components/schemas/AdminMapPlaceGrowthResponse"},"posts":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceImageItem"}}}},"AdminMapPlaceGrowthResponse":{"type":"object","properties":{"photoCount":{"type":"integer","description":"장소 성장에 반영된 노출 게시글 사진 수","format":"int64","example":10},"hiddenPhotoCount":{"type":"integer","description":"장소 성장에 반영되지 않는 숨김 게시글 사진 수","format":"int64","example":1},"level":{"type":"integer","format":"int32"},"currentLevelMinPhotoCount":{"type":"integer","format":"int64"},"nextLevelMinPhotoCount":{"type":"integer","format":"int64"},"progressPercent":{"type":"integer","format":"int32"}},"description":"관리자 장소 상세 성장 상태"},"AdminMapPlaceImageItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"thumbnailUrl":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"userId":{"type":"integer","format":"int64"},"username":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"likeCount":{"type":"integer","format":"int64"},"visibilityStatus":{"type":"string","description":"일반 사용자 기준 게시글 노출 상태","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"hiddenReason":{"type":"string","description":"게시글이 숨김 처리된 사유. 노출 중인 게시글은 null","nullable":true,"example":"ADMIN_HIDDEN"}}},"AdminPlaceInformationEvidenceResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"evidences":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceItem"}}},"description":"관리자 장소 정보 증빙 목록 응답"},"AdminPlaceRecommendationExplanationItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":1},"placeName":{"type":"string","description":"장소명","example":"진주성"},"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":21},"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v2"},"recommendationStage":{"type":"string","description":"추천 stage","example":"EXPERIMENT","enum":["STABLE","EXPERIMENTAL"]},"ranking":{"type":"integer","description":"노출 순위","format":"int32","example":1},"source":{"type":"string","description":"후보 소스","example":"PERSONALIZED","enum":["PERSONAL","POPULAR","FRESH","GEO","FALLBACK"]},"distanceMeters":{"type":"integer","description":"거리(m)","format":"int64","example":128},"geoScore":{"type":"number","description":"geo score","format":"double","example":0.91},"personalScore":{"type":"number","description":"personal score","format":"double","example":0.42},"qualityScore":{"type":"number","description":"quality score","format":"double","example":0.37},"engagementScore":{"type":"number","description":"engagement score","format":"double","example":0.25},"conversionScore":{"type":"number","description":"conversion score","format":"double","example":0.14},"explorationScore":{"type":"number","description":"exploration score","format":"double","example":0.08},"freshnessScore":{"type":"number","description":"freshness score","format":"double","example":0.19},"trustScore":{"type":"number","description":"검증 제보자 신뢰도 기반 score","format":"double","example":0.82},"contextScore":{"type":"number","description":"K-컬처 관심사와 현재 여행 맥락 기반 score","format":"double","example":0.25},"benefitScore":{"type":"number","description":"현재 이용 가능한 혜택 기반 boost","format":"double","example":0.05},"availabilityScore":{"type":"number","description":"예약 가능 시간 기반 boost","format":"double","example":0.05},"boostScore":{"type":"number","description":"Verified Boost 집행 기반 score","format":"double","example":0.08},"finalScore":{"type":"number","description":"최종 score","format":"double","example":0.74},"createdAt":{"type":"string","description":"로그 생성 시각","format":"date-time"}},"description":"관리자 추천 설명 항목"},"AdminPlaceRecommendationExplanationResponse":{"type":"object","properties":{"requestId":{"type":"string","description":"추천 요청 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"items":{"type":"array","description":"관리자 추천 설명 항목","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationExplanationItem"}}},"description":"관리자 추천 설명 조회 응답"},"AdminPlaceRecommendationMetricItem":{"type":"object","properties":{"id":{"type":"integer","description":"장소 ID","format":"int64","example":1},"name":{"type":"string","description":"장소명","example":"진주성"},"address":{"type":"string","description":"장소 주소","example":"경상남도 진주시 남강로 626"},"photoCount":{"type":"integer","description":"장소 사진 수","format":"int64","example":12},"exposureCount":{"type":"integer","description":"추천 노출 수","format":"int64","example":120},"clickCount":{"type":"integer","description":"추천 클릭 수","format":"int64","example":18},"rawCtr":{"type":"number","description":"원본 CTR","format":"double","example":0.15},"smoothedCtr":{"type":"number","description":"랭킹 기준 smoothed CTR","format":"double","example":0.13},"bookmarkConversionCount":{"type":"integer","description":"북마크 전환 수","format":"int64","example":4},"likeConversionCount":{"type":"integer","description":"좋아요 전환 수","format":"int64","example":6},"bookmarkConversionRate":{"type":"number","description":"북마크 전환율","format":"double","example":0.03},"likeConversionRate":{"type":"number","description":"좋아요 전환율","format":"double","example":0.05},"totalConversionRate":{"type":"number","description":"전체 전환율","format":"double","example":0.08},"snapshotUpdatedAt":{"type":"string","description":"추천 snapshot 최종 갱신 시각","format":"date-time"}},"description":"관리자 추천 성과 항목"},"AdminPlaceRecommendationMetricsResponse":{"type":"object","properties":{"metrics":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricItem"}},"sortBy":{"type":"string","enum":["SMOOTHED_CTR","RAW_CTR","BOOKMARK_CONVERSION","LIKE_CONVERSION","TOTAL_CONVERSION","EXPOSURE","CLICK","UPDATED_AT"]},"recommendationVersion":{"type":"string"},"days":{"type":"integer","format":"int32"},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}},"description":"관리자 추천 성과 목록 응답"},"AdminPlaceRecommendationMetricSummary":{"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v1"},"exposureCount":{"type":"integer","description":"추천 노출 수","format":"int64","example":120},"clickCount":{"type":"integer","description":"추천 클릭 수","format":"int64","example":18},"rawCtr":{"type":"number","description":"원본 CTR","format":"double","example":0.15},"smoothedCtr":{"type":"number","description":"smoothed CTR","format":"double","example":0.13},"bookmarkConversionCount":{"type":"integer","description":"북마크 전환 수","format":"int64","example":4},"likeConversionCount":{"type":"integer","description":"좋아요 전환 수","format":"int64","example":6},"bookmarkConversionRate":{"type":"number","description":"북마크 전환율","format":"double","example":0.03},"likeConversionRate":{"type":"number","description":"좋아요 전환율","format":"double","example":0.05},"totalConversionRate":{"type":"number","description":"전체 전환율","format":"double","example":0.08}},"description":"관리자 추천 성과 요약"},"AdminPlaceRecommendationMetricsCompareResponse":{"type":"object","properties":{"baselineVersion":{"type":"string","description":"기준 추천 버전","example":"place-rec-v1"},"targetVersion":{"type":"string","description":"비교 대상 추천 버전","example":"place-rec-v2"},"days":{"type":"integer","description":"최근 N일 기준 필터","format":"int32","example":7},"keyword":{"type":"string","description":"장소 검색 키워드","example":"진주"},"baseline":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"},"target":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"},"delta":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"}},"description":"관리자 추천 버전 성과 비교 응답"},"AdminPlaceMergeHistoryItem":{"type":"object","properties":{"historyId":{"type":"integer","format":"int64"},"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"adminUserId":{"type":"integer","format":"int64"},"restored":{"type":"boolean"},"mergedAt":{"type":"string","format":"date-time"},"restoredAt":{"type":"string","format":"date-time"}}},"AdminPlaceMergeHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMergeHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDuplicateGroupItem":{"type":"object","properties":{"representativePlaceId":{"type":"integer","format":"int64"},"duplicatePlaceIds":{"type":"array","items":{"type":"integer","format":"int64"}},"reasons":{"type":"array","items":{"type":"string"}}}},"AdminMapPlaceDuplicateResponse":{"type":"object","properties":{"groups":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateGroupItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDuplicateCandidateItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"kakaoPlaceId":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"photoCount":{"type":"integer","format":"int64"},"reason":{"type":"string"},"distanceMeters":{"type":"number","format":"double"}}},"AdminMapPlaceDuplicateDetailResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"kakaoPlaceId":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"photoCount":{"type":"integer","format":"int64"},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateCandidateItem"}}}},"AdminPlaceDuplicateCandidateListResponse":{"type":"object","properties":{"candidates":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminPlaceReviewDeletionRequestPageResponse":{"type":"object","properties":{"deletionRequests":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PlaceInformationReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"장소 정보 신고 페이지 응답"},"AdminPlaceEventListItem":{"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"placeAddress":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"publicationStatus":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminPlaceEventListResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceEventListItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminOutboxEventResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AdminOutboxEventItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 Outbox 이벤트 운영 조회 응답"},"AdminNotificationItem":{"type":"object","properties":{"notificationId":{"type":"integer","description":"알림 ID","format":"int64","example":1},"userId":{"type":"integer","description":"수신 관리자 ID","format":"int64","example":10},"type":{"type":"string","description":"관리자 알림 유형: ADMIN_REPORT_RECEIVED, ADMIN_REPORT_PROCESSED, ADMIN_DUPLICATE_PLACE_DETECTED, ADMIN_USER_SANCTION","example":"ADMIN_REPORT_RECEIVED","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"title":{"type":"string","description":"알림 제목","example":"신고 접수 알림"},"body":{"type":"string","description":"알림 내용","example":"신고 ID 30 접수가 게시글 ID 12에 등록되었습니다."},"token":{"type":"string","description":"관리 화면 연결 token. report:{reportId}, place:{placeId}, sanction:{sanctionId} 형식","example":"report:30"},"read":{"type":"boolean","description":"읽음 여부","example":false},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"}},"description":"관리자 알림 아이템"},"AdminNotificationResponse":{"type":"object","properties":{"notifications":{"type":"array","description":"관리자 알림 목록","items":{"$ref":"#/components/schemas/AdminNotificationItem"}},"page":{"type":"integer","description":"현재 페이지 번호","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 알림 개수","format":"int64","example":1},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false}},"description":"관리자 알림 목록 응답"},"AdminNotificationUnreadCountResponse":{"type":"object","properties":{"unreadCount":{"type":"integer","description":"미확인 알림 개수","format":"int64","example":3}},"description":"관리자 미확인 알림 개수 응답"},"AdminNotificationDeliveryItem":{"type":"object","properties":{"deliveryId":{"type":"integer","description":"발송 결과 ID","format":"int64","example":1},"channel":{"type":"string","description":"발송 채널","example":"FCM","enum":["FCM","EMAIL"]},"status":{"type":"string","description":"발송 상태","example":"SUCCEEDED","enum":["SUCCEEDED","FAILED","RETRY_SCHEDULED","FINAL_FAILED"]},"userId":{"type":"integer","description":"수신 사용자 ID","format":"int64","example":10},"notificationId":{"type":"integer","description":"인앱 알림 ID","format":"int64","example":100},"notificationType":{"type":"string","description":"인앱 알림 유형","example":"NEW_LIKE"},"outboxEventId":{"type":"string","description":"Outbox 이벤트 ID"},"outboxEventType":{"type":"string","description":"Outbox 이벤트 유형","example":"MAP_IMAGE_LIKED"},"providerMessageId":{"type":"string","description":"외부 발송 provider message id"},"providerErrorCode":{"type":"string","description":"외부 발송 provider error code"},"errorCode":{"type":"string","description":"내부 실패 분류 코드"},"failureReason":{"type":"string","description":"실패 사유"},"retryable":{"type":"boolean","description":"재시도 가능 여부","example":true},"attemptCount":{"type":"integer","description":"발송 시도 횟수","format":"int32","example":1},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}},"description":"관리자 알림 발송 결과 아이템"},"AdminNotificationDeliveryResponse":{"type":"object","properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/AdminNotificationDeliveryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 알림 발송 결과 목록 응답"},"AdminMerchantPlaceApplicationListItemResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"maskedBusinessRegistrationNumber":{"type":"string"},"merchantDisplayName":{"type":"string"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminMerchantPlaceApplicationPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationListItemResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMerchantPlaceApplicationAttachmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"documentType":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"uploadedAt":{"type":"string","format":"date-time"},"retentionExpiresAt":{"type":"string","format":"date-time"},"displayOrder":{"type":"integer","format":"int32"}}},"AdminMerchantPlaceApplicationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"businessRegistrationNumber":{"type":"string"},"merchantDisplayName":{"type":"string"},"merchantContactEmail":{"type":"string"},"merchantDescription":{"type":"string"},"merchantContactPhone":{"type":"string"},"newPlace":{"$ref":"#/components/schemas/MerchantPlaceApplicationNewPlaceResponse"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"type":"string"},"reviewReason":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"version":{"type":"integer","format":"int64"},"submissionVersion":{"type":"integer","format":"int64"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationAttachmentResponse"}}}},"MerchantOwnerProfilePageResponse":{"type":"object","properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminDashboardMetricWindowResponse":{"type":"object","properties":{"period":{"type":"string","description":"집계 기간 코드","example":"TODAY","enum":["TODAY","LAST_7_DAYS"]},"startedAt":{"type":"string","description":"집계 시작 시각","format":"date-time"},"endedAt":{"type":"string","description":"집계 종료 시각","format":"date-time"},"placeRegistrationCount":{"type":"integer","description":"기간 내 장소 등록 수","format":"int64","example":3},"postRegistrationCount":{"type":"integer","description":"기간 내 게시글 등록 수","format":"int64","example":7}},"description":"관리자 대시보드 기간별 운영 변화 지표"},"AdminDashboardOperationalMetricsResponse":{"type":"object","properties":{"today":{"$ref":"#/components/schemas/AdminDashboardMetricWindowResponse"},"last7Days":{"$ref":"#/components/schemas/AdminDashboardMetricWindowResponse"},"duplicatePlaceGroupCount":{"type":"integer","description":"중복 장소 후보 그룹 수","format":"int64","example":2},"expiringBannedUserCount":{"type":"integer","description":"7일 이내 임시 밴 만료 예정 사용자 수","format":"int64","example":4},"missingLocationPlaceCount":{"type":"integer","description":"location 좌표 정보가 누락된 장소 수","format":"int64","example":1},"expiringBanUntil":{"type":"string","description":"밴 만료 예정 집계 종료 시각","format":"date-time"},"collectedAt":{"type":"string","description":"지표 집계 기준 시각","format":"date-time"}},"description":"관리자 대시보드 추가 운영 지표"},"AdminDashboardSummaryResponse":{"type":"object","properties":{"placeCount":{"type":"integer","description":"전체 장소 수","format":"int64","example":44},"postCount":{"type":"integer","description":"전체 게시글 수","format":"int64","example":58},"pendingReportCount":{"type":"integer","description":"처리 대기 신고 수","format":"int64","example":5},"bannedUserCount":{"type":"integer","description":"현재 밴 사용자 수","format":"int64","example":6},"operationalMetrics":{"$ref":"#/components/schemas/AdminDashboardOperationalMetricsResponse"}},"description":"관리자 대시보드 전체 운영 현황 요약"},"AdminDashboardRecentActivitiesResponse":{"type":"object","properties":{"places":{"type":"array","description":"최근 장소 등록 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentPlaceItem"}},"posts":{"type":"array","description":"최근 게시글 등록 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentPostItem"}},"reports":{"type":"array","description":"최근 신고 처리 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentReportItem"}},"userSanctions":{"type":"array","description":"최근 사용자 밴 및 밴 해제 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentUserSanctionItem"}}},"description":"관리자 대시보드 최근 운영 활동"},"AdminDashboardRecentPlaceItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":10},"name":{"type":"string","description":"장소명","example":"핑덤 카페"},"address":{"type":"string","description":"주소","example":"서울특별시 중구 세종대로 110"},"userId":{"type":"integer","description":"등록 사용자 ID","format":"int64","example":3},"registrant":{"type":"string","description":"등록자명","example":"pingdom_user"},"createdAt":{"type":"string","description":"장소 등록일","format":"date-time"}},"description":"관리자 대시보드 최근 장소 등록 항목"},"AdminDashboardRecentPostItem":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":10},"title":{"type":"string","description":"게시글 제목","example":"야경이 좋은 장소"},"userId":{"type":"integer","description":"작성자 ID","format":"int64","example":3},"username":{"type":"string","description":"작성자명","example":"pingdom_user"},"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":7},"placeName":{"type":"string","description":"장소명","example":"핑덤 카페"},"createdAt":{"type":"string","description":"생성일","format":"date-time"}},"description":"관리자 대시보드 최근 게시글 등록 항목"},"AdminDashboardRecentReportItem":{"type":"object","properties":{"reportId":{"type":"integer","description":"신고 ID","format":"int64","example":10},"reportedImageId":{"type":"integer","description":"신고 대상 게시글 ID","format":"int64","example":22},"title":{"type":"string","description":"신고 대상 게시글 제목","example":"야경이 좋은 장소"},"status":{"type":"string","description":"신고 상태","example":"ACCEPTED","enum":["PENDING","ACCEPTED","DECLINED","RESTORED"]},"processedAt":{"type":"string","description":"처리일","format":"date-time"},"createdAt":{"type":"string","description":"신고 생성일","format":"date-time"}},"description":"관리자 대시보드 최근 신고 처리 항목"},"AdminDashboardRecentUserSanctionItem":{"type":"object","properties":{"sanctionId":{"type":"integer","description":"제재 이력 ID","format":"int64","example":10},"targetUserId":{"type":"integer","description":"대상 사용자 ID","format":"int64","example":5},"targetUsername":{"type":"string","description":"대상 사용자명","example":"reported_user"},"action":{"type":"string","description":"제재 처리 유형","example":"APPLIED","enum":["APPLIED","RELEASED","EXPIRED"]},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"reason":{"type":"string","description":"처리 사유","example":"부적절한 게시글입니다."},"processedAt":{"type":"string","description":"처리일","format":"date-time"}},"description":"관리자 대시보드 최근 사용자 제재 항목"},"AdminDashboardPendingItem":{"type":"object","properties":{"type":{"type":"string","description":"처리 필요 항목 유형","example":"POST_REPORT","enum":["POST_REPORT","MERCHANT_PLACE_APPLICATION","POST_REPORT","MERCHANT_PLACE_APPLICATION"]},"targetId":{"type":"integer","description":"처리 항목 ID. POST_REPORT에서는 신고 ID와 동일","format":"int64","example":30},"reportId":{"type":"integer","description":"신고 ID. 신고 처리 화면으로 이동할 때 사용","format":"int64","example":30},"postId":{"type":"integer","description":"신고 대상 게시글 ID. 게시글 상세 화면으로 이동할 때 사용","format":"int64","nullable":true,"example":22},"title":{"type":"string","description":"처리 대상 제목","example":"야경이 좋은 장소"},"status":{"type":"string","description":"처리 대상 상태","example":"PENDING"},"createdAt":{"type":"string","description":"생성일","format":"date-time"},"navigationPath":{"type":"string","description":"관리자 화면 이동 경로. 통합 신청 항목에서만 제공","nullable":true,"example":"/admin/merchant-place-applications/12"}},"description":"관리자 대시보드 처리 필요 항목"},"AdminDashboardPendingItemsResponse":{"type":"object","properties":{"items":{"type":"array","description":"처리 필요 항목","items":{"$ref":"#/components/schemas/AdminDashboardPendingItem"}},"totalCount":{"type":"integer","description":"필터링 전 전체 PENDING 처리 필요 항목 수","format":"int64","example":8}},"description":"관리자 대시보드 처리 필요 항목 목록"},"AdminCommunityPostItem":{"type":"object","properties":{"postId":{"type":"integer","format":"int64"},"categoryId":{"type":"string"},"title":{"type":"string"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 글 목록 항목"},"AdminCommunityPostPageResponse":{"type":"object","properties":{"posts":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityPostItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminCommunityPostResponse":{"type":"object","properties":{"postId":{"type":"integer","format":"int64"},"categoryId":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"places":{"type":"array","items":{"$ref":"#/components/schemas/Place"}}}},"Place":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"deleted":{"type":"boolean"}}},"AdminCommunityCommentItem":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"content":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 댓글 목록 항목"},"AdminCommunityCommentPageResponse":{"type":"object","properties":{"comments":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityCommentItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminCommunityCommentResponse":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"content":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"AdminCommunityReportItem":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"targetHidden":{"type":"boolean"},"reporterUserId":{"type":"integer","format":"int64"},"reason":{"type":"string","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"createdAt":{"type":"string","format":"date-time"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 목록 항목"},"AdminCommunityReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityReportItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 커뮤니티 신고 목록 응답"},"AdminCommunityReportResponse":{"required":["postId"],"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"postId":{"type":"integer","description":"원문 글 ID. POST는 targetId와 같고 COMMENT는 대상 댓글이 속한 글 ID입니다. 신고 대상과 댓글의 원문 관계는 DB 제약으로 보장되며, 숨김 여부와 관계없이 반환합니다.","format":"int64","example":101},"targetHidden":{"type":"boolean"},"reporterUserId":{"type":"integer","format":"int64"},"reason":{"type":"string","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"description":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"createdAt":{"type":"string","format":"date-time"},"processedByAdminUserId":{"type":"integer","format":"int64"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 상세 응답"},"AdminAuditLogItem":{"type":"object","properties":{"auditLogId":{"type":"integer","description":"감사 로그 ID","format":"int64","example":1},"actorUserId":{"type":"integer","description":"작업 관리자 ID","format":"int64","example":1},"actorUsername":{"type":"string","description":"작업 관리자명","example":"admin"},"action":{"type":"string","description":"작업 유형","example":"USER_BAN_APPLIED","enum":["ADMIN_ROLE_ASSIGNED","ADMIN_ROLE_REVOKED","USER_BAN_APPLIED","USER_BAN_RELEASED","REPORT_ACCEPTED","REPORT_DECLINED","COMMUNITY_REPORT_ACCEPTED","COMMUNITY_REPORT_DECLINED","POST_DELETED","POST_HIDDEN","POST_RESTORED","APPEAL_APPROVED","APPEAL_REJECTED","PLACE_DELETED","PLACE_BASIC_INFORMATION_UPDATED","PLACE_KAKAO_PLACE_ID_UPDATED","PLACE_GEOCODING_UPDATED","PLACE_TOURIST_INFO_UPDATED","PLACE_INFORMATION_EVIDENCE_UPDATED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_INFORMATION_REVERIFICATION_COMPLETED","PLACE_INFORMATION_REVERIFICATION_CANCELED","PLACE_INFORMATION_REVERIFICATION_EXPIRED","VISITOR_VERIFICATION_REPORT_REVIEWED","VISITOR_VERIFICATION_REPORT_CORRECTION_REVIEWED","SCOUT_FIELD_REPORT_REVIEWED","SCOUT_PROFILE_REVIEWED","SCOUT_ACTIVITY_ELIGIBILITY_REVIEWED","PLACE_DISCOVERY_STATUS_UPDATED","PLACE_OPERATING_STATUS_UPDATED","PLACE_OPERATING_SCHEDULE_UPDATED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_EVENT_CREATED","PLACE_EVENT_UPDATED","PLACE_EVENT_PUBLISHED","PLACE_EVENT_CANCELLED","PLACE_RECOMMENDATION_TRAFFIC_UPDATED","PLACE_RECOMMENDATION_KILL_SWITCH_UPDATED","TRUST_SCORE_ANOMALY_RESOLVED","TRUST_SCORE_INTERVENTION_RULE_CREATED","TRUST_SCORE_INTERVENTION_RULE_UPDATED","TRUST_SCORE_INTERVENTION_RULE_ENABLED","TRUST_SCORE_INTERVENTION_RULE_DISABLED","TRUST_SCORE_INTERVENTION_EVALUATED","NOTIFICATION_READ","NOTIFICATION_READ_ALL","PLACE_DUPLICATE_CONFIRMED","PLACE_DUPLICATE_REJECTED","PLACE_MERGED","MERCHANT_OWNER_APPROVED","MERCHANT_OWNER_REJECTED","MERCHANT_OWNER_REVOKED","MERCHANT_OWNER_PLACES_UPDATED","MERCHANT_ONBOARDING_UPDATED","MERCHANT_OPERATIONAL_QUALITY_UPDATED","MERCHANT_VERIFICATION_REVIEWED","MERCHANT_VERIFICATION_VIEWED","MERCHANT_PLACE_CLAIM_ATTACHMENT_VIEWED","MERCHANT_PLACE_CLAIM_APPROVED","MERCHANT_PLACE_CLAIM_REJECTED","MERCHANT_PLACE_APPLICATION_APPROVED","MERCHANT_PLACE_APPLICATION_REJECTED","MERCHANT_PLACE_APPLICATION_VIEWED","MERCHANT_PLACE_APPLICATION_ATTACHMENT_VIEWED","OUTBOX_EVENT_RETRIED","AD_CREATED","AD_DELETED","RESERVATION_CONFIRMED","RESERVATION_REJECTED"]},"targetType":{"type":"string","description":"대상 유형","example":"USER","enum":["USER","REPORT","COMMUNITY_REPORT","APPEAL","POST","PLACE","PLACE_DUPLICATE_CANDIDATE","PLACE_INFORMATION_EVIDENCE","PLACE_INFORMATION_REPORT","PLACE_INFORMATION_DISPUTE","PLACE_INFORMATION_REVERIFICATION","VISITOR_VERIFICATION_REPORT","VISITOR_VERIFICATION_REPORT_CORRECTION","SCOUT_FIELD_REPORT","SCOUT_PROFILE","SCOUT_ACTIVITY_ELIGIBILITY","PLACE_OPERATING_NOTICE","PLACE_EVENT","TRUST_SCORE_ANOMALY","TRUST_SCORE_INTERVENTION_RULE","NOTIFICATION","OUTBOX_EVENT","MERCHANT_OWNER","MERCHANT_VERIFICATION","MERCHANT_PLACE_CLAIM_ATTACHMENT","MERCHANT_PLACE_CLAIM","MERCHANT_PLACE_APPLICATION","MERCHANT_PLACE_APPLICATION_ATTACHMENT","AD","RESERVATION"]},"targetId":{"type":"string","description":"대상 ID","example":"7"},"reason":{"type":"string","description":"작업 사유","example":"반복적인 신고 누적"},"beforeState":{"type":"string","description":"작업 전 상태 JSON"},"afterState":{"type":"string","description":"작업 후 상태 JSON"},"requestId":{"type":"string","description":"요청 ID","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"createdAt":{"type":"string","description":"감사 로그 생성 시각","format":"date-time"}},"description":"관리자 감사 로그 아이템"},"AdminAuditLogResponse":{"type":"object","properties":{"auditLogs":{"type":"array","items":{"$ref":"#/components/schemas/AdminAuditLogItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 감사 로그 목록 응답"},"AdminRoleAssignmentRevokeRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"역할을 회수하는 사유","example":"담당 업무 변경"}},"description":"관리자 역할 회수 요청"},"AdminS3OrphanDeleteRequest":{"required":["reportId"],"type":"object","properties":{"reportId":{"type":"string"},"keys":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"confirmed":{"type":"boolean"}}},"S3OrphanDeleteFailure":{"type":"object","properties":{"key":{"type":"string"},"reason":{"type":"string"}}},"S3OrphanDeleteResult":{"type":"object","properties":{"requestedKeyCount":{"type":"integer","format":"int32"},"deletedKeyCount":{"type":"integer","format":"int32"},"failedKeyCount":{"type":"integer","format":"int32"},"deletedKeys":{"type":"array","items":{"type":"string"}},"failedKeys":{"type":"array","items":{"$ref":"#/components/schemas/S3OrphanDeleteFailure"}}}},"ValidationErrorResponse":{"required":["code","errors","message"],"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string","example":"VALIDATION_FAILED"},"errors":{"type":"object","additionalProperties":{"type":"string"}}},"description":"필드 검증 오류 응답"},"AdminPlaceMapRegion":{"type":"object","properties":{"regionLevel":{"type":"string"},"regionCode":{"type":"string"},"name":{"type":"string"},"count":{"type":"integer","format":"int64"},"countScope":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"bounds":{"$ref":"#/components/schemas/AdminPlaceMapBounds"},"boundsSource":{"type":"string","enum":["PLACE_EXTENT"]},"action":{"type":"string","enum":["EXPAND"]},"nextZoom":{"type":"integer","format":"int32"}}},"AdminPlaceMapResponse":{"type":"object","properties":{"mode":{"type":"string","enum":["SIDO","SIGUNGU","SPATIAL"]},"zoom":{"type":"integer","format":"int32"},"regions":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMapRegion"}},"clusters":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMapCluster"}},"markers":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMapMarker"}},"viewportPlaceCount":{"type":"integer","description":"현재 화면 안의 동일 필터·유효 좌표 장소 수. 지역 전체 count와 합산하지 않습니다.","format":"int64"},"complete":{"type":"boolean","description":"모든 표시 대상을 누락 없이 표현했는지 여부"},"incompleteReason":{"type":"string","nullable":true,"enum":["RESULT_BUDGET_EXCEEDED"]},"recoveryAction":{"type":"string","nullable":true,"enum":["ZOOM_IN"]}},"description":"관리자 지도. 지역 전체 count와 viewportPlaceCount는 별도 범위이며 합산하지 않습니다."},"AdminPlaceMapGroupPage":{"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMapMarker"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminPlaceMapCluster":{"type":"object","properties":{"clusterKey":{"type":"string"},"clusterId":{"type":"string"},"count":{"type":"integer","format":"int64"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"bounds":{"$ref":"#/components/schemas/AdminPlaceMapBounds"},"countScope":{"type":"string"},"action":{"type":"string","enum":["EXPAND","LIST"]},"nextZoom":{"type":"integer","format":"int32"}}},"AdminPlaceMapMarker":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"category":{"type":"string"},"discoveryStatus":{"type":"string"},"operatingStatus":{"type":"string"}}},"AdminPlaceMapBounds":{"type":"object","properties":{"west":{"type":"number","format":"double"},"south":{"type":"number","format":"double"},"east":{"type":"number","format":"double"},"north":{"type":"number","format":"double"}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}} \ No newline at end of file diff --git a/src/test/resources/openapi-baseline/openapi.json b/src/test/resources/openapi-baseline/openapi.json index 687edc44a..b20a257f2 100644 --- a/src/test/resources/openapi-baseline/openapi.json +++ b/src/test/resources/openapi-baseline/openapi.json @@ -1 +1 @@ -{"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://127.0.0.1:64060","description":"Generated server url"}],"tags":[{"name":"내 정보·계정 연동","description":"내 정보 조회·변경, 계정 연동 및 탈퇴"},{"name":"여행","description":"여행 목적 선호, 여행 일정 및 활동 의향"},{"name":"장소 탐색","description":"지도·검색·추천과 인기 장소 탐색"},{"name":"장소 상세·메뉴","description":"장소 상세, 메뉴, 운영 공지 및 미디어"},{"name":"즐겨찾기","description":"관심 장소 저장 및 조회"},{"name":"내 리뷰","description":"내가 작성한 장소 리뷰 조회"},{"name":"장소 정보 제보","description":"장소 정보 제보 및 이의 제기"},{"name":"방문 인증","description":"위치 체크인, 방문 증빙 및 검증 보고"},{"name":"스카우트","description":"스카우트 프로필 및 현장 보고"},{"name":"커뮤니티 게시글","description":"게시글 작성·탐색 및 연결 장소 조회"},{"name":"댓글·좋아요","description":"게시글 댓글 및 좋아요"},{"name":"신고","description":"커뮤니티 게시글 및 댓글 신고"},{"name":"예약","description":"예약 생성·조회 및 취소 / 예약 및 처리 이력 조회"},{"name":"결제","description":"결제 내역 및 상세 조회 / 사업자 결제·정산 조회 및 환불"},{"name":"쿠폰·혜택","description":"혜택 탐색, 쿠폰 발급 및 조회"},{"name":"행사·팝업","description":"행사 및 팝업 캠페인 탐색"},{"name":"알림","description":"알림 수신 설정 및 기기 토큰 관리"},{"name":"상권 분석","description":"상권 분석 보고서 생성·조회·다운로드"},{"name":"사업자 정보","description":"사업자 프로필 등록 및 조회·변경"},{"name":"팀 관리","description":"장소 팀원 초대 및 권한 관리"},{"name":"장소 등록 신청","description":"장소 등록 신청 및 첨부 자료 관리"},{"name":"장소 정보 관리","description":"장소 정보·미디어·운영 상태 및 재검증 응답"},{"name":"메뉴·운영 공지","description":"메뉴와 장소 운영 공지 관리"},{"name":"리뷰 관리","description":"장소 리뷰 확인 및 삭제 심사 요청"},{"name":"예약 가능 시간","description":"예약 가능 시간 등록·변경 및 활성 상태 관리"},{"name":"예약 관리","description":"사업자 예약 조회·승인·반려 및 취소"},{"name":"캠페인·혜택","description":"캠페인·브랜드·혜택 및 쿠폰 사용 관리"},{"name":"Verified Boost","description":"Verified Boost 상품 조회·선택 및 실행 / Verified Boost 상품 등록 및 활성 상태 관리"},{"name":"실적","description":"사업자 운영 실적 조회"},{"name":"대시보드","description":"운영 현황, 최근 활동 및 처리 대기 항목"},{"name":"회원·권한","description":"회원 제재 및 관리자 역할 관리"},{"name":"사업자 관리","description":"사업자 심사 및 연결 장소 관리"},{"name":"장소 등록 심사","description":"장소 등록 신청과 증빙 확인 및 심사"},{"name":"장소 조회","description":"운영 대상 장소 목록 및 상세 조회"},{"name":"장소 정보·품질","description":"장소 정보 보정, 근거 검토 및 노출 상태 관리"},{"name":"중복·추천 관리","description":"중복 장소 검토·병합 및 추천 운영"},{"name":"제보·재검증","description":"장소 정보 제보 심사 및 재검증 요청 관리"},{"name":"행사·운영 공지","description":"행사 발행 및 운영 공지 관리"},{"name":"리뷰 삭제 심사","description":"장소 리뷰 삭제 요청 확인 및 심사"},{"name":"커뮤니티 관리","description":"게시글과 댓글 운영 조회"},{"name":"신고·이의신청","description":"신고 및 이의신청 검토·처리, 신고 콘텐츠 삭제"},{"name":"신뢰 점수","description":"신뢰 점수·이상 징후 및 개입 규칙 관리"},{"name":"방문 인증·스카우트","description":"방문 보고 심사 및 스카우트 자격 관리"},{"name":"알림·발송 이력","description":"운영 알림 확인 및 발송 이력 조회"},{"name":"감사·개인정보 처리 이력","description":"관리자 작업 감사 및 개인정보 처리 이력 조회"},{"name":"Outbox·스토리지 운영","description":"Outbox 재처리 및 스토리지 고아 객체 관리"},{"name":"로그인·세션","description":"로그인, 토큰 갱신 및 로그아웃"},{"name":"회원가입·이메일 인증","description":"회원가입 및 이메일 인증"},{"name":"비밀번호 재설정","description":"비밀번호 재설정 요청 및 확인"},{"name":"장소 리뷰","description":"장소 리뷰 작성 및 목록 조회"},{"name":"리뷰 미디어","description":"장소 리뷰 첨부 미디어 업로드 및 삭제"},{"name":"서비스 기본","description":"서비스 기본 응답"},{"name":"상담 시작","description":"상권 상담 안내 및 초기 상담"},{"name":"Voice AI","description":"인증 사용자 음성 AI Gateway API"}],"paths":{"/users/me/travel-purposes":{"get":{"tags":["여행"],"summary":"여행 목적 선호 조회","description":"현재 인증된 사용자의 여행 목적 선호 목록을 조회합니다.","operationId":"getTravelPurposes","responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelPurposePreferenceResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["여행"],"summary":"여행 목적 선호 전체 변경","description":"현재 인증된 사용자의 여행 목적 선호를 요청 목록으로 전체 교체합니다.","operationId":"replaceTravelPurposes","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TravelPurposePreferenceUpdateRequest"}}},"required":true},"responses":{"200":{"description":"변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelPurposePreferenceResponse"}}}},"400":{"description":"요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/scout-profile":{"get":{"tags":["스카우트"],"summary":"내 Scout 프로필 및 활동 자격 조회","description":"Scout 프로필을 아직 신청하지 않은 사용자는 404 SCOUT_PROFILE_NOT_FOUND를 받습니다.","operationId":"get_1","responses":{"404":{"description":"Scout 프로필을 찾을 수 없음 (SCOUT_PROFILE_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_NOT_FOUND":{"description":"SCOUT_PROFILE_NOT_FOUND","value":{"message":"Scout 프로필을 찾을 수 없습니다.","code":"SCOUT_PROFILE_NOT_FOUND"}}}}}},"200":{"description":"Scout 프로필 및 활동 자격 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["스카우트"],"summary":"내 Scout 프로필 수정","description":"활성 일반 사용자이며 프로필 상태가 PENDING 또는 ACTIVE일 때만 수정할 수 있습니다.\nSUSPENDED 또는 REVOKED 프로필은 409 INVALID_SCOUT_PROFILE_STATE를 반환합니다.\n활동 자격 상태(PENDING, ELIGIBLE, SUSPENDED, EXPIRED, REVOKED)는 프로필 수정 가능 여부를\n변경하지 않으며 Scout 활동 가능 여부를 판단하는 데 사용합니다.\n","operationId":"update","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileRequest"}}},"required":true},"responses":{"404":{"description":"Scout 프로필을 찾을 수 없음 (SCOUT_PROFILE_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_NOT_FOUND":{"description":"SCOUT_PROFILE_NOT_FOUND","value":{"message":"Scout 프로필을 찾을 수 없습니다.","code":"SCOUT_PROFILE_NOT_FOUND"}}}}}},"200":{"description":"Scout 프로필 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"403":{"description":"활성 일반 사용자 계정이 아님 (SCOUT_PROFILE_ACCOUNT_REQUIRED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_ACCOUNT_REQUIRED":{"description":"SCOUT_PROFILE_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 Scout 프로필을 신청할 수 있습니다.","code":"SCOUT_PROFILE_ACCOUNT_REQUIRED"}}}}}},"409":{"description":"현재 프로필 상태에서 수정 불가 (INVALID_SCOUT_PROFILE_STATE)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_SCOUT_PROFILE_STATE":{"description":"INVALID_SCOUT_PROFILE_STATE","value":{"message":"현재 Scout 프로필 상태에서는 요청을 처리할 수 없습니다.","code":"INVALID_SCOUT_PROFILE_STATE"}}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["스카우트"],"summary":"Scout 프로필 신청","description":"활성 일반 사용자만 Scout 프로필을 신청할 수 있습니다.\nPENDING, ACTIVE, SUSPENDED, REVOKED를 포함해 기존 Scout 프로필이 하나라도 있으면\n재신청할 수 없습니다.\n","operationId":"apply","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileRequest"}}},"required":true},"responses":{"403":{"description":"활성 일반 사용자 계정이 아님 (SCOUT_PROFILE_ACCOUNT_REQUIRED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_ACCOUNT_REQUIRED":{"description":"SCOUT_PROFILE_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 Scout 프로필을 신청할 수 있습니다.","code":"SCOUT_PROFILE_ACCOUNT_REQUIRED"}}}}}},"201":{"description":"Scout 프로필 신청 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"409":{"description":"이미 존재하는 Scout 프로필 (SCOUT_PROFILE_ALREADY_EXISTS)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_ALREADY_EXISTS":{"description":"SCOUT_PROFILE_ALREADY_EXISTS","value":{"message":"Scout 프로필이 이미 존재합니다.","code":"SCOUT_PROFILE_ALREADY_EXISTS"}}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{id}":{"get":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 상세 조회","description":"NEW_PLACE이면 newPlace에 저장된 장소 입력값 전체를 반환합니다. 첨부파일은 별도 첨부 API로 조회·관리합니다.","operationId":"get_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 수정","operationId":"update_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-owner-profile":{"get":{"tags":["사업자 정보"],"summary":"내 Merchant Owner 신청 조회","operationId":"get_3","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["사업자 정보"],"summary":"내 Merchant Owner 프로필 수정","operationId":"update_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["사업자 정보"],"summary":"Merchant Owner 신청","description":"프로필을 생성하거나 거절·회수된 신청을 다시 제출합니다.","operationId":"apply_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/current-activity-intent":{"get":{"tags":["여행"],"summary":"현재 행동 의도 조회","description":"만료되지 않은 현재 행동 의도를 조회합니다.","operationId":"getCurrentActivityIntent","responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CurrentActivityIntentResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["여행"],"summary":"현재 행동 의도 변경","description":"행동 의도를 2시간 동안 유지하도록 설정하거나 갱신합니다.","operationId":"replaceCurrentActivityIntent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentActivityIntentUpdateRequest"}}},"required":true},"responses":{"400":{"description":"요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CurrentActivityIntentResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["여행"],"summary":"현재 행동 의도 해제","description":"현재 행동 의도를 즉시 삭제합니다.","operationId":"clearCurrentActivityIntent","responses":{"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"204":{"description":"해제 성공"},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-schedule":{"put":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 장소 영업시간 변경","operationId":"updateOperatingSchedule","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingScheduleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingScheduleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/media/representative":{"put":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 대표 미디어 지정","operationId":"updateRepresentative","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerRepresentativeMediaUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/information":{"get":{"tags":["장소 정보 관리"],"summary":"Merchant 장소 정보 조회","description":"장소 관리자 또는 소유자만 본인 장소의 Merchant 관리 정보를 조회합니다. 권한 부족은 MERCHANT_TEAM_PERMISSION_REQUIRED, 정보 미등록은 PLACE_INFORMATION_NOT_FOUND로 구분합니다.","operationId":"get_9","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"장소 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceInformationResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소 정보를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["장소 정보 관리"],"summary":"Merchant 장소 정보 등록 및 수정","description":"장소 관리자 또는 소유자가 장소 소개와 방문 전환 링크를 등록하거나 전체 교체합니다. URL·길이 검증은 VALIDATION_FAILED, 권한 부족은 MERCHANT_TEAM_PERMISSION_REQUIRED, 대상 장소 없음은 PLACE_NOT_FOUND로 응답합니다.","operationId":"upsert","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceInformationUpdateRequest"}}},"required":true},"responses":{"200":{"description":"수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceInformationResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"403":{"description":"장소 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_PERMISSION_REQUIRED":{"description":"MERCHANT_TEAM_PERMISSION_REQUIRED","value":{"message":"Merchant 팀원 관리 권한이 필요합니다.","code":"MERCHANT_TEAM_PERMISSION_REQUIRED"}}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_NOT_FOUND":{"description":"PLACE_NOT_FOUND","value":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값이 올바르지 않습니다.","code":"VALIDATION_FAILED","errors":{"websiteUrl":"웹사이트 URL은 http:// 또는 https://로 시작해야 합니다."}}}}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities/{availabilityId}":{"put":{"tags":["예약 가능 시간"],"summary":"예약 가능 시간 수정","description":"productId, productType을 보내면 null이어도 400 INVALID_REQUEST_BODY로 거절합니다. 상품 필드를 제거한 단일 예약 슬롯 본문을 사용하세요.","operationId":"update_3","parameters":[{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityUpsertRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities/{availabilityId}/reservation-terms":{"put":{"tags":["예약 가능 시간"],"summary":"예약 시간대·취소 조건 설정","description":"취소 정책은 명시적 취소 불가 또는 시작 전 지정 기한까지 취소 가능입니다. 기존 예약의 수락 조건은 변경하지 않습니다. unitAmountMinor, additionalAmountMinor, currency를 보내면 null이어도 400 INVALID_REQUEST_BODY로 거절합니다.","operationId":"updateTerms","parameters":[{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationTermsRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationTermsResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}":{"put":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 수정","description":"관리자가 Trust Score 개입 규칙 내용을 수정합니다.","operationId":"updateRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/places":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 연결 장소 및 운영 품질 조회","operationId":"listPlaces_2","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOwnerPlaceResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 장소 연결 변경","description":"현재 연결 장소를 요청의 placeIds 전체로 교체합니다. 빈 목록은 모든 장소 연결을 해제합니다. Merchant Owner 승인과는 별도 요청 및 별도 트랜잭션입니다.","operationId":"replacePlaces","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/places/{placeId}/quality":{"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 장소 운영 품질 지표 변경","operationId":"updateOperationalQuality","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceQualityUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/onboarding":{"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 온보딩 완료도 변경","operationId":"updateOnboarding","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOnboardingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/voice-ai/sessions":{"post":{"tags":["Voice AI"],"summary":"음성 AI 세션 생성","description":"JWT 사용자 소유 세션을 생성합니다. 세션은 5분 뒤 만료됩니다.","operationId":"create","responses":{"201":{"description":"세션 생성 성공","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceAiSessionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/voice-ai/sessions/{sessionId}/refresh":{"post":{"tags":["Voice AI"],"summary":"음성 AI 세션 갱신","description":"활성 세션의 만료 시각을 현재 시점에서 5분으로 갱신합니다.","operationId":"refresh","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceAiSessionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"SESSION_FORBIDDEN: 다른 사용자 세션. ACCESS_DENIED: 공통 접근 거부","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"SESSION_NOT_FOUND: 존재하지 않는 세션","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"SESSION_EXPIRED: 만료 또는 종료된 세션은 갱신할 수 없습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/voice-ai/sessions/{sessionId}/messages":{"post":{"tags":["Voice AI"],"summary":"음성 AI 메시지 전송","description":"ProviderEnvelope v1 최종 JSON 1개만 반환합니다. SSE/WebSocket/reconnect cursor는 지원하지 않습니다.\n최종 envelope는 UTF-8 16 KiB 이하이며 id는 requestId와 정확히 일치합니다.\n활성 세션 내 requestId를 대소문자 구분하여 비교합니다. 동일 ID·동일 text(UTF-8 SHA-256)는 저장된 결과를\n반환하고 다른 text는 409 REPLAY_CONFLICT입니다. 진행 중 재요청은 provider 호출을 중복하지 않고 결과 저장까지\n잠금 없이 재조회합니다. 갱신·종료도 진행 중 요청 완료 후 반영합니다. 실패하여 결과가 저장되지 않았다면 재시도에서 provider를 다시 호출합니다.\n결과는 세션이 활성인 동안 재사용하며 refresh는 이 기간을 연장합니다. 만료·종료 후에는 replay도 410입니다.\n현재 저장 데이터의 자동 삭제 기간은 설정되어 있지 않습니다. 앱의 epoch/generation 및 256개 ledger는 앱 소유입니다.\n앱의 30초 deadline이나 연결 종료는 서버/provider 취소를 보장하지 않습니다. 서버 처리가 커밋되었다면\n동일 ID/text 재시도로 결과를 회수할 수 있습니다. DELETE는 진행 중 전송 완료 후 세션을 종료하며 호출을 취소하지 않습니다.\nprovider 연결/read timeout은 gemini 설정(기본 2초/5초)이며 서버 전체 deadline을 의미하지 않습니다.\n","operationId":"send","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceAiMessageRequest"}}},"required":true},"responses":{"502":{"description":"PROVIDER_UNAVAILABLE: provider timeout·일반 장애·비활성 설정. PROVIDER_RESPONSE_INVALID: schema 위반·16 KiB 초과. timeout 전용 code는 없습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"SESSION_EXPIRED: 만료 또는 종료된 세션. replay도 반환하지 않습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"ProviderEnvelope v1 최종 JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderEnvelopeV1"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"SESSION_FORBIDDEN: 다른 사용자 세션. ACCESS_DENIED: 공통 접근 거부","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"VALIDATION_FAILED: text/requestId 검증 실패(errors 포함). INVALID_REQUEST_BODY: JSON 파싱 실패.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"409":{"description":"REPLAY_CONFLICT: 동일 세션·requestId에 다른 text를 보냈습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED: controller 진입 시 IP 기준 Redis 제한. consultations/intro와 공유하며 기본 1분 10회(설정 가능). replay도 제한에 포함됩니다. Retry-After는 제공하지 않습니다. 즉시 반복하지 말고 backoff 후 동일 requestId/text로 재시도합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"RATE_LIMIT_UNAVAILABLE: fail-open=false일 때 제한 저장소 장애. backoff 후 재시도합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"SESSION_NOT_FOUND: 존재하지 않는 세션","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/visitor-verification-reports":{"get":{"tags":["방문 인증"],"summary":"내 방문자 검증 제보 목록 조회","operationId":"listMine","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"400":{"description":"페이지 요청 값 검증 실패 (VALIDATION_FAILED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"page":"1 이상이어야 합니다."}}}}}}},"403":{"description":"활성 일반 사용자 계정이 아님 (TOURIST_ACCOUNT_REQUIRED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}}}}}},"200":{"description":"내 제보 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportPageResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["방문 인증"],"summary":"방문자 검증 제보 생성","description":"활성 일반 사용자가 장소와 제보 유형별로 처리 중인 제보가 없을 때 새 제보를 제출합니다.\n구조화 필드는 reportType과 일치해야 하며, 같은 장소·유형의 SUBMITTED 제보가 있으면 409를 반환합니다.\n","operationId":"submit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCreateRequest"}}},"required":true},"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"201":{"description":"제보 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportResponse"}}}},"409":{"description":"같은 장소·유형의 처리 중 제보가 이미 있음 (ACTIVE_REPORT_ALREADY_EXISTS)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACTIVE_REPORT_ALREADY_EXISTS":{"description":"ACTIVE_REPORT_ALREADY_EXISTS","value":{"message":"같은 장소와 유형의 처리 중인 제보가 이미 있습니다.","code":"ACTIVE_REPORT_ALREADY_EXISTS"}}}}}},"400":{"description":"요청 검증 실패 또는 제보 유형과 구조화 정보 불일치","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/ErrorResponse"}]},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"description":"공백일 수 없습니다."}}},"INVALID_REPORT_DETAILS":{"description":"INVALID_REPORT_DETAILS","value":{"message":"제보 유형과 구조화 정보가 일치하지 않습니다.","code":"INVALID_REPORT_DETAILS"}}}}}},"404":{"description":"장소를 찾을 수 없음 (PLACE_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_NOT_FOUND":{"description":"PLACE_NOT_FOUND","value":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}}}},"403":{"description":"활성 일반 사용자 계정이 아님 (TOURIST_ACCOUNT_REQUIRED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}}}}}}},"security":[{"bearerAuth":[]}]}},"/visitor-verification-reports/{reportId}/corrections":{"get":{"tags":["방문 인증"],"summary":"내 방문자 검증 제보 정정 이력 조회","operationId":"listCorrections","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"200":{"description":"제보 정정 이력 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportCorrectionPageResponse"}}}},"400":{"description":"페이지 요청 값 검증 실패 (VALIDATION_FAILED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"page":"1 이상이어야 합니다."}}}}}}},"403":{"description":"활성 일반 사용자 계정이 아니거나 본인 소유 제보가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}},"CORRECTION_FORBIDDEN":{"description":"CORRECTION_FORBIDDEN","value":{"message":"이 제보 정정을 조회할 권한이 없습니다.","code":"CORRECTION_FORBIDDEN"}}}}}},"404":{"description":"제보를 찾을 수 없음 (REPORT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"REPORT_NOT_FOUND":{"description":"REPORT_NOT_FOUND","value":{"message":"방문자 검증 제보를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["방문 인증"],"summary":"방문자 검증 제보 정정 제출","description":"제보 소유자만 정정을 제출할 수 있습니다.\n원본 제보 상태가 ACCEPTED 또는 REJECTED일 때만 허용되며, 처리 중인 정정이 있으면 새 정정을 제출할 수 없습니다.\n","operationId":"submitCorrection","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionRequest"}}},"required":true},"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"201":{"description":"제보 정정 제출 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportCorrectionResponse"}}}},"409":{"description":"정정 불가 상태 또는 처리 중인 정정 존재","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CORRECTION_NOT_ALLOWED":{"description":"CORRECTION_NOT_ALLOWED","value":{"message":"현재 제보 상태에서는 정정을 제출할 수 없습니다.","code":"CORRECTION_NOT_ALLOWED"}},"ACTIVE_CORRECTION_ALREADY_EXISTS":{"description":"ACTIVE_CORRECTION_ALREADY_EXISTS","value":{"message":"처리 중인 제보 정정이 이미 있습니다.","code":"ACTIVE_CORRECTION_ALREADY_EXISTS"}}}}}},"400":{"description":"요청 검증 실패 또는 정정 내용 불일치","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/ErrorResponse"}]},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"description":"공백일 수 없습니다."}}},"INVALID_CORRECTION_DETAILS":{"description":"INVALID_CORRECTION_DETAILS","value":{"message":"제보 정정 내용이 올바르지 않습니다.","code":"INVALID_CORRECTION_DETAILS"}}}}}},"404":{"description":"제보를 찾을 수 없음 (REPORT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"REPORT_NOT_FOUND":{"description":"REPORT_NOT_FOUND","value":{"message":"방문자 검증 제보를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}}},"403":{"description":"활성 일반 사용자 계정이 아니거나 본인 소유 제보가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}},"REPORT_FORBIDDEN":{"description":"REPORT_FORBIDDEN","value":{"message":"이 제보를 조회할 권한이 없습니다.","code":"REPORT_FORBIDDEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/visit-verification-sessions":{"post":{"tags":["방문 인증"],"summary":"체류 기반 방문 인증 시작","description":"장소 반경 안의 첫 위치 관측으로 인증 세션을 시작합니다. 앱은 nextObservationRecommendedAt 이전에 다음 위치를 제출해야 하며, 원본 좌표는 저장하지 않습니다.","operationId":"start","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitVerificationStartRequest"}}},"required":true},"responses":{"422":{"description":"장소 인증 허용 반경 밖","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"인증 가능한 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"관측 시각 또는 GPS 정확도 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"동일 장소의 진행 중인 인증 세션이 동시에 생성됨","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"인증 세션 시작 또는 진행 중·완료 세션 재반환","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitVerificationSessionResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/visit-verification-sessions/{sessionId}/observations":{"post":{"tags":["방문 인증"],"summary":"체류 인증 위치 관측 제출","description":"서버 수신 시각과 연속 관측 간격으로 체류 시간을 계산합니다. 반경 이탈은 PROXIMITY_LOST, 관측 공백 또는 세션 기한 초과는 EXPIRED로 반환됩니다.","operationId":"submitObservation","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitVerificationObservationRequest"}}},"required":true},"responses":{"404":{"description":"본인 소유 인증 세션 또는 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"진행 상태 또는 완료 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitVerificationSessionResponse"}}}},"409":{"description":"일일 완료 방문 인증이 이미 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"관측 시각 또는 GPS 정확도 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/visit-verification-sessions/foreground":{"post":{"tags":["방문 인증"],"summary":"좌표 기반 foreground 방문 인증 시작","description":"장소 ID를 받지 않고 서버가 현재 좌표 주변의 공개·운영 중 장소를 판정해 인증 세션을 시작합니다. 진행 중인 동일 장소 세션은 우선 복구하며, 새 후보는 거리순으로 비교해 1·2순위 거리 차이가 GPS 정확도 두 배보다 클 때만 가장 가까운 장소를 선택합니다.","operationId":"startForeground","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForegroundVisitVerificationStartRequest"}}},"required":true},"responses":{"404":{"description":"현재 좌표에서 인증할 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"장소 인증 허용 반경 밖","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"현재 좌표에서 장소를 하나로 결정할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"관측 시각 또는 GPS 정확도 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"인증 세션 시작 또는 진행 중·완료 세션 재반환","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitVerificationSessionResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/travel-schedules":{"get":{"tags":["여행"],"summary":"내 여행 일정 목록 조회","description":"현재 인증된 사용자의 여행 일정을 조회합니다.","operationId":"getTravelSchedules","responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelScheduleListResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["여행"],"summary":"여행 일정 생성","description":"현재 인증된 사용자에게 날짜 범위의 여행 일정을 추가합니다.","operationId":"createTravelSchedule","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TravelScheduleCreateRequest"}}},"required":true},"responses":{"400":{"description":"기간 역전 또는 과거 날짜","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidPeriod":{"description":"invalidPeriod","value":{"message":"여행 종료일은 시작일보다 빠를 수 없습니다.","code":"INVALID_TRAVEL_SCHEDULE_PERIOD"}},"pastStartDate":{"description":"pastStartDate","value":{"message":"여행 시작일은 오늘보다 이전일 수 없습니다.","code":"TRAVEL_SCHEDULE_START_DATE_IN_PAST"}}}}}},"201":{"description":"생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelScheduleResponse"}}}},"409":{"description":"기존 일정과 기간 겹침","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"기존 여행 일정과 기간이 겹칩니다.","code":"TRAVEL_SCHEDULE_PERIOD_OVERLAP"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/travel-schedules/{scheduleId}/cancel":{"post":{"tags":["여행"],"summary":"여행 일정 취소","description":"본인 여행 일정을 취소 상태로 전환합니다.","operationId":"cancelTravelSchedule","parameters":[{"name":"scheduleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"일정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"취소 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelScheduleResponse"}}}},"409":{"description":"다른 요청으로 일정이 변경됨","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/profile-image":{"post":{"tags":["내 정보·계정 연동"],"summary":"내 프로필 이미지 변경","description":"JPEG 또는 PNG 프로필 이미지를 업로드하고 즉시 변경합니다.","operationId":"changeProfileImage","requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"400":{"description":"파일이 비어 있거나 허용되지 않은 이미지 형식","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"파일 크기 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"프로필 이미지 저장소 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"프로필 이미지 변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProfileImageUploadResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/oauth-accounts/google/link":{"post":{"tags":["내 정보·계정 연동"],"summary":"Google 계정 연결 시작","description":"현재 인증된 사용자 계정에 Google OAuth 계정을 연결하기 위한 OAuth 인증 흐름을 시작합니다.","operationId":"startGoogleLink","responses":{"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"연결 시작 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OAuthAccountLinkStartResponse"},"example":{"provider":"GOOGLE","authorizationUrl":"/oauth2/authorization/google","message":"Google 계정 연결을 시작합니다."}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications":{"get":{"tags":["장소 등록 신청"],"summary":"내 Merchant 장소 신청 목록 조회","operationId":"list","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 생성","operationId":"create_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{id}/submit":{"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 제출","operationId":"submit_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{id}/reopen":{"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 재개","operationId":"reopen","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{id}/cancel":{"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 취소","operationId":"cancel","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{applicationId}/attachments":{"get":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 첨부파일 목록 조회","operationId":"list_1","parameters":[{"name":"applicationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceApplicationAttachmentResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 첨부파일 업로드","description":"NEW_PLACE와 EXISTING_PLACE_CLAIM 초안에만 업로드할 수 있습니다. 서버가 파일 형식·서명·크기·악성코드를 검증하고 private 저장소에 보관합니다.","operationId":"upload","parameters":[{"name":"applicationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"documentType","in":"query","required":true,"schema":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationAttachmentResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{applicationId}/attachments/reorder":{"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 대표 이미지 순서 변경","operationId":"reorder","parameters":[{"name":"applicationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"attachmentIds","in":"query","required":true,"schema":{"type":"array","items":{"type":"integer","format":"int64"}}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/bookmarks":{"get":{"tags":["즐겨찾기"],"summary":"장소 북마크 목록 조회","description":"현재 인증된 사용자가 북마크한 장소 목록을 조회합니다.","operationId":"listBookmarks","parameters":[{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"북마크 목록 조회 성공","content":{"*/*":{"example":{"places":[{"id":17,"name":"진주성","address":"경상남도 진주시 남강로 626","latitude":35.1894,"longitude":128.0789}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["즐겨찾기"],"summary":"장소 북마크 추가","description":"placeId를 기반으로 장소를 북마크에 추가합니다.","operationId":"createBookmark","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookmarkCreateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"201":{"description":"북마크 추가 성공","content":{"*/*":{"example":{"id":1,"placeId":17,"message":"장소 북마크를 추가했습니다."}}}},"409":{"description":"이미 북마크한 장소","content":{"*/*":{"example":{"message":"이미 북마크한 장소입니다.","code":"BOOKMARK_ALREADY_EXISTS"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/change-pw":{"post":{"tags":["내 정보·계정 연동"],"summary":"비밀번호 변경","description":"현재 비밀번호를 확인한 뒤 새 비밀번호로 변경합니다.","operationId":"changePassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"200":{"description":"비밀번호 변경 성공","content":{"*/*":{"example":"비밀번호 변경 완료"}}},"401":{"description":"현재 비밀번호 불일치 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid-credentials":{"description":"invalid-credentials","value":{"message":"아이디 또는 비밀번호가 올바르지 않습니다.","code":"INVALID_CREDENTIALS"}},"invalid-token":{"description":"invalid-token","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"400":{"description":"입력값 검증 실패 또는 새 비밀번호 확인 불일치","content":{"*/*":{"examples":{"validation-failure":{"description":"validation-failure","value":{"message":"입력값을 확인해주세요.","errors":{"newPassword":"비밀번호는 8자 이상이어야 합니다."}}},"password-mismatch":{"description":"password-mismatch","value":{"message":"비밀번호가 서로 다릅니다.","code":"PASSWORD_MISMATCH"}}}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/change-id":{"post":{"tags":["내 정보·계정 연동"],"summary":"아이디 변경","description":"현재 인증된 사용자의 아이디를 새 아이디로 변경합니다.","operationId":"changeUsername","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeUsernameRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"newUsername":"아이디는 4자 이상 50자 이하여야 합니다."}}}}},"200":{"description":"아이디 변경 성공","content":{"*/*":{"example":"아이디 변경 완료"}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"409":{"description":"이미 사용 중인 아이디","content":{"*/*":{"example":{"message":"이미 있는 아이디입니다.","code":"USERNAME_ALREADY_EXISTS"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/scout-field-reports":{"get":{"tags":["스카우트"],"summary":"내 Scout 현장 제보 목록 조회","operationId":"listMine_2","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["스카우트"],"summary":"Scout 현장 제보 생성","operationId":"submit_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportCreateRequest"}}},"required":true},"responses":{"403":{"description":"활성 Scout 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"201":{"description":"현장 제보 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"409":{"description":"처리 중인 동일 제보 존재","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"400":{"description":"제보 내용 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/routes":{"post":{"tags":["장소 탐색"],"summary":"자동차·대중교통·보행자 추천 경로 조회","description":"WGS84 출발·도착 좌표로 자동차는 NAVER Directions, 대중교통·보행자는 TMAP 경로를 조회합니다. JWT 인증 필수이며 공급자 키는 서버에서 관리합니다. 자전거는 지원하지 않습니다. 응답은 저장하지 않으며 자동 재시도를 하지 않습니다. 기본 사용자당 10회/분, IP당 100회/분이며 설정에 따라 달라질 수 있습니다.","operationId":"findRoute","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RouteRequest"},"example":{"origin":{"latitude":37.5665,"longitude":126.978},"destination":{"latitude":37.4979,"longitude":127.0276},"mode":"car"}}},"required":true},"responses":{"403":{"description":"기존 접근 권한 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"ROUTE_RATE_LIMITED: 사용자/IP 제한 초과","headers":{"Retry-After":{"description":"두 제한 구간 중 긴 시간(초), 안전한 재시도 대기 상한","style":"simple","schema":{"type":"integer"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"기존 JWT 인증 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"504":{"description":"ROUTE_PROVIDER_TIMEOUT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"ROUTE_PROVIDER_UNAVAILABLE: 비활성·미설정·공급자 인증/쿼터/장애/비정상 응답. 호출 제한 저장소 장애는 기존 RATE_LIMIT_UNAVAILABLE","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"자동차, 대중교통 또는 보행자 경로","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RouteResponse"},{"$ref":"#/components/schemas/TransitRouteResponse"},{"$ref":"#/components/schemas/WalkingRouteResponse"}]}}}},"400":{"description":"INVALID_ROUTE_REQUEST: 누락·문자열·비유한 좌표, 범위 오류, 동일 좌표, 알 수 없는 mode","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"UNSUPPORTED_ROUTE_MODE 또는 ROUTE_NOT_FOUND","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"unsupported":{"description":"unsupported","value":{"message":"지원하지 않는 이동수단입니다.","code":"UNSUPPORTED_ROUTE_MODE"}},"notFound":{"description":"notFound","value":{"message":"자동차 경로를 찾을 수 없습니다.","code":"ROUTE_NOT_FOUND"}}}}}}},"security":[{"bearerAuth":[]}]}},"/reservations":{"get":{"tags":["예약"],"summary":"내 예약 목록 조회","operationId":"list_2","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["예약"],"summary":"예약 생성","description":"confirmationToken을 제공하면 확인한 대상·시간·인원·취소 정책을 원자적으로 검증합니다. 토큰 생략은 기존 터치 계약이며 확인 조건 보장은 없습니다. 성공은 예약 생성(PENDING)이며 상점주 승인 대기 상태입니다. 응답 유실에는 동일 키·토큰·본문을 재전송하세요. 사용자별 키는 예약 또는 거절 기록이 보존되는 동안 만료하지 않습니다. 동일 요청의 성공은 견적 만료 후에도 201로 복구하며, 확정 거절은 같은 오류로 복구합니다. timeout/5xx는 결과 불명이므로 실패로 확정하거나 새 키를 만들지 않습니다. 조건 재확인 후 새 의도는 새 토큰·키로 제출합니다.","operationId":"create_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationCreateRequest"}}},"required":true},"responses":{"201":{"description":"예약 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"404":{"description":"QUOTE_NOT_FOUND: 본인 견적 부재. RESERVATION_SLOT_NOT_FOUND: 슬롯 부재. AVAILABILITY_NOT_FOUND: 기존 터치 요청의 예약 가능 시간 부재.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"IDEMPOTENCY_KEY_REUSED: 같은 키/토큰의 다른 요청. QUOTE_REQUEST_MISMATCH: 대상·인원 불일치. QUOTE_CONDITIONS_CHANGED, RESERVATION_SLOT_INACTIVE, RESERVATION_CAPACITY_EXCEEDED: 최신 조건을 다시 확인해야 합니다. AVAILABILITY_CAPACITY_EXCEEDED: 기존 터치 요청의 정원 부족.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"QUOTE_TERMS_UNAVAILABLE: 시간대/취소 정책 미설정 또는 시간 해석 불가. 취소 정책을 추정하지 않습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"QUOTE_EXPIRED: 견적 만료. 최신 조건과 새 토큰으로 재확인이 필요합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/reservations/{reservationId}/cancel":{"post":{"tags":["예약"],"summary":"내 예약 취소","operationId":"cancel_1","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"409":{"description":"CANCELLATION_NOT_ALLOWED: 취소 불가 또는 기한 경과. RESERVATION_REFUND_REQUIRED: 처리 중 결제/미환불 결제. INVALID_RESERVATION_STATE: 확정되지 않은 예약.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/reviews":{"get":{"tags":["장소 리뷰"],"summary":"장소 리뷰 목록 조회","operationId":"list_4","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PagePlaceReviewResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 리뷰"],"summary":"장소 리뷰 작성","operationId":"create_3","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceReviewCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceReviewResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/reviews/media":{"post":{"tags":["리뷰 미디어"],"summary":"장소 리뷰 사진 업로드","description":"리뷰 작성 전에 JPEG 또는 PNG 사진 한 개를 업로드합니다. 업로드된 사진은 24시간 안에 본인의 같은 장소 리뷰에 한 번만 연결할 수 있습니다.","operationId":"upload_1","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"415":{"description":"지원하지 않는 파일 형식","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"파일 크기 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"리뷰 사진 저장소 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"비어 있거나 손상된 파일","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"리뷰 사진 업로드 완료","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceReviewMediaUploadResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/map-link-conversions":{"post":{"tags":["장소 상세·메뉴"],"summary":"지도 링크 전환 기록","description":"같은 사용자·장소·전환 유형에서 requestId가 같은 재시도는 중복 집계하지 않고 204를 반환합니다.","operationId":"record","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"minimum":1,"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MapLinkConversionRequest"}}},"required":true},"responses":{"204":{"description":"전환 기록 또는 동일 요청 재처리 성공"},"400":{"description":"전환 요청값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/information-reports":{"post":{"tags":["장소 정보 제보"],"summary":"장소 정보 신고 생성","operationId":"submit_3","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/{id}/media/exploration":{"get":{"tags":["장소 상세·메뉴"],"summary":"장소 탐색용 미디어 조회","description":"탐색 화면에 노출할 장소 미디어만 조회합니다.","operationId":"getExplorationMedia","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"200":{"description":"탐색용 미디어 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 상세·메뉴"],"summary":"장소 탐색용 미디어 등록","description":"장소 소유자가 탐색 화면에 노출할 미디어를 등록합니다.","operationId":"createExplorationMedia","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMediaCreateRequest"}}},"required":true},"responses":{"201":{"description":"탐색용 미디어 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaItem"}}}},"403":{"description":"본인 소유가 아닌 장소 미디어 관리 시도","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"자신의 장소 미디어만 관리할 수 있습니다.","code":"OTHERS_PLACE_MEDIA_NOT_MANAGED"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/recommendations/click":{"post":{"tags":["장소 탐색"],"summary":"추천 장소 클릭 기록","description":"추천 목록에서 사용자가 선택한 장소 클릭을 기록합니다.","operationId":"recordRecommendationClick","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceRecommendationClickRequest"}}},"required":true},"responses":{"400":{"description":"요청값 검증 실패","content":{"*/*":{"example":{"message":"placeId는 필수입니다."}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"201":{"description":"추천 장소 클릭 기록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceRecommendationClickResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/information-reports/{reportId}/disputes":{"post":{"tags":["장소 정보 제보"],"summary":"장소 정보 신고 반박 생성","operationId":"submitDispute","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/offers/{offerId}/coupons":{"post":{"tags":["쿠폰·혜택"],"summary":"관광객 Coupon 발급","description":"진행 중인 여행 일정이 있는 일반 사용자에게 Offer당 한 번만 발급합니다. 발급 시 Offer 제목·혜택과 장소 정보를 Coupon에 스냅샷으로 저장합니다.","operationId":"issue","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"중복 발급, 발급 기간 종료 또는 수량 소진","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"Coupon 발급 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CouponResponse"}}}},"403":{"description":"관광객 발급 조건 불충족","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/verified-boost-selections":{"get":{"tags":["Verified Boost"],"summary":"내 Verified Boost 선택 목록 조회","operationId":"list_9","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostSelectionPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 선택","operationId":"select","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifiedBoostSelectionCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostSelectionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/verified-boost-executions":{"get":{"tags":["Verified Boost"],"summary":"내 Verified Boost 집행 목록 조회","operationId":"list_11","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostExecutionPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Verified Boost"],"summary":"Verified Boost 집행 시작","operationId":"start_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifiedBoostExecutionStartRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostExecutionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/verified-boost-executions/{executionId}/stop":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 집행 중단","operationId":"stop","parameters":[{"name":"executionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostExecutionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations/{reservationId}/cancel":{"post":{"tags":["예약 관리"],"summary":"예약 취소","operationId":"cancel_2","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/reviews/{reviewId}/deletion-requests":{"post":{"tags":["리뷰 관리"],"summary":"점주 리뷰 숨김 및 삭제 신청","operationId":"requestDeletion","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"reviewId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceReviewDeletionRequestCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-notices":{"get":{"tags":["메뉴·운영 공지"],"summary":"점주 상점 운영 상태 공지 목록 조회","description":"점주 또는 해당 장소의 운영 공지 관리 권한이 있는 팀원이 전체 운영 상태 공지를 조회합니다.","operationId":"listNotices","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"200":{"description":"운영 상태 공지 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeListResponse"}}}},"403":{"description":"해당 장소 운영 공지를 조회할 권한이 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["메뉴·운영 공지"],"summary":"점주 상점 운영 상태 공지 생성","description":"OWNER만 본인 장소에 공지를 생성할 수 있습니다. startsAt이 현재 시각 이후이면 SCHEDULED, 그렇지 않으면 ACTIVE로 생성되며, 같은 장소·공지 유형에는 활성 또는 예약 공지를 하나만 둘 수 있습니다.","operationId":"createNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCreateRequest"}}},"required":true},"responses":{"201":{"description":"운영 상태 공지 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"403":{"description":"장소 운영 공지 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_OPERATING_NOTICE_FORBIDDEN":{"description":"PLACE_OPERATING_NOTICE_FORBIDDEN","value":{"message":"해당 상점 운영 상태 공지를 관리할 권한이 없습니다.","code":"PLACE_OPERATING_NOTICE_FORBIDDEN"}}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_NOT_FOUND":{"description":"PLACE_NOT_FOUND","value":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}}}},"409":{"description":"같은 공지 유형의 활성 또는 예약 공지가 이미 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_OPERATING_NOTICE_ALREADY_ACTIVE":{"description":"PLACE_OPERATING_NOTICE_ALREADY_ACTIVE","value":{"message":"이미 활성 또는 예약된 상점 운영 상태 공지가 있습니다.","code":"PLACE_OPERATING_NOTICE_ALREADY_ACTIVE"}}}}}},"400":{"description":"입력값 또는 공지 상태가 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"PLACE_OPERATING_NOTICE_INVALID_REQUEST":{"description":"PLACE_OPERATING_NOTICE_INVALID_REQUEST","value":{"message":"상점 운영 상태 공지 요청이 올바르지 않습니다.","code":"PLACE_OPERATING_NOTICE_INVALID_REQUEST"}}}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-notices/{noticeId}/cancel":{"post":{"tags":["메뉴·운영 공지"],"summary":"점주 상점 운영 상태 공지 취소","description":"OWNER만 본인 장소의 SCHEDULED 또는 ACTIVE 공지를 취소할 수 있습니다. 이미 취소되었거나 종료된 공지는 400 PLACE_OPERATING_NOTICE_INVALID_REQUEST로 응답하며, 권한 부족과 대상 없음은 각각 PLACE_OPERATING_NOTICE_FORBIDDEN, PLACE_OPERATING_NOTICE_NOT_FOUND로 구분합니다.","operationId":"cancelNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCancelRequest"}}},"required":true},"responses":{"400":{"description":"입력값 또는 취소 가능하지 않은 공지 상태","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"PLACE_OPERATING_NOTICE_INVALID_REQUEST":{"description":"PLACE_OPERATING_NOTICE_INVALID_REQUEST","value":{"message":"상점 운영 상태 공지 요청이 올바르지 않습니다.","code":"PLACE_OPERATING_NOTICE_INVALID_REQUEST"}}}}}},"403":{"description":"장소 운영 공지 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"운영 상태 공지 취소 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소 또는 공지를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus":{"get":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 목록 조회","operationId":"list_13","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["메뉴·운영 공지"],"summary":"장소 메뉴 등록","operationId":"create_4","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMenuCreateRequest"}}},"required":true},"responses":{"403":{"description":"메뉴 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"메뉴 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"400":{"description":"메뉴 입력값 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus/{menuId}/deactivate":{"post":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 비활성화","operationId":"deactivate","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/members/invitations":{"post":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 초대","description":"OWNER 또는 MANAGER가 STAFF 또는 MANAGER 역할로 초대할 수 있습니다. expiresAt을 생략하면 생성 시각 기준 7일 후 만료됩니다. 활성 팀원 또는 같은 대상의 PENDING 초대가 있으면 409입니다. REVOKED 팀원은 새 초대 수락 시 재활성화됩니다.","operationId":"invite","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantTeamInviteRequest"}}},"required":true},"responses":{"400":{"description":"입력값, OWNER 역할 또는 만료 시각이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"MERCHANT_TEAM_INVITATION_INVALID_EXPIRATION":{"description":"MERCHANT_TEAM_INVITATION_INVALID_EXPIRATION","value":{"message":"Merchant 팀원 초대 만료 시각이 올바르지 않습니다.","code":"MERCHANT_TEAM_INVITATION_INVALID_EXPIRATION"}}}}}},"403":{"description":"OWNER 또는 MANAGER 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"초대 대상을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"활성 팀원이거나 대기 중인 초대가 이미 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_INVITATION_ALREADY_EXISTS":{"description":"MERCHANT_TEAM_INVITATION_ALREADY_EXISTS","value":{"message":"대기 중인 Merchant 팀원 초대가 이미 존재합니다.","code":"MERCHANT_TEAM_INVITATION_ALREADY_EXISTS"}}}}}},"201":{"description":"팀원 초대 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantTeamInvitationResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/media":{"get":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 탐색 미디어 조회","operationId":"getMedia","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 업로드 완료 탐색 미디어 등록","description":"업로드 URL 발급 응답의 s3Key만 등록할 수 있습니다. 만료되거나 등록 완료된 key는 거부됩니다. 등록되지 않은 객체는 S3 lifecycle 정책이 정리합니다.","operationId":"createMedia","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaCreateRequest"}}},"required":true},"responses":{"201":{"description":"탐색 미디어 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/media/upload-url":{"post":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 탐색 미디어 업로드 URL 발급","operationId":"createMediaUploadUrl","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaUploadRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaUploadResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/place-information-reverification-requests/{requestId}/responses":{"post":{"tags":["장소 정보 관리"],"summary":"장소 정보 재확인 응답 제출","operationId":"respond","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponseRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/payments/{paymentId}/refund":{"post":{"tags":["결제"],"summary":"결제 전액 환불","operationId":"refund","parameters":[{"name":"paymentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers":{"get":{"tags":["캠페인·혜택"],"summary":"내 관광객 전용 Offer 목록 조회","description":"placeId는 로그인한 Merchant Owner가 소유한 장소의 Offer만 조회합니다. 소유하지 않은 장소 ID를 전달하면 빈 목록을 반환합니다.","operationId":"list_16","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"placeId","in":"query","description":"소유 장소 ID","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"status","in":"query","description":"Offer 상태","required":false,"schema":{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED"]}}],"responses":{"200":{"description":"Offer 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferPageResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["캠페인·혜택"],"summary":"관광객 전용 Offer 초안 등록","operationId":"create_5","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferCreateRequest"}}},"required":true},"responses":{"403":{"description":"장소 소유 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"Offer 초안 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers/{offerId}/publish":{"post":{"tags":["캠페인·혜택"],"summary":"관광객 전용 Offer 게시","operationId":"publish","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"Offer 게시 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"409":{"description":"게시할 수 없는 상태 또는 기간","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers/{offerId}/close":{"post":{"tags":["캠페인·혜택"],"summary":"관광객 전용 Offer 종료","operationId":"close","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"Offer 종료 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"종료할 수 없는 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers/coupons/redeem":{"post":{"tags":["캠페인·혜택"],"summary":"관광객 Coupon 사용 처리","description":"본인이 소유한 장소의 Offer에서 발급된 Coupon만 사용할 수 있습니다. 응답의 Offer·장소 요약은 발급 시점 스냅샷입니다.","operationId":"redeem","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CouponRedeemRequest"}}},"required":true},"responses":{"409":{"description":"사용되었거나 만료된 Coupon","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"Coupon 사용 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CouponResponse"}}}},"404":{"description":"Coupon을 찾을 수 없거나 소유 장소의 Coupon이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/invitations/{invitationId}/accept":{"post":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 초대 수락","description":"초대 수신자만 수락할 수 있습니다. 이미 수락된 초대는 활성 팀원이 존재하면 동일한 팀원 응답을 반환합니다. 초대 수락은 초대와 기존 팀원을 잠가 동시 요청에서도 중복 팀원을 만들지 않으며, 만료 초대는 410 MERCHANT_TEAM_INVITATION_EXPIRED로 응답합니다. 수신자 불일치는 MERCHANT_TEAM_PERMISSION_REQUIRED, 비활성 계정은 MERCHANT_TEAM_MEMBER_NOT_ACTIVE로 구분합니다.","operationId":"accept","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"409":{"description":"수신자 계정이 비활성 상태이거나 기존 팀원을 재활성화할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"팀원 초대 수락 성공 또는 반복 수락의 멱등 응답","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantTeamMemberResponse"}}}},"404":{"description":"초대를 찾을 수 없거나 수락된 초대에 활성 팀원이 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"초대 수신자가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"초대가 만료됨","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_INVITATION_EXPIRED":{"description":"MERCHANT_TEAM_INVITATION_EXPIRED","value":{"message":"Merchant 팀원 초대가 만료되었습니다.","code":"MERCHANT_TEAM_INVITATION_EXPIRED"}}}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns":{"get":{"tags":["캠페인·혜택"],"summary":"내 팝업 캠페인 목록 조회","operationId":"listCampaigns","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["캠페인·혜택"],"summary":"팝업 캠페인 초안 등록","operationId":"createCampaign","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PopupCampaignCreateRequest"}}},"required":true},"responses":{"404":{"description":"브랜드를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"팝업 캠페인 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignResponse"}}}},"403":{"description":"장소 소유 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/{campaignId}/publish":{"post":{"tags":["캠페인·혜택"],"summary":"팝업 캠페인 공개","operationId":"publish_1","parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/{campaignId}/close":{"post":{"tags":["캠페인·혜택"],"summary":"팝업 캠페인 종료","operationId":"close_1","parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/brands":{"get":{"tags":["캠페인·혜택"],"summary":"내 브랜드 목록 조회","operationId":"listBrands","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BrandPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["캠페인·혜택"],"summary":"브랜드 등록","operationId":"createBrand","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandCreateRequest"}}},"required":true},"responses":{"409":{"description":"브랜드명 중복","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"브랜드 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BrandResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities":{"get":{"tags":["예약 가능 시간"],"summary":"내 예약 가능 시간 목록 조회","operationId":"list_17","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AvailabilityResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["예약 가능 시간"],"summary":"예약 가능 시간 등록","description":"productId, productType을 보내면 null이어도 400 INVALID_REQUEST_BODY로 거절합니다. 상품 필드를 제거한 단일 예약 슬롯 본문을 사용하세요.","operationId":"create_6","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityUpsertRequest"}}},"required":true},"responses":{"201":{"description":"예약 가능 시간 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities/{availabilityId}/deactivate":{"post":{"tags":["예약 가능 시간"],"summary":"예약 가능 시간 비활성화","operationId":"deactivate_1","parameters":[{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities/{availabilityId}/activate":{"post":{"tags":["예약 가능 시간"],"summary":"예약 가능 시간 활성화","operationId":"activate","parameters":[{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/location-check-ins":{"get":{"tags":["방문 인증"],"summary":"내 위치 체크인 목록 조회","operationId":"listMine_5","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LocationCheckInPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["방문 인증"],"summary":"클라이언트 위치 기반 방문 체크인","description":"클라이언트가 제출한 위치와 장소 좌표의 근접성을 확인하며 실제 GPS를 증명하지 않습니다.","operationId":"checkIn","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationCheckInRequest"}}},"required":true},"responses":{"400":{"description":"관측 시각 또는 정확도 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"위치 근접성 확인 기록 생성","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LocationCheckInResponse"}}}},"422":{"description":"장소 체크인 허용 반경 밖","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"일일 중복 체크인","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"체크인 가능한 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/location-check-ins/{checkInId}/evidence":{"get":{"tags":["방문 인증"],"summary":"내 방문 체크인 증빙 조회","operationId":"get_12","parameters":[{"name":"checkInId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"본인 소유 체크인 또는 증빙을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["방문 인증"],"summary":"방문 체크인 증빙 업로드","description":"본인의 완료된 체크인에 JPEG 또는 PNG 증빙 이미지 한 개를 등록합니다. 증빙은 보관 기간 만료 후 삭제됩니다.","operationId":"upload_2","parameters":[{"name":"checkInId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"404":{"description":"본인 소유 체크인을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"체크인 증빙이 이미 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"파일 크기 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"증빙 저장소 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"증빙 등록 완료","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitEvidenceResponse"}}}},"400":{"description":"비어 있거나 지원하지 않는 이미지","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/firebase/fcm-tokens":{"post":{"tags":["알림"],"summary":"FCM 토큰 등록","description":"현재 기기의 FCM 토큰을 사용자에게 등록하거나 재등록합니다.","operationId":"registerFcmToken","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FcmTokenRequest"}}},"required":true},"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["알림"],"summary":"FCM 토큰 삭제","description":"로그아웃 또는 토큰 폐기 시 현재 기기의 FCM 토큰을 삭제합니다.","operationId":"deleteFcmToken","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FcmTokenRequest"}}},"required":true},"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/consultations/intro":{"post":{"tags":["상담 시작"],"summary":"첫 상담 안내 생성","description":"첫 사용자 질문만 외부 AI에 전달해 짧은 안내문을 생성합니다. AI를 사용할 수 없으면 기본 안내문을 반환합니다.","operationId":"createIntro","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsultationIntroRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationIntroResponse"}}}},"200":{"description":"첫 상담 안내 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationIntroResponse"}}}},"429":{"description":"IP 요청 제한 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationIntroResponse"}}}}}}},"/community/posts":{"get":{"tags":["커뮤니티 게시글"],"summary":"전체 커뮤니티 게시글 목록","description":"최신순. 국가 미설정 게시글은 전체 조회에만 포함되며 국가 필터로 추론하지 않습니다. 단일 카테고리를 유지합니다.","operationId":"findAll","parameters":[{"name":"countryCode","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"400":{"description":"INVALID_COUNTRY 또는 페이지 범위 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["커뮤니티 게시글"],"summary":"커뮤니티 게시글 등록","description":"인증된 사용자가 카테고리, 제목, 본문, 연결 장소 ID 목록으로 게시글을 등록합니다.","operationId":"create_7","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityPostCreateRequest"}}},"required":true},"responses":{"400":{"description":"카테고리, 입력값 또는 장소 선택이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"201":{"description":"커뮤니티 게시글 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostCreateResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"연결할 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/reports":{"post":{"tags":["신고"],"summary":"커뮤니티 게시글 신고","description":"동일 사용자·대상은 처리 상태와 관계없이 한 번만 신고할 수 있습니다. 접수만으로 대상이 숨겨지지는 않습니다.","operationId":"reportPost","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityReportCreateRequest"}}},"required":true},"responses":{"201":{"description":"신고 접수 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityReportCreateResponse"}}}},"409":{"description":"이미 신고한 대상","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"신고 대상이 없거나 게시글에 속하지 않는 댓글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"신고 사유 또는 설명이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/places/{placeId}/view":{"post":{"tags":["커뮤니티 게시글"],"summary":"게시글 경유 장소 상세 조회","description":"연결 장소를 조회하고 사용자별 하루 1회만 커뮤니티 유입 조회수를 증가합니다.","operationId":"record_1","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/likes":{"get":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 좋아요 상태 조회","operationId":"find","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostLikeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 좋아요 등록","operationId":"like","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostLikeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 좋아요 취소","operationId":"cancel_5","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostLikeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/comments":{"get":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 댓글 목록 조회","description":"댓글·답글을 최신순 평탄 목록으로 조회합니다. parentCommentId 지정 시 해당 부모의 답글만 페이지 조회하며 숨김 부모의 답글은 제외합니다.","operationId":"findAll_1","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}},{"name":"parentCommentId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"댓글 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostCommentListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 댓글 등록","description":"인증된 사용자가 존재하는 게시글에 댓글을 등록합니다.","operationId":"create_8","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityPostCommentCreateRequest"}}},"required":true},"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"댓글 입력값이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"201":{"description":"댓글 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostCommentCreateResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/comments/{commentId}/reports":{"post":{"tags":["신고"],"summary":"커뮤니티 댓글 신고","description":"동일 사용자·대상은 처리 상태와 관계없이 한 번만 신고할 수 있습니다. 접수만으로 대상이 숨겨지지는 않습니다.","operationId":"reportComment","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityReportCreateRequest"}}},"required":true},"responses":{"201":{"description":"신고 접수 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityReportCreateResponse"}}}},"409":{"description":"이미 신고한 대상","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"신고 대상이 없거나 게시글에 속하지 않는 댓글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"신고 사유 또는 설명이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/images":{"post":{"tags":["커뮤니티 게시글"],"summary":"게시글 이미지 업로드","description":"JPEG/PNG 10MiB 이하. 검증 후 메타데이터를 제거해 저장하며 최대 10개의 본인 imageId를 게시글에 입력 순서대로 연결합니다. 미사용 이미지는 24시간 후 삭제 Outbox로 정리합니다.","operationId":"upload_3","requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"400":{"description":"IMAGE_FILE_INVALID: 빈 파일·크기·실제 형식 오류. INVALID_REQUEST_PARAMETER: file 누락","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityImageUploadResponse"}}}},"503":{"description":"IMAGE_UPLOAD_UNAVAILABLE: 저장소 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityImageUploadResponse"}}}},"413":{"description":"UPLOAD_TOO_LARGE: multipart 파일·요청 크기 제한 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"이미지 ID·URL 및 만료 시각","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityImageUploadResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/comments/{commentId}/likes":{"get":{"tags":["댓글·좋아요"],"summary":"커뮤니티 댓글 좋아요 상태 조회","operationId":"find_1","parameters":[{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 좋아요 수·본인 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityCommentLikeResponse"}}}},"404":{"description":"COMMENT_NOT_FOUND: 없는 댓글·숨김 댓글/부모/게시글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["댓글·좋아요"],"summary":"커뮤니티 댓글 좋아요 등록","operationId":"like_1","parameters":[{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 좋아요 수·본인 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityCommentLikeResponse"}}}},"404":{"description":"COMMENT_NOT_FOUND: 없는 댓글·숨김 댓글/부모/게시글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["댓글·좋아요"],"summary":"커뮤니티 댓글 좋아요 취소","operationId":"cancel_6","parameters":[{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 좋아요 수·본인 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityCommentLikeResponse"}}}},"404":{"description":"COMMENT_NOT_FOUND: 없는 댓글·숨김 댓글/부모/게시글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/auth/token/refresh":{"post":{"tags":["로그인·세션"],"summary":"토큰 재발급","description":"HttpOnly Cookie의 Refresh Token을 검증한 뒤 Access Token을 재발급하고, 회전된 Refresh Token은 Cookie로 갱신합니다.","operationId":"refreshToken","responses":{"404":{"description":"토큰에 해당하는 사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"유효하지 않은 리프레시 토큰","content":{"*/*":{"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"토큰 재발급 성공","headers":{"Set-Cookie":{"description":"회전된 HttpOnly Refresh Token Cookie","style":"simple","schema":{"type":"string"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RefreshTokenResponse"}}}}}}},"/auth/signup":{"post":{"tags":["회원가입·이메일 인증"],"summary":"회원가입","description":"아이디, 이메일, 비밀번호와 기본 프로필 정보를 입력받아 새 사용자를 생성합니다.","operationId":"signup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"201":{"description":"회원가입 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserResponse"},"example":{"id":1,"username":"pingdom_user","email":"pingdom@example.com","birthYear":1998,"profileImageUrl":"https://cdn.pingdom.com/profiles/user1.png","language":"ko","country":"KR","role":"USER"}}}},"409":{"description":"이미 사용 중인 아이디 또는 이메일","content":{"*/*":{"examples":{"duplicate-username":{"description":"duplicate-username","value":{"message":"이미 사용 중인 아이디입니다.","code":"DUPLICATE_USERNAME"}},"duplicate-email":{"description":"duplicate-email","value":{"message":"이미 사용 중인 이메일입니다.","code":"DUPLICATE_EMAIL"}}}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"examples":{"invalid-username":{"description":"invalid-username","value":{"message":"입력값을 확인해주세요.","errors":{"username":"아이디는 4자 이상 50자 이하여야 합니다."}}},"invalid-email":{"description":"invalid-email","value":{"message":"입력값을 확인해주세요.","errors":{"email":"이메일 형식이 올바르지 않습니다."}}},"invalid-language":{"description":"invalid-language","value":{"message":"입력값을 확인해주세요.","errors":{"language":"언어는 20자 이하여야 합니다."}}}}}}}}}},"/auth/password-reset/request":{"post":{"tags":["비밀번호 재설정"],"summary":"비밀번호 재설정 토큰 발급","description":"이메일 주소로 비밀번호 재설정 토큰을 발급하고 메일 발송 이벤트를 생성합니다.","operationId":"requestPasswordReset","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"email":"이메일 형식이 올바르지 않습니다."}}}}},"200":{"description":"비밀번호 재설정 요청 접수"}}}},"/auth/password-reset/confirm":{"post":{"tags":["비밀번호 재설정"],"summary":"비밀번호 재설정 완료","description":"메일로 발급된 재설정 토큰을 검증해 새 비밀번호를 설정합니다.","operationId":"confirmPasswordReset","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirmRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패 또는 유효하지 않은 재설정 토큰","content":{"*/*":{"examples":{"invalid-token":{"description":"invalid-token","value":{"message":"비밀번호 재설정 토큰이 올바르지 않습니다.","code":"INVALID_PASSWORD_RESET_TOKEN"}},"expired-token":{"description":"expired-token","value":{"message":"비밀번호 재설정 토큰이 만료되었습니다.","code":"EXPIRED_PASSWORD_RESET_TOKEN"}}}}}},"204":{"description":"비밀번호 재설정 성공"}}}},"/auth/logout":{"post":{"tags":["로그인·세션"],"summary":"로그아웃","description":"HttpOnly Cookie의 Refresh Token을 검증한 뒤 현재 저장된 Refresh Token을 제거하고 Cookie를 만료 처리합니다.","operationId":"logout","responses":{"404":{"description":"토큰에 해당하는 사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"204":{"description":"로그아웃 성공","headers":{"Set-Cookie":{"description":"만료된 HttpOnly Refresh Token Cookie","style":"simple","schema":{"type":"string"}}}},"401":{"description":"유효하지 않은 리프레시 토큰","content":{"*/*":{"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}}},"/auth/login":{"post":{"tags":["로그인·세션"],"summary":"로그인","description":"아이디와 비밀번호를 검증한 뒤 사용자 정보와 Access Token을 반환하고 Refresh Token은 HttpOnly Cookie로 발급합니다.","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"로그인 성공","headers":{"Set-Cookie":{"description":"HttpOnly Refresh Token Cookie","style":"simple","schema":{"type":"string"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/LoginResponse"},"example":{"id":1,"username":"pingdom_user","email":"pingdom@example.com","birthYear":1998,"profileImageUrl":"https://cdn.pingdom.com/profiles/user1.png","language":"ko","country":"KR","message":"로그인에 성공했습니다.","accessToken":"eyJhbGciOiJIUzI1NiJ9.access.token","role":"USER"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"password":"비밀번호는 8자 이상이어야 합니다."}}}}},"401":{"description":"아이디 또는 비밀번호 불일치","content":{"*/*":{"example":{"message":"아이디 또는 비밀번호가 올바르지 않습니다.","code":"INVALID_CREDENTIALS"}}}}}}},"/auth/email/verify":{"post":{"tags":["회원가입·이메일 인증"],"summary":"이메일 인증","description":"이메일과 인증 코드를 검증해 사용자의 이메일 인증 상태를 완료 처리합니다.","operationId":"verifyEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailVerifyRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패 또는 유효하지 않은 인증 코드","content":{"*/*":{"examples":{"validation-failure":{"description":"validation-failure","value":{"message":"입력값을 확인해주세요.","errors":{"email":"이메일 형식이 올바르지 않습니다."}}},"invalid-code":{"description":"invalid-code","value":{"message":"이메일 인증 코드가 올바르지 않습니다.","code":"INVALID_EMAIL_VERIFICATION_CODE"}},"expired-code":{"description":"expired-code","value":{"message":"이메일 인증 코드가 만료되었습니다.","code":"EXPIRED_EMAIL_VERIFICATION_CODE"}}}}}},"200":{"description":"이메일 인증 성공"},"404":{"description":"이메일에 해당하는 사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}}}}},"/auth/email/resend":{"post":{"tags":["회원가입·이메일 인증"],"summary":"인증 메일 재발송","description":"미인증 사용자의 이메일 인증 코드를 새로 발급하고 인증 메일을 다시 발송합니다.","operationId":"resendVerificationEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailResendRequest"}}},"required":true},"responses":{"409":{"description":"이미 인증된 이메일","content":{"*/*":{"example":{"message":"이미 이메일 인증이 완료된 사용자입니다.","code":"EMAIL_ALREADY_VERIFIED"}}}},"200":{"description":"인증 메일 재발송 성공"},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"email":"이메일 형식이 올바르지 않습니다."}}}}},"404":{"description":"이메일에 해당하는 사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}}}}},"/auth/admin/login":{"post":{"tags":["로그인·세션"],"summary":"관리자 로그인","description":"관리자 계정만 관리자 페이지 전용 Access Token을 발급받고 Refresh Token은 HttpOnly Cookie로 발급합니다.","operationId":"adminLogin","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"관리자 로그인 성공","headers":{"Set-Cookie":{"description":"HttpOnly Refresh Token Cookie","style":"simple","schema":{"type":"string"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/LoginResponse"},"example":{"id":1,"username":"admin_user","email":"admin@example.com","birthYear":1990,"profileImageUrl":null,"language":"ko","country":"KR","message":"로그인에 성공했습니다.","accessToken":"eyJhbGciOiJIUzI1NiJ9.access.token","role":"ADMIN"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"password":"비밀번호는 8자 이상이어야 합니다."}}}}},"401":{"description":"아이디 또는 비밀번호 불일치","content":{"*/*":{"example":{"message":"아이디 또는 비밀번호가 올바르지 않습니다.","code":"INVALID_CREDENTIALS"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"example":{"message":"관리자 권한이 필요합니다.","code":"ADMIN_ACCESS_REQUIRED"}}}}}}},"/analysis/reports/location":{"post":{"tags":["상권 분석"],"summary":"입지 분석 PDF 보고서 생성","description":"입력 조건을 AI/MCP 분석 인터페이스로 전달하고 HTML 분석 결과를 PDF로 반환합니다. 사용자·IP별 호출 한도는 Redis로 모든 인스턴스에 공유되며, 생성 동시 실행·대기열 상한은 인스턴스별로 적용됩니다. 429 응답 시 즉시 반복하지 말고 backoff 후 재시도하세요. Retry-After 헤더는 제공하지 않습니다.","operationId":"generate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationAnalysisRequest"}}},"required":true},"responses":{"429":{"description":"사용자·IP 호출 한도 또는 인스턴스별 생성 동시 실행·대기열 상한 초과","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"AI 분석 응답 처리 실패","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"지역 누락 또는 입력값 검증 실패","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"PDF 보고서 생성 성공","content":{"application/pdf":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/{reportId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 심사","operationId":"review","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/corrections/{correctionId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 정정 심사","operationId":"reviewCorrection","parameters":[{"name":"correctionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionReviewRequest"}}},"required":true},"responses":{"200":{"description":"제보 정정 심사 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionResponse"}}}},"409":{"description":"이미 심사된 정정 또는 활성 제보 충돌","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"심사 요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"제보 정정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관리자 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products":{"get":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 목록 조회","operationId":"list_21","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 생성","operationId":"create_9","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}/deactivate":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 비활성화","operationId":"deactivate_2","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}/activate":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 활성화","operationId":"activate_1","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/roles":{"get":{"tags":["회원·권한"],"summary":"관리자 역할 이력 조회","operationId":"list_22","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"대상 관리자 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["회원·권한"],"summary":"관리자 역할 부여","operationId":"assign","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentRequest"}}},"required":true},"responses":{"404":{"description":"대상 관리자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"역할 할당 요청 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"부여 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}},"409":{"description":"이미 활성 역할이 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}/interventions/evaluate":{"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 수동 평가","description":"관리자가 신고자의 현재 Trust Score 정책에 활성 개입 규칙을 수동 평가합니다.","operationId":"evaluateReporter","parameters":[{"name":"reporterUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionEvaluationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules":{"get":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 목록 조회","description":"관리자가 Trust Score 개입 규칙 목록을 우선순위 순서로 조회합니다.","operationId":"listRules","parameters":[{"name":"enabledOnly","in":"query","description":"활성화된 규칙만 조회할지 여부","required":false,"schema":{"type":"boolean","default":false},"example":false}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 생성","description":"관리자가 Trust Score 개입 규칙을 생성합니다.","operationId":"createRule","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleRequest"}}},"required":true},"responses":{"200":{"description":"Trust Score 개입 규칙 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"},"example":{"id":1,"ruleName":"low trust temporary restriction","triggerType":"FALSE_REPORT_COUNT","actionType":"TEMPORARY_RESTRICT","enabled":true,"minTrustScore":0,"maxTrustScore":60,"minSubmittedCount":3,"minFalseReportCount":3,"durationDays":7,"priority":10,"reason":"허위 신고 누적 사용자 제한"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/batch/recalculate":{"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 일괄 재계산","operationId":"recalculateTrustScores","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreBatchResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/suspend":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 정지","operationId":"suspend","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/revoke":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 회수","operationId":"revoke","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/suspend":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 정지","operationId":"suspendEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/revoke":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 회수","operationId":"revokeEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/grant":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 부여","operationId":"grantEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityGrantRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/approve":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 승인","operationId":"approve","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"Scout 프로필 승인 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"409":{"description":"현재 프로필 상태에서 승인 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"403":{"description":"Scout 심사 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-field-reports/{reportId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 현장 제보 심사","operationId":"review_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"현장 제보 심사 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"409":{"description":"이미 심사된 현장 제보","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"400":{"description":"심사 요청 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"404":{"description":"현장 제보를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/{id}/decline":{"post":{"tags":["신고·이의신청"],"summary":"신고 거절 처리","description":"관리자가 신고를 거절 처리합니다.","operationId":"declineReport","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"신고 거절 성공","content":{"*/*":{"example":{"reportId":1,"status":"DECLINED","reportedUserId":5,"banned":false,"processedAt":"2026-05-07T21:00:00"}}}},"404":{"description":"신고 내역 없음","content":{"*/*":{"example":{"message":"신고 내역을 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"example":{"message":"이미 처리된 신고입니다.","code":"REPORT_ALREADY_PROCESSED"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/{id}/accept":{"post":{"tags":["신고·이의신청"],"summary":"신고 수락 처리","description":"관리자가 신고를 수락하고 대상 사용자를 제재하며 신고 대상 게시글을 숨김 처리합니다.","operationId":"acceptReport","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"404":{"description":"신고 내역 없음","content":{"*/*":{"example":{"message":"신고 내역을 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}},"200":{"description":"신고 수락 성공","content":{"*/*":{"example":{"reportId":1,"status":"ACCEPTED","reportedUserId":5,"banned":true,"processedAt":"2026-05-07T21:00:00"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"example":{"message":"이미 처리된 신고입니다.","code":"REPORT_ALREADY_PROCESSED"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals/{id}/reject":{"post":{"tags":["신고·이의신청"],"summary":"신고 이의제기 반려","operationId":"reject_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals/{id}/approve":{"post":{"tags":["신고·이의신청"],"summary":"신고 이의제기 승인","operationId":"approve_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{postId}/reports/decline":{"post":{"tags":["신고·이의신청"],"summary":"게시글 단위 신고 일괄 거절","description":"관리자가 게시글에 연결된 PENDING 신고를 모두 거절합니다. 게시글 공개 상태와 대상 사용자 제재 상태는 변경하지 않습니다.","operationId":"declinePostReports","parameters":[{"name":"postId","in":"path","description":"신고를 일괄 거절할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"게시글 신고 일괄 거절 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"},"example":{"postId":10,"status":"DECLINED","processedReportCount":3,"visibilityStatus":"ACTIVE","hiddenAt":null,"hiddenReason":null,"processedAt":"2026-05-21T10:15:30"}}}},"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"409":{"description":"처리할 PENDING 신고 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{postId}/reports/accept":{"post":{"tags":["신고·이의신청"],"summary":"게시글 단위 신고 일괄 수락","description":"관리자가 게시글에 연결된 PENDING 신고를 모두 수락하고 게시글 숨김 및 대상 사용자 제재를 처리합니다.","operationId":"acceptPostReports","parameters":[{"name":"postId","in":"path","description":"신고를 일괄 수락할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"200":{"description":"게시글 신고 일괄 수락 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"},"example":{"postId":10,"status":"ACCEPTED","processedReportCount":3,"visibilityStatus":"AUTO_HIDDEN","hiddenAt":"2026-05-21T10:15:30","hiddenReason":"REPORT_BULK_ACCEPTED","processedAt":"2026-05-21T10:15:30"}}}},"409":{"description":"처리할 PENDING 신고 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report/refresh":{"post":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 리포트 생성 시작","description":"DB와 S3를 백그라운드에서 비교해 Redis에 리포트 결과를 저장합니다. 생성된 리포트는 GET report API로 페이지 조회합니다.","operationId":"refreshS3OrphanReport","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReportStatus"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 생성","description":"관리자가 상점 운영 상태 공지를 생성합니다.","operationId":"createNotice_1","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices/{noticeId}/cancel":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 취소","description":"관리자가 예약 또는 활성 운영 상태 공지를 취소합니다.","operationId":"cancelNotice_1","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCancelRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests":{"get":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 목록 조회","operationId":"list_27","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 생성","operationId":"create_10","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/reminders":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 리마인드 발행","operationId":"remind","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/complete":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 완료","operationId":"complete","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/cancel":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 취소","operationId":"cancel_3","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/information-evidence":{"get":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 목록 조회","description":"관리자가 장소 정보 출처와 증빙 메타데이터를 확인합니다.","operationId":"getPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 조회할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceResponse"}}}},"200":{"description":"장소 정보 증빙 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 등록","description":"관리자가 장소 정보 출처와 증빙 메타데이터를 등록합니다.","operationId":"createPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 등록할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceCreateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"200":{"description":"장소 정보 증빙 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-snapshots/resync":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 추천 snapshot 재동기화","description":"관리자가 모든 장소 추천 snapshot을 현재 데이터 기준으로 다시 동기화합니다.","operationId":"resyncRecommendationSnapshots","responses":{"200":{"description":"추천 snapshot 재동기화 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationSnapshotResyncResponse"},"example":{"placeCount":12,"synchronizedSnapshotCount":12,"deletedSnapshotCount":1,"synchronizedSimilaritySnapshotCount":24,"deletedSimilaritySnapshotCount":2,"synchronizedVersionSnapshotCount":3,"deletedVersionSnapshotCount":0,"message":"장소 추천 snapshot 재동기화를 완료했습니다."}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 병합","description":"관리자가 중복 장소의 참조 데이터를 대상 장소로 옮기고 원본 장소를 병합합니다.","operationId":"mergePlaces","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge-histories/{historyId}/restore":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 장소 병합 복구","description":"관리자가 저장된 장소 병합 이력을 기준으로 복구합니다.","operationId":"restoreMerge","parameters":[{"name":"historyId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceMergeRestoreResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/reject":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 거절","operationId":"rejectDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateDecisionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/merge":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 확정 중복 장소 병합","operationId":"mergeDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateMergeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/confirm":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 확정","operationId":"confirmDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateDecisionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests/{deletionRequestId}/review":{"post":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 심사","operationId":"review_2","parameters":[{"name":"deletionRequestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceReviewDeletionRequestReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-operating-notices/expire":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 만료 처리","description":"만료 시간이 지난 운영 상태 공지를 일괄 만료 처리합니다.","operationId":"expireDueNotices","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}/review":{"post":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 검토","operationId":"reviewReport","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}/disputes/{disputeId}/review":{"post":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 반박 검토","operationId":"reviewDispute","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"disputeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events":{"get":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 목록 조회","operationId":"listEvents_1","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":20}},{"name":"keyword","in":"query","required":false,"schema":{"type":"string"}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"eventType","in":"query","required":false,"schema":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]}},{"name":"publicationStatus","in":"query","required":false,"schema":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]}},{"name":"scheduleStatus","in":"query","required":false,"schema":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 등록","description":"장소와 연결된 기간형 이벤트를 초안으로 등록합니다.","operationId":"createEvent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventRequest"}}},"required":true},"responses":{"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"이벤트 초안 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}/publish":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 공개","description":"종료되지 않은 초안 이벤트를 앱 탐색에 공개합니다.","operationId":"publishEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventActionRequest"}}},"required":true},"responses":{"409":{"description":"공개할 수 없는 상태 또는 기간","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 공개 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}/cancel":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 취소","description":"초안 또는 공개된 기간형 이벤트를 취소하고 앱 탐색에서 제외합니다.","operationId":"cancelEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventActionRequest"}}},"required":true},"responses":{"409":{"description":"이미 취소된 이벤트","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 취소 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/outbox-events/{eventId}/retry":{"post":{"tags":["Outbox·스토리지 운영"],"summary":"관리자 Outbox 이벤트 재처리","description":"장애 원인과 중복 처리 안전성을 확인한 뒤 최종 실패 이벤트를 재처리 대상으로 전환합니다.","operationId":"retry","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventRetryRequest"}}},"required":true},"responses":{"400":{"description":"재처리 사유 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Outbox 복구 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"재처리 불가 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"재처리 예약 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventItem"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/reject":{"post":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 반려","operationId":"reject_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/approve":{"post":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 승인","description":"NEW_PLACE 승인 시 장소 생성, Merchant Owner 연결과 신청의 COMPLETED 전이가 하나의 트랜잭션으로 완료됩니다. 신청자의 추가 완료 요청은 필요하지 않습니다.","operationId":"approve_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/revoke":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 권한 회수","operationId":"revoke_1","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/reject":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 반려","operationId":"reject_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/approve":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 승인","description":"승인 사유만 처리합니다. 장소 연결은 변경하지 않으며, 승인 후 연결이 필요하면 PUT /admin/merchant-owners/{userId}/places로 전체 장소 목록을 별도 요청해야 합니다. 승인과 장소 연결은 별도 트랜잭션입니다.","operationId":"approve_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}/decline":{"post":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 반려","description":"반려는 신고 상태만 변경하고 대상 노출 상태를 바꾸지 않습니다.","operationId":"decline","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"신고 반려 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportActionResponse"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"커뮤니티 신고를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}/accept":{"post":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 수락","description":"수락한 신고 대상 글 또는 댓글을 숨깁니다.","operationId":"accept_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"커뮤니티 신고 또는 대상 콘텐츠를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"신고 수락 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/ban/{userId}":{"post":{"tags":["회원·권한"],"summary":"사용자 밴 처리","description":"관리자가 특정 사용자를 밴 처리합니다. expiresAt 또는 durationDays를 전달하면 기간 밴으로, 둘 다 비우면 영구 밴으로 처리합니다.","operationId":"banUser","parameters":[{"name":"userId","in":"path","description":"밴 처리할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BanRequest"}}}},"responses":{"200":{"description":"밴 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BanResponse"}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/ban/{userId}/release":{"post":{"tags":["회원·권한"],"summary":"사용자 밴 해제","description":"관리자가 영구 밴 또는 기간 밴 상태의 사용자를 명시적으로 해제합니다.","operationId":"unbanUser","parameters":[{"name":"userId","in":"path","description":"밴 해제할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnbanRequest"}}}},"responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"밴 해제 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UnbanResponse"}}}},"409":{"description":"제재 중인 사용자가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"제재 중인 사용자가 아닙니다.","code":"USER_NOT_BANNED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/travel-schedules/{scheduleId}":{"patch":{"tags":["여행"],"summary":"여행 일정 기간 변경","description":"취소되지 않은 본인 여행 일정의 날짜 범위를 변경합니다.","operationId":"updateTravelSchedule","parameters":[{"name":"scheduleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TravelScheduleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelScheduleResponse"}}}},"404":{"description":"일정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"기간 역전 또는 과거 날짜","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidPeriod":{"description":"invalidPeriod","value":{"message":"여행 종료일은 시작일보다 빠를 수 없습니다.","code":"INVALID_TRAVEL_SCHEDULE_PERIOD"}},"pastStartDate":{"description":"pastStartDate","value":{"message":"여행 시작일은 오늘보다 이전일 수 없습니다.","code":"TRAVEL_SCHEDULE_START_DATE_IN_PAST"}}}}}},"409":{"description":"기간 겹침, 취소된 일정 또는 동시 수정 충돌","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"periodOverlap":{"description":"periodOverlap","value":{"message":"기존 여행 일정과 기간이 겹칩니다.","code":"TRAVEL_SCHEDULE_PERIOD_OVERLAP"}},"notEditable":{"description":"notEditable","value":{"message":"취소된 여행 일정은 수정할 수 없습니다.","code":"TRAVEL_SCHEDULE_NOT_EDITABLE"}},"concurrentModification":{"description":"concurrentModification","value":{"message":"여행 일정이 다른 요청으로 변경되었습니다. 다시 조회해 주세요.","code":"TRAVEL_SCHEDULE_CONCURRENT_MODIFICATION"}}}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/notifications/settings":{"get":{"tags":["알림"],"summary":"알림 설정 조회","description":"현재 사용자의 알림 타입별 수신 여부와 quiet hours 설정을 조회합니다.","operationId":"getSetting","responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotificationSettingResponse"},"example":{"newHotplaceEnabled":true,"newLikeEnabled":true,"quietHoursEnabled":false,"quietHoursStart":null,"quietHoursEnd":null,"timezone":"Asia/Seoul"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["알림"],"summary":"알림 설정 수정","description":"현재 사용자의 알림 타입별 수신 여부와 quiet hours 설정을 부분 수정합니다.","operationId":"updateSetting","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationSettingUpdateRequest"}}},"required":true},"responses":{"400":{"description":"timezone 또는 quiet hours 설정 오류","content":{"*/*":{"example":{"message":"quiet hours 설정을 확인해주세요.","code":"INVALID_QUIET_HOURS"}}}},"200":{"description":"수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotificationSettingResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-status":{"patch":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 장소 운영 상태 변경","operationId":"updateOperatingStatus","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingStatusUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-notices/{noticeId}":{"patch":{"tags":["메뉴·운영 공지"],"summary":"점주 상점 운영 상태 공지 수정","description":"OWNER만 본인 장소의 SCHEDULED 또는 ACTIVE 공지의 심각도와 메시지를 수정할 수 있습니다. 생성·수정·취소 결과는 공개 운영 공지 조회와 동일한 공지 리소스를 변경합니다. 잘못된 상태는 PLACE_OPERATING_NOTICE_INVALID_REQUEST, 권한 부족은 PLACE_OPERATING_NOTICE_FORBIDDEN, 대상 없음은 PLACE_OPERATING_NOTICE_NOT_FOUND로 응답합니다.","operationId":"updateNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeUpdateRequest"}}},"required":true},"responses":{"403":{"description":"장소 운영 공지 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"운영 상태 공지 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"400":{"description":"입력값 또는 수정 가능하지 않은 공지 상태","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소 또는 공지를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus/{menuId}":{"get":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 상세 조회","operationId":"get_8","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 수정","operationId":"update_4","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMenuUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus/{menuId}/status":{"patch":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 상태 변경","operationId":"changeStatus","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMenuStatusRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus/{menuId}/order":{"patch":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 표시 순서 변경","operationId":"reorder_1","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMenuOrderRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/members/{memberId}":{"delete":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 권한 회수","operationId":"revoke_2","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"memberId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"No Content"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 권한 변경","description":"OWNER 또는 MANAGER가 활성 팀원의 역할을 변경합니다. OWNER 역할은 팀원에게 부여할 수 없으며, 비활성 팀원은 변경할 수 없습니다. 잘못된 역할은 MERCHANT_TEAM_INVITATION_INVALID_ROLE, 비활성 팀원은 MERCHANT_TEAM_MEMBER_NOT_ACTIVE, 대상 없음은 MERCHANT_TEAM_MEMBER_NOT_FOUND로 응답합니다.","operationId":"updateRole","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"memberId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantTeamRoleUpdateRequest"}}},"required":true},"responses":{"409":{"description":"비활성 팀원의 역할은 변경할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_MEMBER_NOT_ACTIVE":{"description":"MERCHANT_TEAM_MEMBER_NOT_ACTIVE","value":{"message":"활성 상태의 Merchant 팀원만 변경할 수 있습니다.","code":"MERCHANT_TEAM_MEMBER_NOT_ACTIVE"}}}}}},"403":{"description":"OWNER 또는 MANAGER 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소의 팀원을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"입력 역할이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"200":{"description":"팀원 역할 변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantTeamMemberResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/media/{mediaId}":{"delete":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 탐색 미디어 삭제","operationId":"deleteMedia","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"mediaId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 탐색 미디어 순서 변경","description":"displayOrder는 0부터 시작하는 이동 대상 위치입니다. 서버가 같은 장소의 탐색 미디어를 재배치해 중복 없이 0부터 연속된 순서를 보장합니다.","operationId":"updateMediaOrder","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"mediaId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaOrderUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/{campaignId}":{"patch":{"tags":["캠페인·혜택"],"summary":"팝업 캠페인 초안 수정","operationId":"updateCampaign","parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PopupCampaignCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/brands/{brandId}":{"patch":{"tags":["캠페인·혜택"],"summary":"내 브랜드 수정","operationId":"updateBrand","parameters":[{"name":"brandId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BrandResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/analysis/reports/{reportId}":{"get":{"tags":["상권 분석"],"summary":"보관된 입지 분석 보고서 상세 조회","operationId":"get_14","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LocationAnalysisReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["상권 분석"],"summary":"보관된 입지 분석 보고서 삭제","operationId":"delete_2","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["상권 분석"],"summary":"보관된 입지 분석 보고서 정보 수정","operationId":"update_5","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationAnalysisReportUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LocationAnalysisReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}/enable":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 활성화","description":"관리자가 Trust Score 개입 규칙을 활성화합니다.","operationId":"enableRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleToggleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}/disable":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 비활성화","description":"관리자가 Trust Score 개입 규칙을 비활성화합니다.","operationId":"disableRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleToggleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/anomalies/{anomalyId}/resolve":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 이상치 해결 처리","description":"관리자가 Trust Score 이상치를 해결 처리하고 감사 로그를 남깁니다.","operationId":"resolveAnomaly","parameters":[{"name":"anomalyId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyResolveRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices/{noticeId}":{"patch":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 수정","description":"관리자가 상점 운영 상태 공지 내용을 수정합니다.","operationId":"updateNotice_1","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/tourist-info":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 관광 정보 수정","description":"관리자가 장소의 영문명, 관광객용 요약, 관광 카테고리를 수정합니다.","operationId":"updatePlaceTouristInfo","parameters":[{"name":"id","in":"path","description":"관광 정보를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceTouristInfoUpdateRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"reason":"수정 사유는 필수입니다."}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"장소 관광 정보 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceTouristInfoUpdateResponse"},"example":{"placeId":1,"englishName":"Jinju Castle","touristSummary":"A historic fortress overlooking the Nam River.","touristCategories":["K_POP","CAFE","POP_UP"],"message":"장소 관광 정보를 수정했습니다."}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/operating-status":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 운영 상태 확인","description":"관리자가 확인한 장소 운영 상태를 기록하고 최신 확인 시각을 서버 시간으로 갱신합니다. 비운영 장소는 앱 장소 조회와 추천에서 숨겨집니다.","operationId":"updatePlaceOperatingStatus","parameters":[{"name":"id","in":"path","description":"운영 상태를 확인할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"200":{"description":"장소 운영 상태 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/operating-schedule":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 영업시간 일정 수정","description":"관리자가 요일별 정규 영업시간과 특정 날짜 휴무·대체 영업시간을 전체 교체합니다. 수동 운영 상태는 변경하지 않습니다.","operationId":"updatePlaceOperatingSchedule","parameters":[{"name":"id","in":"path","description":"영업시간 일정을 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingScheduleUpdateRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"장소 영업시간 일정 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingScheduleUpdateResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/kakao-place-id":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 Kakao place id 수정","description":"관리자가 장소에 연결된 Kakao place id를 재연결하거나 해제합니다.","operationId":"updatePlaceKakaoPlaceId","parameters":[{"name":"id","in":"path","description":"Kakao place id를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceKakaoPlaceIdUpdateRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"kakaoPlaceId":"카카오 장소 ID는 50자 이하여야 합니다."}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"Kakao place id 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceKakaoPlaceIdUpdateResponse"},"example":{"placeId":1,"kakaoPlaceId":"27414316","message":"장소 Kakao place id를 수정했습니다."}}}},"409":{"description":"이미 다른 장소에 연결된 Kakao place id","content":{"*/*":{"example":{"message":"이미 다른 장소에 연결된 Kakao place id입니다.","code":"PLACE_KAKAO_PLACE_ID_CONFLICT"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/information-evidence/{evidenceId}/review":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 검토","description":"관리자가 장소 정보 증빙을 승인 또는 반려하고 장소 정보 검증 요약 상태를 갱신합니다.","operationId":"reviewPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 검토할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"evidenceId","in":"path","description":"증빙 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceReviewRequest"}}},"required":true},"responses":{"404":{"description":"장소 또는 증빙을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"200":{"description":"장소 정보 증빙 검토 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/geocoding":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 주소·좌표 보정","description":"관리자가 대표 주소, 정규화 주소와 좌표를 함께 보정하며 출처는 ADMIN으로 기록합니다.","operationId":"updatePlaceGeocoding","parameters":[{"name":"id","in":"path","description":"주소와 좌표를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceGeocodingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceGeocodingUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/discovery-status":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 탐색 노출 상태 수정","description":"관리자가 장소를 공개 탐색, 자동완성, 북마크 목록, 추천 후보에 노출할지 제어합니다.","operationId":"updatePlaceDiscoveryStatus","parameters":[{"name":"id","in":"path","description":"탐색 노출 상태를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"200":{"description":"장소 탐색 노출 상태 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/coordinates":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 좌표 수정","description":"관리자가 잘못 등록된 장소의 위도와 경도를 수정합니다.","operationId":"updatePlaceCoordinates","parameters":[{"name":"id","in":"path","description":"좌표를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceCoordinateUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"latitude":"위도는 90.0 이하여야 합니다."}}}}},"200":{"description":"장소 좌표 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceCoordinateUpdateResponse"},"example":{"placeId":1,"latitude":35.1796,"longitude":128.1076,"message":"장소 좌표를 수정했습니다."}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/basic-information":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 기본 정보 수정","description":"관리자가 장소명과 표준 카테고리를 수정하고 변경 사유를 감사 로그에 남깁니다.","operationId":"updatePlaceBasicInformation","parameters":[{"name":"id","in":"path","description":"기본 정보를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"200":{"description":"장소 기본 정보 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-traffic":{"patch":{"tags":["중복·추천 관리"],"summary":"관리자 추천 버전 트래픽 비율 수정","description":"관리자가 추천 버전별 traffic percentage를 수정하고 즉시 반영합니다.","operationId":"updateRecommendationTraffic","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}":{"get":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 상세 조회","operationId":"getEvent_1","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventListItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 수정","description":"초안 상태의 기간형 이벤트 정보와 연결 장소를 수정합니다.","operationId":"updateEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventRequest"}}},"required":true},"responses":{"404":{"description":"이벤트 또는 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"초안이 아닌 이벤트 수정 시도","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/{notificationId}/read":{"patch":{"tags":["알림·발송 이력"],"summary":"관리자 알림 읽음 처리","description":"관리자가 운영 확인이 필요한 인앱 알림을 읽음 상태로 변경합니다.","operationId":"markAsRead","parameters":[{"name":"notificationId","in":"path","description":"알림 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"알림 읽음 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationReadResponse"},"example":{"notificationId":1,"read":true,"message":"알림을 읽음 처리했습니다."}}}},"404":{"description":"알림을 찾을 수 없음","content":{"*/*":{"example":{"message":"알림을 찾을 수 없습니다.","code":"NOTIFICATION_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/read":{"patch":{"tags":["알림·발송 이력"],"summary":"관리자 전체 알림 읽음 처리","description":"관리자가 모든 미확인 인앱 알림을 읽음 상태로 변경합니다.","operationId":"markAllAsRead","responses":{"200":{"description":"전체 알림 읽음 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationReadAllResponse"},"example":{"updatedCount":3,"message":"전체 알림을 읽음 처리했습니다."}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/visitor-verification-reports/{reportId}":{"get":{"tags":["방문 인증"],"summary":"내 방문자 검증 제보 상세 조회","operationId":"getMine","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"200":{"description":"내 제보 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportResponse"}}}},"404":{"description":"제보를 찾을 수 없음 (REPORT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"REPORT_NOT_FOUND":{"description":"REPORT_NOT_FOUND","value":{"message":"방문자 검증 제보를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}}},"403":{"description":"활성 일반 사용자 계정이 아니거나 본인 소유 제보가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}},"REPORT_FORBIDDEN":{"description":"REPORT_FORBIDDEN","value":{"message":"이 제보를 조회할 권한이 없습니다.","code":"REPORT_FORBIDDEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/visit-verification-sessions/{sessionId}":{"get":{"tags":["방문 인증"],"summary":"내 체류 기반 방문 인증 상태 조회","operationId":"get","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"현재 인증 세션 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitVerificationSessionResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"본인 소유 인증 세션을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me":{"get":{"tags":["내 정보·계정 연동"],"summary":"내 정보 조회","description":"현재 인증된 사용자의 마이페이지 정보를 조회합니다.","operationId":"getMyPageInfo","responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyPageResponse"},"example":{"id":1,"username":"pingdom_user","email":"pingdom@example.com","birthYear":1998,"profileImageUrl":"https://cdn.pingdom.com/profiles/user1.png","language":"ko","country":"KR"}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["내 정보·계정 연동"],"summary":"회원탈퇴","description":"현재 인증된 사용자의 개인정보를 익명화하고 탈퇴 상태로 전환합니다.","operationId":"withdraw","responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"204":{"description":"회원탈퇴 성공"},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/reviews":{"get":{"tags":["내 리뷰"],"summary":"내가 작성한 장소 리뷰 목록 조회","description":"삭제 완료된 리뷰는 목록과 총 개수에서 제외합니다.","operationId":"listMine_1","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"400":{"description":"페이지 요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"200":{"description":"내 리뷰 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyPlaceReviewPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/naver-place-search":{"get":{"tags":["장소 등록 신청"],"summary":"신규 장소 등록용 네이버 업체명 검색","description":"네이버 Local Search 결과를 최대 5건의 장소명·도로명 주소·지번 주소·WGS84 좌표로 반환합니다.","operationId":"searchNaverPlace","parameters":[{"name":"query","in":"query","description":"업체명. 입력값은 1~100자이며, 앞뒤 공백을 trim한 검색어로 조회합니다. 공백만 있는 값은 허용하지 않습니다.","required":true,"schema":{"maxLength":100,"minLength":1,"type":"string"}}],"responses":{"503":{"description":"NAVER_PLACE_SEARCH_UNAVAILABLE: 비활성 또는 인증값 미설정","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"INVALID_REQUEST_PARAMETER: query 누락. PLACE_SEARCH_CONDITION_INVALID: trim 후 빈 검색어. 입력 검증 오류는 기존 공통 오류 계약을 유지합니다.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"200":{"description":"업체명 검색 후보","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NaverPlaceSearchResponse"}}}},"502":{"description":"NAVER_PLACE_SEARCH_FAILED: 외부 호출 실패·빈 응답·좌표 변환 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/naver-address-search":{"get":{"tags":["장소 등록 신청"],"summary":"신규 장소 등록용 네이버 주소 검색","description":"도로명·지번 주소 후보를 최대 10건 반환합니다. 좌표는 WGS84 기준이며, 우편번호가 없는 후보는 null로 반환합니다.","operationId":"searchNaverAddress","parameters":[{"name":"query","in":"query","description":"도로명 또는 지번 주소. 입력값은 1~100자이며, 앞뒤 공백을 trim한 검색어로 조회합니다. 공백만 있는 값은 허용하지 않습니다.","required":true,"schema":{"maxLength":100,"minLength":1,"type":"string"}}],"responses":{"400":{"description":"INVALID_REQUEST_PARAMETER: query 누락. PLACE_SEARCH_CONDITION_INVALID: trim 후 빈 검색어. 입력 검증 오류는 기존 공통 오류 계약을 유지합니다.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"502":{"description":"NAVER_ADDRESS_SEARCH_FAILED: 외부 호출 실패·비정상 응답·좌표 변환 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"주소 검색 후보","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NaverAddressSearchResponse"}}}},"504":{"description":"NAVER_ADDRESS_SEARCH_TIMEOUT: 외부 Geocoding 응답 시간 초과","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"NAVER_ADDRESS_SEARCH_RATE_LIMITED: 외부 Geocoding 호출 한도 초과","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"NAVER_ADDRESS_SEARCH_UNAVAILABLE: 비활성·미설정·외부 서버 장애·연결 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/export":{"get":{"tags":["내 정보·계정 연동"],"summary":"내 데이터 내보내기","description":"현재 인증된 사용자의 계정 정보, 전체 북마크, 최근 좋아요한 지도 이미지 ID 최대 50개, 여행 일정, Claim 이력과 만료되지 않은 현재 행동 의도를 JSON으로 조회합니다.","operationId":"exportMyData","responses":{"200":{"description":"내보내기 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserDataExportResponse"},"example":{"user":{"id":1,"username":"pingdom_user","profileImageUrl":"https://cdn.pingdom.com/profiles/user1.png"},"bookmarks":[{"id":10,"placeId":123}],"likedMapImageIds":[981,812,700],"travelSchedules":[{"id":31,"startDate":"2026-08-01","endDate":"2026-08-03","state":"SCHEDULED"}],"currentActivityIntent":{"intent":"CAFE","expiresAt":"2026-08-01T14:00:00"},"merchantPlaceClaims":[{"id":40,"placeId":123,"status":"REJECTED","claimReason":"매장 운영자입니다.","reviewReason":"사업자 주소 불일치","reviewedAt":"2026-07-16T10:00:00","createdAt":"2026-07-15T14:00:00"}]}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/scout-field-reports/{reportId}":{"get":{"tags":["스카우트"],"summary":"내 Scout 현장 제보 상세 조회","operationId":"getMine_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/reservations/{reservationId}":{"get":{"tags":["예약"],"summary":"내 예약 상세 조회","description":"활성 일반 사용자는 본인 예약만 조회할 수 있습니다.\n아직 확정되지 않은 예약의 confirmedAt과 취소되지 않은 예약의 canceledAt은 null입니다.\n","operationId":"get_4","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"활성 일반 사용자 계정이 아니거나 다른 사용자의 예약","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"일반 사용자 계정만 예약할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}},"RESERVATION_FORBIDDEN":{"description":"RESERVATION_FORBIDDEN","value":{"message":"이 예약을 처리할 권한이 없습니다.","code":"RESERVATION_FORBIDDEN"}}}}}},"200":{"description":"내 예약 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"404":{"description":"예약을 찾을 수 없음 (RESERVATION_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"RESERVATION_NOT_FOUND":{"description":"RESERVATION_NOT_FOUND","value":{"message":"예약을 찾을 수 없습니다.","code":"RESERVATION_NOT_FOUND"}}}}}},"401":{"description":"유효하지 않거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/popup-campaigns":{"get":{"tags":["행사·팝업"],"summary":"진행 중인 공개 팝업 캠페인 목록 조회","description":"PUBLISHED 상태이며 시작 시각 이상, 종료 시각 미만인 캠페인만 조회합니다. 빈 목록은 items=[], totalCount=0, totalPages=0, hasNext=false로 반환합니다.","operationId":"list_3","parameters":[{"name":"placeId","in":"query","description":"장소 ID 필터","required":false,"schema":{"type":"integer","format":"int64"},"example":101},{"name":"page","in":"query","description":"페이지 번호. 1 미만은 1, 10000 초과는 10000으로 보정됩니다.","required":false,"schema":{"maximum":10000,"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 1 미만은 1, 100 초과는 100으로 보정됩니다.","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"공개 팝업 캠페인 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicPopupCampaignPageResponse"}}}},"400":{"description":"페이지 또는 장소 필터 형식이 올바르지 않음 (INVALID_INPUT)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_INPUT":{"description":"INVALID_INPUT","value":{"message":"브랜드 또는 캠페인 입력값이 올바르지 않습니다.","code":"INVALID_INPUT"}}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/popup-campaigns/{campaignId}":{"get":{"tags":["행사·팝업"],"summary":"진행 중인 공개 팝업 캠페인 상세 조회","description":"종료·비공개·없는 캠페인은 모두 404 CAMPAIGN_NOT_FOUND로 처리합니다.","operationId":"get_5","parameters":[{"name":"campaignId","in":"path","description":"팝업 캠페인 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"캠페인을 찾을 수 없거나 공개 대상이 아님 (CAMPAIGN_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CAMPAIGN_NOT_FOUND":{"description":"CAMPAIGN_NOT_FOUND","value":{"message":"팝업 캠페인을 찾을 수 없습니다.","code":"CAMPAIGN_NOT_FOUND"}}}}}},"200":{"description":"공개 팝업 캠페인 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicPopupCampaignResponse"}}}},"400":{"description":"캠페인 ID 형식이 올바르지 않음 (INVALID_INPUT)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_INPUT":{"description":"INVALID_INPUT","value":{"message":"브랜드 또는 캠페인 입력값이 올바르지 않습니다.","code":"INVALID_INPUT"}}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places":{"get":{"tags":["장소 탐색"],"summary":"장소 목록 조회","description":"장소명·영문명·주소 또는 등록된 공개 메뉴명에 검색어가 부분 일치하는 장소를 조회합니다.\n메뉴 상태 AVAILABLE/SOLD_OUT만 검색하며 숨김·비활성 메뉴와 메뉴 설명은 검색하지 않습니다.\n여러 메뉴가 일치해도 장소는 한 번만 반환합니다. 카테고리는 검색어와 함께 적용하는 선택 필터입니다.\n검색어를 생략하거나 빈 값·공백만 전달하면 일반 장소 탐색을 유지하며 예약 날짜·시간·인원은 필요하지 않습니다.\n위치·반경과 검색 조건을 적용한 뒤 sort로 정렬하고 limit(1~100)으로 페이지를 제한합니다.\n주변 거리순 검색은 latitude/longitude/radiusKm와 sort=NEAREST를 전달하며, 앱은 limit=3을 사용할 수 있습니다.\n결과가 없으면 200과 빈 places, totalCount=0을 반환합니다.\n","operationId":"listPlaces","parameters":[{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"장소명·영문명·주소 또는 공개 메뉴명 부분 검색어. 앞뒤 공백은 제거하며 %, _, 역슬래시는 문자 그대로 검색합니다.","required":false,"schema":{"type":"string"},"example":"갈비탕"},{"name":"category","in":"query","description":"카테고리 필터","required":false,"schema":{"type":"string"},"example":"카페"},{"name":"touristCategory","in":"query","description":"관광 카테고리 필터","required":false,"schema":{"type":"string"},"example":"K_POP"},{"name":"latitude","in":"query","description":"현재 위도. 거리 검색 시 longitude, radiusKm와 함께 전달합니다.","required":false,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.1801},{"name":"longitude","in":"query","description":"현재 경도. 거리 검색 시 latitude, radiusKm와 함께 전달합니다.","required":false,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.1078},{"name":"radiusKm","in":"query","description":"검색 반경(km). 거리 검색 시 latitude, longitude와 함께 전달합니다.","required":false,"schema":{"maximum":20.0,"exclusiveMaximum":false,"minimum":0.1,"exclusiveMinimum":false,"type":"number","format":"double"},"example":3.0},{"name":"sort","in":"query","description":"정렬 기준. LATEST, NEAREST 또는 POPULAR","required":false,"schema":{"type":"string","default":"LATEST"},"example":"LATEST"}],"responses":{"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"장소 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceListResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/visit-decision":{"get":{"tags":["장소 상세·메뉴"],"summary":"관광객용 장소 방문 결정 정보 조회","description":"현재 운영 상태, 공지, 진행 이벤트, 예약 가능 시간과 발급 가능한 혜택을 한 번에 조회합니다.","operationId":"getPlaceVisitDecision","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"공개 중인 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"방문 결정 정보 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceVisitDecisionResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/operating-notices":{"get":{"tags":["장소 상세·메뉴"],"summary":"장소 활성 운영 상태 공지 조회","description":"현재 영업시간 기준 운영 여부와 활성 운영 상태 공지를 조회합니다.","operationId":"listOperatingNotices","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"활성 운영 상태 공지 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeListResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/menus":{"get":{"tags":["장소 상세·메뉴"],"summary":"관광객용 장소 메뉴 목록 조회","description":"AVAILABLE와 SOLD_OUT 메뉴만 displayOrder 오름차순으로 반환합니다. 로그인 사용자는 국가 코드에 따른 참고 환산 가격을 함께 받습니다. 예를 들어 원래 가격이 KRW 9,000원인 메뉴는 USD 6.43으로 환산될 수 있으며, 이는 가정된 환율 예시입니다. 원래 통화와 표시 통화가 같으면 convertedPrice는 null이고, 실제 결제 기준은 항상 원래 가격과 통화입니다.","operationId":"list_5","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"공개 메뉴 목록 조회 성공","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlaceMenuPublicResponse"}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/card":{"get":{"tags":["장소 상세·메뉴"],"summary":"관광객용 장소 카드 조회","description":"관광객의 장소 탐색과 방문 결정을 위한 요약 정보를 조회합니다.","operationId":"getTouristPlaceCard","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"공개 중인 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"장소 카드 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TouristPlaceCardResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/availabilities":{"get":{"tags":["예약"],"summary":"장소 예약 가능 시간 조회","operationId":"list_6","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AvailabilityResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/availabilities/{availabilityId}/quote":{"get":{"tags":["예약"],"summary":"예약 전 견적·취소 조건 조회","description":"활성 일반 사용자 본인의 확인 토큰을 준비합니다. 예약 생성·결제·재고 점유는 수행하지 않습니다. 유효기간은 최대 5분이며 슬롯 시작 전까지입니다. 사용자 확인 직전에 다시 조회하세요.","operationId":"quote","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"quantity","in":"query","required":true,"schema":{"minimum":1,"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationQuoteResponse"}}}},"404":{"description":"RESERVATION_SLOT_NOT_FOUND: 슬롯 부재/장소 불일치. 재확인이 필요합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"QUOTE_CONDITIONS_CHANGED: 조건 변경. RESERVATION_SLOT_INACTIVE: 비활성/시작된 슬롯. RESERVATION_CAPACITY_EXCEEDED: 정원 부족. 재확인이 필요합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"QUOTE_TERMS_UNAVAILABLE: 시간대/취소 정책 미설정 또는 시간 해석 불가. 취소 정책을 추정하지 않습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"TOURIST_ACCOUNT_REQUIRED: 활성 일반 사용자만 견적을 조회할 수 있습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"QUOTE_RATE_LIMITED: 사용자당 시간당 60건 또는 미사용 견적 120건 한도 초과. 잠시 후 다시 조회하세요.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/{id}/media/verification":{"get":{"tags":["장소 상세·메뉴"],"summary":"장소 검증용 미디어 조회","description":"장소 소유자가 검증 출처로 기록된 미디어를 조회합니다.","operationId":"getVerificationMedia","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"200":{"description":"검증용 미디어 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaResponse"}}}},"403":{"description":"본인 소유가 아닌 장소의 검증 미디어 조회","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{id}":{"get":{"tags":["장소 상세·메뉴"],"summary":"장소 상세 조회","description":"특정 장소의 상세 정보를 조회합니다.","operationId":"getPlace","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"장소 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceDetailResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/trends":{"get":{"tags":["장소 탐색"],"summary":"전국 장소 트렌드 조회","description":"이력 수집 시작 시점부터 최근 7일의 북마크 순증가량으로 공개 운영 장소를 조회합니다.","operationId":"findTrends","parameters":[{"name":"period","in":"query","description":"지원 기간. 현재 WEEK만 지원합니다.","required":false,"schema":{"type":"string","default":"WEEK"},"example":"WEEK"},{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 최대 50","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"전국 장소 트렌드 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceTrendResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"지원하지 않는 기간 또는 페이지 조건","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceTrendResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/recommendations":{"get":{"tags":["장소 탐색"],"summary":"장소 추천 조회","description":"현재 위치와 사용자 반응 이력을 기반으로 추천 장소를 조회합니다.","operationId":"recommendPlaces","parameters":[{"name":"latitude","in":"query","description":"현재 위도","required":true,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.1801},{"name":"longitude","in":"query","description":"현재 경도","required":true,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.1078},{"name":"limit","in":"query","description":"추천 최대 개수","required":false,"schema":{"maximum":20,"minimum":1,"type":"integer","format":"int32","default":10},"example":10},{"name":"radiusKm","in":"query","description":"초기 탐색 반경(km)","required":false,"schema":{"maximum":20.0,"exclusiveMaximum":false,"minimum":1.0,"exclusiveMinimum":false,"type":"number","format":"double","default":5.0},"example":5.0},{"name":"recommendationVersion","in":"query","description":"강제 추천 버전","required":false,"schema":{"type":"string"},"example":"place-rec-v2"}],"responses":{"400":{"description":"좌표 또는 요청값 검증 실패","content":{"*/*":{"example":{"message":"recommendPlaces.latitude: 위도는 -90.0 이상이어야 합니다."}}}},"200":{"description":"장소 추천 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceRecommendationResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/recommendations/{requestId}/explanation":{"get":{"tags":["장소 탐색"],"summary":"추천 설명 조회","description":"사용자가 본인 추천 응답 requestId의 후보 source, score, ranking 정보를 조회합니다.","operationId":"getRecommendationExplanation","parameters":[{"name":"requestId","in":"path","description":"추천 응답 requestId","required":true,"schema":{"type":"string"},"example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}],"responses":{"404":{"description":"추천 설명 정보를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"추천 설명 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceRecommendationExplanationResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/nearby-reservable":{"get":{"tags":["장소 탐색"],"summary":"현재 위치 주변 예약 가능 장소 조회","description":"현재 위치와 예약 조건에 맞는 장소를 한 번에 조회합니다.","operationId":"nearbyReservablePlaces","parameters":[{"name":"latitude","in":"query","description":"현재 위도","required":true,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.8714},{"name":"longitude","in":"query","description":"현재 경도","required":true,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.6014},{"name":"radiusKm","in":"query","description":"검색 반경(km)","required":false,"schema":{"maximum":20.0,"exclusiveMaximum":false,"minimum":0.1,"exclusiveMinimum":false,"type":"number","format":"double","default":3.0},"example":3.0},{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-10T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-11T00:00:00"},{"name":"quantity","in":"query","description":"예약 인원","required":false,"schema":{"minimum":1,"type":"integer","format":"int32"},"example":2},{"name":"category","in":"query","description":"장소 카테고리","required":false,"schema":{"type":"string"},"example":"테마파크"},{"name":"touristCategory","in":"query","description":"관광 카테고리","required":false,"schema":{"type":"string"},"example":"ATTRACTION"},{"name":"sort","in":"query","description":"정렬","required":false,"schema":{"type":"string","default":"NEAREST","enum":["NEAREST","EARLIEST_AVAILABLE","POPULAR"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NearbyReservablePlaceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/map":{"get":{"tags":["장소 탐색"],"summary":"지도 viewport 장소 조회","description":"지도 경계와 zoom에 따라 장소 cluster 또는 marker를 조회합니다.","operationId":"mapViewport","parameters":[{"name":"west","in":"query","description":"서쪽 경도 경계","required":true,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.0},{"name":"south","in":"query","description":"남쪽 위도 경계","required":true,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.0},{"name":"east","in":"query","description":"동쪽 경도 경계","required":true,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":129.0},{"name":"north","in":"query","description":"북쪽 위도 경계","required":true,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":36.0},{"name":"zoom","in":"query","description":"지도 zoom 단계","required":true,"schema":{"maximum":20,"minimum":0,"type":"integer","format":"int32"},"example":14}],"responses":{"400":{"description":"지도 경계 또는 zoom 조건이 올바르지 않음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"지도 viewport 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MapViewportResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/local-hot":{"get":{"tags":["장소 탐색"],"summary":"시·군·구 우리 지역 핫플 조회","description":"좌표 또는 이전 응답의 regionCode 중 하나로 시·군·구의 공개 운영 장소를 현재 북마크 수 순으로 조회합니다.","operationId":"findLocalHotPlaces","parameters":[{"name":"latitude","in":"query","description":"현재 위도. longitude와 함께 전달하며 regionCode와 동시에 전달할 수 없습니다.","required":false,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":37.5172},{"name":"longitude","in":"query","description":"현재 경도. latitude와 함께 전달하며 regionCode와 동시에 전달할 수 없습니다.","required":false,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":127.0473},{"name":"regionCode","in":"query","description":"이전 좌표 조회 응답의 5자리 시·군·구 코드","required":false,"schema":{"pattern":"\\d{5}","type":"string"},"example":11680},{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 최대 50","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"502":{"description":"외부 지역 판정 서비스 호출 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"200":{"description":"지역 핫플 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"404":{"description":"판정되거나 등록된 시·군·구를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"좌표·지역 코드·페이지 조건이 올바르지 않음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"503":{"description":"외부 지역 판정 서비스 미설정 또는 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/information-reports":{"get":{"tags":["장소 정보 제보"],"summary":"내 장소 정보 신고 목록 조회","operationId":"listMine_3","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/information-reports/{reportId}":{"get":{"tags":["장소 정보 제보"],"summary":"내 장소 정보 신고 상세 조회","operationId":"getMine_2","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/autocomplete":{"get":{"tags":["장소 탐색"],"summary":"장소 검색 자동완성","description":"검색어 입력 중 장소 후보를 자동완성으로 조회합니다.","operationId":"autocompletePlaces","parameters":[{"name":"keyword","in":"query","description":"검색어","required":true,"schema":{"type":"string"},"example":"진주"},{"name":"limit","in":"query","description":"최대 반환 개수","required":false,"schema":{"type":"integer","format":"int32","default":10},"example":10},{"name":"latitude","in":"query","description":"현재 위도","required":false,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.1801},{"name":"longitude","in":"query","description":"현재 경도","required":false,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.1078}],"responses":{"400":{"description":"잘못된 요청값","content":{"*/*":{"example":{"message":"latitude와 longitude는 함께 전달해야 합니다."}}}},"200":{"description":"장소 자동완성 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceAutocompleteResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/payments":{"get":{"tags":["결제"],"summary":"내 결제 목록 조회","description":"결제 내역이 없으면 payments가 빈 배열인 200 응답을 반환합니다.","operationId":"list_7","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"400":{"description":"페이지 요청 값 검증 실패 (VALIDATION_FAILED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"page":"1 이상이어야 합니다."}}}}}}},"200":{"description":"내 결제 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentPageResponse"}}}},"403":{"description":"활성 일반 사용자 계정이 아님 (PAYMENT_FORBIDDEN)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PAYMENT_FORBIDDEN":{"description":"PAYMENT_FORBIDDEN","value":{"message":"이 결제 거래를 처리할 권한이 없습니다.","code":"PAYMENT_FORBIDDEN"}}}}}},"401":{"description":"유효하지 않거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/payments/{paymentId}":{"get":{"tags":["결제"],"summary":"내 결제 상세 조회","description":"본인 결제만 조회할 수 있으며, 실패·환불 상태별 nullable 필드는 응답에 포함됩니다.","operationId":"get_6","parameters":[{"name":"paymentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"결제 거래를 찾을 수 없음 (PAYMENT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PAYMENT_NOT_FOUND":{"description":"PAYMENT_NOT_FOUND","value":{"message":"결제 거래를 찾을 수 없습니다.","code":"PAYMENT_NOT_FOUND"}}}}}},"401":{"description":"유효하지 않거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"200":{"description":"내 결제 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentResponse"}}}},"403":{"description":"활성 일반 사용자 계정이 아니거나 다른 사용자의 결제","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PAYMENT_FORBIDDEN":{"description":"PAYMENT_FORBIDDEN","value":{"message":"이 결제 거래를 처리할 권한이 없습니다.","code":"PAYMENT_FORBIDDEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/offers":{"get":{"tags":["쿠폰·혜택"],"summary":"발급 가능한 관광객 전용 Offer 목록 조회","operationId":"list_8","parameters":[{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"Offer 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferPageResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/offers/{offerId}":{"get":{"tags":["쿠폰·혜택"],"summary":"발급 가능한 관광객 전용 Offer 상세 조회","operationId":"get_7","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Offer 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"404":{"description":"발급 가능한 Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/verified-boost-products":{"get":{"tags":["Verified Boost"],"summary":"선택 가능한 Verified Boost 활성 상품 목록 조회","operationId":"list_10","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantVerifiedBoostProductPageResponse"}}}},"403":{"description":"활성 Merchant Owner 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations":{"get":{"tags":["예약 관리"],"summary":"소유 장소 예약 목록 조회","operationId":"list_12","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"reservationFrom","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"reservationTo","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}":{"get":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 장소 상세 조회","operationId":"getPlace_1","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/reviews":{"get":{"tags":["리뷰 관리"],"summary":"점주 리뷰 관리 목록 조회","description":"소유 장소의 VISIBLE, HIDDEN, DELETED 리뷰와 최신 삭제 신청 상태를 1-based 페이지로 조회합니다.","operationId":"listMerchantPlaceReviews","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceReviewPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating":{"get":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 장소 운영 정보 조회","operationId":"getOperating","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/members":{"get":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 목록 조회","description":"OWNER 또는 MANAGER만 활성 상태의 팀원을 ID 오름차순으로 조회할 수 있습니다. REVOKED 팀원과 만료·취소된 초대는 목록에 포함되지 않으며, 권한 부족은 MERCHANT_TEAM_PERMISSION_REQUIRED로 응답합니다.","operationId":"list_14","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"팀원 목록 조회 성공","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MerchantTeamMemberResponse"}}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"403":{"description":"OWNER 또는 MANAGER 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_PERMISSION_REQUIRED":{"description":"MERCHANT_TEAM_PERMISSION_REQUIRED","value":{"message":"Merchant 팀원 관리 권한이 필요합니다.","code":"MERCHANT_TEAM_PERMISSION_REQUIRED"}}}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/place-information-reverification-requests":{"get":{"tags":["장소 정보 관리"],"summary":"내 장소 정보 재확인 요청 목록 조회","operationId":"listMine_4","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/performance":{"get":{"tags":["실적"],"summary":"Merchant 성과 요약 조회","description":"소유 장소의 추천 노출, 클릭, 북마크, 예약 전환 성과를 조회합니다.","operationId":"get_10","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPerformanceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/payments":{"get":{"tags":["결제"],"summary":"소유 장소 결제 목록 조회","operationId":"list_15","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/payments/settlements":{"get":{"tags":["결제"],"summary":"정산 원장 조회","operationId":"settlements","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SettlementLedgerPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers/{offerId}":{"get":{"tags":["캠페인·혜택"],"summary":"내 관광객 전용 Offer 상세 조회","operationId":"get_11","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"Offer 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/me":{"get":{"tags":["사업자 정보"],"summary":"승인된 Merchant Owner 프로필 조회","description":"DB의 현재 역할과 승인 상태를 확인합니다.","operationId":"getActiveProfile","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/location-check-ins/{checkInId}/evidence/file":{"get":{"tags":["방문 인증"],"summary":"내 방문 체크인 증빙 파일 다운로드","operationId":"download","parameters":[{"name":"checkInId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"증빙 이미지","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"본인 소유 체크인 또는 증빙을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/events":{"get":{"tags":["행사·팝업"],"summary":"공개 기간형 이벤트 목록 조회","description":"PUBLISHED 상태이며 종료 시각이 현재보다 이후인 이벤트를 시작 시각 순으로 조회합니다. 기간 필터는 [fromAt, toAt)와 겹치는 이벤트에 적용됩니다. 빈 목록은 events=[], totalCount=0, totalPages=0, hasNext=false로 반환합니다.","operationId":"listEvents","parameters":[{"name":"eventType","in":"query","description":"이벤트 유형","required":false,"schema":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]}},{"name":"fromAt","in":"query","description":"기간 겹침 조회 시작 시각. RFC 3339 offset을 받아 UTC로 정규화합니다.","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-08-01T00:00:00Z"},{"name":"toAt","in":"query","description":"기간 겹침 조회 종료 시각. fromAt보다 이후여야 하며 RFC 3339 offset을 받아 UTC로 정규화합니다.","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-01T00:00:00Z"},{"name":"page","in":"query","description":"페이지 번호. 1 미만은 1, 10000 초과는 10000으로 보정됩니다.","required":false,"schema":{"maximum":10000,"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 1 미만은 1, 100 초과는 100으로 보정됩니다.","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"400":{"description":"기간 또는 필터 조건이 올바르지 않음 (PLACE_EVENT_SEARCH_CONDITION_INVALID)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_EVENT_SEARCH_CONDITION_INVALID":{"description":"PLACE_EVENT_SEARCH_CONDITION_INVALID","value":{"message":"이벤트 조회 기간 조건이 올바르지 않습니다.","code":"PLACE_EVENT_SEARCH_CONDITION_INVALID"}}}}}},"200":{"description":"공개 이벤트 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceEventListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/events/{eventId}":{"get":{"tags":["행사·팝업"],"summary":"공개 기간형 이벤트 상세 조회","description":"종료·비공개·없는 이벤트는 모두 404 PLACE_EVENT_NOT_FOUND로 처리합니다.","operationId":"getEvent","parameters":[{"name":"eventId","in":"path","description":"이벤트 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"400":{"description":"이벤트 ID 형식이 올바르지 않음 (PLACE_EVENT_SEARCH_CONDITION_INVALID)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_EVENT_SEARCH_CONDITION_INVALID":{"description":"PLACE_EVENT_SEARCH_CONDITION_INVALID","value":{"message":"이벤트 조회 기간 조건이 올바르지 않습니다.","code":"PLACE_EVENT_SEARCH_CONDITION_INVALID"}}}}}},"404":{"description":"이벤트를 찾을 수 없거나 공개 대상이 아님 (PLACE_EVENT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_EVENT_NOT_FOUND":{"description":"PLACE_EVENT_NOT_FOUND","value":{"message":"이벤트를 찾을 수 없습니다.","code":"PLACE_EVENT_NOT_FOUND"}}}}}},"200":{"description":"공개 이벤트 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceEventDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/coupons":{"get":{"tags":["쿠폰·혜택"],"summary":"내 관광객 Coupon 목록 조회","description":"Offer 제목·혜택과 장소 정보는 Coupon 발급 시점 스냅샷을 반환하므로 Offer 종료 또는 이후 정보 변경과 무관하게 유지됩니다. 원본 정보를 복구할 수 없으면 해당 필드는 null입니다. 발급일 기간은 양 끝값을 포함합니다. status=ISSUED는 아직 만료되지 않은 쿠폰, EXPIRED는 발급 상태이면서 expiresAt이 현재 시각 이하인 쿠폰입니다. 기본 정렬은 issuedAt 내림차순, id 내림차순이며 page와 limit은 각각 최소 1, limit 최대 100으로 보정됩니다.","operationId":"list_18","parameters":[{"name":"status","in":"query","description":"쿠폰 상태. 생략하면 모든 상태를 조회합니다.","required":false,"schema":{"type":"string","enum":["ISSUED","REDEEMED","EXPIRED"]},"example":"ISSUED"},{"name":"issuedFrom","in":"query","description":"발급일 조회 시작 시각(포함, ISO-8601 local date-time)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-08-01T00:00:00"},{"name":"issuedTo","in":"query","description":"발급일 조회 종료 시각(포함, ISO-8601 local date-time)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-08-31T23:59:59"},{"name":"page","in":"query","description":"1부터 시작하는 페이지 번호","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"400":{"description":"발급일 기간 조건 또는 요청 파라미터 형식이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"COUPON_LIST_FILTER_INVALID":{"description":"COUPON_LIST_FILTER_INVALID","value":{"message":"쿠폰 조회 기간 조건이 올바르지 않습니다.","code":"COUPON_LIST_FILTER_INVALID"}},"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값이 올바르지 않습니다.","code":"VALIDATION_FAILED","errors":{"issuedFrom":"날짜 형식이 올바르지 않습니다."}}}}}}},"200":{"description":"Coupon 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CouponPageResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/coupons/{couponId}":{"get":{"tags":["쿠폰·혜택"],"summary":"내 관광객 Coupon 단건 조회","description":"본인이 발급받은 Coupon의 현재 상태를 조회합니다. 만료 시각이 지난 미사용 Coupon은 EXPIRED로 반환하며, REDEEMED Coupon은 redeemedAt을 함께 반환합니다.","operationId":"get_13","parameters":[{"name":"couponId","in":"path","description":"Coupon ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"404":{"description":"Coupon을 찾을 수 없거나 요청자의 Coupon이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"COUPON_NOT_FOUND":{"description":"COUPON_NOT_FOUND","value":{"message":"쿠폰을 찾을 수 없습니다.","code":"COUPON_NOT_FOUND"}}}}}},"200":{"description":"Coupon 단건 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CouponResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}":{"get":{"tags":["커뮤니티 게시글"],"summary":"커뮤니티 게시글 상세 조회","description":"게시글 제목, 본문, 연결 장소의 현재 표시 정보를 조회합니다.","operationId":"findDetail","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"커뮤니티 게시글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/countries":{"get":{"tags":["커뮤니티 게시글"],"summary":"커뮤니티 국가 필터 허용 코드","operationId":"countries","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"type":"string"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/categories":{"get":{"tags":["커뮤니티 게시글"],"summary":"커뮤니티 게시글 카테고리 조회","description":"게시글 작성과 카테고리별 조회에 사용할 활성 카테고리의 식별자와 표시 이름을 조회합니다.","operationId":"findCategories","responses":{"200":{"description":"커뮤니티 게시글 카테고리 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostCategoryListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/categories/{categoryId}/posts":{"get":{"tags":["커뮤니티 게시글"],"summary":"카테고리별 커뮤니티 게시글 목록 조회","description":"미리보기·사진·지역·생성 시각·조회/좋아요/댓글 수와 단일 카테고리를 최신순으로 조회합니다.","operationId":"findByCategory","parameters":[{"name":"categoryId","in":"path","required":true,"schema":{"type":"string"}},{"name":"countryCode","in":"query","description":"ISO alpha-2 국가 코드. 허용 값은 GET /community/countries","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 최대 100","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"카테고리별 게시글 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostListResponse"}}}},"400":{"description":"카테고리 또는 페이지 요청값이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/auth/oauth2/success":{"get":{"tags":["o-auth-2-token-controller"],"summary":"OAuth2 로그인 성공 토큰 교환","operationId":"oauth2Success","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/analysis/reports":{"get":{"tags":["상권 분석"],"summary":"보관된 입지 분석 보고서 목록 조회","operationId":"list_19","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LocationAnalysisReportResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/analysis/reports/{reportId}/html":{"get":{"tags":["상권 분석"],"summary":"보관된 입지 분석 HTML 디버그 조회","operationId":"html","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"text/html":{"schema":{"type":"string"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/analysis/reports/{reportId}/download":{"get":{"tags":["상권 분석"],"summary":"보관된 입지 분석 PDF 다운로드","operationId":"download_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/pdf":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports":{"get":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 목록 조회","operationId":"list_20","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/corrections":{"get":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 정정 목록 조회","operationId":"listCorrections_1","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}":{"get":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 상세 조회","operationId":"get_15","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/sanctions":{"get":{"tags":["회원·권한"],"summary":"사용자 제재 이력 조회","description":"관리자가 특정 사용자의 제재 변경 이력을 페이지 단위로 조회합니다. 제재 이력이 없으면 500이 아니라 빈 histories 배열과 페이지 메타데이터를 반환합니다.","operationId":"listUserSanctionHistories","parameters":[{"name":"userId","in":"path","description":"조회할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"banType","in":"query","description":"제재 유형 필터","required":false,"schema":{"type":"string","enum":["PERMANENT","TEMPORARY"]},"example":"TEMPORARY"},{"name":"action","in":"query","description":"처리 상태 필터","required":false,"schema":{"type":"string","enum":["APPLIED","RELEASED","EXPIRED"]},"example":"APPLIED"},{"name":"from","in":"query","description":"처리 시각 시작 필터","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"처리 시각 종료 필터","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"}],"responses":{"400":{"description":"조회 기간 필터 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"제재 이력 조회 종료 시각은 시작 시각보다 이후여야 합니다.","code":"INVALID_SANCTION_FILTER_PERIOD"}}}},"200":{"description":"사용자 제재 이력 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminUserSanctionHistoryResponse"},"example":{"histories":[],"page":1,"limit":5,"totalCount":0,"totalPages":1,"hasNext":false}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/sanction":{"get":{"tags":["회원·권한"],"summary":"사용자 제재 상태 조회","description":"관리자가 특정 사용자의 현재 제재 상태를 조회합니다. 만료된 기간 밴은 현재 제재로 보지 않습니다.","operationId":"getUserSanctionStatus","parameters":[{"name":"userId","in":"path","description":"조회할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminUserSanctionStatusResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/role-targets":{"get":{"tags":["회원·권한"],"summary":"관리자 역할 부여 대상 사용자 검색","description":"관리자 역할 API에 전달할 수 있는 관리자 계정만 username 부분 일치로 검색합니다. 사용자 공통 표시 이름은 제공되지 않아 username만 검색하며, 빈 keyword는 전체 대상 조회로 처리합니다. page는 1부터 시작하고 limit은 1~100으로 보정됩니다. 이메일과 전화번호는 반환하지 않습니다.","operationId":"search","parameters":[{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기(1~100)","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"username 부분 일치 검색어. 비어 있으면 전체 역할 부여 대상을 조회합니다.","required":false,"schema":{"type":"string"},"example":"operator"}],"responses":{"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"검색 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentTargetSearchResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/banned":{"get":{"tags":["회원·권한"],"summary":"밴 유저 목록 조회","description":"관리자가 현재 밴 처리된 사용자 목록을 페이지 단위로 조회합니다. keyword는 숫자만 입력하면 userId 정확히 일치로 검색하고, 그 외에는 username 부분 일치로 검색합니다. counts는 현재 밴 중인 사용자 기준이며, keyword 검색어가 있으면 검색 결과 기준으로 계산됩니다. 기간 필터는 from과 to를 사용합니다. limit 값은 내부적으로 1~100 범위로 보정됩니다.","operationId":"listBannedUsers","parameters":[{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"숫자만 입력하면 userId 정확히 일치, 그 외에는 username 부분 일치 검색","required":false,"schema":{"type":"string"},"example":"blockedUser01"},{"name":"banType","in":"query","description":"밴 유형","required":false,"schema":{"type":"string","enum":["PERMANENT","TEMPORARY"]},"example":"PERMANENT"},{"name":"from","in":"query","description":"밴 처리 시작 시각 이상","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"밴 처리 종료 시각 이하","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"sortBy","in":"query","description":"정렬 기준","required":false,"schema":{"type":"string","default":"BANNED_AT","enum":["BANNED_AT","EXPIRES_AT","USER_ID"]},"example":"BANNED_AT"},{"name":"sortDirection","in":"query","description":"정렬 방향","required":false,"schema":{"type":"string","default":"DESC","enum":["ASC","DESC"]},"example":"DESC"}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"밴 유저 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminBannedUserResponse"},"example":{"users":[{"userId":7,"username":"blockedUser01","banned":true,"banType":"PERMANENT","bannedAt":"2026-06-07T13:30:00","banExpiresAt":null}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false,"counts":{"total":1,"permanent":1,"temporary":0}}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/banned/{userId}":{"get":{"tags":["회원·권한"],"summary":"밴 유저 상세 조회","description":"관리자가 특정 밴 유저의 상세 정보를 조회합니다.","operationId":"getBannedUser","parameters":[{"name":"userId","in":"path","description":"조회할 밴 유저 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"밴 유저 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminBannedUserDetailResponse"},"example":{"userId":7,"username":"blockedUser01","email":"blockedUser01@example.com","birthYear":1998,"language":"ko","country":"KR","role":"USER","banned":true,"bannedAt":"2026-06-07T13:30:00","banType":"PERMANENT","banExpiresAt":null,"banReason":"반복적인 신고 누적","createdAt":"2026-06-01T10:00:00"}}}},"404":{"description":"밴 유저를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}":{"get":{"tags":["신뢰 점수"],"summary":"신고자 신뢰 등급과 점수 근거 조회","description":"관리자가 신고자의 신뢰 점수, 등급, 신고 처리 통계 기반 점수 근거를 조회합니다.","operationId":"getTrustScore","parameters":[{"name":"reporterUserId","in":"path","description":"신고자 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"200":{"description":"신뢰 등급과 점수 근거 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreResponse"},"example":{"reporterUserId":7,"reporterUsername":"pingdom_user","trustScore":80,"trustGrade":"HIGH","restricted":false,"restrictedUntil":null,"restrictionReason":null,"evidence":{"submittedCount":12,"acceptedCount":8,"declinedCount":4,"falseReportCount":3,"acceptanceRate":66.67,"baseScore":100,"acceptedScoreBonus":40,"falseReportScorePenalty":60}}}}},"404":{"description":"신고자 Trust Score 정책을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"신고자 Trust Score 정책을 찾을 수 없습니다.","code":"TRUST_SCORE_REPORTER_POLICY_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}/history":{"get":{"tags":["신뢰 점수"],"summary":"신고자 Trust Score 변경 이력 조회","operationId":"listTrustScoreHistory","parameters":[{"name":"reporterUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreChangeHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/anomalies":{"get":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 이상치 목록 조회","description":"관리자가 Trust Score 이상치 목록을 조회합니다. page는 1 이상, limit은 1~100 범위로 보정됩니다.","operationId":"listAnomalies","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"reporterUserId","in":"query","description":"신고자 사용자 ID 필터","required":false,"schema":{"type":"integer","format":"int64"},"example":12},{"name":"unresolvedOnly","in":"query","description":"미해결 이상치만 조회할지 여부","required":false,"schema":{"type":"boolean","default":false},"example":true}],"responses":{"200":{"description":"Trust Score 이상치 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 목록 조회","operationId":"list_23","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACTIVE","SUSPENDED","REVOKED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfilePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 및 활동 자격 상세 조회","operationId":"get_16","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-field-reports":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 현장 제보 목록 조회","operationId":"list_24","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/s3/orphan-objects":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"S3 orphan 객체 dry-run 리포트","description":"DB에 등록된 게시글 원본/썸네일 S3 key와 S3 객체 목록을 비교해 DB에서 사용 중이지 않은 객체를 조회합니다. 실제 삭제는 수행하지 않습니다.","operationId":"reportOrphanObjects","parameters":[{"name":"prefix","in":"query","description":"조회할 S3 key prefix","required":false,"schema":{"type":"string","default":"map/"},"example":"map/"},{"name":"limit","in":"query","description":"최대 스캔 객체 수. 1~10000 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1000},"example":1000}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminS3OrphanObjectReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reservations":{"get":{"tags":["예약"],"summary":"관리자 예약 기록 목록 조회","operationId":"list_25","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"merchantOwnerUserId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"touristUserId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"reservationFrom","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"reservationTo","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReservationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reservations/{reservationId}":{"get":{"tags":["예약"],"summary":"관리자 예약 기록 상세 조회","operationId":"get_18","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/reported-users":{"get":{"tags":["신고·이의신청"],"summary":"관리자 신고 유저 목록 조회","description":"관리자가 PENDING 상태의 신고 유저 목록을 조회합니다. limit 값은 내부적으로 1~100 범위로 보정됩니다.","operationId":"getReportedUsers","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"검색 키워드. 신고자 이름, 신고 사유, 신고받은 유저 ID로 검색합니다.","required":false,"schema":{"type":"string","default":""},"example":"욕설"}],"responses":{"200":{"description":"신고 유저 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReportedUsersResponse"},"example":{"users":[{"reportId":12,"reporterUserId":3,"reporterUsername":"reporter01","reportedImageId":101,"reportedUserId":55,"reason":"욕설"}],"page":1,"limit":20,"totalCount":123,"totalPages":7,"hasNext":true}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/reported-users/{id}":{"get":{"tags":["신고·이의신청"],"summary":"관리자 신고 유저 상세 조회","description":"관리자가 신고 상세 정보를 조회합니다.","operationId":"getReportedUser","parameters":[{"name":"id","in":"path","description":"조회할 신고 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":12}],"responses":{"404":{"description":"신고를 찾을 수 없음","content":{"*/*":{"example":{"message":"신고를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}},"200":{"description":"신고 유저 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReportedUsersItem"},"example":{"reportId":12,"reporterUserId":3,"reporterUsername":"reporter01","reportedImageId":101,"reportedUserId":55,"reason":"욕설"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals":{"get":{"tags":["신고·이의신청"],"summary":"신고 이의제기 목록 조회","operationId":"list_26","parameters":[{"name":"status","in":"query","description":"이의제기 상태","required":false,"schema":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]}},{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/privacy-processing-histories":{"get":{"tags":["감사·개인정보 처리 이력"],"summary":"개인정보 처리 이력 조회","description":"관리자가 개인정보 export, 탈퇴, 익명화, 삭제 처리 이력을 페이지 단위로 조회합니다.","operationId":"listHistories","parameters":[{"name":"subjectUserId","in":"query","description":"처리 대상 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"actorUserId","in":"query","description":"처리 수행 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"action","in":"query","description":"처리 유형","required":false,"schema":{"type":"string","enum":["EXPORT_REQUESTED","WITHDRAWAL_REQUESTED","ANONYMIZED","DELETED"]},"example":"EXPORT_REQUESTED"},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-31T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PrivacyProcessingHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 삭제 후보 리포트 생성","description":"최근 생성된 S3 고아 파일 리포트의 삭제 후보를 페이지 단위로 조회합니다. 이 API는 S3/DB 전체 스캔이나 실제 삭제를 수행하지 않습니다.","operationId":"createS3OrphanReport","parameters":[{"name":"reportId","in":"query","description":"조회할 리포트 ID. 생략하면 최근 생성된 리포트를 조회합니다.","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReport"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report/status":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 리포트 생성 상태 조회","description":"리포트 생성 작업의 RUNNING/COMPLETED/FAILED 상태와 집계 정보를 조회합니다.","operationId":"getS3OrphanReportStatus","parameters":[{"name":"reportId","in":"query","description":"조회할 리포트 ID. 생략하면 최근 생성된 리포트를 조회합니다.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReportStatus"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places":{"get":{"tags":["장소 조회"],"summary":"관리자 장소 목록 조회","description":"관리자가 등록된 장소 목록을 페이지 단위로 조회합니다.","operationId":"listPlaces_1","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"sortParam","in":"query","description":"장소 정렬 기준. LATEST, OLDEST, LEVEL_DESC만 지원합니다.","required":false,"schema":{"type":"string","enum":["LATEST","OLDEST","LEVEL_DESC"]},"example":"LATEST"},{"name":"keyword","in":"query","description":"장소 검색 키워드. 장소명, 등록자 ID, 주소로 검색합니다.","required":false,"schema":{"type":"string","default":""},"example":"용인"},{"name":"category","in":"query","description":"일반 장소 카테고리 필터. 입력값을 표준 카테고리로 정규화한 뒤 AdminMapPlaceItem.category와 정확히 비교합니다. touristCategories와는 별도 기준입니다.","required":false,"schema":{"type":"string","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"example":"CAFE"}],"responses":{"200":{"description":"장소 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceResponse"},"examples":{"categoryFilteredResult":{"summary":"카테고리 필터 조회 결과","description":"categoryFilteredResult","value":{"places":[{"id":1,"name":"진주성","address":"경상남도 진주시 남강로 626","discoveryStatus":"VISIBLE","category":"CULTURAL_HERITAGE","categoryName":"문화재","touristCategories":["EXHIBITION"],"latitude":35.1894,"longitude":128.0789,"userId":3,"registrant":"placeRegistrar","level":5,"placeGrowth":{"photoCount":10,"level":5,"currentLevelMinPhotoCount":10,"nextLevelMinPhotoCount":16,"progressPercent":0}}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}},"emptyResult":{"summary":"카테고리 필터 결과 없음","description":"emptyResult","value":{"places":[],"page":1,"limit":20,"totalCount":0,"totalPages":1,"hasNext":false}}}}}},"400":{"description":"지원하지 않는 장소 정렬 기준","content":{"*/*":{"example":{"message":"장소 목록은 LATEST 또는 OLDEST 정렬만 지원합니다.","code":"UNSUPPORTED_PLACE_SORT_PARAM"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}":{"get":{"tags":["장소 조회"],"summary":"관리자 장소 상세 조회","description":"관리자가 특정 장소의 기본 정보와 연결된 게시글 목록을 조회합니다.","operationId":"getPlace_2","parameters":[{"name":"id","in":"path","description":"조회할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"sortParam","in":"query","description":"게시글 정렬 기준","required":false,"schema":{"type":"string","default":"LATEST","enum":["LATEST","OLDEST","MOST_LIKED"]},"example":"LATEST"},{"name":"keyword","in":"query","description":"게시글 검색","required":false,"schema":{"type":"string","default":""},"example":"용인"}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"장소 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDetailResponse"},"example":{"id":1,"name":"진주성","imageUrl":"https://example.com/places/1/representative.jpg","address":"경상남도 진주시 남강로 626","discoveryStatus":"VISIBLE","category":"CULTURAL_HERITAGE","categoryName":"문화재","latitude":35.1894,"longitude":128.0789,"userId":3,"username":"placeOwner","sortParam":"LATEST","postCount":1,"level":5,"placeGrowth":{"photoCount":10,"hiddenPhotoCount":1,"level":5,"currentLevelMinPhotoCount":10,"nextLevelMinPhotoCount":16,"progressPercent":0},"posts":[{"id":10,"imageUrl":"https://example.com/image.jpg","title":"야경 사진","description":"남강 야경입니다.","userId":3,"username":"pingdom_user","createdAt":"2026-05-28T12:00:00","likeCount":5,"visibilityStatus":"HIDDEN","hiddenReason":"ADMIN_HIDDEN"}]}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendations/{requestId}/explanation":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 설명 조회","description":"관리자가 추천 응답 requestId의 후보 source, score, ranking, feature log 정보를 조회합니다.","operationId":"getRecommendationExplanation_1","parameters":[{"name":"requestId","in":"path","description":"추천 응답 requestId","required":true,"schema":{"type":"string"},"example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}],"responses":{"200":{"description":"추천 설명 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationExplanationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-metrics":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 성과 조회","description":"관리자가 장소별 추천 노출, 클릭, CTR 지표를 조회합니다.","operationId":"listRecommendationMetrics","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"sortBy","in":"query","description":"추천 성과 정렬 기준","required":false,"schema":{"type":"string","enum":["SMOOTHED_CTR","RAW_CTR","BOOKMARK_CONVERSION","LIKE_CONVERSION","TOTAL_CONVERSION","EXPOSURE","CLICK","UPDATED_AT"]},"example":"SMOOTHED_CTR"},{"name":"keyword","in":"query","description":"장소 검색 키워드","required":false,"schema":{"type":"string","default":""},"example":"진주"},{"name":"recommendationVersion","in":"query","description":"추천 버전 필터","required":false,"schema":{"type":"string","default":""},"example":"place-rec-v1"},{"name":"days","in":"query","description":"최근 N일 기준 필터","required":false,"schema":{"type":"integer","format":"int32"},"example":7}],"responses":{"200":{"description":"추천 성과 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricsResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-metrics/compare":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 버전 성과 비교","description":"관리자가 두 추천 버전의 CTR, 전환율, 노출 지표를 같은 조건에서 비교합니다.","operationId":"compareRecommendationMetrics","parameters":[{"name":"baselineVersion","in":"query","description":"기준 추천 버전","required":true,"schema":{"type":"string"},"example":"place-rec-v1"},{"name":"targetVersion","in":"query","description":"비교 대상 추천 버전","required":true,"schema":{"type":"string"},"example":"place-rec-v2"},{"name":"keyword","in":"query","description":"장소 검색 키워드","required":false,"schema":{"type":"string","default":""},"example":"진주"},{"name":"days","in":"query","description":"최근 N일 기준 필터","required":false,"schema":{"type":"integer","format":"int32"},"example":7}],"responses":{"200":{"description":"추천 버전 성과 비교 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricsCompareResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge-histories":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 장소 병합 이력 조회","description":"관리자가 최근 장소 병합 이력을 조회합니다.","operationId":"listMergeHistories","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceMergeHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicates":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 목록 조회","description":"관리자가 병합 대상이 될 수 있는 중복 장소 그룹을 조회합니다.","operationId":"listDuplicatePlaces","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicates/{id}":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 상세 조회","description":"관리자가 특정 장소의 중복 후보 목록을 조회합니다.","operationId":"getDuplicatePlace","parameters":[{"name":"id","in":"path","description":"중복 후보를 확인할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 조회","operationId":"listDuplicateCandidates","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","default":"PENDING","enum":["PENDING","CONFIRMED","REJECTED","MERGED"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 상세 조회","operationId":"getDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests":{"get":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 목록 조회","operationId":"list_28","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests/{deletionRequestId}":{"get":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 상세 조회","operationId":"get_18","parameters":[{"name":"deletionRequestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports":{"get":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 목록 조회","operationId":"list_29","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}":{"get":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 상세 조회","operationId":"get_19","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/outbox-events":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"관리자 Outbox 이벤트 조회","description":"운영자가 Outbox 이벤트의 상태와 실패 원인을 조회합니다. 민감한 payload와 deduplication key는 반환하지 않습니다.","operationId":"list_30","parameters":[{"name":"status","in":"query","description":"처리 상태","required":false,"schema":{"type":"string","enum":["PENDING","PROCESSING","RETRY","SUCCEEDED","FAILED"]},"example":"FAILED"},{"name":"eventType","in":"query","description":"이벤트 유형","required":false,"schema":{"type":"string","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"example":"EMAIL_VERIFICATION_REQUESTED"},{"name":"aggregateType","in":"query","description":"aggregate 유형","required":false,"schema":{"type":"string"},"example":"USER"},{"name":"aggregateId","in":"query","description":"aggregate ID","required":false,"schema":{"type":"string"},"example":10},{"name":"from","in":"query","description":"생성 시각 조회 시작","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"생성 시각 조회 종료","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"400":{"description":"조회 기간 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Outbox 복구 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 알림 목록 조회","description":"인증된 관리자가 자신에게 전달된 운영 알림을 유형, 읽음 상태, 기간 조건으로 조회합니다. 알림 token은 report:{reportId}, place:{placeId}, sanction:{sanctionId} 형식을 사용합니다.","operationId":"listNotifications","parameters":[{"name":"type","in":"query","description":"관리자 알림 유형: ADMIN_REPORT_RECEIVED, ADMIN_REPORT_PROCESSED, ADMIN_DUPLICATE_PLACE_DETECTED, ADMIN_USER_SANCTION","required":false,"schema":{"type":"string","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"example":"ADMIN_REPORT_RECEIVED"},{"name":"read","in":"query","description":"읽음 여부","required":false,"schema":{"type":"boolean"},"example":false},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-31T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"조회 기간 오류","content":{"*/*":{"example":{"message":"알림 조회 종료 시각은 시작 시각보다 이후여야 합니다.","code":"INVALID_NOTIFICATION_FILTER_PERIOD"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"관리자 알림 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationResponse"},"example":{"notifications":[{"notificationId":1,"userId":10,"type":"ADMIN_REPORT_RECEIVED","title":"신고 접수 알림","body":"신고 ID 30 접수가 게시글 ID 12에 등록되었습니다.","token":"report:30","read":false,"createdAt":"2026-07-21T15:30:00"}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/unread-count":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 미확인 알림 개수 조회","description":"관리자가 아직 읽음 처리하지 않은 인앱 알림 개수를 조회합니다.","operationId":"countUnread","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"미확인 알림 개수 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationUnreadCountResponse"},"example":{"unreadCount":3}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notification-deliveries":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 알림 발송 결과 조회","description":"관리자가 사용자, 채널, 상태, 알림 유형, 기간 조건으로 알림 발송 결과를 페이지 단위로 조회합니다.","operationId":"listDeliveries","parameters":[{"name":"userId","in":"query","description":"수신 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":10},{"name":"channel","in":"query","description":"발송 채널","required":false,"schema":{"type":"string","enum":["FCM","EMAIL"]},"example":"FCM"},{"name":"status","in":"query","description":"발송 상태","required":false,"schema":{"type":"string","enum":["SUCCEEDED","FAILED","RETRY_SCHEDULED","FINAL_FAILED"]},"example":"SUCCEEDED"},{"name":"notificationType","in":"query","description":"인앱 알림 유형","required":false,"schema":{"type":"string","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"example":"NEW_LIKE"},{"name":"outboxEventType","in":"query","description":"Outbox 이벤트 유형","required":false,"schema":{"type":"string","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"example":"EMAIL_VERIFICATION_REQUESTED"},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationDeliveryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 목록 조회","description":"keyword는 장소명과 신청자 username을 부분 일치로 검색합니다. NEW_PLACE는 신청 장소명, EXISTING_PLACE_CLAIM은 대상 기존 장소명을 검색합니다. submittedFrom·submittedTo는 신청 제출 시각(Asia/Seoul 기준 LocalDateTime)을 포함 경계로 필터링하며, DRAFT는 제출 시각이 없어 기간 필터에서 제외됩니다. 한쪽 기간 경계만 전달할 수 있고 종료 시각이 시작 시각보다 빠르면 400을 반환합니다. 빈 keyword는 검색 조건을 적용하지 않습니다.","operationId":"list_31","parameters":[{"name":"status","in":"query","description":"반복 전달 가능한 신청 상태 필터","required":false,"style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]}}},{"name":"applicationType","in":"query","required":false,"schema":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]}},{"name":"keyword","in":"query","description":"장소명 또는 신청자 username 부분 일치 검색어. 공백 또는 빈 값은 미적용","required":false,"schema":{"type":"string"},"example":"서울"},{"name":"submittedFrom","in":"query","description":"신청 제출 시각 시작 경계(포함)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-01T00:00:00"},{"name":"submittedTo","in":"query","description":"신청 제출 시각 종료 경계(포함)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-30T23:59:59"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 상세 조회","operationId":"get_20","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/attachments":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 첨부파일 목록 조회","operationId":"listAttachments","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationAttachmentResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/attachments/{attachmentId}/content":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 첨부파일 다운로드","operationId":"attachmentContent","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"attachmentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 신청 목록 조회","operationId":"list_32","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfilePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 신청 상세 조회","operationId":"get_21","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/data-quality/issues":{"get":{"tags":["data-quality-monitoring-controller"],"summary":"데이터 품질 이슈 목록 조회","operationId":"openIssues","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DataQualityIssuePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/summary":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 요약 조회","description":"전체 장소, 게시글, 처리 대기 신고, 현재 밴 사용자 수와 운영 지표를 조회합니다. 등록 변화 지표는 서버 기준 오늘 00시부터 현재까지와 오늘을 포함한 최근 7일을 제공합니다. 중복 장소는 이름·주소 기준 후보 그룹 수, 밴 만료 예정 사용자는 현재 시각부터 7일 이내의 임시 밴 사용자 수, 위치 정보 누락 장소는 location이 없는 장소 수를 의미합니다.","operationId":"getSummary","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"대시보드 요약 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardSummaryResponse"},"example":{"placeCount":44,"postCount":58,"pendingReportCount":5,"bannedUserCount":6,"operationalMetrics":{"today":{"period":"TODAY","startedAt":"2026-07-21T00:00:00","endedAt":"2026-07-21T15:30:00","placeRegistrationCount":3,"postRegistrationCount":7},"last7Days":{"period":"LAST_7_DAYS","startedAt":"2026-07-15T00:00:00","endedAt":"2026-07-21T15:30:00","placeRegistrationCount":12,"postRegistrationCount":31},"duplicatePlaceGroupCount":2,"expiringBannedUserCount":4,"missingLocationPlaceCount":1,"expiringBanUntil":"2026-07-28T15:30:00","collectedAt":"2026-07-21T15:30:00"}}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/recent-activities":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 최근 운영 활동 조회","description":"최근 장소 등록, 게시글 등록, 신고 처리, 사용자 밴 및 밴 해제 내역을 조회합니다. limit 값은 내부적으로 1~50 범위로 보정됩니다.","operationId":"getRecentActivities","parameters":[{"name":"limit","in":"query","description":"조회할 최대 개수. 1~50 범위로 보정됩니다.","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","default":10},"example":10}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"최근 운영 활동 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardRecentActivitiesResponse"},"example":{"places":[{"placeId":10,"name":"핑덤 카페","address":"서울특별시 중구 세종대로 110","userId":3,"registrant":"pingdom_user","createdAt":"2026-07-21T15:30:00"}],"posts":[{"postId":22,"title":"야경이 좋은 장소","userId":3,"username":"pingdom_user","placeId":10,"placeName":"핑덤 카페","createdAt":"2026-07-21T15:30:00"}],"reports":[{"reportId":30,"reportedImageId":22,"title":"야경이 좋은 장소","status":"ACCEPTED","processedAt":"2026-07-21T16:00:00","createdAt":"2026-07-21T15:40:00"}],"userSanctions":[{"sanctionId":40,"targetUserId":5,"targetUsername":"reported_user","action":"APPLIED","banType":"PERMANENT","reason":"부적절한 게시글입니다.","processedAt":"2026-07-21T16:00:00"}]}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/pending-items":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 처리 필요 항목 조회","description":"우선 처리해야 하는 PENDING 신고와 통합 사업자·장소 신청 목록을 조회합니다. 통합 신청은 navigationPath로 관리자 심사 상세 화면 이동 경로를 제공합니다. limit 값은 내부적으로 1~50 범위로 보정됩니다.","operationId":"getPendingItems","parameters":[{"name":"limit","in":"query","description":"조회할 최대 개수. 1~50 범위로 보정됩니다.","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","default":10},"example":10}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"처리 필요 항목 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardPendingItemsResponse"},"example":{"items":[{"type":"POST_REPORT","targetId":30,"reportId":30,"postId":22,"title":"야경이 좋은 장소","status":"PENDING","createdAt":"2026-07-21T15:40:00","navigationPath":null}],"totalCount":1}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 글 목록 조회","description":"숨김 글을 포함해 카테고리와 숨김 상태로 조회합니다.","operationId":"findPosts","parameters":[{"name":"categoryId","in":"query","required":false,"schema":{"type":"string"}},{"name":"hidden","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityPostPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 글 상세 조회","description":"숨김 여부와 연결 장소를 포함해 조회합니다.","operationId":"findPost","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityPostResponse"}}}},"404":{"description":"커뮤니티 글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}/comments":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 댓글 목록 조회","description":"숨김 댓글을 포함해 숨김 상태로 조회합니다.","operationId":"findComments","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"hidden","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"댓글 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityCommentPageResponse"}}}},"404":{"description":"커뮤니티 글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}/comments/{commentId}":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 댓글 상세 조회","operationId":"findComment","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityCommentResponse"}}}},"404":{"description":"커뮤니티 글 또는 댓글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports":{"get":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 목록 조회","operationId":"list_33","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]}},{"name":"targetType","in":"query","required":false,"schema":{"type":"string","enum":["POST","COMMENT"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}":{"get":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 상세 조회","operationId":"get_22","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"신고 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportResponse"},"examples":{"POST":{"summary":"글 신고: postId와 targetId가 동일","description":"POST","value":{"reportId":1,"targetType":"POST","targetId":101,"postId":101,"targetHidden":false,"reporterUserId":10,"reason":"SPAM","description":"글 신고","status":"PENDING","createdAt":"2026-09-17T10:00:00","processedByAdminUserId":null,"processedAt":null}},"COMMENT":{"summary":"댓글 신고: postId는 원문 글, targetId는 댓글","description":"COMMENT","value":{"reportId":2,"targetType":"COMMENT","targetId":202,"postId":101,"targetHidden":false,"reporterUserId":10,"reason":"ABUSE","description":"댓글 신고","status":"PENDING","createdAt":"2026-09-17T10:00:00","processedByAdminUserId":null,"processedAt":null}}}}}},"404":{"description":"커뮤니티 신고를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/audit-logs":{"get":{"tags":["감사·개인정보 처리 이력"],"summary":"관리자 감사 로그 조회","description":"관리자가 actor, action, target, 기간 조건으로 운영 감사 로그를 페이지 단위로 조회합니다.","operationId":"listAuditLogs","parameters":[{"name":"actorUserId","in":"query","description":"작업 관리자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"action","in":"query","description":"작업 유형","required":false,"schema":{"type":"string","enum":["ADMIN_ROLE_ASSIGNED","ADMIN_ROLE_REVOKED","USER_BAN_APPLIED","USER_BAN_RELEASED","REPORT_ACCEPTED","REPORT_DECLINED","COMMUNITY_REPORT_ACCEPTED","COMMUNITY_REPORT_DECLINED","POST_DELETED","POST_HIDDEN","POST_RESTORED","APPEAL_APPROVED","APPEAL_REJECTED","PLACE_DELETED","PLACE_BASIC_INFORMATION_UPDATED","PLACE_KAKAO_PLACE_ID_UPDATED","PLACE_GEOCODING_UPDATED","PLACE_TOURIST_INFO_UPDATED","PLACE_INFORMATION_EVIDENCE_UPDATED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_INFORMATION_REVERIFICATION_COMPLETED","PLACE_INFORMATION_REVERIFICATION_CANCELED","PLACE_INFORMATION_REVERIFICATION_EXPIRED","VISITOR_VERIFICATION_REPORT_REVIEWED","VISITOR_VERIFICATION_REPORT_CORRECTION_REVIEWED","SCOUT_FIELD_REPORT_REVIEWED","SCOUT_PROFILE_REVIEWED","SCOUT_ACTIVITY_ELIGIBILITY_REVIEWED","PLACE_DISCOVERY_STATUS_UPDATED","PLACE_OPERATING_STATUS_UPDATED","PLACE_OPERATING_SCHEDULE_UPDATED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_EVENT_CREATED","PLACE_EVENT_UPDATED","PLACE_EVENT_PUBLISHED","PLACE_EVENT_CANCELLED","PLACE_RECOMMENDATION_TRAFFIC_UPDATED","PLACE_RECOMMENDATION_KILL_SWITCH_UPDATED","TRUST_SCORE_ANOMALY_RESOLVED","TRUST_SCORE_INTERVENTION_RULE_CREATED","TRUST_SCORE_INTERVENTION_RULE_UPDATED","TRUST_SCORE_INTERVENTION_RULE_ENABLED","TRUST_SCORE_INTERVENTION_RULE_DISABLED","TRUST_SCORE_INTERVENTION_EVALUATED","NOTIFICATION_READ","NOTIFICATION_READ_ALL","PLACE_DUPLICATE_CONFIRMED","PLACE_DUPLICATE_REJECTED","PLACE_MERGED","MERCHANT_OWNER_APPROVED","MERCHANT_OWNER_REJECTED","MERCHANT_OWNER_REVOKED","MERCHANT_OWNER_PLACES_UPDATED","MERCHANT_ONBOARDING_UPDATED","MERCHANT_OPERATIONAL_QUALITY_UPDATED","MERCHANT_VERIFICATION_REVIEWED","MERCHANT_VERIFICATION_VIEWED","MERCHANT_PLACE_CLAIM_ATTACHMENT_VIEWED","MERCHANT_PLACE_CLAIM_APPROVED","MERCHANT_PLACE_CLAIM_REJECTED","MERCHANT_PLACE_APPLICATION_APPROVED","MERCHANT_PLACE_APPLICATION_REJECTED","MERCHANT_PLACE_APPLICATION_VIEWED","MERCHANT_PLACE_APPLICATION_ATTACHMENT_VIEWED","OUTBOX_EVENT_RETRIED","AD_CREATED","AD_DELETED","RESERVATION_CONFIRMED","RESERVATION_REJECTED"]},"example":"USER_BAN_APPLIED"},{"name":"targetType","in":"query","description":"대상 유형","required":false,"schema":{"type":"string","enum":["USER","REPORT","COMMUNITY_REPORT","APPEAL","POST","PLACE","PLACE_DUPLICATE_CANDIDATE","PLACE_INFORMATION_EVIDENCE","PLACE_INFORMATION_REPORT","PLACE_INFORMATION_DISPUTE","PLACE_INFORMATION_REVERIFICATION","VISITOR_VERIFICATION_REPORT","VISITOR_VERIFICATION_REPORT_CORRECTION","SCOUT_FIELD_REPORT","SCOUT_PROFILE","SCOUT_ACTIVITY_ELIGIBILITY","PLACE_OPERATING_NOTICE","PLACE_EVENT","TRUST_SCORE_ANOMALY","TRUST_SCORE_INTERVENTION_RULE","NOTIFICATION","OUTBOX_EVENT","MERCHANT_OWNER","MERCHANT_VERIFICATION","MERCHANT_PLACE_CLAIM_ATTACHMENT","MERCHANT_PLACE_CLAIM","MERCHANT_PLACE_APPLICATION","MERCHANT_PLACE_APPLICATION_ATTACHMENT","AD","RESERVATION"]},"example":"USER"},{"name":"targetId","in":"query","description":"대상 ID","required":false,"schema":{"type":"string"},"example":7},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminAuditLogResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/":{"get":{"tags":["서비스 기본"],"summary":"서버 상태 확인","description":"백엔드 서버 구동 여부와 주요 공개 엔드포인트 정보를 반환합니다.","operationId":"home","responses":{"200":{"description":"서버 상태 조회 성공","content":{"*/*":{"example":{"message":"Pingdom Backend is running.","availableEndpoints":["/auth/signup","/auth/login","/auth/email/resend","/auth/email/verify","/auth/token/refresh","/auth/logout","/users/me"],"signupFields":["username","email","password","birthYear","profileImageUrl","language","country"],"loginFields":["username","password"]}}}}}}},"/voice-ai/sessions/{sessionId}":{"delete":{"tags":["Voice AI"],"summary":"음성 AI 세션 종료","description":"동일 세션의 반복 종료 요청은 성공으로 처리됩니다.","operationId":"close_2","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"SESSION_FORBIDDEN: 다른 사용자 세션. ACCESS_DENIED: 공통 접근 거부","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"SESSION_NOT_FOUND: 존재하지 않는 세션","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/oauth-accounts/google":{"delete":{"tags":["내 정보·계정 연동"],"summary":"Google 계정 연결 해제","description":"현재 인증된 사용자 계정에서 Google OAuth 계정 연결을 해제합니다.","operationId":"unlinkGoogle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthAccountDisconnectRequest"}}}},"responses":{"409":{"description":"마지막 로그인 수단 보호 정책 위반","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OAuthAccountResponse"}}}},"401":{"description":"유효하지 않은 토큰 또는 현재 비밀번호 불일치","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"연결된 Google 계정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OAuthAccountResponse"}}}},"200":{"description":"연결 해제 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OAuthAccountResponse"},"example":{"provider":"GOOGLE","linked":false,"message":"Google 계정 연결을 해제했습니다."}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{applicationId}/attachments/{attachmentId}":{"delete":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 첨부파일 삭제","operationId":"delete","parameters":[{"name":"applicationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"attachmentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"No Content"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/bookmarks/{placeId}":{"delete":{"tags":["즐겨찾기"],"summary":"장소 북마크 해제","description":"placeId를 기반으로 장소 북마크를 해제합니다.","operationId":"removeBookmark","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"북마크를 찾을 수 없음","content":{"*/*":{"example":{"message":"북마크를 찾을 수 없습니다.","code":"BOOKMARK_NOT_FOUND"}}}},"200":{"description":"북마크 해제 성공","content":{"*/*":{"example":{"userId":1,"placeId":17,"message":"장소 북마크를 해제했습니다."}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/reviews/media/{reviewMediaId}":{"delete":{"tags":["리뷰 미디어"],"summary":"장소 리뷰 사진 업로드 취소","description":"리뷰에 연결하지 않은 본인의 사진 업로드를 취소합니다.","operationId":"cancel_4","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"reviewMediaId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"리뷰 사진 업로드 취소 완료"},"409":{"description":"이미 리뷰에 연결된 사진","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"리뷰 사진을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"다른 사용자의 사진","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{id}/media/exploration/{mediaId}":{"delete":{"tags":["장소 상세·메뉴"],"summary":"장소 탐색용 미디어 삭제","description":"장소 소유자가 탐색용 미디어를 삭제합니다.","operationId":"deleteExplorationMedia","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"mediaId","in":"path","description":"장소 미디어 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"탐색용 미디어 삭제 성공","content":{"*/*":{"example":"장소 탐색용 미디어를 삭제했습니다."}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/images/{imageId}":{"delete":{"tags":["커뮤니티 게시글"],"summary":"본인 게시글 이미지 또는 미사용 이미지 삭제","operationId":"delete_1","parameters":[{"name":"imageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"IMAGE_NOT_FOUND: 없는 이미지·타인 이미지·숨김 게시글"},"204":{"description":"No Content"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/roles/{role}":{"delete":{"tags":["회원·권한"],"summary":"관리자 역할 회수","operationId":"revoke_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"role","in":"path","required":true,"schema":{"type":"string","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentRevokeRequest"}}}},"responses":{"200":{"description":"회수 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"활성 역할을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{id}/delete":{"delete":{"tags":["신고·이의신청"],"summary":"관리자 게시글 삭제","description":"관리자가 게시글을 강제로 삭제합니다. S3 객체 삭제는 DB 삭제 확정 후 Outbox로 비동기 처리됩니다.","operationId":"deletePost","parameters":[{"name":"id","in":"path","description":"삭제할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"204":{"description":"게시글 삭제 성공"},"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"example":{"message":"게시글을 찾을 수 없습니다.","code":"POST_NOT_FOUND"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans":{"delete":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 삭제","description":"완료된 리포트의 삭제 후보인지 확인하고, 삭제 직전 DB에서 사용 중인 키를 다시 제외한 뒤 S3 객체를 삭제합니다.","operationId":"deleteS3Orphans","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminS3OrphanDeleteRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanDeleteResult"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/delete":{"delete":{"tags":["장소 정보·품질"],"summary":"관리자 장소 삭제","description":"관리자가 장소를 강제로 삭제합니다.","operationId":"forceDeletePlace","parameters":[{"name":"id","in":"path","description":"강제 삭제할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":5}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"409":{"description":"연결된 기간형 이벤트가 있어 장소를 삭제할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"204":{"description":"장소 삭제 성공"},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations/{reservationId}":{"get":{"tags":["예약 관리"],"summary":"소유 장소 예약 상세 및 처리 이력 조회","operationId":"get_8","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantReservationDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations/{reservationId}/confirm":{"post":{"tags":["예약 관리"],"summary":"소유 장소 예약 승인","description":"현재 장소 소유자만 대기 예약을 승인할 수 있습니다. 승인 사유는 선택입니다.","operationId":"confirm","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationReviewRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations/{reservationId}/reject":{"post":{"tags":["예약 관리"],"summary":"소유 장소 예약 반려","description":"현재 장소 소유자만 대기 예약을 반려할 수 있습니다. 반려 사유는 필수입니다.","operationId":"reject","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}}},"components":{"schemas":{"TravelPurposePreferenceUpdateRequest":{"required":["travelPurposes"],"type":"object","properties":{"travelPurposes":{"maxItems":9,"minItems":0,"uniqueItems":true,"type":"array","description":"선호 여행 목적 전체 목록. 빈 배열이면 모든 선호를 해제합니다.","example":["K_POP","FOOD"],"items":{"type":"string","description":"선호 여행 목적 전체 목록. 빈 배열이면 모든 선호를 해제합니다.","example":"[\"K_POP\",\"FOOD\"]","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}}},"description":"여행 목적 선호 전체 변경 요청"},"TravelPurposePreferenceResponse":{"type":"object","properties":{"travelPurposes":{"uniqueItems":true,"type":"array","description":"선호 여행 목적 목록","example":["K_POP","FOOD"],"items":{"type":"string","description":"선호 여행 목적 목록","example":"[\"K_POP\",\"FOOD\"]","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}}},"description":"여행 목적 선호 응답"},"ErrorResponse":{"required":["message"],"type":"object","properties":{"message":{"type":"string","description":"에러 메시지","example":"유효하지 않은 토큰입니다."},"code":{"type":"string","description":"도메인 에러 코드. 일부 공통 검증 오류에서는 제공되지 않을 수 있습니다.","nullable":true,"example":"INVALID_TOKEN"}},"description":"에러 응답"},"ScoutProfileRequest":{"required":["displayName"],"type":"object","properties":{"displayName":{"maxLength":100,"minLength":0,"type":"string"},"introduction":{"maxLength":1000,"minLength":0,"type":"string"}}},"ScoutProfileResponse":{"required":["activityEligibilityStatus","createdAt","displayName","eligibilityReviewedAt","eligibilityReviewedByAdminUserId","eligibilityStatusReason","eligibleFrom","eligibleUntil","introduction","profileReviewedAt","profileReviewedByAdminUserId","profileStatus","profileStatusReason","updatedAt","userId"],"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"displayName":{"type":"string"},"introduction":{"type":"string","nullable":true},"profileStatus":{"type":"string","enum":["PENDING","ACTIVE","SUSPENDED","REVOKED"]},"profileReviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"profileReviewedAt":{"type":"string","format":"date-time","nullable":true},"profileStatusReason":{"type":"string","nullable":true},"activityEligibilityStatus":{"type":"string","enum":["PENDING","ELIGIBLE","SUSPENDED","EXPIRED","REVOKED"]},"eligibleFrom":{"type":"string","format":"date-time","nullable":true},"eligibleUntil":{"type":"string","format":"date-time","nullable":true},"eligibilityReviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"eligibilityReviewedAt":{"type":"string","format":"date-time","nullable":true},"eligibilityStatusReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Scout 프로필 및 활동 자격 응답"},"BreakTime":{"required":["closesAt","opensAt"],"type":"object","properties":{"opensAt":{"$ref":"#/components/schemas/LocalTime"},"closesAt":{"$ref":"#/components/schemas/LocalTime"}}},"LocalTime":{"type":"object","properties":{"hour":{"type":"integer","format":"int32"},"minute":{"type":"integer","format":"int32"},"second":{"type":"integer","format":"int32"},"nano":{"type":"integer","format":"int32"}}},"MerchantPlaceApplicationRequest":{"required":["applicationType","businessName","businessRegistrationNumber","legalName","merchantContactEmail","merchantContactPhone","merchantDisplayName"],"type":"object","properties":{"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"legalName":{"maxLength":100,"minLength":0,"type":"string"},"businessName":{"maxLength":100,"minLength":0,"type":"string"},"businessRegistrationNumber":{"maxLength":30,"minLength":0,"type":"string"},"merchantDisplayName":{"maxLength":100,"minLength":0,"type":"string"},"merchantDescription":{"maxLength":1000,"minLength":0,"type":"string"},"merchantContactEmail":{"maxLength":255,"minLength":0,"type":"string"},"merchantContactPhone":{"maxLength":30,"minLength":0,"type":"string"},"newPlace":{"$ref":"#/components/schemas/PlaceRegistrationRequest"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"maxLength":500,"minLength":0,"type":"string"}}},"PlaceRegistrationOperatingDay":{"required":["dayOfWeek","status"],"type":"object","properties":{"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"status":{"type":"string","enum":["OPEN","CLOSED","OPEN_24_HOURS"]},"opensAt":{"$ref":"#/components/schemas/LocalTime"},"closesAt":{"$ref":"#/components/schemas/LocalTime"},"breakTimes":{"type":"array","items":{"$ref":"#/components/schemas/BreakTime"}}}},"PlaceRegistrationRequest":{"required":["applicantContactPhone","businessContactPhone","category","description","jibunAddress","latitude","longitude","placeName","postalCode","roadAddress"],"type":"object","properties":{"placeName":{"maxLength":100,"minLength":0,"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"latitude":{"maximum":90,"exclusiveMaximum":false,"minimum":-90,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180,"exclusiveMaximum":false,"minimum":-180,"exclusiveMinimum":false,"type":"number","format":"double"},"roadAddress":{"maxLength":255,"minLength":0,"type":"string"},"jibunAddress":{"maxLength":255,"minLength":0,"type":"string"},"postalCode":{"maxLength":20,"minLength":0,"type":"string"},"description":{"maxLength":1000,"minLength":0,"type":"string"},"businessContactPhone":{"maxLength":20,"minLength":0,"type":"string"},"applicantContactPhone":{"maxLength":20,"minLength":0,"type":"string"},"tags":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["ENGLISH_SERVICE_AVAILABLE","ENGLISH_MENU_AVAILABLE","RESERVATION_AVAILABLE","RESERVATION_COUPON_AVAILABLE","GENERAL_COUPON_AVAILABLE","GOOD_AMBIENCE"]}},"timezone":{"maxLength":64,"minLength":0,"type":"string"},"operatingDays":{"maxItems":7,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/PlaceRegistrationOperatingDay"}}}},"MerchantPlaceApplicationAttachmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"fileId":{"type":"string"},"documentType":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"uploadedAt":{"type":"string","format":"date-time"},"retentionExpiresAt":{"type":"string","format":"date-time"},"displayOrder":{"type":"integer","format":"int32"}}},"MerchantPlaceApplicationNewPlaceResponse":{"type":"object","properties":{"placeName":{"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"description":{"type":"string"},"businessContactPhone":{"type":"string"},"applicantContactPhone":{"type":"string"},"tags":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["ENGLISH_SERVICE_AVAILABLE","ENGLISH_MENU_AVAILABLE","RESERVATION_AVAILABLE","RESERVATION_COUPON_AVAILABLE","GENERAL_COUPON_AVAILABLE","GOOD_AMBIENCE"]}},"timezone":{"type":"string"},"operatingDays":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegistrationOperatingDay"}}}},"MerchantPlaceApplicationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"merchantDisplayName":{"type":"string"},"merchantContactEmail":{"type":"string"},"merchantDescription":{"type":"string"},"merchantContactPhone":{"type":"string"},"newPlace":{"$ref":"#/components/schemas/MerchantPlaceApplicationNewPlaceResponse"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"type":"string"},"reviewReason":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"version":{"type":"integer","format":"int64"},"submissionVersion":{"type":"integer","format":"int64"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceApplicationAttachmentResponse"}}}},"MerchantOwnerProfileRequest":{"required":["businessName","contactEmail","contactPhone","displayName"],"type":"object","properties":{"businessName":{"maxLength":100,"minLength":0,"type":"string"},"displayName":{"maxLength":100,"minLength":0,"type":"string"},"description":{"maxLength":1000,"minLength":0,"type":"string"},"contactEmail":{"maxLength":255,"minLength":0,"type":"string"},"contactPhone":{"maxLength":30,"minLength":0,"type":"string"}}},"MerchantOwnerProfileResponse":{"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"businessName":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string","nullable":true},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]},"onboardingStatus":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"]},"onboardingCompletionRate":{"type":"integer","format":"int32"},"onboardingCompletedAt":{"type":"string","format":"date-time","nullable":true},"reviewedBy":{"type":"integer","format":"int64","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"reviewReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"placeIds":{"type":"array","items":{"type":"integer","format":"int64"}}},"description":"Merchant Owner 프로필 응답"},"CurrentActivityIntentUpdateRequest":{"required":["intent"],"type":"object","properties":{"intent":{"type":"string","description":"현재 탐색하려는 행동","example":"CAFE","enum":["EXPLORE","EAT","CAFE","SHOP","ATTEND_EVENT","NIGHTLIFE"]}},"description":"현재 행동 의도 변경 요청"},"CurrentActivityIntentResponse":{"type":"object","properties":{"intent":{"type":"string","description":"현재 행동 의도. 설정되지 않았거나 만료됐으면 null","nullable":true,"example":"CAFE","enum":["EXPLORE","EAT","CAFE","SHOP","ATTEND_EVENT","NIGHTLIFE"]},"expiresAt":{"type":"string","description":"행동 의도 만료 시각. 의도가 없으면 null","format":"date-time","nullable":true}},"description":"현재 행동 의도 응답"},"AdminMapPlaceOperatingExceptionRequest":{"required":["date"],"type":"object","properties":{"date":{"type":"string","format":"date","example":"2026-08-15"},"closed":{"type":"boolean","description":"true이면 종일 휴무이며 hours는 비워야 합니다.","example":true},"hours":{"uniqueItems":true,"type":"array","description":"대체 영업 시간대. closed가 false이면 하나 이상 필요합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingTimeRangeRequest"}}},"description":"관리자 특정 날짜 영업 예외"},"AdminMapPlaceOperatingTimeRangeRequest":{"required":["closesAt","opensAt"],"type":"object","properties":{"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"관리자 장소 운영 시간대"},"AdminMapPlaceRegularOperatingHourRequest":{"required":["closesAt","dayOfWeek","opensAt"],"type":"object","properties":{"dayOfWeek":{"type":"string","example":"MONDAY","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"관리자 요일별 정규 영업 시간대"},"MerchantOwnerOperatingScheduleUpdateRequest":{"type":"object","properties":{"regularHours":{"uniqueItems":true,"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceRegularOperatingHourRequest"}},"exceptions":{"uniqueItems":true,"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingExceptionRequest"}}},"description":"Merchant Owner 장소 영업시간 변경 요청"},"MerchantOwnerOperatingScheduleResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"message":{"type":"string"}},"description":"Merchant Owner 장소 영업시간 변경 응답"},"PlaceOperatingExceptionResponse":{"type":"object","properties":{"date":{"type":"string","description":"Asia/Seoul 기준 예외 날짜","format":"date","example":"2026-08-15"},"closed":{"type":"boolean","description":"true이면 종일 휴무이며 hours는 비어 있습니다."},"hours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingTimeRangeResponse"}}},"description":"Asia/Seoul 기준 특정 날짜의 휴무 또는 대체 영업 시간"},"PlaceOperatingTimeRangeResponse":{"type":"object","properties":{"opensAt":{"type":"string","description":"Asia/Seoul 기준 시작 시각(포함)","format":"time","example":"09:00:00"},"closesAt":{"type":"string","description":"Asia/Seoul 기준 종료 시각(제외)","format":"time","example":"18:00:00"}},"description":"Asia/Seoul 기준 하루 중 장소 운영 시간대"},"PlaceRegularOperatingHourResponse":{"type":"object","properties":{"dayOfWeek":{"type":"string","description":"Asia/Seoul 기준 요일","example":"MONDAY","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"opensAt":{"type":"string","description":"Asia/Seoul 기준 시작 시각(포함)","format":"time","example":"09:00:00"},"closesAt":{"type":"string","description":"Asia/Seoul 기준 종료 시각(제외)","format":"time","example":"18:00:00"}},"description":"Asia/Seoul 기준 요일별 정규 영업 시간대"},"MerchantOwnerRepresentativeMediaUpdateRequest":{"required":["mediaId"],"type":"object","properties":{"mediaId":{"type":"integer","format":"int64"}},"description":"Merchant Owner 대표 미디어 지정 요청"},"MerchantOwnerMediaResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"representativeMediaId":{"type":"integer","format":"int64"},"media":{"type":"array","items":{"$ref":"#/components/schemas/PlaceMediaItem"}}},"description":"Merchant Owner 탐색 미디어 목록 응답"},"PlaceMediaItem":{"required":["createdAt","displayOrder","id","imageUrl","placeId","purpose","s3Key","sourceMapImageId","thumbnailS3Key","thumbnailUrl","updatedAt"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"purpose":{"type":"string","enum":["VERIFICATION","EXPLORATION"]},"imageUrl":{"type":"string"},"s3Key":{"type":"string","nullable":true},"thumbnailUrl":{"type":"string","nullable":true},"thumbnailS3Key":{"type":"string","nullable":true},"sourceMapImageId":{"type":"integer","format":"int64","nullable":true},"displayOrder":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"장소 미디어 항목"},"MerchantPlaceInformationUpdateRequest":{"type":"object","properties":{"description":{"maxLength":1000,"minLength":0,"type":"string","description":"관광객에게 노출할 장소 소개","nullable":true,"example":"K-컬처 굿즈와 체험을 함께 즐길 수 있는 공간입니다."},"contactPhone":{"maxLength":30,"minLength":0,"type":"string","description":"장소 문의 전화번호","nullable":true,"example":"02-1234-5678"},"websiteUrl":{"maxLength":500,"minLength":0,"pattern":"^https?://\\S+$","type":"string","description":"장소 웹사이트 URL","nullable":true,"example":"https://example.com/place"},"reservationUrl":{"maxLength":500,"minLength":0,"pattern":"^https?://\\S+$","type":"string","description":"예약 페이지 URL","nullable":true,"example":"https://example.com/reservations"}},"description":"Merchant 장소 정보 수정 요청"},"MerchantPlaceInformationResponse":{"required":["contactPhone","createdAt","description","placeId","reservationUrl","updatedAt","updatedByUserId","websiteUrl"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"description":{"type":"string","nullable":true},"contactPhone":{"type":"string","nullable":true},"websiteUrl":{"type":"string","nullable":true},"reservationUrl":{"type":"string","nullable":true},"updatedByUserId":{"type":"integer","format":"int64","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Merchant 장소 정보 응답"},"ValidationErrorResponse":{"required":["code","errors","message"],"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string","example":"VALIDATION_FAILED"},"errors":{"type":"object","additionalProperties":{"type":"string"}}},"description":"필드 검증 오류 응답"},"AvailabilityUpsertRequest":{"required":["endsAt","placeId","startsAt"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalCapacity":{"minimum":1,"type":"integer","format":"int32"}}},"AvailabilityResponse":{"required":["conditionsVersion","endsAt","id","placeId","remainingCapacity","reservationTerms","startsAt","status","totalCapacity"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":77},"placeId":{"type":"integer","format":"int64","example":70069},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalCapacity":{"type":"integer","format":"int32","example":100},"remainingCapacity":{"type":"integer","format":"int32","example":42},"status":{"type":"string","example":"ACTIVE","enum":["ACTIVE","INACTIVE"]},"conditionsVersion":{"minimum":0,"type":"integer","description":"시간대·취소 조건 변경 버전. 조건이 미설정이어도 반환합니다.","format":"int64","example":1},"reservationTerms":{"$ref":"#/components/schemas/ReservationTermsResponse"}},"description":"예약 가능 시간 응답"},"ReservationTermsResponse":{"required":["cancellable","cancellationCutoffMinutes","timezone"],"type":"object","properties":{"timezone":{"type":"string","description":"IANA 시간대","example":"Asia/Seoul"},"cancellable":{"type":"boolean","example":true},"cancellationCutoffMinutes":{"type":"integer","description":"취소 가능할 때만 제공하는 시작 전 취소 기한(분)","format":"int32","nullable":true,"example":60}},"description":"저장된 예약 시간대·취소 조건","nullable":true},"ReservationTermsRequest":{"required":["cancellable","timezone"],"type":"object","properties":{"timezone":{"maxLength":64,"minLength":0,"type":"string"},"cancellable":{"type":"boolean"},"cancellationCutoffMinutes":{"minimum":0,"type":"integer","format":"int32"}}},"AdminTrustScoreInterventionRuleRequest":{"required":["actionType","reason","ruleName","triggerType"],"type":"object","properties":{"ruleName":{"maxLength":100,"minLength":0,"type":"string","description":"규칙 이름","example":"low trust temporary restriction"},"triggerType":{"type":"string","description":"트리거 유형","example":"FALSE_REPORT_COUNT","enum":["TRUST_SCORE_RANGE","FALSE_REPORT_COUNT","ACCEPTANCE_RATE","ANOMALY_DETECTED"]},"actionType":{"type":"string","description":"액션 유형","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"minTrustScore":{"maximum":100,"minimum":0,"type":"integer","description":"최소 Trust Score","format":"int32","example":0},"maxTrustScore":{"maximum":100,"minimum":0,"type":"integer","description":"최대 Trust Score","format":"int32","example":60},"minSubmittedCount":{"minimum":0,"type":"integer","description":"최소 신고 수","format":"int64","example":3},"minFalseReportCount":{"minimum":0,"type":"integer","description":"최소 허위 신고 수","format":"int64","example":3},"durationDays":{"type":"integer","description":"임시 제한 기간 일수. TEMPORARY_RESTRICT일 때만 입력합니다.","format":"int32","example":7},"priority":{"minimum":0,"type":"integer","description":"우선순위. 낮을수록 먼저 적용됩니다.","format":"int32","example":10},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"개입 규칙 적용 사유","example":"허위 신고 누적 사용자 제한"}}},"AdminTrustScoreInterventionRuleItem":{"type":"object","properties":{"id":{"type":"integer","description":"개입 규칙 ID","format":"int64","example":1},"ruleName":{"type":"string","description":"규칙 이름","example":"low trust review"},"triggerType":{"type":"string","description":"트리거 유형","example":"FALSE_REPORT_COUNT","enum":["TRUST_SCORE_RANGE","FALSE_REPORT_COUNT","ACCEPTANCE_RATE","ANOMALY_DETECTED"]},"actionType":{"type":"string","description":"액션 유형","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"minTrustScore":{"type":"integer","description":"최소 Trust Score","format":"int32","example":0},"maxTrustScore":{"type":"integer","description":"최대 Trust Score","format":"int32","example":60},"minSubmittedCount":{"type":"integer","description":"최소 신고 수","format":"int64","example":3},"minFalseReportCount":{"type":"integer","description":"최소 허위 신고 수","format":"int64","example":3},"durationDays":{"type":"integer","description":"제한 기간 일수","format":"int32","example":7},"priority":{"type":"integer","description":"우선순위","format":"int32","example":10},"reason":{"type":"string","description":"적용 사유","example":"허위 신고 누적"},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}}},"MerchantOwnerPlaceUpdateRequest":{"type":"object","properties":{"placeIds":{"maxItems":100,"minItems":0,"uniqueItems":true,"type":"array","items":{"type":"integer","format":"int64"}},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerPlaceQualityUpdateRequest":{"required":["noShowRate","reservationCancellationRate","reservationResponseRate","status"],"type":"object","properties":{"status":{"type":"string","enum":["UNMEASURED","HEALTHY","NEEDS_ATTENTION","AT_RISK"]},"reservationResponseRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"reservationCancellationRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"noShowRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"evaluatedAt":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerPlaceResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"operationalQualityStatus":{"type":"string","enum":["UNMEASURED","HEALTHY","NEEDS_ATTENTION","AT_RISK"]},"reservationResponseRate":{"type":"integer","format":"int32"},"reservationCancellationRate":{"type":"integer","format":"int32"},"noShowRate":{"type":"integer","format":"int32"},"qualityEvaluatedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"MerchantOnboardingUpdateRequest":{"required":["completionRate","status"],"type":"object","properties":{"status":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"]},"completionRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"completedAt":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"VoiceAiSessionResponse":{"required":["expiresAt","sessionId"],"type":"object","properties":{"sessionId":{"type":"string"},"expiresAt":{"type":"string","description":"만료 시각. ISO-8601 offset 포함. 현재 시각이 이 값 이상이면 만료됩니다.","format":"date-time","example":"2026-09-17T12:05:00+09:00"}}},"VoiceAiMessageRequest":{"required":["requestId","text"],"type":"object","properties":{"text":{"maxLength":2000,"minLength":0,"type":"string"},"requestId":{"maxLength":128,"minLength":0,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string","description":"최종 envelope.id와 동일한 요청 ID. 재시도 시 동일 text와 함께 유지합니다."}}},"JsonNode":{"type":"object"},"VisitorVerificationReportCreateRequest":{"required":["description","placeId","reportType"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"maxLength":1000,"minLength":0,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"pattern":"^https://[^\\s]+$","type":"string"},"waitTimeMinutes":{"maximum":1440,"minimum":0,"type":"integer","format":"int32"},"languageCode":{"maxLength":10,"minLength":0,"pattern":"^[a-z]{2,3}(-[A-Z]{2})?$","type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]}}},"MyVisitorVerificationReportResponse":{"required":["couponUsageStatus","createdAt","crowdLevel","description","evidenceUrl","id","languageCode","placeId","rejectionReason","reportType","reviewedAt","status","updatedAt","waitTimeMinutes"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"waitTimeMinutes":{"type":"integer","format":"int32","nullable":true},"languageCode":{"type":"string","nullable":true},"couponUsageStatus":{"type":"string","nullable":true,"enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","nullable":true,"enum":["LOW","MODERATE","HIGH","FULL"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"rejectionReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time"}},"description":"내 방문자 검증 제보 응답"},"VisitorVerificationReportCorrectionRequest":{"required":["description"],"type":"object","properties":{"description":{"maxLength":1000,"minLength":0,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"pattern":"^https://[^\\s]+$","type":"string"},"waitTimeMinutes":{"maximum":1440,"minimum":0,"type":"integer","format":"int32"},"languageCode":{"maxLength":10,"minLength":0,"pattern":"^[a-z]{2,3}(-[A-Z]{2})?$","type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]}}},"MyVisitorVerificationReportCorrectionResponse":{"required":["couponUsageStatus","createdAt","crowdLevel","description","evidenceUrl","id","languageCode","placeId","rejectionReason","reportId","reportStatus","reportType","reviewedAt","status","updatedAt","waitTimeMinutes"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"waitTimeMinutes":{"type":"integer","format":"int32","nullable":true},"languageCode":{"type":"string","nullable":true},"couponUsageStatus":{"type":"string","nullable":true,"enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","nullable":true,"enum":["LOW","MODERATE","HIGH","FULL"]},"reportStatus":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"rejectionReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time"}},"description":"내 방문자 검증 제보 정정 응답"},"VisitVerificationStartRequest":{"required":["accuracyMeters","latitude","longitude","observedAt","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"accuracyMeters":{"minimum":0.0,"exclusiveMinimum":false,"type":"number","format":"double"},"observedAt":{"type":"string","format":"date-time"}}},"VisitVerificationSessionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"touristUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["STARTED","IN_PROGRESS","PROXIMITY_LOST","COMPLETED","EXPIRED","REJECTED"]},"startedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time","nullable":true},"requiredRadiusMeters":{"type":"number","description":"세션 생성 시 확정된 장소 반경 기준(미터)","format":"double","example":500},"requiredDwellSeconds":{"type":"integer","description":"세션 생성 시 확정된 연속 체류 기준(초)","format":"int64","example":30},"latestDistanceMeters":{"type":"number","format":"double"},"verifiedDwellSeconds":{"type":"integer","format":"int64"},"nextObservationRecommendedAt":{"type":"string","format":"date-time","nullable":true},"remainingSeconds":{"type":"integer","format":"int64"},"completedCheckInId":{"type":"integer","format":"int64","nullable":true},"reviewEligible":{"type":"boolean"}}},"VisitVerificationObservationRequest":{"required":["accuracyMeters","latitude","longitude","observedAt"],"type":"object","properties":{"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"accuracyMeters":{"minimum":0.0,"exclusiveMinimum":false,"type":"number","format":"double"},"observedAt":{"type":"string","format":"date-time"}}},"ForegroundVisitVerificationStartRequest":{"required":["accuracyMeters","latitude","longitude","observedAt"],"type":"object","properties":{"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"accuracyMeters":{"minimum":0.0,"exclusiveMinimum":false,"type":"number","format":"double"},"observedAt":{"type":"string","format":"date-time"}}},"TravelScheduleCreateRequest":{"required":["endDate","startDate"],"type":"object","properties":{"startDate":{"type":"string","description":"여행 시작일","format":"date","example":"2026-08-01"},"endDate":{"type":"string","description":"여행 종료일","format":"date","example":"2026-08-04"}},"description":"여행 일정 생성 요청"},"TravelScheduleResponse":{"type":"object","properties":{"id":{"type":"integer","description":"여행 일정 ID","format":"int64","example":1},"startDate":{"type":"string","description":"여행 시작일","format":"date","example":"2026-08-01"},"endDate":{"type":"string","description":"여행 종료일","format":"date","example":"2026-08-04"},"status":{"type":"string","description":"기준일에 계산한 일정 상태","example":"UPCOMING","enum":["UPCOMING","ONGOING","ENDED","CANCELLED"]}},"description":"여행 일정 응답"},"ProfileImageUploadResponse":{"type":"object","properties":{"profileImageUrl":{"type":"string","description":"변경된 프로필 이미지 URL","example":"https://cdn.pingdom.com/users/profile-images/1/profile.jpg"}},"description":"프로필 이미지 변경 응답"},"OAuthAccountLinkStartResponse":{"type":"object","properties":{"provider":{"type":"string","description":"OAuth Provider","example":"GOOGLE"},"authorizationUrl":{"type":"string","description":"브라우저가 이동할 OAuth 인증 시작 URL","example":"/oauth2/authorization/google"},"message":{"type":"string","description":"처리 결과 메시지","example":"Google 계정 연결을 시작합니다."}},"description":"OAuth 계정 연결 시작 응답"},"BookmarkCreateRequest":{"required":["placeId"],"type":"object","properties":{"placeId":{"type":"integer","description":"북마크에 추가할 장소 ID","format":"int64","example":17}},"description":"장소 북마크 생성 요청"},"ChangePasswordRequest":{"required":["confirmPassword","currentPassword","newPassword"],"type":"object","properties":{"currentPassword":{"type":"string","description":"현재 비밀번호","example":"currentPass123!"},"newPassword":{"maxLength":2147483647,"minLength":8,"type":"string","description":"변경할 새 비밀번호","example":"newSecurePass123!"},"confirmPassword":{"maxLength":2147483647,"minLength":8,"type":"string","description":"새 비밀번호 확인 입력","example":"newSecurePass123!"}},"description":"비밀번호 변경 요청 정보"},"ChangeUsernameRequest":{"required":["newUsername"],"type":"object","properties":{"newUsername":{"maxLength":50,"minLength":4,"type":"string","description":"변경할 새 아이디","example":"new_pingdom_user"}},"description":"아이디 변경 요청 정보"},"ScoutFieldReportCreateRequest":{"required":["description","placeId","reportType"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","CROWD_LEVEL","SAFETY","OTHER"]},"description":{"maxLength":1000,"minLength":0,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"pattern":"^https://[^\\s]+$","type":"string"}}},"MyScoutFieldReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","CROWD_LEVEL","SAFETY","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"rejectionReason":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RouteCoordinate":{"required":["latitude","longitude"],"type":"object","properties":{"latitude":{"maximum":90,"minimum":-90,"type":"number","description":"WGS84 위도, JSON 숫자","format":"double","example":37.5665},"longitude":{"maximum":180,"minimum":-180,"type":"number","description":"WGS84 경도, JSON 숫자","format":"double","example":126.978}}},"RouteRequest":{"required":["destination","mode","origin"],"type":"object","properties":{"origin":{"$ref":"#/components/schemas/RouteCoordinate"},"destination":{"$ref":"#/components/schemas/RouteCoordinate"},"mode":{"type":"string","description":"car, transit 또는 walk 지원. bike는 422, 그 밖의 값은 400","example":"walk","enum":["car","transit","walk"]}},"description":"현재 조회 시점의 자동차·대중교통·보행자 추천 경로 요청. 동일 출발·도착 좌표는 허용하지 않습니다."},"RouteResponse":{"required":["distanceMeters","durationSeconds","mode","provider"],"type":"object","properties":{"mode":{"type":"string","example":"car","enum":["car"]},"provider":{"type":"string","example":"naver","enum":["naver"]},"distanceMeters":{"minimum":0,"type":"integer","description":"공급자가 계산한 총거리(m)","format":"int64","example":12500},"durationSeconds":{"minimum":0,"type":"integer","description":"예상 소요시간(초), 공급자 밀리초를 올림하여 변환","format":"int64","example":1800},"path":{"minItems":2,"type":"array","description":"출발→도착 순서의 도로 형상 전체. 직선 대체·끝점 덮어쓰기를 하지 않습니다.","items":{"$ref":"#/components/schemas/RouteCoordinate"}}},"description":"NAVER traoptimal 첫 번째 실제 자동차 경로. 입력 좌표와 도로 위 시작·끝 좌표는 다를 수 있습니다."},"Itinerary":{"type":"object","properties":{"totalTimeSeconds":{"type":"integer","format":"int64"},"totalDistanceMeters":{"type":"integer","format":"int64"},"transferCount":{"type":"integer","format":"int32"},"totalWalkDistanceMeters":{"type":"integer","format":"int64"},"totalWalkTimeSeconds":{"type":"integer","format":"int64"},"totalFare":{"type":"integer","format":"int64"},"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}}}},"Leg":{"type":"object","properties":{"mode":{"type":"string"},"distanceMeters":{"type":"integer","format":"int64"},"durationSeconds":{"type":"integer","format":"int64"},"routeName":{"type":"string"},"routeId":{"type":"string"},"routeColor":{"type":"string"},"routeType":{"type":"integer","format":"int32"},"start":{"$ref":"#/components/schemas/Stop"},"end":{"$ref":"#/components/schemas/Stop"},"path":{"type":"array","items":{"$ref":"#/components/schemas/RouteCoordinate"}},"stations":{"type":"array","items":{"$ref":"#/components/schemas/Stop"}}}},"Stop":{"type":"object","properties":{"name":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"stationId":{"type":"string"}}},"TransitRouteResponse":{"type":"object","properties":{"mode":{"type":"string","example":"transit"},"provider":{"type":"string","example":"tmap"},"itineraries":{"type":"array","items":{"$ref":"#/components/schemas/Itinerary"}}},"description":"TMAP 대중교통 추천 경로 목록"},"Step":{"type":"object","properties":{"instruction":{"type":"string","description":"보행 안내 문구"},"distanceMeters":{"minimum":0,"type":"integer","description":"구간 거리(m)","format":"int64"},"durationSeconds":{"minimum":0,"type":"integer","description":"구간 예상 소요시간(초)","format":"int64"},"path":{"type":"array","items":{"$ref":"#/components/schemas/RouteCoordinate"}}},"description":"공급자가 제공한 순서의 보행 구간 안내"},"WalkingRouteResponse":{"required":["distanceMeters","durationSeconds","mode","provider"],"type":"object","properties":{"mode":{"type":"string","example":"walk","enum":["walk"]},"provider":{"type":"string","example":"tmap","enum":["tmap"]},"distanceMeters":{"minimum":0,"type":"integer","description":"공급자가 계산한 총거리(m)","format":"int64"},"durationSeconds":{"minimum":0,"type":"integer","description":"예상 소요시간(초)","format":"int64"},"path":{"minItems":2,"type":"array","description":"출발→도착 순서의 전체 보행 경로","items":{"$ref":"#/components/schemas/RouteCoordinate"}},"steps":{"type":"array","description":"공급자가 제공한 순서의 보행 구간 안내","items":{"$ref":"#/components/schemas/Step"}}},"description":"TMAP 보행자 추천 경로"},"ReservationCreateRequest":{"required":["availabilityId","bookerName","bookerPhone","idempotencyKey"],"type":"object","properties":{"availabilityId":{"type":"integer","format":"int64"},"idempotencyKey":{"maxLength":100,"minLength":0,"type":"string"},"quantity":{"minimum":1,"type":"integer","format":"int32"},"bookerName":{"maxLength":100,"minLength":0,"type":"string"},"bookerPhone":{"maxLength":30,"minLength":0,"pattern":"^[0-9+()\\- ]+$","type":"string"},"requestNote":{"maxLength":500,"minLength":0,"type":"string"},"confirmationToken":{"maxLength":36,"minLength":36,"type":"string","description":"최신 견적의 확인 토큰. 생략하면 기존 터치 예약 계약이며 확인 조건 보장은 적용되지 않음","nullable":true}}},"ReservationConfirmation":{"required":["availabilityId","cancellable","cancellationDeadline","conditionsVersion","endsAt","expiresAt","placeId","placeName","quantity","startsAt","timezone"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"availabilityId":{"type":"integer","format":"int64"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"quantity":{"type":"integer","format":"int32"},"timezone":{"type":"string"},"cancellable":{"type":"boolean"},"cancellationDeadline":{"type":"string","format":"date-time","nullable":true},"conditionsVersion":{"type":"integer","format":"int64"},"expiresAt":{"type":"string","format":"date-time"}},"description":"사용자가 확인할 예약 대상·시간·인원·취소 조건","nullable":true},"ReservationResponse":{"required":["availabilityId","bookerName","bookerPhone","canceledAt","confirmation","confirmedAt","createdAt","id","quantity","requestNote","reservationEndsAt","reservationStartsAt","status","touristUserId","updatedAt"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"touristUserId":{"type":"integer","format":"int64"},"availabilityId":{"type":"integer","format":"int64"},"quantity":{"type":"integer","format":"int32"},"reservationStartsAt":{"type":"string","format":"date-time","nullable":true},"reservationEndsAt":{"type":"string","format":"date-time","nullable":true},"bookerName":{"type":"string","nullable":true},"bookerPhone":{"type":"string","nullable":true},"requestNote":{"type":"string","nullable":true},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"createdAt":{"type":"string","format":"date-time"},"confirmedAt":{"type":"string","description":"예약이 CONFIRMED 상태가 되기 전에는 null입니다.","format":"date-time","nullable":true},"reviewedBy":{"type":"integer","format":"int64"},"reviewedAt":{"type":"string","format":"date-time"},"reviewReason":{"type":"string"},"rejectedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","description":"예약이 CANCELED 상태가 되기 전에는 null입니다.","format":"date-time","nullable":true},"canceledBy":{"type":"integer","format":"int64"},"updatedAt":{"type":"string","format":"date-time"},"confirmation":{"description":"실제 수락한 확인 조건. 구버전 예약이면 null","nullable":true,"allOf":[{"$ref":"#/components/schemas/ReservationConfirmation"}]}},"description":"관광객 예약 응답"},"PlaceReviewCreateRequest":{"required":["content"],"type":"object","properties":{"recommendReason":{"maxLength":100,"minLength":0,"type":"string","description":"기존 단일 추천 이유. recommendReasons가 없을 때만 사용할 수 있습니다.","deprecated":true},"recommendReasons":{"maxItems":5,"minItems":1,"type":"array","description":"추천 이유 코드. 1~5개를 입력하며 저장·응답 순서가 유지됩니다.","items":{"type":"string","description":"추천 이유 코드. 1~5개를 입력하며 저장·응답 순서가 유지됩니다.","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"maxLength":2000,"minLength":0,"type":"string"},"reviewMediaIds":{"maxItems":3,"minItems":0,"type":"array","description":"리뷰 사진 업로드 API가 반환한 ID. 최대 3개이며 입력 순서가 사진 표시 순서입니다.","items":{"type":"integer","description":"리뷰 사진 업로드 API가 반환한 ID. 최대 3개이며 입력 순서가 사진 표시 순서입니다.","format":"int64"}},"imageUrls":{"maxItems":3,"minItems":0,"type":"array","description":"임의 URL 입력은 지원하지 않습니다. 빈 배열만 허용하며 reviewMediaIds를 사용해야 합니다.","deprecated":true,"items":{"type":"string","description":"임의 URL 입력은 지원하지 않습니다. 빈 배열만 허용하며 reviewMediaIds를 사용해야 합니다.","deprecated":true}}},"description":"장소 리뷰 작성 요청. recommendReasons와 reviewMediaIds가 새 표준 계약입니다."},"PlaceReviewMediaResponse":{"type":"object","properties":{"reviewMediaId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"contentType":{"type":"string"}},"description":"리뷰에 연결된 검증 완료 사진"},"PlaceReviewResponse":{"type":"object","properties":{"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"userId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"createdAt":{"type":"string","format":"date-time"}}},"PlaceReviewMediaUploadResponse":{"type":"object","properties":{"reviewMediaId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"expiresAt":{"type":"string","description":"리뷰 연결 전까지 유효한 시각","format":"date-time"}},"description":"리뷰 작성 전 임시 저장된 사진 업로드 결과"},"MapLinkConversionRequest":{"required":["linkType","provider","requestId"],"type":"object","properties":{"linkType":{"type":"string","description":"지도 링크 전환 유형","enum":["DIRECTIONS","EXTERNAL_MAP"]},"provider":{"maxLength":30,"minLength":0,"type":"string","description":"지도 제공자 (예: NAVER)","example":"NAVER"},"requestId":{"maxLength":128,"minLength":0,"type":"string","description":"같은 사용자·장소·전환 유형의 재시도에서 재사용하는 멱등성 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}}},"PlaceInformationReportCreateRequest":{"required":["reasonType","targetType"],"type":"object","properties":{"evidenceId":{"type":"integer","description":"신고 대상 증빙 ID","format":"int64","nullable":true},"targetType":{"type":"string","enum":["NAME","ADDRESS","GEOLOCATION","OPERATING_STATUS","TOURIST_INFORMATION","SOURCE_EVIDENCE","MEDIA","OTHER"]},"reasonType":{"type":"string","enum":["INCORRECT","OUTDATED","MISSING","MISLEADING","DUPLICATE","CLOSED_OR_MOVED","SPAM_OR_ABUSE","OTHER"]},"description":{"maxLength":1000,"minLength":1,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"type":"string","nullable":true}},"description":"장소 정보 신고 생성 요청"},"PlaceInformationDisputeResponse":{"type":"object","properties":{"disputeId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"disputedByUserId":{"type":"integer","format":"int64"},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"장소 정보 반박 응답"},"PlaceInformationReportResponse":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"evidenceId":{"type":"integer","format":"int64","nullable":true},"reporterUserId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["NAME","ADDRESS","GEOLOCATION","OPERATING_STATUS","TOURIST_INFORMATION","SOURCE_EVIDENCE","MEDIA","OTHER"]},"reasonType":{"type":"string","enum":["INCORRECT","OUTDATED","MISSING","MISLEADING","DUPLICATE","CLOSED_OR_MOVED","SPAM_OR_ABUSE","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"status":{"type":"string","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"resolvedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"disputes":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}},"description":"장소 정보 신고 응답"},"PlaceMediaCreateRequest":{"required":["s3Key"],"type":"object","properties":{"imageUrl":{"maxLength":500,"minLength":0,"type":"string","description":"호환성을 위해 수신하지만 서버는 검증된 s3Key로 URL을 생성합니다.","nullable":true},"s3Key":{"maxLength":500,"minLength":0,"type":"string"},"thumbnailUrl":{"maxLength":500,"minLength":0,"type":"string","nullable":true},"thumbnailS3Key":{"maxLength":500,"minLength":0,"type":"string","nullable":true},"displayOrder":{"type":"integer","format":"int32","nullable":true}},"description":"장소 탐색용 미디어 생성 요청"},"PlaceRecommendationClickRequest":{"required":["placeId","recommendationVersion","requestId"],"type":"object","properties":{"placeId":{"type":"integer","description":"클릭한 추천 장소 ID","format":"int64","example":17},"recommendationVersion":{"type":"string","description":"클릭한 추천 응답의 버전","example":"place-rec-v1"},"requestId":{"type":"string","description":"추천 응답 requestId","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}},"description":"추천 장소 클릭 기록 요청"},"PlaceRecommendationClickResponse":{"type":"object","properties":{"placeId":{"type":"integer","description":"클릭 기록이 저장된 장소 ID","format":"int64","example":17},"message":{"type":"string","description":"처리 결과 메시지","example":"추천 장소 클릭을 기록했습니다."}},"description":"추천 장소 클릭 기록 응답"},"PlaceInformationDisputeCreateRequest":{"type":"object","properties":{"description":{"maxLength":1000,"minLength":1,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"type":"string","nullable":true}},"description":"장소 정보 신고 반박 생성 요청"},"CouponResponse":{"required":["benefitDescription","code","expiresAt","id","issuedAt","offerId","offerTitle","placeId","placeName","redeemedAt","status"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"offerId":{"type":"integer","format":"int64","example":1},"offerTitle":{"type":"string","nullable":true,"example":"관광객 웰컴 음료"},"benefitDescription":{"type":"string","nullable":true,"example":"음료 1잔 무료"},"placeId":{"type":"integer","format":"int64","nullable":true,"example":1},"placeName":{"type":"string","nullable":true,"example":"핑덤 카페"},"code":{"type":"string","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},"status":{"type":"string","enum":["ISSUED","REDEEMED","EXPIRED"]},"issuedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"redeemedAt":{"type":"string","format":"date-time","nullable":true}}},"VerifiedBoostSelectionCreateRequest":{"required":["idempotencyKey","placeId","productId"],"type":"object","properties":{"productId":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":10},"idempotencyKey":{"maxLength":64,"minLength":0,"type":"string","example":"boost-select-20260726-001"}}},"VerifiedBoostSelectionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"productId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"selectedAt":{"type":"string","format":"date-time"}}},"VerifiedBoostExecutionStartRequest":{"required":["selectionId"],"type":"object","properties":{"selectionId":{"type":"integer","format":"int64","example":1}}},"VerifiedBoostExecutionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"selectionId":{"type":"integer","format":"int64"},"productId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["ACTIVE","STOPPED","EXPIRED"]},"startedAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"stoppedAt":{"type":"string","format":"date-time"}}},"PlaceReviewDeletionRequestCreateRequest":{"required":["requestReason"],"type":"object","properties":{"requestReason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantPlaceReviewDeletionRequestResponse":{"type":"object","properties":{"deletionRequestId":{"type":"integer","format":"int64"},"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reviewVisibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"requestedAt":{"type":"string","format":"date-time"}}},"PlaceOperatingNoticeCreateRequest":{"required":["expiresAt","message","noticeType","severity","startsAt"],"type":"object","properties":{"noticeType":{"type":"string","enum":["TEMPORARY_CLOSURE","HOURS_CHANGE","CROWDING","REOPENING","GENERAL"]},"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"message":{"maxLength":500,"minLength":0,"type":"string"},"startsAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}},"description":"상점 운영 상태 공지 생성 요청"},"PlaceOperatingNoticeResponse":{"required":["cancelReason","canceledAt","createdAt","expiredAt","expiresAt","id","message","noticeType","placeId","severity","startsAt","status","updatedAt","visibleNow"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"noticeType":{"type":"string","enum":["TEMPORARY_CLOSURE","HOURS_CHANGE","CROWDING","REOPENING","GENERAL"]},"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"status":{"type":"string","enum":["SCHEDULED","ACTIVE","EXPIRED","CANCELED"]},"message":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"expiredAt":{"type":"string","format":"date-time","nullable":true},"canceledAt":{"type":"string","format":"date-time","nullable":true},"cancelReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"visibleNow":{"type":"boolean"}},"description":"상점 운영 상태 공지 응답"},"PlaceOperatingNoticeCancelRequest":{"required":["cancelReason"],"type":"object","properties":{"cancelReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"상점 운영 상태 공지 취소 요청"},"PlaceMenuCreateRequest":{"required":["currency","displayOrder","name","priceAmount"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string"},"description":{"maxLength":500,"minLength":0,"type":"string"},"priceAmount":{"maximum":1000000000,"type":"integer","format":"int64"},"currency":{"type":"string","enum":["KRW","USD","JPY","CNY","EUR"]},"imageUrl":{"maxLength":500,"minLength":0,"type":"string","description":"기존 공개 미디어 URL. 없으면 null","nullable":true},"displayOrder":{"minimum":0,"type":"integer","format":"int32"}}},"PlaceMenuResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string","description":"메뉴 설명이 없으면 null","nullable":true},"priceAmount":{"type":"integer","format":"int64"},"currency":{"type":"string","description":"가격 통화. 금액은 해당 통화의 기본 단위로 저장","enum":["KRW","USD","JPY","CNY","EUR"]},"imageUrl":{"type":"string","description":"대표 이미지가 없으면 null","nullable":true},"status":{"type":"string","enum":["AVAILABLE","SOLD_OUT","HIDDEN","INACTIVE"]},"displayOrder":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"MerchantTeamInviteRequest":{"required":["inviteeUserId","role"],"type":"object","properties":{"inviteeUserId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["OWNER","MANAGER","STAFF"]},"expiresAt":{"type":"string","format":"date-time"}}},"MerchantTeamInvitationResponse":{"required":["createdAt","expiresAt","id","inviteeUserId","placeId","role","status"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"inviteeUserId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["OWNER","MANAGER","STAFF"]},"status":{"type":"string","enum":["PENDING","ACCEPTED","REVOKED","EXPIRED"]},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"Merchant 장소 팀원 초대 응답"},"MerchantOwnerMediaCreateRequest":{"required":["s3Key"],"type":"object","properties":{"s3Key":{"maxLength":500,"minLength":0,"type":"string","description":"업로드 URL 발급 응답의 s3Key"},"displayOrder":{"type":"integer","description":"미입력 시 현재 탐색 미디어 마지막 순서 다음으로 등록됩니다.","format":"int32","nullable":true}},"description":"업로드를 완료한 Merchant Owner 탐색 미디어 등록 요청"},"MerchantOwnerMediaUploadRequest":{"required":["contentType","fileName","fileSize"],"type":"object","properties":{"fileName":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"maximum":10485760,"type":"integer","format":"int64"}},"description":"Merchant Owner 탐색 미디어 업로드 URL 요청"},"MerchantOwnerMediaUploadResponse":{"type":"object","properties":{"uploadUrl":{"type":"string"},"imageUrl":{"type":"string"},"s3Key":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"description":"Merchant Owner 탐색 미디어 업로드 URL 응답"},"PlaceInformationReverificationResponseRequest":{"required":["responseNote"],"type":"object","properties":{"responseNote":{"maxLength":1000,"minLength":0,"type":"string"}}},"PlaceInformationReverificationResponse":{"type":"object","properties":{"requestId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["REQUESTED","RESPONDED","COMPLETED","CANCELED","EXPIRED"]},"reason":{"type":"string"},"requestedAt":{"type":"string","format":"date-time"},"dueAt":{"type":"string","format":"date-time"},"lastRemindedAt":{"type":"string","format":"date-time"},"reminderCount":{"type":"integer","format":"int32"},"respondedAt":{"type":"string","format":"date-time"},"responseNote":{"type":"string"},"completedAt":{"type":"string","format":"date-time"}}},"PaymentResponse":{"required":["amountMinor","createdAt","currency","failedAt","failureCode","id","paidAt","provider","providerPaymentId","refundedAt","reservationId","status"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reservationId":{"type":"integer","format":"int64"},"provider":{"type":"string"},"providerPaymentId":{"type":"string","description":"결제가 PAID 상태가 되기 전에는 null입니다.","nullable":true},"amountMinor":{"type":"integer","description":"결제가 성공하기 전에는 null입니다.","format":"int64","nullable":true},"currency":{"type":"string","description":"결제가 성공하기 전에는 null입니다.","nullable":true},"status":{"type":"string","enum":["PROCESSING","PAID","REFUND_PROCESSING","FAILED","REFUNDED"]},"failureCode":{"type":"string","description":"결제가 FAILED 상태일 때만 제공됩니다.","nullable":true},"createdAt":{"type":"string","format":"date-time"},"paidAt":{"type":"string","description":"결제가 PAID, REFUND_PROCESSING 또는 REFUNDED 상태가 되기 전에는 null입니다.","format":"date-time","nullable":true},"failedAt":{"type":"string","description":"결제가 FAILED 상태일 때만 제공됩니다.","format":"date-time","nullable":true},"refundedAt":{"type":"string","description":"결제가 REFUNDED 상태가 되기 전에는 null입니다.","format":"date-time","nullable":true}},"description":"관광객 결제 응답"},"OfferCreateRequest":{"required":["benefitDescription","couponValidityDays","description","endsAt","placeId","startsAt","title"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64","example":10},"title":{"maxLength":100,"minLength":1,"type":"string","example":"관광객 웰컴 음료"},"description":{"maxLength":1000,"minLength":1,"type":"string","example":"여행 중인 관광객에게 제공하는 한정 Offer입니다."},"benefitDescription":{"maxLength":500,"minLength":1,"type":"string","example":"음료 1잔 무료"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalQuantity":{"maximum":100000,"minimum":1,"type":"integer","description":"LIMITED 재고에서 필요한 발급 수량. UNLIMITED이면 생략합니다.","format":"int32","nullable":true,"example":100},"couponValidityDays":{"maximum":365,"minimum":1,"type":"integer","format":"int32","example":7},"eligibilityPolicy":{"type":"string","description":"쿠폰 발급 대상 정책. 생략하면 ACTIVE_TRAVEL_SCHEDULE입니다.","nullable":true,"enum":["ACTIVE_TRAVEL_SCHEDULE","PUBLIC"]},"inventoryPolicy":{"type":"string","description":"쿠폰 재고 정책. 생략하면 LIMITED입니다.","nullable":true,"enum":["LIMITED","UNLIMITED"]},"expiryPolicy":{"type":"string","description":"쿠폰 만료 정책. 생략하면 ISSUE_PLUS_DAYS_CAPPED_BY_OFFER_END입니다.","nullable":true,"enum":["ISSUE_PLUS_DAYS_CAPPED_BY_OFFER_END","ISSUE_PLUS_DAYS","OFFER_END"]}}},"OfferResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":10},"title":{"type":"string","example":"관광객 웰컴 음료"},"description":{"type":"string"},"benefitDescription":{"type":"string","example":"음료 1잔 무료"},"status":{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED"]},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalQuantity":{"type":"integer","description":"LIMITED 재고의 총 발급 수량. UNLIMITED이면 null","format":"int32","nullable":true},"issuedQuantity":{"type":"integer","format":"int32"},"remainingQuantity":{"type":"integer","description":"남은 발급 수량. UNLIMITED이면 null","format":"int32","nullable":true},"couponValidityDays":{"type":"integer","format":"int32"},"eligibilityPolicy":{"type":"string","enum":["ACTIVE_TRAVEL_SCHEDULE","PUBLIC"]},"inventoryPolicy":{"type":"string","enum":["LIMITED","UNLIMITED"]},"expiryPolicy":{"type":"string","enum":["ISSUE_PLUS_DAYS_CAPPED_BY_OFFER_END","ISSUE_PLUS_DAYS","OFFER_END"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CouponRedeemRequest":{"required":["code"],"type":"object","properties":{"code":{"pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$","type":"string","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}}},"MerchantTeamMemberResponse":{"required":["createdAt","id","placeId","role","status","updatedAt","userId"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"userId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["OWNER","MANAGER","STAFF"]},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Merchant 장소 팀원 응답"},"PopupCampaignCreateRequest":{"required":["brandId","description","endsAt","placeId","startsAt","title"],"type":"object","properties":{"brandId":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":10},"title":{"maxLength":150,"minLength":0,"type":"string","example":"성수 여름 팝업"},"description":{"maxLength":2000,"minLength":0,"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"}}},"PopupCampaignResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"brandId":{"type":"integer","format":"int64"},"brandName":{"type":"string"},"brandLogoUrl":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"title":{"type":"string"},"description":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"BrandCreateRequest":{"required":["name"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","example":"핑덤 스튜디오"},"description":{"maxLength":1000,"minLength":0,"type":"string","example":"지역 경험을 만드는 라이프스타일 브랜드"},"logoUrl":{"maxLength":500,"minLength":0,"type":"string","example":"https://cdn.example.com/brands/pingdom.png"}}},"BrandResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string"},"logoUrl":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"LocationCheckInRequest":{"required":["accuracyMeters","latitude","longitude","observedAt","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"accuracyMeters":{"minimum":0.0,"exclusiveMinimum":false,"type":"number","format":"double"},"observedAt":{"type":"string","format":"date-time"}}},"LocationCheckInResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"checkInDate":{"type":"string","format":"date"},"observedAt":{"type":"string","format":"date-time"},"recordedAt":{"type":"string","format":"date-time"},"distanceMeters":{"type":"number","format":"double"},"status":{"type":"string","enum":["PROXIMITY_MATCHED","DWELL_VERIFIED"]}}},"VisitEvidenceResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"locationCheckInId":{"type":"integer","format":"int64"},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}}},"FcmTokenRequest":{"required":["token"],"type":"object","properties":{"token":{"type":"string","description":"최신 기기 FCM 토큰","example":"fcm-device-token-sample"}},"description":"FCM 토큰 업데이트 요청"},"ConsultationIntroRequest":{"required":["message"],"type":"object","properties":{"message":{"maxLength":300,"minLength":0,"type":"string","description":"사용자가 입력한 첫 상담 질문","example":"작은 카페를 열고 싶은데 어떤 업종으로 시작하면 좋을까요?"}},"description":"첫 상담 안내 요청"},"ConsultationIntroResponse":{"type":"object","properties":{"message":{"type":"string","description":"사용자에게 표시할 첫 상담 안내문","example":"카페 창업을 고민하고 계시는군요. 먼저 관심 있는 업종을 선택해 주세요."},"source":{"type":"string","description":"안내문 생성 출처","example":"gemini","enum":["gemini","fallback"]}},"description":"첫 상담 안내 응답"},"CommunityPostCreateRequest":{"required":["categoryId","content","title"],"type":"object","properties":{"categoryId":{"maxLength":30,"minLength":0,"type":"string","description":"게시글 카테고리 식별자","example":"PLACE"},"title":{"maxLength":50,"minLength":0,"type":"string","description":"게시글 제목","example":"대소고 다녀왔어요"},"content":{"maxLength":5000,"minLength":0,"type":"string","description":"게시글 본문","example":"즐거운 경험이었습니다."},"placeIds":{"type":"array","description":"연결할 장소 ID 목록. 장소 카테고리에서는 1개 이상 필수입니다.","example":[1,2],"items":{"type":"integer","description":"연결할 장소 ID 목록. 장소 카테고리에서는 1개 이상 필수입니다.","format":"int64"}},"imageIds":{"maxItems":10,"minItems":0,"type":"array","description":"업로드한 본인 이미지 ID. 입력 순서대로 표시하며 최대 10장","items":{"type":"integer","description":"업로드한 본인 이미지 ID. 입력 순서대로 표시하며 최대 10장","format":"int64"}},"countryCode":{"pattern":"^[A-Z]{2}$","type":"string","description":"ISO 3166-1 alpha-2 국가 코드. 미설정은 null","example":"KR"},"region":{"maxLength":100,"minLength":0,"type":"string","description":"작성자가 지정한 표시 지역. 미설정은 null","example":"서울"}},"description":"커뮤니티 게시글 등록 요청"},"CommunityPostCreateResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"등록된 게시글 ID","format":"int64","example":1},"placeIds":{"type":"array","description":"연결된 장소 ID 목록","example":[1,2],"items":{"type":"integer","description":"연결된 장소 ID 목록","format":"int64"}}},"description":"커뮤니티 게시글 등록 응답"},"CommunityReportCreateRequest":{"required":["description","reason"],"type":"object","properties":{"reason":{"type":"string","description":"신고 사유","example":"SPAM","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"description":{"maxLength":500,"minLength":0,"type":"string","description":"상세 설명","example":"같은 광고를 반복 게시합니다."}},"description":"커뮤니티 신고 요청"},"CommunityReportCreateResponse":{"type":"object","properties":{"reportId":{"type":"integer","description":"신고 ID","format":"int64","example":1},"status":{"type":"string","description":"신고 처리 상태","example":"PENDING","enum":["PENDING","ACCEPTED","DECLINED"]}},"description":"커뮤니티 신고 접수 결과"},"MerchantOwnerPublicResponse":{"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"businessName":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string","nullable":true},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"}},"description":"장소에 연결된 Merchant Owner 공개 프로필","nullable":true},"PlaceDetailResponse":{"required":["activeOperatingNotices","address","communityViewCount","currentlyOperating","currentlyOperatingCheckedAt","description","englishName","geocodingSource","id","informationEvidenceUpdatedAt","informationVerificationStatus","informationVerifiedAt","jibunAddress","lastVerifiedAt","lastVerifiedSourceType","latitude","longitude","merchantOwner","name","operatingExceptions","operatingStatus","operatingStatusCheckedAt","postalCode","primaryInformationSource","registrant","regularHours","roadAddress","touristCategories","touristSummary","verifiedEvidenceCount"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"currentlyOperating":{"type":"boolean"},"currentlyOperatingCheckedAt":{"type":"string","description":"현재 영업 여부를 평가한 UTC 기준 시각. 영업 일정은 Asia/Seoul 기준으로 해석합니다.","format":"date-time"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"activeOperatingNotices":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}},"description":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"primaryInformationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"informationVerificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"informationVerifiedAt":{"type":"string","format":"date-time","nullable":true},"informationEvidenceUpdatedAt":{"type":"string","format":"date-time","nullable":true},"verifiedEvidenceCount":{"type":"integer","description":"검증 완료된 근거 수","format":"int32","example":3},"lastVerifiedAt":{"type":"string","description":"가장 최근 검증이 완료된 시각","format":"date-time","nullable":true},"lastVerifiedSourceType":{"type":"string","description":"가장 최근 검증 근거의 출처","nullable":true,"enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"latitude":{"maximum":90.0,"minimum":-90.0,"type":"number","format":"double"},"longitude":{"maximum":180.0,"minimum":-180.0,"type":"number","format":"double"},"registrant":{"type":"string"},"communityViewCount":{"type":"integer","description":"커뮤니티 게시글을 통해 유입된 일별 중복 제거 조회수","format":"int64","example":12},"merchantOwner":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/MerchantOwnerPublicResponse"}]}},"description":"장소 상세 조회 응답"},"CommunityPostLikeResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":1},"likeCount":{"type":"integer","description":"좋아요 수","format":"int64","example":12},"liked":{"type":"boolean","description":"현재 사용자의 좋아요 여부","example":true}},"description":"커뮤니티 게시글 좋아요 상태 응답"},"CommunityPostCommentCreateRequest":{"required":["content"],"type":"object","properties":{"content":{"maxLength":1000,"minLength":0,"type":"string","description":"댓글 내용","example":"저도 가보고 싶네요!"},"parentCommentId":{"type":"integer","description":"대댓글의 부모 댓글 ID. null은 최상위 댓글, 답글은 1단계만 지원","format":"int64"}},"description":"커뮤니티 게시글 댓글 등록 요청"},"CommunityPostCommentCreateResponse":{"type":"object","properties":{"commentId":{"type":"integer","description":"댓글 ID","format":"int64","example":1},"postId":{"type":"integer","description":"대상 게시글 ID","format":"int64","example":1},"content":{"type":"string","description":"저장된 댓글 내용","example":"저도 가보고 싶네요!"},"parentCommentId":{"type":"integer","description":"대댓글 부모 ID. 최상위 댓글이면 null","format":"int64"}},"description":"커뮤니티 게시글 댓글 등록 응답"},"CommunityImageUploadResponse":{"type":"object","properties":{"imageId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"description":"게시글에 연결할 이미지. 본인 미사용 이미지만 만료 전 1회 연결 가능"},"CommunityCommentLikeResponse":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"likeCount":{"type":"integer","format":"int64"},"liked":{"type":"boolean"}}},"RefreshTokenResponse":{"type":"object","properties":{"accessToken":{"type":"string","description":"새로 발급된 Access Token","example":"eyJhbGciOiJIUzI1NiJ9.new.access.token"}},"description":"토큰 재발급 응답"},"SignupRequest":{"required":["birthYear","country","email","language","password","username"],"type":"object","properties":{"username":{"maxLength":50,"minLength":4,"type":"string","description":"로그인에 사용할 아이디","example":"pingdom_user"},"email":{"type":"string","description":"이메일 인증을 받을 메일 주소","example":"pingdom@example.com"},"password":{"maxLength":2147483647,"minLength":8,"type":"string","description":"로그인 비밀번호","example":"securePass123!"},"birthYear":{"minimum":1900,"type":"integer","description":"출생 연도","format":"int32","nullable":true,"example":1998},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"},"language":{"maxLength":20,"minLength":0,"type":"string","description":"언어 코드 또는 언어명","example":"ko"},"country":{"maxLength":100,"minLength":0,"type":"string","description":"국가 코드 또는 국가명","example":"KR"}},"description":"회원가입 요청 정보"},"UserResponse":{"type":"object","properties":{"id":{"type":"integer","description":"생성된 사용자 ID","format":"int64","example":1},"username":{"type":"string","description":"생성된 사용자 아이디","example":"pingdom_user"},"email":{"type":"string","description":"생성된 사용자 이메일","example":"pingdom@example.com"},"birthYear":{"type":"integer","description":"출생 연도","format":"int32","example":1998},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"role":{"type":"string","description":"생성된 사용자 역할","example":"USER","enum":["USER","MERCHANT_OWNER","ADMIN"]}},"description":"회원가입 성공 응답"},"PasswordResetRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string","description":"비밀번호 재설정 메일을 받을 이메일 주소","example":"pingdom@example.com"}},"description":"비밀번호 재설정 토큰 발급 요청 정보"},"PasswordResetConfirmRequest":{"required":["confirmPassword","email","newPassword","token"],"type":"object","properties":{"email":{"type":"string","description":"비밀번호를 재설정할 이메일 주소","example":"pingdom@example.com"},"token":{"type":"string","description":"메일로 발급된 비밀번호 재설정 토큰"},"newPassword":{"maxLength":2147483647,"minLength":8,"type":"string","description":"변경할 새 비밀번호","example":"newSecurePass123!"},"confirmPassword":{"maxLength":2147483647,"minLength":8,"type":"string","description":"새 비밀번호 확인 입력","example":"newSecurePass123!"}},"description":"비밀번호 재설정 완료 요청 정보"},"LoginRequest":{"required":["password","username"],"type":"object","properties":{"username":{"maxLength":50,"minLength":4,"type":"string","description":"로그인에 사용할 아이디","example":"pingdom_user"},"password":{"maxLength":2147483647,"minLength":8,"type":"string","description":"로그인 비밀번호","example":"securePass123!"}},"description":"로그인 요청 정보"},"LoginResponse":{"type":"object","properties":{"id":{"type":"integer","description":"사용자 ID","format":"int64","example":1},"username":{"type":"string","description":"사용자 아이디","example":"pingdom_user"},"email":{"type":"string","description":"사용자 이메일","example":"pingdom@example.com"},"birthYear":{"type":"integer","description":"출생 연도","format":"int32","example":1998},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"message":{"type":"string","description":"로그인 결과 메시지","example":"로그인에 성공했습니다."},"accessToken":{"type":"string","description":"인증에 사용할 Access Token","example":"eyJhbGciOiJIUzI1NiJ9.access.token"},"role":{"type":"string","description":"현재 사용자 역할","example":"MERCHANT_OWNER","enum":["USER","MERCHANT_OWNER","ADMIN"]}},"description":"로그인 성공 응답"},"EmailVerifyRequest":{"required":["code","email"],"type":"object","properties":{"email":{"type":"string","description":"인증 대상 이메일 주소","example":"pingdom@example.com"},"code":{"type":"string","description":"이메일로 전달된 인증 코드","example":"123456"}},"description":"이메일 인증 요청 정보"},"EmailResendRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string","description":"인증 메일을 다시 받을 이메일 주소","example":"pingdom@example.com"}},"description":"이메일 인증 메일 재발송 요청 정보"},"LocationAnalysisRequest":{"required":["category","email","privacyConsent","region"],"type":"object","properties":{"region":{"type":"string","description":"희망 지역","example":"대구광역시 북구 서변동"},"category":{"type":"string","description":"가게 업종 또는 카테고리","example":"카페"},"targetCustomerGroup":{"type":"string","description":"주요 고객층(연령·성별)","example":"20~30대 여성"},"operatingHours":{"type":"string","description":"주요 영업 시간대","example":"평일 09:00~22:00"},"email":{"type":"string","description":"보고서 보관을 위한 이메일","example":"owner@example.com"},"privacyConsent":{"type":"boolean","description":"개인정보 수집·이용 동의 여부","example":true}}},"VisitorVerificationReportReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"VisitorVerificationReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"waitTimeMinutes":{"type":"integer","format":"int32"},"languageCode":{"type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"VisitorVerificationReportCorrectionReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"VisitorVerificationReportCorrectionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"requesterUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"waitTimeMinutes":{"type":"integer","format":"int32"},"languageCode":{"type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]},"reportStatus":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"VerifiedBoostProductCreateRequest":{"required":["description","durationDays","name","priceAmount"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","example":"Verified Boost 7일"},"description":{"maxLength":500,"minLength":0,"type":"string","example":"검증된 장소의 추천 노출을 7일간 강화합니다."},"priceAmount":{"type":"integer","description":"KRW 기준 가격","format":"int64","example":30000},"durationDays":{"maximum":365,"minimum":1,"type":"integer","format":"int32","example":7}}},"VerifiedBoostProductResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"name":{"type":"string"},"description":{"type":"string"},"priceAmount":{"type":"integer","description":"KRW 기준 가격","format":"int64","example":30000},"durationDays":{"type":"integer","format":"int32","example":7},"status":{"type":"string","enum":["DRAFT","ACTIVE","INACTIVE"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminRoleAssignmentRequest":{"required":["role"],"type":"object","properties":{"role":{"type":"string","description":"할당할 관리자 역할","example":"CONTENT_MODERATOR","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"역할을 부여하거나 회수하는 사유","example":"장소 정보 검수 담당 배정"}},"description":"관리자 역할 할당 요청"},"AdminRoleAssignmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"adminUserId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"assignedByUserId":{"type":"integer","format":"int64"},"assignedAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time"},"permissions":{"type":"array","items":{"type":"string","enum":["ADMIN_ROLE_MANAGE","USER_READ","USER_SANCTION","PLACE_READ","PLACE_MODERATE","MERCHANT_REVIEW","REPORT_REVIEW","SCOUT_REVIEW","DASHBOARD_READ","AUDIT_READ","OUTBOX_RECOVERY"]}}},"description":"관리자 역할 할당 응답"},"AdminTrustScoreInterventionEvaluationResponse":{"type":"object","properties":{"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":12},"trustScore":{"type":"integer","description":"현재 Trust Score","format":"int32","example":40},"matchedRuleId":{"type":"integer","description":"매칭된 규칙 ID","format":"int64","example":1},"matchedRuleName":{"type":"string","description":"매칭된 규칙 이름","example":"low trust temporary restriction"},"actionType":{"type":"string","description":"적용 액션","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"restrictedUntil":{"type":"string","description":"제한 만료 시각","format":"date-time"},"message":{"type":"string","description":"처리 결과 메시지","example":"Trust Score 개입 규칙을 적용했습니다."}}},"AdminTrustScoreBatchResponse":{"type":"object","properties":{"processedCount":{"type":"integer","format":"int32"},"changedCount":{"type":"integer","format":"int32"}}},"ScoutProfileReviewRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutActivityEligibilityReviewRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutActivityEligibilityGrantRequest":{"required":["eligibleFrom"],"type":"object","properties":{"eligibleFrom":{"type":"string","format":"date-time"},"eligibleUntil":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutFieldReportReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutFieldReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"scoutUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","CROWD_LEVEL","SAFETY","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ReservationReviewRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminReservationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"quantity":{"type":"integer","format":"int32"},"touristUserId":{"type":"integer","format":"int64"},"touristUsername":{"type":"string"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"merchantOwnerUsername":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"availabilityId":{"type":"integer","format":"int64"},"reservationStartsAt":{"type":"string","format":"date-time"},"reservationEndsAt":{"type":"string","format":"date-time"},"bookerName":{"type":"string"},"bookerPhone":{"type":"string"},"requestNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"confirmedAt":{"type":"string","format":"date-time"},"reviewedBy":{"type":"integer","format":"int64"},"reviewedAt":{"type":"string","format":"date-time"},"reviewReason":{"type":"string"},"rejectedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"canceledBy":{"type":"integer","format":"int64"},"statusHistory":{"type":"array","items":{"$ref":"#/components/schemas/AdminReservationStatusHistoryResponse"}}}},"AdminReservationStatusHistoryResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"changedBy":{"type":"integer","format":"int64"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}},"AdminReportAppealActionRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminReportAppealActionResponse":{"type":"object","properties":{"appealId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]},"processedAt":{"type":"string","format":"date-time"}}},"AdminPostReportBulkActionResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":10},"status":{"type":"string","description":"일괄 처리된 신고 상태","example":"ACCEPTED","enum":["PENDING","ACCEPTED","DECLINED","RESTORED"]},"processedReportCount":{"type":"integer","description":"처리된 신고 수","format":"int32","example":3},"visibilityStatus":{"type":"string","description":"게시글 공개 상태","example":"AUTO_HIDDEN","enum":["ACTIVE","AUTO_HIDDEN"]},"hiddenAt":{"type":"string","description":"게시글 숨김 처리 시각","format":"date-time"},"hiddenReason":{"type":"string","description":"게시글 숨김 사유","example":"REPORT_BULK_ACCEPTED"},"processedAt":{"type":"string","description":"신고 처리 시각","format":"date-time"}},"description":"관리자 게시글 단위 신고 일괄 처리 응답"},"S3OrphanReportStatus":{"type":"object","properties":{"reportId":{"type":"string"},"status":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"dbKeyCount":{"type":"integer","format":"int64"},"s3KeyCount":{"type":"integer","format":"int64"},"deleteCandidateCount":{"type":"integer","format":"int64"},"errorMessage":{"type":"string"}}},"PlaceInformationReverificationCreateRequest":{"required":["dueAt","reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"},"dueAt":{"type":"string","format":"date-time"}}},"AdminPlaceInformationEvidenceCreateRequest":{"required":["evidenceType","sourceType"],"type":"object","properties":{"sourceType":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"evidenceType":{"type":"string","enum":["EXTERNAL_PLACE_ID","BUSINESS_CLAIM","DOCUMENT","PHOTO","ADMIN_REVIEW","USER_VISIT","SYSTEM_SIGNAL"]},"externalReference":{"maxLength":100,"minLength":0,"type":"string","description":"외부 장소 ID, 사업자 등록 번호 등 외부 참조값","nullable":true},"referenceUrl":{"maxLength":500,"minLength":0,"type":"string","description":"증빙 URL","nullable":true},"description":{"maxLength":1000,"minLength":0,"type":"string","description":"관리자 메모 또는 증빙 설명","nullable":true},"submittedByUserId":{"type":"integer","description":"증빙 제출 사용자 ID. 미입력 시 관리자 ID를 사용","format":"int64","nullable":true}},"description":"관리자 장소 정보 증빙 등록 요청"},"AdminPlaceInformationEvidenceItem":{"type":"object","properties":{"evidenceId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"sourceType":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"evidenceType":{"type":"string","enum":["EXTERNAL_PLACE_ID","BUSINESS_CLAIM","DOCUMENT","PHOTO","ADMIN_REVIEW","USER_VISIT","SYSTEM_SIGNAL"]},"verificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"externalReference":{"type":"string","nullable":true},"referenceUrl":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"submittedByUserId":{"type":"integer","format":"int64","nullable":true},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"관리자 장소 정보 증빙 항목"},"AdminPlaceInformationEvidenceUpdateResponse":{"type":"object","properties":{"evidence":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceItem"},"message":{"type":"string"}},"description":"관리자 장소 정보 증빙 변경 응답"},"AdminPlaceRecommendationSnapshotResyncResponse":{"type":"object","properties":{"placeCount":{"type":"integer","format":"int64"},"synchronizedSnapshotCount":{"type":"integer","format":"int64"},"deletedSnapshotCount":{"type":"integer","format":"int64"},"synchronizedSimilaritySnapshotCount":{"type":"integer","format":"int64"},"deletedSimilaritySnapshotCount":{"type":"integer","format":"int64"},"synchronizedVersionSnapshotCount":{"type":"integer","format":"int64"},"deletedVersionSnapshotCount":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminMapPlaceMergeRequest":{"type":"object","properties":{"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"candidateId":{"type":"integer","format":"int64"}}},"AdminMapPlaceMergeResponse":{"type":"object","properties":{"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminPlaceMergeRestoreResponse":{"type":"object","properties":{"historyId":{"type":"integer","format":"int64"},"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminPlaceDuplicateDecisionRequest":{"required":["reviewNote"],"type":"object","properties":{"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminPlaceDuplicateCandidateResponse":{"type":"object","properties":{"candidateId":{"type":"integer","format":"int64"},"leftPlaceId":{"type":"integer","format":"int64"},"rightPlaceId":{"type":"integer","format":"int64"},"matchReason":{"type":"string"},"confidenceScore":{"type":"number"},"distanceMeters":{"type":"integer","format":"int32"},"status":{"type":"string"},"reviewedByAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"mergeHistoryId":{"type":"integer","format":"int64"},"detectedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminPlaceDuplicateMergeRequest":{"required":["targetPlaceId"],"type":"object","properties":{"targetPlaceId":{"type":"integer","format":"int64"}}},"PlaceReviewDeletionRequestReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminPlaceReviewDeletionRequestResponse":{"type":"object","properties":{"deletionRequestId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"requestReason":{"type":"string"},"requesterUserId":{"type":"integer","format":"int64"},"requestedAt":{"type":"string","format":"date-time"},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"reviewedAt":{"type":"string","format":"date-time"},"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reviewAuthorUserId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"reviewVisibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]},"reviewCreatedAt":{"type":"string","format":"date-time"}}},"PlaceInformationReportReviewRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","description":"UNDER_REVIEW, ACCEPTED, REJECTED, RESOLVED만 허용","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"관리자 장소 정보 신고 검토 요청"},"PlaceInformationDisputeReviewRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","description":"ACCEPTED 또는 REJECTED만 허용","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"관리자 장소 정보 반박 검토 요청"},"AdminPlaceEventRequest":{"required":["endAt","eventType","placeId","reason","startAt","title"],"type":"object","properties":{"placeId":{"type":"integer","description":"행사 장소 ID","format":"int64","example":17},"title":{"maxLength":150,"minLength":0,"type":"string","description":"이벤트 제목","example":"진주 여름 빛 축제"},"description":{"maxLength":1000,"minLength":0,"type":"string","description":"이벤트 설명","example":"남강을 배경으로 열리는 야간 공연과 전시입니다."},"eventType":{"type":"string","description":"이벤트 유형","example":"EXHIBITION","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","description":"시작 시각","format":"date-time"},"endAt":{"type":"string","description":"종료 시각","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"관리자 변경 사유","example":"공식 일정 등록"}},"description":"관리자 기간형 이벤트 등록·수정 요청"},"AdminPlaceEventResponse":{"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"publicationStatus":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]},"message":{"type":"string"}},"description":"관리자 기간형 이벤트 응답"},"AdminPlaceEventActionRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"변경 사유","example":"운영 검토를 완료했습니다."}},"description":"관리자 이벤트 상태 변경 요청"},"AdminOutboxEventRetryRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"장애 원인 제거와 중복 처리 안전성을 확인한 재처리 사유","example":"외부 메일 공급자 장애 복구 확인"}},"description":"관리자 Outbox 이벤트 재처리 요청"},"AdminOutboxEventItem":{"type":"object","properties":{"eventId":{"type":"string","description":"이벤트 ID"},"eventType":{"type":"string","description":"이벤트 유형","example":"EMAIL_VERIFICATION_REQUESTED","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"aggregateType":{"type":"string","description":"aggregate 유형","example":"USER"},"aggregateId":{"type":"string","description":"aggregate ID","example":"10"},"status":{"type":"string","description":"처리 상태","example":"FAILED","enum":["PENDING","PROCESSING","RETRY","SUCCEEDED","FAILED"]},"attemptCount":{"type":"integer","description":"현재 재시도 주기의 실패 횟수","format":"int32","example":5},"nextAttemptAt":{"type":"string","description":"다음 처리 가능 시각","format":"date-time"},"processingStartedAt":{"type":"string","description":"처리 선점 시각","format":"date-time"},"processedAt":{"type":"string","description":"처리 완료 시각","format":"date-time"},"lastError":{"type":"string","description":"마지막 실패 원인"},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}},"description":"관리자 Outbox 이벤트 운영 조회 항목"},"MerchantPlaceApplicationReviewRequest":{"required":["reviewedVersion"],"type":"object","properties":{"reviewedVersion":{"type":"integer","format":"int64"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerReviewRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminCommunityReportActionResponse":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"targetHidden":{"type":"boolean"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 처리 결과"},"BanRequest":{"type":"object","properties":{"reason":{"maxLength":255,"minLength":0,"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"expiresAt":{"type":"string","description":"기간 밴 종료 시각. 비우면 영구 밴으로 처리됩니다.","format":"date-time"},"durationDays":{"minimum":1,"type":"integer","description":"현재 시각부터 적용할 밴 기간(일). expiresAt과 동시에 사용할 수 없습니다.","format":"int64","example":7}},"description":"관리자 밴 처리 요청 정보"},"BanResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"밴 처리된 사용자 ID","format":"int64","example":7},"banned":{"type":"boolean","description":"밴 여부","example":true},"bannedAt":{"type":"string","description":"밴 처리 시각","format":"date-time"},"reason":{"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"banType":{"type":"string","description":"밴 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"}},"description":"관리자 밴 처리 응답"},"UnbanRequest":{"type":"object","properties":{"reason":{"maxLength":255,"minLength":0,"type":"string","description":"밴 해제 사유","example":"운영 검토 결과 해제"}},"description":"관리자 밴 해제 요청 정보"},"UnbanResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"밴 해제된 사용자 ID","format":"int64","example":7},"banned":{"type":"boolean","description":"현재 밴 여부","example":false},"releasedAt":{"type":"string","description":"밴 해제 처리 시각","format":"date-time"},"reason":{"type":"string","description":"밴 해제 사유","example":"운영 검토 결과 해제"}},"description":"관리자 밴 해제 응답"},"TravelScheduleUpdateRequest":{"required":["endDate","startDate"],"type":"object","properties":{"startDate":{"type":"string","description":"여행 시작일","format":"date","example":"2026-08-02"},"endDate":{"type":"string","description":"여행 종료일","format":"date","example":"2026-08-05"}},"description":"여행 일정 기간 변경 요청"},"NotificationSettingUpdateRequest":{"type":"object","properties":{"newHotplaceEnabled":{"type":"boolean","description":"핫플레이스 알림 수신 여부","example":true},"newLikeEnabled":{"type":"boolean","description":"좋아요 알림 수신 여부","example":false},"quietHoursEnabled":{"type":"boolean","description":"quiet hours 적용 여부","example":true},"quietHoursStart":{"type":"string","description":"quiet hours 시작 시각","format":"time","example":"22:00:00"},"quietHoursEnd":{"type":"string","description":"quiet hours 종료 시각","format":"time","example":"08:00:00"},"timezone":{"type":"string","description":"IANA timezone","example":"Asia/Seoul"}},"description":"알림 수신 설정 수정 요청"},"NotificationSettingResponse":{"type":"object","properties":{"newHotplaceEnabled":{"type":"boolean","description":"핫플레이스 알림 수신 여부","example":true},"newLikeEnabled":{"type":"boolean","description":"좋아요 알림 수신 여부","example":true},"quietHoursEnabled":{"type":"boolean","description":"quiet hours 적용 여부","example":false},"quietHoursStart":{"type":"string","description":"quiet hours 시작 시각","format":"time","example":"22:00:00"},"quietHoursEnd":{"type":"string","description":"quiet hours 종료 시각","format":"time","example":"08:00:00"},"timezone":{"type":"string","description":"IANA timezone","example":"Asia/Seoul"}},"description":"알림 수신 설정 응답"},"MerchantOwnerOperatingStatusUpdateRequest":{"required":["operatingStatus"],"type":"object","properties":{"operatingStatus":{"type":"string","example":"OPERATING","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]}},"description":"Merchant Owner 장소 운영 상태 변경 요청"},"MerchantOwnerOperatingResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time"},"currentlyOperating":{"type":"boolean"},"checkedAt":{"type":"string","description":"현재 영업 여부를 평가한 UTC 기준 시각","format":"date-time"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"informationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"verificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]}},"description":"Merchant Owner 장소 운영 정보 응답"},"PlaceOperatingNoticeUpdateRequest":{"required":["message","severity"],"type":"object","properties":{"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"message":{"maxLength":500,"minLength":0,"type":"string"}},"description":"상점 운영 상태 공지 수정 요청"},"PlaceMenuUpdateRequest":{"required":["currency","name","priceAmount"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string"},"description":{"maxLength":500,"minLength":0,"type":"string"},"priceAmount":{"maximum":1000000000,"type":"integer","format":"int64"},"currency":{"type":"string","enum":["KRW","USD","JPY","CNY","EUR"]},"imageUrl":{"maxLength":500,"minLength":0,"type":"string","description":"기존 공개 미디어 URL. 없으면 null","nullable":true}}},"PlaceMenuStatusRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","enum":["AVAILABLE","SOLD_OUT","HIDDEN","INACTIVE"]}}},"PlaceMenuOrderRequest":{"required":["displayOrder"],"type":"object","properties":{"displayOrder":{"minimum":0,"type":"integer","format":"int32"}}},"MerchantTeamRoleUpdateRequest":{"required":["role"],"type":"object","properties":{"role":{"type":"string","enum":["OWNER","MANAGER","STAFF"]}}},"MerchantOwnerMediaOrderUpdateRequest":{"type":"object","properties":{"displayOrder":{"type":"integer","description":"0부터 시작하는 이동 대상 위치입니다. 현재 탐색 미디어 개수보다 작은 값만 허용됩니다.","format":"int32","example":0}},"description":"Merchant Owner 탐색 미디어 순서 변경 요청"},"LocationAnalysisReportUpdateRequest":{"required":["email","reportName"],"type":"object","properties":{"reportName":{"type":"string"},"email":{"type":"string"}}},"LocationAnalysisReportResponse":{"type":"object","properties":{"reportId":{"type":"string"},"reportName":{"type":"string"},"category":{"type":"string"},"region":{"type":"string"},"targetCustomerGroup":{"type":"string"},"operatingHours":{"type":"string"},"email":{"type":"string"},"privacyConsent":{"type":"boolean"},"publishedDate":{"type":"string","format":"date"},"analysisBasisDate":{"type":"string","format":"date"},"createdAt":{"type":"string","format":"date-time"},"downloadPath":{"type":"string"},"htmlDebugPath":{"type":"string"}}},"AdminTrustScoreInterventionRuleToggleResponse":{"type":"object","properties":{"ruleId":{"type":"integer","description":"개입 규칙 ID","format":"int64","example":1},"enabled":{"type":"boolean","description":"활성화 여부","example":false},"message":{"type":"string","description":"처리 결과 메시지","example":"Trust Score 개입 규칙을 비활성화했습니다."}}},"AdminTrustScoreAnomalyResolveRequest":{"required":["resolutionReason"],"type":"object","properties":{"resolutionReason":{"maxLength":500,"minLength":0,"type":"string","description":"이상치 해결 사유","example":"관리자 검토 후 정상 패턴으로 확인했습니다."}}},"AdminTrustScoreAnomalyItem":{"type":"object","properties":{"id":{"type":"integer","description":"Trust Score 이상치 ID","format":"int64","example":1},"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":12},"reporterUsername":{"type":"string","description":"신고자 username","example":"ping-user"},"anomalyType":{"type":"string","description":"이상치 유형","example":"FALSE_REPORT_SPIKE","enum":["RAPID_DROP","FALSE_REPORT_SPIKE","LOW_ACCEPTANCE_RATE","MANUAL_REVIEW"]},"severity":{"type":"string","description":"이상치 심각도","example":"HIGH","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"baselineScore":{"type":"integer","description":"기준 Trust Score","format":"int32","example":100},"observedScore":{"type":"integer","description":"감지 시점 Trust Score","format":"int32","example":40},"submittedCount":{"type":"integer","description":"전체 신고 수","format":"int64","example":5},"acceptedCount":{"type":"integer","description":"수락 신고 수","format":"int64","example":1},"declinedCount":{"type":"integer","description":"거절 신고 수","format":"int64","example":4},"falseReportCount":{"type":"integer","description":"허위 신고 수","format":"int64","example":4},"detectedAt":{"type":"string","description":"감지 시각","format":"date-time"},"resolvedAt":{"type":"string","description":"해결 시각","format":"date-time"},"resolutionReason":{"type":"string","description":"해결 사유","example":"관리자 검토 완료"}},"description":"이상치 목록"},"AdminMapPlaceTouristInfoUpdateRequest":{"required":["reason"],"type":"object","properties":{"englishName":{"maxLength":150,"minLength":0,"type":"string","description":"영문 장소명. 공백 또는 null이면 제거합니다.","nullable":true,"example":"Jinju Castle"},"touristSummary":{"maxLength":500,"minLength":0,"type":"string","description":"관광객용 장소 요약. 공백 또는 null이면 제거합니다.","nullable":true},"touristCategories":{"maxItems":9,"minItems":0,"uniqueItems":true,"type":"array","description":"관광 목적 카테고리 전체 목록. 생략하면 모두 제거합니다.","items":{"type":"string","description":"관광 목적 카테고리 전체 목록. 생략하면 모두 제거합니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"영문 정보와 관광 분류 최신화"}},"description":"관리자 장소 관광 정보 전체 교체 요청"},"AdminMapPlaceTouristInfoUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"message":{"type":"string"}}},"AdminMapPlaceOperatingStatusUpdateRequest":{"required":["operatingStatus","reason"],"type":"object","properties":{"operatingStatus":{"type":"string","description":"확인된 장소 운영 상태","example":"TEMPORARILY_CLOSED","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 확인 근거","example":"현장 확인 결과 임시 휴업"}},"description":"관리자 장소 운영 상태 확인 요청"},"AdminMapPlaceOperatingStatusUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","description":"운영 상태 최신 확인 시각","format":"date-time"},"message":{"type":"string"}}},"AdminMapPlaceOperatingScheduleUpdateRequest":{"required":["reason"],"type":"object","properties":{"regularHours":{"uniqueItems":true,"type":"array","description":"요일별 정규 영업 시간대. 생략하면 모두 제거합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceRegularOperatingHourRequest"}},"exceptions":{"uniqueItems":true,"type":"array","description":"특정 날짜의 휴무 또는 대체 영업 일정. 생략하면 모두 제거합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingExceptionRequest"}},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"광복절 휴무와 주말 영업시간 반영"}},"description":"관리자 장소 정규 영업시간과 예외 일정 전체 교체 요청"},"AdminMapPlaceOperatingScheduleUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"exceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"message":{"type":"string"}}},"AdminMapPlaceKakaoPlaceIdUpdateRequest":{"type":"object","properties":{"kakaoPlaceId":{"maxLength":50,"minLength":0,"type":"string"}}},"AdminMapPlaceKakaoPlaceIdUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"kakaoPlaceId":{"type":"string"},"message":{"type":"string"}}},"AdminPlaceInformationEvidenceReviewRequest":{"required":["verificationStatus"],"type":"object","properties":{"verificationStatus":{"type":"string","description":"관리자 검토 결과. ADMIN_VERIFIED 또는 REJECTED만 허용","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string","description":"검토 사유. REJECTED일 때 필수","nullable":true}},"description":"관리자 장소 정보 증빙 검토 요청"},"AdminMapPlaceGeocodingUpdateRequest":{"required":["address","latitude","longitude","reason"],"type":"object","properties":{"address":{"maxLength":255,"minLength":0,"type":"string"},"roadAddress":{"maxLength":255,"minLength":0,"type":"string"},"jibunAddress":{"maxLength":255,"minLength":0,"type":"string"},"postalCode":{"maxLength":20,"minLength":0,"type":"string"},"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminMapPlaceGeocodingUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"address":{"type":"string"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"message":{"type":"string"}}},"AdminMapPlaceDiscoveryStatusUpdateRequest":{"required":["discoveryStatus","reason"],"type":"object","properties":{"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"HIDDEN","enum":["VISIBLE","HIDDEN"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"중복 장소 검수 전 임시 숨김"}},"description":"관리자 장소 탐색 노출 상태 수정 요청"},"AdminMapPlaceDiscoveryStatusUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"HIDDEN","enum":["VISIBLE","HIDDEN"]},"message":{"type":"string"}},"description":"관리자 장소 탐색 노출 상태 수정 응답"},"AdminMapPlaceCoordinateUpdateRequest":{"required":["latitude","longitude"],"type":"object","properties":{"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"}}},"AdminMapPlaceCoordinateUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"message":{"type":"string"}}},"AdminMapPlaceBasicInformationUpdateRequest":{"required":["category","name","reason"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","description":"수정할 장소명","example":"진주성"},"category":{"type":"string","description":"수정할 표준 장소 카테고리","example":"CULTURAL_HERITAGE","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"장소명과 분류 오등록 정정"}},"description":"관리자 장소 기본 정보 수정 요청"},"AdminMapPlaceBasicInformationUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"modifiedAt":{"type":"string","description":"감사 로그에 기록된 기본 정보 수정 시각","format":"date-time"},"message":{"type":"string"}},"description":"관리자 장소 기본 정보 수정 응답"},"AdminPlaceRecommendationTrafficUpdateItem":{"required":["recommendationVersion"],"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v2"},"trafficPercentage":{"maximum":100,"minimum":0,"type":"integer","description":"트래픽 비율","format":"int32","example":30},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"fallbackVersion":{"type":"string","description":"비활성화된 추천 버전 요청 시 대체할 버전","nullable":true,"example":"place-rec-v1"}},"description":"수정할 추천 버전별 트래픽 비율 목록"},"AdminPlaceRecommendationTrafficUpdateRequest":{"required":["policies","reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"추천 정책 변경 사유","example":"추천 실험 v2 트래픽을 확대합니다."},"policies":{"type":"array","description":"수정할 추천 버전별 트래픽 비율 목록","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateItem"}}}},"AdminPlaceRecommendationTrafficPolicyItem":{"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v1"},"stage":{"type":"string","description":"추천 단계","example":"STABLE"},"trafficPercentage":{"type":"integer","description":"트래픽 비율","format":"int32","example":70},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"fallbackVersion":{"type":"string","description":"비활성화 시 fallback 추천 버전","nullable":true,"example":"place-rec-v1"}},"description":"현재 추천 버전별 트래픽 정책"},"AdminPlaceRecommendationTrafficUpdateResponse":{"type":"object","properties":{"defaultVersion":{"type":"string","description":"기본 추천 버전","example":"place-rec-v1"},"policies":{"type":"array","description":"현재 추천 버전별 트래픽 정책","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficPolicyItem"}},"message":{"type":"string","description":"수정 결과 메시지","example":"추천 버전 트래픽 비율을 수정했습니다."}}},"AdminNotificationReadResponse":{"type":"object","properties":{"notificationId":{"type":"integer","description":"읽음 처리된 알림 ID","format":"int64","example":1},"read":{"type":"boolean","description":"읽음 여부","example":true},"message":{"type":"string","description":"처리 메시지","example":"알림을 읽음 처리했습니다."}},"description":"관리자 알림 읽음 처리 응답"},"AdminNotificationReadAllResponse":{"type":"object","properties":{"updatedCount":{"type":"integer","description":"읽음 처리된 알림 개수","format":"int64","example":3},"message":{"type":"string","description":"처리 메시지","example":"전체 알림을 읽음 처리했습니다."}},"description":"관리자 전체 알림 읽음 처리 응답"},"MyVisitorVerificationReportPageResponse":{"required":["hasNext","limit","page","reports","totalElements","totalPages"],"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/MyVisitorVerificationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"내 방문자 검증 제보 목록 페이지 응답"},"MyVisitorVerificationReportCorrectionPageResponse":{"required":["corrections","hasNext","limit","page","totalElements","totalPages"],"type":"object","properties":{"corrections":{"type":"array","items":{"$ref":"#/components/schemas/MyVisitorVerificationReportCorrectionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"내 방문자 검증 제보 정정 이력 페이지 응답"},"MyPageResponse":{"type":"object","properties":{"id":{"type":"integer","description":"사용자 ID","format":"int64","example":1},"username":{"type":"string","description":"사용자 아이디","example":"pingdom_user"},"email":{"type":"string","description":"사용자 이메일","example":"pingdom@example.com"},"birthYear":{"type":"integer","description":"출생 연도","format":"int32","example":1998},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"role":{"type":"string","description":"현재 사용자 역할","example":"MERCHANT_OWNER","enum":["USER","MERCHANT_OWNER","ADMIN"]}},"description":"내 정보 조회 응답"},"TravelScheduleListResponse":{"type":"object","properties":{"schedules":{"type":"array","description":"여행 일정 목록","items":{"$ref":"#/components/schemas/TravelScheduleResponse"}}},"description":"여행 일정 목록 응답"},"MyPlaceReviewPageResponse":{"type":"object","properties":{"reviews":{"type":"array","items":{"$ref":"#/components/schemas/MyPlaceReviewResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"내가 작성한 장소 리뷰 목록 페이지"},"MyPlaceReviewResponse":{"type":"object","properties":{"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"createdAt":{"type":"string","format":"date-time"},"visibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]}},"description":"내가 작성한 장소 리뷰"},"MerchantPlaceApplicationPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"NaverPlaceSearchItem":{"type":"object","properties":{"name":{"type":"string","description":"HTML 태그를 제거한 장소명","example":"네이버 본사"},"roadAddress":{"type":"string","description":"도로명 주소","example":"경기도 성남시 분당구 불정로 6"},"jibunAddress":{"type":"string","description":"지번 주소","example":"경기도 성남시 분당구 정자동 178-1"},"latitude":{"type":"number","description":"WGS84 위도","format":"double","example":37.3595963},"longitude":{"type":"number","description":"WGS84 경도","format":"double","example":127.1054328}},"description":"네이버 업체명 검색 후보"},"NaverPlaceSearchResponse":{"type":"object","properties":{"items":{"maxItems":5,"type":"array","description":"장소 검색 후보 목록. 검색 결과가 없으면 빈 목록입니다.","items":{"$ref":"#/components/schemas/NaverPlaceSearchItem"}}},"description":"신규 장소 등록용 네이버 업체명 검색 결과"},"NaverAddressSearchItem":{"type":"object","properties":{"roadAddress":{"type":"string","description":"도로명 주소","example":"경기도 성남시 분당구 불정로 6"},"jibunAddress":{"type":"string","description":"지번 주소","example":"경기도 성남시 분당구 정자동 178-1"},"postalCode":{"type":"string","description":"우편번호. 제공되지 않는 후보는 null입니다.","nullable":true,"example":"13561"},"latitude":{"type":"number","description":"WGS84 위도","format":"double","example":37.3595963},"longitude":{"type":"number","description":"WGS84 경도","format":"double","example":127.1054328}},"description":"네이버 주소 검색 후보"},"NaverAddressSearchResponse":{"type":"object","properties":{"items":{"maxItems":10,"type":"array","description":"주소 검색 후보 목록. 검색 결과가 없으면 빈 목록입니다.","items":{"$ref":"#/components/schemas/NaverAddressSearchItem"}}},"description":"신규 장소 등록용 네이버 주소 검색 결과"},"ExportBookmarkResponse":{"type":"object","properties":{"id":{"type":"integer","description":"북마크 ID","format":"int64","example":10},"placeId":{"type":"integer","description":"북마크 대상 장소 ID","format":"int64","example":123}},"description":"사용자 북마크 전체 목록"},"ExportCurrentActivityIntentResponse":{"type":"object","properties":{"intent":{"type":"string","description":"현재 행동 의도","example":"CAFE","enum":["EXPLORE","EAT","CAFE","SHOP","ATTEND_EVENT","NIGHTLIFE"]},"expiresAt":{"type":"string","description":"행동 의도 만료 시각","format":"date-time"}},"description":"만료되지 않은 현재 행동 의도. 없으면 null","nullable":true},"ExportMerchantOwnerProfileResponse":{"type":"object","properties":{"businessName":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string","nullable":true},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]},"placeIds":{"type":"array","items":{"type":"integer","format":"int64"}}},"description":"Merchant Owner 신청 및 프로필. 없으면 null","nullable":true},"ExportMerchantVerificationResponse":{"type":"object","properties":{"legalName":{"type":"string"},"businessName":{"type":"string"},"businessRegistrationNumber":{"type":"string"},"identityStatus":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"businessStatus":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true}},"description":"Merchant 신원 및 사업자 검증 신청. 없으면 null","nullable":true},"ExportTouristCouponResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"offerId":{"type":"integer","format":"int64"},"code":{"type":"string"},"status":{"type":"string","enum":["ISSUED","REDEEMED","EXPIRED"]},"issuedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"redeemedAt":{"type":"string","format":"date-time","nullable":true}},"description":"사용자가 발급받은 관광객 Coupon 이력"},"ExportTouristOfferResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"title":{"type":"string"},"description":{"type":"string"},"benefitDescription":{"type":"string"},"status":{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED"]},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalQuantity":{"type":"integer","format":"int32"},"issuedQuantity":{"type":"integer","format":"int32"},"couponValidityDays":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Merchant Owner가 만든 관광객 전용 Offer 이력"},"ExportTravelScheduleResponse":{"type":"object","properties":{"id":{"type":"integer","description":"여행 일정 ID","format":"int64","example":1},"startDate":{"type":"string","description":"여행 시작일","format":"date","example":"2026-08-01"},"endDate":{"type":"string","description":"여행 종료일","format":"date","example":"2026-08-04"},"state":{"type":"string","description":"저장된 일정 상태","example":"SCHEDULED","enum":["SCHEDULED","CANCELLED"]}},"description":"사용자 여행 일정 목록"},"ExportUserResponse":{"type":"object","properties":{"id":{"type":"integer","description":"사용자 ID","format":"int64","example":1},"username":{"type":"string","description":"사용자 아이디","example":"pingdom_user"},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"}},"description":"사용자 기본 정보"},"UserDataExportResponse":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/ExportUserResponse"},"bookmarks":{"type":"array","description":"사용자 북마크 전체 목록","items":{"$ref":"#/components/schemas/ExportBookmarkResponse"}},"likedMapImageIds":{"type":"array","description":"최근 좋아요한 지도 이미지 ID 목록. 최대 50개","items":{"type":"integer","description":"최근 좋아요한 지도 이미지 ID 목록. 최대 50개","format":"int64"}},"travelSchedules":{"type":"array","description":"사용자 여행 일정 목록","items":{"$ref":"#/components/schemas/ExportTravelScheduleResponse"}},"currentActivityIntent":{"$ref":"#/components/schemas/ExportCurrentActivityIntentResponse"},"merchantOwnerProfile":{"$ref":"#/components/schemas/ExportMerchantOwnerProfileResponse"},"merchantVerification":{"$ref":"#/components/schemas/ExportMerchantVerificationResponse"},"touristOffers":{"type":"array","description":"Merchant Owner가 만든 관광객 전용 Offer 이력","items":{"$ref":"#/components/schemas/ExportTouristOfferResponse"}},"touristCoupons":{"type":"array","description":"사용자가 발급받은 관광객 Coupon 이력","items":{"$ref":"#/components/schemas/ExportTouristCouponResponse"}}},"description":"사용자 데이터 내보내기 응답"},"MyScoutFieldReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"ReservationPageResponse":{"type":"object","properties":{"reservations":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PublicPopupCampaignPageResponse":{"required":["hasNext","items","limit","page","totalCount","totalPages"],"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PublicPopupCampaignResponse"}},"page":{"type":"integer","format":"int32","example":1},"limit":{"type":"integer","format":"int32","example":20},"totalCount":{"type":"integer","format":"int64","example":42},"totalPages":{"type":"integer","format":"int32","example":3},"hasNext":{"type":"boolean","example":true}},"description":"진행 중인 공개 팝업 캠페인 목록 응답"},"PublicPopupCampaignResponse":{"required":["brandId","brandLogoUrl","brandName","createdAt","description","endsAt","id","placeId","startsAt","status","title","updatedAt"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"brandId":{"type":"integer","format":"int64","example":10},"brandName":{"type":"string","example":"진주문화재단"},"brandLogoUrl":{"type":"string","nullable":true,"example":"https://cdn.pingdom.com/brands/jinju.png"},"placeId":{"type":"integer","format":"int64","example":101},"title":{"type":"string","example":"진주 여름 팝업"},"description":{"type":"string","example":"남강변에서 진행하는 여름 체험형 팝업입니다."},"startsAt":{"type":"string","format":"date-time","example":"2026-08-01T00:00:00Z"},"endsAt":{"type":"string","format":"date-time","example":"2026-08-08T00:00:00Z"},"status":{"type":"string","example":"PUBLISHED","enum":["PUBLISHED"]},"createdAt":{"type":"string","format":"date-time","example":"2026-07-20T00:00:00Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-07-21T00:00:00Z"}},"description":"진행 중인 공개 팝업 캠페인 응답"},"PlaceListItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"category":{"type":"string"},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"primaryInformationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"informationVerificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"informationVerifiedAt":{"type":"string","format":"date-time","nullable":true},"informationEvidenceUpdatedAt":{"type":"string","format":"date-time","nullable":true},"verifiedEvidenceCount":{"type":"integer","description":"검증 완료된 근거 수","format":"int32","example":3},"lastVerifiedAt":{"type":"string","description":"가장 최근 검증이 완료된 시각","format":"date-time","nullable":true},"lastVerifiedSourceType":{"type":"string","description":"가장 최근 검증 근거의 출처","nullable":true,"enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"distanceMeters":{"type":"integer","format":"int64"}}},"PlaceListResponse":{"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/PlaceListItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}},"description":"장소 목록 조회 응답"},"OfferPageResponse":{"type":"object","properties":{"offers":{"type":"array","items":{"$ref":"#/components/schemas/OfferResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PlaceVisitDecisionEventResponse":{"required":["description","endAt","eventId","eventType","scheduleStatus","startAt","title"],"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]}},"description":"방문 결정 화면에 노출하는 진행 중 장소 이벤트"},"PlaceVisitDecisionMerchantInformationResponse":{"required":["contactPhone","description","reservationUrl","updatedAt","websiteUrl"],"type":"object","properties":{"description":{"type":"string","nullable":true},"contactPhone":{"type":"string","nullable":true},"websiteUrl":{"type":"string","nullable":true},"reservationUrl":{"type":"string","nullable":true},"updatedAt":{"type":"string","format":"date-time"}},"description":"관광객에게 공개하는 Merchant 장소 안내 정보","nullable":true},"PlaceVisitDecisionResponse":{"required":["availableOffers","checkedAt","merchantInformation","ongoingEvents","place","reservableAvailabilities"],"type":"object","properties":{"place":{"$ref":"#/components/schemas/PlaceDetailResponse"},"merchantInformation":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/PlaceVisitDecisionMerchantInformationResponse"}]},"ongoingEvents":{"type":"array","items":{"$ref":"#/components/schemas/PlaceVisitDecisionEventResponse"}},"reservableAvailabilities":{"type":"array","items":{"$ref":"#/components/schemas/AvailabilityResponse"}},"availableOffers":{"$ref":"#/components/schemas/OfferPageResponse"},"checkedAt":{"type":"string","description":"응답의 상태성 데이터를 조회한 시각","format":"date-time"}},"description":"관광객 장소 상세 방문 결정 화면 응답"},"PagePlaceReviewResponse":{"type":"object","properties":{"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"pageable":{"$ref":"#/components/schemas/PageableObject"},"numberOfElements":{"type":"integer","format":"int32"},"first":{"type":"boolean"},"last":{"type":"boolean"},"empty":{"type":"boolean"}}},"PageableObject":{"type":"object","properties":{"offset":{"type":"integer","format":"int64"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"paged":{"type":"boolean"},"pageNumber":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"unpaged":{"type":"boolean"}}},"SortObject":{"type":"object","properties":{"direction":{"type":"string"},"nullHandling":{"type":"string"},"ascending":{"type":"boolean"},"property":{"type":"string"},"ignoreCase":{"type":"boolean"}}},"PlaceOperatingNoticeListResponse":{"required":["checkedAt","currentlyOperating","notices","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"currentlyOperating":{"type":"boolean"},"checkedAt":{"type":"string","description":"현재 영업 여부와 공지 노출 상태를 평가한 UTC 기준 시각","format":"date-time"},"notices":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}},"description":"상점 운영 상태 공지 목록 응답"},"MenuConvertedPriceResponse":{"type":"object","properties":{"amount":{"type":"number","description":"환산 금액. 실제 결제 기준은 메뉴의 원래 금액과 통화입니다.","example":6.43},"currency":{"type":"string","description":"환산 통화","example":"USD","enum":["KRW","USD","JPY","CNY","EUR"]},"rateDate":{"type":"string","description":"환산에 사용한 환율 기준 일자","format":"date","example":"2026-09-10"}},"description":"사용자 표시 통화로 환산한 메뉴 참고 가격","nullable":true},"PlaceMenuPublicResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string","description":"메뉴 설명이 없으면 null","nullable":true},"priceAmount":{"type":"integer","description":"원래 메뉴 가격. 환산 가격과 무관하게 항상 유지됩니다.","format":"int64","example":9000},"currency":{"type":"string","description":"원래 메뉴 가격의 통화. 실제 결제 기준 통화입니다.","example":"KRW","enum":["KRW","USD","JPY","CNY","EUR"]},"imageUrl":{"type":"string","description":"대표 이미지가 없으면 null","nullable":true},"status":{"type":"string","enum":["AVAILABLE","SOLD_OUT","HIDDEN","INACTIVE"]},"displayOrder":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"convertedPrice":{"$ref":"#/components/schemas/MenuConvertedPriceResponse"}},"description":"관광객용 장소 메뉴 응답"},"TouristPlaceCardResponse":{"required":["address","category","currentlyOperating","currentlyOperatingCheckedAt","englishName","geocodingSource","id","imageUrl","informationEvidenceUpdatedAt","informationVerificationStatus","informationVerifiedAt","lastVerifiedAt","lastVerifiedSourceType","latitude","longitude","name","operatingStatus","primaryInformationSource","roadAddress","touristCategories","touristSummary","verifiedEvidenceCount"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"currentlyOperating":{"type":"boolean"},"currentlyOperatingCheckedAt":{"type":"string","description":"현재 영업 여부를 평가한 UTC 기준 시각. 영업 일정은 Asia/Seoul 기준으로 해석합니다.","format":"date-time"},"category":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"primaryInformationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"informationVerificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"informationVerifiedAt":{"type":"string","format":"date-time","nullable":true},"informationEvidenceUpdatedAt":{"type":"string","format":"date-time","nullable":true},"verifiedEvidenceCount":{"type":"integer","description":"검증 완료된 근거 수","format":"int32","example":3},"lastVerifiedAt":{"type":"string","description":"가장 최근 검증이 완료된 시각","format":"date-time","nullable":true},"lastVerifiedSourceType":{"type":"string","description":"가장 최근 검증 근거의 출처","nullable":true,"enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"latitude":{"maximum":90.0,"minimum":-90.0,"type":"number","format":"double"},"longitude":{"maximum":180.0,"minimum":-180.0,"type":"number","format":"double"}},"description":"관광객용 장소 카드 조회 응답"},"ReservationQuoteResponse":{"required":["confirmation","confirmationToken","remainingCapacity"],"type":"object","properties":{"confirmationToken":{"type":"string","description":"본인 예약 생성에만 사용 가능한 불투명 토큰. 같은 토큰은 하나의 예약 의도에만 사용"},"confirmation":{"$ref":"#/components/schemas/ReservationConfirmation"},"remainingCapacity":{"type":"integer","format":"int32"}}},"PlaceMediaResponse":{"required":["media","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"media":{"type":"array","items":{"$ref":"#/components/schemas/PlaceMediaItem"}}},"description":"장소 미디어 목록 응답"},"Item":{"type":"object","properties":{"rank":{"type":"integer","format":"int32"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"category":{"type":"string"},"imageUrl":{"type":"string"},"address":{"type":"string"},"bookmarkAdds":{"type":"integer","format":"int64"},"bookmarkRemoves":{"type":"integer","format":"int64"},"netBookmarkGrowth":{"type":"integer","format":"int64"},"bookmarkCount":{"type":"integer","format":"int64"},"bookmarked":{"type":"boolean"}}},"PlaceTrendResponse":{"type":"object","properties":{"scope":{"type":"string"},"period":{"type":"string","enum":["WEEK"]},"periodStart":{"type":"string","format":"date-time"},"periodEnd":{"type":"string","format":"date-time"},"generatedAt":{"type":"string","format":"date-time"},"places":{"type":"array","items":{"$ref":"#/components/schemas/Item"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PlaceGrowthSnapshot":{"type":"object","properties":{"photoCount":{"type":"integer","format":"int64"},"level":{"type":"integer","format":"int32"},"currentLevelMinPhotoCount":{"type":"integer","format":"int64"},"nextLevelMinPhotoCount":{"type":"integer","format":"int64"},"progressPercent":{"type":"integer","format":"int32"}}},"PlaceRecommendationItem":{"type":"object","properties":{"id":{"type":"integer","description":"장소 ID","format":"int64","example":5},"name":{"type":"string","description":"장소명","example":"진주성"},"address":{"type":"string","description":"장소 주소","example":"경상남도 진주시 남강로 626"},"roadAddress":{"type":"string","description":"도로명 주소","nullable":true},"jibunAddress":{"type":"string","description":"지번 주소","nullable":true},"postalCode":{"type":"string","description":"우편번호","nullable":true},"geocodingSource":{"type":"string","description":"주소 및 좌표 생성 출처","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","description":"장소 운영 상태","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","description":"운영 상태 최신 확인 시각","format":"date-time","nullable":true},"currentlyOperating":{"type":"boolean","description":"현재 영업 여부. 영업시간 미등록 시 null","nullable":true},"currentlyOperatingCheckedAt":{"type":"string","description":"현재 영업 여부를 평가한 UTC 기준 시각. 영업 일정은 Asia/Seoul 기준으로 해석합니다.","format":"date-time","nullable":true},"latitude":{"type":"number","description":"장소 위도","format":"double","example":35.1894},"longitude":{"type":"number","description":"장소 경도","format":"double","example":128.0789},"distanceMeters":{"type":"integer","description":"현재 위치와의 거리(미터)","format":"int64","example":215},"reason":{"type":"string","description":"추천 사유","example":"저장한 장소와 가까운 추천 장소입니다."},"reasonCode":{"type":"string","description":"추천 사유 코드","example":"PERSONAL_SIGNAL","enum":["BENEFIT_AND_RESERVABLE","ACTIVE_BENEFIT","RESERVABLE","CONTEXT_MATCH","PERSONAL_SIGNAL","FRESH_CONTENT","HIGH_ENGAGEMENT","HIGH_CONVERSION","EXPLORATION","QUALITY_SIGNAL","NEARBY"]},"hasActiveBenefit":{"type":"boolean","description":"현재 발급 가능한 관광 혜택 존재 여부"},"reservable":{"type":"boolean","description":"현재 예약 가능한 시간 존재 여부"},"boosted":{"type":"boolean","description":"Verified Boost가 적용된 추천 여부"},"placeGrowth":{"$ref":"#/components/schemas/PlaceGrowthSnapshot"}},"description":"장소 추천 항목"},"PlaceRecommendationResponse":{"type":"object","properties":{"places":{"type":"array","description":"추천 장소 목록","items":{"$ref":"#/components/schemas/PlaceRecommendationItem"}},"recommendationVersion":{"type":"string","description":"추천 알고리즘 버전","example":"place-rec-v1"},"recommendationRequestId":{"type":"string","description":"추천 요청 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"limit":{"type":"integer","description":"요청 제한 수","format":"int32","example":10},"requestedRadiusKm":{"type":"number","description":"요청 반경(km)","format":"double","example":5.0},"appliedRadiusKm":{"type":"number","description":"실제 적용 반경(km)","format":"double","example":10.0},"recommendedCount":{"type":"integer","description":"추천 결과 수","format":"int32","example":4},"appliedTravelPurposes":{"uniqueItems":true,"type":"array","description":"추천에 적용된 K-컬처 및 여행 관심사","items":{"type":"string","description":"추천에 적용된 K-컬처 및 여행 관심사","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"appliedActivityIntent":{"type":"string","description":"추천에 적용된 현재 행동 의도","nullable":true,"example":"CAFE","enum":["EXPLORE","EAT","CAFE","SHOP","ATTEND_EVENT","NIGHTLIFE"]},"limitReasons":{"type":"array","description":"추천 결과에 영향을 준 제한 사유 코드","items":{"type":"string","description":"추천 결과에 영향을 준 제한 사유 코드","enum":["REQUEST_LIMIT_CLAMPED","RADIUS_EXPANDED","OPERATING_STATUS_PRIORITY","INTERACTED_PLACE_EXCLUDED","FALLBACK_CANDIDATE_POOL"]}}},"description":"장소 추천 조회 응답"},"PlaceRecommendationExplanationItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":1},"placeName":{"type":"string","description":"장소명","example":"진주성"},"ranking":{"type":"integer","description":"노출 순위","format":"int32","example":1},"source":{"type":"string","description":"후보 소스","example":"PERSONAL","enum":["PERSONAL","POPULAR","FRESH","GEO","FALLBACK"]},"distanceMeters":{"type":"integer","description":"거리(m)","format":"int64","example":128},"geoScore":{"type":"number","description":"geo score","format":"double","example":0.91},"personalScore":{"type":"number","description":"personal score","format":"double","example":0.42},"qualityScore":{"type":"number","description":"quality score","format":"double","example":0.37},"engagementScore":{"type":"number","description":"engagement score","format":"double","example":0.25},"conversionScore":{"type":"number","description":"conversion score","format":"double","example":0.14},"explorationScore":{"type":"number","description":"exploration score","format":"double","example":0.08},"freshnessScore":{"type":"number","description":"freshness score","format":"double","example":0.19},"trustScore":{"type":"number","description":"검증 제보자 신뢰도 기반 score","format":"double","example":0.82},"contextScore":{"type":"number","description":"K-컬처 관심사와 현재 여행 맥락 기반 score","format":"double","example":0.25},"benefitScore":{"type":"number","description":"현재 이용 가능한 혜택 기반 boost","format":"double","example":0.05},"availabilityScore":{"type":"number","description":"예약 가능 시간 기반 boost","format":"double","example":0.05},"boostScore":{"type":"number","description":"Verified Boost 집행 기반 score","format":"double","example":0.08},"finalScore":{"type":"number","description":"최종 score","format":"double","example":0.74}},"description":"추천 설명 항목"},"PlaceRecommendationExplanationResponse":{"type":"object","properties":{"requestId":{"type":"string","description":"추천 요청 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"items":{"type":"array","description":"추천 설명 항목","items":{"$ref":"#/components/schemas/PlaceRecommendationExplanationItem"}}},"description":"추천 설명 조회 응답"},"NearbyReservablePlaceItem":{"required":["address","availabilityId","availableEndsAt","availableStartsAt","category","distanceMeters","imageUrl","latitude","longitude","name","placeId","remainingCapacity"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64","example":70069},"name":{"type":"string","example":"이월드"},"category":{"type":"string","nullable":true,"example":"테마파크"},"latitude":{"type":"number","format":"double","example":35.8532},"longitude":{"type":"number","format":"double","example":128.5638},"address":{"type":"string","nullable":true,"example":"대구광역시 달서구 두류공원로 200"},"imageUrl":{"type":"string","nullable":true},"distanceMeters":{"type":"integer","format":"int64","example":430},"availabilityId":{"type":"integer","format":"int64","example":77},"availableStartsAt":{"type":"string","format":"date-time"},"availableEndsAt":{"type":"string","format":"date-time"},"remainingCapacity":{"type":"integer","format":"int32","example":42}},"description":"현재 위치 주변 예약 가능 장소 요약"},"NearbyReservablePlaceResponse":{"required":["hasNext","limit","page","places","queriedAt","totalElements","totalPages"],"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/NearbyReservablePlaceItem"}},"page":{"type":"integer","format":"int32","example":1},"limit":{"type":"integer","format":"int32","example":20},"totalElements":{"type":"integer","format":"int64","example":42},"totalPages":{"type":"integer","format":"int32","example":3},"hasNext":{"type":"boolean","example":true},"queriedAt":{"type":"string","format":"date-time"}},"description":"현재 위치 주변 예약 가능 장소 페이지 응답"},"MapClusterItem":{"required":["clusterId","latitude","longitude","placeCount"],"type":"object","properties":{"clusterId":{"type":"string"},"latitude":{"maximum":90.0,"minimum":-90.0,"type":"number","format":"double"},"longitude":{"maximum":180.0,"minimum":-180.0,"type":"number","format":"double"},"placeCount":{"type":"integer","format":"int64"}}},"MapMarkerItem":{"required":["category","imageUrl","latitude","longitude","name","photoCount","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"category":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"latitude":{"maximum":90.0,"minimum":-90.0,"type":"number","format":"double"},"longitude":{"maximum":180.0,"minimum":-180.0,"type":"number","format":"double"},"photoCount":{"type":"integer","format":"int64"}}},"MapViewportResponse":{"required":["clusters","markers","mode","truncated","zoom"],"type":"object","properties":{"mode":{"type":"string","description":"zoom에 따른 응답 표현 방식","enum":["MARKERS","CLUSTERS"]},"zoom":{"maximum":20,"minimum":0,"type":"integer","description":"요청한 지도 zoom 단계","format":"int32"},"clusters":{"type":"array","items":{"$ref":"#/components/schemas/MapClusterItem"}},"markers":{"type":"array","items":{"$ref":"#/components/schemas/MapMarkerItem"}},"truncated":{"type":"boolean","description":"최대 500개 결과로 잘렸는지 여부"}}},"PlaceLocalHotResponse":{"type":"object","properties":{"region":{"$ref":"#/components/schemas/Region"},"places":{"type":"array","items":{"$ref":"#/components/schemas/Item"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"Region":{"type":"object","properties":{"regionCode":{"type":"string"},"sido":{"type":"string"},"sigungu":{"type":"string"},"regionName":{"type":"string"}}},"PlaceInformationReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"장소 정보 신고 페이지 응답"},"PlaceAutocompleteItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"category":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"distanceMeters":{"type":"number","format":"double"}}},"PlaceAutocompleteResponse":{"type":"object","properties":{"keyword":{"type":"string"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int32"},"places":{"type":"array","items":{"$ref":"#/components/schemas/PlaceAutocompleteItem"}}}},"PaymentPageResponse":{"required":["hasNext","limit","page","payments","totalElements","totalPages"],"type":"object","properties":{"payments":{"type":"array","items":{"$ref":"#/components/schemas/PaymentResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관광객 결제 목록 페이지 응답"},"VerifiedBoostSelectionPageResponse":{"type":"object","properties":{"selections":{"type":"array","items":{"$ref":"#/components/schemas/VerifiedBoostSelectionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"MerchantVerifiedBoostProductPageResponse":{"type":"object","properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/MerchantVerifiedBoostProductResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"MerchantVerifiedBoostProductResponse":{"type":"object","properties":{"productId":{"type":"integer","format":"int64","example":1},"name":{"type":"string"},"description":{"type":"string"},"priceAmount":{"type":"integer","format":"int64","example":30000},"currency":{"type":"string","example":"KRW"},"durationDays":{"type":"integer","format":"int32","example":7},"status":{"type":"string","enum":["DRAFT","ACTIVE","INACTIVE"]}}},"VerifiedBoostExecutionPageResponse":{"type":"object","properties":{"executions":{"type":"array","items":{"$ref":"#/components/schemas/VerifiedBoostExecutionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"MerchantOwnerPlaceDetailResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string"},"category":{"type":"string"},"address":{"type":"string"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"imageUrl":{"type":"string"},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"description":{"type":"string"},"touristSummary":{"type":"string"},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"primaryInformationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"informationVerificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"informationVerifiedAt":{"type":"string","format":"date-time"},"informationEvidenceUpdatedAt":{"type":"string","format":"date-time"}},"description":"Merchant Owner 장소 상세 응답"},"MerchantPlaceReviewDeletionRequestStatusResponse":{"type":"object","properties":{"deletionRequestId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"requestedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"reviewNote":{"type":"string"}},"description":"상점주 리뷰 삭제 신청 최신 상태","nullable":true},"MerchantPlaceReviewPageResponse":{"type":"object","properties":{"reviews":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceReviewResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"상점주 관리 장소 리뷰 목록 페이지"},"MerchantPlaceReviewResponse":{"type":"object","properties":{"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"userId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"createdAt":{"type":"string","format":"date-time"},"visibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]},"deletionRequest":{"$ref":"#/components/schemas/MerchantPlaceReviewDeletionRequestStatusResponse"}},"description":"상점주 관리 장소 리뷰"},"PlaceInformationReverificationListResponse":{"type":"object","properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"MerchantPerformanceResponse":{"type":"object","properties":{"placeCount":{"type":"integer","description":"소유 장소 수","format":"int64","example":3},"exposureCount":{"type":"integer","description":"추천 카드 노출 수","format":"int64","example":1200},"clickCount":{"type":"integer","description":"추천 카드 클릭 수","format":"int64","example":240},"bookmarkCount":{"type":"integer","description":"장소 북마크 수","format":"int64","example":85},"reservationCount":{"type":"integer","description":"전체 예약 수","format":"int64","example":42},"confirmedReservationCount":{"type":"integer","description":"확정 예약 수","format":"int64","example":36},"clickThroughRate":{"type":"number","description":"노출 대비 클릭률(%)","format":"double","example":20.0},"reservationConversionRate":{"type":"number","description":"클릭 대비 예약 전환율(%)","format":"double","example":17.5}},"description":"Merchant 소유 장소의 탐색·예약 전환 성과 요약"},"SettlementLedgerPageResponse":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/SettlementLedgerResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"SettlementLedgerResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"paymentTransactionId":{"type":"integer","format":"int64"},"entryType":{"type":"string","enum":["PAYMENT","REFUND"]},"grossAmountMinor":{"type":"integer","format":"int64"},"feeAmountMinor":{"type":"integer","format":"int64"},"netAmountMinor":{"type":"integer","format":"int64"},"currency":{"type":"string"},"status":{"type":"string","enum":["PENDING","SETTLED","REVERSED"]},"createdAt":{"type":"string","format":"date-time"},"settledAt":{"type":"string","format":"date-time"}}},"PopupCampaignPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PopupCampaignResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"BrandPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BrandResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"LocationCheckInPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LocationCheckInResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PlaceEventListItem":{"required":["endAt","eventType","id","placeId","placeName","scheduleStatus","startAt","title"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":101},"placeName":{"type":"string","example":"진주성"},"title":{"type":"string","example":"진주 여름 빛 축제"},"eventType":{"type":"string","example":"EXHIBITION","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time","example":"2026-08-01T00:00:00Z"},"endAt":{"type":"string","format":"date-time","example":"2026-08-08T00:00:00Z"},"scheduleStatus":{"type":"string","example":"UPCOMING","enum":["UPCOMING","ONGOING"]}},"description":"공개 기간형 이벤트 목록 항목"},"PlaceEventListResponse":{"required":["events","hasNext","limit","page","totalCount","totalPages"],"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/PlaceEventListItem"}},"page":{"type":"integer","format":"int32","example":1},"limit":{"type":"integer","format":"int32","example":20},"totalCount":{"type":"integer","format":"int64","example":42},"totalPages":{"type":"integer","format":"int64","example":3},"hasNext":{"type":"boolean","example":true}},"description":"공개 기간형 이벤트 목록 응답"},"PlaceEventDetailResponse":{"required":["description","endAt","eventType","id","placeAddress","placeId","placeName","scheduleStatus","startAt","title"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":101},"placeName":{"type":"string","example":"진주성"},"placeAddress":{"type":"string","example":"경상남도 진주시 남강로 626"},"title":{"type":"string","example":"진주 여름 빛 축제"},"description":{"type":"string","nullable":true,"example":"남강 야간 전시와 공연"},"eventType":{"type":"string","example":"EXHIBITION","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time","example":"2026-08-01T00:00:00Z"},"endAt":{"type":"string","format":"date-time","example":"2026-08-08T00:00:00Z"},"scheduleStatus":{"type":"string","example":"UPCOMING","enum":["UPCOMING","ONGOING"]}},"description":"공개 기간형 이벤트 상세 응답"},"CouponPageResponse":{"required":["coupons","hasNext","limit","page","totalElements","totalPages"],"type":"object","properties":{"coupons":{"type":"array","items":{"$ref":"#/components/schemas/CouponResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"Category":{"type":"object","properties":{"categoryId":{"type":"string","description":"카테고리 식별자","example":"TRAVEL"},"categoryName":{"type":"string","description":"카테고리 표시 이름","example":"여행"}},"description":"게시글 카테고리 표시 정보"},"CommunityPostListResponse":{"type":"object","properties":{"posts":{"type":"array","description":"게시글 목록","items":{"$ref":"#/components/schemas/CommunityPostSummary"}},"page":{"type":"integer","description":"현재 페이지","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 게시글 수","format":"int64","example":42},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":3},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":true}},"description":"카테고리별 커뮤니티 게시글 목록 조회 응답"},"CommunityPostSummary":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":1},"title":{"type":"string","description":"게시글 제목","example":"대소고 다녀왔어요"},"contentPreview":{"type":"string","description":"본문 앞 150자"},"imageUrl":{"type":"string","description":"첫 게시글 사진 URL. 사진 없으면 null"},"imageCount":{"type":"integer","description":"게시글 전체 사진 수","format":"int64"},"countryCode":{"type":"string","description":"ISO alpha-2 국가 코드. 미설정은 null"},"region":{"type":"string","description":"작성자가 지정한 표시 지역"},"createdAt":{"type":"string","format":"date-time"},"viewCount":{"type":"integer","description":"정상 상세 조회 횟수","format":"int64"},"likeCount":{"type":"integer","format":"int64"},"commentCount":{"type":"integer","description":"숨김 댓글·숨김 부모의 답글을 제외한 댓글 수","format":"int64"},"category":{"$ref":"#/components/schemas/Category"}},"description":"게시글 목록 항목"},"Author":{"type":"object","properties":{"authorId":{"type":"integer","description":"게시글 작성자 ID","format":"int64"},"authorName":{"type":"string","description":"작성자 표시 이름. 탈퇴 또는 조회 불가 시 대체 이름"},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL. 없거나 탈퇴한 경우 null"}},"description":"게시글 작성자 표시 정보"},"CommunityPostDetailResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":1},"title":{"type":"string","description":"게시글 제목","example":"대소고 다녀왔어요"},"content":{"type":"string","description":"게시글 본문","example":"즐거운 경험이었습니다."},"places":{"type":"array","description":"연결 장소 목록","items":{"$ref":"#/components/schemas/Place"}},"author":{"$ref":"#/components/schemas/Author"},"category":{"$ref":"#/components/schemas/Category"},"createdAt":{"type":"string","description":"게시글 작성 시각","format":"date-time"},"images":{"type":"array","description":"표시 순서대로 정렬된 게시글 사진. position은 0부터 시작","items":{"$ref":"#/components/schemas/CommunityPostImageItem"}},"countryCode":{"type":"string","description":"ISO alpha-2 국가 코드. 기존 미설정 글은 null"},"region":{"type":"string","description":"작성자가 지정한 표시 지역. 미설정은 null"},"viewCount":{"type":"integer","description":"정상 상세 요청 횟수. 사용자별 고유 조회가 아님","format":"int64"}},"description":"커뮤니티 게시글 상세 조회 응답"},"CommunityPostImageItem":{"type":"object","properties":{"imageId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"position":{"type":"integer","format":"int32"}},"description":"표시 순서대로 정렬된 게시글 사진. position은 0부터 시작"},"Place":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":1},"placeName":{"type":"string","description":"현재 장소 이름. 삭제된 장소는 삭제 안내 문구","example":"대소고"},"deleted":{"type":"boolean","description":"삭제된 장소 여부","example":false},"imageUrl":{"type":"string","description":"장소 대표 이미지. 미설정 또는 삭제 시 null"},"category":{"type":"string","description":"기존 장소 분류. 미설정 또는 삭제 시 null"},"regionCode":{"type":"string","description":"기존 장소 지역 코드"},"address":{"type":"string","description":"장소 표시 주소"},"region":{"type":"string","description":"기존 지역 사전의 표시 이름. 미해석 또는 삭제 시 null"}},"description":"게시글에 연결된 장소"},"CommunityCommentSummary":{"type":"object","properties":{"commentId":{"type":"integer","description":"댓글 ID","format":"int64","example":1},"content":{"type":"string","description":"댓글 내용","example":"저도 가보고 싶네요!"},"authorId":{"type":"integer","description":"작성자 ID","format":"int64","example":7},"authorName":{"type":"string","description":"작성자 표시 이름","example":"pingdom"},"createdAt":{"type":"string","description":"댓글 작성 시각","format":"date-time"},"parentCommentId":{"type":"integer","description":"최상위 댓글이면 null, 대댓글이면 부모 ID","format":"int64"},"likeCount":{"type":"integer","format":"int64"},"liked":{"type":"boolean","description":"현재 인증 사용자 좋아요 여부"}},"description":"댓글 목록 항목"},"CommunityPostCommentListResponse":{"type":"object","properties":{"comments":{"type":"array","description":"댓글 목록","items":{"$ref":"#/components/schemas/CommunityCommentSummary"}},"page":{"type":"integer","description":"현재 페이지","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 댓글 수","format":"int64","example":42},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":3},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":true}},"description":"커뮤니티 게시글 댓글 목록 조회 응답"},"CommunityCategoryItem":{"type":"object","properties":{"categoryId":{"type":"string","description":"저장과 요청에 사용할 카테고리 식별자","example":"PLACE"},"categoryName":{"type":"string","description":"화면 표시용 카테고리 이름","example":"장소"}},"description":"커뮤니티 카테고리 목록 항목"},"CommunityPostCategoryListResponse":{"type":"object","properties":{"categories":{"type":"array","description":"작성 및 조회에 사용할 활성 카테고리 목록","items":{"$ref":"#/components/schemas/CommunityCategoryItem"}}},"description":"커뮤니티 게시글 카테고리 목록 응답"},"VisitorVerificationReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/VisitorVerificationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"VisitorVerificationReportCorrectionPageResponse":{"type":"object","properties":{"corrections":{"type":"array","items":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"VerifiedBoostProductPageResponse":{"type":"object","properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminUserSanctionHistoryItem":{"type":"object","properties":{"historyId":{"type":"integer","description":"제재 이력 ID","format":"int64","example":1},"targetUserId":{"type":"integer","description":"대상 사용자 ID","format":"int64","example":7},"targetUsername":{"type":"string","description":"대상 사용자명","example":"blockedUser01"},"banType":{"type":"string","description":"제재 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"action":{"type":"string","description":"처리 상태","example":"APPLIED","enum":["APPLIED","RELEASED","EXPIRED"]},"reason":{"type":"string","description":"처리 사유","example":"반복적인 신고 누적"},"startedAt":{"type":"string","description":"제재 시작 시각","format":"date-time"},"endedAt":{"type":"string","description":"제재 종료 시각","format":"date-time"},"adminUserId":{"type":"integer","description":"처리 관리자 ID","format":"int64","example":1},"adminUsername":{"type":"string","description":"처리 관리자명","example":"admin"},"processedAt":{"type":"string","description":"처리 시각","format":"date-time"}},"description":"관리자 사용자 제재 이력 아이템"},"AdminUserSanctionHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/AdminUserSanctionHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 사용자 제재 이력 목록 응답"},"AdminUserSanctionStatusResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"banned":{"type":"boolean","description":"현재 제재 여부","example":true},"banType":{"type":"string","description":"제재 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"bannedAt":{"type":"string","description":"제재 시작 시각","format":"date-time"},"banExpiresAt":{"type":"string","description":"제재 종료 시각","format":"date-time"},"banReason":{"type":"string","description":"제재 사유","example":"반복적인 신고 누적"}},"description":"관리자 사용자 제재 상태 조회 응답"},"AdminRoleAssignmentTargetItem":{"type":"object","properties":{"userId":{"type":"integer","description":"역할 API에 전달할 사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"admin_operator"}},"description":"관리자 역할 부여 대상 사용자"},"AdminRoleAssignmentTargetSearchResponse":{"type":"object","properties":{"users":{"type":"array","description":"현재 페이지의 역할 부여 대상 사용자","items":{"$ref":"#/components/schemas/AdminRoleAssignmentTargetItem"}},"page":{"type":"integer","description":"현재 페이지 번호(1부터 시작)","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"검색 조건에 맞는 전체 사용자 수","format":"int64","example":12},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false}},"description":"관리자 역할 부여 대상 사용자 검색 응답"},"AdminBannedUserCounts":{"type":"object","properties":{"total":{"type":"integer","description":"현재 밴 중인 전체 사용자 수","format":"int64","example":12},"permanent":{"type":"integer","description":"현재 영구 밴 중인 사용자 수","format":"int64","example":7},"temporary":{"type":"integer","description":"현재 기간 밴 중인 사용자 수","format":"int64","example":5}},"description":"현재 밴 사용자 필터별 카운트"},"AdminBannedUserItem":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"banned":{"type":"boolean","description":"밴 처리 여부","example":true},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"bannedAt":{"type":"string","description":"밴 처리 시각","format":"date-time"},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"}},"description":"밴 유저 목록 아이템"},"AdminBannedUserResponse":{"type":"object","properties":{"users":{"type":"array","description":"현재 페이지의 밴 사용자 목록","items":{"$ref":"#/components/schemas/AdminBannedUserItem"}},"page":{"type":"integer","description":"현재 페이지 번호(1부터 시작)","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"조회 조건에 맞는 현재 밴 사용자 전체 수","format":"int64","example":12},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int64","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false},"counts":{"$ref":"#/components/schemas/AdminBannedUserCounts"}},"description":"밴 유저 목록 조회 응답"},"AdminBannedUserDetailResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"email":{"type":"string","description":"이메일","example":"blockedUser01@example.com"},"birthYear":{"type":"integer","description":"출생연도","format":"int32","example":1998},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"role":{"type":"string","description":"권한","example":"USER"},"banned":{"type":"boolean","description":"밴 여부","example":true},"bannedAt":{"type":"string","description":"밴 시각","format":"date-time"},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"},"banReason":{"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"createdAt":{"type":"string","description":"가입 시각","format":"date-time"}},"description":"밴 유저 상세 조회 응답"},"AdminTrustScoreEvidenceResponse":{"type":"object","properties":{"submittedCount":{"type":"integer","description":"신고 제출 수","format":"int64","example":12},"acceptedCount":{"type":"integer","description":"승인된 신고 수","format":"int64","example":8},"declinedCount":{"type":"integer","description":"반려된 신고 수","format":"int64","example":4},"falseReportCount":{"type":"integer","description":"허위 신고 수","format":"int64","example":3},"acceptanceRate":{"type":"number","description":"승인률","format":"double","example":66.67},"baseScore":{"type":"integer","description":"기본 점수","format":"int32","example":100},"acceptedScoreBonus":{"type":"integer","description":"승인 신고 가산점 합계","format":"int64","example":40},"falseReportScorePenalty":{"type":"integer","description":"허위 신고 감점 합계","format":"int64","example":60}},"description":"신뢰 점수 산정 근거"},"AdminTrustScoreResponse":{"type":"object","properties":{"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":7},"reporterUsername":{"type":"string","description":"신고자 username","example":"pingdom_user"},"trustScore":{"type":"integer","description":"신뢰 점수","format":"int32","example":80},"trustGrade":{"type":"string","description":"신뢰 등급","example":"HIGH","enum":["HIGH","NORMAL","LOW"]},"restricted":{"type":"boolean","description":"현재 신고 제한 여부","example":false},"restrictedUntil":{"type":"string","description":"신고 제한 종료 시각","format":"date-time","nullable":true},"restrictionReason":{"type":"string","description":"신고 제한 사유","nullable":true,"example":"FALSE_REPORT_THRESHOLD_EXCEEDED"},"evidence":{"$ref":"#/components/schemas/AdminTrustScoreEvidenceResponse"}},"description":"신고자 신뢰 등급 및 점수 근거 응답"},"AdminTrustScoreChangeHistoryItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"beforeScore":{"type":"integer","format":"int32"},"afterScore":{"type":"integer","format":"int32"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}},"AdminTrustScoreChangeHistoryResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminTrustScoreChangeHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminTrustScoreInterventionRuleResponse":{"type":"object","properties":{"rules":{"type":"array","description":"개입 규칙 목록","items":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"}}}},"AdminTrustScoreAnomalyResponse":{"type":"object","properties":{"anomalies":{"type":"array","description":"이상치 목록","items":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyItem"}},"page":{"type":"integer","description":"현재 페이지","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 개수","format":"int64","example":42},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":3}}},"ScoutProfilePageResponse":{"type":"object","properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/ScoutProfileResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 Scout 프로필 목록 응답"},"ScoutFieldReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminS3OrphanObjectReportResponse":{"type":"object","properties":{"prefix":{"type":"string"},"scanLimit":{"type":"integer","format":"int32"},"dryRun":{"type":"boolean"},"truncated":{"type":"boolean"},"dbKeyCount":{"type":"integer","format":"int64"},"s3ObjectCount":{"type":"integer","format":"int64"},"orphanObjectCount":{"type":"integer","format":"int64"},"orphanKeys":{"type":"array","items":{"type":"string"}}}},"AdminReservationPageResponse":{"type":"object","properties":{"reservations":{"type":"array","items":{"$ref":"#/components/schemas/AdminReservationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"ReportedUsersItem":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"reporterUsername":{"type":"string"},"reportedImageId":{"type":"integer","format":"int64"},"reportedUserId":{"type":"integer","format":"int64"},"reason":{"type":"string"}}},"ReportedUsersResponse":{"type":"object","properties":{"users":{"type":"array","items":{"$ref":"#/components/schemas/ReportedUsersItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminReportAppealItem":{"type":"object","properties":{"appealId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"appellantUserId":{"type":"integer","format":"int64"},"appellantUsername":{"type":"string"},"targetUserId":{"type":"integer","format":"int64"},"reason":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]},"adminUserId":{"type":"integer","format":"int64"},"adminReason":{"type":"string"},"processedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"AdminReportAppealResponse":{"type":"object","properties":{"appeals":{"type":"array","items":{"$ref":"#/components/schemas/AdminReportAppealItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PrivacyProcessingHistoryItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"subjectUserId":{"type":"integer","format":"int64"},"actorUserId":{"type":"integer","format":"int64"},"actorType":{"type":"string","enum":["USER","SYSTEM","ADMIN"]},"action":{"type":"string","enum":["EXPORT_REQUESTED","WITHDRAWAL_REQUESTED","ANONYMIZED","DELETED"]},"details":{"type":"string"},"requestId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"PrivacyProcessingHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/PrivacyProcessingHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"S3OrphanCandidate":{"type":"object","properties":{"key":{"type":"string"},"reason":{"type":"string"}}},"S3OrphanReport":{"type":"object","properties":{"reportId":{"type":"string"},"status":{"type":"string"},"errorMessage":{"type":"string"},"deleteCandidates":{"type":"array","items":{"$ref":"#/components/schemas/S3OrphanCandidate"}},"dbKeyCount":{"type":"integer","format":"int64"},"s3KeyCount":{"type":"integer","format":"int64"},"deleteCandidateCount":{"type":"integer","format":"int64"},"generatedAt":{"type":"string","format":"date-time"},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceItem":{"required":["level"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"category":{"type":"string","description":"일반 장소 카테고리. touristCategories와 별도 기준이며 미분류 장소는 null입니다.","nullable":true,"example":"OTHER","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"categoryName":{"type":"string","description":"화면 표시용 일반 장소 카테고리명. category가 없으면 미분류입니다.","example":"기타","enum":["음식점","음악","팝업","패션","뷰티","전시","카페","문화재","기타","미분류"]},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","description":"외국인 관광 관심사 분류. 일반 장소 category 필터와는 별도 기준입니다.","items":{"type":"string","description":"외국인 관광 관심사 분류. 일반 장소 category 필터와는 별도 기준입니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"level":{"minimum":0,"type":"integer","description":"장소 성장 레벨. 10 이상이면 관리자 지도에서 불꽃 마커로 표시할 수 있습니다.","format":"int32","example":5},"placeGrowth":{"$ref":"#/components/schemas/PlaceGrowthSnapshot"}}},"AdminMapPlaceResponse":{"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"minimum":1,"type":"integer","description":"전체 페이지 수. 조회 결과가 없어도 1을 반환합니다.","format":"int64","example":1},"hasNext":{"type":"boolean"}},"description":"관리자 장소 목록 조회 응답"},"AdminMapPlaceDetailResponse":{"required":["imageUrl","level"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"imageUrl":{"type":"string","description":"장소 목록·상세에서 공통으로 사용하는 canonical 대표 이미지 URL입니다. 대표 이미지가 없으면 null입니다.","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"category":{"type":"string","description":"일반 장소 카테고리. touristCategories와 별도 기준이며 미분류 장소는 null입니다.","nullable":true,"example":"OTHER","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"categoryName":{"type":"string","description":"화면 표시용 일반 장소 카테고리명. category가 없으면 미분류입니다.","example":"기타","enum":["음식점","음악","팝업","패션","뷰티","전시","카페","문화재","기타","미분류"]},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","description":"외국인 관광 관심사 분류. 일반 장소 category와는 별도 기준입니다.","items":{"type":"string","description":"외국인 관광 관심사 분류. 일반 장소 category와는 별도 기준입니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"username":{"type":"string"},"sortParam":{"type":"string","enum":["LATEST","OLDEST","MOST_LIKED"]},"postCount":{"type":"integer","format":"int32"},"level":{"minimum":0,"type":"integer","description":"장소 성장 레벨. 10 이상이면 관리자 지도에서 불꽃 마커로 표시할 수 있습니다.","format":"int32","example":5},"placeGrowth":{"$ref":"#/components/schemas/AdminMapPlaceGrowthResponse"},"posts":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceImageItem"}}}},"AdminMapPlaceGrowthResponse":{"type":"object","properties":{"photoCount":{"type":"integer","description":"장소 성장에 반영된 노출 게시글 사진 수","format":"int64","example":10},"hiddenPhotoCount":{"type":"integer","description":"장소 성장에 반영되지 않는 숨김 게시글 사진 수","format":"int64","example":1},"level":{"type":"integer","format":"int32"},"currentLevelMinPhotoCount":{"type":"integer","format":"int64"},"nextLevelMinPhotoCount":{"type":"integer","format":"int64"},"progressPercent":{"type":"integer","format":"int32"}},"description":"관리자 장소 상세 성장 상태"},"AdminMapPlaceImageItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"thumbnailUrl":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"userId":{"type":"integer","format":"int64"},"username":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"likeCount":{"type":"integer","format":"int64"},"visibilityStatus":{"type":"string","description":"일반 사용자 기준 게시글 노출 상태","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"hiddenReason":{"type":"string","description":"게시글이 숨김 처리된 사유. 노출 중인 게시글은 null","nullable":true,"example":"ADMIN_HIDDEN"}}},"AdminPlaceInformationEvidenceResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"evidences":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceItem"}}},"description":"관리자 장소 정보 증빙 목록 응답"},"AdminPlaceRecommendationExplanationItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":1},"placeName":{"type":"string","description":"장소명","example":"진주성"},"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":21},"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v2"},"recommendationStage":{"type":"string","description":"추천 stage","example":"EXPERIMENT","enum":["STABLE","EXPERIMENTAL"]},"ranking":{"type":"integer","description":"노출 순위","format":"int32","example":1},"source":{"type":"string","description":"후보 소스","example":"PERSONALIZED","enum":["PERSONAL","POPULAR","FRESH","GEO","FALLBACK"]},"distanceMeters":{"type":"integer","description":"거리(m)","format":"int64","example":128},"geoScore":{"type":"number","description":"geo score","format":"double","example":0.91},"personalScore":{"type":"number","description":"personal score","format":"double","example":0.42},"qualityScore":{"type":"number","description":"quality score","format":"double","example":0.37},"engagementScore":{"type":"number","description":"engagement score","format":"double","example":0.25},"conversionScore":{"type":"number","description":"conversion score","format":"double","example":0.14},"explorationScore":{"type":"number","description":"exploration score","format":"double","example":0.08},"freshnessScore":{"type":"number","description":"freshness score","format":"double","example":0.19},"trustScore":{"type":"number","description":"검증 제보자 신뢰도 기반 score","format":"double","example":0.82},"contextScore":{"type":"number","description":"K-컬처 관심사와 현재 여행 맥락 기반 score","format":"double","example":0.25},"benefitScore":{"type":"number","description":"현재 이용 가능한 혜택 기반 boost","format":"double","example":0.05},"availabilityScore":{"type":"number","description":"예약 가능 시간 기반 boost","format":"double","example":0.05},"boostScore":{"type":"number","description":"Verified Boost 집행 기반 score","format":"double","example":0.08},"finalScore":{"type":"number","description":"최종 score","format":"double","example":0.74},"createdAt":{"type":"string","description":"로그 생성 시각","format":"date-time"}},"description":"관리자 추천 설명 항목"},"AdminPlaceRecommendationExplanationResponse":{"type":"object","properties":{"requestId":{"type":"string","description":"추천 요청 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"items":{"type":"array","description":"관리자 추천 설명 항목","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationExplanationItem"}}},"description":"관리자 추천 설명 조회 응답"},"AdminPlaceRecommendationMetricItem":{"type":"object","properties":{"id":{"type":"integer","description":"장소 ID","format":"int64","example":1},"name":{"type":"string","description":"장소명","example":"진주성"},"address":{"type":"string","description":"장소 주소","example":"경상남도 진주시 남강로 626"},"photoCount":{"type":"integer","description":"장소 사진 수","format":"int64","example":12},"exposureCount":{"type":"integer","description":"추천 노출 수","format":"int64","example":120},"clickCount":{"type":"integer","description":"추천 클릭 수","format":"int64","example":18},"rawCtr":{"type":"number","description":"원본 CTR","format":"double","example":0.15},"smoothedCtr":{"type":"number","description":"랭킹 기준 smoothed CTR","format":"double","example":0.13},"bookmarkConversionCount":{"type":"integer","description":"북마크 전환 수","format":"int64","example":4},"likeConversionCount":{"type":"integer","description":"좋아요 전환 수","format":"int64","example":6},"bookmarkConversionRate":{"type":"number","description":"북마크 전환율","format":"double","example":0.03},"likeConversionRate":{"type":"number","description":"좋아요 전환율","format":"double","example":0.05},"totalConversionRate":{"type":"number","description":"전체 전환율","format":"double","example":0.08},"snapshotUpdatedAt":{"type":"string","description":"추천 snapshot 최종 갱신 시각","format":"date-time"}},"description":"관리자 추천 성과 항목"},"AdminPlaceRecommendationMetricsResponse":{"type":"object","properties":{"metrics":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricItem"}},"sortBy":{"type":"string","enum":["SMOOTHED_CTR","RAW_CTR","BOOKMARK_CONVERSION","LIKE_CONVERSION","TOTAL_CONVERSION","EXPOSURE","CLICK","UPDATED_AT"]},"recommendationVersion":{"type":"string"},"days":{"type":"integer","format":"int32"},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}},"description":"관리자 추천 성과 목록 응답"},"AdminPlaceRecommendationMetricSummary":{"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v1"},"exposureCount":{"type":"integer","description":"추천 노출 수","format":"int64","example":120},"clickCount":{"type":"integer","description":"추천 클릭 수","format":"int64","example":18},"rawCtr":{"type":"number","description":"원본 CTR","format":"double","example":0.15},"smoothedCtr":{"type":"number","description":"smoothed CTR","format":"double","example":0.13},"bookmarkConversionCount":{"type":"integer","description":"북마크 전환 수","format":"int64","example":4},"likeConversionCount":{"type":"integer","description":"좋아요 전환 수","format":"int64","example":6},"bookmarkConversionRate":{"type":"number","description":"북마크 전환율","format":"double","example":0.03},"likeConversionRate":{"type":"number","description":"좋아요 전환율","format":"double","example":0.05},"totalConversionRate":{"type":"number","description":"전체 전환율","format":"double","example":0.08}},"description":"관리자 추천 성과 요약"},"AdminPlaceRecommendationMetricsCompareResponse":{"type":"object","properties":{"baselineVersion":{"type":"string","description":"기준 추천 버전","example":"place-rec-v1"},"targetVersion":{"type":"string","description":"비교 대상 추천 버전","example":"place-rec-v2"},"days":{"type":"integer","description":"최근 N일 기준 필터","format":"int32","example":7},"keyword":{"type":"string","description":"장소 검색 키워드","example":"진주"},"baseline":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"},"target":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"},"delta":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"}},"description":"관리자 추천 버전 성과 비교 응답"},"AdminPlaceMergeHistoryItem":{"type":"object","properties":{"historyId":{"type":"integer","format":"int64"},"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"adminUserId":{"type":"integer","format":"int64"},"restored":{"type":"boolean"},"mergedAt":{"type":"string","format":"date-time"},"restoredAt":{"type":"string","format":"date-time"}}},"AdminPlaceMergeHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMergeHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDuplicateGroupItem":{"type":"object","properties":{"representativePlaceId":{"type":"integer","format":"int64"},"duplicatePlaceIds":{"type":"array","items":{"type":"integer","format":"int64"}},"reasons":{"type":"array","items":{"type":"string"}}}},"AdminMapPlaceDuplicateResponse":{"type":"object","properties":{"groups":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateGroupItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDuplicateCandidateItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"kakaoPlaceId":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"photoCount":{"type":"integer","format":"int64"},"reason":{"type":"string"},"distanceMeters":{"type":"number","format":"double"}}},"AdminMapPlaceDuplicateDetailResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"kakaoPlaceId":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"photoCount":{"type":"integer","format":"int64"},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateCandidateItem"}}}},"AdminPlaceDuplicateCandidateListResponse":{"type":"object","properties":{"candidates":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminPlaceReviewDeletionRequestPageResponse":{"type":"object","properties":{"deletionRequests":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminPlaceEventListItem":{"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"placeAddress":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"publicationStatus":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminPlaceEventListResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceEventListItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminOutboxEventResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AdminOutboxEventItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 Outbox 이벤트 운영 조회 응답"},"AdminNotificationItem":{"type":"object","properties":{"notificationId":{"type":"integer","description":"알림 ID","format":"int64","example":1},"userId":{"type":"integer","description":"수신 관리자 ID","format":"int64","example":10},"type":{"type":"string","description":"관리자 알림 유형: ADMIN_REPORT_RECEIVED, ADMIN_REPORT_PROCESSED, ADMIN_DUPLICATE_PLACE_DETECTED, ADMIN_USER_SANCTION","example":"ADMIN_REPORT_RECEIVED","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"title":{"type":"string","description":"알림 제목","example":"신고 접수 알림"},"body":{"type":"string","description":"알림 내용","example":"신고 ID 30 접수가 게시글 ID 12에 등록되었습니다."},"token":{"type":"string","description":"관리 화면 연결 token. report:{reportId}, place:{placeId}, sanction:{sanctionId} 형식","example":"report:30"},"read":{"type":"boolean","description":"읽음 여부","example":false},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"}},"description":"관리자 알림 아이템"},"AdminNotificationResponse":{"type":"object","properties":{"notifications":{"type":"array","description":"관리자 알림 목록","items":{"$ref":"#/components/schemas/AdminNotificationItem"}},"page":{"type":"integer","description":"현재 페이지 번호","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 알림 개수","format":"int64","example":1},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false}},"description":"관리자 알림 목록 응답"},"AdminNotificationUnreadCountResponse":{"type":"object","properties":{"unreadCount":{"type":"integer","description":"미확인 알림 개수","format":"int64","example":3}},"description":"관리자 미확인 알림 개수 응답"},"AdminNotificationDeliveryItem":{"type":"object","properties":{"deliveryId":{"type":"integer","description":"발송 결과 ID","format":"int64","example":1},"channel":{"type":"string","description":"발송 채널","example":"FCM","enum":["FCM","EMAIL"]},"status":{"type":"string","description":"발송 상태","example":"SUCCEEDED","enum":["SUCCEEDED","FAILED","RETRY_SCHEDULED","FINAL_FAILED"]},"userId":{"type":"integer","description":"수신 사용자 ID","format":"int64","example":10},"notificationId":{"type":"integer","description":"인앱 알림 ID","format":"int64","example":100},"notificationType":{"type":"string","description":"인앱 알림 유형","example":"NEW_LIKE"},"outboxEventId":{"type":"string","description":"Outbox 이벤트 ID"},"outboxEventType":{"type":"string","description":"Outbox 이벤트 유형","example":"MAP_IMAGE_LIKED"},"providerMessageId":{"type":"string","description":"외부 발송 provider message id"},"providerErrorCode":{"type":"string","description":"외부 발송 provider error code"},"errorCode":{"type":"string","description":"내부 실패 분류 코드"},"failureReason":{"type":"string","description":"실패 사유"},"retryable":{"type":"boolean","description":"재시도 가능 여부","example":true},"attemptCount":{"type":"integer","description":"발송 시도 횟수","format":"int32","example":1},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}},"description":"관리자 알림 발송 결과 아이템"},"AdminNotificationDeliveryResponse":{"type":"object","properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/AdminNotificationDeliveryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 알림 발송 결과 목록 응답"},"AdminMerchantPlaceApplicationListItemResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"maskedBusinessRegistrationNumber":{"type":"string"},"merchantDisplayName":{"type":"string"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminMerchantPlaceApplicationPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationListItemResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMerchantPlaceApplicationAttachmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"documentType":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"uploadedAt":{"type":"string","format":"date-time"},"retentionExpiresAt":{"type":"string","format":"date-time"},"displayOrder":{"type":"integer","format":"int32"}}},"AdminMerchantPlaceApplicationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"businessRegistrationNumber":{"type":"string"},"merchantDisplayName":{"type":"string"},"merchantContactEmail":{"type":"string"},"merchantDescription":{"type":"string"},"merchantContactPhone":{"type":"string"},"newPlace":{"$ref":"#/components/schemas/MerchantPlaceApplicationNewPlaceResponse"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"type":"string"},"reviewReason":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"version":{"type":"integer","format":"int64"},"submissionVersion":{"type":"integer","format":"int64"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationAttachmentResponse"}}}},"MerchantOwnerProfilePageResponse":{"type":"object","properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"DataQualityIssuePageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DataQualityIssueResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"DataQualityIssueResponse":{"type":"object","properties":{"entityType":{"type":"string"},"entityId":{"type":"integer","format":"int64"},"ruleCode":{"type":"string"},"severity":{"type":"string","enum":["INFO","WARNING","ERROR"]},"status":{"type":"string","enum":["OPEN","RESOLVED","IGNORED"]},"details":{"type":"string"},"detectedAt":{"type":"string","format":"date-time"}}},"AdminDashboardMetricWindowResponse":{"type":"object","properties":{"period":{"type":"string","description":"집계 기간 코드","example":"TODAY","enum":["TODAY","LAST_7_DAYS"]},"startedAt":{"type":"string","description":"집계 시작 시각","format":"date-time"},"endedAt":{"type":"string","description":"집계 종료 시각","format":"date-time"},"placeRegistrationCount":{"type":"integer","description":"기간 내 장소 등록 수","format":"int64","example":3},"postRegistrationCount":{"type":"integer","description":"기간 내 게시글 등록 수","format":"int64","example":7}},"description":"관리자 대시보드 기간별 운영 변화 지표"},"AdminDashboardOperationalMetricsResponse":{"type":"object","properties":{"today":{"$ref":"#/components/schemas/AdminDashboardMetricWindowResponse"},"last7Days":{"$ref":"#/components/schemas/AdminDashboardMetricWindowResponse"},"duplicatePlaceGroupCount":{"type":"integer","description":"중복 장소 후보 그룹 수","format":"int64","example":2},"expiringBannedUserCount":{"type":"integer","description":"7일 이내 임시 밴 만료 예정 사용자 수","format":"int64","example":4},"missingLocationPlaceCount":{"type":"integer","description":"location 좌표 정보가 누락된 장소 수","format":"int64","example":1},"expiringBanUntil":{"type":"string","description":"밴 만료 예정 집계 종료 시각","format":"date-time"},"collectedAt":{"type":"string","description":"지표 집계 기준 시각","format":"date-time"}},"description":"관리자 대시보드 추가 운영 지표"},"AdminDashboardSummaryResponse":{"type":"object","properties":{"placeCount":{"type":"integer","description":"전체 장소 수","format":"int64","example":44},"postCount":{"type":"integer","description":"전체 게시글 수","format":"int64","example":58},"pendingReportCount":{"type":"integer","description":"처리 대기 신고 수","format":"int64","example":5},"bannedUserCount":{"type":"integer","description":"현재 밴 사용자 수","format":"int64","example":6},"operationalMetrics":{"$ref":"#/components/schemas/AdminDashboardOperationalMetricsResponse"}},"description":"관리자 대시보드 전체 운영 현황 요약"},"AdminDashboardRecentActivitiesResponse":{"type":"object","properties":{"places":{"type":"array","description":"최근 장소 등록 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentPlaceItem"}},"posts":{"type":"array","description":"최근 게시글 등록 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentPostItem"}},"reports":{"type":"array","description":"최근 신고 처리 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentReportItem"}},"userSanctions":{"type":"array","description":"최근 사용자 밴 및 밴 해제 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentUserSanctionItem"}}},"description":"관리자 대시보드 최근 운영 활동"},"AdminDashboardRecentPlaceItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":10},"name":{"type":"string","description":"장소명","example":"핑덤 카페"},"address":{"type":"string","description":"주소","example":"서울특별시 중구 세종대로 110"},"userId":{"type":"integer","description":"등록 사용자 ID","format":"int64","example":3},"registrant":{"type":"string","description":"등록자명","example":"pingdom_user"},"createdAt":{"type":"string","description":"장소 등록일","format":"date-time"}},"description":"관리자 대시보드 최근 장소 등록 항목"},"AdminDashboardRecentPostItem":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":10},"title":{"type":"string","description":"게시글 제목","example":"야경이 좋은 장소"},"userId":{"type":"integer","description":"작성자 ID","format":"int64","example":3},"username":{"type":"string","description":"작성자명","example":"pingdom_user"},"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":7},"placeName":{"type":"string","description":"장소명","example":"핑덤 카페"},"createdAt":{"type":"string","description":"생성일","format":"date-time"}},"description":"관리자 대시보드 최근 게시글 등록 항목"},"AdminDashboardRecentReportItem":{"type":"object","properties":{"reportId":{"type":"integer","description":"신고 ID","format":"int64","example":10},"reportedImageId":{"type":"integer","description":"신고 대상 게시글 ID","format":"int64","example":22},"title":{"type":"string","description":"신고 대상 게시글 제목","example":"야경이 좋은 장소"},"status":{"type":"string","description":"신고 상태","example":"ACCEPTED","enum":["PENDING","ACCEPTED","DECLINED","RESTORED"]},"processedAt":{"type":"string","description":"처리일","format":"date-time"},"createdAt":{"type":"string","description":"신고 생성일","format":"date-time"}},"description":"관리자 대시보드 최근 신고 처리 항목"},"AdminDashboardRecentUserSanctionItem":{"type":"object","properties":{"sanctionId":{"type":"integer","description":"제재 이력 ID","format":"int64","example":10},"targetUserId":{"type":"integer","description":"대상 사용자 ID","format":"int64","example":5},"targetUsername":{"type":"string","description":"대상 사용자명","example":"reported_user"},"action":{"type":"string","description":"제재 처리 유형","example":"APPLIED","enum":["APPLIED","RELEASED","EXPIRED"]},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"reason":{"type":"string","description":"처리 사유","example":"부적절한 게시글입니다."},"processedAt":{"type":"string","description":"처리일","format":"date-time"}},"description":"관리자 대시보드 최근 사용자 제재 항목"},"AdminDashboardPendingItem":{"type":"object","properties":{"type":{"type":"string","description":"처리 필요 항목 유형","example":"POST_REPORT","enum":["POST_REPORT","MERCHANT_PLACE_APPLICATION","POST_REPORT","MERCHANT_PLACE_APPLICATION"]},"targetId":{"type":"integer","description":"처리 항목 ID. POST_REPORT에서는 신고 ID와 동일","format":"int64","example":30},"reportId":{"type":"integer","description":"신고 ID. 신고 처리 화면으로 이동할 때 사용","format":"int64","example":30},"postId":{"type":"integer","description":"신고 대상 게시글 ID. 게시글 상세 화면으로 이동할 때 사용","format":"int64","nullable":true,"example":22},"title":{"type":"string","description":"처리 대상 제목","example":"야경이 좋은 장소"},"status":{"type":"string","description":"처리 대상 상태","example":"PENDING"},"createdAt":{"type":"string","description":"생성일","format":"date-time"},"navigationPath":{"type":"string","description":"관리자 화면 이동 경로. 통합 신청 항목에서만 제공","nullable":true,"example":"/admin/merchant-place-applications/12"}},"description":"관리자 대시보드 처리 필요 항목"},"AdminDashboardPendingItemsResponse":{"type":"object","properties":{"items":{"type":"array","description":"처리 필요 항목","items":{"$ref":"#/components/schemas/AdminDashboardPendingItem"}},"totalCount":{"type":"integer","description":"필터링 전 전체 PENDING 처리 필요 항목 수","format":"int64","example":8}},"description":"관리자 대시보드 처리 필요 항목 목록"},"AdminCommunityPostItem":{"type":"object","properties":{"postId":{"type":"integer","format":"int64"},"categoryId":{"type":"string"},"title":{"type":"string"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 글 목록 항목"},"AdminCommunityPostPageResponse":{"type":"object","properties":{"posts":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityPostItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminCommunityPostResponse":{"type":"object","properties":{"postId":{"type":"integer","format":"int64"},"categoryId":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"places":{"type":"array","items":{"$ref":"#/components/schemas/Place"}}}},"AdminCommunityCommentItem":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"content":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 댓글 목록 항목"},"AdminCommunityCommentPageResponse":{"type":"object","properties":{"comments":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityCommentItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminCommunityCommentResponse":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"content":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"AdminCommunityReportItem":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"targetHidden":{"type":"boolean"},"reporterUserId":{"type":"integer","format":"int64"},"reason":{"type":"string","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"createdAt":{"type":"string","format":"date-time"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 목록 항목"},"AdminCommunityReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityReportItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 커뮤니티 신고 목록 응답"},"AdminCommunityReportResponse":{"required":["postId"],"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"postId":{"type":"integer","description":"원문 글 ID. POST는 targetId와 같고 COMMENT는 대상 댓글이 속한 글 ID입니다. 신고 대상과 댓글의 원문 관계는 DB 제약으로 보장되며, 숨김 여부와 관계없이 반환합니다.","format":"int64","example":101},"targetHidden":{"type":"boolean"},"reporterUserId":{"type":"integer","format":"int64"},"reason":{"type":"string","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"description":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"createdAt":{"type":"string","format":"date-time"},"processedByAdminUserId":{"type":"integer","format":"int64"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 상세 응답"},"AdminAuditLogItem":{"type":"object","properties":{"auditLogId":{"type":"integer","description":"감사 로그 ID","format":"int64","example":1},"actorUserId":{"type":"integer","description":"작업 관리자 ID","format":"int64","example":1},"actorUsername":{"type":"string","description":"작업 관리자명","example":"admin"},"action":{"type":"string","description":"작업 유형","example":"USER_BAN_APPLIED","enum":["ADMIN_ROLE_ASSIGNED","ADMIN_ROLE_REVOKED","USER_BAN_APPLIED","USER_BAN_RELEASED","REPORT_ACCEPTED","REPORT_DECLINED","COMMUNITY_REPORT_ACCEPTED","COMMUNITY_REPORT_DECLINED","POST_DELETED","POST_HIDDEN","POST_RESTORED","APPEAL_APPROVED","APPEAL_REJECTED","PLACE_DELETED","PLACE_BASIC_INFORMATION_UPDATED","PLACE_KAKAO_PLACE_ID_UPDATED","PLACE_GEOCODING_UPDATED","PLACE_TOURIST_INFO_UPDATED","PLACE_INFORMATION_EVIDENCE_UPDATED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_INFORMATION_REVERIFICATION_COMPLETED","PLACE_INFORMATION_REVERIFICATION_CANCELED","PLACE_INFORMATION_REVERIFICATION_EXPIRED","VISITOR_VERIFICATION_REPORT_REVIEWED","VISITOR_VERIFICATION_REPORT_CORRECTION_REVIEWED","SCOUT_FIELD_REPORT_REVIEWED","SCOUT_PROFILE_REVIEWED","SCOUT_ACTIVITY_ELIGIBILITY_REVIEWED","PLACE_DISCOVERY_STATUS_UPDATED","PLACE_OPERATING_STATUS_UPDATED","PLACE_OPERATING_SCHEDULE_UPDATED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_EVENT_CREATED","PLACE_EVENT_UPDATED","PLACE_EVENT_PUBLISHED","PLACE_EVENT_CANCELLED","PLACE_RECOMMENDATION_TRAFFIC_UPDATED","PLACE_RECOMMENDATION_KILL_SWITCH_UPDATED","TRUST_SCORE_ANOMALY_RESOLVED","TRUST_SCORE_INTERVENTION_RULE_CREATED","TRUST_SCORE_INTERVENTION_RULE_UPDATED","TRUST_SCORE_INTERVENTION_RULE_ENABLED","TRUST_SCORE_INTERVENTION_RULE_DISABLED","TRUST_SCORE_INTERVENTION_EVALUATED","NOTIFICATION_READ","NOTIFICATION_READ_ALL","PLACE_DUPLICATE_CONFIRMED","PLACE_DUPLICATE_REJECTED","PLACE_MERGED","MERCHANT_OWNER_APPROVED","MERCHANT_OWNER_REJECTED","MERCHANT_OWNER_REVOKED","MERCHANT_OWNER_PLACES_UPDATED","MERCHANT_ONBOARDING_UPDATED","MERCHANT_OPERATIONAL_QUALITY_UPDATED","MERCHANT_VERIFICATION_REVIEWED","MERCHANT_VERIFICATION_VIEWED","MERCHANT_PLACE_CLAIM_ATTACHMENT_VIEWED","MERCHANT_PLACE_CLAIM_APPROVED","MERCHANT_PLACE_CLAIM_REJECTED","MERCHANT_PLACE_APPLICATION_APPROVED","MERCHANT_PLACE_APPLICATION_REJECTED","MERCHANT_PLACE_APPLICATION_VIEWED","MERCHANT_PLACE_APPLICATION_ATTACHMENT_VIEWED","OUTBOX_EVENT_RETRIED","AD_CREATED","AD_DELETED","RESERVATION_CONFIRMED","RESERVATION_REJECTED"]},"targetType":{"type":"string","description":"대상 유형","example":"USER","enum":["USER","REPORT","COMMUNITY_REPORT","APPEAL","POST","PLACE","PLACE_DUPLICATE_CANDIDATE","PLACE_INFORMATION_EVIDENCE","PLACE_INFORMATION_REPORT","PLACE_INFORMATION_DISPUTE","PLACE_INFORMATION_REVERIFICATION","VISITOR_VERIFICATION_REPORT","VISITOR_VERIFICATION_REPORT_CORRECTION","SCOUT_FIELD_REPORT","SCOUT_PROFILE","SCOUT_ACTIVITY_ELIGIBILITY","PLACE_OPERATING_NOTICE","PLACE_EVENT","TRUST_SCORE_ANOMALY","TRUST_SCORE_INTERVENTION_RULE","NOTIFICATION","OUTBOX_EVENT","MERCHANT_OWNER","MERCHANT_VERIFICATION","MERCHANT_PLACE_CLAIM_ATTACHMENT","MERCHANT_PLACE_CLAIM","MERCHANT_PLACE_APPLICATION","MERCHANT_PLACE_APPLICATION_ATTACHMENT","AD","RESERVATION"]},"targetId":{"type":"string","description":"대상 ID","example":"7"},"reason":{"type":"string","description":"작업 사유","example":"반복적인 신고 누적"},"beforeState":{"type":"string","description":"작업 전 상태 JSON"},"afterState":{"type":"string","description":"작업 후 상태 JSON"},"requestId":{"type":"string","description":"요청 ID","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"createdAt":{"type":"string","description":"감사 로그 생성 시각","format":"date-time"}},"description":"관리자 감사 로그 아이템"},"AdminAuditLogResponse":{"type":"object","properties":{"auditLogs":{"type":"array","items":{"$ref":"#/components/schemas/AdminAuditLogItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 감사 로그 목록 응답"},"OAuthAccountDisconnectRequest":{"type":"object","properties":{"currentPassword":{"type":"string","description":"마지막 OAuth 계정을 해제할 때 확인할 현재 비밀번호","nullable":true,"example":"password123"}},"description":"OAuth 계정 연결 해제 요청"},"OAuthAccountResponse":{"type":"object","properties":{"provider":{"type":"string","description":"OAuth Provider","example":"GOOGLE"},"linked":{"type":"boolean","description":"연결 여부","example":false},"message":{"type":"string","description":"처리 결과 메시지","example":"Google 계정 연결을 해제했습니다."}},"description":"OAuth 계정 상태 응답"},"AdminRoleAssignmentRevokeRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"역할을 회수하는 사유","example":"담당 업무 변경"}},"description":"관리자 역할 회수 요청"},"AdminS3OrphanDeleteRequest":{"required":["reportId"],"type":"object","properties":{"reportId":{"type":"string"},"keys":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"confirmed":{"type":"boolean"}}},"S3OrphanDeleteFailure":{"type":"object","properties":{"key":{"type":"string"},"reason":{"type":"string"}}},"S3OrphanDeleteResult":{"type":"object","properties":{"requestedKeyCount":{"type":"integer","format":"int32"},"deletedKeyCount":{"type":"integer","format":"int32"},"failedKeyCount":{"type":"integer","format":"int32"},"deletedKeys":{"type":"array","items":{"type":"string"}},"failedKeys":{"type":"array","items":{"$ref":"#/components/schemas/S3OrphanDeleteFailure"}}}},"ProviderEnvelopeV1":{"title":"Pingdom provider envelope v1","oneOf":[{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["searchNearbyPlaces"]},"args":{"required":["useCurrentLocation"],"type":"object","properties":{"useCurrentLocation":{"type":"boolean"},"touristCategory":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["searchNearbyReservablePlaces"]},"args":{"required":["date","endTime","quantity","startTime","useCurrentLocation"],"type":"object","properties":{"touristCategory":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]},"date":{"pattern":"^(?!0000)[0-9]{4}-[0-9]{2}-[0-9]{2}$","type":"string","format":"date"},"startTime":{"pattern":"^(?:[01][0-9]|2[0-3]):[0-5][0-9]$","type":"string"},"endTime":{"pattern":"^(?:[01][0-9]|2[0-3]):[0-5][0-9]$","type":"string"},"quantity":{"maximum":12,"minimum":1,"type":"integer"},"useCurrentLocation":{"type":"boolean"}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["getPlaceDetails"]},"args":{"required":["placeId"],"type":"object","properties":{"placeId":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["getAvailabilities"]},"args":{"required":["date","placeId","quantity"],"type":"object","properties":{"placeId":{"maximum":9007199254740991,"minimum":1,"type":"integer"},"date":{"pattern":"^(?!0000)[0-9]{4}-[0-9]{2}-[0-9]{2}$","type":"string","format":"date"},"quantity":{"maximum":12,"minimum":1,"type":"integer"}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["prepareReservation"]},"args":{"required":["availabilityId","placeId","quantity"],"type":"object","properties":{"placeId":{"maximum":9007199254740991,"minimum":1,"type":"integer"},"availabilityId":{"maximum":9007199254740991,"minimum":1,"type":"integer"},"quantity":{"maximum":12,"minimum":1,"type":"integer"}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["cancelVoiceSession"]},"args":{"type":"object","properties":{},"additionalProperties":false}},"additionalProperties":false},{"required":["field","id","kind","schemaVersion","text"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["clarification_request"]},"field":{"type":"string","enum":["touristCategory","date","timeRange","quantity","useCurrentLocation","placeId","availabilityId"]},"text":{"maxLength":2000,"minLength":1,"pattern":"\\S","type":"string"}},"additionalProperties":false},{"required":["id","kind","schemaVersion","text"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["assistant_message"]},"text":{"maxLength":2000,"minLength":1,"pattern":"\\S","type":"string"}},"additionalProperties":false},{"required":["code","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["protocol_error"]},"code":{"type":"string","enum":["UNSUPPORTED_REQUEST","PROVIDER_UNAVAILABLE","INVALID_RESPONSE"]}},"additionalProperties":false}]},"MerchantReservationDetailResponse":{"type":"object","properties":{"reservation":{"$ref":"#/components/schemas/ReservationResponse"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"statusHistory":{"type":"array","items":{"$ref":"#/components/schemas/ReservationStatusHistoryResponse"}}}},"ReservationStatusHistoryResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"changedBy":{"type":"integer","format":"int64"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}} \ No newline at end of file +{"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://127.0.0.1:64060","description":"Generated server url"}],"tags":[{"name":"내 정보·계정 연동","description":"내 정보 조회·변경, 계정 연동 및 탈퇴"},{"name":"여행","description":"여행 목적 선호, 여행 일정 및 활동 의향"},{"name":"장소 탐색","description":"지도·검색·추천과 인기 장소 탐색"},{"name":"장소 상세·메뉴","description":"장소 상세, 메뉴, 운영 공지 및 미디어"},{"name":"즐겨찾기","description":"관심 장소 저장 및 조회"},{"name":"내 리뷰","description":"내가 작성한 장소 리뷰 조회"},{"name":"장소 정보 제보","description":"장소 정보 제보 및 이의 제기"},{"name":"방문 인증","description":"위치 체크인, 방문 증빙 및 검증 보고"},{"name":"스카우트","description":"스카우트 프로필 및 현장 보고"},{"name":"커뮤니티 게시글","description":"게시글 작성·탐색 및 연결 장소 조회"},{"name":"댓글·좋아요","description":"게시글 댓글 및 좋아요"},{"name":"신고","description":"커뮤니티 게시글 및 댓글 신고"},{"name":"예약","description":"예약 생성·조회 및 취소 / 예약 및 처리 이력 조회"},{"name":"결제","description":"결제 내역 및 상세 조회 / 사업자 결제·정산 조회 및 환불"},{"name":"쿠폰·혜택","description":"혜택 탐색, 쿠폰 발급 및 조회"},{"name":"행사·팝업","description":"행사 및 팝업 캠페인 탐색"},{"name":"알림","description":"알림 수신 설정 및 기기 토큰 관리"},{"name":"상권 분석","description":"상권 분석 보고서 생성·조회·다운로드"},{"name":"사업자 정보","description":"사업자 프로필 등록 및 조회·변경"},{"name":"팀 관리","description":"장소 팀원 초대 및 권한 관리"},{"name":"장소 등록 신청","description":"장소 등록 신청 및 첨부 자료 관리"},{"name":"장소 정보 관리","description":"장소 정보·미디어·운영 상태 및 재검증 응답"},{"name":"메뉴·운영 공지","description":"메뉴와 장소 운영 공지 관리"},{"name":"리뷰 관리","description":"장소 리뷰 확인 및 삭제 심사 요청"},{"name":"예약 가능 시간","description":"예약 가능 시간 등록·변경 및 활성 상태 관리"},{"name":"예약 관리","description":"사업자 예약 조회·승인·반려 및 취소"},{"name":"캠페인·혜택","description":"캠페인·브랜드·혜택 및 쿠폰 사용 관리"},{"name":"Verified Boost","description":"Verified Boost 상품 조회·선택 및 실행 / Verified Boost 상품 등록 및 활성 상태 관리"},{"name":"실적","description":"사업자 운영 실적 조회"},{"name":"대시보드","description":"운영 현황, 최근 활동 및 처리 대기 항목"},{"name":"회원·권한","description":"회원 제재 및 관리자 역할 관리"},{"name":"사업자 관리","description":"사업자 심사 및 연결 장소 관리"},{"name":"장소 등록 심사","description":"장소 등록 신청과 증빙 확인 및 심사"},{"name":"장소 조회","description":"운영 대상 장소 목록 및 상세 조회"},{"name":"장소 정보·품질","description":"장소 정보 보정, 근거 검토 및 노출 상태 관리"},{"name":"중복·추천 관리","description":"중복 장소 검토·병합 및 추천 운영"},{"name":"제보·재검증","description":"장소 정보 제보 심사 및 재검증 요청 관리"},{"name":"행사·운영 공지","description":"행사 발행 및 운영 공지 관리"},{"name":"리뷰 삭제 심사","description":"장소 리뷰 삭제 요청 확인 및 심사"},{"name":"커뮤니티 관리","description":"게시글과 댓글 운영 조회"},{"name":"신고·이의신청","description":"신고 및 이의신청 검토·처리, 신고 콘텐츠 삭제"},{"name":"신뢰 점수","description":"신뢰 점수·이상 징후 및 개입 규칙 관리"},{"name":"방문 인증·스카우트","description":"방문 보고 심사 및 스카우트 자격 관리"},{"name":"알림·발송 이력","description":"운영 알림 확인 및 발송 이력 조회"},{"name":"감사·개인정보 처리 이력","description":"관리자 작업 감사 및 개인정보 처리 이력 조회"},{"name":"Outbox·스토리지 운영","description":"Outbox 재처리 및 스토리지 고아 객체 관리"},{"name":"로그인·세션","description":"로그인, 토큰 갱신 및 로그아웃"},{"name":"회원가입·이메일 인증","description":"회원가입 및 이메일 인증"},{"name":"비밀번호 재설정","description":"비밀번호 재설정 요청 및 확인"},{"name":"장소 리뷰","description":"장소 리뷰 작성 및 목록 조회"},{"name":"리뷰 미디어","description":"장소 리뷰 첨부 미디어 업로드 및 삭제"},{"name":"서비스 기본","description":"서비스 기본 응답"},{"name":"상담 시작","description":"상권 상담 안내 및 초기 상담"},{"name":"Voice AI","description":"인증 사용자 음성 AI Gateway API"}],"paths":{"/users/me/travel-purposes":{"get":{"tags":["여행"],"summary":"여행 목적 선호 조회","description":"현재 인증된 사용자의 여행 목적 선호 목록을 조회합니다.","operationId":"getTravelPurposes","responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelPurposePreferenceResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["여행"],"summary":"여행 목적 선호 전체 변경","description":"현재 인증된 사용자의 여행 목적 선호를 요청 목록으로 전체 교체합니다.","operationId":"replaceTravelPurposes","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TravelPurposePreferenceUpdateRequest"}}},"required":true},"responses":{"200":{"description":"변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelPurposePreferenceResponse"}}}},"400":{"description":"요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/scout-profile":{"get":{"tags":["스카우트"],"summary":"내 Scout 프로필 및 활동 자격 조회","description":"Scout 프로필을 아직 신청하지 않은 사용자는 404 SCOUT_PROFILE_NOT_FOUND를 받습니다.","operationId":"get_1","responses":{"404":{"description":"Scout 프로필을 찾을 수 없음 (SCOUT_PROFILE_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_NOT_FOUND":{"description":"SCOUT_PROFILE_NOT_FOUND","value":{"message":"Scout 프로필을 찾을 수 없습니다.","code":"SCOUT_PROFILE_NOT_FOUND"}}}}}},"200":{"description":"Scout 프로필 및 활동 자격 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["스카우트"],"summary":"내 Scout 프로필 수정","description":"활성 일반 사용자이며 프로필 상태가 PENDING 또는 ACTIVE일 때만 수정할 수 있습니다.\nSUSPENDED 또는 REVOKED 프로필은 409 INVALID_SCOUT_PROFILE_STATE를 반환합니다.\n활동 자격 상태(PENDING, ELIGIBLE, SUSPENDED, EXPIRED, REVOKED)는 프로필 수정 가능 여부를\n변경하지 않으며 Scout 활동 가능 여부를 판단하는 데 사용합니다.\n","operationId":"update","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileRequest"}}},"required":true},"responses":{"404":{"description":"Scout 프로필을 찾을 수 없음 (SCOUT_PROFILE_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_NOT_FOUND":{"description":"SCOUT_PROFILE_NOT_FOUND","value":{"message":"Scout 프로필을 찾을 수 없습니다.","code":"SCOUT_PROFILE_NOT_FOUND"}}}}}},"200":{"description":"Scout 프로필 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"403":{"description":"활성 일반 사용자 계정이 아님 (SCOUT_PROFILE_ACCOUNT_REQUIRED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_ACCOUNT_REQUIRED":{"description":"SCOUT_PROFILE_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 Scout 프로필을 신청할 수 있습니다.","code":"SCOUT_PROFILE_ACCOUNT_REQUIRED"}}}}}},"409":{"description":"현재 프로필 상태에서 수정 불가 (INVALID_SCOUT_PROFILE_STATE)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_SCOUT_PROFILE_STATE":{"description":"INVALID_SCOUT_PROFILE_STATE","value":{"message":"현재 Scout 프로필 상태에서는 요청을 처리할 수 없습니다.","code":"INVALID_SCOUT_PROFILE_STATE"}}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["스카우트"],"summary":"Scout 프로필 신청","description":"활성 일반 사용자만 Scout 프로필을 신청할 수 있습니다.\nPENDING, ACTIVE, SUSPENDED, REVOKED를 포함해 기존 Scout 프로필이 하나라도 있으면\n재신청할 수 없습니다.\n","operationId":"apply","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileRequest"}}},"required":true},"responses":{"403":{"description":"활성 일반 사용자 계정이 아님 (SCOUT_PROFILE_ACCOUNT_REQUIRED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_ACCOUNT_REQUIRED":{"description":"SCOUT_PROFILE_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 Scout 프로필을 신청할 수 있습니다.","code":"SCOUT_PROFILE_ACCOUNT_REQUIRED"}}}}}},"201":{"description":"Scout 프로필 신청 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"409":{"description":"이미 존재하는 Scout 프로필 (SCOUT_PROFILE_ALREADY_EXISTS)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SCOUT_PROFILE_ALREADY_EXISTS":{"description":"SCOUT_PROFILE_ALREADY_EXISTS","value":{"message":"Scout 프로필이 이미 존재합니다.","code":"SCOUT_PROFILE_ALREADY_EXISTS"}}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{id}":{"get":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 상세 조회","description":"NEW_PLACE이면 newPlace에 저장된 장소 입력값 전체를 반환합니다. 첨부파일은 별도 첨부 API로 조회·관리합니다.","operationId":"get_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 수정","operationId":"update_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-owner-profile":{"get":{"tags":["사업자 정보"],"summary":"내 Merchant Owner 신청 조회","operationId":"get_3","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["사업자 정보"],"summary":"내 Merchant Owner 프로필 수정","operationId":"update_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["사업자 정보"],"summary":"Merchant Owner 신청","description":"프로필을 생성하거나 거절·회수된 신청을 다시 제출합니다.","operationId":"apply_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/current-activity-intent":{"get":{"tags":["여행"],"summary":"현재 행동 의도 조회","description":"만료되지 않은 현재 행동 의도를 조회합니다.","operationId":"getCurrentActivityIntent","responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CurrentActivityIntentResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["여행"],"summary":"현재 행동 의도 변경","description":"행동 의도를 2시간 동안 유지하도록 설정하거나 갱신합니다.","operationId":"replaceCurrentActivityIntent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentActivityIntentUpdateRequest"}}},"required":true},"responses":{"400":{"description":"요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CurrentActivityIntentResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["여행"],"summary":"현재 행동 의도 해제","description":"현재 행동 의도를 즉시 삭제합니다.","operationId":"clearCurrentActivityIntent","responses":{"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"204":{"description":"해제 성공"},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-schedule":{"put":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 장소 영업시간 변경","operationId":"updateOperatingSchedule","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingScheduleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingScheduleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/media/representative":{"put":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 대표 미디어 지정","operationId":"updateRepresentative","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerRepresentativeMediaUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/information":{"get":{"tags":["장소 정보 관리"],"summary":"Merchant 장소 정보 조회","description":"장소 관리자 또는 소유자만 본인 장소의 Merchant 관리 정보를 조회합니다. 권한 부족은 MERCHANT_TEAM_PERMISSION_REQUIRED, 정보 미등록은 PLACE_INFORMATION_NOT_FOUND로 구분합니다.","operationId":"get_9","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"장소 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceInformationResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소 정보를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["장소 정보 관리"],"summary":"Merchant 장소 정보 등록 및 수정","description":"장소 관리자 또는 소유자가 장소 소개와 방문 전환 링크를 등록하거나 전체 교체합니다. URL·길이 검증은 VALIDATION_FAILED, 권한 부족은 MERCHANT_TEAM_PERMISSION_REQUIRED, 대상 장소 없음은 PLACE_NOT_FOUND로 응답합니다.","operationId":"upsert","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceInformationUpdateRequest"}}},"required":true},"responses":{"200":{"description":"수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceInformationResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"403":{"description":"장소 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_PERMISSION_REQUIRED":{"description":"MERCHANT_TEAM_PERMISSION_REQUIRED","value":{"message":"Merchant 팀원 관리 권한이 필요합니다.","code":"MERCHANT_TEAM_PERMISSION_REQUIRED"}}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_NOT_FOUND":{"description":"PLACE_NOT_FOUND","value":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값이 올바르지 않습니다.","code":"VALIDATION_FAILED","errors":{"websiteUrl":"웹사이트 URL은 http:// 또는 https://로 시작해야 합니다."}}}}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities/{availabilityId}":{"put":{"tags":["예약 가능 시간"],"summary":"예약 가능 시간 수정","description":"productId, productType을 보내면 null이어도 400 INVALID_REQUEST_BODY로 거절합니다. 상품 필드를 제거한 단일 예약 슬롯 본문을 사용하세요.","operationId":"update_3","parameters":[{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityUpsertRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities/{availabilityId}/reservation-terms":{"put":{"tags":["예약 가능 시간"],"summary":"예약 시간대·취소 조건 설정","description":"취소 정책은 명시적 취소 불가 또는 시작 전 지정 기한까지 취소 가능입니다. 기존 예약의 수락 조건은 변경하지 않습니다. unitAmountMinor, additionalAmountMinor, currency를 보내면 null이어도 400 INVALID_REQUEST_BODY로 거절합니다.","operationId":"updateTerms","parameters":[{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationTermsRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationTermsResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}":{"put":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 수정","description":"관리자가 Trust Score 개입 규칙 내용을 수정합니다.","operationId":"updateRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/places":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 연결 장소 및 운영 품질 조회","operationId":"listPlaces_2","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOwnerPlaceResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 장소 연결 변경","description":"현재 연결 장소를 요청의 placeIds 전체로 교체합니다. 빈 목록은 모든 장소 연결을 해제합니다. Merchant Owner 승인과는 별도 요청 및 별도 트랜잭션입니다.","operationId":"replacePlaces","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/places/{placeId}/quality":{"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 장소 운영 품질 지표 변경","operationId":"updateOperationalQuality","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceQualityUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/onboarding":{"put":{"tags":["사업자 관리"],"summary":"Merchant Owner 온보딩 완료도 변경","operationId":"updateOnboarding","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOnboardingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/voice-ai/sessions":{"post":{"tags":["Voice AI"],"summary":"음성 AI 세션 생성","description":"JWT 사용자 소유 세션을 생성합니다. 세션은 5분 뒤 만료됩니다.","operationId":"create","responses":{"201":{"description":"세션 생성 성공","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceAiSessionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/voice-ai/sessions/{sessionId}/refresh":{"post":{"tags":["Voice AI"],"summary":"음성 AI 세션 갱신","description":"활성 세션의 만료 시각을 현재 시점에서 5분으로 갱신합니다.","operationId":"refresh","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceAiSessionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"SESSION_FORBIDDEN: 다른 사용자 세션. ACCESS_DENIED: 공통 접근 거부","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"SESSION_NOT_FOUND: 존재하지 않는 세션","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"SESSION_EXPIRED: 만료 또는 종료된 세션은 갱신할 수 없습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/voice-ai/sessions/{sessionId}/messages":{"post":{"tags":["Voice AI"],"summary":"음성 AI 메시지 전송","description":"ProviderEnvelope v1 최종 JSON 1개만 반환합니다. SSE/WebSocket/reconnect cursor는 지원하지 않습니다.\n최종 envelope는 UTF-8 16 KiB 이하이며 id는 requestId와 정확히 일치합니다.\n활성 세션 내 requestId를 대소문자 구분하여 비교합니다. 동일 ID·동일 text(UTF-8 SHA-256)는 저장된 결과를\n반환하고 다른 text는 409 REPLAY_CONFLICT입니다. 진행 중 재요청은 provider 호출을 중복하지 않고 결과 저장까지\n잠금 없이 재조회합니다. 갱신·종료도 진행 중 요청 완료 후 반영합니다. 실패하여 결과가 저장되지 않았다면 재시도에서 provider를 다시 호출합니다.\n결과는 세션이 활성인 동안 재사용하며 refresh는 이 기간을 연장합니다. 만료·종료 후에는 replay도 410입니다.\n현재 저장 데이터의 자동 삭제 기간은 설정되어 있지 않습니다. 앱의 epoch/generation 및 256개 ledger는 앱 소유입니다.\n앱의 30초 deadline이나 연결 종료는 서버/provider 취소를 보장하지 않습니다. 서버 처리가 커밋되었다면\n동일 ID/text 재시도로 결과를 회수할 수 있습니다. DELETE는 진행 중 전송 완료 후 세션을 종료하며 호출을 취소하지 않습니다.\nprovider 연결/read timeout은 gemini 설정(기본 2초/5초)이며 서버 전체 deadline을 의미하지 않습니다.\n","operationId":"send","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceAiMessageRequest"}}},"required":true},"responses":{"502":{"description":"PROVIDER_UNAVAILABLE: provider timeout·일반 장애·비활성 설정. PROVIDER_RESPONSE_INVALID: schema 위반·16 KiB 초과. timeout 전용 code는 없습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"SESSION_EXPIRED: 만료 또는 종료된 세션. replay도 반환하지 않습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"ProviderEnvelope v1 최종 JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderEnvelopeV1"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"SESSION_FORBIDDEN: 다른 사용자 세션. ACCESS_DENIED: 공통 접근 거부","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"VALIDATION_FAILED: text/requestId 검증 실패(errors 포함). INVALID_REQUEST_BODY: JSON 파싱 실패.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"409":{"description":"REPLAY_CONFLICT: 동일 세션·requestId에 다른 text를 보냈습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED: controller 진입 시 IP 기준 Redis 제한. consultations/intro와 공유하며 기본 1분 10회(설정 가능). replay도 제한에 포함됩니다. Retry-After는 제공하지 않습니다. 즉시 반복하지 말고 backoff 후 동일 requestId/text로 재시도합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"RATE_LIMIT_UNAVAILABLE: fail-open=false일 때 제한 저장소 장애. backoff 후 재시도합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"SESSION_NOT_FOUND: 존재하지 않는 세션","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/visitor-verification-reports":{"get":{"tags":["방문 인증"],"summary":"내 방문자 검증 제보 목록 조회","operationId":"listMine","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"400":{"description":"페이지 요청 값 검증 실패 (VALIDATION_FAILED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"page":"1 이상이어야 합니다."}}}}}}},"403":{"description":"활성 일반 사용자 계정이 아님 (TOURIST_ACCOUNT_REQUIRED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}}}}}},"200":{"description":"내 제보 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportPageResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["방문 인증"],"summary":"방문자 검증 제보 생성","description":"활성 일반 사용자가 장소와 제보 유형별로 처리 중인 제보가 없을 때 새 제보를 제출합니다.\n구조화 필드는 reportType과 일치해야 하며, 같은 장소·유형의 SUBMITTED 제보가 있으면 409를 반환합니다.\n","operationId":"submit","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCreateRequest"}}},"required":true},"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"201":{"description":"제보 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportResponse"}}}},"409":{"description":"같은 장소·유형의 처리 중 제보가 이미 있음 (ACTIVE_REPORT_ALREADY_EXISTS)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACTIVE_REPORT_ALREADY_EXISTS":{"description":"ACTIVE_REPORT_ALREADY_EXISTS","value":{"message":"같은 장소와 유형의 처리 중인 제보가 이미 있습니다.","code":"ACTIVE_REPORT_ALREADY_EXISTS"}}}}}},"400":{"description":"요청 검증 실패 또는 제보 유형과 구조화 정보 불일치","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/ErrorResponse"}]},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"description":"공백일 수 없습니다."}}},"INVALID_REPORT_DETAILS":{"description":"INVALID_REPORT_DETAILS","value":{"message":"제보 유형과 구조화 정보가 일치하지 않습니다.","code":"INVALID_REPORT_DETAILS"}}}}}},"404":{"description":"장소를 찾을 수 없음 (PLACE_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_NOT_FOUND":{"description":"PLACE_NOT_FOUND","value":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}}}},"403":{"description":"활성 일반 사용자 계정이 아님 (TOURIST_ACCOUNT_REQUIRED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}}}}}}},"security":[{"bearerAuth":[]}]}},"/visitor-verification-reports/{reportId}/corrections":{"get":{"tags":["방문 인증"],"summary":"내 방문자 검증 제보 정정 이력 조회","operationId":"listCorrections","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"200":{"description":"제보 정정 이력 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportCorrectionPageResponse"}}}},"400":{"description":"페이지 요청 값 검증 실패 (VALIDATION_FAILED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"page":"1 이상이어야 합니다."}}}}}}},"403":{"description":"활성 일반 사용자 계정이 아니거나 본인 소유 제보가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}},"CORRECTION_FORBIDDEN":{"description":"CORRECTION_FORBIDDEN","value":{"message":"이 제보 정정을 조회할 권한이 없습니다.","code":"CORRECTION_FORBIDDEN"}}}}}},"404":{"description":"제보를 찾을 수 없음 (REPORT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"REPORT_NOT_FOUND":{"description":"REPORT_NOT_FOUND","value":{"message":"방문자 검증 제보를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["방문 인증"],"summary":"방문자 검증 제보 정정 제출","description":"제보 소유자만 정정을 제출할 수 있습니다.\n원본 제보 상태가 ACCEPTED 또는 REJECTED일 때만 허용되며, 처리 중인 정정이 있으면 새 정정을 제출할 수 없습니다.\n","operationId":"submitCorrection","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionRequest"}}},"required":true},"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"201":{"description":"제보 정정 제출 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportCorrectionResponse"}}}},"409":{"description":"정정 불가 상태 또는 처리 중인 정정 존재","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CORRECTION_NOT_ALLOWED":{"description":"CORRECTION_NOT_ALLOWED","value":{"message":"현재 제보 상태에서는 정정을 제출할 수 없습니다.","code":"CORRECTION_NOT_ALLOWED"}},"ACTIVE_CORRECTION_ALREADY_EXISTS":{"description":"ACTIVE_CORRECTION_ALREADY_EXISTS","value":{"message":"처리 중인 제보 정정이 이미 있습니다.","code":"ACTIVE_CORRECTION_ALREADY_EXISTS"}}}}}},"400":{"description":"요청 검증 실패 또는 정정 내용 불일치","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/ErrorResponse"}]},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"description":"공백일 수 없습니다."}}},"INVALID_CORRECTION_DETAILS":{"description":"INVALID_CORRECTION_DETAILS","value":{"message":"제보 정정 내용이 올바르지 않습니다.","code":"INVALID_CORRECTION_DETAILS"}}}}}},"404":{"description":"제보를 찾을 수 없음 (REPORT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"REPORT_NOT_FOUND":{"description":"REPORT_NOT_FOUND","value":{"message":"방문자 검증 제보를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}}},"403":{"description":"활성 일반 사용자 계정이 아니거나 본인 소유 제보가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}},"REPORT_FORBIDDEN":{"description":"REPORT_FORBIDDEN","value":{"message":"이 제보를 조회할 권한이 없습니다.","code":"REPORT_FORBIDDEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/visit-verification-sessions":{"post":{"tags":["방문 인증"],"summary":"체류 기반 방문 인증 시작","description":"장소 반경 안의 첫 위치 관측으로 인증 세션을 시작합니다. 앱은 nextObservationRecommendedAt 이전에 다음 위치를 제출해야 하며, 원본 좌표는 저장하지 않습니다.","operationId":"start","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitVerificationStartRequest"}}},"required":true},"responses":{"422":{"description":"장소 인증 허용 반경 밖","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"인증 가능한 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"관측 시각 또는 GPS 정확도 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"동일 장소의 진행 중인 인증 세션이 동시에 생성됨","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"인증 세션 시작 또는 진행 중·완료 세션 재반환","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitVerificationSessionResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/visit-verification-sessions/{sessionId}/observations":{"post":{"tags":["방문 인증"],"summary":"체류 인증 위치 관측 제출","description":"서버 수신 시각과 연속 관측 간격으로 체류 시간을 계산합니다. 반경 이탈은 PROXIMITY_LOST, 관측 공백 또는 세션 기한 초과는 EXPIRED로 반환됩니다.","operationId":"submitObservation","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitVerificationObservationRequest"}}},"required":true},"responses":{"404":{"description":"본인 소유 인증 세션 또는 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"진행 상태 또는 완료 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitVerificationSessionResponse"}}}},"409":{"description":"일일 완료 방문 인증이 이미 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"관측 시각 또는 GPS 정확도 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/visit-verification-sessions/foreground":{"post":{"tags":["방문 인증"],"summary":"좌표 기반 foreground 방문 인증 시작","description":"장소 ID를 받지 않고 서버가 현재 좌표 주변의 공개·운영 중 장소를 판정해 인증 세션을 시작합니다. 진행 중인 동일 장소 세션은 우선 복구하며, 새 후보는 거리순으로 비교해 1·2순위 거리 차이가 GPS 정확도 두 배보다 클 때만 가장 가까운 장소를 선택합니다.","operationId":"startForeground","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForegroundVisitVerificationStartRequest"}}},"required":true},"responses":{"404":{"description":"현재 좌표에서 인증할 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"장소 인증 허용 반경 밖","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"현재 좌표에서 장소를 하나로 결정할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"관측 시각 또는 GPS 정확도 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"인증 세션 시작 또는 진행 중·완료 세션 재반환","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitVerificationSessionResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/travel-schedules":{"get":{"tags":["여행"],"summary":"내 여행 일정 목록 조회","description":"현재 인증된 사용자의 여행 일정을 조회합니다.","operationId":"getTravelSchedules","responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelScheduleListResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["여행"],"summary":"여행 일정 생성","description":"현재 인증된 사용자에게 날짜 범위의 여행 일정을 추가합니다.","operationId":"createTravelSchedule","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TravelScheduleCreateRequest"}}},"required":true},"responses":{"400":{"description":"기간 역전 또는 과거 날짜","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidPeriod":{"description":"invalidPeriod","value":{"message":"여행 종료일은 시작일보다 빠를 수 없습니다.","code":"INVALID_TRAVEL_SCHEDULE_PERIOD"}},"pastStartDate":{"description":"pastStartDate","value":{"message":"여행 시작일은 오늘보다 이전일 수 없습니다.","code":"TRAVEL_SCHEDULE_START_DATE_IN_PAST"}}}}}},"201":{"description":"생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelScheduleResponse"}}}},"409":{"description":"기존 일정과 기간 겹침","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"기존 여행 일정과 기간이 겹칩니다.","code":"TRAVEL_SCHEDULE_PERIOD_OVERLAP"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/travel-schedules/{scheduleId}/cancel":{"post":{"tags":["여행"],"summary":"여행 일정 취소","description":"본인 여행 일정을 취소 상태로 전환합니다.","operationId":"cancelTravelSchedule","parameters":[{"name":"scheduleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"일정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"취소 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelScheduleResponse"}}}},"409":{"description":"다른 요청으로 일정이 변경됨","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/profile-image":{"post":{"tags":["내 정보·계정 연동"],"summary":"내 프로필 이미지 변경","description":"JPEG 또는 PNG 프로필 이미지를 업로드하고 즉시 변경합니다.","operationId":"changeProfileImage","requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"400":{"description":"파일이 비어 있거나 허용되지 않은 이미지 형식","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"파일 크기 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"프로필 이미지 저장소 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"프로필 이미지 변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProfileImageUploadResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/oauth-accounts/google/link":{"post":{"tags":["내 정보·계정 연동"],"summary":"Google 계정 연결 시작","description":"현재 인증된 사용자 계정에 Google OAuth 계정을 연결하기 위한 OAuth 인증 흐름을 시작합니다.","operationId":"startGoogleLink","responses":{"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"연결 시작 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OAuthAccountLinkStartResponse"},"example":{"provider":"GOOGLE","authorizationUrl":"/oauth2/authorization/google","message":"Google 계정 연결을 시작합니다."}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications":{"get":{"tags":["장소 등록 신청"],"summary":"내 Merchant 장소 신청 목록 조회","operationId":"list","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 생성","operationId":"create_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{id}/submit":{"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 제출","operationId":"submit_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{id}/reopen":{"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 재개","operationId":"reopen","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{id}/cancel":{"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 취소","operationId":"cancel","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{applicationId}/attachments":{"get":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 첨부파일 목록 조회","operationId":"list_1","parameters":[{"name":"applicationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceApplicationAttachmentResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 첨부파일 업로드","description":"NEW_PLACE와 EXISTING_PLACE_CLAIM 초안에만 업로드할 수 있습니다. 서버가 파일 형식·서명·크기·악성코드를 검증하고 private 저장소에 보관합니다.","operationId":"upload","parameters":[{"name":"applicationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"documentType","in":"query","required":true,"schema":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationAttachmentResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{applicationId}/attachments/reorder":{"post":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 대표 이미지 순서 변경","operationId":"reorder","parameters":[{"name":"applicationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"attachmentIds","in":"query","required":true,"schema":{"type":"array","items":{"type":"integer","format":"int64"}}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/bookmarks":{"get":{"tags":["즐겨찾기"],"summary":"장소 북마크 목록 조회","description":"현재 인증된 사용자가 북마크한 장소 목록을 조회합니다.","operationId":"listBookmarks","parameters":[{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"북마크 목록 조회 성공","content":{"*/*":{"example":{"places":[{"id":17,"name":"진주성","address":"경상남도 진주시 남강로 626","latitude":35.1894,"longitude":128.0789}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["즐겨찾기"],"summary":"장소 북마크 추가","description":"placeId를 기반으로 장소를 북마크에 추가합니다.","operationId":"createBookmark","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookmarkCreateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"201":{"description":"북마크 추가 성공","content":{"*/*":{"example":{"id":1,"placeId":17,"message":"장소 북마크를 추가했습니다."}}}},"409":{"description":"이미 북마크한 장소","content":{"*/*":{"example":{"message":"이미 북마크한 장소입니다.","code":"BOOKMARK_ALREADY_EXISTS"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/change-pw":{"post":{"tags":["내 정보·계정 연동"],"summary":"비밀번호 변경","description":"현재 비밀번호를 확인한 뒤 새 비밀번호로 변경합니다.","operationId":"changePassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"200":{"description":"비밀번호 변경 성공","content":{"*/*":{"example":"비밀번호 변경 완료"}}},"401":{"description":"현재 비밀번호 불일치 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid-credentials":{"description":"invalid-credentials","value":{"message":"아이디 또는 비밀번호가 올바르지 않습니다.","code":"INVALID_CREDENTIALS"}},"invalid-token":{"description":"invalid-token","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"400":{"description":"입력값 검증 실패 또는 새 비밀번호 확인 불일치","content":{"*/*":{"examples":{"validation-failure":{"description":"validation-failure","value":{"message":"입력값을 확인해주세요.","errors":{"newPassword":"비밀번호는 8자 이상이어야 합니다."}}},"password-mismatch":{"description":"password-mismatch","value":{"message":"비밀번호가 서로 다릅니다.","code":"PASSWORD_MISMATCH"}}}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/change-id":{"post":{"tags":["내 정보·계정 연동"],"summary":"아이디 변경","description":"현재 인증된 사용자의 아이디를 새 아이디로 변경합니다.","operationId":"changeUsername","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeUsernameRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"newUsername":"아이디는 4자 이상 50자 이하여야 합니다."}}}}},"200":{"description":"아이디 변경 성공","content":{"*/*":{"example":"아이디 변경 완료"}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"409":{"description":"이미 사용 중인 아이디","content":{"*/*":{"example":{"message":"이미 있는 아이디입니다.","code":"USERNAME_ALREADY_EXISTS"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/scout-field-reports":{"get":{"tags":["스카우트"],"summary":"내 Scout 현장 제보 목록 조회","operationId":"listMine_2","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["스카우트"],"summary":"Scout 현장 제보 생성","operationId":"submit_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportCreateRequest"}}},"required":true},"responses":{"403":{"description":"활성 Scout 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"201":{"description":"현장 제보 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"409":{"description":"처리 중인 동일 제보 존재","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"400":{"description":"제보 내용 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/routes":{"post":{"tags":["장소 탐색"],"summary":"자동차·대중교통·보행자 추천 경로 조회","description":"WGS84 출발·도착 좌표로 자동차는 NAVER Directions, 대중교통·보행자는 TMAP 경로를 조회합니다. JWT 인증 필수이며 공급자 키는 서버에서 관리합니다. 자전거는 지원하지 않습니다. 응답은 저장하지 않으며 자동 재시도를 하지 않습니다. 기본 사용자당 10회/분, IP당 100회/분이며 설정에 따라 달라질 수 있습니다.","operationId":"findRoute","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RouteRequest"},"example":{"origin":{"latitude":37.5665,"longitude":126.978},"destination":{"latitude":37.4979,"longitude":127.0276},"mode":"car"}}},"required":true},"responses":{"403":{"description":"기존 접근 권한 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"ROUTE_RATE_LIMITED: 사용자/IP 제한 초과","headers":{"Retry-After":{"description":"두 제한 구간 중 긴 시간(초), 안전한 재시도 대기 상한","style":"simple","schema":{"type":"integer"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"기존 JWT 인증 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"504":{"description":"ROUTE_PROVIDER_TIMEOUT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"ROUTE_PROVIDER_UNAVAILABLE: 비활성·미설정·공급자 인증/쿼터/장애/비정상 응답. 호출 제한 저장소 장애는 기존 RATE_LIMIT_UNAVAILABLE","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"자동차, 대중교통 또는 보행자 경로","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RouteResponse"},{"$ref":"#/components/schemas/TransitRouteResponse"},{"$ref":"#/components/schemas/WalkingRouteResponse"}]}}}},"400":{"description":"INVALID_ROUTE_REQUEST: 누락·문자열·비유한 좌표, 범위 오류, 동일 좌표, 알 수 없는 mode","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"UNSUPPORTED_ROUTE_MODE 또는 ROUTE_NOT_FOUND","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"unsupported":{"description":"unsupported","value":{"message":"지원하지 않는 이동수단입니다.","code":"UNSUPPORTED_ROUTE_MODE"}},"notFound":{"description":"notFound","value":{"message":"자동차 경로를 찾을 수 없습니다.","code":"ROUTE_NOT_FOUND"}}}}}}},"security":[{"bearerAuth":[]}]}},"/reservations":{"get":{"tags":["예약"],"summary":"내 예약 목록 조회","operationId":"list_2","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["예약"],"summary":"예약 생성","description":"confirmationToken을 제공하면 확인한 대상·시간·인원·취소 정책을 원자적으로 검증합니다. 토큰 생략은 기존 터치 계약이며 확인 조건 보장은 없습니다. 성공은 예약 생성(PENDING)이며 상점주 승인 대기 상태입니다. 응답 유실에는 동일 키·토큰·본문을 재전송하세요. 사용자별 키는 예약 또는 거절 기록이 보존되는 동안 만료하지 않습니다. 동일 요청의 성공은 견적 만료 후에도 201로 복구하며, 확정 거절은 같은 오류로 복구합니다. timeout/5xx는 결과 불명이므로 실패로 확정하거나 새 키를 만들지 않습니다. 조건 재확인 후 새 의도는 새 토큰·키로 제출합니다.","operationId":"create_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationCreateRequest"}}},"required":true},"responses":{"201":{"description":"예약 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"404":{"description":"QUOTE_NOT_FOUND: 본인 견적 부재. RESERVATION_SLOT_NOT_FOUND: 슬롯 부재. AVAILABILITY_NOT_FOUND: 기존 터치 요청의 예약 가능 시간 부재.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"IDEMPOTENCY_KEY_REUSED: 같은 키/토큰의 다른 요청. QUOTE_REQUEST_MISMATCH: 대상·인원 불일치. QUOTE_CONDITIONS_CHANGED, RESERVATION_SLOT_INACTIVE, RESERVATION_CAPACITY_EXCEEDED: 최신 조건을 다시 확인해야 합니다. AVAILABILITY_CAPACITY_EXCEEDED: 기존 터치 요청의 정원 부족.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"QUOTE_TERMS_UNAVAILABLE: 시간대/취소 정책 미설정 또는 시간 해석 불가. 취소 정책을 추정하지 않습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"QUOTE_EXPIRED: 견적 만료. 최신 조건과 새 토큰으로 재확인이 필요합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/reservations/{reservationId}/cancel":{"post":{"tags":["예약"],"summary":"내 예약 취소","operationId":"cancel_1","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"409":{"description":"CANCELLATION_NOT_ALLOWED: 취소 불가 또는 기한 경과. RESERVATION_REFUND_REQUIRED: 처리 중 결제/미환불 결제. INVALID_RESERVATION_STATE: 확정되지 않은 예약.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/reviews":{"get":{"tags":["장소 리뷰"],"summary":"장소 리뷰 목록 조회","operationId":"list_4","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PagePlaceReviewResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 리뷰"],"summary":"장소 리뷰 작성","operationId":"create_3","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceReviewCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceReviewResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/reviews/media":{"post":{"tags":["리뷰 미디어"],"summary":"장소 리뷰 사진 업로드","description":"리뷰 작성 전에 JPEG 또는 PNG 사진 한 개를 업로드합니다. 업로드된 사진은 24시간 안에 본인의 같은 장소 리뷰에 한 번만 연결할 수 있습니다.","operationId":"upload_1","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"415":{"description":"지원하지 않는 파일 형식","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"파일 크기 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"리뷰 사진 저장소 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"비어 있거나 손상된 파일","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"리뷰 사진 업로드 완료","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceReviewMediaUploadResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/map-link-conversions":{"post":{"tags":["장소 상세·메뉴"],"summary":"지도 링크 전환 기록","description":"같은 사용자·장소·전환 유형에서 requestId가 같은 재시도는 중복 집계하지 않고 204를 반환합니다.","operationId":"record","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"minimum":1,"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MapLinkConversionRequest"}}},"required":true},"responses":{"204":{"description":"전환 기록 또는 동일 요청 재처리 성공"},"400":{"description":"전환 요청값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/information-reports":{"post":{"tags":["장소 정보 제보"],"summary":"장소 정보 신고 생성","operationId":"submit_3","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/{id}/media/exploration":{"get":{"tags":["장소 상세·메뉴"],"summary":"장소 탐색용 미디어 조회","description":"탐색 화면에 노출할 장소 미디어만 조회합니다.","operationId":"getExplorationMedia","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"200":{"description":"탐색용 미디어 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 상세·메뉴"],"summary":"장소 탐색용 미디어 등록","description":"장소 소유자가 탐색 화면에 노출할 미디어를 등록합니다.","operationId":"createExplorationMedia","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMediaCreateRequest"}}},"required":true},"responses":{"201":{"description":"탐색용 미디어 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaItem"}}}},"403":{"description":"본인 소유가 아닌 장소 미디어 관리 시도","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"자신의 장소 미디어만 관리할 수 있습니다.","code":"OTHERS_PLACE_MEDIA_NOT_MANAGED"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/recommendations/click":{"post":{"tags":["장소 탐색"],"summary":"추천 장소 클릭 기록","description":"추천 목록에서 사용자가 선택한 장소 클릭을 기록합니다.","operationId":"recordRecommendationClick","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceRecommendationClickRequest"}}},"required":true},"responses":{"400":{"description":"요청값 검증 실패","content":{"*/*":{"example":{"message":"placeId는 필수입니다."}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"201":{"description":"추천 장소 클릭 기록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceRecommendationClickResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/information-reports/{reportId}/disputes":{"post":{"tags":["장소 정보 제보"],"summary":"장소 정보 신고 반박 생성","operationId":"submitDispute","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/offers/{offerId}/coupons":{"post":{"tags":["쿠폰·혜택"],"summary":"관광객 Coupon 발급","description":"진행 중인 여행 일정이 있는 일반 사용자에게 Offer당 한 번만 발급합니다. 발급 시 Offer 제목·혜택과 장소 정보를 Coupon에 스냅샷으로 저장합니다.","operationId":"issue","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"중복 발급, 발급 기간 종료 또는 수량 소진","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"Coupon 발급 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CouponResponse"}}}},"403":{"description":"관광객 발급 조건 불충족","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/verified-boost-selections":{"get":{"tags":["Verified Boost"],"summary":"내 Verified Boost 선택 목록 조회","operationId":"list_9","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostSelectionPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 선택","operationId":"select","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifiedBoostSelectionCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostSelectionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/verified-boost-executions":{"get":{"tags":["Verified Boost"],"summary":"내 Verified Boost 집행 목록 조회","operationId":"list_11","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostExecutionPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Verified Boost"],"summary":"Verified Boost 집행 시작","operationId":"start_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifiedBoostExecutionStartRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostExecutionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/verified-boost-executions/{executionId}/stop":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 집행 중단","operationId":"stop","parameters":[{"name":"executionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostExecutionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations/{reservationId}/cancel":{"post":{"tags":["예약 관리"],"summary":"예약 취소","operationId":"cancel_2","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/reviews/{reviewId}/deletion-requests":{"post":{"tags":["리뷰 관리"],"summary":"점주 리뷰 숨김 및 삭제 신청","operationId":"requestDeletion","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"reviewId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceReviewDeletionRequestCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-notices":{"get":{"tags":["메뉴·운영 공지"],"summary":"점주 상점 운영 상태 공지 목록 조회","description":"점주 또는 해당 장소의 운영 공지 관리 권한이 있는 팀원이 전체 운영 상태 공지를 조회합니다.","operationId":"listNotices","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"200":{"description":"운영 상태 공지 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeListResponse"}}}},"403":{"description":"해당 장소 운영 공지를 조회할 권한이 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["메뉴·운영 공지"],"summary":"점주 상점 운영 상태 공지 생성","description":"OWNER만 본인 장소에 공지를 생성할 수 있습니다. startsAt이 현재 시각 이후이면 SCHEDULED, 그렇지 않으면 ACTIVE로 생성되며, 같은 장소·공지 유형에는 활성 또는 예약 공지를 하나만 둘 수 있습니다.","operationId":"createNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCreateRequest"}}},"required":true},"responses":{"201":{"description":"운영 상태 공지 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"403":{"description":"장소 운영 공지 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_OPERATING_NOTICE_FORBIDDEN":{"description":"PLACE_OPERATING_NOTICE_FORBIDDEN","value":{"message":"해당 상점 운영 상태 공지를 관리할 권한이 없습니다.","code":"PLACE_OPERATING_NOTICE_FORBIDDEN"}}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_NOT_FOUND":{"description":"PLACE_NOT_FOUND","value":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}}}},"409":{"description":"같은 공지 유형의 활성 또는 예약 공지가 이미 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_OPERATING_NOTICE_ALREADY_ACTIVE":{"description":"PLACE_OPERATING_NOTICE_ALREADY_ACTIVE","value":{"message":"이미 활성 또는 예약된 상점 운영 상태 공지가 있습니다.","code":"PLACE_OPERATING_NOTICE_ALREADY_ACTIVE"}}}}}},"400":{"description":"입력값 또는 공지 상태가 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"PLACE_OPERATING_NOTICE_INVALID_REQUEST":{"description":"PLACE_OPERATING_NOTICE_INVALID_REQUEST","value":{"message":"상점 운영 상태 공지 요청이 올바르지 않습니다.","code":"PLACE_OPERATING_NOTICE_INVALID_REQUEST"}}}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-notices/{noticeId}/cancel":{"post":{"tags":["메뉴·운영 공지"],"summary":"점주 상점 운영 상태 공지 취소","description":"OWNER만 본인 장소의 SCHEDULED 또는 ACTIVE 공지를 취소할 수 있습니다. 이미 취소되었거나 종료된 공지는 400 PLACE_OPERATING_NOTICE_INVALID_REQUEST로 응답하며, 권한 부족과 대상 없음은 각각 PLACE_OPERATING_NOTICE_FORBIDDEN, PLACE_OPERATING_NOTICE_NOT_FOUND로 구분합니다.","operationId":"cancelNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCancelRequest"}}},"required":true},"responses":{"400":{"description":"입력값 또는 취소 가능하지 않은 공지 상태","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"PLACE_OPERATING_NOTICE_INVALID_REQUEST":{"description":"PLACE_OPERATING_NOTICE_INVALID_REQUEST","value":{"message":"상점 운영 상태 공지 요청이 올바르지 않습니다.","code":"PLACE_OPERATING_NOTICE_INVALID_REQUEST"}}}}}},"403":{"description":"장소 운영 공지 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"운영 상태 공지 취소 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소 또는 공지를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus":{"get":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 목록 조회","operationId":"list_13","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["메뉴·운영 공지"],"summary":"장소 메뉴 등록","operationId":"create_4","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMenuCreateRequest"}}},"required":true},"responses":{"403":{"description":"메뉴 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"메뉴 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"400":{"description":"메뉴 입력값 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus/{menuId}/deactivate":{"post":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 비활성화","operationId":"deactivate","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/members/invitations":{"post":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 초대","description":"OWNER 또는 MANAGER가 STAFF 또는 MANAGER 역할로 초대할 수 있습니다. expiresAt을 생략하면 생성 시각 기준 7일 후 만료됩니다. 활성 팀원 또는 같은 대상의 PENDING 초대가 있으면 409입니다. REVOKED 팀원은 새 초대 수락 시 재활성화됩니다.","operationId":"invite","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantTeamInviteRequest"}}},"required":true},"responses":{"400":{"description":"입력값, OWNER 역할 또는 만료 시각이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"MERCHANT_TEAM_INVITATION_INVALID_EXPIRATION":{"description":"MERCHANT_TEAM_INVITATION_INVALID_EXPIRATION","value":{"message":"Merchant 팀원 초대 만료 시각이 올바르지 않습니다.","code":"MERCHANT_TEAM_INVITATION_INVALID_EXPIRATION"}}}}}},"403":{"description":"OWNER 또는 MANAGER 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"초대 대상을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"활성 팀원이거나 대기 중인 초대가 이미 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_INVITATION_ALREADY_EXISTS":{"description":"MERCHANT_TEAM_INVITATION_ALREADY_EXISTS","value":{"message":"대기 중인 Merchant 팀원 초대가 이미 존재합니다.","code":"MERCHANT_TEAM_INVITATION_ALREADY_EXISTS"}}}}}},"201":{"description":"팀원 초대 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantTeamInvitationResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/media":{"get":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 탐색 미디어 조회","operationId":"getMedia","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 업로드 완료 탐색 미디어 등록","description":"업로드 URL 발급 응답의 s3Key만 등록할 수 있습니다. 만료되거나 등록 완료된 key는 거부됩니다. 등록되지 않은 객체는 S3 lifecycle 정책이 정리합니다.","operationId":"createMedia","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaCreateRequest"}}},"required":true},"responses":{"201":{"description":"탐색 미디어 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/media/upload-url":{"post":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 탐색 미디어 업로드 URL 발급","operationId":"createMediaUploadUrl","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaUploadRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaUploadResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/place-information-reverification-requests/{requestId}/responses":{"post":{"tags":["장소 정보 관리"],"summary":"장소 정보 재확인 응답 제출","operationId":"respond","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponseRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/payments/{paymentId}/refund":{"post":{"tags":["결제"],"summary":"결제 전액 환불","operationId":"refund","parameters":[{"name":"paymentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers":{"get":{"tags":["캠페인·혜택"],"summary":"내 관광객 전용 Offer 목록 조회","description":"placeId는 로그인한 Merchant Owner가 소유한 장소의 Offer만 조회합니다. 소유하지 않은 장소 ID를 전달하면 빈 목록을 반환합니다.","operationId":"list_16","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"placeId","in":"query","description":"소유 장소 ID","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"status","in":"query","description":"Offer 상태","required":false,"schema":{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED"]}}],"responses":{"200":{"description":"Offer 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferPageResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["캠페인·혜택"],"summary":"관광객 전용 Offer 초안 등록","operationId":"create_5","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferCreateRequest"}}},"required":true},"responses":{"403":{"description":"장소 소유 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"Offer 초안 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers/{offerId}/publish":{"post":{"tags":["캠페인·혜택"],"summary":"관광객 전용 Offer 게시","operationId":"publish","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"Offer 게시 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"409":{"description":"게시할 수 없는 상태 또는 기간","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers/{offerId}/close":{"post":{"tags":["캠페인·혜택"],"summary":"관광객 전용 Offer 종료","operationId":"close","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"Offer 종료 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"종료할 수 없는 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers/coupons/redeem":{"post":{"tags":["캠페인·혜택"],"summary":"관광객 Coupon 사용 처리","description":"본인이 소유한 장소의 Offer에서 발급된 Coupon만 사용할 수 있습니다. 응답의 Offer·장소 요약은 발급 시점 스냅샷입니다.","operationId":"redeem","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CouponRedeemRequest"}}},"required":true},"responses":{"409":{"description":"사용되었거나 만료된 Coupon","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"Coupon 사용 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CouponResponse"}}}},"404":{"description":"Coupon을 찾을 수 없거나 소유 장소의 Coupon이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/invitations/{invitationId}/accept":{"post":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 초대 수락","description":"초대 수신자만 수락할 수 있습니다. 이미 수락된 초대는 활성 팀원이 존재하면 동일한 팀원 응답을 반환합니다. 초대 수락은 초대와 기존 팀원을 잠가 동시 요청에서도 중복 팀원을 만들지 않으며, 만료 초대는 410 MERCHANT_TEAM_INVITATION_EXPIRED로 응답합니다. 수신자 불일치는 MERCHANT_TEAM_PERMISSION_REQUIRED, 비활성 계정은 MERCHANT_TEAM_MEMBER_NOT_ACTIVE로 구분합니다.","operationId":"accept","parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"409":{"description":"수신자 계정이 비활성 상태이거나 기존 팀원을 재활성화할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"팀원 초대 수락 성공 또는 반복 수락의 멱등 응답","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantTeamMemberResponse"}}}},"404":{"description":"초대를 찾을 수 없거나 수락된 초대에 활성 팀원이 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"초대 수신자가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"초대가 만료됨","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_INVITATION_EXPIRED":{"description":"MERCHANT_TEAM_INVITATION_EXPIRED","value":{"message":"Merchant 팀원 초대가 만료되었습니다.","code":"MERCHANT_TEAM_INVITATION_EXPIRED"}}}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns":{"get":{"tags":["캠페인·혜택"],"summary":"내 팝업 캠페인 목록 조회","operationId":"listCampaigns","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["캠페인·혜택"],"summary":"팝업 캠페인 초안 등록","operationId":"createCampaign","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PopupCampaignCreateRequest"}}},"required":true},"responses":{"404":{"description":"브랜드를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"팝업 캠페인 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignResponse"}}}},"403":{"description":"장소 소유 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/{campaignId}/publish":{"post":{"tags":["캠페인·혜택"],"summary":"팝업 캠페인 공개","operationId":"publish_1","parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/{campaignId}/close":{"post":{"tags":["캠페인·혜택"],"summary":"팝업 캠페인 종료","operationId":"close_1","parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/brands":{"get":{"tags":["캠페인·혜택"],"summary":"내 브랜드 목록 조회","operationId":"listBrands","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BrandPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["캠페인·혜택"],"summary":"브랜드 등록","operationId":"createBrand","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandCreateRequest"}}},"required":true},"responses":{"409":{"description":"브랜드명 중복","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"브랜드 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BrandResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities":{"get":{"tags":["예약 가능 시간"],"summary":"내 예약 가능 시간 목록 조회","operationId":"list_17","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AvailabilityResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["예약 가능 시간"],"summary":"예약 가능 시간 등록","description":"productId, productType을 보내면 null이어도 400 INVALID_REQUEST_BODY로 거절합니다. 상품 필드를 제거한 단일 예약 슬롯 본문을 사용하세요.","operationId":"create_6","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityUpsertRequest"}}},"required":true},"responses":{"201":{"description":"예약 가능 시간 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities/{availabilityId}/deactivate":{"post":{"tags":["예약 가능 시간"],"summary":"예약 가능 시간 비활성화","operationId":"deactivate_1","parameters":[{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/availabilities/{availabilityId}/activate":{"post":{"tags":["예약 가능 시간"],"summary":"예약 가능 시간 활성화","operationId":"activate","parameters":[{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/location-check-ins":{"get":{"tags":["방문 인증"],"summary":"내 위치 체크인 목록 조회","operationId":"listMine_5","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LocationCheckInPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["방문 인증"],"summary":"클라이언트 위치 기반 방문 체크인","description":"클라이언트가 제출한 위치와 장소 좌표의 근접성을 확인하며 실제 GPS를 증명하지 않습니다.","operationId":"checkIn","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationCheckInRequest"}}},"required":true},"responses":{"400":{"description":"관측 시각 또는 정확도 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"위치 근접성 확인 기록 생성","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LocationCheckInResponse"}}}},"422":{"description":"장소 체크인 허용 반경 밖","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"일일 중복 체크인","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"체크인 가능한 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/location-check-ins/{checkInId}/evidence":{"get":{"tags":["방문 인증"],"summary":"내 방문 체크인 증빙 조회","operationId":"get_12","parameters":[{"name":"checkInId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"본인 소유 체크인 또는 증빙을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["방문 인증"],"summary":"방문 체크인 증빙 업로드","description":"본인의 완료된 체크인에 JPEG 또는 PNG 증빙 이미지 한 개를 등록합니다. 증빙은 보관 기간 만료 후 삭제됩니다.","operationId":"upload_2","parameters":[{"name":"checkInId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"404":{"description":"본인 소유 체크인을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"체크인 증빙이 이미 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"파일 크기 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"증빙 저장소 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"증빙 등록 완료","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitEvidenceResponse"}}}},"400":{"description":"비어 있거나 지원하지 않는 이미지","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/firebase/fcm-tokens":{"post":{"tags":["알림"],"summary":"FCM 토큰 등록","description":"현재 기기의 FCM 토큰을 사용자에게 등록하거나 재등록합니다.","operationId":"registerFcmToken","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FcmTokenRequest"}}},"required":true},"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["알림"],"summary":"FCM 토큰 삭제","description":"로그아웃 또는 토큰 폐기 시 현재 기기의 FCM 토큰을 삭제합니다.","operationId":"deleteFcmToken","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FcmTokenRequest"}}},"required":true},"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/consultations/intro":{"post":{"tags":["상담 시작"],"summary":"첫 상담 안내 생성","description":"첫 사용자 질문만 외부 AI에 전달해 짧은 안내문을 생성합니다. AI를 사용할 수 없으면 기본 안내문을 반환합니다.","operationId":"createIntro","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsultationIntroRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationIntroResponse"}}}},"200":{"description":"첫 상담 안내 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationIntroResponse"}}}},"429":{"description":"IP 요청 제한 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationIntroResponse"}}}}}}},"/community/posts":{"get":{"tags":["커뮤니티 게시글"],"summary":"전체 커뮤니티 게시글 목록","description":"최신순. 국가 미설정 게시글은 전체 조회에만 포함되며 국가 필터로 추론하지 않습니다. 단일 카테고리를 유지합니다.","operationId":"findAll","parameters":[{"name":"countryCode","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"400":{"description":"INVALID_COUNTRY 또는 페이지 범위 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["커뮤니티 게시글"],"summary":"커뮤니티 게시글 등록","description":"인증된 사용자가 카테고리, 제목, 본문, 연결 장소 ID 목록으로 게시글을 등록합니다.","operationId":"create_7","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityPostCreateRequest"}}},"required":true},"responses":{"400":{"description":"카테고리, 입력값 또는 장소 선택이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"201":{"description":"커뮤니티 게시글 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostCreateResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"연결할 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/reports":{"post":{"tags":["신고"],"summary":"커뮤니티 게시글 신고","description":"동일 사용자·대상은 처리 상태와 관계없이 한 번만 신고할 수 있습니다. 접수만으로 대상이 숨겨지지는 않습니다.","operationId":"reportPost","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityReportCreateRequest"}}},"required":true},"responses":{"201":{"description":"신고 접수 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityReportCreateResponse"}}}},"409":{"description":"이미 신고한 대상","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"신고 대상이 없거나 게시글에 속하지 않는 댓글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"신고 사유 또는 설명이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/places/{placeId}/view":{"post":{"tags":["커뮤니티 게시글"],"summary":"게시글 경유 장소 상세 조회","description":"연결 장소를 조회하고 사용자별 하루 1회만 커뮤니티 유입 조회수를 증가합니다.","operationId":"record_1","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/likes":{"get":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 좋아요 상태 조회","operationId":"find","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostLikeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 좋아요 등록","operationId":"like","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostLikeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 좋아요 취소","operationId":"cancel_5","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostLikeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/comments":{"get":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 댓글 목록 조회","description":"댓글·답글을 최신순 평탄 목록으로 조회합니다. parentCommentId 지정 시 해당 부모의 답글만 페이지 조회하며 숨김 부모의 답글은 제외합니다.","operationId":"findAll_1","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}},{"name":"parentCommentId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"댓글 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostCommentListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["댓글·좋아요"],"summary":"커뮤니티 게시글 댓글 등록","description":"인증된 사용자가 존재하는 게시글에 댓글을 등록합니다.","operationId":"create_8","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityPostCommentCreateRequest"}}},"required":true},"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"댓글 입력값이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"201":{"description":"댓글 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostCommentCreateResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}/comments/{commentId}/reports":{"post":{"tags":["신고"],"summary":"커뮤니티 댓글 신고","description":"동일 사용자·대상은 처리 상태와 관계없이 한 번만 신고할 수 있습니다. 접수만으로 대상이 숨겨지지는 않습니다.","operationId":"reportComment","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommunityReportCreateRequest"}}},"required":true},"responses":{"201":{"description":"신고 접수 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityReportCreateResponse"}}}},"409":{"description":"이미 신고한 대상","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"신고 대상이 없거나 게시글에 속하지 않는 댓글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"신고 사유 또는 설명이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/images":{"post":{"tags":["커뮤니티 게시글"],"summary":"게시글 이미지 업로드","description":"JPEG/PNG 10MiB 이하. 검증 후 메타데이터를 제거해 저장하며 최대 10개의 본인 imageId를 게시글에 입력 순서대로 연결합니다. 미사용 이미지는 24시간 후 삭제 Outbox로 정리합니다.","operationId":"upload_3","requestBody":{"content":{"multipart/form-data":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"400":{"description":"IMAGE_FILE_INVALID: 빈 파일·크기·실제 형식 오류. INVALID_REQUEST_PARAMETER: file 누락","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityImageUploadResponse"}}}},"503":{"description":"IMAGE_UPLOAD_UNAVAILABLE: 저장소 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityImageUploadResponse"}}}},"413":{"description":"UPLOAD_TOO_LARGE: multipart 파일·요청 크기 제한 초과","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"이미지 ID·URL 및 만료 시각","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityImageUploadResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/comments/{commentId}/likes":{"get":{"tags":["댓글·좋아요"],"summary":"커뮤니티 댓글 좋아요 상태 조회","operationId":"find_1","parameters":[{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 좋아요 수·본인 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityCommentLikeResponse"}}}},"404":{"description":"COMMENT_NOT_FOUND: 없는 댓글·숨김 댓글/부모/게시글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["댓글·좋아요"],"summary":"커뮤니티 댓글 좋아요 등록","operationId":"like_1","parameters":[{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 좋아요 수·본인 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityCommentLikeResponse"}}}},"404":{"description":"COMMENT_NOT_FOUND: 없는 댓글·숨김 댓글/부모/게시글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["댓글·좋아요"],"summary":"커뮤니티 댓글 좋아요 취소","operationId":"cancel_6","parameters":[{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 좋아요 수·본인 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityCommentLikeResponse"}}}},"404":{"description":"COMMENT_NOT_FOUND: 없는 댓글·숨김 댓글/부모/게시글","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/auth/token/refresh":{"post":{"tags":["로그인·세션"],"summary":"토큰 재발급","description":"HttpOnly Cookie의 Refresh Token을 검증한 뒤 Access Token을 재발급하고, 회전된 Refresh Token은 Cookie로 갱신합니다.","operationId":"refreshToken","responses":{"404":{"description":"토큰에 해당하는 사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"유효하지 않은 리프레시 토큰","content":{"*/*":{"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"토큰 재발급 성공","headers":{"Set-Cookie":{"description":"회전된 HttpOnly Refresh Token Cookie","style":"simple","schema":{"type":"string"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RefreshTokenResponse"}}}}}}},"/auth/signup":{"post":{"tags":["회원가입·이메일 인증"],"summary":"회원가입","description":"아이디, 이메일, 비밀번호와 기본 프로필 정보를 입력받아 새 사용자를 생성합니다.","operationId":"signup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"201":{"description":"회원가입 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserResponse"},"example":{"id":1,"username":"pingdom_user","email":"pingdom@example.com","birthYear":1998,"profileImageUrl":"https://cdn.pingdom.com/profiles/user1.png","language":"ko","country":"KR","role":"USER"}}}},"409":{"description":"이미 사용 중인 아이디 또는 이메일","content":{"*/*":{"examples":{"duplicate-username":{"description":"duplicate-username","value":{"message":"이미 사용 중인 아이디입니다.","code":"DUPLICATE_USERNAME"}},"duplicate-email":{"description":"duplicate-email","value":{"message":"이미 사용 중인 이메일입니다.","code":"DUPLICATE_EMAIL"}}}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"examples":{"invalid-username":{"description":"invalid-username","value":{"message":"입력값을 확인해주세요.","errors":{"username":"아이디는 4자 이상 50자 이하여야 합니다."}}},"invalid-email":{"description":"invalid-email","value":{"message":"입력값을 확인해주세요.","errors":{"email":"이메일 형식이 올바르지 않습니다."}}},"invalid-language":{"description":"invalid-language","value":{"message":"입력값을 확인해주세요.","errors":{"language":"언어는 20자 이하여야 합니다."}}}}}}}}}},"/auth/password-reset/request":{"post":{"tags":["비밀번호 재설정"],"summary":"비밀번호 재설정 토큰 발급","description":"이메일 주소로 비밀번호 재설정 토큰을 발급하고 메일 발송 이벤트를 생성합니다.","operationId":"requestPasswordReset","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"email":"이메일 형식이 올바르지 않습니다."}}}}},"200":{"description":"비밀번호 재설정 요청 접수"}}}},"/auth/password-reset/confirm":{"post":{"tags":["비밀번호 재설정"],"summary":"비밀번호 재설정 완료","description":"메일로 발급된 재설정 토큰을 검증해 새 비밀번호를 설정합니다.","operationId":"confirmPasswordReset","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirmRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패 또는 유효하지 않은 재설정 토큰","content":{"*/*":{"examples":{"invalid-token":{"description":"invalid-token","value":{"message":"비밀번호 재설정 토큰이 올바르지 않습니다.","code":"INVALID_PASSWORD_RESET_TOKEN"}},"expired-token":{"description":"expired-token","value":{"message":"비밀번호 재설정 토큰이 만료되었습니다.","code":"EXPIRED_PASSWORD_RESET_TOKEN"}}}}}},"204":{"description":"비밀번호 재설정 성공"}}}},"/auth/logout":{"post":{"tags":["로그인·세션"],"summary":"로그아웃","description":"HttpOnly Cookie의 Refresh Token을 검증한 뒤 현재 저장된 Refresh Token을 제거하고 Cookie를 만료 처리합니다.","operationId":"logout","responses":{"404":{"description":"토큰에 해당하는 사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"204":{"description":"로그아웃 성공","headers":{"Set-Cookie":{"description":"만료된 HttpOnly Refresh Token Cookie","style":"simple","schema":{"type":"string"}}}},"401":{"description":"유효하지 않은 리프레시 토큰","content":{"*/*":{"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}}},"/auth/login":{"post":{"tags":["로그인·세션"],"summary":"로그인","description":"아이디와 비밀번호를 검증한 뒤 사용자 정보와 Access Token을 반환하고 Refresh Token은 HttpOnly Cookie로 발급합니다.","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"로그인 성공","headers":{"Set-Cookie":{"description":"HttpOnly Refresh Token Cookie","style":"simple","schema":{"type":"string"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/LoginResponse"},"example":{"id":1,"username":"pingdom_user","email":"pingdom@example.com","birthYear":1998,"profileImageUrl":"https://cdn.pingdom.com/profiles/user1.png","language":"ko","country":"KR","message":"로그인에 성공했습니다.","accessToken":"eyJhbGciOiJIUzI1NiJ9.access.token","role":"USER"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"password":"비밀번호는 8자 이상이어야 합니다."}}}}},"401":{"description":"아이디 또는 비밀번호 불일치","content":{"*/*":{"example":{"message":"아이디 또는 비밀번호가 올바르지 않습니다.","code":"INVALID_CREDENTIALS"}}}}}}},"/auth/email/verify":{"post":{"tags":["회원가입·이메일 인증"],"summary":"이메일 인증","description":"이메일과 인증 코드를 검증해 사용자의 이메일 인증 상태를 완료 처리합니다.","operationId":"verifyEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailVerifyRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패 또는 유효하지 않은 인증 코드","content":{"*/*":{"examples":{"validation-failure":{"description":"validation-failure","value":{"message":"입력값을 확인해주세요.","errors":{"email":"이메일 형식이 올바르지 않습니다."}}},"invalid-code":{"description":"invalid-code","value":{"message":"이메일 인증 코드가 올바르지 않습니다.","code":"INVALID_EMAIL_VERIFICATION_CODE"}},"expired-code":{"description":"expired-code","value":{"message":"이메일 인증 코드가 만료되었습니다.","code":"EXPIRED_EMAIL_VERIFICATION_CODE"}}}}}},"200":{"description":"이메일 인증 성공"},"404":{"description":"이메일에 해당하는 사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}}}}},"/auth/email/resend":{"post":{"tags":["회원가입·이메일 인증"],"summary":"인증 메일 재발송","description":"미인증 사용자의 이메일 인증 코드를 새로 발급하고 인증 메일을 다시 발송합니다.","operationId":"resendVerificationEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailResendRequest"}}},"required":true},"responses":{"409":{"description":"이미 인증된 이메일","content":{"*/*":{"example":{"message":"이미 이메일 인증이 완료된 사용자입니다.","code":"EMAIL_ALREADY_VERIFIED"}}}},"200":{"description":"인증 메일 재발송 성공"},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"email":"이메일 형식이 올바르지 않습니다."}}}}},"404":{"description":"이메일에 해당하는 사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}}}}},"/auth/admin/login":{"post":{"tags":["로그인·세션"],"summary":"관리자 로그인","description":"관리자 계정만 관리자 페이지 전용 Access Token을 발급받고 Refresh Token은 HttpOnly Cookie로 발급합니다.","operationId":"adminLogin","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"관리자 로그인 성공","headers":{"Set-Cookie":{"description":"HttpOnly Refresh Token Cookie","style":"simple","schema":{"type":"string"}}},"content":{"*/*":{"schema":{"$ref":"#/components/schemas/LoginResponse"},"example":{"id":1,"username":"admin_user","email":"admin@example.com","birthYear":1990,"profileImageUrl":null,"language":"ko","country":"KR","message":"로그인에 성공했습니다.","accessToken":"eyJhbGciOiJIUzI1NiJ9.access.token","role":"ADMIN"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"password":"비밀번호는 8자 이상이어야 합니다."}}}}},"401":{"description":"아이디 또는 비밀번호 불일치","content":{"*/*":{"example":{"message":"아이디 또는 비밀번호가 올바르지 않습니다.","code":"INVALID_CREDENTIALS"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"example":{"message":"관리자 권한이 필요합니다.","code":"ADMIN_ACCESS_REQUIRED"}}}}}}},"/analysis/reports/location":{"post":{"tags":["상권 분석"],"summary":"입지 분석 PDF 보고서 생성","description":"입력 조건을 AI/MCP 분석 인터페이스로 전달하고 HTML 분석 결과를 PDF로 반환합니다. 사용자·IP별 호출 한도는 Redis로 모든 인스턴스에 공유되며, 생성 동시 실행·대기열 상한은 인스턴스별로 적용됩니다. 429 응답 시 즉시 반복하지 말고 backoff 후 재시도하세요. Retry-After 헤더는 제공하지 않습니다.","operationId":"generate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationAnalysisRequest"}}},"required":true},"responses":{"429":{"description":"사용자·IP 호출 한도 또는 인스턴스별 생성 동시 실행·대기열 상한 초과","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"AI 분석 응답 처리 실패","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"지역 누락 또는 입력값 검증 실패","content":{"application/pdf":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"PDF 보고서 생성 성공","content":{"application/pdf":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/{reportId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 심사","operationId":"review","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/corrections/{correctionId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 정정 심사","operationId":"reviewCorrection","parameters":[{"name":"correctionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionReviewRequest"}}},"required":true},"responses":{"200":{"description":"제보 정정 심사 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionResponse"}}}},"409":{"description":"이미 심사된 정정 또는 활성 제보 충돌","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"심사 요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"제보 정정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"활성 관리자 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products":{"get":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 목록 조회","operationId":"list_21","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 생성","operationId":"create_9","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}/deactivate":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 비활성화","operationId":"deactivate_2","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}/activate":{"post":{"tags":["Verified Boost"],"summary":"Verified Boost 상품 활성화","operationId":"activate_1","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/roles":{"get":{"tags":["회원·권한"],"summary":"관리자 역할 이력 조회","operationId":"list_22","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"대상 관리자 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["회원·권한"],"summary":"관리자 역할 부여","operationId":"assign","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentRequest"}}},"required":true},"responses":{"404":{"description":"대상 관리자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"역할 할당 요청 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"부여 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}},"409":{"description":"이미 활성 역할이 존재함","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}/interventions/evaluate":{"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 수동 평가","description":"관리자가 신고자의 현재 Trust Score 정책에 활성 개입 규칙을 수동 평가합니다.","operationId":"evaluateReporter","parameters":[{"name":"reporterUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionEvaluationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules":{"get":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 목록 조회","description":"관리자가 Trust Score 개입 규칙 목록을 우선순위 순서로 조회합니다.","operationId":"listRules","parameters":[{"name":"enabledOnly","in":"query","description":"활성화된 규칙만 조회할지 여부","required":false,"schema":{"type":"boolean","default":false},"example":false}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 생성","description":"관리자가 Trust Score 개입 규칙을 생성합니다.","operationId":"createRule","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleRequest"}}},"required":true},"responses":{"200":{"description":"Trust Score 개입 규칙 생성 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"},"example":{"id":1,"ruleName":"low trust temporary restriction","triggerType":"FALSE_REPORT_COUNT","actionType":"TEMPORARY_RESTRICT","enabled":true,"minTrustScore":0,"maxTrustScore":60,"minSubmittedCount":3,"minFalseReportCount":3,"durationDays":7,"priority":10,"reason":"허위 신고 누적 사용자 제한"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/batch/recalculate":{"post":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 일괄 재계산","operationId":"recalculateTrustScores","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreBatchResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/suspend":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 정지","operationId":"suspend","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/revoke":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 회수","operationId":"revoke","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/suspend":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 정지","operationId":"suspendEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/revoke":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 회수","operationId":"revokeEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/eligibility/grant":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 활동 자격 부여","operationId":"grantEligibility","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutActivityEligibilityGrantRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}/approve":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 승인","operationId":"approve","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutProfileReviewRequest"}}},"required":true},"responses":{"200":{"description":"Scout 프로필 승인 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"409":{"description":"현재 프로필 상태에서 승인 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"403":{"description":"Scout 심사 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-field-reports/{reportId}/review":{"post":{"tags":["방문 인증·스카우트"],"summary":"Scout 현장 제보 심사","operationId":"review_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"현장 제보 심사 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"409":{"description":"이미 심사된 현장 제보","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"400":{"description":"심사 요청 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"404":{"description":"현장 제보를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/{id}/decline":{"post":{"tags":["신고·이의신청"],"summary":"신고 거절 처리","description":"관리자가 신고를 거절 처리합니다.","operationId":"declineReport","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"신고 거절 성공","content":{"*/*":{"example":{"reportId":1,"status":"DECLINED","reportedUserId":5,"banned":false,"processedAt":"2026-05-07T21:00:00"}}}},"404":{"description":"신고 내역 없음","content":{"*/*":{"example":{"message":"신고 내역을 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"example":{"message":"이미 처리된 신고입니다.","code":"REPORT_ALREADY_PROCESSED"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/{id}/accept":{"post":{"tags":["신고·이의신청"],"summary":"신고 수락 처리","description":"관리자가 신고를 수락하고 대상 사용자를 제재하며 신고 대상 게시글을 숨김 처리합니다.","operationId":"acceptReport","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"404":{"description":"신고 내역 없음","content":{"*/*":{"example":{"message":"신고 내역을 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}},"200":{"description":"신고 수락 성공","content":{"*/*":{"example":{"reportId":1,"status":"ACCEPTED","reportedUserId":5,"banned":true,"processedAt":"2026-05-07T21:00:00"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"example":{"message":"이미 처리된 신고입니다.","code":"REPORT_ALREADY_PROCESSED"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals/{id}/reject":{"post":{"tags":["신고·이의신청"],"summary":"신고 이의제기 반려","operationId":"reject_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals/{id}/approve":{"post":{"tags":["신고·이의신청"],"summary":"신고 이의제기 승인","operationId":"approve_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{postId}/reports/decline":{"post":{"tags":["신고·이의신청"],"summary":"게시글 단위 신고 일괄 거절","description":"관리자가 게시글에 연결된 PENDING 신고를 모두 거절합니다. 게시글 공개 상태와 대상 사용자 제재 상태는 변경하지 않습니다.","operationId":"declinePostReports","parameters":[{"name":"postId","in":"path","description":"신고를 일괄 거절할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"게시글 신고 일괄 거절 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"},"example":{"postId":10,"status":"DECLINED","processedReportCount":3,"visibilityStatus":"ACTIVE","hiddenAt":null,"hiddenReason":null,"processedAt":"2026-05-21T10:15:30"}}}},"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"409":{"description":"처리할 PENDING 신고 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{postId}/reports/accept":{"post":{"tags":["신고·이의신청"],"summary":"게시글 단위 신고 일괄 수락","description":"관리자가 게시글에 연결된 PENDING 신고를 모두 수락하고 게시글 숨김 및 대상 사용자 제재를 처리합니다.","operationId":"acceptPostReports","parameters":[{"name":"postId","in":"path","description":"신고를 일괄 수락할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"200":{"description":"게시글 신고 일괄 수락 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"},"example":{"postId":10,"status":"ACCEPTED","processedReportCount":3,"visibilityStatus":"AUTO_HIDDEN","hiddenAt":"2026-05-21T10:15:30","hiddenReason":"REPORT_BULK_ACCEPTED","processedAt":"2026-05-21T10:15:30"}}}},"409":{"description":"처리할 PENDING 신고 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPostReportBulkActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report/refresh":{"post":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 리포트 생성 시작","description":"DB와 S3를 백그라운드에서 비교해 Redis에 리포트 결과를 저장합니다. 생성된 리포트는 GET report API로 페이지 조회합니다.","operationId":"refreshS3OrphanReport","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReportStatus"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 생성","description":"관리자가 상점 운영 상태 공지를 생성합니다.","operationId":"createNotice_1","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices/{noticeId}/cancel":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 취소","description":"관리자가 예약 또는 활성 운영 상태 공지를 취소합니다.","operationId":"cancelNotice_1","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeCancelRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests":{"get":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 목록 조회","operationId":"list_27","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 생성","operationId":"create_10","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/reminders":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 리마인드 발행","operationId":"remind","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/complete":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 완료","operationId":"complete","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/information-reverification-requests/{requestId}/cancel":{"post":{"tags":["제보·재검증"],"summary":"장소 정보 재확인 요청 취소","operationId":"cancel_3","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/information-evidence":{"get":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 목록 조회","description":"관리자가 장소 정보 출처와 증빙 메타데이터를 확인합니다.","operationId":"getPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 조회할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceResponse"}}}},"200":{"description":"장소 정보 증빙 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 등록","description":"관리자가 장소 정보 출처와 증빙 메타데이터를 등록합니다.","operationId":"createPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 등록할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceCreateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"200":{"description":"장소 정보 증빙 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-snapshots/resync":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 추천 snapshot 재동기화","description":"관리자가 모든 장소 추천 snapshot을 현재 데이터 기준으로 다시 동기화합니다.","operationId":"resyncRecommendationSnapshots","responses":{"200":{"description":"추천 snapshot 재동기화 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationSnapshotResyncResponse"},"example":{"placeCount":12,"synchronizedSnapshotCount":12,"deletedSnapshotCount":1,"synchronizedSimilaritySnapshotCount":24,"deletedSimilaritySnapshotCount":2,"synchronizedVersionSnapshotCount":3,"deletedVersionSnapshotCount":0,"message":"장소 추천 snapshot 재동기화를 완료했습니다."}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 병합","description":"관리자가 중복 장소의 참조 데이터를 대상 장소로 옮기고 원본 장소를 병합합니다.","operationId":"mergePlaces","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge-histories/{historyId}/restore":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 장소 병합 복구","description":"관리자가 저장된 장소 병합 이력을 기준으로 복구합니다.","operationId":"restoreMerge","parameters":[{"name":"historyId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceMergeRestoreResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/reject":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 거절","operationId":"rejectDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateDecisionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/merge":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 확정 중복 장소 병합","operationId":"mergeDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateMergeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceMergeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}/confirm":{"post":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 확정","operationId":"confirmDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateDecisionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests/{deletionRequestId}/review":{"post":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 심사","operationId":"review_2","parameters":[{"name":"deletionRequestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceReviewDeletionRequestReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-operating-notices/expire":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 만료 처리","description":"만료 시간이 지난 운영 상태 공지를 일괄 만료 처리합니다.","operationId":"expireDueNotices","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}/review":{"post":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 검토","operationId":"reviewReport","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}/disputes/{disputeId}/review":{"post":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 반박 검토","operationId":"reviewDispute","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"disputeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events":{"get":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 목록 조회","operationId":"listEvents_1","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":20}},{"name":"keyword","in":"query","required":false,"schema":{"type":"string"}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"eventType","in":"query","required":false,"schema":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]}},{"name":"publicationStatus","in":"query","required":false,"schema":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]}},{"name":"scheduleStatus","in":"query","required":false,"schema":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 등록","description":"장소와 연결된 기간형 이벤트를 초안으로 등록합니다.","operationId":"createEvent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventRequest"}}},"required":true},"responses":{"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"201":{"description":"이벤트 초안 등록 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}/publish":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 공개","description":"종료되지 않은 초안 이벤트를 앱 탐색에 공개합니다.","operationId":"publishEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventActionRequest"}}},"required":true},"responses":{"409":{"description":"공개할 수 없는 상태 또는 기간","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 공개 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}/cancel":{"post":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 취소","description":"초안 또는 공개된 기간형 이벤트를 취소하고 앱 탐색에서 제외합니다.","operationId":"cancelEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventActionRequest"}}},"required":true},"responses":{"409":{"description":"이미 취소된 이벤트","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 취소 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/outbox-events/{eventId}/retry":{"post":{"tags":["Outbox·스토리지 운영"],"summary":"관리자 Outbox 이벤트 재처리","description":"장애 원인과 중복 처리 안전성을 확인한 뒤 최종 실패 이벤트를 재처리 대상으로 전환합니다.","operationId":"retry","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventRetryRequest"}}},"required":true},"responses":{"400":{"description":"재처리 사유 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Outbox 복구 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"재처리 불가 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"이벤트 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"재처리 예약 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventItem"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/reject":{"post":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 반려","operationId":"reject_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/approve":{"post":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 승인","description":"NEW_PLACE 승인 시 장소 생성, Merchant Owner 연결과 신청의 COMPLETED 전이가 하나의 트랜잭션으로 완료됩니다. 신청자의 추가 완료 요청은 필요하지 않습니다.","operationId":"approve_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/revoke":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 권한 회수","operationId":"revoke_1","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/reject":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 반려","operationId":"reject_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}/approve":{"post":{"tags":["사업자 관리"],"summary":"Merchant Owner 승인","description":"승인 사유만 처리합니다. 장소 연결은 변경하지 않으며, 승인 후 연결이 필요하면 PUT /admin/merchant-owners/{userId}/places로 전체 장소 목록을 별도 요청해야 합니다. 승인과 장소 연결은 별도 트랜잭션입니다.","operationId":"approve_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}/decline":{"post":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 반려","description":"반려는 신고 상태만 변경하고 대상 노출 상태를 바꾸지 않습니다.","operationId":"decline","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"신고 반려 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportActionResponse"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"커뮤니티 신고를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}/accept":{"post":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 수락","description":"수락한 신고 대상 글 또는 댓글을 숨깁니다.","operationId":"accept_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"커뮤니티 신고 또는 대상 콘텐츠를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"이미 처리된 신고","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"신고 수락 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportActionResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/ban/{userId}":{"post":{"tags":["회원·권한"],"summary":"사용자 밴 처리","description":"관리자가 특정 사용자를 밴 처리합니다. expiresAt 또는 durationDays를 전달하면 기간 밴으로, 둘 다 비우면 영구 밴으로 처리합니다.","operationId":"banUser","parameters":[{"name":"userId","in":"path","description":"밴 처리할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BanRequest"}}}},"responses":{"200":{"description":"밴 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BanResponse"}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/ban/{userId}/release":{"post":{"tags":["회원·권한"],"summary":"사용자 밴 해제","description":"관리자가 영구 밴 또는 기간 밴 상태의 사용자를 명시적으로 해제합니다.","operationId":"unbanUser","parameters":[{"name":"userId","in":"path","description":"밴 해제할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnbanRequest"}}}},"responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"밴 해제 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UnbanResponse"}}}},"409":{"description":"제재 중인 사용자가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"제재 중인 사용자가 아닙니다.","code":"USER_NOT_BANNED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/travel-schedules/{scheduleId}":{"patch":{"tags":["여행"],"summary":"여행 일정 기간 변경","description":"취소되지 않은 본인 여행 일정의 날짜 범위를 변경합니다.","operationId":"updateTravelSchedule","parameters":[{"name":"scheduleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TravelScheduleUpdateRequest"}}},"required":true},"responses":{"200":{"description":"변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TravelScheduleResponse"}}}},"404":{"description":"일정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"기간 역전 또는 과거 날짜","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidPeriod":{"description":"invalidPeriod","value":{"message":"여행 종료일은 시작일보다 빠를 수 없습니다.","code":"INVALID_TRAVEL_SCHEDULE_PERIOD"}},"pastStartDate":{"description":"pastStartDate","value":{"message":"여행 시작일은 오늘보다 이전일 수 없습니다.","code":"TRAVEL_SCHEDULE_START_DATE_IN_PAST"}}}}}},"409":{"description":"기간 겹침, 취소된 일정 또는 동시 수정 충돌","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"periodOverlap":{"description":"periodOverlap","value":{"message":"기존 여행 일정과 기간이 겹칩니다.","code":"TRAVEL_SCHEDULE_PERIOD_OVERLAP"}},"notEditable":{"description":"notEditable","value":{"message":"취소된 여행 일정은 수정할 수 없습니다.","code":"TRAVEL_SCHEDULE_NOT_EDITABLE"}},"concurrentModification":{"description":"concurrentModification","value":{"message":"여행 일정이 다른 요청으로 변경되었습니다. 다시 조회해 주세요.","code":"TRAVEL_SCHEDULE_CONCURRENT_MODIFICATION"}}}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/notifications/settings":{"get":{"tags":["알림"],"summary":"알림 설정 조회","description":"현재 사용자의 알림 타입별 수신 여부와 quiet hours 설정을 조회합니다.","operationId":"getSetting","responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotificationSettingResponse"},"example":{"newHotplaceEnabled":true,"newLikeEnabled":true,"quietHoursEnabled":false,"quietHoursStart":null,"quietHoursEnd":null,"timezone":"Asia/Seoul"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["알림"],"summary":"알림 설정 수정","description":"현재 사용자의 알림 타입별 수신 여부와 quiet hours 설정을 부분 수정합니다.","operationId":"updateSetting","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationSettingUpdateRequest"}}},"required":true},"responses":{"400":{"description":"timezone 또는 quiet hours 설정 오류","content":{"*/*":{"example":{"message":"quiet hours 설정을 확인해주세요.","code":"INVALID_QUIET_HOURS"}}}},"200":{"description":"수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotificationSettingResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-status":{"patch":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 장소 운영 상태 변경","operationId":"updateOperatingStatus","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingStatusUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating-notices/{noticeId}":{"patch":{"tags":["메뉴·운영 공지"],"summary":"점주 상점 운영 상태 공지 수정","description":"OWNER만 본인 장소의 SCHEDULED 또는 ACTIVE 공지의 심각도와 메시지를 수정할 수 있습니다. 생성·수정·취소 결과는 공개 운영 공지 조회와 동일한 공지 리소스를 변경합니다. 잘못된 상태는 PLACE_OPERATING_NOTICE_INVALID_REQUEST, 권한 부족은 PLACE_OPERATING_NOTICE_FORBIDDEN, 대상 없음은 PLACE_OPERATING_NOTICE_NOT_FOUND로 응답합니다.","operationId":"updateNotice","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeUpdateRequest"}}},"required":true},"responses":{"403":{"description":"장소 운영 공지 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"운영 상태 공지 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"400":{"description":"입력값 또는 수정 가능하지 않은 공지 상태","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소 또는 공지를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus/{menuId}":{"get":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 상세 조회","operationId":"get_8","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 수정","operationId":"update_4","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMenuUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus/{menuId}/status":{"patch":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 상태 변경","operationId":"changeStatus","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMenuStatusRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/menus/{menuId}/order":{"patch":{"tags":["메뉴·운영 공지"],"summary":"Merchant 장소 메뉴 표시 순서 변경","operationId":"reorder_1","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"menuId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceMenuOrderRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMenuResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/members/{memberId}":{"delete":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 권한 회수","operationId":"revoke_2","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"memberId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"No Content"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 권한 변경","description":"OWNER 또는 MANAGER가 활성 팀원의 역할을 변경합니다. OWNER 역할은 팀원에게 부여할 수 없으며, 비활성 팀원은 변경할 수 없습니다. 잘못된 역할은 MERCHANT_TEAM_INVITATION_INVALID_ROLE, 비활성 팀원은 MERCHANT_TEAM_MEMBER_NOT_ACTIVE, 대상 없음은 MERCHANT_TEAM_MEMBER_NOT_FOUND로 응답합니다.","operationId":"updateRole","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"memberId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantTeamRoleUpdateRequest"}}},"required":true},"responses":{"409":{"description":"비활성 팀원의 역할은 변경할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_MEMBER_NOT_ACTIVE":{"description":"MERCHANT_TEAM_MEMBER_NOT_ACTIVE","value":{"message":"활성 상태의 Merchant 팀원만 변경할 수 있습니다.","code":"MERCHANT_TEAM_MEMBER_NOT_ACTIVE"}}}}}},"403":{"description":"OWNER 또는 MANAGER 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소의 팀원을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"입력 역할이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"200":{"description":"팀원 역할 변경 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantTeamMemberResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/media/{mediaId}":{"delete":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 탐색 미디어 삭제","operationId":"deleteMedia","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"mediaId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 탐색 미디어 순서 변경","description":"displayOrder는 0부터 시작하는 이동 대상 위치입니다. 서버가 같은 장소의 탐색 미디어를 재배치해 중복 없이 0부터 연속된 순서를 보장합니다.","operationId":"updateMediaOrder","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"mediaId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOwnerMediaOrderUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/{campaignId}":{"patch":{"tags":["캠페인·혜택"],"summary":"팝업 캠페인 초안 수정","operationId":"updateCampaign","parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PopupCampaignCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PopupCampaignResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/campaigns/brands/{brandId}":{"patch":{"tags":["캠페인·혜택"],"summary":"내 브랜드 수정","operationId":"updateBrand","parameters":[{"name":"brandId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/BrandResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/analysis/reports/{reportId}":{"get":{"tags":["상권 분석"],"summary":"보관된 입지 분석 보고서 상세 조회","operationId":"get_14","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LocationAnalysisReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["상권 분석"],"summary":"보관된 입지 분석 보고서 삭제","operationId":"delete_2","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["상권 분석"],"summary":"보관된 입지 분석 보고서 정보 수정","operationId":"update_5","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationAnalysisReportUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LocationAnalysisReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}/enable":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 활성화","description":"관리자가 Trust Score 개입 규칙을 활성화합니다.","operationId":"enableRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleToggleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/intervention-rules/{ruleId}/disable":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 개입 규칙 비활성화","description":"관리자가 Trust Score 개입 규칙을 비활성화합니다.","operationId":"disableRule","parameters":[{"name":"ruleId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleToggleResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/anomalies/{anomalyId}/resolve":{"patch":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 이상치 해결 처리","description":"관리자가 Trust Score 이상치를 해결 처리하고 감사 로그를 남깁니다.","operationId":"resolveAnomaly","parameters":[{"name":"anomalyId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyResolveRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{placeId}/operating-notices/{noticeId}":{"patch":{"tags":["행사·운영 공지"],"summary":"관리자 상점 운영 상태 공지 수정","description":"관리자가 상점 운영 상태 공지 내용을 수정합니다.","operationId":"updateNotice_1","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"noticeId","in":"path","description":"공지 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/tourist-info":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 관광 정보 수정","description":"관리자가 장소의 영문명, 관광객용 요약, 관광 카테고리를 수정합니다.","operationId":"updatePlaceTouristInfo","parameters":[{"name":"id","in":"path","description":"관광 정보를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceTouristInfoUpdateRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"reason":"수정 사유는 필수입니다."}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"장소 관광 정보 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceTouristInfoUpdateResponse"},"example":{"placeId":1,"englishName":"Jinju Castle","touristSummary":"A historic fortress overlooking the Nam River.","touristCategories":["K_POP","CAFE","POP_UP"],"message":"장소 관광 정보를 수정했습니다."}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/operating-status":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 운영 상태 확인","description":"관리자가 확인한 장소 운영 상태를 기록하고 최신 확인 시각을 서버 시간으로 갱신합니다. 비운영 장소는 앱 장소 조회와 추천에서 숨겨집니다.","operationId":"updatePlaceOperatingStatus","parameters":[{"name":"id","in":"path","description":"운영 상태를 확인할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"200":{"description":"장소 운영 상태 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingStatusUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/operating-schedule":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 영업시간 일정 수정","description":"관리자가 요일별 정규 영업시간과 특정 날짜 휴무·대체 영업시간을 전체 교체합니다. 수동 운영 상태는 변경하지 않습니다.","operationId":"updatePlaceOperatingSchedule","parameters":[{"name":"id","in":"path","description":"영업시간 일정을 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingScheduleUpdateRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"장소 영업시간 일정 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceOperatingScheduleUpdateResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/kakao-place-id":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 Kakao place id 수정","description":"관리자가 장소에 연결된 Kakao place id를 재연결하거나 해제합니다.","operationId":"updatePlaceKakaoPlaceId","parameters":[{"name":"id","in":"path","description":"Kakao place id를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceKakaoPlaceIdUpdateRequest"}}},"required":true},"responses":{"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"kakaoPlaceId":"카카오 장소 ID는 50자 이하여야 합니다."}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"Kakao place id 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceKakaoPlaceIdUpdateResponse"},"example":{"placeId":1,"kakaoPlaceId":"27414316","message":"장소 Kakao place id를 수정했습니다."}}}},"409":{"description":"이미 다른 장소에 연결된 Kakao place id","content":{"*/*":{"example":{"message":"이미 다른 장소에 연결된 Kakao place id입니다.","code":"PLACE_KAKAO_PLACE_ID_CONFLICT"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/information-evidence/{evidenceId}/review":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 정보 증빙 검토","description":"관리자가 장소 정보 증빙을 승인 또는 반려하고 장소 정보 검증 요약 상태를 갱신합니다.","operationId":"reviewPlaceInformationEvidence","parameters":[{"name":"id","in":"path","description":"증빙을 검토할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"evidenceId","in":"path","description":"증빙 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceReviewRequest"}}},"required":true},"responses":{"404":{"description":"장소 또는 증빙을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"200":{"description":"장소 정보 증빙 검토 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/geocoding":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 주소·좌표 보정","description":"관리자가 대표 주소, 정규화 주소와 좌표를 함께 보정하며 출처는 ADMIN으로 기록합니다.","operationId":"updatePlaceGeocoding","parameters":[{"name":"id","in":"path","description":"주소와 좌표를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceGeocodingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceGeocodingUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/discovery-status":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 탐색 노출 상태 수정","description":"관리자가 장소를 공개 탐색, 자동완성, 북마크 목록, 추천 후보에 노출할지 제어합니다.","operationId":"updatePlaceDiscoveryStatus","parameters":[{"name":"id","in":"path","description":"탐색 노출 상태를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"200":{"description":"장소 탐색 노출 상태 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDiscoveryStatusUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/coordinates":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 좌표 수정","description":"관리자가 잘못 등록된 장소의 위도와 경도를 수정합니다.","operationId":"updatePlaceCoordinates","parameters":[{"name":"id","in":"path","description":"좌표를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceCoordinateUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"example":{"message":"입력값을 확인해주세요.","errors":{"latitude":"위도는 90.0 이하여야 합니다."}}}}},"200":{"description":"장소 좌표 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceCoordinateUpdateResponse"},"example":{"placeId":1,"latitude":35.1796,"longitude":128.1076,"message":"장소 좌표를 수정했습니다."}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/basic-information":{"patch":{"tags":["장소 정보·품질"],"summary":"관리자 장소 기본 정보 수정","description":"관리자가 장소명과 표준 카테고리를 수정하고 변경 사유를 감사 로그에 남깁니다.","operationId":"updatePlaceBasicInformation","parameters":[{"name":"id","in":"path","description":"기본 정보를 수정할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateRequest"}}},"required":true},"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"400":{"description":"입력값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"200":{"description":"장소 기본 정보 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceBasicInformationUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-traffic":{"patch":{"tags":["중복·추천 관리"],"summary":"관리자 추천 버전 트래픽 비율 수정","description":"관리자가 추천 버전별 traffic percentage를 수정하고 즉시 반영합니다.","operationId":"updateRecommendationTraffic","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-events/{eventId}":{"get":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 상세 조회","operationId":"getEvent_1","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventListItem"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["행사·운영 공지"],"summary":"관리자 기간형 이벤트 수정","description":"초안 상태의 기간형 이벤트 정보와 연결 장소를 수정합니다.","operationId":"updateEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventRequest"}}},"required":true},"responses":{"404":{"description":"이벤트 또는 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"입력값 또는 기간 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"초안이 아닌 이벤트 수정 시도","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"이벤트 수정 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceEventResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/{notificationId}/read":{"patch":{"tags":["알림·발송 이력"],"summary":"관리자 알림 읽음 처리","description":"관리자가 운영 확인이 필요한 인앱 알림을 읽음 상태로 변경합니다.","operationId":"markAsRead","parameters":[{"name":"notificationId","in":"path","description":"알림 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"알림 읽음 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationReadResponse"},"example":{"notificationId":1,"read":true,"message":"알림을 읽음 처리했습니다."}}}},"404":{"description":"알림을 찾을 수 없음","content":{"*/*":{"example":{"message":"알림을 찾을 수 없습니다.","code":"NOTIFICATION_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/read":{"patch":{"tags":["알림·발송 이력"],"summary":"관리자 전체 알림 읽음 처리","description":"관리자가 모든 미확인 인앱 알림을 읽음 상태로 변경합니다.","operationId":"markAllAsRead","responses":{"200":{"description":"전체 알림 읽음 처리 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationReadAllResponse"},"example":{"updatedCount":3,"message":"전체 알림을 읽음 처리했습니다."}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/visitor-verification-reports/{reportId}":{"get":{"tags":["방문 인증"],"summary":"내 방문자 검증 제보 상세 조회","operationId":"getMine","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"401":{"description":"인증되지 않았거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"200":{"description":"내 제보 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyVisitorVerificationReportResponse"}}}},"404":{"description":"제보를 찾을 수 없음 (REPORT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"REPORT_NOT_FOUND":{"description":"REPORT_NOT_FOUND","value":{"message":"방문자 검증 제보를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}}}},"403":{"description":"활성 일반 사용자 계정이 아니거나 본인 소유 제보가 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"활성 일반 사용자만 제보할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}},"REPORT_FORBIDDEN":{"description":"REPORT_FORBIDDEN","value":{"message":"이 제보를 조회할 권한이 없습니다.","code":"REPORT_FORBIDDEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/visit-verification-sessions/{sessionId}":{"get":{"tags":["방문 인증"],"summary":"내 체류 기반 방문 인증 상태 조회","operationId":"get","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"현재 인증 세션 상태","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitVerificationSessionResponse"}}}},"403":{"description":"활성 관광객 계정이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"본인 소유 인증 세션을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me":{"get":{"tags":["내 정보·계정 연동"],"summary":"내 정보 조회","description":"현재 인증된 사용자의 마이페이지 정보를 조회합니다.","operationId":"getMyPageInfo","responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyPageResponse"},"example":{"id":1,"username":"pingdom_user","email":"pingdom@example.com","birthYear":1998,"profileImageUrl":"https://cdn.pingdom.com/profiles/user1.png","language":"ko","country":"KR"}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["내 정보·계정 연동"],"summary":"회원탈퇴","description":"현재 인증된 사용자의 개인정보를 익명화하고 탈퇴 상태로 전환합니다.","operationId":"withdraw","responses":{"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"204":{"description":"회원탈퇴 성공"},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/reviews":{"get":{"tags":["내 리뷰"],"summary":"내가 작성한 장소 리뷰 목록 조회","description":"삭제 완료된 리뷰는 목록과 총 개수에서 제외합니다.","operationId":"listMine_1","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"400":{"description":"페이지 요청 값 검증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"200":{"description":"내 리뷰 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyPlaceReviewPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/naver-place-search":{"get":{"tags":["장소 등록 신청"],"summary":"신규 장소 등록용 네이버 업체명 검색","description":"네이버 Local Search 결과를 최대 5건의 장소명·도로명 주소·지번 주소·WGS84 좌표로 반환합니다.","operationId":"searchNaverPlace","parameters":[{"name":"query","in":"query","description":"업체명. 입력값은 1~100자이며, 앞뒤 공백을 trim한 검색어로 조회합니다. 공백만 있는 값은 허용하지 않습니다.","required":true,"schema":{"maxLength":100,"minLength":1,"type":"string"}}],"responses":{"503":{"description":"NAVER_PLACE_SEARCH_UNAVAILABLE: 비활성 또는 인증값 미설정","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"INVALID_REQUEST_PARAMETER: query 누락. PLACE_SEARCH_CONDITION_INVALID: trim 후 빈 검색어. 입력 검증 오류는 기존 공통 오류 계약을 유지합니다.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"200":{"description":"업체명 검색 후보","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NaverPlaceSearchResponse"}}}},"502":{"description":"NAVER_PLACE_SEARCH_FAILED: 외부 호출 실패·빈 응답·좌표 변환 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/naver-address-search":{"get":{"tags":["장소 등록 신청"],"summary":"신규 장소 등록용 네이버 주소 검색","description":"도로명·지번 주소 후보를 최대 10건 반환합니다. 좌표는 WGS84 기준이며, 우편번호가 없는 후보는 null로 반환합니다.","operationId":"searchNaverAddress","parameters":[{"name":"query","in":"query","description":"도로명 또는 지번 주소. 입력값은 1~100자이며, 앞뒤 공백을 trim한 검색어로 조회합니다. 공백만 있는 값은 허용하지 않습니다.","required":true,"schema":{"maxLength":100,"minLength":1,"type":"string"}}],"responses":{"400":{"description":"INVALID_REQUEST_PARAMETER: query 누락. PLACE_SEARCH_CONDITION_INVALID: trim 후 빈 검색어. 입력 검증 오류는 기존 공통 오류 계약을 유지합니다.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"502":{"description":"NAVER_ADDRESS_SEARCH_FAILED: 외부 호출 실패·비정상 응답·좌표 변환 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"주소 검색 후보","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NaverAddressSearchResponse"}}}},"504":{"description":"NAVER_ADDRESS_SEARCH_TIMEOUT: 외부 Geocoding 응답 시간 초과","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"NAVER_ADDRESS_SEARCH_RATE_LIMITED: 외부 Geocoding 호출 한도 초과","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"NAVER_ADDRESS_SEARCH_UNAVAILABLE: 비활성·미설정·외부 서버 장애·연결 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/export":{"get":{"tags":["내 정보·계정 연동"],"summary":"내 데이터 내보내기","description":"현재 인증된 사용자의 계정 정보, 전체 북마크, 최근 좋아요한 지도 이미지 ID 최대 50개, 여행 일정, Claim 이력과 만료되지 않은 현재 행동 의도를 JSON으로 조회합니다.","operationId":"exportMyData","responses":{"200":{"description":"내보내기 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserDataExportResponse"},"example":{"user":{"id":1,"username":"pingdom_user","profileImageUrl":"https://cdn.pingdom.com/profiles/user1.png"},"bookmarks":[{"id":10,"placeId":123}],"likedMapImageIds":[981,812,700],"travelSchedules":[{"id":31,"startDate":"2026-08-01","endDate":"2026-08-03","state":"SCHEDULED"}],"currentActivityIntent":{"intent":"CAFE","expiresAt":"2026-08-01T14:00:00"},"merchantPlaceClaims":[{"id":40,"placeId":123,"status":"REJECTED","claimReason":"매장 운영자입니다.","reviewReason":"사업자 주소 불일치","reviewedAt":"2026-07-16T10:00:00","createdAt":"2026-07-15T14:00:00"}]}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"인증되지 않은 요청 또는 유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/scout-field-reports/{reportId}":{"get":{"tags":["스카우트"],"summary":"내 Scout 현장 제보 상세 조회","operationId":"getMine_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/reservations/{reservationId}":{"get":{"tags":["예약"],"summary":"내 예약 상세 조회","description":"활성 일반 사용자는 본인 예약만 조회할 수 있습니다.\n아직 확정되지 않은 예약의 confirmedAt과 취소되지 않은 예약의 canceledAt은 null입니다.\n","operationId":"get_4","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"403":{"description":"활성 일반 사용자 계정이 아니거나 다른 사용자의 예약","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOURIST_ACCOUNT_REQUIRED":{"description":"TOURIST_ACCOUNT_REQUIRED","value":{"message":"일반 사용자 계정만 예약할 수 있습니다.","code":"TOURIST_ACCOUNT_REQUIRED"}},"RESERVATION_FORBIDDEN":{"description":"RESERVATION_FORBIDDEN","value":{"message":"이 예약을 처리할 권한이 없습니다.","code":"RESERVATION_FORBIDDEN"}}}}}},"200":{"description":"내 예약 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"404":{"description":"예약을 찾을 수 없음 (RESERVATION_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"RESERVATION_NOT_FOUND":{"description":"RESERVATION_NOT_FOUND","value":{"message":"예약을 찾을 수 없습니다.","code":"RESERVATION_NOT_FOUND"}}}}}},"401":{"description":"유효하지 않거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/popup-campaigns":{"get":{"tags":["행사·팝업"],"summary":"진행 중인 공개 팝업 캠페인 목록 조회","description":"PUBLISHED 상태이며 시작 시각 이상, 종료 시각 미만인 캠페인만 조회합니다. 빈 목록은 items=[], totalCount=0, totalPages=0, hasNext=false로 반환합니다.","operationId":"list_3","parameters":[{"name":"placeId","in":"query","description":"장소 ID 필터","required":false,"schema":{"type":"integer","format":"int64"},"example":101},{"name":"page","in":"query","description":"페이지 번호. 1 미만은 1, 10000 초과는 10000으로 보정됩니다.","required":false,"schema":{"maximum":10000,"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 1 미만은 1, 100 초과는 100으로 보정됩니다.","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"공개 팝업 캠페인 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicPopupCampaignPageResponse"}}}},"400":{"description":"페이지 또는 장소 필터 형식이 올바르지 않음 (INVALID_INPUT)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_INPUT":{"description":"INVALID_INPUT","value":{"message":"브랜드 또는 캠페인 입력값이 올바르지 않습니다.","code":"INVALID_INPUT"}}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/popup-campaigns/{campaignId}":{"get":{"tags":["행사·팝업"],"summary":"진행 중인 공개 팝업 캠페인 상세 조회","description":"종료·비공개·없는 캠페인은 모두 404 CAMPAIGN_NOT_FOUND로 처리합니다.","operationId":"get_5","parameters":[{"name":"campaignId","in":"path","description":"팝업 캠페인 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"캠페인을 찾을 수 없거나 공개 대상이 아님 (CAMPAIGN_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CAMPAIGN_NOT_FOUND":{"description":"CAMPAIGN_NOT_FOUND","value":{"message":"팝업 캠페인을 찾을 수 없습니다.","code":"CAMPAIGN_NOT_FOUND"}}}}}},"200":{"description":"공개 팝업 캠페인 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicPopupCampaignResponse"}}}},"400":{"description":"캠페인 ID 형식이 올바르지 않음 (INVALID_INPUT)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_INPUT":{"description":"INVALID_INPUT","value":{"message":"브랜드 또는 캠페인 입력값이 올바르지 않습니다.","code":"INVALID_INPUT"}}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places":{"get":{"tags":["장소 탐색"],"summary":"장소 목록 조회","description":"장소명·영문명·주소 또는 등록된 공개 메뉴명에 검색어가 부분 일치하는 장소를 조회합니다.\n메뉴 상태 AVAILABLE/SOLD_OUT만 검색하며 숨김·비활성 메뉴와 메뉴 설명은 검색하지 않습니다.\n여러 메뉴가 일치해도 장소는 한 번만 반환합니다. 카테고리는 검색어와 함께 적용하는 선택 필터입니다.\n검색어를 생략하거나 빈 값·공백만 전달하면 일반 장소 탐색을 유지하며 예약 날짜·시간·인원은 필요하지 않습니다.\n위치·반경과 검색 조건을 적용한 뒤 sort로 정렬하고 limit(1~100)으로 페이지를 제한합니다.\n주변 거리순 검색은 latitude/longitude/radiusKm와 sort=NEAREST를 전달하며, 앱은 limit=3을 사용할 수 있습니다.\n결과가 없으면 200과 빈 places, totalCount=0을 반환합니다.\n","operationId":"listPlaces","parameters":[{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"장소명·영문명·주소 또는 공개 메뉴명 부분 검색어. 앞뒤 공백은 제거하며 %, _, 역슬래시는 문자 그대로 검색합니다.","required":false,"schema":{"type":"string"},"example":"갈비탕"},{"name":"category","in":"query","description":"카테고리 필터","required":false,"schema":{"type":"string"},"example":"카페"},{"name":"touristCategory","in":"query","description":"관광 카테고리 필터","required":false,"schema":{"type":"string"},"example":"K_POP"},{"name":"latitude","in":"query","description":"현재 위도. 거리 검색 시 longitude, radiusKm와 함께 전달합니다.","required":false,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.1801},{"name":"longitude","in":"query","description":"현재 경도. 거리 검색 시 latitude, radiusKm와 함께 전달합니다.","required":false,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.1078},{"name":"radiusKm","in":"query","description":"검색 반경(km). 거리 검색 시 latitude, longitude와 함께 전달합니다.","required":false,"schema":{"maximum":20.0,"exclusiveMaximum":false,"minimum":0.1,"exclusiveMinimum":false,"type":"number","format":"double"},"example":3.0},{"name":"sort","in":"query","description":"정렬 기준. LATEST, NEAREST 또는 POPULAR","required":false,"schema":{"type":"string","default":"LATEST"},"example":"LATEST"}],"responses":{"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"200":{"description":"장소 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceListResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/visit-decision":{"get":{"tags":["장소 상세·메뉴"],"summary":"관광객용 장소 방문 결정 정보 조회","description":"현재 운영 상태, 공지, 진행 이벤트, 예약 가능 시간과 발급 가능한 혜택을 한 번에 조회합니다.","operationId":"getPlaceVisitDecision","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"공개 중인 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"방문 결정 정보 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceVisitDecisionResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/operating-notices":{"get":{"tags":["장소 상세·메뉴"],"summary":"장소 활성 운영 상태 공지 조회","description":"현재 영업시간 기준 운영 여부와 활성 운영 상태 공지를 조회합니다.","operationId":"listOperatingNotices","parameters":[{"name":"placeId","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"활성 운영 상태 공지 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceOperatingNoticeListResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/menus":{"get":{"tags":["장소 상세·메뉴"],"summary":"관광객용 장소 메뉴 목록 조회","description":"AVAILABLE와 SOLD_OUT 메뉴만 displayOrder 오름차순으로 반환합니다. 로그인 사용자는 국가 코드에 따른 참고 환산 가격을 함께 받습니다. 예를 들어 원래 가격이 KRW 9,000원인 메뉴는 USD 6.43으로 환산될 수 있으며, 이는 가정된 환율 예시입니다. 원래 통화와 표시 통화가 같으면 convertedPrice는 null이고, 실제 결제 기준은 항상 원래 가격과 통화입니다.","operationId":"list_5","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"공개 메뉴 목록 조회 성공","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlaceMenuPublicResponse"}}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/card":{"get":{"tags":["장소 상세·메뉴"],"summary":"관광객용 장소 카드 조회","description":"관광객의 장소 탐색과 방문 결정을 위한 요약 정보를 조회합니다.","operationId":"getTouristPlaceCard","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"공개 중인 장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"장소 카드 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TouristPlaceCardResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/availabilities":{"get":{"tags":["예약"],"summary":"장소 예약 가능 시간 조회","operationId":"list_6","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AvailabilityResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/availabilities/{availabilityId}/quote":{"get":{"tags":["예약"],"summary":"예약 전 견적·취소 조건 조회","description":"활성 일반 사용자 본인의 확인 토큰을 준비합니다. 예약 생성·결제·재고 점유는 수행하지 않습니다. 유효기간은 최대 5분이며 슬롯 시작 전까지입니다. 사용자 확인 직전에 다시 조회하세요.","operationId":"quote","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"availabilityId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"quantity","in":"query","required":true,"schema":{"minimum":1,"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationQuoteResponse"}}}},"404":{"description":"RESERVATION_SLOT_NOT_FOUND: 슬롯 부재/장소 불일치. 재확인이 필요합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"QUOTE_CONDITIONS_CHANGED: 조건 변경. RESERVATION_SLOT_INACTIVE: 비활성/시작된 슬롯. RESERVATION_CAPACITY_EXCEEDED: 정원 부족. 재확인이 필요합니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"QUOTE_TERMS_UNAVAILABLE: 시간대/취소 정책 미설정 또는 시간 해석 불가. 취소 정책을 추정하지 않습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"TOURIST_ACCOUNT_REQUIRED: 활성 일반 사용자만 견적을 조회할 수 있습니다.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"QUOTE_RATE_LIMITED: 사용자당 시간당 60건 또는 미사용 견적 120건 한도 초과. 잠시 후 다시 조회하세요.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/{id}/media/verification":{"get":{"tags":["장소 상세·메뉴"],"summary":"장소 검증용 미디어 조회","description":"장소 소유자가 검증 출처로 기록된 미디어를 조회합니다.","operationId":"getVerificationMedia","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"200":{"description":"검증용 미디어 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceMediaResponse"}}}},"403":{"description":"본인 소유가 아닌 장소의 검증 미디어 조회","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{id}":{"get":{"tags":["장소 상세·메뉴"],"summary":"장소 상세 조회","description":"특정 장소의 상세 정보를 조회합니다.","operationId":"getPlace","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"장소 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceDetailResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/trends":{"get":{"tags":["장소 탐색"],"summary":"전국 장소 트렌드 조회","description":"이력 수집 시작 시점부터 최근 7일의 북마크 순증가량으로 공개 운영 장소를 조회합니다.","operationId":"findTrends","parameters":[{"name":"period","in":"query","description":"지원 기간. 현재 WEEK만 지원합니다.","required":false,"schema":{"type":"string","default":"WEEK"},"example":"WEEK"},{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 최대 50","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"전국 장소 트렌드 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceTrendResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"지원하지 않는 기간 또는 페이지 조건","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceTrendResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/recommendations":{"get":{"tags":["장소 탐색"],"summary":"장소 추천 조회","description":"현재 위치와 사용자 반응 이력을 기반으로 추천 장소를 조회합니다.","operationId":"recommendPlaces","parameters":[{"name":"latitude","in":"query","description":"현재 위도","required":true,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.1801},{"name":"longitude","in":"query","description":"현재 경도","required":true,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.1078},{"name":"limit","in":"query","description":"추천 최대 개수","required":false,"schema":{"maximum":20,"minimum":1,"type":"integer","format":"int32","default":10},"example":10},{"name":"radiusKm","in":"query","description":"초기 탐색 반경(km)","required":false,"schema":{"maximum":20.0,"exclusiveMaximum":false,"minimum":1.0,"exclusiveMinimum":false,"type":"number","format":"double","default":5.0},"example":5.0},{"name":"recommendationVersion","in":"query","description":"강제 추천 버전","required":false,"schema":{"type":"string"},"example":"place-rec-v2"}],"responses":{"400":{"description":"좌표 또는 요청값 검증 실패","content":{"*/*":{"example":{"message":"recommendPlaces.latitude: 위도는 -90.0 이상이어야 합니다."}}}},"200":{"description":"장소 추천 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceRecommendationResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/recommendations/{requestId}/explanation":{"get":{"tags":["장소 탐색"],"summary":"추천 설명 조회","description":"사용자가 본인 추천 응답 requestId의 후보 source, score, ranking 정보를 조회합니다.","operationId":"getRecommendationExplanation","parameters":[{"name":"requestId","in":"path","description":"추천 응답 requestId","required":true,"schema":{"type":"string"},"example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}],"responses":{"404":{"description":"추천 설명 정보를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"추천 설명 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceRecommendationExplanationResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/nearby-reservable":{"get":{"tags":["장소 탐색"],"summary":"현재 위치 주변 예약 가능 장소 조회","description":"현재 위치와 예약 조건에 맞는 장소를 한 번에 조회합니다.","operationId":"nearbyReservablePlaces","parameters":[{"name":"latitude","in":"query","description":"현재 위도","required":true,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.8714},{"name":"longitude","in":"query","description":"현재 경도","required":true,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.6014},{"name":"radiusKm","in":"query","description":"검색 반경(km)","required":false,"schema":{"maximum":20.0,"exclusiveMaximum":false,"minimum":0.1,"exclusiveMinimum":false,"type":"number","format":"double","default":3.0},"example":3.0},{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-10T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-11T00:00:00"},{"name":"quantity","in":"query","description":"예약 인원","required":false,"schema":{"minimum":1,"type":"integer","format":"int32"},"example":2},{"name":"category","in":"query","description":"장소 카테고리","required":false,"schema":{"type":"string"},"example":"테마파크"},{"name":"touristCategory","in":"query","description":"관광 카테고리","required":false,"schema":{"type":"string"},"example":"ATTRACTION"},{"name":"sort","in":"query","description":"정렬","required":false,"schema":{"type":"string","default":"NEAREST","enum":["NEAREST","EARLIEST_AVAILABLE","POPULAR"]}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NearbyReservablePlaceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/map":{"get":{"tags":["장소 탐색"],"summary":"지도 viewport 장소 조회","description":"지도 경계와 zoom에 따라 장소 cluster 또는 marker를 조회합니다.","operationId":"mapViewport","parameters":[{"name":"west","in":"query","description":"서쪽 경도 경계","required":true,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.0},{"name":"south","in":"query","description":"남쪽 위도 경계","required":true,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.0},{"name":"east","in":"query","description":"동쪽 경도 경계","required":true,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":129.0},{"name":"north","in":"query","description":"북쪽 위도 경계","required":true,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":36.0},{"name":"zoom","in":"query","description":"지도 zoom 단계","required":true,"schema":{"maximum":20,"minimum":0,"type":"integer","format":"int32"},"example":14}],"responses":{"400":{"description":"지도 경계 또는 zoom 조건이 올바르지 않음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"지도 viewport 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MapViewportResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/local-hot":{"get":{"tags":["장소 탐색"],"summary":"시·군·구 우리 지역 핫플 조회","description":"좌표 또는 이전 응답의 regionCode 중 하나로 시·군·구의 공개 운영 장소를 현재 북마크 수 순으로 조회합니다.","operationId":"findLocalHotPlaces","parameters":[{"name":"latitude","in":"query","description":"현재 위도. longitude와 함께 전달하며 regionCode와 동시에 전달할 수 없습니다.","required":false,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":37.5172},{"name":"longitude","in":"query","description":"현재 경도. latitude와 함께 전달하며 regionCode와 동시에 전달할 수 없습니다.","required":false,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":127.0473},{"name":"regionCode","in":"query","description":"이전 좌표 조회 응답의 5자리 시·군·구 코드","required":false,"schema":{"pattern":"\\d{5}","type":"string"},"example":11680},{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 최대 50","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"502":{"description":"외부 지역 판정 서비스 호출 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"200":{"description":"지역 핫플 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"404":{"description":"판정되거나 등록된 시·군·구를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"좌표·지역 코드·페이지 조건이 올바르지 않음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"503":{"description":"외부 지역 판정 서비스 미설정 또는 사용 불가","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceLocalHotResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/information-reports":{"get":{"tags":["장소 정보 제보"],"summary":"내 장소 정보 신고 목록 조회","operationId":"listMine_3","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/places/information-reports/{reportId}":{"get":{"tags":["장소 정보 제보"],"summary":"내 장소 정보 신고 상세 조회","operationId":"getMine_2","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/autocomplete":{"get":{"tags":["장소 탐색"],"summary":"장소 검색 자동완성","description":"검색어 입력 중 장소 후보를 자동완성으로 조회합니다.","operationId":"autocompletePlaces","parameters":[{"name":"keyword","in":"query","description":"검색어","required":true,"schema":{"type":"string"},"example":"진주"},{"name":"limit","in":"query","description":"최대 반환 개수","required":false,"schema":{"type":"integer","format":"int32","default":10},"example":10},{"name":"latitude","in":"query","description":"현재 위도","required":false,"schema":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":35.1801},{"name":"longitude","in":"query","description":"현재 경도","required":false,"schema":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"example":128.1078}],"responses":{"400":{"description":"잘못된 요청값","content":{"*/*":{"example":{"message":"latitude와 longitude는 함께 전달해야 합니다."}}}},"200":{"description":"장소 자동완성 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceAutocompleteResponse"}}}},"401":{"description":"유효하지 않은 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/payments":{"get":{"tags":["결제"],"summary":"내 결제 목록 조회","description":"결제 내역이 없으면 payments가 빈 배열인 200 응답을 반환합니다.","operationId":"list_7","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"400":{"description":"페이지 요청 값 검증 실패 (VALIDATION_FAILED)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"examples":{"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값을 확인해주세요.","code":"VALIDATION_FAILED","errors":{"page":"1 이상이어야 합니다."}}}}}}},"200":{"description":"내 결제 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentPageResponse"}}}},"403":{"description":"활성 일반 사용자 계정이 아님 (PAYMENT_FORBIDDEN)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PAYMENT_FORBIDDEN":{"description":"PAYMENT_FORBIDDEN","value":{"message":"이 결제 거래를 처리할 권한이 없습니다.","code":"PAYMENT_FORBIDDEN"}}}}}},"401":{"description":"유효하지 않거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/payments/{paymentId}":{"get":{"tags":["결제"],"summary":"내 결제 상세 조회","description":"본인 결제만 조회할 수 있으며, 실패·환불 상태별 nullable 필드는 응답에 포함됩니다.","operationId":"get_6","parameters":[{"name":"paymentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"결제 거래를 찾을 수 없음 (PAYMENT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PAYMENT_NOT_FOUND":{"description":"PAYMENT_NOT_FOUND","value":{"message":"결제 거래를 찾을 수 없습니다.","code":"PAYMENT_NOT_FOUND"}}}}}},"401":{"description":"유효하지 않거나 만료된 토큰","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}},"EXPIRED_TOKEN":{"description":"EXPIRED_TOKEN","value":{"message":"만료된 토큰입니다.","code":"EXPIRED_TOKEN"}}}}}},"200":{"description":"내 결제 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentResponse"}}}},"403":{"description":"활성 일반 사용자 계정이 아니거나 다른 사용자의 결제","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PAYMENT_FORBIDDEN":{"description":"PAYMENT_FORBIDDEN","value":{"message":"이 결제 거래를 처리할 권한이 없습니다.","code":"PAYMENT_FORBIDDEN"}}}}}}},"security":[{"bearerAuth":[]}]}},"/offers":{"get":{"tags":["쿠폰·혜택"],"summary":"발급 가능한 관광객 전용 Offer 목록 조회","operationId":"list_8","parameters":[{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"Offer 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferPageResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/offers/{offerId}":{"get":{"tags":["쿠폰·혜택"],"summary":"발급 가능한 관광객 전용 Offer 상세 조회","operationId":"get_7","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Offer 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"404":{"description":"발급 가능한 Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/verified-boost-products":{"get":{"tags":["Verified Boost"],"summary":"선택 가능한 Verified Boost 활성 상품 목록 조회","operationId":"list_10","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantVerifiedBoostProductPageResponse"}}}},"403":{"description":"활성 Merchant Owner 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations":{"get":{"tags":["예약 관리"],"summary":"소유 장소 예약 목록 조회","operationId":"list_12","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"reservationFrom","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"reservationTo","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}":{"get":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 장소 상세 조회","operationId":"getPlace_1","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerPlaceDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/reviews":{"get":{"tags":["리뷰 관리"],"summary":"점주 리뷰 관리 목록 조회","description":"소유 장소의 VISIBLE, HIDDEN, DELETED 리뷰와 최신 삭제 신청 상태를 1-based 페이지로 조회합니다.","operationId":"listMerchantPlaceReviews","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPlaceReviewPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/operating":{"get":{"tags":["장소 정보 관리"],"summary":"Merchant Owner 장소 운영 정보 조회","operationId":"getOperating","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerOperatingResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/places/{placeId}/members":{"get":{"tags":["팀 관리"],"summary":"Merchant 장소 팀원 목록 조회","description":"OWNER 또는 MANAGER만 활성 상태의 팀원을 ID 오름차순으로 조회할 수 있습니다. REVOKED 팀원과 만료·취소된 초대는 목록에 포함되지 않으며, 권한 부족은 MERCHANT_TEAM_PERMISSION_REQUIRED로 응답합니다.","operationId":"list_14","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"팀원 목록 조회 성공","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MerchantTeamMemberResponse"}}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"403":{"description":"OWNER 또는 MANAGER 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_TEAM_PERMISSION_REQUIRED":{"description":"MERCHANT_TEAM_PERMISSION_REQUIRED","value":{"message":"Merchant 팀원 관리 권한이 필요합니다.","code":"MERCHANT_TEAM_PERMISSION_REQUIRED"}}}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/place-information-reverification-requests":{"get":{"tags":["장소 정보 관리"],"summary":"내 장소 정보 재확인 요청 목록 조회","operationId":"listMine_4","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReverificationListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/performance":{"get":{"tags":["실적"],"summary":"Merchant 성과 요약 조회","description":"소유 장소의 추천 노출, 클릭, 북마크, 예약 전환 성과를 조회합니다.","operationId":"get_10","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantPerformanceResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/payments":{"get":{"tags":["결제"],"summary":"소유 장소 결제 목록 조회","operationId":"list_15","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/payments/settlements":{"get":{"tags":["결제"],"summary":"정산 원장 조회","operationId":"settlements","parameters":[{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SettlementLedgerPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/offers/{offerId}":{"get":{"tags":["캠페인·혜택"],"summary":"내 관광객 전용 Offer 상세 조회","operationId":"get_11","parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"Offer를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"Offer 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OfferResponse"}}}},"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/me":{"get":{"tags":["사업자 정보"],"summary":"승인된 Merchant Owner 프로필 조회","description":"DB의 현재 역할과 승인 상태를 확인합니다.","operationId":"getActiveProfile","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/location-check-ins/{checkInId}/evidence/file":{"get":{"tags":["방문 인증"],"summary":"내 방문 체크인 증빙 파일 다운로드","operationId":"download","parameters":[{"name":"checkInId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"증빙 이미지","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"본인 소유 체크인 또는 증빙을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/events":{"get":{"tags":["행사·팝업"],"summary":"공개 기간형 이벤트 목록 조회","description":"PUBLISHED 상태이며 종료 시각이 현재보다 이후인 이벤트를 시작 시각 순으로 조회합니다. 기간 필터는 [fromAt, toAt)와 겹치는 이벤트에 적용됩니다. 빈 목록은 events=[], totalCount=0, totalPages=0, hasNext=false로 반환합니다.","operationId":"listEvents","parameters":[{"name":"eventType","in":"query","description":"이벤트 유형","required":false,"schema":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]}},{"name":"fromAt","in":"query","description":"기간 겹침 조회 시작 시각. RFC 3339 offset을 받아 UTC로 정규화합니다.","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-08-01T00:00:00Z"},{"name":"toAt","in":"query","description":"기간 겹침 조회 종료 시각. fromAt보다 이후여야 하며 RFC 3339 offset을 받아 UTC로 정규화합니다.","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-01T00:00:00Z"},{"name":"page","in":"query","description":"페이지 번호. 1 미만은 1, 10000 초과는 10000으로 보정됩니다.","required":false,"schema":{"maximum":10000,"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 1 미만은 1, 100 초과는 100으로 보정됩니다.","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"400":{"description":"기간 또는 필터 조건이 올바르지 않음 (PLACE_EVENT_SEARCH_CONDITION_INVALID)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_EVENT_SEARCH_CONDITION_INVALID":{"description":"PLACE_EVENT_SEARCH_CONDITION_INVALID","value":{"message":"이벤트 조회 기간 조건이 올바르지 않습니다.","code":"PLACE_EVENT_SEARCH_CONDITION_INVALID"}}}}}},"200":{"description":"공개 이벤트 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceEventListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/events/{eventId}":{"get":{"tags":["행사·팝업"],"summary":"공개 기간형 이벤트 상세 조회","description":"종료·비공개·없는 이벤트는 모두 404 PLACE_EVENT_NOT_FOUND로 처리합니다.","operationId":"getEvent","parameters":[{"name":"eventId","in":"path","description":"이벤트 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"400":{"description":"이벤트 ID 형식이 올바르지 않음 (PLACE_EVENT_SEARCH_CONDITION_INVALID)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_EVENT_SEARCH_CONDITION_INVALID":{"description":"PLACE_EVENT_SEARCH_CONDITION_INVALID","value":{"message":"이벤트 조회 기간 조건이 올바르지 않습니다.","code":"PLACE_EVENT_SEARCH_CONDITION_INVALID"}}}}}},"404":{"description":"이벤트를 찾을 수 없거나 공개 대상이 아님 (PLACE_EVENT_NOT_FOUND)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PLACE_EVENT_NOT_FOUND":{"description":"PLACE_EVENT_NOT_FOUND","value":{"message":"이벤트를 찾을 수 없습니다.","code":"PLACE_EVENT_NOT_FOUND"}}}}}},"200":{"description":"공개 이벤트 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceEventDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/coupons":{"get":{"tags":["쿠폰·혜택"],"summary":"내 관광객 Coupon 목록 조회","description":"Offer 제목·혜택과 장소 정보는 Coupon 발급 시점 스냅샷을 반환하므로 Offer 종료 또는 이후 정보 변경과 무관하게 유지됩니다. 원본 정보를 복구할 수 없으면 해당 필드는 null입니다. 발급일 기간은 양 끝값을 포함합니다. status=ISSUED는 아직 만료되지 않은 쿠폰, EXPIRED는 발급 상태이면서 expiresAt이 현재 시각 이하인 쿠폰입니다. 기본 정렬은 issuedAt 내림차순, id 내림차순이며 page와 limit은 각각 최소 1, limit 최대 100으로 보정됩니다.","operationId":"list_18","parameters":[{"name":"status","in":"query","description":"쿠폰 상태. 생략하면 모든 상태를 조회합니다.","required":false,"schema":{"type":"string","enum":["ISSUED","REDEEMED","EXPIRED"]},"example":"ISSUED"},{"name":"issuedFrom","in":"query","description":"발급일 조회 시작 시각(포함, ISO-8601 local date-time)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-08-01T00:00:00"},{"name":"issuedTo","in":"query","description":"발급일 조회 종료 시각(포함, ISO-8601 local date-time)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-08-31T23:59:59"},{"name":"page","in":"query","description":"1부터 시작하는 페이지 번호","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"400":{"description":"발급일 기간 조건 또는 요청 파라미터 형식이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"COUPON_LIST_FILTER_INVALID":{"description":"COUPON_LIST_FILTER_INVALID","value":{"message":"쿠폰 조회 기간 조건이 올바르지 않습니다.","code":"COUPON_LIST_FILTER_INVALID"}},"VALIDATION_FAILED":{"description":"VALIDATION_FAILED","value":{"message":"입력값이 올바르지 않습니다.","code":"VALIDATION_FAILED","errors":{"issuedFrom":"날짜 형식이 올바르지 않습니다."}}}}}}},"200":{"description":"Coupon 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CouponPageResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/coupons/{couponId}":{"get":{"tags":["쿠폰·혜택"],"summary":"내 관광객 Coupon 단건 조회","description":"본인이 발급받은 Coupon의 현재 상태를 조회합니다. 만료 시각이 지난 미사용 Coupon은 EXPIRED로 반환하며, REDEEMED Coupon은 redeemedAt을 함께 반환합니다.","operationId":"get_13","parameters":[{"name":"couponId","in":"path","description":"Coupon ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"401":{"description":"인증되지 않은 요청","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_TOKEN":{"description":"INVALID_TOKEN","value":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}}},"404":{"description":"Coupon을 찾을 수 없거나 요청자의 Coupon이 아님","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"COUPON_NOT_FOUND":{"description":"COUPON_NOT_FOUND","value":{"message":"쿠폰을 찾을 수 없습니다.","code":"COUPON_NOT_FOUND"}}}}}},"200":{"description":"Coupon 단건 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CouponResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/posts/{postId}":{"get":{"tags":["커뮤니티 게시글"],"summary":"커뮤니티 게시글 상세 조회","description":"게시글 제목, 본문, 연결 장소의 현재 표시 정보를 조회합니다.","operationId":"findDetail","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"커뮤니티 게시글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/countries":{"get":{"tags":["커뮤니티 게시글"],"summary":"커뮤니티 국가 필터 허용 코드","operationId":"countries","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"type":"string"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/categories":{"get":{"tags":["커뮤니티 게시글"],"summary":"커뮤니티 게시글 카테고리 조회","description":"게시글 작성과 카테고리별 조회에 사용할 활성 카테고리의 식별자와 표시 이름을 조회합니다.","operationId":"findCategories","responses":{"200":{"description":"커뮤니티 게시글 카테고리 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostCategoryListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/categories/{categoryId}/posts":{"get":{"tags":["커뮤니티 게시글"],"summary":"카테고리별 커뮤니티 게시글 목록 조회","description":"미리보기·사진·지역·생성 시각·조회/좋아요/댓글 수와 단일 카테고리를 최신순으로 조회합니다.","operationId":"findByCategory","parameters":[{"name":"categoryId","in":"path","required":true,"schema":{"type":"string"}},{"name":"countryCode","in":"query","description":"ISO alpha-2 국가 코드. 허용 값은 GET /community/countries","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"페이지 번호","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기. 최대 100","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"카테고리별 게시글 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommunityPostListResponse"}}}},"400":{"description":"카테고리 또는 페이지 요청값이 올바르지 않음","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/auth/oauth2/success":{"get":{"tags":["o-auth-2-token-controller"],"summary":"OAuth2 로그인 성공 토큰 교환","operationId":"oauth2Success","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/analysis/reports":{"get":{"tags":["상권 분석"],"summary":"보관된 입지 분석 보고서 목록 조회","operationId":"list_19","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LocationAnalysisReportResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/analysis/reports/{reportId}/html":{"get":{"tags":["상권 분석"],"summary":"보관된 입지 분석 HTML 디버그 조회","operationId":"html","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"text/html":{"schema":{"type":"string"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/analysis/reports/{reportId}/download":{"get":{"tags":["상권 분석"],"summary":"보관된 입지 분석 PDF 다운로드","operationId":"download_1","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/pdf":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports":{"get":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 목록 조회","operationId":"list_20","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/visitor-verification-reports/corrections":{"get":{"tags":["방문 인증·스카우트"],"summary":"방문자 검증 제보 정정 목록 조회","operationId":"listCorrections_1","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/verified-boost-products/{productId}":{"get":{"tags":["Verified Boost"],"summary":"관리자 Verified Boost 상품 상세 조회","operationId":"get_15","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/sanctions":{"get":{"tags":["회원·권한"],"summary":"사용자 제재 이력 조회","description":"관리자가 특정 사용자의 제재 변경 이력을 페이지 단위로 조회합니다. 제재 이력이 없으면 500이 아니라 빈 histories 배열과 페이지 메타데이터를 반환합니다.","operationId":"listUserSanctionHistories","parameters":[{"name":"userId","in":"path","description":"조회할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"banType","in":"query","description":"제재 유형 필터","required":false,"schema":{"type":"string","enum":["PERMANENT","TEMPORARY"]},"example":"TEMPORARY"},{"name":"action","in":"query","description":"처리 상태 필터","required":false,"schema":{"type":"string","enum":["APPLIED","RELEASED","EXPIRED"]},"example":"APPLIED"},{"name":"from","in":"query","description":"처리 시각 시작 필터","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"처리 시각 종료 필터","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"}],"responses":{"400":{"description":"조회 기간 필터 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"제재 이력 조회 종료 시각은 시작 시각보다 이후여야 합니다.","code":"INVALID_SANCTION_FILTER_PERIOD"}}}},"200":{"description":"사용자 제재 이력 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminUserSanctionHistoryResponse"},"example":{"histories":[],"page":1,"limit":5,"totalCount":0,"totalPages":1,"hasNext":false}}}},"404":{"description":"사용자를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/sanction":{"get":{"tags":["회원·권한"],"summary":"사용자 제재 상태 조회","description":"관리자가 특정 사용자의 현재 제재 상태를 조회합니다. 만료된 기간 밴은 현재 제재로 보지 않습니다.","operationId":"getUserSanctionStatus","parameters":[{"name":"userId","in":"path","description":"조회할 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminUserSanctionStatusResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/role-targets":{"get":{"tags":["회원·권한"],"summary":"관리자 역할 부여 대상 사용자 검색","description":"관리자 역할 API에 전달할 수 있는 관리자 계정만 username 부분 일치로 검색합니다. 사용자 공통 표시 이름은 제공되지 않아 username만 검색하며, 빈 keyword는 전체 대상 조회로 처리합니다. page는 1부터 시작하고 limit은 1~100으로 보정됩니다. 이메일과 전화번호는 반환하지 않습니다.","operationId":"search","parameters":[{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기(1~100)","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"username 부분 일치 검색어. 비어 있으면 전체 역할 부여 대상을 조회합니다.","required":false,"schema":{"type":"string"},"example":"operator"}],"responses":{"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"검색 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentTargetSearchResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/banned":{"get":{"tags":["회원·권한"],"summary":"밴 유저 목록 조회","description":"관리자가 현재 밴 처리된 사용자 목록을 페이지 단위로 조회합니다. keyword는 숫자만 입력하면 userId 정확히 일치로 검색하고, 그 외에는 username 부분 일치로 검색합니다. counts는 현재 밴 중인 사용자 기준이며, keyword 검색어가 있으면 검색 결과 기준으로 계산됩니다. 기간 필터는 from과 to를 사용합니다. limit 값은 내부적으로 1~100 범위로 보정됩니다.","operationId":"listBannedUsers","parameters":[{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"숫자만 입력하면 userId 정확히 일치, 그 외에는 username 부분 일치 검색","required":false,"schema":{"type":"string"},"example":"blockedUser01"},{"name":"banType","in":"query","description":"밴 유형","required":false,"schema":{"type":"string","enum":["PERMANENT","TEMPORARY"]},"example":"PERMANENT"},{"name":"from","in":"query","description":"밴 처리 시작 시각 이상","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"밴 처리 종료 시각 이하","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"sortBy","in":"query","description":"정렬 기준","required":false,"schema":{"type":"string","default":"BANNED_AT","enum":["BANNED_AT","EXPIRES_AT","USER_ID"]},"example":"BANNED_AT"},{"name":"sortDirection","in":"query","description":"정렬 방향","required":false,"schema":{"type":"string","default":"DESC","enum":["ASC","DESC"]},"example":"DESC"}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"밴 유저 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminBannedUserResponse"},"example":{"users":[{"userId":7,"username":"blockedUser01","banned":true,"banType":"PERMANENT","bannedAt":"2026-06-07T13:30:00","banExpiresAt":null}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false,"counts":{"total":1,"permanent":1,"temporary":0}}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/banned/{userId}":{"get":{"tags":["회원·권한"],"summary":"밴 유저 상세 조회","description":"관리자가 특정 밴 유저의 상세 정보를 조회합니다.","operationId":"getBannedUser","parameters":[{"name":"userId","in":"path","description":"조회할 밴 유저 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"200":{"description":"밴 유저 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminBannedUserDetailResponse"},"example":{"userId":7,"username":"blockedUser01","email":"blockedUser01@example.com","birthYear":1998,"language":"ko","country":"KR","role":"USER","banned":true,"bannedAt":"2026-06-07T13:30:00","banType":"PERMANENT","banExpiresAt":null,"banReason":"반복적인 신고 누적","createdAt":"2026-06-01T10:00:00"}}}},"404":{"description":"밴 유저를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"사용자를 찾을 수 없습니다.","code":"USER_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}":{"get":{"tags":["신뢰 점수"],"summary":"신고자 신뢰 등급과 점수 근거 조회","description":"관리자가 신고자의 신뢰 점수, 등급, 신고 처리 통계 기반 점수 근거를 조회합니다.","operationId":"getTrustScore","parameters":[{"name":"reporterUserId","in":"path","description":"신고자 사용자 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":7}],"responses":{"200":{"description":"신뢰 등급과 점수 근거 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreResponse"},"example":{"reporterUserId":7,"reporterUsername":"pingdom_user","trustScore":80,"trustGrade":"HIGH","restricted":false,"restrictedUntil":null,"restrictionReason":null,"evidence":{"submittedCount":12,"acceptedCount":8,"declinedCount":4,"falseReportCount":3,"acceptanceRate":66.67,"baseScore":100,"acceptedScoreBonus":40,"falseReportScorePenalty":60}}}}},"404":{"description":"신고자 Trust Score 정책을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"신고자 Trust Score 정책을 찾을 수 없습니다.","code":"TRUST_SCORE_REPORTER_POLICY_NOT_FOUND"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/reporters/{reporterUserId}/history":{"get":{"tags":["신뢰 점수"],"summary":"신고자 Trust Score 변경 이력 조회","operationId":"listTrustScoreHistory","parameters":[{"name":"reporterUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreChangeHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/trust-score/anomalies":{"get":{"tags":["신뢰 점수"],"summary":"관리자 Trust Score 이상치 목록 조회","description":"관리자가 Trust Score 이상치 목록을 조회합니다. page는 1 이상, limit은 1~100 범위로 보정됩니다.","operationId":"listAnomalies","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"reporterUserId","in":"query","description":"신고자 사용자 ID 필터","required":false,"schema":{"type":"integer","format":"int64"},"example":12},{"name":"unresolvedOnly","in":"query","description":"미해결 이상치만 조회할지 여부","required":false,"schema":{"type":"boolean","default":false},"example":true}],"responses":{"200":{"description":"Trust Score 이상치 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 목록 조회","operationId":"list_23","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACTIVE","SUSPENDED","REVOKED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfilePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-profiles/{scoutUserId}":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 프로필 및 활동 자격 상세 조회","operationId":"get_16","parameters":[{"name":"scoutUserId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/scout-field-reports":{"get":{"tags":["방문 인증·스카우트"],"summary":"Scout 현장 제보 목록 조회","operationId":"list_24","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScoutFieldReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/s3/orphan-objects":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"S3 orphan 객체 dry-run 리포트","description":"DB에 등록된 게시글 원본/썸네일 S3 key와 S3 객체 목록을 비교해 DB에서 사용 중이지 않은 객체를 조회합니다. 실제 삭제는 수행하지 않습니다.","operationId":"reportOrphanObjects","parameters":[{"name":"prefix","in":"query","description":"조회할 S3 key prefix","required":false,"schema":{"type":"string","default":"map/"},"example":"map/"},{"name":"limit","in":"query","description":"최대 스캔 객체 수. 1~10000 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1000},"example":1000}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminS3OrphanObjectReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reservations":{"get":{"tags":["예약"],"summary":"관리자 예약 기록 목록 조회","operationId":"list_25","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]}},{"name":"placeId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"merchantOwnerUserId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"touristUserId","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"reservationFrom","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"reservationTo","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReservationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reservations/{reservationId}":{"get":{"tags":["예약"],"summary":"관리자 예약 기록 상세 조회","operationId":"get_18","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/reported-users":{"get":{"tags":["신고·이의신청"],"summary":"관리자 신고 유저 목록 조회","description":"관리자가 PENDING 상태의 신고 유저 목록을 조회합니다. limit 값은 내부적으로 1~100 범위로 보정됩니다.","operationId":"getReportedUsers","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"keyword","in":"query","description":"검색 키워드. 신고자 이름, 신고 사유, 신고받은 유저 ID로 검색합니다.","required":false,"schema":{"type":"string","default":""},"example":"욕설"}],"responses":{"200":{"description":"신고 유저 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReportedUsersResponse"},"example":{"users":[{"reportId":12,"reporterUserId":3,"reporterUsername":"reporter01","reportedImageId":101,"reportedUserId":55,"reason":"욕설"}],"page":1,"limit":20,"totalCount":123,"totalPages":7,"hasNext":true}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/reports/reported-users/{id}":{"get":{"tags":["신고·이의신청"],"summary":"관리자 신고 유저 상세 조회","description":"관리자가 신고 상세 정보를 조회합니다.","operationId":"getReportedUser","parameters":[{"name":"id","in":"path","description":"조회할 신고 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":12}],"responses":{"404":{"description":"신고를 찾을 수 없음","content":{"*/*":{"example":{"message":"신고를 찾을 수 없습니다.","code":"REPORT_NOT_FOUND"}}}},"200":{"description":"신고 유저 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReportedUsersItem"},"example":{"reportId":12,"reporterUserId":3,"reporterUsername":"reporter01","reportedImageId":101,"reportedUserId":55,"reason":"욕설"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/report-appeals":{"get":{"tags":["신고·이의신청"],"summary":"신고 이의제기 목록 조회","operationId":"list_26","parameters":[{"name":"status","in":"query","description":"이의제기 상태","required":false,"schema":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]}},{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminReportAppealResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/privacy-processing-histories":{"get":{"tags":["감사·개인정보 처리 이력"],"summary":"개인정보 처리 이력 조회","description":"관리자가 개인정보 export, 탈퇴, 익명화, 삭제 처리 이력을 페이지 단위로 조회합니다.","operationId":"listHistories","parameters":[{"name":"subjectUserId","in":"query","description":"처리 대상 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"actorUserId","in":"query","description":"처리 수행 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"action","in":"query","description":"처리 유형","required":false,"schema":{"type":"string","enum":["EXPORT_REQUESTED","WITHDRAWAL_REQUESTED","ANONYMIZED","DELETED"]},"example":"EXPORT_REQUESTED"},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-31T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PrivacyProcessingHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 삭제 후보 리포트 생성","description":"최근 생성된 S3 고아 파일 리포트의 삭제 후보를 페이지 단위로 조회합니다. 이 API는 S3/DB 전체 스캔이나 실제 삭제를 수행하지 않습니다.","operationId":"createS3OrphanReport","parameters":[{"name":"reportId","in":"query","description":"조회할 리포트 ID. 생략하면 최근 생성된 리포트를 조회합니다.","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReport"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans/report/status":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 리포트 생성 상태 조회","description":"리포트 생성 작업의 RUNNING/COMPLETED/FAILED 상태와 집계 정보를 조회합니다.","operationId":"getS3OrphanReportStatus","parameters":[{"name":"reportId","in":"query","description":"조회할 리포트 ID. 생략하면 최근 생성된 리포트를 조회합니다.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanReportStatus"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places":{"get":{"tags":["장소 조회"],"summary":"관리자 장소 목록 조회","description":"관리자가 등록된 장소 목록을 페이지 단위로 조회합니다.","operationId":"listPlaces_1","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"sortParam","in":"query","description":"장소 정렬 기준. LATEST, OLDEST, LEVEL_DESC만 지원합니다.","required":false,"schema":{"type":"string","enum":["LATEST","OLDEST","LEVEL_DESC"]},"example":"LATEST"},{"name":"keyword","in":"query","description":"장소 검색 키워드. 장소명, 등록자 ID, 주소로 검색합니다.","required":false,"schema":{"type":"string","default":""},"example":"용인"},{"name":"category","in":"query","description":"일반 장소 카테고리 필터. 입력값을 표준 카테고리로 정규화한 뒤 AdminMapPlaceItem.category와 정확히 비교합니다. touristCategories와는 별도 기준입니다.","required":false,"schema":{"type":"string","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"example":"CAFE"}],"responses":{"200":{"description":"장소 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceResponse"},"examples":{"categoryFilteredResult":{"summary":"카테고리 필터 조회 결과","description":"categoryFilteredResult","value":{"places":[{"id":1,"name":"진주성","address":"경상남도 진주시 남강로 626","discoveryStatus":"VISIBLE","category":"CULTURAL_HERITAGE","categoryName":"문화재","touristCategories":["EXHIBITION"],"latitude":35.1894,"longitude":128.0789,"userId":3,"registrant":"placeRegistrar","level":5,"placeGrowth":{"photoCount":10,"level":5,"currentLevelMinPhotoCount":10,"nextLevelMinPhotoCount":16,"progressPercent":0}}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}},"emptyResult":{"summary":"카테고리 필터 결과 없음","description":"emptyResult","value":{"places":[],"page":1,"limit":20,"totalCount":0,"totalPages":1,"hasNext":false}}}}}},"400":{"description":"지원하지 않는 장소 정렬 기준","content":{"*/*":{"example":{"message":"장소 목록은 LATEST 또는 OLDEST 정렬만 지원합니다.","code":"UNSUPPORTED_PLACE_SORT_PARAM"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}":{"get":{"tags":["장소 조회"],"summary":"관리자 장소 상세 조회","description":"관리자가 특정 장소의 기본 정보와 연결된 게시글 목록을 조회합니다.","operationId":"getPlace_2","parameters":[{"name":"id","in":"path","description":"조회할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"sortParam","in":"query","description":"게시글 정렬 기준","required":false,"schema":{"type":"string","default":"LATEST","enum":["LATEST","OLDEST","MOST_LIKED"]},"example":"LATEST"},{"name":"keyword","in":"query","description":"게시글 검색","required":false,"schema":{"type":"string","default":""},"example":"용인"}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"200":{"description":"장소 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDetailResponse"},"example":{"id":1,"name":"진주성","imageUrl":"https://example.com/places/1/representative.jpg","address":"경상남도 진주시 남강로 626","discoveryStatus":"VISIBLE","category":"CULTURAL_HERITAGE","categoryName":"문화재","latitude":35.1894,"longitude":128.0789,"userId":3,"username":"placeOwner","sortParam":"LATEST","postCount":1,"level":5,"placeGrowth":{"photoCount":10,"hiddenPhotoCount":1,"level":5,"currentLevelMinPhotoCount":10,"nextLevelMinPhotoCount":16,"progressPercent":0},"posts":[{"id":10,"imageUrl":"https://example.com/image.jpg","title":"야경 사진","description":"남강 야경입니다.","userId":3,"username":"pingdom_user","createdAt":"2026-05-28T12:00:00","likeCount":5,"visibilityStatus":"HIDDEN","hiddenReason":"ADMIN_HIDDEN"}]}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendations/{requestId}/explanation":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 설명 조회","description":"관리자가 추천 응답 requestId의 후보 source, score, ranking, feature log 정보를 조회합니다.","operationId":"getRecommendationExplanation_1","parameters":[{"name":"requestId","in":"path","description":"추천 응답 requestId","required":true,"schema":{"type":"string"},"example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}],"responses":{"200":{"description":"추천 설명 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationExplanationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-metrics":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 성과 조회","description":"관리자가 장소별 추천 노출, 클릭, CTR 지표를 조회합니다.","operationId":"listRecommendationMetrics","parameters":[{"name":"page","in":"query","description":"조회할 페이지 번호. 1 이상으로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"조회할 최대 개수. 1~100 범위로 보정됩니다.","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"sortBy","in":"query","description":"추천 성과 정렬 기준","required":false,"schema":{"type":"string","enum":["SMOOTHED_CTR","RAW_CTR","BOOKMARK_CONVERSION","LIKE_CONVERSION","TOTAL_CONVERSION","EXPOSURE","CLICK","UPDATED_AT"]},"example":"SMOOTHED_CTR"},{"name":"keyword","in":"query","description":"장소 검색 키워드","required":false,"schema":{"type":"string","default":""},"example":"진주"},{"name":"recommendationVersion","in":"query","description":"추천 버전 필터","required":false,"schema":{"type":"string","default":""},"example":"place-rec-v1"},{"name":"days","in":"query","description":"최근 N일 기준 필터","required":false,"schema":{"type":"integer","format":"int32"},"example":7}],"responses":{"200":{"description":"추천 성과 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricsResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/recommendation-metrics/compare":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 추천 버전 성과 비교","description":"관리자가 두 추천 버전의 CTR, 전환율, 노출 지표를 같은 조건에서 비교합니다.","operationId":"compareRecommendationMetrics","parameters":[{"name":"baselineVersion","in":"query","description":"기준 추천 버전","required":true,"schema":{"type":"string"},"example":"place-rec-v1"},{"name":"targetVersion","in":"query","description":"비교 대상 추천 버전","required":true,"schema":{"type":"string"},"example":"place-rec-v2"},{"name":"keyword","in":"query","description":"장소 검색 키워드","required":false,"schema":{"type":"string","default":""},"example":"진주"},{"name":"days","in":"query","description":"최근 N일 기준 필터","required":false,"schema":{"type":"integer","format":"int32"},"example":7}],"responses":{"200":{"description":"추천 버전 성과 비교 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricsCompareResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/merge-histories":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 장소 병합 이력 조회","description":"관리자가 최근 장소 병합 이력을 조회합니다.","operationId":"listMergeHistories","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceMergeHistoryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicates":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 목록 조회","description":"관리자가 병합 대상이 될 수 있는 중복 장소 그룹을 조회합니다.","operationId":"listDuplicatePlaces","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicates/{id}":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 상세 조회","description":"관리자가 특정 장소의 중복 후보 목록을 조회합니다.","operationId":"getDuplicatePlace","parameters":[{"name":"id","in":"path","description":"중복 후보를 확인할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 조회","operationId":"listDuplicateCandidates","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","default":"PENDING","enum":["PENDING","CONFIRMED","REJECTED","MERGED"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateListResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/duplicate-candidates/{candidateId}":{"get":{"tags":["중복·추천 관리"],"summary":"관리자 중복 장소 후보 상세 조회","operationId":"getDuplicateCandidate","parameters":[{"name":"candidateId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests":{"get":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 목록 조회","operationId":"list_28","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-review-deletion-requests/{deletionRequestId}":{"get":{"tags":["리뷰 삭제 심사"],"summary":"리뷰 삭제 신청 상세 조회","operationId":"get_18","parameters":[{"name":"deletionRequestId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports":{"get":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 목록 조회","operationId":"list_29","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/place-information-reports/{reportId}":{"get":{"tags":["제보·재검증"],"summary":"관리자 장소 정보 신고 상세 조회","operationId":"get_19","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/outbox-events":{"get":{"tags":["Outbox·스토리지 운영"],"summary":"관리자 Outbox 이벤트 조회","description":"운영자가 Outbox 이벤트의 상태와 실패 원인을 조회합니다. 민감한 payload와 deduplication key는 반환하지 않습니다.","operationId":"list_30","parameters":[{"name":"status","in":"query","description":"처리 상태","required":false,"schema":{"type":"string","enum":["PENDING","PROCESSING","RETRY","SUCCEEDED","FAILED"]},"example":"FAILED"},{"name":"eventType","in":"query","description":"이벤트 유형","required":false,"schema":{"type":"string","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"example":"EMAIL_VERIFICATION_REQUESTED"},{"name":"aggregateType","in":"query","description":"aggregate 유형","required":false,"schema":{"type":"string"},"example":"USER"},{"name":"aggregateId","in":"query","description":"aggregate ID","required":false,"schema":{"type":"string"},"example":10},{"name":"from","in":"query","description":"생성 시각 조회 시작","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"생성 시각 조회 종료","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"400":{"description":"조회 기간 오류","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Outbox 복구 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOutboxEventResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 알림 목록 조회","description":"인증된 관리자가 자신에게 전달된 운영 알림을 유형, 읽음 상태, 기간 조건으로 조회합니다. 알림 token은 report:{reportId}, place:{placeId}, sanction:{sanctionId} 형식을 사용합니다.","operationId":"listNotifications","parameters":[{"name":"type","in":"query","description":"관리자 알림 유형: ADMIN_REPORT_RECEIVED, ADMIN_REPORT_PROCESSED, ADMIN_DUPLICATE_PLACE_DETECTED, ADMIN_USER_SANCTION","required":false,"schema":{"type":"string","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"example":"ADMIN_REPORT_RECEIVED"},{"name":"read","in":"query","description":"읽음 여부","required":false,"schema":{"type":"boolean"},"example":false},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-07-31T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"조회 기간 오류","content":{"*/*":{"example":{"message":"알림 조회 종료 시각은 시작 시각보다 이후여야 합니다.","code":"INVALID_NOTIFICATION_FILTER_PERIOD"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"관리자 알림 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationResponse"},"example":{"notifications":[{"notificationId":1,"userId":10,"type":"ADMIN_REPORT_RECEIVED","title":"신고 접수 알림","body":"신고 ID 30 접수가 게시글 ID 12에 등록되었습니다.","token":"report:30","read":false,"createdAt":"2026-07-21T15:30:00"}],"page":1,"limit":20,"totalCount":1,"totalPages":1,"hasNext":false}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notifications/unread-count":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 미확인 알림 개수 조회","description":"관리자가 아직 읽음 처리하지 않은 인앱 알림 개수를 조회합니다.","operationId":"countUnread","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"미확인 알림 개수 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationUnreadCountResponse"},"example":{"unreadCount":3}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/notification-deliveries":{"get":{"tags":["알림·발송 이력"],"summary":"관리자 알림 발송 결과 조회","description":"관리자가 사용자, 채널, 상태, 알림 유형, 기간 조건으로 알림 발송 결과를 페이지 단위로 조회합니다.","operationId":"listDeliveries","parameters":[{"name":"userId","in":"query","description":"수신 사용자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":10},{"name":"channel","in":"query","description":"발송 채널","required":false,"schema":{"type":"string","enum":["FCM","EMAIL"]},"example":"FCM"},{"name":"status","in":"query","description":"발송 상태","required":false,"schema":{"type":"string","enum":["SUCCEEDED","FAILED","RETRY_SCHEDULED","FINAL_FAILED"]},"example":"SUCCEEDED"},{"name":"notificationType","in":"query","description":"인앱 알림 유형","required":false,"schema":{"type":"string","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"example":"NEW_LIKE"},{"name":"outboxEventType","in":"query","description":"Outbox 이벤트 유형","required":false,"schema":{"type":"string","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"example":"EMAIL_VERIFICATION_REQUESTED"},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNotificationDeliveryResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 목록 조회","description":"keyword는 장소명과 신청자 username을 부분 일치로 검색합니다. NEW_PLACE는 신청 장소명, EXISTING_PLACE_CLAIM은 대상 기존 장소명을 검색합니다. submittedFrom·submittedTo는 신청 제출 시각(Asia/Seoul 기준 LocalDateTime)을 포함 경계로 필터링하며, DRAFT는 제출 시각이 없어 기간 필터에서 제외됩니다. 한쪽 기간 경계만 전달할 수 있고 종료 시각이 시작 시각보다 빠르면 400을 반환합니다. 빈 keyword는 검색 조건을 적용하지 않습니다.","operationId":"list_31","parameters":[{"name":"status","in":"query","description":"반복 전달 가능한 신청 상태 필터","required":false,"style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]}}},{"name":"applicationType","in":"query","required":false,"schema":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]}},{"name":"keyword","in":"query","description":"장소명 또는 신청자 username 부분 일치 검색어. 공백 또는 빈 값은 미적용","required":false,"schema":{"type":"string"},"example":"서울"},{"name":"submittedFrom","in":"query","description":"신청 제출 시각 시작 경계(포함)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-01T00:00:00"},{"name":"submittedTo","in":"query","description":"신청 제출 시각 종료 경계(포함)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-09-30T23:59:59"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 상세 조회","operationId":"get_20","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/attachments":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 첨부파일 목록 조회","operationId":"listAttachments","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationAttachmentResponse"}}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-place-applications/{id}/attachments/{attachmentId}/content":{"get":{"tags":["장소 등록 심사"],"summary":"관리자 Merchant 장소 신청 첨부파일 다운로드","operationId":"attachmentContent","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"attachmentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 신청 목록 조회","operationId":"list_32","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfilePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/merchant-owners/{userId}":{"get":{"tags":["사업자 관리"],"summary":"Merchant Owner 신청 상세 조회","operationId":"get_21","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/data-quality/issues":{"get":{"tags":["data-quality-monitoring-controller"],"summary":"데이터 품질 이슈 목록 조회","operationId":"openIssues","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DataQualityIssuePageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/summary":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 요약 조회","description":"전체 장소, 게시글, 처리 대기 신고, 현재 밴 사용자 수와 운영 지표를 조회합니다. 등록 변화 지표는 서버 기준 오늘 00시부터 현재까지와 오늘을 포함한 최근 7일을 제공합니다. 중복 장소는 이름·주소 기준 후보 그룹 수, 밴 만료 예정 사용자는 현재 시각부터 7일 이내의 임시 밴 사용자 수, 위치 정보 누락 장소는 location이 없는 장소 수를 의미합니다.","operationId":"getSummary","responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"대시보드 요약 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardSummaryResponse"},"example":{"placeCount":44,"postCount":58,"pendingReportCount":5,"bannedUserCount":6,"operationalMetrics":{"today":{"period":"TODAY","startedAt":"2026-07-21T00:00:00","endedAt":"2026-07-21T15:30:00","placeRegistrationCount":3,"postRegistrationCount":7},"last7Days":{"period":"LAST_7_DAYS","startedAt":"2026-07-15T00:00:00","endedAt":"2026-07-21T15:30:00","placeRegistrationCount":12,"postRegistrationCount":31},"duplicatePlaceGroupCount":2,"expiringBannedUserCount":4,"missingLocationPlaceCount":1,"expiringBanUntil":"2026-07-28T15:30:00","collectedAt":"2026-07-21T15:30:00"}}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/recent-activities":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 최근 운영 활동 조회","description":"최근 장소 등록, 게시글 등록, 신고 처리, 사용자 밴 및 밴 해제 내역을 조회합니다. limit 값은 내부적으로 1~50 범위로 보정됩니다.","operationId":"getRecentActivities","parameters":[{"name":"limit","in":"query","description":"조회할 최대 개수. 1~50 범위로 보정됩니다.","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","default":10},"example":10}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"최근 운영 활동 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardRecentActivitiesResponse"},"example":{"places":[{"placeId":10,"name":"핑덤 카페","address":"서울특별시 중구 세종대로 110","userId":3,"registrant":"pingdom_user","createdAt":"2026-07-21T15:30:00"}],"posts":[{"postId":22,"title":"야경이 좋은 장소","userId":3,"username":"pingdom_user","placeId":10,"placeName":"핑덤 카페","createdAt":"2026-07-21T15:30:00"}],"reports":[{"reportId":30,"reportedImageId":22,"title":"야경이 좋은 장소","status":"ACCEPTED","processedAt":"2026-07-21T16:00:00","createdAt":"2026-07-21T15:40:00"}],"userSanctions":[{"sanctionId":40,"targetUserId":5,"targetUsername":"reported_user","action":"APPLIED","banType":"PERMANENT","reason":"부적절한 게시글입니다.","processedAt":"2026-07-21T16:00:00"}]}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/dashboard/pending-items":{"get":{"tags":["대시보드"],"summary":"관리자 대시보드 처리 필요 항목 조회","description":"우선 처리해야 하는 PENDING 신고와 통합 사업자·장소 신청 목록을 조회합니다. 통합 신청은 navigationPath로 관리자 심사 상세 화면 이동 경로를 제공합니다. limit 값은 내부적으로 1~50 범위로 보정됩니다.","operationId":"getPendingItems","parameters":[{"name":"limit","in":"query","description":"조회할 최대 개수. 1~50 범위로 보정됩니다.","required":false,"schema":{"maximum":50,"minimum":1,"type":"integer","default":10},"example":10}],"responses":{"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"처리 필요 항목 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDashboardPendingItemsResponse"},"example":{"items":[{"type":"POST_REPORT","targetId":30,"reportId":30,"postId":22,"title":"야경이 좋은 장소","status":"PENDING","createdAt":"2026-07-21T15:40:00","navigationPath":null}],"totalCount":1}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 글 목록 조회","description":"숨김 글을 포함해 카테고리와 숨김 상태로 조회합니다.","operationId":"findPosts","parameters":[{"name":"categoryId","in":"query","required":false,"schema":{"type":"string"}},{"name":"hidden","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityPostPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 글 상세 조회","description":"숨김 여부와 연결 장소를 포함해 조회합니다.","operationId":"findPost","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityPostResponse"}}}},"404":{"description":"커뮤니티 글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}/comments":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 댓글 목록 조회","description":"숨김 댓글을 포함해 숨김 상태로 조회합니다.","operationId":"findComments","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"hidden","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"댓글 목록 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityCommentPageResponse"}}}},"404":{"description":"커뮤니티 글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community/posts/{postId}/comments/{commentId}":{"get":{"tags":["커뮤니티 관리"],"summary":"관리자 커뮤니티 댓글 상세 조회","operationId":"findComment","parameters":[{"name":"postId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"댓글 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityCommentResponse"}}}},"404":{"description":"커뮤니티 글 또는 댓글을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports":{"get":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 목록 조회","operationId":"list_33","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]}},{"name":"targetType","in":"query","required":false,"schema":{"type":"string","enum":["POST","COMMENT"]}},{"name":"page","in":"query","required":false,"schema":{"minimum":1,"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportPageResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/community-reports/{reportId}":{"get":{"tags":["신고·이의신청"],"summary":"관리자 커뮤니티 신고 상세 조회","operationId":"get_22","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"신고 상세 조회 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCommunityReportResponse"},"examples":{"POST":{"summary":"글 신고: postId와 targetId가 동일","description":"POST","value":{"reportId":1,"targetType":"POST","targetId":101,"postId":101,"targetHidden":false,"reporterUserId":10,"reason":"SPAM","description":"글 신고","status":"PENDING","createdAt":"2026-09-17T10:00:00","processedByAdminUserId":null,"processedAt":null}},"COMMENT":{"summary":"댓글 신고: postId는 원문 글, targetId는 댓글","description":"COMMENT","value":{"reportId":2,"targetType":"COMMENT","targetId":202,"postId":101,"targetHidden":false,"reporterUserId":10,"reason":"ABUSE","description":"댓글 신고","status":"PENDING","createdAt":"2026-09-17T10:00:00","processedByAdminUserId":null,"processedAt":null}}}}}},"404":{"description":"커뮤니티 신고를 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/audit-logs":{"get":{"tags":["감사·개인정보 처리 이력"],"summary":"관리자 감사 로그 조회","description":"관리자가 actor, action, target, 기간 조건으로 운영 감사 로그를 페이지 단위로 조회합니다.","operationId":"listAuditLogs","parameters":[{"name":"actorUserId","in":"query","description":"작업 관리자 ID","required":false,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"action","in":"query","description":"작업 유형","required":false,"schema":{"type":"string","enum":["ADMIN_ROLE_ASSIGNED","ADMIN_ROLE_REVOKED","USER_BAN_APPLIED","USER_BAN_RELEASED","REPORT_ACCEPTED","REPORT_DECLINED","COMMUNITY_REPORT_ACCEPTED","COMMUNITY_REPORT_DECLINED","POST_DELETED","POST_HIDDEN","POST_RESTORED","APPEAL_APPROVED","APPEAL_REJECTED","PLACE_DELETED","PLACE_BASIC_INFORMATION_UPDATED","PLACE_KAKAO_PLACE_ID_UPDATED","PLACE_GEOCODING_UPDATED","PLACE_TOURIST_INFO_UPDATED","PLACE_INFORMATION_EVIDENCE_UPDATED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_INFORMATION_REVERIFICATION_COMPLETED","PLACE_INFORMATION_REVERIFICATION_CANCELED","PLACE_INFORMATION_REVERIFICATION_EXPIRED","VISITOR_VERIFICATION_REPORT_REVIEWED","VISITOR_VERIFICATION_REPORT_CORRECTION_REVIEWED","SCOUT_FIELD_REPORT_REVIEWED","SCOUT_PROFILE_REVIEWED","SCOUT_ACTIVITY_ELIGIBILITY_REVIEWED","PLACE_DISCOVERY_STATUS_UPDATED","PLACE_OPERATING_STATUS_UPDATED","PLACE_OPERATING_SCHEDULE_UPDATED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_EVENT_CREATED","PLACE_EVENT_UPDATED","PLACE_EVENT_PUBLISHED","PLACE_EVENT_CANCELLED","PLACE_RECOMMENDATION_TRAFFIC_UPDATED","PLACE_RECOMMENDATION_KILL_SWITCH_UPDATED","TRUST_SCORE_ANOMALY_RESOLVED","TRUST_SCORE_INTERVENTION_RULE_CREATED","TRUST_SCORE_INTERVENTION_RULE_UPDATED","TRUST_SCORE_INTERVENTION_RULE_ENABLED","TRUST_SCORE_INTERVENTION_RULE_DISABLED","TRUST_SCORE_INTERVENTION_EVALUATED","NOTIFICATION_READ","NOTIFICATION_READ_ALL","PLACE_DUPLICATE_CONFIRMED","PLACE_DUPLICATE_REJECTED","PLACE_MERGED","MERCHANT_OWNER_APPROVED","MERCHANT_OWNER_REJECTED","MERCHANT_OWNER_REVOKED","MERCHANT_OWNER_PLACES_UPDATED","MERCHANT_ONBOARDING_UPDATED","MERCHANT_OPERATIONAL_QUALITY_UPDATED","MERCHANT_VERIFICATION_REVIEWED","MERCHANT_VERIFICATION_VIEWED","MERCHANT_PLACE_CLAIM_ATTACHMENT_VIEWED","MERCHANT_PLACE_CLAIM_APPROVED","MERCHANT_PLACE_CLAIM_REJECTED","MERCHANT_PLACE_APPLICATION_APPROVED","MERCHANT_PLACE_APPLICATION_REJECTED","MERCHANT_PLACE_APPLICATION_VIEWED","MERCHANT_PLACE_APPLICATION_ATTACHMENT_VIEWED","OUTBOX_EVENT_RETRIED","AD_CREATED","AD_DELETED","RESERVATION_CONFIRMED","RESERVATION_REJECTED"]},"example":"USER_BAN_APPLIED"},{"name":"targetType","in":"query","description":"대상 유형","required":false,"schema":{"type":"string","enum":["USER","REPORT","COMMUNITY_REPORT","APPEAL","POST","PLACE","PLACE_DUPLICATE_CANDIDATE","PLACE_INFORMATION_EVIDENCE","PLACE_INFORMATION_REPORT","PLACE_INFORMATION_DISPUTE","PLACE_INFORMATION_REVERIFICATION","VISITOR_VERIFICATION_REPORT","VISITOR_VERIFICATION_REPORT_CORRECTION","SCOUT_FIELD_REPORT","SCOUT_PROFILE","SCOUT_ACTIVITY_ELIGIBILITY","PLACE_OPERATING_NOTICE","PLACE_EVENT","TRUST_SCORE_ANOMALY","TRUST_SCORE_INTERVENTION_RULE","NOTIFICATION","OUTBOX_EVENT","MERCHANT_OWNER","MERCHANT_VERIFICATION","MERCHANT_PLACE_CLAIM_ATTACHMENT","MERCHANT_PLACE_CLAIM","MERCHANT_PLACE_APPLICATION","MERCHANT_PLACE_APPLICATION_ATTACHMENT","AD","RESERVATION"]},"example":"USER"},{"name":"targetId","in":"query","description":"대상 ID","required":false,"schema":{"type":"string"},"example":7},{"name":"from","in":"query","description":"조회 시작 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-01T00:00:00"},{"name":"to","in":"query","description":"조회 종료 시각","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-06-30T23:59:59"},{"name":"page","in":"query","description":"페이지 번호(1부터 시작)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"limit","in":"query","description":"페이지 크기","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminAuditLogResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/":{"get":{"tags":["서비스 기본"],"summary":"서버 상태 확인","description":"백엔드 서버 구동 여부와 주요 공개 엔드포인트 정보를 반환합니다.","operationId":"home","responses":{"200":{"description":"서버 상태 조회 성공","content":{"*/*":{"example":{"message":"Pingdom Backend is running.","availableEndpoints":["/auth/signup","/auth/login","/auth/email/resend","/auth/email/verify","/auth/token/refresh","/auth/logout","/users/me"],"signupFields":["username","email","password","birthYear","profileImageUrl","language","country"],"loginFields":["username","password"]}}}}}}},"/voice-ai/sessions/{sessionId}":{"delete":{"tags":["Voice AI"],"summary":"음성 AI 세션 종료","description":"동일 세션의 반복 종료 요청은 성공으로 처리됩니다.","operationId":"close_2","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"SESSION_FORBIDDEN: 다른 사용자 세션. ACCESS_DENIED: 공통 접근 거부","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"SESSION_NOT_FOUND: 존재하지 않는 세션","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/oauth-accounts/google":{"delete":{"tags":["내 정보·계정 연동"],"summary":"Google 계정 연결 해제","description":"현재 인증된 사용자 계정에서 Google OAuth 계정 연결을 해제합니다.","operationId":"unlinkGoogle","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthAccountDisconnectRequest"}}}},"responses":{"409":{"description":"마지막 로그인 수단 보호 정책 위반","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OAuthAccountResponse"}}}},"401":{"description":"유효하지 않은 토큰 또는 현재 비밀번호 불일치","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"연결된 Google 계정을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OAuthAccountResponse"}}}},"200":{"description":"연결 해제 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OAuthAccountResponse"},"example":{"provider":"GOOGLE","linked":false,"message":"Google 계정 연결을 해제했습니다."}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/merchant-place-applications/{applicationId}/attachments/{attachmentId}":{"delete":{"tags":["장소 등록 신청"],"summary":"Merchant 장소 신청 첨부파일 삭제","operationId":"delete","parameters":[{"name":"applicationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"attachmentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"No Content"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/users/me/bookmarks/{placeId}":{"delete":{"tags":["즐겨찾기"],"summary":"장소 북마크 해제","description":"placeId를 기반으로 장소 북마크를 해제합니다.","operationId":"removeBookmark","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"북마크를 찾을 수 없음","content":{"*/*":{"example":{"message":"북마크를 찾을 수 없습니다.","code":"BOOKMARK_NOT_FOUND"}}}},"200":{"description":"북마크 해제 성공","content":{"*/*":{"example":{"userId":1,"placeId":17,"message":"장소 북마크를 해제했습니다."}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{placeId}/reviews/media/{reviewMediaId}":{"delete":{"tags":["리뷰 미디어"],"summary":"장소 리뷰 사진 업로드 취소","description":"리뷰에 연결하지 않은 본인의 사진 업로드를 취소합니다.","operationId":"cancel_4","parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"reviewMediaId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"리뷰 사진 업로드 취소 완료"},"409":{"description":"이미 리뷰에 연결된 사진","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"리뷰 사진을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"다른 사용자의 사진","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/places/{id}/media/exploration/{mediaId}":{"delete":{"tags":["장소 상세·메뉴"],"summary":"장소 탐색용 미디어 삭제","description":"장소 소유자가 탐색용 미디어를 삭제합니다.","operationId":"deleteExplorationMedia","parameters":[{"name":"id","in":"path","description":"장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":1},{"name":"mediaId","in":"path","description":"장소 미디어 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"200":{"description":"탐색용 미디어 삭제 성공","content":{"*/*":{"example":"장소 탐색용 미디어를 삭제했습니다."}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/community/images/{imageId}":{"delete":{"tags":["커뮤니티 게시글"],"summary":"본인 게시글 이미지 또는 미사용 이미지 삭제","operationId":"delete_1","parameters":[{"name":"imageId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"IMAGE_NOT_FOUND: 없는 이미지·타인 이미지·숨김 게시글"},"204":{"description":"No Content"},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/users/{userId}/roles/{role}":{"delete":{"tags":["회원·권한"],"summary":"관리자 역할 회수","operationId":"revoke_3","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"role","in":"path","required":true,"schema":{"type":"string","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentRevokeRequest"}}}},"responses":{"200":{"description":"회수 성공","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRoleAssignmentResponse"}}}},"403":{"description":"관리자 역할 관리 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"활성 역할을 찾을 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/{id}/delete":{"delete":{"tags":["신고·이의신청"],"summary":"관리자 게시글 삭제","description":"관리자가 게시글을 강제로 삭제합니다. S3 객체 삭제는 DB 삭제 확정 후 Outbox로 비동기 처리됩니다.","operationId":"deletePost","parameters":[{"name":"id","in":"path","description":"삭제할 게시글 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":10}],"responses":{"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}},"204":{"description":"게시글 삭제 성공"},"404":{"description":"게시글을 찾을 수 없음","content":{"*/*":{"example":{"message":"게시글을 찾을 수 없습니다.","code":"POST_NOT_FOUND"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/posts/s3/orphans":{"delete":{"tags":["Outbox·스토리지 운영"],"summary":"MapImage S3 고아 파일 삭제","description":"완료된 리포트의 삭제 후보인지 확인하고, 삭제 직전 DB에서 사용 중인 키를 다시 제외한 뒤 S3 객체를 삭제합니다.","operationId":"deleteS3Orphans","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminS3OrphanDeleteRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/S3OrphanDeleteResult"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/{id}/delete":{"delete":{"tags":["장소 정보·품질"],"summary":"관리자 장소 삭제","description":"관리자가 장소를 강제로 삭제합니다.","operationId":"forceDeletePlace","parameters":[{"name":"id","in":"path","description":"강제 삭제할 장소 ID","required":true,"schema":{"type":"integer","format":"int64"},"example":5}],"responses":{"404":{"description":"장소를 찾을 수 없음","content":{"*/*":{"example":{"message":"장소를 찾을 수 없습니다.","code":"PLACE_NOT_FOUND"}}}},"401":{"description":"인증 실패","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"유효하지 않은 토큰입니다.","code":"INVALID_TOKEN"}}}},"409":{"description":"연결된 기간형 이벤트가 있어 장소를 삭제할 수 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"204":{"description":"장소 삭제 성공"},"403":{"description":"관리자 권한 없음","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"message":"관리자 권한이 필요합니다.","code":"ACCESS_DENIED"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations/{reservationId}":{"get":{"tags":["예약 관리"],"summary":"소유 장소 예약 상세 및 처리 이력 조회","operationId":"get_8","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MerchantReservationDetailResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations/{reservationId}/confirm":{"post":{"tags":["예약 관리"],"summary":"소유 장소 예약 승인","description":"현재 장소 소유자만 대기 예약을 승인할 수 있습니다. 승인 사유는 선택입니다.","operationId":"confirm","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationReviewRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/merchant-owner/reservations/{reservationId}/reject":{"post":{"tags":["예약 관리"],"summary":"소유 장소 예약 반려","description":"현재 장소 소유자만 대기 예약을 반려할 수 있습니다. 반려 사유는 필수입니다.","operationId":"reject","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationReviewRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReservationResponse"}}}},"401":{"description":"유효하지 않거나 만료된 Bearer JWT (INVALID_TOKEN 또는 EXPIRED_TOKEN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"권한이 없거나 접근이 거부됨 (ACCESS_DENIED 또는 도메인 권한 오류)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"요청 값 검증 실패 (VALIDATION_FAILED) 또는 도메인 입력 정책 위반","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/map":{"get":{"tags":["장소 조회"],"summary":"관리자 지도 지역 집계 및 공간 그룹 조회","description":"zoom 0~8 SIDO, 9~11 SIGUNGU, 12~20 SPATIAL. 지역은 화면 안 장소 기준으로 선택하며 count는 동일 필터의 지역 전체 수입니다. bounds는 행정 경계가 아닌 PLACE_EXTENT입니다. 지역 미연결 장소는 공간 그룹/마커로 반환합니다. viewportPlaceCount와 지역 count는 합산하지 않습니다. 초기 상한 200개(설정 가능)이며 초과 시 재집계합니다. EXPAND는 nextZoom 이상 확대합니다. clusterKey는 표시용 고정 키입니다. 안전 한도 초과는 complete=false, RESULT_BUDGET_EXCEEDED, ZOOM_IN으로 안내합니다. 정상 0건은 빈 배열, viewportPlaceCount=0, complete=true입니다.","operationId":"find_2","parameters":[{"name":"west","in":"query","required":true,"schema":{"maximum":180,"minimum":-180,"type":"string","example":128.5},"example":128.5},{"name":"south","in":"query","required":true,"schema":{"maximum":85.05112878,"minimum":-85.05112878,"type":"string","example":35.8},"example":35.8},{"name":"east","in":"query","required":true,"schema":{"maximum":180,"minimum":-180,"type":"string","example":128.7},"example":128.7},{"name":"north","in":"query","required":true,"schema":{"maximum":85.05112878,"minimum":-85.05112878,"type":"string","example":35.95},"example":35.95},{"name":"zoom","in":"query","required":true,"schema":{"maximum":20,"minimum":0,"type":"integer","format":"int32"}},{"name":"width","in":"query","required":true,"schema":{"maximum":8192,"minimum":64,"type":"integer","format":"int32"}},{"name":"height","in":"query","required":true,"schema":{"maximum":8192,"minimum":64,"type":"integer","format":"int32"}},{"name":"keyword","in":"query","required":false,"schema":{"maxLength":100,"minLength":0,"type":"string"}},{"name":"category","in":"query","required":false,"schema":{"maxLength":100,"minLength":0,"type":"string"}},{"name":"discoveryStatus","in":"query","required":false,"schema":{"type":"string","enum":["VISIBLE","HIDDEN"]}},{"name":"operatingStatus","in":"query","required":false,"schema":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]}}],"responses":{"503":{"description":"ADMIN_PLACE_MAP_QUERY_TIMEOUT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapResponse"}}}},"200":{"description":"지역/공간 혼합 또는 빈 결과","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapResponse"},"examples":{"spatial":{"summary":"공간 그룹과 개별 장소","description":"spatial","value":{"mode":"SPATIAL","zoom":13,"regions":[],"clusters":[{"clusterKey":"v1:filterHash:resolution:x:y","clusterId":"opaque-token","count":24,"latitude":35.871,"longitude":128.601,"bounds":{"west":128.6,"south":35.87,"east":128.603,"north":35.873},"countScope":"VIEWPORT","action":"EXPAND","nextZoom":14}],"markers":[{"id":1820,"name":"예시 카페","latitude":35.875,"longitude":128.61,"category":"CAFE","discoveryStatus":"HIDDEN","operatingStatus":"OPERATING"}],"viewportPlaceCount":25,"complete":true,"incompleteReason":null,"recoveryAction":null}},"regional":{"summary":"지역 전체 수와 화면 내 수 구분","description":"regional","value":{"mode":"SIGUNGU","zoom":10,"regions":[{"regionLevel":"SIGUNGU","regionCode":"27260","name":"대구광역시 수성구","count":320,"countScope":"REGION","latitude":35.858,"longitude":128.631,"bounds":{"west":128.6,"south":35.8,"east":128.76,"north":35.9},"boundsSource":"PLACE_EXTENT","action":"EXPAND","nextZoom":12}],"clusters":[],"markers":[],"viewportPlaceCount":120,"complete":true,"incompleteReason":null,"recoveryAction":null}},"empty":{"summary":"정상 0건","description":"empty","value":{"mode":"SPATIAL","zoom":13,"regions":[],"clusters":[],"markers":[],"viewportPlaceCount":0,"complete":true,"incompleteReason":null,"recoveryAction":null}}}}}},"400":{"description":"잘못된 경계·zoom·크기·필터","content":{"application/json":{"example":{"message":"관리자 지도 조회 조건이 올바르지 않습니다.","code":"ADMIN_PLACE_MAP_INVALID_REQUEST"}}}},"401":{"description":"인증 필요","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 필요","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/admin/places/map/clusters/{clusterId}/places":{"get":{"tags":["장소 조회"],"summary":"관리자 지도 그룹 내부 장소 조회","description":"원래 필터·영역·격자를 유지한 ID 오름차순 페이지. page 1~1000000, limit 1~100. 토큰은 5분 유효하며 변조·만료·그룹 변경·정책 버전 변경은 409. 409 발생 시 지도 재조회 후 그룹을 다시 선택합니다. 각 요청에서 관리자 권한을 재검사합니다.","operationId":"groupPlaces","parameters":[{"name":"clusterId","in":"path","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"400":{"description":"잘못된 페이지","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapGroupPage"}}}},"503":{"description":"ADMIN_PLACE_MAP_QUERY_TIMEOUT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapGroupPage"}}}},"401":{"description":"인증 필요","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"관리자 권한 필요","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"ADMIN_PLACE_MAP_CLUSTER_INVALID: 지도 재조회 필요","content":{"application/json":{"example":{"message":"지도 그룹이 만료되었거나 변경되었습니다. 지도를 다시 조회해주세요.","code":"ADMIN_PLACE_MAP_CLUSTER_INVALID"}}}},"200":{"description":"그룹 내부 장소 페이지","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlaceMapGroupPage"}}}}},"security":[{"bearerAuth":[]}]}}},"components":{"schemas":{"TravelPurposePreferenceUpdateRequest":{"required":["travelPurposes"],"type":"object","properties":{"travelPurposes":{"maxItems":9,"minItems":0,"uniqueItems":true,"type":"array","description":"선호 여행 목적 전체 목록. 빈 배열이면 모든 선호를 해제합니다.","example":["K_POP","FOOD"],"items":{"type":"string","description":"선호 여행 목적 전체 목록. 빈 배열이면 모든 선호를 해제합니다.","example":"[\"K_POP\",\"FOOD\"]","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}}},"description":"여행 목적 선호 전체 변경 요청"},"TravelPurposePreferenceResponse":{"type":"object","properties":{"travelPurposes":{"uniqueItems":true,"type":"array","description":"선호 여행 목적 목록","example":["K_POP","FOOD"],"items":{"type":"string","description":"선호 여행 목적 목록","example":"[\"K_POP\",\"FOOD\"]","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}}},"description":"여행 목적 선호 응답"},"ErrorResponse":{"required":["message"],"type":"object","properties":{"message":{"type":"string","description":"에러 메시지","example":"유효하지 않은 토큰입니다."},"code":{"type":"string","description":"도메인 에러 코드. 일부 공통 검증 오류에서는 제공되지 않을 수 있습니다.","nullable":true,"example":"INVALID_TOKEN"}},"description":"에러 응답"},"ScoutProfileRequest":{"required":["displayName"],"type":"object","properties":{"displayName":{"maxLength":100,"minLength":0,"type":"string"},"introduction":{"maxLength":1000,"minLength":0,"type":"string"}}},"ScoutProfileResponse":{"required":["activityEligibilityStatus","createdAt","displayName","eligibilityReviewedAt","eligibilityReviewedByAdminUserId","eligibilityStatusReason","eligibleFrom","eligibleUntil","introduction","profileReviewedAt","profileReviewedByAdminUserId","profileStatus","profileStatusReason","updatedAt","userId"],"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"displayName":{"type":"string"},"introduction":{"type":"string","nullable":true},"profileStatus":{"type":"string","enum":["PENDING","ACTIVE","SUSPENDED","REVOKED"]},"profileReviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"profileReviewedAt":{"type":"string","format":"date-time","nullable":true},"profileStatusReason":{"type":"string","nullable":true},"activityEligibilityStatus":{"type":"string","enum":["PENDING","ELIGIBLE","SUSPENDED","EXPIRED","REVOKED"]},"eligibleFrom":{"type":"string","format":"date-time","nullable":true},"eligibleUntil":{"type":"string","format":"date-time","nullable":true},"eligibilityReviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"eligibilityReviewedAt":{"type":"string","format":"date-time","nullable":true},"eligibilityStatusReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Scout 프로필 및 활동 자격 응답"},"BreakTime":{"required":["closesAt","opensAt"],"type":"object","properties":{"opensAt":{"$ref":"#/components/schemas/LocalTime"},"closesAt":{"$ref":"#/components/schemas/LocalTime"}}},"LocalTime":{"type":"object","properties":{"hour":{"type":"integer","format":"int32"},"minute":{"type":"integer","format":"int32"},"second":{"type":"integer","format":"int32"},"nano":{"type":"integer","format":"int32"}}},"MerchantPlaceApplicationRequest":{"required":["applicationType","businessName","businessRegistrationNumber","legalName","merchantContactEmail","merchantContactPhone","merchantDisplayName"],"type":"object","properties":{"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"legalName":{"maxLength":100,"minLength":0,"type":"string"},"businessName":{"maxLength":100,"minLength":0,"type":"string"},"businessRegistrationNumber":{"maxLength":30,"minLength":0,"type":"string"},"merchantDisplayName":{"maxLength":100,"minLength":0,"type":"string"},"merchantDescription":{"maxLength":1000,"minLength":0,"type":"string"},"merchantContactEmail":{"maxLength":255,"minLength":0,"type":"string"},"merchantContactPhone":{"maxLength":30,"minLength":0,"type":"string"},"newPlace":{"$ref":"#/components/schemas/PlaceRegistrationRequest"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"maxLength":500,"minLength":0,"type":"string"}}},"PlaceRegistrationOperatingDay":{"required":["dayOfWeek","status"],"type":"object","properties":{"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"status":{"type":"string","enum":["OPEN","CLOSED","OPEN_24_HOURS"]},"opensAt":{"$ref":"#/components/schemas/LocalTime"},"closesAt":{"$ref":"#/components/schemas/LocalTime"},"breakTimes":{"type":"array","items":{"$ref":"#/components/schemas/BreakTime"}}}},"PlaceRegistrationRequest":{"required":["applicantContactPhone","businessContactPhone","category","description","jibunAddress","latitude","longitude","placeName","postalCode","roadAddress"],"type":"object","properties":{"placeName":{"maxLength":100,"minLength":0,"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"latitude":{"maximum":90,"exclusiveMaximum":false,"minimum":-90,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180,"exclusiveMaximum":false,"minimum":-180,"exclusiveMinimum":false,"type":"number","format":"double"},"roadAddress":{"maxLength":255,"minLength":0,"type":"string"},"jibunAddress":{"maxLength":255,"minLength":0,"type":"string"},"postalCode":{"maxLength":20,"minLength":0,"type":"string"},"description":{"maxLength":1000,"minLength":0,"type":"string"},"businessContactPhone":{"maxLength":20,"minLength":0,"type":"string"},"applicantContactPhone":{"maxLength":20,"minLength":0,"type":"string"},"tags":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["ENGLISH_SERVICE_AVAILABLE","ENGLISH_MENU_AVAILABLE","RESERVATION_AVAILABLE","RESERVATION_COUPON_AVAILABLE","GENERAL_COUPON_AVAILABLE","GOOD_AMBIENCE"]}},"timezone":{"maxLength":64,"minLength":0,"type":"string"},"operatingDays":{"maxItems":7,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/PlaceRegistrationOperatingDay"}}}},"MerchantPlaceApplicationAttachmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"fileId":{"type":"string"},"documentType":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"uploadedAt":{"type":"string","format":"date-time"},"retentionExpiresAt":{"type":"string","format":"date-time"},"displayOrder":{"type":"integer","format":"int32"}}},"MerchantPlaceApplicationNewPlaceResponse":{"type":"object","properties":{"placeName":{"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"description":{"type":"string"},"businessContactPhone":{"type":"string"},"applicantContactPhone":{"type":"string"},"tags":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["ENGLISH_SERVICE_AVAILABLE","ENGLISH_MENU_AVAILABLE","RESERVATION_AVAILABLE","RESERVATION_COUPON_AVAILABLE","GENERAL_COUPON_AVAILABLE","GOOD_AMBIENCE"]}},"timezone":{"type":"string"},"operatingDays":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegistrationOperatingDay"}}}},"MerchantPlaceApplicationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"merchantDisplayName":{"type":"string"},"merchantContactEmail":{"type":"string"},"merchantDescription":{"type":"string"},"merchantContactPhone":{"type":"string"},"newPlace":{"$ref":"#/components/schemas/MerchantPlaceApplicationNewPlaceResponse"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"type":"string"},"reviewReason":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"version":{"type":"integer","format":"int64"},"submissionVersion":{"type":"integer","format":"int64"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceApplicationAttachmentResponse"}}}},"MerchantOwnerProfileRequest":{"required":["businessName","contactEmail","contactPhone","displayName"],"type":"object","properties":{"businessName":{"maxLength":100,"minLength":0,"type":"string"},"displayName":{"maxLength":100,"minLength":0,"type":"string"},"description":{"maxLength":1000,"minLength":0,"type":"string"},"contactEmail":{"maxLength":255,"minLength":0,"type":"string"},"contactPhone":{"maxLength":30,"minLength":0,"type":"string"}}},"MerchantOwnerProfileResponse":{"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"businessName":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string","nullable":true},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]},"onboardingStatus":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"]},"onboardingCompletionRate":{"type":"integer","format":"int32"},"onboardingCompletedAt":{"type":"string","format":"date-time","nullable":true},"reviewedBy":{"type":"integer","format":"int64","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"reviewReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"placeIds":{"type":"array","items":{"type":"integer","format":"int64"}}},"description":"Merchant Owner 프로필 응답"},"CurrentActivityIntentUpdateRequest":{"required":["intent"],"type":"object","properties":{"intent":{"type":"string","description":"현재 탐색하려는 행동","example":"CAFE","enum":["EXPLORE","EAT","CAFE","SHOP","ATTEND_EVENT","NIGHTLIFE"]}},"description":"현재 행동 의도 변경 요청"},"CurrentActivityIntentResponse":{"type":"object","properties":{"intent":{"type":"string","description":"현재 행동 의도. 설정되지 않았거나 만료됐으면 null","nullable":true,"example":"CAFE","enum":["EXPLORE","EAT","CAFE","SHOP","ATTEND_EVENT","NIGHTLIFE"]},"expiresAt":{"type":"string","description":"행동 의도 만료 시각. 의도가 없으면 null","format":"date-time","nullable":true}},"description":"현재 행동 의도 응답"},"AdminMapPlaceOperatingExceptionRequest":{"required":["date"],"type":"object","properties":{"date":{"type":"string","format":"date","example":"2026-08-15"},"closed":{"type":"boolean","description":"true이면 종일 휴무이며 hours는 비워야 합니다.","example":true},"hours":{"uniqueItems":true,"type":"array","description":"대체 영업 시간대. closed가 false이면 하나 이상 필요합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingTimeRangeRequest"}}},"description":"관리자 특정 날짜 영업 예외"},"AdminMapPlaceOperatingTimeRangeRequest":{"required":["closesAt","opensAt"],"type":"object","properties":{"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"관리자 장소 운영 시간대"},"AdminMapPlaceRegularOperatingHourRequest":{"required":["closesAt","dayOfWeek","opensAt"],"type":"object","properties":{"dayOfWeek":{"type":"string","example":"MONDAY","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"opensAt":{"type":"string","format":"time","example":"09:00:00"},"closesAt":{"type":"string","format":"time","example":"18:00:00"}},"description":"관리자 요일별 정규 영업 시간대"},"MerchantOwnerOperatingScheduleUpdateRequest":{"type":"object","properties":{"regularHours":{"uniqueItems":true,"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceRegularOperatingHourRequest"}},"exceptions":{"uniqueItems":true,"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingExceptionRequest"}}},"description":"Merchant Owner 장소 영업시간 변경 요청"},"MerchantOwnerOperatingScheduleResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"message":{"type":"string"}},"description":"Merchant Owner 장소 영업시간 변경 응답"},"PlaceOperatingExceptionResponse":{"type":"object","properties":{"date":{"type":"string","description":"Asia/Seoul 기준 예외 날짜","format":"date","example":"2026-08-15"},"closed":{"type":"boolean","description":"true이면 종일 휴무이며 hours는 비어 있습니다."},"hours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingTimeRangeResponse"}}},"description":"Asia/Seoul 기준 특정 날짜의 휴무 또는 대체 영업 시간"},"PlaceOperatingTimeRangeResponse":{"type":"object","properties":{"opensAt":{"type":"string","description":"Asia/Seoul 기준 시작 시각(포함)","format":"time","example":"09:00:00"},"closesAt":{"type":"string","description":"Asia/Seoul 기준 종료 시각(제외)","format":"time","example":"18:00:00"}},"description":"Asia/Seoul 기준 하루 중 장소 운영 시간대"},"PlaceRegularOperatingHourResponse":{"type":"object","properties":{"dayOfWeek":{"type":"string","description":"Asia/Seoul 기준 요일","example":"MONDAY","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"opensAt":{"type":"string","description":"Asia/Seoul 기준 시작 시각(포함)","format":"time","example":"09:00:00"},"closesAt":{"type":"string","description":"Asia/Seoul 기준 종료 시각(제외)","format":"time","example":"18:00:00"}},"description":"Asia/Seoul 기준 요일별 정규 영업 시간대"},"MerchantOwnerRepresentativeMediaUpdateRequest":{"required":["mediaId"],"type":"object","properties":{"mediaId":{"type":"integer","format":"int64"}},"description":"Merchant Owner 대표 미디어 지정 요청"},"MerchantOwnerMediaResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"representativeMediaId":{"type":"integer","format":"int64"},"media":{"type":"array","items":{"$ref":"#/components/schemas/PlaceMediaItem"}}},"description":"Merchant Owner 탐색 미디어 목록 응답"},"PlaceMediaItem":{"required":["createdAt","displayOrder","id","imageUrl","placeId","purpose","s3Key","sourceMapImageId","thumbnailS3Key","thumbnailUrl","updatedAt"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"purpose":{"type":"string","enum":["VERIFICATION","EXPLORATION"]},"imageUrl":{"type":"string"},"s3Key":{"type":"string","nullable":true},"thumbnailUrl":{"type":"string","nullable":true},"thumbnailS3Key":{"type":"string","nullable":true},"sourceMapImageId":{"type":"integer","format":"int64","nullable":true},"displayOrder":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"장소 미디어 항목"},"MerchantPlaceInformationUpdateRequest":{"type":"object","properties":{"description":{"maxLength":1000,"minLength":0,"type":"string","description":"관광객에게 노출할 장소 소개","nullable":true,"example":"K-컬처 굿즈와 체험을 함께 즐길 수 있는 공간입니다."},"contactPhone":{"maxLength":30,"minLength":0,"type":"string","description":"장소 문의 전화번호","nullable":true,"example":"02-1234-5678"},"websiteUrl":{"maxLength":500,"minLength":0,"pattern":"^https?://\\S+$","type":"string","description":"장소 웹사이트 URL","nullable":true,"example":"https://example.com/place"},"reservationUrl":{"maxLength":500,"minLength":0,"pattern":"^https?://\\S+$","type":"string","description":"예약 페이지 URL","nullable":true,"example":"https://example.com/reservations"}},"description":"Merchant 장소 정보 수정 요청"},"MerchantPlaceInformationResponse":{"required":["contactPhone","createdAt","description","placeId","reservationUrl","updatedAt","updatedByUserId","websiteUrl"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"description":{"type":"string","nullable":true},"contactPhone":{"type":"string","nullable":true},"websiteUrl":{"type":"string","nullable":true},"reservationUrl":{"type":"string","nullable":true},"updatedByUserId":{"type":"integer","format":"int64","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Merchant 장소 정보 응답"},"ValidationErrorResponse":{"required":["code","errors","message"],"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string","example":"VALIDATION_FAILED"},"errors":{"type":"object","additionalProperties":{"type":"string"}}},"description":"필드 검증 오류 응답"},"AvailabilityUpsertRequest":{"required":["endsAt","placeId","startsAt"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalCapacity":{"minimum":1,"type":"integer","format":"int32"}}},"AvailabilityResponse":{"required":["conditionsVersion","endsAt","id","placeId","remainingCapacity","reservationTerms","startsAt","status","totalCapacity"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":77},"placeId":{"type":"integer","format":"int64","example":70069},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalCapacity":{"type":"integer","format":"int32","example":100},"remainingCapacity":{"type":"integer","format":"int32","example":42},"status":{"type":"string","example":"ACTIVE","enum":["ACTIVE","INACTIVE"]},"conditionsVersion":{"minimum":0,"type":"integer","description":"시간대·취소 조건 변경 버전. 조건이 미설정이어도 반환합니다.","format":"int64","example":1},"reservationTerms":{"$ref":"#/components/schemas/ReservationTermsResponse"}},"description":"예약 가능 시간 응답"},"ReservationTermsResponse":{"required":["cancellable","cancellationCutoffMinutes","timezone"],"type":"object","properties":{"timezone":{"type":"string","description":"IANA 시간대","example":"Asia/Seoul"},"cancellable":{"type":"boolean","example":true},"cancellationCutoffMinutes":{"type":"integer","description":"취소 가능할 때만 제공하는 시작 전 취소 기한(분)","format":"int32","nullable":true,"example":60}},"description":"저장된 예약 시간대·취소 조건","nullable":true},"ReservationTermsRequest":{"required":["cancellable","timezone"],"type":"object","properties":{"timezone":{"maxLength":64,"minLength":0,"type":"string"},"cancellable":{"type":"boolean"},"cancellationCutoffMinutes":{"minimum":0,"type":"integer","format":"int32"}}},"AdminTrustScoreInterventionRuleRequest":{"required":["actionType","reason","ruleName","triggerType"],"type":"object","properties":{"ruleName":{"maxLength":100,"minLength":0,"type":"string","description":"규칙 이름","example":"low trust temporary restriction"},"triggerType":{"type":"string","description":"트리거 유형","example":"FALSE_REPORT_COUNT","enum":["TRUST_SCORE_RANGE","FALSE_REPORT_COUNT","ACCEPTANCE_RATE","ANOMALY_DETECTED"]},"actionType":{"type":"string","description":"액션 유형","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"minTrustScore":{"maximum":100,"minimum":0,"type":"integer","description":"최소 Trust Score","format":"int32","example":0},"maxTrustScore":{"maximum":100,"minimum":0,"type":"integer","description":"최대 Trust Score","format":"int32","example":60},"minSubmittedCount":{"minimum":0,"type":"integer","description":"최소 신고 수","format":"int64","example":3},"minFalseReportCount":{"minimum":0,"type":"integer","description":"최소 허위 신고 수","format":"int64","example":3},"durationDays":{"type":"integer","description":"임시 제한 기간 일수. TEMPORARY_RESTRICT일 때만 입력합니다.","format":"int32","example":7},"priority":{"minimum":0,"type":"integer","description":"우선순위. 낮을수록 먼저 적용됩니다.","format":"int32","example":10},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"개입 규칙 적용 사유","example":"허위 신고 누적 사용자 제한"}}},"AdminTrustScoreInterventionRuleItem":{"type":"object","properties":{"id":{"type":"integer","description":"개입 규칙 ID","format":"int64","example":1},"ruleName":{"type":"string","description":"규칙 이름","example":"low trust review"},"triggerType":{"type":"string","description":"트리거 유형","example":"FALSE_REPORT_COUNT","enum":["TRUST_SCORE_RANGE","FALSE_REPORT_COUNT","ACCEPTANCE_RATE","ANOMALY_DETECTED"]},"actionType":{"type":"string","description":"액션 유형","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"minTrustScore":{"type":"integer","description":"최소 Trust Score","format":"int32","example":0},"maxTrustScore":{"type":"integer","description":"최대 Trust Score","format":"int32","example":60},"minSubmittedCount":{"type":"integer","description":"최소 신고 수","format":"int64","example":3},"minFalseReportCount":{"type":"integer","description":"최소 허위 신고 수","format":"int64","example":3},"durationDays":{"type":"integer","description":"제한 기간 일수","format":"int32","example":7},"priority":{"type":"integer","description":"우선순위","format":"int32","example":10},"reason":{"type":"string","description":"적용 사유","example":"허위 신고 누적"},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}}},"MerchantOwnerPlaceUpdateRequest":{"type":"object","properties":{"placeIds":{"maxItems":100,"minItems":0,"uniqueItems":true,"type":"array","items":{"type":"integer","format":"int64"}},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerPlaceQualityUpdateRequest":{"required":["noShowRate","reservationCancellationRate","reservationResponseRate","status"],"type":"object","properties":{"status":{"type":"string","enum":["UNMEASURED","HEALTHY","NEEDS_ATTENTION","AT_RISK"]},"reservationResponseRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"reservationCancellationRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"noShowRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"evaluatedAt":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerPlaceResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"operationalQualityStatus":{"type":"string","enum":["UNMEASURED","HEALTHY","NEEDS_ATTENTION","AT_RISK"]},"reservationResponseRate":{"type":"integer","format":"int32"},"reservationCancellationRate":{"type":"integer","format":"int32"},"noShowRate":{"type":"integer","format":"int32"},"qualityEvaluatedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"MerchantOnboardingUpdateRequest":{"required":["completionRate","status"],"type":"object","properties":{"status":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"]},"completionRate":{"maximum":100,"minimum":0,"type":"integer","format":"int32"},"completedAt":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"VoiceAiSessionResponse":{"required":["expiresAt","sessionId"],"type":"object","properties":{"sessionId":{"type":"string"},"expiresAt":{"type":"string","description":"만료 시각. ISO-8601 offset 포함. 현재 시각이 이 값 이상이면 만료됩니다.","format":"date-time","example":"2026-09-17T12:05:00+09:00"}}},"VoiceAiMessageRequest":{"required":["requestId","text"],"type":"object","properties":{"text":{"maxLength":2000,"minLength":0,"type":"string"},"requestId":{"maxLength":128,"minLength":0,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string","description":"최종 envelope.id와 동일한 요청 ID. 재시도 시 동일 text와 함께 유지합니다."}}},"JsonNode":{"type":"object"},"VisitorVerificationReportCreateRequest":{"required":["description","placeId","reportType"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"maxLength":1000,"minLength":0,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"pattern":"^https://[^\\s]+$","type":"string"},"waitTimeMinutes":{"maximum":1440,"minimum":0,"type":"integer","format":"int32"},"languageCode":{"maxLength":10,"minLength":0,"pattern":"^[a-z]{2,3}(-[A-Z]{2})?$","type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]}}},"MyVisitorVerificationReportResponse":{"required":["couponUsageStatus","createdAt","crowdLevel","description","evidenceUrl","id","languageCode","placeId","rejectionReason","reportType","reviewedAt","status","updatedAt","waitTimeMinutes"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"waitTimeMinutes":{"type":"integer","format":"int32","nullable":true},"languageCode":{"type":"string","nullable":true},"couponUsageStatus":{"type":"string","nullable":true,"enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","nullable":true,"enum":["LOW","MODERATE","HIGH","FULL"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"rejectionReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time"}},"description":"내 방문자 검증 제보 응답"},"VisitorVerificationReportCorrectionRequest":{"required":["description"],"type":"object","properties":{"description":{"maxLength":1000,"minLength":0,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"pattern":"^https://[^\\s]+$","type":"string"},"waitTimeMinutes":{"maximum":1440,"minimum":0,"type":"integer","format":"int32"},"languageCode":{"maxLength":10,"minLength":0,"pattern":"^[a-z]{2,3}(-[A-Z]{2})?$","type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]}}},"MyVisitorVerificationReportCorrectionResponse":{"required":["couponUsageStatus","createdAt","crowdLevel","description","evidenceUrl","id","languageCode","placeId","rejectionReason","reportId","reportStatus","reportType","reviewedAt","status","updatedAt","waitTimeMinutes"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"waitTimeMinutes":{"type":"integer","format":"int32","nullable":true},"languageCode":{"type":"string","nullable":true},"couponUsageStatus":{"type":"string","nullable":true,"enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","nullable":true,"enum":["LOW","MODERATE","HIGH","FULL"]},"reportStatus":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"rejectionReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time"}},"description":"내 방문자 검증 제보 정정 응답"},"VisitVerificationStartRequest":{"required":["accuracyMeters","latitude","longitude","observedAt","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"accuracyMeters":{"minimum":0.0,"exclusiveMinimum":false,"type":"number","format":"double"},"observedAt":{"type":"string","format":"date-time"}}},"VisitVerificationSessionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"touristUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["STARTED","IN_PROGRESS","PROXIMITY_LOST","COMPLETED","EXPIRED","REJECTED"]},"startedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time","nullable":true},"requiredRadiusMeters":{"type":"number","description":"세션 생성 시 확정된 장소 반경 기준(미터)","format":"double","example":500},"requiredDwellSeconds":{"type":"integer","description":"세션 생성 시 확정된 연속 체류 기준(초)","format":"int64","example":30},"latestDistanceMeters":{"type":"number","format":"double"},"verifiedDwellSeconds":{"type":"integer","format":"int64"},"nextObservationRecommendedAt":{"type":"string","format":"date-time","nullable":true},"remainingSeconds":{"type":"integer","format":"int64"},"completedCheckInId":{"type":"integer","format":"int64","nullable":true},"reviewEligible":{"type":"boolean"}}},"VisitVerificationObservationRequest":{"required":["accuracyMeters","latitude","longitude","observedAt"],"type":"object","properties":{"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"accuracyMeters":{"minimum":0.0,"exclusiveMinimum":false,"type":"number","format":"double"},"observedAt":{"type":"string","format":"date-time"}}},"ForegroundVisitVerificationStartRequest":{"required":["accuracyMeters","latitude","longitude","observedAt"],"type":"object","properties":{"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"accuracyMeters":{"minimum":0.0,"exclusiveMinimum":false,"type":"number","format":"double"},"observedAt":{"type":"string","format":"date-time"}}},"TravelScheduleCreateRequest":{"required":["endDate","startDate"],"type":"object","properties":{"startDate":{"type":"string","description":"여행 시작일","format":"date","example":"2026-08-01"},"endDate":{"type":"string","description":"여행 종료일","format":"date","example":"2026-08-04"}},"description":"여행 일정 생성 요청"},"TravelScheduleResponse":{"type":"object","properties":{"id":{"type":"integer","description":"여행 일정 ID","format":"int64","example":1},"startDate":{"type":"string","description":"여행 시작일","format":"date","example":"2026-08-01"},"endDate":{"type":"string","description":"여행 종료일","format":"date","example":"2026-08-04"},"status":{"type":"string","description":"기준일에 계산한 일정 상태","example":"UPCOMING","enum":["UPCOMING","ONGOING","ENDED","CANCELLED"]}},"description":"여행 일정 응답"},"ProfileImageUploadResponse":{"type":"object","properties":{"profileImageUrl":{"type":"string","description":"변경된 프로필 이미지 URL","example":"https://cdn.pingdom.com/users/profile-images/1/profile.jpg"}},"description":"프로필 이미지 변경 응답"},"OAuthAccountLinkStartResponse":{"type":"object","properties":{"provider":{"type":"string","description":"OAuth Provider","example":"GOOGLE"},"authorizationUrl":{"type":"string","description":"브라우저가 이동할 OAuth 인증 시작 URL","example":"/oauth2/authorization/google"},"message":{"type":"string","description":"처리 결과 메시지","example":"Google 계정 연결을 시작합니다."}},"description":"OAuth 계정 연결 시작 응답"},"BookmarkCreateRequest":{"required":["placeId"],"type":"object","properties":{"placeId":{"type":"integer","description":"북마크에 추가할 장소 ID","format":"int64","example":17}},"description":"장소 북마크 생성 요청"},"ChangePasswordRequest":{"required":["confirmPassword","currentPassword","newPassword"],"type":"object","properties":{"currentPassword":{"type":"string","description":"현재 비밀번호","example":"currentPass123!"},"newPassword":{"maxLength":2147483647,"minLength":8,"type":"string","description":"변경할 새 비밀번호","example":"newSecurePass123!"},"confirmPassword":{"maxLength":2147483647,"minLength":8,"type":"string","description":"새 비밀번호 확인 입력","example":"newSecurePass123!"}},"description":"비밀번호 변경 요청 정보"},"ChangeUsernameRequest":{"required":["newUsername"],"type":"object","properties":{"newUsername":{"maxLength":50,"minLength":4,"type":"string","description":"변경할 새 아이디","example":"new_pingdom_user"}},"description":"아이디 변경 요청 정보"},"ScoutFieldReportCreateRequest":{"required":["description","placeId","reportType"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","CROWD_LEVEL","SAFETY","OTHER"]},"description":{"maxLength":1000,"minLength":0,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"pattern":"^https://[^\\s]+$","type":"string"}}},"MyScoutFieldReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","CROWD_LEVEL","SAFETY","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"rejectionReason":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RouteCoordinate":{"required":["latitude","longitude"],"type":"object","properties":{"latitude":{"maximum":90,"minimum":-90,"type":"number","description":"WGS84 위도, JSON 숫자","format":"double","example":37.5665},"longitude":{"maximum":180,"minimum":-180,"type":"number","description":"WGS84 경도, JSON 숫자","format":"double","example":126.978}}},"RouteRequest":{"required":["destination","mode","origin"],"type":"object","properties":{"origin":{"$ref":"#/components/schemas/RouteCoordinate"},"destination":{"$ref":"#/components/schemas/RouteCoordinate"},"mode":{"type":"string","description":"car, transit 또는 walk 지원. bike는 422, 그 밖의 값은 400","example":"walk","enum":["car","transit","walk"]}},"description":"현재 조회 시점의 자동차·대중교통·보행자 추천 경로 요청. 동일 출발·도착 좌표는 허용하지 않습니다."},"RouteResponse":{"required":["distanceMeters","durationSeconds","mode","provider"],"type":"object","properties":{"mode":{"type":"string","example":"car","enum":["car"]},"provider":{"type":"string","example":"naver","enum":["naver"]},"distanceMeters":{"minimum":0,"type":"integer","description":"공급자가 계산한 총거리(m)","format":"int64","example":12500},"durationSeconds":{"minimum":0,"type":"integer","description":"예상 소요시간(초), 공급자 밀리초를 올림하여 변환","format":"int64","example":1800},"path":{"minItems":2,"type":"array","description":"출발→도착 순서의 도로 형상 전체. 직선 대체·끝점 덮어쓰기를 하지 않습니다.","items":{"$ref":"#/components/schemas/RouteCoordinate"}}},"description":"NAVER traoptimal 첫 번째 실제 자동차 경로. 입력 좌표와 도로 위 시작·끝 좌표는 다를 수 있습니다."},"Itinerary":{"type":"object","properties":{"totalTimeSeconds":{"type":"integer","format":"int64"},"totalDistanceMeters":{"type":"integer","format":"int64"},"transferCount":{"type":"integer","format":"int32"},"totalWalkDistanceMeters":{"type":"integer","format":"int64"},"totalWalkTimeSeconds":{"type":"integer","format":"int64"},"totalFare":{"type":"integer","format":"int64"},"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}}}},"Leg":{"type":"object","properties":{"mode":{"type":"string"},"distanceMeters":{"type":"integer","format":"int64"},"durationSeconds":{"type":"integer","format":"int64"},"routeName":{"type":"string"},"routeId":{"type":"string"},"routeColor":{"type":"string"},"routeType":{"type":"integer","format":"int32"},"start":{"$ref":"#/components/schemas/Stop"},"end":{"$ref":"#/components/schemas/Stop"},"path":{"type":"array","items":{"$ref":"#/components/schemas/RouteCoordinate"}},"stations":{"type":"array","items":{"$ref":"#/components/schemas/Stop"}}}},"Stop":{"type":"object","properties":{"name":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"stationId":{"type":"string"}}},"TransitRouteResponse":{"type":"object","properties":{"mode":{"type":"string","example":"transit"},"provider":{"type":"string","example":"tmap"},"itineraries":{"type":"array","items":{"$ref":"#/components/schemas/Itinerary"}}},"description":"TMAP 대중교통 추천 경로 목록"},"Step":{"type":"object","properties":{"instruction":{"type":"string","description":"보행 안내 문구"},"distanceMeters":{"minimum":0,"type":"integer","description":"구간 거리(m)","format":"int64"},"durationSeconds":{"minimum":0,"type":"integer","description":"구간 예상 소요시간(초)","format":"int64"},"path":{"type":"array","items":{"$ref":"#/components/schemas/RouteCoordinate"}}},"description":"공급자가 제공한 순서의 보행 구간 안내"},"WalkingRouteResponse":{"required":["distanceMeters","durationSeconds","mode","provider"],"type":"object","properties":{"mode":{"type":"string","example":"walk","enum":["walk"]},"provider":{"type":"string","example":"tmap","enum":["tmap"]},"distanceMeters":{"minimum":0,"type":"integer","description":"공급자가 계산한 총거리(m)","format":"int64"},"durationSeconds":{"minimum":0,"type":"integer","description":"예상 소요시간(초)","format":"int64"},"path":{"minItems":2,"type":"array","description":"출발→도착 순서의 전체 보행 경로","items":{"$ref":"#/components/schemas/RouteCoordinate"}},"steps":{"type":"array","description":"공급자가 제공한 순서의 보행 구간 안내","items":{"$ref":"#/components/schemas/Step"}}},"description":"TMAP 보행자 추천 경로"},"ReservationCreateRequest":{"required":["availabilityId","bookerName","bookerPhone","idempotencyKey"],"type":"object","properties":{"availabilityId":{"type":"integer","format":"int64"},"idempotencyKey":{"maxLength":100,"minLength":0,"type":"string"},"quantity":{"minimum":1,"type":"integer","format":"int32"},"bookerName":{"maxLength":100,"minLength":0,"type":"string"},"bookerPhone":{"maxLength":30,"minLength":0,"pattern":"^[0-9+()\\- ]+$","type":"string"},"requestNote":{"maxLength":500,"minLength":0,"type":"string"},"confirmationToken":{"maxLength":36,"minLength":36,"type":"string","description":"최신 견적의 확인 토큰. 생략하면 기존 터치 예약 계약이며 확인 조건 보장은 적용되지 않음","nullable":true}}},"ReservationConfirmation":{"required":["availabilityId","cancellable","cancellationDeadline","conditionsVersion","endsAt","expiresAt","placeId","placeName","quantity","startsAt","timezone"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"availabilityId":{"type":"integer","format":"int64"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"quantity":{"type":"integer","format":"int32"},"timezone":{"type":"string"},"cancellable":{"type":"boolean"},"cancellationDeadline":{"type":"string","format":"date-time","nullable":true},"conditionsVersion":{"type":"integer","format":"int64"},"expiresAt":{"type":"string","format":"date-time"}},"description":"사용자가 확인할 예약 대상·시간·인원·취소 조건","nullable":true},"ReservationResponse":{"required":["availabilityId","bookerName","bookerPhone","canceledAt","confirmation","confirmedAt","createdAt","id","quantity","requestNote","reservationEndsAt","reservationStartsAt","status","touristUserId","updatedAt"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"touristUserId":{"type":"integer","format":"int64"},"availabilityId":{"type":"integer","format":"int64"},"quantity":{"type":"integer","format":"int32"},"reservationStartsAt":{"type":"string","format":"date-time","nullable":true},"reservationEndsAt":{"type":"string","format":"date-time","nullable":true},"bookerName":{"type":"string","nullable":true},"bookerPhone":{"type":"string","nullable":true},"requestNote":{"type":"string","nullable":true},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"createdAt":{"type":"string","format":"date-time"},"confirmedAt":{"type":"string","description":"예약이 CONFIRMED 상태가 되기 전에는 null입니다.","format":"date-time","nullable":true},"reviewedBy":{"type":"integer","format":"int64"},"reviewedAt":{"type":"string","format":"date-time"},"reviewReason":{"type":"string"},"rejectedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","description":"예약이 CANCELED 상태가 되기 전에는 null입니다.","format":"date-time","nullable":true},"canceledBy":{"type":"integer","format":"int64"},"updatedAt":{"type":"string","format":"date-time"},"confirmation":{"description":"실제 수락한 확인 조건. 구버전 예약이면 null","nullable":true,"allOf":[{"$ref":"#/components/schemas/ReservationConfirmation"}]}},"description":"관광객 예약 응답"},"PlaceReviewCreateRequest":{"required":["content"],"type":"object","properties":{"recommendReason":{"maxLength":100,"minLength":0,"type":"string","description":"기존 단일 추천 이유. recommendReasons가 없을 때만 사용할 수 있습니다.","deprecated":true},"recommendReasons":{"maxItems":5,"minItems":1,"type":"array","description":"추천 이유 코드. 1~5개를 입력하며 저장·응답 순서가 유지됩니다.","items":{"type":"string","description":"추천 이유 코드. 1~5개를 입력하며 저장·응답 순서가 유지됩니다.","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"maxLength":2000,"minLength":0,"type":"string"},"reviewMediaIds":{"maxItems":3,"minItems":0,"type":"array","description":"리뷰 사진 업로드 API가 반환한 ID. 최대 3개이며 입력 순서가 사진 표시 순서입니다.","items":{"type":"integer","description":"리뷰 사진 업로드 API가 반환한 ID. 최대 3개이며 입력 순서가 사진 표시 순서입니다.","format":"int64"}},"imageUrls":{"maxItems":3,"minItems":0,"type":"array","description":"임의 URL 입력은 지원하지 않습니다. 빈 배열만 허용하며 reviewMediaIds를 사용해야 합니다.","deprecated":true,"items":{"type":"string","description":"임의 URL 입력은 지원하지 않습니다. 빈 배열만 허용하며 reviewMediaIds를 사용해야 합니다.","deprecated":true}}},"description":"장소 리뷰 작성 요청. recommendReasons와 reviewMediaIds가 새 표준 계약입니다."},"PlaceReviewMediaResponse":{"type":"object","properties":{"reviewMediaId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"contentType":{"type":"string"}},"description":"리뷰에 연결된 검증 완료 사진"},"PlaceReviewResponse":{"type":"object","properties":{"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"userId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"createdAt":{"type":"string","format":"date-time"}}},"PlaceReviewMediaUploadResponse":{"type":"object","properties":{"reviewMediaId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"expiresAt":{"type":"string","description":"리뷰 연결 전까지 유효한 시각","format":"date-time"}},"description":"리뷰 작성 전 임시 저장된 사진 업로드 결과"},"MapLinkConversionRequest":{"required":["linkType","provider","requestId"],"type":"object","properties":{"linkType":{"type":"string","description":"지도 링크 전환 유형","enum":["DIRECTIONS","EXTERNAL_MAP"]},"provider":{"maxLength":30,"minLength":0,"type":"string","description":"지도 제공자 (예: NAVER)","example":"NAVER"},"requestId":{"maxLength":128,"minLength":0,"type":"string","description":"같은 사용자·장소·전환 유형의 재시도에서 재사용하는 멱등성 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}}},"PlaceInformationReportCreateRequest":{"required":["reasonType","targetType"],"type":"object","properties":{"evidenceId":{"type":"integer","description":"신고 대상 증빙 ID","format":"int64","nullable":true},"targetType":{"type":"string","enum":["NAME","ADDRESS","GEOLOCATION","OPERATING_STATUS","TOURIST_INFORMATION","SOURCE_EVIDENCE","MEDIA","OTHER"]},"reasonType":{"type":"string","enum":["INCORRECT","OUTDATED","MISSING","MISLEADING","DUPLICATE","CLOSED_OR_MOVED","SPAM_OR_ABUSE","OTHER"]},"description":{"maxLength":1000,"minLength":1,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"type":"string","nullable":true}},"description":"장소 정보 신고 생성 요청"},"PlaceInformationDisputeResponse":{"type":"object","properties":{"disputeId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"disputedByUserId":{"type":"integer","format":"int64"},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"장소 정보 반박 응답"},"PlaceInformationReportResponse":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"evidenceId":{"type":"integer","format":"int64","nullable":true},"reporterUserId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["NAME","ADDRESS","GEOLOCATION","OPERATING_STATUS","TOURIST_INFORMATION","SOURCE_EVIDENCE","MEDIA","OTHER"]},"reasonType":{"type":"string","enum":["INCORRECT","OUTDATED","MISSING","MISLEADING","DUPLICATE","CLOSED_OR_MOVED","SPAM_OR_ABUSE","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string","nullable":true},"status":{"type":"string","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"resolvedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"disputes":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationDisputeResponse"}}},"description":"장소 정보 신고 응답"},"PlaceMediaCreateRequest":{"required":["s3Key"],"type":"object","properties":{"imageUrl":{"maxLength":500,"minLength":0,"type":"string","description":"호환성을 위해 수신하지만 서버는 검증된 s3Key로 URL을 생성합니다.","nullable":true},"s3Key":{"maxLength":500,"minLength":0,"type":"string"},"thumbnailUrl":{"maxLength":500,"minLength":0,"type":"string","nullable":true},"thumbnailS3Key":{"maxLength":500,"minLength":0,"type":"string","nullable":true},"displayOrder":{"type":"integer","format":"int32","nullable":true}},"description":"장소 탐색용 미디어 생성 요청"},"PlaceRecommendationClickRequest":{"required":["placeId","recommendationVersion","requestId"],"type":"object","properties":{"placeId":{"type":"integer","description":"클릭한 추천 장소 ID","format":"int64","example":17},"recommendationVersion":{"type":"string","description":"클릭한 추천 응답의 버전","example":"place-rec-v1"},"requestId":{"type":"string","description":"추천 응답 requestId","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"}},"description":"추천 장소 클릭 기록 요청"},"PlaceRecommendationClickResponse":{"type":"object","properties":{"placeId":{"type":"integer","description":"클릭 기록이 저장된 장소 ID","format":"int64","example":17},"message":{"type":"string","description":"처리 결과 메시지","example":"추천 장소 클릭을 기록했습니다."}},"description":"추천 장소 클릭 기록 응답"},"PlaceInformationDisputeCreateRequest":{"type":"object","properties":{"description":{"maxLength":1000,"minLength":1,"type":"string"},"evidenceUrl":{"maxLength":500,"minLength":0,"type":"string","nullable":true}},"description":"장소 정보 신고 반박 생성 요청"},"CouponResponse":{"required":["benefitDescription","code","expiresAt","id","issuedAt","offerId","offerTitle","placeId","placeName","redeemedAt","status"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"offerId":{"type":"integer","format":"int64","example":1},"offerTitle":{"type":"string","nullable":true,"example":"관광객 웰컴 음료"},"benefitDescription":{"type":"string","nullable":true,"example":"음료 1잔 무료"},"placeId":{"type":"integer","format":"int64","nullable":true,"example":1},"placeName":{"type":"string","nullable":true,"example":"핑덤 카페"},"code":{"type":"string","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},"status":{"type":"string","enum":["ISSUED","REDEEMED","EXPIRED"]},"issuedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"redeemedAt":{"type":"string","format":"date-time","nullable":true}}},"VerifiedBoostSelectionCreateRequest":{"required":["idempotencyKey","placeId","productId"],"type":"object","properties":{"productId":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":10},"idempotencyKey":{"maxLength":64,"minLength":0,"type":"string","example":"boost-select-20260726-001"}}},"VerifiedBoostSelectionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"productId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"selectedAt":{"type":"string","format":"date-time"}}},"VerifiedBoostExecutionStartRequest":{"required":["selectionId"],"type":"object","properties":{"selectionId":{"type":"integer","format":"int64","example":1}}},"VerifiedBoostExecutionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"selectionId":{"type":"integer","format":"int64"},"productId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["ACTIVE","STOPPED","EXPIRED"]},"startedAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"stoppedAt":{"type":"string","format":"date-time"}}},"PlaceReviewDeletionRequestCreateRequest":{"required":["requestReason"],"type":"object","properties":{"requestReason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantPlaceReviewDeletionRequestResponse":{"type":"object","properties":{"deletionRequestId":{"type":"integer","format":"int64"},"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reviewVisibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"requestedAt":{"type":"string","format":"date-time"}}},"PlaceOperatingNoticeCreateRequest":{"required":["expiresAt","message","noticeType","severity","startsAt"],"type":"object","properties":{"noticeType":{"type":"string","enum":["TEMPORARY_CLOSURE","HOURS_CHANGE","CROWDING","REOPENING","GENERAL"]},"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"message":{"maxLength":500,"minLength":0,"type":"string"},"startsAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}},"description":"상점 운영 상태 공지 생성 요청"},"PlaceOperatingNoticeResponse":{"required":["cancelReason","canceledAt","createdAt","expiredAt","expiresAt","id","message","noticeType","placeId","severity","startsAt","status","updatedAt","visibleNow"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"noticeType":{"type":"string","enum":["TEMPORARY_CLOSURE","HOURS_CHANGE","CROWDING","REOPENING","GENERAL"]},"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"status":{"type":"string","enum":["SCHEDULED","ACTIVE","EXPIRED","CANCELED"]},"message":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"expiredAt":{"type":"string","format":"date-time","nullable":true},"canceledAt":{"type":"string","format":"date-time","nullable":true},"cancelReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"visibleNow":{"type":"boolean"}},"description":"상점 운영 상태 공지 응답"},"PlaceOperatingNoticeCancelRequest":{"required":["cancelReason"],"type":"object","properties":{"cancelReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"상점 운영 상태 공지 취소 요청"},"PlaceMenuCreateRequest":{"required":["currency","displayOrder","name","priceAmount"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string"},"description":{"maxLength":500,"minLength":0,"type":"string"},"priceAmount":{"maximum":1000000000,"type":"integer","format":"int64"},"currency":{"type":"string","enum":["KRW","USD","JPY","CNY","EUR"]},"imageUrl":{"maxLength":500,"minLength":0,"type":"string","description":"기존 공개 미디어 URL. 없으면 null","nullable":true},"displayOrder":{"minimum":0,"type":"integer","format":"int32"}}},"PlaceMenuResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string","description":"메뉴 설명이 없으면 null","nullable":true},"priceAmount":{"type":"integer","format":"int64"},"currency":{"type":"string","description":"가격 통화. 금액은 해당 통화의 기본 단위로 저장","enum":["KRW","USD","JPY","CNY","EUR"]},"imageUrl":{"type":"string","description":"대표 이미지가 없으면 null","nullable":true},"status":{"type":"string","enum":["AVAILABLE","SOLD_OUT","HIDDEN","INACTIVE"]},"displayOrder":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"MerchantTeamInviteRequest":{"required":["inviteeUserId","role"],"type":"object","properties":{"inviteeUserId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["OWNER","MANAGER","STAFF"]},"expiresAt":{"type":"string","format":"date-time"}}},"MerchantTeamInvitationResponse":{"required":["createdAt","expiresAt","id","inviteeUserId","placeId","role","status"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"inviteeUserId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["OWNER","MANAGER","STAFF"]},"status":{"type":"string","enum":["PENDING","ACCEPTED","REVOKED","EXPIRED"]},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"Merchant 장소 팀원 초대 응답"},"MerchantOwnerMediaCreateRequest":{"required":["s3Key"],"type":"object","properties":{"s3Key":{"maxLength":500,"minLength":0,"type":"string","description":"업로드 URL 발급 응답의 s3Key"},"displayOrder":{"type":"integer","description":"미입력 시 현재 탐색 미디어 마지막 순서 다음으로 등록됩니다.","format":"int32","nullable":true}},"description":"업로드를 완료한 Merchant Owner 탐색 미디어 등록 요청"},"MerchantOwnerMediaUploadRequest":{"required":["contentType","fileName","fileSize"],"type":"object","properties":{"fileName":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"maximum":10485760,"type":"integer","format":"int64"}},"description":"Merchant Owner 탐색 미디어 업로드 URL 요청"},"MerchantOwnerMediaUploadResponse":{"type":"object","properties":{"uploadUrl":{"type":"string"},"imageUrl":{"type":"string"},"s3Key":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"description":"Merchant Owner 탐색 미디어 업로드 URL 응답"},"PlaceInformationReverificationResponseRequest":{"required":["responseNote"],"type":"object","properties":{"responseNote":{"maxLength":1000,"minLength":0,"type":"string"}}},"PlaceInformationReverificationResponse":{"type":"object","properties":{"requestId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["REQUESTED","RESPONDED","COMPLETED","CANCELED","EXPIRED"]},"reason":{"type":"string"},"requestedAt":{"type":"string","format":"date-time"},"dueAt":{"type":"string","format":"date-time"},"lastRemindedAt":{"type":"string","format":"date-time"},"reminderCount":{"type":"integer","format":"int32"},"respondedAt":{"type":"string","format":"date-time"},"responseNote":{"type":"string"},"completedAt":{"type":"string","format":"date-time"}}},"PaymentResponse":{"required":["amountMinor","createdAt","currency","failedAt","failureCode","id","paidAt","provider","providerPaymentId","refundedAt","reservationId","status"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reservationId":{"type":"integer","format":"int64"},"provider":{"type":"string"},"providerPaymentId":{"type":"string","description":"결제가 PAID 상태가 되기 전에는 null입니다.","nullable":true},"amountMinor":{"type":"integer","description":"결제가 성공하기 전에는 null입니다.","format":"int64","nullable":true},"currency":{"type":"string","description":"결제가 성공하기 전에는 null입니다.","nullable":true},"status":{"type":"string","enum":["PROCESSING","PAID","REFUND_PROCESSING","FAILED","REFUNDED"]},"failureCode":{"type":"string","description":"결제가 FAILED 상태일 때만 제공됩니다.","nullable":true},"createdAt":{"type":"string","format":"date-time"},"paidAt":{"type":"string","description":"결제가 PAID, REFUND_PROCESSING 또는 REFUNDED 상태가 되기 전에는 null입니다.","format":"date-time","nullable":true},"failedAt":{"type":"string","description":"결제가 FAILED 상태일 때만 제공됩니다.","format":"date-time","nullable":true},"refundedAt":{"type":"string","description":"결제가 REFUNDED 상태가 되기 전에는 null입니다.","format":"date-time","nullable":true}},"description":"관광객 결제 응답"},"OfferCreateRequest":{"required":["benefitDescription","couponValidityDays","description","endsAt","placeId","startsAt","title"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64","example":10},"title":{"maxLength":100,"minLength":1,"type":"string","example":"관광객 웰컴 음료"},"description":{"maxLength":1000,"minLength":1,"type":"string","example":"여행 중인 관광객에게 제공하는 한정 Offer입니다."},"benefitDescription":{"maxLength":500,"minLength":1,"type":"string","example":"음료 1잔 무료"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalQuantity":{"maximum":100000,"minimum":1,"type":"integer","description":"LIMITED 재고에서 필요한 발급 수량. UNLIMITED이면 생략합니다.","format":"int32","nullable":true,"example":100},"couponValidityDays":{"maximum":365,"minimum":1,"type":"integer","format":"int32","example":7},"eligibilityPolicy":{"type":"string","description":"쿠폰 발급 대상 정책. 생략하면 ACTIVE_TRAVEL_SCHEDULE입니다.","nullable":true,"enum":["ACTIVE_TRAVEL_SCHEDULE","PUBLIC"]},"inventoryPolicy":{"type":"string","description":"쿠폰 재고 정책. 생략하면 LIMITED입니다.","nullable":true,"enum":["LIMITED","UNLIMITED"]},"expiryPolicy":{"type":"string","description":"쿠폰 만료 정책. 생략하면 ISSUE_PLUS_DAYS_CAPPED_BY_OFFER_END입니다.","nullable":true,"enum":["ISSUE_PLUS_DAYS_CAPPED_BY_OFFER_END","ISSUE_PLUS_DAYS","OFFER_END"]}}},"OfferResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":10},"title":{"type":"string","example":"관광객 웰컴 음료"},"description":{"type":"string"},"benefitDescription":{"type":"string","example":"음료 1잔 무료"},"status":{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED"]},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalQuantity":{"type":"integer","description":"LIMITED 재고의 총 발급 수량. UNLIMITED이면 null","format":"int32","nullable":true},"issuedQuantity":{"type":"integer","format":"int32"},"remainingQuantity":{"type":"integer","description":"남은 발급 수량. UNLIMITED이면 null","format":"int32","nullable":true},"couponValidityDays":{"type":"integer","format":"int32"},"eligibilityPolicy":{"type":"string","enum":["ACTIVE_TRAVEL_SCHEDULE","PUBLIC"]},"inventoryPolicy":{"type":"string","enum":["LIMITED","UNLIMITED"]},"expiryPolicy":{"type":"string","enum":["ISSUE_PLUS_DAYS_CAPPED_BY_OFFER_END","ISSUE_PLUS_DAYS","OFFER_END"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CouponRedeemRequest":{"required":["code"],"type":"object","properties":{"code":{"pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$","type":"string","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}}},"MerchantTeamMemberResponse":{"required":["createdAt","id","placeId","role","status","updatedAt","userId"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"userId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["OWNER","MANAGER","STAFF"]},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Merchant 장소 팀원 응답"},"PopupCampaignCreateRequest":{"required":["brandId","description","endsAt","placeId","startsAt","title"],"type":"object","properties":{"brandId":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":10},"title":{"maxLength":150,"minLength":0,"type":"string","example":"성수 여름 팝업"},"description":{"maxLength":2000,"minLength":0,"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"}}},"PopupCampaignResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"brandId":{"type":"integer","format":"int64"},"brandName":{"type":"string"},"brandLogoUrl":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"title":{"type":"string"},"description":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"BrandCreateRequest":{"required":["name"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","example":"핑덤 스튜디오"},"description":{"maxLength":1000,"minLength":0,"type":"string","example":"지역 경험을 만드는 라이프스타일 브랜드"},"logoUrl":{"maxLength":500,"minLength":0,"type":"string","example":"https://cdn.example.com/brands/pingdom.png"}}},"BrandResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string"},"logoUrl":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"LocationCheckInRequest":{"required":["accuracyMeters","latitude","longitude","observedAt","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"accuracyMeters":{"minimum":0.0,"exclusiveMinimum":false,"type":"number","format":"double"},"observedAt":{"type":"string","format":"date-time"}}},"LocationCheckInResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"checkInDate":{"type":"string","format":"date"},"observedAt":{"type":"string","format":"date-time"},"recordedAt":{"type":"string","format":"date-time"},"distanceMeters":{"type":"number","format":"double"},"status":{"type":"string","enum":["PROXIMITY_MATCHED","DWELL_VERIFIED"]}}},"VisitEvidenceResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"locationCheckInId":{"type":"integer","format":"int64"},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}}},"FcmTokenRequest":{"required":["token"],"type":"object","properties":{"token":{"type":"string","description":"최신 기기 FCM 토큰","example":"fcm-device-token-sample"}},"description":"FCM 토큰 업데이트 요청"},"ConsultationIntroRequest":{"required":["message"],"type":"object","properties":{"message":{"maxLength":300,"minLength":0,"type":"string","description":"사용자가 입력한 첫 상담 질문","example":"작은 카페를 열고 싶은데 어떤 업종으로 시작하면 좋을까요?"}},"description":"첫 상담 안내 요청"},"ConsultationIntroResponse":{"type":"object","properties":{"message":{"type":"string","description":"사용자에게 표시할 첫 상담 안내문","example":"카페 창업을 고민하고 계시는군요. 먼저 관심 있는 업종을 선택해 주세요."},"source":{"type":"string","description":"안내문 생성 출처","example":"gemini","enum":["gemini","fallback"]}},"description":"첫 상담 안내 응답"},"CommunityPostCreateRequest":{"required":["categoryId","content","title"],"type":"object","properties":{"categoryId":{"maxLength":30,"minLength":0,"type":"string","description":"게시글 카테고리 식별자","example":"PLACE"},"title":{"maxLength":50,"minLength":0,"type":"string","description":"게시글 제목","example":"대소고 다녀왔어요"},"content":{"maxLength":5000,"minLength":0,"type":"string","description":"게시글 본문","example":"즐거운 경험이었습니다."},"placeIds":{"type":"array","description":"연결할 장소 ID 목록. 장소 카테고리에서는 1개 이상 필수입니다.","example":[1,2],"items":{"type":"integer","description":"연결할 장소 ID 목록. 장소 카테고리에서는 1개 이상 필수입니다.","format":"int64"}},"imageIds":{"maxItems":10,"minItems":0,"type":"array","description":"업로드한 본인 이미지 ID. 입력 순서대로 표시하며 최대 10장","items":{"type":"integer","description":"업로드한 본인 이미지 ID. 입력 순서대로 표시하며 최대 10장","format":"int64"}},"countryCode":{"pattern":"^[A-Z]{2}$","type":"string","description":"ISO 3166-1 alpha-2 국가 코드. 미설정은 null","example":"KR"},"region":{"maxLength":100,"minLength":0,"type":"string","description":"작성자가 지정한 표시 지역. 미설정은 null","example":"서울"}},"description":"커뮤니티 게시글 등록 요청"},"CommunityPostCreateResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"등록된 게시글 ID","format":"int64","example":1},"placeIds":{"type":"array","description":"연결된 장소 ID 목록","example":[1,2],"items":{"type":"integer","description":"연결된 장소 ID 목록","format":"int64"}}},"description":"커뮤니티 게시글 등록 응답"},"CommunityReportCreateRequest":{"required":["description","reason"],"type":"object","properties":{"reason":{"type":"string","description":"신고 사유","example":"SPAM","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"description":{"maxLength":500,"minLength":0,"type":"string","description":"상세 설명","example":"같은 광고를 반복 게시합니다."}},"description":"커뮤니티 신고 요청"},"CommunityReportCreateResponse":{"type":"object","properties":{"reportId":{"type":"integer","description":"신고 ID","format":"int64","example":1},"status":{"type":"string","description":"신고 처리 상태","example":"PENDING","enum":["PENDING","ACCEPTED","DECLINED"]}},"description":"커뮤니티 신고 접수 결과"},"MerchantOwnerPublicResponse":{"type":"object","properties":{"userId":{"type":"integer","format":"int64"},"businessName":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string","nullable":true},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"}},"description":"장소에 연결된 Merchant Owner 공개 프로필","nullable":true},"PlaceDetailResponse":{"required":["activeOperatingNotices","address","communityViewCount","currentlyOperating","currentlyOperatingCheckedAt","description","englishName","geocodingSource","id","informationEvidenceUpdatedAt","informationVerificationStatus","informationVerifiedAt","jibunAddress","lastVerifiedAt","lastVerifiedSourceType","latitude","longitude","merchantOwner","name","operatingExceptions","operatingStatus","operatingStatusCheckedAt","postalCode","primaryInformationSource","registrant","regularHours","roadAddress","touristCategories","touristSummary","verifiedEvidenceCount"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"currentlyOperating":{"type":"boolean"},"currentlyOperatingCheckedAt":{"type":"string","description":"현재 영업 여부를 평가한 UTC 기준 시각. 영업 일정은 Asia/Seoul 기준으로 해석합니다.","format":"date-time"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"activeOperatingNotices":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}},"description":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"primaryInformationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"informationVerificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"informationVerifiedAt":{"type":"string","format":"date-time","nullable":true},"informationEvidenceUpdatedAt":{"type":"string","format":"date-time","nullable":true},"verifiedEvidenceCount":{"type":"integer","description":"검증 완료된 근거 수","format":"int32","example":3},"lastVerifiedAt":{"type":"string","description":"가장 최근 검증이 완료된 시각","format":"date-time","nullable":true},"lastVerifiedSourceType":{"type":"string","description":"가장 최근 검증 근거의 출처","nullable":true,"enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"latitude":{"maximum":90.0,"minimum":-90.0,"type":"number","format":"double"},"longitude":{"maximum":180.0,"minimum":-180.0,"type":"number","format":"double"},"registrant":{"type":"string"},"communityViewCount":{"type":"integer","description":"커뮤니티 게시글을 통해 유입된 일별 중복 제거 조회수","format":"int64","example":12},"merchantOwner":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/MerchantOwnerPublicResponse"}]}},"description":"장소 상세 조회 응답"},"CommunityPostLikeResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":1},"likeCount":{"type":"integer","description":"좋아요 수","format":"int64","example":12},"liked":{"type":"boolean","description":"현재 사용자의 좋아요 여부","example":true}},"description":"커뮤니티 게시글 좋아요 상태 응답"},"CommunityPostCommentCreateRequest":{"required":["content"],"type":"object","properties":{"content":{"maxLength":1000,"minLength":0,"type":"string","description":"댓글 내용","example":"저도 가보고 싶네요!"},"parentCommentId":{"type":"integer","description":"대댓글의 부모 댓글 ID. null은 최상위 댓글, 답글은 1단계만 지원","format":"int64"}},"description":"커뮤니티 게시글 댓글 등록 요청"},"CommunityPostCommentCreateResponse":{"type":"object","properties":{"commentId":{"type":"integer","description":"댓글 ID","format":"int64","example":1},"postId":{"type":"integer","description":"대상 게시글 ID","format":"int64","example":1},"content":{"type":"string","description":"저장된 댓글 내용","example":"저도 가보고 싶네요!"},"parentCommentId":{"type":"integer","description":"대댓글 부모 ID. 최상위 댓글이면 null","format":"int64"}},"description":"커뮤니티 게시글 댓글 등록 응답"},"CommunityImageUploadResponse":{"type":"object","properties":{"imageId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"description":"게시글에 연결할 이미지. 본인 미사용 이미지만 만료 전 1회 연결 가능"},"CommunityCommentLikeResponse":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"likeCount":{"type":"integer","format":"int64"},"liked":{"type":"boolean"}}},"RefreshTokenResponse":{"type":"object","properties":{"accessToken":{"type":"string","description":"새로 발급된 Access Token","example":"eyJhbGciOiJIUzI1NiJ9.new.access.token"}},"description":"토큰 재발급 응답"},"SignupRequest":{"required":["birthYear","country","email","language","password","username"],"type":"object","properties":{"username":{"maxLength":50,"minLength":4,"type":"string","description":"로그인에 사용할 아이디","example":"pingdom_user"},"email":{"type":"string","description":"이메일 인증을 받을 메일 주소","example":"pingdom@example.com"},"password":{"maxLength":2147483647,"minLength":8,"type":"string","description":"로그인 비밀번호","example":"securePass123!"},"birthYear":{"minimum":1900,"type":"integer","description":"출생 연도","format":"int32","nullable":true,"example":1998},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"},"language":{"maxLength":20,"minLength":0,"type":"string","description":"언어 코드 또는 언어명","example":"ko"},"country":{"maxLength":100,"minLength":0,"type":"string","description":"국가 코드 또는 국가명","example":"KR"}},"description":"회원가입 요청 정보"},"UserResponse":{"type":"object","properties":{"id":{"type":"integer","description":"생성된 사용자 ID","format":"int64","example":1},"username":{"type":"string","description":"생성된 사용자 아이디","example":"pingdom_user"},"email":{"type":"string","description":"생성된 사용자 이메일","example":"pingdom@example.com"},"birthYear":{"type":"integer","description":"출생 연도","format":"int32","example":1998},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"role":{"type":"string","description":"생성된 사용자 역할","example":"USER","enum":["USER","MERCHANT_OWNER","ADMIN"]}},"description":"회원가입 성공 응답"},"PasswordResetRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string","description":"비밀번호 재설정 메일을 받을 이메일 주소","example":"pingdom@example.com"}},"description":"비밀번호 재설정 토큰 발급 요청 정보"},"PasswordResetConfirmRequest":{"required":["confirmPassword","email","newPassword","token"],"type":"object","properties":{"email":{"type":"string","description":"비밀번호를 재설정할 이메일 주소","example":"pingdom@example.com"},"token":{"type":"string","description":"메일로 발급된 비밀번호 재설정 토큰"},"newPassword":{"maxLength":2147483647,"minLength":8,"type":"string","description":"변경할 새 비밀번호","example":"newSecurePass123!"},"confirmPassword":{"maxLength":2147483647,"minLength":8,"type":"string","description":"새 비밀번호 확인 입력","example":"newSecurePass123!"}},"description":"비밀번호 재설정 완료 요청 정보"},"LoginRequest":{"required":["password","username"],"type":"object","properties":{"username":{"maxLength":50,"minLength":4,"type":"string","description":"로그인에 사용할 아이디","example":"pingdom_user"},"password":{"maxLength":2147483647,"minLength":8,"type":"string","description":"로그인 비밀번호","example":"securePass123!"}},"description":"로그인 요청 정보"},"LoginResponse":{"type":"object","properties":{"id":{"type":"integer","description":"사용자 ID","format":"int64","example":1},"username":{"type":"string","description":"사용자 아이디","example":"pingdom_user"},"email":{"type":"string","description":"사용자 이메일","example":"pingdom@example.com"},"birthYear":{"type":"integer","description":"출생 연도","format":"int32","example":1998},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"message":{"type":"string","description":"로그인 결과 메시지","example":"로그인에 성공했습니다."},"accessToken":{"type":"string","description":"인증에 사용할 Access Token","example":"eyJhbGciOiJIUzI1NiJ9.access.token"},"role":{"type":"string","description":"현재 사용자 역할","example":"MERCHANT_OWNER","enum":["USER","MERCHANT_OWNER","ADMIN"]}},"description":"로그인 성공 응답"},"EmailVerifyRequest":{"required":["code","email"],"type":"object","properties":{"email":{"type":"string","description":"인증 대상 이메일 주소","example":"pingdom@example.com"},"code":{"type":"string","description":"이메일로 전달된 인증 코드","example":"123456"}},"description":"이메일 인증 요청 정보"},"EmailResendRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string","description":"인증 메일을 다시 받을 이메일 주소","example":"pingdom@example.com"}},"description":"이메일 인증 메일 재발송 요청 정보"},"LocationAnalysisRequest":{"required":["category","email","privacyConsent","region"],"type":"object","properties":{"region":{"type":"string","description":"희망 지역","example":"대구광역시 북구 서변동"},"category":{"type":"string","description":"가게 업종 또는 카테고리","example":"카페"},"targetCustomerGroup":{"type":"string","description":"주요 고객층(연령·성별)","example":"20~30대 여성"},"operatingHours":{"type":"string","description":"주요 영업 시간대","example":"평일 09:00~22:00"},"email":{"type":"string","description":"보고서 보관을 위한 이메일","example":"owner@example.com"},"privacyConsent":{"type":"boolean","description":"개인정보 수집·이용 동의 여부","example":true}}},"VisitorVerificationReportReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"VisitorVerificationReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"waitTimeMinutes":{"type":"integer","format":"int32"},"languageCode":{"type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"VisitorVerificationReportCorrectionReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"VisitorVerificationReportCorrectionResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"requesterUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","LANGUAGE_SUPPORT","COUPON_USAGE","CROWD_LEVEL","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"waitTimeMinutes":{"type":"integer","format":"int32"},"languageCode":{"type":"string"},"couponUsageStatus":{"type":"string","enum":["AVAILABLE","UNAVAILABLE","UNKNOWN"]},"crowdLevel":{"type":"string","enum":["LOW","MODERATE","HIGH","FULL"]},"reportStatus":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"VerifiedBoostProductCreateRequest":{"required":["description","durationDays","name","priceAmount"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","example":"Verified Boost 7일"},"description":{"maxLength":500,"minLength":0,"type":"string","example":"검증된 장소의 추천 노출을 7일간 강화합니다."},"priceAmount":{"type":"integer","description":"KRW 기준 가격","format":"int64","example":30000},"durationDays":{"maximum":365,"minimum":1,"type":"integer","format":"int32","example":7}}},"VerifiedBoostProductResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"name":{"type":"string"},"description":{"type":"string"},"priceAmount":{"type":"integer","description":"KRW 기준 가격","format":"int64","example":30000},"durationDays":{"type":"integer","format":"int32","example":7},"status":{"type":"string","enum":["DRAFT","ACTIVE","INACTIVE"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminRoleAssignmentRequest":{"required":["role"],"type":"object","properties":{"role":{"type":"string","description":"할당할 관리자 역할","example":"CONTENT_MODERATOR","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"역할을 부여하거나 회수하는 사유","example":"장소 정보 검수 담당 배정"}},"description":"관리자 역할 할당 요청"},"AdminRoleAssignmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"adminUserId":{"type":"integer","format":"int64"},"role":{"type":"string","enum":["SUPER_ADMIN","CONTENT_MODERATOR","MERCHANT_OPERATOR","SUPPORT_OPERATOR","ANALYST"]},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"assignedByUserId":{"type":"integer","format":"int64"},"assignedAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time"},"permissions":{"type":"array","items":{"type":"string","enum":["ADMIN_ROLE_MANAGE","USER_READ","USER_SANCTION","PLACE_READ","PLACE_MODERATE","MERCHANT_REVIEW","REPORT_REVIEW","SCOUT_REVIEW","DASHBOARD_READ","AUDIT_READ","OUTBOX_RECOVERY"]}}},"description":"관리자 역할 할당 응답"},"AdminTrustScoreInterventionEvaluationResponse":{"type":"object","properties":{"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":12},"trustScore":{"type":"integer","description":"현재 Trust Score","format":"int32","example":40},"matchedRuleId":{"type":"integer","description":"매칭된 규칙 ID","format":"int64","example":1},"matchedRuleName":{"type":"string","description":"매칭된 규칙 이름","example":"low trust temporary restriction"},"actionType":{"type":"string","description":"적용 액션","example":"TEMPORARY_RESTRICT","enum":["WARN","REVIEW_REQUIRED","TEMPORARY_RESTRICT","MANUAL_REVIEW"]},"restrictedUntil":{"type":"string","description":"제한 만료 시각","format":"date-time"},"message":{"type":"string","description":"처리 결과 메시지","example":"Trust Score 개입 규칙을 적용했습니다."}}},"AdminTrustScoreBatchResponse":{"type":"object","properties":{"processedCount":{"type":"integer","format":"int32"},"changedCount":{"type":"integer","format":"int32"}}},"ScoutProfileReviewRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutActivityEligibilityReviewRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutActivityEligibilityGrantRequest":{"required":["eligibleFrom"],"type":"object","properties":{"eligibleFrom":{"type":"string","format":"date-time"},"eligibleUntil":{"type":"string","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutFieldReportReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"ScoutFieldReportResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"scoutUserId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reportType":{"type":"string","enum":["PLACE_INFORMATION","OPERATING_HOURS","LOCATION","CLOSED_PLACE","WAIT_TIME","CROWD_LEVEL","SAFETY","OTHER"]},"description":{"type":"string"},"evidenceUrl":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ReservationReviewRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminReservationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"quantity":{"type":"integer","format":"int32"},"touristUserId":{"type":"integer","format":"int64"},"touristUsername":{"type":"string"},"merchantOwnerUserId":{"type":"integer","format":"int64"},"merchantOwnerUsername":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"availabilityId":{"type":"integer","format":"int64"},"reservationStartsAt":{"type":"string","format":"date-time"},"reservationEndsAt":{"type":"string","format":"date-time"},"bookerName":{"type":"string"},"bookerPhone":{"type":"string"},"requestNote":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"confirmedAt":{"type":"string","format":"date-time"},"reviewedBy":{"type":"integer","format":"int64"},"reviewedAt":{"type":"string","format":"date-time"},"reviewReason":{"type":"string"},"rejectedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"canceledBy":{"type":"integer","format":"int64"},"statusHistory":{"type":"array","items":{"$ref":"#/components/schemas/AdminReservationStatusHistoryResponse"}}}},"AdminReservationStatusHistoryResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"changedBy":{"type":"integer","format":"int64"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}},"AdminReportAppealActionRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminReportAppealActionResponse":{"type":"object","properties":{"appealId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]},"processedAt":{"type":"string","format":"date-time"}}},"AdminPostReportBulkActionResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":10},"status":{"type":"string","description":"일괄 처리된 신고 상태","example":"ACCEPTED","enum":["PENDING","ACCEPTED","DECLINED","RESTORED"]},"processedReportCount":{"type":"integer","description":"처리된 신고 수","format":"int32","example":3},"visibilityStatus":{"type":"string","description":"게시글 공개 상태","example":"AUTO_HIDDEN","enum":["ACTIVE","AUTO_HIDDEN"]},"hiddenAt":{"type":"string","description":"게시글 숨김 처리 시각","format":"date-time"},"hiddenReason":{"type":"string","description":"게시글 숨김 사유","example":"REPORT_BULK_ACCEPTED"},"processedAt":{"type":"string","description":"신고 처리 시각","format":"date-time"}},"description":"관리자 게시글 단위 신고 일괄 처리 응답"},"S3OrphanReportStatus":{"type":"object","properties":{"reportId":{"type":"string"},"status":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"dbKeyCount":{"type":"integer","format":"int64"},"s3KeyCount":{"type":"integer","format":"int64"},"deleteCandidateCount":{"type":"integer","format":"int64"},"errorMessage":{"type":"string"}}},"PlaceInformationReverificationCreateRequest":{"required":["dueAt","reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"},"dueAt":{"type":"string","format":"date-time"}}},"AdminPlaceInformationEvidenceCreateRequest":{"required":["evidenceType","sourceType"],"type":"object","properties":{"sourceType":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"evidenceType":{"type":"string","enum":["EXTERNAL_PLACE_ID","BUSINESS_CLAIM","DOCUMENT","PHOTO","ADMIN_REVIEW","USER_VISIT","SYSTEM_SIGNAL"]},"externalReference":{"maxLength":100,"minLength":0,"type":"string","description":"외부 장소 ID, 사업자 등록 번호 등 외부 참조값","nullable":true},"referenceUrl":{"maxLength":500,"minLength":0,"type":"string","description":"증빙 URL","nullable":true},"description":{"maxLength":1000,"minLength":0,"type":"string","description":"관리자 메모 또는 증빙 설명","nullable":true},"submittedByUserId":{"type":"integer","description":"증빙 제출 사용자 ID. 미입력 시 관리자 ID를 사용","format":"int64","nullable":true}},"description":"관리자 장소 정보 증빙 등록 요청"},"AdminPlaceInformationEvidenceItem":{"type":"object","properties":{"evidenceId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"sourceType":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"evidenceType":{"type":"string","enum":["EXTERNAL_PLACE_ID","BUSINESS_CLAIM","DOCUMENT","PHOTO","ADMIN_REVIEW","USER_VISIT","SYSTEM_SIGNAL"]},"verificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"externalReference":{"type":"string","nullable":true},"referenceUrl":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"submittedByUserId":{"type":"integer","format":"int64","nullable":true},"reviewedByAdminUserId":{"type":"integer","format":"int64","nullable":true},"reviewReason":{"type":"string","nullable":true},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"관리자 장소 정보 증빙 항목"},"AdminPlaceInformationEvidenceUpdateResponse":{"type":"object","properties":{"evidence":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceItem"},"message":{"type":"string"}},"description":"관리자 장소 정보 증빙 변경 응답"},"AdminPlaceRecommendationSnapshotResyncResponse":{"type":"object","properties":{"placeCount":{"type":"integer","format":"int64"},"synchronizedSnapshotCount":{"type":"integer","format":"int64"},"deletedSnapshotCount":{"type":"integer","format":"int64"},"synchronizedSimilaritySnapshotCount":{"type":"integer","format":"int64"},"deletedSimilaritySnapshotCount":{"type":"integer","format":"int64"},"synchronizedVersionSnapshotCount":{"type":"integer","format":"int64"},"deletedVersionSnapshotCount":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminMapPlaceMergeRequest":{"type":"object","properties":{"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"candidateId":{"type":"integer","format":"int64"}}},"AdminMapPlaceMergeResponse":{"type":"object","properties":{"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminPlaceMergeRestoreResponse":{"type":"object","properties":{"historyId":{"type":"integer","format":"int64"},"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"message":{"type":"string"}}},"AdminPlaceDuplicateDecisionRequest":{"required":["reviewNote"],"type":"object","properties":{"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminPlaceDuplicateCandidateResponse":{"type":"object","properties":{"candidateId":{"type":"integer","format":"int64"},"leftPlaceId":{"type":"integer","format":"int64"},"rightPlaceId":{"type":"integer","format":"int64"},"matchReason":{"type":"string"},"confidenceScore":{"type":"number"},"distanceMeters":{"type":"integer","format":"int32"},"status":{"type":"string"},"reviewedByAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"mergeHistoryId":{"type":"integer","format":"int64"},"detectedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminPlaceDuplicateMergeRequest":{"required":["targetPlaceId"],"type":"object","properties":{"targetPlaceId":{"type":"integer","format":"int64"}}},"PlaceReviewDeletionRequestReviewRequest":{"required":["decision"],"type":"object","properties":{"decision":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"reviewNote":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminPlaceReviewDeletionRequestResponse":{"type":"object","properties":{"deletionRequestId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"requestReason":{"type":"string"},"requesterUserId":{"type":"integer","format":"int64"},"requestedAt":{"type":"string","format":"date-time"},"reviewerAdminUserId":{"type":"integer","format":"int64"},"reviewNote":{"type":"string"},"reviewedAt":{"type":"string","format":"date-time"},"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"reviewAuthorUserId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"reviewVisibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]},"reviewCreatedAt":{"type":"string","format":"date-time"}}},"PlaceInformationReportReviewRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","description":"UNDER_REVIEW, ACCEPTED, REJECTED, RESOLVED만 허용","enum":["SUBMITTED","UNDER_REVIEW","ACCEPTED","REJECTED","DISPUTED","RESOLVED","CANCELED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"관리자 장소 정보 신고 검토 요청"},"PlaceInformationDisputeReviewRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","description":"ACCEPTED 또는 REJECTED만 허용","enum":["SUBMITTED","ACCEPTED","REJECTED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string"}},"description":"관리자 장소 정보 반박 검토 요청"},"AdminPlaceEventRequest":{"required":["endAt","eventType","placeId","reason","startAt","title"],"type":"object","properties":{"placeId":{"type":"integer","description":"행사 장소 ID","format":"int64","example":17},"title":{"maxLength":150,"minLength":0,"type":"string","description":"이벤트 제목","example":"진주 여름 빛 축제"},"description":{"maxLength":1000,"minLength":0,"type":"string","description":"이벤트 설명","example":"남강을 배경으로 열리는 야간 공연과 전시입니다."},"eventType":{"type":"string","description":"이벤트 유형","example":"EXHIBITION","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","description":"시작 시각","format":"date-time"},"endAt":{"type":"string","description":"종료 시각","format":"date-time"},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"관리자 변경 사유","example":"공식 일정 등록"}},"description":"관리자 기간형 이벤트 등록·수정 요청"},"AdminPlaceEventResponse":{"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"publicationStatus":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]},"message":{"type":"string"}},"description":"관리자 기간형 이벤트 응답"},"AdminPlaceEventActionRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"변경 사유","example":"운영 검토를 완료했습니다."}},"description":"관리자 이벤트 상태 변경 요청"},"AdminOutboxEventRetryRequest":{"required":["reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"장애 원인 제거와 중복 처리 안전성을 확인한 재처리 사유","example":"외부 메일 공급자 장애 복구 확인"}},"description":"관리자 Outbox 이벤트 재처리 요청"},"AdminOutboxEventItem":{"type":"object","properties":{"eventId":{"type":"string","description":"이벤트 ID"},"eventType":{"type":"string","description":"이벤트 유형","example":"EMAIL_VERIFICATION_REQUESTED","enum":["EMAIL_VERIFICATION_REQUESTED","PASSWORD_RESET_REQUESTED","MAP_IMAGE_LIKED","PLACE_RECOMMENDATION_RESYNC_REQUESTED","PLACE_INFORMATION_EVIDENCE_SUBMITTED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_SUBMITTED","PLACE_INFORMATION_REPORT_DISPUTED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_SUBMITTED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_CONVERSION_RECORDED","ADMIN_NOTIFICATION_REQUESTED","S3_OBJECT_DELETE_REQUESTED","PRIVACY_PROCESSING_RECORDED"]},"aggregateType":{"type":"string","description":"aggregate 유형","example":"USER"},"aggregateId":{"type":"string","description":"aggregate ID","example":"10"},"status":{"type":"string","description":"처리 상태","example":"FAILED","enum":["PENDING","PROCESSING","RETRY","SUCCEEDED","FAILED"]},"attemptCount":{"type":"integer","description":"현재 재시도 주기의 실패 횟수","format":"int32","example":5},"nextAttemptAt":{"type":"string","description":"다음 처리 가능 시각","format":"date-time"},"processingStartedAt":{"type":"string","description":"처리 선점 시각","format":"date-time"},"processedAt":{"type":"string","description":"처리 완료 시각","format":"date-time"},"lastError":{"type":"string","description":"마지막 실패 원인"},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}},"description":"관리자 Outbox 이벤트 운영 조회 항목"},"MerchantPlaceApplicationReviewRequest":{"required":["reviewedVersion"],"type":"object","properties":{"reviewedVersion":{"type":"integer","format":"int64"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"MerchantOwnerReviewRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminCommunityReportActionResponse":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"targetHidden":{"type":"boolean"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 처리 결과"},"BanRequest":{"type":"object","properties":{"reason":{"maxLength":255,"minLength":0,"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"expiresAt":{"type":"string","description":"기간 밴 종료 시각. 비우면 영구 밴으로 처리됩니다.","format":"date-time"},"durationDays":{"minimum":1,"type":"integer","description":"현재 시각부터 적용할 밴 기간(일). expiresAt과 동시에 사용할 수 없습니다.","format":"int64","example":7}},"description":"관리자 밴 처리 요청 정보"},"BanResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"밴 처리된 사용자 ID","format":"int64","example":7},"banned":{"type":"boolean","description":"밴 여부","example":true},"bannedAt":{"type":"string","description":"밴 처리 시각","format":"date-time"},"reason":{"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"banType":{"type":"string","description":"밴 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"}},"description":"관리자 밴 처리 응답"},"UnbanRequest":{"type":"object","properties":{"reason":{"maxLength":255,"minLength":0,"type":"string","description":"밴 해제 사유","example":"운영 검토 결과 해제"}},"description":"관리자 밴 해제 요청 정보"},"UnbanResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"밴 해제된 사용자 ID","format":"int64","example":7},"banned":{"type":"boolean","description":"현재 밴 여부","example":false},"releasedAt":{"type":"string","description":"밴 해제 처리 시각","format":"date-time"},"reason":{"type":"string","description":"밴 해제 사유","example":"운영 검토 결과 해제"}},"description":"관리자 밴 해제 응답"},"TravelScheduleUpdateRequest":{"required":["endDate","startDate"],"type":"object","properties":{"startDate":{"type":"string","description":"여행 시작일","format":"date","example":"2026-08-02"},"endDate":{"type":"string","description":"여행 종료일","format":"date","example":"2026-08-05"}},"description":"여행 일정 기간 변경 요청"},"NotificationSettingUpdateRequest":{"type":"object","properties":{"newHotplaceEnabled":{"type":"boolean","description":"핫플레이스 알림 수신 여부","example":true},"newLikeEnabled":{"type":"boolean","description":"좋아요 알림 수신 여부","example":false},"quietHoursEnabled":{"type":"boolean","description":"quiet hours 적용 여부","example":true},"quietHoursStart":{"type":"string","description":"quiet hours 시작 시각","format":"time","example":"22:00:00"},"quietHoursEnd":{"type":"string","description":"quiet hours 종료 시각","format":"time","example":"08:00:00"},"timezone":{"type":"string","description":"IANA timezone","example":"Asia/Seoul"}},"description":"알림 수신 설정 수정 요청"},"NotificationSettingResponse":{"type":"object","properties":{"newHotplaceEnabled":{"type":"boolean","description":"핫플레이스 알림 수신 여부","example":true},"newLikeEnabled":{"type":"boolean","description":"좋아요 알림 수신 여부","example":true},"quietHoursEnabled":{"type":"boolean","description":"quiet hours 적용 여부","example":false},"quietHoursStart":{"type":"string","description":"quiet hours 시작 시각","format":"time","example":"22:00:00"},"quietHoursEnd":{"type":"string","description":"quiet hours 종료 시각","format":"time","example":"08:00:00"},"timezone":{"type":"string","description":"IANA timezone","example":"Asia/Seoul"}},"description":"알림 수신 설정 응답"},"MerchantOwnerOperatingStatusUpdateRequest":{"required":["operatingStatus"],"type":"object","properties":{"operatingStatus":{"type":"string","example":"OPERATING","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]}},"description":"Merchant Owner 장소 운영 상태 변경 요청"},"MerchantOwnerOperatingResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time"},"currentlyOperating":{"type":"boolean"},"checkedAt":{"type":"string","description":"현재 영업 여부를 평가한 UTC 기준 시각","format":"date-time"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"informationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"verificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]}},"description":"Merchant Owner 장소 운영 정보 응답"},"PlaceOperatingNoticeUpdateRequest":{"required":["message","severity"],"type":"object","properties":{"severity":{"type":"string","enum":["INFO","WARNING","CRITICAL"]},"message":{"maxLength":500,"minLength":0,"type":"string"}},"description":"상점 운영 상태 공지 수정 요청"},"PlaceMenuUpdateRequest":{"required":["currency","name","priceAmount"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string"},"description":{"maxLength":500,"minLength":0,"type":"string"},"priceAmount":{"maximum":1000000000,"type":"integer","format":"int64"},"currency":{"type":"string","enum":["KRW","USD","JPY","CNY","EUR"]},"imageUrl":{"maxLength":500,"minLength":0,"type":"string","description":"기존 공개 미디어 URL. 없으면 null","nullable":true}}},"PlaceMenuStatusRequest":{"required":["status"],"type":"object","properties":{"status":{"type":"string","enum":["AVAILABLE","SOLD_OUT","HIDDEN","INACTIVE"]}}},"PlaceMenuOrderRequest":{"required":["displayOrder"],"type":"object","properties":{"displayOrder":{"minimum":0,"type":"integer","format":"int32"}}},"MerchantTeamRoleUpdateRequest":{"required":["role"],"type":"object","properties":{"role":{"type":"string","enum":["OWNER","MANAGER","STAFF"]}}},"MerchantOwnerMediaOrderUpdateRequest":{"type":"object","properties":{"displayOrder":{"type":"integer","description":"0부터 시작하는 이동 대상 위치입니다. 현재 탐색 미디어 개수보다 작은 값만 허용됩니다.","format":"int32","example":0}},"description":"Merchant Owner 탐색 미디어 순서 변경 요청"},"LocationAnalysisReportUpdateRequest":{"required":["email","reportName"],"type":"object","properties":{"reportName":{"type":"string"},"email":{"type":"string"}}},"LocationAnalysisReportResponse":{"type":"object","properties":{"reportId":{"type":"string"},"reportName":{"type":"string"},"category":{"type":"string"},"region":{"type":"string"},"targetCustomerGroup":{"type":"string"},"operatingHours":{"type":"string"},"email":{"type":"string"},"privacyConsent":{"type":"boolean"},"publishedDate":{"type":"string","format":"date"},"analysisBasisDate":{"type":"string","format":"date"},"createdAt":{"type":"string","format":"date-time"},"downloadPath":{"type":"string"},"htmlDebugPath":{"type":"string"}}},"AdminTrustScoreInterventionRuleToggleResponse":{"type":"object","properties":{"ruleId":{"type":"integer","description":"개입 규칙 ID","format":"int64","example":1},"enabled":{"type":"boolean","description":"활성화 여부","example":false},"message":{"type":"string","description":"처리 결과 메시지","example":"Trust Score 개입 규칙을 비활성화했습니다."}}},"AdminTrustScoreAnomalyResolveRequest":{"required":["resolutionReason"],"type":"object","properties":{"resolutionReason":{"maxLength":500,"minLength":0,"type":"string","description":"이상치 해결 사유","example":"관리자 검토 후 정상 패턴으로 확인했습니다."}}},"AdminTrustScoreAnomalyItem":{"type":"object","properties":{"id":{"type":"integer","description":"Trust Score 이상치 ID","format":"int64","example":1},"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":12},"reporterUsername":{"type":"string","description":"신고자 username","example":"ping-user"},"anomalyType":{"type":"string","description":"이상치 유형","example":"FALSE_REPORT_SPIKE","enum":["RAPID_DROP","FALSE_REPORT_SPIKE","LOW_ACCEPTANCE_RATE","MANUAL_REVIEW"]},"severity":{"type":"string","description":"이상치 심각도","example":"HIGH","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"baselineScore":{"type":"integer","description":"기준 Trust Score","format":"int32","example":100},"observedScore":{"type":"integer","description":"감지 시점 Trust Score","format":"int32","example":40},"submittedCount":{"type":"integer","description":"전체 신고 수","format":"int64","example":5},"acceptedCount":{"type":"integer","description":"수락 신고 수","format":"int64","example":1},"declinedCount":{"type":"integer","description":"거절 신고 수","format":"int64","example":4},"falseReportCount":{"type":"integer","description":"허위 신고 수","format":"int64","example":4},"detectedAt":{"type":"string","description":"감지 시각","format":"date-time"},"resolvedAt":{"type":"string","description":"해결 시각","format":"date-time"},"resolutionReason":{"type":"string","description":"해결 사유","example":"관리자 검토 완료"}},"description":"이상치 목록"},"AdminMapPlaceTouristInfoUpdateRequest":{"required":["reason"],"type":"object","properties":{"englishName":{"maxLength":150,"minLength":0,"type":"string","description":"영문 장소명. 공백 또는 null이면 제거합니다.","nullable":true,"example":"Jinju Castle"},"touristSummary":{"maxLength":500,"minLength":0,"type":"string","description":"관광객용 장소 요약. 공백 또는 null이면 제거합니다.","nullable":true},"touristCategories":{"maxItems":9,"minItems":0,"uniqueItems":true,"type":"array","description":"관광 목적 카테고리 전체 목록. 생략하면 모두 제거합니다.","items":{"type":"string","description":"관광 목적 카테고리 전체 목록. 생략하면 모두 제거합니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"영문 정보와 관광 분류 최신화"}},"description":"관리자 장소 관광 정보 전체 교체 요청"},"AdminMapPlaceTouristInfoUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"message":{"type":"string"}}},"AdminMapPlaceOperatingStatusUpdateRequest":{"required":["operatingStatus","reason"],"type":"object","properties":{"operatingStatus":{"type":"string","description":"확인된 장소 운영 상태","example":"TEMPORARILY_CLOSED","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 확인 근거","example":"현장 확인 결과 임시 휴업"}},"description":"관리자 장소 운영 상태 확인 요청"},"AdminMapPlaceOperatingStatusUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","description":"운영 상태 최신 확인 시각","format":"date-time"},"message":{"type":"string"}}},"AdminMapPlaceOperatingScheduleUpdateRequest":{"required":["reason"],"type":"object","properties":{"regularHours":{"uniqueItems":true,"type":"array","description":"요일별 정규 영업 시간대. 생략하면 모두 제거합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceRegularOperatingHourRequest"}},"exceptions":{"uniqueItems":true,"type":"array","description":"특정 날짜의 휴무 또는 대체 영업 일정. 생략하면 모두 제거합니다.","items":{"$ref":"#/components/schemas/AdminMapPlaceOperatingExceptionRequest"}},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"광복절 휴무와 주말 영업시간 반영"}},"description":"관리자 장소 정규 영업시간과 예외 일정 전체 교체 요청"},"AdminMapPlaceOperatingScheduleUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"exceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"message":{"type":"string"}}},"AdminMapPlaceKakaoPlaceIdUpdateRequest":{"type":"object","properties":{"kakaoPlaceId":{"maxLength":50,"minLength":0,"type":"string"}}},"AdminMapPlaceKakaoPlaceIdUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"kakaoPlaceId":{"type":"string"},"message":{"type":"string"}}},"AdminPlaceInformationEvidenceReviewRequest":{"required":["verificationStatus"],"type":"object","properties":{"verificationStatus":{"type":"string","description":"관리자 검토 결과. ADMIN_VERIFIED 또는 REJECTED만 허용","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"reviewReason":{"maxLength":500,"minLength":0,"type":"string","description":"검토 사유. REJECTED일 때 필수","nullable":true}},"description":"관리자 장소 정보 증빙 검토 요청"},"AdminMapPlaceGeocodingUpdateRequest":{"required":["address","latitude","longitude","reason"],"type":"object","properties":{"address":{"maxLength":255,"minLength":0,"type":"string"},"roadAddress":{"maxLength":255,"minLength":0,"type":"string"},"jibunAddress":{"maxLength":255,"minLength":0,"type":"string"},"postalCode":{"maxLength":20,"minLength":0,"type":"string"},"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"},"reason":{"maxLength":500,"minLength":0,"type":"string"}}},"AdminMapPlaceGeocodingUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"address":{"type":"string"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"message":{"type":"string"}}},"AdminMapPlaceDiscoveryStatusUpdateRequest":{"required":["discoveryStatus","reason"],"type":"object","properties":{"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"HIDDEN","enum":["VISIBLE","HIDDEN"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"중복 장소 검수 전 임시 숨김"}},"description":"관리자 장소 탐색 노출 상태 수정 요청"},"AdminMapPlaceDiscoveryStatusUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"HIDDEN","enum":["VISIBLE","HIDDEN"]},"message":{"type":"string"}},"description":"관리자 장소 탐색 노출 상태 수정 응답"},"AdminMapPlaceCoordinateUpdateRequest":{"required":["latitude","longitude"],"type":"object","properties":{"latitude":{"maximum":90.0,"exclusiveMaximum":false,"minimum":-90.0,"exclusiveMinimum":false,"type":"number","format":"double"},"longitude":{"maximum":180.0,"exclusiveMaximum":false,"minimum":-180.0,"exclusiveMinimum":false,"type":"number","format":"double"}}},"AdminMapPlaceCoordinateUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"message":{"type":"string"}}},"AdminMapPlaceBasicInformationUpdateRequest":{"required":["category","name","reason"],"type":"object","properties":{"name":{"maxLength":100,"minLength":0,"type":"string","description":"수정할 장소명","example":"진주성"},"category":{"type":"string","description":"수정할 표준 장소 카테고리","example":"CULTURAL_HERITAGE","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"reason":{"maxLength":500,"minLength":0,"type":"string","description":"감사 로그에 기록할 수정 사유","example":"장소명과 분류 오등록 정정"}},"description":"관리자 장소 기본 정보 수정 요청"},"AdminMapPlaceBasicInformationUpdateResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"category":{"type":"string","enum":["MUSIC","RESTAURANT","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"modifiedAt":{"type":"string","description":"감사 로그에 기록된 기본 정보 수정 시각","format":"date-time"},"message":{"type":"string"}},"description":"관리자 장소 기본 정보 수정 응답"},"AdminPlaceRecommendationTrafficUpdateItem":{"required":["recommendationVersion"],"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v2"},"trafficPercentage":{"maximum":100,"minimum":0,"type":"integer","description":"트래픽 비율","format":"int32","example":30},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"fallbackVersion":{"type":"string","description":"비활성화된 추천 버전 요청 시 대체할 버전","nullable":true,"example":"place-rec-v1"}},"description":"수정할 추천 버전별 트래픽 비율 목록"},"AdminPlaceRecommendationTrafficUpdateRequest":{"required":["policies","reason"],"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"추천 정책 변경 사유","example":"추천 실험 v2 트래픽을 확대합니다."},"policies":{"type":"array","description":"수정할 추천 버전별 트래픽 비율 목록","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficUpdateItem"}}}},"AdminPlaceRecommendationTrafficPolicyItem":{"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v1"},"stage":{"type":"string","description":"추천 단계","example":"STABLE"},"trafficPercentage":{"type":"integer","description":"트래픽 비율","format":"int32","example":70},"enabled":{"type":"boolean","description":"활성화 여부","example":true},"fallbackVersion":{"type":"string","description":"비활성화 시 fallback 추천 버전","nullable":true,"example":"place-rec-v1"}},"description":"현재 추천 버전별 트래픽 정책"},"AdminPlaceRecommendationTrafficUpdateResponse":{"type":"object","properties":{"defaultVersion":{"type":"string","description":"기본 추천 버전","example":"place-rec-v1"},"policies":{"type":"array","description":"현재 추천 버전별 트래픽 정책","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationTrafficPolicyItem"}},"message":{"type":"string","description":"수정 결과 메시지","example":"추천 버전 트래픽 비율을 수정했습니다."}}},"AdminNotificationReadResponse":{"type":"object","properties":{"notificationId":{"type":"integer","description":"읽음 처리된 알림 ID","format":"int64","example":1},"read":{"type":"boolean","description":"읽음 여부","example":true},"message":{"type":"string","description":"처리 메시지","example":"알림을 읽음 처리했습니다."}},"description":"관리자 알림 읽음 처리 응답"},"AdminNotificationReadAllResponse":{"type":"object","properties":{"updatedCount":{"type":"integer","description":"읽음 처리된 알림 개수","format":"int64","example":3},"message":{"type":"string","description":"처리 메시지","example":"전체 알림을 읽음 처리했습니다."}},"description":"관리자 전체 알림 읽음 처리 응답"},"MyVisitorVerificationReportPageResponse":{"required":["hasNext","limit","page","reports","totalElements","totalPages"],"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/MyVisitorVerificationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"내 방문자 검증 제보 목록 페이지 응답"},"MyVisitorVerificationReportCorrectionPageResponse":{"required":["corrections","hasNext","limit","page","totalElements","totalPages"],"type":"object","properties":{"corrections":{"type":"array","items":{"$ref":"#/components/schemas/MyVisitorVerificationReportCorrectionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"내 방문자 검증 제보 정정 이력 페이지 응답"},"MyPageResponse":{"type":"object","properties":{"id":{"type":"integer","description":"사용자 ID","format":"int64","example":1},"username":{"type":"string","description":"사용자 아이디","example":"pingdom_user"},"email":{"type":"string","description":"사용자 이메일","example":"pingdom@example.com"},"birthYear":{"type":"integer","description":"출생 연도","format":"int32","example":1998},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"role":{"type":"string","description":"현재 사용자 역할","example":"MERCHANT_OWNER","enum":["USER","MERCHANT_OWNER","ADMIN"]}},"description":"내 정보 조회 응답"},"TravelScheduleListResponse":{"type":"object","properties":{"schedules":{"type":"array","description":"여행 일정 목록","items":{"$ref":"#/components/schemas/TravelScheduleResponse"}}},"description":"여행 일정 목록 응답"},"MyPlaceReviewPageResponse":{"type":"object","properties":{"reviews":{"type":"array","items":{"$ref":"#/components/schemas/MyPlaceReviewResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"내가 작성한 장소 리뷰 목록 페이지"},"MyPlaceReviewResponse":{"type":"object","properties":{"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"createdAt":{"type":"string","format":"date-time"},"visibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]}},"description":"내가 작성한 장소 리뷰"},"MerchantPlaceApplicationPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceApplicationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"NaverPlaceSearchItem":{"type":"object","properties":{"name":{"type":"string","description":"HTML 태그를 제거한 장소명","example":"네이버 본사"},"roadAddress":{"type":"string","description":"도로명 주소","example":"경기도 성남시 분당구 불정로 6"},"jibunAddress":{"type":"string","description":"지번 주소","example":"경기도 성남시 분당구 정자동 178-1"},"latitude":{"type":"number","description":"WGS84 위도","format":"double","example":37.3595963},"longitude":{"type":"number","description":"WGS84 경도","format":"double","example":127.1054328}},"description":"네이버 업체명 검색 후보"},"NaverPlaceSearchResponse":{"type":"object","properties":{"items":{"maxItems":5,"type":"array","description":"장소 검색 후보 목록. 검색 결과가 없으면 빈 목록입니다.","items":{"$ref":"#/components/schemas/NaverPlaceSearchItem"}}},"description":"신규 장소 등록용 네이버 업체명 검색 결과"},"NaverAddressSearchItem":{"type":"object","properties":{"roadAddress":{"type":"string","description":"도로명 주소","example":"경기도 성남시 분당구 불정로 6"},"jibunAddress":{"type":"string","description":"지번 주소","example":"경기도 성남시 분당구 정자동 178-1"},"postalCode":{"type":"string","description":"우편번호. 제공되지 않는 후보는 null입니다.","nullable":true,"example":"13561"},"latitude":{"type":"number","description":"WGS84 위도","format":"double","example":37.3595963},"longitude":{"type":"number","description":"WGS84 경도","format":"double","example":127.1054328}},"description":"네이버 주소 검색 후보"},"NaverAddressSearchResponse":{"type":"object","properties":{"items":{"maxItems":10,"type":"array","description":"주소 검색 후보 목록. 검색 결과가 없으면 빈 목록입니다.","items":{"$ref":"#/components/schemas/NaverAddressSearchItem"}}},"description":"신규 장소 등록용 네이버 주소 검색 결과"},"ExportBookmarkResponse":{"type":"object","properties":{"id":{"type":"integer","description":"북마크 ID","format":"int64","example":10},"placeId":{"type":"integer","description":"북마크 대상 장소 ID","format":"int64","example":123}},"description":"사용자 북마크 전체 목록"},"ExportCurrentActivityIntentResponse":{"type":"object","properties":{"intent":{"type":"string","description":"현재 행동 의도","example":"CAFE","enum":["EXPLORE","EAT","CAFE","SHOP","ATTEND_EVENT","NIGHTLIFE"]},"expiresAt":{"type":"string","description":"행동 의도 만료 시각","format":"date-time"}},"description":"만료되지 않은 현재 행동 의도. 없으면 null","nullable":true},"ExportMerchantOwnerProfileResponse":{"type":"object","properties":{"businessName":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string","nullable":true},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACTIVE","REJECTED","REVOKED"]},"placeIds":{"type":"array","items":{"type":"integer","format":"int64"}}},"description":"Merchant Owner 신청 및 프로필. 없으면 null","nullable":true},"ExportMerchantVerificationResponse":{"type":"object","properties":{"legalName":{"type":"string"},"businessName":{"type":"string"},"businessRegistrationNumber":{"type":"string"},"identityStatus":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"businessStatus":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"reviewReason":{"type":"string","nullable":true},"reviewedAt":{"type":"string","format":"date-time","nullable":true}},"description":"Merchant 신원 및 사업자 검증 신청. 없으면 null","nullable":true},"ExportTouristCouponResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"offerId":{"type":"integer","format":"int64"},"code":{"type":"string"},"status":{"type":"string","enum":["ISSUED","REDEEMED","EXPIRED"]},"issuedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"redeemedAt":{"type":"string","format":"date-time","nullable":true}},"description":"사용자가 발급받은 관광객 Coupon 이력"},"ExportTouristOfferResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"title":{"type":"string"},"description":{"type":"string"},"benefitDescription":{"type":"string"},"status":{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED"]},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalQuantity":{"type":"integer","format":"int32"},"issuedQuantity":{"type":"integer","format":"int32"},"couponValidityDays":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"Merchant Owner가 만든 관광객 전용 Offer 이력"},"ExportTravelScheduleResponse":{"type":"object","properties":{"id":{"type":"integer","description":"여행 일정 ID","format":"int64","example":1},"startDate":{"type":"string","description":"여행 시작일","format":"date","example":"2026-08-01"},"endDate":{"type":"string","description":"여행 종료일","format":"date","example":"2026-08-04"},"state":{"type":"string","description":"저장된 일정 상태","example":"SCHEDULED","enum":["SCHEDULED","CANCELLED"]}},"description":"사용자 여행 일정 목록"},"ExportUserResponse":{"type":"object","properties":{"id":{"type":"integer","description":"사용자 ID","format":"int64","example":1},"username":{"type":"string","description":"사용자 아이디","example":"pingdom_user"},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL","nullable":true,"example":"https://cdn.pingdom.com/profiles/user1.png"}},"description":"사용자 기본 정보"},"UserDataExportResponse":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/ExportUserResponse"},"bookmarks":{"type":"array","description":"사용자 북마크 전체 목록","items":{"$ref":"#/components/schemas/ExportBookmarkResponse"}},"likedMapImageIds":{"type":"array","description":"최근 좋아요한 지도 이미지 ID 목록. 최대 50개","items":{"type":"integer","description":"최근 좋아요한 지도 이미지 ID 목록. 최대 50개","format":"int64"}},"travelSchedules":{"type":"array","description":"사용자 여행 일정 목록","items":{"$ref":"#/components/schemas/ExportTravelScheduleResponse"}},"currentActivityIntent":{"$ref":"#/components/schemas/ExportCurrentActivityIntentResponse"},"merchantOwnerProfile":{"$ref":"#/components/schemas/ExportMerchantOwnerProfileResponse"},"merchantVerification":{"$ref":"#/components/schemas/ExportMerchantVerificationResponse"},"touristOffers":{"type":"array","description":"Merchant Owner가 만든 관광객 전용 Offer 이력","items":{"$ref":"#/components/schemas/ExportTouristOfferResponse"}},"touristCoupons":{"type":"array","description":"사용자가 발급받은 관광객 Coupon 이력","items":{"$ref":"#/components/schemas/ExportTouristCouponResponse"}}},"description":"사용자 데이터 내보내기 응답"},"MyScoutFieldReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/MyScoutFieldReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"ReservationPageResponse":{"type":"object","properties":{"reservations":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PublicPopupCampaignPageResponse":{"required":["hasNext","items","limit","page","totalCount","totalPages"],"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PublicPopupCampaignResponse"}},"page":{"type":"integer","format":"int32","example":1},"limit":{"type":"integer","format":"int32","example":20},"totalCount":{"type":"integer","format":"int64","example":42},"totalPages":{"type":"integer","format":"int32","example":3},"hasNext":{"type":"boolean","example":true}},"description":"진행 중인 공개 팝업 캠페인 목록 응답"},"PublicPopupCampaignResponse":{"required":["brandId","brandLogoUrl","brandName","createdAt","description","endsAt","id","placeId","startsAt","status","title","updatedAt"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"brandId":{"type":"integer","format":"int64","example":10},"brandName":{"type":"string","example":"진주문화재단"},"brandLogoUrl":{"type":"string","nullable":true,"example":"https://cdn.pingdom.com/brands/jinju.png"},"placeId":{"type":"integer","format":"int64","example":101},"title":{"type":"string","example":"진주 여름 팝업"},"description":{"type":"string","example":"남강변에서 진행하는 여름 체험형 팝업입니다."},"startsAt":{"type":"string","format":"date-time","example":"2026-08-01T00:00:00Z"},"endsAt":{"type":"string","format":"date-time","example":"2026-08-08T00:00:00Z"},"status":{"type":"string","example":"PUBLISHED","enum":["PUBLISHED"]},"createdAt":{"type":"string","format":"date-time","example":"2026-07-20T00:00:00Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-07-21T00:00:00Z"}},"description":"진행 중인 공개 팝업 캠페인 응답"},"PlaceListItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"category":{"type":"string"},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"primaryInformationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"informationVerificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"informationVerifiedAt":{"type":"string","format":"date-time","nullable":true},"informationEvidenceUpdatedAt":{"type":"string","format":"date-time","nullable":true},"verifiedEvidenceCount":{"type":"integer","description":"검증 완료된 근거 수","format":"int32","example":3},"lastVerifiedAt":{"type":"string","description":"가장 최근 검증이 완료된 시각","format":"date-time","nullable":true},"lastVerifiedSourceType":{"type":"string","description":"가장 최근 검증 근거의 출처","nullable":true,"enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"distanceMeters":{"type":"integer","format":"int64"}}},"PlaceListResponse":{"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/PlaceListItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}},"description":"장소 목록 조회 응답"},"OfferPageResponse":{"type":"object","properties":{"offers":{"type":"array","items":{"$ref":"#/components/schemas/OfferResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PlaceVisitDecisionEventResponse":{"required":["description","endAt","eventId","eventType","scheduleStatus","startAt","title"],"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]}},"description":"방문 결정 화면에 노출하는 진행 중 장소 이벤트"},"PlaceVisitDecisionMerchantInformationResponse":{"required":["contactPhone","description","reservationUrl","updatedAt","websiteUrl"],"type":"object","properties":{"description":{"type":"string","nullable":true},"contactPhone":{"type":"string","nullable":true},"websiteUrl":{"type":"string","nullable":true},"reservationUrl":{"type":"string","nullable":true},"updatedAt":{"type":"string","format":"date-time"}},"description":"관광객에게 공개하는 Merchant 장소 안내 정보","nullable":true},"PlaceVisitDecisionResponse":{"required":["availableOffers","checkedAt","merchantInformation","ongoingEvents","place","reservableAvailabilities"],"type":"object","properties":{"place":{"$ref":"#/components/schemas/PlaceDetailResponse"},"merchantInformation":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/PlaceVisitDecisionMerchantInformationResponse"}]},"ongoingEvents":{"type":"array","items":{"$ref":"#/components/schemas/PlaceVisitDecisionEventResponse"}},"reservableAvailabilities":{"type":"array","items":{"$ref":"#/components/schemas/AvailabilityResponse"}},"availableOffers":{"$ref":"#/components/schemas/OfferPageResponse"},"checkedAt":{"type":"string","description":"응답의 상태성 데이터를 조회한 시각","format":"date-time"}},"description":"관광객 장소 상세 방문 결정 화면 응답"},"PagePlaceReviewResponse":{"type":"object","properties":{"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"pageable":{"$ref":"#/components/schemas/PageableObject"},"numberOfElements":{"type":"integer","format":"int32"},"first":{"type":"boolean"},"last":{"type":"boolean"},"empty":{"type":"boolean"}}},"PageableObject":{"type":"object","properties":{"offset":{"type":"integer","format":"int64"},"sort":{"type":"array","items":{"$ref":"#/components/schemas/SortObject"}},"paged":{"type":"boolean"},"pageNumber":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"unpaged":{"type":"boolean"}}},"SortObject":{"type":"object","properties":{"direction":{"type":"string"},"nullHandling":{"type":"string"},"ascending":{"type":"boolean"},"property":{"type":"string"},"ignoreCase":{"type":"boolean"}}},"PlaceOperatingNoticeListResponse":{"required":["checkedAt","currentlyOperating","notices","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"currentlyOperating":{"type":"boolean"},"checkedAt":{"type":"string","description":"현재 영업 여부와 공지 노출 상태를 평가한 UTC 기준 시각","format":"date-time"},"notices":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingNoticeResponse"}}},"description":"상점 운영 상태 공지 목록 응답"},"MenuConvertedPriceResponse":{"type":"object","properties":{"amount":{"type":"number","description":"환산 금액. 실제 결제 기준은 메뉴의 원래 금액과 통화입니다.","example":6.43},"currency":{"type":"string","description":"환산 통화","example":"USD","enum":["KRW","USD","JPY","CNY","EUR"]},"rateDate":{"type":"string","description":"환산에 사용한 환율 기준 일자","format":"date","example":"2026-09-10"}},"description":"사용자 표시 통화로 환산한 메뉴 참고 가격","nullable":true},"PlaceMenuPublicResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string","description":"메뉴 설명이 없으면 null","nullable":true},"priceAmount":{"type":"integer","description":"원래 메뉴 가격. 환산 가격과 무관하게 항상 유지됩니다.","format":"int64","example":9000},"currency":{"type":"string","description":"원래 메뉴 가격의 통화. 실제 결제 기준 통화입니다.","example":"KRW","enum":["KRW","USD","JPY","CNY","EUR"]},"imageUrl":{"type":"string","description":"대표 이미지가 없으면 null","nullable":true},"status":{"type":"string","enum":["AVAILABLE","SOLD_OUT","HIDDEN","INACTIVE"]},"displayOrder":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"convertedPrice":{"$ref":"#/components/schemas/MenuConvertedPriceResponse"}},"description":"관광객용 장소 메뉴 응답"},"TouristPlaceCardResponse":{"required":["address","category","currentlyOperating","currentlyOperatingCheckedAt","englishName","geocodingSource","id","imageUrl","informationEvidenceUpdatedAt","informationVerificationStatus","informationVerifiedAt","lastVerifiedAt","lastVerifiedSourceType","latitude","longitude","name","operatingStatus","primaryInformationSource","roadAddress","touristCategories","touristSummary","verifiedEvidenceCount"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"currentlyOperating":{"type":"boolean"},"currentlyOperatingCheckedAt":{"type":"string","description":"현재 영업 여부를 평가한 UTC 기준 시각. 영업 일정은 Asia/Seoul 기준으로 해석합니다.","format":"date-time"},"category":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"primaryInformationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"informationVerificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"informationVerifiedAt":{"type":"string","format":"date-time","nullable":true},"informationEvidenceUpdatedAt":{"type":"string","format":"date-time","nullable":true},"verifiedEvidenceCount":{"type":"integer","description":"검증 완료된 근거 수","format":"int32","example":3},"lastVerifiedAt":{"type":"string","description":"가장 최근 검증이 완료된 시각","format":"date-time","nullable":true},"lastVerifiedSourceType":{"type":"string","description":"가장 최근 검증 근거의 출처","nullable":true,"enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"latitude":{"maximum":90.0,"minimum":-90.0,"type":"number","format":"double"},"longitude":{"maximum":180.0,"minimum":-180.0,"type":"number","format":"double"}},"description":"관광객용 장소 카드 조회 응답"},"ReservationQuoteResponse":{"required":["confirmation","confirmationToken","remainingCapacity"],"type":"object","properties":{"confirmationToken":{"type":"string","description":"본인 예약 생성에만 사용 가능한 불투명 토큰. 같은 토큰은 하나의 예약 의도에만 사용"},"confirmation":{"$ref":"#/components/schemas/ReservationConfirmation"},"remainingCapacity":{"type":"integer","format":"int32"}}},"PlaceMediaResponse":{"required":["media","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"media":{"type":"array","items":{"$ref":"#/components/schemas/PlaceMediaItem"}}},"description":"장소 미디어 목록 응답"},"Item":{"type":"object","properties":{"rank":{"type":"integer","format":"int32"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"category":{"type":"string"},"imageUrl":{"type":"string"},"address":{"type":"string"},"bookmarkAdds":{"type":"integer","format":"int64"},"bookmarkRemoves":{"type":"integer","format":"int64"},"netBookmarkGrowth":{"type":"integer","format":"int64"},"bookmarkCount":{"type":"integer","format":"int64"},"bookmarked":{"type":"boolean"}}},"PlaceTrendResponse":{"type":"object","properties":{"scope":{"type":"string"},"period":{"type":"string","enum":["WEEK"]},"periodStart":{"type":"string","format":"date-time"},"periodEnd":{"type":"string","format":"date-time"},"generatedAt":{"type":"string","format":"date-time"},"places":{"type":"array","items":{"$ref":"#/components/schemas/Item"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PlaceGrowthSnapshot":{"type":"object","properties":{"photoCount":{"type":"integer","format":"int64"},"level":{"type":"integer","format":"int32"},"currentLevelMinPhotoCount":{"type":"integer","format":"int64"},"nextLevelMinPhotoCount":{"type":"integer","format":"int64"},"progressPercent":{"type":"integer","format":"int32"}}},"PlaceRecommendationItem":{"type":"object","properties":{"id":{"type":"integer","description":"장소 ID","format":"int64","example":5},"name":{"type":"string","description":"장소명","example":"진주성"},"address":{"type":"string","description":"장소 주소","example":"경상남도 진주시 남강로 626"},"roadAddress":{"type":"string","description":"도로명 주소","nullable":true},"jibunAddress":{"type":"string","description":"지번 주소","nullable":true},"postalCode":{"type":"string","description":"우편번호","nullable":true},"geocodingSource":{"type":"string","description":"주소 및 좌표 생성 출처","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","description":"장소 운영 상태","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","description":"운영 상태 최신 확인 시각","format":"date-time","nullable":true},"currentlyOperating":{"type":"boolean","description":"현재 영업 여부. 영업시간 미등록 시 null","nullable":true},"currentlyOperatingCheckedAt":{"type":"string","description":"현재 영업 여부를 평가한 UTC 기준 시각. 영업 일정은 Asia/Seoul 기준으로 해석합니다.","format":"date-time","nullable":true},"latitude":{"type":"number","description":"장소 위도","format":"double","example":35.1894},"longitude":{"type":"number","description":"장소 경도","format":"double","example":128.0789},"distanceMeters":{"type":"integer","description":"현재 위치와의 거리(미터)","format":"int64","example":215},"reason":{"type":"string","description":"추천 사유","example":"저장한 장소와 가까운 추천 장소입니다."},"reasonCode":{"type":"string","description":"추천 사유 코드","example":"PERSONAL_SIGNAL","enum":["BENEFIT_AND_RESERVABLE","ACTIVE_BENEFIT","RESERVABLE","CONTEXT_MATCH","PERSONAL_SIGNAL","FRESH_CONTENT","HIGH_ENGAGEMENT","HIGH_CONVERSION","EXPLORATION","QUALITY_SIGNAL","NEARBY"]},"hasActiveBenefit":{"type":"boolean","description":"현재 발급 가능한 관광 혜택 존재 여부"},"reservable":{"type":"boolean","description":"현재 예약 가능한 시간 존재 여부"},"boosted":{"type":"boolean","description":"Verified Boost가 적용된 추천 여부"},"placeGrowth":{"$ref":"#/components/schemas/PlaceGrowthSnapshot"}},"description":"장소 추천 항목"},"PlaceRecommendationResponse":{"type":"object","properties":{"places":{"type":"array","description":"추천 장소 목록","items":{"$ref":"#/components/schemas/PlaceRecommendationItem"}},"recommendationVersion":{"type":"string","description":"추천 알고리즘 버전","example":"place-rec-v1"},"recommendationRequestId":{"type":"string","description":"추천 요청 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"limit":{"type":"integer","description":"요청 제한 수","format":"int32","example":10},"requestedRadiusKm":{"type":"number","description":"요청 반경(km)","format":"double","example":5.0},"appliedRadiusKm":{"type":"number","description":"실제 적용 반경(km)","format":"double","example":10.0},"recommendedCount":{"type":"integer","description":"추천 결과 수","format":"int32","example":4},"appliedTravelPurposes":{"uniqueItems":true,"type":"array","description":"추천에 적용된 K-컬처 및 여행 관심사","items":{"type":"string","description":"추천에 적용된 K-컬처 및 여행 관심사","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"appliedActivityIntent":{"type":"string","description":"추천에 적용된 현재 행동 의도","nullable":true,"example":"CAFE","enum":["EXPLORE","EAT","CAFE","SHOP","ATTEND_EVENT","NIGHTLIFE"]},"limitReasons":{"type":"array","description":"추천 결과에 영향을 준 제한 사유 코드","items":{"type":"string","description":"추천 결과에 영향을 준 제한 사유 코드","enum":["REQUEST_LIMIT_CLAMPED","RADIUS_EXPANDED","OPERATING_STATUS_PRIORITY","INTERACTED_PLACE_EXCLUDED","FALLBACK_CANDIDATE_POOL"]}}},"description":"장소 추천 조회 응답"},"PlaceRecommendationExplanationItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":1},"placeName":{"type":"string","description":"장소명","example":"진주성"},"ranking":{"type":"integer","description":"노출 순위","format":"int32","example":1},"source":{"type":"string","description":"후보 소스","example":"PERSONAL","enum":["PERSONAL","POPULAR","FRESH","GEO","FALLBACK"]},"distanceMeters":{"type":"integer","description":"거리(m)","format":"int64","example":128},"geoScore":{"type":"number","description":"geo score","format":"double","example":0.91},"personalScore":{"type":"number","description":"personal score","format":"double","example":0.42},"qualityScore":{"type":"number","description":"quality score","format":"double","example":0.37},"engagementScore":{"type":"number","description":"engagement score","format":"double","example":0.25},"conversionScore":{"type":"number","description":"conversion score","format":"double","example":0.14},"explorationScore":{"type":"number","description":"exploration score","format":"double","example":0.08},"freshnessScore":{"type":"number","description":"freshness score","format":"double","example":0.19},"trustScore":{"type":"number","description":"검증 제보자 신뢰도 기반 score","format":"double","example":0.82},"contextScore":{"type":"number","description":"K-컬처 관심사와 현재 여행 맥락 기반 score","format":"double","example":0.25},"benefitScore":{"type":"number","description":"현재 이용 가능한 혜택 기반 boost","format":"double","example":0.05},"availabilityScore":{"type":"number","description":"예약 가능 시간 기반 boost","format":"double","example":0.05},"boostScore":{"type":"number","description":"Verified Boost 집행 기반 score","format":"double","example":0.08},"finalScore":{"type":"number","description":"최종 score","format":"double","example":0.74}},"description":"추천 설명 항목"},"PlaceRecommendationExplanationResponse":{"type":"object","properties":{"requestId":{"type":"string","description":"추천 요청 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"items":{"type":"array","description":"추천 설명 항목","items":{"$ref":"#/components/schemas/PlaceRecommendationExplanationItem"}}},"description":"추천 설명 조회 응답"},"NearbyReservablePlaceItem":{"required":["address","availabilityId","availableEndsAt","availableStartsAt","category","distanceMeters","imageUrl","latitude","longitude","name","placeId","remainingCapacity"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64","example":70069},"name":{"type":"string","example":"이월드"},"category":{"type":"string","nullable":true,"example":"테마파크"},"latitude":{"type":"number","format":"double","example":35.8532},"longitude":{"type":"number","format":"double","example":128.5638},"address":{"type":"string","nullable":true,"example":"대구광역시 달서구 두류공원로 200"},"imageUrl":{"type":"string","nullable":true},"distanceMeters":{"type":"integer","format":"int64","example":430},"availabilityId":{"type":"integer","format":"int64","example":77},"availableStartsAt":{"type":"string","format":"date-time"},"availableEndsAt":{"type":"string","format":"date-time"},"remainingCapacity":{"type":"integer","format":"int32","example":42}},"description":"현재 위치 주변 예약 가능 장소 요약"},"NearbyReservablePlaceResponse":{"required":["hasNext","limit","page","places","queriedAt","totalElements","totalPages"],"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/NearbyReservablePlaceItem"}},"page":{"type":"integer","format":"int32","example":1},"limit":{"type":"integer","format":"int32","example":20},"totalElements":{"type":"integer","format":"int64","example":42},"totalPages":{"type":"integer","format":"int32","example":3},"hasNext":{"type":"boolean","example":true},"queriedAt":{"type":"string","format":"date-time"}},"description":"현재 위치 주변 예약 가능 장소 페이지 응답"},"MapClusterItem":{"required":["clusterId","latitude","longitude","placeCount"],"type":"object","properties":{"clusterId":{"type":"string"},"latitude":{"maximum":90.0,"minimum":-90.0,"type":"number","format":"double"},"longitude":{"maximum":180.0,"minimum":-180.0,"type":"number","format":"double"},"placeCount":{"type":"integer","format":"int64"}}},"MapMarkerItem":{"required":["category","imageUrl","latitude","longitude","name","photoCount","placeId"],"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"name":{"type":"string"},"category":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"latitude":{"maximum":90.0,"minimum":-90.0,"type":"number","format":"double"},"longitude":{"maximum":180.0,"minimum":-180.0,"type":"number","format":"double"},"photoCount":{"type":"integer","format":"int64"}}},"MapViewportResponse":{"required":["clusters","markers","mode","truncated","zoom"],"type":"object","properties":{"mode":{"type":"string","description":"zoom에 따른 응답 표현 방식","enum":["MARKERS","CLUSTERS"]},"zoom":{"maximum":20,"minimum":0,"type":"integer","description":"요청한 지도 zoom 단계","format":"int32"},"clusters":{"type":"array","items":{"$ref":"#/components/schemas/MapClusterItem"}},"markers":{"type":"array","items":{"$ref":"#/components/schemas/MapMarkerItem"}},"truncated":{"type":"boolean","description":"최대 500개 결과로 잘렸는지 여부"}}},"PlaceLocalHotResponse":{"type":"object","properties":{"region":{"$ref":"#/components/schemas/Region"},"places":{"type":"array","items":{"$ref":"#/components/schemas/Item"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"Region":{"type":"object","properties":{"regionCode":{"type":"string"},"sido":{"type":"string"},"sigungu":{"type":"string"},"regionName":{"type":"string"}}},"PlaceInformationReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"장소 정보 신고 페이지 응답"},"PlaceAutocompleteItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"category":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"distanceMeters":{"type":"number","format":"double"}}},"PlaceAutocompleteResponse":{"type":"object","properties":{"keyword":{"type":"string"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int32"},"places":{"type":"array","items":{"$ref":"#/components/schemas/PlaceAutocompleteItem"}}}},"PaymentPageResponse":{"required":["hasNext","limit","page","payments","totalElements","totalPages"],"type":"object","properties":{"payments":{"type":"array","items":{"$ref":"#/components/schemas/PaymentResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관광객 결제 목록 페이지 응답"},"VerifiedBoostSelectionPageResponse":{"type":"object","properties":{"selections":{"type":"array","items":{"$ref":"#/components/schemas/VerifiedBoostSelectionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"MerchantVerifiedBoostProductPageResponse":{"type":"object","properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/MerchantVerifiedBoostProductResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"MerchantVerifiedBoostProductResponse":{"type":"object","properties":{"productId":{"type":"integer","format":"int64","example":1},"name":{"type":"string"},"description":{"type":"string"},"priceAmount":{"type":"integer","format":"int64","example":30000},"currency":{"type":"string","example":"KRW"},"durationDays":{"type":"integer","format":"int32","example":7},"status":{"type":"string","enum":["DRAFT","ACTIVE","INACTIVE"]}}},"VerifiedBoostExecutionPageResponse":{"type":"object","properties":{"executions":{"type":"array","items":{"$ref":"#/components/schemas/VerifiedBoostExecutionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"MerchantOwnerPlaceDetailResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"englishName":{"type":"string"},"category":{"type":"string"},"address":{"type":"string"},"roadAddress":{"type":"string"},"jibunAddress":{"type":"string"},"postalCode":{"type":"string"},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"imageUrl":{"type":"string"},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time"},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"description":{"type":"string"},"touristSummary":{"type":"string"},"touristCategories":{"uniqueItems":true,"type":"array","items":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"primaryInformationSource":{"type":"string","enum":["LEGACY","KAKAO","MERCHANT_OWNER","ADMIN","USER_REPORT","SYSTEM"]},"informationVerificationStatus":{"type":"string","enum":["UNVERIFIED","SOURCE_CONFIRMED","OWNER_SUBMITTED","ADMIN_VERIFIED","REJECTED","DISPUTED","EXPIRED"]},"informationVerifiedAt":{"type":"string","format":"date-time"},"informationEvidenceUpdatedAt":{"type":"string","format":"date-time"}},"description":"Merchant Owner 장소 상세 응답"},"MerchantPlaceReviewDeletionRequestStatusResponse":{"type":"object","properties":{"deletionRequestId":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"requestedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"reviewNote":{"type":"string"}},"description":"상점주 리뷰 삭제 신청 최신 상태","nullable":true},"MerchantPlaceReviewPageResponse":{"type":"object","properties":{"reviews":{"type":"array","items":{"$ref":"#/components/schemas/MerchantPlaceReviewResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"상점주 관리 장소 리뷰 목록 페이지"},"MerchantPlaceReviewResponse":{"type":"object","properties":{"reviewId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"userId":{"type":"integer","format":"int64"},"recommendReason":{"type":"string"},"recommendReasons":{"type":"array","items":{"type":"string","enum":["FRIENDLY","EASY_TO_FIND","GOOD_FOOD","MULTILINGUAL_SUPPORT","PARKING","PHOTO_SPOT","CLEAN"]}},"content":{"type":"string"},"imageUrls":{"type":"array","items":{"type":"string"}},"reviewMedia":{"type":"array","items":{"$ref":"#/components/schemas/PlaceReviewMediaResponse"}},"createdAt":{"type":"string","format":"date-time"},"visibilityStatus":{"type":"string","enum":["VISIBLE","HIDDEN","DELETED"]},"deletionRequest":{"$ref":"#/components/schemas/MerchantPlaceReviewDeletionRequestStatusResponse"}},"description":"상점주 관리 장소 리뷰"},"PlaceInformationReverificationListResponse":{"type":"object","properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/PlaceInformationReverificationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"MerchantPerformanceResponse":{"type":"object","properties":{"placeCount":{"type":"integer","description":"소유 장소 수","format":"int64","example":3},"exposureCount":{"type":"integer","description":"추천 카드 노출 수","format":"int64","example":1200},"clickCount":{"type":"integer","description":"추천 카드 클릭 수","format":"int64","example":240},"bookmarkCount":{"type":"integer","description":"장소 북마크 수","format":"int64","example":85},"reservationCount":{"type":"integer","description":"전체 예약 수","format":"int64","example":42},"confirmedReservationCount":{"type":"integer","description":"확정 예약 수","format":"int64","example":36},"clickThroughRate":{"type":"number","description":"노출 대비 클릭률(%)","format":"double","example":20.0},"reservationConversionRate":{"type":"number","description":"클릭 대비 예약 전환율(%)","format":"double","example":17.5}},"description":"Merchant 소유 장소의 탐색·예약 전환 성과 요약"},"SettlementLedgerPageResponse":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/SettlementLedgerResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"SettlementLedgerResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"paymentTransactionId":{"type":"integer","format":"int64"},"entryType":{"type":"string","enum":["PAYMENT","REFUND"]},"grossAmountMinor":{"type":"integer","format":"int64"},"feeAmountMinor":{"type":"integer","format":"int64"},"netAmountMinor":{"type":"integer","format":"int64"},"currency":{"type":"string"},"status":{"type":"string","enum":["PENDING","SETTLED","REVERSED"]},"createdAt":{"type":"string","format":"date-time"},"settledAt":{"type":"string","format":"date-time"}}},"PopupCampaignPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PopupCampaignResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"BrandPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BrandResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"LocationCheckInPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LocationCheckInResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PlaceEventListItem":{"required":["endAt","eventType","id","placeId","placeName","scheduleStatus","startAt","title"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":101},"placeName":{"type":"string","example":"진주성"},"title":{"type":"string","example":"진주 여름 빛 축제"},"eventType":{"type":"string","example":"EXHIBITION","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time","example":"2026-08-01T00:00:00Z"},"endAt":{"type":"string","format":"date-time","example":"2026-08-08T00:00:00Z"},"scheduleStatus":{"type":"string","example":"UPCOMING","enum":["UPCOMING","ONGOING"]}},"description":"공개 기간형 이벤트 목록 항목"},"PlaceEventListResponse":{"required":["events","hasNext","limit","page","totalCount","totalPages"],"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/PlaceEventListItem"}},"page":{"type":"integer","format":"int32","example":1},"limit":{"type":"integer","format":"int32","example":20},"totalCount":{"type":"integer","format":"int64","example":42},"totalPages":{"type":"integer","format":"int64","example":3},"hasNext":{"type":"boolean","example":true}},"description":"공개 기간형 이벤트 목록 응답"},"PlaceEventDetailResponse":{"required":["description","endAt","eventType","id","placeAddress","placeId","placeName","scheduleStatus","startAt","title"],"type":"object","properties":{"id":{"type":"integer","format":"int64","example":1},"placeId":{"type":"integer","format":"int64","example":101},"placeName":{"type":"string","example":"진주성"},"placeAddress":{"type":"string","example":"경상남도 진주시 남강로 626"},"title":{"type":"string","example":"진주 여름 빛 축제"},"description":{"type":"string","nullable":true,"example":"남강 야간 전시와 공연"},"eventType":{"type":"string","example":"EXHIBITION","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"startAt":{"type":"string","format":"date-time","example":"2026-08-01T00:00:00Z"},"endAt":{"type":"string","format":"date-time","example":"2026-08-08T00:00:00Z"},"scheduleStatus":{"type":"string","example":"UPCOMING","enum":["UPCOMING","ONGOING"]}},"description":"공개 기간형 이벤트 상세 응답"},"CouponPageResponse":{"required":["coupons","hasNext","limit","page","totalElements","totalPages"],"type":"object","properties":{"coupons":{"type":"array","items":{"$ref":"#/components/schemas/CouponResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"Category":{"type":"object","properties":{"categoryId":{"type":"string","description":"카테고리 식별자","example":"TRAVEL"},"categoryName":{"type":"string","description":"카테고리 표시 이름","example":"여행"}},"description":"게시글 카테고리 표시 정보"},"CommunityPostListResponse":{"type":"object","properties":{"posts":{"type":"array","description":"게시글 목록","items":{"$ref":"#/components/schemas/CommunityPostSummary"}},"page":{"type":"integer","description":"현재 페이지","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 게시글 수","format":"int64","example":42},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":3},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":true}},"description":"카테고리별 커뮤니티 게시글 목록 조회 응답"},"CommunityPostSummary":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":1},"title":{"type":"string","description":"게시글 제목","example":"대소고 다녀왔어요"},"contentPreview":{"type":"string","description":"본문 앞 150자"},"imageUrl":{"type":"string","description":"첫 게시글 사진 URL. 사진 없으면 null"},"imageCount":{"type":"integer","description":"게시글 전체 사진 수","format":"int64"},"countryCode":{"type":"string","description":"ISO alpha-2 국가 코드. 미설정은 null"},"region":{"type":"string","description":"작성자가 지정한 표시 지역"},"createdAt":{"type":"string","format":"date-time"},"viewCount":{"type":"integer","description":"정상 상세 조회 횟수","format":"int64"},"likeCount":{"type":"integer","format":"int64"},"commentCount":{"type":"integer","description":"숨김 댓글·숨김 부모의 답글을 제외한 댓글 수","format":"int64"},"category":{"$ref":"#/components/schemas/Category"}},"description":"게시글 목록 항목"},"Author":{"type":"object","properties":{"authorId":{"type":"integer","description":"게시글 작성자 ID","format":"int64"},"authorName":{"type":"string","description":"작성자 표시 이름. 탈퇴 또는 조회 불가 시 대체 이름"},"profileImageUrl":{"type":"string","description":"프로필 이미지 URL. 없거나 탈퇴한 경우 null"}},"description":"게시글 작성자 표시 정보"},"CommunityPostDetailResponse":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":1},"title":{"type":"string","description":"게시글 제목","example":"대소고 다녀왔어요"},"content":{"type":"string","description":"게시글 본문","example":"즐거운 경험이었습니다."},"places":{"type":"array","description":"연결 장소 목록","items":{"$ref":"#/components/schemas/Place"}},"author":{"$ref":"#/components/schemas/Author"},"category":{"$ref":"#/components/schemas/Category"},"createdAt":{"type":"string","description":"게시글 작성 시각","format":"date-time"},"images":{"type":"array","description":"표시 순서대로 정렬된 게시글 사진. position은 0부터 시작","items":{"$ref":"#/components/schemas/CommunityPostImageItem"}},"countryCode":{"type":"string","description":"ISO alpha-2 국가 코드. 기존 미설정 글은 null"},"region":{"type":"string","description":"작성자가 지정한 표시 지역. 미설정은 null"},"viewCount":{"type":"integer","description":"정상 상세 요청 횟수. 사용자별 고유 조회가 아님","format":"int64"}},"description":"커뮤니티 게시글 상세 조회 응답"},"CommunityPostImageItem":{"type":"object","properties":{"imageId":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"position":{"type":"integer","format":"int32"}},"description":"표시 순서대로 정렬된 게시글 사진. position은 0부터 시작"},"Place":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":1},"placeName":{"type":"string","description":"현재 장소 이름. 삭제된 장소는 삭제 안내 문구","example":"대소고"},"deleted":{"type":"boolean","description":"삭제된 장소 여부","example":false},"imageUrl":{"type":"string","description":"장소 대표 이미지. 미설정 또는 삭제 시 null"},"category":{"type":"string","description":"기존 장소 분류. 미설정 또는 삭제 시 null"},"regionCode":{"type":"string","description":"기존 장소 지역 코드"},"address":{"type":"string","description":"장소 표시 주소"},"region":{"type":"string","description":"기존 지역 사전의 표시 이름. 미해석 또는 삭제 시 null"}},"description":"게시글에 연결된 장소"},"CommunityCommentSummary":{"type":"object","properties":{"commentId":{"type":"integer","description":"댓글 ID","format":"int64","example":1},"content":{"type":"string","description":"댓글 내용","example":"저도 가보고 싶네요!"},"authorId":{"type":"integer","description":"작성자 ID","format":"int64","example":7},"authorName":{"type":"string","description":"작성자 표시 이름","example":"pingdom"},"createdAt":{"type":"string","description":"댓글 작성 시각","format":"date-time"},"parentCommentId":{"type":"integer","description":"최상위 댓글이면 null, 대댓글이면 부모 ID","format":"int64"},"likeCount":{"type":"integer","format":"int64"},"liked":{"type":"boolean","description":"현재 인증 사용자 좋아요 여부"}},"description":"댓글 목록 항목"},"CommunityPostCommentListResponse":{"type":"object","properties":{"comments":{"type":"array","description":"댓글 목록","items":{"$ref":"#/components/schemas/CommunityCommentSummary"}},"page":{"type":"integer","description":"현재 페이지","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 댓글 수","format":"int64","example":42},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":3},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":true}},"description":"커뮤니티 게시글 댓글 목록 조회 응답"},"CommunityCategoryItem":{"type":"object","properties":{"categoryId":{"type":"string","description":"저장과 요청에 사용할 카테고리 식별자","example":"PLACE"},"categoryName":{"type":"string","description":"화면 표시용 카테고리 이름","example":"장소"}},"description":"커뮤니티 카테고리 목록 항목"},"CommunityPostCategoryListResponse":{"type":"object","properties":{"categories":{"type":"array","description":"작성 및 조회에 사용할 활성 카테고리 목록","items":{"$ref":"#/components/schemas/CommunityCategoryItem"}}},"description":"커뮤니티 게시글 카테고리 목록 응답"},"VisitorVerificationReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/VisitorVerificationReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"VisitorVerificationReportCorrectionPageResponse":{"type":"object","properties":{"corrections":{"type":"array","items":{"$ref":"#/components/schemas/VisitorVerificationReportCorrectionResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"VerifiedBoostProductPageResponse":{"type":"object","properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/VerifiedBoostProductResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminUserSanctionHistoryItem":{"type":"object","properties":{"historyId":{"type":"integer","description":"제재 이력 ID","format":"int64","example":1},"targetUserId":{"type":"integer","description":"대상 사용자 ID","format":"int64","example":7},"targetUsername":{"type":"string","description":"대상 사용자명","example":"blockedUser01"},"banType":{"type":"string","description":"제재 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"action":{"type":"string","description":"처리 상태","example":"APPLIED","enum":["APPLIED","RELEASED","EXPIRED"]},"reason":{"type":"string","description":"처리 사유","example":"반복적인 신고 누적"},"startedAt":{"type":"string","description":"제재 시작 시각","format":"date-time"},"endedAt":{"type":"string","description":"제재 종료 시각","format":"date-time"},"adminUserId":{"type":"integer","description":"처리 관리자 ID","format":"int64","example":1},"adminUsername":{"type":"string","description":"처리 관리자명","example":"admin"},"processedAt":{"type":"string","description":"처리 시각","format":"date-time"}},"description":"관리자 사용자 제재 이력 아이템"},"AdminUserSanctionHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/AdminUserSanctionHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 사용자 제재 이력 목록 응답"},"AdminUserSanctionStatusResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"banned":{"type":"boolean","description":"현재 제재 여부","example":true},"banType":{"type":"string","description":"제재 유형","example":"TEMPORARY","enum":["PERMANENT","TEMPORARY"]},"bannedAt":{"type":"string","description":"제재 시작 시각","format":"date-time"},"banExpiresAt":{"type":"string","description":"제재 종료 시각","format":"date-time"},"banReason":{"type":"string","description":"제재 사유","example":"반복적인 신고 누적"}},"description":"관리자 사용자 제재 상태 조회 응답"},"AdminRoleAssignmentTargetItem":{"type":"object","properties":{"userId":{"type":"integer","description":"역할 API에 전달할 사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"admin_operator"}},"description":"관리자 역할 부여 대상 사용자"},"AdminRoleAssignmentTargetSearchResponse":{"type":"object","properties":{"users":{"type":"array","description":"현재 페이지의 역할 부여 대상 사용자","items":{"$ref":"#/components/schemas/AdminRoleAssignmentTargetItem"}},"page":{"type":"integer","description":"현재 페이지 번호(1부터 시작)","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"검색 조건에 맞는 전체 사용자 수","format":"int64","example":12},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false}},"description":"관리자 역할 부여 대상 사용자 검색 응답"},"AdminBannedUserCounts":{"type":"object","properties":{"total":{"type":"integer","description":"현재 밴 중인 전체 사용자 수","format":"int64","example":12},"permanent":{"type":"integer","description":"현재 영구 밴 중인 사용자 수","format":"int64","example":7},"temporary":{"type":"integer","description":"현재 기간 밴 중인 사용자 수","format":"int64","example":5}},"description":"현재 밴 사용자 필터별 카운트"},"AdminBannedUserItem":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"banned":{"type":"boolean","description":"밴 처리 여부","example":true},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"bannedAt":{"type":"string","description":"밴 처리 시각","format":"date-time"},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"}},"description":"밴 유저 목록 아이템"},"AdminBannedUserResponse":{"type":"object","properties":{"users":{"type":"array","description":"현재 페이지의 밴 사용자 목록","items":{"$ref":"#/components/schemas/AdminBannedUserItem"}},"page":{"type":"integer","description":"현재 페이지 번호(1부터 시작)","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"조회 조건에 맞는 현재 밴 사용자 전체 수","format":"int64","example":12},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int64","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false},"counts":{"$ref":"#/components/schemas/AdminBannedUserCounts"}},"description":"밴 유저 목록 조회 응답"},"AdminBannedUserDetailResponse":{"type":"object","properties":{"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":7},"username":{"type":"string","description":"사용자명","example":"blockedUser01"},"email":{"type":"string","description":"이메일","example":"blockedUser01@example.com"},"birthYear":{"type":"integer","description":"출생연도","format":"int32","example":1998},"language":{"type":"string","description":"언어","example":"ko"},"country":{"type":"string","description":"국가","example":"KR"},"role":{"type":"string","description":"권한","example":"USER"},"banned":{"type":"boolean","description":"밴 여부","example":true},"bannedAt":{"type":"string","description":"밴 시각","format":"date-time"},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"banExpiresAt":{"type":"string","description":"기간 밴 종료 시각","format":"date-time"},"banReason":{"type":"string","description":"밴 사유","example":"반복적인 신고 누적"},"createdAt":{"type":"string","description":"가입 시각","format":"date-time"}},"description":"밴 유저 상세 조회 응답"},"AdminTrustScoreEvidenceResponse":{"type":"object","properties":{"submittedCount":{"type":"integer","description":"신고 제출 수","format":"int64","example":12},"acceptedCount":{"type":"integer","description":"승인된 신고 수","format":"int64","example":8},"declinedCount":{"type":"integer","description":"반려된 신고 수","format":"int64","example":4},"falseReportCount":{"type":"integer","description":"허위 신고 수","format":"int64","example":3},"acceptanceRate":{"type":"number","description":"승인률","format":"double","example":66.67},"baseScore":{"type":"integer","description":"기본 점수","format":"int32","example":100},"acceptedScoreBonus":{"type":"integer","description":"승인 신고 가산점 합계","format":"int64","example":40},"falseReportScorePenalty":{"type":"integer","description":"허위 신고 감점 합계","format":"int64","example":60}},"description":"신뢰 점수 산정 근거"},"AdminTrustScoreResponse":{"type":"object","properties":{"reporterUserId":{"type":"integer","description":"신고자 사용자 ID","format":"int64","example":7},"reporterUsername":{"type":"string","description":"신고자 username","example":"pingdom_user"},"trustScore":{"type":"integer","description":"신뢰 점수","format":"int32","example":80},"trustGrade":{"type":"string","description":"신뢰 등급","example":"HIGH","enum":["HIGH","NORMAL","LOW"]},"restricted":{"type":"boolean","description":"현재 신고 제한 여부","example":false},"restrictedUntil":{"type":"string","description":"신고 제한 종료 시각","format":"date-time","nullable":true},"restrictionReason":{"type":"string","description":"신고 제한 사유","nullable":true,"example":"FALSE_REPORT_THRESHOLD_EXCEEDED"},"evidence":{"$ref":"#/components/schemas/AdminTrustScoreEvidenceResponse"}},"description":"신고자 신뢰 등급 및 점수 근거 응답"},"AdminTrustScoreChangeHistoryItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"beforeScore":{"type":"integer","format":"int32"},"afterScore":{"type":"integer","format":"int32"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}},"AdminTrustScoreChangeHistoryResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminTrustScoreChangeHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminTrustScoreInterventionRuleResponse":{"type":"object","properties":{"rules":{"type":"array","description":"개입 규칙 목록","items":{"$ref":"#/components/schemas/AdminTrustScoreInterventionRuleItem"}}}},"AdminTrustScoreAnomalyResponse":{"type":"object","properties":{"anomalies":{"type":"array","description":"이상치 목록","items":{"$ref":"#/components/schemas/AdminTrustScoreAnomalyItem"}},"page":{"type":"integer","description":"현재 페이지","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 개수","format":"int64","example":42},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":3}}},"ScoutProfilePageResponse":{"type":"object","properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/ScoutProfileResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 Scout 프로필 목록 응답"},"ScoutFieldReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/ScoutFieldReportResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminS3OrphanObjectReportResponse":{"type":"object","properties":{"prefix":{"type":"string"},"scanLimit":{"type":"integer","format":"int32"},"dryRun":{"type":"boolean"},"truncated":{"type":"boolean"},"dbKeyCount":{"type":"integer","format":"int64"},"s3ObjectCount":{"type":"integer","format":"int64"},"orphanObjectCount":{"type":"integer","format":"int64"},"orphanKeys":{"type":"array","items":{"type":"string"}}}},"AdminReservationPageResponse":{"type":"object","properties":{"reservations":{"type":"array","items":{"$ref":"#/components/schemas/AdminReservationResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"ReportedUsersItem":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"reporterUserId":{"type":"integer","format":"int64"},"reporterUsername":{"type":"string"},"reportedImageId":{"type":"integer","format":"int64"},"reportedUserId":{"type":"integer","format":"int64"},"reason":{"type":"string"}}},"ReportedUsersResponse":{"type":"object","properties":{"users":{"type":"array","items":{"$ref":"#/components/schemas/ReportedUsersItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminReportAppealItem":{"type":"object","properties":{"appealId":{"type":"integer","format":"int64"},"reportId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"appellantUserId":{"type":"integer","format":"int64"},"appellantUsername":{"type":"string"},"targetUserId":{"type":"integer","format":"int64"},"reason":{"type":"string"},"status":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED"]},"adminUserId":{"type":"integer","format":"int64"},"adminReason":{"type":"string"},"processedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"AdminReportAppealResponse":{"type":"object","properties":{"appeals":{"type":"array","items":{"$ref":"#/components/schemas/AdminReportAppealItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"PrivacyProcessingHistoryItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"subjectUserId":{"type":"integer","format":"int64"},"actorUserId":{"type":"integer","format":"int64"},"actorType":{"type":"string","enum":["USER","SYSTEM","ADMIN"]},"action":{"type":"string","enum":["EXPORT_REQUESTED","WITHDRAWAL_REQUESTED","ANONYMIZED","DELETED"]},"details":{"type":"string"},"requestId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"PrivacyProcessingHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/PrivacyProcessingHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"S3OrphanCandidate":{"type":"object","properties":{"key":{"type":"string"},"reason":{"type":"string"}}},"S3OrphanReport":{"type":"object","properties":{"reportId":{"type":"string"},"status":{"type":"string"},"errorMessage":{"type":"string"},"deleteCandidates":{"type":"array","items":{"$ref":"#/components/schemas/S3OrphanCandidate"}},"dbKeyCount":{"type":"integer","format":"int64"},"s3KeyCount":{"type":"integer","format":"int64"},"deleteCandidateCount":{"type":"integer","format":"int64"},"generatedAt":{"type":"string","format":"date-time"},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceItem":{"required":["level"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"category":{"type":"string","description":"일반 장소 카테고리. touristCategories와 별도 기준이며 미분류 장소는 null입니다.","nullable":true,"example":"OTHER","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"categoryName":{"type":"string","description":"화면 표시용 일반 장소 카테고리명. category가 없으면 미분류입니다.","example":"기타","enum":["음식점","음악","팝업","패션","뷰티","전시","카페","문화재","기타","미분류"]},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","description":"외국인 관광 관심사 분류. 일반 장소 category 필터와는 별도 기준입니다.","items":{"type":"string","description":"외국인 관광 관심사 분류. 일반 장소 category 필터와는 별도 기준입니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"level":{"minimum":0,"type":"integer","description":"장소 성장 레벨. 10 이상이면 관리자 지도에서 불꽃 마커로 표시할 수 있습니다.","format":"int32","example":5},"placeGrowth":{"$ref":"#/components/schemas/PlaceGrowthSnapshot"}}},"AdminMapPlaceResponse":{"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"minimum":1,"type":"integer","description":"전체 페이지 수. 조회 결과가 없어도 1을 반환합니다.","format":"int64","example":1},"hasNext":{"type":"boolean"}},"description":"관리자 장소 목록 조회 응답"},"AdminMapPlaceDetailResponse":{"required":["imageUrl","level"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"imageUrl":{"type":"string","description":"장소 목록·상세에서 공통으로 사용하는 canonical 대표 이미지 URL입니다. 대표 이미지가 없으면 null입니다.","nullable":true},"address":{"type":"string"},"roadAddress":{"type":"string","nullable":true},"jibunAddress":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"geocodingSource":{"type":"string","enum":["KAKAO","USER_PIN","ADMIN","LEGACY"]},"operatingStatus":{"type":"string","enum":["OPERATING","TEMPORARILY_CLOSED","PERMANENTLY_CLOSED"]},"operatingStatusCheckedAt":{"type":"string","format":"date-time","nullable":true},"discoveryStatus":{"type":"string","description":"탐색 노출 상태. VISIBLE은 공개 탐색·자동완성·북마크 목록·추천 후보에 노출되고, HIDDEN은 제외됩니다.","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"regularHours":{"type":"array","items":{"$ref":"#/components/schemas/PlaceRegularOperatingHourResponse"}},"operatingExceptions":{"type":"array","items":{"$ref":"#/components/schemas/PlaceOperatingExceptionResponse"}},"category":{"type":"string","description":"일반 장소 카테고리. touristCategories와 별도 기준이며 미분류 장소는 null입니다.","nullable":true,"example":"OTHER","enum":["RESTAURANT","MUSIC","POP_UP","FASHION","BEAUTY","EXHIBITION","CAFE","CULTURAL_HERITAGE","OTHER"]},"categoryName":{"type":"string","description":"화면 표시용 일반 장소 카테고리명. category가 없으면 미분류입니다.","example":"기타","enum":["음식점","음악","팝업","패션","뷰티","전시","카페","문화재","기타","미분류"]},"englishName":{"type":"string","nullable":true},"touristSummary":{"type":"string","nullable":true},"touristCategories":{"uniqueItems":true,"type":"array","description":"외국인 관광 관심사 분류. 일반 장소 category와는 별도 기준입니다.","items":{"type":"string","description":"외국인 관광 관심사 분류. 일반 장소 category와는 별도 기준입니다.","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"username":{"type":"string"},"sortParam":{"type":"string","enum":["LATEST","OLDEST","MOST_LIKED"]},"postCount":{"type":"integer","format":"int32"},"level":{"minimum":0,"type":"integer","description":"장소 성장 레벨. 10 이상이면 관리자 지도에서 불꽃 마커로 표시할 수 있습니다.","format":"int32","example":5},"placeGrowth":{"$ref":"#/components/schemas/AdminMapPlaceGrowthResponse"},"posts":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceImageItem"}}}},"AdminMapPlaceGrowthResponse":{"type":"object","properties":{"photoCount":{"type":"integer","description":"장소 성장에 반영된 노출 게시글 사진 수","format":"int64","example":10},"hiddenPhotoCount":{"type":"integer","description":"장소 성장에 반영되지 않는 숨김 게시글 사진 수","format":"int64","example":1},"level":{"type":"integer","format":"int32"},"currentLevelMinPhotoCount":{"type":"integer","format":"int64"},"nextLevelMinPhotoCount":{"type":"integer","format":"int64"},"progressPercent":{"type":"integer","format":"int32"}},"description":"관리자 장소 상세 성장 상태"},"AdminMapPlaceImageItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"imageUrl":{"type":"string"},"thumbnailUrl":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"userId":{"type":"integer","format":"int64"},"username":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"likeCount":{"type":"integer","format":"int64"},"visibilityStatus":{"type":"string","description":"일반 사용자 기준 게시글 노출 상태","example":"VISIBLE","enum":["VISIBLE","HIDDEN"]},"hiddenReason":{"type":"string","description":"게시글이 숨김 처리된 사유. 노출 중인 게시글은 null","nullable":true,"example":"ADMIN_HIDDEN"}}},"AdminPlaceInformationEvidenceResponse":{"type":"object","properties":{"placeId":{"type":"integer","format":"int64"},"evidences":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceInformationEvidenceItem"}}},"description":"관리자 장소 정보 증빙 목록 응답"},"AdminPlaceRecommendationExplanationItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":1},"placeName":{"type":"string","description":"장소명","example":"진주성"},"userId":{"type":"integer","description":"사용자 ID","format":"int64","example":21},"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v2"},"recommendationStage":{"type":"string","description":"추천 stage","example":"EXPERIMENT","enum":["STABLE","EXPERIMENTAL"]},"ranking":{"type":"integer","description":"노출 순위","format":"int32","example":1},"source":{"type":"string","description":"후보 소스","example":"PERSONALIZED","enum":["PERSONAL","POPULAR","FRESH","GEO","FALLBACK"]},"distanceMeters":{"type":"integer","description":"거리(m)","format":"int64","example":128},"geoScore":{"type":"number","description":"geo score","format":"double","example":0.91},"personalScore":{"type":"number","description":"personal score","format":"double","example":0.42},"qualityScore":{"type":"number","description":"quality score","format":"double","example":0.37},"engagementScore":{"type":"number","description":"engagement score","format":"double","example":0.25},"conversionScore":{"type":"number","description":"conversion score","format":"double","example":0.14},"explorationScore":{"type":"number","description":"exploration score","format":"double","example":0.08},"freshnessScore":{"type":"number","description":"freshness score","format":"double","example":0.19},"trustScore":{"type":"number","description":"검증 제보자 신뢰도 기반 score","format":"double","example":0.82},"contextScore":{"type":"number","description":"K-컬처 관심사와 현재 여행 맥락 기반 score","format":"double","example":0.25},"benefitScore":{"type":"number","description":"현재 이용 가능한 혜택 기반 boost","format":"double","example":0.05},"availabilityScore":{"type":"number","description":"예약 가능 시간 기반 boost","format":"double","example":0.05},"boostScore":{"type":"number","description":"Verified Boost 집행 기반 score","format":"double","example":0.08},"finalScore":{"type":"number","description":"최종 score","format":"double","example":0.74},"createdAt":{"type":"string","description":"로그 생성 시각","format":"date-time"}},"description":"관리자 추천 설명 항목"},"AdminPlaceRecommendationExplanationResponse":{"type":"object","properties":{"requestId":{"type":"string","description":"추천 요청 식별자","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"items":{"type":"array","description":"관리자 추천 설명 항목","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationExplanationItem"}}},"description":"관리자 추천 설명 조회 응답"},"AdminPlaceRecommendationMetricItem":{"type":"object","properties":{"id":{"type":"integer","description":"장소 ID","format":"int64","example":1},"name":{"type":"string","description":"장소명","example":"진주성"},"address":{"type":"string","description":"장소 주소","example":"경상남도 진주시 남강로 626"},"photoCount":{"type":"integer","description":"장소 사진 수","format":"int64","example":12},"exposureCount":{"type":"integer","description":"추천 노출 수","format":"int64","example":120},"clickCount":{"type":"integer","description":"추천 클릭 수","format":"int64","example":18},"rawCtr":{"type":"number","description":"원본 CTR","format":"double","example":0.15},"smoothedCtr":{"type":"number","description":"랭킹 기준 smoothed CTR","format":"double","example":0.13},"bookmarkConversionCount":{"type":"integer","description":"북마크 전환 수","format":"int64","example":4},"likeConversionCount":{"type":"integer","description":"좋아요 전환 수","format":"int64","example":6},"bookmarkConversionRate":{"type":"number","description":"북마크 전환율","format":"double","example":0.03},"likeConversionRate":{"type":"number","description":"좋아요 전환율","format":"double","example":0.05},"totalConversionRate":{"type":"number","description":"전체 전환율","format":"double","example":0.08},"snapshotUpdatedAt":{"type":"string","description":"추천 snapshot 최종 갱신 시각","format":"date-time"}},"description":"관리자 추천 성과 항목"},"AdminPlaceRecommendationMetricsResponse":{"type":"object","properties":{"metrics":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricItem"}},"sortBy":{"type":"string","enum":["SMOOTHED_CTR","RAW_CTR","BOOKMARK_CONVERSION","LIKE_CONVERSION","TOTAL_CONVERSION","EXPOSURE","CLICK","UPDATED_AT"]},"recommendationVersion":{"type":"string"},"days":{"type":"integer","format":"int32"},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}},"description":"관리자 추천 성과 목록 응답"},"AdminPlaceRecommendationMetricSummary":{"type":"object","properties":{"recommendationVersion":{"type":"string","description":"추천 버전","example":"place-rec-v1"},"exposureCount":{"type":"integer","description":"추천 노출 수","format":"int64","example":120},"clickCount":{"type":"integer","description":"추천 클릭 수","format":"int64","example":18},"rawCtr":{"type":"number","description":"원본 CTR","format":"double","example":0.15},"smoothedCtr":{"type":"number","description":"smoothed CTR","format":"double","example":0.13},"bookmarkConversionCount":{"type":"integer","description":"북마크 전환 수","format":"int64","example":4},"likeConversionCount":{"type":"integer","description":"좋아요 전환 수","format":"int64","example":6},"bookmarkConversionRate":{"type":"number","description":"북마크 전환율","format":"double","example":0.03},"likeConversionRate":{"type":"number","description":"좋아요 전환율","format":"double","example":0.05},"totalConversionRate":{"type":"number","description":"전체 전환율","format":"double","example":0.08}},"description":"관리자 추천 성과 요약"},"AdminPlaceRecommendationMetricsCompareResponse":{"type":"object","properties":{"baselineVersion":{"type":"string","description":"기준 추천 버전","example":"place-rec-v1"},"targetVersion":{"type":"string","description":"비교 대상 추천 버전","example":"place-rec-v2"},"days":{"type":"integer","description":"최근 N일 기준 필터","format":"int32","example":7},"keyword":{"type":"string","description":"장소 검색 키워드","example":"진주"},"baseline":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"},"target":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"},"delta":{"$ref":"#/components/schemas/AdminPlaceRecommendationMetricSummary"}},"description":"관리자 추천 버전 성과 비교 응답"},"AdminPlaceMergeHistoryItem":{"type":"object","properties":{"historyId":{"type":"integer","format":"int64"},"sourcePlaceId":{"type":"integer","format":"int64"},"targetPlaceId":{"type":"integer","format":"int64"},"adminUserId":{"type":"integer","format":"int64"},"restored":{"type":"boolean"},"mergedAt":{"type":"string","format":"date-time"},"restoredAt":{"type":"string","format":"date-time"}}},"AdminPlaceMergeHistoryResponse":{"type":"object","properties":{"histories":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMergeHistoryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDuplicateGroupItem":{"type":"object","properties":{"representativePlaceId":{"type":"integer","format":"int64"},"duplicatePlaceIds":{"type":"array","items":{"type":"integer","format":"int64"}},"reasons":{"type":"array","items":{"type":"string"}}}},"AdminMapPlaceDuplicateResponse":{"type":"object","properties":{"groups":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateGroupItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMapPlaceDuplicateCandidateItem":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"kakaoPlaceId":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"photoCount":{"type":"integer","format":"int64"},"reason":{"type":"string"},"distanceMeters":{"type":"number","format":"double"}}},"AdminMapPlaceDuplicateDetailResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"address":{"type":"string"},"kakaoPlaceId":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"userId":{"type":"integer","format":"int64"},"registrant":{"type":"string"},"photoCount":{"type":"integer","format":"int64"},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/AdminMapPlaceDuplicateCandidateItem"}}}},"AdminPlaceDuplicateCandidateListResponse":{"type":"object","properties":{"candidates":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceDuplicateCandidateResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminPlaceReviewDeletionRequestPageResponse":{"type":"object","properties":{"deletionRequests":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceReviewDeletionRequestResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminPlaceEventListItem":{"type":"object","properties":{"eventId":{"type":"integer","format":"int64"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"placeAddress":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"eventType":{"type":"string","enum":["POP_UP","PERFORMANCE","EXHIBITION"]},"publicationStatus":{"type":"string","enum":["DRAFT","PUBLISHED","CANCELLED"]},"scheduleStatus":{"type":"string","enum":["UPCOMING","ONGOING","ENDED"]},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminPlaceEventListResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceEventListItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminOutboxEventResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AdminOutboxEventItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 Outbox 이벤트 운영 조회 응답"},"AdminNotificationItem":{"type":"object","properties":{"notificationId":{"type":"integer","description":"알림 ID","format":"int64","example":1},"userId":{"type":"integer","description":"수신 관리자 ID","format":"int64","example":10},"type":{"type":"string","description":"관리자 알림 유형: ADMIN_REPORT_RECEIVED, ADMIN_REPORT_PROCESSED, ADMIN_DUPLICATE_PLACE_DETECTED, ADMIN_USER_SANCTION","example":"ADMIN_REPORT_RECEIVED","enum":["NEW_HOTPLACE","NEW_LIKE","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER","ADMIN_REPORT_RECEIVED","ADMIN_REPORT_PROCESSED","ADMIN_DUPLICATE_PLACE_DETECTED","ADMIN_USER_SANCTION"]},"title":{"type":"string","description":"알림 제목","example":"신고 접수 알림"},"body":{"type":"string","description":"알림 내용","example":"신고 ID 30 접수가 게시글 ID 12에 등록되었습니다."},"token":{"type":"string","description":"관리 화면 연결 token. report:{reportId}, place:{placeId}, sanction:{sanctionId} 형식","example":"report:30"},"read":{"type":"boolean","description":"읽음 여부","example":false},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"}},"description":"관리자 알림 아이템"},"AdminNotificationResponse":{"type":"object","properties":{"notifications":{"type":"array","description":"관리자 알림 목록","items":{"$ref":"#/components/schemas/AdminNotificationItem"}},"page":{"type":"integer","description":"현재 페이지 번호","format":"int32","example":1},"limit":{"type":"integer","description":"페이지 크기","format":"int32","example":20},"totalCount":{"type":"integer","description":"전체 알림 개수","format":"int64","example":1},"totalPages":{"type":"integer","description":"전체 페이지 수","format":"int32","example":1},"hasNext":{"type":"boolean","description":"다음 페이지 존재 여부","example":false}},"description":"관리자 알림 목록 응답"},"AdminNotificationUnreadCountResponse":{"type":"object","properties":{"unreadCount":{"type":"integer","description":"미확인 알림 개수","format":"int64","example":3}},"description":"관리자 미확인 알림 개수 응답"},"AdminNotificationDeliveryItem":{"type":"object","properties":{"deliveryId":{"type":"integer","description":"발송 결과 ID","format":"int64","example":1},"channel":{"type":"string","description":"발송 채널","example":"FCM","enum":["FCM","EMAIL"]},"status":{"type":"string","description":"발송 상태","example":"SUCCEEDED","enum":["SUCCEEDED","FAILED","RETRY_SCHEDULED","FINAL_FAILED"]},"userId":{"type":"integer","description":"수신 사용자 ID","format":"int64","example":10},"notificationId":{"type":"integer","description":"인앱 알림 ID","format":"int64","example":100},"notificationType":{"type":"string","description":"인앱 알림 유형","example":"NEW_LIKE"},"outboxEventId":{"type":"string","description":"Outbox 이벤트 ID"},"outboxEventType":{"type":"string","description":"Outbox 이벤트 유형","example":"MAP_IMAGE_LIKED"},"providerMessageId":{"type":"string","description":"외부 발송 provider message id"},"providerErrorCode":{"type":"string","description":"외부 발송 provider error code"},"errorCode":{"type":"string","description":"내부 실패 분류 코드"},"failureReason":{"type":"string","description":"실패 사유"},"retryable":{"type":"boolean","description":"재시도 가능 여부","example":true},"attemptCount":{"type":"integer","description":"발송 시도 횟수","format":"int32","example":1},"createdAt":{"type":"string","description":"생성 시각","format":"date-time"},"updatedAt":{"type":"string","description":"수정 시각","format":"date-time"}},"description":"관리자 알림 발송 결과 아이템"},"AdminNotificationDeliveryResponse":{"type":"object","properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/AdminNotificationDeliveryItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 알림 발송 결과 목록 응답"},"AdminMerchantPlaceApplicationListItemResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"maskedBusinessRegistrationNumber":{"type":"string"},"merchantDisplayName":{"type":"string"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AdminMerchantPlaceApplicationPageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationListItemResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminMerchantPlaceApplicationAttachmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"documentType":{"type":"string","enum":["BUSINESS_REGISTRATION","IDENTITY_DOCUMENT","REPRESENTATIVE_IMAGE"]},"originalFilename":{"type":"string"},"contentType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"uploadedAt":{"type":"string","format":"date-time"},"retentionExpiresAt":{"type":"string","format":"date-time"},"displayOrder":{"type":"integer","format":"int32"}}},"AdminMerchantPlaceApplicationResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"applicantUserId":{"type":"integer","format":"int64"},"applicationType":{"type":"string","enum":["NEW_PLACE","EXISTING_PLACE_CLAIM"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED","REJECTED","COMPLETED","CANCELED"]},"legalName":{"type":"string"},"businessName":{"type":"string"},"businessRegistrationNumber":{"type":"string"},"merchantDisplayName":{"type":"string"},"merchantContactEmail":{"type":"string"},"merchantDescription":{"type":"string"},"merchantContactPhone":{"type":"string"},"newPlace":{"$ref":"#/components/schemas/MerchantPlaceApplicationNewPlaceResponse"},"placeName":{"type":"string"},"existingPlaceId":{"type":"integer","format":"int64"},"claimReason":{"type":"string"},"reviewReason":{"type":"string"},"placeId":{"type":"integer","format":"int64"},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"version":{"type":"integer","format":"int64"},"submissionVersion":{"type":"integer","format":"int64"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantPlaceApplicationAttachmentResponse"}}}},"MerchantOwnerProfilePageResponse":{"type":"object","properties":{"profiles":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOwnerProfileResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"DataQualityIssuePageResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DataQualityIssueResponse"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"DataQualityIssueResponse":{"type":"object","properties":{"entityType":{"type":"string"},"entityId":{"type":"integer","format":"int64"},"ruleCode":{"type":"string"},"severity":{"type":"string","enum":["INFO","WARNING","ERROR"]},"status":{"type":"string","enum":["OPEN","RESOLVED","IGNORED"]},"details":{"type":"string"},"detectedAt":{"type":"string","format":"date-time"}}},"AdminDashboardMetricWindowResponse":{"type":"object","properties":{"period":{"type":"string","description":"집계 기간 코드","example":"TODAY","enum":["TODAY","LAST_7_DAYS"]},"startedAt":{"type":"string","description":"집계 시작 시각","format":"date-time"},"endedAt":{"type":"string","description":"집계 종료 시각","format":"date-time"},"placeRegistrationCount":{"type":"integer","description":"기간 내 장소 등록 수","format":"int64","example":3},"postRegistrationCount":{"type":"integer","description":"기간 내 게시글 등록 수","format":"int64","example":7}},"description":"관리자 대시보드 기간별 운영 변화 지표"},"AdminDashboardOperationalMetricsResponse":{"type":"object","properties":{"today":{"$ref":"#/components/schemas/AdminDashboardMetricWindowResponse"},"last7Days":{"$ref":"#/components/schemas/AdminDashboardMetricWindowResponse"},"duplicatePlaceGroupCount":{"type":"integer","description":"중복 장소 후보 그룹 수","format":"int64","example":2},"expiringBannedUserCount":{"type":"integer","description":"7일 이내 임시 밴 만료 예정 사용자 수","format":"int64","example":4},"missingLocationPlaceCount":{"type":"integer","description":"location 좌표 정보가 누락된 장소 수","format":"int64","example":1},"expiringBanUntil":{"type":"string","description":"밴 만료 예정 집계 종료 시각","format":"date-time"},"collectedAt":{"type":"string","description":"지표 집계 기준 시각","format":"date-time"}},"description":"관리자 대시보드 추가 운영 지표"},"AdminDashboardSummaryResponse":{"type":"object","properties":{"placeCount":{"type":"integer","description":"전체 장소 수","format":"int64","example":44},"postCount":{"type":"integer","description":"전체 게시글 수","format":"int64","example":58},"pendingReportCount":{"type":"integer","description":"처리 대기 신고 수","format":"int64","example":5},"bannedUserCount":{"type":"integer","description":"현재 밴 사용자 수","format":"int64","example":6},"operationalMetrics":{"$ref":"#/components/schemas/AdminDashboardOperationalMetricsResponse"}},"description":"관리자 대시보드 전체 운영 현황 요약"},"AdminDashboardRecentActivitiesResponse":{"type":"object","properties":{"places":{"type":"array","description":"최근 장소 등록 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentPlaceItem"}},"posts":{"type":"array","description":"최근 게시글 등록 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentPostItem"}},"reports":{"type":"array","description":"최근 신고 처리 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentReportItem"}},"userSanctions":{"type":"array","description":"최근 사용자 밴 및 밴 해제 내역","items":{"$ref":"#/components/schemas/AdminDashboardRecentUserSanctionItem"}}},"description":"관리자 대시보드 최근 운영 활동"},"AdminDashboardRecentPlaceItem":{"type":"object","properties":{"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":10},"name":{"type":"string","description":"장소명","example":"핑덤 카페"},"address":{"type":"string","description":"주소","example":"서울특별시 중구 세종대로 110"},"userId":{"type":"integer","description":"등록 사용자 ID","format":"int64","example":3},"registrant":{"type":"string","description":"등록자명","example":"pingdom_user"},"createdAt":{"type":"string","description":"장소 등록일","format":"date-time"}},"description":"관리자 대시보드 최근 장소 등록 항목"},"AdminDashboardRecentPostItem":{"type":"object","properties":{"postId":{"type":"integer","description":"게시글 ID","format":"int64","example":10},"title":{"type":"string","description":"게시글 제목","example":"야경이 좋은 장소"},"userId":{"type":"integer","description":"작성자 ID","format":"int64","example":3},"username":{"type":"string","description":"작성자명","example":"pingdom_user"},"placeId":{"type":"integer","description":"장소 ID","format":"int64","example":7},"placeName":{"type":"string","description":"장소명","example":"핑덤 카페"},"createdAt":{"type":"string","description":"생성일","format":"date-time"}},"description":"관리자 대시보드 최근 게시글 등록 항목"},"AdminDashboardRecentReportItem":{"type":"object","properties":{"reportId":{"type":"integer","description":"신고 ID","format":"int64","example":10},"reportedImageId":{"type":"integer","description":"신고 대상 게시글 ID","format":"int64","example":22},"title":{"type":"string","description":"신고 대상 게시글 제목","example":"야경이 좋은 장소"},"status":{"type":"string","description":"신고 상태","example":"ACCEPTED","enum":["PENDING","ACCEPTED","DECLINED","RESTORED"]},"processedAt":{"type":"string","description":"처리일","format":"date-time"},"createdAt":{"type":"string","description":"신고 생성일","format":"date-time"}},"description":"관리자 대시보드 최근 신고 처리 항목"},"AdminDashboardRecentUserSanctionItem":{"type":"object","properties":{"sanctionId":{"type":"integer","description":"제재 이력 ID","format":"int64","example":10},"targetUserId":{"type":"integer","description":"대상 사용자 ID","format":"int64","example":5},"targetUsername":{"type":"string","description":"대상 사용자명","example":"reported_user"},"action":{"type":"string","description":"제재 처리 유형","example":"APPLIED","enum":["APPLIED","RELEASED","EXPIRED"]},"banType":{"type":"string","description":"밴 유형","example":"PERMANENT","enum":["PERMANENT","TEMPORARY"]},"reason":{"type":"string","description":"처리 사유","example":"부적절한 게시글입니다."},"processedAt":{"type":"string","description":"처리일","format":"date-time"}},"description":"관리자 대시보드 최근 사용자 제재 항목"},"AdminDashboardPendingItem":{"type":"object","properties":{"type":{"type":"string","description":"처리 필요 항목 유형","example":"POST_REPORT","enum":["POST_REPORT","MERCHANT_PLACE_APPLICATION","POST_REPORT","MERCHANT_PLACE_APPLICATION"]},"targetId":{"type":"integer","description":"처리 항목 ID. POST_REPORT에서는 신고 ID와 동일","format":"int64","example":30},"reportId":{"type":"integer","description":"신고 ID. 신고 처리 화면으로 이동할 때 사용","format":"int64","example":30},"postId":{"type":"integer","description":"신고 대상 게시글 ID. 게시글 상세 화면으로 이동할 때 사용","format":"int64","nullable":true,"example":22},"title":{"type":"string","description":"처리 대상 제목","example":"야경이 좋은 장소"},"status":{"type":"string","description":"처리 대상 상태","example":"PENDING"},"createdAt":{"type":"string","description":"생성일","format":"date-time"},"navigationPath":{"type":"string","description":"관리자 화면 이동 경로. 통합 신청 항목에서만 제공","nullable":true,"example":"/admin/merchant-place-applications/12"}},"description":"관리자 대시보드 처리 필요 항목"},"AdminDashboardPendingItemsResponse":{"type":"object","properties":{"items":{"type":"array","description":"처리 필요 항목","items":{"$ref":"#/components/schemas/AdminDashboardPendingItem"}},"totalCount":{"type":"integer","description":"필터링 전 전체 PENDING 처리 필요 항목 수","format":"int64","example":8}},"description":"관리자 대시보드 처리 필요 항목 목록"},"AdminCommunityPostItem":{"type":"object","properties":{"postId":{"type":"integer","format":"int64"},"categoryId":{"type":"string"},"title":{"type":"string"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 글 목록 항목"},"AdminCommunityPostPageResponse":{"type":"object","properties":{"posts":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityPostItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminCommunityPostResponse":{"type":"object","properties":{"postId":{"type":"integer","format":"int64"},"categoryId":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"places":{"type":"array","items":{"$ref":"#/components/schemas/Place"}}}},"AdminCommunityCommentItem":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"content":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 댓글 목록 항목"},"AdminCommunityCommentPageResponse":{"type":"object","properties":{"comments":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityCommentItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}}},"AdminCommunityCommentResponse":{"type":"object","properties":{"commentId":{"type":"integer","format":"int64"},"postId":{"type":"integer","format":"int64"},"authorUserId":{"type":"integer","format":"int64"},"authorUsername":{"type":"string"},"content":{"type":"string"},"hidden":{"type":"boolean"},"hiddenByAdminUserId":{"type":"integer","format":"int64"},"hiddenAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"AdminCommunityReportItem":{"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"targetHidden":{"type":"boolean"},"reporterUserId":{"type":"integer","format":"int64"},"reason":{"type":"string","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"createdAt":{"type":"string","format":"date-time"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 목록 항목"},"AdminCommunityReportPageResponse":{"type":"object","properties":{"reports":{"type":"array","items":{"$ref":"#/components/schemas/AdminCommunityReportItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 커뮤니티 신고 목록 응답"},"AdminCommunityReportResponse":{"required":["postId"],"type":"object","properties":{"reportId":{"type":"integer","format":"int64"},"targetType":{"type":"string","enum":["POST","COMMENT"]},"targetId":{"type":"integer","format":"int64"},"postId":{"type":"integer","description":"원문 글 ID. POST는 targetId와 같고 COMMENT는 대상 댓글이 속한 글 ID입니다. 신고 대상과 댓글의 원문 관계는 DB 제약으로 보장되며, 숨김 여부와 관계없이 반환합니다.","format":"int64","example":101},"targetHidden":{"type":"boolean"},"reporterUserId":{"type":"integer","format":"int64"},"reason":{"type":"string","enum":["SPAM","ABUSE","INAPPROPRIATE_CONTENT","PERSONAL_INFORMATION","OTHER"]},"description":{"type":"string"},"status":{"type":"string","enum":["PENDING","ACCEPTED","DECLINED"]},"createdAt":{"type":"string","format":"date-time"},"processedByAdminUserId":{"type":"integer","format":"int64"},"processedAt":{"type":"string","format":"date-time"}},"description":"관리자 커뮤니티 신고 상세 응답"},"AdminAuditLogItem":{"type":"object","properties":{"auditLogId":{"type":"integer","description":"감사 로그 ID","format":"int64","example":1},"actorUserId":{"type":"integer","description":"작업 관리자 ID","format":"int64","example":1},"actorUsername":{"type":"string","description":"작업 관리자명","example":"admin"},"action":{"type":"string","description":"작업 유형","example":"USER_BAN_APPLIED","enum":["ADMIN_ROLE_ASSIGNED","ADMIN_ROLE_REVOKED","USER_BAN_APPLIED","USER_BAN_RELEASED","REPORT_ACCEPTED","REPORT_DECLINED","COMMUNITY_REPORT_ACCEPTED","COMMUNITY_REPORT_DECLINED","POST_DELETED","POST_HIDDEN","POST_RESTORED","APPEAL_APPROVED","APPEAL_REJECTED","PLACE_DELETED","PLACE_BASIC_INFORMATION_UPDATED","PLACE_KAKAO_PLACE_ID_UPDATED","PLACE_GEOCODING_UPDATED","PLACE_TOURIST_INFO_UPDATED","PLACE_INFORMATION_EVIDENCE_UPDATED","PLACE_INFORMATION_VERIFICATION_UPDATED","PLACE_INFORMATION_REPORT_REVIEWED","PLACE_INFORMATION_DISPUTE_REVIEWED","PLACE_INFORMATION_REVERIFICATION_REQUESTED","PLACE_INFORMATION_REVERIFICATION_REMINDER_REQUESTED","PLACE_INFORMATION_REVERIFICATION_COMPLETED","PLACE_INFORMATION_REVERIFICATION_CANCELED","PLACE_INFORMATION_REVERIFICATION_EXPIRED","VISITOR_VERIFICATION_REPORT_REVIEWED","VISITOR_VERIFICATION_REPORT_CORRECTION_REVIEWED","SCOUT_FIELD_REPORT_REVIEWED","SCOUT_PROFILE_REVIEWED","SCOUT_ACTIVITY_ELIGIBILITY_REVIEWED","PLACE_DISCOVERY_STATUS_UPDATED","PLACE_OPERATING_STATUS_UPDATED","PLACE_OPERATING_SCHEDULE_UPDATED","PLACE_OPERATING_NOTICE_CREATED","PLACE_OPERATING_NOTICE_UPDATED","PLACE_OPERATING_NOTICE_CANCELED","PLACE_OPERATING_NOTICE_EXPIRED","PLACE_EVENT_CREATED","PLACE_EVENT_UPDATED","PLACE_EVENT_PUBLISHED","PLACE_EVENT_CANCELLED","PLACE_RECOMMENDATION_TRAFFIC_UPDATED","PLACE_RECOMMENDATION_KILL_SWITCH_UPDATED","TRUST_SCORE_ANOMALY_RESOLVED","TRUST_SCORE_INTERVENTION_RULE_CREATED","TRUST_SCORE_INTERVENTION_RULE_UPDATED","TRUST_SCORE_INTERVENTION_RULE_ENABLED","TRUST_SCORE_INTERVENTION_RULE_DISABLED","TRUST_SCORE_INTERVENTION_EVALUATED","NOTIFICATION_READ","NOTIFICATION_READ_ALL","PLACE_DUPLICATE_CONFIRMED","PLACE_DUPLICATE_REJECTED","PLACE_MERGED","MERCHANT_OWNER_APPROVED","MERCHANT_OWNER_REJECTED","MERCHANT_OWNER_REVOKED","MERCHANT_OWNER_PLACES_UPDATED","MERCHANT_ONBOARDING_UPDATED","MERCHANT_OPERATIONAL_QUALITY_UPDATED","MERCHANT_VERIFICATION_REVIEWED","MERCHANT_VERIFICATION_VIEWED","MERCHANT_PLACE_CLAIM_ATTACHMENT_VIEWED","MERCHANT_PLACE_CLAIM_APPROVED","MERCHANT_PLACE_CLAIM_REJECTED","MERCHANT_PLACE_APPLICATION_APPROVED","MERCHANT_PLACE_APPLICATION_REJECTED","MERCHANT_PLACE_APPLICATION_VIEWED","MERCHANT_PLACE_APPLICATION_ATTACHMENT_VIEWED","OUTBOX_EVENT_RETRIED","AD_CREATED","AD_DELETED","RESERVATION_CONFIRMED","RESERVATION_REJECTED"]},"targetType":{"type":"string","description":"대상 유형","example":"USER","enum":["USER","REPORT","COMMUNITY_REPORT","APPEAL","POST","PLACE","PLACE_DUPLICATE_CANDIDATE","PLACE_INFORMATION_EVIDENCE","PLACE_INFORMATION_REPORT","PLACE_INFORMATION_DISPUTE","PLACE_INFORMATION_REVERIFICATION","VISITOR_VERIFICATION_REPORT","VISITOR_VERIFICATION_REPORT_CORRECTION","SCOUT_FIELD_REPORT","SCOUT_PROFILE","SCOUT_ACTIVITY_ELIGIBILITY","PLACE_OPERATING_NOTICE","PLACE_EVENT","TRUST_SCORE_ANOMALY","TRUST_SCORE_INTERVENTION_RULE","NOTIFICATION","OUTBOX_EVENT","MERCHANT_OWNER","MERCHANT_VERIFICATION","MERCHANT_PLACE_CLAIM_ATTACHMENT","MERCHANT_PLACE_CLAIM","MERCHANT_PLACE_APPLICATION","MERCHANT_PLACE_APPLICATION_ATTACHMENT","AD","RESERVATION"]},"targetId":{"type":"string","description":"대상 ID","example":"7"},"reason":{"type":"string","description":"작업 사유","example":"반복적인 신고 누적"},"beforeState":{"type":"string","description":"작업 전 상태 JSON"},"afterState":{"type":"string","description":"작업 후 상태 JSON"},"requestId":{"type":"string","description":"요청 ID","example":"9f7263d5-65f1-4834-9ca3-86ad2fc4e7d0"},"createdAt":{"type":"string","description":"감사 로그 생성 시각","format":"date-time"}},"description":"관리자 감사 로그 아이템"},"AdminAuditLogResponse":{"type":"object","properties":{"auditLogs":{"type":"array","items":{"$ref":"#/components/schemas/AdminAuditLogItem"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"hasNext":{"type":"boolean"}},"description":"관리자 감사 로그 목록 응답"},"OAuthAccountDisconnectRequest":{"type":"object","properties":{"currentPassword":{"type":"string","description":"마지막 OAuth 계정을 해제할 때 확인할 현재 비밀번호","nullable":true,"example":"password123"}},"description":"OAuth 계정 연결 해제 요청"},"OAuthAccountResponse":{"type":"object","properties":{"provider":{"type":"string","description":"OAuth Provider","example":"GOOGLE"},"linked":{"type":"boolean","description":"연결 여부","example":false},"message":{"type":"string","description":"처리 결과 메시지","example":"Google 계정 연결을 해제했습니다."}},"description":"OAuth 계정 상태 응답"},"AdminRoleAssignmentRevokeRequest":{"type":"object","properties":{"reason":{"maxLength":500,"minLength":0,"type":"string","description":"역할을 회수하는 사유","example":"담당 업무 변경"}},"description":"관리자 역할 회수 요청"},"AdminS3OrphanDeleteRequest":{"required":["reportId"],"type":"object","properties":{"reportId":{"type":"string"},"keys":{"maxItems":100,"minItems":0,"type":"array","items":{"type":"string"}},"confirmed":{"type":"boolean"}}},"S3OrphanDeleteFailure":{"type":"object","properties":{"key":{"type":"string"},"reason":{"type":"string"}}},"S3OrphanDeleteResult":{"type":"object","properties":{"requestedKeyCount":{"type":"integer","format":"int32"},"deletedKeyCount":{"type":"integer","format":"int32"},"failedKeyCount":{"type":"integer","format":"int32"},"deletedKeys":{"type":"array","items":{"type":"string"}},"failedKeys":{"type":"array","items":{"$ref":"#/components/schemas/S3OrphanDeleteFailure"}}}},"ProviderEnvelopeV1":{"title":"Pingdom provider envelope v1","oneOf":[{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["searchNearbyPlaces"]},"args":{"required":["useCurrentLocation"],"type":"object","properties":{"useCurrentLocation":{"type":"boolean"},"touristCategory":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["searchNearbyReservablePlaces"]},"args":{"required":["date","endTime","quantity","startTime","useCurrentLocation"],"type":"object","properties":{"touristCategory":{"type":"string","enum":["K_POP","BEAUTY","FASHION","CAFE","FOOD","POP_UP","EXHIBITION","NIGHTLIFE","OTHER"]},"date":{"pattern":"^(?!0000)[0-9]{4}-[0-9]{2}-[0-9]{2}$","type":"string","format":"date"},"startTime":{"pattern":"^(?:[01][0-9]|2[0-3]):[0-5][0-9]$","type":"string"},"endTime":{"pattern":"^(?:[01][0-9]|2[0-3]):[0-5][0-9]$","type":"string"},"quantity":{"maximum":12,"minimum":1,"type":"integer"},"useCurrentLocation":{"type":"boolean"}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["getPlaceDetails"]},"args":{"required":["placeId"],"type":"object","properties":{"placeId":{"maximum":9007199254740991,"minimum":1,"type":"integer"}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["getAvailabilities"]},"args":{"required":["date","placeId","quantity"],"type":"object","properties":{"placeId":{"maximum":9007199254740991,"minimum":1,"type":"integer"},"date":{"pattern":"^(?!0000)[0-9]{4}-[0-9]{2}-[0-9]{2}$","type":"string","format":"date"},"quantity":{"maximum":12,"minimum":1,"type":"integer"}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["prepareReservation"]},"args":{"required":["availabilityId","placeId","quantity"],"type":"object","properties":{"placeId":{"maximum":9007199254740991,"minimum":1,"type":"integer"},"availabilityId":{"maximum":9007199254740991,"minimum":1,"type":"integer"},"quantity":{"maximum":12,"minimum":1,"type":"integer"}},"additionalProperties":false}},"additionalProperties":false},{"required":["args","command","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["command_request"]},"command":{"type":"string","enum":["cancelVoiceSession"]},"args":{"type":"object","properties":{},"additionalProperties":false}},"additionalProperties":false},{"required":["field","id","kind","schemaVersion","text"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["clarification_request"]},"field":{"type":"string","enum":["touristCategory","date","timeRange","quantity","useCurrentLocation","placeId","availabilityId"]},"text":{"maxLength":2000,"minLength":1,"pattern":"\\S","type":"string"}},"additionalProperties":false},{"required":["id","kind","schemaVersion","text"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["assistant_message"]},"text":{"maxLength":2000,"minLength":1,"pattern":"\\S","type":"string"}},"additionalProperties":false},{"required":["code","id","kind","schemaVersion"],"type":"object","properties":{"schemaVersion":{"type":"integer","enum":[1]},"id":{"maxLength":128,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","type":"string"},"kind":{"type":"string","enum":["protocol_error"]},"code":{"type":"string","enum":["UNSUPPORTED_REQUEST","PROVIDER_UNAVAILABLE","INVALID_RESPONSE"]}},"additionalProperties":false}]},"MerchantReservationDetailResponse":{"type":"object","properties":{"reservation":{"$ref":"#/components/schemas/ReservationResponse"},"placeId":{"type":"integer","format":"int64"},"placeName":{"type":"string"},"statusHistory":{"type":"array","items":{"$ref":"#/components/schemas/ReservationStatusHistoryResponse"}}}},"ReservationStatusHistoryResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["PENDING","CONFIRMED","REJECTED","CANCELED"]},"changedBy":{"type":"integer","format":"int64"},"reason":{"type":"string"},"changedAt":{"type":"string","format":"date-time"}}},"AdminPlaceMapRegion":{"type":"object","properties":{"regionLevel":{"type":"string"},"regionCode":{"type":"string"},"name":{"type":"string"},"count":{"type":"integer","format":"int64"},"countScope":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"bounds":{"$ref":"#/components/schemas/AdminPlaceMapBounds"},"boundsSource":{"type":"string","enum":["PLACE_EXTENT"]},"action":{"type":"string","enum":["EXPAND"]},"nextZoom":{"type":"integer","format":"int32"}}},"AdminPlaceMapResponse":{"type":"object","properties":{"mode":{"type":"string","enum":["SIDO","SIGUNGU","SPATIAL"]},"zoom":{"type":"integer","format":"int32"},"regions":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMapRegion"}},"clusters":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMapCluster"}},"markers":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMapMarker"}},"viewportPlaceCount":{"type":"integer","description":"현재 화면 안의 동일 필터·유효 좌표 장소 수. 지역 전체 count와 합산하지 않습니다.","format":"int64"},"complete":{"type":"boolean","description":"모든 표시 대상을 누락 없이 표현했는지 여부"},"incompleteReason":{"type":"string","nullable":true,"enum":["RESULT_BUDGET_EXCEEDED"]},"recoveryAction":{"type":"string","nullable":true,"enum":["ZOOM_IN"]}},"description":"관리자 지도. 지역 전체 count와 viewportPlaceCount는 별도 범위이며 합산하지 않습니다."},"AdminPlaceMapGroupPage":{"type":"object","properties":{"places":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlaceMapMarker"}},"page":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int64"},"hasNext":{"type":"boolean"}}},"AdminPlaceMapCluster":{"type":"object","properties":{"clusterKey":{"type":"string"},"clusterId":{"type":"string"},"count":{"type":"integer","format":"int64"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"bounds":{"$ref":"#/components/schemas/AdminPlaceMapBounds"},"countScope":{"type":"string"},"action":{"type":"string","enum":["EXPAND","LIST"]},"nextZoom":{"type":"integer","format":"int32"}}},"AdminPlaceMapMarker":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"category":{"type":"string"},"discoveryStatus":{"type":"string"},"operatingStatus":{"type":"string"}}},"AdminPlaceMapBounds":{"type":"object","properties":{"west":{"type":"number","format":"double"},"south":{"type":"number","format":"double"},"east":{"type":"number","format":"double"},"north":{"type":"number","format":"double"}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}} \ No newline at end of file