diff --git a/src/main/java/com/space/server/common/annotation/PersistenceAdapter.java b/src/main/java/com/space/server/common/annotation/PersistenceAdapter.java new file mode 100644 index 00000000..bd1d27ed --- /dev/null +++ b/src/main/java/com/space/server/common/annotation/PersistenceAdapter.java @@ -0,0 +1,21 @@ +package com.space.server.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.core.annotation.AliasFor; +import org.springframework.stereotype.Component; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Component +public @interface PersistenceAdapter { + + @AliasFor(annotation = Component.class) + String value() default ""; + +} diff --git a/src/main/java/com/space/server/common/annotation/UseCase.java b/src/main/java/com/space/server/common/annotation/UseCase.java new file mode 100644 index 00000000..0ad639cd --- /dev/null +++ b/src/main/java/com/space/server/common/annotation/UseCase.java @@ -0,0 +1,22 @@ +package com.space.server.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.core.annotation.AliasFor; +import org.springframework.stereotype.Component; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Component +public @interface UseCase { + + @AliasFor(annotation = Component.class) + String value() default ""; + +} + diff --git a/src/main/java/com/space/server/common/annotation/WebAdapter.java b/src/main/java/com/space/server/common/annotation/WebAdapter.java new file mode 100644 index 00000000..d5840445 --- /dev/null +++ b/src/main/java/com/space/server/common/annotation/WebAdapter.java @@ -0,0 +1,21 @@ +package com.space.server.common.annotation; + +import org.springframework.core.annotation.AliasFor; +import org.springframework.stereotype.Component; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Component +public @interface WebAdapter { + + @AliasFor(annotation = Component.class) + String value() default ""; + +} diff --git a/src/main/java/com/space/server/domain/auth/service/implementation/UserJoiner.java b/src/main/java/com/space/server/domain/auth/service/implementation/UserJoiner.java index 7e055a32..92a9da68 100644 --- a/src/main/java/com/space/server/domain/auth/service/implementation/UserJoiner.java +++ b/src/main/java/com/space/server/domain/auth/service/implementation/UserJoiner.java @@ -1,11 +1,11 @@ package com.space.server.domain.auth.service.implementation; +import com.space.server.domain.inventory.adapter.out.persistence.EquipInventoryAdapter; +import com.space.server.domain.inventory.application.port.out.CreateInventoryPort; import com.space.server.domain.auth.presentation.dto.request.JoinUserRequest; import com.space.server.domain.inventory.domain.Inventory; -import com.space.server.domain.inventory.service.implementation.InventoryCreator; -import com.space.server.domain.inventory.service.implementation.InventoryUpdater; +import com.space.server.domain.item.application.port.in.GetItemQuery; import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.service.implementation.ItemReader; import com.space.server.domain.mail.exception.EmailNotVerifiedException; import com.space.server.domain.mail.service.EmailTokenService; import com.space.server.domain.user.domain.Users; @@ -23,9 +23,9 @@ public class UserJoiner { private final UserRepository userRepository; private final BCryptPasswordEncoder passwordEncoder; - private final InventoryCreator inventoryCreator; - private final InventoryUpdater inventoryUpdater; - private final ItemReader itemReader; + private final CreateInventoryPort createInventoryPort; + private final GetItemQuery getItemQuery; + private final EquipInventoryAdapter equipInventoryAdapter; private final EmailTokenService emailTokenService; @Transactional @@ -55,16 +55,13 @@ public void joinProcess(JoinUserRequest joinUserRequest) { userRepository.save(user); - Item head = itemReader.findById(1L); - Item theme = itemReader.findById(2L); + Item head = getItemQuery.getItem(1L); + Item theme = getItemQuery.getItem(2L); - Inventory In_head = new Inventory(head, user); - Inventory In_theme = new Inventory(theme, user); + Inventory In_head = createInventoryPort.create(head, user); + Inventory In_theme = createInventoryPort.create(theme, user); - inventoryCreator.create(In_head); - inventoryCreator.create(In_theme); - - inventoryUpdater.equip(In_head); - inventoryUpdater.equip(In_theme); + equipInventoryAdapter.equipInventory(In_head); + equipInventoryAdapter.equipInventory(In_theme); } } diff --git a/src/main/java/com/space/server/domain/chapter/presentation/ChapterController.java b/src/main/java/com/space/server/domain/chapter/adapter/in/web/ChapterController.java similarity index 53% rename from src/main/java/com/space/server/domain/chapter/presentation/ChapterController.java rename to src/main/java/com/space/server/domain/chapter/adapter/in/web/ChapterController.java index 47c602dd..86b13d4a 100644 --- a/src/main/java/com/space/server/domain/chapter/presentation/ChapterController.java +++ b/src/main/java/com/space/server/domain/chapter/adapter/in/web/ChapterController.java @@ -1,7 +1,8 @@ -package com.space.server.domain.chapter.presentation; +package com.space.server.domain.chapter.adapter.in.web; -import com.space.server.domain.chapter.presentation.dto.response.ChapterResponse; -import com.space.server.domain.chapter.service.QueryChapterService; +import com.space.server.domain.chapter.adapter.in.web.dto.response.ChapterResponse; +import com.space.server.domain.chapter.application.port.in.GetChapterQuery; +import com.space.server.domain.chapter.application.port.in.GetChaptersQuery; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -16,19 +17,19 @@ @Tag(name = "Chapter", description = "챕터 API") public class ChapterController { - private final QueryChapterService queryChapterService; + private final GetChaptersQuery getChaptersQuery; + private final GetChapterQuery getChapterQuery; @GetMapping("{chapter-id}") @Operation(summary = "챕터 조회", description = "해당 챕터를 조회합니다.") - public ChapterResponse readOne( - @Parameter(description = "챕터 ID", required = true) @PathVariable(name = "chapter-id") Long chapterId) { - return ChapterResponse.from(queryChapterService.readOne(chapterId)); + public ChapterResponse readOne(@Parameter(description = "챕터 ID", required = true) @PathVariable(name = "chapter-id") Long chapterId) { + return ChapterResponse.from(getChapterQuery.getChapter(chapterId)); } @GetMapping @Operation(summary = "모든 챕터 조회", description = "모든 챕터를 조회합니다.") public List readAll() { - return queryChapterService.readAll().stream() + return getChaptersQuery.getChapters().stream() .map(ChapterResponse::from) .toList(); } diff --git a/src/main/java/com/space/server/domain/chapter/presentation/dto/response/ChapterResponse.java b/src/main/java/com/space/server/domain/chapter/adapter/in/web/dto/response/ChapterResponse.java similarity index 77% rename from src/main/java/com/space/server/domain/chapter/presentation/dto/response/ChapterResponse.java rename to src/main/java/com/space/server/domain/chapter/adapter/in/web/dto/response/ChapterResponse.java index bb8be53d..e1eca6aa 100644 --- a/src/main/java/com/space/server/domain/chapter/presentation/dto/response/ChapterResponse.java +++ b/src/main/java/com/space/server/domain/chapter/adapter/in/web/dto/response/ChapterResponse.java @@ -1,4 +1,4 @@ -package com.space.server.domain.chapter.presentation.dto.response; +package com.space.server.domain.chapter.adapter.in.web.dto.response; import com.space.server.domain.chapter.domain.Chapter; import io.swagger.v3.oas.annotations.media.Schema; @@ -19,6 +19,6 @@ public record ChapterResponse( Map mapObjectImage ) { public static ChapterResponse from(Chapter chapter) { - return new ChapterResponse(chapter.getId(), chapter.getExplanation(), chapter.getMapObject(), chapter.getMapObjectImage()); + return new ChapterResponse(chapter.getId().getValue(), chapter.getExplanation(), chapter.getMapObject(), chapter.getMapObjectImage()); } } diff --git a/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterGetAdapter.java b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterGetAdapter.java new file mode 100644 index 00000000..72074586 --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterGetAdapter.java @@ -0,0 +1,22 @@ +package com.space.server.domain.chapter.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.chapter.application.port.out.LoadChapterPort; +import com.space.server.domain.chapter.domain.Chapter; +import com.space.server.domain.chapter.exception.ChapterNotFoundException; +import lombok.RequiredArgsConstructor; + +@PersistenceAdapter +@RequiredArgsConstructor +public class ChapterGetAdapter implements LoadChapterPort { + + private final ChapterRepository chapterRepository; + private final ChapterMapper chapterMapper; + + @Override + public Chapter loadChapter(Long chapterId) { + return chapterRepository.findById(chapterId) + .map(chapterMapper::mapToChapter) + .orElseThrow(ChapterNotFoundException::new); + } +} diff --git a/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterJpaEntity.java b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterJpaEntity.java new file mode 100644 index 00000000..23a9cea5 --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterJpaEntity.java @@ -0,0 +1,36 @@ +package com.space.server.domain.chapter.adapter.out.persistence; + +import io.hypersistence.utils.hibernate.type.basic.PostgreSQLHStoreType; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Type; + +import java.util.Map; + +@Builder +@Entity +@Table(name = "chapter") +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class ChapterJpaEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column + private String explanation; + + @Type(PostgreSQLHStoreType.class) + @Column(columnDefinition = "hstore") + private Map mapObject; + + @Type(PostgreSQLHStoreType.class) + @Column(columnDefinition = "hstore") + private Map mapObjectImage; + +} diff --git a/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterMapper.java b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterMapper.java new file mode 100644 index 00000000..0db43d7e --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterMapper.java @@ -0,0 +1,26 @@ +package com.space.server.domain.chapter.adapter.out.persistence; + +import com.space.server.domain.chapter.domain.Chapter; +import org.springframework.stereotype.Component; + +@Component +public class ChapterMapper { + + public Chapter mapToChapter(ChapterJpaEntity chapter) { + return Chapter.builder() + .id(new Chapter.ChapterId(chapter.getId())) + .explanation(chapter.getExplanation()) + .mapObject(chapter.getMapObject()) + .mapObjectImage(chapter.getMapObjectImage()) + .build(); + } + + public ChapterJpaEntity mapToChapterJpaEntity(Chapter chapter) { + return ChapterJpaEntity.builder() + .id(chapter.getId() == null ? null : chapter.getId().getValue()) + .explanation(chapter.getExplanation()) + .mapObject(chapter.getMapObject()) + .mapObjectImage(chapter.getMapObjectImage()) + .build(); + } +} diff --git a/src/main/java/com/space/server/domain/chapter/domain/repository/ChapterRepository.java b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterRepository.java similarity index 57% rename from src/main/java/com/space/server/domain/chapter/domain/repository/ChapterRepository.java rename to src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterRepository.java index 7725a3ff..d6b116da 100644 --- a/src/main/java/com/space/server/domain/chapter/domain/repository/ChapterRepository.java +++ b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChapterRepository.java @@ -1,12 +1,11 @@ -package com.space.server.domain.chapter.domain.repository; +package com.space.server.domain.chapter.adapter.out.persistence; -import com.space.server.domain.chapter.domain.Chapter; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.List; @Repository -public interface ChapterRepository extends JpaRepository { - List findAllByOrderById(); +public interface ChapterRepository extends JpaRepository { + List findAllByOrderById(); } diff --git a/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChaptersGetAdapter.java b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChaptersGetAdapter.java new file mode 100644 index 00000000..ebb7fd38 --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/adapter/out/persistence/ChaptersGetAdapter.java @@ -0,0 +1,23 @@ +package com.space.server.domain.chapter.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.chapter.application.port.out.LoadChaptersPort; +import com.space.server.domain.chapter.domain.Chapter; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@PersistenceAdapter +@RequiredArgsConstructor +public class ChaptersGetAdapter implements LoadChaptersPort { + + private final ChapterRepository chapterRepository; + private final ChapterMapper chapterMapper; + + @Override + public List loadChapters() { + return chapterRepository.findAll().stream() + .map(chapterMapper::mapToChapter) + .toList(); + } +} diff --git a/src/main/java/com/space/server/domain/chapter/application/port/in/GetChapterQuery.java b/src/main/java/com/space/server/domain/chapter/application/port/in/GetChapterQuery.java new file mode 100644 index 00000000..27634c43 --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/application/port/in/GetChapterQuery.java @@ -0,0 +1,8 @@ +package com.space.server.domain.chapter.application.port.in; + +import com.space.server.domain.chapter.domain.Chapter; + +public interface GetChapterQuery { + + Chapter getChapter(Long id); +} diff --git a/src/main/java/com/space/server/domain/chapter/application/port/in/GetChaptersQuery.java b/src/main/java/com/space/server/domain/chapter/application/port/in/GetChaptersQuery.java new file mode 100644 index 00000000..0b7ab229 --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/application/port/in/GetChaptersQuery.java @@ -0,0 +1,10 @@ +package com.space.server.domain.chapter.application.port.in; + +import com.space.server.domain.chapter.domain.Chapter; + +import java.util.List; + +public interface GetChaptersQuery { + + List getChapters(); +} diff --git a/src/main/java/com/space/server/domain/chapter/application/port/out/LoadChapterPort.java b/src/main/java/com/space/server/domain/chapter/application/port/out/LoadChapterPort.java new file mode 100644 index 00000000..26350244 --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/application/port/out/LoadChapterPort.java @@ -0,0 +1,8 @@ +package com.space.server.domain.chapter.application.port.out; + +import com.space.server.domain.chapter.domain.Chapter; + +public interface LoadChapterPort { + + Chapter loadChapter(Long chapterId); +} diff --git a/src/main/java/com/space/server/domain/chapter/application/port/out/LoadChaptersPort.java b/src/main/java/com/space/server/domain/chapter/application/port/out/LoadChaptersPort.java new file mode 100644 index 00000000..c12d2154 --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/application/port/out/LoadChaptersPort.java @@ -0,0 +1,10 @@ +package com.space.server.domain.chapter.application.port.out; + +import com.space.server.domain.chapter.domain.Chapter; + +import java.util.List; + +public interface LoadChaptersPort { + + List loadChapters(); +} diff --git a/src/main/java/com/space/server/domain/chapter/application/service/GetChapterService.java b/src/main/java/com/space/server/domain/chapter/application/service/GetChapterService.java new file mode 100644 index 00000000..d61288c0 --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/application/service/GetChapterService.java @@ -0,0 +1,19 @@ +package com.space.server.domain.chapter.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.chapter.application.port.in.GetChapterQuery; +import com.space.server.domain.chapter.application.port.out.LoadChapterPort; +import com.space.server.domain.chapter.domain.Chapter; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class GetChapterService implements GetChapterQuery { + + private final LoadChapterPort loadChapterPort; + + @Override + public Chapter getChapter(Long chapterId) { + return loadChapterPort.loadChapter(chapterId); + } +} diff --git a/src/main/java/com/space/server/domain/chapter/application/service/GetChaptersService.java b/src/main/java/com/space/server/domain/chapter/application/service/GetChaptersService.java new file mode 100644 index 00000000..fb429148 --- /dev/null +++ b/src/main/java/com/space/server/domain/chapter/application/service/GetChaptersService.java @@ -0,0 +1,21 @@ +package com.space.server.domain.chapter.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.chapter.application.port.in.GetChaptersQuery; +import com.space.server.domain.chapter.application.port.out.LoadChaptersPort; +import com.space.server.domain.chapter.domain.Chapter; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@UseCase +@RequiredArgsConstructor +public class GetChaptersService implements GetChaptersQuery { + + private final LoadChaptersPort loadChaptersPort; + + @Override + public List getChapters() { + return loadChaptersPort.loadChapters(); + } +} diff --git a/src/main/java/com/space/server/domain/chapter/domain/Chapter.java b/src/main/java/com/space/server/domain/chapter/domain/Chapter.java index a6dfeeba..047665f0 100644 --- a/src/main/java/com/space/server/domain/chapter/domain/Chapter.java +++ b/src/main/java/com/space/server/domain/chapter/domain/Chapter.java @@ -1,53 +1,28 @@ package com.space.server.domain.chapter.domain; -import io.hypersistence.utils.hibernate.type.basic.PostgreSQLHStoreType; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.hibernate.annotations.Type; +import lombok.*; import java.util.Map; @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -@Schema(description = "챕터 Entity") +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) public class Chapter { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Schema(description = "챕터 ID") - private Long id; + private ChapterId id; @NotNull - @Schema(description = "챕터 설명") private String explanation; - @Type(PostgreSQLHStoreType.class) - @Column(columnDefinition = "hstore") @NotNull - @Schema(description = "맵오브젝트") private Map mapObject; - @Type(PostgreSQLHStoreType.class) - @Column(columnDefinition = "hstore") @NotNull - @Schema(description = "맵오브젝트 이미지") private Map mapObjectImage; - @Builder - public Chapter(String explanation, Map mapObject, Map mapObjectImage) { - this.explanation = explanation; - this.mapObject = mapObject; - this.mapObjectImage = mapObjectImage; - } - - public void update(Chapter chapter) { - this.explanation = chapter.getExplanation(); - this.mapObject = chapter.getMapObject(); + @Value + public static class ChapterId { + private final Long value; } } diff --git a/src/main/java/com/space/server/domain/chapter/service/CommandChapterService.java b/src/main/java/com/space/server/domain/chapter/service/CommandChapterService.java deleted file mode 100644 index 88fced89..00000000 --- a/src/main/java/com/space/server/domain/chapter/service/CommandChapterService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.space.server.domain.chapter.service; - -import com.space.server.domain.chapter.domain.Chapter; -import com.space.server.domain.chapter.service.implementation.ChapterCreator; -import com.space.server.domain.chapter.service.implementation.ChapterDeleter; -import com.space.server.domain.chapter.service.implementation.ChapterReader; -import com.space.server.domain.chapter.service.implementation.ChapterUpdater; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -@Transactional -public class CommandChapterService { - - private final ChapterCreator chapterCreator; - private final ChapterReader chapterReader; - private final ChapterUpdater chapterUpdater; - private final ChapterDeleter chapterDeleter; - - public void createChapter(Chapter chapter) { - chapterCreator.create(chapter); - } - - public void updateChapter(Long chapterId, Chapter chapter) { - Chapter updatableChapter = chapterReader.findById(chapterId); - chapterUpdater.update(updatableChapter, chapter); - } - - public void deleteChapter(Long chapterId) { - Chapter chapter = chapterReader.findById(chapterId); - chapterDeleter.delete(chapter); - } -} diff --git a/src/main/java/com/space/server/domain/chapter/service/QueryChapterService.java b/src/main/java/com/space/server/domain/chapter/service/QueryChapterService.java deleted file mode 100644 index 7895ca92..00000000 --- a/src/main/java/com/space/server/domain/chapter/service/QueryChapterService.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.space.server.domain.chapter.service; - -import com.space.server.domain.chapter.domain.Chapter; -import com.space.server.domain.chapter.service.implementation.ChapterReader; -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 QueryChapterService { - - private final ChapterReader chapterReader; - - public Chapter readOne(Long chapterId) { - return chapterReader.findById(chapterId); - } - - public List readAll() { - return chapterReader.findAll(); - } -} diff --git a/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterCreator.java b/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterCreator.java deleted file mode 100644 index 83e01a28..00000000 --- a/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterCreator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.chapter.service.implementation; - -import com.space.server.domain.chapter.domain.Chapter; -import com.space.server.domain.chapter.domain.repository.ChapterRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class ChapterCreator { - - private final ChapterRepository chapterRepository; - - public void create(Chapter chapter) { - chapterRepository.save(chapter); - } -} diff --git a/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterDeleter.java b/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterDeleter.java deleted file mode 100644 index f5fe0c72..00000000 --- a/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterDeleter.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.chapter.service.implementation; - -import com.space.server.domain.chapter.domain.Chapter; -import com.space.server.domain.chapter.domain.repository.ChapterRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class ChapterDeleter { - - private final ChapterRepository chapterRepository; - - public void delete(Chapter chapter) { - chapterRepository.delete(chapter); - } -} diff --git a/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterReader.java b/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterReader.java deleted file mode 100644 index c3e3e0b9..00000000 --- a/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterReader.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.space.server.domain.chapter.service.implementation; - -import com.space.server.domain.chapter.domain.Chapter; -import com.space.server.domain.chapter.domain.repository.ChapterRepository; -import com.space.server.domain.chapter.exception.ChapterNotFoundException; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -@RequiredArgsConstructor -public class ChapterReader { - - private final ChapterRepository chapterRepository; - - public Chapter findById(Long id) { - return chapterRepository.findById(id) - .orElseThrow(ChapterNotFoundException::new); - } - - public List findAll() { - return chapterRepository.findAllByOrderById(); - } -} diff --git a/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterUpdater.java b/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterUpdater.java deleted file mode 100644 index a3c37751..00000000 --- a/src/main/java/com/space/server/domain/chapter/service/implementation/ChapterUpdater.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.space.server.domain.chapter.service.implementation; - -import com.space.server.domain.chapter.domain.Chapter; -import org.springframework.stereotype.Service; - -@Service -public class ChapterUpdater { - - public void update(Chapter updatableChapter, Chapter chapter) { - updatableChapter.update(chapter); - } -} diff --git a/src/main/java/com/space/server/domain/chat/service/CommandChatService.java b/src/main/java/com/space/server/domain/chat/service/CommandChatService.java index 91268c39..d638eb98 100644 --- a/src/main/java/com/space/server/domain/chat/service/CommandChatService.java +++ b/src/main/java/com/space/server/domain/chat/service/CommandChatService.java @@ -8,6 +8,7 @@ import com.space.server.domain.ai.service.dto.response.gpt.AiThreadResponse; import com.space.server.domain.ai.service.implementation.ChatCompleter; import com.space.server.domain.ai.service.implementation.PromptCreator; +import com.space.server.domain.chapter.application.port.in.GetChapterQuery; import com.space.server.domain.chat.domain.Chat; import com.space.server.domain.chat.domain.value.Type; import com.space.server.domain.chat.presentation.dto.request.CreateChatRequest; @@ -16,11 +17,11 @@ import com.space.server.domain.chat.service.implementation.AiResponseJsonParsing; import com.space.server.domain.chat.service.implementation.ChatValidator; import com.space.server.domain.chapter.domain.Chapter; -import com.space.server.domain.chapter.service.implementation.ChapterReader; +import com.space.server.domain.checklist.application.port.in.GetChecklistsByQuizQuery; import com.space.server.domain.checklist.domain.Checklist; -import com.space.server.domain.checklist.service.implementation.ChecklistReader; +import com.space.server.domain.quiz.adapter.out.persistence.QuizMapper; +import com.space.server.domain.quiz.application.port.in.GetQuizQuery; import com.space.server.domain.quiz.domain.Quiz; -import com.space.server.domain.quiz.service.implementation.QuizReader; import com.space.server.domain.state.domain.State; import com.space.server.domain.state.domain.value.Status; import com.space.server.domain.state.service.implementation.StateCreator; @@ -43,22 +44,23 @@ public class CommandChatService { private final StateReader stateReader; private final StateCreator stateCreator; - private final QuizReader quizReader; + private final GetQuizQuery getQuizQuery; + private final GetChapterQuery getChapterQuery; private final UserReader userReader; private final ChatReader chatReader; private final ChatCreator chatCreator; private final ChatValidator chatValidator; - private final ChecklistReader checklistReader; - private final ChapterReader chapterReader; + private final GetChecklistsByQuizQuery getChecklistsByQuizQuery; private final ChatCompleter chatCompleter; private final StateUpdater stateUpdater; private final AiResponseJsonParsing aiResponseJsonParsing; + private final QuizMapper quizMapper; public AiResponse create(Long quizId, CreateChatRequest request, Long userId) { - Quiz quiz = quizReader.findById(quizId); + Quiz quiz = getQuizQuery.getQuiz(quizId); Users user = userReader.findById(userId); - List checklists = checklistReader.findByQuiz(quiz); - Chapter chapter = chapterReader.findById(quiz.getChapter().getId()); + List checklists = getChecklistsByQuizQuery.getChecklistsByQuiz(quizId); + Chapter chapter = getChapterQuery.getChapter(quiz.getChapter().getId().getValue()); Optional state = stateReader.findByQuizIdAndUserId(quiz, user); @@ -139,7 +141,7 @@ public AiResponse create(Long quizId, CreateChatRequest request, Long userId) { stateCreator.create(State.createBuilder() .user(user) - .quiz(quiz) + .quiz(quizMapper.mapToQuizJpaEntity(quiz)) .status(botChat.isSuccess() == true ? Status.SUCCESS : Status.FAIL) .move(botChat.move()) .score(botChat.score()) diff --git a/src/main/java/com/space/server/domain/chat/service/QueryChatService.java b/src/main/java/com/space/server/domain/chat/service/QueryChatService.java index 98ade3dd..1350f638 100644 --- a/src/main/java/com/space/server/domain/chat/service/QueryChatService.java +++ b/src/main/java/com/space/server/domain/chat/service/QueryChatService.java @@ -3,7 +3,7 @@ import com.space.server.domain.chat.domain.Chat; import com.space.server.domain.chat.presentation.dto.response.ChatResponse; import com.space.server.domain.chat.service.implementation.ChatReader; -import com.space.server.domain.quiz.service.implementation.QuizReader; +import com.space.server.domain.quiz.application.port.in.GetQuizQuery; import com.space.server.domain.state.service.implementation.StateReader; import com.space.server.domain.user.service.implementation.UserReader; import lombok.RequiredArgsConstructor; @@ -20,12 +20,12 @@ public class QueryChatService { private final ChatReader chatReader; private final StateReader stateReader; - private final QuizReader quizReader; + private final GetQuizQuery getQuizQuery; private final UserReader userReader; public List readChats(Long quizId, Long userId){ List chatList = chatReader.findAllChatByState(stateReader.findByQuizIdAndUserId( - quizReader.findById(quizId), + getQuizQuery.getQuiz(quizId), userReader.findById(userId) ).get()); List chatResponseList = new ArrayList<>(); diff --git a/src/main/java/com/space/server/domain/checklist/presentation/ChecklistController.java b/src/main/java/com/space/server/domain/checklist/adapter/in/web/ChecklistController.java similarity index 68% rename from src/main/java/com/space/server/domain/checklist/presentation/ChecklistController.java rename to src/main/java/com/space/server/domain/checklist/adapter/in/web/ChecklistController.java index 7762231d..06130c82 100644 --- a/src/main/java/com/space/server/domain/checklist/presentation/ChecklistController.java +++ b/src/main/java/com/space/server/domain/checklist/adapter/in/web/ChecklistController.java @@ -1,7 +1,7 @@ -package com.space.server.domain.checklist.presentation; +package com.space.server.domain.checklist.adapter.in.web; -import com.space.server.domain.checklist.presentation.dto.response.ChecklistResponse; -import com.space.server.domain.checklist.service.QueryChecklistService; +import com.space.server.domain.checklist.adapter.in.web.dto.response.ChecklistResponse; +import com.space.server.domain.checklist.application.port.in.GetChecklistsByQuizQuery; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -16,12 +16,13 @@ @Tag(name = "Checklist", description = "체크리스트 API") public class ChecklistController { - private final QueryChecklistService queryChecklistService; + private final GetChecklistsByQuizQuery getChecklistsByQuizQuery; + @GetMapping("/quiz/{quiz-id}") @Operation(summary = "퀴즈 내 모든 체크리스트 조회", description = "해당 퀴즈의 전체 체크리스트를 조회합니다.") public List findByQuiz(@PathVariable(name = "quiz-id") @Parameter(description = "퀴즈 ID") Long quizId) { - return queryChecklistService.findByQuiz(quizId).stream() + return getChecklistsByQuizQuery.getChecklistsByQuiz(quizId).stream() .map(ChecklistResponse::from) .toList(); } diff --git a/src/main/java/com/space/server/domain/checklist/presentation/dto/response/ChecklistResponse.java b/src/main/java/com/space/server/domain/checklist/adapter/in/web/dto/response/ChecklistResponse.java similarity index 75% rename from src/main/java/com/space/server/domain/checklist/presentation/dto/response/ChecklistResponse.java rename to src/main/java/com/space/server/domain/checklist/adapter/in/web/dto/response/ChecklistResponse.java index e1e164e6..f0e8d6fd 100644 --- a/src/main/java/com/space/server/domain/checklist/presentation/dto/response/ChecklistResponse.java +++ b/src/main/java/com/space/server/domain/checklist/adapter/in/web/dto/response/ChecklistResponse.java @@ -1,4 +1,4 @@ -package com.space.server.domain.checklist.presentation.dto.response; +package com.space.server.domain.checklist.adapter.in.web.dto.response; import com.space.server.domain.checklist.domain.Checklist; import io.swagger.v3.oas.annotations.media.Schema; @@ -19,9 +19,9 @@ public record ChecklistResponse( ) { public static ChecklistResponse from(Checklist checklist) { return new ChecklistResponse( - checklist.getId(), - checklist.getQuiz().getId(), - checklist.getChapter().getId(), + checklist.getId().getValue(), + checklist.getQuiz().getId().getValue(), + checklist.getChapter().getId().getValue(), checklist.getContent() ); } diff --git a/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistJpaEntity.java b/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistJpaEntity.java new file mode 100644 index 00000000..e1d16e5b --- /dev/null +++ b/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistJpaEntity.java @@ -0,0 +1,33 @@ +package com.space.server.domain.checklist.adapter.out.persistence; + +import com.space.server.domain.chapter.adapter.out.persistence.ChapterJpaEntity; +import com.space.server.domain.quiz.adapter.out.persistence.QuizJpaEntity; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Builder +@Entity +@Table(name = "checklist") +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class ChecklistJpaEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JoinColumn + @ManyToOne(fetch = FetchType.LAZY) + private QuizJpaEntity quiz; + + @JoinColumn + @ManyToOne(fetch = FetchType.LAZY) + private ChapterJpaEntity chapter; + + @Column + private String content; +} diff --git a/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistMapper.java b/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistMapper.java new file mode 100644 index 00000000..068a38d0 --- /dev/null +++ b/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistMapper.java @@ -0,0 +1,24 @@ +package com.space.server.domain.checklist.adapter.out.persistence; + +import com.space.server.domain.chapter.adapter.out.persistence.ChapterMapper; +import com.space.server.domain.checklist.domain.Checklist; +import com.space.server.domain.quiz.adapter.out.persistence.QuizMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class ChecklistMapper { + + private final ChapterMapper chapterMapper; + private final QuizMapper quizMapper; + + public Checklist mapToChecklist(ChecklistJpaEntity checklist) { + return Checklist.builder() + .id(new Checklist.ChecklistId(checklist.getId())) + .quiz(quizMapper.mapToQuiz(checklist.getQuiz())) + .chapter(chapterMapper.mapToChapter(checklist.getChapter())) + .content(checklist.getContent()) + .build(); + } +} diff --git a/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistRepository.java b/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistRepository.java new file mode 100644 index 00000000..35bc18b8 --- /dev/null +++ b/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistRepository.java @@ -0,0 +1,12 @@ +package com.space.server.domain.checklist.adapter.out.persistence; + +import com.space.server.domain.quiz.adapter.out.persistence.QuizJpaEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ChecklistRepository extends JpaRepository { + List findByQuiz(QuizJpaEntity quiz); +} diff --git a/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistsByQuizGetAdapter.java b/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistsByQuizGetAdapter.java new file mode 100644 index 00000000..385a8503 --- /dev/null +++ b/src/main/java/com/space/server/domain/checklist/adapter/out/persistence/ChecklistsByQuizGetAdapter.java @@ -0,0 +1,30 @@ +package com.space.server.domain.checklist.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.checklist.application.port.out.LoadChecklistsByQuizPort; +import com.space.server.domain.checklist.domain.Checklist; +import com.space.server.domain.quiz.adapter.out.persistence.QuizJpaEntity; +import com.space.server.domain.quiz.adapter.out.persistence.QuizRepository; +import com.space.server.domain.quiz.exception.QuizNotFoundException; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@PersistenceAdapter +@RequiredArgsConstructor +public class ChecklistsByQuizGetAdapter implements LoadChecklistsByQuizPort { + + private final ChecklistRepository checklistRepository; + private final ChecklistMapper checklistMapper; + private final QuizRepository quizRepository; + + @Override + public List loadChecklistsByQuiz(Long quizId) { + QuizJpaEntity quiz = quizRepository.findById(quizId) + .orElseThrow(QuizNotFoundException::new); + + return checklistRepository.findByQuiz(quiz).stream() + .map(checklistMapper::mapToChecklist) + .toList(); + } +} diff --git a/src/main/java/com/space/server/domain/checklist/application/port/in/GetChecklistsByQuizQuery.java b/src/main/java/com/space/server/domain/checklist/application/port/in/GetChecklistsByQuizQuery.java new file mode 100644 index 00000000..60bb8e23 --- /dev/null +++ b/src/main/java/com/space/server/domain/checklist/application/port/in/GetChecklistsByQuizQuery.java @@ -0,0 +1,9 @@ +package com.space.server.domain.checklist.application.port.in; + +import com.space.server.domain.checklist.domain.Checklist; + +import java.util.List; + +public interface GetChecklistsByQuizQuery { + List getChecklistsByQuiz(Long quizId); +} diff --git a/src/main/java/com/space/server/domain/checklist/application/port/out/LoadChecklistsByQuizPort.java b/src/main/java/com/space/server/domain/checklist/application/port/out/LoadChecklistsByQuizPort.java new file mode 100644 index 00000000..0eb64853 --- /dev/null +++ b/src/main/java/com/space/server/domain/checklist/application/port/out/LoadChecklistsByQuizPort.java @@ -0,0 +1,9 @@ +package com.space.server.domain.checklist.application.port.out; + +import com.space.server.domain.checklist.domain.Checklist; + +import java.util.List; + +public interface LoadChecklistsByQuizPort { + List loadChecklistsByQuiz(Long quizId); +} diff --git a/src/main/java/com/space/server/domain/checklist/application/service/GetChecklistsByQuizService.java b/src/main/java/com/space/server/domain/checklist/application/service/GetChecklistsByQuizService.java new file mode 100644 index 00000000..1f50dd0a --- /dev/null +++ b/src/main/java/com/space/server/domain/checklist/application/service/GetChecklistsByQuizService.java @@ -0,0 +1,21 @@ +package com.space.server.domain.checklist.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.checklist.application.port.in.GetChecklistsByQuizQuery; +import com.space.server.domain.checklist.application.port.out.LoadChecklistsByQuizPort; +import com.space.server.domain.checklist.domain.Checklist; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@UseCase +@RequiredArgsConstructor +public class GetChecklistsByQuizService implements GetChecklistsByQuizQuery { + + private final LoadChecklistsByQuizPort loadChecklistsByQuizPort; + + @Override + public List getChecklistsByQuiz(Long quizId) { + return loadChecklistsByQuizPort.loadChecklistsByQuiz(quizId); + } +} diff --git a/src/main/java/com/space/server/domain/checklist/domain/Checklist.java b/src/main/java/com/space/server/domain/checklist/domain/Checklist.java index 4ebc7b88..26aba7d1 100644 --- a/src/main/java/com/space/server/domain/checklist/domain/Checklist.java +++ b/src/main/java/com/space/server/domain/checklist/domain/Checklist.java @@ -2,47 +2,28 @@ import com.space.server.domain.chapter.domain.Chapter; import com.space.server.domain.quiz.domain.Quiz; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -@Schema(description = "체크리스트 Entity") +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) public class Checklist { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Schema(description = "체크리스트 ID") - private Long id; + @NotNull + private ChecklistId id; - @ManyToOne(fetch = FetchType.LAZY) @NotNull - @Schema(description = "퀴즈", required = true) private Quiz quiz; - @ManyToOne(fetch = FetchType.LAZY) @NotNull - @Schema(description = "챕터", required = true) private Chapter chapter; @NotNull - @Schema(description = "체크리스트 내용") private String content; - @Builder - public Checklist(Quiz quiz, Chapter chapter, String content) { - this.quiz = quiz; - this.chapter = chapter; - this.content = content; - } - - public void update(Checklist checklist) { - this.content = checklist.getContent(); + @Value + public static class ChecklistId { + private final Long value; } } diff --git a/src/main/java/com/space/server/domain/checklist/domain/repository/ChecklistRepository.java b/src/main/java/com/space/server/domain/checklist/domain/repository/ChecklistRepository.java deleted file mode 100644 index 7199f1b2..00000000 --- a/src/main/java/com/space/server/domain/checklist/domain/repository/ChecklistRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.space.server.domain.checklist.domain.repository; - -import com.space.server.domain.checklist.domain.Checklist; -import com.space.server.domain.quiz.domain.Quiz; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface ChecklistRepository extends JpaRepository { - List findByQuiz(Quiz quiz); -} diff --git a/src/main/java/com/space/server/domain/checklist/service/CommandChecklistService.java b/src/main/java/com/space/server/domain/checklist/service/CommandChecklistService.java deleted file mode 100644 index 71fe62a9..00000000 --- a/src/main/java/com/space/server/domain/checklist/service/CommandChecklistService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.space.server.domain.checklist.service; - -import com.space.server.domain.checklist.domain.Checklist; -import com.space.server.domain.checklist.service.implementation.ChecklistCreator; -import com.space.server.domain.checklist.service.implementation.ChecklistDeleter; -import com.space.server.domain.checklist.service.implementation.ChecklistReader; -import com.space.server.domain.checklist.service.implementation.ChecklistUpdater; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -@Transactional -public class CommandChecklistService { - - private final ChecklistCreator checklistCreator; - private final ChecklistReader checklistReader; - private final ChecklistUpdater checklistUpdater; - private final ChecklistDeleter checklistDeleter; - - public void createChecklist(Checklist checklist) { - checklistCreator.create(checklist); - } - - public void updateChecklist(Long checklistId, Checklist checklist) { - Checklist updatablechecklist = checklistReader.readOne(checklistId); - checklistUpdater.update(updatablechecklist, checklist); - } - - public void deleteChecklist(Long checklistId) { - Checklist checklist = checklistReader.readOne(checklistId); - checklistDeleter.delete(checklist); - } -} diff --git a/src/main/java/com/space/server/domain/checklist/service/QueryChecklistService.java b/src/main/java/com/space/server/domain/checklist/service/QueryChecklistService.java deleted file mode 100644 index d0801f7a..00000000 --- a/src/main/java/com/space/server/domain/checklist/service/QueryChecklistService.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.space.server.domain.checklist.service; - -import com.space.server.domain.checklist.domain.Checklist; -import com.space.server.domain.checklist.service.implementation.ChecklistReader; -import com.space.server.domain.quiz.domain.Quiz; -import com.space.server.domain.quiz.service.implementation.QuizReader; -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 QueryChecklistService { - - private final ChecklistReader checklistReader; - private final QuizReader quizReader; - - public Checklist readOne(Long checklistId) { - return checklistReader.readOne(checklistId); - } - - public List readAll() { - return checklistReader.readALL(); - } - - public List findByQuiz(Long quizId) { - Quiz quiz = quizReader.findById(quizId); - return checklistReader.findByQuiz(quiz); - } -} diff --git a/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistCreator.java b/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistCreator.java deleted file mode 100644 index 71586d7d..00000000 --- a/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistCreator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.checklist.service.implementation; - -import com.space.server.domain.checklist.domain.Checklist; -import com.space.server.domain.checklist.domain.repository.ChecklistRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class ChecklistCreator { - - private final ChecklistRepository checklistRepository; - - public void create(Checklist checklist) { - checklistRepository.save(checklist); - } -} diff --git a/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistDeleter.java b/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistDeleter.java deleted file mode 100644 index 15a397d4..00000000 --- a/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistDeleter.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.checklist.service.implementation; - -import com.space.server.domain.checklist.domain.Checklist; -import com.space.server.domain.checklist.domain.repository.ChecklistRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class ChecklistDeleter { - - private final ChecklistRepository checklistRepository; - - public void delete(Checklist checklist) { - checklistRepository.delete(checklist); - } -} diff --git a/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistReader.java b/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistReader.java deleted file mode 100644 index 96601600..00000000 --- a/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistReader.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.space.server.domain.checklist.service.implementation; - -import com.space.server.domain.checklist.domain.Checklist; -import com.space.server.domain.checklist.domain.repository.ChecklistRepository; -import com.space.server.domain.checklist.exception.ChecklistNotFoundException; -import com.space.server.domain.quiz.domain.Quiz; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -@RequiredArgsConstructor -public class ChecklistReader { - - private final ChecklistRepository repository; - - public Checklist readOne(Long checklistId) { - return repository.findById(checklistId) - .orElseThrow(ChecklistNotFoundException::new); - } - - public List readALL() { - return repository.findAll(); - } - - public List findByQuiz(Quiz quiz) { - return repository.findByQuiz(quiz); - } -} diff --git a/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistUpdater.java b/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistUpdater.java deleted file mode 100644 index 2a4d8568..00000000 --- a/src/main/java/com/space/server/domain/checklist/service/implementation/ChecklistUpdater.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.space.server.domain.checklist.service.implementation; - -import com.space.server.domain.checklist.domain.Checklist; -import org.springframework.stereotype.Service; - -@Service -public class ChecklistUpdater { - - public void update(Checklist updatableChecklist, Checklist checklist) { - updatableChecklist.update(checklist); - } -} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/in/web/InventoryController.java b/src/main/java/com/space/server/domain/inventory/adapter/in/web/InventoryController.java new file mode 100644 index 00000000..4a3aed9a --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/in/web/InventoryController.java @@ -0,0 +1,48 @@ +package com.space.server.domain.inventory.adapter.in.web; + +import com.space.server.domain.inventory.adapter.in.web.dto.response.InventoryResponse; +import com.space.server.domain.inventory.application.port.in.EquipInventoryUseCase; +import com.space.server.domain.inventory.application.port.in.GetInventoriesByIsEquippedQuery; +import com.space.server.domain.inventory.application.port.in.GetInventoriesQuery; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static com.space.server.common.jwt.util.AuthenticationUtil.getMemberId; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/inventories") +@Tag(name = "Inventory", description = "인벤토리 API") +public class InventoryController { + + private final GetInventoriesQuery getInventoriesQuery; + private final GetInventoriesByIsEquippedQuery getInventoriesByIsEquippedQuery; + private final EquipInventoryUseCase equipInventoryUseCase; + + @GetMapping + @Operation(summary = "전체 인벤토리 조회", description = "해당 유저의 전체 인벤토리를 조회합니다.") + public List readAll() { + return getInventoriesQuery.getInventories(getMemberId()).stream() + .map(InventoryResponse::from) + .toList(); + } + + @GetMapping("/equip") + @Operation(summary = "장착된 인벤토리 조회", description = "해당 유저의 장착된 인벤토리를 조회합니다.") + public List readIsEquipped() { + return getInventoriesByIsEquippedQuery.getInventoriesByIsEquippedQuery(getMemberId()).stream() + .map(InventoryResponse::from) + .toList(); + } + + @PutMapping("/{inventory-id}") + @Operation(summary = "인벤토리 장착", description = "해당 인벤토리를 장착합니다.") + public void equipItem(@PathVariable(name = "inventory-id") @Parameter(description = "인벤토리 ID") Long inventoryId) { + equipInventoryUseCase.equipInventory(inventoryId, getMemberId()); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/presentation/dto/response/InventoryResponse.java b/src/main/java/com/space/server/domain/inventory/adapter/in/web/dto/response/InventoryResponse.java similarity index 78% rename from src/main/java/com/space/server/domain/inventory/presentation/dto/response/InventoryResponse.java rename to src/main/java/com/space/server/domain/inventory/adapter/in/web/dto/response/InventoryResponse.java index 9be46a8f..2f532e2e 100644 --- a/src/main/java/com/space/server/domain/inventory/presentation/dto/response/InventoryResponse.java +++ b/src/main/java/com/space/server/domain/inventory/adapter/in/web/dto/response/InventoryResponse.java @@ -1,4 +1,4 @@ -package com.space.server.domain.inventory.presentation.dto.response; +package com.space.server.domain.inventory.adapter.in.web.dto.response; import com.space.server.domain.inventory.domain.Inventory; import com.space.server.domain.item.domain.value.Category; @@ -11,6 +11,8 @@ public record InventoryResponse( @Schema(description = "인벤토리 ID", example = "1") Long id, + String name, + @Schema(description = "아이템 ID", example = "10") Long itemId, @@ -22,8 +24,9 @@ public record InventoryResponse( ) { public static InventoryResponse from(Inventory inventory) { return InventoryResponse.builder() - .id(inventory.getId()) - .itemId(inventory.getItem().getId()) + .id(inventory.getId().getValue()) + .name(inventory.getItem().getName()) + .itemId(inventory.getItem().getId().getValue()) .category(inventory.getItem().getCategory()) .isEquipped(inventory.isEquipped()) .build(); diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/CheckHaveItemAdapter.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/CheckHaveItemAdapter.java new file mode 100644 index 00000000..03c25778 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/CheckHaveItemAdapter.java @@ -0,0 +1,23 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.inventory.application.port.out.CheckHaveItemPort; +import com.space.server.domain.item.adapter.out.persistence.ItemJpaEntity; +import com.space.server.domain.item.adapter.out.persistence.ItemMapper; +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.user.domain.Users; +import lombok.RequiredArgsConstructor; + +@PersistenceAdapter +@RequiredArgsConstructor +public class CheckHaveItemAdapter implements CheckHaveItemPort { + + private final InventoryRepository inventoryRepository; + private final ItemMapper itemMapper; + + @Override + public Boolean checkHaveItem(Item item, Users user) { + ItemJpaEntity itemJpaEntity = itemMapper.mapToItemJpaEntity(item); + return inventoryRepository.existsByItemAndUser(itemJpaEntity, user); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/CreateInventoryAdapter.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/CreateInventoryAdapter.java new file mode 100644 index 00000000..33fe2ed8 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/CreateInventoryAdapter.java @@ -0,0 +1,22 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.inventory.application.port.out.CreateInventoryPort; +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.user.domain.Users; +import lombok.RequiredArgsConstructor; + +@PersistenceAdapter +@RequiredArgsConstructor +public class CreateInventoryAdapter implements CreateInventoryPort { + + @Override + public Inventory create(Item item, Users user) { + return Inventory.builder() + .item(item) + .user(user) + .isEquipped(false) + .build(); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/EquipInventoryAdapter.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/EquipInventoryAdapter.java new file mode 100644 index 00000000..c4bb6a12 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/EquipInventoryAdapter.java @@ -0,0 +1,30 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.inventory.application.port.out.EquipInventoryPort; +import com.space.server.domain.inventory.domain.Inventory; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@PersistenceAdapter +@RequiredArgsConstructor +public class EquipInventoryAdapter implements EquipInventoryPort { + + private final InventoryRepository inventoryRepository; + private final InventoryMapper inventoryMapper; + + @Override + public void equipInventory(Inventory inventory) { + inventory.equip(); + InventoryJpaEntity inventoryJpaEntity = inventoryMapper.mapToInventoryJpaEntity(inventory); + inventoryRepository.save(inventoryJpaEntity); + } + + @Override + public void unEquipInventory(Inventory inventory) { + inventory.unEquip(); + InventoryJpaEntity inventoryJpaEntity = inventoryMapper.mapToInventoryJpaEntity(inventory); + inventoryRepository.save(inventoryJpaEntity); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/EquippedInventoryByCategoryGetAdapter.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/EquippedInventoryByCategoryGetAdapter.java new file mode 100644 index 00000000..847442dc --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/EquippedInventoryByCategoryGetAdapter.java @@ -0,0 +1,28 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.inventory.application.port.out.LoadEquippedInventoryByCategoryPort; +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.item.domain.value.Category; +import com.space.server.domain.user.domain.Users; +import com.space.server.domain.user.domain.repository.UserRepository; +import com.space.server.domain.user.exception.UserNotFoundException; +import lombok.RequiredArgsConstructor; + +@PersistenceAdapter +@RequiredArgsConstructor +public class EquippedInventoryByCategoryGetAdapter implements LoadEquippedInventoryByCategoryPort { + + private final InventoryRepository inventoryRepository; + private final UserRepository userRepository; + private final InventoryMapper inventoryMapper; + + @Override + public Inventory findEquippedInventoryByCategoryAndUser(Category category, Long userId) { + Users user = userRepository.findById(userId) + .orElseThrow(UserNotFoundException::new); + + InventoryJpaEntity equippedByCategoryInventory = inventoryRepository.findByCategoryAndUserAndIsEquipped(category, user); + return inventoryMapper.mapToInventory(equippedByCategoryInventory); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoriesByIsEquippedGetAdapter.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoriesByIsEquippedGetAdapter.java new file mode 100644 index 00000000..cdf93bcc --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoriesByIsEquippedGetAdapter.java @@ -0,0 +1,27 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.inventory.application.port.out.LoadInventoriesByIsEquippedPort; +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.user.domain.repository.UserRepository; +import com.space.server.domain.user.exception.UserNotFoundException; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@PersistenceAdapter +@RequiredArgsConstructor +public class InventoriesByIsEquippedGetAdapter implements LoadInventoriesByIsEquippedPort { + + private final InventoryRepository inventoryRepository; + private final InventoryMapper inventoryMapper; + private final UserRepository userRepository; + + @Override + public List loadInventoriesByIsEquippedPort(Long userId) { + return inventoryRepository.findByIsEquippedAndUser(userRepository.findById(userId) + .orElseThrow(UserNotFoundException::new)).stream() + .map(inventoryMapper::mapToInventory) + .toList(); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoriesGetAdapter.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoriesGetAdapter.java new file mode 100644 index 00000000..6f664714 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoriesGetAdapter.java @@ -0,0 +1,27 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.inventory.application.port.out.LoadInventoriesPort; +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.user.domain.repository.UserRepository; +import com.space.server.domain.user.exception.UserExistedException; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@PersistenceAdapter +@RequiredArgsConstructor +public class InventoriesGetAdapter implements LoadInventoriesPort { + + private final InventoryRepository inventoryRepository; + private final InventoryMapper inventoryMapper; + private final UserRepository userRepository; + + @Override + public List loadInventories(Long userId) { + return inventoryRepository.findByUser(userRepository.findById(userId) + .orElseThrow(UserExistedException::new)).stream() + .map(inventoryMapper::mapToInventory) + .toList(); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryGetAdapter.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryGetAdapter.java new file mode 100644 index 00000000..15ccad33 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryGetAdapter.java @@ -0,0 +1,21 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.inventory.application.port.out.LoadInventoryPort; +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.inventory.exception.InventoryNotFoundException; +import lombok.RequiredArgsConstructor; + +@PersistenceAdapter +@RequiredArgsConstructor +public class InventoryGetAdapter implements LoadInventoryPort { + + private final InventoryRepository inventoryRepository; + private final InventoryMapper inventoryMapper; + + @Override + public Inventory loadInventory(Long inventoryId) { + return inventoryMapper.mapToInventory(inventoryRepository.findById(inventoryId) + .orElseThrow(InventoryNotFoundException::new)); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryJpaEntity.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryJpaEntity.java new file mode 100644 index 00000000..39253666 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryJpaEntity.java @@ -0,0 +1,30 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.domain.item.adapter.out.persistence.ItemJpaEntity; +import com.space.server.domain.user.domain.Users; +import jakarta.persistence.*; +import lombok.*; + +@Builder +@Entity +@Table(name = "inventory") +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class InventoryJpaEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "user_id") + private Users user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "item_id") + private ItemJpaEntity item; + + @Column + private boolean isEquipped; +} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryMapper.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryMapper.java new file mode 100644 index 00000000..3df1f34f --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryMapper.java @@ -0,0 +1,31 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.item.adapter.out.persistence.ItemMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class InventoryMapper { + + private final ItemMapper itemMapper; + + public Inventory mapToInventory(InventoryJpaEntity inventory) { + return Inventory.builder() + .id(new Inventory.InventoryId(inventory.getId())) + .user(inventory.getUser()) + .item(itemMapper.mapToItem(inventory.getItem())) + .isEquipped(inventory.isEquipped()) + .build(); + } + + public InventoryJpaEntity mapToInventoryJpaEntity(Inventory inventory) { + return InventoryJpaEntity.builder() + .id(inventory.getId() == null ? null : inventory.getId().getValue()) + .user(inventory.getUser()) + .item(itemMapper.mapToItemJpaEntity(inventory.getItem())) + .isEquipped(inventory.isEquipped()) + .build(); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryRepository.java b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryRepository.java new file mode 100644 index 00000000..0aa592e1 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/adapter/out/persistence/InventoryRepository.java @@ -0,0 +1,21 @@ +package com.space.server.domain.inventory.adapter.out.persistence; + +import com.space.server.domain.item.adapter.out.persistence.ItemJpaEntity; +import com.space.server.domain.item.domain.value.Category; +import com.space.server.domain.user.domain.Users; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface InventoryRepository extends JpaRepository { + List findByUser(Users user); + Boolean existsByItemAndUser(ItemJpaEntity item, Users user); + @Query("SELECT i FROM InventoryJpaEntity i WHERE i.user = :user AND i.isEquipped = true") + List findByIsEquippedAndUser(@Param("user") Users user); + @Query("SELECT i FROM InventoryJpaEntity i WHERE i.user = :user AND i.item.category = :category AND i.isEquipped = true") + InventoryJpaEntity findByCategoryAndUserAndIsEquipped(@Param("category") Category category, @Param("user") Users user); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/in/EquipInventoryUseCase.java b/src/main/java/com/space/server/domain/inventory/application/port/in/EquipInventoryUseCase.java new file mode 100644 index 00000000..025144d1 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/in/EquipInventoryUseCase.java @@ -0,0 +1,6 @@ +package com.space.server.domain.inventory.application.port.in; + +public interface EquipInventoryUseCase { + + void equipInventory(Long InventoryId, Long userId); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/in/GetInventoriesByIsEquippedQuery.java b/src/main/java/com/space/server/domain/inventory/application/port/in/GetInventoriesByIsEquippedQuery.java new file mode 100644 index 00000000..35de6675 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/in/GetInventoriesByIsEquippedQuery.java @@ -0,0 +1,10 @@ +package com.space.server.domain.inventory.application.port.in; + +import com.space.server.domain.inventory.domain.Inventory; + +import java.util.List; + +public interface GetInventoriesByIsEquippedQuery { + + List getInventoriesByIsEquippedQuery(Long userId); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/in/GetInventoriesQuery.java b/src/main/java/com/space/server/domain/inventory/application/port/in/GetInventoriesQuery.java new file mode 100644 index 00000000..a5ecd1b2 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/in/GetInventoriesQuery.java @@ -0,0 +1,10 @@ +package com.space.server.domain.inventory.application.port.in; + +import com.space.server.domain.inventory.domain.Inventory; + +import java.util.List; + +public interface GetInventoriesQuery { + + List getInventories(Long userId); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/out/CheckHaveItemPort.java b/src/main/java/com/space/server/domain/inventory/application/port/out/CheckHaveItemPort.java new file mode 100644 index 00000000..2678c8c9 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/out/CheckHaveItemPort.java @@ -0,0 +1,9 @@ +package com.space.server.domain.inventory.application.port.out; + +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.user.domain.Users; + +public interface CheckHaveItemPort { + + Boolean checkHaveItem(Item item, Users user); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/out/CreateInventoryPort.java b/src/main/java/com/space/server/domain/inventory/application/port/out/CreateInventoryPort.java new file mode 100644 index 00000000..7d71a1eb --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/out/CreateInventoryPort.java @@ -0,0 +1,10 @@ +package com.space.server.domain.inventory.application.port.out; + +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.user.domain.Users; + +public interface CreateInventoryPort { + + Inventory create(Item item, Users user); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/out/EquipInventoryPort.java b/src/main/java/com/space/server/domain/inventory/application/port/out/EquipInventoryPort.java new file mode 100644 index 00000000..d020c941 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/out/EquipInventoryPort.java @@ -0,0 +1,10 @@ +package com.space.server.domain.inventory.application.port.out; + +import com.space.server.domain.inventory.domain.Inventory; + +public interface EquipInventoryPort { + + void equipInventory(Inventory inventory); + + void unEquipInventory(Inventory inventory); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/out/LoadEquippedInventoryByCategoryPort.java b/src/main/java/com/space/server/domain/inventory/application/port/out/LoadEquippedInventoryByCategoryPort.java new file mode 100644 index 00000000..46be8589 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/out/LoadEquippedInventoryByCategoryPort.java @@ -0,0 +1,9 @@ +package com.space.server.domain.inventory.application.port.out; + +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.item.domain.value.Category; + +public interface LoadEquippedInventoryByCategoryPort { + + Inventory findEquippedInventoryByCategoryAndUser(Category category, Long userId); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/out/LoadInventoriesByIsEquippedPort.java b/src/main/java/com/space/server/domain/inventory/application/port/out/LoadInventoriesByIsEquippedPort.java new file mode 100644 index 00000000..4502bb7b --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/out/LoadInventoriesByIsEquippedPort.java @@ -0,0 +1,10 @@ +package com.space.server.domain.inventory.application.port.out; + +import com.space.server.domain.inventory.domain.Inventory; + +import java.util.List; + +public interface LoadInventoriesByIsEquippedPort { + + List loadInventoriesByIsEquippedPort(Long userId); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/out/LoadInventoriesPort.java b/src/main/java/com/space/server/domain/inventory/application/port/out/LoadInventoriesPort.java new file mode 100644 index 00000000..e97d2894 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/out/LoadInventoriesPort.java @@ -0,0 +1,10 @@ +package com.space.server.domain.inventory.application.port.out; + +import com.space.server.domain.inventory.domain.Inventory; + +import java.util.List; + +public interface LoadInventoriesPort { + + List loadInventories(Long userid); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/port/out/LoadInventoryPort.java b/src/main/java/com/space/server/domain/inventory/application/port/out/LoadInventoryPort.java new file mode 100644 index 00000000..c4058937 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/port/out/LoadInventoryPort.java @@ -0,0 +1,8 @@ +package com.space.server.domain.inventory.application.port.out; + +import com.space.server.domain.inventory.domain.Inventory; + +public interface LoadInventoryPort { + + Inventory loadInventory(Long inventoryId); +} diff --git a/src/main/java/com/space/server/domain/inventory/application/service/EquipInventoryService.java b/src/main/java/com/space/server/domain/inventory/application/service/EquipInventoryService.java new file mode 100644 index 00000000..1c3e5b11 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/service/EquipInventoryService.java @@ -0,0 +1,34 @@ +package com.space.server.domain.inventory.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.inventory.application.port.in.EquipInventoryUseCase; +import com.space.server.domain.inventory.application.port.out.EquipInventoryPort; +import com.space.server.domain.inventory.application.port.out.LoadEquippedInventoryByCategoryPort; +import com.space.server.domain.inventory.application.port.out.LoadInventoryPort; +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.inventory.exception.InventoryNotFoundException; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class EquipInventoryService implements EquipInventoryUseCase { + + private final LoadEquippedInventoryByCategoryPort loadEquippedInventoryByCategoryPort; + private final LoadInventoryPort loadInventoryPort; + private final EquipInventoryPort equipInventoryPort; + + @Override + public void equipInventory(Long inventoryId, Long userId) { + Inventory inventory = loadInventoryPort.loadInventory(inventoryId); + + if(!inventory.getUser().getId().equals(userId)) throw new InventoryNotFoundException(); + + Inventory equippedInventory = loadEquippedInventoryByCategoryPort.findEquippedInventoryByCategoryAndUser( + inventory.getItem().getCategory(), + userId + ); + + equipInventoryPort.unEquipInventory(equippedInventory); + equipInventoryPort.equipInventory(inventory); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/application/service/GetInventoriesByIsEquippedService.java b/src/main/java/com/space/server/domain/inventory/application/service/GetInventoriesByIsEquippedService.java new file mode 100644 index 00000000..519abacb --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/service/GetInventoriesByIsEquippedService.java @@ -0,0 +1,21 @@ +package com.space.server.domain.inventory.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.inventory.application.port.in.GetInventoriesByIsEquippedQuery; +import com.space.server.domain.inventory.application.port.out.LoadInventoriesByIsEquippedPort; +import com.space.server.domain.inventory.domain.Inventory; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@UseCase +@RequiredArgsConstructor +public class GetInventoriesByIsEquippedService implements GetInventoriesByIsEquippedQuery { + + private final LoadInventoriesByIsEquippedPort loadInventoriesByIsEquippedPort; + + @Override + public List getInventoriesByIsEquippedQuery(Long userId) { + return loadInventoriesByIsEquippedPort.loadInventoriesByIsEquippedPort(userId); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/application/service/GetInventoriesService.java b/src/main/java/com/space/server/domain/inventory/application/service/GetInventoriesService.java new file mode 100644 index 00000000..ce228f11 --- /dev/null +++ b/src/main/java/com/space/server/domain/inventory/application/service/GetInventoriesService.java @@ -0,0 +1,21 @@ +package com.space.server.domain.inventory.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.inventory.application.port.in.GetInventoriesQuery; +import com.space.server.domain.inventory.application.port.out.LoadInventoriesPort; +import com.space.server.domain.inventory.domain.Inventory; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@UseCase +@RequiredArgsConstructor +public class GetInventoriesService implements GetInventoriesQuery { + + private final LoadInventoriesPort loadInventoriesPort; + + @Override + public List getInventories(Long userId) { + return loadInventoriesPort.loadInventories(userId); + } +} diff --git a/src/main/java/com/space/server/domain/inventory/domain/Inventory.java b/src/main/java/com/space/server/domain/inventory/domain/Inventory.java index cdb15601..628ed49c 100644 --- a/src/main/java/com/space/server/domain/inventory/domain/Inventory.java +++ b/src/main/java/com/space/server/domain/inventory/domain/Inventory.java @@ -2,44 +2,26 @@ import com.space.server.domain.item.domain.Item; import com.space.server.domain.user.domain.Users; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; import lombok.*; @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -@Schema(description = "인벤토리 Entity") +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) public class Inventory { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Schema(description = "인벤토리 ID") - private Long id; + @NotNull + private final InventoryId id; - @ManyToOne - @JoinColumn(name = "user_id") @NotNull - @Schema(description = "사용자 정보") - private Users user; + private final Users user; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "item_id") @NotNull - @Schema(description = "아이템 정보") - private Item item; + private final Item item; - @Schema(description = "아이템 장착 여부", example = "false") + @NotNull private boolean isEquipped; - - @Builder - public Inventory(Item item, Users user) { - this.item = item; - this.user = user; - } - public void equip() { isEquipped = true; } @@ -47,4 +29,9 @@ public void equip() { public void unEquip() { isEquipped = false; } + + @Value + public static class InventoryId { + private final Long value; + } } diff --git a/src/main/java/com/space/server/domain/inventory/domain/repository/InventoryRepository.java b/src/main/java/com/space/server/domain/inventory/domain/repository/InventoryRepository.java deleted file mode 100644 index 5de6a2fd..00000000 --- a/src/main/java/com/space/server/domain/inventory/domain/repository/InventoryRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.space.server.domain.inventory.domain.repository; - -import com.space.server.domain.inventory.domain.Inventory; -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.domain.value.Category; -import com.space.server.domain.user.domain.Users; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface InventoryRepository extends JpaRepository { - List findByUser(Users user); - Boolean existsByItemAndUser(Item item, Users user); - @Query("SELECT i FROM Inventory i WHERE i.user = :user AND i.isEquipped = true") - List findByIsEquippedAndUser(@Param("user") Users user); - @Query("SELECT i FROM Inventory i WHERE i.user = :user AND i.item.category = :category AND i.isEquipped = true") - Inventory findByCategoryAndUserAndIsEquipped(@Param("category") Category category, @Param("user") Users user); -} diff --git a/src/main/java/com/space/server/domain/inventory/presentation/InventoryController.java b/src/main/java/com/space/server/domain/inventory/presentation/InventoryController.java deleted file mode 100644 index 7e11475a..00000000 --- a/src/main/java/com/space/server/domain/inventory/presentation/InventoryController.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.space.server.domain.inventory.presentation; - -import com.space.server.domain.inventory.presentation.dto.response.InventoryResponse; -import com.space.server.domain.inventory.service.CommandInventoryService; -import com.space.server.domain.inventory.service.QueryInventoryService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import jakarta.servlet.http.HttpServletRequest; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -import static com.space.server.common.jwt.util.AuthenticationUtil.getMemberId; - -@Slf4j -@RestController -@RequiredArgsConstructor -@RequestMapping("/inventories") -@Tag(name = "Inventory", description = "인벤토리 API") -public class InventoryController { - - private final CommandInventoryService commandInventoryService; - private final QueryInventoryService queryInventoryService; - - @GetMapping - @Operation(summary = "전체 인벤토리 조회", description = "전체 구매한 아이템을 조회합니다.") - public List readAll(HttpServletRequest request) { - log.warn("인벤토리 조회 로그(MemberId) : " + getMemberId()); - log.warn("인벤토리 조회 로그(HttpServletRequest,cookie) : " + request.getCookies()); - log.warn("인벤토리 조회 로그(HttpServletRequest,cookie) : " + request.getRequestURI()); - log.warn("인벤토리 조회 로그(HttpServletRequest,cookie) : " + request.getUserPrincipal()); - log.warn("인벤토리 조회 로그(HttpServletRequest,cookie) : " + request.getMethod()); - log.warn("인벤토리 조회 로그(HttpServletRequest,cookie) : " + request.getServletPath()); - return queryInventoryService.readMine(getMemberId()).stream() - .map(InventoryResponse::from) - .toList(); - } - - @GetMapping("/equip") - @Operation(summary = "장착 인벤토리 조회", description = "장착된 아이템을 조회합니다.") - public List readIsEquipped() { - return queryInventoryService.readIsEquipped(getMemberId()).stream() - .map(InventoryResponse::from) - .toList(); - } - - @PutMapping("/{inventory-id}") - @Operation(summary = "아이템 장착", description = "해당 구매한 아이템을 장착합니다.") - public void equipItem( - @Parameter(description = "장착할 인벤토리 ID", required = true) @PathVariable(name = "inventory-id") Long inventoryId) { - commandInventoryService.equipInventory(inventoryId, getMemberId()); - } -} diff --git a/src/main/java/com/space/server/domain/inventory/service/CommandInventoryService.java b/src/main/java/com/space/server/domain/inventory/service/CommandInventoryService.java deleted file mode 100644 index 393b2393..00000000 --- a/src/main/java/com/space/server/domain/inventory/service/CommandInventoryService.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.space.server.domain.inventory.service; - -import com.space.server.domain.inventory.domain.Inventory; -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.domain.value.Category; -import com.space.server.domain.item.service.implementation.ItemReader; -import com.space.server.domain.inventory.service.implementation.*; -import com.space.server.domain.user.domain.Users; -import com.space.server.domain.user.domain.repository.UserRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -@Transactional -public class CommandInventoryService { - - private final InventoryCreator inventoryCreator; - private final InventoryReader inventoryReader; - private final InventoryUpdater inventoryUpdater; - private final InventoryDeleter inventoryDeleter; - private final InventoryValidator inventoryValidator; - private final ItemReader itemReader; - private final UserRepository userRepository; - - public void createInventory(Long itemId, Long userId) { - Users user = userRepository.findById(userId) - .orElse(null); - Item item = itemReader.findById(itemId); - Inventory inventory = new Inventory(item, user); - inventoryUpdater.equip(inventory); - inventoryCreator.create(inventory); - } - - public void buyItem(Long itemId, Long userId) { - Users user = userRepository.findById(userId) - .orElse(null); - Item item = itemReader.findById(itemId); - inventoryValidator.hasItem(item, user); - inventoryValidator.buyItem(item, user); - Inventory inventory = new Inventory(item, user); - inventoryCreator.create(inventory); - } - - public void equipInventory(Long inventoryId, Long userId) { - Users user = userRepository.findById(userId) - .orElse(null); - Inventory inventory = inventoryReader.findById(inventoryId); - Category category = inventory.getItem().getCategory(); - Inventory unequipInventory = inventoryReader.findByCategoryAndUserAndIsEquipped(category, user); - inventoryUpdater.unEquip(unequipInventory); - inventoryUpdater.equip(inventory); - } - - public void deleteInventory(Long inventoryId) { - Inventory inventory = inventoryReader.findById(inventoryId); - inventoryDeleter.delete(inventory); - } -} diff --git a/src/main/java/com/space/server/domain/inventory/service/QueryInventoryService.java b/src/main/java/com/space/server/domain/inventory/service/QueryInventoryService.java deleted file mode 100644 index cc42f8ae..00000000 --- a/src/main/java/com/space/server/domain/inventory/service/QueryInventoryService.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.space.server.domain.inventory.service; - -import com.space.server.domain.inventory.domain.Inventory; -import com.space.server.domain.inventory.service.implementation.InventoryReader; -import com.space.server.domain.user.domain.Users; -import com.space.server.domain.user.domain.repository.UserRepository; -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 QueryInventoryService { - - private final InventoryReader inventoryReader; - private final UserRepository userRepository; - - public Inventory readOne(Long inventoryId) { - return inventoryReader.findById(inventoryId); - } - - public List readMine(Long userId) { - Users user = userRepository.findById(userId) - .orElse(null); - return inventoryReader.findByUser(user); - } - - public List readIsEquipped(Long userId) { - Users user = userRepository.findById(userId) - .orElse(null); - return inventoryReader.findByIsEquippedAndUser(user); - } -} diff --git a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryCreator.java b/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryCreator.java deleted file mode 100644 index 4d8b3489..00000000 --- a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryCreator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.inventory.service.implementation; - -import com.space.server.domain.inventory.domain.Inventory; -import com.space.server.domain.inventory.domain.repository.InventoryRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class InventoryCreator { - - private final InventoryRepository inventoryRepository; - - public void create(Inventory inventory) { - inventoryRepository.save(inventory); - } -} diff --git a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryDeleter.java b/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryDeleter.java deleted file mode 100644 index 8539050a..00000000 --- a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryDeleter.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.inventory.service.implementation; - -import com.space.server.domain.inventory.domain.Inventory; -import com.space.server.domain.inventory.domain.repository.InventoryRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class InventoryDeleter { - - private final InventoryRepository inventoryRepository; - - public void delete(Inventory inventory) { - inventoryRepository.delete(inventory); - } -} diff --git a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryReader.java b/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryReader.java deleted file mode 100644 index 3339b25e..00000000 --- a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryReader.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.space.server.domain.inventory.service.implementation; - -import com.space.server.domain.inventory.domain.Inventory; -import com.space.server.domain.inventory.domain.repository.InventoryRepository; -import com.space.server.domain.inventory.exception.InventoryNotFoundException; -import com.space.server.domain.item.domain.value.Category; -import com.space.server.domain.user.domain.Users; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -@RequiredArgsConstructor -public class InventoryReader { - - private final InventoryRepository inventoryRepository; - - public Inventory findById(Long inventoryId) { - return inventoryRepository.findById(inventoryId) - .orElseThrow(InventoryNotFoundException::new); - } - - public List findByUser(Users user) { - return inventoryRepository.findByUser(user); - } - - public List findByIsEquippedAndUser(Users user) { - return inventoryRepository.findByIsEquippedAndUser(user); - } - - public Inventory findByCategoryAndUserAndIsEquipped(Category category, Users user) { - return inventoryRepository.findByCategoryAndUserAndIsEquipped(category, user); - } -} diff --git a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryUpdater.java b/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryUpdater.java deleted file mode 100644 index 10f19229..00000000 --- a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryUpdater.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.space.server.domain.inventory.service.implementation; - -import com.space.server.domain.inventory.domain.Inventory; -import org.springframework.stereotype.Service; - -@Service -public class InventoryUpdater { - - public void equip(Inventory inventory) { - inventory.equip(); - } - - public void unEquip(Inventory inventory) { - inventory.unEquip(); - } -} diff --git a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryValidator.java b/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryValidator.java deleted file mode 100644 index 463ca773..00000000 --- a/src/main/java/com/space/server/domain/inventory/service/implementation/InventoryValidator.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.space.server.domain.inventory.service.implementation; - -import com.space.server.domain.inventory.domain.repository.InventoryRepository; -import com.space.server.domain.inventory.exception.InventoryItemExistedException; -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.user.domain.Users; -import com.space.server.domain.user.exception.InsufficientPointsException; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class InventoryValidator { - private final InventoryRepository inventoryRepository; - - public void hasItem(Item item, Users user) { - if(inventoryRepository.existsByItemAndUser(item, user)) { - throw new InventoryItemExistedException(); - } - } - - public void buyItem(Item item, Users user) { - if(item.getPrice() > user.getPoint()) { - throw new InsufficientPointsException(); - } - else user.payPoint(item.getPrice()); - } -} diff --git a/src/main/java/com/space/server/domain/item/adapter/in/web/ItemController.java b/src/main/java/com/space/server/domain/item/adapter/in/web/ItemController.java new file mode 100644 index 00000000..2b6dde3c --- /dev/null +++ b/src/main/java/com/space/server/domain/item/adapter/in/web/ItemController.java @@ -0,0 +1,60 @@ +package com.space.server.domain.item.adapter.in.web; + +import com.space.server.domain.item.adapter.in.web.converter.CategoryConverter; +import com.space.server.domain.item.adapter.in.web.dto.response.ItemResponse; +import com.space.server.domain.item.application.port.in.BuyItemUseCase; +import com.space.server.domain.item.application.port.in.GetItemQuery; +import com.space.server.common.annotation.WebAdapter; +import com.space.server.domain.item.application.port.in.GetItemsByCategoryQuery; +import com.space.server.domain.item.application.port.in.GetItemsQuery; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static com.space.server.common.jwt.util.AuthenticationUtil.getMemberId; + +@WebAdapter +@RestController +@RequiredArgsConstructor +@RequestMapping("/stores/items") +@Tag(name = "Item", description = "아이템 API") +public class ItemController { + + private final GetItemQuery getItemQuery; + private final GetItemsQuery getItemsQuery; + private final GetItemsByCategoryQuery getItemsByCategoryQuery; + private final BuyItemUseCase buyItemUseCase; + private final CategoryConverter converter; + + @PostMapping("/{item-id}") + @Operation(summary = "해당 아이템 구매", description = "해당 아이템을 구매합니다.") + public void buyItem(@PathVariable("item-id") @Parameter(description = "아이템 ID") Long itemId) { + buyItemUseCase.buyItem(itemId, getMemberId()); + } + + @GetMapping("/{item-id}") + @Operation(summary = "해당 아이템 조회", description = "해당 아이템을 조회합니다.") + public ItemResponse readOne(@PathVariable("item-id") @Parameter(description = "아이템 ID") Long itemId) { + return ItemResponse.from(getItemQuery.getItem(itemId)); + } + + @GetMapping() + @Operation(summary = "전체 아이템 조회", description = "전체 아이템을 조회합니다.") + public List readAll() { + return getItemsQuery.getItems().stream() + .map(ItemResponse::from) + .toList(); + } + + @GetMapping("/categories/{category}") + @Operation(summary = "카테고리별 아이템 전체 조회", description = "해당 카테고리의 아이템들을 조회합니다.") + public List readAllByCategory(@PathVariable("category") @Parameter(description = "아이템 카테고리") String category) { + return getItemsByCategoryQuery.getItemsByCategory(converter.convert(category)).stream() + .map((ItemResponse::from)) + .toList(); + } +} diff --git a/src/main/java/com/space/server/domain/item/presentation/converter/CategoryConverter.java b/src/main/java/com/space/server/domain/item/adapter/in/web/converter/CategoryConverter.java similarity index 80% rename from src/main/java/com/space/server/domain/item/presentation/converter/CategoryConverter.java rename to src/main/java/com/space/server/domain/item/adapter/in/web/converter/CategoryConverter.java index 3653cab8..8cf088d8 100644 --- a/src/main/java/com/space/server/domain/item/presentation/converter/CategoryConverter.java +++ b/src/main/java/com/space/server/domain/item/adapter/in/web/converter/CategoryConverter.java @@ -1,4 +1,4 @@ -package com.space.server.domain.item.presentation.converter; +package com.space.server.domain.item.adapter.in.web.converter; import com.space.server.domain.item.domain.value.Category; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/space/server/domain/item/adapter/in/web/dto/response/ItemResponse.java b/src/main/java/com/space/server/domain/item/adapter/in/web/dto/response/ItemResponse.java new file mode 100644 index 00000000..f84a7231 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/adapter/in/web/dto/response/ItemResponse.java @@ -0,0 +1,22 @@ +package com.space.server.domain.item.adapter.in.web.dto.response; + +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.item.domain.value.Category; +import lombok.Builder; + +@Builder +public record ItemResponse( + String name, + Integer price, + String image, + Category category +) { + public static ItemResponse from(Item item) { + return ItemResponse.builder() + .name(item.getName()) + .price(item.getPrice()) + .image(item.getImage()) + .category(item.getCategory()) + .build(); + } +} diff --git a/src/main/java/com/space/server/domain/item/adapter/out/persistence/BuyItemAdapter.java b/src/main/java/com/space/server/domain/item/adapter/out/persistence/BuyItemAdapter.java new file mode 100644 index 00000000..bf148164 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/adapter/out/persistence/BuyItemAdapter.java @@ -0,0 +1,28 @@ +package com.space.server.domain.item.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.inventory.adapter.out.persistence.InventoryJpaEntity; +import com.space.server.domain.inventory.adapter.out.persistence.InventoryMapper; +import com.space.server.domain.inventory.adapter.out.persistence.InventoryRepository; +import com.space.server.domain.inventory.application.port.out.CreateInventoryPort; +import com.space.server.domain.inventory.domain.Inventory; +import com.space.server.domain.item.application.port.out.BuyItemPort; +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.user.domain.Users; +import lombok.RequiredArgsConstructor; + +@PersistenceAdapter +@RequiredArgsConstructor +public class BuyItemAdapter implements BuyItemPort { + + private final InventoryRepository inventoryRepository; + private final InventoryMapper inventoryMapper; + private final CreateInventoryPort createInventoryPort; + + @Override + public void buyItemPort(Item item, Users user) { + Inventory inventory = createInventoryPort.create(item, user); + InventoryJpaEntity itemJpaEntity = inventoryMapper.mapToInventoryJpaEntity(inventory); + inventoryRepository.save(itemJpaEntity); + } +} diff --git a/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemByCategoryGetAdapter.java b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemByCategoryGetAdapter.java new file mode 100644 index 00000000..859b30b0 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemByCategoryGetAdapter.java @@ -0,0 +1,25 @@ +package com.space.server.domain.item.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.item.application.port.out.LoadItemsByCategoryPort; +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.item.domain.value.Category; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@PersistenceAdapter +@RequiredArgsConstructor +public class ItemByCategoryGetAdapter implements LoadItemsByCategoryPort { + + private final ItemRepository itemRepository; + private final ItemMapper itemMapper; + + @Override + public List loadItemsByCategory(Category category) { + return itemRepository.findByCategory(category) + .stream() + .map(itemMapper::mapToItem) + .toList(); + } +} diff --git a/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemGetAdapter.java b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemGetAdapter.java new file mode 100644 index 00000000..a87aeaea --- /dev/null +++ b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemGetAdapter.java @@ -0,0 +1,22 @@ +package com.space.server.domain.item.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.item.application.port.out.LoadItemPort; +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.item.exception.ItemNotFoundException; +import lombok.RequiredArgsConstructor; + +@PersistenceAdapter +@RequiredArgsConstructor +public class ItemGetAdapter implements LoadItemPort { + + private final ItemRepository itemRepository; + private final ItemMapper itemMapper; + + @Override + public Item loadItem(Long itemId) { + return itemRepository.findById(itemId) + .map(itemMapper::mapToItem) + .orElseThrow(ItemNotFoundException::new); + } +} diff --git a/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemJpaEntity.java b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemJpaEntity.java new file mode 100644 index 00000000..d9095563 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemJpaEntity.java @@ -0,0 +1,34 @@ +package com.space.server.domain.item.adapter.out.persistence; + +import com.space.server.domain.item.domain.value.Category; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Builder +@Entity +@Table(name = "item") +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class ItemJpaEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column + private String name; + + @Column + private Integer price; + + @Column + private String image; + + @Enumerated(EnumType.STRING) + @Column + private Category category; +} diff --git a/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemMapper.java b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemMapper.java new file mode 100644 index 00000000..ed1d614e --- /dev/null +++ b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemMapper.java @@ -0,0 +1,28 @@ +package com.space.server.domain.item.adapter.out.persistence; + +import com.space.server.domain.item.domain.Item; +import org.springframework.stereotype.Component; + +@Component +public class ItemMapper { + + public Item mapToItem(ItemJpaEntity item) { + return Item.builder() + .id(new Item.ItemId(item.getId())) + .name(item.getName()) + .price(item.getPrice()) + .image(item.getImage()) + .category(item.getCategory()) + .build(); + } + + public ItemJpaEntity mapToItemJpaEntity(Item item) { + return ItemJpaEntity.builder() + .id(item.getId().getValue()) + .name(item.getName()) + .price(item.getPrice()) + .image(item.getImage()) + .category(item.getCategory()) + .build(); + } +} diff --git a/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemRepository.java b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemRepository.java new file mode 100644 index 00000000..ebf6686b --- /dev/null +++ b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemRepository.java @@ -0,0 +1,10 @@ +package com.space.server.domain.item.adapter.out.persistence; + +import com.space.server.domain.item.domain.value.Category; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ItemRepository extends JpaRepository { + List findByCategory(Category category); +} diff --git a/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemsGetAdapter.java b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemsGetAdapter.java new file mode 100644 index 00000000..d80976d2 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/adapter/out/persistence/ItemsGetAdapter.java @@ -0,0 +1,23 @@ +package com.space.server.domain.item.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.item.application.port.out.LoadItemsPort; +import com.space.server.domain.item.domain.Item; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@PersistenceAdapter +@RequiredArgsConstructor +public class ItemsGetAdapter implements LoadItemsPort { + + private final ItemRepository itemRepository; + private final ItemMapper itemMapper; + + @Override + public List loadItems() { + return itemRepository.findAll().stream() + .map(itemMapper::mapToItem) + .toList(); + } +} diff --git a/src/main/java/com/space/server/domain/item/application/port/in/BuyItemUseCase.java b/src/main/java/com/space/server/domain/item/application/port/in/BuyItemUseCase.java new file mode 100644 index 00000000..e91b6b1c --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/port/in/BuyItemUseCase.java @@ -0,0 +1,7 @@ +package com.space.server.domain.item.application.port.in; + +public interface BuyItemUseCase { + + void buyItem(Long itemId, Long userId); +} + diff --git a/src/main/java/com/space/server/domain/item/application/port/in/GetItemQuery.java b/src/main/java/com/space/server/domain/item/application/port/in/GetItemQuery.java new file mode 100644 index 00000000..02350c44 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/port/in/GetItemQuery.java @@ -0,0 +1,8 @@ +package com.space.server.domain.item.application.port.in; + +import com.space.server.domain.item.domain.Item; + +public interface GetItemQuery { + + Item getItem(Long id); +} diff --git a/src/main/java/com/space/server/domain/item/application/port/in/GetItemsByCategoryQuery.java b/src/main/java/com/space/server/domain/item/application/port/in/GetItemsByCategoryQuery.java new file mode 100644 index 00000000..8d9647b1 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/port/in/GetItemsByCategoryQuery.java @@ -0,0 +1,11 @@ +package com.space.server.domain.item.application.port.in; + +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.item.domain.value.Category; + +import java.util.List; + +public interface GetItemsByCategoryQuery { + + List getItemsByCategory(Category category); +} diff --git a/src/main/java/com/space/server/domain/item/application/port/in/GetItemsQuery.java b/src/main/java/com/space/server/domain/item/application/port/in/GetItemsQuery.java new file mode 100644 index 00000000..92665c41 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/port/in/GetItemsQuery.java @@ -0,0 +1,10 @@ +package com.space.server.domain.item.application.port.in; + +import com.space.server.domain.item.domain.Item; + +import java.util.List; + +public interface GetItemsQuery { + + List getItems(); +} diff --git a/src/main/java/com/space/server/domain/item/application/port/out/BuyItemPort.java b/src/main/java/com/space/server/domain/item/application/port/out/BuyItemPort.java new file mode 100644 index 00000000..ab979367 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/port/out/BuyItemPort.java @@ -0,0 +1,10 @@ + +package com.space.server.domain.item.application.port.out; + +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.user.domain.Users; + +public interface BuyItemPort { + + void buyItemPort(Item item, Users user); +} diff --git a/src/main/java/com/space/server/domain/item/application/port/out/LoadItemPort.java b/src/main/java/com/space/server/domain/item/application/port/out/LoadItemPort.java new file mode 100644 index 00000000..2ae1a9f4 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/port/out/LoadItemPort.java @@ -0,0 +1,8 @@ +package com.space.server.domain.item.application.port.out; + +import com.space.server.domain.item.domain.Item; + +public interface LoadItemPort { + + Item loadItem(Long id); +} diff --git a/src/main/java/com/space/server/domain/item/application/port/out/LoadItemsByCategoryPort.java b/src/main/java/com/space/server/domain/item/application/port/out/LoadItemsByCategoryPort.java new file mode 100644 index 00000000..4da0a656 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/port/out/LoadItemsByCategoryPort.java @@ -0,0 +1,11 @@ +package com.space.server.domain.item.application.port.out; + +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.item.domain.value.Category; + +import java.util.List; + +public interface LoadItemsByCategoryPort { + + List loadItemsByCategory(Category category); +} diff --git a/src/main/java/com/space/server/domain/item/application/port/out/LoadItemsPort.java b/src/main/java/com/space/server/domain/item/application/port/out/LoadItemsPort.java new file mode 100644 index 00000000..278b206e --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/port/out/LoadItemsPort.java @@ -0,0 +1,10 @@ +package com.space.server.domain.item.application.port.out; + +import com.space.server.domain.item.domain.Item; + +import java.util.List; + +public interface LoadItemsPort { + + List loadItems(); +} diff --git a/src/main/java/com/space/server/domain/item/application/service/BuyItemService.java b/src/main/java/com/space/server/domain/item/application/service/BuyItemService.java new file mode 100644 index 00000000..ba201d30 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/service/BuyItemService.java @@ -0,0 +1,34 @@ +package com.space.server.domain.item.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.inventory.application.port.out.CheckHaveItemPort; +import com.space.server.domain.inventory.exception.InventoryItemExistedException; +import com.space.server.domain.item.application.port.in.BuyItemUseCase; +import com.space.server.domain.item.application.port.out.BuyItemPort; +import com.space.server.domain.item.application.port.out.LoadItemPort; +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.user.domain.Users; +import com.space.server.domain.user.domain.repository.UserRepository; +import com.space.server.domain.user.exception.UserNotFoundException; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class BuyItemService implements BuyItemUseCase { + + private final BuyItemPort buyItemPort; + private final LoadItemPort loadItemPort; + private final CheckHaveItemPort checkHaveItemPort; + private final UserRepository userRepository; + + @Override + public void buyItem(Long itemId, Long userId) { + Item item = loadItemPort.loadItem(itemId); + Users user = userRepository.findById(userId) + .orElseThrow(UserNotFoundException::new); + + if(checkHaveItemPort.checkHaveItem(item, user)) throw new InventoryItemExistedException(); + + buyItemPort.buyItemPort(item, user); + } +} diff --git a/src/main/java/com/space/server/domain/item/application/service/GetItemService.java b/src/main/java/com/space/server/domain/item/application/service/GetItemService.java new file mode 100644 index 00000000..9bf2f32f --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/service/GetItemService.java @@ -0,0 +1,19 @@ +package com.space.server.domain.item.application.service; + +import com.space.server.domain.item.application.port.in.GetItemQuery; +import com.space.server.domain.item.application.port.out.LoadItemPort; +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.item.domain.Item; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class GetItemService implements GetItemQuery { + + private final LoadItemPort loadItemPort; + + @Override + public Item getItem(Long id) { + return loadItemPort.loadItem(id); + } +} diff --git a/src/main/java/com/space/server/domain/item/application/service/GetItemsByCategoryService.java b/src/main/java/com/space/server/domain/item/application/service/GetItemsByCategoryService.java new file mode 100644 index 00000000..c8f5ae34 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/service/GetItemsByCategoryService.java @@ -0,0 +1,22 @@ +package com.space.server.domain.item.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.item.application.port.in.GetItemsByCategoryQuery; +import com.space.server.domain.item.application.port.out.LoadItemsByCategoryPort; +import com.space.server.domain.item.domain.Item; +import com.space.server.domain.item.domain.value.Category; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@UseCase +@RequiredArgsConstructor +public class GetItemsByCategoryService implements GetItemsByCategoryQuery { + + private final LoadItemsByCategoryPort loadItemsByCategoryPort; + + @Override + public List getItemsByCategory(Category category) { + return loadItemsByCategoryPort.loadItemsByCategory(category); + } +} diff --git a/src/main/java/com/space/server/domain/item/application/service/GetItemsService.java b/src/main/java/com/space/server/domain/item/application/service/GetItemsService.java new file mode 100644 index 00000000..a97b3fc7 --- /dev/null +++ b/src/main/java/com/space/server/domain/item/application/service/GetItemsService.java @@ -0,0 +1,21 @@ +package com.space.server.domain.item.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.item.application.port.in.GetItemsQuery; +import com.space.server.domain.item.application.port.out.LoadItemsPort; +import com.space.server.domain.item.domain.Item; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@UseCase +@RequiredArgsConstructor +public class GetItemsService implements GetItemsQuery { + + private final LoadItemsPort loadItemsPort; + + @Override + public List getItems() { + return loadItemsPort.loadItems(); + } +} diff --git a/src/main/java/com/space/server/domain/item/domain/Item.java b/src/main/java/com/space/server/domain/item/domain/Item.java index a18ed52d..23141a3e 100644 --- a/src/main/java/com/space/server/domain/item/domain/Item.java +++ b/src/main/java/com/space/server/domain/item/domain/Item.java @@ -1,53 +1,38 @@ package com.space.server.domain.item.domain; import com.space.server.domain.item.domain.value.Category; -import io.swagger.v3.oas.annotations.media.Schema; import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; import lombok.*; +import java.util.Optional; + @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -@Schema(description = "아이템 Entity") +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) public class Item { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Schema(description = "아이템 ID") - private Long id; + private final ItemId id; - @Column(length = 10) @NotNull - @Schema(description = "아이템 이름") - private String name; + private final String name; @NotNull - @Schema(description = "아이템 가격") - private Integer price; + private final Integer price; - @Column(name = "item_image", length = 100) @NotNull - @Schema(description = "아이템 이미지 URL") - private String image; + private final String image; @Enumerated(EnumType.STRING) @NotNull - @Schema(description = "아이템 카테고리") - private Category category; - - @Builder - public Item(String name, int price, String image, Category category) { - this.name = name; - this.price = price; - this.image = image; - this.category = category; + private final Category category; + + public static Item create(ItemId id, String name, Integer price, String image, Category category) { + return new Item(id, name, price, image, category); } - public void update(Item item) { - this.name = item.getName(); - this.price = item.getPrice(); - this.image = item.getImage(); - this.category = item.getCategory(); + @Value + public static class ItemId { + private final Long value; } } diff --git a/src/main/java/com/space/server/domain/item/domain/repository/ItemRepository.java b/src/main/java/com/space/server/domain/item/domain/repository/ItemRepository.java deleted file mode 100644 index 7a7ceee2..00000000 --- a/src/main/java/com/space/server/domain/item/domain/repository/ItemRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.space.server.domain.item.domain.repository; - -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.domain.value.Category; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface ItemRepository extends JpaRepository { - List findByCategory(Category category); -} diff --git a/src/main/java/com/space/server/domain/item/presentation/ItemController.java b/src/main/java/com/space/server/domain/item/presentation/ItemController.java deleted file mode 100644 index f9720163..00000000 --- a/src/main/java/com/space/server/domain/item/presentation/ItemController.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.space.server.domain.item.presentation; - -import com.space.server.domain.inventory.service.CommandInventoryService; -import com.space.server.domain.item.presentation.converter.CategoryConverter; -import com.space.server.domain.item.presentation.dto.response.ItemResponse; -import com.space.server.domain.item.service.QueryItemService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -import static com.space.server.common.jwt.util.AuthenticationUtil.getMemberId; - -@RestController -@RequiredArgsConstructor -@RequestMapping("/stores/items") -@Tag(name = "Item", description = "아이템 API") -public class ItemController { - - private final QueryItemService queryItemService; - private final CommandInventoryService commandInventoryService; - private final CategoryConverter categoryConverter; - - @PostMapping("/{item-id}") - @Operation(summary = "아이템 구매", description = "해당 아이템을 구매합니다.") - public void buyItem(@PathVariable("item-id") @Parameter(description = "구매할 아이템 ID") Long itemId) { - commandInventoryService.buyItem(itemId, getMemberId()); - } - - @GetMapping("/{item-id}") - @Operation(summary = "아이템 조회", description = "해당 아이템을 조회합니다.") - public ItemResponse readOne(@PathVariable("item-id") @Parameter(description = "조회할 아이템 ID") Long itemId) { - return ItemResponse.from(queryItemService.readOne(itemId)); - } - - @GetMapping - @Operation(summary = "아이템 전체 조회", description = "전체 아이템을 조회합니다.") - public List readAll() { - return queryItemService.readAll().stream() - .map(ItemResponse::from) - .toList(); - } - - @GetMapping("/categories/{category}") - @Operation(summary = "카테고리별 아이템 조회", description = "카테고리별 아이템을 조회합니다.") - public List findByCategory(@PathVariable("category") @Parameter(description = "조회할 카테고리") String category) { - return queryItemService.findAllByCategory(categoryConverter.convert(category)).stream() - .map(ItemResponse::from) - .toList(); - } -} diff --git a/src/main/java/com/space/server/domain/item/presentation/dto/response/ItemResponse.java b/src/main/java/com/space/server/domain/item/presentation/dto/response/ItemResponse.java deleted file mode 100644 index 29b8e89e..00000000 --- a/src/main/java/com/space/server/domain/item/presentation/dto/response/ItemResponse.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.space.server.domain.item.presentation.dto.response; - -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.domain.value.Category; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Builder; - -@Builder -public record ItemResponse( - @Schema(description = "아이템 ID", example = "1") - Long id, - - @Schema(description = "아이템 이름", example = "모자") - String name, - - @Schema(description = "아이템 가격", example = "100") - Integer price, - - @Schema(description = "아이템 이미지 URL", example = "http://example.com/image.png") - String image, - - @Schema(description = "아이템 카테고리", example = "HEAD") - Category category -) { - public static ItemResponse from(Item item) { - return ItemResponse.builder() - .id(item.getId()) - .name(item.getName()) - .price(item.getPrice()) - .image(item.getImage()) - .category(item.getCategory()) - .build(); - } -} diff --git a/src/main/java/com/space/server/domain/item/service/CommandItemService.java b/src/main/java/com/space/server/domain/item/service/CommandItemService.java deleted file mode 100644 index e3a17329..00000000 --- a/src/main/java/com/space/server/domain/item/service/CommandItemService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.space.server.domain.item.service; - -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.service.implementation.ItemCreator; -import com.space.server.domain.item.service.implementation.ItemDeleter; -import com.space.server.domain.item.service.implementation.ItemReader; -import com.space.server.domain.item.service.implementation.ItemUpdater; -import org.springframework.transaction.annotation.Transactional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -@Transactional -public class CommandItemService { - - private final ItemCreator itemCreator; - private final ItemDeleter itemDeleter; - private final ItemUpdater itemUpdater; - private final ItemReader itemReader; - - public void createItem(Item item) { - itemCreator.create(item); - } - - public void updateItem(Long itemId, Item item) { - Item updatableItem = itemReader.findById(itemId); - itemUpdater.update(updatableItem, item); - } - - public void deleteItem(Long itemId) { - Item item = itemReader.findById(itemId); - itemDeleter.delete(item); - } -} diff --git a/src/main/java/com/space/server/domain/item/service/QueryItemService.java b/src/main/java/com/space/server/domain/item/service/QueryItemService.java deleted file mode 100644 index e7286bcc..00000000 --- a/src/main/java/com/space/server/domain/item/service/QueryItemService.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.space.server.domain.item.service; - -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.domain.value.Category; -import com.space.server.domain.item.service.implementation.ItemReader; -import org.springframework.transaction.annotation.Transactional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class QueryItemService { - - private final ItemReader itemReader; - - public List findAllByCategory(Category category) { - return itemReader.findAllByCategory(category); - } - - public List readAll() { - return itemReader.findAll(); - } - - public Item readOne(Long itemId) { - return itemReader.findById(itemId); - } -} diff --git a/src/main/java/com/space/server/domain/item/service/implementation/ItemCreator.java b/src/main/java/com/space/server/domain/item/service/implementation/ItemCreator.java deleted file mode 100644 index b562094e..00000000 --- a/src/main/java/com/space/server/domain/item/service/implementation/ItemCreator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.item.service.implementation; - -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.domain.repository.ItemRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class ItemCreator { - - private final ItemRepository itemRepository; - - public void create(Item item) { - itemRepository.save(item); - } -} diff --git a/src/main/java/com/space/server/domain/item/service/implementation/ItemDeleter.java b/src/main/java/com/space/server/domain/item/service/implementation/ItemDeleter.java deleted file mode 100644 index 575f6686..00000000 --- a/src/main/java/com/space/server/domain/item/service/implementation/ItemDeleter.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.item.service.implementation; - -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.domain.repository.ItemRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class ItemDeleter { - - private final ItemRepository itemRepository; - - public void delete(Item item) { - itemRepository.delete(item); - } -} \ No newline at end of file diff --git a/src/main/java/com/space/server/domain/item/service/implementation/ItemReader.java b/src/main/java/com/space/server/domain/item/service/implementation/ItemReader.java deleted file mode 100644 index 70f6a2e0..00000000 --- a/src/main/java/com/space/server/domain/item/service/implementation/ItemReader.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.space.server.domain.item.service.implementation; - -import com.space.server.domain.item.domain.Item; -import com.space.server.domain.item.domain.value.Category; -import com.space.server.domain.item.domain.repository.ItemRepository; -import com.space.server.domain.item.exception.ItemNotFoundException; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -@RequiredArgsConstructor -public class ItemReader { - - private final ItemRepository itemRepository; - - public Item findById(Long itemId) { - return itemRepository.findById(itemId) - .orElseThrow(ItemNotFoundException::new); - } - - public List findAll() { - return itemRepository.findAll(); - } - - public List findAllByCategory(Category category) { - return itemRepository.findByCategory(category); - } -} diff --git a/src/main/java/com/space/server/domain/item/service/implementation/ItemUpdater.java b/src/main/java/com/space/server/domain/item/service/implementation/ItemUpdater.java deleted file mode 100644 index 2929f85e..00000000 --- a/src/main/java/com/space/server/domain/item/service/implementation/ItemUpdater.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.space.server.domain.item.service.implementation; - -import com.space.server.domain.item.domain.Item; -import org.springframework.stereotype.Service; - -@Service -public class ItemUpdater { - - public void update(Item updatableItem, Item item) { - updatableItem.update(item); - } -} \ No newline at end of file diff --git a/src/main/java/com/space/server/domain/quiz/presentation/QuizController.java b/src/main/java/com/space/server/domain/quiz/adapter/in/web/QuizController.java similarity index 58% rename from src/main/java/com/space/server/domain/quiz/presentation/QuizController.java rename to src/main/java/com/space/server/domain/quiz/adapter/in/web/QuizController.java index ed63b4db..f58592e5 100644 --- a/src/main/java/com/space/server/domain/quiz/presentation/QuizController.java +++ b/src/main/java/com/space/server/domain/quiz/adapter/in/web/QuizController.java @@ -1,8 +1,10 @@ -package com.space.server.domain.quiz.presentation; +package com.space.server.domain.quiz.adapter.in.web; -import com.space.server.domain.quiz.presentation.dto.response.QuizAllResponse; -import com.space.server.domain.quiz.presentation.dto.response.QuizResponse; -import com.space.server.domain.quiz.service.QueryQuizService; +import com.space.server.common.annotation.WebAdapter; +import com.space.server.domain.quiz.adapter.in.web.dto.response.QuizResponse; +import com.space.server.domain.quiz.adapter.in.web.dto.response.QuizAllResponse; +import com.space.server.domain.quiz.application.port.in.GetQuizQuery; +import com.space.server.domain.quiz.application.port.in.GetQuizzesByChapterQuery; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -11,16 +13,19 @@ import java.util.List; +@WebAdapter @RestController @RequiredArgsConstructor @Tag(name = "Quiz", description = "퀴즈 API") public class QuizController { - private final QueryQuizService queryQuizService; + + private final GetQuizzesByChapterQuery getQuizzesByChapterQuery; + private final GetQuizQuery getQuizQuery; @GetMapping("/quizzes/{quiz-id}") @Operation(summary = "퀴즈 조회", description = "해당 퀴즈를 조회합니다.") public QuizResponse getQuiz(@PathVariable("quiz-id") long quizId) { - return QuizResponse.from(queryQuizService.readOne(quizId)); + return QuizResponse.from(getQuizQuery.getQuiz(quizId)); } @GetMapping("/chapters/{chapter-id}/quizzes") @@ -28,7 +33,7 @@ public QuizResponse getQuiz(@PathVariable("quiz-id") long quizId) { public List findAll( @Parameter(description = "챕터 ID", required = true) @PathVariable("chapter-id") Long chapterId ) { - return queryQuizService.findAll(chapterId).stream() + return getQuizzesByChapterQuery.getQuizzesByChapter(chapterId).stream() .map(QuizAllResponse::from) .toList(); } diff --git a/src/main/java/com/space/server/domain/quiz/presentation/dto/response/QuizAllResponse.java b/src/main/java/com/space/server/domain/quiz/adapter/in/web/dto/response/QuizAllResponse.java similarity index 68% rename from src/main/java/com/space/server/domain/quiz/presentation/dto/response/QuizAllResponse.java rename to src/main/java/com/space/server/domain/quiz/adapter/in/web/dto/response/QuizAllResponse.java index dc99abda..5a6503ff 100644 --- a/src/main/java/com/space/server/domain/quiz/presentation/dto/response/QuizAllResponse.java +++ b/src/main/java/com/space/server/domain/quiz/adapter/in/web/dto/response/QuizAllResponse.java @@ -1,4 +1,4 @@ -package com.space.server.domain.quiz.presentation.dto.response; +package com.space.server.domain.quiz.adapter.in.web.dto.response; import com.space.server.domain.quiz.domain.Quiz; import io.swagger.v3.oas.annotations.media.Schema; @@ -9,6 +9,6 @@ public record QuizAllResponse( Long id ) { public static QuizAllResponse from(Quiz quiz) { - return new QuizAllResponse(quiz.getId()); + return new QuizAllResponse(quiz.getId().getValue()); } } diff --git a/src/main/java/com/space/server/domain/quiz/presentation/dto/response/QuizResponse.java b/src/main/java/com/space/server/domain/quiz/adapter/in/web/dto/response/QuizResponse.java similarity index 89% rename from src/main/java/com/space/server/domain/quiz/presentation/dto/response/QuizResponse.java rename to src/main/java/com/space/server/domain/quiz/adapter/in/web/dto/response/QuizResponse.java index 033da9d5..0d05d190 100644 --- a/src/main/java/com/space/server/domain/quiz/presentation/dto/response/QuizResponse.java +++ b/src/main/java/com/space/server/domain/quiz/adapter/in/web/dto/response/QuizResponse.java @@ -1,6 +1,6 @@ -package com.space.server.domain.quiz.presentation.dto.response; +package com.space.server.domain.quiz.adapter.in.web.dto.response; -import com.space.server.domain.chapter.presentation.dto.response.ChapterResponse; +import com.space.server.domain.chapter.adapter.in.web.dto.response.ChapterResponse; import com.space.server.domain.quiz.domain.Quiz; import com.space.server.domain.quiz.domain.value.CharacterDirection; import io.swagger.v3.oas.annotations.media.Schema; @@ -36,7 +36,7 @@ public record QuizResponse( ) { public static QuizResponse from(Quiz quiz) { return new QuizResponse( - quiz.getId(), + quiz.getId().getValue(), ChapterResponse.from(quiz.getChapter()), quiz.getTitle(), quiz.getContent(), diff --git a/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizGetAdapter.java b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizGetAdapter.java new file mode 100644 index 00000000..c321ed0c --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizGetAdapter.java @@ -0,0 +1,22 @@ +package com.space.server.domain.quiz.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.quiz.application.port.out.LoadQuizPort; +import com.space.server.domain.quiz.domain.Quiz; +import com.space.server.domain.quiz.exception.QuizNotFoundException; +import lombok.RequiredArgsConstructor; + +@PersistenceAdapter +@RequiredArgsConstructor +public class QuizGetAdapter implements LoadQuizPort { + + private final QuizRepository quizRepository; + private final QuizMapper quizMapper; + + @Override + public Quiz loadQuiz(Long quizId) { + return quizRepository.findById(quizId) + .map(quizMapper::mapToQuiz) + .orElseThrow(QuizNotFoundException::new); + } +} diff --git a/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizJpaEntity.java b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizJpaEntity.java new file mode 100644 index 00000000..7b56c8eb --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizJpaEntity.java @@ -0,0 +1,54 @@ +package com.space.server.domain.quiz.adapter.out.persistence; + +import com.space.server.domain.chapter.adapter.out.persistence.ChapterJpaEntity; +import com.space.server.domain.quiz.domain.value.CharacterDirection; +import io.hypersistence.utils.hibernate.type.array.IntArrayType; +import io.hypersistence.utils.hibernate.type.basic.PostgreSQLHStoreType; +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.Type; + +import java.util.Map; + +@Builder +@Entity +@Table(name = "quiz") +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class QuizJpaEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JoinColumn + @ManyToOne(fetch = FetchType.LAZY) + private ChapterJpaEntity chapter; + + @Column + private Long stepId; + + @Column + private String title; + + @Column + private String content; + + + @Type(IntArrayType.class) + @Column(columnDefinition = "int[][]") + private Integer[][] map; + + @Column + @Enumerated(EnumType.STRING) + private CharacterDirection characterDirection; + + @Type(PostgreSQLHStoreType.class) + @Column(columnDefinition = "hstore") + private Map mapObject; + + @Type(PostgreSQLHStoreType.class) + @Column(columnDefinition = "hstore") + private Map mapObjectImage; +} diff --git a/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizMapper.java b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizMapper.java new file mode 100644 index 00000000..8d6ca9e1 --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizMapper.java @@ -0,0 +1,41 @@ +package com.space.server.domain.quiz.adapter.out.persistence; + +import com.space.server.domain.chapter.adapter.out.persistence.ChapterMapper; +import com.space.server.domain.quiz.domain.Quiz; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class QuizMapper { + + private final ChapterMapper chapterMapper; + + public Quiz mapToQuiz(QuizJpaEntity quiz) { + return Quiz.builder() + .id(new Quiz.QuizId(quiz.getId())) + .chapter(chapterMapper.mapToChapter(quiz.getChapter())) + .stepId(quiz.getStepId()) + .title(quiz.getTitle()) + .content(quiz.getContent()) + .map(quiz.getMap()) + .characterDirection(quiz.getCharacterDirection()) + .mapObject(quiz.getMapObject()) + .mapObjectImage(quiz.getMapObjectImage()) + .build(); + } + + public QuizJpaEntity mapToQuizJpaEntity(Quiz quiz) { + return QuizJpaEntity.builder() + .id(quiz.getId() == null ? null : quiz.getId().getValue()) + .chapter(chapterMapper.mapToChapterJpaEntity(quiz.getChapter())) + .stepId(quiz.getStepId()) + .title(quiz.getTitle()) + .content(quiz.getContent()) + .map(quiz.getMap()) + .characterDirection(quiz.getCharacterDirection()) + .mapObject(quiz.getMapObject()) + .mapObjectImage(quiz.getMapObjectImage()) + .build(); + } +} diff --git a/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizRepository.java b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizRepository.java new file mode 100644 index 00000000..46373576 --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizRepository.java @@ -0,0 +1,12 @@ +package com.space.server.domain.quiz.adapter.out.persistence; + +import com.space.server.domain.chapter.adapter.out.persistence.ChapterJpaEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface QuizRepository extends JpaRepository { + List findAllByChapterOrderByStepId(ChapterJpaEntity chapter); +} diff --git a/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizzesByChapterGetAdapter.java b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizzesByChapterGetAdapter.java new file mode 100644 index 00000000..ce655cc0 --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/adapter/out/persistence/QuizzesByChapterGetAdapter.java @@ -0,0 +1,30 @@ +package com.space.server.domain.quiz.adapter.out.persistence; + +import com.space.server.common.annotation.PersistenceAdapter; +import com.space.server.domain.chapter.adapter.out.persistence.ChapterJpaEntity; +import com.space.server.domain.chapter.adapter.out.persistence.ChapterRepository; +import com.space.server.domain.chapter.exception.ChapterNotFoundException; +import com.space.server.domain.quiz.application.port.out.LoadQuizzesByChapterPort; +import com.space.server.domain.quiz.domain.Quiz; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@PersistenceAdapter +@RequiredArgsConstructor +public class QuizzesByChapterGetAdapter implements LoadQuizzesByChapterPort { + + private final ChapterRepository chapterRepository; + private final QuizRepository quizRepository; + private final QuizMapper quizMapper; + + @Override + public List loadQuizzesByChapter(Long chapterId) { + ChapterJpaEntity chapter = chapterRepository.findById(chapterId) + .orElseThrow(ChapterNotFoundException::new); + + return quizRepository.findAllByChapterOrderByStepId(chapter).stream() + .map(quizMapper::mapToQuiz) + .toList(); + } +} diff --git a/src/main/java/com/space/server/domain/quiz/application/port/in/GetQuizQuery.java b/src/main/java/com/space/server/domain/quiz/application/port/in/GetQuizQuery.java new file mode 100644 index 00000000..f4ae4149 --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/application/port/in/GetQuizQuery.java @@ -0,0 +1,8 @@ +package com.space.server.domain.quiz.application.port.in; + +import com.space.server.domain.quiz.domain.Quiz; + +public interface GetQuizQuery { + + Quiz getQuiz(Long quizId); +} diff --git a/src/main/java/com/space/server/domain/quiz/application/port/in/GetQuizzesByChapterQuery.java b/src/main/java/com/space/server/domain/quiz/application/port/in/GetQuizzesByChapterQuery.java new file mode 100644 index 00000000..3dee50c3 --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/application/port/in/GetQuizzesByChapterQuery.java @@ -0,0 +1,10 @@ +package com.space.server.domain.quiz.application.port.in; + +import com.space.server.domain.quiz.domain.Quiz; + +import java.util.List; + +public interface GetQuizzesByChapterQuery { + + List getQuizzesByChapter(Long chapterId); +} diff --git a/src/main/java/com/space/server/domain/quiz/application/port/out/LoadQuizPort.java b/src/main/java/com/space/server/domain/quiz/application/port/out/LoadQuizPort.java new file mode 100644 index 00000000..55f91f90 --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/application/port/out/LoadQuizPort.java @@ -0,0 +1,8 @@ +package com.space.server.domain.quiz.application.port.out; + +import com.space.server.domain.quiz.domain.Quiz; + +public interface LoadQuizPort { + + Quiz loadQuiz(Long quizId); +} diff --git a/src/main/java/com/space/server/domain/quiz/application/port/out/LoadQuizzesByChapterPort.java b/src/main/java/com/space/server/domain/quiz/application/port/out/LoadQuizzesByChapterPort.java new file mode 100644 index 00000000..bbbf0749 --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/application/port/out/LoadQuizzesByChapterPort.java @@ -0,0 +1,10 @@ +package com.space.server.domain.quiz.application.port.out; + +import com.space.server.domain.quiz.domain.Quiz; + +import java.util.List; + +public interface LoadQuizzesByChapterPort { + + List loadQuizzesByChapter(Long chapterId); +} diff --git a/src/main/java/com/space/server/domain/quiz/application/service/GetQuizService.java b/src/main/java/com/space/server/domain/quiz/application/service/GetQuizService.java new file mode 100644 index 00000000..0c6a3fb5 --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/application/service/GetQuizService.java @@ -0,0 +1,20 @@ +package com.space.server.domain.quiz.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.quiz.application.port.in.GetQuizQuery; +import com.space.server.domain.quiz.application.port.out.LoadQuizPort; +import com.space.server.domain.quiz.domain.Quiz; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class GetQuizService implements GetQuizQuery { + + private final LoadQuizPort loadQuizPort; + + @Override + public Quiz getQuiz(Long quizId) { + return loadQuizPort.loadQuiz(quizId); + } + +} diff --git a/src/main/java/com/space/server/domain/quiz/application/service/GetQuizzesByChapterService.java b/src/main/java/com/space/server/domain/quiz/application/service/GetQuizzesByChapterService.java new file mode 100644 index 00000000..31b796a4 --- /dev/null +++ b/src/main/java/com/space/server/domain/quiz/application/service/GetQuizzesByChapterService.java @@ -0,0 +1,21 @@ +package com.space.server.domain.quiz.application.service; + +import com.space.server.common.annotation.UseCase; +import com.space.server.domain.quiz.application.port.in.GetQuizzesByChapterQuery; +import com.space.server.domain.quiz.application.port.out.LoadQuizzesByChapterPort; +import com.space.server.domain.quiz.domain.Quiz; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@UseCase +@RequiredArgsConstructor +public class GetQuizzesByChapterService implements GetQuizzesByChapterQuery { + + private final LoadQuizzesByChapterPort loadQuizzesByChapterPort; + + @Override + public List getQuizzesByChapter(Long chapterId) { + return loadQuizzesByChapterPort.loadQuizzesByChapter(chapterId); + } +} diff --git a/src/main/java/com/space/server/domain/quiz/domain/Quiz.java b/src/main/java/com/space/server/domain/quiz/domain/Quiz.java index 552b0d3d..efffb272 100644 --- a/src/main/java/com/space/server/domain/quiz/domain/Quiz.java +++ b/src/main/java/com/space/server/domain/quiz/domain/Quiz.java @@ -2,95 +2,44 @@ import com.space.server.domain.chapter.domain.Chapter; import com.space.server.domain.quiz.domain.value.CharacterDirection; -import io.hypersistence.utils.hibernate.type.array.IntArrayType; -import io.hypersistence.utils.hibernate.type.basic.PostgreSQLHStoreType; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.hibernate.annotations.Type; +import lombok.*; import java.util.Map; @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -@Schema(description = "퀴즈 Entity") +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) public class Quiz { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Schema(description = "퀴즈 ID") - private Long id; + private QuizId id; - @ManyToOne(fetch = FetchType.LAZY) @NotNull - @Schema(description = "챕터 정보") private Chapter chapter; @NotNull - @Schema(description = "스텝 ID") private Long stepId; @NotNull - @Schema(description = "퀴즈 제목") private String title; @NotNull - @Schema(description = "퀴즈 내용") private String content; - @Type(IntArrayType.class) - @Column(columnDefinition = "int[][]") @NotNull - @Schema(description = "퀴즈 맵 (7x7)") private Integer[][] map; - @Enumerated(EnumType.STRING) @NotNull - @Schema(description = "캐릭터 방향") private CharacterDirection characterDirection; - @Type(PostgreSQLHStoreType.class) - @Column(columnDefinition = "hstore") @NotNull - @Schema(description = "맵 오브젝트 정보") private Map mapObject; - @Type(PostgreSQLHStoreType.class) - @Column(columnDefinition = "hstore") @NotNull - @Schema(description = "맵 오브젝트 이미지 정보") private Map mapObjectImage; - @Builder - public Quiz(Chapter chapter, Long stepId, String title, String content, Integer[][] map, CharacterDirection characterDirection, Map mapObject, Map mapObjectImage) { - this.chapter = chapter; - this.stepId = stepId; - this.title = title; - this.content = content; - this.map = map; - this.characterDirection = characterDirection; - this.mapObject = mapObject; - this.mapObjectImage = mapObjectImage; - } - - @Builder - public Quiz(Integer[][] map, CharacterDirection characterDirection) { - this.map = map; - this.characterDirection = characterDirection; - } - - public void update(Quiz quiz) { - if (quiz.getMap() != null) { - this.map = new Integer[7][7]; - for (int i = 0; i < 7; i++) { - System.arraycopy(quiz.getMap()[i], 0, this.map[i], 0, 7); - } - } - this.characterDirection = quiz.getCharacterDirection(); + @Value + public static class QuizId { + private final Long value; } } diff --git a/src/main/java/com/space/server/domain/quiz/domain/repository/QuizRepository.java b/src/main/java/com/space/server/domain/quiz/domain/repository/QuizRepository.java deleted file mode 100644 index 89e73849..00000000 --- a/src/main/java/com/space/server/domain/quiz/domain/repository/QuizRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.space.server.domain.quiz.domain.repository; - -import com.space.server.domain.chapter.domain.Chapter; -import com.space.server.domain.quiz.domain.Quiz; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface QuizRepository extends JpaRepository { - Quiz findByChapterAndStepId(Chapter chapter, Long stepId); - List findAllByChapterOrderByStepId(Chapter chapter); -} diff --git a/src/main/java/com/space/server/domain/quiz/presentation/dto/request/QuizRequest.java b/src/main/java/com/space/server/domain/quiz/presentation/dto/request/QuizRequest.java deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/java/com/space/server/domain/quiz/service/CommandQuizService.java b/src/main/java/com/space/server/domain/quiz/service/CommandQuizService.java deleted file mode 100644 index 7564bd08..00000000 --- a/src/main/java/com/space/server/domain/quiz/service/CommandQuizService.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.space.server.domain.quiz.service; - -import com.space.server.domain.chapter.service.implementation.ChapterReader; -import com.space.server.domain.quiz.domain.Quiz; -import com.space.server.domain.quiz.service.implementation.QuizCreator; -import com.space.server.domain.quiz.service.implementation.QuizDeleter; -import com.space.server.domain.quiz.service.implementation.QuizReader; -import com.space.server.domain.quiz.service.implementation.QuizUpdater; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -@Transactional -public class CommandQuizService { - - private final QuizCreator quizCreator; - private final QuizReader quizReader; - private final QuizUpdater quizUpdater; - private final QuizDeleter quizDeleter; - private final ChapterReader chapterReader; - - public void create(Quiz quiz) { - quizCreator.create(quiz); - } - - public void update(Long quizId, Quiz quiz) { - Quiz updatableQuiz = quizReader.findById(quizId); - quizUpdater.update(updatableQuiz, quiz); - } - - public void delete(Long quizId) { - Quiz quiz = quizReader.findById(quizId); - quizDeleter.delete(quiz); - } -} diff --git a/src/main/java/com/space/server/domain/quiz/service/QueryQuizService.java b/src/main/java/com/space/server/domain/quiz/service/QueryQuizService.java deleted file mode 100644 index 5a37781b..00000000 --- a/src/main/java/com/space/server/domain/quiz/service/QueryQuizService.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.space.server.domain.quiz.service; - -import com.space.server.domain.chapter.domain.Chapter; -import com.space.server.domain.chapter.service.implementation.ChapterReader; -import com.space.server.domain.quiz.domain.Quiz; -import com.space.server.domain.quiz.service.implementation.QuizReader; -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 QueryQuizService { - - private final QuizReader quizReader; - private final ChapterReader chapterReader; - - public Quiz readOne(Long quizId) { - return quizReader.findById(quizId); - } - - public List readAll() { - return quizReader.findAll(); - } - - public Quiz findOne(Long chapterId, Long stepId) { - Chapter chapter = chapterReader.findById(chapterId); - return quizReader.findByChapterAndStepId(chapter, stepId); - } - - public List findAll(Long chapterId) { - Chapter chapter = chapterReader.findById(chapterId); - return quizReader.findAll(chapter); - } -} diff --git a/src/main/java/com/space/server/domain/quiz/service/implementation/QuizCreator.java b/src/main/java/com/space/server/domain/quiz/service/implementation/QuizCreator.java deleted file mode 100644 index a365b07f..00000000 --- a/src/main/java/com/space/server/domain/quiz/service/implementation/QuizCreator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.quiz.service.implementation; - -import com.space.server.domain.quiz.domain.Quiz; -import com.space.server.domain.quiz.domain.repository.QuizRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class QuizCreator { - - private final QuizRepository quizRepository; - - public void create(Quiz quiz) { - quizRepository.save(quiz); - } -} diff --git a/src/main/java/com/space/server/domain/quiz/service/implementation/QuizDeleter.java b/src/main/java/com/space/server/domain/quiz/service/implementation/QuizDeleter.java deleted file mode 100644 index 85ceb3d3..00000000 --- a/src/main/java/com/space/server/domain/quiz/service/implementation/QuizDeleter.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.space.server.domain.quiz.service.implementation; - -import com.space.server.domain.quiz.domain.Quiz; -import com.space.server.domain.quiz.domain.repository.QuizRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class QuizDeleter { - - private final QuizRepository quizRepository; - - public void delete(Quiz quiz) { - quizRepository.delete(quiz); - } -} diff --git a/src/main/java/com/space/server/domain/quiz/service/implementation/QuizReader.java b/src/main/java/com/space/server/domain/quiz/service/implementation/QuizReader.java deleted file mode 100644 index 55c4c71f..00000000 --- a/src/main/java/com/space/server/domain/quiz/service/implementation/QuizReader.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.space.server.domain.quiz.service.implementation; - -import com.space.server.domain.chapter.domain.Chapter; -import com.space.server.domain.quiz.domain.Quiz; -import com.space.server.domain.quiz.domain.repository.QuizRepository; -import com.space.server.domain.quiz.exception.QuizNotFoundException; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -@RequiredArgsConstructor -public class QuizReader { - - private final QuizRepository quizRepository; - - public Quiz findById(Long quizId) { - return quizRepository.findById(quizId) - .orElseThrow(QuizNotFoundException::new); - } - - public List findAll() { - return quizRepository.findAll(); - } - - public List findAll(Chapter chapter) { - return quizRepository.findAllByChapterOrderByStepId(chapter); - } - - public Quiz findByChapterAndStepId(Chapter chapter, Long stepId) { - return quizRepository.findByChapterAndStepId(chapter, stepId); - } -} diff --git a/src/main/java/com/space/server/domain/quiz/service/implementation/QuizUpdater.java b/src/main/java/com/space/server/domain/quiz/service/implementation/QuizUpdater.java deleted file mode 100644 index 99606e4a..00000000 --- a/src/main/java/com/space/server/domain/quiz/service/implementation/QuizUpdater.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.space.server.domain.quiz.service.implementation; - -import com.space.server.domain.quiz.domain.Quiz; -import org.springframework.stereotype.Service; - -@Service -public class QuizUpdater { - - public void update(Quiz updatableQuiz, Quiz quiz) { - updatableQuiz.update(quiz); - } -} diff --git a/src/main/java/com/space/server/domain/state/domain/State.java b/src/main/java/com/space/server/domain/state/domain/State.java index 4fee9a0f..b9375781 100644 --- a/src/main/java/com/space/server/domain/state/domain/State.java +++ b/src/main/java/com/space/server/domain/state/domain/State.java @@ -1,6 +1,6 @@ package com.space.server.domain.state.domain; -import com.space.server.domain.quiz.domain.Quiz; +import com.space.server.domain.quiz.adapter.out.persistence.QuizJpaEntity; import com.space.server.domain.state.domain.value.Status; import com.space.server.domain.user.domain.Users; import io.hypersistence.utils.hibernate.type.array.IntArrayType; @@ -27,7 +27,7 @@ public class State { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "quiz_id") - private Quiz quiz; + private QuizJpaEntity quiz; @Enumerated(EnumType.STRING) private Status status; @@ -43,7 +43,7 @@ public class State { private String threadId; @Builder(builderMethodName = "createBuilder") - public State(Users user, Quiz quiz, Status status, String[] move, Long[] score, String threadId) { + public State(Users user, QuizJpaEntity quiz, Status status, String[] move, Long[] score, String threadId) { this.user = user; this.quiz = quiz; this.status = status; diff --git a/src/main/java/com/space/server/domain/state/presentation/dto/response/StateResponse.java b/src/main/java/com/space/server/domain/state/presentation/dto/response/StateResponse.java index 7741a63d..3cc6be48 100644 --- a/src/main/java/com/space/server/domain/state/presentation/dto/response/StateResponse.java +++ b/src/main/java/com/space/server/domain/state/presentation/dto/response/StateResponse.java @@ -1,6 +1,6 @@ package com.space.server.domain.state.presentation.dto.response; -import com.space.server.domain.quiz.domain.Quiz; +import com.space.server.domain.quiz.adapter.out.persistence.QuizJpaEntity; import com.space.server.domain.state.domain.value.Status; import com.space.server.domain.state.domain.State; import com.space.server.domain.user.domain.Users; @@ -8,7 +8,7 @@ public record StateResponse( Long stateId, Users userId, - Quiz quizId, + QuizJpaEntity quizId, Status status, Long[] score ) {