냉파마스터의 장보기 도메인 기능을 구현했다.
장보기 기능은 사용자가 구매할 재료를 목록으로 관리하고, 구매 여부를 체크한 뒤 냉장고 재료로 반영할 수 있는 흐름이다.
작업 범위는 다음과 같다.
- #26 장보기 항목 추가 API
- #27 장보기 목록 조회 API
- #28 장보기 항목 삭제 API
- #29 장보기 항목 체크/체크 해제 API
- #30 장보기 항목 냉장고 반영 API
1. 장보기 항목 추가 API
장보기 항목 추가 API는 사용자가 구매할 재료를 장보기 목록에 등록하는 기능이다.
POST /api/v1/shopping-items
요청 데이터는 사전 재료 ID와 수량을 받는다.
{
"productId": 1,
"quantity": "1개"
}
이 API에서 중요한 점은 memberId를 요청으로 받지 않는다는 것이다.
회원 정보는 로그인 토큰에서 가져온 email을 기준으로 조회한다.
Member member = findMemberByEmail(email);
이후 요청으로 들어온 productId가 실제 존재하는 사전 재료인지 검증한다.
productService.validateExists(request.productId());
장보기 항목을 처음 추가할 때는 아직 구매한 상태가 아니기 때문에 isPurchased는 false로 저장했다.
shoppingItem.isPurchased = false;
2. 장보기 목록 조회 API
장보기 목록 조회 API는 로그인한 사용자의 장보기 항목을 조회한다.
GET /api/v1/shopping-items
이 API는 반드시 본인 데이터만 조회해야 한다.
조회 조건은 다음과 같다.
member_id = 로그인한 회원 id
is_deleted = false
장보기 테이블에는 productId만 있고, 실제 재료명과 카테고리는 products 테이블에 있다.
그래서 목록 응답에서는 ShoppingItem과 Product 정보를 합쳐서 ShoppingItemListResponse로 변환했다.
ShoppingItem
+ Product
= ShoppingItemListResponse
이 과정에서 productId 목록을 먼저 뽑고, 해당 ID들로 상품 정보를 한 번에 조회했다.
List<Long> productIds = shoppingItems.stream()
.map(ShoppingItem::getProductId)
.toList();
이렇게 한 이유는 장보기 항목마다 상품을 하나씩 조회하지 않고, 필요한 상품 정보를 한 번에 가져오기 위해서다.
3. 장보기 항목 삭제 API
장보기 항목 삭제 API는 실제 DB row를 삭제하지 않고 isDeleted 값을 변경하는 소프트 삭제 방식으로 구현했다.
DELETE /api/v1/shopping-items/{shoppingItemId}
삭제 대상은 다음 조건으로 찾는다.
shopping_item_id = 요청 path variable
member_id = 로그인한 회원 id
is_deleted = false
이 조건을 사용한 이유는 다른 사용자의 장보기 항목을 삭제하지 못하도록 하기 위해서다.
엔티티에는 삭제 상태를 변경하는 메서드를 두었다.
public void delete() {
this.isDeleted = true;
this.deletedAt = LocalDate.now();
}
삭제 후 목록 조회에서는 isDeleted = false 조건만 조회하기 때문에 삭제된 항목은 더 이상 보이지 않는다.
4. 장보기 항목 체크/체크 해제 API
장보기 항목 체크/체크 해제 API는 사용자가 장보기 항목을 구매했는지 표시하는 기능이다.
PATCH /api/v1/shopping-items/{shoppingItemId}/check
체크 처리:
{
"isPurchased": true
}
체크 해제:
{
"isPurchased": false
}
이 API는 isPurchased 값을 요청값에 따라 변경한다.
shoppingItem.updatePurchased(request.isPurchased());
isPurchased의 의미는 다음과 같다.
false = 아직 구매하지 않음
true = 구매 완료
이 기능은 장보기 목록에서 사용자가 어떤 항목을 이미 샀는지 표시하는 데 사용된다.
5. 장보기 항목 냉장고 반영 API
장보기 항목 냉장고 반영 API는 장보기에서 구매한 항목을 냉장고 재료로 등록하는 기능이다.
POST /api/v1/shopping-items/{shoppingItemId}/fridge
요청 Body는 냉장고에 추가로 필요한 값을 받는다.
{
"expiryDate": "2026-07-05",
"memo": "장보기에서 냉장고로 추가"
}
장보기 항목에는 이미 productId, quantity가 있기 때문에 요청으로 다시 받을 필요가 없다.
냉장고 재료 등록에 추가로 필요한 expiryDate, memo만 받았다.
처리 흐름은 다음과 같다.
1. 로그인 회원 조회
2. 내 장보기 항목 단건 조회
3. 장보기 항목의 productId, quantity로 FridgeItem 생성
4. fridge_items 테이블에 저장
5. 기존 shopping_items 항목은 삭제 처리
6. FridgeItemResponse 반환
즉 이 API는 단순 조회나 수정이 아니라:
장보기 항목 → 냉장고 재료
로 이동시키는 기능이다.
그래서 서비스 메서드에는 @Transactional을 적용했다.
냉장고 저장은 됐는데 장보기 삭제가 실패하거나, 반대로 장보기만 삭제되고 냉장고 저장이 실패하면 데이터가 꼬일 수 있기 때문이다.
6. 구현하면서 정리한 개념
이번 장보기 API를 구현하면서 가장 많이 사용한 흐름은 다음과 같다.
Controller
→ 요청값 받기
Service
→ 회원 검증
→ 본인 데이터 조회
→ 비즈니스 로직 처리
Repository
→ DB 조회/저장
Entity
→ 자기 상태 변경
DTO
→ 요청/응답 데이터 구조 분리
특히 장보기 목록 조회와 냉장고 반영 기능에서는 단순히 한 테이블만 보는 것이 아니라, 다른 도메인 데이터와 연결해야 했다.
장보기 목록 조회:
shopping_items + products
장보기 냉장고 반영:
shopping_items → fridge_items
이 과정을 통해 단순 CRUD뿐 아니라 도메인 간 데이터 흐름도 조금씩 이해할 수 있었다.
7. 정리
이번 작업으로 장보기 도메인의 기본 흐름을 구현했다.
사용자는 장보기 항목을 추가하고, 목록을 조회하고, 필요 없는 항목을 삭제할 수 있다.
또한 구매 여부를 체크하거나 해제할 수 있고, 구매한 항목을 냉장고 재료로 반영할 수 있다.
이번 작업에서 핵심은 “로그인한 사용자의 데이터만 다룬다”는 점이었다.
모든 조회/수정/삭제/반영 로직에서 memberId 조건을 함께 사용해 본인 데이터만 처리하도록 구현했다.
장보기 기능은 냉장고 기능과 연결되는 도메인이기 때문에, 이후 프론트 연동 시 장보기에서 냉장고로 자연스럽게 재료를 옮기는 사용자 흐름을 만들 수 있다.
'개발 프로젝트 > [팀 프로젝트] 냉파마스터' 카테고리의 다른 글
| 냉장고 유통기한 자동 반영 보완 (0) | 2026.07.02 |
|---|---|
| 장보기 연동과 사전 재료 관리자 기능 정리 (0) | 2026.06.30 |
| 냉장고 유통기한 조회와 프론트 연동, 그리고 검색 성능 개선 정리 (0) | 2026.06.28 |
| 냉장고 재료 CRUD 및 사용 처리 API 구현 (0) | 2026.06.28 |
| 냉파마스터 BE 작업 정리: 사전 재료 검색 API / 카테고리 목록 조회 API (0) | 2026.06.27 |