Skip to content

Commit

Permalink
Merge pull request #19 from KUIT-Couphone/feature/store
Browse files Browse the repository at this point in the history
feat:  store api 개발 및 cd 파일 추가
  • Loading branch information
versatile0010 authored Aug 5, 2023
2 parents 08e30e0 + 2bee20a commit c117f89
Show file tree
Hide file tree
Showing 25 changed files with 586 additions and 34 deletions.
15 changes: 15 additions & 0 deletions appspec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: 0.0
os: linux

files:
- source: /
destination: /home/ubuntu/couphone
permissions:
- object: /home/ubuntu/couphone/
owner: ubuntu
group: ubuntu
hooks:
AfterInstall:
- location: scripts/deploy.sh
timeout: 60
runas: ubuntu
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'mysql:mysql-connector-java:8.0.28'
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'
implementation 'org.projectlombok:lombok:1.18.22'
testImplementation 'junit:junit:4.13.1'
//JWT
implementation 'org.springframework.boot:spring-boot-starter-security'
Expand All @@ -44,6 +43,8 @@ dependencies {
//Marvin for image resizing
implementation 'com.github.downgoon:marvin:1.5.5'
implementation 'com.github.downgoon:MarvinPlugins:1.5.5'
//json
implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
Expand Down
21 changes: 21 additions & 0 deletions scripts/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

REPOSITORY=/home/ubuntu/couphone
cd $REPOSITORY

APP_NAME=couphone
JAR_NAME=$(ls $REPOSITORY/build/libs/ | grep 'SNAPSHOT.jar' | tail -n 1)
JAR_PATH=$REPOSITORY/build/libs/$JAR_NAME

CURRENT_PID=$(pgrep -f $APP_NAME)

if [ -z $CURRENT_PID ]
then
echo "> 종료할 애플리케이션이 없습니다."
else
echo "> kill -9 $CURRENT_PID"
kill -15 $CURRENT_PID
sleep 5
fi

echo "> Deploy - $JAR_PATH "
nohup java -jar $JAR_PATH > /dev/null 2> /dev/null < /dev/null &
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1 @@
rootProject.name = 'Couphone-Server'
rootProject.name = 'couphone-server'
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.couphoneserver.common.datatype;

import lombok.Builder;
import lombok.Data;

@Data
public class Coordinate {
private double longitude;
private double latitude;

@Builder
public Coordinate(double longitude, double latitude) {
this.longitude = longitude;
this.latitude = latitude;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.couphoneserver.common.exception;

import com.example.couphoneserver.common.response.status.ResponseStatus;
import lombok.Getter;

@Getter
public class StoreException extends RuntimeException {
private final ResponseStatus exceptionStatus;

public StoreException(ResponseStatus exceptionStatus) {
super(exceptionStatus.getMessage());
this.exceptionStatus = exceptionStatus;
}

public StoreException(ResponseStatus exceptionStatus, String message) {
super(message);
this.exceptionStatus = exceptionStatus;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.couphoneserver.common.exception_handler;

import com.example.couphoneserver.common.exception.StoreException;
import com.example.couphoneserver.common.response.BaseErrorResponse;
import jakarta.annotation.Priority;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Priority(0)
@RestControllerAdvice
public class StoreExceptionControllerAdvice {

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(StoreException.class)
public BaseErrorResponse handle_StoreException(StoreException e) {
return new BaseErrorResponse(e.getExceptionStatus(), e.getMessage());
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public enum BaseExceptionResponseStatus implements ResponseStatus {
*/
BRAND_NOT_FOUND(7000, HttpStatus.BAD_REQUEST.value(), "브랜드가 존재하지 않습니다."),
DUPLICATE_BRAND_NAME(7001, HttpStatus.BAD_REQUEST.value(), "중복된 브랜드 이름이 존재합니다."),
/**
* 8000: 가게 오류
*/
INVALID_STORE_VALUE(8000,HttpStatus.BAD_REQUEST.value(), "가게 등록에 유효하지 않은 정보입니다."),
COORDINATE_NOT_FOUND(8001,HttpStatus.BAD_REQUEST.value(), "좌표를 찾을 수 없습니다."),
DUPLICATE_STORE_NAME(8002,HttpStatus.BAD_REQUEST.value(), "중복된 지점이 존재합니다."),
NEARBY_STORE_NOT_FOUND(8003,HttpStatus.BAD_REQUEST.value(), "좌표 기준 주변 가게가 없습니다."),

/**
* 9000: 쿠폰 오류
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public CustomAuthenticationProvider customAuthenticationProvider() throws Except
return new CustomAuthenticationProvider(memberDetailService);
}


// 비밀번호 암호화 관련
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class WebConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtAuthenticationInterceptor)
.order(1)
.addPathPatterns("/auth", "/brands", "/users")
.addPathPatterns("/auth", "/brands", "/users","/stores")
.excludePathPatterns("/auth/login");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.example.couphoneserver.controller;

import com.example.couphoneserver.common.annotation.NoAuth;
import com.example.couphoneserver.common.datatype.Coordinate;
import com.example.couphoneserver.common.exception.StoreException;
import com.example.couphoneserver.common.response.BaseResponse;
import com.example.couphoneserver.dto.store.*;
import com.example.couphoneserver.repository.mappingInterface.StoreInfoMapping;
import com.example.couphoneserver.service.StoreService;
import com.example.couphoneserver.utils.CoordinateConverter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.List;

import static com.example.couphoneserver.common.response.status.BaseExceptionResponseStatus.INVALID_STORE_VALUE;
import static com.example.couphoneserver.utils.BindingResultUtils.getErrorMessages;

@Tag(name = "store", description = "가게 관련 API 입니다.")
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/stores")
public class StoreController {
private final StoreService storeService;
private final CoordinateConverter coordinateConverter;

@NoAuth
@PostMapping("")
@Operation(summary = "가게 등록", description = "Request Body에 브랜드 아이디, 매장명, 위도, 경도, 주소를 담아서 보내주세요!")
public BaseResponse<PostStoreResponse> postBrand(@Validated @RequestBody PostStoreRequest request,
BindingResult bindingResult){
if (bindingResult.hasErrors()){
throw new StoreException(INVALID_STORE_VALUE,getErrorMessages(bindingResult));
}
return new BaseResponse<>(storeService.save(request));
}

@NoAuth
@PostMapping("/coordinate")
@Operation(summary = "좌표 변환", description = "Request Body에 주소를 담아 보내면 좌표를 반환합니다.")
public BaseResponse<Coordinate> translateCoordinate(@Validated @RequestBody PostCoordinateRequest request,
BindingResult bindingResult){
if (bindingResult.hasErrors()){
throw new StoreException(INVALID_STORE_VALUE,getErrorMessages(bindingResult));
}
return new BaseResponse<>(coordinateConverter.getCoordinate(request.getAddress()));
}

@PostMapping("/nearby")
@Operation(summary = "좌표 중심 가게 반환", description = "Request Body에 좌표를 담아 보내면 주변 가게 리스트를 반환합니다.")
public BaseResponse<List<PostNearbyStoreResponse>> translateCoordinate(@Validated @RequestBody PostNearbyStoreRequest request,
Principal principal,
BindingResult bindingResult){
if (bindingResult.hasErrors()){
throw new StoreException(INVALID_STORE_VALUE,getErrorMessages(bindingResult));
}
return new BaseResponse<>(storeService.findNearbyStores(principal,request));
}

}
21 changes: 0 additions & 21 deletions src/main/java/com/example/couphoneserver/domain/Address.java

This file was deleted.

22 changes: 16 additions & 6 deletions src/main/java/com/example/couphoneserver/domain/entity/Store.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
package com.example.couphoneserver.domain.entity;

import com.example.couphoneserver.domain.Address;
import com.example.couphoneserver.domain.StoreStatus;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;


@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "STORE")
@ToString
public class Store extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "store_id")
private Long id;
private String name;
@Embedded
private Address address; // 불필요시 제거
private String address;
private Double longitude;
private Double latitude;

Expand All @@ -27,4 +26,15 @@ public class Store extends BaseTimeEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "brand_id")
private Brand brand; // 해당 매장의 브랜드

@Builder
public Store(String name, String address, Double longitude, Double latitude, StoreStatus status, Brand brand) {
this.name = name;
this.address = address;
this.longitude = longitude;
this.latitude = latitude;
this.status = status;
this.brand = brand;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.couphoneserver.dto.store;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class PostCoordinateRequest {
@NotBlank(message = "address: {NotBlank}")
@Schema(example = "서울특별시 광진구 능동로 120")
private String address;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.example.couphoneserver.dto.store;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class PostNearbyStoreRequest {
private static final int radius = 500;
/*
**버튼 있을 경우 ⇒ 지름 1km**
**버튼 없을 경우 ⇒ 반지름 1km**
*/
@NotNull(message = "longitude: {NotNull}")
@Schema(example = "207005.189144674")
private double longitude;
@NotNull(message = "latitude: {NotNull}")
@Schema(example = "449492.810069438")
private double latitude;
@NotNull(message = "is1km: {NotNull}")
@Schema(example="true",description = "반지름이 1km인 경우 true를 넣어주세요")
private Boolean is1km;
@Nullable
@Schema(description = "값을 넣어 보내지 마세요!")
private double distance;

public void setDistance() {
this.distance = is1km?radius*2:radius;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.example.couphoneserver.dto.store;

import com.example.couphoneserver.domain.entity.Brand;
import com.example.couphoneserver.dto.brand.GetBrandResponse;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class PostNearbyStoreResponse {
private Long store_id;
private String name;
private Long brand_id;
private GetBrandResponse getBrandResponse;
private double distance;

@Builder
public PostNearbyStoreResponse(Long store_id, String name, Long brand_id) {
this.store_id = store_id;
this.name = name;
this.brand_id = brand_id;
}
}
Loading

0 comments on commit c117f89

Please sign in to comment.