Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
c4960b6
docs : ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ ๋ฌธ์„œ ์ž‘์„ฑ
chanani Nov 25, 2025
a117751
docs : ๋‚˜์˜ ํ•™์Šต ๋ชฉํ‘œ, PR์ „ ํ™•์ธํ•ด์•ผํ•  ๋ชฉ๋ก ์ž‘์„ฑ(ํ˜ธ์„ฑ๋‹˜์ด ์ž‘์„ฑํ•œ ๋‚ด์šฉ์— ๊ฐ๋ช… ๋ฐ›์•„ ์ €๋„ ๊ด€๋ฆฌํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.)
chanani Nov 25, 2025
3cdb2ed
refactor : Question ๊ฐ์ฒด์— ์งˆ๋ฌธ ์‚ญ์ œ ๊ถŒํ•œ ์ฒดํฌ ๋ฉ”์„œ๋“œ ์ƒ์„ฑ ๋ฐ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ, Answer ๊ฐ์ฒด์— ์‚ญ์ œโ€ฆ
chanani Nov 25, 2025
9c9d031
refactor : Question ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜(answer) ํ™œ์šฉํ•ด ์ง์ ‘ Answer ๊ฐ์ฒด์˜ validateAnsโ€ฆ
chanani Nov 25, 2025
625a895
refactor : ์งˆ๋ฌธ, ๋‹ต๋ณ€ ์‚ญ์ œ ๋กœ์ง Question ๊ฐ์ฒด๋กœ ์ด๋™(Deleted ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋กœ์ง์ด ํฌํ•จ๋˜์–ด ์žˆ์–ด์„œ โ€ฆ
chanani Nov 25, 2025
188c9d7
refactor : Question ํด๋ž˜์Šค์˜ List<Answer> ๋ณ€์ˆ˜ ํฌ์žฅ
chanani Nov 25, 2025
8312ece
docs : ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋‚ด์šฉ Todo ์ถ”๊ฐ€
chanani Nov 26, 2025
f1b3547
refactor : ๊ณต๋™์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” createdDate, updatedDate, delted๋ฅผ BaseModel๋กœ ๋ถ„๋ฆฌ
chanani Nov 26, 2025
54e1f6d
refactor : title, contents ๊ฐ์ฒด ํฌ์žฅ
chanani Nov 26, 2025
c4db9bd
refactor : delete() ๋ฉ”์„œ๋“œ ํŒŒ๋ผ๋ฏธํ„ฐ ์ œ๊ฑฐ ๋ฐ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ˆ˜์ •
chanani Nov 26, 2025
400b772
refactor : ๊ฒ€์ฆํ•˜๋Š” ๋กœ์ง๊ณผ ์ƒํƒœ ๋ณ€๊ฒฝํ•˜๋Š” ๋กœ์ง์„ ํ•จ๊ป˜ ๊ตฌํ˜„,
chanani Nov 26, 2025
73effd2
feat : Answers ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ƒ์„ฑ
chanani Nov 26, 2025
797023c
refactor : updateDeleted() ๋ฉ”์„œ๋“œ private์œผ๋กœ ๋ณ€๊ฒฝ, ํ˜ธ์ถœํ•˜๋Š” ์œ„์น˜ ๋ณ€๊ฒฝ ๋ฐ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ˆ˜์ •
chanani Nov 27, 2025
660f24f
refactor : BaseModel ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ private๋กœ ๋ณ€๊ฒฝ, ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ protected๋กœ ์„ ์–ธ โ€ฆ
chanani Nov 27, 2025
22a45a9
refactor : BaseModel ํด๋ž˜์Šค๋ช… ๋ณ€๊ฒฝ
chanani Nov 27, 2025
aa75be9
refactor : Title, Contents ํด๋ž˜์Šค ์ œ๊ฑฐ ํ›„ ๊ณต์šฉ์œผ๋กœ ์‚ฌ์šฉํ•  QuestionBody ํด๋ž˜์Šค ์ƒ์„ฑ
chanani Nov 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# ํ•™์Šต ๊ด€๋ฆฌ ์‹œ์Šคํ…œ(Learning Management System)

## ๋‹จ๊ณ„๋ณ„ ๋ฌธ์„œ
- [๐Ÿš€ 1๋‹จ๊ณ„ - ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ ๋ฆฌํŒฉํ„ฐ๋ง](./docs/01-refactoring.md)

## ์ง„ํ–‰ ๋ฐฉ๋ฒ•
* ํ•™์Šต ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์˜ ์ˆ˜๊ฐ•์‹ ์ฒญ ์š”๊ตฌ์‚ฌํ•ญ์„ ํŒŒ์•…ํ•œ๋‹ค.
* ์š”๊ตฌ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๊ตฌํ˜„์„ ์™„๋ฃŒํ•œ ํ›„ ์ž์‹ ์˜ github ์•„์ด๋””์— ํ•ด๋‹นํ•˜๋Š” ๋ธŒ๋žœ์น˜์— Pull Request(์ดํ•˜ PR)๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ๋ฆฌ๋ทฐ ์š”์ฒญ์„ ํ•œ๋‹ค.
Expand Down
37 changes: 37 additions & 0 deletions docs/01-refactoring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# ๐Ÿš€ 1๋‹จ๊ณ„ - ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ ๋ฆฌํŒฉํ„ฐ๋ง
***

## ์ฝ”๋“œ ๋ฆฌ๋ทฐ
> PR ๋งํฌ : [#790](https://github.com/next-step/java-lms/pull/790)

## ๋‚˜์˜ ํ•™์Šต ๋ชฉํ‘œ
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿ‘


### 1. TDD ์‚ฌ์ดํด์„ ์˜์‹ํ•˜๋ฉฐ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค.
- `์‹คํŒจ โ†’ ์„ฑ๊ณต โ†’ ๋ฆฌํŒฉํ„ฐ๋ง` ๊ณผ์ •์œผ๋กœ ์ž‘์—…ํ•œ๋‹ค.
- ์Šต๊ด€์ฒ˜๋Ÿผ ์ด ๊ณผ์ •์„ ์ง€๋‚˜์น˜๋ฉด, ๋‹ค์‹œ ๋Œ์•„์™€ ์‚ฌ์ดํด์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
- TDD ์‚ฌ์ดํด ์Šต๊ด€์„ ๋งŒ๋“ค์ž.

### 2. ๋„๋ฉ”์ธ์— ํŠนํ™”๋œ ์ด๋ฆ„์„ ์ง“๋Š”๋‹ค.
- AI์—๊ฒŒ ์ถ”์ฒœ ๋ฐ›๋Š” ์Šต๊ด€์„ ๋งŒ๋“ค์ž.

### 3. ๋ฐ˜๋ณต๋œ ํ”ผ๋“œ๋ฐฑ์€ ํ”ผํ•˜์ž.
- ๊ฐ™์€ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜๋ณตํ•˜์ง€ ์•Š๋„๋ก, ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์ ๊ฒ€ํ•˜์ž.

## ์งˆ๋ฌธ ์‚ญ์ œํ•˜๊ธฐ ์š”๊ตฌ์‚ฌํ•ญ

- [x] ์งˆ๋ฌธ ๋ฐ์ดํ„ฐ๋ฅผ ์™„์ „ํžˆ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ฐ์ดํ„ฐ์˜ ์ƒํƒœ๋ฅผ ์‚ญ์ œ ์ƒํƒœ(deleted - boolean type)๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.
- [x] ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์™€ ์งˆ๋ฌธํ•œ ์‚ฌ๋žŒ์ด ๊ฐ™์€ ๊ฒฝ์šฐ ์‚ญ์ œ ๊ฐ€๋Šฅํ•˜๋‹ค.
- [x] ๋‹ต๋ณ€์ด ์—†๋Š” ๊ฒฝ์šฐ ์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
- [x] ์งˆ๋ฌธ์ž์™€ ๋‹ต๋ณ€ ๊ธ€์˜ ๋ชจ๋“  ๋‹ต๋ณ€์ž๊ฐ€ ๊ฐ™์€ ๊ฒฝ์šฐ ์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
- [x] ์งˆ๋ฌธ์„ ์‚ญ์ œํ•  ๋•Œ ๋‹ต๋ณ€ ๋˜ํ•œ ์‚ญ์ œํ•ด์•ผ ํ•˜๋ฉฐ, ๋‹ต๋ณ€์˜ ์‚ญ์ œ ๋˜ํ•œ ์‚ญ์ œ ์ƒํƒœ(deleted)๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.
- [x] ์งˆ๋ฌธ์ž์™€ ๋‹ต๋ณ€์ž๊ฐ€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ ๋‹ต๋ณ€์„ ์‚ญ์ œํ•  ์ˆ˜ ์—†๋‹ค.
- [x] ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€ ์‚ญ์ œ ์ด๋ ฅ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ DeleteHistory๋ฅผ ํ™œ์šฉํ•ด ๋‚จ๊ธด๋‹ค.

## ๋ฆฌํŒฉํ„ฐ๋ง ์š”๊ตฌ์‚ฌํ•ญ

- [x] nextstep.qna.service.QnaService์˜ deleteQuestion()๋Š” ์•ž์˜ ์งˆ๋ฌธ ์‚ญ์ œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ์ด๋‹ค.
์ด ๋ฉ”์†Œ๋“œ๋Š” ๋‹จ์œ„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์–ด๋ ค์šด ์ฝ”๋“œ์™€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๊ฐ€ ์„ž์—ฌ ์žˆ๋‹ค.
- [x] QnaService์˜ deleteQuestion() ๋ฉ”์„œ๋“œ์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ(ํ•ต์‹ฌ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง)๋ฅผ ๋„๋ฉ”์ธ ๋ชจ๋ธ ๊ฐ์ฒด์— ๊ตฌํ˜„ํ•œ๋‹ค.
- [x] QnaService์˜ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์„ ๋„๋ฉ”์ธ ๋ชจ๋ธ๋กœ ์ด๋™ํ•˜๋Š” ๋ฆฌํŒฉํ„ฐ๋ง์„ ์ง„ํ–‰ํ•  ๋•Œ TDD๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.
- [x] QnaService์˜ deleteQuestion() ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” src/test/java ํด๋” nextstep.qna.service.QnaServiceTest์ด๋‹ค.
๋„๋ฉ”์ธ ๋ชจ๋ธ๋กœ ๋กœ์ง์„ ์ด๋™ํ•œ ํ›„์—๋„ QnaServiceTest์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๋Š” ํ†ต๊ณผํ•ด์•ผ ํ•œ๋‹ค.
12 changes: 12 additions & 0 deletions docs/check-list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# โœ”๏ธ PR ์ „ ํ™•์ธํ•ด์•ผ๋  ๋ชฉ๋ก
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿ‘

***

- ๊ฐ์ฒด์ง€ํ–ฅ ์ƒํ™œ์ฒด์กฐ ์›์น™์„ ์ค€์ˆ˜ํ•˜์˜€๋Š”๊ฐ€ ?
- TDD ์‚ฌ์ดํด๋กœ ๊ตฌํ˜„ํ•˜์˜€๋Š”๊ฐ€ ?
- TDD ์‚ฌ์ดํด ๋‹จ์œ„๋กœ ์ปค๋ฐ‹ํ•˜์˜€๋Š”๊ฐ€ ?
- ๊ฐ์ฒด์—๊ฒŒ ์ƒํƒœ๋ฅผ ๋…ธ์ถœ์‹œํ‚ค์ง€ ์•Š๊ณ  ์ฑ…์ž„์„ ๋งก๊ฒผ๋Š”๊ฐ€ ?
- ํ…Œ์Šฝ์œผ๋Š” ๊ฐ์ฒด์˜ ์ฑ…์ž„๊ณผ ๊ฒฐ๊ณผ๋งŒ ๊ฒ€์ฆํ–ˆ๋Š”๊ฐ€ ?
- ๋ถˆ๋ณ€์„ฑ์„ ์ตœ๋Œ€ํ•œ ์œ ์ง€ํ–ˆ๋Š”๊ฐ€ ?
- ๋„๋ฉ”์ธ ์šฉ์–ด๋กœ ๋„ค์ด๋ฐ ํ–ˆ๋Š”๊ฐ€ ?
- ํ˜‘๋ ฅ ๊ตฌ์กฐ๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ฝํžˆ๋Š”๊ฐ€ ?
- ๊ฐ™์€ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜๋ณตํ•˜์ง€๋Š” ์•Š์•˜๋Š”๊ฐ€ ?
40 changes: 20 additions & 20 deletions src/main/java/nextstep/qna/domain/Answer.java
Original file line number Diff line number Diff line change
@@ -1,40 +1,37 @@
package nextstep.qna.domain;

import nextstep.qna.CannotDeleteException;
import nextstep.qna.NotFoundException;
import nextstep.qna.UnAuthorizedException;
import nextstep.users.domain.NsUser;

import java.time.LocalDateTime;

public class Answer {
public class Answer extends SoftDeletableModel {
private Long id;

private NsUser writer;

private Question question;

private String contents;

private boolean deleted = false;

private LocalDateTime createdDate = LocalDateTime.now();

private LocalDateTime updatedDate;
private QuestionBody contents;

public Answer() {
}

public Answer(NsUser writer, Question question, String contents) {
this(null, writer, question, contents);
this(null, writer, question, new QuestionBody(contents));
}

public Answer(Long id, NsUser writer, Question question, String contents) {
this(id, writer, question, new QuestionBody(contents));
}

public Answer(Long id, NsUser writer, Question question, QuestionBody contents) {
this.id = id;
if(writer == null) {
if (writer == null) {
throw new UnAuthorizedException();
}

if(question == null) {
if (question == null) {
throw new NotFoundException();
}

Expand All @@ -47,13 +44,12 @@ public Long getId() {
return id;
}

public Answer setDeleted(boolean deleted) {
this.deleted = deleted;
return this;
private void updateDeleted() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ตณ์ด ์ด ๋ฉ”์„œ๋“œ ํ•„์š”์—†์ง€ ์•Š์„๊นŒ?
๋ฐ”๋กœ ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœํ•˜๋ฉด ๋˜์ง€ ์•Š์„๊นŒ?

deleted();
}

public boolean isDeleted() {
return deleted;
return getDeleted();
}

public boolean isOwner(NsUser writer) {
Expand All @@ -64,14 +60,18 @@ public NsUser getWriter() {
return writer;
}

public String getContents() {
return contents;
}

public void toQuestion(Question question) {
this.question = question;
}

public void validateAnswerOwner(NsUser loginUser) throws CannotDeleteException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public void validateAnswerOwner(NsUser loginUser) throws CannotDeleteException {
public void delete(NsUser loginUser) throws CannotDeleteException {

์‚ญ์ œ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด ์•„๋‹ˆ๋ผ ์‚ญ์ œ๊ฐ€ ํ•ต์‹ฌ์ด์ง€ ์•Š์„๊นŒ?

if (!this.isOwner(loginUser)) {
throw new CannotDeleteException("๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์“ด ๋‹ต๋ณ€์ด ์žˆ์–ด ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
}
updateDeleted();
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ˜„์žฌ๋Š” valid์™€ updateDeleted๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ๊ตฌํ˜„๋˜์–ด ์žˆ์Œ.
์ด ๋‘˜์„ ํ•˜๋‚˜๋กœ ๊ตฌํ˜„ํ•˜๋Š” ์•„๋ž˜์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ ์–ด๋А ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์„๊นŒ?

Suggested change
public void delete(NsUser loginUser) throws CannotDeleteException {
// ์œ ํšจ์„ฑ ์ฒดํฌ์™€ ์‚ญ์ œ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ด ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜ํ–ˆ๋Š”์ง€ ํ™•์ธ ํ•„์š”

@Override
public String toString() {
return "Answer [id=" + getId() + ", writer=" + writer + ", contents=" + contents + "]";
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/nextstep/qna/domain/Answers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package nextstep.qna.domain;

import nextstep.qna.CannotDeleteException;
import nextstep.users.domain.NsUser;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class Answers {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ผ๊ธ‰ ์ฝœ๋ ‰์…˜ ์ ์šฉ ๐Ÿ‘


private List<Answer> answers = new ArrayList<>();

public void add(Answer answer) {
this.answers.add(answer);
}

public List<Answer> getAnswers() {
return answers;
}

public void validateAnswerOwner(NsUser loginUser) throws CannotDeleteException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public void validateAnswerOwner(NsUser loginUser) throws CannotDeleteException {
public void delete(NsUser loginUser) throws CannotDeleteException {

์‚ญ์ œ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด ์•„๋‹ˆ๋ผ ์‚ญ์ œ๊ฐ€ ํ•ต์‹ฌ์ด์ง€ ์•Š์„๊นŒ?

for (Answer answer : this.answers) {
answer.validateAnswerOwner(loginUser);

}
}

public List<DeleteHistory> addDeleteAnswerHistory() {
List<DeleteHistory> deleteHistories = new ArrayList<>();
for (Answer answer : this.answers) {
deleteHistories.add(new DeleteHistory(ContentType.ANSWER, answer.getId(), answer.getWriter(), LocalDateTime.now()));
}
return deleteHistories;
}
}
73 changes: 38 additions & 35 deletions src/main/java/nextstep/qna/domain/Question.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
package nextstep.qna.domain;

import nextstep.qna.CannotDeleteException;
import nextstep.users.domain.NsUser;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class Question {
public class Question extends SoftDeletableModel {
private Long id;

private String title;
private QuestionBody title;

private String contents;
private QuestionBody contents;

private NsUser writer;

private List<Answer> answers = new ArrayList<>();

private boolean deleted = false;

private LocalDateTime createdDate = LocalDateTime.now();

private LocalDateTime updatedDate;
private Answers answers = new Answers();

public Question() {
}
Expand All @@ -31,6 +26,10 @@ public Question(NsUser writer, String title, String contents) {
}

public Question(Long id, NsUser writer, String title, String contents) {
this(id, writer, new QuestionBody(title), new QuestionBody(contents));
}

public Question(Long id, NsUser writer, QuestionBody title, QuestionBody contents) {
this.id = id;
this.writer = writer;
this.title = title;
Expand All @@ -41,52 +40,56 @@ public Long getId() {
return id;
}

public String getTitle() {
return title;
public NsUser getWriter() {
return writer;
}

public Question setTitle(String title) {
this.title = title;
return this;
public void addAnswer(Answer answer) {
answer.toQuestion(this);
this.answers.add(answer);
}

public String getContents() {
return contents;
public boolean isOwner(NsUser loginUser) {
return writer.equals(loginUser);
}

public Question setContents(String contents) {
this.contents = contents;
return this;
public boolean isDeleted() {
return getDeleted();
}

public NsUser getWriter() {
return writer;
private void validateOwner(NsUser loginUser) throws CannotDeleteException {
if (!this.isOwner(loginUser)) {
throw new CannotDeleteException("์งˆ๋ฌธ์„ ์‚ญ์ œํ•  ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค.");
}
updateDeleted();
}

public void addAnswer(Answer answer) {
answer.toQuestion(this);
answers.add(answer);
public void delete(NsUser loginUser) throws CannotDeleteException {
validateOwner(loginUser);
answers.validateAnswerOwner(loginUser);
}

public boolean isOwner(NsUser loginUser) {
return writer.equals(loginUser);
}
public List<DeleteHistory> toDeleteHistories(){
List<DeleteHistory> deleteHistories = new ArrayList<>();
deleteHistories.add(new DeleteHistory(ContentType.QUESTION, this.id, this.writer, LocalDateTime.now()));

public Question setDeleted(boolean deleted) {
this.deleted = deleted;
return this;
List<DeleteHistory> answerDeleteHistories = addDeleteAnswerHistory();
deleteHistories.addAll(answerDeleteHistories);

return deleteHistories;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ˜„์žฌ๋Š” delete()์—์„œ ์ƒํƒœ ๋ณ€๊ฒฝ๊ณผ List ์ƒ์„ฑ ํ›„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ˜„์žฌ ๊ตฌํ˜„๊ณผ delete()์™€ toDeleteHistories()์™€ ๊ฐ™์ด ์ƒํƒœ ๋ณ€๊ฒฝ๊ณผ List ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ ๋‘ ๊ฐœ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ ์ค‘ ์–ด๋А ์ ‘๊ทผ ๋ฐฉ์‹์ด ์ข‹์„๊นŒ?

public boolean isDeleted() {
return deleted;
private List<DeleteHistory> addDeleteAnswerHistory() {
return this.answers.addDeleteAnswerHistory();
}

public List<Answer> getAnswers() {
return answers;
private void updateDeleted() {
deleted();
}

@Override
public String toString() {
return "Question [id=" + getId() + ", title=" + title + ", contents=" + contents + ", writer=" + writer + "]";
}

}
10 changes: 10 additions & 0 deletions src/main/java/nextstep/qna/domain/QuestionBody.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package nextstep.qna.domain;

public class QuestionBody {

private String value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private String value;
private String title;
private String cotents;

์ด ๋‘ ๊ฐœ์˜ ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ–ˆ์Œ


public QuestionBody(String value) {
this.value = value;
}
}
20 changes: 20 additions & 0 deletions src/main/java/nextstep/qna/domain/SoftDeletableModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package nextstep.qna.domain;

import java.time.LocalDateTime;

public abstract class SoftDeletableModel {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿ‘


private LocalDateTime createdDate = LocalDateTime.now();

private LocalDateTime updatedDate;

private boolean deleted = false;

protected void deleted(){
this.deleted = true;
}

protected boolean getDeleted() {
return deleted;
}
}
21 changes: 2 additions & 19 deletions src/main/java/nextstep/qna/service/QnAService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service("qnaService")
Expand All @@ -26,24 +24,9 @@ public class QnAService {
@Transactional
public void deleteQuestion(NsUser loginUser, long questionId) throws CannotDeleteException {
Question question = questionRepository.findById(questionId).orElseThrow(NotFoundException::new);
if (!question.isOwner(loginUser)) {
throw new CannotDeleteException("์งˆ๋ฌธ์„ ์‚ญ์ œํ•  ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค.");
}
question.delete(loginUser);

List<Answer> answers = question.getAnswers();
for (Answer answer : answers) {
if (!answer.isOwner(loginUser)) {
throw new CannotDeleteException("๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์“ด ๋‹ต๋ณ€์ด ์žˆ์–ด ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
}
}

List<DeleteHistory> deleteHistories = new ArrayList<>();
question.setDeleted(true);
deleteHistories.add(new DeleteHistory(ContentType.QUESTION, questionId, question.getWriter(), LocalDateTime.now()));
for (Answer answer : answers) {
answer.setDeleted(true);
deleteHistories.add(new DeleteHistory(ContentType.ANSWER, answer.getId(), answer.getWriter(), LocalDateTime.now()));
}
List<DeleteHistory> deleteHistories = question.toDeleteHistories();
deleteHistoryService.saveAll(deleteHistories);
}
}
Loading