Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

합주실 매물 생성 api 구현 #108

Merged
merged 6 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/main/java/com/ajou/hertz/common/dto/CoordinateDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ajou.hertz.common.dto;

import com.ajou.hertz.common.entity.Coordinate;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class CoordinateDto {

private String lat;
private String lng;

public static CoordinateDto from(Coordinate coordinate) {
return new CoordinateDto(coordinate.getLat(), coordinate.getLng());
}
}
30 changes: 30 additions & 0 deletions src/main/java/com/ajou/hertz/common/dto/FullAddressDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.ajou.hertz.common.dto;

import com.ajou.hertz.common.entity.FullAddress;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class FullAddressDto {

private String sido;
private String sgg;
private String lotNumberAddress;
private String roadAddress;
private String detailAddress;

public static FullAddressDto from(FullAddress fullAddress) {
return new FullAddressDto(
fullAddress.getSido(),
fullAddress.getSgg(),
fullAddress.getLotNumberAddress(),
fullAddress.getRoadAddress(),
fullAddress.getDetailAddress()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.ajou.hertz.common.dto.request;

import com.ajou.hertz.common.entity.Coordinate;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Setter
@Getter
public class CoordinateRequest {

@Schema(description = "위도", example = "37.123456")
@NotBlank
private String lat;

@Schema(description = "경도", example = "127.123456")
@NotBlank
private String lng;

public Coordinate toEntity() {
return new Coordinate(lat, lng);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.ajou.hertz.common.dto.request;

import com.ajou.hertz.common.entity.FullAddress;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Setter
@Getter
public class FullAddressRequest {

@Schema(description = "전체 주소", example = "서울특별시 강남구 역삼동 123-45")
@NotBlank
private String fullAddress;

@Schema(description = "상세주소", example = "아주 빌딩 2층")
@NotBlank
private String detailAddress;

public FullAddress toEntity() {
return FullAddress.of(fullAddress, detailAddress);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.ajou.hertz.common.dto.response;

import com.ajou.hertz.common.dto.CoordinateDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class CoordinateResponse {

@Schema(description = "위도", example = "37.123456")
private String lat;

@Schema(description = "경도", example = "127.123456")
private String lng;

public static CoordinateResponse from(CoordinateDto coordinateDto) {
return new CoordinateResponse(coordinateDto.getLat(), coordinateDto.getLng());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.ajou.hertz.common.dto.response;

import com.ajou.hertz.common.dto.FullAddressDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class FullAddressResponse {


@Schema(description = "시/도", example = "서울특별시")
private String sido;

@Schema(description = "시/군/구", example = "강남구")
private String sgg;

@Schema(description = "지번주소", example = "수원시 팔달구 권선로11")
private String lotNumberAddress;

@Schema(description = "도로명 주소", example = "서울특별시 강남구 역삼동 123-45번지")
private String roadAddress;

@Schema(description = "상세주소", example = "아주 빌딩 2층")
private String detailAddress;

public static FullAddressResponse from(FullAddressDto fullAddressDto) {
return new FullAddressResponse(
fullAddressDto.getSido(),
fullAddressDto.getSgg(),
fullAddressDto.getLotNumberAddress(),
fullAddressDto.getRoadAddress(),
fullAddressDto.getDetailAddress()
);
}
}
31 changes: 16 additions & 15 deletions src/main/java/com/ajou/hertz/common/entity/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package com.ajou.hertz.common.entity;

import java.time.LocalDateTime;

import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.LastModifiedBy;

import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.LastModifiedBy;

import java.time.LocalDateTime;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@MappedSuperclass
public abstract class BaseEntity extends TimeTrackedBaseEntity {

@CreatedBy
@Column(nullable = false, updatable = false)
protected Long createdBy;
@CreatedBy
@Column(nullable = false, updatable = false)
protected Long createdBy;

@LastModifiedBy
@Column(nullable = false)
protected Long updatedBy;
@LastModifiedBy
@Column(nullable = false)
protected Long updatedBy;

protected BaseEntity(LocalDateTime createdAt, LocalDateTime updatedAt, Long createdBy, Long updatedBy) {
super(createdAt, updatedAt);
this.createdBy = createdBy;
this.updatedBy = updatedBy;
}
protected BaseEntity(LocalDateTime createdAt, LocalDateTime updatedAt, Long createdBy, Long updatedBy) {
super(createdAt, updatedAt);
this.createdBy = createdBy;
this.updatedBy = updatedBy;
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/ajou/hertz/common/entity/Coordinate.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Embeddable
public class Coordinate {
Expand All @@ -18,5 +18,4 @@ public class Coordinate {

@Column(nullable = false)
private String lng;

}
3 changes: 1 addition & 2 deletions src/main/java/com/ajou/hertz/common/entity/FullAddress.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Embeddable
Expand Down Expand Up @@ -64,5 +64,4 @@ public static FullAddress of(String fullAddress, String detailAddress) {

return new FullAddress(sido, sgg, lotNumberAddress, roadAddress, detailAddress);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* <li>2200 ~ 2399: 유저 관련 예외</li>
* <li>2400 ~ 2599: 주소 관련 예외</li>
* <li>2600 ~ 2799: 악기 관련 예외</li>
* <li>2800 ~ 2999: 악기 관련 예외</li>
* </ul>
*/
@AllArgsConstructor(access = AccessLevel.PRIVATE)
Expand Down Expand Up @@ -57,7 +58,12 @@ public enum CustomExceptionType {
INSTRUMENT_NOT_FOUND_BY_ID(2600, "일치하는 매물 정보를 찾을 수 없습니다."),
INSTRUMENT_DELETE_PERMISSION_DENIED(2601, "악기 매물을 삭제할 권한이 없습니다. 매물은 판매자 본인만 삭제할 수 있습니다."),
INSTRUMENT_UPDATE_PERMISSION_DENIED(2602, "악기 매물 정보를 수정할 권한이 없습니다. 매물 정보는 판매자 본인만 수정할 수 있습니다."),
UNEXPECTED_LINK_IN_INSTRUMENT_DESCRIPTION(2603, "악기 설명에는 링크(URL)를 첨부할 수 없습니다. 링크 정보를 제거한 후 다시 시도하세요.");
UNEXPECTED_LINK_IN_INSTRUMENT_DESCRIPTION(2603, "악기 설명에는 링크(URL)를 첨부할 수 없습니다. 링크 정보를 제거한 후 다시 시도하세요."),

/**
* 합주실 관련 예외
*/
UNEXPECTED_LINK_IN_PRACTICEROOM_DESCRIPTION(2800, "합주실 관련 설명에는 링크(URL)를 첨부할 수 없습니다. 링크 정보를 제거한 후 다시 시도하세요.");

private final Integer code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.ajou.hertz.domain.practice_room.controller;

import static com.ajou.hertz.common.constant.GlobalConstants.*;

import java.net.URI;

import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ajou.hertz.common.auth.UserPrincipal;
import com.ajou.hertz.domain.practice_room.dto.PracticeRoomDto;
import com.ajou.hertz.domain.practice_room.dto.request.CreateNewPracticeRoomRequest;
import com.ajou.hertz.domain.practice_room.dto.response.PracticeRoomResponse;
import com.ajou.hertz.domain.practice_room.service.PracticeRoomCommandService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@Tag(name = "합주실 관련 API")
@RequiredArgsConstructor
@RequestMapping("/api/practice-rooms")
@RestController
public class PracticeRoomController {

private final PracticeRoomCommandService practiceRoomCommandService;

@Operation(
summary = "합주실 매물 등록",
description = """
<p>합주실 매물을 등록합니다.
<p>요청 시 <strong>multipart/form-data</strong> content-type으로 요쳥해야 합니다.
""",
security = @SecurityRequirement(name = "access-token")
)
@ApiResponses({
@ApiResponse(responseCode = "201"),
@ApiResponse(responseCode = "400", description = "[2800] 악기 설명에 링크(URL)이 첨부되어 있는 경우.", content = @Content)
})
@PostMapping(
headers = API_VERSION_HEADER_NAME + "=" + 1,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE
)
public ResponseEntity<PracticeRoomResponse> createNewPracticeRoomV1(
@AuthenticationPrincipal UserPrincipal userPrincipal,
@ParameterObject @ModelAttribute @Valid CreateNewPracticeRoomRequest createNewPracticeRoomRequest
) {
PracticeRoomDto practiceRoomCreated = practiceRoomCommandService.createNewPracticeRoom(
userPrincipal.getUserId(),
createNewPracticeRoomRequest
);
return ResponseEntity
.created(URI.create("/api/practice-rooms/" + practiceRoomCreated.getId()))
.body(PracticeRoomResponse.from(practiceRoomCreated));
}

}
Loading
Loading