From e853545203494d5f3649f593dc21d7ff6e77da70 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Mon, 11 Dec 2023 12:56:32 +0900 Subject: [PATCH 01/27] Init: Create program controller + test --- .../app/product/domain/ProgramRepository.java | 12 +++++ .../app/product/service/ProgramService.java | 14 +++++ .../product/service/ProgramServiceImpl.java | 44 +++++++++++++++ .../web/api/program/ProgramController.java | 29 ++++++++++ .../program/request/CreateProgramRequest.java | 21 ++++++++ .../program/request/CreateSpotRequest.java | 11 ++++ .../product/service/ProgramServiceTest.java | 53 +++++++++++++++++++ 7 files changed, 184 insertions(+) create mode 100644 src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java create mode 100644 src/main/java/TripAmi/backend/app/product/service/ProgramService.java create mode 100644 src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java create mode 100644 src/main/java/TripAmi/backend/web/api/program/ProgramController.java create mode 100644 src/main/java/TripAmi/backend/web/api/program/request/CreateProgramRequest.java create mode 100644 src/main/java/TripAmi/backend/web/api/program/request/CreateSpotRequest.java create mode 100644 src/test/java/TripAmi/backend/app/product/service/ProgramServiceTest.java diff --git a/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java b/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java new file mode 100644 index 0000000..759d39f --- /dev/null +++ b/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java @@ -0,0 +1,12 @@ +package TripAmi.backend.app.product.domain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface ProgramRepository extends JpaRepository { + + @Query("SELECT p FROM Program p WHERE p.title = :title") + List findByTitle(String title); +} diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramService.java b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java new file mode 100644 index 0000000..816afe4 --- /dev/null +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java @@ -0,0 +1,14 @@ +package TripAmi.backend.app.product.service; + +import TripAmi.backend.app.product.domain.Program; +import TripAmi.backend.web.api.program.request.CreateProgramRequest; + +import java.util.List; + +public interface ProgramService { + void createProgram(CreateProgramRequest request); + + Program findById(Long id); + + List findByTitle(String title); +} diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java new file mode 100644 index 0000000..399aec6 --- /dev/null +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java @@ -0,0 +1,44 @@ +package TripAmi.backend.app.product.service; + +import TripAmi.backend.app.product.domain.Program; +import TripAmi.backend.app.product.domain.ProgramRepository; +import TripAmi.backend.web.api.program.request.CreateProgramRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional +public class ProgramServiceImpl implements ProgramService { + + private final ProgramRepository programRepository; + + @Override + public void createProgram(CreateProgramRequest request) { + Program program = Program.builder() + .title(request.title()) + .images(request.images()) + .content(request.content()) + .price(request.price()) + .totalPersonnel(request.totalPersonnel()) + .theme(request.theme()) + .keyWords(request.keyWords()) + .spots(request.spots()) + .location(request.location()) + .build(); + programRepository.save(program); + } + + @Override + public Program findById(Long id) { + return programRepository.findById(id).orElseThrow(); + } + + @Override + public List findByTitle(String title) { + return programRepository.findByTitle(title); + } +} diff --git a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java new file mode 100644 index 0000000..80843c8 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java @@ -0,0 +1,29 @@ +package TripAmi.backend.web.api.program; + + +import TripAmi.backend.app.product.service.ProgramService; +import TripAmi.backend.web.api.program.request.CreateProgramRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("‘api/v1/programs’") +@RequiredArgsConstructor +public class ProgramController { + private final ProgramService programService; + + @PostMapping + public void CreateProgram(@RequestBody CreateProgramRequest request) { + programService.createProgram(request); + } + + /** + * 테마 목록 조회 + * 테마 별 조회 + * 기간 별 조회 + * 상세 조회 + * FAQ 생성 + * FAQ 목록 조회 + * 잔여 인원 조회 + */ +} diff --git a/src/main/java/TripAmi/backend/web/api/program/request/CreateProgramRequest.java b/src/main/java/TripAmi/backend/web/api/program/request/CreateProgramRequest.java new file mode 100644 index 0000000..ff80df0 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/program/request/CreateProgramRequest.java @@ -0,0 +1,21 @@ +package TripAmi.backend.web.api.program.request; + +import TripAmi.backend.app.product.ProgramTheme; +import TripAmi.backend.app.product.domain.Spot; + +import java.util.List; + +public record CreateProgramRequest( + Long amiId, + String title, + String content, + String profileImgUrl, + List images, + Integer price, + Integer totalPersonnel, + ProgramTheme theme, + List keyWords, + List spots, + String location +) { +} diff --git a/src/main/java/TripAmi/backend/web/api/program/request/CreateSpotRequest.java b/src/main/java/TripAmi/backend/web/api/program/request/CreateSpotRequest.java new file mode 100644 index 0000000..fd854bb --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/program/request/CreateSpotRequest.java @@ -0,0 +1,11 @@ +package TripAmi.backend.web.api.program.request; + +import java.time.LocalTime; + +public record CreateSpotRequest( + String title, + String imgUrl, + String content, + LocalTime requiredTime +) { +} diff --git a/src/test/java/TripAmi/backend/app/product/service/ProgramServiceTest.java b/src/test/java/TripAmi/backend/app/product/service/ProgramServiceTest.java new file mode 100644 index 0000000..e88028e --- /dev/null +++ b/src/test/java/TripAmi/backend/app/product/service/ProgramServiceTest.java @@ -0,0 +1,53 @@ +package TripAmi.backend.app.product.service; + +import TripAmi.backend.app.product.ProgramTheme; +import TripAmi.backend.app.product.domain.ProgramRepository; +import TripAmi.backend.web.api.program.request.CreateProgramRequest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Collections; + +@SpringBootTest +public class ProgramServiceTest { + + @Mock + private ProgramRepository programRepository; + + @InjectMocks + private ProgramService programService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void create_program() { + // Arrange + CreateProgramRequest request = new CreateProgramRequest( + 1L, + "Program Title", + "Program Content", + "img_url", + Collections.singletonList("image1.jpg"), + 100, + 10, + ProgramTheme.ACTIVITY, + Collections.singletonList("keyword"), + Collections.emptyList(), // Assuming no spots for simplicity + "Location" + ); + +// // Act + programService.createProgram(request); +// +// // Assert + Assertions.assertNotNull(programService.findByTitle("Program Title")); // Correct title + } +} \ No newline at end of file From e3454ef653b86c50b06e8665f0ff492502554fec Mon Sep 17 00:00:00 2001 From: jaekkang Date: Mon, 11 Dec 2023 12:57:23 +0900 Subject: [PATCH 02/27] Style: Remove test + enum (not use) --- .../backend/app/product/domain/Product.java | 4 -- .../backend/app/util/ProgramTheme.java | 10 ----- .../TripAmi/backend/config/JwtProperties.java | 4 +- .../web/api/member/MemberControllerTest.java | 39 ------------------- 4 files changed, 2 insertions(+), 55 deletions(-) delete mode 100644 src/main/java/TripAmi/backend/app/util/ProgramTheme.java delete mode 100644 src/test/java/TripAmi/backend/web/api/member/MemberControllerTest.java diff --git a/src/main/java/TripAmi/backend/app/product/domain/Product.java b/src/main/java/TripAmi/backend/app/product/domain/Product.java index db702e5..5ababf6 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/Product.java +++ b/src/main/java/TripAmi/backend/app/product/domain/Product.java @@ -36,8 +36,4 @@ public Product(String title, List images, String content, Integer price) this.content = content; this.price = price; } - -// public void delete() { -// baseEntity.delete(); -// } } diff --git a/src/main/java/TripAmi/backend/app/util/ProgramTheme.java b/src/main/java/TripAmi/backend/app/util/ProgramTheme.java deleted file mode 100644 index 1728f2e..0000000 --- a/src/main/java/TripAmi/backend/app/util/ProgramTheme.java +++ /dev/null @@ -1,10 +0,0 @@ -package TripAmi.backend.app.util; - -public enum ProgramTheme { - ACTIVITY, - RESTAURANT, - TOURISM, - PHOTO, - K_POP, - SHOPPING, -} diff --git a/src/main/java/TripAmi/backend/config/JwtProperties.java b/src/main/java/TripAmi/backend/config/JwtProperties.java index d0320d3..1ead260 100644 --- a/src/main/java/TripAmi/backend/config/JwtProperties.java +++ b/src/main/java/TripAmi/backend/config/JwtProperties.java @@ -6,7 +6,7 @@ import org.springframework.boot.context.properties.bind.DefaultValue; @Getter -@ConfigurationProperties(prefix = "social-feed.jwt") +@ConfigurationProperties(prefix = "trip-ami.jwt") public class JwtProperties { private final long accessTokenLifespanInMinutes; private final long refreshTokenLifespanInMinutes; @@ -18,7 +18,7 @@ public JwtProperties( @DefaultValue("1800") long accessTokenLifespanInMinutes, @DefaultValue("180000") long refreshTokenLifespanInMinutes, @DefaultValue("self") String issuer, - @DefaultValue("BeforeSpring") String subject + @DefaultValue("TripAmi") String subject ) { this.accessTokenLifespanInMinutes = accessTokenLifespanInMinutes; this.refreshTokenLifespanInMinutes = refreshTokenLifespanInMinutes; diff --git a/src/test/java/TripAmi/backend/web/api/member/MemberControllerTest.java b/src/test/java/TripAmi/backend/web/api/member/MemberControllerTest.java deleted file mode 100644 index 2fc7bdf..0000000 --- a/src/test/java/TripAmi/backend/web/api/member/MemberControllerTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package TripAmi.backend.web.api.member; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@SpringBootTest -@AutoConfigureMockMvc -class MemberControllerTest { - - @Autowired - private MockMvc mockMvc; - - @InjectMocks - private MemberController memberController; - - @BeforeEach - public void setup() { - mockMvc = MockMvcBuilders.standaloneSetup(memberController).build(); - } - - @Test - public void testGetMapping() throws Exception { - String testName = "TestUser"; - - mockMvc.perform(get("/api/v1/members") - .param("name", testName)) - .andExpect(status().isOk()); - - } -} From cdb3183b50998846e4d7bfba0ab00f8817f93eb3 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Mon, 11 Dec 2023 16:31:01 +0900 Subject: [PATCH 03/27] Feat: Add method for find by theme in program service --- .../backend/app/product/domain/ProgramRepository.java | 6 ++++++ .../backend/app/product/service/ProgramService.java | 4 ++++ .../backend/app/product/service/ProgramServiceImpl.java | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java b/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java index 759d39f..d3d1deb 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java +++ b/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java @@ -1,7 +1,10 @@ package TripAmi.backend.app.product.domain; +import TripAmi.backend.app.product.ProgramTheme; +import TripAmi.backend.web.api.program.response.ProgramDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.List; @@ -9,4 +12,7 @@ public interface ProgramRepository extends JpaRepository { @Query("SELECT p FROM Program p WHERE p.title = :title") List findByTitle(String title); + + @Query("SELECT p FROM Program p WHERE p.theme = :theme") + List findByTheme(@Param("theme") ProgramTheme theme); } diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramService.java b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java index 816afe4..7fcc81d 100644 --- a/src/main/java/TripAmi/backend/app/product/service/ProgramService.java +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java @@ -1,7 +1,9 @@ package TripAmi.backend.app.product.service; +import TripAmi.backend.app.product.ProgramTheme; import TripAmi.backend.app.product.domain.Program; import TripAmi.backend.web.api.program.request.CreateProgramRequest; +import TripAmi.backend.web.api.program.response.ProgramDto; import java.util.List; @@ -11,4 +13,6 @@ public interface ProgramService { Program findById(Long id); List findByTitle(String title); + + List findByTheme(ProgramTheme theme); } diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java index 399aec6..23b899f 100644 --- a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java @@ -1,9 +1,12 @@ package TripAmi.backend.app.product.service; +import TripAmi.backend.app.product.ProgramTheme; import TripAmi.backend.app.product.domain.Program; import TripAmi.backend.app.product.domain.ProgramRepository; import TripAmi.backend.web.api.program.request.CreateProgramRequest; +import TripAmi.backend.web.api.program.response.ProgramDto; import lombok.RequiredArgsConstructor; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -41,4 +44,9 @@ public Program findById(Long id) { public List findByTitle(String title) { return programRepository.findByTitle(title); } + + @Override + public List findByTheme(ProgramTheme theme) { + return programRepository.findByTheme(theme); + } } From e127ec064680fa739c65ff5838603aa6bc8aae5f Mon Sep 17 00:00:00 2001 From: jaekkang Date: Mon, 11 Dec 2023 16:32:13 +0900 Subject: [PATCH 04/27] Feat: Create request & response dto for program service --- .../web/api/common/GenericResponse.java | 10 ++++ .../web/api/program/ProgramController.java | 51 +++++++++++++++++-- .../web/api/program/response/ProgramDto.java | 16 ++++++ .../program/response/ProgramListResponse.java | 12 +++++ .../web/api/program/response/ThemeDto.java | 5 ++ .../program/response/ThemeListResponse.java | 11 ++++ 6 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 src/main/java/TripAmi/backend/web/api/program/response/ProgramDto.java create mode 100644 src/main/java/TripAmi/backend/web/api/program/response/ProgramListResponse.java create mode 100644 src/main/java/TripAmi/backend/web/api/program/response/ThemeDto.java create mode 100644 src/main/java/TripAmi/backend/web/api/program/response/ThemeListResponse.java diff --git a/src/main/java/TripAmi/backend/web/api/common/GenericResponse.java b/src/main/java/TripAmi/backend/web/api/common/GenericResponse.java index a41a8bd..7ffcd56 100644 --- a/src/main/java/TripAmi/backend/web/api/common/GenericResponse.java +++ b/src/main/java/TripAmi/backend/web/api/common/GenericResponse.java @@ -1,7 +1,9 @@ package TripAmi.backend.web.api.common; +import TripAmi.backend.web.api.program.response.ThemeListResponse; import lombok.Builder; import lombok.Getter; +import org.springframework.http.HttpStatus; @Getter public class GenericResponse { @@ -14,4 +16,12 @@ public GenericResponse(int statusCode, T data, String message) { this.data = data; this.message = message; } + + public static GenericResponse ok(T data) { + return new GenericResponse<>(HttpStatus.OK.value(), data, HttpStatus.OK.getReasonPhrase()); + } + + public static GenericResponse ok() { + return new GenericResponse<>(HttpStatus.OK.value(), null, HttpStatus.OK.getReasonPhrase()); + } } diff --git a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java index 80843c8..e6c3aa7 100644 --- a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java +++ b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java @@ -1,25 +1,70 @@ package TripAmi.backend.web.api.program; +import TripAmi.backend.app.product.ProgramTheme; import TripAmi.backend.app.product.service.ProgramService; +import TripAmi.backend.web.api.common.GenericResponse; import TripAmi.backend.web.api.program.request.CreateProgramRequest; +import TripAmi.backend.web.api.program.response.ProgramDto; +import TripAmi.backend.web.api.program.response.ProgramListResponse; +import TripAmi.backend.web.api.program.response.ThemeDto; +import TripAmi.backend.web.api.program.response.ThemeListResponse; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + @RestController @RequestMapping("‘api/v1/programs’") @RequiredArgsConstructor public class ProgramController { private final ProgramService programService; + /** + * 프로그램 생성 url + * 필요 데이터를 가지고 메소드 호출시 생성 (return은 없습니다.) + * + * @param request 생성 DTO (CreateProgramRequest) + */ @PostMapping - public void CreateProgram(@RequestBody CreateProgramRequest request) { + public void createProgram(@RequestBody CreateProgramRequest request) { programService.createProgram(request); } /** - * 테마 목록 조회 - * 테마 별 조회 + * 현재 Program들이 가지고 있는 Theme 전체 검색 + * 데이터가 있는 Theme만 불러와짐 + * + * @return themes + */ + @GetMapping("/themes") + public GenericResponse getThemes() { + List result = Arrays.stream(ProgramTheme.values()) + .map(theme -> new ThemeDto(theme.toString())) + .collect(Collectors.toList()); + + ThemeListResponse response = new ThemeListResponse(result); + return GenericResponse.ok(response); + } + + /** + * 파람으로 던져지는 Theme에 해당하는 프로그램들을 리턴해줌 + * 없는 Theme 던져지면 Exception + * + * @param theme 테마 (String) + * @return 해당하는 Theme에 포함된 Program + */ + @GetMapping("/{theme}") + public GenericResponse getProgramByTheme(@PathVariable String theme) { + ProgramTheme programTheme = ProgramTheme.valueOf(theme.toUpperCase()); + List result = programService.findByTheme(programTheme); + ProgramListResponse response = new ProgramListResponse(result); + return GenericResponse.ok(response); + } + /** + * ToDo * 기간 별 조회 * 상세 조회 * FAQ 생성 diff --git a/src/main/java/TripAmi/backend/web/api/program/response/ProgramDto.java b/src/main/java/TripAmi/backend/web/api/program/response/ProgramDto.java new file mode 100644 index 0000000..967f08c --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/program/response/ProgramDto.java @@ -0,0 +1,16 @@ +package TripAmi.backend.web.api.program.response; + +import TripAmi.backend.app.product.ProgramTheme; + +import java.util.List; + +public record ProgramDto( + String title, + List images, + String content, + Integer price, + Long amiId, + ProgramTheme theme + +) { +} diff --git a/src/main/java/TripAmi/backend/web/api/program/response/ProgramListResponse.java b/src/main/java/TripAmi/backend/web/api/program/response/ProgramListResponse.java new file mode 100644 index 0000000..48dab46 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/program/response/ProgramListResponse.java @@ -0,0 +1,12 @@ +package TripAmi.backend.web.api.program.response; + +import TripAmi.backend.app.product.domain.Program; +import lombok.Builder; + +import java.util.List; + +public record ProgramListResponse(List programs) { + @Builder + public ProgramListResponse { + } +} diff --git a/src/main/java/TripAmi/backend/web/api/program/response/ThemeDto.java b/src/main/java/TripAmi/backend/web/api/program/response/ThemeDto.java new file mode 100644 index 0000000..d192437 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/program/response/ThemeDto.java @@ -0,0 +1,5 @@ +package TripAmi.backend.web.api.program.response; + +public record ThemeDto(String theme) { + +} diff --git a/src/main/java/TripAmi/backend/web/api/program/response/ThemeListResponse.java b/src/main/java/TripAmi/backend/web/api/program/response/ThemeListResponse.java new file mode 100644 index 0000000..de337f6 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/program/response/ThemeListResponse.java @@ -0,0 +1,11 @@ +package TripAmi.backend.web.api.program.response; + +import lombok.Builder; + +import java.util.List; + +public record ThemeListResponse(List themes) { + @Builder + public ThemeListResponse { + } +} From eb9ba883ab56cfb6cd9f92030250484af62b0b96 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Mon, 11 Dec 2023 16:33:02 +0900 Subject: [PATCH 05/27] Init: Create OpenDay entity for save fixed date --- .../backend/app/product/domain/OpenDay.java | 35 +++++++++++++++++++ .../app/product/domain/OpenDayRepository.java | 6 ++++ 2 files changed, 41 insertions(+) create mode 100644 src/main/java/TripAmi/backend/app/product/domain/OpenDay.java create mode 100644 src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java diff --git a/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java b/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java new file mode 100644 index 0000000..abcaa33 --- /dev/null +++ b/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java @@ -0,0 +1,35 @@ +package TripAmi.backend.app.product.domain; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "open_day") +public class OpenDay { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "open_day_id") + Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "program_id") + Program program; + + @Column(nullable = false) + LocalDateTime fixedDate; + + @Column(nullable = false) + Integer count; + + @Builder + public OpenDay(Program program, LocalDateTime fixedDate, Integer count) { + this.program = program; + this.fixedDate = fixedDate; + this.count = count; + } +} diff --git a/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java b/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java new file mode 100644 index 0000000..77073ff --- /dev/null +++ b/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java @@ -0,0 +1,6 @@ +package TripAmi.backend.app.product.domain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OpenDayRepository extends JpaRepository { +} From c523167c0b48d958c82547953b839b4b613568e0 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Mon, 11 Dec 2023 17:38:46 +0900 Subject: [PATCH 06/27] Init: Create FAQ entity --- .../TripAmi/backend/app/faq/domain/Faq.java | 28 +++++++++++++++ .../backend/app/faq/domain/FaqRepository.java | 6 ++++ .../backend/app/faq/service/FaqService.java | 13 +++++++ .../app/faq/service/FaqServiceImpl.java | 36 +++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 src/main/java/TripAmi/backend/app/faq/domain/Faq.java create mode 100644 src/main/java/TripAmi/backend/app/faq/domain/FaqRepository.java create mode 100644 src/main/java/TripAmi/backend/app/faq/service/FaqService.java create mode 100644 src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java diff --git a/src/main/java/TripAmi/backend/app/faq/domain/Faq.java b/src/main/java/TripAmi/backend/app/faq/domain/Faq.java new file mode 100644 index 0000000..f41bbda --- /dev/null +++ b/src/main/java/TripAmi/backend/app/faq/domain/Faq.java @@ -0,0 +1,28 @@ +package TripAmi.backend.app.faq.domain; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "faq") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Faq { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "faq_id") + private Long id; + + private String question; + + private String answer; + + @Builder + public Faq(String question, String answer) { + this.question = question; + this.answer = answer; + } +} diff --git a/src/main/java/TripAmi/backend/app/faq/domain/FaqRepository.java b/src/main/java/TripAmi/backend/app/faq/domain/FaqRepository.java new file mode 100644 index 0000000..9d310cc --- /dev/null +++ b/src/main/java/TripAmi/backend/app/faq/domain/FaqRepository.java @@ -0,0 +1,6 @@ +package TripAmi.backend.app.faq.domain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FaqRepository extends JpaRepository { +} diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java new file mode 100644 index 0000000..66a922e --- /dev/null +++ b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java @@ -0,0 +1,13 @@ +package TripAmi.backend.app.faq.service; + +import TripAmi.backend.app.faq.domain.Faq; + +import java.util.List; + +public interface FaqService { + void save(String question, String answer); + + Faq findById(Long id); + + List findAll(); +} diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java b/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java new file mode 100644 index 0000000..aaf3e2c --- /dev/null +++ b/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java @@ -0,0 +1,36 @@ +package TripAmi.backend.app.faq.service; + +import TripAmi.backend.app.faq.domain.Faq; +import TripAmi.backend.app.faq.domain.FaqRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class FaqServiceImpl implements FaqService { + private final FaqRepository faqRepository; + + @Override + @Transactional + public void save(String question, String answer) { + Faq faq = Faq.builder() + .question(question) + .answer(answer) + .build(); + faqRepository.save(faq); + } + + @Override + public Faq findById(Long id) { + return faqRepository.findById(id).orElseThrow(); + } + + @Override + public List findAll() { + return faqRepository.findAll(); + } +} From dae213cf3fbfa1363fafaccbe3e489c246381fcb Mon Sep 17 00:00:00 2001 From: jaekkang Date: Mon, 11 Dec 2023 17:39:31 +0900 Subject: [PATCH 07/27] Feat: Edit method name (create / get -> save / find) --- .../app/product/service/ProgramService.java | 4 +- .../product/service/ProgramServiceImpl.java | 10 +++- .../web/api/program/ProgramController.java | 53 +++++++++++++++---- .../program/response/ProgramDetailDto.java | 18 +++++++ .../web/api/program/response/ProgramDto.java | 3 +- 5 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 src/main/java/TripAmi/backend/web/api/program/response/ProgramDetailDto.java diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramService.java b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java index 7fcc81d..9ecacaa 100644 --- a/src/main/java/TripAmi/backend/app/product/service/ProgramService.java +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java @@ -8,11 +8,13 @@ import java.util.List; public interface ProgramService { - void createProgram(CreateProgramRequest request); + void save(CreateProgramRequest request); Program findById(Long id); List findByTitle(String title); List findByTheme(ProgramTheme theme); + + Program findDetailById(Long id); } diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java index 23b899f..3765cf7 100644 --- a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java @@ -14,13 +14,14 @@ @Service @RequiredArgsConstructor -@Transactional +@Transactional(readOnly = true) public class ProgramServiceImpl implements ProgramService { private final ProgramRepository programRepository; @Override - public void createProgram(CreateProgramRequest request) { + @Transactional + public void save(CreateProgramRequest request) { Program program = Program.builder() .title(request.title()) .images(request.images()) @@ -49,4 +50,9 @@ public List findByTitle(String title) { public List findByTheme(ProgramTheme theme) { return programRepository.findByTheme(theme); } + + @Override + public Program findDetailById(Long id) { + return programRepository.findById(id).orElseThrow(); + } } diff --git a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java index e6c3aa7..df6eaa9 100644 --- a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java +++ b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java @@ -2,13 +2,11 @@ import TripAmi.backend.app.product.ProgramTheme; +import TripAmi.backend.app.product.domain.Program; import TripAmi.backend.app.product.service.ProgramService; import TripAmi.backend.web.api.common.GenericResponse; import TripAmi.backend.web.api.program.request.CreateProgramRequest; -import TripAmi.backend.web.api.program.response.ProgramDto; -import TripAmi.backend.web.api.program.response.ProgramListResponse; -import TripAmi.backend.web.api.program.response.ThemeDto; -import TripAmi.backend.web.api.program.response.ThemeListResponse; +import TripAmi.backend.web.api.program.response.*; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -29,8 +27,8 @@ public class ProgramController { * @param request 생성 DTO (CreateProgramRequest) */ @PostMapping - public void createProgram(@RequestBody CreateProgramRequest request) { - programService.createProgram(request); + public void save(@RequestBody CreateProgramRequest request) { + programService.save(request); } /** @@ -39,8 +37,44 @@ public void createProgram(@RequestBody CreateProgramRequest request) { * * @return themes */ + + @GetMapping("/{id}") + public GenericResponse findById(@PathVariable Long id) { + Program program = programService.findById(id); + ProgramDto response = ProgramDto.builder() + .title(program.getTitle()) + .amiId(program.getAmiId()) + .content(program.getContent()) + .images(program.getImages()) + .price(program.getPrice()) + .theme(program.getTheme()) + .build(); + return GenericResponse.ok(response); + } + + /** + * ToDo 현재 일반 프로그램 조회와 디테일 조회의 차이가 없음 + * + * @param id program id + * @return 해당하는 id의 프로그램 정보 + */ + @GetMapping("/{id}/detail") + public GenericResponse findProgramDetail(@PathVariable Long id) { + Program program = programService.findDetailById(id); + ProgramDetailDto response = ProgramDetailDto.builder() + .title(program.getTitle()) + .amiId(program.getAmiId()) + .content(program.getContent()) + .images(program.getImages()) + .price(program.getPrice()) + .theme(program.getTheme()) + .build(); + + return GenericResponse.ok(response); + } + @GetMapping("/themes") - public GenericResponse getThemes() { + public GenericResponse findThemes() { List result = Arrays.stream(ProgramTheme.values()) .map(theme -> new ThemeDto(theme.toString())) .collect(Collectors.toList()); @@ -57,16 +91,17 @@ public GenericResponse getThemes() { * @return 해당하는 Theme에 포함된 Program */ @GetMapping("/{theme}") - public GenericResponse getProgramByTheme(@PathVariable String theme) { + public GenericResponse findProgramByTheme(@PathVariable String theme) { ProgramTheme programTheme = ProgramTheme.valueOf(theme.toUpperCase()); List result = programService.findByTheme(programTheme); ProgramListResponse response = new ProgramListResponse(result); return GenericResponse.ok(response); } + + /** * ToDo * 기간 별 조회 - * 상세 조회 * FAQ 생성 * FAQ 목록 조회 * 잔여 인원 조회 diff --git a/src/main/java/TripAmi/backend/web/api/program/response/ProgramDetailDto.java b/src/main/java/TripAmi/backend/web/api/program/response/ProgramDetailDto.java new file mode 100644 index 0000000..7e3164b --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/program/response/ProgramDetailDto.java @@ -0,0 +1,18 @@ +package TripAmi.backend.web.api.program.response; + +import TripAmi.backend.app.product.ProgramTheme; +import lombok.Builder; + +import java.util.List; + +@Builder +public record ProgramDetailDto( + String title, + List images, + String content, + Integer price, + Long amiId, + ProgramTheme theme + +) { +} diff --git a/src/main/java/TripAmi/backend/web/api/program/response/ProgramDto.java b/src/main/java/TripAmi/backend/web/api/program/response/ProgramDto.java index 967f08c..83f2e71 100644 --- a/src/main/java/TripAmi/backend/web/api/program/response/ProgramDto.java +++ b/src/main/java/TripAmi/backend/web/api/program/response/ProgramDto.java @@ -1,9 +1,11 @@ package TripAmi.backend.web.api.program.response; import TripAmi.backend.app.product.ProgramTheme; +import lombok.Builder; import java.util.List; +@Builder public record ProgramDto( String title, List images, @@ -11,6 +13,5 @@ public record ProgramDto( Integer price, Long amiId, ProgramTheme theme - ) { } From 581d9d97490d84d58a5e85977ad278485f5df24c Mon Sep 17 00:00:00 2001 From: jaekkang Date: Mon, 11 Dec 2023 18:01:04 +0900 Subject: [PATCH 08/27] Feat: Add Service for faq controller --- .../backend/app/faq/service/FaqService.java | 9 +++-- .../app/faq/service/FaqServiceImpl.java | 27 ++++++++++---- .../backend/web/api/faq/FaqController.java | 37 +++++++++++++++++++ .../web/api/faq/request/CreateFaqRequest.java | 7 ++++ .../backend/web/api/faq/response/FaqDto.java | 12 ++++++ .../web/api/faq/response/FaqListResponse.java | 14 +++++++ 6 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 src/main/java/TripAmi/backend/web/api/faq/FaqController.java create mode 100644 src/main/java/TripAmi/backend/web/api/faq/request/CreateFaqRequest.java create mode 100644 src/main/java/TripAmi/backend/web/api/faq/response/FaqDto.java create mode 100644 src/main/java/TripAmi/backend/web/api/faq/response/FaqListResponse.java diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java index 66a922e..9cfea22 100644 --- a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java +++ b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java @@ -1,13 +1,14 @@ package TripAmi.backend.app.faq.service; -import TripAmi.backend.app.faq.domain.Faq; +import TripAmi.backend.web.api.faq.request.CreateFaqRequest; +import TripAmi.backend.web.api.faq.response.FaqDto; import java.util.List; public interface FaqService { - void save(String question, String answer); + void save(CreateFaqRequest request); - Faq findById(Long id); + FaqDto findById(Long id); - List findAll(); + List findAll(); } diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java b/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java index aaf3e2c..31c71a3 100644 --- a/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java @@ -2,11 +2,14 @@ import TripAmi.backend.app.faq.domain.Faq; import TripAmi.backend.app.faq.domain.FaqRepository; +import TripAmi.backend.web.api.faq.request.CreateFaqRequest; +import TripAmi.backend.web.api.faq.response.FaqDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -16,21 +19,31 @@ public class FaqServiceImpl implements FaqService { @Override @Transactional - public void save(String question, String answer) { + public void save(CreateFaqRequest request) { Faq faq = Faq.builder() - .question(question) - .answer(answer) + .question(request.question()) + .answer(request.answer()) .build(); faqRepository.save(faq); } @Override - public Faq findById(Long id) { - return faqRepository.findById(id).orElseThrow(); + public FaqDto findById(Long id) { + Faq item = faqRepository.findById(id).orElseThrow(); + return FaqDto.builder() + .question(item.getQuestion()) + .answer(item.getAnswer()) + .build(); } @Override - public List findAll() { - return faqRepository.findAll(); + public List findAll() { + List allFaq = faqRepository.findAll(); + return allFaq.stream() + .map(item -> new FaqDto( + item.getQuestion(), + item.getAnswer() + )) + .collect(Collectors.toList()); } } diff --git a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java new file mode 100644 index 0000000..dc7486b --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java @@ -0,0 +1,37 @@ +package TripAmi.backend.web.api.faq; + +import TripAmi.backend.app.faq.service.FaqService; +import TripAmi.backend.web.api.common.GenericResponse; +import TripAmi.backend.web.api.faq.request.CreateFaqRequest; +import TripAmi.backend.web.api.faq.response.FaqDto; +import TripAmi.backend.web.api.faq.response.FaqListResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("api/v1/faqs") +@RequiredArgsConstructor +public class FaqController { + private final FaqService faqService; + + @PostMapping + public void save(@RequestBody CreateFaqRequest request) { + faqService.save(request); + } + + @GetMapping + public GenericResponse findAll() { + List result = faqService.findAll(); + FaqListResponse response = FaqListResponse.builder() + .faqs(result) + .build(); + return GenericResponse.ok(response); + } + + @GetMapping("/{id}") + public GenericResponse findById(@PathVariable Long id) { + return GenericResponse.ok(faqService.findById(id)); + } +} diff --git a/src/main/java/TripAmi/backend/web/api/faq/request/CreateFaqRequest.java b/src/main/java/TripAmi/backend/web/api/faq/request/CreateFaqRequest.java new file mode 100644 index 0000000..2923140 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/faq/request/CreateFaqRequest.java @@ -0,0 +1,7 @@ +package TripAmi.backend.web.api.faq.request; + +public record CreateFaqRequest( + String question, + String answer +) { +} diff --git a/src/main/java/TripAmi/backend/web/api/faq/response/FaqDto.java b/src/main/java/TripAmi/backend/web/api/faq/response/FaqDto.java new file mode 100644 index 0000000..2aef2ed --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/faq/response/FaqDto.java @@ -0,0 +1,12 @@ +package TripAmi.backend.web.api.faq.response; + +import lombok.Builder; + +public record FaqDto( + String question, + String answer +) { + @Builder + public FaqDto { + } +} diff --git a/src/main/java/TripAmi/backend/web/api/faq/response/FaqListResponse.java b/src/main/java/TripAmi/backend/web/api/faq/response/FaqListResponse.java new file mode 100644 index 0000000..d665ede --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/faq/response/FaqListResponse.java @@ -0,0 +1,14 @@ +package TripAmi.backend.web.api.faq.response; + +import lombok.Builder; + +import java.util.List; + +public record FaqListResponse( + List faqs + +) { + @Builder + public FaqListResponse { + } +} From 2370a8f8c85d7e332443e6fb379086263e45dd37 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Tue, 12 Dec 2023 15:26:42 +0900 Subject: [PATCH 09/27] Feat: Create entity for fixed date info in Program --- .../backend/app/product/domain/OpenDay.java | 24 ++++++++++++++++--- .../app/product/domain/OpenDayRepository.java | 6 +++++ .../backend/app/product/domain/Product.java | 1 - .../app/product/service/ProgramService.java | 3 +++ .../product/service/ProgramServiceImpl.java | 9 +++++++ .../web/api/program/ProgramController.java | 18 ++++++++------ .../product/service/ProgramServiceTest.java | 2 +- 7 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java b/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java index abcaa33..2566b8d 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java +++ b/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java @@ -4,8 +4,11 @@ import lombok.AccessLevel; import lombok.Builder; import lombok.NoArgsConstructor; +import lombok.SneakyThrows; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -24,12 +27,27 @@ public class OpenDay { LocalDateTime fixedDate; @Column(nullable = false) - Integer count; + Integer fixedPeople; + + @ElementCollection + @CollectionTable(name = "open_day_joined_persons", joinColumns = @JoinColumn(name = "open_day_id")) + @Column(name = "person_id") + List joinedPersonIds = new ArrayList<>(); @Builder - public OpenDay(Program program, LocalDateTime fixedDate, Integer count) { + public OpenDay(Program program, LocalDateTime fixedDate) { this.program = program; this.fixedDate = fixedDate; - this.count = count; + this.fixedPeople = 0; + } + + @SneakyThrows + public void joinPerson(Long personId) { + if (this.fixedPeople < program.getTotalPersonnel()) + fixedPeople++; + else + throw new RuntimeException("정원 초과되었습니다."); + + joinedPersonIds.add(personId); } } diff --git a/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java b/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java index 77073ff..37d8c11 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java +++ b/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java @@ -1,6 +1,12 @@ package TripAmi.backend.app.product.domain; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; public interface OpenDayRepository extends JpaRepository { + + @Query("SELECT o FROM OpenDay o WHERE o.program.id = : programId") + List findByProgramId(Long programId); } diff --git a/src/main/java/TripAmi/backend/app/product/domain/Product.java b/src/main/java/TripAmi/backend/app/product/domain/Product.java index 5ababf6..824dc59 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/Product.java +++ b/src/main/java/TripAmi/backend/app/product/domain/Product.java @@ -1,6 +1,5 @@ package TripAmi.backend.app.product.domain; -import TripAmi.backend.app.util.BaseEntity; import TripAmi.backend.app.util.infra.StringListConverter; import jakarta.persistence.*; import lombok.AccessLevel; diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramService.java b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java index 9ecacaa..4e69799 100644 --- a/src/main/java/TripAmi/backend/app/product/service/ProgramService.java +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java @@ -1,6 +1,7 @@ package TripAmi.backend.app.product.service; import TripAmi.backend.app.product.ProgramTheme; +import TripAmi.backend.app.product.domain.OpenDay; import TripAmi.backend.app.product.domain.Program; import TripAmi.backend.web.api.program.request.CreateProgramRequest; import TripAmi.backend.web.api.program.response.ProgramDto; @@ -17,4 +18,6 @@ public interface ProgramService { List findByTheme(ProgramTheme theme); Program findDetailById(Long id); + + List findFixedDays(Long programId); } diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java index 3765cf7..b0dd5b9 100644 --- a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java @@ -1,6 +1,8 @@ package TripAmi.backend.app.product.service; import TripAmi.backend.app.product.ProgramTheme; +import TripAmi.backend.app.product.domain.OpenDay; +import TripAmi.backend.app.product.domain.OpenDayRepository; import TripAmi.backend.app.product.domain.Program; import TripAmi.backend.app.product.domain.ProgramRepository; import TripAmi.backend.web.api.program.request.CreateProgramRequest; @@ -19,6 +21,8 @@ public class ProgramServiceImpl implements ProgramService { private final ProgramRepository programRepository; + private final OpenDayRepository openDayRepository; + @Override @Transactional public void save(CreateProgramRequest request) { @@ -55,4 +59,9 @@ public List findByTheme(ProgramTheme theme) { public Program findDetailById(Long id) { return programRepository.findById(id).orElseThrow(); } + + @Override + public List findFixedDays(Long programId) { + return openDayRepository.findByProgramId(programId); + } } diff --git a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java index df6eaa9..efd4d92 100644 --- a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java +++ b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java @@ -84,11 +84,11 @@ public GenericResponse findThemes() { } /** - * 파람으로 던져지는 Theme에 해당하는 프로그램들을 리턴해줌 - * 없는 Theme 던져지면 Exception + * Parameter로 받은 Theme에 해당하는 프로그램들을 조회 + * 없는 Theme를 받으면 Exception * - * @param theme 테마 (String) - * @return 해당하는 Theme에 포함된 Program + * @param theme 테마이름 (String) + * @return 해당하는 Theme에 포함된 Program(s) */ @GetMapping("/{theme}") public GenericResponse findProgramByTheme(@PathVariable String theme) { @@ -98,12 +98,16 @@ public GenericResponse findProgramByTheme(@PathVariable Str return GenericResponse.ok(response); } + @GetMapping("/{id}/checkRemaining") + public GenericResponse getRemainingCount(@PathVariable Long id) { + Program program = programService.findById(id); + + // ToDo 전체 인원에서 조인한 인원 빼줘야됨 + return GenericResponse.ok(program.getTotalPersonnel()); + } /** * ToDo * 기간 별 조회 - * FAQ 생성 - * FAQ 목록 조회 - * 잔여 인원 조회 */ } diff --git a/src/test/java/TripAmi/backend/app/product/service/ProgramServiceTest.java b/src/test/java/TripAmi/backend/app/product/service/ProgramServiceTest.java index e88028e..cc77291 100644 --- a/src/test/java/TripAmi/backend/app/product/service/ProgramServiceTest.java +++ b/src/test/java/TripAmi/backend/app/product/service/ProgramServiceTest.java @@ -45,7 +45,7 @@ void create_program() { ); // // Act - programService.createProgram(request); + programService.save(request); // // // Assert Assertions.assertNotNull(programService.findByTitle("Program Title")); // Correct title From be6b1d9352aac6df10ff9a142240717b3401d8a9 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Tue, 12 Dec 2023 16:27:55 +0900 Subject: [PATCH 10/27] Feat: rm OneDay and edit reservation entity --- .../backend/app/product/domain/OpenDay.java | 53 ------------------- .../app/product/domain/OpenDayRepository.java | 12 ----- .../app/product/domain/ProgramRepository.java | 3 +- .../app/product/service/ProgramService.java | 6 +-- .../product/service/ProgramServiceImpl.java | 14 +---- .../app/reservation/domain/Reservation.java | 48 ++++++++++++----- .../domain/ReservationRepository.java | 5 ++ .../service/ReservationService.java | 9 ++++ .../service/ReservationServiceImpl.java | 21 ++++++++ .../web/api/program/ProgramController.java | 14 ++++- 10 files changed, 86 insertions(+), 99 deletions(-) delete mode 100644 src/main/java/TripAmi/backend/app/product/domain/OpenDay.java delete mode 100644 src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java create mode 100644 src/main/java/TripAmi/backend/app/reservation/service/ReservationService.java create mode 100644 src/main/java/TripAmi/backend/app/reservation/service/ReservationServiceImpl.java diff --git a/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java b/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java deleted file mode 100644 index 2566b8d..0000000 --- a/src/main/java/TripAmi/backend/app/product/domain/OpenDay.java +++ /dev/null @@ -1,53 +0,0 @@ -package TripAmi.backend.app.product.domain; - -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.NoArgsConstructor; -import lombok.SneakyThrows; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -@Entity -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Table(name = "open_day") -public class OpenDay { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "open_day_id") - Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "program_id") - Program program; - - @Column(nullable = false) - LocalDateTime fixedDate; - - @Column(nullable = false) - Integer fixedPeople; - - @ElementCollection - @CollectionTable(name = "open_day_joined_persons", joinColumns = @JoinColumn(name = "open_day_id")) - @Column(name = "person_id") - List joinedPersonIds = new ArrayList<>(); - - @Builder - public OpenDay(Program program, LocalDateTime fixedDate) { - this.program = program; - this.fixedDate = fixedDate; - this.fixedPeople = 0; - } - - @SneakyThrows - public void joinPerson(Long personId) { - if (this.fixedPeople < program.getTotalPersonnel()) - fixedPeople++; - else - throw new RuntimeException("정원 초과되었습니다."); - - joinedPersonIds.add(personId); - } -} diff --git a/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java b/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java deleted file mode 100644 index 37d8c11..0000000 --- a/src/main/java/TripAmi/backend/app/product/domain/OpenDayRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package TripAmi.backend.app.product.domain; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -import java.util.List; - -public interface OpenDayRepository extends JpaRepository { - - @Query("SELECT o FROM OpenDay o WHERE o.program.id = : programId") - List findByProgramId(Long programId); -} diff --git a/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java b/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java index d3d1deb..d99c910 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java +++ b/src/main/java/TripAmi/backend/app/product/domain/ProgramRepository.java @@ -1,7 +1,6 @@ package TripAmi.backend.app.product.domain; import TripAmi.backend.app.product.ProgramTheme; -import TripAmi.backend.web.api.program.response.ProgramDto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -14,5 +13,5 @@ public interface ProgramRepository extends JpaRepository { List findByTitle(String title); @Query("SELECT p FROM Program p WHERE p.theme = :theme") - List findByTheme(@Param("theme") ProgramTheme theme); + List findByTheme(@Param("theme") ProgramTheme theme); } diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramService.java b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java index 4e69799..4775ff4 100644 --- a/src/main/java/TripAmi/backend/app/product/service/ProgramService.java +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramService.java @@ -1,10 +1,8 @@ package TripAmi.backend.app.product.service; import TripAmi.backend.app.product.ProgramTheme; -import TripAmi.backend.app.product.domain.OpenDay; import TripAmi.backend.app.product.domain.Program; import TripAmi.backend.web.api.program.request.CreateProgramRequest; -import TripAmi.backend.web.api.program.response.ProgramDto; import java.util.List; @@ -15,9 +13,7 @@ public interface ProgramService { List findByTitle(String title); - List findByTheme(ProgramTheme theme); + List findByTheme(ProgramTheme theme); Program findDetailById(Long id); - - List findFixedDays(Long programId); } diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java index b0dd5b9..4b18c7e 100644 --- a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java @@ -1,14 +1,10 @@ package TripAmi.backend.app.product.service; import TripAmi.backend.app.product.ProgramTheme; -import TripAmi.backend.app.product.domain.OpenDay; -import TripAmi.backend.app.product.domain.OpenDayRepository; import TripAmi.backend.app.product.domain.Program; import TripAmi.backend.app.product.domain.ProgramRepository; import TripAmi.backend.web.api.program.request.CreateProgramRequest; -import TripAmi.backend.web.api.program.response.ProgramDto; import lombok.RequiredArgsConstructor; -import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -21,8 +17,6 @@ public class ProgramServiceImpl implements ProgramService { private final ProgramRepository programRepository; - private final OpenDayRepository openDayRepository; - @Override @Transactional public void save(CreateProgramRequest request) { @@ -51,7 +45,7 @@ public List findByTitle(String title) { } @Override - public List findByTheme(ProgramTheme theme) { + public List findByTheme(ProgramTheme theme) { return programRepository.findByTheme(theme); } @@ -59,9 +53,5 @@ public List findByTheme(ProgramTheme theme) { public Program findDetailById(Long id) { return programRepository.findById(id).orElseThrow(); } - - @Override - public List findFixedDays(Long programId) { - return openDayRepository.findByProgramId(programId); - } + } diff --git a/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java b/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java index b1eb9d1..83354d7 100644 --- a/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java +++ b/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java @@ -1,11 +1,13 @@ package TripAmi.backend.app.reservation.domain; import TripAmi.backend.app.member.domain.Member; +import TripAmi.backend.app.product.domain.Program; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -13,18 +15,38 @@ @Getter public class Reservation { @Id - @Column(name = "reservation_id") @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + @Column(name = "reservation_id") + Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "program_id") + Program program; -// private Program program + @Column(nullable = false) + LocalDateTime fixedDate; + + @Column(nullable = false) + Integer fixedPeople; + + @ElementCollection + @CollectionTable(name = "reservation_people", joinColumns = @JoinColumn(name = "reservation_id")) + @Column(name = "authmember_id") + List joinedPersonIds = new ArrayList<>(); + + public Reservation(Program program, LocalDateTime fixedDate) { + this.program = program; + this.fixedDate = fixedDate; + this.fixedPeople = 0; + } - @ManyToOne - @JoinColumn(name = "member_id") - private Member member; + @SneakyThrows + public void joinPerson(Long personId) { + if (this.fixedPeople < program.getTotalPersonnel()) + fixedPeople++; + else + throw new RuntimeException("정원 초과되었습니다."); - @Builder - public Reservation(Member member) { - this.member = member; + joinedPersonIds.add(personId); } } diff --git a/src/main/java/TripAmi/backend/app/reservation/domain/ReservationRepository.java b/src/main/java/TripAmi/backend/app/reservation/domain/ReservationRepository.java index 70b9b11..d8c4474 100644 --- a/src/main/java/TripAmi/backend/app/reservation/domain/ReservationRepository.java +++ b/src/main/java/TripAmi/backend/app/reservation/domain/ReservationRepository.java @@ -1,6 +1,11 @@ package TripAmi.backend.app.reservation.domain; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; public interface ReservationRepository extends JpaRepository { + @Query("SELECT r FROM Reservation r WHERE r.program.id = :programId") + List findByProgramId(Long programId); } diff --git a/src/main/java/TripAmi/backend/app/reservation/service/ReservationService.java b/src/main/java/TripAmi/backend/app/reservation/service/ReservationService.java new file mode 100644 index 0000000..95c12c3 --- /dev/null +++ b/src/main/java/TripAmi/backend/app/reservation/service/ReservationService.java @@ -0,0 +1,9 @@ +package TripAmi.backend.app.reservation.service; + +import TripAmi.backend.app.reservation.domain.Reservation; + +import java.util.List; + +public interface ReservationService { + List findFixedDays(Long programId); +} diff --git a/src/main/java/TripAmi/backend/app/reservation/service/ReservationServiceImpl.java b/src/main/java/TripAmi/backend/app/reservation/service/ReservationServiceImpl.java new file mode 100644 index 0000000..4bba42e --- /dev/null +++ b/src/main/java/TripAmi/backend/app/reservation/service/ReservationServiceImpl.java @@ -0,0 +1,21 @@ +package TripAmi.backend.app.reservation.service; + +import TripAmi.backend.app.reservation.domain.Reservation; +import TripAmi.backend.app.reservation.domain.ReservationRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class ReservationServiceImpl implements ReservationService { + + private final ReservationRepository reservationRepository; + @Override + public List findFixedDays(Long programId) { + return reservationRepository.findByProgramId(programId); + } +} diff --git a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java index efd4d92..6bb66a3 100644 --- a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java +++ b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java @@ -93,12 +93,22 @@ public GenericResponse findThemes() { @GetMapping("/{theme}") public GenericResponse findProgramByTheme(@PathVariable String theme) { ProgramTheme programTheme = ProgramTheme.valueOf(theme.toUpperCase()); - List result = programService.findByTheme(programTheme); + List result = programService.findByTheme(programTheme).stream() + .map(item -> ProgramDto.builder() + .title(item.getTitle()) + .theme(item.getTheme()) + .price(item.getPrice()) + .amiId(item.getAmiId()) + .content(item.getContent()) + .images(item.getImages()) + .build() + ).collect(Collectors.toList()); + ProgramListResponse response = new ProgramListResponse(result); return GenericResponse.ok(response); } - @GetMapping("/{id}/checkRemaining") + @GetMapping("/{id}/remain") public GenericResponse getRemainingCount(@PathVariable Long id) { Program program = programService.findById(id); From e69c8dda08cfae1b124bd20a8f3b44cae381d52c Mon Sep 17 00:00:00 2001 From: jaekkang Date: Tue, 12 Dec 2023 17:03:34 +0900 Subject: [PATCH 11/27] Feat: Edit some column name --- .../java/TripAmi/backend/app/product/domain/Program.java | 8 +++++--- .../backend/app/reservation/domain/Reservation.java | 4 ++-- .../app/util/service/exception/SendMailException.java | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/TripAmi/backend/app/product/domain/Program.java b/src/main/java/TripAmi/backend/app/product/domain/Program.java index 8b8f664..f13b336 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/Program.java +++ b/src/main/java/TripAmi/backend/app/product/domain/Program.java @@ -17,30 +17,32 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter public class Program extends Product { + @Column(name = "ami_id") Long amiId; @OneToMany(mappedBy = "program") List spots = new ArrayList<>(); + @Column(name = "total_people") Integer totalPersonnel; @Enumerated(value = EnumType.STRING) ProgramTheme theme; @Convert(converter = StringListConverter.class) - List keyWords; + List keywords; //todo address class 작성 String location; @Builder - public Program(String title, List images, String content, Integer price, List spots, Long amiId, Integer totalPersonnel, ProgramTheme theme, List keyWords, String location) { + public Program(String title, List images, String content, Integer price, List spots, Long amiId, Integer totalPersonnel, ProgramTheme theme, List keywords, String location) { super(title, images, content, price); this.amiId = amiId; this.spots.addAll(spots); this.totalPersonnel = totalPersonnel; this.theme = theme; - this.keyWords = keyWords; + this.keywords = keywords; this.location = location; } } diff --git a/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java b/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java index 83354d7..658b9be 100644 --- a/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java +++ b/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java @@ -23,10 +23,10 @@ public class Reservation { @JoinColumn(name = "program_id") Program program; - @Column(nullable = false) + @Column(nullable = false, name = "fixed_date") LocalDateTime fixedDate; - @Column(nullable = false) + @Column(nullable = false, name = "fixed_people") Integer fixedPeople; @ElementCollection diff --git a/src/main/java/TripAmi/backend/app/util/service/exception/SendMailException.java b/src/main/java/TripAmi/backend/app/util/service/exception/SendMailException.java index acd6e6c..0bfa974 100644 --- a/src/main/java/TripAmi/backend/app/util/service/exception/SendMailException.java +++ b/src/main/java/TripAmi/backend/app/util/service/exception/SendMailException.java @@ -1,4 +1,4 @@ package TripAmi.backend.app.util.service.exception; -public class SendMailException extends RuntimeException{ +public class SendMailException extends RuntimeException { } From e59b02a81a86324abe508af9fabf94464a93bbd1 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 17:11:49 +0900 Subject: [PATCH 12/27] Feat: Add update method for FAQ --- .../java/TripAmi/backend/app/faq/domain/Faq.java | 5 +++++ .../backend/app/faq/service/FaqService.java | 7 +++++-- .../backend/app/faq/service/FaqServiceImpl.java | 16 ++++++++++++++-- .../backend/web/api/faq/FaqController.java | 10 ++++++++-- ...eateFaqRequest.java => FaqCreateRequest.java} | 2 +- .../web/api/faq/request/FaqUpdateRequest.java | 9 +++++++++ 6 files changed, 42 insertions(+), 7 deletions(-) rename src/main/java/TripAmi/backend/web/api/faq/request/{CreateFaqRequest.java => FaqCreateRequest.java} (73%) create mode 100644 src/main/java/TripAmi/backend/web/api/faq/request/FaqUpdateRequest.java diff --git a/src/main/java/TripAmi/backend/app/faq/domain/Faq.java b/src/main/java/TripAmi/backend/app/faq/domain/Faq.java index f41bbda..d16935f 100644 --- a/src/main/java/TripAmi/backend/app/faq/domain/Faq.java +++ b/src/main/java/TripAmi/backend/app/faq/domain/Faq.java @@ -25,4 +25,9 @@ public Faq(String question, String answer) { this.question = question; this.answer = answer; } + + public void update(String question, String answer) { + this.question = question; + this.answer = answer; + } } diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java index 9cfea22..b5cd8cc 100644 --- a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java +++ b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java @@ -1,14 +1,17 @@ package TripAmi.backend.app.faq.service; -import TripAmi.backend.web.api.faq.request.CreateFaqRequest; +import TripAmi.backend.web.api.faq.request.FaqCreateRequest; +import TripAmi.backend.web.api.faq.request.FaqUpdateRequest; import TripAmi.backend.web.api.faq.response.FaqDto; import java.util.List; public interface FaqService { - void save(CreateFaqRequest request); + void save(FaqCreateRequest request); FaqDto findById(Long id); List findAll(); + + FaqDto updateFaq(Long faqId, FaqUpdateRequest request); } diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java b/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java index 31c71a3..2471214 100644 --- a/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java @@ -2,7 +2,8 @@ import TripAmi.backend.app.faq.domain.Faq; import TripAmi.backend.app.faq.domain.FaqRepository; -import TripAmi.backend.web.api.faq.request.CreateFaqRequest; +import TripAmi.backend.web.api.faq.request.FaqCreateRequest; +import TripAmi.backend.web.api.faq.request.FaqUpdateRequest; import TripAmi.backend.web.api.faq.response.FaqDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -19,7 +20,7 @@ public class FaqServiceImpl implements FaqService { @Override @Transactional - public void save(CreateFaqRequest request) { + public void save(FaqCreateRequest request) { Faq faq = Faq.builder() .question(request.question()) .answer(request.answer()) @@ -46,4 +47,15 @@ public List findAll() { )) .collect(Collectors.toList()); } + + @Override + @Transactional + public FaqDto updateFaq(Long faqId, FaqUpdateRequest request) { + Faq faq = faqRepository.findById(faqId).orElseThrow(); + faq.update(request.question(), request.answer()); + return FaqDto.builder() + .question(request.question()) + .answer(request.answer()) + .build(); + } } diff --git a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java index dc7486b..9d9677b 100644 --- a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java +++ b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java @@ -2,7 +2,8 @@ import TripAmi.backend.app.faq.service.FaqService; import TripAmi.backend.web.api.common.GenericResponse; -import TripAmi.backend.web.api.faq.request.CreateFaqRequest; +import TripAmi.backend.web.api.faq.request.FaqCreateRequest; +import TripAmi.backend.web.api.faq.request.FaqUpdateRequest; import TripAmi.backend.web.api.faq.response.FaqDto; import TripAmi.backend.web.api.faq.response.FaqListResponse; import lombok.RequiredArgsConstructor; @@ -17,7 +18,7 @@ public class FaqController { private final FaqService faqService; @PostMapping - public void save(@RequestBody CreateFaqRequest request) { + public void save(@RequestBody FaqCreateRequest request) { faqService.save(request); } @@ -34,4 +35,9 @@ public GenericResponse findAll() { public GenericResponse findById(@PathVariable Long id) { return GenericResponse.ok(faqService.findById(id)); } + + @PostMapping("/{id}") + public GenericResponse updateFaq(@PathVariable Long id, @RequestBody FaqUpdateRequest request) { + return GenericResponse.ok(faqService.updateFaq(id, request)); + } } diff --git a/src/main/java/TripAmi/backend/web/api/faq/request/CreateFaqRequest.java b/src/main/java/TripAmi/backend/web/api/faq/request/FaqCreateRequest.java similarity index 73% rename from src/main/java/TripAmi/backend/web/api/faq/request/CreateFaqRequest.java rename to src/main/java/TripAmi/backend/web/api/faq/request/FaqCreateRequest.java index 2923140..559ac24 100644 --- a/src/main/java/TripAmi/backend/web/api/faq/request/CreateFaqRequest.java +++ b/src/main/java/TripAmi/backend/web/api/faq/request/FaqCreateRequest.java @@ -1,6 +1,6 @@ package TripAmi.backend.web.api.faq.request; -public record CreateFaqRequest( +public record FaqCreateRequest( String question, String answer ) { diff --git a/src/main/java/TripAmi/backend/web/api/faq/request/FaqUpdateRequest.java b/src/main/java/TripAmi/backend/web/api/faq/request/FaqUpdateRequest.java new file mode 100644 index 0000000..89fe0f8 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/faq/request/FaqUpdateRequest.java @@ -0,0 +1,9 @@ +package TripAmi.backend.web.api.faq.request; + +import lombok.Builder; + +public record FaqUpdateRequest(String question, String answer) { + @Builder + public FaqUpdateRequest { + } +} From 384685353c2e1a63bd96f8e50cb8f56ecb25fbf1 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 17:12:10 +0900 Subject: [PATCH 13/27] Style: Edit directory root, --- .../app/product/{service => infra}/ProgramServiceImpl.java | 7 ++++--- .../{service => infra}/ReservationServiceImpl.java | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) rename src/main/java/TripAmi/backend/app/product/{service => infra}/ProgramServiceImpl.java (91%) rename src/main/java/TripAmi/backend/app/reservation/{service => infra}/ReservationServiceImpl.java (85%) diff --git a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java b/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java similarity index 91% rename from src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java rename to src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java index 4b18c7e..fdb1906 100644 --- a/src/main/java/TripAmi/backend/app/product/service/ProgramServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java @@ -1,8 +1,9 @@ -package TripAmi.backend.app.product.service; +package TripAmi.backend.app.product.infra; import TripAmi.backend.app.product.ProgramTheme; import TripAmi.backend.app.product.domain.Program; import TripAmi.backend.app.product.domain.ProgramRepository; +import TripAmi.backend.app.product.service.ProgramService; import TripAmi.backend.web.api.program.request.CreateProgramRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -27,7 +28,7 @@ public void save(CreateProgramRequest request) { .price(request.price()) .totalPersonnel(request.totalPersonnel()) .theme(request.theme()) - .keyWords(request.keyWords()) + .keywords(request.keyWords()) .spots(request.spots()) .location(request.location()) .build(); @@ -53,5 +54,5 @@ public List findByTheme(ProgramTheme theme) { public Program findDetailById(Long id) { return programRepository.findById(id).orElseThrow(); } - + } diff --git a/src/main/java/TripAmi/backend/app/reservation/service/ReservationServiceImpl.java b/src/main/java/TripAmi/backend/app/reservation/infra/ReservationServiceImpl.java similarity index 85% rename from src/main/java/TripAmi/backend/app/reservation/service/ReservationServiceImpl.java rename to src/main/java/TripAmi/backend/app/reservation/infra/ReservationServiceImpl.java index 4bba42e..c682e4d 100644 --- a/src/main/java/TripAmi/backend/app/reservation/service/ReservationServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/reservation/infra/ReservationServiceImpl.java @@ -1,7 +1,8 @@ -package TripAmi.backend.app.reservation.service; +package TripAmi.backend.app.reservation.infra; import TripAmi.backend.app.reservation.domain.Reservation; import TripAmi.backend.app.reservation.domain.ReservationRepository; +import TripAmi.backend.app.reservation.service.ReservationService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; From f36da7752f0822966d23c89980662ac37f1f1182 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 17:12:34 +0900 Subject: [PATCH 14/27] Comment: Edit comment --- .../backend/web/api/program/ProgramController.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java index 6bb66a3..f1446e0 100644 --- a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java +++ b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java @@ -31,12 +31,7 @@ public void save(@RequestBody CreateProgramRequest request) { programService.save(request); } - /** - * 현재 Program들이 가지고 있는 Theme 전체 검색 - * 데이터가 있는 Theme만 불러와짐 - * - * @return themes - */ + @GetMapping("/{id}") public GenericResponse findById(@PathVariable Long id) { @@ -73,6 +68,13 @@ public GenericResponse findProgramDetail(@PathVariable Long id return GenericResponse.ok(response); } + /** + * 현재 Program들이 가지고 있는 Theme 전체 검색 + * 데이터가 있는 Theme만 불러와짐 + * + * @return themes + */ + @GetMapping("/themes") public GenericResponse findThemes() { List result = Arrays.stream(ProgramTheme.values()) From 5a754e5f79fae285baf1d0bc2917ae647d9f3e41 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 18:17:01 +0900 Subject: [PATCH 15/27] Feat: Create banner service , controller --- .../backend/app/banner/domain/Banner.java | 16 ++++- .../app/banner/domain/BannerRepository.java | 1 + .../app/banner/infra/BannerServiceImpl.java | 63 +++++++++++++++++++ .../app/banner/service/BannerService.java | 17 +++++ .../web/api/banner/BannerController.java | 54 ++++++++++++++++ .../banner/request/BannerCreateRequest.java | 9 +++ .../banner/request/BannerUpdateRequest.java | 9 +++ .../web/api/banner/response/BannerDto.java | 11 ++++ .../banner/response/BannerListResponse.java | 12 ++++ 9 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java create mode 100644 src/main/java/TripAmi/backend/app/banner/service/BannerService.java create mode 100644 src/main/java/TripAmi/backend/web/api/banner/BannerController.java create mode 100644 src/main/java/TripAmi/backend/web/api/banner/request/BannerCreateRequest.java create mode 100644 src/main/java/TripAmi/backend/web/api/banner/request/BannerUpdateRequest.java create mode 100644 src/main/java/TripAmi/backend/web/api/banner/response/BannerDto.java create mode 100644 src/main/java/TripAmi/backend/web/api/banner/response/BannerListResponse.java diff --git a/src/main/java/TripAmi/backend/app/banner/domain/Banner.java b/src/main/java/TripAmi/backend/app/banner/domain/Banner.java index 78bf616..a430aec 100644 --- a/src/main/java/TripAmi/backend/app/banner/domain/Banner.java +++ b/src/main/java/TripAmi/backend/app/banner/domain/Banner.java @@ -28,10 +28,22 @@ public class Banner { @Column(nullable = false, name = "create_at") private LocalDateTime createdAt; + @Column(nullable = false, name = "open_status") + private Boolean isOpened; + @Builder - public Banner(String imgUrl, String title, LocalDateTime createdAt) { + public Banner(String imgUrl, String title) { this.imgUrl = imgUrl; this.title = title; - this.createdAt = createdAt; + this.isOpened = true; + } + + public void update(String title, String imgUrl) { + this.title = title; + this.imgUrl = imgUrl; + } + + public void delete() { + this.isOpened = false; } } diff --git a/src/main/java/TripAmi/backend/app/banner/domain/BannerRepository.java b/src/main/java/TripAmi/backend/app/banner/domain/BannerRepository.java index 85c9909..55eaf47 100644 --- a/src/main/java/TripAmi/backend/app/banner/domain/BannerRepository.java +++ b/src/main/java/TripAmi/backend/app/banner/domain/BannerRepository.java @@ -3,4 +3,5 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface BannerRepository extends JpaRepository { + } diff --git a/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java b/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java new file mode 100644 index 0000000..4ed47cd --- /dev/null +++ b/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java @@ -0,0 +1,63 @@ +package TripAmi.backend.app.banner.infra; + +import TripAmi.backend.app.banner.domain.Banner; +import TripAmi.backend.app.banner.domain.BannerRepository; +import TripAmi.backend.app.banner.service.BannerService; +import TripAmi.backend.web.api.banner.response.BannerDto; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class BannerServiceImpl implements BannerService { + private final BannerRepository bannerRepository; + + @Override + @Transactional + public void join(String title, String imgUrl) { + Banner banner = Banner.builder() + .title(title) + .imgUrl(imgUrl) + .build(); + bannerRepository.save(banner); + } + + @Override + public BannerDto findById(Long id) { + Banner findOne = bannerRepository.findById(id).orElseThrow(); + return new BannerDto(id, findOne.getTitle(), findOne.getImgUrl()); + } + + @Override + public List findAll() { + List items = bannerRepository.findAll(); + return items.stream() + .map(item -> new BannerDto( + item.getId(), + item.getTitle(), + item.getImgUrl() + )).collect(Collectors.toList()); + } + + @Override + public BannerDto update(Long id, String title, String imgUrl) { + Banner banner = bannerRepository.findById(id).orElseThrow(); + banner.update(title, imgUrl); + return BannerDto.builder() + .title(title) + .imgUrl(imgUrl) + .build(); + } + + @Override + public void delete(Long id) { + Banner banner = bannerRepository.findById(id).orElseThrow(); + banner.delete(); + } + +} diff --git a/src/main/java/TripAmi/backend/app/banner/service/BannerService.java b/src/main/java/TripAmi/backend/app/banner/service/BannerService.java new file mode 100644 index 0000000..bbcd83d --- /dev/null +++ b/src/main/java/TripAmi/backend/app/banner/service/BannerService.java @@ -0,0 +1,17 @@ +package TripAmi.backend.app.banner.service; + +import TripAmi.backend.web.api.banner.response.BannerDto; + +import java.util.List; + +public interface BannerService { + void join(String title, String imgUrl); + + BannerDto findById(Long id); + + List findAll(); + + BannerDto update(Long id, String title, String imgUrl); + + void delete(Long id); +} diff --git a/src/main/java/TripAmi/backend/web/api/banner/BannerController.java b/src/main/java/TripAmi/backend/web/api/banner/BannerController.java new file mode 100644 index 0000000..b0af28f --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/banner/BannerController.java @@ -0,0 +1,54 @@ +package TripAmi.backend.web.api.banner; + +import TripAmi.backend.app.banner.service.BannerService; +import TripAmi.backend.web.api.banner.request.BannerCreateRequest; +import TripAmi.backend.web.api.banner.request.BannerUpdateRequest; +import TripAmi.backend.web.api.banner.response.BannerDto; +import TripAmi.backend.web.api.banner.response.BannerListResponse; +import TripAmi.backend.web.api.common.GenericResponse; +import TripAmi.backend.web.api.response.EmptyResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/v1/banners") +@RequiredArgsConstructor +public class BannerController { + private final BannerService bannerService; + + @PostMapping + public GenericResponse save(@RequestBody BannerCreateRequest request) { + bannerService.join(request.title(), request.imgUrl()); + return GenericResponse.ok(BannerDto.builder() + .title(request.title()) + .imgUrl(request.imgUrl()) + .build()); + } + + @GetMapping("/{id}") + public GenericResponse findById(@PathVariable Long id) { + return GenericResponse.ok(bannerService.findById(id)); + } + + @GetMapping + public GenericResponse findAll() { + List banners = bannerService.findAll(); + BannerListResponse response = BannerListResponse.builder() + .banners(banners) + .build(); + return GenericResponse.ok(response); + } + + @PutMapping("/{id}") + public GenericResponse update(@PathVariable Long id, @RequestBody BannerUpdateRequest request) { + return GenericResponse.ok(bannerService.update(id, request.title(), request.imgUrl())); + } + + @DeleteMapping("/{id}") + public GenericResponse delete(@PathVariable Long id) { + bannerService.findById(id); + return GenericResponse.ok(); + } +} diff --git a/src/main/java/TripAmi/backend/web/api/banner/request/BannerCreateRequest.java b/src/main/java/TripAmi/backend/web/api/banner/request/BannerCreateRequest.java new file mode 100644 index 0000000..a5c891f --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/banner/request/BannerCreateRequest.java @@ -0,0 +1,9 @@ +package TripAmi.backend.web.api.banner.request; + +import lombok.Builder; + +public record BannerCreateRequest(String title, String imgUrl) { + @Builder + public BannerCreateRequest { + } +} diff --git a/src/main/java/TripAmi/backend/web/api/banner/request/BannerUpdateRequest.java b/src/main/java/TripAmi/backend/web/api/banner/request/BannerUpdateRequest.java new file mode 100644 index 0000000..bb9e134 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/banner/request/BannerUpdateRequest.java @@ -0,0 +1,9 @@ +package TripAmi.backend.web.api.banner.request; + +import lombok.Builder; + +public record BannerUpdateRequest(String title, String imgUrl) { + @Builder + public BannerUpdateRequest { + } +} diff --git a/src/main/java/TripAmi/backend/web/api/banner/response/BannerDto.java b/src/main/java/TripAmi/backend/web/api/banner/response/BannerDto.java new file mode 100644 index 0000000..bad2a9d --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/banner/response/BannerDto.java @@ -0,0 +1,11 @@ +package TripAmi.backend.web.api.banner.response; + + +import lombok.Builder; + +public record BannerDto(Long id, String title, String imgUrl) { + + @Builder + public BannerDto { + } +} diff --git a/src/main/java/TripAmi/backend/web/api/banner/response/BannerListResponse.java b/src/main/java/TripAmi/backend/web/api/banner/response/BannerListResponse.java new file mode 100644 index 0000000..2840f23 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/banner/response/BannerListResponse.java @@ -0,0 +1,12 @@ +package TripAmi.backend.web.api.banner.response; + +import lombok.Builder; + +import java.util.List; + +public record BannerListResponse(List banners) { + + @Builder + public BannerListResponse { + } +} From 2211a2ab63cfcfff2a67e32d24d875fac78b7d2e Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 18:17:17 +0900 Subject: [PATCH 16/27] Feat: Edit faq --- .../{service => infra}/FaqServiceImpl.java | 19 +++++++++---------- .../backend/web/api/faq/FaqController.java | 4 ++-- .../web/api/response/EmptyResponse.java | 6 ++++++ 3 files changed, 17 insertions(+), 12 deletions(-) rename src/main/java/TripAmi/backend/app/faq/{service => infra}/FaqServiceImpl.java (73%) create mode 100644 src/main/java/TripAmi/backend/web/api/response/EmptyResponse.java diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java b/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java similarity index 73% rename from src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java rename to src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java index 2471214..57c20d6 100644 --- a/src/main/java/TripAmi/backend/app/faq/service/FaqServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java @@ -1,9 +1,8 @@ -package TripAmi.backend.app.faq.service; +package TripAmi.backend.app.faq.infra; import TripAmi.backend.app.faq.domain.Faq; import TripAmi.backend.app.faq.domain.FaqRepository; -import TripAmi.backend.web.api.faq.request.FaqCreateRequest; -import TripAmi.backend.web.api.faq.request.FaqUpdateRequest; +import TripAmi.backend.app.faq.service.FaqService; import TripAmi.backend.web.api.faq.response.FaqDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -20,10 +19,10 @@ public class FaqServiceImpl implements FaqService { @Override @Transactional - public void save(FaqCreateRequest request) { + public void save(String question, String answer) { Faq faq = Faq.builder() - .question(request.question()) - .answer(request.answer()) + .question(question) + .answer(answer) .build(); faqRepository.save(faq); } @@ -50,12 +49,12 @@ public List findAll() { @Override @Transactional - public FaqDto updateFaq(Long faqId, FaqUpdateRequest request) { + public FaqDto updateFaq(Long faqId, String question, String answer) { Faq faq = faqRepository.findById(faqId).orElseThrow(); - faq.update(request.question(), request.answer()); + faq.update(question, answer); return FaqDto.builder() - .question(request.question()) - .answer(request.answer()) + .question(question) + .answer(answer) .build(); } } diff --git a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java index 9d9677b..5157bd7 100644 --- a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java +++ b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java @@ -19,7 +19,7 @@ public class FaqController { @PostMapping public void save(@RequestBody FaqCreateRequest request) { - faqService.save(request); + faqService.save(request.question(), request.answer()); } @GetMapping @@ -38,6 +38,6 @@ public GenericResponse findById(@PathVariable Long id) { @PostMapping("/{id}") public GenericResponse updateFaq(@PathVariable Long id, @RequestBody FaqUpdateRequest request) { - return GenericResponse.ok(faqService.updateFaq(id, request)); + return GenericResponse.ok(faqService.updateFaq(id, request.question(), request.answer())); } } diff --git a/src/main/java/TripAmi/backend/web/api/response/EmptyResponse.java b/src/main/java/TripAmi/backend/web/api/response/EmptyResponse.java new file mode 100644 index 0000000..3204fa9 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/response/EmptyResponse.java @@ -0,0 +1,6 @@ +package TripAmi.backend.web.api.response; + +import lombok.Builder; + +public record EmptyResponse() { +} From 7219a7a963933a816eedff520ee9a3aa1d05e257 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 18:19:06 +0900 Subject: [PATCH 17/27] Feat: Edit faq --- src/main/java/TripAmi/backend/app/faq/service/FaqService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java index b5cd8cc..aa720aa 100644 --- a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java +++ b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java @@ -7,11 +7,11 @@ import java.util.List; public interface FaqService { - void save(FaqCreateRequest request); + void save(String question, String answer); FaqDto findById(Long id); List findAll(); - FaqDto updateFaq(Long faqId, FaqUpdateRequest request); + FaqDto updateFaq(Long faqId, String question, String answer); } From 727fc04c7550776e3acc59a86d40bc4360d65ac8 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 18:21:13 +0900 Subject: [PATCH 18/27] gitignore --- .gitignore | 4 ++-- docker-compose.yml | 19 --------------- gradle/wrapper/gradle-wrapper.properties | 7 ------ src/main/resources/application.properties | 3 --- src/main/resources/application.yml | 28 ----------------------- 5 files changed, 2 insertions(+), 59 deletions(-) delete mode 100644 docker-compose.yml delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100644 src/main/resources/application.properties delete mode 100644 src/main/resources/application.yml diff --git a/.gitignore b/.gitignore index e4e622f..d209ac3 100644 --- a/.gitignore +++ b/.gitignore @@ -234,8 +234,8 @@ $RECYCLE.BIN/ *.lnk # application config -application.properties -application.yml +*.properties +*.yml # End of https://www.toptal.com/developers/gitignore/api/java,intellij,macos,windows diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 729cea0..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,19 +0,0 @@ -version: '3' -services: - mysql: - image: mysql - environment: - MYSQL_ROOT_PASSWORD: 1111 - MYSQL_DATABASE: tripami - - your-application: - image: kangjaekwon/tripami_be - depends_on: - - mysql - environment: - SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/tripami - SPRING_DATASOURCE_USERNAME: root - SPRING_DATASOURCE_PASSWORD: 1111 - - ports: - - "8080:8080" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3fa8f86..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index ebf445e..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -MYSQL_PASSWD="1111" - -MYSQL_URL="13.124.9.1:3306/tripami" \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml deleted file mode 100644 index 4d93be0..0000000 --- a/src/main/resources/application.yml +++ /dev/null @@ -1,28 +0,0 @@ -spring: - - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://43.202.134.168:3306/tripami?useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8 - username: root - password: 1111 - - - thymeleaf: - prefix: classpath:/templates/ - suffix: .html - - jpa: - open-in-view: true - hibernate: - ddl-auto: create - naming: - physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl - - show-sql: true - properties: - hibernate.format_sql: true - dialect: org.hibernate.dialect.MySQL8InnoDBDialect - -logging.level: - org.hibernate.SQL: debug - org.hibernate.orm.jdbc.bind: trace From 6edb29db50e7d8928bf49180c4bc7282b8b7914b Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 19:49:29 +0900 Subject: [PATCH 19/27] Feat: add base entity in banner --- .../TripAmi/backend/app/banner/domain/Banner.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/TripAmi/backend/app/banner/domain/Banner.java b/src/main/java/TripAmi/backend/app/banner/domain/Banner.java index a430aec..fc51e19 100644 --- a/src/main/java/TripAmi/backend/app/banner/domain/Banner.java +++ b/src/main/java/TripAmi/backend/app/banner/domain/Banner.java @@ -1,5 +1,6 @@ package TripAmi.backend.app.banner.domain; +import TripAmi.backend.app.util.BaseEntity; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; @@ -24,18 +25,13 @@ public class Banner { private String title; - @CreatedDate - @Column(nullable = false, name = "create_at") - private LocalDateTime createdAt; - - @Column(nullable = false, name = "open_status") - private Boolean isOpened; + @Embedded + private BaseEntity baseEntity = new BaseEntity(); @Builder public Banner(String imgUrl, String title) { this.imgUrl = imgUrl; this.title = title; - this.isOpened = true; } public void update(String title, String imgUrl) { @@ -44,6 +40,6 @@ public void update(String title, String imgUrl) { } public void delete() { - this.isOpened = false; + this.baseEntity.delete(); } } From 6d7af50a3b4a38c88f367fdf7d346bcb3260c8b7 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 19:50:28 +0900 Subject: [PATCH 20/27] Style: Change method name ( findAll -> findBanners) --- .../TripAmi/backend/app/banner/infra/BannerServiceImpl.java | 2 +- .../java/TripAmi/backend/app/banner/service/BannerService.java | 2 +- .../java/TripAmi/backend/web/api/banner/BannerController.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java b/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java index 4ed47cd..de93e46 100644 --- a/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java @@ -34,7 +34,7 @@ public BannerDto findById(Long id) { } @Override - public List findAll() { + public List findBanners() { List items = bannerRepository.findAll(); return items.stream() .map(item -> new BannerDto( diff --git a/src/main/java/TripAmi/backend/app/banner/service/BannerService.java b/src/main/java/TripAmi/backend/app/banner/service/BannerService.java index bbcd83d..18dee96 100644 --- a/src/main/java/TripAmi/backend/app/banner/service/BannerService.java +++ b/src/main/java/TripAmi/backend/app/banner/service/BannerService.java @@ -9,7 +9,7 @@ public interface BannerService { BannerDto findById(Long id); - List findAll(); + List findBanners(); BannerDto update(Long id, String title, String imgUrl); diff --git a/src/main/java/TripAmi/backend/web/api/banner/BannerController.java b/src/main/java/TripAmi/backend/web/api/banner/BannerController.java index b0af28f..4e4862d 100644 --- a/src/main/java/TripAmi/backend/web/api/banner/BannerController.java +++ b/src/main/java/TripAmi/backend/web/api/banner/BannerController.java @@ -34,7 +34,7 @@ public GenericResponse findById(@PathVariable Long id) { @GetMapping public GenericResponse findAll() { - List banners = bannerService.findAll(); + List banners = bannerService.findBanners(); BannerListResponse response = BannerListResponse.builder() .banners(banners) .build(); From 50d15d3607e431f105584d44d8f8a5782438ee4c Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 19:51:59 +0900 Subject: [PATCH 21/27] Feat: Add exception for find logic in banner --- .../backend/app/banner/exception/BannerNotFound.java | 4 ++++ .../backend/app/banner/infra/BannerServiceImpl.java | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 src/main/java/TripAmi/backend/app/banner/exception/BannerNotFound.java diff --git a/src/main/java/TripAmi/backend/app/banner/exception/BannerNotFound.java b/src/main/java/TripAmi/backend/app/banner/exception/BannerNotFound.java new file mode 100644 index 0000000..1e4058b --- /dev/null +++ b/src/main/java/TripAmi/backend/app/banner/exception/BannerNotFound.java @@ -0,0 +1,4 @@ +package TripAmi.backend.app.banner.exception; + +public class BannerNotFound extends RuntimeException{ +} diff --git a/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java b/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java index de93e46..c7efbbf 100644 --- a/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/banner/infra/BannerServiceImpl.java @@ -2,6 +2,7 @@ import TripAmi.backend.app.banner.domain.Banner; import TripAmi.backend.app.banner.domain.BannerRepository; +import TripAmi.backend.app.banner.exception.BannerNotFound; import TripAmi.backend.app.banner.service.BannerService; import TripAmi.backend.web.api.banner.response.BannerDto; import lombok.RequiredArgsConstructor; @@ -29,7 +30,7 @@ public void join(String title, String imgUrl) { @Override public BannerDto findById(Long id) { - Banner findOne = bannerRepository.findById(id).orElseThrow(); + Banner findOne = bannerRepository.findById(id).orElseThrow(BannerNotFound::new); return new BannerDto(id, findOne.getTitle(), findOne.getImgUrl()); } @@ -46,7 +47,7 @@ public List findBanners() { @Override public BannerDto update(Long id, String title, String imgUrl) { - Banner banner = bannerRepository.findById(id).orElseThrow(); + Banner banner = bannerRepository.findById(id).orElseThrow(BannerNotFound::new); banner.update(title, imgUrl); return BannerDto.builder() .title(title) @@ -56,7 +57,7 @@ public BannerDto update(Long id, String title, String imgUrl) { @Override public void delete(Long id) { - Banner banner = bannerRepository.findById(id).orElseThrow(); + Banner banner = bannerRepository.findById(id).orElseThrow(BannerNotFound::new); banner.delete(); } From 93e5d635cd2255cc01c48b5176012bb9d87e8787 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Thu, 14 Dec 2023 19:54:37 +0900 Subject: [PATCH 22/27] Feat: Add exception for find logic in FAQ & edit method name --- .../TripAmi/backend/app/faq/exception/FaqNotFound.java | 4 ++++ .../TripAmi/backend/app/faq/infra/FaqServiceImpl.java | 9 +++++---- .../java/TripAmi/backend/app/faq/service/FaqService.java | 4 ++-- .../java/TripAmi/backend/web/api/faq/FaqController.java | 4 ++-- 4 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 src/main/java/TripAmi/backend/app/faq/exception/FaqNotFound.java diff --git a/src/main/java/TripAmi/backend/app/faq/exception/FaqNotFound.java b/src/main/java/TripAmi/backend/app/faq/exception/FaqNotFound.java new file mode 100644 index 0000000..a8c9b0d --- /dev/null +++ b/src/main/java/TripAmi/backend/app/faq/exception/FaqNotFound.java @@ -0,0 +1,4 @@ +package TripAmi.backend.app.faq.exception; + +public class FaqNotFound extends RuntimeException{ +} diff --git a/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java b/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java index 57c20d6..9f17134 100644 --- a/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java @@ -2,6 +2,7 @@ import TripAmi.backend.app.faq.domain.Faq; import TripAmi.backend.app.faq.domain.FaqRepository; +import TripAmi.backend.app.faq.exception.FaqNotFound; import TripAmi.backend.app.faq.service.FaqService; import TripAmi.backend.web.api.faq.response.FaqDto; import lombok.RequiredArgsConstructor; @@ -29,7 +30,7 @@ public void save(String question, String answer) { @Override public FaqDto findById(Long id) { - Faq item = faqRepository.findById(id).orElseThrow(); + Faq item = faqRepository.findById(id).orElseThrow(FaqNotFound::new); return FaqDto.builder() .question(item.getQuestion()) .answer(item.getAnswer()) @@ -37,7 +38,7 @@ public FaqDto findById(Long id) { } @Override - public List findAll() { + public List findFaqs() { List allFaq = faqRepository.findAll(); return allFaq.stream() .map(item -> new FaqDto( @@ -49,8 +50,8 @@ public List findAll() { @Override @Transactional - public FaqDto updateFaq(Long faqId, String question, String answer) { - Faq faq = faqRepository.findById(faqId).orElseThrow(); + public FaqDto update(Long faqId, String question, String answer) { + Faq faq = faqRepository.findById(faqId).orElseThrow(FaqNotFound::new); faq.update(question, answer); return FaqDto.builder() .question(question) diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java index aa720aa..d8f135e 100644 --- a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java +++ b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java @@ -11,7 +11,7 @@ public interface FaqService { FaqDto findById(Long id); - List findAll(); + List findFaqs(); - FaqDto updateFaq(Long faqId, String question, String answer); + FaqDto update(Long faqId, String question, String answer); } diff --git a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java index 5157bd7..649348e 100644 --- a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java +++ b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java @@ -24,7 +24,7 @@ public void save(@RequestBody FaqCreateRequest request) { @GetMapping public GenericResponse findAll() { - List result = faqService.findAll(); + List result = faqService.findFaqs(); FaqListResponse response = FaqListResponse.builder() .faqs(result) .build(); @@ -38,6 +38,6 @@ public GenericResponse findById(@PathVariable Long id) { @PostMapping("/{id}") public GenericResponse updateFaq(@PathVariable Long id, @RequestBody FaqUpdateRequest request) { - return GenericResponse.ok(faqService.updateFaq(id, request.question(), request.answer())); + return GenericResponse.ok(faqService.update(id, request.question(), request.answer())); } } From a8636400cadd9f9a803ce1182b08c6ed8460cc86 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Fri, 15 Dec 2023 10:24:16 +0900 Subject: [PATCH 23/27] Feat: Add delete method in Faq --- src/main/java/TripAmi/backend/app/faq/domain/Faq.java | 8 ++++++++ .../TripAmi/backend/app/faq/infra/FaqServiceImpl.java | 6 ++++++ .../java/TripAmi/backend/app/faq/service/FaqService.java | 2 ++ .../java/TripAmi/backend/web/api/faq/FaqController.java | 7 +++++++ 4 files changed, 23 insertions(+) diff --git a/src/main/java/TripAmi/backend/app/faq/domain/Faq.java b/src/main/java/TripAmi/backend/app/faq/domain/Faq.java index d16935f..ccad2f4 100644 --- a/src/main/java/TripAmi/backend/app/faq/domain/Faq.java +++ b/src/main/java/TripAmi/backend/app/faq/domain/Faq.java @@ -1,5 +1,6 @@ package TripAmi.backend.app.faq.domain; +import TripAmi.backend.app.util.BaseEntity; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; @@ -20,6 +21,9 @@ public class Faq { private String answer; + @Embedded + private BaseEntity baseEntity = new BaseEntity(); + @Builder public Faq(String question, String answer) { this.question = question; @@ -30,4 +34,8 @@ public void update(String question, String answer) { this.question = question; this.answer = answer; } + + public void delete() { + this.baseEntity.delete(); + } } diff --git a/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java b/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java index 9f17134..325d6a2 100644 --- a/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/faq/infra/FaqServiceImpl.java @@ -58,4 +58,10 @@ public FaqDto update(Long faqId, String question, String answer) { .answer(answer) .build(); } + + @Override + public void delete(Long id) { + Faq faq = faqRepository.findById(id).orElseThrow(FaqNotFound::new); + faq.delete(); + } } diff --git a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java index d8f135e..c8cbf7d 100644 --- a/src/main/java/TripAmi/backend/app/faq/service/FaqService.java +++ b/src/main/java/TripAmi/backend/app/faq/service/FaqService.java @@ -14,4 +14,6 @@ public interface FaqService { List findFaqs(); FaqDto update(Long faqId, String question, String answer); + + void delete(Long id); } diff --git a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java index 649348e..ef86f30 100644 --- a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java +++ b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java @@ -6,6 +6,7 @@ import TripAmi.backend.web.api.faq.request.FaqUpdateRequest; import TripAmi.backend.web.api.faq.response.FaqDto; import TripAmi.backend.web.api.faq.response.FaqListResponse; +import TripAmi.backend.web.api.response.EmptyResponse; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -40,4 +41,10 @@ public GenericResponse findById(@PathVariable Long id) { public GenericResponse updateFaq(@PathVariable Long id, @RequestBody FaqUpdateRequest request) { return GenericResponse.ok(faqService.update(id, request.question(), request.answer())); } + + @DeleteMapping("/{id}") + public GenericResponse delete(@PathVariable Long id) { + faqService.delete(id); + return GenericResponse.ok(); + } } From ae123082630561ba7cac080b80e4dbe64c53c108 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Fri, 15 Dec 2023 10:25:00 +0900 Subject: [PATCH 24/27] Style: Variable name integrated --- .../java/TripAmi/backend/app/product/domain/Program.java | 6 +++--- .../TripAmi/backend/web/api/program/ProgramController.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/TripAmi/backend/app/product/domain/Program.java b/src/main/java/TripAmi/backend/app/product/domain/Program.java index f13b336..4c295b6 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/Program.java +++ b/src/main/java/TripAmi/backend/app/product/domain/Program.java @@ -24,7 +24,7 @@ public class Program extends Product { List spots = new ArrayList<>(); @Column(name = "total_people") - Integer totalPersonnel; + Integer totalPeople; @Enumerated(value = EnumType.STRING) ProgramTheme theme; @@ -36,11 +36,11 @@ public class Program extends Product { String location; @Builder - public Program(String title, List images, String content, Integer price, List spots, Long amiId, Integer totalPersonnel, ProgramTheme theme, List keywords, String location) { + public Program(String title, List images, String content, Integer price, List spots, Long amiId, Integer totalPeople, ProgramTheme theme, List keywords, String location) { super(title, images, content, price); this.amiId = amiId; this.spots.addAll(spots); - this.totalPersonnel = totalPersonnel; + this.totalPeople = totalPeople; this.theme = theme; this.keywords = keywords; this.location = location; diff --git a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java index f1446e0..b46fb09 100644 --- a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java +++ b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java @@ -115,7 +115,7 @@ public GenericResponse getRemainingCount(@PathVariable Long id) { Program program = programService.findById(id); // ToDo 전체 인원에서 조인한 인원 빼줘야됨 - return GenericResponse.ok(program.getTotalPersonnel()); + return GenericResponse.ok(program.getTotalPeople()); } /** From 366d75ccff86fd39ba5e6f400569ce07e9d6db57 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Tue, 2 Jan 2024 12:50:19 +0900 Subject: [PATCH 25/27] Feat: Add Notification entity --- .../domain/EmitterRepository.java | 21 ++++++ .../app/notification/domain/Notification.java | 37 ++++++++++ .../domain/NotificationRepository.java | 6 ++ .../infra/EmitterRepositoryImpl.java | 71 +++++++++++++++++++ .../infra/NotificationServiceImpl.java | 23 ++++++ .../service/NotificationService.java | 9 +++ .../backend/app/product/domain/Spot.java | 1 - .../backend/web/api/faq/FaqController.java | 2 +- .../notification/NotificationController.java | 19 +++++ 9 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 src/main/java/TripAmi/backend/app/notification/domain/EmitterRepository.java create mode 100644 src/main/java/TripAmi/backend/app/notification/domain/Notification.java create mode 100644 src/main/java/TripAmi/backend/app/notification/domain/NotificationRepository.java create mode 100644 src/main/java/TripAmi/backend/app/notification/infra/EmitterRepositoryImpl.java create mode 100644 src/main/java/TripAmi/backend/app/notification/infra/NotificationServiceImpl.java create mode 100644 src/main/java/TripAmi/backend/app/notification/service/NotificationService.java create mode 100644 src/main/java/TripAmi/backend/web/api/notification/NotificationController.java diff --git a/src/main/java/TripAmi/backend/app/notification/domain/EmitterRepository.java b/src/main/java/TripAmi/backend/app/notification/domain/EmitterRepository.java new file mode 100644 index 0000000..59e6959 --- /dev/null +++ b/src/main/java/TripAmi/backend/app/notification/domain/EmitterRepository.java @@ -0,0 +1,21 @@ +package TripAmi.backend.app.notification.domain; + +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.Map; + +public interface EmitterRepository { + SseEmitter save(String emitterId, SseEmitter sseEmitter); + + void saveEventCache(String emitterId, Object event); + + Map findAllEmitterStartWithMemberId(String memberId); + + Map findAllEventCacheStartWithByMemberId(String memberId); + + void deleteById(String id); + + void deleteAllEmitterStartWithId(String memberId); + + void deleteAllEventCacheStartWithId(String memberId); +} diff --git a/src/main/java/TripAmi/backend/app/notification/domain/Notification.java b/src/main/java/TripAmi/backend/app/notification/domain/Notification.java new file mode 100644 index 0000000..c3a4070 --- /dev/null +++ b/src/main/java/TripAmi/backend/app/notification/domain/Notification.java @@ -0,0 +1,37 @@ +package TripAmi.backend.app.notification.domain; + +import TripAmi.backend.app.util.BaseEntity; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "notification") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Notification { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false, name = "noti_id") + private Long id; + + private String title; + + private String content; + + @Column(name = "is_read") + private Boolean isRead; + + @Embedded + private BaseEntity baseEntity = new BaseEntity(); + + @Builder + public Notification(String title, String content) { + this.title = title; + this.content = content; + this.isRead = false; + } +} diff --git a/src/main/java/TripAmi/backend/app/notification/domain/NotificationRepository.java b/src/main/java/TripAmi/backend/app/notification/domain/NotificationRepository.java new file mode 100644 index 0000000..91f632c --- /dev/null +++ b/src/main/java/TripAmi/backend/app/notification/domain/NotificationRepository.java @@ -0,0 +1,6 @@ +package TripAmi.backend.app.notification.domain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface NotificationRepository extends JpaRepository { +} diff --git a/src/main/java/TripAmi/backend/app/notification/infra/EmitterRepositoryImpl.java b/src/main/java/TripAmi/backend/app/notification/infra/EmitterRepositoryImpl.java new file mode 100644 index 0000000..15b990b --- /dev/null +++ b/src/main/java/TripAmi/backend/app/notification/infra/EmitterRepositoryImpl.java @@ -0,0 +1,71 @@ +package TripAmi.backend.app.notification.infra; + +import TripAmi.backend.app.notification.domain.EmitterRepository; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.springframework.stereotype.Repository; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +@Repository +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class EmitterRepositoryImpl implements EmitterRepository { + private final Map emitters = new ConcurrentHashMap<>(); + private final Map eventCache = new ConcurrentHashMap<>(); + + @Override + public SseEmitter save(String emitterId, SseEmitter sseEmitter) { + emitters.put(emitterId, sseEmitter); + return sseEmitter; + } + + @Override + public void saveEventCache(String emitterId, Object event) { + eventCache.put(emitterId, event); + } + + + @Override + public Map findAllEmitterStartWithMemberId(String memberId) { + return emitters.entrySet().stream() + .filter(entry -> entry.getKey().startsWith(memberId)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + @Override + public Map findAllEventCacheStartWithByMemberId(String memberId) { + return eventCache.entrySet().stream() + .filter(entry -> entry.getKey().startsWith(memberId)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + @Override + public void deleteById(String id) { + emitters.remove(id); + } + + @Override + public void deleteAllEmitterStartWithId(String memberId) { + emitters.forEach( + (key, emitter) -> { + if (key.startsWith(memberId)) { + emitters.remove(key); + } + } + ); + } + + @Override + public void deleteAllEventCacheStartWithId(String memberId) { + eventCache.forEach( + (key, emitter) -> { + if (key.startsWith(memberId)) { + eventCache.remove(key); + } + } + ); + } +} diff --git a/src/main/java/TripAmi/backend/app/notification/infra/NotificationServiceImpl.java b/src/main/java/TripAmi/backend/app/notification/infra/NotificationServiceImpl.java new file mode 100644 index 0000000..bdd8c4d --- /dev/null +++ b/src/main/java/TripAmi/backend/app/notification/infra/NotificationServiceImpl.java @@ -0,0 +1,23 @@ +package TripAmi.backend.app.notification.infra; + +import TripAmi.backend.app.notification.service.NotificationService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class NotificationServiceImpl implements NotificationService { + + @Override + public SseEmitter subscribe(Long memberId, String lastEventId) { + return null; + } + + @Override + public String makeTimeIncludeId(Long memberId) { + return memberId + "_" + System.currentTimeMillis(); + } +} diff --git a/src/main/java/TripAmi/backend/app/notification/service/NotificationService.java b/src/main/java/TripAmi/backend/app/notification/service/NotificationService.java new file mode 100644 index 0000000..b27f479 --- /dev/null +++ b/src/main/java/TripAmi/backend/app/notification/service/NotificationService.java @@ -0,0 +1,9 @@ +package TripAmi.backend.app.notification.service; + +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +public interface NotificationService { + SseEmitter subscribe(Long memberId, String lastEventId); + + String makeTimeIncludeId(Long memberId); +} diff --git a/src/main/java/TripAmi/backend/app/product/domain/Spot.java b/src/main/java/TripAmi/backend/app/product/domain/Spot.java index e5b21f0..4844d08 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/Spot.java +++ b/src/main/java/TripAmi/backend/app/product/domain/Spot.java @@ -1,6 +1,5 @@ package TripAmi.backend.app.product.domain; -import TripAmi.backend.app.product.domain.Program; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; diff --git a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java index ef86f30..5a5bc71 100644 --- a/src/main/java/TripAmi/backend/web/api/faq/FaqController.java +++ b/src/main/java/TripAmi/backend/web/api/faq/FaqController.java @@ -38,7 +38,7 @@ public GenericResponse findById(@PathVariable Long id) { } @PostMapping("/{id}") - public GenericResponse updateFaq(@PathVariable Long id, @RequestBody FaqUpdateRequest request) { + public GenericResponse update(@PathVariable Long id, @RequestBody FaqUpdateRequest request) { return GenericResponse.ok(faqService.update(id, request.question(), request.answer())); } diff --git a/src/main/java/TripAmi/backend/web/api/notification/NotificationController.java b/src/main/java/TripAmi/backend/web/api/notification/NotificationController.java new file mode 100644 index 0000000..8613a44 --- /dev/null +++ b/src/main/java/TripAmi/backend/web/api/notification/NotificationController.java @@ -0,0 +1,19 @@ +package TripAmi.backend.web.api.notification; + +import TripAmi.backend.app.notification.service.NotificationService; +import TripAmi.backend.auth.authmember.domain.AuthMember; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +@RestController +@RequiredArgsConstructor +public class NotificationController { + private final NotificationService notificationService; + + public SseEmitter subscribe(@AuthenticationPrincipal AuthMember member, @RequestHeader(value = "Last-Event-ID", required = false, defaultValue = "") String lastEventId) { + return notificationService.subscribe(member.getId(), lastEventId); + } +} From ae25628d3da2ed42800642a777a9ce419fd666a4 Mon Sep 17 00:00:00 2001 From: jaekkang Date: Tue, 2 Jan 2024 14:43:08 +0900 Subject: [PATCH 26/27] Style: Change variable name --- .../backend/app/product/infra/ProgramServiceImpl.java | 2 +- .../backend/app/reservation/domain/Reservation.java | 8 +++++--- .../web/api/program/request/CreateProgramRequest.java | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java b/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java index fdb1906..98eec40 100644 --- a/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java @@ -26,7 +26,7 @@ public void save(CreateProgramRequest request) { .images(request.images()) .content(request.content()) .price(request.price()) - .totalPersonnel(request.totalPersonnel()) + .totalPeople(request.totalPeople()) .theme(request.theme()) .keywords(request.keyWords()) .spots(request.spots()) diff --git a/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java b/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java index 658b9be..7237f89 100644 --- a/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java +++ b/src/main/java/TripAmi/backend/app/reservation/domain/Reservation.java @@ -1,9 +1,11 @@ package TripAmi.backend.app.reservation.domain; -import TripAmi.backend.app.member.domain.Member; import TripAmi.backend.app.product.domain.Program; import jakarta.persistence.*; -import lombok.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.SneakyThrows; import java.time.LocalDateTime; import java.util.ArrayList; @@ -42,7 +44,7 @@ public Reservation(Program program, LocalDateTime fixedDate) { @SneakyThrows public void joinPerson(Long personId) { - if (this.fixedPeople < program.getTotalPersonnel()) + if (this.fixedPeople < program.getTotalPeople()) fixedPeople++; else throw new RuntimeException("정원 초과되었습니다."); diff --git a/src/main/java/TripAmi/backend/web/api/program/request/CreateProgramRequest.java b/src/main/java/TripAmi/backend/web/api/program/request/CreateProgramRequest.java index ff80df0..8e232c1 100644 --- a/src/main/java/TripAmi/backend/web/api/program/request/CreateProgramRequest.java +++ b/src/main/java/TripAmi/backend/web/api/program/request/CreateProgramRequest.java @@ -12,7 +12,7 @@ public record CreateProgramRequest( String profileImgUrl, List images, Integer price, - Integer totalPersonnel, + Integer totalPeople, ProgramTheme theme, List keyWords, List spots, From 4523be4457cfd9a07a19a3f0cc9a0777cd9f1e6e Mon Sep 17 00:00:00 2001 From: jaekkang Date: Mon, 8 Jan 2024 17:08:08 +0900 Subject: [PATCH 27/27] Feat: merge --- .../java/TripAmi/backend/BackendApplication.java | 2 ++ .../TripAmi/backend/app/banner/domain/Banner.java | 4 +--- .../java/TripAmi/backend/app/faq/domain/Faq.java | 2 +- .../app/notification/domain/Notification.java | 3 ++- .../TripAmi/backend/app/product/domain/Program.java | 8 +++++++- .../app/product/infra/ProgramServiceImpl.java | 1 + .../java/TripAmi/backend/app/util/BaseEntity.java | 9 ++++----- .../auth/security/JwtAuthenticationFilter.java | 2 +- .../java/TripAmi/backend/config/SecurityConfig.java | 12 +++++------- .../backend/web/api/program/ProgramController.java | 2 +- 10 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/main/java/TripAmi/backend/BackendApplication.java b/src/main/java/TripAmi/backend/BackendApplication.java index e757938..b1522d1 100644 --- a/src/main/java/TripAmi/backend/BackendApplication.java +++ b/src/main/java/TripAmi/backend/BackendApplication.java @@ -2,8 +2,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication +@EnableJpaAuditing public class BackendApplication { public static void main(String[] args) { diff --git a/src/main/java/TripAmi/backend/app/banner/domain/Banner.java b/src/main/java/TripAmi/backend/app/banner/domain/Banner.java index fc51e19..0fd454f 100644 --- a/src/main/java/TripAmi/backend/app/banner/domain/Banner.java +++ b/src/main/java/TripAmi/backend/app/banner/domain/Banner.java @@ -1,14 +1,12 @@ package TripAmi.backend.app.banner.domain; import TripAmi.backend.app.util.BaseEntity; -import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.data.annotation.CreatedDate; -import java.time.LocalDateTime; +import javax.persistence.*; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/src/main/java/TripAmi/backend/app/faq/domain/Faq.java b/src/main/java/TripAmi/backend/app/faq/domain/Faq.java index ccad2f4..303a6ce 100644 --- a/src/main/java/TripAmi/backend/app/faq/domain/Faq.java +++ b/src/main/java/TripAmi/backend/app/faq/domain/Faq.java @@ -1,7 +1,7 @@ package TripAmi.backend.app.faq.domain; import TripAmi.backend.app.util.BaseEntity; -import jakarta.persistence.*; +import javax.persistence.*; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/TripAmi/backend/app/notification/domain/Notification.java b/src/main/java/TripAmi/backend/app/notification/domain/Notification.java index c3a4070..10c480c 100644 --- a/src/main/java/TripAmi/backend/app/notification/domain/Notification.java +++ b/src/main/java/TripAmi/backend/app/notification/domain/Notification.java @@ -1,12 +1,13 @@ package TripAmi.backend.app.notification.domain; import TripAmi.backend.app.util.BaseEntity; -import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import javax.persistence.*; + @Entity @Getter @Table(name = "notification") diff --git a/src/main/java/TripAmi/backend/app/product/domain/Program.java b/src/main/java/TripAmi/backend/app/product/domain/Program.java index bb0f8e2..3a6f448 100644 --- a/src/main/java/TripAmi/backend/app/product/domain/Program.java +++ b/src/main/java/TripAmi/backend/app/product/domain/Program.java @@ -1,6 +1,7 @@ package TripAmi.backend.app.product.domain; import TripAmi.backend.app.product.ProgramTheme; +import TripAmi.backend.app.util.BaseEntity; import TripAmi.backend.app.util.infra.StringListConverter; import javax.persistence.*; import lombok.AccessLevel; @@ -15,12 +16,13 @@ @DiscriminatorValue("program") @PrimaryKeyJoinColumn(name = "program_id") @NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "program") @Getter public class Program extends Product { @Column(name = "ami_id") Long amiId; - @OneToMany(mappedBy = "program") + @OneToMany(mappedBy = "program", cascade = CascadeType.ALL) List spots = new ArrayList<>(); @Column(name = "total_people") @@ -35,6 +37,9 @@ public class Program extends Product { //todo address class 작성 String location; + @Embedded + private BaseEntity baseEntity; + @Builder public Program(String title, List images, String content, Integer price, List spots, Long amiId, Integer totalPeople, ProgramTheme theme, List keywords, String location) { super(title, images, content, price); @@ -44,5 +49,6 @@ public Program(String title, List images, String content, Integer price, this.theme = theme; this.keywords = keywords; this.location = location; + this.baseEntity = new BaseEntity(); } } diff --git a/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java b/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java index 98eec40..2bdbc48 100644 --- a/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java +++ b/src/main/java/TripAmi/backend/app/product/infra/ProgramServiceImpl.java @@ -22,6 +22,7 @@ public class ProgramServiceImpl implements ProgramService { @Transactional public void save(CreateProgramRequest request) { Program program = Program.builder() + .amiId(request.amiId()) .title(request.title()) .images(request.images()) .content(request.content()) diff --git a/src/main/java/TripAmi/backend/app/util/BaseEntity.java b/src/main/java/TripAmi/backend/app/util/BaseEntity.java index aff9cbf..350052e 100644 --- a/src/main/java/TripAmi/backend/app/util/BaseEntity.java +++ b/src/main/java/TripAmi/backend/app/util/BaseEntity.java @@ -1,14 +1,11 @@ package TripAmi.backend.app.util; -import javax.persistence.Column; -import javax.persistence.Embeddable; -import javax.persistence.MappedSuperclass; -import lombok.AccessLevel; import lombok.Getter; -import lombok.NoArgsConstructor; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; +import javax.persistence.Column; +import javax.persistence.Embeddable; import java.time.LocalDateTime; @Embeddable @@ -17,10 +14,12 @@ public class BaseEntity { @CreatedDate @Column(name = "created_at") LocalDateTime createdAt; + @LastModifiedDate @Column(name = "updated_at") LocalDateTime updatedAt; Boolean deleted; + public void delete() { this.deleted = true; } diff --git a/src/main/java/TripAmi/backend/auth/security/JwtAuthenticationFilter.java b/src/main/java/TripAmi/backend/auth/security/JwtAuthenticationFilter.java index fe1576a..57e2573 100644 --- a/src/main/java/TripAmi/backend/auth/security/JwtAuthenticationFilter.java +++ b/src/main/java/TripAmi/backend/auth/security/JwtAuthenticationFilter.java @@ -74,7 +74,7 @@ protected void successfulAuthentication(HttpServletRequest request, Authentication authResult) throws IOException, ServletException { log.info("JwtAuthenticationFilter.successfulAuthentication"); Set roles = new HashSet<>(); - roles.add(Role.ROLE_ADMIN); + roles.add(Role.ROLE_MEMBER); CustomUserDetails customUserDetails = CustomUserDetails.of((String)authResult.getPrincipal(), "", roles); TokenDto tokenDto = jwtProvider.generateTokenDto(customUserDetails); String accessToken = tokenDto.accessToken(); diff --git a/src/main/java/TripAmi/backend/config/SecurityConfig.java b/src/main/java/TripAmi/backend/config/SecurityConfig.java index 899223a..b71692a 100644 --- a/src/main/java/TripAmi/backend/config/SecurityConfig.java +++ b/src/main/java/TripAmi/backend/config/SecurityConfig.java @@ -71,12 +71,6 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .and() .apply(new CustomFilterConfigurer()) .and() -// // 조건별로 요청 허용/제한 설정 -// .authorizeRequests() -// .antMatchers("/api/v1/join/**", "/api/v1/login", "/api/v1/refresh").permitAll() -// .antMatchers("/api/v1/admin/**").hasRole("ADMIN") -// .antMatchers("/api/v1/member/**", "/api/v1/program/**").hasAnyRole("MEMBER", "ADMIN") -// .anyRequest().denyAll() // //에러 핸들링 .exceptionHandling() .accessDeniedHandler(new AccessDeniedHandler() { @@ -100,7 +94,11 @@ public void commence(HttpServletRequest request, HttpServletResponse response, A } }) .and() - .authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()); + .authorizeRequests() + .antMatchers("/api/v1/join/**", "/api/v1/login", "/api/v1/refresh").permitAll() + .antMatchers("/api/v1/admin/**").hasRole("ADMIN") + .antMatchers("/api/v1/member/**", "/api/v1/program/**").hasAnyRole("MEMBER", "ADMIN") + .anyRequest().authenticated(); return http.build(); } @Bean diff --git a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java index b46fb09..5a9c622 100644 --- a/src/main/java/TripAmi/backend/web/api/program/ProgramController.java +++ b/src/main/java/TripAmi/backend/web/api/program/ProgramController.java @@ -15,7 +15,7 @@ import java.util.stream.Collectors; @RestController -@RequestMapping("‘api/v1/programs’") +@RequestMapping("api/v1/programs") @RequiredArgsConstructor public class ProgramController { private final ProgramService programService;