Skip to content

Commit d16342d

Browse files
committed
[feat] 위키 수정 이력 관리 로직 변경 및 관련 API 수정
1 parent ee87248 commit d16342d

9 files changed

Lines changed: 140 additions & 33 deletions

File tree

src/main/java/kr/dgucaps/caps/domain/member/entity/Member.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import jakarta.persistence.*;
44
import kr.dgucaps.caps.domain.common.entity.BaseTimeEntity;
55
import kr.dgucaps.caps.domain.wiki.entity.Wiki;
6+
import kr.dgucaps.caps.domain.wiki.entity.WikiHistory;
67
import lombok.AccessLevel;
78
import lombok.Builder;
89
import lombok.Getter;
@@ -87,6 +88,9 @@ public Member(String kakaoId, String name, String email, String phoneNumber, Str
8788
@OneToMany(mappedBy = "member")
8889
List<Wiki> wikis = new ArrayList<>();
8990

91+
@OneToMany(mappedBy = "member")
92+
List<WikiHistory> wikiHistories = new ArrayList<>();
93+
9094
public void completeRegistration(String studentNumber, float grade) {
9195
this.studentNumber = studentNumber;
9296
this.grade = grade;

src/main/java/kr/dgucaps/caps/domain/wiki/controller/WikiApi.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,27 @@
2121
public interface WikiApi {
2222

2323
@Operation(
24-
summary = "위키 작성 & 수정",
25-
description = "위키를 작성하거나 수정합니다. \n" +
26-
"title이 존재하지 않으면 새로 작성하고, 존재하면 수정합니다."
24+
summary = "위키 작성",
25+
description = "위키를 작성합니다."
2726
)
28-
@ApiResponse(responseCode = "200", description = "위키 작성/수정 성공",
27+
@ApiResponse(responseCode = "200", description = "위키 작성 성공",
2928
content = @Content(mediaType = "application/json",
3029
schema = @Schema(implementation = WikiResponse.class))
3130
)
3231
ResponseEntity<SuccessResponse<?>> createWiki(@AuthenticationPrincipal Long memberId,
3332
@Valid @RequestBody CreateOrModifyWikiRequest request);
3433

34+
@Operation(
35+
summary = "위키 수정",
36+
description = "위키를 수정합니다."
37+
)
38+
@ApiResponse(responseCode = "200", description = "위키 수정 성공",
39+
content = @Content(mediaType = "application/json",
40+
schema = @Schema(implementation = WikiResponse.class))
41+
)
42+
ResponseEntity<SuccessResponse<?>> modifyWiki(@AuthenticationPrincipal Long memberId,
43+
@Valid @RequestBody CreateOrModifyWikiRequest request);
44+
3545
@Operation(
3646
summary = "위키 조회",
3747
description = "title에 해당하는 위키를 조회합니다."

src/main/java/kr/dgucaps/caps/domain/wiki/controller/WikiController.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,14 @@ public class WikiController implements WikiApi {
2121
@PostMapping
2222
public ResponseEntity<SuccessResponse<?>> createWiki(@AuthenticationPrincipal Long memberId,
2323
@Valid @RequestBody CreateOrModifyWikiRequest request) {
24-
return SuccessResponse.ok(wikiService.createOrModifyWiki(memberId, request));
24+
return SuccessResponse.ok(wikiService.createWiki(memberId, request));
25+
}
26+
27+
@PreAuthorize("hasAnyRole('MEMBER', 'GRADUATE', 'COUNCIL', 'PRESIDENT', 'ADMIN')")
28+
@PatchMapping
29+
public ResponseEntity<SuccessResponse<?>> modifyWiki(@AuthenticationPrincipal Long memberId,
30+
@Valid @RequestBody CreateOrModifyWikiRequest request) {
31+
return SuccessResponse.ok(wikiService.modifyWiki(memberId, request));
2532
}
2633

2734
@GetMapping("/{title}")

src/main/java/kr/dgucaps/caps/domain/wiki/dto/response/WikiResponse.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import kr.dgucaps.caps.domain.dto.MemberSummary;
44
import kr.dgucaps.caps.domain.wiki.entity.Wiki;
5+
import kr.dgucaps.caps.domain.wiki.entity.WikiHistory;
56
import lombok.Builder;
67

78
import java.time.LocalDateTime;
@@ -10,15 +11,27 @@
1011
public record WikiResponse(
1112
String title,
1213
String content,
13-
MemberSummary editor,
14-
LocalDateTime createdAt
14+
MemberSummary member,
15+
LocalDateTime createdAt,
16+
LocalDateTime updatedAt
1517
) {
1618
public static WikiResponse from(Wiki wiki) {
1719
return WikiResponse.builder()
1820
.title(wiki.getTitle())
1921
.content(wiki.getContent())
20-
.editor(MemberSummary.from(wiki.getMember()))
22+
.member(MemberSummary.from(wiki.getMember()))
2123
.createdAt(wiki.getCreatedAt())
24+
.updatedAt(wiki.getUpdatedAt())
25+
.build();
26+
}
27+
28+
public static WikiResponse from(WikiHistory wikiHistory) {
29+
return WikiResponse.builder()
30+
.title(wikiHistory.getTitle())
31+
.content(wikiHistory.getContent())
32+
.member(MemberSummary.from(wikiHistory.getMember()))
33+
.createdAt(wikiHistory.getCreatedAt())
34+
.updatedAt(wikiHistory.getUpdatedAt())
2235
.build();
2336
}
2437
}

src/main/java/kr/dgucaps/caps/domain/wiki/entity/Wiki.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
import lombok.Builder;
99
import lombok.Getter;
1010
import lombok.NoArgsConstructor;
11-
import org.hibernate.annotations.ColumnDefault;
12-
import org.hibernate.annotations.SQLDelete;
11+
12+
import java.util.ArrayList;
13+
import java.util.List;
1314

1415
@Entity
1516
@Getter
1617
@Table(name = "wiki")
1718
@NoArgsConstructor(access = AccessLevel.PROTECTED)
18-
@SQLDelete(sql = "UPDATE wiki SET is_deleted = true WHERE id = ?")
1919
public class Wiki extends BaseTimeEntity {
2020

2121
@Id
@@ -36,10 +36,6 @@ public class Wiki extends BaseTimeEntity {
3636
@Column(nullable = true)
3737
private String jamo;
3838

39-
@Column(nullable = false)
40-
@ColumnDefault("false")
41-
private boolean isDeleted;
42-
4339
@PrePersist
4440
public void initJamo(){
4541
this.jamo = WikiJamoUtils.convertToJamo(this.title);
@@ -50,7 +46,15 @@ public Wiki(Member member, String title, String content) {
5046
this.member = member;
5147
this.title = title;
5248
this.content = content;
53-
this.isDeleted = false;
49+
}
50+
51+
@OneToMany(mappedBy = "wiki")
52+
private List<WikiHistory> wikiHistories = new ArrayList<>();
53+
54+
public void updateWiki(Member member, String title, String content) {
55+
this.member = member;
56+
this.title = title;
57+
this.content = content;
5458
}
5559

5660
// 배포 후 false로 변경
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package kr.dgucaps.caps.domain.wiki.entity;
2+
3+
import jakarta.persistence.*;
4+
import kr.dgucaps.caps.domain.common.entity.BaseTimeEntity;
5+
import kr.dgucaps.caps.domain.member.entity.Member;
6+
import lombok.AccessLevel;
7+
import lombok.Builder;
8+
import lombok.Getter;
9+
import lombok.NoArgsConstructor;
10+
11+
@Entity
12+
@Getter
13+
@Table(name = "wiki_history")
14+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
15+
public class WikiHistory extends BaseTimeEntity {
16+
17+
@Id
18+
@GeneratedValue(strategy = GenerationType.IDENTITY)
19+
private Long id;
20+
21+
@ManyToOne(fetch = FetchType.LAZY)
22+
@JoinColumn(name = "wiki_id", nullable = false)
23+
private Wiki wiki;
24+
25+
@ManyToOne(fetch = FetchType.LAZY)
26+
@JoinColumn(name = "member_id", nullable = false)
27+
private Member member;
28+
29+
@Column(nullable = false)
30+
private String title;
31+
32+
@Column(nullable = false, columnDefinition = "TEXT")
33+
private String content;
34+
35+
@Builder
36+
public WikiHistory(Wiki wiki, Member member, String title, String content) {
37+
this.wiki = wiki;
38+
this.member = member;
39+
this.title = title;
40+
this.content = content;
41+
}
42+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package kr.dgucaps.caps.domain.wiki.repository;
2+
3+
import kr.dgucaps.caps.domain.wiki.entity.WikiHistory;
4+
import org.springframework.data.jpa.repository.EntityGraph;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
7+
import java.util.List;
8+
9+
public interface WikiHistoryRepository extends JpaRepository<WikiHistory, Long> {
10+
11+
@EntityGraph(attributePaths = {"member"})
12+
List<WikiHistory> findByTitleOrderByCreatedAtDesc(String title);
13+
}

src/main/java/kr/dgucaps/caps/domain/wiki/repository/WikiRepository.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package kr.dgucaps.caps.domain.wiki.repository;
22

33
import kr.dgucaps.caps.domain.wiki.entity.Wiki;
4+
import org.springframework.data.jpa.repository.EntityGraph;
45
import org.springframework.data.jpa.repository.JpaRepository;
56
import org.springframework.data.jpa.repository.Query;
67
import org.springframework.stereotype.Repository;
@@ -11,18 +12,13 @@
1112
@Repository
1213
public interface WikiRepository extends JpaRepository<Wiki, Long> {
1314

14-
boolean existsByTitleAndIsDeletedFalse(String title);
15+
@EntityGraph(attributePaths = {"member"})
16+
Optional<Wiki> findByTitle(String title);
1517

16-
void deleteByTitleAndIsDeletedFalse(String title);
17-
18-
Optional<Wiki> findByTitleAndIsDeletedFalse(String title);
19-
20-
List<Wiki> findByTitleOrderByCreatedAtDesc(String title);
21-
22-
@Query("SELECT w FROM Wiki w WHERE w.isDeleted = false ORDER BY RAND() LIMIT 1")
18+
@Query("SELECT w FROM Wiki w ORDER BY RAND() LIMIT 1")
2319
Optional<Wiki> findRandomWiki();
2420

25-
List<Wiki> findFirst10ByIsDeletedFalseOrderByCreatedAtDesc();
21+
List<Wiki> findFirst10ByOrderByUpdatedAtDesc();
2622

2723
List<Wiki> findByJamoStartsWith(String jamo);
2824

src/main/java/kr/dgucaps/caps/domain/wiki/service/WikiService.java

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import kr.dgucaps.caps.domain.wiki.dto.response.WikiResponse;
77
import kr.dgucaps.caps.domain.wiki.dto.response.WikiTitleResponse;
88
import kr.dgucaps.caps.domain.wiki.entity.Wiki;
9+
import kr.dgucaps.caps.domain.wiki.entity.WikiHistory;
10+
import kr.dgucaps.caps.domain.wiki.repository.WikiHistoryRepository;
911
import kr.dgucaps.caps.domain.wiki.repository.WikiRepository;
1012
import kr.dgucaps.caps.domain.wiki.util.WikiJamoUtils;
1113
import kr.dgucaps.caps.global.error.ErrorCode;
@@ -24,27 +26,43 @@ public class WikiService {
2426

2527
private final WikiRepository wikiRepository;
2628
private final MemberRepository memberRepository;
29+
private final WikiHistoryRepository wikiHistoryRepository;
2730

2831
@Transactional
29-
public WikiResponse createOrModifyWiki(Long memberId, CreateOrModifyWikiRequest request) {
30-
if (wikiRepository.existsByTitleAndIsDeletedFalse(request.title())) {
31-
wikiRepository.deleteByTitleAndIsDeletedFalse(request.title());
32-
}
32+
public WikiResponse createWiki(Long memberId, CreateOrModifyWikiRequest request) {
3333
Member member = memberRepository.findById(memberId)
3434
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.MEMBER_NOT_FOUND));
3535
Wiki savedWiki = wikiRepository.save(request.toEntity(member));
3636
return WikiResponse.from(savedWiki);
3737
}
3838

39+
@Transactional
40+
public WikiResponse modifyWiki(Long memberId, CreateOrModifyWikiRequest request) {
41+
Member member = memberRepository.findById(memberId)
42+
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.MEMBER_NOT_FOUND));
43+
Wiki wiki = wikiRepository.findByTitle(request.title())
44+
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.WIKI_NOT_FOUND));
45+
WikiHistory wikiHistory = WikiHistory.builder()
46+
.wiki(wiki)
47+
.member(wiki.getMember())
48+
.title(wiki.getTitle())
49+
.content(wiki.getContent())
50+
.build();
51+
wikiHistoryRepository.save(wikiHistory);
52+
wiki.updateWiki(member, request.title(), request.content());
53+
Wiki updatedWiki = wikiRepository.save(wiki);
54+
return WikiResponse.from(updatedWiki);
55+
}
56+
3957
public WikiResponse getWiki(String title) {
40-
Wiki wiki = wikiRepository.findByTitleAndIsDeletedFalse(title)
58+
Wiki wiki = wikiRepository.findByTitle(title)
4159
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.WIKI_NOT_FOUND));
4260
return WikiResponse.from(wiki);
4361
}
4462

4563
public List<WikiResponse> getWikiHistory(String title) {
46-
List<Wiki> wikiHistory = wikiRepository.findByTitleOrderByCreatedAtDesc(title);
47-
return wikiHistory.stream()
64+
List<WikiHistory> wikiHistories = wikiHistoryRepository.findByTitleOrderByCreatedAtDesc(title);
65+
return wikiHistories.stream()
4866
.map(WikiResponse::from)
4967
.collect(Collectors.toList());
5068
}
@@ -56,7 +74,7 @@ public WikiResponse getRandomWiki() {
5674
}
5775

5876
public List<WikiTitleResponse> getRecentWiki() {
59-
List<Wiki> recentWikis = wikiRepository.findFirst10ByIsDeletedFalseOrderByCreatedAtDesc();
77+
List<Wiki> recentWikis = wikiRepository.findFirst10ByOrderByUpdatedAtDesc();
6078
return recentWikis.stream()
6179
.map(WikiTitleResponse::from)
6280
.collect(Collectors.toList());

0 commit comments

Comments
 (0)