diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/post/controller/PostController.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/post/controller/PostController.java index 90f59f94..56a729ab 100644 --- a/LeeKunHee/src/main/java/com/leets/assignment/domain/post/controller/PostController.java +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/post/controller/PostController.java @@ -65,4 +65,13 @@ public ApiResponse deletePost( return ApiResponse.onSuccess("POST200_4", "게시글 삭제에 성공했습니다.", null); } + // 6. 게시글 숨기기 + @PatchMapping("/{postId}/hide") + public ApiResponse hidePost( + @PathVariable Long postId, + @RequestParam Long userId // 실제로는 인증된 유저 정보를 사용해야 함 + ) { + postService.hidePost(postId, userId); + return ApiResponse.onSuccess("POST200_5", "게시글이 숨김 처리되었습니다.", null); + } } \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/post/entity/Post.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/post/entity/Post.java index 822c93d3..1915f9b8 100644 --- a/LeeKunHee/src/main/java/com/leets/assignment/domain/post/entity/Post.java +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/post/entity/Post.java @@ -23,6 +23,10 @@ public class Post extends BaseEntity { @Column(name = "title", nullable = false) private String title; + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false) + private PostStatus status = PostStatus.ACTIVE; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") // FK 컬럼명 명시 private User user; @@ -34,6 +38,20 @@ public class Post extends BaseEntity { private Post(String title, User user) { this.title = title; this.user = user; + this.status = PostStatus.ACTIVE; + } + + + public void hideByUser() { + this.status = PostStatus.HIDDEN_BY_USER; + } + + public void hideByAdmin() { + this.status = PostStatus.HIDDEN_BY_ADMIN; + } + + public void unhide() { + this.status = PostStatus.ACTIVE; } public void softDelete() { diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/post/entity/PostStatus.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/post/entity/PostStatus.java new file mode 100644 index 00000000..c3a74783 --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/post/entity/PostStatus.java @@ -0,0 +1,14 @@ +package com.leets.assignment.domain.post.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum PostStatus { + ACTIVE("Active"), + HIDDEN_BY_USER("Hidden by user"), + HIDDEN_BY_ADMIN("Hidden by admin"); + + private final String description; +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/post/service/PostService.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/post/service/PostService.java index 555297ab..9da00570 100644 --- a/LeeKunHee/src/main/java/com/leets/assignment/domain/post/service/PostService.java +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/post/service/PostService.java @@ -4,6 +4,7 @@ import com.leets.assignment.domain.post.dto.res.PostResponseDTO; import com.leets.assignment.domain.post.entity.Post; import com.leets.assignment.domain.post.entity.PostBlock; +import com.leets.assignment.domain.post.entity.PostStatus; import com.leets.assignment.domain.post.exception.code.PostErrorCode; import com.leets.assignment.domain.post.exception.PostException; import com.leets.assignment.domain.post.repository.PostRepository; @@ -62,6 +63,7 @@ public PostResponseDTO.PostDetailResDTO getPost(Long postId) { // 2. 데이터가 없으면 PostNotFoundException 예외 발생! (-> 404 응답) Post post = postRepository.findById(postId) .filter(p -> p.getDeletedAt() == null) // 삭제 안 된 것만 필터링 + .filter(p -> p.getStatus() == PostStatus.ACTIVE) // 활성 상태 필터링 .orElseThrow(() -> new PostException(PostErrorCode.POST_NOT_FOUND)); // 3. 찾은 엔티티를 DTO로 변환하여 반환 @@ -73,6 +75,7 @@ public List getPostList() { // DB의 모든 글을 가져와서 ListResDTO로 변환 return postRepository.findAll().stream() .filter(post -> post.getDeletedAt() == null) // 삭제된 글 제외 + .filter(post -> post.getStatus() == PostStatus.ACTIVE) // 활성 상태 필터링 .map(PostResponseDTO.PostListResDTO::from) .collect(Collectors.toList()); } @@ -102,15 +105,20 @@ public PostResponseDTO.PostDetailResDTO updatePost(Long postId, PostRequestDTO.U .filter(p -> p.getDeletedAt() == null) .orElseThrow(() -> new PostException(PostErrorCode.POST_NOT_FOUND)); - // 2. 수정 권한 확인 + // 2. 관리자가 숨긴 글은 수정 불가 + if (post.getStatus() == PostStatus.HIDDEN_BY_ADMIN) { + throw new PostException(PostErrorCode.POST_FORBIDDEN); // 혹은 전용 에러 코드 사용 + } + + // 3. 수정 권한 확인 if (!post.getUser().getUserId().equals(request.getUserId())) { throw new PostException(PostErrorCode.POST_FORBIDDEN); } - // 3. 제목 수정 (Dirty Checking) + // 4. 제목 수정 (Dirty Checking) post.update(request.getTitle()); - // 4. 블록 수정 (기존 블록 비우고 새로 추가) + // 5. 블록 수정 (기존 블록 비우고 새로 추가) post.getBlocks().clear(); request.getBlocks().forEach(blockDto -> { PostBlock block = PostBlock.builder() @@ -124,4 +132,25 @@ public PostResponseDTO.PostDetailResDTO updatePost(Long postId, PostRequestDTO.U return PostResponseDTO.PostDetailResDTO.from(post); } + + // 게시글 숨김 + @Transactional + public void hidePost(Long postId, Long userId) { + + // 1. 게시글 존재 및 삭제 여부 확인 + Post post = postRepository.findById(postId) + .filter(p -> p.getDeletedAt() == null) + .orElseThrow(() -> new PostException(PostErrorCode.POST_NOT_FOUND)); + + // 2. 권한 확인 (관리자 기능이 없다면 우선 작성자 혹은 특정 조건 확인) + // post.getUser()가 null인지 먼저 확인하거나, equals를 활용 + if (post.getUser() == null || !post.getUser().getUserId().equals(userId)) { + throw new PostException(PostErrorCode.POST_FORBIDDEN); + } + + // 3. 상태 변경 (ACTIVE -> HIDDEN) + post.hideByUser(); + } + + } \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/controller/PostReportController.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/controller/PostReportController.java new file mode 100644 index 00000000..58ad03c7 --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/controller/PostReportController.java @@ -0,0 +1,34 @@ +package com.leets.assignment.domain.report.controller; + +import com.leets.assignment.domain.report.dto.req.PostReportRequestDTO; +import com.leets.assignment.domain.report.dto.res.PostReportResponseDTO; +import com.leets.assignment.domain.report.service.PostReportService; +import com.leets.assignment.global.common.ApiResponse; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/posts") +@RequiredArgsConstructor +public class PostReportController { + + private final PostReportService postReportService; + + @PostMapping("/{postId}/reports") + public ApiResponse createReport( + @PathVariable Long postId, + @Valid @RequestBody PostReportRequestDTO request) { + + PostReportResponseDTO response = postReportService.reportPost(postId, request.reporterId(), request.reason()); + return ApiResponse.onSuccess("REPORT201", "신고가 정상적으로 접수되었습니다.", response); + } + + @PatchMapping("/reports/{reportId}/resolve") + public ApiResponse resolveReport( + @PathVariable Long reportId + ) { + PostReportResponseDTO response = postReportService.resolveReport(reportId); + return ApiResponse.onSuccess("REPORT200_1", "신고 처리가 완료되어 해당 게시글이 숨겨졌습니다.", response); + } +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/dto/req/PostReportRequestDTO.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/dto/req/PostReportRequestDTO.java new file mode 100644 index 00000000..f0337642 --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/dto/req/PostReportRequestDTO.java @@ -0,0 +1,13 @@ +package com.leets.assignment.domain.report.dto.req; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +public record PostReportRequestDTO( + @NotNull(message = "신고자 ID는 필수입니다.") + Long reporterId, + + @NotBlank(message = "신고 사유를 입력해주세요.") + String reason +) { +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/dto/res/PostReportResponseDTO.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/dto/res/PostReportResponseDTO.java new file mode 100644 index 00000000..9ec2cd45 --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/dto/res/PostReportResponseDTO.java @@ -0,0 +1,16 @@ +package com.leets.assignment.domain.report.dto.res; + +import com.leets.assignment.domain.report.entity.ReportStatus; +import lombok.Builder; +import java.time.LocalDateTime; + +@Builder +public record PostReportResponseDTO( + Long reportId, + Long postId, + Long reporterId, + String reason, + ReportStatus status, + LocalDateTime createdAt +) { +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/entity/BaseReport.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/entity/BaseReport.java new file mode 100644 index 00000000..1957dc53 --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/entity/BaseReport.java @@ -0,0 +1,39 @@ +package com.leets.assignment.domain.report.entity; + +import com.leets.assignment.domain.user.entity.User; +import com.leets.assignment.global.baseEntity.BaseEntity; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@MappedSuperclass +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public abstract class BaseReport extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long reportId; // 신고 아이디 + + @Column(nullable = false) + private String reason; // 신고 사유 + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private ReportStatus status = ReportStatus.PENDING; // 신고 상태 (기본값: 대기중) + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "reporter_id", nullable = false) + private User reporter; // 신고자 + + protected BaseReport(User reporter, String reason) { + this.reporter = reporter; + this.reason = reason; + this.status = ReportStatus.PENDING; + } + + public void resolve() { + this.status = ReportStatus.RESOLVED; + } +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/entity/PostReport.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/entity/PostReport.java new file mode 100644 index 00000000..6cb41422 --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/entity/PostReport.java @@ -0,0 +1,26 @@ +package com.leets.assignment.domain.report.entity; + +import com.leets.assignment.domain.post.entity.Post; +import com.leets.assignment.domain.user.entity.User; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "post_reports") +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class PostReport extends BaseReport { + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id", nullable = false) + private Post post; // 신고 대상 게시글 + + @Builder + public PostReport(User reporter, Post post, String reason) { + super(reporter, reason); + this.post = post; + } +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/entity/ReportStatus.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/entity/ReportStatus.java new file mode 100644 index 00000000..e8263414 --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/entity/ReportStatus.java @@ -0,0 +1,13 @@ +package com.leets.assignment.domain.report.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum ReportStatus { + PENDING("Pending"), // 대기 중 + RESOLVED("Resolved"); // 처리 완료 + + private final String description; +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/exception/ReportException.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/exception/ReportException.java new file mode 100644 index 00000000..302c4e37 --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/exception/ReportException.java @@ -0,0 +1,14 @@ +package com.leets.assignment.domain.report.exception; + +import com.leets.assignment.domain.report.exception.code.ReportErrorCode; +import lombok.Getter; + +@Getter +public class ReportException extends RuntimeException { + private final ReportErrorCode errorCode; + + public ReportException(ReportErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/exception/code/ReportErrorCode.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/exception/code/ReportErrorCode.java new file mode 100644 index 00000000..640bf4df --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/exception/code/ReportErrorCode.java @@ -0,0 +1,19 @@ +package com.leets.assignment.domain.report.exception.code; + +import com.leets.assignment.global.exception.code.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum ReportErrorCode implements BaseErrorCode { + REPORT_DUPLICATED("REPORT409_1", "이미 신고한 게시글입니다.", HttpStatus.CONFLICT), + REPORT_SELF_FORBIDDEN("REPORT403_1", "자신의 게시글은 신고할 수 없습니다.", HttpStatus.FORBIDDEN), + REPORT_NOT_FOUND("REPORT404_1", "해당 신고 내역을 찾을 수 없습니다.", HttpStatus.NOT_FOUND), + REPORT_ALREADY_RESOLVED("REPORT400_1", "이미 처리가 완료된 신고입니다.", HttpStatus.BAD_REQUEST); + + private final String code; + private final String message; + private final HttpStatus httpStatus; +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/repository/PostReportRepository.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/repository/PostReportRepository.java new file mode 100644 index 00000000..c96922c8 --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/repository/PostReportRepository.java @@ -0,0 +1,14 @@ +package com.leets.assignment.domain.report.repository; + +import com.leets.assignment.domain.post.entity.Post; +import com.leets.assignment.domain.report.entity.PostReport; +import com.leets.assignment.domain.user.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostReportRepository extends JpaRepository { + // 특정 게시글의 전체 신고 횟수를 카운트하는 메서드 + // Post 엔티티 필드명(post) + Post 엔티티 내부의 PK 필드명(PostId) + long countByPost_PostId(Long postId); + // 중복 신고 확인: 동일 신고자가 동일 게시글을 이미 신고했는지 체크 + boolean existsByReporter_UserIdAndPost_PostId(Long userId, Long postId); +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/domain/report/service/PostReportService.java b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/service/PostReportService.java new file mode 100644 index 00000000..72147b5c --- /dev/null +++ b/LeeKunHee/src/main/java/com/leets/assignment/domain/report/service/PostReportService.java @@ -0,0 +1,111 @@ +package com.leets.assignment.domain.report.service; + +import com.leets.assignment.domain.post.entity.Post; +import com.leets.assignment.domain.post.entity.PostStatus; +import com.leets.assignment.domain.post.exception.PostException; +import com.leets.assignment.domain.post.exception.code.PostErrorCode; +import com.leets.assignment.domain.post.repository.PostRepository; +import com.leets.assignment.domain.report.dto.res.PostReportResponseDTO; +import com.leets.assignment.domain.report.entity.PostReport; +import com.leets.assignment.domain.report.entity.ReportStatus; +import com.leets.assignment.domain.report.exception.ReportException; +import com.leets.assignment.domain.report.exception.code.ReportErrorCode; +import com.leets.assignment.domain.report.repository.PostReportRepository; +import com.leets.assignment.domain.user.entity.User; +import com.leets.assignment.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class PostReportService { + + private final PostReportRepository postReportRepository; + private final PostRepository postRepository; + private final UserRepository userRepository; + + @Transactional + public PostReportResponseDTO reportPost(Long postId, Long reporterId, String reason) { + // 1. 검증 (중복/자기 신고 체크) + validateReport(postId, reporterId); + + // 2. 신고 저장 + PostReport report = postReportRepository.save(createReport(postId, reporterId, reason)); + + // 3. [핵심] 누적 신고 횟수 확인 (3회 이상이면 자동 숨김) + long reportCount = postReportRepository.countByPost_PostId(postId); + if (reportCount >= 3) { + Post post = report.getPost(); + if (post.getStatus() == PostStatus.ACTIVE) { + post.hideByAdmin(); // 누적 신고 임계치 도달 시 자동 숨김 + } + } + + return convertToDTO(report); + } + + // --- 내부 헬퍼 메서드 (기존 로직을 깔끔하게 정리) --- + + private void validateReport(Long postId, Long reporterId) { + Post post = postRepository.findById(postId) + .orElseThrow(() -> new PostException(PostErrorCode.POST_NOT_FOUND)); + + if (post.getUser().getUserId().equals(reporterId)) { + throw new ReportException(ReportErrorCode.REPORT_SELF_FORBIDDEN); + } + + if (postReportRepository.existsByReporter_UserIdAndPost_PostId(reporterId, postId)) { + throw new ReportException(ReportErrorCode.REPORT_DUPLICATED); + } + } + + private PostReport createReport(Long postId, Long reporterId, String reason) { + User reporter = userRepository.findById(reporterId) + .orElseThrow(() -> new RuntimeException("존재하지 않는 유저입니다.")); + Post post = postRepository.findById(postId).orElseThrow(); + + return PostReport.builder() + .reporter(reporter) + .post(post) + .reason(reason) + .build(); + } + + private PostReportResponseDTO convertToDTO(PostReport report) { + return PostReportResponseDTO.builder() + .reportId(report.getReportId()) + .postId(report.getPost().getPostId()) + .reporterId(report.getReporter().getUserId()) + .reason(report.getReason()) + .status(report.getStatus()) + .createdAt(report.getCreatedAt()) + .build(); + } + + @Transactional + public PostReportResponseDTO resolveReport(Long reportId) { + // 1. 신고 존재 확인 + PostReport report = postReportRepository.findById(reportId) + .orElseThrow(() -> new ReportException(ReportErrorCode.REPORT_NOT_FOUND)); + + // 2. 연결된 게시글 존재 확인 + Post post = report.getPost(); + if (post == null) { + throw new PostException(PostErrorCode.POST_NOT_FOUND); + } + + // 3. 상태 변경 (이미 RESOLVED인 경우 중복 처리 방지) + if (report.getStatus() == ReportStatus.RESOLVED) { + throw new ReportException(ReportErrorCode.REPORT_ALREADY_RESOLVED); + } + + report.resolve(); + post.hideByAdmin(); // Post 엔티티 내 status = PostStatus.HIDDEN_BY_ADMIN + + return convertToDTO(report); + + } + + +} \ No newline at end of file diff --git a/LeeKunHee/src/main/java/com/leets/assignment/global/exception/GlobalExceptionHandler.java b/LeeKunHee/src/main/java/com/leets/assignment/global/exception/GlobalExceptionHandler.java index 0a27acbb..29c217da 100644 --- a/LeeKunHee/src/main/java/com/leets/assignment/global/exception/GlobalExceptionHandler.java +++ b/LeeKunHee/src/main/java/com/leets/assignment/global/exception/GlobalExceptionHandler.java @@ -2,6 +2,8 @@ import com.leets.assignment.domain.post.exception.code.PostErrorCode; import com.leets.assignment.domain.post.exception.PostException; +import com.leets.assignment.domain.report.exception.ReportException; +import com.leets.assignment.domain.report.exception.code.ReportErrorCode; import com.leets.assignment.global.common.ApiResponse; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; @@ -69,6 +71,20 @@ public ResponseEntity> handleHttpMessageNotReadableException(H ); } + /** + * [REPORT400] ReportException + */ + @ExceptionHandler(ReportException.class) + public ResponseEntity> handleReportException(ReportException e) { + ReportErrorCode errorCode = e.getErrorCode(); + return ResponseEntity.status(errorCode.getHttpStatus()).body( + ApiResponse.builder() + .isSuccess(false) + .code(errorCode.getCode()) + .message(errorCode.getMessage()) + .build() + ); + } /** * [COMMON500_1] 기타 예기치 못한 서버 에러 diff --git a/LeeKunHee/src/main/resources/data.sql b/LeeKunHee/src/main/resources/data.sql index 85992066..86d676b1 100644 --- a/LeeKunHee/src/main/resources/data.sql +++ b/LeeKunHee/src/main/resources/data.sql @@ -1,3 +1,23 @@ --- 테스트용 유저 데이터 (서버 실행 시 자동 삽입) +-- 1번 유저 INSERT INTO users (user_id, email, name, nickname, password, created_at, updated_at) -VALUES (1, 'test@test.com', '강아지', '가나디', '1234', NOW(), NOW()); \ No newline at end of file +VALUES (1, 'test1@test.com', '강아지1', '가나디1', '1234', NOW(), NOW()); + +-- 2번 유저 +INSERT INTO users (user_id, email, name, nickname, password, created_at, updated_at) +VALUES (2, 'test2@test.com', '강아지2', '가나디2', '1234', NOW(), NOW()); + +-- 3번 유저 +INSERT INTO users (user_id, email, name, nickname, password, created_at, updated_at) +VALUES (3, 'test3@test.com', '강아지3', '가나디3', '1234', NOW(), NOW()); + +-- 4번 유저 +INSERT INTO users (user_id, email, name, nickname, password, created_at, updated_at) +VALUES (4, 'test4@test.com', '강아지4', '가나디4', '1234', NOW(), NOW()); + +-- 5번 유저 +INSERT INTO users (user_id, email, name, nickname, password, created_at, updated_at) +VALUES (5, 'test5@test.com', '강아지5', '가나디5', '1234', NOW(), NOW()); + +-- 6번 유저 +INSERT INTO users (user_id, email, name, nickname, password, created_at, updated_at) +VALUES (6, 'test6@test.com', '강아지6', '가나디6', '1234', NOW(), NOW()); \ No newline at end of file