Skip to content

Commit 9df22ab

Browse files
authored
Merge pull request #135 from swyp-app-team-4/feat#129-point-event
[Feat] 이벤트 로그 테이블 추가
2 parents d28d0d2 + 00746bb commit 9df22ab

9 files changed

Lines changed: 122 additions & 36 deletions

File tree

src/main/java/boombimapi/domain/member/domain/entity/Member.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ public class Member {
7777

7878
// 10) 포인트 내역 조회
7979
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
80-
private List<PointHistory> pointHistory = new ArrayList<>();
80+
private List<PointHistory> pointHistories = new ArrayList<>();
8181

8282
// 11) 이벤트 응모
8383
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
84-
private List<EventCampaign> eventCampaign = new ArrayList<>();
84+
private List<EventCampaign> eventCampaigns = new ArrayList<>();
8585

8686

8787
@Column(nullable = false)

src/main/java/boombimapi/domain/point/application/PointService.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
package boombimapi.domain.point.application;
22

33
import boombimapi.domain.member.domain.entity.Member;
4+
import boombimapi.domain.point.presentation.dto.req.UsePointForEventReq;
45
import boombimapi.domain.point.presentation.dto.res.GetPointRes;
56

67
/**
7-
* PointService
8-
* 포인트 관련 핵심 기능 정의 인터페이스.
8+
* PointService 포인트 관련 핵심 기능 정의 인터페이스.
99
* <p>
10-
* - 혼잡도 작성 시 포인트 적립<br>
11-
* - 포인트 및 이력 조회<br>
12-
* - 이벤트 응모 시 포인트 차감
10+
* - 혼잡도 작성 시 포인트 적립<br> - 포인트 및 이력 조회<br> - 이벤트 응모 시 포인트 차감
1311
*/
1412
public interface PointService {
1513

@@ -39,7 +37,7 @@ public interface PointService {
3937
* 회원의 포인트 잔액에서 지정 금액을 차감하고, 응모 이력 및 포인트 사용 이력을 기록한다.
4038
*
4139
* @param memberId 회원 ID
42-
* @param balance 차감할 포인트 금액
40+
* @param req 이벤트 응모 요청 (이벤트 캠페인 ID 및 차감할 포인트 금액 포함)
4341
*/
44-
void usePointForEvent(String memberId, Long balance);
42+
void usePointForEvent(String memberId, UsePointForEventReq req);
4543
}

src/main/java/boombimapi/domain/point/application/impl/PointServiceImpl.java

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44
import boombimapi.domain.member.domain.repository.MemberRepository;
55
import boombimapi.domain.point.application.PointService;
66
import boombimapi.domain.point.domain.entity.EventCampaign;
7+
import boombimapi.domain.point.domain.entity.EventLog;
78
import boombimapi.domain.point.domain.entity.Point;
89
import boombimapi.domain.point.domain.entity.PointHistory;
910
import boombimapi.domain.point.domain.entity.type.EventCategory;
1011
import boombimapi.domain.point.domain.entity.type.PointAction;
1112
import boombimapi.domain.point.domain.entity.type.PointCategory;
1213
import boombimapi.domain.point.domain.repository.EventCampaignRepository;
14+
import boombimapi.domain.point.domain.repository.EventLogRepository;
1315
import boombimapi.domain.point.domain.repository.PointHistoryRepository;
1416
import boombimapi.domain.point.domain.repository.PointRepository;
17+
import boombimapi.domain.point.presentation.dto.req.UsePointForEventReq;
1518
import boombimapi.domain.point.presentation.dto.res.GetPointHistoryRes;
1619
import boombimapi.domain.point.presentation.dto.res.GetPointRes;
1720
import boombimapi.global.infra.exception.error.BoombimException;
@@ -26,11 +29,8 @@
2629
import static boombimapi.global.infra.exception.error.ErrorCode.*;
2730

2831
/**
29-
* PointServiceImpl
30-
* 포인트 적립, 조회, 사용(이벤트 응모) 관련 비즈니스 로직을 담당한다.
31-
* - 혼잡도 작성 시 포인트 적립
32-
* - 포인트 및 이력 조회
33-
* - 이벤트 응모 시 포인트 차감 및 응모 이력 생성
32+
* PointServiceImpl 포인트 적립, 조회, 사용(이벤트 응모) 관련 비즈니스 로직을 담당한다. - 혼잡도 작성 시 포인트 적립 - 포인트 및 이력 조회 - 이벤트 응모 시 포인트 차감 및 응모 이력
33+
* 생성
3434
*/
3535
@Service
3636
@RequiredArgsConstructor
@@ -41,12 +41,11 @@ public class PointServiceImpl implements PointService {
4141
private final PointRepository pointRepository;
4242
private final PointHistoryRepository pointHistoryRepository;
4343
private final MemberRepository memberRepository;
44+
private final EventLogRepository eventLogRepository;
4445
private final EventCampaignRepository eventCampaignRepository;
4546

4647
/**
47-
* [혼잡도 작성 시 포인트 적립]
48-
* - 특정 회원의 포인트 잔액을 증가시키고, 적립 이력을 저장한다.
49-
* - 포인트가 존재하지 않으면 예외 발생.
48+
* [혼잡도 작성 시 포인트 적립] - 특정 회원의 포인트 잔액을 증가시키고, 적립 이력을 저장한다. - 포인트가 존재하지 않으면 예외 발생.
5049
*
5150
* @param member 포인트를 적립할 회원
5251
* @param balance 적립할 포인트 금액
@@ -72,9 +71,7 @@ public void earnPointForCongestion(Member member, Long balance) {
7271
}
7372

7473
/**
75-
* [회원 포인트 및 이력 조회]
76-
* - 회원의 현재 포인트 잔액과 포인트 거래 이력을 조회한다.
77-
* - 회원 또는 포인트 정보가 존재하지 않으면 예외 발생.
74+
* [회원 포인트 및 이력 조회] - 회원의 현재 포인트 잔액과 포인트 거래 이력을 조회한다. - 회원 또는 포인트 정보가 존재하지 않으면 예외 발생.
7875
*
7976
* @param memberId 조회할 회원 ID
8077
* @return 포인트 잔액 및 거래 이력 응답 DTO
@@ -98,24 +95,24 @@ public GetPointRes getPointHistory(String memberId) {
9895
}
9996

10097
/**
101-
* [이벤트 응모 시 포인트 차감]
102-
* - 회원 포인트 잔액에서 지정 금액을 차감하고, 응모 이력을 저장한다.
103-
* - 응모 횟수가 5회를 초과하면 예외 발생.
104-
* - 포인트가 부족한 경우 예외 발생.
98+
* [이벤트 응모 시 포인트 차감] - 회원 포인트 잔액에서 지정 금액을 차감하고, 응모 이력을 저장한다. - 응모 횟수가 5회를 초과하면 예외 발생. - 포인트가 부족한 경우 예외 발생.
10599
*
106100
* @param memberId 회원 ID
107-
* @param balance 차감할 포인트 금액
101+
* @param req 이벤트 응모 요청 (이벤트 캠페인 ID 및 차감할 포인트 금액 포함)
108102
*/
109103
@Override
110-
public void usePointForEvent(String memberId, Long balance) {
104+
public void usePointForEvent(String memberId, UsePointForEventReq req) {
111105
Member member = memberRepository.findById(memberId)
112106
.orElseThrow(() -> new BoombimException(USER_NOT_EXIST));
113107

114108
Point point = pointRepository.findByMember(member)
115109
.orElseThrow(() -> new BoombimException(POINT_NOT_EXIST));
116110

111+
EventCampaign eventCampaign = eventCampaignRepository.findById(req.eventCampaignId())
112+
.orElseThrow(() -> new BoombimException(EVENT_NOT_EXIST));
113+
117114
// 포인트 잔액 부족 예외
118-
if (point.getBalance() - balance < 0) {
115+
if (point.getBalance() - req.amount() < 0) {
119116
throw new BoombimException(INSUFFICIENT_POINT_FOR_EVENT);
120117
}
121118

@@ -125,21 +122,21 @@ public void usePointForEvent(String memberId, Long balance) {
125122
}
126123

127124
// 포인트 차감 및 응모 횟수 증가
128-
point.subtractBalance(balance);
125+
point.subtractBalance(req.amount());
129126
point.addApplyEventCnt();
130127

131128
// 이벤트 응모 이력 저장
132-
EventCampaign eventCampaign = EventCampaign.builder()
129+
EventLog eventLog = EventLog.builder()
133130
.member(member)
134-
.eventCategory(EventCategory.EVENT_PARTICIPATION_TICKET)
131+
.eventCampaign(eventCampaign)
135132
.build();
136133

137-
eventCampaignRepository.save(eventCampaign);
134+
eventLogRepository.save(eventLog);
138135

139136
// 포인트 거래 이력 저장
140137
PointHistory pointHistory = PointHistory.builder()
141138
.member(member)
142-
.amount(balance)
139+
.amount(req.amount())
143140
.balance(point.getBalance())
144141
.pointCategory(PointCategory.EVENT)
145142
.pointAction(PointAction.USE)

src/main/java/boombimapi/domain/point/domain/entity/EventCampaign.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import boombimapi.domain.member.domain.entity.Member;
44
import boombimapi.domain.point.domain.entity.type.EventCategory;
55
import boombimapi.domain.point.domain.entity.type.PointAction;
6+
import jakarta.persistence.CascadeType;
67
import jakarta.persistence.Column;
78
import jakarta.persistence.Entity;
89
import jakarta.persistence.EnumType;
@@ -17,6 +18,8 @@
1718
import jakarta.persistence.OneToOne;
1819
import jakarta.persistence.Table;
1920
import java.time.LocalDateTime;
21+
import java.util.ArrayList;
22+
import java.util.List;
2023
import lombok.Builder;
2124
import lombok.Getter;
2225
import lombok.NoArgsConstructor;
@@ -39,6 +42,9 @@ public class EventCampaign {
3942
@JoinColumn(name = "member_id", nullable = false)
4043
private Member member;
4144

45+
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
46+
private List<EventLog> eventlogs = new ArrayList<>();
47+
4248
@Enumerated(EnumType.STRING)
4349
@Column(name = "event_category", nullable = false)
4450
@Comment("이벤트 타입 ex) EVENT_PARTICIPATION_TICKETE")
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package boombimapi.domain.point.domain.entity;
2+
3+
import boombimapi.domain.member.domain.entity.Member;
4+
import boombimapi.domain.point.domain.entity.type.EventCategory;
5+
import jakarta.persistence.Column;
6+
import jakarta.persistence.Entity;
7+
import jakarta.persistence.EnumType;
8+
import jakarta.persistence.Enumerated;
9+
import jakarta.persistence.FetchType;
10+
import jakarta.persistence.GeneratedValue;
11+
import jakarta.persistence.GenerationType;
12+
import jakarta.persistence.Id;
13+
import jakarta.persistence.JoinColumn;
14+
import jakarta.persistence.ManyToOne;
15+
import jakarta.persistence.Table;
16+
import java.time.LocalDateTime;
17+
import lombok.Builder;
18+
import lombok.Getter;
19+
import lombok.NoArgsConstructor;
20+
import org.hibernate.annotations.Comment;
21+
import org.hibernate.annotations.CreationTimestamp;
22+
import org.hibernate.annotations.DynamicUpdate;
23+
24+
@Getter
25+
@Entity
26+
@NoArgsConstructor
27+
@DynamicUpdate
28+
@Table(name = "event_log")
29+
public class EventLog {
30+
31+
@Id
32+
@GeneratedValue(strategy = GenerationType.IDENTITY)
33+
private Long id;
34+
35+
@ManyToOne(fetch = FetchType.LAZY)
36+
@JoinColumn(name = "member_id", nullable = false)
37+
private Member member;
38+
39+
@ManyToOne(fetch = FetchType.LAZY)
40+
@JoinColumn(name = "event_campaign_id", nullable = false)
41+
private EventCampaign eventCampaign;
42+
43+
@Column(nullable = false)
44+
@CreationTimestamp
45+
private LocalDateTime createdAt;
46+
47+
@Builder
48+
public EventLog(Member member, EventCampaign eventCampaign) {
49+
this.member = member;
50+
this.eventCampaign = eventCampaign;
51+
}
52+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package boombimapi.domain.point.domain.repository;
2+
3+
import boombimapi.domain.point.domain.entity.EventCampaign;
4+
import boombimapi.domain.point.domain.entity.EventLog;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.stereotype.Repository;
7+
8+
@Repository
9+
public interface EventLogRepository extends JpaRepository<EventLog, Long> {
10+
}

src/main/java/boombimapi/domain/point/presentation/controller/PointController.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package boombimapi.domain.point.presentation.controller;
22

33
import boombimapi.domain.point.application.PointService;
4+
import boombimapi.domain.point.presentation.dto.req.UsePointForEventReq;
45
import boombimapi.domain.point.presentation.dto.res.GetPointRes;
56
import io.swagger.v3.oas.annotations.Operation;
67
import io.swagger.v3.oas.annotations.responses.ApiResponse;
@@ -54,6 +55,7 @@ public ResponseEntity<GetPointRes> getPointHistory(@AuthenticationPrincipal Stri
5455
* - 포인트 잔액 부족 또는 응모 횟수 초과 시 예외 발생.
5556
*
5657
* @param memberId 인증된 회원 ID
58+
* @param req 이벤트 응모 요청 (이벤트 캠페인 ID 및 차감할 포인트 금액 포함)
5759
* @return HTTP 200 OK (성공 시 바디 없음)
5860
*/
5961
@Operation(summary = "이벤트 응모 API", description = "이벤트에 응모하여 포인트를 차감합니다. (1회당 20포인트 차감)")
@@ -63,8 +65,9 @@ public ResponseEntity<GetPointRes> getPointHistory(@AuthenticationPrincipal Stri
6365
@ApiResponse(responseCode = "404", description = "포인트 정보가 존재하지 않음")
6466
})
6567
@PatchMapping
66-
public ResponseEntity<Void> applyEvent(@AuthenticationPrincipal String memberId) {
67-
pointService.usePointForEvent(memberId, 20L);
68+
public ResponseEntity<Void> applyEvent(@AuthenticationPrincipal String memberId,
69+
@RequestBody UsePointForEventReq req) {
70+
pointService.usePointForEvent(memberId, req);
6871
return ResponseEntity.ok().build();
6972
}
7073
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package boombimapi.domain.point.presentation.dto.req;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
/**
6+
* 이벤트 응모 시 포인트 차감 요청 DTO
7+
*
8+
* <p>이 클래스는 사용자가 특정 이벤트에 응모하면서 포인트를 차감할 때 사용됩니다.
9+
* 이벤트 캠페인 식별자와 차감할 포인트 금액을 전달받습니다.</p>
10+
*/
11+
@Schema(description = "이벤트 응모 포인트 차감 요청")
12+
public record UsePointForEventReq(
13+
14+
@Schema(description = "이벤트 캠페인 ID", example = "1")
15+
Long eventCampaignId,
16+
17+
@Schema(description = "차감할 포인트 금액", example = "1000")
18+
Long amount
19+
20+
) {}

src/main/java/boombimapi/global/infra/exception/error/ErrorCode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ public enum ErrorCode {
9999
POINT_NOT_EXIST(-1000, "해당 포인트가 존재하지 않습니다.", 404),
100100
POINT_HISTORY_NOT_EXIST(-1001, "해당 포인트 내역이 존재하지 않습니다.", 404),
101101
EVENT_PARTICIPATION_LIMIT_EXCEEDED(-1002, "이벤트 응모 가능 횟수를 초과했습니다.", 400),
102-
INSUFFICIENT_POINT_FOR_EVENT(-1003, "포인트가 부족하여 이벤트에 응모할 수 없습니다.", 400);
103-
102+
INSUFFICIENT_POINT_FOR_EVENT(-1003, "포인트가 부족하여 이벤트에 응모할 수 없습니다.", 400),
103+
EVENT_NOT_EXIST(-1004,"존재하지 않는 이벤트입니다.",404);
104104

105105
private final int code;
106106
private final String message;

0 commit comments

Comments
 (0)