Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
78b3626
[fix] 사장님 예약 내역에서 푸드트럭 이름까지 반환하도록 변경된 요구사항에 맞게 로직 수정 (#16)
ksg1227 Sep 16, 2025
4b0f00b
[refactor] dto 필드 네이밍 컨벤션 통일 (#16)
ksg1227 Sep 16, 2025
bf556eb
[feat] 나의 푸드트럭 조회용 응담 DTO 구현 (#16)
ksg1227 Sep 17, 2025
a77f62a
[feat] 나의 푸드트럭 조회를 위한 리포지토리 메서드 구현 (#16)
ksg1227 Sep 17, 2025
33c814b
[refactor] 응답 DTO 내에서 호출 가능 지역 List 를 문자열로 변환해줄 수 있도록 팩토리 메서드 구현 (#16)
ksg1227 Sep 17, 2025
a9479a9
[feat] 나의 푸드트럭 조회 서비스 로직 구현 (#16)
ksg1227 Sep 17, 2025
ccf1011
[feat] 나의 푸드트럭 목록 조회 API 구현 (#16)
ksg1227 Sep 17, 2025
378a04b
[feat] 리포지토리 추가 구현 (#16)
ksg1227 Sep 17, 2025
79a7bbf
[refactor] 권한 검증 메서드 분리 및 네이밍 구분 (#16)
ksg1227 Sep 17, 2025
7a66740
[feat] 나의 푸드트럭 삭제 서비스 로직 구현 (#16)
ksg1227 Sep 18, 2025
bdb2dc2
[feat] 나의 푸드트럭 삭제 API 구현 (#16)
ksg1227 Sep 17, 2025
54cbfc1
[refactor] 코드 컨벤션에 맞게 트랜잭션 재설정 (#16)
ksg1227 Sep 18, 2025
f4501f5
[fix] 푸드트럭 소유 검증 에러코드 수정 (#16)
ksg1227 Sep 18, 2025
8e94e4e
[refactor] 호출 가능 지역 문자열 생성 책임을 FoodTruck 이 갖도록 수정 (#16)
ksg1227 Sep 18, 2025
9d404b6
[refactor] 파사드 클래스 메서드에만 @Transactional 붙이도록 수정 (#16)
ksg1227 Sep 19, 2025
a307f03
[chore] 패키지명 소문자로 통일 (#16)
ksg1227 Sep 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import konkuk.chacall.global.common.domain.BaseEntity;
import lombok.*;

import java.util.List;
import java.util.stream.Collectors;

@Builder
@Entity
@Table(name = "food_trucks")
Expand Down Expand Up @@ -70,7 +73,18 @@ public class FoodTruck extends BaseEntity {
@JoinColumn(name = "user_id", nullable = false)
private User owner;

public boolean isOwnedBy(Long ownerId) {
return this.getOwner().getUserId().equals(ownerId);
}

public void updateAverageRating(double rating) {
ratingInfo.updateAverageRating(rating);
}

// 푸드트럭의 호출 가능 지역을 반환해주는 메서드
public String getServiceAreas(List<FoodTruckServiceArea> serviceAreaList) {
return serviceAreaList.stream()
.map(serviceArea -> serviceArea.getRegion().getFullName())
.collect(Collectors.joining(", "));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package konkuk.chacall.domain.foodtruck.domain.repository;

import konkuk.chacall.domain.foodtruck.domain.AvailableDate;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface AvailableDateRepository extends JpaRepository<AvailableDate, Long> {

@Modifying
@Query("DELETE FROM AvailableDate ad WHERE ad.foodTruck.foodTruckId = :foodTruckId")
void deleteAllByFoodTruckId(@Param("foodTruckId") Long foodTruckId);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
package konkuk.chacall.domain.foodtruck.domain.repository;

import konkuk.chacall.domain.foodtruck.domain.FoodTruck;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface FoodTruckRepository extends JpaRepository<FoodTruck, Long> {

@Query("SELECT ft FROM FoodTruck ft " +
"WHERE ft.owner.userId = :ownerId " +
"AND ft.foodTruckId < :lastCursor " +
"ORDER BY ft.foodTruckId DESC")
Slice<FoodTruck> findByOwnerUserIdWithCursor(@Param("ownerId") Long ownerId, @Param("lastCursor") Long lastCursor, Pageable pageable);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package konkuk.chacall.domain.foodtruck.domain.repository;

import konkuk.chacall.domain.foodtruck.domain.FoodTruckServiceArea;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface FoodTruckServiceAreaRepository extends JpaRepository<FoodTruckServiceArea, Long> {

@Query("SELECT ftsa FROM FoodTruckServiceArea ftsa " +
"JOIN FETCH ftsa.region r " +
"WHERE ftsa.foodTruck.foodTruckId IN :foodTruckIds")
List<FoodTruckServiceArea> findAllWithRegionByFoodTruckIdIn(@Param("foodTruckIds") List<Long> foodTruckIds);

@Modifying
@Query("DELETE FROM FoodTruckServiceArea ftsa WHERE ftsa.foodTruck.foodTruckId = :foodTruckId")
void deleteAllByFoodTruckId(@Param("foodTruckId") Long foodTruckId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package konkuk.chacall.domain.foodtruck.domain.repository;

import konkuk.chacall.domain.foodtruck.domain.Menu;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface MenuRepository extends JpaRepository<Menu, Long> {

@Modifying
@Query("DELETE FROM Menu m WHERE m.foodTruck.foodTruckId = :foodTruckId")
void deleteAllByFoodTruckId(@Param("foodTruckId") Long foodTruckId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import konkuk.chacall.domain.user.domain.model.User;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;
Expand All @@ -19,4 +21,8 @@ public interface RatingRepository extends JpaRepository<Rating, Long> {
"WHERE r.member = :member " +
"AND r.isRated = false")
List<Rating> findAllByMemberAndIsRatedFalse(User member);

@Modifying
@Query("DELETE FROM Rating r WHERE r.foodTruck.foodTruckId = :foodTruckId")
void deleteAllByFoodTruckId(@Param("foodTruckId") Long foodTruckId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

Expand All @@ -27,4 +28,8 @@ Slice<SavedFoodTruck> findMemberSavedFoodTruckWithCursor(
@Param("member") User member,
@Param("lastCursor") Long lastCursor,
Pageable pageable);

@Modifying
@Query("DELETE FROM SavedFoodTruck sft WHERE sft.foodTruck.foodTruckId = :foodTruckId")
void deleteAllByFoodTruckId(@Param("foodTruckId") Long foodTruckId);
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package konkuk.chacall.domain.owner.application;

import konkuk.chacall.domain.owner.application.bankAccount.BankAccountService;
import konkuk.chacall.domain.owner.application.chatTemplate.ChatTemplateService;
import konkuk.chacall.domain.owner.application.bankaccount.BankAccountService;
import konkuk.chacall.domain.owner.application.chattemplate.ChatTemplateService;
import konkuk.chacall.domain.owner.application.myfoodtruck.MyFoodTruckService;
import konkuk.chacall.domain.owner.application.reservation.OwnerReservationService;
import konkuk.chacall.domain.owner.application.validator.OwnerValidator;
import konkuk.chacall.domain.owner.presentation.dto.request.*;
import konkuk.chacall.domain.owner.presentation.dto.response.BankAccountResponse;
import konkuk.chacall.domain.owner.presentation.dto.response.ChatTemplateResponse;
import konkuk.chacall.domain.owner.presentation.dto.response.OwnerReservationDetailResponse;
import konkuk.chacall.domain.owner.presentation.dto.response.OwnerReservationHistoryResponse;
import konkuk.chacall.domain.owner.presentation.dto.response.*;
import konkuk.chacall.domain.user.domain.model.User;
import konkuk.chacall.global.common.dto.CursorPagingResponse;
import konkuk.chacall.global.common.dto.CursorPagingRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

Expand All @@ -24,10 +23,12 @@ public class OwnerService {
private final BankAccountService bankAccountService;
private final ChatTemplateService chatTemplateService;
private final OwnerReservationService ownerReservationService;
private final MyFoodTruckService myFoodTruckService;

// 파사드에서 사장님 검증을 거침으로써 서비스 로직에서는 사장님 검증에 신경쓰지 않도록 책임 분리
private final OwnerValidator ownerValidator;

@Transactional
public void registerBankAccount(RegisterBankAccountRequest request, Long ownerId) {
// 사장님인지 먼저 검증
User owner = ownerValidator.validateAndGetOwner(ownerId);
Expand All @@ -36,6 +37,7 @@ public void registerBankAccount(RegisterBankAccountRequest request, Long ownerId
bankAccountService.registerBankAccount(request, owner);
}

@Transactional(readOnly = true)
public BankAccountResponse getBankAccount(Long ownerId) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);
Expand All @@ -44,6 +46,7 @@ public BankAccountResponse getBankAccount(Long ownerId) {
return bankAccountService.getBankAccount(ownerId);
}

@Transactional
public void updateBankAccount(Long ownerId, Long bankAccountId, UpdateBankAccountRequest request) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);
Expand All @@ -52,6 +55,7 @@ public void updateBankAccount(Long ownerId, Long bankAccountId, UpdateBankAccoun
bankAccountService.updateBankAccount(ownerId, bankAccountId, request);
}

@Transactional
public void deleteBankAccount(Long ownerId, Long bankAccountId) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);
Expand All @@ -60,7 +64,7 @@ public void deleteBankAccount(Long ownerId, Long bankAccountId) {
bankAccountService.deleteBankAccount(ownerId, bankAccountId);
}


@Transactional
public void registerChatTemplate(RegisterChatTemplateRequest request, Long ownerId) {
// 사장님인지 먼저 검증
User owner = ownerValidator.validateAndGetOwner(ownerId);
Expand All @@ -69,6 +73,7 @@ public void registerChatTemplate(RegisterChatTemplateRequest request, Long owner
chatTemplateService.registerChatTemplate(request, owner);
}

@Transactional(readOnly = true)
public List<ChatTemplateResponse> getChatTemplates(Long ownerId) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);
Expand All @@ -77,6 +82,7 @@ public List<ChatTemplateResponse> getChatTemplates(Long ownerId) {
return chatTemplateService.getChatTemplates(ownerId);
}

@Transactional
public void updateChatTemplate(UpdateChatTemplateRequest request, Long ownerId, Long chatTemplateId) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);
Expand All @@ -85,6 +91,7 @@ public void updateChatTemplate(UpdateChatTemplateRequest request, Long ownerId,
chatTemplateService.updateChatTemplate(request, chatTemplateId);
}

@Transactional
public void deleteChatTemplate(Long ownerId, Long chatTemplateId) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);
Expand All @@ -93,6 +100,7 @@ public void deleteChatTemplate(Long ownerId, Long chatTemplateId) {
chatTemplateService.deleteChatTemplate(chatTemplateId);
}

@Transactional(readOnly = true)
public CursorPagingResponse<OwnerReservationHistoryResponse> getOwnerReservations(GetReservationHistoryRequest request, Long ownerId) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);
Expand All @@ -102,11 +110,30 @@ public CursorPagingResponse<OwnerReservationHistoryResponse> getOwnerReservation
return ownerReservationService.getOwnerReservations(ownerId, request.status(), cursorPagingRequest.cursor(), cursorPagingRequest.size());
}

@Transactional(readOnly = true)
public OwnerReservationDetailResponse getReservationDetail(Long ownerId, Long reservationId) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);

// 사장님 예약 내역 상세 조회 로직 호출
return ownerReservationService.getReservationDetail(ownerId, reservationId);
}

@Transactional(readOnly = true)
public CursorPagingResponse<MyFoodTruckResponse> getMyFoodTrucks(CursorPagingRequest request, Long ownerId) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);

// 사장님 - 나의 푸드트럭 목록 조회 로직 호출
return myFoodTruckService.getMyFoodTrucks(request, ownerId);
}

@Transactional
public void deleteMyFoodTruck(Long ownerId, Long foodTruckId) {
// 사장님인지 먼저 검증
ownerValidator.validateAndGetOwner(ownerId);

// 사장님 - 나의 푸드트럭 삭제 로직 호출
myFoodTruckService.deleteMyFoodTruck(ownerId, foodTruckId);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package konkuk.chacall.domain.owner.application.bankAccount;
package konkuk.chacall.domain.owner.application.bankaccount;

import konkuk.chacall.domain.owner.domain.model.BankAccount;
import konkuk.chacall.domain.owner.domain.repository.BankAccountRepository;
Expand All @@ -7,23 +7,19 @@
import konkuk.chacall.domain.owner.presentation.dto.response.BankAccountResponse;
import konkuk.chacall.domain.user.domain.model.User;
import konkuk.chacall.global.common.exception.BusinessException;
import konkuk.chacall.global.common.exception.DomainRuleException;
import konkuk.chacall.global.common.exception.EntityNotFoundException;
import konkuk.chacall.global.common.exception.code.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BankAccountService {

private final BankAccountRepository bankAccountRepository;

@Transactional
public void registerBankAccount(RegisterBankAccountRequest request, User owner) {

// 해당 유저의 계좌가 이미 있는지 확인
Expand Down Expand Up @@ -52,7 +48,6 @@ public BankAccountResponse getBankAccount(Long ownerId) {
}


@Transactional
public void updateBankAccount(Long ownerId, Long bankAccountId, UpdateBankAccountRequest request) {
// 수정할 계좌를 찾고 요청자가 실제 소유주인지 검증
BankAccount bankAccount = findBankAccountAndVerifyOwner(ownerId, bankAccountId);
Expand All @@ -72,7 +67,6 @@ public void updateBankAccount(Long ownerId, Long bankAccountId, UpdateBankAccoun
);
}

@Transactional
public void deleteBankAccount(Long ownerId, Long bankAccountId) {
// 삭제할 계좌를 찾고, 요청자가 실제 소유주인지 검증
BankAccount bankAccount = findBankAccountAndVerifyOwner(ownerId, bankAccountId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
package konkuk.chacall.domain.owner.application.chatTemplate;
package konkuk.chacall.domain.owner.application.chattemplate;

import konkuk.chacall.domain.owner.domain.model.ChatTemplate;
import konkuk.chacall.domain.owner.domain.repository.ChatTemplateRepository;
import konkuk.chacall.domain.owner.presentation.dto.request.RegisterChatTemplateRequest;
import konkuk.chacall.domain.owner.presentation.dto.request.UpdateChatTemplateRequest;
import konkuk.chacall.domain.owner.presentation.dto.response.ChatTemplateResponse;
import konkuk.chacall.domain.user.domain.model.User;
import konkuk.chacall.global.common.exception.BusinessException;
import konkuk.chacall.global.common.exception.EntityNotFoundException;
import konkuk.chacall.global.common.exception.code.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@RequiredArgsConstructor
@Service
@Transactional(readOnly = true)
public class ChatTemplateService {

private final ChatTemplateRepository chatTemplateRepository;

@Transactional
public void registerChatTemplate(RegisterChatTemplateRequest request, User owner) {
ChatTemplate chatTemplate = ChatTemplate.of(request.content(), owner);

Expand All @@ -37,7 +33,6 @@ public List<ChatTemplateResponse> getChatTemplates(Long ownerId) {
.toList();
}

@Transactional
public void updateChatTemplate(UpdateChatTemplateRequest request, Long chatTemplateId) {
ChatTemplate chatTemplate = chatTemplateRepository.findById(chatTemplateId)
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.CHAT_TEMPLATE_NOT_FOUND));
Expand All @@ -47,7 +42,6 @@ public void updateChatTemplate(UpdateChatTemplateRequest request, Long chatTempl
);
}

@Transactional
public void deleteChatTemplate(Long chatTemplateId) {
if(!chatTemplateRepository.existsById(chatTemplateId)) {
throw new EntityNotFoundException(ErrorCode.CHAT_TEMPLATE_NOT_FOUND);
Expand Down
Loading