CustomerCommandController.java
package com.github.jenkaby.bikerental.customer.web.command;
import com.github.jenkaby.bikerental.customer.application.usecase.CreateCustomerUseCase;
import com.github.jenkaby.bikerental.customer.application.usecase.UpdateCustomerUseCase;
import com.github.jenkaby.bikerental.customer.domain.model.Customer;
import com.github.jenkaby.bikerental.customer.web.command.dto.CustomerRequest;
import com.github.jenkaby.bikerental.customer.web.command.mapper.CustomerCommandMapper;
import com.github.jenkaby.bikerental.customer.web.query.dto.CustomerResponse;
import com.github.jenkaby.bikerental.shared.config.OpenApiConfig;
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 jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.UUID;
@Validated
@RestController
@RequestMapping("/api/customers")
@Slf4j
@Tag(name = OpenApiConfig.Tags.CUSTOMERS)
class CustomerCommandController {
private final CreateCustomerUseCase createCustomerUseCase;
private final UpdateCustomerUseCase updateCustomerUseCase;
private final CustomerCommandMapper mapper;
CustomerCommandController(
CreateCustomerUseCase createCustomerUseCase,
UpdateCustomerUseCase updateCustomerUseCase,
CustomerCommandMapper mapper) {
this.createCustomerUseCase = createCustomerUseCase;
this.updateCustomerUseCase = updateCustomerUseCase;
this.mapper = mapper;
}
@PostMapping
@Operation(summary = "Create customer", description = "Creates a new customer profile")
@ApiResponses({
@ApiResponse(responseCode = "201", description = "Customer created",
content = @Content(schema = @Schema(implementation = CustomerResponse.class))),
@ApiResponse(responseCode = "400", description = "Validation error",
content = @Content(schema = @Schema(implementation = ProblemDetail.class))),
@ApiResponse(responseCode = "409", description = "Phone number already exists",
content = @Content(schema = @Schema(implementation = ProblemDetail.class)))
})
public ResponseEntity<CustomerResponse> createCustomer(@Valid @RequestBody CustomerRequest request) {
log.info("[POST] Creating customer with phone: {}", request.phone());
var command = mapper.toCreateCommand(request);
Customer customer = createCustomerUseCase.execute(command);
var response = mapper.toResponse(customer);
log.info("[POST] Customer created successfully with id: {}", customer.getId());
return ResponseEntity.status(HttpStatus.CREATED).body(response);
}
@PutMapping("/{id}")
@Operation(summary = "Update customer", description = "Replaces all fields of an existing customer profile")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Customer updated",
content = @Content(schema = @Schema(implementation = CustomerResponse.class))),
@ApiResponse(responseCode = "400", description = "Validation error",
content = @Content(schema = @Schema(implementation = ProblemDetail.class))),
@ApiResponse(responseCode = "404", description = "Customer not found",
content = @Content(schema = @Schema(implementation = ProblemDetail.class))),
@ApiResponse(responseCode = "409", description = "Phone number already used by another customer",
content = @Content(schema = @Schema(implementation = ProblemDetail.class)))
})
public ResponseEntity<CustomerResponse> updateCustomer(
@Parameter(description = "Customer UUID") @PathVariable("id") UUID id,
@Valid @RequestBody CustomerRequest request) {
log.info("[PUT] Updating customer with id: {}", id);
var command = mapper.toUpdateCommand(id, request);
Customer customer = updateCustomerUseCase.execute(command);
var response = mapper.toResponse(customer);
log.info("[PUT] Customer updated successfully with id: {}", customer.getId());
return ResponseEntity.ok(response);
}
}