CodeBloom - AI를 활용한 주문 관리 플랫폼 프로젝트 결과물

2024. 11. 19. 10:38· 자바 심화 2기
목차
  1. 1. 프로젝트 간단 소개
  2. 2. `ERD`, 인프라 설계서
  3. 3. 주요 기능 구현 및 기술 도입 이유
  4. 3 - 1. `AuditorAware`를 사용하여 사용자 정보 자동 입력
  5. 3 - 2. `AI - GPT API`를 사용하여 메뉴 설명 자동 생성
  6. 2 - 3. `Junit5`를 사용하여 자동화된 테스트
  7. 2 - 4. `Scheduler`를 사용하여 가게의 평점 갱신
  8. 3. 어려웠던 점, 그에 대한 해결 방안
  9. 3 - 1. `AuditorAware` 를 사용하여 사용자 정보 자동 입력
  10. 4. 잘된 점과 그 이유
  11. 4 - 1. 깃허브를 이용한 협업
  12. 5. 협업간 발생한 문제와 해결방안
  13. 5 - 1. `DTO` 클래스 명칭 통일 문제
  14. 5 - 2. `Repository` 사용 방식
  15. 5 - 3. `PR` 생성 방식
  16. 6. 팀 프로젝트를 진행하며 느낀 점
  17. 은우
  18. 해성
  19. 시원

https://github.com/Griotold/CodeBloom_DeliveryApp

 

GitHub - Griotold/CodeBloom_DeliveryApp

Contribute to Griotold/CodeBloom_DeliveryApp development by creating an account on GitHub.

github.com

 

1. 프로젝트 간단 소개

스프링부트 개발환경을 통해 '00의 민족'과 같은 주문 관리 플랫폼의 백엔드 구축했습니다.

생성형 인공지능 서비스(`API`)를 활용하여 `AI` 기능 적용했습니다.

 

2. `ERD`, 인프라 설계서

ERD

특징적인 것은 "음식점 허가 요청(`p_store_request`)"라는 테이블을 따로 만들어서 

가게 생성시 곧장 "음식점(`p_store`)" 테이블에 생성하지 않고

먼저 음식점 허가 요청에 생성한 뒤,

관리자가 승인 또는 반려하는 관리자 승인 프로세스를 도입했습니다.

 

인프라 설계서

`AWS EC2` 에 서버를 띄웠고, `RDS`에 데이터베이스를 구축하였습니다.

 

3. 주요 기능 구현 및 기술 도입 이유

3 - 1. `AuditorAware`를 사용하여 사용자 정보 자동 입력

`AuditorAware`를 사용하여, 사용자 정보를 자동 입력되게 했습니다.

데이터베이스에 데이터를 생성하거나 수정할 때,

현재 로그인된 사용자의 userId가 자동으로 입력되도록 했습니다.

@Slf4j
public class AuditorAwareImpl implements AuditorAware<String> {

    @Override
    public Optional<String> getCurrentAuditor() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (null == authentication || !authentication.isAuthenticated()) {
            return null;
        }

        //사용자 환경에 맞게 로그인한 사용자의 정보를 불러온다.
        log.info("authentication.getName(): {}", authentication.getName());
        if (authentication.getName().equals("anonymousUser")) {
            return Optional.of("anonymous");
        }

        return Optional.of(authentication.getName());
    }
}

 

3 - 2. `AI - GPT API`를 사용하여 메뉴 설명 자동 생성

`GPT API`를 사용한 이유는 `GPT-4o`의 벤치마크 결과를 확인하고 선택하였습니다.

 

퀄리티, 속도, 가격 측면을 고려하여 높은 효율을 낼 수 있는 `GPT-4o` 버전을 선택하게 되었습니다.

 

2 - 3. `Junit5`를 사용하여 자동화된 테스트

결제 도메인에 결제시도 로직의 결제 성공 케이스, 결제 실패 케이스를 테스트했습니다.

- `PaymentServiceTest`

`Service Layer`와 `Repository Layer` 통합 테스트이고,

@Transactional
@ActiveProfiles("test")
@SpringBootTest
class PaymentServiceTest {

    @Autowired
    PaymentService paymentService;

    @Autowired
    PaymentRepository paymentRepository;

    @Autowired
    OrderRepository orderRepository;

    @Autowired
    UserRepository userRepository;

    @Autowired
    AddressRepository addressRepository;

    @Autowired
    StoreCategoryRepository storeCategoryRepository;

    @Autowired
    LocationRepository locationRepository;

    @Autowired
    StoreRepository storeRepository;

    @MockBean
    PgClient pgClient;         // Mocking!

    @BeforeEach
    void setUp() {
        // Payment 외 부수적인 엔티티 ex) User, Order, Store 등등...
    }
    
    @DisplayName("결제 성공")
    @Test
    void createPayment_success() {...}
    
    @DisplayName("없는 주문을 결제하려고하면 결제 실패한다.")
    @Test
    void createPayment_fail_1() {...}
    
