-
Notifications
You must be signed in to change notification settings - Fork 0
[FEAT] 룩 조회(스와이프, 상세) 및 좋아요,싫어요 기능 구현 #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a3390c8
ffedebf
612de51
9b3bead
4c2da78
c860c6d
8a1fed2
1fe7b14
da0a8cb
546b7bd
3685612
efa0a06
aa8e41d
68bb459
3191536
5a69f7b
04527c4
b646730
1df3330
29b2aac
3482d77
a6374e4
e4314ec
5f7e33f
4af2691
3b27667
706129f
2e1cec9
c258be5
d4962e0
2aa9ea0
28b21d6
94330e8
691acc7
85f2a17
6f892da
f01c4cf
769f9c2
d25e900
57633a5
4f37abf
228026f
6e89244
95693b5
59cea01
e41f6af
4fce6a9
b52fff4
b4c24c8
6a6157c
bf5b287
27de4bc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.dh.baro.look.application | ||
|
|
||
| data class LookCreateCommand( | ||
| val creatorId: Long, | ||
| val title: String, | ||
| val description: String?, | ||
| val thumbnailUrl: String, | ||
| val imageUrls: List<String>, | ||
| val productIds: List<Long>, | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package com.dh.baro.look.application | ||
|
|
||
| import com.dh.baro.identity.domain.service.UserService | ||
| import com.dh.baro.look.domain.* | ||
| import com.dh.baro.look.domain.service.LookService | ||
| import com.dh.baro.look.presentation.dto.LookDetailResponse | ||
| import com.dh.baro.product.domain.service.ProductQueryService | ||
| import org.springframework.data.domain.Slice | ||
| import org.springframework.stereotype.Service | ||
|
|
||
| @Service | ||
| class LookFacade( | ||
| private val userService: UserService, | ||
| private val productQueryService: ProductQueryService, | ||
| private val lookService: LookService, | ||
| ) { | ||
|
|
||
| fun createLook(cmd: LookCreateCommand): Look { | ||
| userService.checkUserExists(cmd.creatorId) | ||
| productQueryService.checkProductsExists(cmd.productIds) | ||
| return lookService.createLook(cmd) | ||
| } | ||
|
|
||
| fun getSwipeLooks(userId: Long, cursorId: Long?, size: Int): Slice<Look> = | ||
| lookService.getSwipeLooks(userId, cursorId, size) | ||
|
|
||
| fun getLookDetail(lookId: Long): LookDetailResponse { | ||
| val look = lookService.getLookDetail(lookId) | ||
| val orderedProducts = look.getOrderedProductViews() | ||
|
|
||
| val productIds = orderedProducts.map { it.productId } | ||
| val products = productQueryService.getAllByIds(productIds) | ||
|
|
||
| return LookDetailResponse.of( | ||
| look = look, | ||
| images = look.getOrderedImageViews(), | ||
| lookProducts = orderedProducts, | ||
| products = products, | ||
| ) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package com.dh.baro.look.application | ||
|
|
||
| import com.dh.baro.identity.domain.service.UserService | ||
| import com.dh.baro.look.domain.ReactionType | ||
| import com.dh.baro.look.domain.service.LookReactionService | ||
| import org.springframework.stereotype.Service | ||
|
|
||
| @Service | ||
| class LookReactionFacade( | ||
| private val userService: UserService, | ||
| private val lookReactionService: LookReactionService, | ||
| ) { | ||
|
|
||
| fun recordReaction(userId: Long, lookId: Long, reactionType: ReactionType) { | ||
| userService.checkUserExists(userId) | ||
| lookReactionService.createReactionIfAbsent( | ||
| userId = userId, | ||
| lookId = lookId, | ||
| reactionType = reactionType, | ||
| ) | ||
| } | ||
|
|
||
| fun cancelReaction(userId: Long, lookId: Long) = | ||
| lookReactionService.deleteReaction(userId, lookId) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package com.dh.baro.look.domain | ||
|
|
||
| import com.dh.baro.core.IdGenerator | ||
| import jakarta.persistence.* | ||
|
|
||
| @Entity | ||
| @Table( | ||
| name = "look_products", | ||
| uniqueConstraints = [ | ||
| UniqueConstraint(columnNames = ["look_id", "product_id"]), | ||
| UniqueConstraint(columnNames = ["look_id", "display_order"]) | ||
| ], | ||
| ) | ||
| class LookProduct( | ||
| @Id | ||
| @Column(name = "id") | ||
| val id: Long, | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "look_id", nullable = false, updatable = false) | ||
| val look: Look, | ||
|
|
||
| @Column(name = "product_id", nullable = false, updatable = false) | ||
| val productId: Long, | ||
|
Comment on lines
+23
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainproductId 필드 설계 검토 productId를 Long 타입으로 저장하고 있는데, Product 엔티티와의 직접적인 연관관계 대신 ID만 저장하는 이유를 확인해보세요. 일반적으로는 @manytoone으로 Product 엔티티와 연관관계를 맺는 것이 일반적입니다. 다음 스크립트를 실행하여 Product 엔티티와의 관계 설정 패턴을 확인해보세요: 🏁 Script executed: #!/bin/bash
# Product와 다른 엔티티들의 연관관계 패턴 확인
echo "=== Product 엔티티와의 연관관계 패턴 확인 ==="
rg -A 5 -B 5 "Product" --type kotlin | rg -A 10 -B 10 "@ManyToOne|@OneToMany"
echo -e "\n=== productId 필드 사용 패턴 확인 ==="
rg "productId.*Long" --type kotlinLength of output: 12699 LookProduct의 productId 필드 설계 검토 및 문서화 필요 LookProduct에서 Product 엔티티를 @manytoone으로 직접 연관관계 매핑하지 않고 · 파일: src/main/kotlin/com/dh/baro/look/domain/LookProduct.kt 🤖 Prompt for AI Agents
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 도메인을 분리된 Bounded Context로 유지하기 위한 설계입니다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| @Column(name = "display_order", nullable = false) | ||
| val displayOrder: Int, | ||
| ) { | ||
|
|
||
| companion object { | ||
| fun of( | ||
| look: Look, | ||
| productId: Long, | ||
| displayOrder: Int | ||
| ) = LookProduct( | ||
| id = IdGenerator.generate(), | ||
| look = look, | ||
| productId = productId, | ||
| displayOrder = displayOrder, | ||
| ) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
이미지 추가 로직 검증
Product 도메인과 동일한 패턴으로 구현되어 일관성이 있습니다.
다음 스크립트로 LookImage 엔티티의 구조를 확인해보세요:
🏁 Script executed:
Length of output: 1297
displayOrder 복합 유니크 제약 추가 검토 필요
현재
addImages로직으로 순서(displayOrder)를 관리하지만,LookImage엔티티에는 DB 레벨에서(look_id, display_order)에 대한 유니크 제약이 없습니다. 순서 중복 삽입을 방지하려면 아래 항목을 검토해주세요.src/main/kotlin/com/dh/baro/look/domain/LookImage.kt•
@Table애너테이션에 uniqueConstraints 추가🤖 Prompt for AI Agents