CustomerCommandController.java
package com.deveagles.be15_deveagles_be.features.customers.command.application.controller;
import com.deveagles.be15_deveagles_be.common.dto.ApiResponse;
import com.deveagles.be15_deveagles_be.features.auth.command.application.model.CustomUser;
import com.deveagles.be15_deveagles_be.features.customers.command.application.dto.request.CreateCustomerRequest;
import com.deveagles.be15_deveagles_be.features.customers.command.application.dto.request.UpdateCustomerRequest;
import com.deveagles.be15_deveagles_be.features.customers.command.application.dto.response.CustomerCommandResponse;
import com.deveagles.be15_deveagles_be.features.customers.command.application.service.CustomerCommandService;
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.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
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 = "고객 관리", description = "고객 생성, 수정, 삭제 API")
@RestController
@RequestMapping("/customers")
@RequiredArgsConstructor
@Validated
@Slf4j
public class CustomerCommandController {
private final CustomerCommandService customerCommandService;
@Operation(summary = "고객 생성", description = "새로운 고객을 등록합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "201",
description = "고객 생성 성공",
content = @Content(schema = @Schema(implementation = CustomerCommandResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "400",
description = "잘못된 요청 데이터"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "409",
description = "중복된 전화번호")
})
@PostMapping
public ResponseEntity<ApiResponse<CustomerCommandResponse>> createCustomer(
@AuthenticationPrincipal CustomUser user,
@Parameter(description = "고객 생성 정보", required = true) @Valid @RequestBody
CreateCustomerRequest request) {
log.info(
"고객 생성 요청 - 이름: {}, 전화번호: {}, 매장ID: {}",
request.customerName(),
request.phoneNumber(),
user.getShopId());
CustomerCommandResponse response = customerCommandService.createCustomer(request);
return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(response));
}
@Operation(summary = "고객 정보 수정", description = "기존 고객의 정보를 수정합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "고객 정보 수정 성공",
content = @Content(schema = @Schema(implementation = CustomerCommandResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "고객을 찾을 수 없음"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "400",
description = "잘못된 요청 데이터")
})
@PutMapping("/{customerId}")
public ResponseEntity<ApiResponse<CustomerCommandResponse>> updateCustomer(
@AuthenticationPrincipal CustomUser user,
@Parameter(description = "고객 ID", required = true) @PathVariable Long customerId,
@Parameter(description = "고객 수정 정보", required = true) @Valid @RequestBody
UpdateCustomerRequest request) {
log.info("고객 정보 수정 요청 - 고객ID: {}, 이름: {}", customerId, request.customerName());
// customerId를 request에 설정
UpdateCustomerRequest updatedRequest =
new UpdateCustomerRequest(
customerId,
request.customerName(),
request.phoneNumber(),
request.memo(),
request.gender(),
request.channelId(),
request.staffId(),
request.customerGradeId(),
request.birthdate(),
request.marketingConsent(),
request.notificationConsent());
CustomerCommandResponse response = customerCommandService.updateCustomer(updatedRequest);
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(summary = "고객 삭제", description = "고객을 소프트 삭제합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "고객 삭제 성공"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "고객을 찾을 수 없음"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "400",
description = "이미 삭제된 고객")
})
@DeleteMapping("/{customerId}")
public ResponseEntity<ApiResponse<String>> deleteCustomer(
@AuthenticationPrincipal CustomUser user,
@Parameter(description = "고객 ID", required = true) @PathVariable Long customerId) {
log.info("고객 삭제 요청 - 고객ID: {}, 매장ID: {}", customerId, user.getShopId());
customerCommandService.deleteCustomer(customerId, user.getShopId());
return ResponseEntity.ok(ApiResponse.success("고객이 성공적으로 삭제되었습니다."));
}
@Operation(summary = "마케팅 동의 변경", description = "고객의 마케팅 수신 동의 상태를 변경합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "마케팅 동의 상태 변경 성공",
content = @Content(schema = @Schema(implementation = CustomerCommandResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "고객을 찾을 수 없음")
})
@PatchMapping("/{customerId}/marketing-consent")
public ResponseEntity<ApiResponse<CustomerCommandResponse>> updateMarketingConsent(
@AuthenticationPrincipal CustomUser user,
@Parameter(description = "고객 ID", required = true) @PathVariable Long customerId,
@Parameter(description = "마케팅 동의 여부", required = true) @RequestParam Boolean consent) {
log.info("마케팅 동의 변경 요청 - 고객ID: {}, 매장ID: {}, 동의: {}", customerId, user.getShopId(), consent);
CustomerCommandResponse response =
customerCommandService.updateMarketingConsent(customerId, user.getShopId(), consent);
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(summary = "알림 동의 변경", description = "고객의 알림 수신 동의 상태를 변경합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "알림 동의 상태 변경 성공",
content = @Content(schema = @Schema(implementation = CustomerCommandResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "고객을 찾을 수 없음")
})
@PatchMapping("/{customerId}/notification-consent")
public ResponseEntity<ApiResponse<CustomerCommandResponse>> updateNotificationConsent(
@AuthenticationPrincipal CustomUser user,
@Parameter(description = "고객 ID", required = true) @PathVariable Long customerId,
@Parameter(description = "알림 동의 여부", required = true) @RequestParam Boolean consent) {
log.info("알림 동의 변경 요청 - 고객ID: {}, 매장ID: {}, 동의: {}", customerId, user.getShopId(), consent);
CustomerCommandResponse response =
customerCommandService.updateNotificationConsent(customerId, user.getShopId(), consent);
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(summary = "방문 추가", description = "고객의 방문 정보를 추가합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "방문 추가 성공",
content = @Content(schema = @Schema(implementation = CustomerCommandResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "고객을 찾을 수 없음")
})
@PatchMapping("/{customerId}/visit")
public ResponseEntity<ApiResponse<CustomerCommandResponse>> addVisit(
@AuthenticationPrincipal CustomUser user,
@Parameter(description = "고객 ID", required = true) @PathVariable Long customerId,
@Parameter(description = "매출액", required = true) @RequestParam Integer revenue) {
log.info("방문 추가 요청 - 고객ID: {}, 매장ID: {}, 매출: {}", customerId, user.getShopId(), revenue);
CustomerCommandResponse response =
customerCommandService.addVisit(customerId, user.getShopId(), revenue);
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(summary = "노쇼 추가", description = "고객의 노쇼 정보를 추가합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "노쇼 추가 성공",
content = @Content(schema = @Schema(implementation = CustomerCommandResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "고객을 찾을 수 없음")
})
@PatchMapping("/{customerId}/noshow")
public ResponseEntity<ApiResponse<CustomerCommandResponse>> addNoshow(
@AuthenticationPrincipal CustomUser user,
@Parameter(description = "고객 ID", required = true) @PathVariable Long customerId) {
log.info("노쇼 추가 요청 - 고객ID: {}, 매장ID: {}", customerId, user.getShopId());
CustomerCommandResponse response =
customerCommandService.addNoshow(customerId, user.getShopId());
return ResponseEntity.ok(ApiResponse.success(response));
}
}