    @DisplayName("주문자와 결제요청자가 다르면 결제 실패한다.")
    @Test
    void createPayment_fail_2() {...}
    
    @DisplayName("외부 결제 시스템에서 결제 승인 실패 시 예외 발생")
    @Test
    void createPayment_fail_3() {...}
    
    @DisplayName("CARD 또는 CASH가 아니면 결제 실패")
    @Test
    void createPayment_fail_4() {...}
    
    @DisplayName("NHN, TOSS, KG가 아니면 결제 실패")
    @Test
    void createPayment_fail_5() {...}
    
    // 생성을 위한 private method 들...
}

외부 `PG`사를 호출하는 `PgClient`는 `Mocking` 처리하였고,

`@BeforeEach` 에서 `Payment` 외 부수적인 엔티티를 생성하도록 했습니다.

 

2 - 4. `Scheduler`를 사용하여 가게의 평점 갱신

1시간 마다 가게에 달린 리뷰들의 점수를 계산하여 가게의 평점을 갱신하도록 구현했습니다.

가게의 평점은 실시간성이 중요하지 않다고 판단하였습니다.

 

2 - 4 - 1. `Scheduler`의 장점

리뷰가 등록/수정/삭제될 때마다 평점을 계산하지 않아도 되어 서비스 응답 시간이 개선됩니다.

 

2 - 4 - 2. `Scheduler`의 단점

실시간성이 떨어집니다. (최대 1시간의 지연 발생)

스케줄러가 실행되는 동안 `DB` 부하가 집중될 수 있습니다.

 

2 - 4 - 3. 대안으로 고려할 수 있는 방법

1. 리뷰 변경시 즉시 평점을 업데이트

2. Redis 캐시를 활용한 하이브리드 방식 (실시간 캐시 + 주기적 `DB` 업데이트)

    a. 리뷰 추가/수정/삭제시 `Redis` 캐시에 해당 가게의 평점을 즉시 갱신

    b. 평점 조회시

        i. `Redis` 캐시에서 먼저 조회

        ii. 캐시에 없으면 `DB`에서 조회후 `Redis` 캐시에 저장

    c. 주기적 `DB` 동기화

        i. `Redis`에 저장된 모든 가게의 평점을 DB에 업데이트

 

3. 어려웠던 점, 그에 대한 해결 방안

3 - 1. `AuditorAware` 를 사용하여 사용자 정보 자동 입력

회원가입, 로그인 시도하면 `Authentication` 객체에 사용자 정보가 없기 때문에

`Authentication.getName()`을 호출하면 `"anonymousUser"` 라는 값을 반환받게 됩니다.

우리 프로젝트의 `BaseEntity`의 `createdBy`, `updatedBy` 는 10글자 제약 조건이 걸려 있어서 

충돌이 발생하게 되었습니다. 

@CreatedBy
@Column(name="created_by", length=10)
private String createdBy;

@LastModifiedBy
@Column(name="updated_by", length=10)
private String updatedBy;

 

3 - 1 - 1. 해결 방안

`Authentication` 객체에 사용자 정보가 없는 경우 `"anonymous"` (9글자) 가 사용자 정보로 입력되도록 했습니다.

추가적으로 제약조건을 `10` -> `2048` 로 늘렸습니다.

 

4. 잘된 점과 그 이유

4 - 1. 깃허브를 이용한 협업

각자 브랜치를 나눠, 맡은 부분 개발을 진행해 역할 분담이 잘 이루어졌습니다.

기능 구현별 PR과 코드리뷰를 통해 자신이 미처 발견하지 못한 오류를 수정하거나 개선할 수 있는 부분을 발견하는 등

피드백과 반영이 잘 이루어졌습니다.

 

5. 협업간 발생한 문제와 해결방안

5 - 1. `DTO` 클래스 명칭 통일 문제

`DomainRequestDto`, `DomainResponseDto` 로 할지

`dto` 명칭을 뺄지 의견이 나뉘었습니다.

결론은 `DomainRequest`, `DomainResponse`로 통일하였습니다.

 

5 - 2. `Repository` 사용 방식

`QueryDSL`을 사용하는 `Repository`를 `JpaRepository` 와 합쳐서 사용할지 따로 사용할지

의견이 나뉘었습니다.

결론은 각 도베인별 개인시 선호하는 방식을 사용하기로 합의했습니다.

 

5 - 3. `PR` 생성 방식

도메인별 기능 하나 구현할 때마다 `PR`을 올릴지, `CRUD` 전체를 구현 후에 한꺼번에 올릴지

의견이 나뉘었습니다.

`PR`을 잘게 나눌 경우 리뷰할 코드의 양이 적어 빠른 피드백 및 승인이 가능한 장점이 있습니다.

`PR`을 합칠 경우 잦은 피드백 요청을 피하고 개인 개발에 집중 가능한 장점이 있습니다.

