-
Notifications
You must be signed in to change notification settings - Fork 0
Draft > Application: Draft 제목, 시리즈, URL을 임시저장 합니다. #440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
import java.util.function.Supplier; | ||
|
||
public enum DraftErrorCode implements ErrorCode { | ||
|
||
// user input | ||
DRAFT_BLOG_ID_REQUIRED("블로그 ID를 반드시 제공해야 합니다.", HttpStatus.BAD_REQUEST), | ||
DRAFT_TITLE_MIN_LENGTH("블로그 제목은 반드시 3글자 이상입니다.", HttpStatus.BAD_REQUEST), | ||
|
@@ -19,7 +20,13 @@ public enum DraftErrorCode implements ErrorCode { | |
DRAFT_GONE("더 이상 존재하지 않는 게시물입니다.", HttpStatus.GONE), | ||
DRAFT_FORBIDDEN("권한이 없습니다.", HttpStatus.FORBIDDEN), | ||
DRAFT_ALREADY_EXIST("임시글이 이미 존재합니다.", HttpStatus.CONFLICT), | ||
DEFAULT("임시글 조작 오류", HttpStatus.INTERNAL_SERVER_ERROR); | ||
DEFAULT("임시글 조작 오류", HttpStatus.INTERNAL_SERVER_ERROR), | ||
BLOG_MISMATCH("드래프트와 시리즈가 같은 블로그에 속하지 않습니다.", HttpStatus.BAD_REQUEST), | ||
|
||
// series status | ||
SERIES_ARTICLE_NOT_FOUND("시리즈 아티클을 찾을 수 없습니다.", HttpStatus.NOT_FOUND), | ||
SERIES_NOT_FOUND("시리즈를 찾을 수 없습니다.", HttpStatus.NOT_FOUND), | ||
SERIES_ALREADY_REGISTERED("이미 등록된 시리즈 아티클입니다.", HttpStatus.CONFLICT); | ||
Comment on lines
+23
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
private final String message; | ||
private final HttpStatus httpStatus; | ||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -2,20 +2,28 @@ | |||
|
||||
import nettee.blolet.article.domain.Draft; | ||||
import nettee.blolet.article.domain.DraftImage; | ||||
import nettee.blolet.article.domain.SeriesArticle; | ||||
import nettee.blolet.article.domain.sub.DraftStatus; | ||||
import nettee.blolet.article.readmodel.DraftReadModels.DraftDetail; | ||||
import nettee.blolet.article.readmodel.SeriesQueryModels.SeriesDetail; | ||||
|
||||
import java.util.Optional; | ||||
|
||||
public interface DraftCommandPort { | ||||
|
||||
Optional<DraftDetail> findById(String id); | ||||
Optional<DraftDetail> findDraftById(String id); | ||||
Optional<SeriesDetail> findSeriesById(String seriesId); | ||||
|
||||
boolean existsSeriesArticle(String draftId, String seriesId); | ||||
|
||||
Draft save(Draft draft); | ||||
DraftImage save(DraftImage draftImage); | ||||
SeriesArticle createSeriesArticle(String draftId, String seriesId, String articleId); | ||||
|
||||
Draft update(Draft draft); | ||||
|
||||
Draft updateTitle(String draftId, String title); | ||||
Draft updatePath(String draftId, String path); | ||||
SeriesArticle updateSeriesArticle(String draftId, String seriesId, String articleId); | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 코 덜 파셨나 |
||||
void updateDraftSeriesInfo(String draftId, String seriesId); | ||||
void updateStatus(String id, DraftStatus draftStatus); | ||||
|
||||
DraftImage save(DraftImage draftImage); | ||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,21 +5,32 @@ | |
import nettee.blolet.article.application.usecase.DraftCreateUseCase; | ||
import nettee.blolet.article.application.usecase.DraftDeleteUseCase; | ||
import nettee.blolet.article.application.usecase.DraftImageCreateUseCase; | ||
import nettee.blolet.article.application.usecase.DraftPatchUseCase; | ||
import nettee.blolet.article.application.usecase.DraftUpdateUseCase; | ||
import nettee.blolet.article.domain.Draft; | ||
import nettee.blolet.article.domain.DraftImage; | ||
import nettee.blolet.article.domain.SeriesArticle; | ||
import nettee.blolet.article.domain.sub.DraftStatus; | ||
import nettee.blolet.blog.export.client.api.BlogClient; | ||
import nettee.upload.port.ImageStorage; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import static nettee.blolet.article.exception.DraftErrorCode.SERIES_ALREADY_REGISTERED; | ||
import static nettee.blolet.article.exception.DraftErrorCode.BLOG_MISMATCH; | ||
import static nettee.blolet.article.exception.DraftErrorCode.DRAFT_FORBIDDEN; | ||
import static nettee.blolet.article.exception.DraftErrorCode.DRAFT_NOT_FOUND; | ||
import static nettee.blolet.article.exception.DraftErrorCode.SERIES_NOT_FOUND; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class DraftCommandService implements DraftCreateUseCase, DraftUpdateUseCase, DraftDeleteUseCase, DraftImageCreateUseCase { | ||
public class DraftCommandService implements | ||
DraftCreateUseCase, | ||
DraftUpdateUseCase, | ||
DraftDeleteUseCase, | ||
DraftImageCreateUseCase, | ||
DraftPatchUseCase { | ||
|
||
private final DraftCommandPort draftCommandPort; | ||
private final BlogClient blogClient; | ||
private final ImageStorage imageStorage; | ||
|
@@ -38,7 +49,7 @@ public Draft updateDraft(String userId, Draft draft) { | |
|
||
@Override | ||
public void deleteDraft(String userId, String draftId) { | ||
var blogId = draftCommandPort.findById(draftId) | ||
var blogId = draftCommandPort.findDraftById(draftId) | ||
.orElseThrow(DRAFT_NOT_FOUND::exception) | ||
.blogId(); | ||
validateOwnership(userId, blogId); | ||
|
@@ -48,7 +59,7 @@ public void deleteDraft(String userId, String draftId) { | |
|
||
@Override | ||
public DraftImage createDraftImage(String userId, String draftId, MultipartFile file, String targetName) { | ||
var blogId = draftCommandPort.findById(draftId) | ||
var blogId = draftCommandPort.findDraftById(draftId) | ||
.orElseThrow(DRAFT_NOT_FOUND::exception) | ||
.blogId(); | ||
validateOwnership(userId, blogId); | ||
|
@@ -64,6 +75,58 @@ public DraftImage createDraftImage(String userId, String draftId, MultipartFile | |
return draftCommandPort.save(draftImage); | ||
} | ||
|
||
@Override | ||
public Draft patchTitle(String userId, String draftId, String title) { | ||
merge-simpson marked this conversation as resolved.
Show resolved
Hide resolved
|
||
var draft = draftCommandPort.findDraftById(draftId) | ||
.orElseThrow(DRAFT_NOT_FOUND::exception); | ||
|
||
validateOwnership(userId, draft.blogId()); | ||
|
||
return draftCommandPort.updateTitle(draft.id(), title); | ||
} | ||
|
||
@Override | ||
public Draft patchPath(String userId, String draftId, String path) { | ||
var draft = draftCommandPort.findDraftById(draftId) | ||
.orElseThrow(DRAFT_NOT_FOUND::exception); | ||
|
||
validateOwnership(userId, draft.blogId()); | ||
|
||
return draftCommandPort.updatePath(draft.id(), path); | ||
} | ||
|
||
@Override | ||
public SeriesArticle registerSeriesArticle(String userId, String draftId, String seriesId, String articleId) { | ||
// 드래프트, 시리즈 조회 | ||
var draft = draftCommandPort.findDraftById(draftId) | ||
.orElseThrow(DRAFT_NOT_FOUND::exception); | ||
|
||
var series = draftCommandPort.findSeriesById(seriesId) | ||
.orElseThrow(SERIES_NOT_FOUND::exception); | ||
|
||
// 권한 검증 | ||
validateOwnership(userId, draft.blogId()); | ||
validateOwnership(userId, series.blogId()); | ||
Comment on lines
+108
to
+109
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다음처럼 개선해 볼 수 있을까요? // [1] 서로 같은 블로그의 리소스인지 확인
var blogId = draft.blogId();
var seriesBlogId = series.blogId();
if (!Objects.equals(blogId, seriesBlogId)) {
// NOTE 정상적인 시나리오에서 발생하지 않으므로 너무 구체적인 메시지를 주지 않아도 충분합니다:
throw DRAFT_FORBIDDEN.exception();
}
// [2] 권한 검증
validateOwnership(userId, blogId);
|
||
|
||
// 블로그 동일 여부 확인 | ||
if (!draft.blogId().equals(series.blogId())) { | ||
throw BLOG_MISMATCH.exception(); | ||
} | ||
Comment on lines
+107
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다음처럼 개선해 볼 수 있을까요? // [1] 서로 같은 블로그의 리소스인지 확인
var blogId = draft.blogId();
var seriesBlogId = series.blogId();
if (!Objects.equals(blogId, seriesBlogId)) {
// NOTE 정상적인 시나리오에서 발생하지 않으므로 너무 구체적인 메시지를 주지 않아도 충분합니다:
throw DRAFT_FORBIDDEN.exception();
}
// [2] 권한 검증
validateOwnership(userId, blogId);
|
||
|
||
// 시리즈 존재 여부 확인 | ||
if (draftCommandPort.existsSeriesArticle(draftId, seriesId)) { | ||
throw SERIES_ALREADY_REGISTERED.exception(); | ||
} | ||
|
||
// 시리즈 등록 | ||
var seriesArticle = draftCommandPort.createSeriesArticle(draftId, seriesId, articleId); | ||
Comment on lines
+121
to
+122
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❓ 아티클 아이디, 드래프트 아이디를 모두 입력받는지, 그중 일부만 입력받을 수도 있는 건지 궁금합니다.
따라서, 모두 입력받는다는 전제에서는 다음과 같은 흐름을 표현하는 코드가 선행되어야 할 수 있습니다. var draftArticleId = draft.articleId();
if (!Objects.equals(draftArticleId, articleId)) {
throw ...
} 또는 일부만 입력받는다는 전제에서 다음과 같은 코드가 추가될 수 있습니다. // [1] 최소 하나 이상 입력
// articleId 또는 draftId 중 하나는 필수로 입력되어야 함.
if (articleId == null && draftId == null) {
throw ...
}
// draftId 조회
if (articleId != null) {
// [2] article 조회
// [3] 파라미터로 입력받은 draftId는 null이거나 article.draftId()와 일치해야 함.
// [4] 파라미터로 입력받은 draftId가 null이었다면 article.draftId()를 draftId로 사용.
}
// articleId 조회
// [5] draft 조회
// [6] 파라미터로 입력받은 articleId는 null이거나 draft.articleId()와 일치해야 함.
// [7] 파라미터로 입력받은 articleId가 null이었다면 draft.articleId()를 articleId로 사용. |
||
|
||
// 드래프트에 시리즈 정보 업데이트 | ||
draftCommandPort.updateDraftSeriesInfo(draftId, seriesId); | ||
|
||
return seriesArticle; | ||
} | ||
|
||
private void validateOwnership(String userId, String draftId) { | ||
var isOwner = blogClient.verifyOwnership(userId, draftId) | ||
.isOwner(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package nettee.blolet.article.application.usecase; | ||
|
||
import nettee.blolet.article.domain.Draft; | ||
import nettee.blolet.article.domain.SeriesArticle; | ||
|
||
public interface DraftPatchUseCase { | ||
|
||
Draft patchTitle(String userId, String draftId, String title); | ||
|
||
Draft patchPath(String userId, String draftId, String path); | ||
|
||
SeriesArticle registerSeriesArticle(String userId, String draftId, String seriesId, String articleId); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The empty line and comment placement creates inconsistent formatting. Remove the blank line after the enum declaration or move the comment to align with other comment groupings.
Copilot uses AI. Check for mistakes.