Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
14 changes: 0 additions & 14 deletions .github/ISSUE_TEMPLATE/백엔드-이슈.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ public ResponseEntity<?> createStore(@Valid @RequestBody StoreCreateRequest requ
@GetMapping("/{storeId}")
@Operation(summary = "주점 조회", description = "주점 ID로 주점을 조회합니다.")
@ApiResponse(responseCode = "200", description = "주점 조회 성공")
public ResponseEntity<?> getStoreById(@PathVariable Long storeId,@AuthenticationPrincipal MemberDetails memberDetails) {
public ResponseEntity<?> getStoreById(@PathVariable Long storeId, @AuthenticationPrincipal MemberDetails memberDetails) {
return ResponseEntity
.status(HttpStatus.OK)
.body(
ApiUtils.success(
storeService.getStoreByStoreId(storeId,memberDetails)
storeService.getStoreByStoreId(storeId, memberDetails)
)
);
}
Expand All @@ -84,7 +84,7 @@ public ResponseEntity<?> updateStore(
@DeleteMapping("/{storeId}")
@Operation(summary = "주점 삭제", description = "주점 ID로 주점을 삭제합니다.")
@ApiResponse(responseCode = "200", description = "주점 삭제 성공")
public ResponseEntity<?> deleteStore(@PathVariable Long storeId,@AuthenticationPrincipal MemberDetails memberDetails) {
public ResponseEntity<?> deleteStore(@PathVariable Long storeId, @AuthenticationPrincipal MemberDetails memberDetails) {
return ResponseEntity
.ok()
.body(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.nowait.applicationadmin.storePayment.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
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.RestController;

import com.nowait.applicationadmin.storePayment.dto.StorePaymentCreateRequest;
import com.nowait.applicationadmin.storePayment.dto.StorePaymentCreateResponse;
import com.nowait.applicationadmin.storePayment.dto.StorePaymentUpdateRequest;
import com.nowait.applicationadmin.storePayment.service.StorePaymentService;
import com.nowait.common.api.ApiUtils;
import com.nowait.domaincorerdb.user.entity.MemberDetails;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Tag(name = "Store Payment API", description = "주점 결제 정보 API")
@RestController
@RequestMapping("admin/store-payments")
@RequiredArgsConstructor
@Slf4j
public class StorePaymentController {

private final StorePaymentService storePaymentService;

@PostMapping("/create")
@Operation(summary = "주점 결제 Url 등록 및 생성", description = "새로운 주점 결제 정보를 생성합니다.")
@ApiResponse(responseCode = "201", description = "주점 결제 정보 생성 성공")
public ResponseEntity<?> createStorePayment(@Valid @RequestBody StorePaymentCreateRequest request, @AuthenticationPrincipal MemberDetails memberDetails) {
StorePaymentCreateResponse response = storePaymentService.createStorePayment(request, memberDetails);

return ResponseEntity
.status(HttpStatus.CREATED)
.body(
ApiUtils.success(
response
)
);
}

@GetMapping()
@Operation(summary = "주점 결제 정보 조회", description = "인증된 사용자의 주점 결제 정보를 조회합니다.")
@ApiResponse(responseCode = "200", description = "주점 결제 정보 조회 성공")
public ResponseEntity<?> getStorePaymentByStoreId(@AuthenticationPrincipal MemberDetails memberDetails) {
return ResponseEntity
.status(HttpStatus.OK)
.body(
ApiUtils.success(
storePaymentService.getStorePaymentByStoreId(memberDetails)
)
);
}

@PatchMapping("/update")
@Operation(summary = "주점 결제 정보 수정", description = "주점 결제 정보를 수정합니다.")
@ApiResponse(responseCode = "200", description = "주점 결제 정보 수정 성공")
public ResponseEntity<?> updateStorePayment(@RequestBody StorePaymentUpdateRequest request, @AuthenticationPrincipal MemberDetails memberDetails) {
return ResponseEntity
.status(HttpStatus.OK)
.body(
ApiUtils.success(
storePaymentService.updateStorePayment(request, memberDetails)
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.nowait.applicationadmin.storePayment.dto;

import com.nowait.domaincorerdb.storepayment.entity.StorePayment;

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

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class StorePaymentCreateRequest {

private String tossUrl;
private String kakaoPayUrl;
private String naverPayUrl;
Comment on lines +14 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

결제 URL 필드들에 대한 검증이 필요합니다.

결제 URL 필드들이 null 값을 허용하는지 명확하지 않으며, 비즈니스 로직에 따라 필수 값일 수 있습니다.

다음과 같이 검증 어노테이션을 추가하는 것을 권장합니다:

+	@NotBlank(message = "Toss URL은 필수입니다")
	private String tossUrl;
+	@NotBlank(message = "KakaoPay URL은 필수입니다")
	private String kakaoPayUrl;
+	@NotBlank(message = "NaverPay URL은 필수입니다")
	private String naverPayUrl;

또는 선택적 필드라면 명시적으로 문서화하거나 null 체크를 추가해야 합니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private String tossUrl;
private String kakaoPayUrl;
private String naverPayUrl;
@NotBlank(message = "Toss URL은 필수입니다")
private String tossUrl;
@NotBlank(message = "KakaoPay URL은 필수입니다")
private String kakaoPayUrl;
@NotBlank(message = "NaverPay URL은 필수입니다")
private String naverPayUrl;
🤖 Prompt for AI Agents
In
nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/storePayment/dto/StorePaymentCreateRequest.java
around lines 15 to 17, the payment URL fields tossUrl, kakaoPayUrl, and
naverPayUrl lack validation annotations. Determine if these fields are mandatory
or optional based on business requirements. If mandatory, add appropriate
validation annotations such as @NotNull or @NotBlank to enforce non-null values.
If optional, explicitly document their nullable nature or add null checks in the
business logic to handle absent values safely.


public StorePayment toEntity(Long storeId) {
return StorePayment.builder()
.storeId(storeId)
.tossUrl(tossUrl)
.kakaoPayUrl(kakaoPayUrl)
.naverPayUrl(naverPayUrl)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.nowait.applicationadmin.storePayment.dto;

import java.time.LocalDateTime;

import com.nowait.domaincorerdb.storepayment.entity.StorePayment;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Getter
@AllArgsConstructor
@Builder
public class StorePaymentCreateResponse {

private Long paymentMethodId;
private Long storeId;
private String tossUrl;
private String kakaoPayUrl;
private String naverPayUrl;
private LocalDateTime createdAt;

public static StorePaymentCreateResponse fromEntity(StorePayment storePayment) {
return StorePaymentCreateResponse.builder()
.paymentMethodId(storePayment.getPaymentMethodId())
.storeId(storePayment.getStoreId())
.tossUrl(storePayment.getTossUrl())
.kakaoPayUrl(storePayment.getKakaoPayUrl())
.naverPayUrl(storePayment.getNaverPayUrl())
.createdAt(storePayment.getCreatedAt())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.nowait.applicationadmin.storePayment.dto;

import java.time.LocalDateTime;

import com.nowait.domaincorerdb.storepayment.entity.StorePayment;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Getter
@AllArgsConstructor
@Builder
public class StorePaymentReadDto {
private Long paymentMethodId;
private Long storeId;
private String tossUrl;
private String kakaoPayUrl;
private String naverPayUrl;
private LocalDateTime createdAt;

public static StorePaymentReadDto fromEntity(StorePayment storePayment) {
return StorePaymentReadDto.builder()
.paymentMethodId(storePayment.getPaymentMethodId())
.storeId(storePayment.getStoreId())
.tossUrl(storePayment.getTossUrl())
.kakaoPayUrl(storePayment.getKakaoPayUrl())
.naverPayUrl(storePayment.getNaverPayUrl())
.createdAt(storePayment.getCreatedAt())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.nowait.applicationadmin.storePayment.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class StorePaymentUpdateRequest {
private String tossUrl;
private String kakaoPayUrl;
private String naverPayUrl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.nowait.applicationadmin.storePayment.service;

import com.nowait.applicationadmin.storePayment.dto.StorePaymentCreateRequest;
import com.nowait.applicationadmin.storePayment.dto.StorePaymentCreateResponse;
import com.nowait.applicationadmin.storePayment.dto.StorePaymentReadDto;
import com.nowait.applicationadmin.storePayment.dto.StorePaymentUpdateRequest;
import com.nowait.domaincorerdb.user.entity.MemberDetails;

public interface StorePaymentService {

StorePaymentCreateResponse createStorePayment(StorePaymentCreateRequest request, MemberDetails memberDetails);
StorePaymentReadDto getStorePaymentByStoreId(MemberDetails memberDetails);
StorePaymentReadDto updateStorePayment(StorePaymentUpdateRequest request, MemberDetails memberDetails);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.nowait.applicationadmin.storePayment.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.nowait.applicationadmin.storePayment.dto.StorePaymentCreateRequest;
import com.nowait.applicationadmin.storePayment.dto.StorePaymentCreateResponse;
import com.nowait.applicationadmin.storePayment.dto.StorePaymentReadDto;
import com.nowait.applicationadmin.storePayment.dto.StorePaymentUpdateRequest;
import com.nowait.common.enums.Role;
import com.nowait.domaincorerdb.storepayment.entity.StorePayment;
import com.nowait.domaincorerdb.storepayment.exception.StorePaymentAlreadyExistsException;
import com.nowait.domaincorerdb.storepayment.exception.StorePaymentCreationUnauthorizedException;
import com.nowait.domaincorerdb.storepayment.exception.StorePaymentNotFoundException;
import com.nowait.domaincorerdb.storepayment.exception.StorePaymentParamEmptyException;
import com.nowait.domaincorerdb.storepayment.exception.StorePaymentUpdateUnauthorizedException;
import com.nowait.domaincorerdb.storepayment.exception.StorePaymentViewUnauthorizedException;
import com.nowait.domaincorerdb.storepayment.repository.StorePaymentRepository;
import com.nowait.domaincorerdb.user.entity.MemberDetails;
import com.nowait.domaincorerdb.user.entity.User;
import com.nowait.domaincorerdb.user.exception.UserNotFoundException;
import com.nowait.domaincorerdb.user.repository.UserRepository;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class StorePaymentServiceImpl implements StorePaymentService {

private final StorePaymentRepository storePaymentRepository;
private final UserRepository userRepository;

@Override
@Transactional
public StorePaymentCreateResponse createStorePayment(StorePaymentCreateRequest request, MemberDetails memberDetails) {
if (request == null) throw new StorePaymentParamEmptyException();

User user = userRepository.findById(memberDetails.getId()).orElseThrow(UserNotFoundException::new);
Long storeId = user.getStoreId();
if (storePaymentRepository.findByStoreId(storeId).isPresent()) {
throw new StorePaymentAlreadyExistsException();
}
if (!Role.SUPER_ADMIN.equals(user.getRole()) && !user.getStoreId().equals(storeId)) {
throw new StorePaymentCreationUnauthorizedException();
}
StorePayment toSave = request.toEntity(storeId);
StorePayment saved = storePaymentRepository.save(toSave);

return StorePaymentCreateResponse.fromEntity(saved);
}

@Override
@Transactional(readOnly = true)
public StorePaymentReadDto getStorePaymentByStoreId(MemberDetails memberDetails) {
if (memberDetails == null) throw new StorePaymentParamEmptyException();

User user = userRepository.findById(memberDetails.getId()).orElseThrow(UserNotFoundException::new);
Long storeId = user.getStoreId();
if (!Role.SUPER_ADMIN.equals(user.getRole()) && !user.getStoreId().equals(storeId)) {
throw new StorePaymentViewUnauthorizedException();
Comment thread
Jjiggu marked this conversation as resolved.
}
StorePayment storePayment = storePaymentRepository.findByStoreId(storeId)
.orElseThrow(StorePaymentNotFoundException::new);

return StorePaymentReadDto.fromEntity(storePayment);
}

@Override
@Transactional
public StorePaymentReadDto updateStorePayment(StorePaymentUpdateRequest request, MemberDetails memberDetails) {
if (request == null) throw new StorePaymentParamEmptyException();

User user = userRepository.findById(memberDetails.getId()).orElseThrow(UserNotFoundException::new);
Long storeId = user.getStoreId();
if (!Role.SUPER_ADMIN.equals(user.getRole()) && !user.getStoreId().equals(storeId)) {
throw new StorePaymentUpdateUnauthorizedException();
Comment thread
Jjiggu marked this conversation as resolved.
}
StorePayment storePayment = storePaymentRepository.findByStoreId(storeId)
.orElseThrow(StorePaymentNotFoundException::new);

storePayment.updatePaymentMethodUrl(
request.getTossUrl(),
request.getKakaoPayUrl(),
request.getNaverPayUrl()
);
storePaymentRepository.save(storePayment);

return StorePaymentReadDto.fromEntity(storePayment);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.nowait.applicationuser.storepayment.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.nowait.applicationuser.storepayment.service.StorePaymentService;
import com.nowait.common.api.ApiUtils;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Tag(name = "Store Payment API", description = "주점 결제 정보 API")
@RestController
@RequestMapping("v1/store-payments")
@RequiredArgsConstructor
@Slf4j
public class StorePaymentController {

private final StorePaymentService storePaymentService;

@GetMapping(("/{storeId}"))
@Operation(summary = "주점 결제 정보 조회", description = "주점 ID로 주점 결제 정보를 조회합니다.")
@ApiResponse(responseCode = "200", description = "주점 결제 정보 조회 성공")
public ResponseEntity<?> getStorePaymentByStoreId(@PathVariable Long storeId) {
return ResponseEntity
.status(HttpStatus.OK)
.body(
ApiUtils.success(
storePaymentService.getStorePaymentByStoreId(storeId)
)
);
}
}
Loading