Skip to content

Commit bfcdbbf

Browse files
Merge pull request #99 from YAPP-Github/feat/ISSUE-91
feat: Carpool delete API
2 parents 96846a4 + 0a62988 commit bfcdbbf

18 files changed

+250
-87
lines changed

src/main/java/com/fullcar/carpool/application/carpool/CarpoolService.java

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,26 @@ public CarpoolResponseDto.CarpoolDetailDtO closeCarpool(Member member, CarpoolId
9696
}
9797
List<Form> forms = formRepository.findAllByCarpoolIdAndIsDeleted(carpoolId, false);
9898

99-
carpool.close();
99+
carpool.close(forms);
100100

101-
for (Form form: forms) {
102-
if (form.getFormState() == FormState.REQUEST) {
103-
form.reject(
104-
memberRepository.findByIdAndIsDeletedOrThrow(
105-
form.getPassenger().getMemberId(),
106-
false
107-
)
108-
);
109-
}
101+
carpoolRepository.saveAndFlush(carpool);
110102

111-
} // TODO: N+1 문제 개선 필요.
103+
return carpoolMapper.toDetailDto(carpool, member, car);
104+
}
112105

113-
carpoolRepository.save(carpool);
114-
formRepository.saveAllAndFlush(forms);
106+
@Transactional
107+
public CarpoolResponseDto deleteCarpool(Member member, CarpoolId carpoolId) {
108+
Carpool carpool = carpoolRepository.findByCarpoolIdAndIsDeletedOrThrow(carpoolId, false);
115109

116-
return carpoolMapper.toDetailDto(carpool, member, car);
110+
if (!carpool.isMyCarpool(member.getId())) {
111+
throw new CustomException(ErrorCode.CANNOT_DELETE_CARPOOL);
112+
}
113+
List<Form> forms = formRepository.findAllByCarpoolIdAndIsDeleted(carpoolId, false);
114+
115+
carpool.delete(forms);
116+
117+
carpoolRepository.saveAndFlush(carpool);
118+
119+
return carpoolMapper.toDto(carpool, member);
117120
}
118121
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.fullcar.carpool.application.form;
2+
3+
4+
import com.fullcar.carpool.domain.carpool.event.CarpoolClosedEvent;
5+
import com.fullcar.carpool.domain.form.Form;
6+
import com.fullcar.carpool.domain.form.FormRepository;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.stereotype.Service;
10+
import org.springframework.transaction.annotation.Propagation;
11+
import org.springframework.transaction.annotation.Transactional;
12+
import org.springframework.transaction.event.TransactionPhase;
13+
import org.springframework.transaction.event.TransactionalEventListener;
14+
15+
import java.util.List;
16+
17+
@Slf4j
18+
@Service
19+
@RequiredArgsConstructor
20+
public class CarpoolClosedEventHandler {
21+
private final FormRepository formRepository;
22+
23+
@Transactional(propagation = Propagation.REQUIRES_NEW)
24+
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
25+
public void rejectForms(CarpoolClosedEvent carpoolClosedEvent) {
26+
log.info("CarpoolClosedEvent received");
27+
List<Form> forms = carpoolClosedEvent.getForms();
28+
29+
forms.forEach(Form::reject);
30+
formRepository.saveAllAndFlush(forms);
31+
}
32+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.fullcar.carpool.application.form;
2+
3+
import com.fullcar.carpool.domain.carpool.event.CarpoolDeletedEvent;
4+
import com.fullcar.carpool.domain.form.Form;
5+
import com.fullcar.carpool.domain.form.FormRepository;
6+
import com.fullcar.carpool.domain.form.FormState;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.stereotype.Service;
10+
import org.springframework.transaction.annotation.Propagation;
11+
import org.springframework.transaction.annotation.Transactional;
12+
import org.springframework.transaction.event.TransactionPhase;
13+
import org.springframework.transaction.event.TransactionalEventListener;
14+
15+
import java.util.List;
16+
17+
@Slf4j
18+
@Service
19+
@RequiredArgsConstructor
20+
public class CarpoolDeletedEventHandler {
21+
private final FormRepository formRepository;
22+
23+
@Transactional(propagation = Propagation.REQUIRES_NEW)
24+
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
25+
public void rejectForms(CarpoolDeletedEvent carpoolDeletedEvent) {
26+
log.info("CarpoolDeletedEvent received");
27+
List<Form> forms = carpoolDeletedEvent.getForms();
28+
29+
for (Form form: forms) {
30+
if (form.getFormState() == FormState.REQUEST || form.getFormState() == FormState.ACCEPT) {
31+
form.reject();
32+
}
33+
form.disconnectCarpool();
34+
}
35+
formRepository.saveAllAndFlush(forms);
36+
}
37+
}

src/main/java/com/fullcar/carpool/application/form/FormMapper.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ public FormResponseDto toDto(Form form, Member member) {
3131
}
3232

3333
public FormResponseDto.FormDetailDto toDetailDto(Form form, Member member) {
34+
Long carpoolId;
35+
36+
if (form.getCarpoolId() != null) {
37+
carpoolId = form.getCarpoolId().getId();
38+
}
39+
else {
40+
carpoolId = null;
41+
}
42+
3443
return FormResponseDto.FormDetailDto.builder()
3544
.id(form.getFormId().getId())
3645
.pickupLocation(form.getPickupLocation())
@@ -42,7 +51,7 @@ public FormResponseDto.FormDetailDto toDetailDto(Form form, Member member) {
4251
.createdAt(form.getCreatedAt())
4352
.content(form.getContent())
4453
.resultMessage(form.getResultMessage())
45-
.carpoolId(form.getCarpoolId().getId())
54+
.carpoolId(carpoolId)
4655
.build();
4756
}
4857

src/main/java/com/fullcar/carpool/application/form/FormService.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,11 @@ public FormResponseDto requestForm(Member member, CarpoolId carpoolId, FormReque
6464
Form form = formMapper.toEntity(member, carpoolId, formRequestDto);
6565

6666
eventPublisher.publishEvent(
67-
new FormStateChangedEvent(
68-
NotificationDto.builder()
69-
.nickName(driver.getNickname())
70-
.deviceToken(driver.getDeviceToken())
71-
.title(FormMessage.REQUEST_TITLE.getMessage())
72-
.body(FormMessage.REQUEST_BODY.getMessage())
73-
.build()
74-
)
67+
FormStateChangedEvent.builder()
68+
.memberId(driver.getId())
69+
.title(FormMessage.REQUEST_TITLE.getMessage())
70+
.body(FormMessage.REQUEST_BODY.getMessage())
71+
.build()
7572
);
7673

7774
return formMapper.toDto(
@@ -114,14 +111,13 @@ public List<FormResponseDto> readReceivedFormList(Member member) {
114111
@Transactional
115112
public FormResponseDto.FormDetailDto updateForm(Member member, FormId formId, FormUpdateDto formUpdateDto) {
116113
Form form = formRepository.findByFormIdAndIsDeletedOrThrow(formId, false);
117-
Member passenger = memberRepository.findByIdAndIsDeletedOrThrow(form.getPassenger().getMemberId(), false);
118114
Carpool carpool = carpoolRepository.findByCarpoolIdAndIsDeletedOrThrow(form.getCarpoolId(), false);
119115

120116
if (!carpool.isMyCarpool(member.getId())) {
121117
throw new CustomException(ErrorCode.CANNOT_CHANGE_FORM_STATE);
122118
}
123119

124-
form.changeFormState(formUpdateDto, passenger);
120+
form.changeFormState(formUpdateDto);
125121

126122
return formMapper.toDetailDto(
127123
formRepository.saveAndFlush(form),
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.fullcar.carpool.application.form;
2+
3+
import com.fullcar.carpool.domain.form.event.FormStateChangedEvent;
4+
import com.fullcar.carpool.domain.service.NotificationService;
5+
import com.fullcar.carpool.infra.dto.NotificationDto;
6+
import com.fullcar.member.domain.member.MemberRepository;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.stereotype.Service;
10+
import org.springframework.transaction.annotation.Propagation;
11+
import org.springframework.transaction.annotation.Transactional;
12+
import org.springframework.transaction.event.TransactionPhase;
13+
import org.springframework.transaction.event.TransactionalEventListener;
14+
15+
@Slf4j
16+
@Service
17+
@RequiredArgsConstructor
18+
public class FormStateChangedEventHandler {
19+
private final NotificationService notificationService;
20+
private final MemberRepository memberRepository;
21+
22+
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
23+
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
24+
public void sendNotification(FormStateChangedEvent formStateChangedEvent) {
25+
log.info("FormStateChangedEvent received");
26+
notificationService.sendNotification(
27+
NotificationDto.builder()
28+
.member(
29+
memberRepository.findByIdAndIsDeletedOrThrow(formStateChangedEvent.getMemberId(), false)
30+
)
31+
.title(formStateChangedEvent.getTitle())
32+
.body(formStateChangedEvent.getBody())
33+
.build()
34+
);
35+
log.info("Notification send");
36+
}
37+
}

src/main/java/com/fullcar/carpool/domain/carpool/Carpool.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
package com.fullcar.carpool.domain.carpool;
22

3+
import com.fullcar.carpool.domain.carpool.event.CarpoolClosedEvent;
4+
import com.fullcar.carpool.domain.carpool.event.CarpoolDeletedEvent;
5+
import com.fullcar.carpool.domain.form.Form;
6+
import com.fullcar.carpool.domain.form.FormState;
7+
import com.fullcar.core.exception.CustomException;
8+
import com.fullcar.core.response.ErrorCode;
39
import com.fullcar.member.domain.member.MemberId;
410
import jakarta.persistence.*;
511
import lombok.*;
612
import org.springframework.data.annotation.CreatedDate;
713
import org.springframework.data.annotation.LastModifiedDate;
14+
import org.springframework.data.domain.AbstractAggregateRoot;
815
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
916

1017
import java.time.LocalDateTime;
18+
import java.util.List;
1119

1220
import static lombok.AccessLevel.PROTECTED;
1321

@@ -18,7 +26,7 @@
1826
@AllArgsConstructor(access = PROTECTED)
1927
@EntityListeners(AuditingEntityListener.class)
2028
@Table(name = "carpool")
21-
public class Carpool {
29+
public class Carpool extends AbstractAggregateRoot<Carpool> {
2230

2331
@EmbeddedId
2432
private CarpoolId carpoolId;
@@ -59,7 +67,28 @@ public boolean isMyCarpool(MemberId memberId) {
5967
return this.getDriver().getMemberId().getId().equals(memberId.getId());
6068
}
6169

62-
public void close() {
70+
public void close(List<Form> forms) {
71+
if (this.carpoolState == CarpoolState.CLOSE) {
72+
throw new CustomException(ErrorCode.ALREADY_CLOSED);
73+
}
6374
this.carpoolState = CarpoolState.CLOSE;
75+
registerEvent(
76+
new CarpoolClosedEvent(
77+
forms.stream()
78+
.filter(form -> form.getFormState() == FormState.REQUEST)
79+
.toList()
80+
)
81+
);
82+
}
83+
84+
public void delete(List<Form> forms) {
85+
if (this.carpoolState == CarpoolState.OPEN) {
86+
throw new CustomException(ErrorCode.CANNOT_DELETE_OPEN_CARPOOL);
87+
}
88+
89+
this.isDeleted = true;
90+
registerEvent(
91+
new CarpoolDeletedEvent(forms)
92+
);
6493
}
6594
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.fullcar.carpool.domain.carpool.event;
2+
3+
import com.fullcar.carpool.domain.form.Form;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
7+
import java.util.List;
8+
9+
@Getter
10+
@AllArgsConstructor
11+
public class CarpoolClosedEvent {
12+
private List<Form> forms;
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.fullcar.carpool.domain.carpool.event;
2+
3+
import com.fullcar.carpool.domain.form.Form;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
7+
import java.util.List;
8+
9+
@Getter
10+
@AllArgsConstructor
11+
public class CarpoolDeletedEvent {
12+
private List<Form> forms;
13+
}

src/main/java/com/fullcar/carpool/domain/form/Form.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,50 +63,52 @@ public class Form extends AbstractAggregateRoot<Form> {
6363
@LastModifiedDate
6464
private LocalDateTime updatedAt;
6565

66-
public void changeFormState(FormUpdateDto formUpdateDto, Member passenger) {
66+
public void changeFormState(FormUpdateDto formUpdateDto) {
6767
FormState formState = formUpdateDto.getFormState();
6868

6969
if (formState == FormState.ACCEPT) {
70-
this.accept(formUpdateDto.getContact(), formUpdateDto.getToPassenger(), passenger);
70+
this.accept(formUpdateDto.getContact(), formUpdateDto.getToPassenger());
7171
}
7272
else if (formState == FormState.REJECT) {
73-
this.reject(passenger);
73+
this.reject();
7474
}
7575
else {
7676
throw new CustomException(ErrorCode.INVALID_FORM_STATE);
7777
}
7878
}
7979

80-
public void accept(String contact, String toPassenger, Member passenger) {
80+
public void accept(String contact, String toPassenger) {
8181
this.formState = FormState.ACCEPT;
8282
this.resultMessage = ResultMessage.builder()
8383
.contact(contact)
8484
.toPassenger(toPassenger)
8585
.build();
8686

87-
registerEvent(new FormStateChangedEvent(
88-
NotificationDto.builder()
89-
.nickName(passenger.getNickname())
90-
.deviceToken(passenger.getDeviceToken())
87+
registerEvent(
88+
FormStateChangedEvent.builder()
89+
.memberId(this.passenger.getMemberId())
9190
.title(FormMessage.ACCEPT_TITLE.getMessage())
9291
.body(FormMessage.ACCEPT_BODY.getMessage())
9392
.build()
94-
));
93+
);
9594
}
9695

97-
public void reject(Member passenger) {
96+
public void reject() {
9897
this.formState = FormState.REJECT;
9998
this.resultMessage = ResultMessage.builder()
10099
.toPassenger(FormMessage.REJECT_MESSAGE.getMessage())
101100
.build();
102101

103-
registerEvent(new FormStateChangedEvent(
104-
NotificationDto.builder()
105-
.nickName(passenger.getNickname())
106-
.deviceToken(passenger.getDeviceToken())
102+
registerEvent(
103+
FormStateChangedEvent.builder()
104+
.memberId(this.passenger.getMemberId())
107105
.title(FormMessage.REJECT_TITLE.getMessage())
108106
.body(FormMessage.REJECT_BODY.getMessage())
109107
.build()
110-
));
108+
);
109+
}
110+
111+
public void disconnectCarpool() {
112+
this.carpoolId = null;
111113
}
112114
}
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
package com.fullcar.carpool.domain.form.event;
22

33
import com.fullcar.carpool.infra.dto.NotificationDto;
4+
import com.fullcar.member.domain.member.Member;
5+
import com.fullcar.member.domain.member.MemberId;
46
import lombok.AllArgsConstructor;
7+
import lombok.Builder;
58
import lombok.Getter;
9+
import lombok.NoArgsConstructor;
610

711
@Getter
12+
@Builder
13+
@NoArgsConstructor
814
@AllArgsConstructor
915
public class FormStateChangedEvent {
10-
private NotificationDto notificationDto;
16+
private MemberId memberId;
17+
18+
private String title;
19+
20+
private String body;
1121
}

0 commit comments

Comments
 (0)