Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.sopt.makers.api.controller.admin.crew.mumu;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.sopt.makers.api.controller.admin.crew.mumu.dto.MumuTextUpsertRequest;
import org.sopt.makers.core.response.BaseResponse;
import org.springframework.http.ResponseEntity;

@Tag(name = "어드민 CREW 무무 텍스트", description = "CREW 무무 텍스트 관리 API")
public interface AdminMumuTextApi {

@Operation(summary = "무무 텍스트 목록 조회")
ResponseEntity<BaseResponse<?>> getMumuTexts();

@Operation(summary = "무무 텍스트 생성")
ResponseEntity<BaseResponse<?>> createMumuText(MumuTextUpsertRequest request);

@Operation(summary = "무무 텍스트 수정")
ResponseEntity<BaseResponse<?>> updateMumuText(Long mumuTextId, MumuTextUpsertRequest request);

@Operation(summary = "무무 텍스트 삭제")
ResponseEntity<BaseResponse<?>> deleteMumuText(Long mumuTextId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.sopt.makers.api.controller.admin.crew.mumu;

import static org.sopt.makers.api.controller.admin.crew.mumu.AdminMumuTextSuccessCode.CREATE_MUMU_TEXT;
import static org.sopt.makers.api.controller.admin.crew.mumu.AdminMumuTextSuccessCode.DELETE_MUMU_TEXT;
import static org.sopt.makers.api.controller.admin.crew.mumu.AdminMumuTextSuccessCode.GET_MUMU_TEXTS;
import static org.sopt.makers.api.controller.admin.crew.mumu.AdminMumuTextSuccessCode.UPDATE_MUMU_TEXT;

import jakarta.validation.Valid;
import java.time.Clock;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.sopt.makers.api.common.factory.ResponseFactory;
import org.sopt.makers.api.controller.admin.crew.mumu.dto.MumuTextResponse;
import org.sopt.makers.api.controller.admin.crew.mumu.dto.MumuTextUpsertRequest;
import org.sopt.makers.core.response.BaseResponse;
import org.sopt.makers.domain.crew.mumu.MumuText;
import org.sopt.makers.domain.crew.mumu.service.MumuTextService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/admin/crew/mumu-text")
@RequiredArgsConstructor
public class AdminMumuTextController implements AdminMumuTextApi {

private final MumuTextService mumuTextService;
private final Clock clock;

@Override
@GetMapping
public ResponseEntity<BaseResponse<?>> getMumuTexts() {
LocalDateTime now = LocalDateTime.now(clock);
return ResponseFactory.success(
GET_MUMU_TEXTS,
mumuTextService.findAll().stream().map(text -> MumuTextResponse.from(text, now)).toList());
}

@Override
@PostMapping
public ResponseEntity<BaseResponse<?>> createMumuText(
@Valid @RequestBody MumuTextUpsertRequest request) {
MumuText text = mumuTextService.create(request.toCommand());
return ResponseFactory.success(
CREATE_MUMU_TEXT, MumuTextResponse.from(text, LocalDateTime.now(clock)));
}

@Override
@PatchMapping("/{mumuTextId}")
public ResponseEntity<BaseResponse<?>> updateMumuText(
@PathVariable Long mumuTextId, @Valid @RequestBody MumuTextUpsertRequest request) {
MumuText text = mumuTextService.update(mumuTextId, request.toCommand());
return ResponseFactory.success(
UPDATE_MUMU_TEXT, MumuTextResponse.from(text, LocalDateTime.now(clock)));
}

@Override
@DeleteMapping("/{mumuTextId}")
public ResponseEntity<BaseResponse<?>> deleteMumuText(@PathVariable Long mumuTextId) {
mumuTextService.delete(mumuTextId);
return ResponseFactory.success(DELETE_MUMU_TEXT);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.sopt.makers.api.controller.admin.crew.mumu;

import static lombok.AccessLevel.PRIVATE;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.sopt.makers.core.code.SuccessCode;

@Getter
@RequiredArgsConstructor(access = PRIVATE)
public enum AdminMumuTextSuccessCode implements SuccessCode {
GET_MUMU_TEXTS(200, "무무 텍스트 목록 조회에 성공했습니다."),
CREATE_MUMU_TEXT(201, "무무 텍스트 생성에 성공했습니다."),
UPDATE_MUMU_TEXT(200, "무무 텍스트 수정에 성공했습니다."),
DELETE_MUMU_TEXT(200, "무무 텍스트 삭제에 성공했습니다.");

private final int statusCode;
private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.sopt.makers.api.controller.admin.crew.mumu.dto;

import java.time.LocalDateTime;
import org.sopt.makers.domain.crew.mumu.MumuText;

public record MumuTextResponse(
Long id,
String text,
String category,
LocalDateTime showStartDate,
LocalDateTime showEndDate,
MumuTextStatus status) {

public static MumuTextResponse from(MumuText mumuText, LocalDateTime now) {
return new MumuTextResponse(
mumuText.id(),
mumuText.text(),
mumuText.category(),
mumuText.showStartDate(),
mumuText.showEndDate(),
MumuTextStatus.from(now, mumuText.showStartDate(), mumuText.showEndDate()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.sopt.makers.api.controller.admin.crew.mumu.dto;

import java.time.LocalDateTime;

public enum MumuTextStatus {
ACTIVE,
SCHEDULED,
ENDED;

public static MumuTextStatus from(
LocalDateTime now, LocalDateTime startDate, LocalDateTime endDate) {
if (!now.isBefore(startDate) && now.isBefore(endDate)) {
return ACTIVE;
}
return now.isBefore(startDate) ? SCHEDULED : ENDED;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.sopt.makers.api.controller.admin.crew.mumu.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import org.sopt.makers.domain.crew.mumu.service.MumuTextService;

public record MumuTextUpsertRequest(
@NotBlank String text,
@NotBlank String category,
@NotNull LocalDateTime showStartDate,
@NotNull LocalDateTime showEndDate) {

public MumuTextService.CreateMumuTextCommand toCommand() {
return new MumuTextService.CreateMumuTextCommand(text, category, showStartDate, showEndDate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.sopt.makers.api.controller.crew.comment;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.sopt.makers.api.controller.crew.comment.dto.CreateCommentRequest;
import org.sopt.makers.api.controller.crew.comment.dto.GetCommentsRequest;
import org.sopt.makers.api.controller.crew.comment.dto.MentionCommentRequest;
import org.sopt.makers.api.controller.crew.comment.dto.UpdateCommentRequest;
import org.sopt.makers.core.response.BaseResponse;
import org.springframework.http.ResponseEntity;

@Tag(name = "CREW 게시글 댓글", description = "CREW 모임 게시글 댓글·대댓글 API")
public interface CommentApi {

@Operation(summary = "모임 게시글 댓글·대댓글 생성")
ResponseEntity<BaseResponse<?>> createComment(
CreateCommentRequest request, @Parameter(hidden = true) Long userId);

@Operation(summary = "모임 게시글 댓글·대댓글 조회")
ResponseEntity<BaseResponse<?>> getComments(
GetCommentsRequest request, @Parameter(hidden = true) Long userId);

@Operation(summary = "모임 게시글 댓글 수정")
ResponseEntity<BaseResponse<?>> updateComment(
Long commentId, UpdateCommentRequest request, @Parameter(hidden = true) Long userId);

@Operation(summary = "모임 게시글 댓글 삭제")
ResponseEntity<BaseResponse<?>> deleteComment(
Long commentId, @Parameter(hidden = true) Long userId);

@Operation(summary = "모임 게시글 댓글 신고")
ResponseEntity<BaseResponse<?>> reportComment(
Long commentId, @Parameter(hidden = true) Long userId);

@Operation(summary = "모임 게시글 댓글 좋아요 토글")
ResponseEntity<BaseResponse<?>> toggleCommentLike(
Long commentId, @Parameter(hidden = true) Long userId);

@Operation(summary = "모임 게시글 댓글에서 사용자 멘션")
ResponseEntity<BaseResponse<?>> mentionUsers(
MentionCommentRequest request, @Parameter(hidden = true) Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package org.sopt.makers.api.controller.crew.comment;

import static org.sopt.makers.api.controller.crew.comment.CommentSuccessCode.CREATE_COMMENT;
import static org.sopt.makers.api.controller.crew.comment.CommentSuccessCode.DELETE_COMMENT;
import static org.sopt.makers.api.controller.crew.comment.CommentSuccessCode.GET_COMMENTS;
import static org.sopt.makers.api.controller.crew.comment.CommentSuccessCode.MENTION_COMMENT_USERS;
import static org.sopt.makers.api.controller.crew.comment.CommentSuccessCode.REPORT_COMMENT;
import static org.sopt.makers.api.controller.crew.comment.CommentSuccessCode.TOGGLE_COMMENT_LIKE;
import static org.sopt.makers.api.controller.crew.comment.CommentSuccessCode.UPDATE_COMMENT;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.sopt.makers.api.common.factory.ResponseFactory;
import org.sopt.makers.api.common.resolver.CurrentUserId;
import org.sopt.makers.api.controller.crew.comment.dto.CommentPageResponse;
import org.sopt.makers.api.controller.crew.comment.dto.CreateCommentRequest;
import org.sopt.makers.api.controller.crew.comment.dto.CreateCommentResponse;
import org.sopt.makers.api.controller.crew.comment.dto.GetCommentsRequest;
import org.sopt.makers.api.controller.crew.comment.dto.MentionCommentRequest;
import org.sopt.makers.api.controller.crew.comment.dto.ReportCommentResponse;
import org.sopt.makers.api.controller.crew.comment.dto.ToggleCommentLikeResponse;
import org.sopt.makers.api.controller.crew.comment.dto.UpdateCommentRequest;
import org.sopt.makers.api.controller.crew.comment.dto.UpdateCommentResponse;
import org.sopt.makers.core.response.BaseResponse;
import org.sopt.makers.domain.playground.post.comment.PostComment;
import org.sopt.makers.domain.playground.post.report.PostCommentReport;
import org.sopt.makers.domain.playground.post.service.PostCommentService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/comment/v2")
@RequiredArgsConstructor
public class CommentController implements CommentApi {

private final PostCommentService commentService;

@Override
@PostMapping
public ResponseEntity<BaseResponse<?>> createComment(
@Valid @RequestBody CreateCommentRequest request, @CurrentUserId Long userId) {
PostComment comment =
commentService.createComment(request.postId(), request.toCommand(), userId);
return ResponseFactory.success(CREATE_COMMENT, new CreateCommentResponse(comment.id()));
}

@Override
@GetMapping
public ResponseEntity<BaseResponse<?>> getComments(
@Valid @ModelAttribute GetCommentsRequest request, @CurrentUserId Long userId) {
return ResponseFactory.success(
GET_COMMENTS,
CommentPageResponse.from(
commentService.findComments(
request.postId(), userId, request.pageOrDefault(), request.takeOrDefault())));
}

@Override
@PutMapping("/{commentId}")
public ResponseEntity<BaseResponse<?>> updateComment(
@PathVariable Long commentId,
@Valid @RequestBody UpdateCommentRequest request,
@CurrentUserId Long userId) {
PostCommentService.UpdatedComment updated =
commentService.updateComment(commentId, request.contents(), userId);
return ResponseFactory.success(
UPDATE_COMMENT,
new UpdateCommentResponse(
updated.comment().id(),
updated.comment().contents(),
String.valueOf(updated.updatedAt())));
}

@Override
@DeleteMapping("/{commentId}")
public ResponseEntity<BaseResponse<?>> deleteComment(
@PathVariable Long commentId, @CurrentUserId Long userId) {
commentService.deleteComment(commentId, userId);
return ResponseFactory.success(DELETE_COMMENT);
}

@Override
@PostMapping("/{commentId}/report")
public ResponseEntity<BaseResponse<?>> reportComment(
@PathVariable Long commentId, @CurrentUserId Long userId) {
PostCommentReport report = commentService.reportComment(commentId, userId);
return ResponseFactory.success(REPORT_COMMENT, new ReportCommentResponse(report.id()));
}

@Override
@PostMapping("/{commentId}/like")
public ResponseEntity<BaseResponse<?>> toggleCommentLike(
@PathVariable Long commentId, @CurrentUserId Long userId) {
return ResponseFactory.success(
TOGGLE_COMMENT_LIKE,
new ToggleCommentLikeResponse(commentService.toggleCommentLike(commentId, userId)));
}

@Override
@PostMapping("/mention")
public ResponseEntity<BaseResponse<?>> mentionUsers(
@Valid @RequestBody MentionCommentRequest request, @CurrentUserId Long userId) {
commentService.mentionUsers(request.postId(), request.orgIds(), request.content(), userId);
return ResponseFactory.success(MENTION_COMMENT_USERS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.sopt.makers.api.controller.crew.comment;

import static lombok.AccessLevel.PRIVATE;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.sopt.makers.core.code.SuccessCode;

@Getter
@RequiredArgsConstructor(access = PRIVATE)
public enum CommentSuccessCode implements SuccessCode {
CREATE_COMMENT(201, "모임 게시글 댓글 생성에 성공했습니다."),
GET_COMMENTS(200, "모임 게시글 댓글 조회에 성공했습니다."),
UPDATE_COMMENT(200, "모임 게시글 댓글 수정에 성공했습니다."),
DELETE_COMMENT(200, "모임 게시글 댓글 삭제에 성공했습니다."),
REPORT_COMMENT(201, "모임 게시글 댓글 신고에 성공했습니다."),
TOGGLE_COMMENT_LIKE(201, "모임 게시글 댓글 좋아요 상태 변경에 성공했습니다."),
MENTION_COMMENT_USERS(200, "모임 게시글 댓글 멘션 알림 전송에 성공했습니다.");

private final int statusCode;
private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.sopt.makers.api.controller.crew.comment.dto;

import java.util.List;
import org.sopt.makers.api.controller.crew.post.dto.PostPageMetaResponse;
import org.sopt.makers.core.pagination.PageResult;
import org.sopt.makers.domain.playground.post.service.PostCommentService;

public record CommentPageResponse(List<CommentResponse> comments, PostPageMetaResponse meta) {

public static CommentPageResponse from(PageResult<PostCommentService.CommentView> page) {
return new CommentPageResponse(
page.content().stream().map(CommentResponse::from).toList(),
PostPageMetaResponse.from(page));
}
}
Loading
Loading