결론은 튜터님의 `Git` 특강 조언에 따라 `PR`을 나누어 올리기로 합의했습니다.

 

6. 팀 프로젝트를 진행하며 느낀 점

은우

- 사람마다 같은 `CRUD`를 개발해도 코딩하는 방식이 다름을 느꼈다.

- `PR`을 통해 서로의 코드에 대한 각자의 의견을 공유할 수 있었다.

 

해성

- `PR`로 협업한 건 처음이라 좋은 경험했다.

- `API` 설계, `ERD` 설계가 약했는데 이번 프로젝트를 진행하며 감이 좀 잡혔다.

- 테스트 코드가 없으니 리팩토링할 때 일일이 `API`로 요청해 봐야 해서 번거로웠다.

 

시원

- 이렇게 단기로 빠르게 개발한 경험은 처음이라 신기했다.

- 제출 후에도 차근차근 리팩터링을 진행하면 좋을 것 같다.

- 네이밍 등에서도 다양한 의견을 들을 수 있어서 좋았다.

'자바 심화 2기' 카테고리의 다른 글

Spring Dozen - 물류 관리 시스템 - MSA 기반 플랫폼  (0) 2024.12.19
2024 11 14 TIL - Spring Data의 @PageableDefault, @SortDefault  (0) 2024.11.14
2024 11 13 TIL - QueryDSL, BooleanExpression  (2) 2024.11.13
2024 11 12 TIL - 회원가입하려는데 왜 자꾸 인증하라고 그러는걸까? (Feat. AuditorAware)  (0) 2024.11.12
2024 11 11 TIL - AuditorAware 구현하기  (3) 2024.11.11
  1. 1. 프로젝트 간단 소개
  2. 2. `ERD`, 인프라 설계서
  3. 3. 주요 기능 구현 및 기술 도입 이유
  4. 3 - 1. `AuditorAware`를 사용하여 사용자 정보 자동 입력
  5. 3 - 2. `AI - GPT API`를 사용하여 메뉴 설명 자동 생성
  6. 2 - 3. `Junit5`를 사용하여 자동화된 테스트
  7. 2 - 4. `Scheduler`를 사용하여 가게의 평점 갱신
  8. 3. 어려웠던 점, 그에 대한 해결 방안
  9. 3 - 1. `AuditorAware` 를 사용하여 사용자 정보 자동 입력
  10. 4. 잘된 점과 그 이유
  11. 4 - 1. 깃허브를 이용한 협업
  12. 5. 협업간 발생한 문제와 해결방안
  13. 5 - 1. `DTO` 클래스 명칭 통일 문제
  14. 5 - 2. `Repository` 사용 방식
  15. 5 - 3. `PR` 생성 방식
  16. 6. 팀 프로젝트를 진행하며 느낀 점
  17. 은우
  18. 해성
  19. 시원
'자바 심화 2기' 카테고리의 다른 글
  • Spring Dozen - 물류 관리 시스템 - MSA 기반 플랫폼
  • 2024 11 14 TIL - Spring Data의 @PageableDefault, @SortDefault
  • 2024 11 13 TIL - QueryDSL, BooleanExpression
  • 2024 11 12 TIL - 회원가입하려는데 왜 자꾸 인증하라고 그러는걸까? (Feat. AuditorAware)
Griotold
Griotold
Griotold's Olive OilGriotold 님의 블로그입니다.
Griotold
Griotold's Olive Oil
Griotold
전체
오늘
어제
  • 분류 전체보기 (94)
    • 테스트 (4)
      • Spock (1)
      • Junit (3)
    • 디자인 패턴 (1)
    • 깃 (2)
    • 리팩토링 (4)
    • 항해플러스 백엔드 5기 (3)
    • 인프런 워밍업 클럽 스터디 2기 백엔드 (4)
    • 코딩테스트 (10)
    • 자바 심화 2기 (7)
    • 백엔드 면접 질문 (19)
    • 인프라 (17)
      • docker (5)
      • CI, CD (5)
      • Monitoring (6)
      • AWS (1)
    • 데이터베이스 (1)
      • Redis (1)
    • 메시지큐 (3)
      • rabbitMQ (0)
      • kafka (3)
    • MSA (7)
    • JPA (1)
    • Spring (8)
      • Spring AI (1)
    • GraphQL (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기

공지사항

인기 글

태그

  • 백엔드
  • grafana
  • 티스토리챌린지
  • CICD
  • github
  • 개발자취업
  • backend
  • 프로그래머스
  • 99클럽
  • 리팩터링
  • actuator
  • 코딩테스트준비
  • 배포
  • 자바
  • micrometer
  • TIL
  • Spring
  • junit5
  • 이분탐색
  • 백준
  • MSA
  • 항해99
  • java
  • docker
  • JPA
  • 오블완
  • prometheus
  • 읽기좋은코드
  • DATABASE
  • githubactions

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
Griotold
CodeBloom - AI를 활용한 주문 관리 플랫폼 프로젝트 결과물
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.