package com.kamco.cd.kamcoback.zoo; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.zoo.dto.ZooDto; import com.kamco.cd.kamcoback.zoo.dto.ZooDto.Detail; import com.kamco.cd.kamcoback.zoo.service.ZooService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; 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 lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Tag(name = "Zoo", description = "동물원 관리 API") @RequiredArgsConstructor @RestController @RequestMapping({"/api/zoos", "/v1/api/zoos"}) public class ZooApiController { private final ZooService zooService; /** * 동물원 생성 * * @param req 동물원 생성 요청 * @return 생성된 동물원 정보 (동물 개수 포함) */ @Operation(summary = "동물원 생성", description = "새로운 동물원 정보를 등록합니다.") @ApiResponses( value = { @ApiResponse( responseCode = "201", description = "동물원 생성 성공", content = @Content( mediaType = "application/json", schema = @Schema(implementation = ZooDto.Detail.class))), @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @PostMapping public ApiResponseDto createZoo( @io.swagger.v3.oas.annotations.parameters.RequestBody( description = "동물원 생성 요청 정보", required = true, content = @Content( mediaType = "application/json", schema = @Schema(implementation = ZooDto.AddReq.class))) @RequestBody ZooDto.AddReq req) { ZooDto.Detail created = zooService.createZoo(req); return ApiResponseDto.createOK(created); } /** * UUID로 동물원 조회 * * @param uuid 동물원 UUID * @return 동물원 정보 (현재 동물 개수 포함) */ @Operation(summary = "동물원 단건 조회", description = "UUID로 특정 동물원의 상세 정보를 조회합니다.") @ApiResponses( value = { @ApiResponse( responseCode = "200", description = "조회 성공", content = @Content( mediaType = "application/json", schema = @Schema(implementation = ZooDto.Detail.class))), @ApiResponse(responseCode = "404", description = "동물원을 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @GetMapping("/{uuid}") public ApiResponseDto getZoo( @Parameter( description = "조회할 동물원의 UUID", required = true, example = "550e8400-e29b-41d4-a716-446655440000") @PathVariable String uuid) { Long id = zooService.getZooByUuid(uuid); ZooDto.Detail zoo = zooService.getZoo(id); return ApiResponseDto.ok(zoo); } /** * UUID로 동물원 삭제 (논리 삭제) * * @param uuid 동물원 UUID * @return 삭제 성공 메시지 */ @Operation(summary = "동물원 삭제", description = "UUID로 특정 동물원을 삭제합니다 (논리 삭제).") @ApiResponses( value = { @ApiResponse(responseCode = "204", description = "삭제 성공", content = @Content), @ApiResponse(responseCode = "404", description = "동물원을 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @DeleteMapping("/{uuid}") public ApiResponseDto deleteZoo( @Parameter( description = "삭제할 동물원의 UUID", required = true, example = "550e8400-e29b-41d4-a716-446655440000") @PathVariable String uuid) { Long id = zooService.getZooByUuid(uuid); zooService.deleteZoo(id); return ApiResponseDto.deleteOk(uuid); } /** * 동물원 검색 (페이징) * * @param name 동물원 이름 (선택) * @param location 위치 (선택) * @param page 페이지 번호 (기본값: 0) * @param size 페이지 크기 (기본값: 20) * @param sort 정렬 조건 (예: "name,asc") * @return 페이징 처리된 동물원 목록 (각 동물원의 현재 동물 개수 포함) */ @Operation( summary = "동물원 검색", description = "다양한 조건으로 동물원을 검색하고 페이징된 결과를 반환합니다. 모든 검색 조건은 선택적이며, 조건 없이 호출하면 전체 동물원 목록을 반환합니다.") @ApiResponses( value = { @ApiResponse( responseCode = "200", description = "검색 성공", content = @Content( mediaType = "application/json", schema = @Schema(implementation = Page.class))), @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @GetMapping public ApiResponseDto> searchZoos( @Parameter(description = "동물원 이름 (부분 일치 검색)", example = "서울동물원") @RequestParam(required = false) String name, @Parameter(description = "위치", example = "서울") @RequestParam(required = false) String location, @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") int size, @Parameter(description = "정렬 조건 (형식: 필드명,방향)", example = "name,asc") @RequestParam(required = false) String sort) { ZooDto.SearchReq searchReq = new ZooDto.SearchReq(name, location, page, size, sort); Page zoos = zooService.search(searchReq); return ApiResponseDto.ok(zoos); } }