[241114 TIL] AI 검증 비즈니스 프로젝트

카테고리, 가게, 리뷰 CRUD API 구현

  • 코드리뷰 수정사항 반영
  • Soft Delete 수정
  • 리뷰 CRUD 추가 기능 구현

코드리뷰 수정사항 반영

 

✔️ 카테고리 아이디 null 체크 부분 ➡️ 공백값도 같이 체크 가능하게 변경

 

  • 수정 전
if (categoryId == null) 

 

  • 수정 후
if (!StringUtils.hasText(String.valueOf(categoryId)))

 

StringUtils.hasText 이용

 

내부 로직

public static boolean hasText(@Nullable String str) {
    return str != null && !str.isEmpty() && containsText(str);
}

private static boolean containsText(CharSequence str) {
    int strLen = str.length();
    
    for(int i = 0; i < strLen; ++i) {
      if (!Character.isWhitespace(str.charAt(i))) {
        return true;
      }
    }
    
    return false;
}

 

  • str 이 null 인가
  • str이 빈 문자열 ("")인가
  • str이 공백으로만(whitespace) 이루어져 있는가 

[241113 TIL] AI 검증 비즈니스 프로젝트

카테고리, 가게, 리뷰 CRUD API 구현

 

  • API 동작 확인
  • 리뷰 평점 스케줄러 적용
  • Soft Delete 적용

API 동작 확인

⚠️ 트러블슈팅 ⚠️

 

1. 문제 정의

  • 가게 생성 API 동작 확인 중 에러 발생 (POST)
org.springframework.dao.DataIntegrityViolationException: could not execute statement [Duplicate entry 'b\xDD\x98\xF0\xBD\x8E\x11\xED\x93\xAB2P\x96\xB3\x9FG' for key 'p_stores.UK260ia2wautdp3fq67hyklg3cu'] [/* insert for com.sparta.gourmate.domain.store.entity.Store */insert into p_stores (average_rating,category_id,created_at,created_by,deleted_at,deleted_by,is_deleted,location,name,updated_at,updated_by,user_id,id) values (?,?,?,?,?,?,?,?,?,?,?,?,?)]; SQL [/* insert for com.sparta.gourmate.domain.store.entity.Store */insert into p_stores (average_rating,category_id,created_at,created_by,deleted_at,deleted_by,is_deleted,location,name,updated_at,updated_by,user_id,id) values (?,?,?,?,?,?,?,?,?,?,?,?,?)]; constraint [p_stores.UK260ia2wautdp3fq67hyklg3cu]

 

 

  • org.springframework.dao.DataIntegrityViolationException
    • 데이터베이스에서 중복된 값이 삽입되려고 했을 때 발생하는 오류

2. 원인 추론

 

1) 가게 엔티티에 중복된 값을 허용하지 않는 컬럼 확인

  • id - UUID 로 자동 생성되므로 고려 대상 아님
  • user_id - 같은 유저로 여러 개의 가게 생성이 가능됨을 확인
  • category_id - 같은 카테고리의 가게를 생성하려고 할 때 위의 에러 발생

2) 카테고리 엔티티와 가게 엔티티의 연관관계 확인

  • 현재 카테고리와 가게의 연관관계 - @OneToOne
  • 한 가게 당 하나의 카테고리를 갖기에 위 연관관계 설정

3) 연관관계 고려

  • @OneToOne
    • 한 가게가 하나의 카테고리만 가질 수 있다는 것 의미
    • 예를 들어, "피자 가게" 하나가 "피자 카테고리"를 가진다면 적합
    • 여러 가게가 동일한 카테고리를 공유할 수 있다면, @OneToOne 설정은 적합하지 않음

 

 

3. 해결 방안 및 결과

  • 연관관계 변경
    • 여러 개의 가게가 하나의 카테고리를 공유 ➡️ @ManyToOne 이 적합
    • 가게 엔티티에서 @ManyToOne 사용하고, 카테고리 엔티티에서 @OneToMany 사용
@Entity
public class Store {
	// 중략
    @ManyToOne
    @JoinColumn(name = "category_id")
    private Category category;
   
}



@Entity
public class Category {
	// 중략
    @OneToMany(mappedBy = "category")
    private List<Store> storeList;
    
}
  • 연관관계 변경 후 같은 카테고리를 가진 가게 생성 성공!



[241112 TIL] AI 검증 비즈니스 프로젝트

CRUD 구현


Spring Data Jpa

Containing

  • 컬럼에 특정 문자열이 포함된 엔티티 검색
  • SQL Qurey 의 LIKE 와 같음
// SELECT * FROM Store WHERE category_id = categoryID AND name LIKE %query%;
Page<Store> storeList = storeRepository.findByCategoryIdAndNameContaining(categoryId, query, pageable);

 


 

POSTMAN 

⚠️ 트러블슈팅 ⚠️

 

1. 문제 정의

  • API 테스트 진행을 위해 POSTMAN 을 사용하여 회원가입 진행 중 에러 발생
{
    "code": null,
    "message": "Required request body is missing: public com.sparta.gourmate.domain.user.dto.UserResponseDto com.sparta.gourmate.domain.user.controller.UserController.createUser(com.sparta.gourmate.domain.user.dto.SignupRequestDto)"
}

 

 

2. 원인 추론

  • POSTMAN POST 상황

 

1) 입력 조건을 만족하지 못했나?

@NotBlank
@Size(min = 4, max = 10)
@Pattern(regexp = "^[a-z0-9]+$")
private String username;

@NotBlank
@Size(min = 8, max = 15)
@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[!@#$%^&*)(+=._-])[a-zA-Z\\d!@#$%^&*)(+=._-]+$")
private String password;

@Email
@NotBlank
private String email;

 

  • 모든 조건 만족

 

2) NOTNULL 값만 작성하고 나머지는 작성하지 않아서 그런가?

  • 회원가입(SignupRequestDto)에 필요한 모든 값을 작성해도 같은 에러 발생

 

