Skip to content

Commit a406120

Browse files
authored
[DDING-87] 동아리 지원 폼지 삭제 API 구현 (#232)
1 parent 4612739 commit a406120

17 files changed

+214
-51
lines changed

src/main/java/ddingdong/ddingdongBE/common/exception/AuthenticationException.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ sealed public class AuthenticationException extends CustomException {
77
public static final String UNREGISTERED_ID_ERROR_MESSAGE = "등록되지 않은 ID입니다.";
88
public static final String INVALIDATED_PASSWORD_ERROR_MESSAGE = "잘못된 비밀번호입니다.";
99
public static final String NON_EXIST_USER_ROLE_ERROR_MESSAGE = "유저 권한이 존재하지 않습니다.";
10+
public static final String NON_HAVE_AUTHORITY_MESSAGE = "해당 유저에게 권한이 없습니다.";
1011

1112
public AuthenticationException(String message, int errorCode) {
1213
super(message, errorCode);
@@ -32,4 +33,11 @@ public NonExistUserRole() {
3233
super(NON_EXIST_USER_ROLE_ERROR_MESSAGE, UNAUTHORIZED.value());
3334
}
3435
}
36+
37+
public static final class NonHaveAuthority extends AuthenticationException {
38+
39+
public NonHaveAuthority() {
40+
super(NON_HAVE_AUTHORITY_MESSAGE, UNAUTHORIZED.value());
41+
}
42+
}
3543
}

src/main/java/ddingdong/ddingdongBE/domain/form/api/CentralFormApi.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
import io.swagger.v3.oas.annotations.responses.ApiResponse;
88
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
99
import io.swagger.v3.oas.annotations.tags.Tag;
10+
import jakarta.validation.Valid;
1011
import org.springframework.http.HttpStatus;
1112
import org.springframework.security.core.annotation.AuthenticationPrincipal;
13+
import org.springframework.web.bind.annotation.DeleteMapping;
1214
import org.springframework.web.bind.annotation.PathVariable;
1315
import org.springframework.web.bind.annotation.PostMapping;
1416
import org.springframework.web.bind.annotation.PutMapping;
@@ -26,7 +28,7 @@ public interface CentralFormApi {
2628
@SecurityRequirement(name = "AccessToken")
2729
@PostMapping("/my/forms")
2830
void createForm(
29-
@RequestBody CreateFormRequest createFormRequest,
31+
@Valid @RequestBody CreateFormRequest createFormRequest,
3032
@AuthenticationPrincipal PrincipalDetails principalDetails
3133
);
3234

@@ -36,7 +38,17 @@ void createForm(
3638
@SecurityRequirement(name = "AccessToken")
3739
@PutMapping("/my/forms/{formId}")
3840
void updateForm(
39-
@RequestBody UpdateFormRequest updateFormRequest,
41+
@Valid @RequestBody UpdateFormRequest updateFormRequest,
42+
@PathVariable("formId") Long formId,
43+
@AuthenticationPrincipal PrincipalDetails principalDetails
44+
);
45+
46+
@Operation(summary = "동아리 지원 폼지 삭제 API")
47+
@ApiResponse(responseCode = "204", description = "동아리 지원 폼지 삭제 성공")
48+
@ResponseStatus(HttpStatus.NO_CONTENT)
49+
@SecurityRequirement(name = "AccessToken")
50+
@DeleteMapping("/my/forms/{formId}")
51+
void deleteForm(
4052
@PathVariable("formId") Long formId,
4153
@AuthenticationPrincipal PrincipalDetails principalDetails
4254
);

src/main/java/ddingdong/ddingdongBE/domain/form/controller/CentralFormController.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,10 @@ public void updateForm(
3232
) {
3333
facadeCentralFormService.updateForm(updateFormRequest.toCommand(formId));
3434
}
35+
36+
@Override
37+
public void deleteForm(Long formId, PrincipalDetails principalDetails) {
38+
User user = principalDetails.getUser();
39+
facadeCentralFormService.deleteForm(formId, user);
40+
}
3541
}

src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
import ddingdong.ddingdongBE.domain.form.service.dto.command.CreateFormCommand;
44
import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand;
5+
import ddingdong.ddingdongBE.domain.user.entity.User;
56

67
public interface FacadeCentralFormService {
78

89
void createForm(CreateFormCommand command);
910

1011
void updateForm(UpdateFormCommand command);
12+
13+
void deleteForm(Long formId, User user);
1114
}

src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package ddingdong.ddingdongBE.domain.form.service;
22

3+
import ddingdong.ddingdongBE.common.exception.AuthenticationException.NonHaveAuthority;
34
import ddingdong.ddingdongBE.domain.club.entity.Club;
45
import ddingdong.ddingdongBE.domain.club.service.ClubService;
56
import ddingdong.ddingdongBE.domain.form.entity.Form;
@@ -8,7 +9,9 @@
89
import ddingdong.ddingdongBE.domain.form.service.dto.command.CreateFormCommand.CreateFormFieldCommand;
910
import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand;
1011
import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand.UpdateFormFieldCommand;
12+
import ddingdong.ddingdongBE.domain.user.entity.User;
1113
import java.util.List;
14+
import java.util.Objects;
1215
import lombok.RequiredArgsConstructor;
1316
import org.springframework.stereotype.Service;
1417
import org.springframework.transaction.annotation.Transactional;
@@ -47,6 +50,21 @@ public void updateForm(UpdateFormCommand updateFormCommand) {
4750
formFieldService.createAll(updateFormFields);
4851
}
4952

53+
@Transactional
54+
@Override
55+
public void deleteForm(Long formId, User user) {
56+
Club club = clubService.getByUserId(user.getId());
57+
Form form = formService.getById(formId);
58+
validateEqualsClub(club, form);
59+
formService.delete(form); //테이블 생성 시 외래 키에 cascade 설정하여 formField 삭제도 자동으로 됨.
60+
}
61+
62+
private void validateEqualsClub(Club club, Form form) {
63+
if (!Objects.equals(club.getId(), form.getClub().getId())) {
64+
throw new NonHaveAuthority();
65+
}
66+
}
67+
5068
private List<FormField> toUpdateFormFields(Form originform, List<UpdateFormFieldCommand> updateFormFieldCommands) {
5169
return updateFormFieldCommands.stream()
5270
.map(formFieldCommand -> formFieldCommand.toEntity(originform))

src/main/java/ddingdong/ddingdongBE/domain/form/service/FormService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ public interface FormService {
77
Form create(Form form);
88

99
Form getById(Long formId);
10+
11+
void delete(Form form);
1012
}

src/main/java/ddingdong/ddingdongBE/domain/form/service/GeneralFormFieldService.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package ddingdong.ddingdongBE.domain.form.service;
22

3+
import ddingdong.ddingdongBE.common.exception.PersistenceException.ResourceNotFound;
34
import ddingdong.ddingdongBE.domain.form.entity.Form;
45
import ddingdong.ddingdongBE.domain.form.entity.FormField;
56
import ddingdong.ddingdongBE.domain.form.repository.FormFieldRepository;
67
import java.util.List;
7-
import java.util.Optional;
8-
98
import lombok.RequiredArgsConstructor;
109
import org.springframework.stereotype.Service;
1110
import org.springframework.transaction.annotation.Transactional;
@@ -27,8 +26,9 @@ public void createAll(List<FormField> formFields) {
2726
@Override
2827
public FormField getById(Long id) {
2928
return formFieldRepository.findById(id)
30-
.orElseThrow(() -> new IllegalArgumentException("해당 field를 id로 찾을 수 없습니다: " + id));
31-
29+
.orElseThrow(() -> new ResourceNotFound("FormField(fieldId=" + id + ")를 찾을 수 없습니다."));
30+
}
31+
3232
@Override
3333
public List<FormField> findAllByForm(Form form) {
3434
return formFieldRepository.findAllByForm(form);

src/main/java/ddingdong/ddingdongBE/domain/form/service/GeneralFormService.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,10 @@ public Form getById(Long formId) {
2525
return formRepository.findById(formId)
2626
.orElseThrow(() -> new ResourceNotFound("Form(formId=" + formId + ")를 찾을 수 없습니다."));
2727
}
28+
29+
@Transactional
30+
@Override
31+
public void delete(Form form) {
32+
formRepository.delete(form);
33+
}
2834
}

src/main/java/ddingdong/ddingdongBE/domain/formapplicaion/controller/UserFormController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ public class UserFormController implements UserFormApi {
1414

1515
@Override
1616
public void createFormResponse(Long formId, CreateFormApplicationRequest createFormApplicationRequest) {
17-
facadeUserFormService.createFormApplication(formId, createFormApplicationRequest.toCommand());
17+
facadeUserFormService.createFormApplication(createFormApplicationRequest.toCommand(formId));
1818
}
1919
}

src/main/java/ddingdong/ddingdongBE/domain/formapplicaion/controller/dto/request/CreateFormApplicationRequest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ public CreateFormAnswerCommand toCommand() {
4242
}
4343
}
4444

45-
public CreateFormApplicationCommand toCommand() {
45+
public CreateFormApplicationCommand toCommand(Long formId) {
4646
List<CreateFormAnswerCommand> createFormAnswerCommands = formAnswers.stream()
4747
.map(CreateFormAnswerRequest::toCommand)
4848
.toList();
4949
return CreateFormApplicationCommand.builder()
50+
.formId(formId)
5051
.name(name)
5152
.studentNumber(studentNumber)
5253
.department(department)

src/main/java/ddingdong/ddingdongBE/domain/formapplicaion/entity/FormAnswer.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@
22

33
import ddingdong.ddingdongBE.common.BaseEntity;
44
import ddingdong.ddingdongBE.common.converter.StringListConverter;
5-
import ddingdong.ddingdongBE.domain.form.entity.FieldType;
65
import ddingdong.ddingdongBE.domain.form.entity.FormField;
7-
import jakarta.persistence.*;
6+
import jakarta.persistence.Convert;
7+
import jakarta.persistence.Entity;
8+
import jakarta.persistence.FetchType;
9+
import jakarta.persistence.GeneratedValue;
10+
import jakarta.persistence.GenerationType;
11+
import jakarta.persistence.Id;
12+
import jakarta.persistence.JoinColumn;
13+
import jakarta.persistence.ManyToOne;
14+
import java.util.List;
815
import lombok.AccessLevel;
916
import lombok.Builder;
1017
import lombok.Getter;
1118
import lombok.NoArgsConstructor;
12-
import java.util.List;
1319

1420
@Entity
1521
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@@ -20,13 +26,14 @@ public class FormAnswer extends BaseEntity {
2026
@GeneratedValue(strategy = GenerationType.IDENTITY)
2127
private Long id;
2228

23-
@Column(nullable = false)
2429
@Convert(converter = StringListConverter.class)
2530
private List<String> value;
2631

32+
@JoinColumn(name = "application_id")
2733
@ManyToOne(fetch = FetchType.LAZY)
2834
private FormApplication formApplication;
2935

36+
@JoinColumn(name = "field_id")
3037
@ManyToOne(fetch = FetchType.LAZY)
3138
private FormField formField;
3239

src/main/java/ddingdong/ddingdongBE/domain/formapplicaion/service/FacadeUserFormService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44

55
public interface FacadeUserFormService {
66

7-
void createFormApplication(Long formId, CreateFormApplicationCommand createFormApplicationCommand);
7+
void createFormApplication(CreateFormApplicationCommand createFormApplicationCommand);
88

99
}
Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
package ddingdong.ddingdongBE.domain.formapplicaion.service;
22

33
import ddingdong.ddingdongBE.domain.form.entity.Form;
4-
import ddingdong.ddingdongBE.domain.formapplicaion.entity.FormAnswer;
5-
import ddingdong.ddingdongBE.domain.form.entity.FormField;
6-
import ddingdong.ddingdongBE.domain.formapplicaion.entity.FormApplication;
74
import ddingdong.ddingdongBE.domain.form.service.FormFieldService;
85
import ddingdong.ddingdongBE.domain.form.service.FormService;
6+
import ddingdong.ddingdongBE.domain.formapplicaion.entity.FormAnswer;
7+
import ddingdong.ddingdongBE.domain.formapplicaion.entity.FormApplication;
98
import ddingdong.ddingdongBE.domain.formapplicaion.service.dto.CreateFormApplicationCommand;
109
import ddingdong.ddingdongBE.domain.formapplicaion.service.dto.CreateFormApplicationCommand.CreateFormAnswerCommand;
10+
import java.util.List;
1111
import lombok.RequiredArgsConstructor;
1212
import org.springframework.stereotype.Service;
1313
import org.springframework.transaction.annotation.Transactional;
1414

15-
import java.util.List;
16-
1715
@Service
1816
@RequiredArgsConstructor
1917
@Transactional(readOnly = true)
@@ -26,21 +24,22 @@ public class FacadeUserFormServiceImpl implements FacadeUserFormService {
2624

2725
@Transactional
2826
@Override
29-
public void createFormApplication(Long formId, CreateFormApplicationCommand createFormApplicationCommand) {
30-
Form form = formService.getById(formId);
27+
public void createFormApplication(CreateFormApplicationCommand createFormApplicationCommand) {
28+
Form form = formService.getById(createFormApplicationCommand.formId());
3129
FormApplication formApplication = createFormApplicationCommand.toEntity(form);
3230
FormApplication savedFormApplication = formApplicationService.create(formApplication);
3331

3432
List<FormAnswer> formAnswers = toFormAnswers(savedFormApplication, createFormApplicationCommand.formAnswerCommands());
3533
formAnswerService.createAll(formAnswers);
3634
}
3735

38-
private List<FormAnswer> toFormAnswers(FormApplication savedFormApplication, List<CreateFormAnswerCommand> createFormAnswerCommands) {
36+
private List<FormAnswer> toFormAnswers(
37+
FormApplication savedFormApplication,
38+
List<CreateFormAnswerCommand> createFormAnswerCommands
39+
) {
3940
return createFormAnswerCommands.stream()
40-
.map(formAnswerCommand -> {
41-
FormField formField = formFieldService.getById(formAnswerCommand.fieldId());
42-
return formAnswerCommand.toEntity(savedFormApplication, formField);
43-
})
41+
.map(formAnswerCommand
42+
-> formAnswerCommand.toEntity(savedFormApplication, formFieldService.getById(formAnswerCommand.fieldId())))
4443
.toList();
4544
}
4645
}

src/main/java/ddingdong/ddingdongBE/domain/formapplicaion/service/dto/CreateFormApplicationCommand.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
package ddingdong.ddingdongBE.domain.formapplicaion.service.dto;
22

3-
import ddingdong.ddingdongBE.domain.form.entity.FieldType;
43
import ddingdong.ddingdongBE.domain.form.entity.Form;
5-
import ddingdong.ddingdongBE.domain.formapplicaion.entity.FormAnswer;
64
import ddingdong.ddingdongBE.domain.form.entity.FormField;
5+
import ddingdong.ddingdongBE.domain.formapplicaion.entity.FormAnswer;
76
import ddingdong.ddingdongBE.domain.formapplicaion.entity.FormApplication;
87
import ddingdong.ddingdongBE.domain.formapplicaion.entity.FormApplicationStatus;
9-
import lombok.Builder;
10-
118
import java.util.List;
9+
import lombok.Builder;
1210

1311
@Builder
1412
public record CreateFormApplicationCommand(
15-
Form form,
13+
Long formId,
1614
String name,
1715
String studentNumber,
1816
String department,
@@ -22,8 +20,7 @@ public record CreateFormApplicationCommand(
2220
@Builder
2321
public record CreateFormAnswerCommand(
2422
Long fieldId,
25-
List<String> value,
26-
FieldType valueType
23+
List<String> value
2724
) {
2825
public FormAnswer toEntity(FormApplication formApplication, FormField formField) {
2926
return FormAnswer.builder()
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
1-
CREATE TABLE form_response
1+
CREATE TABLE form_application
22
(
33
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
4-
submitted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
54
name VARCHAR(50) NOT NULL,
65
student_number VARCHAR(50) NOT NULL,
76
status VARCHAR(50) NOT NULL,
87
form_id BIGINT,
98
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL,
109
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NULL,
11-
CONSTRAINT fk_response_form FOREIGN KEY (form_id) REFERENCES form (id) ON DELETE CASCADE
10+
CONSTRAINT fk_application_form FOREIGN KEY (form_id) REFERENCES form (id) ON DELETE CASCADE
1211
);
1312

1413
CREATE TABLE form_answer
1514
(
1615
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
17-
value VARCHAR(1500) NULL,
18-
value_type VARCHAR(50) NOT NULL,
19-
response_id BIGINT,
16+
value TEXT NULL,
17+
application_id BIGINT,
2018
field_id BIGINT,
2119
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL,
2220
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NULL,
23-
CONSTRAINT fk_answer_response FOREIGN KEY (response_id) REFERENCES form_response (id) ON DELETE CASCADE,
21+
CONSTRAINT fk_answer_application FOREIGN KEY (application_id) REFERENCES form_application (id) ON DELETE CASCADE,
2422
CONSTRAINT fk_answer_field FOREIGN KEY (field_id) REFERENCES form_field (id) ON DELETE CASCADE
2523
);

0 commit comments

Comments
 (0)