Skip to content

Commit

Permalink
feat: add headquarter api
Browse files Browse the repository at this point in the history
  • Loading branch information
lcaohoanq committed Dec 11, 2024
1 parent ba79dab commit 0306399
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
String.format("%s/wallets/**", apiPrefix),
String.format("%s/warehouses/**", apiPrefix),
String.format("%s/payments/**", apiPrefix),
String.format("%s/headquarters/**", apiPrefix),
"/error"
).permitAll()
// Swagger UI with basic auth
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
public class Regex {

public static final String PASSWORD_REGEX = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$";

public static final String PHONE_NUMBER_REGEX = "^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\\s\\./0-9]*$";

public static final String HEADQUARTER_DOMAIN_URL_REGEX = "^https:\\/\\/shopee\\.\\w{2,3}\\/?(\\.\\w{2}\\/?)?$";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.lcaohoanq.shoppe.domain.headquarter;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.lcaohoanq.shoppe.base.entity.BaseEntity;
import com.lcaohoanq.shoppe.enums.Country;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;

@Entity
@Table(name = "headquarters")
@Getter
@Setter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@JsonPropertyOrder({"id", "region", "domain_url", "created_at", "updated_at"})
public class Headquarter extends BaseEntity {

@Id
@SequenceGenerator(name = "headquarters_seq", sequenceName = "headquarters_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "headquarters_seq")
@Column(name="id", unique=true, nullable=false)
@JsonProperty("id")
private Long id;

@Enumerated(EnumType.STRING)
@Column(name = "region")
private Country region;

@JsonProperty("domain_url")
private String domainUrl;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.lcaohoanq.shoppe.domain.headquarter;

import com.lcaohoanq.shoppe.api.ApiResponse;
import com.lcaohoanq.shoppe.constant.Regex;
import com.lcaohoanq.shoppe.enums.Country;
import com.lcaohoanq.shoppe.exception.MethodArgumentNotValidException;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
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;

@RestController
@RequestMapping("${api.prefix}/headquarters")
@RequiredArgsConstructor
@Slf4j
public class HeadquarterController {

private final IHeadquarterService headquarterService;

@GetMapping("")
public ResponseEntity<ApiResponse<List<Headquarter>>> getAll(){
return ResponseEntity.ok(
ApiResponse.<List<Headquarter>>builder()
.message("Get all headquarters successfully")
.statusCode(HttpStatus.OK.value())
.isSuccess(true)
.data(headquarterService.getAll())
.build());
}

@PostMapping("")
@PreAuthorize("hasRole('ROLE_MANAGER')")
public ResponseEntity<ApiResponse<List<Headquarter>>> create(
@Valid @RequestBody List<HeadquarterDTO> headquarterList,
BindingResult result
){
if(result.hasErrors()){
throw new MethodArgumentNotValidException(result);
}

return ResponseEntity.ok(
ApiResponse.<List<Headquarter>>builder()
.message("Create headquarter successfully")
.statusCode(HttpStatus.OK.value())
.isSuccess(true)
.data(headquarterService.create(headquarterList))
.build());
}

public record HeadquarterDTO(

Country region,
@Pattern(regexp = Regex.HEADQUARTER_DOMAIN_URL_REGEX) String domainUrl

) {}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.lcaohoanq.shoppe.domain.headquarter;

import com.lcaohoanq.shoppe.enums.Country;
import org.springframework.data.jpa.repository.JpaRepository;

public interface HeadquarterRepository extends JpaRepository<Headquarter, Long> {

Boolean existsByRegion(Country region);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.lcaohoanq.shoppe.domain.headquarter;

import com.lcaohoanq.shoppe.domain.headquarter.HeadquarterController.HeadquarterDTO;
import com.lcaohoanq.shoppe.enums.Country;
import com.lcaohoanq.shoppe.exception.MalformBehaviourException;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class HeadquarterService implements IHeadquarterService{

private final HeadquarterRepository headquarterRepository;

@Override
public List<Headquarter> getAll() {
return headquarterRepository.findAll();
}

@Override
public List<Headquarter> create(List<HeadquarterDTO> headquarterList) {

headquarterList.forEach(
headquarterDTO -> {
if (headquarterRepository.existsByRegion(headquarterDTO.region())) {
throw new MalformBehaviourException(String.format("Headquarter %s already exists", headquarterDTO.region()));
}
}
);

headquarterList.forEach(headquarterDTO -> {
headquarterRepository.save(
Headquarter.builder()
.region(headquarterDTO.region())
.domainUrl(headquarterDTO.domainUrl())
.build()
);
});

return getAll();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.lcaohoanq.shoppe.domain.headquarter;

import com.lcaohoanq.shoppe.domain.headquarter.HeadquarterController.HeadquarterDTO;
import java.util.List;

public interface IHeadquarterService {

List<Headquarter> getAll();

List<Headquarter> create(List<HeadquarterDTO> headquarterList);

}
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ private boolean isPublicEndpoint(String path, HttpServletRequest request) {
if (path.startsWith(apiPrefix + "/products")) {
return request.getMethod().equals("GET");
}

// Only allow GET requests for headquarters
if (path.startsWith(apiPrefix + "/headquarters")) {
return request.getMethod().equals("GET");
}

return false;
}
Expand Down

0 comments on commit 0306399

Please sign in to comment.