3) @RequestBody 가 제대로 작동되고 있는지?

  • 모든 값을 Query Params 으로 넘기고 있음을 확인

 

3. 해결 방안 및 결과

  • Boby - JSON raw 로 값 넘겨주기
{
    "username" : "customer",
    "password" : "customer1!",
    "email" : "customer@naver.com",
    "isAdmin" : false,
    "isOwner" : false

}

 

  • 성공적으로 POST
{
    "id": 3,
    "username": "customer",
    "email": "customer@naver.com",
    "role": "CUSTOMER"
}

 

 

 

사실 너무 어이없는 실수라 트러블슈팅으로 적어도 되나~ 싶지만~

그래도 나는 바보라서 똑같은 실수를 하게 될 수도 있으니 일단 적어놓자...

 


POSTMAN 

로그인 후 토큰 처리

 

Login - POST username, password Authorization

Response Header >  Authorization 값 복사

 

Request Header 에 Authorization 입력


[241111 TIL] AI 검증 비즈니스 프로젝트

[Github] IntelliJ 에서 Git Branch 생성하고 Merge 하기


branch 생성

  1. develop 에서 Update Project
  2. develop 에서 New Branch from 'origin/devlop' 클릭 후 branch 생성
  3. 생성한 branch 로 Checkout

branch 작업 후 Merge

  1. develop 에서 Update Project
  2. 작업하던 branch 로 Checkout
  3. Git > Merge 클릭

 




 

[241104 TIL] 

AI 검증 비즈니스 프로젝트

S.A (Starting Assignments) 작성

  • API 명세서
  • 테이블 명세서
  • ERD 명세서
  • 인프라 설계서

 

테이블 명세서 - (메뉴, 주문, 주문 항목, 결제, AI)

  • 기본값, PK, FK 항목을 따로 만드는 게 나을지?
  • 데이터 감사 로그: 모든 정보에 생성일, 생성 아이디, 수정일, 수정 아이디, 삭제일, 삭제 아이디를 포함
    • 생성자(username) → 생성 아이디(user_id) 로 변경
  • 결제 테이블(p_payments) - amount(결제 금액)
    • 주문 테이블(p_orders) - total_amount(총 가격) 랑 같은거?
    • 할인, 쿠폰 등 적용한다고 생각하면 구분하는 게 맞는 듯
  • 결제, AI 테이블 - 생성만 / 수정, 삭제는 불가능할 것 같음

[241105 TIL] 

My Select Shop 프로젝트

  • 구현 기능 점검
  • 카카오 로그인 구현
  • Spring AOP, Timer 적용
  • 예외처리

구현 기능 점검

⚠️ 트러블슈팅 ⚠️

 

1. 문제 정의

  • 관심 상품 폴더 기능 점검중, 폴더 추가가 제대로 이뤄지지 않는 문제 발견
    • 관심 상품에서 폴더 추가 버튼을 누르면 작동하지 않음
    • 폴더 추가를 하면 중복하지 않는 폴더명임에도 중복된 폴더라는 알림이 뜨지만, 폴더 추가는 됨

 

2. 원인 추론

 

ERROR

org.thymeleaf.exceptions.TemplateInputException: Error resolving template [api/folders], template might not exist or might not be accessible by any of the configured Template Resolvers

 

 

 

1. thymeleaf exception 이 발생했기에 front 문제인가?

  • console 오류를 확인해보니 basic.js 파일의 folders.map 이 제대로 동작하지 않음을 확인
  • front 의 문제는 아니고, folder 를 제대로 넘겨받지 못하는 문제인듯함

 

2. FolderController 에 API 를 잘못 작성했나?

  • 구글링해보니 API 주소를 잘못 적은 경우가 다반사이길래 확인해보니, 모두 정확하게 적혀있음

 

3. FolderService 에 폴더 추가 함수 자체가 잘못 작성됐나?

  • 조회 함수에서 print를 찍어보니 folderList 가 제대로 생성되지 않음을 확인

  • 추가 함수에서 print를 찍어보니 print 안됨 -> addFolders 함수 안으로 들어가지 못함

 

➡️  folder 가 제대로 넘어오지 못함

 

 

4. FolderController 에서는 folder 가 제대로 생성되는지?

  • PostMapping 에서 print를 찍어보니 print 안됨

 

➡️ @RequestBody 가 제대로 동작하지 않음

 

 

5. @RequestBody 사용을 위한 애노테이션이 제대로 작성되어 있는지?

  • @Controller 만 작성되어 있음을 확인!!

 

3. 해결 방안 및 결과 

  • @Controller -> @RestController
    • @RequestBody 를 사용하려면 @RestController 혹은 @Controller + @ResponseBody 가 명시되어야 함!!
  • @RestController 변경 후 폴더 추가가 제대로 동작됨을 확인

 


카카오 로그인 구현

⚠️ 트러블슈팅 ⚠️

 

1. 문제 정의

  • 카카오 로그인 앱 관리자 설정 오류

 

2. 원인 추론

 

1. Redirect URI 가 잘못 작성되었나?

  • 카카오에 등록한 Redirect URI : http://localhost:8080/api/user/kakao/callback
  • KakaoService 에 작성한 Redirect URI : http://localhost:8080/api/user/login-page/api/user/kakao/callback

 

3. 해결 방안 및 결과

  • redirect_uri 수정
    • http://localhost:8080/api/user/login-page/api/user/kakao/callback
      -> http://localhost:8080/api/user/kakao/callback
  • 수정 후 카카오 로그인 성공!

 

+ Recent posts