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
Expand Up @@ -28,4 +28,11 @@ public class Comment extends BaseEntity {

@Column(length = 255)
private String content;

// domain/comment/entity/Comment.java
private boolean isAdopted = false; // 기본값 false

public void adopt() {
this.isAdopted = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ public ResponseEntity<BaseResponse<Map<String, Long>>> handleNotFoundException(N
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(BaseResponse.onFailure("4040", e.getMessage(), null));
}
@ExceptionHandler(IllegalStateException.class)
public BaseResponse<String> handleIllegalStateException(IllegalStateException e) {
// 500 에러 대신 400(Bad Request) 계열의 코드로 응답을 보냅니다.
return BaseResponse.onFailure("REPORT400", e.getMessage(), null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,10 @@ public BaseResponse<String> deletePost(@PathVariable Long postId) {
postService.delete(postId);
return BaseResponse.onSuccess("2003", "게시글 삭제 성공", "삭제된 게시글 ID: " + postId);
}
// domain/post/controller/PostController.java (기존 파일에 추가)
@PatchMapping("/{postId}/hide")
public BaseResponse<String> hidePost(@PathVariable Long postId) {
postService.hidePost(postId); // postStatus를 HIDDEN으로 바꾸는 로직
return BaseResponse.onSuccess("POST200", "게시글 숨김 처리가 완료되었습니다.", null);
}
}
7 changes: 7 additions & 0 deletions src/main/java/com/example/demo1/domain/post/entity/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,11 @@ public void update(String title, String content, String description) {
this.content = content;
this.description = description;
}
// domain/post/entity/Post.java 파일 안에 추가
@Enumerated(EnumType.STRING)
private PostStatus status = PostStatus.ACTIVE; // 기본값은 ACTIVE

public void hide() {
this.status = PostStatus.HIDDEN; // 상태를 HIDDEN으로 변경
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/example/demo1/domain/post/entity/PostStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.demo1.domain.post.entity;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum PostStatus {
ACTIVE("활성화"),
HIDDEN("숨김");

Comment on lines +8 to +11
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

과제에서 요구한 내용 명확하게 잘 구현하신 것 같습니다. 고생 많으셨습니다!

private final String description;
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,14 @@ public void delete(Long postId) {
}
postRepository.deleteById(postId);
}
// domain/post/service/PostService.java 파일 안에 추가
@Transactional
public void hidePost(Long postId) {
// 1. 해당 ID의 게시글을 찾고, 없으면 에러 발생
Post post = postRepository.findById(postId)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 게시글입니다."));

// 2. 게시글의 상태를 숨김으로 변경
post.hide();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.demo1.domain.report.controller;

import com.example.demo1.domain.global.response.BaseResponse;
import com.example.demo1.domain.report.dto.ReportRequestDto;
import com.example.demo1.domain.report.service.ReportService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/reports")
@RequiredArgsConstructor
public class ReportController {

private final ReportService reportService;

@PostMapping
public BaseResponse<String> report(@RequestBody ReportRequestDto dto) {
String result = reportService.createReport(dto.getReporterId(), dto.getTargetId());
return BaseResponse.onSuccess("REP200", result, null);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.demo1.domain.report.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class ReportRequestDto {
private Long reporterId;
private Long targetId;
}
28 changes: 28 additions & 0 deletions src/main/java/com/example/demo1/domain/report/entity/Report.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.example.demo1.domain.report.entity;

import com.example.demo1.domain.global.entity.BaseEntity;
import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED) // JPA를 위한 기본 생성자
@AllArgsConstructor
public class Report extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private Long reporterId; // 신고자 ID
private Long targetId; // 게시물 또는 댓글 ID
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

나중에 게시글(targetId = 1)이나 댓글(targetId=1)로 신고가 들어왔을 경우에 중복되는 문제가 생길 수도 있을 것 같습니다..! 따로 targetType을 지정해서 Post에 대한 신고인지, Comment에 대한 신고인지 구분해 놓으면 위 문제를 방지할 수 있을 것 같습니다. 고생하셨습니다! 💊


@Enumerated(EnumType.STRING)
private ReportStatus status = ReportStatus.PENDING; // 기본값: 대기중

public void resolve() {
this.status = ReportStatus.RESOLVED;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.demo1.domain.report.entity;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum ReportStatus {
PENDING("대기 중"),
RESOLVED("처리 완료");

private final String description;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.example.demo1.domain.report.entity;

public class ReportType {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.demo1.domain.report.repository;

import com.example.demo1.domain.report.entity.Report;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ReportRepository extends JpaRepository<Report, Long> {
// [중복 방지] 신고자와 타겟 ID로 이미 데이터가 있는지 확인하는 메서드
boolean existsByReporterIdAndTargetId(Long reporterId, Long targetId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.demo1.domain.report.service;

import com.example.demo1.domain.report.entity.Report;
import com.example.demo1.domain.report.entity.ReportStatus;
import com.example.demo1.domain.report.repository.ReportRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ReportService {

private final ReportRepository reportRepository;

@Transactional
public String createReport(Long reporterId, Long targetId) {
// [오류 해결 포인트 1] 리포지토리에 existsByReporterIdAndTargetId 메서드가 선언되어 있어야 합니다.
if (reportRepository.existsByReporterIdAndTargetId(reporterId, targetId)) {
throw new IllegalStateException("이미 신고한 대상입니다.");
}

Report report = Report.builder()
.reporterId(reporterId)
.targetId(targetId)
.status(ReportStatus.PENDING)
.build();

reportRepository.save(report);
return "신고가 정상적으로 접수되었습니다.";
}


}
14 changes: 8 additions & 6 deletions src/main/java/com/example/demo1/domain/user/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
import java.util.List;

@Entity
@Table(name = "user")
// [수정 포인트 1] 'user'는 예약어이므로 테이블 이름을 'users'로 변경합니다.
@Table(name = "users")
@Builder
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -23,20 +24,21 @@ public class User extends BaseEntity {

private Integer age;

@Column(length = 255)
// [수정 포인트 2] 실무에서는 null 방지나 유니크 설정을 위해 column 정의를 더 구체적으로 합니다.
@Column(nullable = false, length = 20)
private String name;

@Column(length = 255)
@Column(nullable = false, unique = true, length = 100)
private String email;

@Column(length = 255)
@Column(length = 50)
private String nickname;

@Builder.Default
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Post> posts = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();
}
1 change: 1 addition & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
spring.application.name=demo
spring.jpa.open-in-view=false